diff --git a/.gitignore b/.gitignore index a3c30f016..558848c08 100755 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,12 @@ iguana/tests/.priv2wif.swp agents/libiguana.a iguana/iguana_rpc.o-2ed461a0 +agents/win32/iguana.exe +agents/win32/libcrypto777.a +agents/win32/confs/.tmpmarker +agents/win32/DB/.tmpmarker +agents/win32/DB/purgeable/.tmpmarker +agents/* + +iguana/confs/BTC_hdrs.txt + diff --git a/android/Android_Readme.md b/OSlibs/android/Android_Readme.md similarity index 100% rename from android/Android_Readme.md rename to OSlibs/android/Android_Readme.md diff --git a/android/include/curl/Makefile b/OSlibs/android/include/curl/Makefile similarity index 100% rename from android/include/curl/Makefile rename to OSlibs/android/include/curl/Makefile diff --git a/android/include/curl/Makefile.am b/OSlibs/android/include/curl/Makefile.am similarity index 100% rename from android/include/curl/Makefile.am rename to OSlibs/android/include/curl/Makefile.am diff --git a/android/include/curl/Makefile.in b/OSlibs/android/include/curl/Makefile.in similarity index 100% rename from android/include/curl/Makefile.in rename to OSlibs/android/include/curl/Makefile.in diff --git a/android/include/curl/curl.h b/OSlibs/android/include/curl/curl.h similarity index 100% rename from android/include/curl/curl.h rename to OSlibs/android/include/curl/curl.h diff --git a/android/include/curl/curlbuild.h b/OSlibs/android/include/curl/curlbuild.h similarity index 100% rename from android/include/curl/curlbuild.h rename to OSlibs/android/include/curl/curlbuild.h diff --git a/android/include/curl/curlbuild.h.cmake b/OSlibs/android/include/curl/curlbuild.h.cmake similarity index 100% rename from android/include/curl/curlbuild.h.cmake rename to OSlibs/android/include/curl/curlbuild.h.cmake diff --git a/android/include/curl/curlbuild.h.in b/OSlibs/android/include/curl/curlbuild.h.in similarity index 100% rename from android/include/curl/curlbuild.h.in rename to OSlibs/android/include/curl/curlbuild.h.in diff --git a/android/include/curl/curlrules.h b/OSlibs/android/include/curl/curlrules.h similarity index 100% rename from android/include/curl/curlrules.h rename to OSlibs/android/include/curl/curlrules.h diff --git a/android/include/curl/curlver.h b/OSlibs/android/include/curl/curlver.h similarity index 100% rename from android/include/curl/curlver.h rename to OSlibs/android/include/curl/curlver.h diff --git a/android/include/curl/easy.h b/OSlibs/android/include/curl/easy.h similarity index 100% rename from android/include/curl/easy.h rename to OSlibs/android/include/curl/easy.h diff --git a/android/include/curl/mprintf.h b/OSlibs/android/include/curl/mprintf.h similarity index 100% rename from android/include/curl/mprintf.h rename to OSlibs/android/include/curl/mprintf.h diff --git a/android/include/curl/multi.h b/OSlibs/android/include/curl/multi.h similarity index 100% rename from android/include/curl/multi.h rename to OSlibs/android/include/curl/multi.h diff --git a/android/include/curl/stamp-h2 b/OSlibs/android/include/curl/stamp-h2 similarity index 100% rename from android/include/curl/stamp-h2 rename to OSlibs/android/include/curl/stamp-h2 diff --git a/android/include/curl/stdcheaders.h b/OSlibs/android/include/curl/stdcheaders.h similarity index 100% rename from android/include/curl/stdcheaders.h rename to OSlibs/android/include/curl/stdcheaders.h diff --git a/android/include/curl/typecheck-gcc.h b/OSlibs/android/include/curl/typecheck-gcc.h similarity index 100% rename from android/include/curl/typecheck-gcc.h rename to OSlibs/android/include/curl/typecheck-gcc.h diff --git a/android/include/openssl/aes.h b/OSlibs/android/include/openssl/aes.h similarity index 100% rename from android/include/openssl/aes.h rename to OSlibs/android/include/openssl/aes.h diff --git a/android/include/openssl/asn1.h b/OSlibs/android/include/openssl/asn1.h similarity index 100% rename from android/include/openssl/asn1.h rename to OSlibs/android/include/openssl/asn1.h diff --git a/android/include/openssl/asn1_mac.h b/OSlibs/android/include/openssl/asn1_mac.h similarity index 100% rename from android/include/openssl/asn1_mac.h rename to OSlibs/android/include/openssl/asn1_mac.h diff --git a/android/include/openssl/asn1t.h b/OSlibs/android/include/openssl/asn1t.h similarity index 100% rename from android/include/openssl/asn1t.h rename to OSlibs/android/include/openssl/asn1t.h diff --git a/android/include/openssl/bio.h b/OSlibs/android/include/openssl/bio.h similarity index 100% rename from android/include/openssl/bio.h rename to OSlibs/android/include/openssl/bio.h diff --git a/android/include/openssl/blowfish.h b/OSlibs/android/include/openssl/blowfish.h similarity index 100% rename from android/include/openssl/blowfish.h rename to OSlibs/android/include/openssl/blowfish.h diff --git a/android/include/openssl/bn.h b/OSlibs/android/include/openssl/bn.h similarity index 100% rename from android/include/openssl/bn.h rename to OSlibs/android/include/openssl/bn.h diff --git a/android/include/openssl/buffer.h b/OSlibs/android/include/openssl/buffer.h similarity index 100% rename from android/include/openssl/buffer.h rename to OSlibs/android/include/openssl/buffer.h diff --git a/android/include/openssl/camellia.h b/OSlibs/android/include/openssl/camellia.h similarity index 100% rename from android/include/openssl/camellia.h rename to OSlibs/android/include/openssl/camellia.h diff --git a/android/include/openssl/cast.h b/OSlibs/android/include/openssl/cast.h similarity index 100% rename from android/include/openssl/cast.h rename to OSlibs/android/include/openssl/cast.h diff --git a/android/include/openssl/cmac.h b/OSlibs/android/include/openssl/cmac.h similarity index 100% rename from android/include/openssl/cmac.h rename to OSlibs/android/include/openssl/cmac.h diff --git a/android/include/openssl/cms.h b/OSlibs/android/include/openssl/cms.h similarity index 100% rename from android/include/openssl/cms.h rename to OSlibs/android/include/openssl/cms.h diff --git a/android/include/openssl/comp.h b/OSlibs/android/include/openssl/comp.h similarity index 100% rename from android/include/openssl/comp.h rename to OSlibs/android/include/openssl/comp.h diff --git a/android/include/openssl/conf.h b/OSlibs/android/include/openssl/conf.h similarity index 100% rename from android/include/openssl/conf.h rename to OSlibs/android/include/openssl/conf.h diff --git a/android/include/openssl/conf_api.h b/OSlibs/android/include/openssl/conf_api.h similarity index 100% rename from android/include/openssl/conf_api.h rename to OSlibs/android/include/openssl/conf_api.h diff --git a/android/include/openssl/cryptlib.h b/OSlibs/android/include/openssl/cryptlib.h similarity index 100% rename from android/include/openssl/cryptlib.h rename to OSlibs/android/include/openssl/cryptlib.h diff --git a/android/include/openssl/crypto.h b/OSlibs/android/include/openssl/crypto.h similarity index 100% rename from android/include/openssl/crypto.h rename to OSlibs/android/include/openssl/crypto.h diff --git a/android/include/openssl/curl.h b/OSlibs/android/include/openssl/curl.h similarity index 100% rename from android/include/openssl/curl.h rename to OSlibs/android/include/openssl/curl.h diff --git a/android/include/openssl/curlbuild.h b/OSlibs/android/include/openssl/curlbuild.h similarity index 100% rename from android/include/openssl/curlbuild.h rename to OSlibs/android/include/openssl/curlbuild.h diff --git a/android/include/openssl/curlrules.h b/OSlibs/android/include/openssl/curlrules.h similarity index 100% rename from android/include/openssl/curlrules.h rename to OSlibs/android/include/openssl/curlrules.h diff --git a/android/include/openssl/curlver.h b/OSlibs/android/include/openssl/curlver.h similarity index 100% rename from android/include/openssl/curlver.h rename to OSlibs/android/include/openssl/curlver.h diff --git a/android/include/openssl/des.h b/OSlibs/android/include/openssl/des.h similarity index 100% rename from android/include/openssl/des.h rename to OSlibs/android/include/openssl/des.h diff --git a/android/include/openssl/des_old.h b/OSlibs/android/include/openssl/des_old.h similarity index 100% rename from android/include/openssl/des_old.h rename to OSlibs/android/include/openssl/des_old.h diff --git a/android/include/openssl/dh.h b/OSlibs/android/include/openssl/dh.h similarity index 100% rename from android/include/openssl/dh.h rename to OSlibs/android/include/openssl/dh.h diff --git a/android/include/openssl/dsa.h b/OSlibs/android/include/openssl/dsa.h similarity index 100% rename from android/include/openssl/dsa.h rename to OSlibs/android/include/openssl/dsa.h diff --git a/android/include/openssl/dso.h b/OSlibs/android/include/openssl/dso.h similarity index 100% rename from android/include/openssl/dso.h rename to OSlibs/android/include/openssl/dso.h diff --git a/android/include/openssl/dtls1.h b/OSlibs/android/include/openssl/dtls1.h similarity index 100% rename from android/include/openssl/dtls1.h rename to OSlibs/android/include/openssl/dtls1.h diff --git a/android/include/openssl/e_os.h b/OSlibs/android/include/openssl/e_os.h similarity index 100% rename from android/include/openssl/e_os.h rename to OSlibs/android/include/openssl/e_os.h diff --git a/android/include/openssl/e_os2.h b/OSlibs/android/include/openssl/e_os2.h similarity index 100% rename from android/include/openssl/e_os2.h rename to OSlibs/android/include/openssl/e_os2.h diff --git a/android/include/openssl/easy.h b/OSlibs/android/include/openssl/easy.h similarity index 100% rename from android/include/openssl/easy.h rename to OSlibs/android/include/openssl/easy.h diff --git a/android/include/openssl/ebcdic.h b/OSlibs/android/include/openssl/ebcdic.h similarity index 100% rename from android/include/openssl/ebcdic.h rename to OSlibs/android/include/openssl/ebcdic.h diff --git a/android/include/openssl/ec.h b/OSlibs/android/include/openssl/ec.h similarity index 100% rename from android/include/openssl/ec.h rename to OSlibs/android/include/openssl/ec.h diff --git a/android/include/openssl/ecdh.h b/OSlibs/android/include/openssl/ecdh.h similarity index 100% rename from android/include/openssl/ecdh.h rename to OSlibs/android/include/openssl/ecdh.h diff --git a/android/include/openssl/ecdsa.h b/OSlibs/android/include/openssl/ecdsa.h similarity index 100% rename from android/include/openssl/ecdsa.h rename to OSlibs/android/include/openssl/ecdsa.h diff --git a/android/include/openssl/engine.h b/OSlibs/android/include/openssl/engine.h similarity index 100% rename from android/include/openssl/engine.h rename to OSlibs/android/include/openssl/engine.h diff --git a/android/include/openssl/err.h b/OSlibs/android/include/openssl/err.h similarity index 100% rename from android/include/openssl/err.h rename to OSlibs/android/include/openssl/err.h diff --git a/android/include/openssl/evp.h b/OSlibs/android/include/openssl/evp.h similarity index 100% rename from android/include/openssl/evp.h rename to OSlibs/android/include/openssl/evp.h diff --git a/android/include/openssl/fips_err.h b/OSlibs/android/include/openssl/fips_err.h similarity index 100% rename from android/include/openssl/fips_err.h rename to OSlibs/android/include/openssl/fips_err.h diff --git a/android/include/openssl/hmac.h b/OSlibs/android/include/openssl/hmac.h similarity index 100% rename from android/include/openssl/hmac.h rename to OSlibs/android/include/openssl/hmac.h diff --git a/android/include/openssl/idea.h b/OSlibs/android/include/openssl/idea.h similarity index 100% rename from android/include/openssl/idea.h rename to OSlibs/android/include/openssl/idea.h diff --git a/android/include/openssl/krb5_asn.h b/OSlibs/android/include/openssl/krb5_asn.h similarity index 100% rename from android/include/openssl/krb5_asn.h rename to OSlibs/android/include/openssl/krb5_asn.h diff --git a/android/include/openssl/kssl.h b/OSlibs/android/include/openssl/kssl.h similarity index 100% rename from android/include/openssl/kssl.h rename to OSlibs/android/include/openssl/kssl.h diff --git a/android/include/openssl/lhash.h b/OSlibs/android/include/openssl/lhash.h similarity index 100% rename from android/include/openssl/lhash.h rename to OSlibs/android/include/openssl/lhash.h diff --git a/android/include/openssl/md32_common.h b/OSlibs/android/include/openssl/md32_common.h similarity index 100% rename from android/include/openssl/md32_common.h rename to OSlibs/android/include/openssl/md32_common.h diff --git a/android/include/openssl/md4.h b/OSlibs/android/include/openssl/md4.h similarity index 100% rename from android/include/openssl/md4.h rename to OSlibs/android/include/openssl/md4.h diff --git a/android/include/openssl/md5.h b/OSlibs/android/include/openssl/md5.h similarity index 100% rename from android/include/openssl/md5.h rename to OSlibs/android/include/openssl/md5.h diff --git a/android/include/openssl/mdc2.h b/OSlibs/android/include/openssl/mdc2.h similarity index 100% rename from android/include/openssl/mdc2.h rename to OSlibs/android/include/openssl/mdc2.h diff --git a/android/include/openssl/modes.h b/OSlibs/android/include/openssl/modes.h similarity index 100% rename from android/include/openssl/modes.h rename to OSlibs/android/include/openssl/modes.h diff --git a/android/include/openssl/mprintf.h b/OSlibs/android/include/openssl/mprintf.h similarity index 100% rename from android/include/openssl/mprintf.h rename to OSlibs/android/include/openssl/mprintf.h diff --git a/android/include/openssl/multi.h b/OSlibs/android/include/openssl/multi.h similarity index 100% rename from android/include/openssl/multi.h rename to OSlibs/android/include/openssl/multi.h diff --git a/android/include/openssl/o_dir.h b/OSlibs/android/include/openssl/o_dir.h similarity index 100% rename from android/include/openssl/o_dir.h rename to OSlibs/android/include/openssl/o_dir.h diff --git a/android/include/openssl/o_str.h b/OSlibs/android/include/openssl/o_str.h similarity index 100% rename from android/include/openssl/o_str.h rename to OSlibs/android/include/openssl/o_str.h diff --git a/android/include/openssl/o_time.h b/OSlibs/android/include/openssl/o_time.h similarity index 100% rename from android/include/openssl/o_time.h rename to OSlibs/android/include/openssl/o_time.h diff --git a/android/include/openssl/obj_mac.h b/OSlibs/android/include/openssl/obj_mac.h similarity index 100% rename from android/include/openssl/obj_mac.h rename to OSlibs/android/include/openssl/obj_mac.h diff --git a/android/include/openssl/objects.h b/OSlibs/android/include/openssl/objects.h similarity index 100% rename from android/include/openssl/objects.h rename to OSlibs/android/include/openssl/objects.h diff --git a/android/include/openssl/ocsp.h b/OSlibs/android/include/openssl/ocsp.h similarity index 100% rename from android/include/openssl/ocsp.h rename to OSlibs/android/include/openssl/ocsp.h diff --git a/android/include/openssl/opensslconf.h b/OSlibs/android/include/openssl/opensslconf.h similarity index 100% rename from android/include/openssl/opensslconf.h rename to OSlibs/android/include/openssl/opensslconf.h diff --git a/android/include/openssl/opensslv.h b/OSlibs/android/include/openssl/opensslv.h similarity index 100% rename from android/include/openssl/opensslv.h rename to OSlibs/android/include/openssl/opensslv.h diff --git a/android/include/openssl/ossl_typ.h b/OSlibs/android/include/openssl/ossl_typ.h similarity index 100% rename from android/include/openssl/ossl_typ.h rename to OSlibs/android/include/openssl/ossl_typ.h diff --git a/android/include/openssl/pem.h b/OSlibs/android/include/openssl/pem.h similarity index 100% rename from android/include/openssl/pem.h rename to OSlibs/android/include/openssl/pem.h diff --git a/android/include/openssl/pem2.h b/OSlibs/android/include/openssl/pem2.h similarity index 100% rename from android/include/openssl/pem2.h rename to OSlibs/android/include/openssl/pem2.h diff --git a/android/include/openssl/pkcs12.h b/OSlibs/android/include/openssl/pkcs12.h similarity index 100% rename from android/include/openssl/pkcs12.h rename to OSlibs/android/include/openssl/pkcs12.h diff --git a/android/include/openssl/pkcs7.h b/OSlibs/android/include/openssl/pkcs7.h similarity index 100% rename from android/include/openssl/pkcs7.h rename to OSlibs/android/include/openssl/pkcs7.h diff --git a/android/include/openssl/pqueue.h b/OSlibs/android/include/openssl/pqueue.h similarity index 100% rename from android/include/openssl/pqueue.h rename to OSlibs/android/include/openssl/pqueue.h diff --git a/android/include/openssl/rand.h b/OSlibs/android/include/openssl/rand.h similarity index 100% rename from android/include/openssl/rand.h rename to OSlibs/android/include/openssl/rand.h diff --git a/android/include/openssl/rc2.h b/OSlibs/android/include/openssl/rc2.h similarity index 100% rename from android/include/openssl/rc2.h rename to OSlibs/android/include/openssl/rc2.h diff --git a/android/include/openssl/rc4.h b/OSlibs/android/include/openssl/rc4.h similarity index 100% rename from android/include/openssl/rc4.h rename to OSlibs/android/include/openssl/rc4.h diff --git a/android/include/openssl/ripemd.h b/OSlibs/android/include/openssl/ripemd.h similarity index 100% rename from android/include/openssl/ripemd.h rename to OSlibs/android/include/openssl/ripemd.h diff --git a/android/include/openssl/rsa.h b/OSlibs/android/include/openssl/rsa.h similarity index 100% rename from android/include/openssl/rsa.h rename to OSlibs/android/include/openssl/rsa.h diff --git a/android/include/openssl/safestack.h b/OSlibs/android/include/openssl/safestack.h similarity index 100% rename from android/include/openssl/safestack.h rename to OSlibs/android/include/openssl/safestack.h diff --git a/android/include/openssl/seed.h b/OSlibs/android/include/openssl/seed.h similarity index 100% rename from android/include/openssl/seed.h rename to OSlibs/android/include/openssl/seed.h diff --git a/android/include/openssl/sha.h b/OSlibs/android/include/openssl/sha.h similarity index 100% rename from android/include/openssl/sha.h rename to OSlibs/android/include/openssl/sha.h diff --git a/android/include/openssl/srp.h b/OSlibs/android/include/openssl/srp.h similarity index 100% rename from android/include/openssl/srp.h rename to OSlibs/android/include/openssl/srp.h diff --git a/android/include/openssl/srtp.h b/OSlibs/android/include/openssl/srtp.h similarity index 100% rename from android/include/openssl/srtp.h rename to OSlibs/android/include/openssl/srtp.h diff --git a/android/include/openssl/ssl.h b/OSlibs/android/include/openssl/ssl.h similarity index 100% rename from android/include/openssl/ssl.h rename to OSlibs/android/include/openssl/ssl.h diff --git a/android/include/openssl/ssl2.h b/OSlibs/android/include/openssl/ssl2.h similarity index 100% rename from android/include/openssl/ssl2.h rename to OSlibs/android/include/openssl/ssl2.h diff --git a/android/include/openssl/ssl23.h b/OSlibs/android/include/openssl/ssl23.h similarity index 100% rename from android/include/openssl/ssl23.h rename to OSlibs/android/include/openssl/ssl23.h diff --git a/android/include/openssl/ssl3.h b/OSlibs/android/include/openssl/ssl3.h similarity index 100% rename from android/include/openssl/ssl3.h rename to OSlibs/android/include/openssl/ssl3.h diff --git a/android/include/openssl/stack.h b/OSlibs/android/include/openssl/stack.h similarity index 100% rename from android/include/openssl/stack.h rename to OSlibs/android/include/openssl/stack.h diff --git a/android/include/openssl/stdcheaders.h b/OSlibs/android/include/openssl/stdcheaders.h similarity index 100% rename from android/include/openssl/stdcheaders.h rename to OSlibs/android/include/openssl/stdcheaders.h diff --git a/android/include/openssl/symhacks.h b/OSlibs/android/include/openssl/symhacks.h similarity index 100% rename from android/include/openssl/symhacks.h rename to OSlibs/android/include/openssl/symhacks.h diff --git a/android/include/openssl/tls1.h b/OSlibs/android/include/openssl/tls1.h similarity index 100% rename from android/include/openssl/tls1.h rename to OSlibs/android/include/openssl/tls1.h diff --git a/android/include/openssl/ts.h b/OSlibs/android/include/openssl/ts.h similarity index 100% rename from android/include/openssl/ts.h rename to OSlibs/android/include/openssl/ts.h diff --git a/android/include/openssl/txt_db.h b/OSlibs/android/include/openssl/txt_db.h similarity index 100% rename from android/include/openssl/txt_db.h rename to OSlibs/android/include/openssl/txt_db.h diff --git a/android/include/openssl/typecheck-gcc.h b/OSlibs/android/include/openssl/typecheck-gcc.h similarity index 100% rename from android/include/openssl/typecheck-gcc.h rename to OSlibs/android/include/openssl/typecheck-gcc.h diff --git a/android/include/openssl/ui.h b/OSlibs/android/include/openssl/ui.h similarity index 100% rename from android/include/openssl/ui.h rename to OSlibs/android/include/openssl/ui.h diff --git a/android/include/openssl/ui_compat.h b/OSlibs/android/include/openssl/ui_compat.h similarity index 100% rename from android/include/openssl/ui_compat.h rename to OSlibs/android/include/openssl/ui_compat.h diff --git a/android/include/openssl/vms_rms.h b/OSlibs/android/include/openssl/vms_rms.h similarity index 100% rename from android/include/openssl/vms_rms.h rename to OSlibs/android/include/openssl/vms_rms.h diff --git a/android/include/openssl/whrlpool.h b/OSlibs/android/include/openssl/whrlpool.h similarity index 100% rename from android/include/openssl/whrlpool.h rename to OSlibs/android/include/openssl/whrlpool.h diff --git a/android/include/openssl/x509.h b/OSlibs/android/include/openssl/x509.h similarity index 100% rename from android/include/openssl/x509.h rename to OSlibs/android/include/openssl/x509.h diff --git a/android/include/openssl/x509_vfy.h b/OSlibs/android/include/openssl/x509_vfy.h similarity index 100% rename from android/include/openssl/x509_vfy.h rename to OSlibs/android/include/openssl/x509_vfy.h diff --git a/android/include/openssl/x509v3.h b/OSlibs/android/include/openssl/x509v3.h similarity index 100% rename from android/include/openssl/x509v3.h rename to OSlibs/android/include/openssl/x509v3.h diff --git a/android/include/openssl/zconf.h b/OSlibs/android/include/openssl/zconf.h similarity index 100% rename from android/include/openssl/zconf.h rename to OSlibs/android/include/openssl/zconf.h diff --git a/android/include/openssl/zlib.h b/OSlibs/android/include/openssl/zlib.h similarity index 100% rename from android/include/openssl/zlib.h rename to OSlibs/android/include/openssl/zlib.h diff --git a/android/lib/libcrypto.so b/OSlibs/android/lib/libcrypto.so similarity index 100% rename from android/lib/libcrypto.so rename to OSlibs/android/lib/libcrypto.so diff --git a/android/lib/libcurl.a b/OSlibs/android/lib/libcurl.a similarity index 100% rename from android/lib/libcurl.a rename to OSlibs/android/lib/libcurl.a diff --git a/android/lib/libssl.so b/OSlibs/android/lib/libssl.so similarity index 100% rename from android/lib/libssl.so rename to OSlibs/android/lib/libssl.so diff --git a/android/set_android_env.sh b/OSlibs/android/set_android_env.sh similarity index 100% rename from android/set_android_env.sh rename to OSlibs/android/set_android_env.sh diff --git a/ios/iOS_Readme.md b/OSlibs/ios/iOS_Readme.md similarity index 100% rename from ios/iOS_Readme.md rename to OSlibs/ios/iOS_Readme.md diff --git a/OSlibs/ios/include/curl/curl.h b/OSlibs/ios/include/curl/curl.h new file mode 100755 index 000000000..516ede6ae --- /dev/null +++ b/OSlibs/ios/include/curl/curl.h @@ -0,0 +1,2440 @@ +#ifndef __CURL_CURL_H +#define __CURL_CURL_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * If you have libcurl problems, all docs and details are found here: + * https://curl.haxx.se/libcurl/ + * + * curl-library mailing list subscription and unsubscription web interface: + * https://cool.haxx.se/mailman/listinfo/curl-library/ + */ + +#include "curlver.h" /* libcurl version defines */ +#include "curlbuild.h" /* libcurl build definitions */ +#include "curlrules.h" /* libcurl rules enforcement */ + +/* + * Define WIN32 when build target is Win32 API + */ + +#if (defined(_WIN32) || defined(__WIN32__)) && \ + !defined(WIN32) && !defined(__SYMBIAN32__) +#define WIN32 +#endif + +#include +#include + +#if defined(__FreeBSD__) && (__FreeBSD__ >= 2) +/* Needed for __FreeBSD_version symbol definition */ +#include +#endif + +/* The include stuff here below is mainly for time_t! */ +#include +#include + +#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__CYGWIN__) +#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H) || \ + defined(__LWIP_OPT_H__) || defined(LWIP_HDR_OPT_H)) +/* The check above prevents the winsock2 inclusion if winsock.h already was + included, since they can't co-exist without problems */ +#include +#include +#endif +#endif + +/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish + libc5-based Linux systems. Only include it on systems that are known to + require it! */ +#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \ + defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \ + defined(ANDROID) || defined(__ANDROID__) || defined(__OpenBSD__) || \ + (defined(__FreeBSD_version) && (__FreeBSD_version < 800000)) +#include +#endif + +#if !defined(WIN32) && !defined(_WIN32_WCE) +#include +#endif + +#if !defined(WIN32) && !defined(__WATCOMC__) && !defined(__VXWORKS__) +#include +#endif + +#ifdef __BEOS__ +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct Curl_easy CURL; + +/* + * libcurl external API function linkage decorations. + */ + +#ifdef CURL_STATICLIB +# define CURL_EXTERN +#elif defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__) +# if defined(BUILDING_LIBCURL) +# define CURL_EXTERN __declspec(dllexport) +# else +# define CURL_EXTERN __declspec(dllimport) +# endif +#elif defined(BUILDING_LIBCURL) && defined(CURL_HIDDEN_SYMBOLS) +# define CURL_EXTERN CURL_EXTERN_SYMBOL +#else +# define CURL_EXTERN +#endif + +#ifndef curl_socket_typedef +/* socket typedef */ +#if defined(WIN32) && !defined(__LWIP_OPT_H__) && !defined(LWIP_HDR_OPT_H) +typedef SOCKET curl_socket_t; +#define CURL_SOCKET_BAD INVALID_SOCKET +#else +typedef int curl_socket_t; +#define CURL_SOCKET_BAD -1 +#endif +#define curl_socket_typedef +#endif /* curl_socket_typedef */ + +struct curl_httppost { + struct curl_httppost *next; /* next entry in the list */ + char *name; /* pointer to allocated name */ + long namelength; /* length of name length */ + char *contents; /* pointer to allocated data contents */ + long contentslength; /* length of contents field, see also + CURL_HTTPPOST_LARGE */ + char *buffer; /* pointer to allocated buffer contents */ + long bufferlength; /* length of buffer field */ + char *contenttype; /* Content-Type */ + struct curl_slist* contentheader; /* list of extra headers for this form */ + struct curl_httppost *more; /* if one field name has more than one + file, this link should link to following + files */ + long flags; /* as defined below */ + +/* specified content is a file name */ +#define CURL_HTTPPOST_FILENAME (1<<0) +/* specified content is a file name */ +#define CURL_HTTPPOST_READFILE (1<<1) +/* name is only stored pointer do not free in formfree */ +#define CURL_HTTPPOST_PTRNAME (1<<2) +/* contents is only stored pointer do not free in formfree */ +#define CURL_HTTPPOST_PTRCONTENTS (1<<3) +/* upload file from buffer */ +#define CURL_HTTPPOST_BUFFER (1<<4) +/* upload file from pointer contents */ +#define CURL_HTTPPOST_PTRBUFFER (1<<5) +/* upload file contents by using the regular read callback to get the data and + pass the given pointer as custom pointer */ +#define CURL_HTTPPOST_CALLBACK (1<<6) +/* use size in 'contentlen', added in 7.46.0 */ +#define CURL_HTTPPOST_LARGE (1<<7) + + char *showfilename; /* The file name to show. If not set, the + actual file name will be used (if this + is a file part) */ + void *userp; /* custom pointer used for + HTTPPOST_CALLBACK posts */ + curl_off_t contentlen; /* alternative length of contents + field. Used if CURL_HTTPPOST_LARGE is + set. Added in 7.46.0 */ +}; + +/* This is the CURLOPT_PROGRESSFUNCTION callback proto. It is now considered + deprecated but was the only choice up until 7.31.0 */ +typedef int (*curl_progress_callback)(void *clientp, + double dltotal, + double dlnow, + double ultotal, + double ulnow); + +/* This is the CURLOPT_XFERINFOFUNCTION callback proto. It was introduced in + 7.32.0, it avoids floating point and provides more detailed information. */ +typedef int (*curl_xferinfo_callback)(void *clientp, + curl_off_t dltotal, + curl_off_t dlnow, + curl_off_t ultotal, + curl_off_t ulnow); + +#ifndef CURL_MAX_WRITE_SIZE + /* Tests have proven that 20K is a very bad buffer size for uploads on + Windows, while 16K for some odd reason performed a lot better. + We do the ifndef check to allow this value to easier be changed at build + time for those who feel adventurous. The practical minimum is about + 400 bytes since libcurl uses a buffer of this size as a scratch area + (unrelated to network send operations). */ +#define CURL_MAX_WRITE_SIZE 16384 +#endif + +#ifndef CURL_MAX_HTTP_HEADER +/* The only reason to have a max limit for this is to avoid the risk of a bad + server feeding libcurl with a never-ending header that will cause reallocs + infinitely */ +#define CURL_MAX_HTTP_HEADER (100*1024) +#endif + +/* This is a magic return code for the write callback that, when returned, + will signal libcurl to pause receiving on the current transfer. */ +#define CURL_WRITEFUNC_PAUSE 0x10000001 + +typedef size_t (*curl_write_callback)(char *buffer, + size_t size, + size_t nitems, + void *outstream); + + + +/* enumeration of file types */ +typedef enum { + CURLFILETYPE_FILE = 0, + CURLFILETYPE_DIRECTORY, + CURLFILETYPE_SYMLINK, + CURLFILETYPE_DEVICE_BLOCK, + CURLFILETYPE_DEVICE_CHAR, + CURLFILETYPE_NAMEDPIPE, + CURLFILETYPE_SOCKET, + CURLFILETYPE_DOOR, /* is possible only on Sun Solaris now */ + + CURLFILETYPE_UNKNOWN /* should never occur */ +} curlfiletype; + +#define CURLFINFOFLAG_KNOWN_FILENAME (1<<0) +#define CURLFINFOFLAG_KNOWN_FILETYPE (1<<1) +#define CURLFINFOFLAG_KNOWN_TIME (1<<2) +#define CURLFINFOFLAG_KNOWN_PERM (1<<3) +#define CURLFINFOFLAG_KNOWN_UID (1<<4) +#define CURLFINFOFLAG_KNOWN_GID (1<<5) +#define CURLFINFOFLAG_KNOWN_SIZE (1<<6) +#define CURLFINFOFLAG_KNOWN_HLINKCOUNT (1<<7) + +/* Content of this structure depends on information which is known and is + achievable (e.g. by FTP LIST parsing). Please see the url_easy_setopt(3) man + page for callbacks returning this structure -- some fields are mandatory, + some others are optional. The FLAG field has special meaning. */ +struct curl_fileinfo { + char *filename; + curlfiletype filetype; + time_t time; + unsigned int perm; + int uid; + int gid; + curl_off_t size; + long int hardlinks; + + struct { + /* If some of these fields is not NULL, it is a pointer to b_data. */ + char *time; + char *perm; + char *user; + char *group; + char *target; /* pointer to the target filename of a symlink */ + } strings; + + unsigned int flags; + + /* used internally */ + char * b_data; + size_t b_size; + size_t b_used; +}; + +/* return codes for CURLOPT_CHUNK_BGN_FUNCTION */ +#define CURL_CHUNK_BGN_FUNC_OK 0 +#define CURL_CHUNK_BGN_FUNC_FAIL 1 /* tell the lib to end the task */ +#define CURL_CHUNK_BGN_FUNC_SKIP 2 /* skip this chunk over */ + +/* if splitting of data transfer is enabled, this callback is called before + download of an individual chunk started. Note that parameter "remains" works + only for FTP wildcard downloading (for now), otherwise is not used */ +typedef long (*curl_chunk_bgn_callback)(const void *transfer_info, + void *ptr, + int remains); + +/* return codes for CURLOPT_CHUNK_END_FUNCTION */ +#define CURL_CHUNK_END_FUNC_OK 0 +#define CURL_CHUNK_END_FUNC_FAIL 1 /* tell the lib to end the task */ + +/* If splitting of data transfer is enabled this callback is called after + download of an individual chunk finished. + Note! After this callback was set then it have to be called FOR ALL chunks. + Even if downloading of this chunk was skipped in CHUNK_BGN_FUNC. + This is the reason why we don't need "transfer_info" parameter in this + callback and we are not interested in "remains" parameter too. */ +typedef long (*curl_chunk_end_callback)(void *ptr); + +/* return codes for FNMATCHFUNCTION */ +#define CURL_FNMATCHFUNC_MATCH 0 /* string corresponds to the pattern */ +#define CURL_FNMATCHFUNC_NOMATCH 1 /* pattern doesn't match the string */ +#define CURL_FNMATCHFUNC_FAIL 2 /* an error occurred */ + +/* callback type for wildcard downloading pattern matching. If the + string matches the pattern, return CURL_FNMATCHFUNC_MATCH value, etc. */ +typedef int (*curl_fnmatch_callback)(void *ptr, + const char *pattern, + const char *string); + +/* These are the return codes for the seek callbacks */ +#define CURL_SEEKFUNC_OK 0 +#define CURL_SEEKFUNC_FAIL 1 /* fail the entire transfer */ +#define CURL_SEEKFUNC_CANTSEEK 2 /* tell libcurl seeking can't be done, so + libcurl might try other means instead */ +typedef int (*curl_seek_callback)(void *instream, + curl_off_t offset, + int origin); /* 'whence' */ + +/* This is a return code for the read callback that, when returned, will + signal libcurl to immediately abort the current transfer. */ +#define CURL_READFUNC_ABORT 0x10000000 +/* This is a return code for the read callback that, when returned, will + signal libcurl to pause sending data on the current transfer. */ +#define CURL_READFUNC_PAUSE 0x10000001 + +typedef size_t (*curl_read_callback)(char *buffer, + size_t size, + size_t nitems, + void *instream); + +typedef enum { + CURLSOCKTYPE_IPCXN, /* socket created for a specific IP connection */ + CURLSOCKTYPE_ACCEPT, /* socket created by accept() call */ + CURLSOCKTYPE_LAST /* never use */ +} curlsocktype; + +/* The return code from the sockopt_callback can signal information back + to libcurl: */ +#define CURL_SOCKOPT_OK 0 +#define CURL_SOCKOPT_ERROR 1 /* causes libcurl to abort and return + CURLE_ABORTED_BY_CALLBACK */ +#define CURL_SOCKOPT_ALREADY_CONNECTED 2 + +typedef int (*curl_sockopt_callback)(void *clientp, + curl_socket_t curlfd, + curlsocktype purpose); + +struct curl_sockaddr { + int family; + int socktype; + int protocol; + unsigned int addrlen; /* addrlen was a socklen_t type before 7.18.0 but it + turned really ugly and painful on the systems that + lack this type */ + struct sockaddr addr; +}; + +typedef curl_socket_t +(*curl_opensocket_callback)(void *clientp, + curlsocktype purpose, + struct curl_sockaddr *address); + +typedef int +(*curl_closesocket_callback)(void *clientp, curl_socket_t item); + +typedef enum { + CURLIOE_OK, /* I/O operation successful */ + CURLIOE_UNKNOWNCMD, /* command was unknown to callback */ + CURLIOE_FAILRESTART, /* failed to restart the read */ + CURLIOE_LAST /* never use */ +} curlioerr; + +typedef enum { + CURLIOCMD_NOP, /* no operation */ + CURLIOCMD_RESTARTREAD, /* restart the read stream from start */ + CURLIOCMD_LAST /* never use */ +} curliocmd; + +typedef curlioerr (*curl_ioctl_callback)(CURL *handle, + int cmd, + void *clientp); + +#ifndef CURL_DID_MEMORY_FUNC_TYPEDEFS +/* + * The following typedef's are signatures of malloc, free, realloc, strdup and + * calloc respectively. Function pointers of these types can be passed to the + * curl_global_init_mem() function to set user defined memory management + * callback routines. + */ +typedef void *(*curl_malloc_callback)(size_t size); +typedef void (*curl_free_callback)(void *ptr); +typedef void *(*curl_realloc_callback)(void *ptr, size_t size); +typedef char *(*curl_strdup_callback)(const char *str); +typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size); + +#define CURL_DID_MEMORY_FUNC_TYPEDEFS +#endif + +/* the kind of data that is passed to information_callback*/ +typedef enum { + CURLINFO_TEXT = 0, + CURLINFO_HEADER_IN, /* 1 */ + CURLINFO_HEADER_OUT, /* 2 */ + CURLINFO_DATA_IN, /* 3 */ + CURLINFO_DATA_OUT, /* 4 */ + CURLINFO_SSL_DATA_IN, /* 5 */ + CURLINFO_SSL_DATA_OUT, /* 6 */ + CURLINFO_END +} curl_infotype; + +typedef int (*curl_debug_callback) + (CURL *handle, /* the handle/transfer this concerns */ + curl_infotype type, /* what kind of data */ + char *data, /* points to the data */ + size_t size, /* size of the data pointed to */ + void *userptr); /* whatever the user please */ + +/* All possible error codes from all sorts of curl functions. Future versions + may return other values, stay prepared. + + Always add new return codes last. Never *EVER* remove any. The return + codes must remain the same! + */ + +typedef enum { + CURLE_OK = 0, + CURLE_UNSUPPORTED_PROTOCOL, /* 1 */ + CURLE_FAILED_INIT, /* 2 */ + CURLE_URL_MALFORMAT, /* 3 */ + CURLE_NOT_BUILT_IN, /* 4 - [was obsoleted in August 2007 for + 7.17.0, reused in April 2011 for 7.21.5] */ + CURLE_COULDNT_RESOLVE_PROXY, /* 5 */ + CURLE_COULDNT_RESOLVE_HOST, /* 6 */ + CURLE_COULDNT_CONNECT, /* 7 */ + CURLE_FTP_WEIRD_SERVER_REPLY, /* 8 */ + CURLE_REMOTE_ACCESS_DENIED, /* 9 a service was denied by the server + due to lack of access - when login fails + this is not returned. */ + CURLE_FTP_ACCEPT_FAILED, /* 10 - [was obsoleted in April 2006 for + 7.15.4, reused in Dec 2011 for 7.24.0]*/ + CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */ + CURLE_FTP_ACCEPT_TIMEOUT, /* 12 - timeout occurred accepting server + [was obsoleted in August 2007 for 7.17.0, + reused in Dec 2011 for 7.24.0]*/ + CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */ + CURLE_FTP_WEIRD_227_FORMAT, /* 14 */ + CURLE_FTP_CANT_GET_HOST, /* 15 */ + CURLE_HTTP2, /* 16 - A problem in the http2 framing layer. + [was obsoleted in August 2007 for 7.17.0, + reused in July 2014 for 7.38.0] */ + CURLE_FTP_COULDNT_SET_TYPE, /* 17 */ + CURLE_PARTIAL_FILE, /* 18 */ + CURLE_FTP_COULDNT_RETR_FILE, /* 19 */ + CURLE_OBSOLETE20, /* 20 - NOT USED */ + CURLE_QUOTE_ERROR, /* 21 - quote command failure */ + CURLE_HTTP_RETURNED_ERROR, /* 22 */ + CURLE_WRITE_ERROR, /* 23 */ + CURLE_OBSOLETE24, /* 24 - NOT USED */ + CURLE_UPLOAD_FAILED, /* 25 - failed upload "command" */ + CURLE_READ_ERROR, /* 26 - couldn't open/read from file */ + CURLE_OUT_OF_MEMORY, /* 27 */ + /* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error + instead of a memory allocation error if CURL_DOES_CONVERSIONS + is defined + */ + CURLE_OPERATION_TIMEDOUT, /* 28 - the timeout time was reached */ + CURLE_OBSOLETE29, /* 29 - NOT USED */ + CURLE_FTP_PORT_FAILED, /* 30 - FTP PORT operation failed */ + CURLE_FTP_COULDNT_USE_REST, /* 31 - the REST command failed */ + CURLE_OBSOLETE32, /* 32 - NOT USED */ + CURLE_RANGE_ERROR, /* 33 - RANGE "command" didn't work */ + CURLE_HTTP_POST_ERROR, /* 34 */ + CURLE_SSL_CONNECT_ERROR, /* 35 - wrong when connecting with SSL */ + CURLE_BAD_DOWNLOAD_RESUME, /* 36 - couldn't resume download */ + CURLE_FILE_COULDNT_READ_FILE, /* 37 */ + CURLE_LDAP_CANNOT_BIND, /* 38 */ + CURLE_LDAP_SEARCH_FAILED, /* 39 */ + CURLE_OBSOLETE40, /* 40 - NOT USED */ + CURLE_FUNCTION_NOT_FOUND, /* 41 */ + CURLE_ABORTED_BY_CALLBACK, /* 42 */ + CURLE_BAD_FUNCTION_ARGUMENT, /* 43 */ + CURLE_OBSOLETE44, /* 44 - NOT USED */ + CURLE_INTERFACE_FAILED, /* 45 - CURLOPT_INTERFACE failed */ + CURLE_OBSOLETE46, /* 46 - NOT USED */ + CURLE_TOO_MANY_REDIRECTS, /* 47 - catch endless re-direct loops */ + CURLE_UNKNOWN_OPTION, /* 48 - User specified an unknown option */ + CURLE_TELNET_OPTION_SYNTAX, /* 49 - Malformed telnet option */ + CURLE_OBSOLETE50, /* 50 - NOT USED */ + CURLE_PEER_FAILED_VERIFICATION, /* 51 - peer's certificate or fingerprint + wasn't verified fine */ + CURLE_GOT_NOTHING, /* 52 - when this is a specific error */ + CURLE_SSL_ENGINE_NOTFOUND, /* 53 - SSL crypto engine not found */ + CURLE_SSL_ENGINE_SETFAILED, /* 54 - can not set SSL crypto engine as + default */ + CURLE_SEND_ERROR, /* 55 - failed sending network data */ + CURLE_RECV_ERROR, /* 56 - failure in receiving network data */ + CURLE_OBSOLETE57, /* 57 - NOT IN USE */ + CURLE_SSL_CERTPROBLEM, /* 58 - problem with the local certificate */ + CURLE_SSL_CIPHER, /* 59 - couldn't use specified cipher */ + CURLE_SSL_CACERT, /* 60 - problem with the CA cert (path?) */ + CURLE_BAD_CONTENT_ENCODING, /* 61 - Unrecognized/bad encoding */ + CURLE_LDAP_INVALID_URL, /* 62 - Invalid LDAP URL */ + CURLE_FILESIZE_EXCEEDED, /* 63 - Maximum file size exceeded */ + CURLE_USE_SSL_FAILED, /* 64 - Requested FTP SSL level failed */ + CURLE_SEND_FAIL_REWIND, /* 65 - Sending the data requires a rewind + that failed */ + CURLE_SSL_ENGINE_INITFAILED, /* 66 - failed to initialise ENGINE */ + CURLE_LOGIN_DENIED, /* 67 - user, password or similar was not + accepted and we failed to login */ + CURLE_TFTP_NOTFOUND, /* 68 - file not found on server */ + CURLE_TFTP_PERM, /* 69 - permission problem on server */ + CURLE_REMOTE_DISK_FULL, /* 70 - out of disk space on server */ + CURLE_TFTP_ILLEGAL, /* 71 - Illegal TFTP operation */ + CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */ + CURLE_REMOTE_FILE_EXISTS, /* 73 - File already exists */ + CURLE_TFTP_NOSUCHUSER, /* 74 - No such user */ + CURLE_CONV_FAILED, /* 75 - conversion failed */ + CURLE_CONV_REQD, /* 76 - caller must register conversion + callbacks using curl_easy_setopt options + CURLOPT_CONV_FROM_NETWORK_FUNCTION, + CURLOPT_CONV_TO_NETWORK_FUNCTION, and + CURLOPT_CONV_FROM_UTF8_FUNCTION */ + CURLE_SSL_CACERT_BADFILE, /* 77 - could not load CACERT file, missing + or wrong format */ + CURLE_REMOTE_FILE_NOT_FOUND, /* 78 - remote file not found */ + CURLE_SSH, /* 79 - error from the SSH layer, somewhat + generic so the error message will be of + interest when this has happened */ + + CURLE_SSL_SHUTDOWN_FAILED, /* 80 - Failed to shut down the SSL + connection */ + CURLE_AGAIN, /* 81 - socket is not ready for send/recv, + wait till it's ready and try again (Added + in 7.18.2) */ + CURLE_SSL_CRL_BADFILE, /* 82 - could not load CRL file, missing or + wrong format (Added in 7.19.0) */ + CURLE_SSL_ISSUER_ERROR, /* 83 - Issuer check failed. (Added in + 7.19.0) */ + CURLE_FTP_PRET_FAILED, /* 84 - a PRET command failed */ + CURLE_RTSP_CSEQ_ERROR, /* 85 - mismatch of RTSP CSeq numbers */ + CURLE_RTSP_SESSION_ERROR, /* 86 - mismatch of RTSP Session Ids */ + CURLE_FTP_BAD_FILE_LIST, /* 87 - unable to parse FTP file list */ + CURLE_CHUNK_FAILED, /* 88 - chunk callback reported error */ + CURLE_NO_CONNECTION_AVAILABLE, /* 89 - No connection available, the + session will be queued */ + CURLE_SSL_PINNEDPUBKEYNOTMATCH, /* 90 - specified pinned public key did not + match */ + CURLE_SSL_INVALIDCERTSTATUS, /* 91 - invalid certificate status */ + CURLE_HTTP2_STREAM, /* 92 - stream error in HTTP/2 framing layer + */ + CURL_LAST /* never use! */ +} CURLcode; + +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all + the obsolete stuff removed! */ + +/* Previously obsolete error code re-used in 7.38.0 */ +#define CURLE_OBSOLETE16 CURLE_HTTP2 + +/* Previously obsolete error codes re-used in 7.24.0 */ +#define CURLE_OBSOLETE10 CURLE_FTP_ACCEPT_FAILED +#define CURLE_OBSOLETE12 CURLE_FTP_ACCEPT_TIMEOUT + +/* compatibility with older names */ +#define CURLOPT_ENCODING CURLOPT_ACCEPT_ENCODING + +/* The following were added in 7.21.5, April 2011 */ +#define CURLE_UNKNOWN_TELNET_OPTION CURLE_UNKNOWN_OPTION + +/* The following were added in 7.17.1 */ +/* These are scheduled to disappear by 2009 */ +#define CURLE_SSL_PEER_CERTIFICATE CURLE_PEER_FAILED_VERIFICATION + +/* The following were added in 7.17.0 */ +/* These are scheduled to disappear by 2009 */ +#define CURLE_OBSOLETE CURLE_OBSOLETE50 /* no one should be using this! */ +#define CURLE_BAD_PASSWORD_ENTERED CURLE_OBSOLETE46 +#define CURLE_BAD_CALLING_ORDER CURLE_OBSOLETE44 +#define CURLE_FTP_USER_PASSWORD_INCORRECT CURLE_OBSOLETE10 +#define CURLE_FTP_CANT_RECONNECT CURLE_OBSOLETE16 +#define CURLE_FTP_COULDNT_GET_SIZE CURLE_OBSOLETE32 +#define CURLE_FTP_COULDNT_SET_ASCII CURLE_OBSOLETE29 +#define CURLE_FTP_WEIRD_USER_REPLY CURLE_OBSOLETE12 +#define CURLE_FTP_WRITE_ERROR CURLE_OBSOLETE20 +#define CURLE_LIBRARY_NOT_FOUND CURLE_OBSOLETE40 +#define CURLE_MALFORMAT_USER CURLE_OBSOLETE24 +#define CURLE_SHARE_IN_USE CURLE_OBSOLETE57 +#define CURLE_URL_MALFORMAT_USER CURLE_NOT_BUILT_IN + +#define CURLE_FTP_ACCESS_DENIED CURLE_REMOTE_ACCESS_DENIED +#define CURLE_FTP_COULDNT_SET_BINARY CURLE_FTP_COULDNT_SET_TYPE +#define CURLE_FTP_QUOTE_ERROR CURLE_QUOTE_ERROR +#define CURLE_TFTP_DISKFULL CURLE_REMOTE_DISK_FULL +#define CURLE_TFTP_EXISTS CURLE_REMOTE_FILE_EXISTS +#define CURLE_HTTP_RANGE_ERROR CURLE_RANGE_ERROR +#define CURLE_FTP_SSL_FAILED CURLE_USE_SSL_FAILED + +/* The following were added earlier */ + +#define CURLE_OPERATION_TIMEOUTED CURLE_OPERATION_TIMEDOUT + +#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR +#define CURLE_HTTP_PORT_FAILED CURLE_INTERFACE_FAILED +#define CURLE_FTP_COULDNT_STOR_FILE CURLE_UPLOAD_FAILED + +#define CURLE_FTP_PARTIAL_FILE CURLE_PARTIAL_FILE +#define CURLE_FTP_BAD_DOWNLOAD_RESUME CURLE_BAD_DOWNLOAD_RESUME + +/* This was the error code 50 in 7.7.3 and a few earlier versions, this + is no longer used by libcurl but is instead #defined here only to not + make programs break */ +#define CURLE_ALREADY_COMPLETE 99999 + +/* Provide defines for really old option names */ +#define CURLOPT_FILE CURLOPT_WRITEDATA /* name changed in 7.9.7 */ +#define CURLOPT_INFILE CURLOPT_READDATA /* name changed in 7.9.7 */ +#define CURLOPT_WRITEHEADER CURLOPT_HEADERDATA + +/* Since long deprecated options with no code in the lib that does anything + with them. */ +#define CURLOPT_WRITEINFO CURLOPT_OBSOLETE40 +#define CURLOPT_CLOSEPOLICY CURLOPT_OBSOLETE72 + +#endif /*!CURL_NO_OLDIES*/ + +/* This prototype applies to all conversion callbacks */ +typedef CURLcode (*curl_conv_callback)(char *buffer, size_t length); + +typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl, /* easy handle */ + void *ssl_ctx, /* actually an + OpenSSL SSL_CTX */ + void *userptr); + +typedef enum { + CURLPROXY_HTTP = 0, /* added in 7.10, new in 7.19.4 default is to use + CONNECT HTTP/1.1 */ + CURLPROXY_HTTP_1_0 = 1, /* added in 7.19.4, force to use CONNECT + HTTP/1.0 */ + CURLPROXY_SOCKS4 = 4, /* support added in 7.15.2, enum existed already + in 7.10 */ + CURLPROXY_SOCKS5 = 5, /* added in 7.10 */ + CURLPROXY_SOCKS4A = 6, /* added in 7.18.0 */ + CURLPROXY_SOCKS5_HOSTNAME = 7 /* Use the SOCKS5 protocol but pass along the + host name rather than the IP address. added + in 7.18.0 */ +} curl_proxytype; /* this enum was added in 7.10 */ + +/* + * Bitmasks for CURLOPT_HTTPAUTH and CURLOPT_PROXYAUTH options: + * + * CURLAUTH_NONE - No HTTP authentication + * CURLAUTH_BASIC - HTTP Basic authentication (default) + * CURLAUTH_DIGEST - HTTP Digest authentication + * CURLAUTH_NEGOTIATE - HTTP Negotiate (SPNEGO) authentication + * CURLAUTH_GSSNEGOTIATE - Alias for CURLAUTH_NEGOTIATE (deprecated) + * CURLAUTH_NTLM - HTTP NTLM authentication + * CURLAUTH_DIGEST_IE - HTTP Digest authentication with IE flavour + * CURLAUTH_NTLM_WB - HTTP NTLM authentication delegated to winbind helper + * CURLAUTH_ONLY - Use together with a single other type to force no + * authentication or just that single type + * CURLAUTH_ANY - All fine types set + * CURLAUTH_ANYSAFE - All fine types except Basic + */ + +#define CURLAUTH_NONE ((unsigned long)0) +#define CURLAUTH_BASIC (((unsigned long)1)<<0) +#define CURLAUTH_DIGEST (((unsigned long)1)<<1) +#define CURLAUTH_NEGOTIATE (((unsigned long)1)<<2) +/* Deprecated since the advent of CURLAUTH_NEGOTIATE */ +#define CURLAUTH_GSSNEGOTIATE CURLAUTH_NEGOTIATE +#define CURLAUTH_NTLM (((unsigned long)1)<<3) +#define CURLAUTH_DIGEST_IE (((unsigned long)1)<<4) +#define CURLAUTH_NTLM_WB (((unsigned long)1)<<5) +#define CURLAUTH_ONLY (((unsigned long)1)<<31) +#define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE) +#define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE)) + +#define CURLSSH_AUTH_ANY ~0 /* all types supported by the server */ +#define CURLSSH_AUTH_NONE 0 /* none allowed, silly but complete */ +#define CURLSSH_AUTH_PUBLICKEY (1<<0) /* public/private key files */ +#define CURLSSH_AUTH_PASSWORD (1<<1) /* password */ +#define CURLSSH_AUTH_HOST (1<<2) /* host key files */ +#define CURLSSH_AUTH_KEYBOARD (1<<3) /* keyboard interactive */ +#define CURLSSH_AUTH_AGENT (1<<4) /* agent (ssh-agent, pageant...) */ +#define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY + +#define CURLGSSAPI_DELEGATION_NONE 0 /* no delegation (default) */ +#define CURLGSSAPI_DELEGATION_POLICY_FLAG (1<<0) /* if permitted by policy */ +#define CURLGSSAPI_DELEGATION_FLAG (1<<1) /* delegate always */ + +#define CURL_ERROR_SIZE 256 + +enum curl_khtype { + CURLKHTYPE_UNKNOWN, + CURLKHTYPE_RSA1, + CURLKHTYPE_RSA, + CURLKHTYPE_DSS +}; + +struct curl_khkey { + const char *key; /* points to a zero-terminated string encoded with base64 + if len is zero, otherwise to the "raw" data */ + size_t len; + enum curl_khtype keytype; +}; + +/* this is the set of return values expected from the curl_sshkeycallback + callback */ +enum curl_khstat { + CURLKHSTAT_FINE_ADD_TO_FILE, + CURLKHSTAT_FINE, + CURLKHSTAT_REJECT, /* reject the connection, return an error */ + CURLKHSTAT_DEFER, /* do not accept it, but we can't answer right now so + this causes a CURLE_DEFER error but otherwise the + connection will be left intact etc */ + CURLKHSTAT_LAST /* not for use, only a marker for last-in-list */ +}; + +/* this is the set of status codes pass in to the callback */ +enum curl_khmatch { + CURLKHMATCH_OK, /* match */ + CURLKHMATCH_MISMATCH, /* host found, key mismatch! */ + CURLKHMATCH_MISSING, /* no matching host/key found */ + CURLKHMATCH_LAST /* not for use, only a marker for last-in-list */ +}; + +typedef int + (*curl_sshkeycallback) (CURL *easy, /* easy handle */ + const struct curl_khkey *knownkey, /* known */ + const struct curl_khkey *foundkey, /* found */ + enum curl_khmatch, /* libcurl's view on the keys */ + void *clientp); /* custom pointer passed from app */ + +/* parameter for the CURLOPT_USE_SSL option */ +typedef enum { + CURLUSESSL_NONE, /* do not attempt to use SSL */ + CURLUSESSL_TRY, /* try using SSL, proceed anyway otherwise */ + CURLUSESSL_CONTROL, /* SSL for the control connection or fail */ + CURLUSESSL_ALL, /* SSL for all communication or fail */ + CURLUSESSL_LAST /* not an option, never use */ +} curl_usessl; + +/* Definition of bits for the CURLOPT_SSL_OPTIONS argument: */ + +/* - ALLOW_BEAST tells libcurl to allow the BEAST SSL vulnerability in the + name of improving interoperability with older servers. Some SSL libraries + have introduced work-arounds for this flaw but those work-arounds sometimes + make the SSL communication fail. To regain functionality with those broken + servers, a user can this way allow the vulnerability back. */ +#define CURLSSLOPT_ALLOW_BEAST (1<<0) + +/* - NO_REVOKE tells libcurl to disable certificate revocation checks for those + SSL backends where such behavior is present. */ +#define CURLSSLOPT_NO_REVOKE (1<<1) + +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all + the obsolete stuff removed! */ + +/* Backwards compatibility with older names */ +/* These are scheduled to disappear by 2009 */ + +#define CURLFTPSSL_NONE CURLUSESSL_NONE +#define CURLFTPSSL_TRY CURLUSESSL_TRY +#define CURLFTPSSL_CONTROL CURLUSESSL_CONTROL +#define CURLFTPSSL_ALL CURLUSESSL_ALL +#define CURLFTPSSL_LAST CURLUSESSL_LAST +#define curl_ftpssl curl_usessl +#endif /*!CURL_NO_OLDIES*/ + +/* parameter for the CURLOPT_FTP_SSL_CCC option */ +typedef enum { + CURLFTPSSL_CCC_NONE, /* do not send CCC */ + CURLFTPSSL_CCC_PASSIVE, /* Let the server initiate the shutdown */ + CURLFTPSSL_CCC_ACTIVE, /* Initiate the shutdown */ + CURLFTPSSL_CCC_LAST /* not an option, never use */ +} curl_ftpccc; + +/* parameter for the CURLOPT_FTPSSLAUTH option */ +typedef enum { + CURLFTPAUTH_DEFAULT, /* let libcurl decide */ + CURLFTPAUTH_SSL, /* use "AUTH SSL" */ + CURLFTPAUTH_TLS, /* use "AUTH TLS" */ + CURLFTPAUTH_LAST /* not an option, never use */ +} curl_ftpauth; + +/* parameter for the CURLOPT_FTP_CREATE_MISSING_DIRS option */ +typedef enum { + CURLFTP_CREATE_DIR_NONE, /* do NOT create missing dirs! */ + CURLFTP_CREATE_DIR, /* (FTP/SFTP) if CWD fails, try MKD and then CWD + again if MKD succeeded, for SFTP this does + similar magic */ + CURLFTP_CREATE_DIR_RETRY, /* (FTP only) if CWD fails, try MKD and then CWD + again even if MKD failed! */ + CURLFTP_CREATE_DIR_LAST /* not an option, never use */ +} curl_ftpcreatedir; + +/* parameter for the CURLOPT_FTP_FILEMETHOD option */ +typedef enum { + CURLFTPMETHOD_DEFAULT, /* let libcurl pick */ + CURLFTPMETHOD_MULTICWD, /* single CWD operation for each path part */ + CURLFTPMETHOD_NOCWD, /* no CWD at all */ + CURLFTPMETHOD_SINGLECWD, /* one CWD to full dir, then work on file */ + CURLFTPMETHOD_LAST /* not an option, never use */ +} curl_ftpmethod; + +/* bitmask defines for CURLOPT_HEADEROPT */ +#define CURLHEADER_UNIFIED 0 +#define CURLHEADER_SEPARATE (1<<0) + +/* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */ +#define CURLPROTO_HTTP (1<<0) +#define CURLPROTO_HTTPS (1<<1) +#define CURLPROTO_FTP (1<<2) +#define CURLPROTO_FTPS (1<<3) +#define CURLPROTO_SCP (1<<4) +#define CURLPROTO_SFTP (1<<5) +#define CURLPROTO_TELNET (1<<6) +#define CURLPROTO_LDAP (1<<7) +#define CURLPROTO_LDAPS (1<<8) +#define CURLPROTO_DICT (1<<9) +#define CURLPROTO_FILE (1<<10) +#define CURLPROTO_TFTP (1<<11) +#define CURLPROTO_IMAP (1<<12) +#define CURLPROTO_IMAPS (1<<13) +#define CURLPROTO_POP3 (1<<14) +#define CURLPROTO_POP3S (1<<15) +#define CURLPROTO_SMTP (1<<16) +#define CURLPROTO_SMTPS (1<<17) +#define CURLPROTO_RTSP (1<<18) +#define CURLPROTO_RTMP (1<<19) +#define CURLPROTO_RTMPT (1<<20) +#define CURLPROTO_RTMPE (1<<21) +#define CURLPROTO_RTMPTE (1<<22) +#define CURLPROTO_RTMPS (1<<23) +#define CURLPROTO_RTMPTS (1<<24) +#define CURLPROTO_GOPHER (1<<25) +#define CURLPROTO_SMB (1<<26) +#define CURLPROTO_SMBS (1<<27) +#define CURLPROTO_ALL (~0) /* enable everything */ + +/* long may be 32 or 64 bits, but we should never depend on anything else + but 32 */ +#define CURLOPTTYPE_LONG 0 +#define CURLOPTTYPE_OBJECTPOINT 10000 +#define CURLOPTTYPE_STRINGPOINT 10000 +#define CURLOPTTYPE_FUNCTIONPOINT 20000 +#define CURLOPTTYPE_OFF_T 30000 + +/* *STRINGPOINT is an alias for OBJECTPOINT to allow tools to extract the + string options from the header file */ + +/* name is uppercase CURLOPT_, + type is one of the defined CURLOPTTYPE_ + number is unique identifier */ +#ifdef CINIT +#undef CINIT +#endif + +#ifdef CURL_ISOCPP +#define CINIT(na,t,nu) CURLOPT_ ## na = CURLOPTTYPE_ ## t + nu +#else +/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ +#define LONG CURLOPTTYPE_LONG +#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT +#define STRINGPOINT CURLOPTTYPE_OBJECTPOINT +#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT +#define OFF_T CURLOPTTYPE_OFF_T +#define CINIT(name,type,number) CURLOPT_/**/name = type + number +#endif + +/* + * This macro-mania below setups the CURLOPT_[what] enum, to be used with + * curl_easy_setopt(). The first argument in the CINIT() macro is the [what] + * word. + */ + +typedef enum { + /* This is the FILE * or void * the regular output should be written to. */ + CINIT(WRITEDATA, OBJECTPOINT, 1), + + /* The full URL to get/put */ + CINIT(URL, STRINGPOINT, 2), + + /* Port number to connect to, if other than default. */ + CINIT(PORT, LONG, 3), + + /* Name of proxy to use. */ + CINIT(PROXY, STRINGPOINT, 4), + + /* "user:password;options" to use when fetching. */ + CINIT(USERPWD, STRINGPOINT, 5), + + /* "user:password" to use with proxy. */ + CINIT(PROXYUSERPWD, STRINGPOINT, 6), + + /* Range to get, specified as an ASCII string. */ + CINIT(RANGE, STRINGPOINT, 7), + + /* not used */ + + /* Specified file stream to upload from (use as input): */ + CINIT(READDATA, OBJECTPOINT, 9), + + /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE + * bytes big. If this is not used, error messages go to stderr instead: */ + CINIT(ERRORBUFFER, OBJECTPOINT, 10), + + /* Function that will be called to store the output (instead of fwrite). The + * parameters will use fwrite() syntax, make sure to follow them. */ + CINIT(WRITEFUNCTION, FUNCTIONPOINT, 11), + + /* Function that will be called to read the input (instead of fread). The + * parameters will use fread() syntax, make sure to follow them. */ + CINIT(READFUNCTION, FUNCTIONPOINT, 12), + + /* Time-out the read operation after this amount of seconds */ + CINIT(TIMEOUT, LONG, 13), + + /* If the CURLOPT_INFILE is used, this can be used to inform libcurl about + * how large the file being sent really is. That allows better error + * checking and better verifies that the upload was successful. -1 means + * unknown size. + * + * For large file support, there is also a _LARGE version of the key + * which takes an off_t type, allowing platforms with larger off_t + * sizes to handle larger files. See below for INFILESIZE_LARGE. + */ + CINIT(INFILESIZE, LONG, 14), + + /* POST static input fields. */ + CINIT(POSTFIELDS, OBJECTPOINT, 15), + + /* Set the referrer page (needed by some CGIs) */ + CINIT(REFERER, STRINGPOINT, 16), + + /* Set the FTP PORT string (interface name, named or numerical IP address) + Use i.e '-' to use default address. */ + CINIT(FTPPORT, STRINGPOINT, 17), + + /* Set the User-Agent string (examined by some CGIs) */ + CINIT(USERAGENT, STRINGPOINT, 18), + + /* If the download receives less than "low speed limit" bytes/second + * during "low speed time" seconds, the operations is aborted. + * You could i.e if you have a pretty high speed connection, abort if + * it is less than 2000 bytes/sec during 20 seconds. + */ + + /* Set the "low speed limit" */ + CINIT(LOW_SPEED_LIMIT, LONG, 19), + + /* Set the "low speed time" */ + CINIT(LOW_SPEED_TIME, LONG, 20), + + /* Set the continuation offset. + * + * Note there is also a _LARGE version of this key which uses + * off_t types, allowing for large file offsets on platforms which + * use larger-than-32-bit off_t's. Look below for RESUME_FROM_LARGE. + */ + CINIT(RESUME_FROM, LONG, 21), + + /* Set cookie in request: */ + CINIT(COOKIE, STRINGPOINT, 22), + + /* This points to a linked list of headers, struct curl_slist kind. This + list is also used for RTSP (in spite of its name) */ + CINIT(HTTPHEADER, OBJECTPOINT, 23), + + /* This points to a linked list of post entries, struct curl_httppost */ + CINIT(HTTPPOST, OBJECTPOINT, 24), + + /* name of the file keeping your private SSL-certificate */ + CINIT(SSLCERT, STRINGPOINT, 25), + + /* password for the SSL or SSH private key */ + CINIT(KEYPASSWD, STRINGPOINT, 26), + + /* send TYPE parameter? */ + CINIT(CRLF, LONG, 27), + + /* send linked-list of QUOTE commands */ + CINIT(QUOTE, OBJECTPOINT, 28), + + /* send FILE * or void * to store headers to, if you use a callback it + is simply passed to the callback unmodified */ + CINIT(HEADERDATA, OBJECTPOINT, 29), + + /* point to a file to read the initial cookies from, also enables + "cookie awareness" */ + CINIT(COOKIEFILE, STRINGPOINT, 31), + + /* What version to specifically try to use. + See CURL_SSLVERSION defines below. */ + CINIT(SSLVERSION, LONG, 32), + + /* What kind of HTTP time condition to use, see defines */ + CINIT(TIMECONDITION, LONG, 33), + + /* Time to use with the above condition. Specified in number of seconds + since 1 Jan 1970 */ + CINIT(TIMEVALUE, LONG, 34), + + /* 35 = OBSOLETE */ + + /* Custom request, for customizing the get command like + HTTP: DELETE, TRACE and others + FTP: to use a different list command + */ + CINIT(CUSTOMREQUEST, STRINGPOINT, 36), + + /* FILE handle to use instead of stderr */ + CINIT(STDERR, OBJECTPOINT, 37), + + /* 38 is not used */ + + /* send linked-list of post-transfer QUOTE commands */ + CINIT(POSTQUOTE, OBJECTPOINT, 39), + + CINIT(OBSOLETE40, OBJECTPOINT, 40), /* OBSOLETE, do not use! */ + + CINIT(VERBOSE, LONG, 41), /* talk a lot */ + CINIT(HEADER, LONG, 42), /* throw the header out too */ + CINIT(NOPROGRESS, LONG, 43), /* shut off the progress meter */ + CINIT(NOBODY, LONG, 44), /* use HEAD to get http document */ + CINIT(FAILONERROR, LONG, 45), /* no output on http error codes >= 400 */ + CINIT(UPLOAD, LONG, 46), /* this is an upload */ + CINIT(POST, LONG, 47), /* HTTP POST method */ + CINIT(DIRLISTONLY, LONG, 48), /* bare names when listing directories */ + + CINIT(APPEND, LONG, 50), /* Append instead of overwrite on upload! */ + + /* Specify whether to read the user+password from the .netrc or the URL. + * This must be one of the CURL_NETRC_* enums below. */ + CINIT(NETRC, LONG, 51), + + CINIT(FOLLOWLOCATION, LONG, 52), /* use Location: Luke! */ + + CINIT(TRANSFERTEXT, LONG, 53), /* transfer data in text/ASCII format */ + CINIT(PUT, LONG, 54), /* HTTP PUT */ + + /* 55 = OBSOLETE */ + + /* DEPRECATED + * Function that will be called instead of the internal progress display + * function. This function should be defined as the curl_progress_callback + * prototype defines. */ + CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56), + + /* Data passed to the CURLOPT_PROGRESSFUNCTION and CURLOPT_XFERINFOFUNCTION + callbacks */ + CINIT(PROGRESSDATA, OBJECTPOINT, 57), +#define CURLOPT_XFERINFODATA CURLOPT_PROGRESSDATA + + /* We want the referrer field set automatically when following locations */ + CINIT(AUTOREFERER, LONG, 58), + + /* Port of the proxy, can be set in the proxy string as well with: + "[host]:[port]" */ + CINIT(PROXYPORT, LONG, 59), + + /* size of the POST input data, if strlen() is not good to use */ + CINIT(POSTFIELDSIZE, LONG, 60), + + /* tunnel non-http operations through a HTTP proxy */ + CINIT(HTTPPROXYTUNNEL, LONG, 61), + + /* Set the interface string to use as outgoing network interface */ + CINIT(INTERFACE, STRINGPOINT, 62), + + /* Set the krb4/5 security level, this also enables krb4/5 awareness. This + * is a string, 'clear', 'safe', 'confidential' or 'private'. If the string + * is set but doesn't match one of these, 'private' will be used. */ + CINIT(KRBLEVEL, STRINGPOINT, 63), + + /* Set if we should verify the peer in ssl handshake, set 1 to verify. */ + CINIT(SSL_VERIFYPEER, LONG, 64), + + /* The CApath or CAfile used to validate the peer certificate + this option is used only if SSL_VERIFYPEER is true */ + CINIT(CAINFO, STRINGPOINT, 65), + + /* 66 = OBSOLETE */ + /* 67 = OBSOLETE */ + + /* Maximum number of http redirects to follow */ + CINIT(MAXREDIRS, LONG, 68), + + /* Pass a long set to 1 to get the date of the requested document (if + possible)! Pass a zero to shut it off. */ + CINIT(FILETIME, LONG, 69), + + /* This points to a linked list of telnet options */ + CINIT(TELNETOPTIONS, OBJECTPOINT, 70), + + /* Max amount of cached alive connections */ + CINIT(MAXCONNECTS, LONG, 71), + + CINIT(OBSOLETE72, LONG, 72), /* OBSOLETE, do not use! */ + + /* 73 = OBSOLETE */ + + /* Set to explicitly use a new connection for the upcoming transfer. + Do not use this unless you're absolutely sure of this, as it makes the + operation slower and is less friendly for the network. */ + CINIT(FRESH_CONNECT, LONG, 74), + + /* Set to explicitly forbid the upcoming transfer's connection to be re-used + when done. Do not use this unless you're absolutely sure of this, as it + makes the operation slower and is less friendly for the network. */ + CINIT(FORBID_REUSE, LONG, 75), + + /* Set to a file name that contains random data for libcurl to use to + seed the random engine when doing SSL connects. */ + CINIT(RANDOM_FILE, STRINGPOINT, 76), + + /* Set to the Entropy Gathering Daemon socket pathname */ + CINIT(EGDSOCKET, STRINGPOINT, 77), + + /* Time-out connect operations after this amount of seconds, if connects are + OK within this time, then fine... This only aborts the connect phase. */ + CINIT(CONNECTTIMEOUT, LONG, 78), + + /* Function that will be called to store headers (instead of fwrite). The + * parameters will use fwrite() syntax, make sure to follow them. */ + CINIT(HEADERFUNCTION, FUNCTIONPOINT, 79), + + /* Set this to force the HTTP request to get back to GET. Only really usable + if POST, PUT or a custom request have been used first. + */ + CINIT(HTTPGET, LONG, 80), + + /* Set if we should verify the Common name from the peer certificate in ssl + * handshake, set 1 to check existence, 2 to ensure that it matches the + * provided hostname. */ + CINIT(SSL_VERIFYHOST, LONG, 81), + + /* Specify which file name to write all known cookies in after completed + operation. Set file name to "-" (dash) to make it go to stdout. */ + CINIT(COOKIEJAR, STRINGPOINT, 82), + + /* Specify which SSL ciphers to use */ + CINIT(SSL_CIPHER_LIST, STRINGPOINT, 83), + + /* Specify which HTTP version to use! This must be set to one of the + CURL_HTTP_VERSION* enums set below. */ + CINIT(HTTP_VERSION, LONG, 84), + + /* Specifically switch on or off the FTP engine's use of the EPSV command. By + default, that one will always be attempted before the more traditional + PASV command. */ + CINIT(FTP_USE_EPSV, LONG, 85), + + /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */ + CINIT(SSLCERTTYPE, STRINGPOINT, 86), + + /* name of the file keeping your private SSL-key */ + CINIT(SSLKEY, STRINGPOINT, 87), + + /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") */ + CINIT(SSLKEYTYPE, STRINGPOINT, 88), + + /* crypto engine for the SSL-sub system */ + CINIT(SSLENGINE, STRINGPOINT, 89), + + /* set the crypto engine for the SSL-sub system as default + the param has no meaning... + */ + CINIT(SSLENGINE_DEFAULT, LONG, 90), + + /* Non-zero value means to use the global dns cache */ + CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91), /* DEPRECATED, do not use! */ + + /* DNS cache timeout */ + CINIT(DNS_CACHE_TIMEOUT, LONG, 92), + + /* send linked-list of pre-transfer QUOTE commands */ + CINIT(PREQUOTE, OBJECTPOINT, 93), + + /* set the debug function */ + CINIT(DEBUGFUNCTION, FUNCTIONPOINT, 94), + + /* set the data for the debug function */ + CINIT(DEBUGDATA, OBJECTPOINT, 95), + + /* mark this as start of a cookie session */ + CINIT(COOKIESESSION, LONG, 96), + + /* The CApath directory used to validate the peer certificate + this option is used only if SSL_VERIFYPEER is true */ + CINIT(CAPATH, STRINGPOINT, 97), + + /* Instruct libcurl to use a smaller receive buffer */ + CINIT(BUFFERSIZE, LONG, 98), + + /* Instruct libcurl to not use any signal/alarm handlers, even when using + timeouts. This option is useful for multi-threaded applications. + See libcurl-the-guide for more background information. */ + CINIT(NOSIGNAL, LONG, 99), + + /* Provide a CURLShare for mutexing non-ts data */ + CINIT(SHARE, OBJECTPOINT, 100), + + /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default), + CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and CURLPROXY_SOCKS5. */ + CINIT(PROXYTYPE, LONG, 101), + + /* Set the Accept-Encoding string. Use this to tell a server you would like + the response to be compressed. Before 7.21.6, this was known as + CURLOPT_ENCODING */ + CINIT(ACCEPT_ENCODING, STRINGPOINT, 102), + + /* Set pointer to private data */ + CINIT(PRIVATE, OBJECTPOINT, 103), + + /* Set aliases for HTTP 200 in the HTTP Response header */ + CINIT(HTTP200ALIASES, OBJECTPOINT, 104), + + /* Continue to send authentication (user+password) when following locations, + even when hostname changed. This can potentially send off the name + and password to whatever host the server decides. */ + CINIT(UNRESTRICTED_AUTH, LONG, 105), + + /* Specifically switch on or off the FTP engine's use of the EPRT command ( + it also disables the LPRT attempt). By default, those ones will always be + attempted before the good old traditional PORT command. */ + CINIT(FTP_USE_EPRT, LONG, 106), + + /* Set this to a bitmask value to enable the particular authentications + methods you like. Use this in combination with CURLOPT_USERPWD. + Note that setting multiple bits may cause extra network round-trips. */ + CINIT(HTTPAUTH, LONG, 107), + + /* Set the ssl context callback function, currently only for OpenSSL ssl_ctx + in second argument. The function must be matching the + curl_ssl_ctx_callback proto. */ + CINIT(SSL_CTX_FUNCTION, FUNCTIONPOINT, 108), + + /* Set the userdata for the ssl context callback function's third + argument */ + CINIT(SSL_CTX_DATA, OBJECTPOINT, 109), + + /* FTP Option that causes missing dirs to be created on the remote server. + In 7.19.4 we introduced the convenience enums for this option using the + CURLFTP_CREATE_DIR prefix. + */ + CINIT(FTP_CREATE_MISSING_DIRS, LONG, 110), + + /* Set this to a bitmask value to enable the particular authentications + methods you like. Use this in combination with CURLOPT_PROXYUSERPWD. + Note that setting multiple bits may cause extra network round-trips. */ + CINIT(PROXYAUTH, LONG, 111), + + /* FTP option that changes the timeout, in seconds, associated with + getting a response. This is different from transfer timeout time and + essentially places a demand on the FTP server to acknowledge commands + in a timely manner. */ + CINIT(FTP_RESPONSE_TIMEOUT, LONG, 112), +#define CURLOPT_SERVER_RESPONSE_TIMEOUT CURLOPT_FTP_RESPONSE_TIMEOUT + + /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to + tell libcurl to resolve names to those IP versions only. This only has + affect on systems with support for more than one, i.e IPv4 _and_ IPv6. */ + CINIT(IPRESOLVE, LONG, 113), + + /* Set this option to limit the size of a file that will be downloaded from + an HTTP or FTP server. + + Note there is also _LARGE version which adds large file support for + platforms which have larger off_t sizes. See MAXFILESIZE_LARGE below. */ + CINIT(MAXFILESIZE, LONG, 114), + + /* See the comment for INFILESIZE above, but in short, specifies + * the size of the file being uploaded. -1 means unknown. + */ + CINIT(INFILESIZE_LARGE, OFF_T, 115), + + /* Sets the continuation offset. There is also a LONG version of this; + * look above for RESUME_FROM. + */ + CINIT(RESUME_FROM_LARGE, OFF_T, 116), + + /* Sets the maximum size of data that will be downloaded from + * an HTTP or FTP server. See MAXFILESIZE above for the LONG version. + */ + CINIT(MAXFILESIZE_LARGE, OFF_T, 117), + + /* Set this option to the file name of your .netrc file you want libcurl + to parse (using the CURLOPT_NETRC option). If not set, libcurl will do + a poor attempt to find the user's home directory and check for a .netrc + file in there. */ + CINIT(NETRC_FILE, STRINGPOINT, 118), + + /* Enable SSL/TLS for FTP, pick one of: + CURLUSESSL_TRY - try using SSL, proceed anyway otherwise + CURLUSESSL_CONTROL - SSL for the control connection or fail + CURLUSESSL_ALL - SSL for all communication or fail + */ + CINIT(USE_SSL, LONG, 119), + + /* The _LARGE version of the standard POSTFIELDSIZE option */ + CINIT(POSTFIELDSIZE_LARGE, OFF_T, 120), + + /* Enable/disable the TCP Nagle algorithm */ + CINIT(TCP_NODELAY, LONG, 121), + + /* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 123 OBSOLETE. Gone in 7.16.0 */ + /* 124 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 125 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 126 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 127 OBSOLETE. Gone in 7.16.0 */ + /* 128 OBSOLETE. Gone in 7.16.0 */ + + /* When FTP over SSL/TLS is selected (with CURLOPT_USE_SSL), this option + can be used to change libcurl's default action which is to first try + "AUTH SSL" and then "AUTH TLS" in this order, and proceed when a OK + response has been received. + + Available parameters are: + CURLFTPAUTH_DEFAULT - let libcurl decide + CURLFTPAUTH_SSL - try "AUTH SSL" first, then TLS + CURLFTPAUTH_TLS - try "AUTH TLS" first, then SSL + */ + CINIT(FTPSSLAUTH, LONG, 129), + + CINIT(IOCTLFUNCTION, FUNCTIONPOINT, 130), + CINIT(IOCTLDATA, OBJECTPOINT, 131), + + /* 132 OBSOLETE. Gone in 7.16.0 */ + /* 133 OBSOLETE. Gone in 7.16.0 */ + + /* zero terminated string for pass on to the FTP server when asked for + "account" info */ + CINIT(FTP_ACCOUNT, STRINGPOINT, 134), + + /* feed cookie into cookie engine */ + CINIT(COOKIELIST, STRINGPOINT, 135), + + /* ignore Content-Length */ + CINIT(IGNORE_CONTENT_LENGTH, LONG, 136), + + /* Set to non-zero to skip the IP address received in a 227 PASV FTP server + response. Typically used for FTP-SSL purposes but is not restricted to + that. libcurl will then instead use the same IP address it used for the + control connection. */ + CINIT(FTP_SKIP_PASV_IP, LONG, 137), + + /* Select "file method" to use when doing FTP, see the curl_ftpmethod + above. */ + CINIT(FTP_FILEMETHOD, LONG, 138), + + /* Local port number to bind the socket to */ + CINIT(LOCALPORT, LONG, 139), + + /* Number of ports to try, including the first one set with LOCALPORT. + Thus, setting it to 1 will make no additional attempts but the first. + */ + CINIT(LOCALPORTRANGE, LONG, 140), + + /* no transfer, set up connection and let application use the socket by + extracting it with CURLINFO_LASTSOCKET */ + CINIT(CONNECT_ONLY, LONG, 141), + + /* Function that will be called to convert from the + network encoding (instead of using the iconv calls in libcurl) */ + CINIT(CONV_FROM_NETWORK_FUNCTION, FUNCTIONPOINT, 142), + + /* Function that will be called to convert to the + network encoding (instead of using the iconv calls in libcurl) */ + CINIT(CONV_TO_NETWORK_FUNCTION, FUNCTIONPOINT, 143), + + /* Function that will be called to convert from UTF8 + (instead of using the iconv calls in libcurl) + Note that this is used only for SSL certificate processing */ + CINIT(CONV_FROM_UTF8_FUNCTION, FUNCTIONPOINT, 144), + + /* if the connection proceeds too quickly then need to slow it down */ + /* limit-rate: maximum number of bytes per second to send or receive */ + CINIT(MAX_SEND_SPEED_LARGE, OFF_T, 145), + CINIT(MAX_RECV_SPEED_LARGE, OFF_T, 146), + + /* Pointer to command string to send if USER/PASS fails. */ + CINIT(FTP_ALTERNATIVE_TO_USER, STRINGPOINT, 147), + + /* callback function for setting socket options */ + CINIT(SOCKOPTFUNCTION, FUNCTIONPOINT, 148), + CINIT(SOCKOPTDATA, OBJECTPOINT, 149), + + /* set to 0 to disable session ID re-use for this transfer, default is + enabled (== 1) */ + CINIT(SSL_SESSIONID_CACHE, LONG, 150), + + /* allowed SSH authentication methods */ + CINIT(SSH_AUTH_TYPES, LONG, 151), + + /* Used by scp/sftp to do public/private key authentication */ + CINIT(SSH_PUBLIC_KEYFILE, STRINGPOINT, 152), + CINIT(SSH_PRIVATE_KEYFILE, STRINGPOINT, 153), + + /* Send CCC (Clear Command Channel) after authentication */ + CINIT(FTP_SSL_CCC, LONG, 154), + + /* Same as TIMEOUT and CONNECTTIMEOUT, but with ms resolution */ + CINIT(TIMEOUT_MS, LONG, 155), + CINIT(CONNECTTIMEOUT_MS, LONG, 156), + + /* set to zero to disable the libcurl's decoding and thus pass the raw body + data to the application even when it is encoded/compressed */ + CINIT(HTTP_TRANSFER_DECODING, LONG, 157), + CINIT(HTTP_CONTENT_DECODING, LONG, 158), + + /* Permission used when creating new files and directories on the remote + server for protocols that support it, SFTP/SCP/FILE */ + CINIT(NEW_FILE_PERMS, LONG, 159), + CINIT(NEW_DIRECTORY_PERMS, LONG, 160), + + /* Set the behaviour of POST when redirecting. Values must be set to one + of CURL_REDIR* defines below. This used to be called CURLOPT_POST301 */ + CINIT(POSTREDIR, LONG, 161), + + /* used by scp/sftp to verify the host's public key */ + CINIT(SSH_HOST_PUBLIC_KEY_MD5, STRINGPOINT, 162), + + /* Callback function for opening socket (instead of socket(2)). Optionally, + callback is able change the address or refuse to connect returning + CURL_SOCKET_BAD. The callback should have type + curl_opensocket_callback */ + CINIT(OPENSOCKETFUNCTION, FUNCTIONPOINT, 163), + CINIT(OPENSOCKETDATA, OBJECTPOINT, 164), + + /* POST volatile input fields. */ + CINIT(COPYPOSTFIELDS, OBJECTPOINT, 165), + + /* set transfer mode (;type=) when doing FTP via an HTTP proxy */ + CINIT(PROXY_TRANSFER_MODE, LONG, 166), + + /* Callback function for seeking in the input stream */ + CINIT(SEEKFUNCTION, FUNCTIONPOINT, 167), + CINIT(SEEKDATA, OBJECTPOINT, 168), + + /* CRL file */ + CINIT(CRLFILE, STRINGPOINT, 169), + + /* Issuer certificate */ + CINIT(ISSUERCERT, STRINGPOINT, 170), + + /* (IPv6) Address scope */ + CINIT(ADDRESS_SCOPE, LONG, 171), + + /* Collect certificate chain info and allow it to get retrievable with + CURLINFO_CERTINFO after the transfer is complete. */ + CINIT(CERTINFO, LONG, 172), + + /* "name" and "pwd" to use when fetching. */ + CINIT(USERNAME, STRINGPOINT, 173), + CINIT(PASSWORD, STRINGPOINT, 174), + + /* "name" and "pwd" to use with Proxy when fetching. */ + CINIT(PROXYUSERNAME, STRINGPOINT, 175), + CINIT(PROXYPASSWORD, STRINGPOINT, 176), + + /* Comma separated list of hostnames defining no-proxy zones. These should + match both hostnames directly, and hostnames within a domain. For + example, local.com will match local.com and www.local.com, but NOT + notlocal.com or www.notlocal.com. For compatibility with other + implementations of this, .local.com will be considered to be the same as + local.com. A single * is the only valid wildcard, and effectively + disables the use of proxy. */ + CINIT(NOPROXY, STRINGPOINT, 177), + + /* block size for TFTP transfers */ + CINIT(TFTP_BLKSIZE, LONG, 178), + + /* Socks Service */ + CINIT(SOCKS5_GSSAPI_SERVICE, STRINGPOINT, 179), /* DEPRECATED, do not use! */ + + /* Socks Service */ + CINIT(SOCKS5_GSSAPI_NEC, LONG, 180), + + /* set the bitmask for the protocols that are allowed to be used for the + transfer, which thus helps the app which takes URLs from users or other + external inputs and want to restrict what protocol(s) to deal + with. Defaults to CURLPROTO_ALL. */ + CINIT(PROTOCOLS, LONG, 181), + + /* set the bitmask for the protocols that libcurl is allowed to follow to, + as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs + to be set in both bitmasks to be allowed to get redirected to. Defaults + to all protocols except FILE and SCP. */ + CINIT(REDIR_PROTOCOLS, LONG, 182), + + /* set the SSH knownhost file name to use */ + CINIT(SSH_KNOWNHOSTS, STRINGPOINT, 183), + + /* set the SSH host key callback, must point to a curl_sshkeycallback + function */ + CINIT(SSH_KEYFUNCTION, FUNCTIONPOINT, 184), + + /* set the SSH host key callback custom pointer */ + CINIT(SSH_KEYDATA, OBJECTPOINT, 185), + + /* set the SMTP mail originator */ + CINIT(MAIL_FROM, STRINGPOINT, 186), + + /* set the list of SMTP mail receiver(s) */ + CINIT(MAIL_RCPT, OBJECTPOINT, 187), + + /* FTP: send PRET before PASV */ + CINIT(FTP_USE_PRET, LONG, 188), + + /* RTSP request method (OPTIONS, SETUP, PLAY, etc...) */ + CINIT(RTSP_REQUEST, LONG, 189), + + /* The RTSP session identifier */ + CINIT(RTSP_SESSION_ID, STRINGPOINT, 190), + + /* The RTSP stream URI */ + CINIT(RTSP_STREAM_URI, STRINGPOINT, 191), + + /* The Transport: header to use in RTSP requests */ + CINIT(RTSP_TRANSPORT, STRINGPOINT, 192), + + /* Manually initialize the client RTSP CSeq for this handle */ + CINIT(RTSP_CLIENT_CSEQ, LONG, 193), + + /* Manually initialize the server RTSP CSeq for this handle */ + CINIT(RTSP_SERVER_CSEQ, LONG, 194), + + /* The stream to pass to INTERLEAVEFUNCTION. */ + CINIT(INTERLEAVEDATA, OBJECTPOINT, 195), + + /* Let the application define a custom write method for RTP data */ + CINIT(INTERLEAVEFUNCTION, FUNCTIONPOINT, 196), + + /* Turn on wildcard matching */ + CINIT(WILDCARDMATCH, LONG, 197), + + /* Directory matching callback called before downloading of an + individual file (chunk) started */ + CINIT(CHUNK_BGN_FUNCTION, FUNCTIONPOINT, 198), + + /* Directory matching callback called after the file (chunk) + was downloaded, or skipped */ + CINIT(CHUNK_END_FUNCTION, FUNCTIONPOINT, 199), + + /* Change match (fnmatch-like) callback for wildcard matching */ + CINIT(FNMATCH_FUNCTION, FUNCTIONPOINT, 200), + + /* Let the application define custom chunk data pointer */ + CINIT(CHUNK_DATA, OBJECTPOINT, 201), + + /* FNMATCH_FUNCTION user pointer */ + CINIT(FNMATCH_DATA, OBJECTPOINT, 202), + + /* send linked-list of name:port:address sets */ + CINIT(RESOLVE, OBJECTPOINT, 203), + + /* Set a username for authenticated TLS */ + CINIT(TLSAUTH_USERNAME, STRINGPOINT, 204), + + /* Set a password for authenticated TLS */ + CINIT(TLSAUTH_PASSWORD, STRINGPOINT, 205), + + /* Set authentication type for authenticated TLS */ + CINIT(TLSAUTH_TYPE, STRINGPOINT, 206), + + /* Set to 1 to enable the "TE:" header in HTTP requests to ask for + compressed transfer-encoded responses. Set to 0 to disable the use of TE: + in outgoing requests. The current default is 0, but it might change in a + future libcurl release. + + libcurl will ask for the compressed methods it knows of, and if that + isn't any, it will not ask for transfer-encoding at all even if this + option is set to 1. + + */ + CINIT(TRANSFER_ENCODING, LONG, 207), + + /* Callback function for closing socket (instead of close(2)). The callback + should have type curl_closesocket_callback */ + CINIT(CLOSESOCKETFUNCTION, FUNCTIONPOINT, 208), + CINIT(CLOSESOCKETDATA, OBJECTPOINT, 209), + + /* allow GSSAPI credential delegation */ + CINIT(GSSAPI_DELEGATION, LONG, 210), + + /* Set the name servers to use for DNS resolution */ + CINIT(DNS_SERVERS, STRINGPOINT, 211), + + /* Time-out accept operations (currently for FTP only) after this amount + of miliseconds. */ + CINIT(ACCEPTTIMEOUT_MS, LONG, 212), + + /* Set TCP keepalive */ + CINIT(TCP_KEEPALIVE, LONG, 213), + + /* non-universal keepalive knobs (Linux, AIX, HP-UX, more) */ + CINIT(TCP_KEEPIDLE, LONG, 214), + CINIT(TCP_KEEPINTVL, LONG, 215), + + /* Enable/disable specific SSL features with a bitmask, see CURLSSLOPT_* */ + CINIT(SSL_OPTIONS, LONG, 216), + + /* Set the SMTP auth originator */ + CINIT(MAIL_AUTH, STRINGPOINT, 217), + + /* Enable/disable SASL initial response */ + CINIT(SASL_IR, LONG, 218), + + /* Function that will be called instead of the internal progress display + * function. This function should be defined as the curl_xferinfo_callback + * prototype defines. (Deprecates CURLOPT_PROGRESSFUNCTION) */ + CINIT(XFERINFOFUNCTION, FUNCTIONPOINT, 219), + + /* The XOAUTH2 bearer token */ + CINIT(XOAUTH2_BEARER, STRINGPOINT, 220), + + /* Set the interface string to use as outgoing network + * interface for DNS requests. + * Only supported by the c-ares DNS backend */ + CINIT(DNS_INTERFACE, STRINGPOINT, 221), + + /* Set the local IPv4 address to use for outgoing DNS requests. + * Only supported by the c-ares DNS backend */ + CINIT(DNS_LOCAL_IP4, STRINGPOINT, 222), + + /* Set the local IPv4 address to use for outgoing DNS requests. + * Only supported by the c-ares DNS backend */ + CINIT(DNS_LOCAL_IP6, STRINGPOINT, 223), + + /* Set authentication options directly */ + CINIT(LOGIN_OPTIONS, STRINGPOINT, 224), + + /* Enable/disable TLS NPN extension (http2 over ssl might fail without) */ + CINIT(SSL_ENABLE_NPN, LONG, 225), + + /* Enable/disable TLS ALPN extension (http2 over ssl might fail without) */ + CINIT(SSL_ENABLE_ALPN, LONG, 226), + + /* Time to wait for a response to a HTTP request containing an + * Expect: 100-continue header before sending the data anyway. */ + CINIT(EXPECT_100_TIMEOUT_MS, LONG, 227), + + /* This points to a linked list of headers used for proxy requests only, + struct curl_slist kind */ + CINIT(PROXYHEADER, OBJECTPOINT, 228), + + /* Pass in a bitmask of "header options" */ + CINIT(HEADEROPT, LONG, 229), + + /* The public key in DER form used to validate the peer public key + this option is used only if SSL_VERIFYPEER is true */ + CINIT(PINNEDPUBLICKEY, STRINGPOINT, 230), + + /* Path to Unix domain socket */ + CINIT(UNIX_SOCKET_PATH, STRINGPOINT, 231), + + /* Set if we should verify the certificate status. */ + CINIT(SSL_VERIFYSTATUS, LONG, 232), + + /* Set if we should enable TLS false start. */ + CINIT(SSL_FALSESTART, LONG, 233), + + /* Do not squash dot-dot sequences */ + CINIT(PATH_AS_IS, LONG, 234), + + /* Proxy Service Name */ + CINIT(PROXY_SERVICE_NAME, STRINGPOINT, 235), + + /* Service Name */ + CINIT(SERVICE_NAME, STRINGPOINT, 236), + + /* Wait/don't wait for pipe/mutex to clarify */ + CINIT(PIPEWAIT, LONG, 237), + + /* Set the protocol used when curl is given a URL without a protocol */ + CINIT(DEFAULT_PROTOCOL, STRINGPOINT, 238), + + /* Set stream weight, 1 - 256 (default is 16) */ + CINIT(STREAM_WEIGHT, LONG, 239), + + /* Set stream dependency on another CURL handle */ + CINIT(STREAM_DEPENDS, OBJECTPOINT, 240), + + /* Set E-xclusive stream dependency on another CURL handle */ + CINIT(STREAM_DEPENDS_E, OBJECTPOINT, 241), + + /* Do not send any tftp option requests to the server */ + CINIT(TFTP_NO_OPTIONS, LONG, 242), + + /* Linked-list of host:port:connect-to-host:connect-to-port, + overrides the URL's host:port (only for the network layer) */ + CINIT(CONNECT_TO, OBJECTPOINT, 243), + + /* Set TCP Fast Open */ + CINIT(TCP_FASTOPEN, LONG, 244), + + CURLOPT_LASTENTRY /* the last unused */ +} CURLoption; + +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all + the obsolete stuff removed! */ + +/* Backwards compatibility with older names */ +/* These are scheduled to disappear by 2011 */ + +/* This was added in version 7.19.1 */ +#define CURLOPT_POST301 CURLOPT_POSTREDIR + +/* These are scheduled to disappear by 2009 */ + +/* The following were added in 7.17.0 */ +#define CURLOPT_SSLKEYPASSWD CURLOPT_KEYPASSWD +#define CURLOPT_FTPAPPEND CURLOPT_APPEND +#define CURLOPT_FTPLISTONLY CURLOPT_DIRLISTONLY +#define CURLOPT_FTP_SSL CURLOPT_USE_SSL + +/* The following were added earlier */ + +#define CURLOPT_SSLCERTPASSWD CURLOPT_KEYPASSWD +#define CURLOPT_KRB4LEVEL CURLOPT_KRBLEVEL + +#else +/* This is set if CURL_NO_OLDIES is defined at compile-time */ +#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */ +#endif + + + /* Below here follows defines for the CURLOPT_IPRESOLVE option. If a host + name resolves addresses using more than one IP protocol version, this + option might be handy to force libcurl to use a specific IP version. */ +#define CURL_IPRESOLVE_WHATEVER 0 /* default, resolves addresses to all IP + versions that your system allows */ +#define CURL_IPRESOLVE_V4 1 /* resolve to IPv4 addresses */ +#define CURL_IPRESOLVE_V6 2 /* resolve to IPv6 addresses */ + + /* three convenient "aliases" that follow the name scheme better */ +#define CURLOPT_RTSPHEADER CURLOPT_HTTPHEADER + + /* These enums are for use with the CURLOPT_HTTP_VERSION option. */ +enum { + CURL_HTTP_VERSION_NONE, /* setting this means we don't care, and that we'd + like the library to choose the best possible + for us! */ + CURL_HTTP_VERSION_1_0, /* please use HTTP 1.0 in the request */ + CURL_HTTP_VERSION_1_1, /* please use HTTP 1.1 in the request */ + CURL_HTTP_VERSION_2_0, /* please use HTTP 2 in the request */ + CURL_HTTP_VERSION_2TLS, /* use version 2 for HTTPS, version 1.1 for HTTP */ + CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE, /* please use HTTP 2 without HTTP/1.1 + Upgrade */ + + CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */ +}; + +/* Convenience definition simple because the name of the version is HTTP/2 and + not 2.0. The 2_0 version of the enum name was set while the version was + still planned to be 2.0 and we stick to it for compatibility. */ +#define CURL_HTTP_VERSION_2 CURL_HTTP_VERSION_2_0 + +/* + * Public API enums for RTSP requests + */ +enum { + CURL_RTSPREQ_NONE, /* first in list */ + CURL_RTSPREQ_OPTIONS, + CURL_RTSPREQ_DESCRIBE, + CURL_RTSPREQ_ANNOUNCE, + CURL_RTSPREQ_SETUP, + CURL_RTSPREQ_PLAY, + CURL_RTSPREQ_PAUSE, + CURL_RTSPREQ_TEARDOWN, + CURL_RTSPREQ_GET_PARAMETER, + CURL_RTSPREQ_SET_PARAMETER, + CURL_RTSPREQ_RECORD, + CURL_RTSPREQ_RECEIVE, + CURL_RTSPREQ_LAST /* last in list */ +}; + + /* These enums are for use with the CURLOPT_NETRC option. */ +enum CURL_NETRC_OPTION { + CURL_NETRC_IGNORED, /* The .netrc will never be read. + * This is the default. */ + CURL_NETRC_OPTIONAL, /* A user:password in the URL will be preferred + * to one in the .netrc. */ + CURL_NETRC_REQUIRED, /* A user:password in the URL will be ignored. + * Unless one is set programmatically, the .netrc + * will be queried. */ + CURL_NETRC_LAST +}; + +enum { + CURL_SSLVERSION_DEFAULT, + CURL_SSLVERSION_TLSv1, /* TLS 1.x */ + CURL_SSLVERSION_SSLv2, + CURL_SSLVERSION_SSLv3, + CURL_SSLVERSION_TLSv1_0, + CURL_SSLVERSION_TLSv1_1, + CURL_SSLVERSION_TLSv1_2, + + CURL_SSLVERSION_LAST /* never use, keep last */ +}; + +enum CURL_TLSAUTH { + CURL_TLSAUTH_NONE, + CURL_TLSAUTH_SRP, + CURL_TLSAUTH_LAST /* never use, keep last */ +}; + +/* symbols to use with CURLOPT_POSTREDIR. + CURL_REDIR_POST_301, CURL_REDIR_POST_302 and CURL_REDIR_POST_303 + can be bitwise ORed so that CURL_REDIR_POST_301 | CURL_REDIR_POST_302 + | CURL_REDIR_POST_303 == CURL_REDIR_POST_ALL */ + +#define CURL_REDIR_GET_ALL 0 +#define CURL_REDIR_POST_301 1 +#define CURL_REDIR_POST_302 2 +#define CURL_REDIR_POST_303 4 +#define CURL_REDIR_POST_ALL \ + (CURL_REDIR_POST_301|CURL_REDIR_POST_302|CURL_REDIR_POST_303) + +typedef enum { + CURL_TIMECOND_NONE, + + CURL_TIMECOND_IFMODSINCE, + CURL_TIMECOND_IFUNMODSINCE, + CURL_TIMECOND_LASTMOD, + + CURL_TIMECOND_LAST +} curl_TimeCond; + + +/* curl_strequal() and curl_strnequal() are subject for removal in a future + libcurl, see lib/README.curlx for details */ +CURL_EXTERN int (curl_strequal)(const char *s1, const char *s2); +CURL_EXTERN int (curl_strnequal)(const char *s1, const char *s2, size_t n); + +/* name is uppercase CURLFORM_ */ +#ifdef CFINIT +#undef CFINIT +#endif + +#ifdef CURL_ISOCPP +#define CFINIT(name) CURLFORM_ ## name +#else +/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ +#define CFINIT(name) CURLFORM_/**/name +#endif + +typedef enum { + CFINIT(NOTHING), /********* the first one is unused ************/ + + /* */ + CFINIT(COPYNAME), + CFINIT(PTRNAME), + CFINIT(NAMELENGTH), + CFINIT(COPYCONTENTS), + CFINIT(PTRCONTENTS), + CFINIT(CONTENTSLENGTH), + CFINIT(FILECONTENT), + CFINIT(ARRAY), + CFINIT(OBSOLETE), + CFINIT(FILE), + + CFINIT(BUFFER), + CFINIT(BUFFERPTR), + CFINIT(BUFFERLENGTH), + + CFINIT(CONTENTTYPE), + CFINIT(CONTENTHEADER), + CFINIT(FILENAME), + CFINIT(END), + CFINIT(OBSOLETE2), + + CFINIT(STREAM), + CFINIT(CONTENTLEN), /* added in 7.46.0, provide a curl_off_t length */ + + CURLFORM_LASTENTRY /* the last unused */ +} CURLformoption; + +#undef CFINIT /* done */ + +/* structure to be used as parameter for CURLFORM_ARRAY */ +struct curl_forms { + CURLformoption option; + const char *value; +}; + +/* use this for multipart formpost building */ +/* Returns code for curl_formadd() + * + * Returns: + * CURL_FORMADD_OK on success + * CURL_FORMADD_MEMORY if the FormInfo allocation fails + * CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form + * CURL_FORMADD_NULL if a null pointer was given for a char + * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed + * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used + * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or error) + * CURL_FORMADD_MEMORY if a curl_httppost struct cannot be allocated + * CURL_FORMADD_MEMORY if some allocation for string copying failed. + * CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array + * + ***************************************************************************/ +typedef enum { + CURL_FORMADD_OK, /* first, no error */ + + CURL_FORMADD_MEMORY, + CURL_FORMADD_OPTION_TWICE, + CURL_FORMADD_NULL, + CURL_FORMADD_UNKNOWN_OPTION, + CURL_FORMADD_INCOMPLETE, + CURL_FORMADD_ILLEGAL_ARRAY, + CURL_FORMADD_DISABLED, /* libcurl was built with this disabled */ + + CURL_FORMADD_LAST /* last */ +} CURLFORMcode; + +/* + * NAME curl_formadd() + * + * DESCRIPTION + * + * Pretty advanced function for building multi-part formposts. Each invoke + * adds one part that together construct a full post. Then use + * CURLOPT_HTTPPOST to send it off to libcurl. + */ +CURL_EXTERN CURLFORMcode curl_formadd(struct curl_httppost **httppost, + struct curl_httppost **last_post, + ...); + +/* + * callback function for curl_formget() + * The void *arg pointer will be the one passed as second argument to + * curl_formget(). + * The character buffer passed to it must not be freed. + * Should return the buffer length passed to it as the argument "len" on + * success. + */ +typedef size_t (*curl_formget_callback)(void *arg, const char *buf, + size_t len); + +/* + * NAME curl_formget() + * + * DESCRIPTION + * + * Serialize a curl_httppost struct built with curl_formadd(). + * Accepts a void pointer as second argument which will be passed to + * the curl_formget_callback function. + * Returns 0 on success. + */ +CURL_EXTERN int curl_formget(struct curl_httppost *form, void *arg, + curl_formget_callback append); +/* + * NAME curl_formfree() + * + * DESCRIPTION + * + * Free a multipart formpost previously built with curl_formadd(). + */ +CURL_EXTERN void curl_formfree(struct curl_httppost *form); + +/* + * NAME curl_getenv() + * + * DESCRIPTION + * + * Returns a malloc()'ed string that MUST be curl_free()ed after usage is + * complete. DEPRECATED - see lib/README.curlx + */ +CURL_EXTERN char *curl_getenv(const char *variable); + +/* + * NAME curl_version() + * + * DESCRIPTION + * + * Returns a static ascii string of the libcurl version. + */ +CURL_EXTERN char *curl_version(void); + +/* + * NAME curl_easy_escape() + * + * DESCRIPTION + * + * Escapes URL strings (converts all letters consider illegal in URLs to their + * %XX versions). This function returns a new allocated string or NULL if an + * error occurred. + */ +CURL_EXTERN char *curl_easy_escape(CURL *handle, + const char *string, + int length); + +/* the previous version: */ +CURL_EXTERN char *curl_escape(const char *string, + int length); + + +/* + * NAME curl_easy_unescape() + * + * DESCRIPTION + * + * Unescapes URL encoding in strings (converts all %XX codes to their 8bit + * versions). This function returns a new allocated string or NULL if an error + * occurred. + * Conversion Note: On non-ASCII platforms the ASCII %XX codes are + * converted into the host encoding. + */ +CURL_EXTERN char *curl_easy_unescape(CURL *handle, + const char *string, + int length, + int *outlength); + +/* the previous version */ +CURL_EXTERN char *curl_unescape(const char *string, + int length); + +/* + * NAME curl_free() + * + * DESCRIPTION + * + * Provided for de-allocation in the same translation unit that did the + * allocation. Added in libcurl 7.10 + */ +CURL_EXTERN void curl_free(void *p); + +/* + * NAME curl_global_init() + * + * DESCRIPTION + * + * curl_global_init() should be invoked exactly once for each application that + * uses libcurl and before any call of other libcurl functions. + * + * This function is not thread-safe! + */ +CURL_EXTERN CURLcode curl_global_init(long flags); + +/* + * NAME curl_global_init_mem() + * + * DESCRIPTION + * + * curl_global_init() or curl_global_init_mem() should be invoked exactly once + * for each application that uses libcurl. This function can be used to + * initialize libcurl and set user defined memory management callback + * functions. Users can implement memory management routines to check for + * memory leaks, check for mis-use of the curl library etc. User registered + * callback routines with be invoked by this library instead of the system + * memory management routines like malloc, free etc. + */ +CURL_EXTERN CURLcode curl_global_init_mem(long flags, + curl_malloc_callback m, + curl_free_callback f, + curl_realloc_callback r, + curl_strdup_callback s, + curl_calloc_callback c); + +/* + * NAME curl_global_cleanup() + * + * DESCRIPTION + * + * curl_global_cleanup() should be invoked exactly once for each application + * that uses libcurl + */ +CURL_EXTERN void curl_global_cleanup(void); + +/* linked-list structure for the CURLOPT_QUOTE option (and other) */ +struct curl_slist { + char *data; + struct curl_slist *next; +}; + +/* + * NAME curl_slist_append() + * + * DESCRIPTION + * + * Appends a string to a linked list. If no list exists, it will be created + * first. Returns the new list, after appending. + */ +CURL_EXTERN struct curl_slist *curl_slist_append(struct curl_slist *, + const char *); + +/* + * NAME curl_slist_free_all() + * + * DESCRIPTION + * + * free a previously built curl_slist. + */ +CURL_EXTERN void curl_slist_free_all(struct curl_slist *); + +/* + * NAME curl_getdate() + * + * DESCRIPTION + * + * Returns the time, in seconds since 1 Jan 1970 of the time string given in + * the first argument. The time argument in the second parameter is unused + * and should be set to NULL. + */ +CURL_EXTERN time_t curl_getdate(const char *p, const time_t *unused); + +/* info about the certificate chain, only for OpenSSL builds. Asked + for with CURLOPT_CERTINFO / CURLINFO_CERTINFO */ +struct curl_certinfo { + int num_of_certs; /* number of certificates with information */ + struct curl_slist **certinfo; /* for each index in this array, there's a + linked list with textual information in the + format "name: value" */ +}; + +/* enum for the different supported SSL backends */ +typedef enum { + CURLSSLBACKEND_NONE = 0, + CURLSSLBACKEND_OPENSSL = 1, + CURLSSLBACKEND_GNUTLS = 2, + CURLSSLBACKEND_NSS = 3, + CURLSSLBACKEND_OBSOLETE4 = 4, /* Was QSOSSL. */ + CURLSSLBACKEND_GSKIT = 5, + CURLSSLBACKEND_POLARSSL = 6, + CURLSSLBACKEND_CYASSL = 7, + CURLSSLBACKEND_SCHANNEL = 8, + CURLSSLBACKEND_DARWINSSL = 9, + CURLSSLBACKEND_AXTLS = 10, + CURLSSLBACKEND_MBEDTLS = 11 +} curl_sslbackend; + +/* aliases for library clones and renames */ +#define CURLSSLBACKEND_LIBRESSL 1 +#define CURLSSLBACKEND_BORINGSSL 1 +#define CURLSSLBACKEND_WOLFSSL 6 + +/* Information about the SSL library used and the respective internal SSL + handle, which can be used to obtain further information regarding the + connection. Asked for with CURLINFO_TLS_SSL_PTR or CURLINFO_TLS_SESSION. */ +struct curl_tlssessioninfo { + curl_sslbackend backend; + void *internals; +}; + +#define CURLINFO_STRING 0x100000 +#define CURLINFO_LONG 0x200000 +#define CURLINFO_DOUBLE 0x300000 +#define CURLINFO_SLIST 0x400000 +#define CURLINFO_SOCKET 0x500000 +#define CURLINFO_MASK 0x0fffff +#define CURLINFO_TYPEMASK 0xf00000 + +typedef enum { + CURLINFO_NONE, /* first, never use this */ + CURLINFO_EFFECTIVE_URL = CURLINFO_STRING + 1, + CURLINFO_RESPONSE_CODE = CURLINFO_LONG + 2, + CURLINFO_TOTAL_TIME = CURLINFO_DOUBLE + 3, + CURLINFO_NAMELOOKUP_TIME = CURLINFO_DOUBLE + 4, + CURLINFO_CONNECT_TIME = CURLINFO_DOUBLE + 5, + CURLINFO_PRETRANSFER_TIME = CURLINFO_DOUBLE + 6, + CURLINFO_SIZE_UPLOAD = CURLINFO_DOUBLE + 7, + CURLINFO_SIZE_DOWNLOAD = CURLINFO_DOUBLE + 8, + CURLINFO_SPEED_DOWNLOAD = CURLINFO_DOUBLE + 9, + CURLINFO_SPEED_UPLOAD = CURLINFO_DOUBLE + 10, + CURLINFO_HEADER_SIZE = CURLINFO_LONG + 11, + CURLINFO_REQUEST_SIZE = CURLINFO_LONG + 12, + CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG + 13, + CURLINFO_FILETIME = CURLINFO_LONG + 14, + CURLINFO_CONTENT_LENGTH_DOWNLOAD = CURLINFO_DOUBLE + 15, + CURLINFO_CONTENT_LENGTH_UPLOAD = CURLINFO_DOUBLE + 16, + CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE + 17, + CURLINFO_CONTENT_TYPE = CURLINFO_STRING + 18, + CURLINFO_REDIRECT_TIME = CURLINFO_DOUBLE + 19, + CURLINFO_REDIRECT_COUNT = CURLINFO_LONG + 20, + CURLINFO_PRIVATE = CURLINFO_STRING + 21, + CURLINFO_HTTP_CONNECTCODE = CURLINFO_LONG + 22, + CURLINFO_HTTPAUTH_AVAIL = CURLINFO_LONG + 23, + CURLINFO_PROXYAUTH_AVAIL = CURLINFO_LONG + 24, + CURLINFO_OS_ERRNO = CURLINFO_LONG + 25, + CURLINFO_NUM_CONNECTS = CURLINFO_LONG + 26, + CURLINFO_SSL_ENGINES = CURLINFO_SLIST + 27, + CURLINFO_COOKIELIST = CURLINFO_SLIST + 28, + CURLINFO_LASTSOCKET = CURLINFO_LONG + 29, + CURLINFO_FTP_ENTRY_PATH = CURLINFO_STRING + 30, + CURLINFO_REDIRECT_URL = CURLINFO_STRING + 31, + CURLINFO_PRIMARY_IP = CURLINFO_STRING + 32, + CURLINFO_APPCONNECT_TIME = CURLINFO_DOUBLE + 33, + CURLINFO_CERTINFO = CURLINFO_SLIST + 34, + CURLINFO_CONDITION_UNMET = CURLINFO_LONG + 35, + CURLINFO_RTSP_SESSION_ID = CURLINFO_STRING + 36, + CURLINFO_RTSP_CLIENT_CSEQ = CURLINFO_LONG + 37, + CURLINFO_RTSP_SERVER_CSEQ = CURLINFO_LONG + 38, + CURLINFO_RTSP_CSEQ_RECV = CURLINFO_LONG + 39, + CURLINFO_PRIMARY_PORT = CURLINFO_LONG + 40, + CURLINFO_LOCAL_IP = CURLINFO_STRING + 41, + CURLINFO_LOCAL_PORT = CURLINFO_LONG + 42, + CURLINFO_TLS_SESSION = CURLINFO_SLIST + 43, + CURLINFO_ACTIVESOCKET = CURLINFO_SOCKET + 44, + CURLINFO_TLS_SSL_PTR = CURLINFO_SLIST + 45, + CURLINFO_HTTP_VERSION = CURLINFO_LONG + 46, + /* Fill in new entries below here! */ + + CURLINFO_LASTONE = 46 +} CURLINFO; + +/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as + CURLINFO_HTTP_CODE */ +#define CURLINFO_HTTP_CODE CURLINFO_RESPONSE_CODE + +typedef enum { + CURLCLOSEPOLICY_NONE, /* first, never use this */ + + CURLCLOSEPOLICY_OLDEST, + CURLCLOSEPOLICY_LEAST_RECENTLY_USED, + CURLCLOSEPOLICY_LEAST_TRAFFIC, + CURLCLOSEPOLICY_SLOWEST, + CURLCLOSEPOLICY_CALLBACK, + + CURLCLOSEPOLICY_LAST /* last, never use this */ +} curl_closepolicy; + +#define CURL_GLOBAL_SSL (1<<0) +#define CURL_GLOBAL_WIN32 (1<<1) +#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32) +#define CURL_GLOBAL_NOTHING 0 +#define CURL_GLOBAL_DEFAULT CURL_GLOBAL_ALL +#define CURL_GLOBAL_ACK_EINTR (1<<2) + + +/***************************************************************************** + * Setup defines, protos etc for the sharing stuff. + */ + +/* Different data locks for a single share */ +typedef enum { + CURL_LOCK_DATA_NONE = 0, + /* CURL_LOCK_DATA_SHARE is used internally to say that + * the locking is just made to change the internal state of the share + * itself. + */ + CURL_LOCK_DATA_SHARE, + CURL_LOCK_DATA_COOKIE, + CURL_LOCK_DATA_DNS, + CURL_LOCK_DATA_SSL_SESSION, + CURL_LOCK_DATA_CONNECT, + CURL_LOCK_DATA_LAST +} curl_lock_data; + +/* Different lock access types */ +typedef enum { + CURL_LOCK_ACCESS_NONE = 0, /* unspecified action */ + CURL_LOCK_ACCESS_SHARED = 1, /* for read perhaps */ + CURL_LOCK_ACCESS_SINGLE = 2, /* for write perhaps */ + CURL_LOCK_ACCESS_LAST /* never use */ +} curl_lock_access; + +typedef void (*curl_lock_function)(CURL *handle, + curl_lock_data data, + curl_lock_access locktype, + void *userptr); +typedef void (*curl_unlock_function)(CURL *handle, + curl_lock_data data, + void *userptr); + +typedef struct Curl_share CURLSH; + +typedef enum { + CURLSHE_OK, /* all is fine */ + CURLSHE_BAD_OPTION, /* 1 */ + CURLSHE_IN_USE, /* 2 */ + CURLSHE_INVALID, /* 3 */ + CURLSHE_NOMEM, /* 4 out of memory */ + CURLSHE_NOT_BUILT_IN, /* 5 feature not present in lib */ + CURLSHE_LAST /* never use */ +} CURLSHcode; + +typedef enum { + CURLSHOPT_NONE, /* don't use */ + CURLSHOPT_SHARE, /* specify a data type to share */ + CURLSHOPT_UNSHARE, /* specify which data type to stop sharing */ + CURLSHOPT_LOCKFUNC, /* pass in a 'curl_lock_function' pointer */ + CURLSHOPT_UNLOCKFUNC, /* pass in a 'curl_unlock_function' pointer */ + CURLSHOPT_USERDATA, /* pass in a user data pointer used in the lock/unlock + callback functions */ + CURLSHOPT_LAST /* never use */ +} CURLSHoption; + +CURL_EXTERN CURLSH *curl_share_init(void); +CURL_EXTERN CURLSHcode curl_share_setopt(CURLSH *, CURLSHoption option, ...); +CURL_EXTERN CURLSHcode curl_share_cleanup(CURLSH *); + +/**************************************************************************** + * Structures for querying information about the curl library at runtime. + */ + +typedef enum { + CURLVERSION_FIRST, + CURLVERSION_SECOND, + CURLVERSION_THIRD, + CURLVERSION_FOURTH, + CURLVERSION_LAST /* never actually use this */ +} CURLversion; + +/* The 'CURLVERSION_NOW' is the symbolic name meant to be used by + basically all programs ever that want to get version information. It is + meant to be a built-in version number for what kind of struct the caller + expects. If the struct ever changes, we redefine the NOW to another enum + from above. */ +#define CURLVERSION_NOW CURLVERSION_FOURTH + +typedef struct { + CURLversion age; /* age of the returned struct */ + const char *version; /* LIBCURL_VERSION */ + unsigned int version_num; /* LIBCURL_VERSION_NUM */ + const char *host; /* OS/host/cpu/machine when configured */ + int features; /* bitmask, see defines below */ + const char *ssl_version; /* human readable string */ + long ssl_version_num; /* not used anymore, always 0 */ + const char *libz_version; /* human readable string */ + /* protocols is terminated by an entry with a NULL protoname */ + const char * const *protocols; + + /* The fields below this were added in CURLVERSION_SECOND */ + const char *ares; + int ares_num; + + /* This field was added in CURLVERSION_THIRD */ + const char *libidn; + + /* These field were added in CURLVERSION_FOURTH */ + + /* Same as '_libiconv_version' if built with HAVE_ICONV */ + int iconv_ver_num; + + const char *libssh_version; /* human readable string */ + +} curl_version_info_data; + +#define CURL_VERSION_IPV6 (1<<0) /* IPv6-enabled */ +#define CURL_VERSION_KERBEROS4 (1<<1) /* Kerberos V4 auth is supported + (deprecated) */ +#define CURL_VERSION_SSL (1<<2) /* SSL options are present */ +#define CURL_VERSION_LIBZ (1<<3) /* libz features are present */ +#define CURL_VERSION_NTLM (1<<4) /* NTLM auth is supported */ +#define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth is supported + (deprecated) */ +#define CURL_VERSION_DEBUG (1<<6) /* Built with debug capabilities */ +#define CURL_VERSION_ASYNCHDNS (1<<7) /* Asynchronous DNS resolves */ +#define CURL_VERSION_SPNEGO (1<<8) /* SPNEGO auth is supported */ +#define CURL_VERSION_LARGEFILE (1<<9) /* Supports files larger than 2GB */ +#define CURL_VERSION_IDN (1<<10) /* Internationized Domain Names are + supported */ +#define CURL_VERSION_SSPI (1<<11) /* Built against Windows SSPI */ +#define CURL_VERSION_CONV (1<<12) /* Character conversions supported */ +#define CURL_VERSION_CURLDEBUG (1<<13) /* Debug memory tracking supported */ +#define CURL_VERSION_TLSAUTH_SRP (1<<14) /* TLS-SRP auth is supported */ +#define CURL_VERSION_NTLM_WB (1<<15) /* NTLM delegation to winbind helper + is suported */ +#define CURL_VERSION_HTTP2 (1<<16) /* HTTP2 support built-in */ +#define CURL_VERSION_GSSAPI (1<<17) /* Built against a GSS-API library */ +#define CURL_VERSION_KERBEROS5 (1<<18) /* Kerberos V5 auth is supported */ +#define CURL_VERSION_UNIX_SOCKETS (1<<19) /* Unix domain sockets support */ +#define CURL_VERSION_PSL (1<<20) /* Mozilla's Public Suffix List, used + for cookie domain verification */ + + /* + * NAME curl_version_info() + * + * DESCRIPTION + * + * This function returns a pointer to a static copy of the version info + * struct. See above. + */ +CURL_EXTERN curl_version_info_data *curl_version_info(CURLversion); + +/* + * NAME curl_easy_strerror() + * + * DESCRIPTION + * + * The curl_easy_strerror function may be used to turn a CURLcode value + * into the equivalent human readable error string. This is useful + * for printing meaningful error messages. + */ +CURL_EXTERN const char *curl_easy_strerror(CURLcode); + +/* + * NAME curl_share_strerror() + * + * DESCRIPTION + * + * The curl_share_strerror function may be used to turn a CURLSHcode value + * into the equivalent human readable error string. This is useful + * for printing meaningful error messages. + */ +CURL_EXTERN const char *curl_share_strerror(CURLSHcode); + +/* + * NAME curl_easy_pause() + * + * DESCRIPTION + * + * The curl_easy_pause function pauses or unpauses transfers. Select the new + * state by setting the bitmask, use the convenience defines below. + * + */ +CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask); + +#define CURLPAUSE_RECV (1<<0) +#define CURLPAUSE_RECV_CONT (0) + +#define CURLPAUSE_SEND (1<<2) +#define CURLPAUSE_SEND_CONT (0) + +#define CURLPAUSE_ALL (CURLPAUSE_RECV|CURLPAUSE_SEND) +#define CURLPAUSE_CONT (CURLPAUSE_RECV_CONT|CURLPAUSE_SEND_CONT) + +#ifdef __cplusplus +} +#endif + +/* unfortunately, the easy.h and multi.h include files need options and info + stuff before they can be included! */ +#include "easy.h" /* nothing in curl is fun without the easy stuff */ +#include "multi.h" + +/* the typechecker doesn't work in C++ (yet) */ +#if defined(__GNUC__) && defined(__GNUC_MINOR__) && \ + ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && \ + !defined(__cplusplus) && !defined(CURL_DISABLE_TYPECHECK) +#include "typecheck-gcc.h" +#else +#if defined(__STDC__) && (__STDC__ >= 1) +/* This preprocessor magic that replaces a call with the exact same call is + only done to make sure application authors pass exactly three arguments + to these functions. */ +#define curl_easy_setopt(handle,opt,param) curl_easy_setopt(handle,opt,param) +#define curl_easy_getinfo(handle,info,arg) curl_easy_getinfo(handle,info,arg) +#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param) +#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param) +#endif /* __STDC__ >= 1 */ +#endif /* gcc >= 4.3 && !__cplusplus */ + +#endif /* __CURL_CURL_H */ diff --git a/OSlibs/ios/include/curl/curlbuild.h b/OSlibs/ios/include/curl/curlbuild.h new file mode 100755 index 000000000..fbc184b13 --- /dev/null +++ b/OSlibs/ios/include/curl/curlbuild.h @@ -0,0 +1,234 @@ +/* include/curl/curlbuild.h. Generated from curlbuild.h.in by configure. */ +#ifndef __CURL_CURLBUILD_H +#define __CURL_CURLBUILD_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* ================================================================ */ +/* NOTES FOR CONFIGURE CAPABLE SYSTEMS */ +/* ================================================================ */ + +/* + * NOTE 1: + * ------- + * + * Nothing in this file is intended to be modified or adjusted by the + * curl library user nor by the curl library builder. + * + * If you think that something actually needs to be changed, adjusted + * or fixed in this file, then, report it on the libcurl development + * mailing list: https://cool.haxx.se/mailman/listinfo/curl-library/ + * + * This header file shall only export symbols which are 'curl' or 'CURL' + * prefixed, otherwise public name space would be polluted. + * + * NOTE 2: + * ------- + * + * Right now you might be staring at file include/curl/curlbuild.h.in or + * at file include/curl/curlbuild.h, this is due to the following reason: + * + * On systems capable of running the configure script, the configure process + * will overwrite the distributed include/curl/curlbuild.h file with one that + * is suitable and specific to the library being configured and built, which + * is generated from the include/curl/curlbuild.h.in template file. + * + */ + +/* ================================================================ */ +/* DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE */ +/* ================================================================ */ + +#ifdef CURL_SIZEOF_LONG +#error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined +#endif + +#ifdef CURL_TYPEOF_CURL_SOCKLEN_T +#error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined +#endif + +#ifdef CURL_SIZEOF_CURL_SOCKLEN_T +#error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined +#endif + +#ifdef CURL_TYPEOF_CURL_OFF_T +#error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_FORMAT_CURL_OFF_T +#error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_FORMAT_CURL_OFF_TU +#error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined +#endif + +#ifdef CURL_FORMAT_OFF_T +#error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined +#endif + +#ifdef CURL_SIZEOF_CURL_OFF_T +#error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_SUFFIX_CURL_OFF_T +#error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_SUFFIX_CURL_OFF_TU +#error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined +#endif + +/* ================================================================ */ +/* EXTERNAL INTERFACE SETTINGS FOR CONFIGURE CAPABLE SYSTEMS ONLY */ +/* ================================================================ */ + +/* Configure process defines this to 1 when it finds out that system */ +/* header file ws2tcpip.h must be included by the external interface. */ +/* #undef CURL_PULL_WS2TCPIP_H */ +#ifdef CURL_PULL_WS2TCPIP_H +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include +# include +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file sys/types.h must be included by the external interface. */ +#define CURL_PULL_SYS_TYPES_H 1 +#ifdef CURL_PULL_SYS_TYPES_H +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file stdint.h must be included by the external interface. */ +#ifdef __LP64__ +/* #undef CURL_PULL_STDINT_H */ +#else +#define CURL_PULL_STDINT_H 1 +#endif +#ifdef CURL_PULL_STDINT_H +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file inttypes.h must be included by the external interface. */ +#ifdef __LP64__ +/* #undef CURL_PULL_INTTYPES_H */ +#else +#define CURL_PULL_INTTYPES_H 1 +#endif +#ifdef CURL_PULL_INTTYPES_H +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file sys/socket.h must be included by the external interface. */ +#define CURL_PULL_SYS_SOCKET_H 1 +#ifdef CURL_PULL_SYS_SOCKET_H +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file sys/poll.h must be included by the external interface. */ +/* #undef CURL_PULL_SYS_POLL_H */ +#ifdef CURL_PULL_SYS_POLL_H +# include +#endif + +/* The size of `long', as computed by sizeof. */ +#ifdef __LP64__ +#define CURL_SIZEOF_LONG 8 +#else +#define CURL_SIZEOF_LONG 4 +#endif + +/* Integral data type used for curl_socklen_t. */ +#define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t + +/* The size of `curl_socklen_t', as computed by sizeof. */ +#define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +/* Data type definition of curl_socklen_t. */ +typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t; + +/* Signed integral data type used for curl_off_t. */ +#ifdef __LP64__ +#define CURL_TYPEOF_CURL_OFF_T long +#else +#define CURL_TYPEOF_CURL_OFF_T int64_t +#endif + +/* Data type definition of curl_off_t. */ +typedef CURL_TYPEOF_CURL_OFF_T curl_off_t; + +/* curl_off_t formatting string directive without "%" conversion specifier. */ +#ifdef __LP64__ +#define CURL_FORMAT_CURL_OFF_T "ld" +#else +#define CURL_FORMAT_CURL_OFF_T "lld" +#endif + +/* unsigned curl_off_t formatting string without "%" conversion specifier. */ +#ifdef __LP64__ +#define CURL_FORMAT_CURL_OFF_TU "lu" +#else +#define CURL_FORMAT_CURL_OFF_TU "llu" +#endif + +/* curl_off_t formatting string directive with "%" conversion specifier. */ +#ifdef __LP64__ +#define CURL_FORMAT_OFF_T "%ld" +#else +#define CURL_FORMAT_OFF_T "%lld" +#endif + +/* The size of `curl_off_t', as computed by sizeof. */ +#define CURL_SIZEOF_CURL_OFF_T 8 + +/* curl_off_t constant suffix. */ +#ifdef __LP64__ +#define CURL_SUFFIX_CURL_OFF_T L +#else +#define CURL_SUFFIX_CURL_OFF_T LL +#endif + +/* unsigned curl_off_t constant suffix. */ +#ifdef __LP64__ +#define CURL_SUFFIX_CURL_OFF_TU UL +#else +#define CURL_SUFFIX_CURL_OFF_TU ULL +#endif + +#endif /* __CURL_CURLBUILD_H */ diff --git a/OSlibs/ios/include/curl/curlrules.h b/OSlibs/ios/include/curl/curlrules.h new file mode 100755 index 000000000..55d21f68f --- /dev/null +++ b/OSlibs/ios/include/curl/curlrules.h @@ -0,0 +1,262 @@ +#ifndef __CURL_CURLRULES_H +#define __CURL_CURLRULES_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* ================================================================ */ +/* COMPILE TIME SANITY CHECKS */ +/* ================================================================ */ + +/* + * NOTE 1: + * ------- + * + * All checks done in this file are intentionally placed in a public + * header file which is pulled by curl/curl.h when an application is + * being built using an already built libcurl library. Additionally + * this file is also included and used when building the library. + * + * If compilation fails on this file it is certainly sure that the + * problem is elsewhere. It could be a problem in the curlbuild.h + * header file, or simply that you are using different compilation + * settings than those used to build the library. + * + * Nothing in this file is intended to be modified or adjusted by the + * curl library user nor by the curl library builder. + * + * Do not deactivate any check, these are done to make sure that the + * library is properly built and used. + * + * You can find further help on the libcurl development mailing list: + * https://cool.haxx.se/mailman/listinfo/curl-library/ + * + * NOTE 2 + * ------ + * + * Some of the following compile time checks are based on the fact + * that the dimension of a constant array can not be a negative one. + * In this way if the compile time verification fails, the compilation + * will fail issuing an error. The error description wording is compiler + * dependent but it will be quite similar to one of the following: + * + * "negative subscript or subscript is too large" + * "array must have at least one element" + * "-1 is an illegal array size" + * "size of array is negative" + * + * If you are building an application which tries to use an already + * built libcurl library and you are getting this kind of errors on + * this file, it is a clear indication that there is a mismatch between + * how the library was built and how you are trying to use it for your + * application. Your already compiled or binary library provider is the + * only one who can give you the details you need to properly use it. + */ + +/* + * Verify that some macros are actually defined. + */ + +#ifndef CURL_SIZEOF_LONG +# error "CURL_SIZEOF_LONG definition is missing!" + Error Compilation_aborted_CURL_SIZEOF_LONG_is_missing +#endif + +#ifndef CURL_TYPEOF_CURL_SOCKLEN_T +# error "CURL_TYPEOF_CURL_SOCKLEN_T definition is missing!" + Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_is_missing +#endif + +#ifndef CURL_SIZEOF_CURL_SOCKLEN_T +# error "CURL_SIZEOF_CURL_SOCKLEN_T definition is missing!" + Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_is_missing +#endif + +#ifndef CURL_TYPEOF_CURL_OFF_T +# error "CURL_TYPEOF_CURL_OFF_T definition is missing!" + Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_is_missing +#endif + +#ifndef CURL_FORMAT_CURL_OFF_T +# error "CURL_FORMAT_CURL_OFF_T definition is missing!" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_is_missing +#endif + +#ifndef CURL_FORMAT_CURL_OFF_TU +# error "CURL_FORMAT_CURL_OFF_TU definition is missing!" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_is_missing +#endif + +#ifndef CURL_FORMAT_OFF_T +# error "CURL_FORMAT_OFF_T definition is missing!" + Error Compilation_aborted_CURL_FORMAT_OFF_T_is_missing +#endif + +#ifndef CURL_SIZEOF_CURL_OFF_T +# error "CURL_SIZEOF_CURL_OFF_T definition is missing!" + Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_is_missing +#endif + +#ifndef CURL_SUFFIX_CURL_OFF_T +# error "CURL_SUFFIX_CURL_OFF_T definition is missing!" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_is_missing +#endif + +#ifndef CURL_SUFFIX_CURL_OFF_TU +# error "CURL_SUFFIX_CURL_OFF_TU definition is missing!" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_is_missing +#endif + +/* + * Macros private to this header file. + */ + +#define CurlchkszEQ(t, s) sizeof(t) == s ? 1 : -1 + +#define CurlchkszGE(t1, t2) sizeof(t1) >= sizeof(t2) ? 1 : -1 + +/* + * Verify that the size previously defined and expected for long + * is the same as the one reported by sizeof() at compile time. + */ + +typedef char + __curl_rule_01__ + [CurlchkszEQ(long, CURL_SIZEOF_LONG)]; + +/* + * Verify that the size previously defined and expected for + * curl_off_t is actually the the same as the one reported + * by sizeof() at compile time. + */ + +typedef char + __curl_rule_02__ + [CurlchkszEQ(curl_off_t, CURL_SIZEOF_CURL_OFF_T)]; + +/* + * Verify at compile time that the size of curl_off_t as reported + * by sizeof() is greater or equal than the one reported for long + * for the current compilation. + */ + +typedef char + __curl_rule_03__ + [CurlchkszGE(curl_off_t, long)]; + +/* + * Verify that the size previously defined and expected for + * curl_socklen_t is actually the the same as the one reported + * by sizeof() at compile time. + */ + +typedef char + __curl_rule_04__ + [CurlchkszEQ(curl_socklen_t, CURL_SIZEOF_CURL_SOCKLEN_T)]; + +/* + * Verify at compile time that the size of curl_socklen_t as reported + * by sizeof() is greater or equal than the one reported for int for + * the current compilation. + */ + +typedef char + __curl_rule_05__ + [CurlchkszGE(curl_socklen_t, int)]; + +/* ================================================================ */ +/* EXTERNALLY AND INTERNALLY VISIBLE DEFINITIONS */ +/* ================================================================ */ + +/* + * CURL_ISOCPP and CURL_OFF_T_C definitions are done here in order to allow + * these to be visible and exported by the external libcurl interface API, + * while also making them visible to the library internals, simply including + * curl_setup.h, without actually needing to include curl.h internally. + * If some day this section would grow big enough, all this should be moved + * to its own header file. + */ + +/* + * Figure out if we can use the ## preprocessor operator, which is supported + * by ISO/ANSI C and C++. Some compilers support it without setting __STDC__ + * or __cplusplus so we need to carefully check for them too. + */ + +#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \ + defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \ + defined(__POCC__) || defined(__SALFORDC__) || defined(__HIGHC__) || \ + defined(__ILEC400__) + /* This compiler is believed to have an ISO compatible preprocessor */ +#define CURL_ISOCPP +#else + /* This compiler is believed NOT to have an ISO compatible preprocessor */ +#undef CURL_ISOCPP +#endif + +/* + * Macros for minimum-width signed and unsigned curl_off_t integer constants. + */ + +#if defined(__BORLANDC__) && (__BORLANDC__ == 0x0551) +# define __CURL_OFF_T_C_HLPR2(x) x +# define __CURL_OFF_T_C_HLPR1(x) __CURL_OFF_T_C_HLPR2(x) +# define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \ + __CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_T) +# define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \ + __CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_TU) +#else +# ifdef CURL_ISOCPP +# define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val ## Suffix +# else +# define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val/**/Suffix +# endif +# define __CURL_OFF_T_C_HLPR1(Val,Suffix) __CURL_OFF_T_C_HLPR2(Val,Suffix) +# define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_T) +# define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_TU) +#endif + +/* + * Get rid of macros private to this header file. + */ + +#undef CurlchkszEQ +#undef CurlchkszGE + +/* + * Get rid of macros not intended to exist beyond this point. + */ + +#undef CURL_PULL_WS2TCPIP_H +#undef CURL_PULL_SYS_TYPES_H +#undef CURL_PULL_SYS_SOCKET_H +#undef CURL_PULL_SYS_POLL_H +#undef CURL_PULL_STDINT_H +#undef CURL_PULL_INTTYPES_H + +#undef CURL_TYPEOF_CURL_SOCKLEN_T +#undef CURL_TYPEOF_CURL_OFF_T + +#ifdef CURL_NO_OLDIES +#undef CURL_FORMAT_OFF_T /* not required since 7.19.0 - obsoleted in 7.20.0 */ +#endif + +#endif /* __CURL_CURLRULES_H */ diff --git a/OSlibs/ios/include/curl/curlver.h b/OSlibs/ios/include/curl/curlver.h new file mode 100755 index 000000000..cebcf422c --- /dev/null +++ b/OSlibs/ios/include/curl/curlver.h @@ -0,0 +1,77 @@ +#ifndef __CURL_CURLVER_H +#define __CURL_CURLVER_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* This header file contains nothing but libcurl version info, generated by + a script at release-time. This was made its own header file in 7.11.2 */ + +/* This is the global package copyright */ +#define LIBCURL_COPYRIGHT "1996 - 2016 Daniel Stenberg, ." + +/* This is the version number of the libcurl package from which this header + file origins: */ +#define LIBCURL_VERSION "7.50.0" + +/* The numeric version number is also available "in parts" by using these + defines: */ +#define LIBCURL_VERSION_MAJOR 7 +#define LIBCURL_VERSION_MINOR 50 +#define LIBCURL_VERSION_PATCH 0 + +/* This is the numeric version of the libcurl version number, meant for easier + parsing and comparions by programs. The LIBCURL_VERSION_NUM define will + always follow this syntax: + + 0xXXYYZZ + + Where XX, YY and ZZ are the main version, release and patch numbers in + hexadecimal (using 8 bits each). All three numbers are always represented + using two digits. 1.2 would appear as "0x010200" while version 9.11.7 + appears as "0x090b07". + + This 6-digit (24 bits) hexadecimal number does not show pre-release number, + and it is always a greater number in a more recent release. It makes + comparisons with greater than and less than work. + + Note: This define is the full hex number and _does not_ use the + CURL_VERSION_BITS() macro since curl's own configure script greps for it + and needs it to contain the full number. +*/ +#define LIBCURL_VERSION_NUM 0x073200 + +/* + * This is the date and time when the full source package was created. The + * timestamp is not stored in git, as the timestamp is properly set in the + * tarballs by the maketgz script. + * + * The format of the date should follow this template: + * + * "Mon Feb 12 11:35:33 UTC 2007" + */ +#define LIBCURL_TIMESTAMP "Thu Jul 21 08:55:43 UTC 2016" + +#define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|z) +#define CURL_AT_LEAST_VERSION(x,y,z) \ + (LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z)) + +#endif /* __CURL_CURLVER_H */ diff --git a/OSlibs/ios/include/curl/easy.h b/OSlibs/ios/include/curl/easy.h new file mode 100755 index 000000000..afc766cd2 --- /dev/null +++ b/OSlibs/ios/include/curl/easy.h @@ -0,0 +1,102 @@ +#ifndef __CURL_EASY_H +#define __CURL_EASY_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2008, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + +CURL_EXTERN CURL *curl_easy_init(void); +CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...); +CURL_EXTERN CURLcode curl_easy_perform(CURL *curl); +CURL_EXTERN void curl_easy_cleanup(CURL *curl); + +/* + * NAME curl_easy_getinfo() + * + * DESCRIPTION + * + * Request internal information from the curl session with this function. The + * third argument MUST be a pointer to a long, a pointer to a char * or a + * pointer to a double (as the documentation describes elsewhere). The data + * pointed to will be filled in accordingly and can be relied upon only if the + * function returns CURLE_OK. This function is intended to get used *AFTER* a + * performed transfer, all results from this function are undefined until the + * transfer is completed. + */ +CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...); + + +/* + * NAME curl_easy_duphandle() + * + * DESCRIPTION + * + * Creates a new curl session handle with the same options set for the handle + * passed in. Duplicating a handle could only be a matter of cloning data and + * options, internal state info and things like persistent connections cannot + * be transferred. It is useful in multithreaded applications when you can run + * curl_easy_duphandle() for each new thread to avoid a series of identical + * curl_easy_setopt() invokes in every thread. + */ +CURL_EXTERN CURL* curl_easy_duphandle(CURL *curl); + +/* + * NAME curl_easy_reset() + * + * DESCRIPTION + * + * Re-initializes a CURL handle to the default values. This puts back the + * handle to the same state as it was in when it was just created. + * + * It does keep: live connections, the Session ID cache, the DNS cache and the + * cookies. + */ +CURL_EXTERN void curl_easy_reset(CURL *curl); + +/* + * NAME curl_easy_recv() + * + * DESCRIPTION + * + * Receives data from the connected socket. Use after successful + * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. + */ +CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, + size_t *n); + +/* + * NAME curl_easy_send() + * + * DESCRIPTION + * + * Sends data over the connected socket. Use after successful + * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. + */ +CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer, + size_t buflen, size_t *n); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/OSlibs/ios/include/curl/mprintf.h b/OSlibs/ios/include/curl/mprintf.h new file mode 100755 index 000000000..e20f546e1 --- /dev/null +++ b/OSlibs/ios/include/curl/mprintf.h @@ -0,0 +1,50 @@ +#ifndef __CURL_MPRINTF_H +#define __CURL_MPRINTF_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include +#include /* needed for FILE */ +#include "curl.h" /* for CURL_EXTERN */ + +#ifdef __cplusplus +extern "C" { +#endif + +CURL_EXTERN int curl_mprintf(const char *format, ...); +CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...); +CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...); +CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength, + const char *format, ...); +CURL_EXTERN int curl_mvprintf(const char *format, va_list args); +CURL_EXTERN int curl_mvfprintf(FILE *fd, const char *format, va_list args); +CURL_EXTERN int curl_mvsprintf(char *buffer, const char *format, va_list args); +CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength, + const char *format, va_list args); +CURL_EXTERN char *curl_maprintf(const char *format, ...); +CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args); + +#ifdef __cplusplus +} +#endif + +#endif /* __CURL_MPRINTF_H */ diff --git a/OSlibs/ios/include/curl/multi.h b/OSlibs/ios/include/curl/multi.h new file mode 100755 index 000000000..7a1040f46 --- /dev/null +++ b/OSlibs/ios/include/curl/multi.h @@ -0,0 +1,435 @@ +#ifndef __CURL_MULTI_H +#define __CURL_MULTI_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +/* + This is an "external" header file. Don't give away any internals here! + + GOALS + + o Enable a "pull" interface. The application that uses libcurl decides where + and when to ask libcurl to get/send data. + + o Enable multiple simultaneous transfers in the same thread without making it + complicated for the application. + + o Enable the application to select() on its own file descriptors and curl's + file descriptors simultaneous easily. + +*/ + +/* + * This header file should not really need to include "curl.h" since curl.h + * itself includes this file and we expect user applications to do #include + * without the need for especially including multi.h. + * + * For some reason we added this include here at one point, and rather than to + * break existing (wrongly written) libcurl applications, we leave it as-is + * but with this warning attached. + */ +#include "curl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct Curl_multi CURLM; + +typedef enum { + CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or + curl_multi_socket*() soon */ + CURLM_OK, + CURLM_BAD_HANDLE, /* the passed-in handle is not a valid CURLM handle */ + CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */ + CURLM_OUT_OF_MEMORY, /* if you ever get this, you're in deep sh*t */ + CURLM_INTERNAL_ERROR, /* this is a libcurl bug */ + CURLM_BAD_SOCKET, /* the passed in socket argument did not match */ + CURLM_UNKNOWN_OPTION, /* curl_multi_setopt() with unsupported option */ + CURLM_ADDED_ALREADY, /* an easy handle already added to a multi handle was + attempted to get added - again */ + CURLM_LAST +} CURLMcode; + +/* just to make code nicer when using curl_multi_socket() you can now check + for CURLM_CALL_MULTI_SOCKET too in the same style it works for + curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */ +#define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM + +/* bitmask bits for CURLMOPT_PIPELINING */ +#define CURLPIPE_NOTHING 0L +#define CURLPIPE_HTTP1 1L +#define CURLPIPE_MULTIPLEX 2L + +typedef enum { + CURLMSG_NONE, /* first, not used */ + CURLMSG_DONE, /* This easy handle has completed. 'result' contains + the CURLcode of the transfer */ + CURLMSG_LAST /* last, not used */ +} CURLMSG; + +struct CURLMsg { + CURLMSG msg; /* what this message means */ + CURL *easy_handle; /* the handle it concerns */ + union { + void *whatever; /* message-specific data */ + CURLcode result; /* return code for transfer */ + } data; +}; +typedef struct CURLMsg CURLMsg; + +/* Based on poll(2) structure and values. + * We don't use pollfd and POLL* constants explicitly + * to cover platforms without poll(). */ +#define CURL_WAIT_POLLIN 0x0001 +#define CURL_WAIT_POLLPRI 0x0002 +#define CURL_WAIT_POLLOUT 0x0004 + +struct curl_waitfd { + curl_socket_t fd; + short events; + short revents; /* not supported yet */ +}; + +/* + * Name: curl_multi_init() + * + * Desc: inititalize multi-style curl usage + * + * Returns: a new CURLM handle to use in all 'curl_multi' functions. + */ +CURL_EXTERN CURLM *curl_multi_init(void); + +/* + * Name: curl_multi_add_handle() + * + * Desc: add a standard curl handle to the multi stack + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *multi_handle, + CURL *curl_handle); + + /* + * Name: curl_multi_remove_handle() + * + * Desc: removes a curl handle from the multi stack again + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *multi_handle, + CURL *curl_handle); + + /* + * Name: curl_multi_fdset() + * + * Desc: Ask curl for its fd_set sets. The app can use these to select() or + * poll() on. We want curl_multi_perform() called as soon as one of + * them are ready. + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle, + fd_set *read_fd_set, + fd_set *write_fd_set, + fd_set *exc_fd_set, + int *max_fd); + +/* + * Name: curl_multi_wait() + * + * Desc: Poll on all fds within a CURLM set as well as any + * additional fds passed to the function. + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_wait(CURLM *multi_handle, + struct curl_waitfd extra_fds[], + unsigned int extra_nfds, + int timeout_ms, + int *ret); + + /* + * Name: curl_multi_perform() + * + * Desc: When the app thinks there's data available for curl it calls this + * function to read/write whatever there is right now. This returns + * as soon as the reads and writes are done. This function does not + * require that there actually is data available for reading or that + * data can be written, it can be called just in case. It returns + * the number of handles that still transfer data in the second + * argument's integer-pointer. + * + * Returns: CURLMcode type, general multi error code. *NOTE* that this only + * returns errors etc regarding the whole multi stack. There might + * still have occurred problems on invidual transfers even when this + * returns OK. + */ +CURL_EXTERN CURLMcode curl_multi_perform(CURLM *multi_handle, + int *running_handles); + + /* + * Name: curl_multi_cleanup() + * + * Desc: Cleans up and removes a whole multi stack. It does not free or + * touch any individual easy handles in any way. We need to define + * in what state those handles will be if this function is called + * in the middle of a transfer. + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle); + +/* + * Name: curl_multi_info_read() + * + * Desc: Ask the multi handle if there's any messages/informationals from + * the individual transfers. Messages include informationals such as + * error code from the transfer or just the fact that a transfer is + * completed. More details on these should be written down as well. + * + * Repeated calls to this function will return a new struct each + * time, until a special "end of msgs" struct is returned as a signal + * that there is no more to get at this point. + * + * The data the returned pointer points to will not survive calling + * curl_multi_cleanup(). + * + * The 'CURLMsg' struct is meant to be very simple and only contain + * very basic informations. If more involved information is wanted, + * we will provide the particular "transfer handle" in that struct + * and that should/could/would be used in subsequent + * curl_easy_getinfo() calls (or similar). The point being that we + * must never expose complex structs to applications, as then we'll + * undoubtably get backwards compatibility problems in the future. + * + * Returns: A pointer to a filled-in struct, or NULL if it failed or ran out + * of structs. It also writes the number of messages left in the + * queue (after this read) in the integer the second argument points + * to. + */ +CURL_EXTERN CURLMsg *curl_multi_info_read(CURLM *multi_handle, + int *msgs_in_queue); + +/* + * Name: curl_multi_strerror() + * + * Desc: The curl_multi_strerror function may be used to turn a CURLMcode + * value into the equivalent human readable error string. This is + * useful for printing meaningful error messages. + * + * Returns: A pointer to a zero-terminated error message. + */ +CURL_EXTERN const char *curl_multi_strerror(CURLMcode); + +/* + * Name: curl_multi_socket() and + * curl_multi_socket_all() + * + * Desc: An alternative version of curl_multi_perform() that allows the + * application to pass in one of the file descriptors that have been + * detected to have "action" on them and let libcurl perform. + * See man page for details. + */ +#define CURL_POLL_NONE 0 +#define CURL_POLL_IN 1 +#define CURL_POLL_OUT 2 +#define CURL_POLL_INOUT 3 +#define CURL_POLL_REMOVE 4 + +#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD + +#define CURL_CSELECT_IN 0x01 +#define CURL_CSELECT_OUT 0x02 +#define CURL_CSELECT_ERR 0x04 + +typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */ + curl_socket_t s, /* socket */ + int what, /* see above */ + void *userp, /* private callback + pointer */ + void *socketp); /* private socket + pointer */ +/* + * Name: curl_multi_timer_callback + * + * Desc: Called by libcurl whenever the library detects a change in the + * maximum number of milliseconds the app is allowed to wait before + * curl_multi_socket() or curl_multi_perform() must be called + * (to allow libcurl's timed events to take place). + * + * Returns: The callback should return zero. + */ +typedef int (*curl_multi_timer_callback)(CURLM *multi, /* multi handle */ + long timeout_ms, /* see above */ + void *userp); /* private callback + pointer */ + +CURL_EXTERN CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s, + int *running_handles); + +CURL_EXTERN CURLMcode curl_multi_socket_action(CURLM *multi_handle, + curl_socket_t s, + int ev_bitmask, + int *running_handles); + +CURL_EXTERN CURLMcode curl_multi_socket_all(CURLM *multi_handle, + int *running_handles); + +#ifndef CURL_ALLOW_OLD_MULTI_SOCKET +/* This macro below was added in 7.16.3 to push users who recompile to use + the new curl_multi_socket_action() instead of the old curl_multi_socket() +*/ +#define curl_multi_socket(x,y,z) curl_multi_socket_action(x,y,0,z) +#endif + +/* + * Name: curl_multi_timeout() + * + * Desc: Returns the maximum number of milliseconds the app is allowed to + * wait before curl_multi_socket() or curl_multi_perform() must be + * called (to allow libcurl's timed events to take place). + * + * Returns: CURLM error code. + */ +CURL_EXTERN CURLMcode curl_multi_timeout(CURLM *multi_handle, + long *milliseconds); + +#undef CINIT /* re-using the same name as in curl.h */ + +#ifdef CURL_ISOCPP +#define CINIT(name,type,num) CURLMOPT_ ## name = CURLOPTTYPE_ ## type + num +#else +/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ +#define LONG CURLOPTTYPE_LONG +#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT +#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT +#define OFF_T CURLOPTTYPE_OFF_T +#define CINIT(name,type,number) CURLMOPT_/**/name = type + number +#endif + +typedef enum { + /* This is the socket callback function pointer */ + CINIT(SOCKETFUNCTION, FUNCTIONPOINT, 1), + + /* This is the argument passed to the socket callback */ + CINIT(SOCKETDATA, OBJECTPOINT, 2), + + /* set to 1 to enable pipelining for this multi handle */ + CINIT(PIPELINING, LONG, 3), + + /* This is the timer callback function pointer */ + CINIT(TIMERFUNCTION, FUNCTIONPOINT, 4), + + /* This is the argument passed to the timer callback */ + CINIT(TIMERDATA, OBJECTPOINT, 5), + + /* maximum number of entries in the connection cache */ + CINIT(MAXCONNECTS, LONG, 6), + + /* maximum number of (pipelining) connections to one host */ + CINIT(MAX_HOST_CONNECTIONS, LONG, 7), + + /* maximum number of requests in a pipeline */ + CINIT(MAX_PIPELINE_LENGTH, LONG, 8), + + /* a connection with a content-length longer than this + will not be considered for pipelining */ + CINIT(CONTENT_LENGTH_PENALTY_SIZE, OFF_T, 9), + + /* a connection with a chunk length longer than this + will not be considered for pipelining */ + CINIT(CHUNK_LENGTH_PENALTY_SIZE, OFF_T, 10), + + /* a list of site names(+port) that are blacklisted from + pipelining */ + CINIT(PIPELINING_SITE_BL, OBJECTPOINT, 11), + + /* a list of server types that are blacklisted from + pipelining */ + CINIT(PIPELINING_SERVER_BL, OBJECTPOINT, 12), + + /* maximum number of open connections in total */ + CINIT(MAX_TOTAL_CONNECTIONS, LONG, 13), + + /* This is the server push callback function pointer */ + CINIT(PUSHFUNCTION, FUNCTIONPOINT, 14), + + /* This is the argument passed to the server push callback */ + CINIT(PUSHDATA, OBJECTPOINT, 15), + + CURLMOPT_LASTENTRY /* the last unused */ +} CURLMoption; + + +/* + * Name: curl_multi_setopt() + * + * Desc: Sets options for the multi handle. + * + * Returns: CURLM error code. + */ +CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle, + CURLMoption option, ...); + + +/* + * Name: curl_multi_assign() + * + * Desc: This function sets an association in the multi handle between the + * given socket and a private pointer of the application. This is + * (only) useful for curl_multi_socket uses. + * + * Returns: CURLM error code. + */ +CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle, + curl_socket_t sockfd, void *sockp); + + +/* + * Name: curl_push_callback + * + * Desc: This callback gets called when a new stream is being pushed by the + * server. It approves or denies the new stream. + * + * Returns: CURL_PUSH_OK or CURL_PUSH_DENY. + */ +#define CURL_PUSH_OK 0 +#define CURL_PUSH_DENY 1 + +struct curl_pushheaders; /* forward declaration only */ + +CURL_EXTERN char *curl_pushheader_bynum(struct curl_pushheaders *h, + size_t num); +CURL_EXTERN char *curl_pushheader_byname(struct curl_pushheaders *h, + const char *name); + +typedef int (*curl_push_callback)(CURL *parent, + CURL *easy, + size_t num_headers, + struct curl_pushheaders *headers, + void *userp); + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +#endif diff --git a/OSlibs/ios/include/curl/stdcheaders.h b/OSlibs/ios/include/curl/stdcheaders.h new file mode 100755 index 000000000..6f0f7f343 --- /dev/null +++ b/OSlibs/ios/include/curl/stdcheaders.h @@ -0,0 +1,33 @@ +#ifndef __STDC_HEADERS_H +#define __STDC_HEADERS_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2010, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include + +size_t fread (void *, size_t, size_t, FILE *); +size_t fwrite (const void *, size_t, size_t, FILE *); + +int strcasecmp(const char *, const char *); +int strncasecmp(const char *, const char *, size_t); + +#endif /* __STDC_HEADERS_H */ diff --git a/OSlibs/ios/include/curl/typecheck-gcc.h b/OSlibs/ios/include/curl/typecheck-gcc.h new file mode 100755 index 000000000..6ec8bcfd4 --- /dev/null +++ b/OSlibs/ios/include/curl/typecheck-gcc.h @@ -0,0 +1,622 @@ +#ifndef __CURL_TYPECHECK_GCC_H +#define __CURL_TYPECHECK_GCC_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* wraps curl_easy_setopt() with typechecking */ + +/* To add a new kind of warning, add an + * if(_curl_is_sometype_option(_curl_opt)) + * if(!_curl_is_sometype(value)) + * _curl_easy_setopt_err_sometype(); + * block and define _curl_is_sometype_option, _curl_is_sometype and + * _curl_easy_setopt_err_sometype below + * + * NOTE: We use two nested 'if' statements here instead of the && operator, in + * order to work around gcc bug #32061. It affects only gcc 4.3.x/4.4.x + * when compiling with -Wlogical-op. + * + * To add an option that uses the same type as an existing option, you'll just + * need to extend the appropriate _curl_*_option macro + */ +#define curl_easy_setopt(handle, option, value) \ +__extension__ ({ \ + __typeof__ (option) _curl_opt = option; \ + if(__builtin_constant_p(_curl_opt)) { \ + if(_curl_is_long_option(_curl_opt)) \ + if(!_curl_is_long(value)) \ + _curl_easy_setopt_err_long(); \ + if(_curl_is_off_t_option(_curl_opt)) \ + if(!_curl_is_off_t(value)) \ + _curl_easy_setopt_err_curl_off_t(); \ + if(_curl_is_string_option(_curl_opt)) \ + if(!_curl_is_string(value)) \ + _curl_easy_setopt_err_string(); \ + if(_curl_is_write_cb_option(_curl_opt)) \ + if(!_curl_is_write_cb(value)) \ + _curl_easy_setopt_err_write_callback(); \ + if((_curl_opt) == CURLOPT_READFUNCTION) \ + if(!_curl_is_read_cb(value)) \ + _curl_easy_setopt_err_read_cb(); \ + if((_curl_opt) == CURLOPT_IOCTLFUNCTION) \ + if(!_curl_is_ioctl_cb(value)) \ + _curl_easy_setopt_err_ioctl_cb(); \ + if((_curl_opt) == CURLOPT_SOCKOPTFUNCTION) \ + if(!_curl_is_sockopt_cb(value)) \ + _curl_easy_setopt_err_sockopt_cb(); \ + if((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION) \ + if(!_curl_is_opensocket_cb(value)) \ + _curl_easy_setopt_err_opensocket_cb(); \ + if((_curl_opt) == CURLOPT_PROGRESSFUNCTION) \ + if(!_curl_is_progress_cb(value)) \ + _curl_easy_setopt_err_progress_cb(); \ + if((_curl_opt) == CURLOPT_DEBUGFUNCTION) \ + if(!_curl_is_debug_cb(value)) \ + _curl_easy_setopt_err_debug_cb(); \ + if((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION) \ + if(!_curl_is_ssl_ctx_cb(value)) \ + _curl_easy_setopt_err_ssl_ctx_cb(); \ + if(_curl_is_conv_cb_option(_curl_opt)) \ + if(!_curl_is_conv_cb(value)) \ + _curl_easy_setopt_err_conv_cb(); \ + if((_curl_opt) == CURLOPT_SEEKFUNCTION) \ + if(!_curl_is_seek_cb(value)) \ + _curl_easy_setopt_err_seek_cb(); \ + if(_curl_is_cb_data_option(_curl_opt)) \ + if(!_curl_is_cb_data(value)) \ + _curl_easy_setopt_err_cb_data(); \ + if((_curl_opt) == CURLOPT_ERRORBUFFER) \ + if(!_curl_is_error_buffer(value)) \ + _curl_easy_setopt_err_error_buffer(); \ + if((_curl_opt) == CURLOPT_STDERR) \ + if(!_curl_is_FILE(value)) \ + _curl_easy_setopt_err_FILE(); \ + if(_curl_is_postfields_option(_curl_opt)) \ + if(!_curl_is_postfields(value)) \ + _curl_easy_setopt_err_postfields(); \ + if((_curl_opt) == CURLOPT_HTTPPOST) \ + if(!_curl_is_arr((value), struct curl_httppost)) \ + _curl_easy_setopt_err_curl_httpost(); \ + if(_curl_is_slist_option(_curl_opt)) \ + if(!_curl_is_arr((value), struct curl_slist)) \ + _curl_easy_setopt_err_curl_slist(); \ + if((_curl_opt) == CURLOPT_SHARE) \ + if(!_curl_is_ptr((value), CURLSH)) \ + _curl_easy_setopt_err_CURLSH(); \ + } \ + curl_easy_setopt(handle, _curl_opt, value); \ +}) + +/* wraps curl_easy_getinfo() with typechecking */ +/* FIXME: don't allow const pointers */ +#define curl_easy_getinfo(handle, info, arg) \ +__extension__ ({ \ + __typeof__ (info) _curl_info = info; \ + if(__builtin_constant_p(_curl_info)) { \ + if(_curl_is_string_info(_curl_info)) \ + if(!_curl_is_arr((arg), char *)) \ + _curl_easy_getinfo_err_string(); \ + if(_curl_is_long_info(_curl_info)) \ + if(!_curl_is_arr((arg), long)) \ + _curl_easy_getinfo_err_long(); \ + if(_curl_is_double_info(_curl_info)) \ + if(!_curl_is_arr((arg), double)) \ + _curl_easy_getinfo_err_double(); \ + if(_curl_is_slist_info(_curl_info)) \ + if(!_curl_is_arr((arg), struct curl_slist *)) \ + _curl_easy_getinfo_err_curl_slist(); \ + } \ + curl_easy_getinfo(handle, _curl_info, arg); \ +}) + +/* TODO: typechecking for curl_share_setopt() and curl_multi_setopt(), + * for now just make sure that the functions are called with three + * arguments + */ +#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param) +#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param) + + +/* the actual warnings, triggered by calling the _curl_easy_setopt_err* + * functions */ + +/* To define a new warning, use _CURL_WARNING(identifier, "message") */ +#define _CURL_WARNING(id, message) \ + static void __attribute__((__warning__(message))) \ + __attribute__((__unused__)) __attribute__((__noinline__)) \ + id(void) { __asm__(""); } + +_CURL_WARNING(_curl_easy_setopt_err_long, + "curl_easy_setopt expects a long argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_curl_off_t, + "curl_easy_setopt expects a curl_off_t argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_string, + "curl_easy_setopt expects a " + "string (char* or char[]) argument for this option" + ) +_CURL_WARNING(_curl_easy_setopt_err_write_callback, + "curl_easy_setopt expects a curl_write_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_read_cb, + "curl_easy_setopt expects a curl_read_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_ioctl_cb, + "curl_easy_setopt expects a curl_ioctl_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_sockopt_cb, + "curl_easy_setopt expects a curl_sockopt_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_opensocket_cb, + "curl_easy_setopt expects a " + "curl_opensocket_callback argument for this option" + ) +_CURL_WARNING(_curl_easy_setopt_err_progress_cb, + "curl_easy_setopt expects a curl_progress_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_debug_cb, + "curl_easy_setopt expects a curl_debug_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_ssl_ctx_cb, + "curl_easy_setopt expects a curl_ssl_ctx_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_conv_cb, + "curl_easy_setopt expects a curl_conv_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_seek_cb, + "curl_easy_setopt expects a curl_seek_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_cb_data, + "curl_easy_setopt expects a " + "private data pointer as argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_error_buffer, + "curl_easy_setopt expects a " + "char buffer of CURL_ERROR_SIZE as argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_FILE, + "curl_easy_setopt expects a FILE* argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_postfields, + "curl_easy_setopt expects a void* or char* argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_curl_httpost, + "curl_easy_setopt expects a struct curl_httppost* argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_curl_slist, + "curl_easy_setopt expects a struct curl_slist* argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_CURLSH, + "curl_easy_setopt expects a CURLSH* argument for this option") + +_CURL_WARNING(_curl_easy_getinfo_err_string, + "curl_easy_getinfo expects a pointer to char * for this info") +_CURL_WARNING(_curl_easy_getinfo_err_long, + "curl_easy_getinfo expects a pointer to long for this info") +_CURL_WARNING(_curl_easy_getinfo_err_double, + "curl_easy_getinfo expects a pointer to double for this info") +_CURL_WARNING(_curl_easy_getinfo_err_curl_slist, + "curl_easy_getinfo expects a pointer to struct curl_slist * for this info") + +/* groups of curl_easy_setops options that take the same type of argument */ + +/* To add a new option to one of the groups, just add + * (option) == CURLOPT_SOMETHING + * to the or-expression. If the option takes a long or curl_off_t, you don't + * have to do anything + */ + +/* evaluates to true if option takes a long argument */ +#define _curl_is_long_option(option) \ + (0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT) + +#define _curl_is_off_t_option(option) \ + ((option) > CURLOPTTYPE_OFF_T) + +/* evaluates to true if option takes a char* argument */ +#define _curl_is_string_option(option) \ + ((option) == CURLOPT_ACCEPT_ENCODING || \ + (option) == CURLOPT_CAINFO || \ + (option) == CURLOPT_CAPATH || \ + (option) == CURLOPT_COOKIE || \ + (option) == CURLOPT_COOKIEFILE || \ + (option) == CURLOPT_COOKIEJAR || \ + (option) == CURLOPT_COOKIELIST || \ + (option) == CURLOPT_CRLFILE || \ + (option) == CURLOPT_CUSTOMREQUEST || \ + (option) == CURLOPT_DEFAULT_PROTOCOL || \ + (option) == CURLOPT_DNS_INTERFACE || \ + (option) == CURLOPT_DNS_LOCAL_IP4 || \ + (option) == CURLOPT_DNS_LOCAL_IP6 || \ + (option) == CURLOPT_DNS_SERVERS || \ + (option) == CURLOPT_EGDSOCKET || \ + (option) == CURLOPT_FTPPORT || \ + (option) == CURLOPT_FTP_ACCOUNT || \ + (option) == CURLOPT_FTP_ALTERNATIVE_TO_USER || \ + (option) == CURLOPT_INTERFACE || \ + (option) == CURLOPT_ISSUERCERT || \ + (option) == CURLOPT_KEYPASSWD || \ + (option) == CURLOPT_KRBLEVEL || \ + (option) == CURLOPT_LOGIN_OPTIONS || \ + (option) == CURLOPT_MAIL_AUTH || \ + (option) == CURLOPT_MAIL_FROM || \ + (option) == CURLOPT_NETRC_FILE || \ + (option) == CURLOPT_NOPROXY || \ + (option) == CURLOPT_PASSWORD || \ + (option) == CURLOPT_PINNEDPUBLICKEY || \ + (option) == CURLOPT_PROXY || \ + (option) == CURLOPT_PROXYPASSWORD || \ + (option) == CURLOPT_PROXYUSERNAME || \ + (option) == CURLOPT_PROXYUSERPWD || \ + (option) == CURLOPT_PROXY_SERVICE_NAME || \ + (option) == CURLOPT_RANDOM_FILE || \ + (option) == CURLOPT_RANGE || \ + (option) == CURLOPT_REFERER || \ + (option) == CURLOPT_RTSP_SESSION_ID || \ + (option) == CURLOPT_RTSP_STREAM_URI || \ + (option) == CURLOPT_RTSP_TRANSPORT || \ + (option) == CURLOPT_SERVICE_NAME || \ + (option) == CURLOPT_SOCKS5_GSSAPI_SERVICE || \ + (option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 || \ + (option) == CURLOPT_SSH_KNOWNHOSTS || \ + (option) == CURLOPT_SSH_PRIVATE_KEYFILE || \ + (option) == CURLOPT_SSH_PUBLIC_KEYFILE || \ + (option) == CURLOPT_SSLCERT || \ + (option) == CURLOPT_SSLCERTTYPE || \ + (option) == CURLOPT_SSLENGINE || \ + (option) == CURLOPT_SSLKEY || \ + (option) == CURLOPT_SSLKEYTYPE || \ + (option) == CURLOPT_SSL_CIPHER_LIST || \ + (option) == CURLOPT_TLSAUTH_PASSWORD || \ + (option) == CURLOPT_TLSAUTH_TYPE || \ + (option) == CURLOPT_TLSAUTH_USERNAME || \ + (option) == CURLOPT_UNIX_SOCKET_PATH || \ + (option) == CURLOPT_URL || \ + (option) == CURLOPT_USERAGENT || \ + (option) == CURLOPT_USERNAME || \ + (option) == CURLOPT_USERPWD || \ + (option) == CURLOPT_XOAUTH2_BEARER || \ + 0) + +/* evaluates to true if option takes a curl_write_callback argument */ +#define _curl_is_write_cb_option(option) \ + ((option) == CURLOPT_HEADERFUNCTION || \ + (option) == CURLOPT_WRITEFUNCTION) + +/* evaluates to true if option takes a curl_conv_callback argument */ +#define _curl_is_conv_cb_option(option) \ + ((option) == CURLOPT_CONV_TO_NETWORK_FUNCTION || \ + (option) == CURLOPT_CONV_FROM_NETWORK_FUNCTION || \ + (option) == CURLOPT_CONV_FROM_UTF8_FUNCTION) + +/* evaluates to true if option takes a data argument to pass to a callback */ +#define _curl_is_cb_data_option(option) \ + ((option) == CURLOPT_CHUNK_DATA || \ + (option) == CURLOPT_CLOSESOCKETDATA || \ + (option) == CURLOPT_DEBUGDATA || \ + (option) == CURLOPT_FNMATCH_DATA || \ + (option) == CURLOPT_HEADERDATA || \ + (option) == CURLOPT_INTERLEAVEDATA || \ + (option) == CURLOPT_IOCTLDATA || \ + (option) == CURLOPT_OPENSOCKETDATA || \ + (option) == CURLOPT_PRIVATE || \ + (option) == CURLOPT_PROGRESSDATA || \ + (option) == CURLOPT_READDATA || \ + (option) == CURLOPT_SEEKDATA || \ + (option) == CURLOPT_SOCKOPTDATA || \ + (option) == CURLOPT_SSH_KEYDATA || \ + (option) == CURLOPT_SSL_CTX_DATA || \ + (option) == CURLOPT_WRITEDATA || \ + 0) + +/* evaluates to true if option takes a POST data argument (void* or char*) */ +#define _curl_is_postfields_option(option) \ + ((option) == CURLOPT_POSTFIELDS || \ + (option) == CURLOPT_COPYPOSTFIELDS || \ + 0) + +/* evaluates to true if option takes a struct curl_slist * argument */ +#define _curl_is_slist_option(option) \ + ((option) == CURLOPT_HTTP200ALIASES || \ + (option) == CURLOPT_HTTPHEADER || \ + (option) == CURLOPT_MAIL_RCPT || \ + (option) == CURLOPT_POSTQUOTE || \ + (option) == CURLOPT_PREQUOTE || \ + (option) == CURLOPT_PROXYHEADER || \ + (option) == CURLOPT_QUOTE || \ + (option) == CURLOPT_RESOLVE || \ + (option) == CURLOPT_TELNETOPTIONS || \ + 0) + +/* groups of curl_easy_getinfo infos that take the same type of argument */ + +/* evaluates to true if info expects a pointer to char * argument */ +#define _curl_is_string_info(info) \ + (CURLINFO_STRING < (info) && (info) < CURLINFO_LONG) + +/* evaluates to true if info expects a pointer to long argument */ +#define _curl_is_long_info(info) \ + (CURLINFO_LONG < (info) && (info) < CURLINFO_DOUBLE) + +/* evaluates to true if info expects a pointer to double argument */ +#define _curl_is_double_info(info) \ + (CURLINFO_DOUBLE < (info) && (info) < CURLINFO_SLIST) + +/* true if info expects a pointer to struct curl_slist * argument */ +#define _curl_is_slist_info(info) \ + (CURLINFO_SLIST < (info)) + + +/* typecheck helpers -- check whether given expression has requested type*/ + +/* For pointers, you can use the _curl_is_ptr/_curl_is_arr macros, + * otherwise define a new macro. Search for __builtin_types_compatible_p + * in the GCC manual. + * NOTE: these macros MUST NOT EVALUATE their arguments! The argument is + * the actual expression passed to the curl_easy_setopt macro. This + * means that you can only apply the sizeof and __typeof__ operators, no + * == or whatsoever. + */ + +/* XXX: should evaluate to true iff expr is a pointer */ +#define _curl_is_any_ptr(expr) \ + (sizeof(expr) == sizeof(void*)) + +/* evaluates to true if expr is NULL */ +/* XXX: must not evaluate expr, so this check is not accurate */ +#define _curl_is_NULL(expr) \ + (__builtin_types_compatible_p(__typeof__(expr), __typeof__(NULL))) + +/* evaluates to true if expr is type*, const type* or NULL */ +#define _curl_is_ptr(expr, type) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), type *) || \ + __builtin_types_compatible_p(__typeof__(expr), const type *)) + +/* evaluates to true if expr is one of type[], type*, NULL or const type* */ +#define _curl_is_arr(expr, type) \ + (_curl_is_ptr((expr), type) || \ + __builtin_types_compatible_p(__typeof__(expr), type [])) + +/* evaluates to true if expr is a string */ +#define _curl_is_string(expr) \ + (_curl_is_arr((expr), char) || \ + _curl_is_arr((expr), signed char) || \ + _curl_is_arr((expr), unsigned char)) + +/* evaluates to true if expr is a long (no matter the signedness) + * XXX: for now, int is also accepted (and therefore short and char, which + * are promoted to int when passed to a variadic function) */ +#define _curl_is_long(expr) \ + (__builtin_types_compatible_p(__typeof__(expr), long) || \ + __builtin_types_compatible_p(__typeof__(expr), signed long) || \ + __builtin_types_compatible_p(__typeof__(expr), unsigned long) || \ + __builtin_types_compatible_p(__typeof__(expr), int) || \ + __builtin_types_compatible_p(__typeof__(expr), signed int) || \ + __builtin_types_compatible_p(__typeof__(expr), unsigned int) || \ + __builtin_types_compatible_p(__typeof__(expr), short) || \ + __builtin_types_compatible_p(__typeof__(expr), signed short) || \ + __builtin_types_compatible_p(__typeof__(expr), unsigned short) || \ + __builtin_types_compatible_p(__typeof__(expr), char) || \ + __builtin_types_compatible_p(__typeof__(expr), signed char) || \ + __builtin_types_compatible_p(__typeof__(expr), unsigned char)) + +/* evaluates to true if expr is of type curl_off_t */ +#define _curl_is_off_t(expr) \ + (__builtin_types_compatible_p(__typeof__(expr), curl_off_t)) + +/* evaluates to true if expr is abuffer suitable for CURLOPT_ERRORBUFFER */ +/* XXX: also check size of an char[] array? */ +#define _curl_is_error_buffer(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), char *) || \ + __builtin_types_compatible_p(__typeof__(expr), char[])) + +/* evaluates to true if expr is of type (const) void* or (const) FILE* */ +#if 0 +#define _curl_is_cb_data(expr) \ + (_curl_is_ptr((expr), void) || \ + _curl_is_ptr((expr), FILE)) +#else /* be less strict */ +#define _curl_is_cb_data(expr) \ + _curl_is_any_ptr(expr) +#endif + +/* evaluates to true if expr is of type FILE* */ +#define _curl_is_FILE(expr) \ + (__builtin_types_compatible_p(__typeof__(expr), FILE *)) + +/* evaluates to true if expr can be passed as POST data (void* or char*) */ +#define _curl_is_postfields(expr) \ + (_curl_is_ptr((expr), void) || \ + _curl_is_arr((expr), char)) + +/* FIXME: the whole callback checking is messy... + * The idea is to tolerate char vs. void and const vs. not const + * pointers in arguments at least + */ +/* helper: __builtin_types_compatible_p distinguishes between functions and + * function pointers, hide it */ +#define _curl_callback_compatible(func, type) \ + (__builtin_types_compatible_p(__typeof__(func), type) || \ + __builtin_types_compatible_p(__typeof__(func), type*)) + +/* evaluates to true if expr is of type curl_read_callback or "similar" */ +#define _curl_is_read_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), __typeof__(fread)) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_read_callback) || \ + _curl_callback_compatible((expr), _curl_read_callback1) || \ + _curl_callback_compatible((expr), _curl_read_callback2) || \ + _curl_callback_compatible((expr), _curl_read_callback3) || \ + _curl_callback_compatible((expr), _curl_read_callback4) || \ + _curl_callback_compatible((expr), _curl_read_callback5) || \ + _curl_callback_compatible((expr), _curl_read_callback6)) +typedef size_t (_curl_read_callback1)(char *, size_t, size_t, void*); +typedef size_t (_curl_read_callback2)(char *, size_t, size_t, const void*); +typedef size_t (_curl_read_callback3)(char *, size_t, size_t, FILE*); +typedef size_t (_curl_read_callback4)(void *, size_t, size_t, void*); +typedef size_t (_curl_read_callback5)(void *, size_t, size_t, const void*); +typedef size_t (_curl_read_callback6)(void *, size_t, size_t, FILE*); + +/* evaluates to true if expr is of type curl_write_callback or "similar" */ +#define _curl_is_write_cb(expr) \ + (_curl_is_read_cb(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), __typeof__(fwrite)) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_write_callback) || \ + _curl_callback_compatible((expr), _curl_write_callback1) || \ + _curl_callback_compatible((expr), _curl_write_callback2) || \ + _curl_callback_compatible((expr), _curl_write_callback3) || \ + _curl_callback_compatible((expr), _curl_write_callback4) || \ + _curl_callback_compatible((expr), _curl_write_callback5) || \ + _curl_callback_compatible((expr), _curl_write_callback6)) +typedef size_t (_curl_write_callback1)(const char *, size_t, size_t, void*); +typedef size_t (_curl_write_callback2)(const char *, size_t, size_t, + const void*); +typedef size_t (_curl_write_callback3)(const char *, size_t, size_t, FILE*); +typedef size_t (_curl_write_callback4)(const void *, size_t, size_t, void*); +typedef size_t (_curl_write_callback5)(const void *, size_t, size_t, + const void*); +typedef size_t (_curl_write_callback6)(const void *, size_t, size_t, FILE*); + +/* evaluates to true if expr is of type curl_ioctl_callback or "similar" */ +#define _curl_is_ioctl_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_ioctl_callback) || \ + _curl_callback_compatible((expr), _curl_ioctl_callback1) || \ + _curl_callback_compatible((expr), _curl_ioctl_callback2) || \ + _curl_callback_compatible((expr), _curl_ioctl_callback3) || \ + _curl_callback_compatible((expr), _curl_ioctl_callback4)) +typedef curlioerr (_curl_ioctl_callback1)(CURL *, int, void*); +typedef curlioerr (_curl_ioctl_callback2)(CURL *, int, const void*); +typedef curlioerr (_curl_ioctl_callback3)(CURL *, curliocmd, void*); +typedef curlioerr (_curl_ioctl_callback4)(CURL *, curliocmd, const void*); + +/* evaluates to true if expr is of type curl_sockopt_callback or "similar" */ +#define _curl_is_sockopt_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_sockopt_callback) || \ + _curl_callback_compatible((expr), _curl_sockopt_callback1) || \ + _curl_callback_compatible((expr), _curl_sockopt_callback2)) +typedef int (_curl_sockopt_callback1)(void *, curl_socket_t, curlsocktype); +typedef int (_curl_sockopt_callback2)(const void *, curl_socket_t, + curlsocktype); + +/* evaluates to true if expr is of type curl_opensocket_callback or + "similar" */ +#define _curl_is_opensocket_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_opensocket_callback) ||\ + _curl_callback_compatible((expr), _curl_opensocket_callback1) || \ + _curl_callback_compatible((expr), _curl_opensocket_callback2) || \ + _curl_callback_compatible((expr), _curl_opensocket_callback3) || \ + _curl_callback_compatible((expr), _curl_opensocket_callback4)) +typedef curl_socket_t (_curl_opensocket_callback1) + (void *, curlsocktype, struct curl_sockaddr *); +typedef curl_socket_t (_curl_opensocket_callback2) + (void *, curlsocktype, const struct curl_sockaddr *); +typedef curl_socket_t (_curl_opensocket_callback3) + (const void *, curlsocktype, struct curl_sockaddr *); +typedef curl_socket_t (_curl_opensocket_callback4) + (const void *, curlsocktype, const struct curl_sockaddr *); + +/* evaluates to true if expr is of type curl_progress_callback or "similar" */ +#define _curl_is_progress_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_progress_callback) || \ + _curl_callback_compatible((expr), _curl_progress_callback1) || \ + _curl_callback_compatible((expr), _curl_progress_callback2)) +typedef int (_curl_progress_callback1)(void *, + double, double, double, double); +typedef int (_curl_progress_callback2)(const void *, + double, double, double, double); + +/* evaluates to true if expr is of type curl_debug_callback or "similar" */ +#define _curl_is_debug_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_debug_callback) || \ + _curl_callback_compatible((expr), _curl_debug_callback1) || \ + _curl_callback_compatible((expr), _curl_debug_callback2) || \ + _curl_callback_compatible((expr), _curl_debug_callback3) || \ + _curl_callback_compatible((expr), _curl_debug_callback4) || \ + _curl_callback_compatible((expr), _curl_debug_callback5) || \ + _curl_callback_compatible((expr), _curl_debug_callback6) || \ + _curl_callback_compatible((expr), _curl_debug_callback7) || \ + _curl_callback_compatible((expr), _curl_debug_callback8)) +typedef int (_curl_debug_callback1) (CURL *, + curl_infotype, char *, size_t, void *); +typedef int (_curl_debug_callback2) (CURL *, + curl_infotype, char *, size_t, const void *); +typedef int (_curl_debug_callback3) (CURL *, + curl_infotype, const char *, size_t, void *); +typedef int (_curl_debug_callback4) (CURL *, + curl_infotype, const char *, size_t, const void *); +typedef int (_curl_debug_callback5) (CURL *, + curl_infotype, unsigned char *, size_t, void *); +typedef int (_curl_debug_callback6) (CURL *, + curl_infotype, unsigned char *, size_t, const void *); +typedef int (_curl_debug_callback7) (CURL *, + curl_infotype, const unsigned char *, size_t, void *); +typedef int (_curl_debug_callback8) (CURL *, + curl_infotype, const unsigned char *, size_t, const void *); + +/* evaluates to true if expr is of type curl_ssl_ctx_callback or "similar" */ +/* this is getting even messier... */ +#define _curl_is_ssl_ctx_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_ssl_ctx_callback) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback1) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback2) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback3) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback4) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback5) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback6) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback7) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback8)) +typedef CURLcode (_curl_ssl_ctx_callback1)(CURL *, void *, void *); +typedef CURLcode (_curl_ssl_ctx_callback2)(CURL *, void *, const void *); +typedef CURLcode (_curl_ssl_ctx_callback3)(CURL *, const void *, void *); +typedef CURLcode (_curl_ssl_ctx_callback4)(CURL *, const void *, const void *); +#ifdef HEADER_SSL_H +/* hack: if we included OpenSSL's ssl.h, we know about SSL_CTX + * this will of course break if we're included before OpenSSL headers... + */ +typedef CURLcode (_curl_ssl_ctx_callback5)(CURL *, SSL_CTX, void *); +typedef CURLcode (_curl_ssl_ctx_callback6)(CURL *, SSL_CTX, const void *); +typedef CURLcode (_curl_ssl_ctx_callback7)(CURL *, const SSL_CTX, void *); +typedef CURLcode (_curl_ssl_ctx_callback8)(CURL *, const SSL_CTX, + const void *); +#else +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback5; +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback6; +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback7; +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback8; +#endif + +/* evaluates to true if expr is of type curl_conv_callback or "similar" */ +#define _curl_is_conv_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_conv_callback) || \ + _curl_callback_compatible((expr), _curl_conv_callback1) || \ + _curl_callback_compatible((expr), _curl_conv_callback2) || \ + _curl_callback_compatible((expr), _curl_conv_callback3) || \ + _curl_callback_compatible((expr), _curl_conv_callback4)) +typedef CURLcode (*_curl_conv_callback1)(char *, size_t length); +typedef CURLcode (*_curl_conv_callback2)(const char *, size_t length); +typedef CURLcode (*_curl_conv_callback3)(void *, size_t length); +typedef CURLcode (*_curl_conv_callback4)(const void *, size_t length); + +/* evaluates to true if expr is of type curl_seek_callback or "similar" */ +#define _curl_is_seek_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_seek_callback) || \ + _curl_callback_compatible((expr), _curl_seek_callback1) || \ + _curl_callback_compatible((expr), _curl_seek_callback2)) +typedef CURLcode (*_curl_seek_callback1)(void *, curl_off_t, int); +typedef CURLcode (*_curl_seek_callback2)(const void *, curl_off_t, int); + + +#endif /* __CURL_TYPECHECK_GCC_H */ diff --git a/OSlibs/ios/include/openssl/aes.h b/OSlibs/ios/include/openssl/aes.h new file mode 100755 index 000000000..faa66c491 --- /dev/null +++ b/OSlibs/ios/include/openssl/aes.h @@ -0,0 +1,149 @@ +/* crypto/aes/aes.h */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#ifndef HEADER_AES_H +# define HEADER_AES_H + +# include + +# ifdef OPENSSL_NO_AES +# error AES is disabled. +# endif + +# include + +# define AES_ENCRYPT 1 +# define AES_DECRYPT 0 + +/* + * Because array size can't be a const in C, the following two are macros. + * Both sizes are in bytes. + */ +# define AES_MAXNR 14 +# define AES_BLOCK_SIZE 16 + +#ifdef __cplusplus +extern "C" { +#endif + +/* This should be a hidden type, but EVP requires that the size be known */ +struct aes_key_st { +# ifdef AES_LONG + unsigned long rd_key[4 * (AES_MAXNR + 1)]; +# else + unsigned int rd_key[4 * (AES_MAXNR + 1)]; +# endif + int rounds; +}; +typedef struct aes_key_st AES_KEY; + +const char *AES_options(void); + +int AES_set_encrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key); +int AES_set_decrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key); + +int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key); +int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key); + +void AES_encrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); +void AES_decrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); + +void AES_ecb_encrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key, const int enc); +void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, const int enc); +void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, int *num, const int enc); +void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, int *num, const int enc); +void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, int *num, const int enc); +void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, int *num); +void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char ivec[AES_BLOCK_SIZE], + unsigned char ecount_buf[AES_BLOCK_SIZE], + unsigned int *num); +/* NB: the IV is _two_ blocks long */ +void AES_ige_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, const int enc); +/* NB: the IV is _four_ blocks long */ +void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + const AES_KEY *key2, const unsigned char *ivec, + const int enc); + +int AES_wrap_key(AES_KEY *key, const unsigned char *iv, + unsigned char *out, + const unsigned char *in, unsigned int inlen); +int AES_unwrap_key(AES_KEY *key, const unsigned char *iv, + unsigned char *out, + const unsigned char *in, unsigned int inlen); + + +#ifdef __cplusplus +} +#endif + +#endif /* !HEADER_AES_H */ diff --git a/OSlibs/ios/include/openssl/asn1.h b/OSlibs/ios/include/openssl/asn1.h new file mode 100755 index 000000000..68e791fcd --- /dev/null +++ b/OSlibs/ios/include/openssl/asn1.h @@ -0,0 +1,1419 @@ +/* crypto/asn1/asn1.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_ASN1_H +# define HEADER_ASN1_H + +# include +# include +# ifndef OPENSSL_NO_BIO +# include +# endif +# include +# include + +# include + +# include +# ifndef OPENSSL_NO_DEPRECATED +# include +# endif + +# ifdef OPENSSL_BUILD_SHLIBCRYPTO +# undef OPENSSL_EXTERN +# define OPENSSL_EXTERN OPENSSL_EXPORT +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +# define V_ASN1_UNIVERSAL 0x00 +# define V_ASN1_APPLICATION 0x40 +# define V_ASN1_CONTEXT_SPECIFIC 0x80 +# define V_ASN1_PRIVATE 0xc0 + +# define V_ASN1_CONSTRUCTED 0x20 +# define V_ASN1_PRIMITIVE_TAG 0x1f +# define V_ASN1_PRIMATIVE_TAG 0x1f + +# define V_ASN1_APP_CHOOSE -2/* let the recipient choose */ +# define V_ASN1_OTHER -3/* used in ASN1_TYPE */ +# define V_ASN1_ANY -4/* used in ASN1 template code */ + +# define V_ASN1_NEG 0x100/* negative flag */ + +# define V_ASN1_UNDEF -1 +# define V_ASN1_EOC 0 +# define V_ASN1_BOOLEAN 1 /**/ +# define V_ASN1_INTEGER 2 +# define V_ASN1_NEG_INTEGER (2 | V_ASN1_NEG) +# define V_ASN1_BIT_STRING 3 +# define V_ASN1_OCTET_STRING 4 +# define V_ASN1_NULL 5 +# define V_ASN1_OBJECT 6 +# define V_ASN1_OBJECT_DESCRIPTOR 7 +# define V_ASN1_EXTERNAL 8 +# define V_ASN1_REAL 9 +# define V_ASN1_ENUMERATED 10 +# define V_ASN1_NEG_ENUMERATED (10 | V_ASN1_NEG) +# define V_ASN1_UTF8STRING 12 +# define V_ASN1_SEQUENCE 16 +# define V_ASN1_SET 17 +# define V_ASN1_NUMERICSTRING 18 /**/ +# define V_ASN1_PRINTABLESTRING 19 +# define V_ASN1_T61STRING 20 +# define V_ASN1_TELETEXSTRING 20/* alias */ +# define V_ASN1_VIDEOTEXSTRING 21 /**/ +# define V_ASN1_IA5STRING 22 +# define V_ASN1_UTCTIME 23 +# define V_ASN1_GENERALIZEDTIME 24 /**/ +# define V_ASN1_GRAPHICSTRING 25 /**/ +# define V_ASN1_ISO64STRING 26 /**/ +# define V_ASN1_VISIBLESTRING 26/* alias */ +# define V_ASN1_GENERALSTRING 27 /**/ +# define V_ASN1_UNIVERSALSTRING 28 /**/ +# define V_ASN1_BMPSTRING 30 +/* For use with d2i_ASN1_type_bytes() */ +# define B_ASN1_NUMERICSTRING 0x0001 +# define B_ASN1_PRINTABLESTRING 0x0002 +# define B_ASN1_T61STRING 0x0004 +# define B_ASN1_TELETEXSTRING 0x0004 +# define B_ASN1_VIDEOTEXSTRING 0x0008 +# define B_ASN1_IA5STRING 0x0010 +# define B_ASN1_GRAPHICSTRING 0x0020 +# define B_ASN1_ISO64STRING 0x0040 +# define B_ASN1_VISIBLESTRING 0x0040 +# define B_ASN1_GENERALSTRING 0x0080 +# define B_ASN1_UNIVERSALSTRING 0x0100 +# define B_ASN1_OCTET_STRING 0x0200 +# define B_ASN1_BIT_STRING 0x0400 +# define B_ASN1_BMPSTRING 0x0800 +# define B_ASN1_UNKNOWN 0x1000 +# define B_ASN1_UTF8STRING 0x2000 +# define B_ASN1_UTCTIME 0x4000 +# define B_ASN1_GENERALIZEDTIME 0x8000 +# define B_ASN1_SEQUENCE 0x10000 +/* For use with ASN1_mbstring_copy() */ +# define MBSTRING_FLAG 0x1000 +# define MBSTRING_UTF8 (MBSTRING_FLAG) +# define MBSTRING_ASC (MBSTRING_FLAG|1) +# define MBSTRING_BMP (MBSTRING_FLAG|2) +# define MBSTRING_UNIV (MBSTRING_FLAG|4) +# define SMIME_OLDMIME 0x400 +# define SMIME_CRLFEOL 0x800 +# define SMIME_STREAM 0x1000 + struct X509_algor_st; +DECLARE_STACK_OF(X509_ALGOR) + +# define DECLARE_ASN1_SET_OF(type)/* filled in by mkstack.pl */ +# define IMPLEMENT_ASN1_SET_OF(type)/* nothing, no longer needed */ + +/* + * We MUST make sure that, except for constness, asn1_ctx_st and + * asn1_const_ctx are exactly the same. Fortunately, as soon as the old ASN1 + * parsing macros are gone, we can throw this away as well... + */ +typedef struct asn1_ctx_st { + unsigned char *p; /* work char pointer */ + int eos; /* end of sequence read for indefinite + * encoding */ + int error; /* error code to use when returning an error */ + int inf; /* constructed if 0x20, indefinite is 0x21 */ + int tag; /* tag from last 'get object' */ + int xclass; /* class from last 'get object' */ + long slen; /* length of last 'get object' */ + unsigned char *max; /* largest value of p allowed */ + unsigned char *q; /* temporary variable */ + unsigned char **pp; /* variable */ + int line; /* used in error processing */ +} ASN1_CTX; + +typedef struct asn1_const_ctx_st { + const unsigned char *p; /* work char pointer */ + int eos; /* end of sequence read for indefinite + * encoding */ + int error; /* error code to use when returning an error */ + int inf; /* constructed if 0x20, indefinite is 0x21 */ + int tag; /* tag from last 'get object' */ + int xclass; /* class from last 'get object' */ + long slen; /* length of last 'get object' */ + const unsigned char *max; /* largest value of p allowed */ + const unsigned char *q; /* temporary variable */ + const unsigned char **pp; /* variable */ + int line; /* used in error processing */ +} ASN1_const_CTX; + +/* + * These are used internally in the ASN1_OBJECT to keep track of whether the + * names and data need to be free()ed + */ +# define ASN1_OBJECT_FLAG_DYNAMIC 0x01/* internal use */ +# define ASN1_OBJECT_FLAG_CRITICAL 0x02/* critical x509v3 object id */ +# define ASN1_OBJECT_FLAG_DYNAMIC_STRINGS 0x04/* internal use */ +# define ASN1_OBJECT_FLAG_DYNAMIC_DATA 0x08/* internal use */ +struct asn1_object_st { + const char *sn, *ln; + int nid; + int length; + const unsigned char *data; /* data remains const after init */ + int flags; /* Should we free this one */ +}; + +# define ASN1_STRING_FLAG_BITS_LEFT 0x08/* Set if 0x07 has bits left value */ +/* + * This indicates that the ASN1_STRING is not a real value but just a place + * holder for the location where indefinite length constructed data should be + * inserted in the memory buffer + */ +# define ASN1_STRING_FLAG_NDEF 0x010 + +/* + * This flag is used by the CMS code to indicate that a string is not + * complete and is a place holder for content when it had all been accessed. + * The flag will be reset when content has been written to it. + */ + +# define ASN1_STRING_FLAG_CONT 0x020 +/* + * This flag is used by ASN1 code to indicate an ASN1_STRING is an MSTRING + * type. + */ +# define ASN1_STRING_FLAG_MSTRING 0x040 +/* This is the base type that holds just about everything :-) */ +struct asn1_string_st { + int length; + int type; + unsigned char *data; + /* + * The value of the following field depends on the type being held. It + * is mostly being used for BIT_STRING so if the input data has a + * non-zero 'unused bits' value, it will be handled correctly + */ + long flags; +}; + +/* + * ASN1_ENCODING structure: this is used to save the received encoding of an + * ASN1 type. This is useful to get round problems with invalid encodings + * which can break signatures. + */ + +typedef struct ASN1_ENCODING_st { + unsigned char *enc; /* DER encoding */ + long len; /* Length of encoding */ + int modified; /* set to 1 if 'enc' is invalid */ +} ASN1_ENCODING; + +/* Used with ASN1 LONG type: if a long is set to this it is omitted */ +# define ASN1_LONG_UNDEF 0x7fffffffL + +# define STABLE_FLAGS_MALLOC 0x01 +# define STABLE_NO_MASK 0x02 +# define DIRSTRING_TYPE \ + (B_ASN1_PRINTABLESTRING|B_ASN1_T61STRING|B_ASN1_BMPSTRING|B_ASN1_UTF8STRING) +# define PKCS9STRING_TYPE (DIRSTRING_TYPE|B_ASN1_IA5STRING) + +typedef struct asn1_string_table_st { + int nid; + long minsize; + long maxsize; + unsigned long mask; + unsigned long flags; +} ASN1_STRING_TABLE; + +DECLARE_STACK_OF(ASN1_STRING_TABLE) + +/* size limits: this stuff is taken straight from RFC2459 */ + +# define ub_name 32768 +# define ub_common_name 64 +# define ub_locality_name 128 +# define ub_state_name 128 +# define ub_organization_name 64 +# define ub_organization_unit_name 64 +# define ub_title 64 +# define ub_email_address 128 + +/* + * Declarations for template structures: for full definitions see asn1t.h + */ +typedef struct ASN1_TEMPLATE_st ASN1_TEMPLATE; +typedef struct ASN1_TLC_st ASN1_TLC; +/* This is just an opaque pointer */ +typedef struct ASN1_VALUE_st ASN1_VALUE; + +/* Declare ASN1 functions: the implement macro in in asn1t.h */ + +# define DECLARE_ASN1_FUNCTIONS(type) DECLARE_ASN1_FUNCTIONS_name(type, type) + +# define DECLARE_ASN1_ALLOC_FUNCTIONS(type) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, type) + +# define DECLARE_ASN1_FUNCTIONS_name(type, name) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name) + +# define DECLARE_ASN1_FUNCTIONS_fname(type, itname, name) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) + +# define DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) \ + type *d2i_##name(type **a, const unsigned char **in, long len); \ + int i2d_##name(type *a, unsigned char **out); \ + DECLARE_ASN1_ITEM(itname) + +# define DECLARE_ASN1_ENCODE_FUNCTIONS_const(type, name) \ + type *d2i_##name(type **a, const unsigned char **in, long len); \ + int i2d_##name(const type *a, unsigned char **out); \ + DECLARE_ASN1_ITEM(name) + +# define DECLARE_ASN1_NDEF_FUNCTION(name) \ + int i2d_##name##_NDEF(name *a, unsigned char **out); + +# define DECLARE_ASN1_FUNCTIONS_const(name) \ + DECLARE_ASN1_ALLOC_FUNCTIONS(name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS_const(name, name) + +# define DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ + type *name##_new(void); \ + void name##_free(type *a); + +# define DECLARE_ASN1_PRINT_FUNCTION(stname) \ + DECLARE_ASN1_PRINT_FUNCTION_fname(stname, stname) + +# define DECLARE_ASN1_PRINT_FUNCTION_fname(stname, fname) \ + int fname##_print_ctx(BIO *out, stname *x, int indent, \ + const ASN1_PCTX *pctx); + +# define D2I_OF(type) type *(*)(type **,const unsigned char **,long) +# define I2D_OF(type) int (*)(type *,unsigned char **) +# define I2D_OF_const(type) int (*)(const type *,unsigned char **) + +# define CHECKED_D2I_OF(type, d2i) \ + ((d2i_of_void*) (1 ? d2i : ((D2I_OF(type))0))) +# define CHECKED_I2D_OF(type, i2d) \ + ((i2d_of_void*) (1 ? i2d : ((I2D_OF(type))0))) +# define CHECKED_NEW_OF(type, xnew) \ + ((void *(*)(void)) (1 ? xnew : ((type *(*)(void))0))) +# define CHECKED_PTR_OF(type, p) \ + ((void*) (1 ? p : (type*)0)) +# define CHECKED_PPTR_OF(type, p) \ + ((void**) (1 ? p : (type**)0)) + +# define TYPEDEF_D2I_OF(type) typedef type *d2i_of_##type(type **,const unsigned char **,long) +# define TYPEDEF_I2D_OF(type) typedef int i2d_of_##type(type *,unsigned char **) +# define TYPEDEF_D2I2D_OF(type) TYPEDEF_D2I_OF(type); TYPEDEF_I2D_OF(type) + +TYPEDEF_D2I2D_OF(void); + +/*- + * The following macros and typedefs allow an ASN1_ITEM + * to be embedded in a structure and referenced. Since + * the ASN1_ITEM pointers need to be globally accessible + * (possibly from shared libraries) they may exist in + * different forms. On platforms that support it the + * ASN1_ITEM structure itself will be globally exported. + * Other platforms will export a function that returns + * an ASN1_ITEM pointer. + * + * To handle both cases transparently the macros below + * should be used instead of hard coding an ASN1_ITEM + * pointer in a structure. + * + * The structure will look like this: + * + * typedef struct SOMETHING_st { + * ... + * ASN1_ITEM_EXP *iptr; + * ... + * } SOMETHING; + * + * It would be initialised as e.g.: + * + * SOMETHING somevar = {...,ASN1_ITEM_ref(X509),...}; + * + * and the actual pointer extracted with: + * + * const ASN1_ITEM *it = ASN1_ITEM_ptr(somevar.iptr); + * + * Finally an ASN1_ITEM pointer can be extracted from an + * appropriate reference with: ASN1_ITEM_rptr(X509). This + * would be used when a function takes an ASN1_ITEM * argument. + * + */ + +# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION + +/* ASN1_ITEM pointer exported type */ +typedef const ASN1_ITEM ASN1_ITEM_EXP; + +/* Macro to obtain ASN1_ITEM pointer from exported type */ +# define ASN1_ITEM_ptr(iptr) (iptr) + +/* Macro to include ASN1_ITEM pointer from base type */ +# define ASN1_ITEM_ref(iptr) (&(iptr##_it)) + +# define ASN1_ITEM_rptr(ref) (&(ref##_it)) + +# define DECLARE_ASN1_ITEM(name) \ + OPENSSL_EXTERN const ASN1_ITEM name##_it; + +# else + +/* + * Platforms that can't easily handle shared global variables are declared as + * functions returning ASN1_ITEM pointers. + */ + +/* ASN1_ITEM pointer exported type */ +typedef const ASN1_ITEM *ASN1_ITEM_EXP (void); + +/* Macro to obtain ASN1_ITEM pointer from exported type */ +# define ASN1_ITEM_ptr(iptr) (iptr()) + +/* Macro to include ASN1_ITEM pointer from base type */ +# define ASN1_ITEM_ref(iptr) (iptr##_it) + +# define ASN1_ITEM_rptr(ref) (ref##_it()) + +# define DECLARE_ASN1_ITEM(name) \ + const ASN1_ITEM * name##_it(void); + +# endif + +/* Parameters used by ASN1_STRING_print_ex() */ + +/* + * These determine which characters to escape: RFC2253 special characters, + * control characters and MSB set characters + */ + +# define ASN1_STRFLGS_ESC_2253 1 +# define ASN1_STRFLGS_ESC_CTRL 2 +# define ASN1_STRFLGS_ESC_MSB 4 + +/* + * This flag determines how we do escaping: normally RC2253 backslash only, + * set this to use backslash and quote. + */ + +# define ASN1_STRFLGS_ESC_QUOTE 8 + +/* These three flags are internal use only. */ + +/* Character is a valid PrintableString character */ +# define CHARTYPE_PRINTABLESTRING 0x10 +/* Character needs escaping if it is the first character */ +# define CHARTYPE_FIRST_ESC_2253 0x20 +/* Character needs escaping if it is the last character */ +# define CHARTYPE_LAST_ESC_2253 0x40 + +/* + * NB the internal flags are safely reused below by flags handled at the top + * level. + */ + +/* + * If this is set we convert all character strings to UTF8 first + */ + +# define ASN1_STRFLGS_UTF8_CONVERT 0x10 + +/* + * If this is set we don't attempt to interpret content: just assume all + * strings are 1 byte per character. This will produce some pretty odd + * looking output! + */ + +# define ASN1_STRFLGS_IGNORE_TYPE 0x20 + +/* If this is set we include the string type in the output */ +# define ASN1_STRFLGS_SHOW_TYPE 0x40 + +/* + * This determines which strings to display and which to 'dump' (hex dump of + * content octets or DER encoding). We can only dump non character strings or + * everything. If we don't dump 'unknown' they are interpreted as character + * strings with 1 octet per character and are subject to the usual escaping + * options. + */ + +# define ASN1_STRFLGS_DUMP_ALL 0x80 +# define ASN1_STRFLGS_DUMP_UNKNOWN 0x100 + +/* + * These determine what 'dumping' does, we can dump the content octets or the + * DER encoding: both use the RFC2253 #XXXXX notation. + */ + +# define ASN1_STRFLGS_DUMP_DER 0x200 + +/* + * All the string flags consistent with RFC2253, escaping control characters + * isn't essential in RFC2253 but it is advisable anyway. + */ + +# define ASN1_STRFLGS_RFC2253 (ASN1_STRFLGS_ESC_2253 | \ + ASN1_STRFLGS_ESC_CTRL | \ + ASN1_STRFLGS_ESC_MSB | \ + ASN1_STRFLGS_UTF8_CONVERT | \ + ASN1_STRFLGS_DUMP_UNKNOWN | \ + ASN1_STRFLGS_DUMP_DER) + +DECLARE_STACK_OF(ASN1_INTEGER) +DECLARE_ASN1_SET_OF(ASN1_INTEGER) + +DECLARE_STACK_OF(ASN1_GENERALSTRING) + +typedef struct asn1_type_st { + int type; + union { + char *ptr; + ASN1_BOOLEAN boolean; + ASN1_STRING *asn1_string; + ASN1_OBJECT *object; + ASN1_INTEGER *integer; + ASN1_ENUMERATED *enumerated; + ASN1_BIT_STRING *bit_string; + ASN1_OCTET_STRING *octet_string; + ASN1_PRINTABLESTRING *printablestring; + ASN1_T61STRING *t61string; + ASN1_IA5STRING *ia5string; + ASN1_GENERALSTRING *generalstring; + ASN1_BMPSTRING *bmpstring; + ASN1_UNIVERSALSTRING *universalstring; + ASN1_UTCTIME *utctime; + ASN1_GENERALIZEDTIME *generalizedtime; + ASN1_VISIBLESTRING *visiblestring; + ASN1_UTF8STRING *utf8string; + /* + * set and sequence are left complete and still contain the set or + * sequence bytes + */ + ASN1_STRING *set; + ASN1_STRING *sequence; + ASN1_VALUE *asn1_value; + } value; +} ASN1_TYPE; + +DECLARE_STACK_OF(ASN1_TYPE) +DECLARE_ASN1_SET_OF(ASN1_TYPE) + +typedef STACK_OF(ASN1_TYPE) ASN1_SEQUENCE_ANY; + +DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY) +DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SET_ANY) + +typedef struct NETSCAPE_X509_st { + ASN1_OCTET_STRING *header; + X509 *cert; +} NETSCAPE_X509; + +/* This is used to contain a list of bit names */ +typedef struct BIT_STRING_BITNAME_st { + int bitnum; + const char *lname; + const char *sname; +} BIT_STRING_BITNAME; + +# define M_ASN1_STRING_length(x) ((x)->length) +# define M_ASN1_STRING_length_set(x, n) ((x)->length = (n)) +# define M_ASN1_STRING_type(x) ((x)->type) +# define M_ASN1_STRING_data(x) ((x)->data) + +/* Macros for string operations */ +# define M_ASN1_BIT_STRING_new() (ASN1_BIT_STRING *)\ + ASN1_STRING_type_new(V_ASN1_BIT_STRING) +# define M_ASN1_BIT_STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_ASN1_BIT_STRING_dup(a) (ASN1_BIT_STRING *)\ + ASN1_STRING_dup((const ASN1_STRING *)a) +# define M_ASN1_BIT_STRING_cmp(a,b) ASN1_STRING_cmp(\ + (const ASN1_STRING *)a,(const ASN1_STRING *)b) +# define M_ASN1_BIT_STRING_set(a,b,c) ASN1_STRING_set((ASN1_STRING *)a,b,c) + +# define M_ASN1_INTEGER_new() (ASN1_INTEGER *)\ + ASN1_STRING_type_new(V_ASN1_INTEGER) +# define M_ASN1_INTEGER_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_ASN1_INTEGER_dup(a) (ASN1_INTEGER *)\ + ASN1_STRING_dup((const ASN1_STRING *)a) +# define M_ASN1_INTEGER_cmp(a,b) ASN1_STRING_cmp(\ + (const ASN1_STRING *)a,(const ASN1_STRING *)b) + +# define M_ASN1_ENUMERATED_new() (ASN1_ENUMERATED *)\ + ASN1_STRING_type_new(V_ASN1_ENUMERATED) +# define M_ASN1_ENUMERATED_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_ASN1_ENUMERATED_dup(a) (ASN1_ENUMERATED *)\ + ASN1_STRING_dup((const ASN1_STRING *)a) +# define M_ASN1_ENUMERATED_cmp(a,b) ASN1_STRING_cmp(\ + (const ASN1_STRING *)a,(const ASN1_STRING *)b) + +# define M_ASN1_OCTET_STRING_new() (ASN1_OCTET_STRING *)\ + ASN1_STRING_type_new(V_ASN1_OCTET_STRING) +# define M_ASN1_OCTET_STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_ASN1_OCTET_STRING_dup(a) (ASN1_OCTET_STRING *)\ + ASN1_STRING_dup((const ASN1_STRING *)a) +# define M_ASN1_OCTET_STRING_cmp(a,b) ASN1_STRING_cmp(\ + (const ASN1_STRING *)a,(const ASN1_STRING *)b) +# define M_ASN1_OCTET_STRING_set(a,b,c) ASN1_STRING_set((ASN1_STRING *)a,b,c) +# define M_ASN1_OCTET_STRING_print(a,b) ASN1_STRING_print(a,(ASN1_STRING *)b) +# define M_i2d_ASN1_OCTET_STRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_OCTET_STRING,\ + V_ASN1_UNIVERSAL) + +# define B_ASN1_TIME \ + B_ASN1_UTCTIME | \ + B_ASN1_GENERALIZEDTIME + +# define B_ASN1_PRINTABLE \ + B_ASN1_NUMERICSTRING| \ + B_ASN1_PRINTABLESTRING| \ + B_ASN1_T61STRING| \ + B_ASN1_IA5STRING| \ + B_ASN1_BIT_STRING| \ + B_ASN1_UNIVERSALSTRING|\ + B_ASN1_BMPSTRING|\ + B_ASN1_UTF8STRING|\ + B_ASN1_SEQUENCE|\ + B_ASN1_UNKNOWN + +# define B_ASN1_DIRECTORYSTRING \ + B_ASN1_PRINTABLESTRING| \ + B_ASN1_TELETEXSTRING|\ + B_ASN1_BMPSTRING|\ + B_ASN1_UNIVERSALSTRING|\ + B_ASN1_UTF8STRING + +# define B_ASN1_DISPLAYTEXT \ + B_ASN1_IA5STRING| \ + B_ASN1_VISIBLESTRING| \ + B_ASN1_BMPSTRING|\ + B_ASN1_UTF8STRING + +# define M_ASN1_PRINTABLE_new() ASN1_STRING_type_new(V_ASN1_T61STRING) +# define M_ASN1_PRINTABLE_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_i2d_ASN1_PRINTABLE(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\ + pp,a->type,V_ASN1_UNIVERSAL) +# define M_d2i_ASN1_PRINTABLE(a,pp,l) \ + d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \ + B_ASN1_PRINTABLE) + +# define M_DIRECTORYSTRING_new() ASN1_STRING_type_new(V_ASN1_PRINTABLESTRING) +# define M_DIRECTORYSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_i2d_DIRECTORYSTRING(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\ + pp,a->type,V_ASN1_UNIVERSAL) +# define M_d2i_DIRECTORYSTRING(a,pp,l) \ + d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \ + B_ASN1_DIRECTORYSTRING) + +# define M_DISPLAYTEXT_new() ASN1_STRING_type_new(V_ASN1_VISIBLESTRING) +# define M_DISPLAYTEXT_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_i2d_DISPLAYTEXT(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\ + pp,a->type,V_ASN1_UNIVERSAL) +# define M_d2i_DISPLAYTEXT(a,pp,l) \ + d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \ + B_ASN1_DISPLAYTEXT) + +# define M_ASN1_PRINTABLESTRING_new() (ASN1_PRINTABLESTRING *)\ + ASN1_STRING_type_new(V_ASN1_PRINTABLESTRING) +# define M_ASN1_PRINTABLESTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_i2d_ASN1_PRINTABLESTRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_PRINTABLESTRING,\ + V_ASN1_UNIVERSAL) +# define M_d2i_ASN1_PRINTABLESTRING(a,pp,l) \ + (ASN1_PRINTABLESTRING *)d2i_ASN1_type_bytes\ + ((ASN1_STRING **)a,pp,l,B_ASN1_PRINTABLESTRING) + +# define M_ASN1_T61STRING_new() (ASN1_T61STRING *)\ + ASN1_STRING_type_new(V_ASN1_T61STRING) +# define M_ASN1_T61STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_i2d_ASN1_T61STRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_T61STRING,\ + V_ASN1_UNIVERSAL) +# define M_d2i_ASN1_T61STRING(a,pp,l) \ + (ASN1_T61STRING *)d2i_ASN1_type_bytes\ + ((ASN1_STRING **)a,pp,l,B_ASN1_T61STRING) + +# define M_ASN1_IA5STRING_new() (ASN1_IA5STRING *)\ + ASN1_STRING_type_new(V_ASN1_IA5STRING) +# define M_ASN1_IA5STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_ASN1_IA5STRING_dup(a) \ + (ASN1_IA5STRING *)ASN1_STRING_dup((const ASN1_STRING *)a) +# define M_i2d_ASN1_IA5STRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_IA5STRING,\ + V_ASN1_UNIVERSAL) +# define M_d2i_ASN1_IA5STRING(a,pp,l) \ + (ASN1_IA5STRING *)d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l,\ + B_ASN1_IA5STRING) + +# define M_ASN1_UTCTIME_new() (ASN1_UTCTIME *)\ + ASN1_STRING_type_new(V_ASN1_UTCTIME) +# define M_ASN1_UTCTIME_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_ASN1_UTCTIME_dup(a) (ASN1_UTCTIME *)\ + ASN1_STRING_dup((const ASN1_STRING *)a) + +# define M_ASN1_GENERALIZEDTIME_new() (ASN1_GENERALIZEDTIME *)\ + ASN1_STRING_type_new(V_ASN1_GENERALIZEDTIME) +# define M_ASN1_GENERALIZEDTIME_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_ASN1_GENERALIZEDTIME_dup(a) (ASN1_GENERALIZEDTIME *)ASN1_STRING_dup(\ + (const ASN1_STRING *)a) + +# define M_ASN1_TIME_new() (ASN1_TIME *)\ + ASN1_STRING_type_new(V_ASN1_UTCTIME) +# define M_ASN1_TIME_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_ASN1_TIME_dup(a) (ASN1_TIME *)\ + ASN1_STRING_dup((const ASN1_STRING *)a) + +# define M_ASN1_GENERALSTRING_new() (ASN1_GENERALSTRING *)\ + ASN1_STRING_type_new(V_ASN1_GENERALSTRING) +# define M_ASN1_GENERALSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_i2d_ASN1_GENERALSTRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_GENERALSTRING,\ + V_ASN1_UNIVERSAL) +# define M_d2i_ASN1_GENERALSTRING(a,pp,l) \ + (ASN1_GENERALSTRING *)d2i_ASN1_type_bytes\ + ((ASN1_STRING **)a,pp,l,B_ASN1_GENERALSTRING) + +# define M_ASN1_UNIVERSALSTRING_new() (ASN1_UNIVERSALSTRING *)\ + ASN1_STRING_type_new(V_ASN1_UNIVERSALSTRING) +# define M_ASN1_UNIVERSALSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_i2d_ASN1_UNIVERSALSTRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_UNIVERSALSTRING,\ + V_ASN1_UNIVERSAL) +# define M_d2i_ASN1_UNIVERSALSTRING(a,pp,l) \ + (ASN1_UNIVERSALSTRING *)d2i_ASN1_type_bytes\ + ((ASN1_STRING **)a,pp,l,B_ASN1_UNIVERSALSTRING) + +# define M_ASN1_BMPSTRING_new() (ASN1_BMPSTRING *)\ + ASN1_STRING_type_new(V_ASN1_BMPSTRING) +# define M_ASN1_BMPSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_i2d_ASN1_BMPSTRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_BMPSTRING,\ + V_ASN1_UNIVERSAL) +# define M_d2i_ASN1_BMPSTRING(a,pp,l) \ + (ASN1_BMPSTRING *)d2i_ASN1_type_bytes\ + ((ASN1_STRING **)a,pp,l,B_ASN1_BMPSTRING) + +# define M_ASN1_VISIBLESTRING_new() (ASN1_VISIBLESTRING *)\ + ASN1_STRING_type_new(V_ASN1_VISIBLESTRING) +# define M_ASN1_VISIBLESTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_i2d_ASN1_VISIBLESTRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_VISIBLESTRING,\ + V_ASN1_UNIVERSAL) +# define M_d2i_ASN1_VISIBLESTRING(a,pp,l) \ + (ASN1_VISIBLESTRING *)d2i_ASN1_type_bytes\ + ((ASN1_STRING **)a,pp,l,B_ASN1_VISIBLESTRING) + +# define M_ASN1_UTF8STRING_new() (ASN1_UTF8STRING *)\ + ASN1_STRING_type_new(V_ASN1_UTF8STRING) +# define M_ASN1_UTF8STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_i2d_ASN1_UTF8STRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_UTF8STRING,\ + V_ASN1_UNIVERSAL) +# define M_d2i_ASN1_UTF8STRING(a,pp,l) \ + (ASN1_UTF8STRING *)d2i_ASN1_type_bytes\ + ((ASN1_STRING **)a,pp,l,B_ASN1_UTF8STRING) + + /* for the is_set parameter to i2d_ASN1_SET */ +# define IS_SEQUENCE 0 +# define IS_SET 1 + +DECLARE_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE) + +int ASN1_TYPE_get(ASN1_TYPE *a); +void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value); +int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value); +int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b); + +ASN1_OBJECT *ASN1_OBJECT_new(void); +void ASN1_OBJECT_free(ASN1_OBJECT *a); +int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp); +ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, + long length); +ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, + long length); + +DECLARE_ASN1_ITEM(ASN1_OBJECT) + +DECLARE_STACK_OF(ASN1_OBJECT) +DECLARE_ASN1_SET_OF(ASN1_OBJECT) + +ASN1_STRING *ASN1_STRING_new(void); +void ASN1_STRING_free(ASN1_STRING *a); +void ASN1_STRING_clear_free(ASN1_STRING *a); +int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str); +ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *a); +ASN1_STRING *ASN1_STRING_type_new(int type); +int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b); + /* + * Since this is used to store all sorts of things, via macros, for now, + * make its data void * + */ +int ASN1_STRING_set(ASN1_STRING *str, const void *data, int len); +void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len); +int ASN1_STRING_length(const ASN1_STRING *x); +void ASN1_STRING_length_set(ASN1_STRING *x, int n); +int ASN1_STRING_type(ASN1_STRING *x); +unsigned char *ASN1_STRING_data(ASN1_STRING *x); + +DECLARE_ASN1_FUNCTIONS(ASN1_BIT_STRING) +int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp); +ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, + const unsigned char **pp, long length); +int ASN1_BIT_STRING_set(ASN1_BIT_STRING *a, unsigned char *d, int length); +int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value); +int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n); +int ASN1_BIT_STRING_check(ASN1_BIT_STRING *a, + unsigned char *flags, int flags_len); + +# ifndef OPENSSL_NO_BIO +int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs, + BIT_STRING_BITNAME *tbl, int indent); +# endif +int ASN1_BIT_STRING_num_asc(char *name, BIT_STRING_BITNAME *tbl); +int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, char *name, int value, + BIT_STRING_BITNAME *tbl); + +int i2d_ASN1_BOOLEAN(int a, unsigned char **pp); +int d2i_ASN1_BOOLEAN(int *a, const unsigned char **pp, long length); + +DECLARE_ASN1_FUNCTIONS(ASN1_INTEGER) +int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp); +ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp, + long length); +ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp, + long length); +ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x); +int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y); + +DECLARE_ASN1_FUNCTIONS(ASN1_ENUMERATED) + +int ASN1_UTCTIME_check(const ASN1_UTCTIME *a); +ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t); +ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t, + int offset_day, long offset_sec); +int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str); +int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t); +# if 0 +time_t ASN1_UTCTIME_get(const ASN1_UTCTIME *s); +# endif + +int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *a); +ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s, + time_t t); +ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s, + time_t t, int offset_day, + long offset_sec); +int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str); +int ASN1_TIME_diff(int *pday, int *psec, + const ASN1_TIME *from, const ASN1_TIME *to); + +DECLARE_ASN1_FUNCTIONS(ASN1_OCTET_STRING) +ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *a); +int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, + const ASN1_OCTET_STRING *b); +int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *str, const unsigned char *data, + int len); + +DECLARE_ASN1_FUNCTIONS(ASN1_VISIBLESTRING) +DECLARE_ASN1_FUNCTIONS(ASN1_UNIVERSALSTRING) +DECLARE_ASN1_FUNCTIONS(ASN1_UTF8STRING) +DECLARE_ASN1_FUNCTIONS(ASN1_NULL) +DECLARE_ASN1_FUNCTIONS(ASN1_BMPSTRING) + +int UTF8_getc(const unsigned char *str, int len, unsigned long *val); +int UTF8_putc(unsigned char *str, int len, unsigned long value); + +DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, ASN1_PRINTABLE) + +DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DIRECTORYSTRING) +DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DISPLAYTEXT) +DECLARE_ASN1_FUNCTIONS(ASN1_PRINTABLESTRING) +DECLARE_ASN1_FUNCTIONS(ASN1_T61STRING) +DECLARE_ASN1_FUNCTIONS(ASN1_IA5STRING) +DECLARE_ASN1_FUNCTIONS(ASN1_GENERALSTRING) +DECLARE_ASN1_FUNCTIONS(ASN1_UTCTIME) +DECLARE_ASN1_FUNCTIONS(ASN1_GENERALIZEDTIME) +DECLARE_ASN1_FUNCTIONS(ASN1_TIME) + +DECLARE_ASN1_ITEM(ASN1_OCTET_STRING_NDEF) + +ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t); +ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t, + int offset_day, long offset_sec); +int ASN1_TIME_check(ASN1_TIME *t); +ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME + **out); +int ASN1_TIME_set_string(ASN1_TIME *s, const char *str); + +int i2d_ASN1_SET(STACK_OF(OPENSSL_BLOCK) *a, unsigned char **pp, + i2d_of_void *i2d, int ex_tag, int ex_class, int is_set); +STACK_OF(OPENSSL_BLOCK) *d2i_ASN1_SET(STACK_OF(OPENSSL_BLOCK) **a, + const unsigned char **pp, + long length, d2i_of_void *d2i, + void (*free_func) (OPENSSL_BLOCK), + int ex_tag, int ex_class); + +# ifndef OPENSSL_NO_BIO +int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a); +int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size); +int i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a); +int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size); +int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a); +int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size); +int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type); +# endif +int i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a); + +int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num); +ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len, + const char *sn, const char *ln); + +int ASN1_INTEGER_set(ASN1_INTEGER *a, long v); +long ASN1_INTEGER_get(const ASN1_INTEGER *a); +ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai); +BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn); + +int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v); +long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a); +ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai); +BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai, BIGNUM *bn); + +/* General */ +/* given a string, return the correct type, max is the maximum length */ +int ASN1_PRINTABLE_type(const unsigned char *s, int max); + +int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass); +ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp, + long length, int Ptag, int Pclass); +unsigned long ASN1_tag2bit(int tag); +/* type is one or more of the B_ASN1_ values. */ +ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a, const unsigned char **pp, + long length, int type); + +/* PARSING */ +int asn1_Finish(ASN1_CTX *c); +int asn1_const_Finish(ASN1_const_CTX *c); + +/* SPECIALS */ +int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag, + int *pclass, long omax); +int ASN1_check_infinite_end(unsigned char **p, long len); +int ASN1_const_check_infinite_end(const unsigned char **p, long len); +void ASN1_put_object(unsigned char **pp, int constructed, int length, + int tag, int xclass); +int ASN1_put_eoc(unsigned char **pp); +int ASN1_object_size(int constructed, int length, int tag); + +/* Used to implement other functions */ +void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x); + +# define ASN1_dup_of(type,i2d,d2i,x) \ + ((type*)ASN1_dup(CHECKED_I2D_OF(type, i2d), \ + CHECKED_D2I_OF(type, d2i), \ + CHECKED_PTR_OF(type, x))) + +# define ASN1_dup_of_const(type,i2d,d2i,x) \ + ((type*)ASN1_dup(CHECKED_I2D_OF(const type, i2d), \ + CHECKED_D2I_OF(type, d2i), \ + CHECKED_PTR_OF(const type, x))) + +void *ASN1_item_dup(const ASN1_ITEM *it, void *x); + +/* ASN1 alloc/free macros for when a type is only used internally */ + +# define M_ASN1_new_of(type) (type *)ASN1_item_new(ASN1_ITEM_rptr(type)) +# define M_ASN1_free_of(x, type) \ + ASN1_item_free(CHECKED_PTR_OF(type, x), ASN1_ITEM_rptr(type)) + +# ifndef OPENSSL_NO_FP_API +void *ASN1_d2i_fp(void *(*xnew) (void), d2i_of_void *d2i, FILE *in, void **x); + +# define ASN1_d2i_fp_of(type,xnew,d2i,in,x) \ + ((type*)ASN1_d2i_fp(CHECKED_NEW_OF(type, xnew), \ + CHECKED_D2I_OF(type, d2i), \ + in, \ + CHECKED_PPTR_OF(type, x))) + +void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x); +int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x); + +# define ASN1_i2d_fp_of(type,i2d,out,x) \ + (ASN1_i2d_fp(CHECKED_I2D_OF(type, i2d), \ + out, \ + CHECKED_PTR_OF(type, x))) + +# define ASN1_i2d_fp_of_const(type,i2d,out,x) \ + (ASN1_i2d_fp(CHECKED_I2D_OF(const type, i2d), \ + out, \ + CHECKED_PTR_OF(const type, x))) + +int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x); +int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags); +# endif + +int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in); + +# ifndef OPENSSL_NO_BIO +void *ASN1_d2i_bio(void *(*xnew) (void), d2i_of_void *d2i, BIO *in, void **x); + +# define ASN1_d2i_bio_of(type,xnew,d2i,in,x) \ + ((type*)ASN1_d2i_bio( CHECKED_NEW_OF(type, xnew), \ + CHECKED_D2I_OF(type, d2i), \ + in, \ + CHECKED_PPTR_OF(type, x))) + +void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x); +int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x); + +# define ASN1_i2d_bio_of(type,i2d,out,x) \ + (ASN1_i2d_bio(CHECKED_I2D_OF(type, i2d), \ + out, \ + CHECKED_PTR_OF(type, x))) + +# define ASN1_i2d_bio_of_const(type,i2d,out,x) \ + (ASN1_i2d_bio(CHECKED_I2D_OF(const type, i2d), \ + out, \ + CHECKED_PTR_OF(const type, x))) + +int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x); +int ASN1_UTCTIME_print(BIO *fp, const ASN1_UTCTIME *a); +int ASN1_GENERALIZEDTIME_print(BIO *fp, const ASN1_GENERALIZEDTIME *a); +int ASN1_TIME_print(BIO *fp, const ASN1_TIME *a); +int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v); +int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags); +int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num, + unsigned char *buf, int off); +int ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent); +int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent, + int dump); +# endif +const char *ASN1_tag2str(int tag); + +/* Used to load and write netscape format cert */ + +DECLARE_ASN1_FUNCTIONS(NETSCAPE_X509) + +int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s); + +int ASN1_TYPE_set_octetstring(ASN1_TYPE *a, unsigned char *data, int len); +int ASN1_TYPE_get_octetstring(ASN1_TYPE *a, unsigned char *data, int max_len); +int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num, + unsigned char *data, int len); +int ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a, long *num, + unsigned char *data, int max_len); + +STACK_OF(OPENSSL_BLOCK) *ASN1_seq_unpack(const unsigned char *buf, int len, + d2i_of_void *d2i, + void (*free_func) (OPENSSL_BLOCK)); +unsigned char *ASN1_seq_pack(STACK_OF(OPENSSL_BLOCK) *safes, i2d_of_void *i2d, + unsigned char **buf, int *len); +void *ASN1_unpack_string(ASN1_STRING *oct, d2i_of_void *d2i); +void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it); +ASN1_STRING *ASN1_pack_string(void *obj, i2d_of_void *i2d, + ASN1_OCTET_STRING **oct); + +# define ASN1_pack_string_of(type,obj,i2d,oct) \ + (ASN1_pack_string(CHECKED_PTR_OF(type, obj), \ + CHECKED_I2D_OF(type, i2d), \ + oct)) + +ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, + ASN1_OCTET_STRING **oct); + +void ASN1_STRING_set_default_mask(unsigned long mask); +int ASN1_STRING_set_default_mask_asc(const char *p); +unsigned long ASN1_STRING_get_default_mask(void); +int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len, + int inform, unsigned long mask); +int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, + int inform, unsigned long mask, + long minsize, long maxsize); + +ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, + const unsigned char *in, int inlen, + int inform, int nid); +ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid); +int ASN1_STRING_TABLE_add(int, long, long, unsigned long, unsigned long); +void ASN1_STRING_TABLE_cleanup(void); + +/* ASN1 template functions */ + +/* Old API compatible functions */ +ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it); +void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it); +ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **val, const unsigned char **in, + long len, const ASN1_ITEM *it); +int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it); +int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out, + const ASN1_ITEM *it); + +void ASN1_add_oid_module(void); + +ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf); +ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf); + +/* ASN1 Print flags */ + +/* Indicate missing OPTIONAL fields */ +# define ASN1_PCTX_FLAGS_SHOW_ABSENT 0x001 +/* Mark start and end of SEQUENCE */ +# define ASN1_PCTX_FLAGS_SHOW_SEQUENCE 0x002 +/* Mark start and end of SEQUENCE/SET OF */ +# define ASN1_PCTX_FLAGS_SHOW_SSOF 0x004 +/* Show the ASN1 type of primitives */ +# define ASN1_PCTX_FLAGS_SHOW_TYPE 0x008 +/* Don't show ASN1 type of ANY */ +# define ASN1_PCTX_FLAGS_NO_ANY_TYPE 0x010 +/* Don't show ASN1 type of MSTRINGs */ +# define ASN1_PCTX_FLAGS_NO_MSTRING_TYPE 0x020 +/* Don't show field names in SEQUENCE */ +# define ASN1_PCTX_FLAGS_NO_FIELD_NAME 0x040 +/* Show structure names of each SEQUENCE field */ +# define ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME 0x080 +/* Don't show structure name even at top level */ +# define ASN1_PCTX_FLAGS_NO_STRUCT_NAME 0x100 + +int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent, + const ASN1_ITEM *it, const ASN1_PCTX *pctx); +ASN1_PCTX *ASN1_PCTX_new(void); +void ASN1_PCTX_free(ASN1_PCTX *p); +unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p); +void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p); +void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p); +void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p); +void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p); +void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags); + +BIO_METHOD *BIO_f_asn1(void); + +BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it); + +int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, + const ASN1_ITEM *it); +int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, + const char *hdr, const ASN1_ITEM *it); +int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, + int ctype_nid, int econt_nid, + STACK_OF(X509_ALGOR) *mdalgs, const ASN1_ITEM *it); +ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it); +int SMIME_crlf_copy(BIO *in, BIO *out, int flags); +int SMIME_text(BIO *in, BIO *out); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_ASN1_strings(void); + +/* Error codes for the ASN1 functions. */ + +/* Function codes. */ +# define ASN1_F_A2D_ASN1_OBJECT 100 +# define ASN1_F_A2I_ASN1_ENUMERATED 101 +# define ASN1_F_A2I_ASN1_INTEGER 102 +# define ASN1_F_A2I_ASN1_STRING 103 +# define ASN1_F_APPEND_EXP 176 +# define ASN1_F_ASN1_BIT_STRING_SET_BIT 183 +# define ASN1_F_ASN1_CB 177 +# define ASN1_F_ASN1_CHECK_TLEN 104 +# define ASN1_F_ASN1_COLLATE_PRIMITIVE 105 +# define ASN1_F_ASN1_COLLECT 106 +# define ASN1_F_ASN1_D2I_EX_PRIMITIVE 108 +# define ASN1_F_ASN1_D2I_FP 109 +# define ASN1_F_ASN1_D2I_READ_BIO 107 +# define ASN1_F_ASN1_DIGEST 184 +# define ASN1_F_ASN1_DO_ADB 110 +# define ASN1_F_ASN1_DUP 111 +# define ASN1_F_ASN1_ENUMERATED_SET 112 +# define ASN1_F_ASN1_ENUMERATED_TO_BN 113 +# define ASN1_F_ASN1_EX_C2I 204 +# define ASN1_F_ASN1_FIND_END 190 +# define ASN1_F_ASN1_GENERALIZEDTIME_ADJ 216 +# define ASN1_F_ASN1_GENERALIZEDTIME_SET 185 +# define ASN1_F_ASN1_GENERATE_V3 178 +# define ASN1_F_ASN1_GET_OBJECT 114 +# define ASN1_F_ASN1_HEADER_NEW 115 +# define ASN1_F_ASN1_I2D_BIO 116 +# define ASN1_F_ASN1_I2D_FP 117 +# define ASN1_F_ASN1_INTEGER_SET 118 +# define ASN1_F_ASN1_INTEGER_TO_BN 119 +# define ASN1_F_ASN1_ITEM_D2I_FP 206 +# define ASN1_F_ASN1_ITEM_DUP 191 +# define ASN1_F_ASN1_ITEM_EX_COMBINE_NEW 121 +# define ASN1_F_ASN1_ITEM_EX_D2I 120 +# define ASN1_F_ASN1_ITEM_I2D_BIO 192 +# define ASN1_F_ASN1_ITEM_I2D_FP 193 +# define ASN1_F_ASN1_ITEM_PACK 198 +# define ASN1_F_ASN1_ITEM_SIGN 195 +# define ASN1_F_ASN1_ITEM_SIGN_CTX 220 +# define ASN1_F_ASN1_ITEM_UNPACK 199 +# define ASN1_F_ASN1_ITEM_VERIFY 197 +# define ASN1_F_ASN1_MBSTRING_NCOPY 122 +# define ASN1_F_ASN1_OBJECT_NEW 123 +# define ASN1_F_ASN1_OUTPUT_DATA 214 +# define ASN1_F_ASN1_PACK_STRING 124 +# define ASN1_F_ASN1_PCTX_NEW 205 +# define ASN1_F_ASN1_PKCS5_PBE_SET 125 +# define ASN1_F_ASN1_SEQ_PACK 126 +# define ASN1_F_ASN1_SEQ_UNPACK 127 +# define ASN1_F_ASN1_SIGN 128 +# define ASN1_F_ASN1_STR2TYPE 179 +# define ASN1_F_ASN1_STRING_SET 186 +# define ASN1_F_ASN1_STRING_TABLE_ADD 129 +# define ASN1_F_ASN1_STRING_TYPE_NEW 130 +# define ASN1_F_ASN1_TEMPLATE_EX_D2I 132 +# define ASN1_F_ASN1_TEMPLATE_NEW 133 +# define ASN1_F_ASN1_TEMPLATE_NOEXP_D2I 131 +# define ASN1_F_ASN1_TIME_ADJ 217 +# define ASN1_F_ASN1_TIME_SET 175 +# define ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING 134 +# define ASN1_F_ASN1_TYPE_GET_OCTETSTRING 135 +# define ASN1_F_ASN1_UNPACK_STRING 136 +# define ASN1_F_ASN1_UTCTIME_ADJ 218 +# define ASN1_F_ASN1_UTCTIME_SET 187 +# define ASN1_F_ASN1_VERIFY 137 +# define ASN1_F_B64_READ_ASN1 209 +# define ASN1_F_B64_WRITE_ASN1 210 +# define ASN1_F_BIO_NEW_NDEF 208 +# define ASN1_F_BITSTR_CB 180 +# define ASN1_F_BN_TO_ASN1_ENUMERATED 138 +# define ASN1_F_BN_TO_ASN1_INTEGER 139 +# define ASN1_F_C2I_ASN1_BIT_STRING 189 +# define ASN1_F_C2I_ASN1_INTEGER 194 +# define ASN1_F_C2I_ASN1_OBJECT 196 +# define ASN1_F_COLLECT_DATA 140 +# define ASN1_F_D2I_ASN1_BIT_STRING 141 +# define ASN1_F_D2I_ASN1_BOOLEAN 142 +# define ASN1_F_D2I_ASN1_BYTES 143 +# define ASN1_F_D2I_ASN1_GENERALIZEDTIME 144 +# define ASN1_F_D2I_ASN1_HEADER 145 +# define ASN1_F_D2I_ASN1_INTEGER 146 +# define ASN1_F_D2I_ASN1_OBJECT 147 +# define ASN1_F_D2I_ASN1_SET 148 +# define ASN1_F_D2I_ASN1_TYPE_BYTES 149 +# define ASN1_F_D2I_ASN1_UINTEGER 150 +# define ASN1_F_D2I_ASN1_UTCTIME 151 +# define ASN1_F_D2I_AUTOPRIVATEKEY 207 +# define ASN1_F_D2I_NETSCAPE_RSA 152 +# define ASN1_F_D2I_NETSCAPE_RSA_2 153 +# define ASN1_F_D2I_PRIVATEKEY 154 +# define ASN1_F_D2I_PUBLICKEY 155 +# define ASN1_F_D2I_RSA_NET 200 +# define ASN1_F_D2I_RSA_NET_2 201 +# define ASN1_F_D2I_X509 156 +# define ASN1_F_D2I_X509_CINF 157 +# define ASN1_F_D2I_X509_PKEY 159 +# define ASN1_F_I2D_ASN1_BIO_STREAM 211 +# define ASN1_F_I2D_ASN1_SET 188 +# define ASN1_F_I2D_ASN1_TIME 160 +# define ASN1_F_I2D_DSA_PUBKEY 161 +# define ASN1_F_I2D_EC_PUBKEY 181 +# define ASN1_F_I2D_PRIVATEKEY 163 +# define ASN1_F_I2D_PUBLICKEY 164 +# define ASN1_F_I2D_RSA_NET 162 +# define ASN1_F_I2D_RSA_PUBKEY 165 +# define ASN1_F_LONG_C2I 166 +# define ASN1_F_OID_MODULE_INIT 174 +# define ASN1_F_PARSE_TAGGING 182 +# define ASN1_F_PKCS5_PBE2_SET_IV 167 +# define ASN1_F_PKCS5_PBE_SET 202 +# define ASN1_F_PKCS5_PBE_SET0_ALGOR 215 +# define ASN1_F_PKCS5_PBKDF2_SET 219 +# define ASN1_F_SMIME_READ_ASN1 212 +# define ASN1_F_SMIME_TEXT 213 +# define ASN1_F_X509_CINF_NEW 168 +# define ASN1_F_X509_CRL_ADD0_REVOKED 169 +# define ASN1_F_X509_INFO_NEW 170 +# define ASN1_F_X509_NAME_ENCODE 203 +# define ASN1_F_X509_NAME_EX_D2I 158 +# define ASN1_F_X509_NAME_EX_NEW 171 +# define ASN1_F_X509_NEW 172 +# define ASN1_F_X509_PKEY_NEW 173 + +/* Reason codes. */ +# define ASN1_R_ADDING_OBJECT 171 +# define ASN1_R_ASN1_PARSE_ERROR 203 +# define ASN1_R_ASN1_SIG_PARSE_ERROR 204 +# define ASN1_R_AUX_ERROR 100 +# define ASN1_R_BAD_CLASS 101 +# define ASN1_R_BAD_OBJECT_HEADER 102 +# define ASN1_R_BAD_PASSWORD_READ 103 +# define ASN1_R_BAD_TAG 104 +# define ASN1_R_BMPSTRING_IS_WRONG_LENGTH 214 +# define ASN1_R_BN_LIB 105 +# define ASN1_R_BOOLEAN_IS_WRONG_LENGTH 106 +# define ASN1_R_BUFFER_TOO_SMALL 107 +# define ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 108 +# define ASN1_R_CONTEXT_NOT_INITIALISED 217 +# define ASN1_R_DATA_IS_WRONG 109 +# define ASN1_R_DECODE_ERROR 110 +# define ASN1_R_DECODING_ERROR 111 +# define ASN1_R_DEPTH_EXCEEDED 174 +# define ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED 198 +# define ASN1_R_ENCODE_ERROR 112 +# define ASN1_R_ERROR_GETTING_TIME 173 +# define ASN1_R_ERROR_LOADING_SECTION 172 +# define ASN1_R_ERROR_PARSING_SET_ELEMENT 113 +# define ASN1_R_ERROR_SETTING_CIPHER_PARAMS 114 +# define ASN1_R_EXPECTING_AN_INTEGER 115 +# define ASN1_R_EXPECTING_AN_OBJECT 116 +# define ASN1_R_EXPECTING_A_BOOLEAN 117 +# define ASN1_R_EXPECTING_A_TIME 118 +# define ASN1_R_EXPLICIT_LENGTH_MISMATCH 119 +# define ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED 120 +# define ASN1_R_FIELD_MISSING 121 +# define ASN1_R_FIRST_NUM_TOO_LARGE 122 +# define ASN1_R_HEADER_TOO_LONG 123 +# define ASN1_R_ILLEGAL_BITSTRING_FORMAT 175 +# define ASN1_R_ILLEGAL_BOOLEAN 176 +# define ASN1_R_ILLEGAL_CHARACTERS 124 +# define ASN1_R_ILLEGAL_FORMAT 177 +# define ASN1_R_ILLEGAL_HEX 178 +# define ASN1_R_ILLEGAL_IMPLICIT_TAG 179 +# define ASN1_R_ILLEGAL_INTEGER 180 +# define ASN1_R_ILLEGAL_NESTED_TAGGING 181 +# define ASN1_R_ILLEGAL_NULL 125 +# define ASN1_R_ILLEGAL_NULL_VALUE 182 +# define ASN1_R_ILLEGAL_OBJECT 183 +# define ASN1_R_ILLEGAL_OPTIONAL_ANY 126 +# define ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE 170 +# define ASN1_R_ILLEGAL_TAGGED_ANY 127 +# define ASN1_R_ILLEGAL_TIME_VALUE 184 +# define ASN1_R_INTEGER_NOT_ASCII_FORMAT 185 +# define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG 128 +# define ASN1_R_INVALID_BIT_STRING_BITS_LEFT 220 +# define ASN1_R_INVALID_BMPSTRING_LENGTH 129 +# define ASN1_R_INVALID_DIGIT 130 +# define ASN1_R_INVALID_MIME_TYPE 205 +# define ASN1_R_INVALID_MODIFIER 186 +# define ASN1_R_INVALID_NUMBER 187 +# define ASN1_R_INVALID_OBJECT_ENCODING 216 +# define ASN1_R_INVALID_SEPARATOR 131 +# define ASN1_R_INVALID_TIME_FORMAT 132 +# define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH 133 +# define ASN1_R_INVALID_UTF8STRING 134 +# define ASN1_R_IV_TOO_LARGE 135 +# define ASN1_R_LENGTH_ERROR 136 +# define ASN1_R_LIST_ERROR 188 +# define ASN1_R_MIME_NO_CONTENT_TYPE 206 +# define ASN1_R_MIME_PARSE_ERROR 207 +# define ASN1_R_MIME_SIG_PARSE_ERROR 208 +# define ASN1_R_MISSING_EOC 137 +# define ASN1_R_MISSING_SECOND_NUMBER 138 +# define ASN1_R_MISSING_VALUE 189 +# define ASN1_R_MSTRING_NOT_UNIVERSAL 139 +# define ASN1_R_MSTRING_WRONG_TAG 140 +# define ASN1_R_NESTED_ASN1_STRING 197 +# define ASN1_R_NON_HEX_CHARACTERS 141 +# define ASN1_R_NOT_ASCII_FORMAT 190 +# define ASN1_R_NOT_ENOUGH_DATA 142 +# define ASN1_R_NO_CONTENT_TYPE 209 +# define ASN1_R_NO_DEFAULT_DIGEST 201 +# define ASN1_R_NO_MATCHING_CHOICE_TYPE 143 +# define ASN1_R_NO_MULTIPART_BODY_FAILURE 210 +# define ASN1_R_NO_MULTIPART_BOUNDARY 211 +# define ASN1_R_NO_SIG_CONTENT_TYPE 212 +# define ASN1_R_NULL_IS_WRONG_LENGTH 144 +# define ASN1_R_OBJECT_NOT_ASCII_FORMAT 191 +# define ASN1_R_ODD_NUMBER_OF_CHARS 145 +# define ASN1_R_PRIVATE_KEY_HEADER_MISSING 146 +# define ASN1_R_SECOND_NUMBER_TOO_LARGE 147 +# define ASN1_R_SEQUENCE_LENGTH_MISMATCH 148 +# define ASN1_R_SEQUENCE_NOT_CONSTRUCTED 149 +# define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG 192 +# define ASN1_R_SHORT_LINE 150 +# define ASN1_R_SIG_INVALID_MIME_TYPE 213 +# define ASN1_R_STREAMING_NOT_SUPPORTED 202 +# define ASN1_R_STRING_TOO_LONG 151 +# define ASN1_R_STRING_TOO_SHORT 152 +# define ASN1_R_TAG_VALUE_TOO_HIGH 153 +# define ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 154 +# define ASN1_R_TIME_NOT_ASCII_FORMAT 193 +# define ASN1_R_TOO_LONG 155 +# define ASN1_R_TYPE_NOT_CONSTRUCTED 156 +# define ASN1_R_TYPE_NOT_PRIMITIVE 218 +# define ASN1_R_UNABLE_TO_DECODE_RSA_KEY 157 +# define ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY 158 +# define ASN1_R_UNEXPECTED_EOC 159 +# define ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH 215 +# define ASN1_R_UNKNOWN_FORMAT 160 +# define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM 161 +# define ASN1_R_UNKNOWN_OBJECT_TYPE 162 +# define ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE 163 +# define ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM 199 +# define ASN1_R_UNKNOWN_TAG 194 +# define ASN1_R_UNKOWN_FORMAT 195 +# define ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE 164 +# define ASN1_R_UNSUPPORTED_CIPHER 165 +# define ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM 166 +# define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE 167 +# define ASN1_R_UNSUPPORTED_TYPE 196 +# define ASN1_R_WRONG_PUBLIC_KEY_TYPE 200 +# define ASN1_R_WRONG_TAG 168 +# define ASN1_R_WRONG_TYPE 169 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/asn1_mac.h b/OSlibs/ios/include/openssl/asn1_mac.h new file mode 100755 index 000000000..abc6dc35c --- /dev/null +++ b/OSlibs/ios/include/openssl/asn1_mac.h @@ -0,0 +1,579 @@ +/* crypto/asn1/asn1_mac.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_ASN1_MAC_H +# define HEADER_ASN1_MAC_H + +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# ifndef ASN1_MAC_ERR_LIB +# define ASN1_MAC_ERR_LIB ERR_LIB_ASN1 +# endif + +# define ASN1_MAC_H_err(f,r,line) \ + ERR_PUT_error(ASN1_MAC_ERR_LIB,(f),(r),__FILE__,(line)) + +# define M_ASN1_D2I_vars(a,type,func) \ + ASN1_const_CTX c; \ + type ret=NULL; \ + \ + c.pp=(const unsigned char **)pp; \ + c.q= *(const unsigned char **)pp; \ + c.error=ERR_R_NESTED_ASN1_ERROR; \ + if ((a == NULL) || ((*a) == NULL)) \ + { if ((ret=(type)func()) == NULL) \ + { c.line=__LINE__; goto err; } } \ + else ret=(*a); + +# define M_ASN1_D2I_Init() \ + c.p= *(const unsigned char **)pp; \ + c.max=(length == 0)?0:(c.p+length); + +# define M_ASN1_D2I_Finish_2(a) \ + if (!asn1_const_Finish(&c)) \ + { c.line=__LINE__; goto err; } \ + *(const unsigned char **)pp=c.p; \ + if (a != NULL) (*a)=ret; \ + return(ret); + +# define M_ASN1_D2I_Finish(a,func,e) \ + M_ASN1_D2I_Finish_2(a); \ +err:\ + ASN1_MAC_H_err((e),c.error,c.line); \ + asn1_add_error(*(const unsigned char **)pp,(int)(c.q- *pp)); \ + if ((ret != NULL) && ((a == NULL) || (*a != ret))) func(ret); \ + return(NULL) + +# define M_ASN1_D2I_start_sequence() \ + if (!asn1_GetSequence(&c,&length)) \ + { c.line=__LINE__; goto err; } +/* Begin reading ASN1 without a surrounding sequence */ +# define M_ASN1_D2I_begin() \ + c.slen = length; + +/* End reading ASN1 with no check on length */ +# define M_ASN1_D2I_Finish_nolen(a, func, e) \ + *pp=c.p; \ + if (a != NULL) (*a)=ret; \ + return(ret); \ +err:\ + ASN1_MAC_H_err((e),c.error,c.line); \ + asn1_add_error(*pp,(int)(c.q- *pp)); \ + if ((ret != NULL) && ((a == NULL) || (*a != ret))) func(ret); \ + return(NULL) + +# define M_ASN1_D2I_end_sequence() \ + (((c.inf&1) == 0)?(c.slen <= 0): \ + (c.eos=ASN1_const_check_infinite_end(&c.p,c.slen))) + +/* Don't use this with d2i_ASN1_BOOLEAN() */ +# define M_ASN1_D2I_get(b, func) \ + c.q=c.p; \ + if (func(&(b),&c.p,c.slen) == NULL) \ + {c.line=__LINE__; goto err; } \ + c.slen-=(c.p-c.q); + +/* Don't use this with d2i_ASN1_BOOLEAN() */ +# define M_ASN1_D2I_get_x(type,b,func) \ + c.q=c.p; \ + if (((D2I_OF(type))func)(&(b),&c.p,c.slen) == NULL) \ + {c.line=__LINE__; goto err; } \ + c.slen-=(c.p-c.q); + +/* use this instead () */ +# define M_ASN1_D2I_get_int(b,func) \ + c.q=c.p; \ + if (func(&(b),&c.p,c.slen) < 0) \ + {c.line=__LINE__; goto err; } \ + c.slen-=(c.p-c.q); + +# define M_ASN1_D2I_get_opt(b,func,type) \ + if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) \ + == (V_ASN1_UNIVERSAL|(type)))) \ + { \ + M_ASN1_D2I_get(b,func); \ + } + +# define M_ASN1_D2I_get_int_opt(b,func,type) \ + if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) \ + == (V_ASN1_UNIVERSAL|(type)))) \ + { \ + M_ASN1_D2I_get_int(b,func); \ + } + +# define M_ASN1_D2I_get_imp(b,func, type) \ + M_ASN1_next=(_tmp& V_ASN1_CONSTRUCTED)|type; \ + c.q=c.p; \ + if (func(&(b),&c.p,c.slen) == NULL) \ + {c.line=__LINE__; M_ASN1_next_prev = _tmp; goto err; } \ + c.slen-=(c.p-c.q);\ + M_ASN1_next_prev=_tmp; + +# define M_ASN1_D2I_get_IMP_opt(b,func,tag,type) \ + if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) == \ + (V_ASN1_CONTEXT_SPECIFIC|(tag)))) \ + { \ + unsigned char _tmp = M_ASN1_next; \ + M_ASN1_D2I_get_imp(b,func, type);\ + } + +# define M_ASN1_D2I_get_set(r,func,free_func) \ + M_ASN1_D2I_get_imp_set(r,func,free_func, \ + V_ASN1_SET,V_ASN1_UNIVERSAL); + +# define M_ASN1_D2I_get_set_type(type,r,func,free_func) \ + M_ASN1_D2I_get_imp_set_type(type,r,func,free_func, \ + V_ASN1_SET,V_ASN1_UNIVERSAL); + +# define M_ASN1_D2I_get_set_opt(r,func,free_func) \ + if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \ + V_ASN1_CONSTRUCTED|V_ASN1_SET)))\ + { M_ASN1_D2I_get_set(r,func,free_func); } + +# define M_ASN1_D2I_get_set_opt_type(type,r,func,free_func) \ + if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \ + V_ASN1_CONSTRUCTED|V_ASN1_SET)))\ + { M_ASN1_D2I_get_set_type(type,r,func,free_func); } + +# define M_ASN1_I2D_len_SET_opt(a,f) \ + if ((a != NULL) && (sk_num(a) != 0)) \ + M_ASN1_I2D_len_SET(a,f); + +# define M_ASN1_I2D_put_SET_opt(a,f) \ + if ((a != NULL) && (sk_num(a) != 0)) \ + M_ASN1_I2D_put_SET(a,f); + +# define M_ASN1_I2D_put_SEQUENCE_opt(a,f) \ + if ((a != NULL) && (sk_num(a) != 0)) \ + M_ASN1_I2D_put_SEQUENCE(a,f); + +# define M_ASN1_I2D_put_SEQUENCE_opt_type(type,a,f) \ + if ((a != NULL) && (sk_##type##_num(a) != 0)) \ + M_ASN1_I2D_put_SEQUENCE_type(type,a,f); + +# define M_ASN1_D2I_get_IMP_set_opt(b,func,free_func,tag) \ + if ((c.slen != 0) && \ + (M_ASN1_next == \ + (V_ASN1_CONTEXT_SPECIFIC|V_ASN1_CONSTRUCTED|(tag))))\ + { \ + M_ASN1_D2I_get_imp_set(b,func,free_func,\ + tag,V_ASN1_CONTEXT_SPECIFIC); \ + } + +# define M_ASN1_D2I_get_IMP_set_opt_type(type,b,func,free_func,tag) \ + if ((c.slen != 0) && \ + (M_ASN1_next == \ + (V_ASN1_CONTEXT_SPECIFIC|V_ASN1_CONSTRUCTED|(tag))))\ + { \ + M_ASN1_D2I_get_imp_set_type(type,b,func,free_func,\ + tag,V_ASN1_CONTEXT_SPECIFIC); \ + } + +# define M_ASN1_D2I_get_seq(r,func,free_func) \ + M_ASN1_D2I_get_imp_set(r,func,free_func,\ + V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL); + +# define M_ASN1_D2I_get_seq_type(type,r,func,free_func) \ + M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,\ + V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL) + +# define M_ASN1_D2I_get_seq_opt(r,func,free_func) \ + if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \ + V_ASN1_CONSTRUCTED|V_ASN1_SEQUENCE)))\ + { M_ASN1_D2I_get_seq(r,func,free_func); } + +# define M_ASN1_D2I_get_seq_opt_type(type,r,func,free_func) \ + if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \ + V_ASN1_CONSTRUCTED|V_ASN1_SEQUENCE)))\ + { M_ASN1_D2I_get_seq_type(type,r,func,free_func); } + +# define M_ASN1_D2I_get_IMP_set(r,func,free_func,x) \ + M_ASN1_D2I_get_imp_set(r,func,free_func,\ + x,V_ASN1_CONTEXT_SPECIFIC); + +# define M_ASN1_D2I_get_IMP_set_type(type,r,func,free_func,x) \ + M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,\ + x,V_ASN1_CONTEXT_SPECIFIC); + +# define M_ASN1_D2I_get_imp_set(r,func,free_func,a,b) \ + c.q=c.p; \ + if (d2i_ASN1_SET(&(r),&c.p,c.slen,(char *(*)())func,\ + (void (*)())free_func,a,b) == NULL) \ + { c.line=__LINE__; goto err; } \ + c.slen-=(c.p-c.q); + +# define M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,a,b) \ + c.q=c.p; \ + if (d2i_ASN1_SET_OF_##type(&(r),&c.p,c.slen,func,\ + free_func,a,b) == NULL) \ + { c.line=__LINE__; goto err; } \ + c.slen-=(c.p-c.q); + +# define M_ASN1_D2I_get_set_strings(r,func,a,b) \ + c.q=c.p; \ + if (d2i_ASN1_STRING_SET(&(r),&c.p,c.slen,a,b) == NULL) \ + { c.line=__LINE__; goto err; } \ + c.slen-=(c.p-c.q); + +# define M_ASN1_D2I_get_EXP_opt(r,func,tag) \ + if ((c.slen != 0L) && (M_ASN1_next == \ + (V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \ + { \ + int Tinf,Ttag,Tclass; \ + long Tlen; \ + \ + c.q=c.p; \ + Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \ + if (Tinf & 0x80) \ + { c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \ + c.line=__LINE__; goto err; } \ + if (Tinf == (V_ASN1_CONSTRUCTED+1)) \ + Tlen = c.slen - (c.p - c.q) - 2; \ + if (func(&(r),&c.p,Tlen) == NULL) \ + { c.line=__LINE__; goto err; } \ + if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \ + Tlen = c.slen - (c.p - c.q); \ + if(!ASN1_const_check_infinite_end(&c.p, Tlen)) \ + { c.error=ERR_R_MISSING_ASN1_EOS; \ + c.line=__LINE__; goto err; } \ + }\ + c.slen-=(c.p-c.q); \ + } + +# define M_ASN1_D2I_get_EXP_set_opt(r,func,free_func,tag,b) \ + if ((c.slen != 0) && (M_ASN1_next == \ + (V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \ + { \ + int Tinf,Ttag,Tclass; \ + long Tlen; \ + \ + c.q=c.p; \ + Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \ + if (Tinf & 0x80) \ + { c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \ + c.line=__LINE__; goto err; } \ + if (Tinf == (V_ASN1_CONSTRUCTED+1)) \ + Tlen = c.slen - (c.p - c.q) - 2; \ + if (d2i_ASN1_SET(&(r),&c.p,Tlen,(char *(*)())func, \ + (void (*)())free_func, \ + b,V_ASN1_UNIVERSAL) == NULL) \ + { c.line=__LINE__; goto err; } \ + if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \ + Tlen = c.slen - (c.p - c.q); \ + if(!ASN1_check_infinite_end(&c.p, Tlen)) \ + { c.error=ERR_R_MISSING_ASN1_EOS; \ + c.line=__LINE__; goto err; } \ + }\ + c.slen-=(c.p-c.q); \ + } + +# define M_ASN1_D2I_get_EXP_set_opt_type(type,r,func,free_func,tag,b) \ + if ((c.slen != 0) && (M_ASN1_next == \ + (V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \ + { \ + int Tinf,Ttag,Tclass; \ + long Tlen; \ + \ + c.q=c.p; \ + Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \ + if (Tinf & 0x80) \ + { c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \ + c.line=__LINE__; goto err; } \ + if (Tinf == (V_ASN1_CONSTRUCTED+1)) \ + Tlen = c.slen - (c.p - c.q) - 2; \ + if (d2i_ASN1_SET_OF_##type(&(r),&c.p,Tlen,func, \ + free_func,b,V_ASN1_UNIVERSAL) == NULL) \ + { c.line=__LINE__; goto err; } \ + if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \ + Tlen = c.slen - (c.p - c.q); \ + if(!ASN1_check_infinite_end(&c.p, Tlen)) \ + { c.error=ERR_R_MISSING_ASN1_EOS; \ + c.line=__LINE__; goto err; } \ + }\ + c.slen-=(c.p-c.q); \ + } + +/* New macros */ +# define M_ASN1_New_Malloc(ret,type) \ + if ((ret=(type *)OPENSSL_malloc(sizeof(type))) == NULL) \ + { c.line=__LINE__; goto err2; } + +# define M_ASN1_New(arg,func) \ + if (((arg)=func()) == NULL) return(NULL) + +# define M_ASN1_New_Error(a) \ +/*- err: ASN1_MAC_H_err((a),ERR_R_NESTED_ASN1_ERROR,c.line); \ + return(NULL);*/ \ + err2: ASN1_MAC_H_err((a),ERR_R_MALLOC_FAILURE,c.line); \ + return(NULL) + +/* + * BIG UGLY WARNING! This is so damn ugly I wanna puke. Unfortunately, some + * macros that use ASN1_const_CTX still insist on writing in the input + * stream. ARGH! ARGH! ARGH! Let's get rid of this macro package. Please? -- + * Richard Levitte + */ +# define M_ASN1_next (*((unsigned char *)(c.p))) +# define M_ASN1_next_prev (*((unsigned char *)(c.q))) + +/*************************************************/ + +# define M_ASN1_I2D_vars(a) int r=0,ret=0; \ + unsigned char *p; \ + if (a == NULL) return(0) + +/* Length Macros */ +# define M_ASN1_I2D_len(a,f) ret+=f(a,NULL) +# define M_ASN1_I2D_len_IMP_opt(a,f) if (a != NULL) M_ASN1_I2D_len(a,f) + +# define M_ASN1_I2D_len_SET(a,f) \ + ret+=i2d_ASN1_SET(a,NULL,f,V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET); + +# define M_ASN1_I2D_len_SET_type(type,a,f) \ + ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,V_ASN1_SET, \ + V_ASN1_UNIVERSAL,IS_SET); + +# define M_ASN1_I2D_len_SEQUENCE(a,f) \ + ret+=i2d_ASN1_SET(a,NULL,f,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL, \ + IS_SEQUENCE); + +# define M_ASN1_I2D_len_SEQUENCE_type(type,a,f) \ + ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,V_ASN1_SEQUENCE, \ + V_ASN1_UNIVERSAL,IS_SEQUENCE) + +# define M_ASN1_I2D_len_SEQUENCE_opt(a,f) \ + if ((a != NULL) && (sk_num(a) != 0)) \ + M_ASN1_I2D_len_SEQUENCE(a,f); + +# define M_ASN1_I2D_len_SEQUENCE_opt_type(type,a,f) \ + if ((a != NULL) && (sk_##type##_num(a) != 0)) \ + M_ASN1_I2D_len_SEQUENCE_type(type,a,f); + +# define M_ASN1_I2D_len_IMP_SET(a,f,x) \ + ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC,IS_SET); + +# define M_ASN1_I2D_len_IMP_SET_type(type,a,f,x) \ + ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \ + V_ASN1_CONTEXT_SPECIFIC,IS_SET); + +# define M_ASN1_I2D_len_IMP_SET_opt(a,f,x) \ + if ((a != NULL) && (sk_num(a) != 0)) \ + ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \ + IS_SET); + +# define M_ASN1_I2D_len_IMP_SET_opt_type(type,a,f,x) \ + if ((a != NULL) && (sk_##type##_num(a) != 0)) \ + ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \ + V_ASN1_CONTEXT_SPECIFIC,IS_SET); + +# define M_ASN1_I2D_len_IMP_SEQUENCE(a,f,x) \ + ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \ + IS_SEQUENCE); + +# define M_ASN1_I2D_len_IMP_SEQUENCE_opt(a,f,x) \ + if ((a != NULL) && (sk_num(a) != 0)) \ + ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \ + IS_SEQUENCE); + +# define M_ASN1_I2D_len_IMP_SEQUENCE_opt_type(type,a,f,x) \ + if ((a != NULL) && (sk_##type##_num(a) != 0)) \ + ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \ + V_ASN1_CONTEXT_SPECIFIC, \ + IS_SEQUENCE); + +# define M_ASN1_I2D_len_EXP_opt(a,f,mtag,v) \ + if (a != NULL)\ + { \ + v=f(a,NULL); \ + ret+=ASN1_object_size(1,v,mtag); \ + } + +# define M_ASN1_I2D_len_EXP_SET_opt(a,f,mtag,tag,v) \ + if ((a != NULL) && (sk_num(a) != 0))\ + { \ + v=i2d_ASN1_SET(a,NULL,f,tag,V_ASN1_UNIVERSAL,IS_SET); \ + ret+=ASN1_object_size(1,v,mtag); \ + } + +# define M_ASN1_I2D_len_EXP_SEQUENCE_opt(a,f,mtag,tag,v) \ + if ((a != NULL) && (sk_num(a) != 0))\ + { \ + v=i2d_ASN1_SET(a,NULL,f,tag,V_ASN1_UNIVERSAL, \ + IS_SEQUENCE); \ + ret+=ASN1_object_size(1,v,mtag); \ + } + +# define M_ASN1_I2D_len_EXP_SEQUENCE_opt_type(type,a,f,mtag,tag,v) \ + if ((a != NULL) && (sk_##type##_num(a) != 0))\ + { \ + v=i2d_ASN1_SET_OF_##type(a,NULL,f,tag, \ + V_ASN1_UNIVERSAL, \ + IS_SEQUENCE); \ + ret+=ASN1_object_size(1,v,mtag); \ + } + +/* Put Macros */ +# define M_ASN1_I2D_put(a,f) f(a,&p) + +# define M_ASN1_I2D_put_IMP_opt(a,f,t) \ + if (a != NULL) \ + { \ + unsigned char *q=p; \ + f(a,&p); \ + *q=(V_ASN1_CONTEXT_SPECIFIC|t|(*q&V_ASN1_CONSTRUCTED));\ + } + +# define M_ASN1_I2D_put_SET(a,f) i2d_ASN1_SET(a,&p,f,V_ASN1_SET,\ + V_ASN1_UNIVERSAL,IS_SET) +# define M_ASN1_I2D_put_SET_type(type,a,f) \ + i2d_ASN1_SET_OF_##type(a,&p,f,V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET) +# define M_ASN1_I2D_put_IMP_SET(a,f,x) i2d_ASN1_SET(a,&p,f,x,\ + V_ASN1_CONTEXT_SPECIFIC,IS_SET) +# define M_ASN1_I2D_put_IMP_SET_type(type,a,f,x) \ + i2d_ASN1_SET_OF_##type(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC,IS_SET) +# define M_ASN1_I2D_put_IMP_SEQUENCE(a,f,x) i2d_ASN1_SET(a,&p,f,x,\ + V_ASN1_CONTEXT_SPECIFIC,IS_SEQUENCE) + +# define M_ASN1_I2D_put_SEQUENCE(a,f) i2d_ASN1_SET(a,&p,f,V_ASN1_SEQUENCE,\ + V_ASN1_UNIVERSAL,IS_SEQUENCE) + +# define M_ASN1_I2D_put_SEQUENCE_type(type,a,f) \ + i2d_ASN1_SET_OF_##type(a,&p,f,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL, \ + IS_SEQUENCE) + +# define M_ASN1_I2D_put_SEQUENCE_opt(a,f) \ + if ((a != NULL) && (sk_num(a) != 0)) \ + M_ASN1_I2D_put_SEQUENCE(a,f); + +# define M_ASN1_I2D_put_IMP_SET_opt(a,f,x) \ + if ((a != NULL) && (sk_num(a) != 0)) \ + { i2d_ASN1_SET(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC, \ + IS_SET); } + +# define M_ASN1_I2D_put_IMP_SET_opt_type(type,a,f,x) \ + if ((a != NULL) && (sk_##type##_num(a) != 0)) \ + { i2d_ASN1_SET_OF_##type(a,&p,f,x, \ + V_ASN1_CONTEXT_SPECIFIC, \ + IS_SET); } + +# define M_ASN1_I2D_put_IMP_SEQUENCE_opt(a,f,x) \ + if ((a != NULL) && (sk_num(a) != 0)) \ + { i2d_ASN1_SET(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC, \ + IS_SEQUENCE); } + +# define M_ASN1_I2D_put_IMP_SEQUENCE_opt_type(type,a,f,x) \ + if ((a != NULL) && (sk_##type##_num(a) != 0)) \ + { i2d_ASN1_SET_OF_##type(a,&p,f,x, \ + V_ASN1_CONTEXT_SPECIFIC, \ + IS_SEQUENCE); } + +# define M_ASN1_I2D_put_EXP_opt(a,f,tag,v) \ + if (a != NULL) \ + { \ + ASN1_put_object(&p,1,v,tag,V_ASN1_CONTEXT_SPECIFIC); \ + f(a,&p); \ + } + +# define M_ASN1_I2D_put_EXP_SET_opt(a,f,mtag,tag,v) \ + if ((a != NULL) && (sk_num(a) != 0)) \ + { \ + ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \ + i2d_ASN1_SET(a,&p,f,tag,V_ASN1_UNIVERSAL,IS_SET); \ + } + +# define M_ASN1_I2D_put_EXP_SEQUENCE_opt(a,f,mtag,tag,v) \ + if ((a != NULL) && (sk_num(a) != 0)) \ + { \ + ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \ + i2d_ASN1_SET(a,&p,f,tag,V_ASN1_UNIVERSAL,IS_SEQUENCE); \ + } + +# define M_ASN1_I2D_put_EXP_SEQUENCE_opt_type(type,a,f,mtag,tag,v) \ + if ((a != NULL) && (sk_##type##_num(a) != 0)) \ + { \ + ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \ + i2d_ASN1_SET_OF_##type(a,&p,f,tag,V_ASN1_UNIVERSAL, \ + IS_SEQUENCE); \ + } + +# define M_ASN1_I2D_seq_total() \ + r=ASN1_object_size(1,ret,V_ASN1_SEQUENCE); \ + if (pp == NULL) return(r); \ + p= *pp; \ + ASN1_put_object(&p,1,ret,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL) + +# define M_ASN1_I2D_INF_seq_start(tag,ctx) \ + *(p++)=(V_ASN1_CONSTRUCTED|(tag)|(ctx)); \ + *(p++)=0x80 + +# define M_ASN1_I2D_INF_seq_end() *(p++)=0x00; *(p++)=0x00 + +# define M_ASN1_I2D_finish() *pp=p; \ + return(r); + +int asn1_GetSequence(ASN1_const_CTX *c, long *length); +void asn1_add_error(const unsigned char *address, int offset); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/OSlibs/ios/include/openssl/asn1t.h b/OSlibs/ios/include/openssl/asn1t.h new file mode 100755 index 000000000..99bc0eecf --- /dev/null +++ b/OSlibs/ios/include/openssl/asn1t.h @@ -0,0 +1,973 @@ +/* asn1t.h */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef HEADER_ASN1T_H +# define HEADER_ASN1T_H + +# include +# include +# include + +# ifdef OPENSSL_BUILD_SHLIBCRYPTO +# undef OPENSSL_EXTERN +# define OPENSSL_EXTERN OPENSSL_EXPORT +# endif + +/* ASN1 template defines, structures and functions */ + +#ifdef __cplusplus +extern "C" { +#endif + +# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION + +/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */ +# define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr)) + +/* Macros for start and end of ASN1_ITEM definition */ + +# define ASN1_ITEM_start(itname) \ + OPENSSL_GLOBAL const ASN1_ITEM itname##_it = { + +# define ASN1_ITEM_end(itname) \ + }; + +# else + +/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */ +# define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr())) + +/* Macros for start and end of ASN1_ITEM definition */ + +# define ASN1_ITEM_start(itname) \ + const ASN1_ITEM * itname##_it(void) \ + { \ + static const ASN1_ITEM local_it = { + +# define ASN1_ITEM_end(itname) \ + }; \ + return &local_it; \ + } + +# endif + +/* Macros to aid ASN1 template writing */ + +# define ASN1_ITEM_TEMPLATE(tname) \ + static const ASN1_TEMPLATE tname##_item_tt + +# define ASN1_ITEM_TEMPLATE_END(tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_PRIMITIVE,\ + -1,\ + &tname##_item_tt,\ + 0,\ + NULL,\ + 0,\ + #tname \ + ASN1_ITEM_end(tname) + +/* This is a ASN1 type which just embeds a template */ + +/*- + * This pair helps declare a SEQUENCE. We can do: + * + * ASN1_SEQUENCE(stname) = { + * ... SEQUENCE components ... + * } ASN1_SEQUENCE_END(stname) + * + * This will produce an ASN1_ITEM called stname_it + * for a structure called stname. + * + * If you want the same structure but a different + * name then use: + * + * ASN1_SEQUENCE(itname) = { + * ... SEQUENCE components ... + * } ASN1_SEQUENCE_END_name(stname, itname) + * + * This will create an item called itname_it using + * a structure called stname. + */ + +# define ASN1_SEQUENCE(tname) \ + static const ASN1_TEMPLATE tname##_seq_tt[] + +# define ASN1_SEQUENCE_END(stname) ASN1_SEQUENCE_END_name(stname, stname) + +# define ASN1_SEQUENCE_END_name(stname, tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +# define ASN1_NDEF_SEQUENCE(tname) \ + ASN1_SEQUENCE(tname) + +# define ASN1_NDEF_SEQUENCE_cb(tname, cb) \ + ASN1_SEQUENCE_cb(tname, cb) + +# define ASN1_SEQUENCE_cb(tname, cb) \ + static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \ + ASN1_SEQUENCE(tname) + +# define ASN1_BROKEN_SEQUENCE(tname) \ + static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_BROKEN, 0, 0, 0, 0}; \ + ASN1_SEQUENCE(tname) + +# define ASN1_SEQUENCE_ref(tname, cb, lck) \ + static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), lck, cb, 0}; \ + ASN1_SEQUENCE(tname) + +# define ASN1_SEQUENCE_enc(tname, enc, cb) \ + static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 0, 0, cb, offsetof(tname, enc)}; \ + ASN1_SEQUENCE(tname) + +# define ASN1_NDEF_SEQUENCE_END(tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_NDEF_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(tname),\ + #tname \ + ASN1_ITEM_end(tname) + +# define ASN1_BROKEN_SEQUENCE_END(stname) ASN1_SEQUENCE_END_ref(stname, stname) + +# define ASN1_SEQUENCE_END_enc(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname) + +# define ASN1_SEQUENCE_END_cb(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname) + +# define ASN1_SEQUENCE_END_ref(stname, tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + &tname##_aux,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +# define ASN1_NDEF_SEQUENCE_END_cb(stname, tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_NDEF_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + &tname##_aux,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +/*- + * This pair helps declare a CHOICE type. We can do: + * + * ASN1_CHOICE(chname) = { + * ... CHOICE options ... + * ASN1_CHOICE_END(chname) + * + * This will produce an ASN1_ITEM called chname_it + * for a structure called chname. The structure + * definition must look like this: + * typedef struct { + * int type; + * union { + * ASN1_SOMETHING *opt1; + * ASN1_SOMEOTHER *opt2; + * } value; + * } chname; + * + * the name of the selector must be 'type'. + * to use an alternative selector name use the + * ASN1_CHOICE_END_selector() version. + */ + +# define ASN1_CHOICE(tname) \ + static const ASN1_TEMPLATE tname##_ch_tt[] + +# define ASN1_CHOICE_cb(tname, cb) \ + static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \ + ASN1_CHOICE(tname) + +# define ASN1_CHOICE_END(stname) ASN1_CHOICE_END_name(stname, stname) + +# define ASN1_CHOICE_END_name(stname, tname) ASN1_CHOICE_END_selector(stname, tname, type) + +# define ASN1_CHOICE_END_selector(stname, tname, selname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_CHOICE,\ + offsetof(stname,selname) ,\ + tname##_ch_tt,\ + sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +# define ASN1_CHOICE_END_cb(stname, tname, selname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_CHOICE,\ + offsetof(stname,selname) ,\ + tname##_ch_tt,\ + sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\ + &tname##_aux,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +/* This helps with the template wrapper form of ASN1_ITEM */ + +# define ASN1_EX_TEMPLATE_TYPE(flags, tag, name, type) { \ + (flags), (tag), 0,\ + #name, ASN1_ITEM_ref(type) } + +/* These help with SEQUENCE or CHOICE components */ + +/* used to declare other types */ + +# define ASN1_EX_TYPE(flags, tag, stname, field, type) { \ + (flags), (tag), offsetof(stname, field),\ + #field, ASN1_ITEM_ref(type) } + +/* used when the structure is combined with the parent */ + +# define ASN1_EX_COMBINE(flags, tag, type) { \ + (flags)|ASN1_TFLG_COMBINE, (tag), 0, NULL, ASN1_ITEM_ref(type) } + +/* implicit and explicit helper macros */ + +# define ASN1_IMP_EX(stname, field, type, tag, ex) \ + ASN1_EX_TYPE(ASN1_TFLG_IMPLICIT | ex, tag, stname, field, type) + +# define ASN1_EXP_EX(stname, field, type, tag, ex) \ + ASN1_EX_TYPE(ASN1_TFLG_EXPLICIT | ex, tag, stname, field, type) + +/* Any defined by macros: the field used is in the table itself */ + +# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION +# define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) } +# define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) } +# else +# define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, tblname##_adb } +# define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, tblname##_adb } +# endif +/* Plain simple type */ +# define ASN1_SIMPLE(stname, field, type) ASN1_EX_TYPE(0,0, stname, field, type) + +/* OPTIONAL simple type */ +# define ASN1_OPT(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_OPTIONAL, 0, stname, field, type) + +/* IMPLICIT tagged simple type */ +# define ASN1_IMP(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, 0) + +/* IMPLICIT tagged OPTIONAL simple type */ +# define ASN1_IMP_OPT(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL) + +/* Same as above but EXPLICIT */ + +# define ASN1_EXP(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, 0) +# define ASN1_EXP_OPT(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL) + +/* SEQUENCE OF type */ +# define ASN1_SEQUENCE_OF(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, stname, field, type) + +/* OPTIONAL SEQUENCE OF */ +# define ASN1_SEQUENCE_OF_OPT(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type) + +/* Same as above but for SET OF */ + +# define ASN1_SET_OF(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SET_OF, 0, stname, field, type) + +# define ASN1_SET_OF_OPT(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type) + +/* Finally compound types of SEQUENCE, SET, IMPLICIT, EXPLICIT and OPTIONAL */ + +# define ASN1_IMP_SET_OF(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF) + +# define ASN1_EXP_SET_OF(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF) + +# define ASN1_IMP_SET_OF_OPT(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL) + +# define ASN1_EXP_SET_OF_OPT(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL) + +# define ASN1_IMP_SEQUENCE_OF(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF) + +# define ASN1_IMP_SEQUENCE_OF_OPT(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL) + +# define ASN1_EXP_SEQUENCE_OF(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF) + +# define ASN1_EXP_SEQUENCE_OF_OPT(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL) + +/* EXPLICIT using indefinite length constructed form */ +# define ASN1_NDEF_EXP(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_NDEF) + +/* EXPLICIT OPTIONAL using indefinite length constructed form */ +# define ASN1_NDEF_EXP_OPT(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_NDEF) + +/* Macros for the ASN1_ADB structure */ + +# define ASN1_ADB(name) \ + static const ASN1_ADB_TABLE name##_adbtbl[] + +# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION + +# define ASN1_ADB_END(name, flags, field, app_table, def, none) \ + ;\ + static const ASN1_ADB name##_adb = {\ + flags,\ + offsetof(name, field),\ + app_table,\ + name##_adbtbl,\ + sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\ + def,\ + none\ + } + +# else + +# define ASN1_ADB_END(name, flags, field, app_table, def, none) \ + ;\ + static const ASN1_ITEM *name##_adb(void) \ + { \ + static const ASN1_ADB internal_adb = \ + {\ + flags,\ + offsetof(name, field),\ + app_table,\ + name##_adbtbl,\ + sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\ + def,\ + none\ + }; \ + return (const ASN1_ITEM *) &internal_adb; \ + } \ + void dummy_function(void) + +# endif + +# define ADB_ENTRY(val, template) {val, template} + +# define ASN1_ADB_TEMPLATE(name) \ + static const ASN1_TEMPLATE name##_tt + +/* + * This is the ASN1 template structure that defines a wrapper round the + * actual type. It determines the actual position of the field in the value + * structure, various flags such as OPTIONAL and the field name. + */ + +struct ASN1_TEMPLATE_st { + unsigned long flags; /* Various flags */ + long tag; /* tag, not used if no tagging */ + unsigned long offset; /* Offset of this field in structure */ +# ifndef NO_ASN1_FIELD_NAMES + const char *field_name; /* Field name */ +# endif + ASN1_ITEM_EXP *item; /* Relevant ASN1_ITEM or ASN1_ADB */ +}; + +/* Macro to extract ASN1_ITEM and ASN1_ADB pointer from ASN1_TEMPLATE */ + +# define ASN1_TEMPLATE_item(t) (t->item_ptr) +# define ASN1_TEMPLATE_adb(t) (t->item_ptr) + +typedef struct ASN1_ADB_TABLE_st ASN1_ADB_TABLE; +typedef struct ASN1_ADB_st ASN1_ADB; + +struct ASN1_ADB_st { + unsigned long flags; /* Various flags */ + unsigned long offset; /* Offset of selector field */ + STACK_OF(ASN1_ADB_TABLE) **app_items; /* Application defined items */ + const ASN1_ADB_TABLE *tbl; /* Table of possible types */ + long tblcount; /* Number of entries in tbl */ + const ASN1_TEMPLATE *default_tt; /* Type to use if no match */ + const ASN1_TEMPLATE *null_tt; /* Type to use if selector is NULL */ +}; + +struct ASN1_ADB_TABLE_st { + long value; /* NID for an object or value for an int */ + const ASN1_TEMPLATE tt; /* item for this value */ +}; + +/* template flags */ + +/* Field is optional */ +# define ASN1_TFLG_OPTIONAL (0x1) + +/* Field is a SET OF */ +# define ASN1_TFLG_SET_OF (0x1 << 1) + +/* Field is a SEQUENCE OF */ +# define ASN1_TFLG_SEQUENCE_OF (0x2 << 1) + +/* + * Special case: this refers to a SET OF that will be sorted into DER order + * when encoded *and* the corresponding STACK will be modified to match the + * new order. + */ +# define ASN1_TFLG_SET_ORDER (0x3 << 1) + +/* Mask for SET OF or SEQUENCE OF */ +# define ASN1_TFLG_SK_MASK (0x3 << 1) + +/* + * These flags mean the tag should be taken from the tag field. If EXPLICIT + * then the underlying type is used for the inner tag. + */ + +/* IMPLICIT tagging */ +# define ASN1_TFLG_IMPTAG (0x1 << 3) + +/* EXPLICIT tagging, inner tag from underlying type */ +# define ASN1_TFLG_EXPTAG (0x2 << 3) + +# define ASN1_TFLG_TAG_MASK (0x3 << 3) + +/* context specific IMPLICIT */ +# define ASN1_TFLG_IMPLICIT ASN1_TFLG_IMPTAG|ASN1_TFLG_CONTEXT + +/* context specific EXPLICIT */ +# define ASN1_TFLG_EXPLICIT ASN1_TFLG_EXPTAG|ASN1_TFLG_CONTEXT + +/* + * If tagging is in force these determine the type of tag to use. Otherwise + * the tag is determined by the underlying type. These values reflect the + * actual octet format. + */ + +/* Universal tag */ +# define ASN1_TFLG_UNIVERSAL (0x0<<6) +/* Application tag */ +# define ASN1_TFLG_APPLICATION (0x1<<6) +/* Context specific tag */ +# define ASN1_TFLG_CONTEXT (0x2<<6) +/* Private tag */ +# define ASN1_TFLG_PRIVATE (0x3<<6) + +# define ASN1_TFLG_TAG_CLASS (0x3<<6) + +/* + * These are for ANY DEFINED BY type. In this case the 'item' field points to + * an ASN1_ADB structure which contains a table of values to decode the + * relevant type + */ + +# define ASN1_TFLG_ADB_MASK (0x3<<8) + +# define ASN1_TFLG_ADB_OID (0x1<<8) + +# define ASN1_TFLG_ADB_INT (0x1<<9) + +/* + * This flag means a parent structure is passed instead of the field: this is + * useful is a SEQUENCE is being combined with a CHOICE for example. Since + * this means the structure and item name will differ we need to use the + * ASN1_CHOICE_END_name() macro for example. + */ + +# define ASN1_TFLG_COMBINE (0x1<<10) + +/* + * This flag when present in a SEQUENCE OF, SET OF or EXPLICIT causes + * indefinite length constructed encoding to be used if required. + */ + +# define ASN1_TFLG_NDEF (0x1<<11) + +/* This is the actual ASN1 item itself */ + +struct ASN1_ITEM_st { + char itype; /* The item type, primitive, SEQUENCE, CHOICE + * or extern */ + long utype; /* underlying type */ + const ASN1_TEMPLATE *templates; /* If SEQUENCE or CHOICE this contains + * the contents */ + long tcount; /* Number of templates if SEQUENCE or CHOICE */ + const void *funcs; /* functions that handle this type */ + long size; /* Structure size (usually) */ +# ifndef NO_ASN1_FIELD_NAMES + const char *sname; /* Structure name */ +# endif +}; + +/*- + * These are values for the itype field and + * determine how the type is interpreted. + * + * For PRIMITIVE types the underlying type + * determines the behaviour if items is NULL. + * + * Otherwise templates must contain a single + * template and the type is treated in the + * same way as the type specified in the template. + * + * For SEQUENCE types the templates field points + * to the members, the size field is the + * structure size. + * + * For CHOICE types the templates field points + * to each possible member (typically a union) + * and the 'size' field is the offset of the + * selector. + * + * The 'funcs' field is used for application + * specific functions. + * + * For COMPAT types the funcs field gives a + * set of functions that handle this type, this + * supports the old d2i, i2d convention. + * + * The EXTERN type uses a new style d2i/i2d. + * The new style should be used where possible + * because it avoids things like the d2i IMPLICIT + * hack. + * + * MSTRING is a multiple string type, it is used + * for a CHOICE of character strings where the + * actual strings all occupy an ASN1_STRING + * structure. In this case the 'utype' field + * has a special meaning, it is used as a mask + * of acceptable types using the B_ASN1 constants. + * + * NDEF_SEQUENCE is the same as SEQUENCE except + * that it will use indefinite length constructed + * encoding if requested. + * + */ + +# define ASN1_ITYPE_PRIMITIVE 0x0 + +# define ASN1_ITYPE_SEQUENCE 0x1 + +# define ASN1_ITYPE_CHOICE 0x2 + +# define ASN1_ITYPE_COMPAT 0x3 + +# define ASN1_ITYPE_EXTERN 0x4 + +# define ASN1_ITYPE_MSTRING 0x5 + +# define ASN1_ITYPE_NDEF_SEQUENCE 0x6 + +/* + * Cache for ASN1 tag and length, so we don't keep re-reading it for things + * like CHOICE + */ + +struct ASN1_TLC_st { + char valid; /* Values below are valid */ + int ret; /* return value */ + long plen; /* length */ + int ptag; /* class value */ + int pclass; /* class value */ + int hdrlen; /* header length */ +}; + +/* Typedefs for ASN1 function pointers */ + +typedef ASN1_VALUE *ASN1_new_func(void); +typedef void ASN1_free_func(ASN1_VALUE *a); +typedef ASN1_VALUE *ASN1_d2i_func(ASN1_VALUE **a, const unsigned char **in, + long length); +typedef int ASN1_i2d_func(ASN1_VALUE *a, unsigned char **in); + +typedef int ASN1_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, + const ASN1_ITEM *it, int tag, int aclass, char opt, + ASN1_TLC *ctx); + +typedef int ASN1_ex_i2d(ASN1_VALUE **pval, unsigned char **out, + const ASN1_ITEM *it, int tag, int aclass); +typedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it); +typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it); + +typedef int ASN1_ex_print_func(BIO *out, ASN1_VALUE **pval, + int indent, const char *fname, + const ASN1_PCTX *pctx); + +typedef int ASN1_primitive_i2c(ASN1_VALUE **pval, unsigned char *cont, + int *putype, const ASN1_ITEM *it); +typedef int ASN1_primitive_c2i(ASN1_VALUE **pval, const unsigned char *cont, + int len, int utype, char *free_cont, + const ASN1_ITEM *it); +typedef int ASN1_primitive_print(BIO *out, ASN1_VALUE **pval, + const ASN1_ITEM *it, int indent, + const ASN1_PCTX *pctx); + +typedef struct ASN1_COMPAT_FUNCS_st { + ASN1_new_func *asn1_new; + ASN1_free_func *asn1_free; + ASN1_d2i_func *asn1_d2i; + ASN1_i2d_func *asn1_i2d; +} ASN1_COMPAT_FUNCS; + +typedef struct ASN1_EXTERN_FUNCS_st { + void *app_data; + ASN1_ex_new_func *asn1_ex_new; + ASN1_ex_free_func *asn1_ex_free; + ASN1_ex_free_func *asn1_ex_clear; + ASN1_ex_d2i *asn1_ex_d2i; + ASN1_ex_i2d *asn1_ex_i2d; + ASN1_ex_print_func *asn1_ex_print; +} ASN1_EXTERN_FUNCS; + +typedef struct ASN1_PRIMITIVE_FUNCS_st { + void *app_data; + unsigned long flags; + ASN1_ex_new_func *prim_new; + ASN1_ex_free_func *prim_free; + ASN1_ex_free_func *prim_clear; + ASN1_primitive_c2i *prim_c2i; + ASN1_primitive_i2c *prim_i2c; + ASN1_primitive_print *prim_print; +} ASN1_PRIMITIVE_FUNCS; + +/* + * This is the ASN1_AUX structure: it handles various miscellaneous + * requirements. For example the use of reference counts and an informational + * callback. The "informational callback" is called at various points during + * the ASN1 encoding and decoding. It can be used to provide minor + * customisation of the structures used. This is most useful where the + * supplied routines *almost* do the right thing but need some extra help at + * a few points. If the callback returns zero then it is assumed a fatal + * error has occurred and the main operation should be abandoned. If major + * changes in the default behaviour are required then an external type is + * more appropriate. + */ + +typedef int ASN1_aux_cb(int operation, ASN1_VALUE **in, const ASN1_ITEM *it, + void *exarg); + +typedef struct ASN1_AUX_st { + void *app_data; + int flags; + int ref_offset; /* Offset of reference value */ + int ref_lock; /* Lock type to use */ + ASN1_aux_cb *asn1_cb; + int enc_offset; /* Offset of ASN1_ENCODING structure */ +} ASN1_AUX; + +/* For print related callbacks exarg points to this structure */ +typedef struct ASN1_PRINT_ARG_st { + BIO *out; + int indent; + const ASN1_PCTX *pctx; +} ASN1_PRINT_ARG; + +/* For streaming related callbacks exarg points to this structure */ +typedef struct ASN1_STREAM_ARG_st { + /* BIO to stream through */ + BIO *out; + /* BIO with filters appended */ + BIO *ndef_bio; + /* Streaming I/O boundary */ + unsigned char **boundary; +} ASN1_STREAM_ARG; + +/* Flags in ASN1_AUX */ + +/* Use a reference count */ +# define ASN1_AFLG_REFCOUNT 1 +/* Save the encoding of structure (useful for signatures) */ +# define ASN1_AFLG_ENCODING 2 +/* The Sequence length is invalid */ +# define ASN1_AFLG_BROKEN 4 + +/* operation values for asn1_cb */ + +# define ASN1_OP_NEW_PRE 0 +# define ASN1_OP_NEW_POST 1 +# define ASN1_OP_FREE_PRE 2 +# define ASN1_OP_FREE_POST 3 +# define ASN1_OP_D2I_PRE 4 +# define ASN1_OP_D2I_POST 5 +# define ASN1_OP_I2D_PRE 6 +# define ASN1_OP_I2D_POST 7 +# define ASN1_OP_PRINT_PRE 8 +# define ASN1_OP_PRINT_POST 9 +# define ASN1_OP_STREAM_PRE 10 +# define ASN1_OP_STREAM_POST 11 +# define ASN1_OP_DETACHED_PRE 12 +# define ASN1_OP_DETACHED_POST 13 + +/* Macro to implement a primitive type */ +# define IMPLEMENT_ASN1_TYPE(stname) IMPLEMENT_ASN1_TYPE_ex(stname, stname, 0) +# define IMPLEMENT_ASN1_TYPE_ex(itname, vname, ex) \ + ASN1_ITEM_start(itname) \ + ASN1_ITYPE_PRIMITIVE, V_##vname, NULL, 0, NULL, ex, #itname \ + ASN1_ITEM_end(itname) + +/* Macro to implement a multi string type */ +# define IMPLEMENT_ASN1_MSTRING(itname, mask) \ + ASN1_ITEM_start(itname) \ + ASN1_ITYPE_MSTRING, mask, NULL, 0, NULL, sizeof(ASN1_STRING), #itname \ + ASN1_ITEM_end(itname) + +/* Macro to implement an ASN1_ITEM in terms of old style funcs */ + +# define IMPLEMENT_COMPAT_ASN1(sname) IMPLEMENT_COMPAT_ASN1_type(sname, V_ASN1_SEQUENCE) + +# define IMPLEMENT_COMPAT_ASN1_type(sname, tag) \ + static const ASN1_COMPAT_FUNCS sname##_ff = { \ + (ASN1_new_func *)sname##_new, \ + (ASN1_free_func *)sname##_free, \ + (ASN1_d2i_func *)d2i_##sname, \ + (ASN1_i2d_func *)i2d_##sname, \ + }; \ + ASN1_ITEM_start(sname) \ + ASN1_ITYPE_COMPAT, \ + tag, \ + NULL, \ + 0, \ + &sname##_ff, \ + 0, \ + #sname \ + ASN1_ITEM_end(sname) + +# define IMPLEMENT_EXTERN_ASN1(sname, tag, fptrs) \ + ASN1_ITEM_start(sname) \ + ASN1_ITYPE_EXTERN, \ + tag, \ + NULL, \ + 0, \ + &fptrs, \ + 0, \ + #sname \ + ASN1_ITEM_end(sname) + +/* Macro to implement standard functions in terms of ASN1_ITEM structures */ + +# define IMPLEMENT_ASN1_FUNCTIONS(stname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, stname, stname) + +# define IMPLEMENT_ASN1_FUNCTIONS_name(stname, itname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, itname) + +# define IMPLEMENT_ASN1_FUNCTIONS_ENCODE_name(stname, itname) \ + IMPLEMENT_ASN1_FUNCTIONS_ENCODE_fname(stname, itname, itname) + +# define IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(stname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(static, stname, stname, stname) + +# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS(stname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, stname, stname) + +# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(pre, stname, itname, fname) \ + pre stname *fname##_new(void) \ + { \ + return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \ + } \ + pre void fname##_free(stname *a) \ + { \ + ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \ + } + +# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) \ + stname *fname##_new(void) \ + { \ + return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \ + } \ + void fname##_free(stname *a) \ + { \ + ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \ + } + +# define IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, fname) \ + IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) + +# define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \ + stname *d2i_##fname(stname **a, const unsigned char **in, long len) \ + { \ + return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\ + } \ + int i2d_##fname(stname *a, unsigned char **out) \ + { \ + return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\ + } + +# define IMPLEMENT_ASN1_NDEF_FUNCTION(stname) \ + int i2d_##stname##_NDEF(stname *a, unsigned char **out) \ + { \ + return ASN1_item_ndef_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(stname));\ + } + +/* + * This includes evil casts to remove const: they will go away when full ASN1 + * constification is done. + */ +# define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \ + stname *d2i_##fname(stname **a, const unsigned char **in, long len) \ + { \ + return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\ + } \ + int i2d_##fname(const stname *a, unsigned char **out) \ + { \ + return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\ + } + +# define IMPLEMENT_ASN1_DUP_FUNCTION(stname) \ + stname * stname##_dup(stname *x) \ + { \ + return ASN1_item_dup(ASN1_ITEM_rptr(stname), x); \ + } + +# define IMPLEMENT_ASN1_PRINT_FUNCTION(stname) \ + IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, stname, stname) + +# define IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, itname, fname) \ + int fname##_print_ctx(BIO *out, stname *x, int indent, \ + const ASN1_PCTX *pctx) \ + { \ + return ASN1_item_print(out, (ASN1_VALUE *)x, indent, \ + ASN1_ITEM_rptr(itname), pctx); \ + } + +# define IMPLEMENT_ASN1_FUNCTIONS_const(name) \ + IMPLEMENT_ASN1_FUNCTIONS_const_fname(name, name, name) + +# define IMPLEMENT_ASN1_FUNCTIONS_const_fname(stname, itname, fname) \ + IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) + +/* external definitions for primitive types */ + +DECLARE_ASN1_ITEM(ASN1_BOOLEAN) +DECLARE_ASN1_ITEM(ASN1_TBOOLEAN) +DECLARE_ASN1_ITEM(ASN1_FBOOLEAN) +DECLARE_ASN1_ITEM(ASN1_SEQUENCE) +DECLARE_ASN1_ITEM(CBIGNUM) +DECLARE_ASN1_ITEM(BIGNUM) +DECLARE_ASN1_ITEM(LONG) +DECLARE_ASN1_ITEM(ZLONG) + +DECLARE_STACK_OF(ASN1_VALUE) + +/* Functions used internally by the ASN1 code */ + +int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it); +void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it); +int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); +int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it); + +void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); +int ASN1_template_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, + const ASN1_TEMPLATE *tt); +int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, + const ASN1_ITEM *it, int tag, int aclass, char opt, + ASN1_TLC *ctx); + +int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, + const ASN1_ITEM *it, int tag, int aclass); +int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out, + const ASN1_TEMPLATE *tt); +void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it); + +int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, + const ASN1_ITEM *it); +int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, + int utype, char *free_cont, const ASN1_ITEM *it); + +int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it); +int asn1_set_choice_selector(ASN1_VALUE **pval, int value, + const ASN1_ITEM *it); + +ASN1_VALUE **asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); + +const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, + int nullerr); + +int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it); + +void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it); +void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it); +int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, + const ASN1_ITEM *it); +int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen, + const ASN1_ITEM *it); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/bio.h b/OSlibs/ios/include/openssl/bio.h new file mode 100755 index 000000000..6790aed28 --- /dev/null +++ b/OSlibs/ios/include/openssl/bio.h @@ -0,0 +1,883 @@ +/* crypto/bio/bio.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_BIO_H +# define HEADER_BIO_H + +# include + +# ifndef OPENSSL_NO_FP_API +# include +# endif +# include + +# include + +# ifndef OPENSSL_NO_SCTP +# ifndef OPENSSL_SYS_VMS +# include +# else +# include +# endif +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* These are the 'types' of BIOs */ +# define BIO_TYPE_NONE 0 +# define BIO_TYPE_MEM (1|0x0400) +# define BIO_TYPE_FILE (2|0x0400) + +# define BIO_TYPE_FD (4|0x0400|0x0100) +# define BIO_TYPE_SOCKET (5|0x0400|0x0100) +# define BIO_TYPE_NULL (6|0x0400) +# define BIO_TYPE_SSL (7|0x0200) +# define BIO_TYPE_MD (8|0x0200)/* passive filter */ +# define BIO_TYPE_BUFFER (9|0x0200)/* filter */ +# define BIO_TYPE_CIPHER (10|0x0200)/* filter */ +# define BIO_TYPE_BASE64 (11|0x0200)/* filter */ +# define BIO_TYPE_CONNECT (12|0x0400|0x0100)/* socket - connect */ +# define BIO_TYPE_ACCEPT (13|0x0400|0x0100)/* socket for accept */ +# define BIO_TYPE_PROXY_CLIENT (14|0x0200)/* client proxy BIO */ +# define BIO_TYPE_PROXY_SERVER (15|0x0200)/* server proxy BIO */ +# define BIO_TYPE_NBIO_TEST (16|0x0200)/* server proxy BIO */ +# define BIO_TYPE_NULL_FILTER (17|0x0200) +# define BIO_TYPE_BER (18|0x0200)/* BER -> bin filter */ +# define BIO_TYPE_BIO (19|0x0400)/* (half a) BIO pair */ +# define BIO_TYPE_LINEBUFFER (20|0x0200)/* filter */ +# define BIO_TYPE_DGRAM (21|0x0400|0x0100) +# ifndef OPENSSL_NO_SCTP +# define BIO_TYPE_DGRAM_SCTP (24|0x0400|0x0100) +# endif +# define BIO_TYPE_ASN1 (22|0x0200)/* filter */ +# define BIO_TYPE_COMP (23|0x0200)/* filter */ + +# define BIO_TYPE_DESCRIPTOR 0x0100/* socket, fd, connect or accept */ +# define BIO_TYPE_FILTER 0x0200 +# define BIO_TYPE_SOURCE_SINK 0x0400 + +/* + * BIO_FILENAME_READ|BIO_CLOSE to open or close on free. + * BIO_set_fp(in,stdin,BIO_NOCLOSE); + */ +# define BIO_NOCLOSE 0x00 +# define BIO_CLOSE 0x01 + +/* + * These are used in the following macros and are passed to BIO_ctrl() + */ +# define BIO_CTRL_RESET 1/* opt - rewind/zero etc */ +# define BIO_CTRL_EOF 2/* opt - are we at the eof */ +# define BIO_CTRL_INFO 3/* opt - extra tit-bits */ +# define BIO_CTRL_SET 4/* man - set the 'IO' type */ +# define BIO_CTRL_GET 5/* man - get the 'IO' type */ +# define BIO_CTRL_PUSH 6/* opt - internal, used to signify change */ +# define BIO_CTRL_POP 7/* opt - internal, used to signify change */ +# define BIO_CTRL_GET_CLOSE 8/* man - set the 'close' on free */ +# define BIO_CTRL_SET_CLOSE 9/* man - set the 'close' on free */ +# define BIO_CTRL_PENDING 10/* opt - is their more data buffered */ +# define BIO_CTRL_FLUSH 11/* opt - 'flush' buffered output */ +# define BIO_CTRL_DUP 12/* man - extra stuff for 'duped' BIO */ +# define BIO_CTRL_WPENDING 13/* opt - number of bytes still to write */ +/* callback is int cb(BIO *bio,state,ret); */ +# define BIO_CTRL_SET_CALLBACK 14/* opt - set callback function */ +# define BIO_CTRL_GET_CALLBACK 15/* opt - set callback function */ + +# define BIO_CTRL_SET_FILENAME 30/* BIO_s_file special */ + +/* dgram BIO stuff */ +# define BIO_CTRL_DGRAM_CONNECT 31/* BIO dgram special */ +# define BIO_CTRL_DGRAM_SET_CONNECTED 32/* allow for an externally connected + * socket to be passed in */ +# define BIO_CTRL_DGRAM_SET_RECV_TIMEOUT 33/* setsockopt, essentially */ +# define BIO_CTRL_DGRAM_GET_RECV_TIMEOUT 34/* getsockopt, essentially */ +# define BIO_CTRL_DGRAM_SET_SEND_TIMEOUT 35/* setsockopt, essentially */ +# define BIO_CTRL_DGRAM_GET_SEND_TIMEOUT 36/* getsockopt, essentially */ + +# define BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP 37/* flag whether the last */ +# define BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP 38/* I/O operation tiemd out */ + +/* #ifdef IP_MTU_DISCOVER */ +# define BIO_CTRL_DGRAM_MTU_DISCOVER 39/* set DF bit on egress packets */ +/* #endif */ + +# define BIO_CTRL_DGRAM_QUERY_MTU 40/* as kernel for current MTU */ +# define BIO_CTRL_DGRAM_GET_FALLBACK_MTU 47 +# define BIO_CTRL_DGRAM_GET_MTU 41/* get cached value for MTU */ +# define BIO_CTRL_DGRAM_SET_MTU 42/* set cached value for MTU. + * want to use this if asking + * the kernel fails */ + +# define BIO_CTRL_DGRAM_MTU_EXCEEDED 43/* check whether the MTU was + * exceed in the previous write + * operation */ + +# define BIO_CTRL_DGRAM_GET_PEER 46 +# define BIO_CTRL_DGRAM_SET_PEER 44/* Destination for the data */ + +# define BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT 45/* Next DTLS handshake timeout + * to adjust socket timeouts */ +# define BIO_CTRL_DGRAM_SET_DONT_FRAG 48 + +# define BIO_CTRL_DGRAM_GET_MTU_OVERHEAD 49 + +# ifndef OPENSSL_NO_SCTP +/* SCTP stuff */ +# define BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE 50 +# define BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY 51 +# define BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY 52 +# define BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD 53 +# define BIO_CTRL_DGRAM_SCTP_GET_SNDINFO 60 +# define BIO_CTRL_DGRAM_SCTP_SET_SNDINFO 61 +# define BIO_CTRL_DGRAM_SCTP_GET_RCVINFO 62 +# define BIO_CTRL_DGRAM_SCTP_SET_RCVINFO 63 +# define BIO_CTRL_DGRAM_SCTP_GET_PRINFO 64 +# define BIO_CTRL_DGRAM_SCTP_SET_PRINFO 65 +# define BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN 70 +# endif + +/* modifiers */ +# define BIO_FP_READ 0x02 +# define BIO_FP_WRITE 0x04 +# define BIO_FP_APPEND 0x08 +# define BIO_FP_TEXT 0x10 + +# define BIO_FLAGS_READ 0x01 +# define BIO_FLAGS_WRITE 0x02 +# define BIO_FLAGS_IO_SPECIAL 0x04 +# define BIO_FLAGS_RWS (BIO_FLAGS_READ|BIO_FLAGS_WRITE|BIO_FLAGS_IO_SPECIAL) +# define BIO_FLAGS_SHOULD_RETRY 0x08 +# ifndef BIO_FLAGS_UPLINK +/* + * "UPLINK" flag denotes file descriptors provided by application. It + * defaults to 0, as most platforms don't require UPLINK interface. + */ +# define BIO_FLAGS_UPLINK 0 +# endif + +/* Used in BIO_gethostbyname() */ +# define BIO_GHBN_CTRL_HITS 1 +# define BIO_GHBN_CTRL_MISSES 2 +# define BIO_GHBN_CTRL_CACHE_SIZE 3 +# define BIO_GHBN_CTRL_GET_ENTRY 4 +# define BIO_GHBN_CTRL_FLUSH 5 + +/* Mostly used in the SSL BIO */ +/*- + * Not used anymore + * #define BIO_FLAGS_PROTOCOL_DELAYED_READ 0x10 + * #define BIO_FLAGS_PROTOCOL_DELAYED_WRITE 0x20 + * #define BIO_FLAGS_PROTOCOL_STARTUP 0x40 + */ + +# define BIO_FLAGS_BASE64_NO_NL 0x100 + +/* + * This is used with memory BIOs: it means we shouldn't free up or change the + * data in any way. + */ +# define BIO_FLAGS_MEM_RDONLY 0x200 + +typedef struct bio_st BIO; + +void BIO_set_flags(BIO *b, int flags); +int BIO_test_flags(const BIO *b, int flags); +void BIO_clear_flags(BIO *b, int flags); + +# define BIO_get_flags(b) BIO_test_flags(b, ~(0x0)) +# define BIO_set_retry_special(b) \ + BIO_set_flags(b, (BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY)) +# define BIO_set_retry_read(b) \ + BIO_set_flags(b, (BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY)) +# define BIO_set_retry_write(b) \ + BIO_set_flags(b, (BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY)) + +/* These are normally used internally in BIOs */ +# define BIO_clear_retry_flags(b) \ + BIO_clear_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY)) +# define BIO_get_retry_flags(b) \ + BIO_test_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY)) + +/* These should be used by the application to tell why we should retry */ +# define BIO_should_read(a) BIO_test_flags(a, BIO_FLAGS_READ) +# define BIO_should_write(a) BIO_test_flags(a, BIO_FLAGS_WRITE) +# define BIO_should_io_special(a) BIO_test_flags(a, BIO_FLAGS_IO_SPECIAL) +# define BIO_retry_type(a) BIO_test_flags(a, BIO_FLAGS_RWS) +# define BIO_should_retry(a) BIO_test_flags(a, BIO_FLAGS_SHOULD_RETRY) + +/* + * The next three are used in conjunction with the BIO_should_io_special() + * condition. After this returns true, BIO *BIO_get_retry_BIO(BIO *bio, int + * *reason); will walk the BIO stack and return the 'reason' for the special + * and the offending BIO. Given a BIO, BIO_get_retry_reason(bio) will return + * the code. + */ +/* + * Returned from the SSL bio when the certificate retrieval code had an error + */ +# define BIO_RR_SSL_X509_LOOKUP 0x01 +/* Returned from the connect BIO when a connect would have blocked */ +# define BIO_RR_CONNECT 0x02 +/* Returned from the accept BIO when an accept would have blocked */ +# define BIO_RR_ACCEPT 0x03 + +/* These are passed by the BIO callback */ +# define BIO_CB_FREE 0x01 +# define BIO_CB_READ 0x02 +# define BIO_CB_WRITE 0x03 +# define BIO_CB_PUTS 0x04 +# define BIO_CB_GETS 0x05 +# define BIO_CB_CTRL 0x06 + +/* + * The callback is called before and after the underling operation, The + * BIO_CB_RETURN flag indicates if it is after the call + */ +# define BIO_CB_RETURN 0x80 +# define BIO_CB_return(a) ((a)|BIO_CB_RETURN) +# define BIO_cb_pre(a) (!((a)&BIO_CB_RETURN)) +# define BIO_cb_post(a) ((a)&BIO_CB_RETURN) + +long (*BIO_get_callback(const BIO *b)) (struct bio_st *, int, const char *, + int, long, long); +void BIO_set_callback(BIO *b, + long (*callback) (struct bio_st *, int, const char *, + int, long, long)); +char *BIO_get_callback_arg(const BIO *b); +void BIO_set_callback_arg(BIO *b, char *arg); + +const char *BIO_method_name(const BIO *b); +int BIO_method_type(const BIO *b); + +typedef void bio_info_cb (struct bio_st *, int, const char *, int, long, + long); + +typedef struct bio_method_st { + int type; + const char *name; + int (*bwrite) (BIO *, const char *, int); + int (*bread) (BIO *, char *, int); + int (*bputs) (BIO *, const char *); + int (*bgets) (BIO *, char *, int); + long (*ctrl) (BIO *, int, long, void *); + int (*create) (BIO *); + int (*destroy) (BIO *); + long (*callback_ctrl) (BIO *, int, bio_info_cb *); +} BIO_METHOD; + +struct bio_st { + BIO_METHOD *method; + /* bio, mode, argp, argi, argl, ret */ + long (*callback) (struct bio_st *, int, const char *, int, long, long); + char *cb_arg; /* first argument for the callback */ + int init; + int shutdown; + int flags; /* extra storage */ + int retry_reason; + int num; + void *ptr; + struct bio_st *next_bio; /* used by filter BIOs */ + struct bio_st *prev_bio; /* used by filter BIOs */ + int references; + unsigned long num_read; + unsigned long num_write; + CRYPTO_EX_DATA ex_data; +}; + +DECLARE_STACK_OF(BIO) + +typedef struct bio_f_buffer_ctx_struct { + /*- + * Buffers are setup like this: + * + * <---------------------- size -----------------------> + * +---------------------------------------------------+ + * | consumed | remaining | free space | + * +---------------------------------------------------+ + * <-- off --><------- len -------> + */ + /*- BIO *bio; *//* + * this is now in the BIO struct + */ + int ibuf_size; /* how big is the input buffer */ + int obuf_size; /* how big is the output buffer */ + char *ibuf; /* the char array */ + int ibuf_len; /* how many bytes are in it */ + int ibuf_off; /* write/read offset */ + char *obuf; /* the char array */ + int obuf_len; /* how many bytes are in it */ + int obuf_off; /* write/read offset */ +} BIO_F_BUFFER_CTX; + +/* Prefix and suffix callback in ASN1 BIO */ +typedef int asn1_ps_func (BIO *b, unsigned char **pbuf, int *plen, + void *parg); + +# ifndef OPENSSL_NO_SCTP +/* SCTP parameter structs */ +struct bio_dgram_sctp_sndinfo { + uint16_t snd_sid; + uint16_t snd_flags; + uint32_t snd_ppid; + uint32_t snd_context; +}; + +struct bio_dgram_sctp_rcvinfo { + uint16_t rcv_sid; + uint16_t rcv_ssn; + uint16_t rcv_flags; + uint32_t rcv_ppid; + uint32_t rcv_tsn; + uint32_t rcv_cumtsn; + uint32_t rcv_context; +}; + +struct bio_dgram_sctp_prinfo { + uint16_t pr_policy; + uint32_t pr_value; +}; +# endif + +/* connect BIO stuff */ +# define BIO_CONN_S_BEFORE 1 +# define BIO_CONN_S_GET_IP 2 +# define BIO_CONN_S_GET_PORT 3 +# define BIO_CONN_S_CREATE_SOCKET 4 +# define BIO_CONN_S_CONNECT 5 +# define BIO_CONN_S_OK 6 +# define BIO_CONN_S_BLOCKED_CONNECT 7 +# define BIO_CONN_S_NBIO 8 +/* + * #define BIO_CONN_get_param_hostname BIO_ctrl + */ + +# define BIO_C_SET_CONNECT 100 +# define BIO_C_DO_STATE_MACHINE 101 +# define BIO_C_SET_NBIO 102 +# define BIO_C_SET_PROXY_PARAM 103 +# define BIO_C_SET_FD 104 +# define BIO_C_GET_FD 105 +# define BIO_C_SET_FILE_PTR 106 +# define BIO_C_GET_FILE_PTR 107 +# define BIO_C_SET_FILENAME 108 +# define BIO_C_SET_SSL 109 +# define BIO_C_GET_SSL 110 +# define BIO_C_SET_MD 111 +# define BIO_C_GET_MD 112 +# define BIO_C_GET_CIPHER_STATUS 113 +# define BIO_C_SET_BUF_MEM 114 +# define BIO_C_GET_BUF_MEM_PTR 115 +# define BIO_C_GET_BUFF_NUM_LINES 116 +# define BIO_C_SET_BUFF_SIZE 117 +# define BIO_C_SET_ACCEPT 118 +# define BIO_C_SSL_MODE 119 +# define BIO_C_GET_MD_CTX 120 +# define BIO_C_GET_PROXY_PARAM 121 +# define BIO_C_SET_BUFF_READ_DATA 122/* data to read first */ +# define BIO_C_GET_CONNECT 123 +# define BIO_C_GET_ACCEPT 124 +# define BIO_C_SET_SSL_RENEGOTIATE_BYTES 125 +# define BIO_C_GET_SSL_NUM_RENEGOTIATES 126 +# define BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT 127 +# define BIO_C_FILE_SEEK 128 +# define BIO_C_GET_CIPHER_CTX 129 +# define BIO_C_SET_BUF_MEM_EOF_RETURN 130/* return end of input + * value */ +# define BIO_C_SET_BIND_MODE 131 +# define BIO_C_GET_BIND_MODE 132 +# define BIO_C_FILE_TELL 133 +# define BIO_C_GET_SOCKS 134 +# define BIO_C_SET_SOCKS 135 + +# define BIO_C_SET_WRITE_BUF_SIZE 136/* for BIO_s_bio */ +# define BIO_C_GET_WRITE_BUF_SIZE 137 +# define BIO_C_MAKE_BIO_PAIR 138 +# define BIO_C_DESTROY_BIO_PAIR 139 +# define BIO_C_GET_WRITE_GUARANTEE 140 +# define BIO_C_GET_READ_REQUEST 141 +# define BIO_C_SHUTDOWN_WR 142 +# define BIO_C_NREAD0 143 +# define BIO_C_NREAD 144 +# define BIO_C_NWRITE0 145 +# define BIO_C_NWRITE 146 +# define BIO_C_RESET_READ_REQUEST 147 +# define BIO_C_SET_MD_CTX 148 + +# define BIO_C_SET_PREFIX 149 +# define BIO_C_GET_PREFIX 150 +# define BIO_C_SET_SUFFIX 151 +# define BIO_C_GET_SUFFIX 152 + +# define BIO_C_SET_EX_ARG 153 +# define BIO_C_GET_EX_ARG 154 + +# define BIO_set_app_data(s,arg) BIO_set_ex_data(s,0,arg) +# define BIO_get_app_data(s) BIO_get_ex_data(s,0) + +/* BIO_s_connect() and BIO_s_socks4a_connect() */ +# define BIO_set_conn_hostname(b,name) BIO_ctrl(b,BIO_C_SET_CONNECT,0,(char *)name) +# define BIO_set_conn_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,1,(char *)port) +# define BIO_set_conn_ip(b,ip) BIO_ctrl(b,BIO_C_SET_CONNECT,2,(char *)ip) +# define BIO_set_conn_int_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,3,(char *)port) +# define BIO_get_conn_hostname(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,0) +# define BIO_get_conn_port(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,1) +# define BIO_get_conn_ip(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,2) +# define BIO_get_conn_int_port(b) BIO_ctrl(b,BIO_C_GET_CONNECT,3,NULL) + +# define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) + +/* BIO_s_accept() */ +# define BIO_set_accept_port(b,name) BIO_ctrl(b,BIO_C_SET_ACCEPT,0,(char *)name) +# define BIO_get_accept_port(b) BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,0) +/* #define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) */ +# define BIO_set_nbio_accept(b,n) BIO_ctrl(b,BIO_C_SET_ACCEPT,1,(n)?(void *)"a":NULL) +# define BIO_set_accept_bios(b,bio) BIO_ctrl(b,BIO_C_SET_ACCEPT,2,(char *)bio) + +# define BIO_BIND_NORMAL 0 +# define BIO_BIND_REUSEADDR_IF_UNUSED 1 +# define BIO_BIND_REUSEADDR 2 +# define BIO_set_bind_mode(b,mode) BIO_ctrl(b,BIO_C_SET_BIND_MODE,mode,NULL) +# define BIO_get_bind_mode(b,mode) BIO_ctrl(b,BIO_C_GET_BIND_MODE,0,NULL) + +/* BIO_s_accept() and BIO_s_connect() */ +# define BIO_do_connect(b) BIO_do_handshake(b) +# define BIO_do_accept(b) BIO_do_handshake(b) +# define BIO_do_handshake(b) BIO_ctrl(b,BIO_C_DO_STATE_MACHINE,0,NULL) + +/* BIO_s_proxy_client() */ +# define BIO_set_url(b,url) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,0,(char *)(url)) +# define BIO_set_proxies(b,p) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,1,(char *)(p)) +/* BIO_set_nbio(b,n) */ +# define BIO_set_filter_bio(b,s) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,2,(char *)(s)) +/* BIO *BIO_get_filter_bio(BIO *bio); */ +# define BIO_set_proxy_cb(b,cb) BIO_callback_ctrl(b,BIO_C_SET_PROXY_PARAM,3,(void *(*cb)())) +# define BIO_set_proxy_header(b,sk) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,4,(char *)sk) +# define BIO_set_no_connect_return(b,bool) BIO_int_ctrl(b,BIO_C_SET_PROXY_PARAM,5,bool) + +# define BIO_get_proxy_header(b,skp) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,0,(char *)skp) +# define BIO_get_proxies(b,pxy_p) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,1,(char *)(pxy_p)) +# define BIO_get_url(b,url) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,2,(char *)(url)) +# define BIO_get_no_connect_return(b) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,5,NULL) + +/* BIO_s_datagram(), BIO_s_fd(), BIO_s_socket(), BIO_s_accept() and BIO_s_connect() */ +# define BIO_set_fd(b,fd,c) BIO_int_ctrl(b,BIO_C_SET_FD,c,fd) +# define BIO_get_fd(b,c) BIO_ctrl(b,BIO_C_GET_FD,0,(char *)c) + +/* BIO_s_file() */ +# define BIO_set_fp(b,fp,c) BIO_ctrl(b,BIO_C_SET_FILE_PTR,c,(char *)fp) +# define BIO_get_fp(b,fpp) BIO_ctrl(b,BIO_C_GET_FILE_PTR,0,(char *)fpp) + +/* BIO_s_fd() and BIO_s_file() */ +# define BIO_seek(b,ofs) (int)BIO_ctrl(b,BIO_C_FILE_SEEK,ofs,NULL) +# define BIO_tell(b) (int)BIO_ctrl(b,BIO_C_FILE_TELL,0,NULL) + +/* + * name is cast to lose const, but might be better to route through a + * function so we can do it safely + */ +# ifdef CONST_STRICT +/* + * If you are wondering why this isn't defined, its because CONST_STRICT is + * purely a compile-time kludge to allow const to be checked. + */ +int BIO_read_filename(BIO *b, const char *name); +# else +# define BIO_read_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_READ,(char *)name) +# endif +# define BIO_write_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_WRITE,name) +# define BIO_append_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_APPEND,name) +# define BIO_rw_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_READ|BIO_FP_WRITE,name) + +/* + * WARNING WARNING, this ups the reference count on the read bio of the SSL + * structure. This is because the ssl read BIO is now pointed to by the + * next_bio field in the bio. So when you free the BIO, make sure you are + * doing a BIO_free_all() to catch the underlying BIO. + */ +# define BIO_set_ssl(b,ssl,c) BIO_ctrl(b,BIO_C_SET_SSL,c,(char *)ssl) +# define BIO_get_ssl(b,sslp) BIO_ctrl(b,BIO_C_GET_SSL,0,(char *)sslp) +# define BIO_set_ssl_mode(b,client) BIO_ctrl(b,BIO_C_SSL_MODE,client,NULL) +# define BIO_set_ssl_renegotiate_bytes(b,num) \ + BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_BYTES,num,NULL); +# define BIO_get_num_renegotiates(b) \ + BIO_ctrl(b,BIO_C_GET_SSL_NUM_RENEGOTIATES,0,NULL); +# define BIO_set_ssl_renegotiate_timeout(b,seconds) \ + BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT,seconds,NULL); + +/* defined in evp.h */ +/* #define BIO_set_md(b,md) BIO_ctrl(b,BIO_C_SET_MD,1,(char *)md) */ + +# define BIO_get_mem_data(b,pp) BIO_ctrl(b,BIO_CTRL_INFO,0,(char *)pp) +# define BIO_set_mem_buf(b,bm,c) BIO_ctrl(b,BIO_C_SET_BUF_MEM,c,(char *)bm) +# define BIO_get_mem_ptr(b,pp) BIO_ctrl(b,BIO_C_GET_BUF_MEM_PTR,0,(char *)pp) +# define BIO_set_mem_eof_return(b,v) \ + BIO_ctrl(b,BIO_C_SET_BUF_MEM_EOF_RETURN,v,NULL) + +/* For the BIO_f_buffer() type */ +# define BIO_get_buffer_num_lines(b) BIO_ctrl(b,BIO_C_GET_BUFF_NUM_LINES,0,NULL) +# define BIO_set_buffer_size(b,size) BIO_ctrl(b,BIO_C_SET_BUFF_SIZE,size,NULL) +# define BIO_set_read_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,0) +# define BIO_set_write_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,1) +# define BIO_set_buffer_read_data(b,buf,num) BIO_ctrl(b,BIO_C_SET_BUFF_READ_DATA,num,buf) + +/* Don't use the next one unless you know what you are doing :-) */ +# define BIO_dup_state(b,ret) BIO_ctrl(b,BIO_CTRL_DUP,0,(char *)(ret)) + +# define BIO_reset(b) (int)BIO_ctrl(b,BIO_CTRL_RESET,0,NULL) +# define BIO_eof(b) (int)BIO_ctrl(b,BIO_CTRL_EOF,0,NULL) +# define BIO_set_close(b,c) (int)BIO_ctrl(b,BIO_CTRL_SET_CLOSE,(c),NULL) +# define BIO_get_close(b) (int)BIO_ctrl(b,BIO_CTRL_GET_CLOSE,0,NULL) +# define BIO_pending(b) (int)BIO_ctrl(b,BIO_CTRL_PENDING,0,NULL) +# define BIO_wpending(b) (int)BIO_ctrl(b,BIO_CTRL_WPENDING,0,NULL) +/* ...pending macros have inappropriate return type */ +size_t BIO_ctrl_pending(BIO *b); +size_t BIO_ctrl_wpending(BIO *b); +# define BIO_flush(b) (int)BIO_ctrl(b,BIO_CTRL_FLUSH,0,NULL) +# define BIO_get_info_callback(b,cbp) (int)BIO_ctrl(b,BIO_CTRL_GET_CALLBACK,0, \ + cbp) +# define BIO_set_info_callback(b,cb) (int)BIO_callback_ctrl(b,BIO_CTRL_SET_CALLBACK,cb) + +/* For the BIO_f_buffer() type */ +# define BIO_buffer_get_num_lines(b) BIO_ctrl(b,BIO_CTRL_GET,0,NULL) + +/* For BIO_s_bio() */ +# define BIO_set_write_buf_size(b,size) (int)BIO_ctrl(b,BIO_C_SET_WRITE_BUF_SIZE,size,NULL) +# define BIO_get_write_buf_size(b,size) (size_t)BIO_ctrl(b,BIO_C_GET_WRITE_BUF_SIZE,size,NULL) +# define BIO_make_bio_pair(b1,b2) (int)BIO_ctrl(b1,BIO_C_MAKE_BIO_PAIR,0,b2) +# define BIO_destroy_bio_pair(b) (int)BIO_ctrl(b,BIO_C_DESTROY_BIO_PAIR,0,NULL) +# define BIO_shutdown_wr(b) (int)BIO_ctrl(b, BIO_C_SHUTDOWN_WR, 0, NULL) +/* macros with inappropriate type -- but ...pending macros use int too: */ +# define BIO_get_write_guarantee(b) (int)BIO_ctrl(b,BIO_C_GET_WRITE_GUARANTEE,0,NULL) +# define BIO_get_read_request(b) (int)BIO_ctrl(b,BIO_C_GET_READ_REQUEST,0,NULL) +size_t BIO_ctrl_get_write_guarantee(BIO *b); +size_t BIO_ctrl_get_read_request(BIO *b); +int BIO_ctrl_reset_read_request(BIO *b); + +/* ctrl macros for dgram */ +# define BIO_ctrl_dgram_connect(b,peer) \ + (int)BIO_ctrl(b,BIO_CTRL_DGRAM_CONNECT,0, (char *)peer) +# define BIO_ctrl_set_connected(b, state, peer) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_CONNECTED, state, (char *)peer) +# define BIO_dgram_recv_timedout(b) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP, 0, NULL) +# define BIO_dgram_send_timedout(b) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP, 0, NULL) +# define BIO_dgram_get_peer(b,peer) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_PEER, 0, (char *)peer) +# define BIO_dgram_set_peer(b,peer) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, (char *)peer) +# define BIO_dgram_get_mtu_overhead(b) \ + (unsigned int)BIO_ctrl((b), BIO_CTRL_DGRAM_GET_MTU_OVERHEAD, 0, NULL) + +/* These two aren't currently implemented */ +/* int BIO_get_ex_num(BIO *bio); */ +/* void BIO_set_ex_free_func(BIO *bio,int idx,void (*cb)()); */ +int BIO_set_ex_data(BIO *bio, int idx, void *data); +void *BIO_get_ex_data(BIO *bio, int idx); +int BIO_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +unsigned long BIO_number_read(BIO *bio); +unsigned long BIO_number_written(BIO *bio); + +/* For BIO_f_asn1() */ +int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix, + asn1_ps_func *prefix_free); +int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix, + asn1_ps_func **pprefix_free); +int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix, + asn1_ps_func *suffix_free); +int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix, + asn1_ps_func **psuffix_free); + +# ifndef OPENSSL_NO_FP_API +BIO_METHOD *BIO_s_file(void); +BIO *BIO_new_file(const char *filename, const char *mode); +BIO *BIO_new_fp(FILE *stream, int close_flag); +# define BIO_s_file_internal BIO_s_file +# endif +BIO *BIO_new(BIO_METHOD *type); +int BIO_set(BIO *a, BIO_METHOD *type); +int BIO_free(BIO *a); +void BIO_vfree(BIO *a); +int BIO_read(BIO *b, void *data, int len); +int BIO_gets(BIO *bp, char *buf, int size); +int BIO_write(BIO *b, const void *data, int len); +int BIO_puts(BIO *bp, const char *buf); +int BIO_indent(BIO *b, int indent, int max); +long BIO_ctrl(BIO *bp, int cmd, long larg, void *parg); +long BIO_callback_ctrl(BIO *b, int cmd, + void (*fp) (struct bio_st *, int, const char *, int, + long, long)); +char *BIO_ptr_ctrl(BIO *bp, int cmd, long larg); +long BIO_int_ctrl(BIO *bp, int cmd, long larg, int iarg); +BIO *BIO_push(BIO *b, BIO *append); +BIO *BIO_pop(BIO *b); +void BIO_free_all(BIO *a); +BIO *BIO_find_type(BIO *b, int bio_type); +BIO *BIO_next(BIO *b); +BIO *BIO_get_retry_BIO(BIO *bio, int *reason); +int BIO_get_retry_reason(BIO *bio); +BIO *BIO_dup_chain(BIO *in); + +int BIO_nread0(BIO *bio, char **buf); +int BIO_nread(BIO *bio, char **buf, int num); +int BIO_nwrite0(BIO *bio, char **buf); +int BIO_nwrite(BIO *bio, char **buf, int num); + +long BIO_debug_callback(BIO *bio, int cmd, const char *argp, int argi, + long argl, long ret); + +BIO_METHOD *BIO_s_mem(void); +BIO *BIO_new_mem_buf(const void *buf, int len); +BIO_METHOD *BIO_s_socket(void); +BIO_METHOD *BIO_s_connect(void); +BIO_METHOD *BIO_s_accept(void); +BIO_METHOD *BIO_s_fd(void); +# ifndef OPENSSL_SYS_OS2 +BIO_METHOD *BIO_s_log(void); +# endif +BIO_METHOD *BIO_s_bio(void); +BIO_METHOD *BIO_s_null(void); +BIO_METHOD *BIO_f_null(void); +BIO_METHOD *BIO_f_buffer(void); +# ifdef OPENSSL_SYS_VMS +BIO_METHOD *BIO_f_linebuffer(void); +# endif +BIO_METHOD *BIO_f_nbio_test(void); +# ifndef OPENSSL_NO_DGRAM +BIO_METHOD *BIO_s_datagram(void); +# ifndef OPENSSL_NO_SCTP +BIO_METHOD *BIO_s_datagram_sctp(void); +# endif +# endif + +/* BIO_METHOD *BIO_f_ber(void); */ + +int BIO_sock_should_retry(int i); +int BIO_sock_non_fatal_error(int error); +int BIO_dgram_non_fatal_error(int error); + +int BIO_fd_should_retry(int i); +int BIO_fd_non_fatal_error(int error); +int BIO_dump_cb(int (*cb) (const void *data, size_t len, void *u), + void *u, const char *s, int len); +int BIO_dump_indent_cb(int (*cb) (const void *data, size_t len, void *u), + void *u, const char *s, int len, int indent); +int BIO_dump(BIO *b, const char *bytes, int len); +int BIO_dump_indent(BIO *b, const char *bytes, int len, int indent); +# ifndef OPENSSL_NO_FP_API +int BIO_dump_fp(FILE *fp, const char *s, int len); +int BIO_dump_indent_fp(FILE *fp, const char *s, int len, int indent); +# endif +int BIO_hex_string(BIO *out, int indent, int width, unsigned char *data, + int datalen); + +struct hostent *BIO_gethostbyname(const char *name); +/*- + * We might want a thread-safe interface too: + * struct hostent *BIO_gethostbyname_r(const char *name, + * struct hostent *result, void *buffer, size_t buflen); + * or something similar (caller allocates a struct hostent, + * pointed to by "result", and additional buffer space for the various + * substructures; if the buffer does not suffice, NULL is returned + * and an appropriate error code is set). + */ +int BIO_sock_error(int sock); +int BIO_socket_ioctl(int fd, long type, void *arg); +int BIO_socket_nbio(int fd, int mode); +int BIO_get_port(const char *str, unsigned short *port_ptr); +int BIO_get_host_ip(const char *str, unsigned char *ip); +int BIO_get_accept_socket(char *host_port, int mode); +int BIO_accept(int sock, char **ip_port); +int BIO_sock_init(void); +void BIO_sock_cleanup(void); +int BIO_set_tcp_ndelay(int sock, int turn_on); + +BIO *BIO_new_socket(int sock, int close_flag); +BIO *BIO_new_dgram(int fd, int close_flag); +# ifndef OPENSSL_NO_SCTP +BIO *BIO_new_dgram_sctp(int fd, int close_flag); +int BIO_dgram_is_sctp(BIO *bio); +int BIO_dgram_sctp_notification_cb(BIO *b, + void (*handle_notifications) (BIO *bio, + void + *context, + void *buf), + void *context); +int BIO_dgram_sctp_wait_for_dry(BIO *b); +int BIO_dgram_sctp_msg_waiting(BIO *b); +# endif +BIO *BIO_new_fd(int fd, int close_flag); +BIO *BIO_new_connect(const char *host_port); +BIO *BIO_new_accept(const char *host_port); + +int BIO_new_bio_pair(BIO **bio1, size_t writebuf1, + BIO **bio2, size_t writebuf2); +/* + * If successful, returns 1 and in *bio1, *bio2 two BIO pair endpoints. + * Otherwise returns 0 and sets *bio1 and *bio2 to NULL. Size 0 uses default + * value. + */ + +void BIO_copy_next_retry(BIO *b); + +/* + * long BIO_ghbn_ctrl(int cmd,int iarg,char *parg); + */ + +# ifdef __GNUC__ +# define __bio_h__attr__ __attribute__ +# else +# define __bio_h__attr__(x) +# endif +int BIO_printf(BIO *bio, const char *format, ...) +__bio_h__attr__((__format__(__printf__, 2, 3))); +int BIO_vprintf(BIO *bio, const char *format, va_list args) +__bio_h__attr__((__format__(__printf__, 2, 0))); +int BIO_snprintf(char *buf, size_t n, const char *format, ...) +__bio_h__attr__((__format__(__printf__, 3, 4))); +int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args) +__bio_h__attr__((__format__(__printf__, 3, 0))); +# undef __bio_h__attr__ + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_BIO_strings(void); + +/* Error codes for the BIO functions. */ + +/* Function codes. */ +# define BIO_F_ACPT_STATE 100 +# define BIO_F_BIO_ACCEPT 101 +# define BIO_F_BIO_BER_GET_HEADER 102 +# define BIO_F_BIO_CALLBACK_CTRL 131 +# define BIO_F_BIO_CTRL 103 +# define BIO_F_BIO_GETHOSTBYNAME 120 +# define BIO_F_BIO_GETS 104 +# define BIO_F_BIO_GET_ACCEPT_SOCKET 105 +# define BIO_F_BIO_GET_HOST_IP 106 +# define BIO_F_BIO_GET_PORT 107 +# define BIO_F_BIO_MAKE_PAIR 121 +# define BIO_F_BIO_NEW 108 +# define BIO_F_BIO_NEW_FILE 109 +# define BIO_F_BIO_NEW_MEM_BUF 126 +# define BIO_F_BIO_NREAD 123 +# define BIO_F_BIO_NREAD0 124 +# define BIO_F_BIO_NWRITE 125 +# define BIO_F_BIO_NWRITE0 122 +# define BIO_F_BIO_PUTS 110 +# define BIO_F_BIO_READ 111 +# define BIO_F_BIO_SOCK_INIT 112 +# define BIO_F_BIO_WRITE 113 +# define BIO_F_BUFFER_CTRL 114 +# define BIO_F_CONN_CTRL 127 +# define BIO_F_CONN_STATE 115 +# define BIO_F_DGRAM_SCTP_READ 132 +# define BIO_F_DGRAM_SCTP_WRITE 133 +# define BIO_F_FILE_CTRL 116 +# define BIO_F_FILE_READ 130 +# define BIO_F_LINEBUFFER_CTRL 129 +# define BIO_F_MEM_READ 128 +# define BIO_F_MEM_WRITE 117 +# define BIO_F_SSL_NEW 118 +# define BIO_F_WSASTARTUP 119 + +/* Reason codes. */ +# define BIO_R_ACCEPT_ERROR 100 +# define BIO_R_BAD_FOPEN_MODE 101 +# define BIO_R_BAD_HOSTNAME_LOOKUP 102 +# define BIO_R_BROKEN_PIPE 124 +# define BIO_R_CONNECT_ERROR 103 +# define BIO_R_EOF_ON_MEMORY_BIO 127 +# define BIO_R_ERROR_SETTING_NBIO 104 +# define BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET 105 +# define BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET 106 +# define BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET 107 +# define BIO_R_INVALID_ARGUMENT 125 +# define BIO_R_INVALID_IP_ADDRESS 108 +# define BIO_R_IN_USE 123 +# define BIO_R_KEEPALIVE 109 +# define BIO_R_NBIO_CONNECT_ERROR 110 +# define BIO_R_NO_ACCEPT_PORT_SPECIFIED 111 +# define BIO_R_NO_HOSTNAME_SPECIFIED 112 +# define BIO_R_NO_PORT_DEFINED 113 +# define BIO_R_NO_PORT_SPECIFIED 114 +# define BIO_R_NO_SUCH_FILE 128 +# define BIO_R_NULL_PARAMETER 115 +# define BIO_R_TAG_MISMATCH 116 +# define BIO_R_UNABLE_TO_BIND_SOCKET 117 +# define BIO_R_UNABLE_TO_CREATE_SOCKET 118 +# define BIO_R_UNABLE_TO_LISTEN_SOCKET 119 +# define BIO_R_UNINITIALIZED 120 +# define BIO_R_UNSUPPORTED_METHOD 121 +# define BIO_R_WRITE_TO_READ_ONLY_BIO 126 +# define BIO_R_WSASTARTUP 122 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/blowfish.h b/OSlibs/ios/include/openssl/blowfish.h new file mode 100755 index 000000000..832930272 --- /dev/null +++ b/OSlibs/ios/include/openssl/blowfish.h @@ -0,0 +1,130 @@ +/* crypto/bf/blowfish.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_BLOWFISH_H +# define HEADER_BLOWFISH_H + +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# ifdef OPENSSL_NO_BF +# error BF is disabled. +# endif + +# define BF_ENCRYPT 1 +# define BF_DECRYPT 0 + +/*- + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! BF_LONG has to be at least 32 bits wide. If it's wider, then ! + * ! BF_LONG_LOG2 has to be defined along. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ + +# if defined(__LP32__) +# define BF_LONG unsigned long +# elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__) +# define BF_LONG unsigned long +# define BF_LONG_LOG2 3 +/* + * _CRAY note. I could declare short, but I have no idea what impact + * does it have on performance on none-T3E machines. I could declare + * int, but at least on C90 sizeof(int) can be chosen at compile time. + * So I've chosen long... + * + */ +# else +# define BF_LONG unsigned int +# endif + +# define BF_ROUNDS 16 +# define BF_BLOCK 8 + +typedef struct bf_key_st { + BF_LONG P[BF_ROUNDS + 2]; + BF_LONG S[4 * 256]; +} BF_KEY; + +# ifdef OPENSSL_FIPS +void private_BF_set_key(BF_KEY *key, int len, const unsigned char *data); +# endif +void BF_set_key(BF_KEY *key, int len, const unsigned char *data); + +void BF_encrypt(BF_LONG *data, const BF_KEY *key); +void BF_decrypt(BF_LONG *data, const BF_KEY *key); + +void BF_ecb_encrypt(const unsigned char *in, unsigned char *out, + const BF_KEY *key, int enc); +void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, + const BF_KEY *schedule, unsigned char *ivec, int enc); +void BF_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, const BF_KEY *schedule, + unsigned char *ivec, int *num, int enc); +void BF_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, const BF_KEY *schedule, + unsigned char *ivec, int *num); +const char *BF_options(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/OSlibs/ios/include/openssl/bn.h b/OSlibs/ios/include/openssl/bn.h new file mode 100755 index 000000000..86264ae63 --- /dev/null +++ b/OSlibs/ios/include/openssl/bn.h @@ -0,0 +1,949 @@ +/* crypto/bn/bn.h */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the Eric Young open source + * license provided above. + * + * The binary polynomial arithmetic software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. + * + */ + +#ifndef HEADER_BN_H +# define HEADER_BN_H + +# include +# include +# ifndef OPENSSL_NO_FP_API +# include /* FILE */ +# endif +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * These preprocessor symbols control various aspects of the bignum headers + * and library code. They're not defined by any "normal" configuration, as + * they are intended for development and testing purposes. NB: defining all + * three can be useful for debugging application code as well as openssl + * itself. BN_DEBUG - turn on various debugging alterations to the bignum + * code BN_DEBUG_RAND - uses random poisoning of unused words to trip up + * mismanagement of bignum internals. You must also define BN_DEBUG. + */ +/* #define BN_DEBUG */ +/* #define BN_DEBUG_RAND */ + +# ifndef OPENSSL_SMALL_FOOTPRINT +# define BN_MUL_COMBA +# define BN_SQR_COMBA +# define BN_RECURSION +# endif + +/* + * This next option uses the C libraries (2 word)/(1 word) function. If it is + * not defined, I use my C version (which is slower). The reason for this + * flag is that when the particular C compiler library routine is used, and + * the library is linked with a different compiler, the library is missing. + * This mostly happens when the library is built with gcc and then linked + * using normal cc. This would be a common occurrence because gcc normally + * produces code that is 2 times faster than system compilers for the big + * number stuff. For machines with only one compiler (or shared libraries), + * this should be on. Again this in only really a problem on machines using + * "long long's", are 32bit, and are not using my assembler code. + */ +# if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || \ + defined(OPENSSL_SYS_WIN32) || defined(linux) +# ifndef BN_DIV2W +# define BN_DIV2W +# endif +# endif + +/* + * assuming long is 64bit - this is the DEC Alpha unsigned long long is only + * 64 bits :-(, don't define BN_LLONG for the DEC Alpha + */ +# ifdef SIXTY_FOUR_BIT_LONG +# define BN_ULLONG unsigned long long +# define BN_ULONG unsigned long +# define BN_LONG long +# define BN_BITS 128 +# define BN_BYTES 8 +# define BN_BITS2 64 +# define BN_BITS4 32 +# define BN_MASK (0xffffffffffffffffffffffffffffffffLL) +# define BN_MASK2 (0xffffffffffffffffL) +# define BN_MASK2l (0xffffffffL) +# define BN_MASK2h (0xffffffff00000000L) +# define BN_MASK2h1 (0xffffffff80000000L) +# define BN_TBIT (0x8000000000000000L) +# define BN_DEC_CONV (10000000000000000000UL) +# define BN_DEC_FMT1 "%lu" +# define BN_DEC_FMT2 "%019lu" +# define BN_DEC_NUM 19 +# define BN_HEX_FMT1 "%lX" +# define BN_HEX_FMT2 "%016lX" +# endif + +/* + * This is where the long long data type is 64 bits, but long is 32. For + * machines where there are 64bit registers, this is the mode to use. IRIX, + * on R4000 and above should use this mode, along with the relevant assembler + * code :-). Do NOT define BN_LLONG. + */ +# ifdef SIXTY_FOUR_BIT +# undef BN_LLONG +# undef BN_ULLONG +# define BN_ULONG unsigned long long +# define BN_LONG long long +# define BN_BITS 128 +# define BN_BYTES 8 +# define BN_BITS2 64 +# define BN_BITS4 32 +# define BN_MASK2 (0xffffffffffffffffLL) +# define BN_MASK2l (0xffffffffL) +# define BN_MASK2h (0xffffffff00000000LL) +# define BN_MASK2h1 (0xffffffff80000000LL) +# define BN_TBIT (0x8000000000000000LL) +# define BN_DEC_CONV (10000000000000000000ULL) +# define BN_DEC_FMT1 "%llu" +# define BN_DEC_FMT2 "%019llu" +# define BN_DEC_NUM 19 +# define BN_HEX_FMT1 "%llX" +# define BN_HEX_FMT2 "%016llX" +# endif + +# ifdef THIRTY_TWO_BIT +# ifdef BN_LLONG +# if defined(_WIN32) && !defined(__GNUC__) +# define BN_ULLONG unsigned __int64 +# define BN_MASK (0xffffffffffffffffI64) +# else +# define BN_ULLONG unsigned long long +# define BN_MASK (0xffffffffffffffffLL) +# endif +# endif +# define BN_ULONG unsigned int +# define BN_LONG int +# define BN_BITS 64 +# define BN_BYTES 4 +# define BN_BITS2 32 +# define BN_BITS4 16 +# define BN_MASK2 (0xffffffffL) +# define BN_MASK2l (0xffff) +# define BN_MASK2h1 (0xffff8000L) +# define BN_MASK2h (0xffff0000L) +# define BN_TBIT (0x80000000L) +# define BN_DEC_CONV (1000000000L) +# define BN_DEC_FMT1 "%u" +# define BN_DEC_FMT2 "%09u" +# define BN_DEC_NUM 9 +# define BN_HEX_FMT1 "%X" +# define BN_HEX_FMT2 "%08X" +# endif + +# define BN_DEFAULT_BITS 1280 + +# define BN_FLG_MALLOCED 0x01 +# define BN_FLG_STATIC_DATA 0x02 + +/* + * avoid leaking exponent information through timing, + * BN_mod_exp_mont() will call BN_mod_exp_mont_consttime, + * BN_div() will call BN_div_no_branch, + * BN_mod_inverse() will call BN_mod_inverse_no_branch. + */ +# define BN_FLG_CONSTTIME 0x04 + +# ifdef OPENSSL_NO_DEPRECATED +/* deprecated name for the flag */ +# define BN_FLG_EXP_CONSTTIME BN_FLG_CONSTTIME +/* + * avoid leaking exponent information through timings + * (BN_mod_exp_mont() will call BN_mod_exp_mont_consttime) + */ +# endif + +# ifndef OPENSSL_NO_DEPRECATED +# define BN_FLG_FREE 0x8000 + /* used for debuging */ +# endif +# define BN_set_flags(b,n) ((b)->flags|=(n)) +# define BN_get_flags(b,n) ((b)->flags&(n)) + +/* + * get a clone of a BIGNUM with changed flags, for *temporary* use only (the + * two BIGNUMs cannot not be used in parallel!) + */ +# define BN_with_flags(dest,b,n) ((dest)->d=(b)->d, \ + (dest)->top=(b)->top, \ + (dest)->dmax=(b)->dmax, \ + (dest)->neg=(b)->neg, \ + (dest)->flags=(((dest)->flags & BN_FLG_MALLOCED) \ + | ((b)->flags & ~BN_FLG_MALLOCED) \ + | BN_FLG_STATIC_DATA \ + | (n))) + +/* Already declared in ossl_typ.h */ +# if 0 +typedef struct bignum_st BIGNUM; +/* Used for temp variables (declaration hidden in bn_lcl.h) */ +typedef struct bignum_ctx BN_CTX; +typedef struct bn_blinding_st BN_BLINDING; +typedef struct bn_mont_ctx_st BN_MONT_CTX; +typedef struct bn_recp_ctx_st BN_RECP_CTX; +typedef struct bn_gencb_st BN_GENCB; +# endif + +struct bignum_st { + BN_ULONG *d; /* Pointer to an array of 'BN_BITS2' bit + * chunks. */ + int top; /* Index of last used d +1. */ + /* The next are internal book keeping for bn_expand. */ + int dmax; /* Size of the d array. */ + int neg; /* one if the number is negative */ + int flags; +}; + +/* Used for montgomery multiplication */ +struct bn_mont_ctx_st { + int ri; /* number of bits in R */ + BIGNUM RR; /* used to convert to montgomery form */ + BIGNUM N; /* The modulus */ + BIGNUM Ni; /* R*(1/R mod N) - N*Ni = 1 (Ni is only + * stored for bignum algorithm) */ + BN_ULONG n0[2]; /* least significant word(s) of Ni; (type + * changed with 0.9.9, was "BN_ULONG n0;" + * before) */ + int flags; +}; + +/* + * Used for reciprocal division/mod functions It cannot be shared between + * threads + */ +struct bn_recp_ctx_st { + BIGNUM N; /* the divisor */ + BIGNUM Nr; /* the reciprocal */ + int num_bits; + int shift; + int flags; +}; + +/* Used for slow "generation" functions. */ +struct bn_gencb_st { + unsigned int ver; /* To handle binary (in)compatibility */ + void *arg; /* callback-specific data */ + union { + /* if(ver==1) - handles old style callbacks */ + void (*cb_1) (int, int, void *); + /* if(ver==2) - new callback style */ + int (*cb_2) (int, int, BN_GENCB *); + } cb; +}; +/* Wrapper function to make using BN_GENCB easier, */ +int BN_GENCB_call(BN_GENCB *cb, int a, int b); +/* Macro to populate a BN_GENCB structure with an "old"-style callback */ +# define BN_GENCB_set_old(gencb, callback, cb_arg) { \ + BN_GENCB *tmp_gencb = (gencb); \ + tmp_gencb->ver = 1; \ + tmp_gencb->arg = (cb_arg); \ + tmp_gencb->cb.cb_1 = (callback); } +/* Macro to populate a BN_GENCB structure with a "new"-style callback */ +# define BN_GENCB_set(gencb, callback, cb_arg) { \ + BN_GENCB *tmp_gencb = (gencb); \ + tmp_gencb->ver = 2; \ + tmp_gencb->arg = (cb_arg); \ + tmp_gencb->cb.cb_2 = (callback); } + +# define BN_prime_checks 0 /* default: select number of iterations based + * on the size of the number */ + +/* + * number of Miller-Rabin iterations for an error rate of less than 2^-80 for + * random 'b'-bit input, b >= 100 (taken from table 4.4 in the Handbook of + * Applied Cryptography [Menezes, van Oorschot, Vanstone; CRC Press 1996]; + * original paper: Damgaard, Landrock, Pomerance: Average case error + * estimates for the strong probable prime test. -- Math. Comp. 61 (1993) + * 177-194) + */ +# define BN_prime_checks_for_size(b) ((b) >= 1300 ? 2 : \ + (b) >= 850 ? 3 : \ + (b) >= 650 ? 4 : \ + (b) >= 550 ? 5 : \ + (b) >= 450 ? 6 : \ + (b) >= 400 ? 7 : \ + (b) >= 350 ? 8 : \ + (b) >= 300 ? 9 : \ + (b) >= 250 ? 12 : \ + (b) >= 200 ? 15 : \ + (b) >= 150 ? 18 : \ + /* b >= 100 */ 27) + +# define BN_num_bytes(a) ((BN_num_bits(a)+7)/8) + +/* Note that BN_abs_is_word didn't work reliably for w == 0 until 0.9.8 */ +# define BN_abs_is_word(a,w) ((((a)->top == 1) && ((a)->d[0] == (BN_ULONG)(w))) || \ + (((w) == 0) && ((a)->top == 0))) +# define BN_is_zero(a) ((a)->top == 0) +# define BN_is_one(a) (BN_abs_is_word((a),1) && !(a)->neg) +# define BN_is_word(a,w) (BN_abs_is_word((a),(w)) && (!(w) || !(a)->neg)) +# define BN_is_odd(a) (((a)->top > 0) && ((a)->d[0] & 1)) + +# define BN_one(a) (BN_set_word((a),1)) +# define BN_zero_ex(a) \ + do { \ + BIGNUM *_tmp_bn = (a); \ + _tmp_bn->top = 0; \ + _tmp_bn->neg = 0; \ + } while(0) +# ifdef OPENSSL_NO_DEPRECATED +# define BN_zero(a) BN_zero_ex(a) +# else +# define BN_zero(a) (BN_set_word((a),0)) +# endif + +const BIGNUM *BN_value_one(void); +char *BN_options(void); +BN_CTX *BN_CTX_new(void); +# ifndef OPENSSL_NO_DEPRECATED +void BN_CTX_init(BN_CTX *c); +# endif +void BN_CTX_free(BN_CTX *c); +void BN_CTX_start(BN_CTX *ctx); +BIGNUM *BN_CTX_get(BN_CTX *ctx); +void BN_CTX_end(BN_CTX *ctx); +int BN_rand(BIGNUM *rnd, int bits, int top, int bottom); +int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom); +int BN_rand_range(BIGNUM *rnd, const BIGNUM *range); +int BN_pseudo_rand_range(BIGNUM *rnd, const BIGNUM *range); +int BN_num_bits(const BIGNUM *a); +int BN_num_bits_word(BN_ULONG); +BIGNUM *BN_new(void); +void BN_init(BIGNUM *); +void BN_clear_free(BIGNUM *a); +BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b); +void BN_swap(BIGNUM *a, BIGNUM *b); +BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret); +int BN_bn2bin(const BIGNUM *a, unsigned char *to); +BIGNUM *BN_mpi2bn(const unsigned char *s, int len, BIGNUM *ret); +int BN_bn2mpi(const BIGNUM *a, unsigned char *to); +int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); +int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx); +/** BN_set_negative sets sign of a BIGNUM + * \param b pointer to the BIGNUM object + * \param n 0 if the BIGNUM b should be positive and a value != 0 otherwise + */ +void BN_set_negative(BIGNUM *b, int n); +/** BN_is_negative returns 1 if the BIGNUM is negative + * \param a pointer to the BIGNUM object + * \return 1 if a < 0 and 0 otherwise + */ +# define BN_is_negative(a) ((a)->neg != 0) + +int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, + BN_CTX *ctx); +# define BN_mod(rem,m,d,ctx) BN_div(NULL,(rem),(m),(d),(ctx)) +int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx); +int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, + BN_CTX *ctx); +int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m); +int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, + BN_CTX *ctx); +int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m); +int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, + BN_CTX *ctx); +int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx); +int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx); +int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m); +int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, + BN_CTX *ctx); +int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m); + +BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w); +BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w); +int BN_mul_word(BIGNUM *a, BN_ULONG w); +int BN_add_word(BIGNUM *a, BN_ULONG w); +int BN_sub_word(BIGNUM *a, BN_ULONG w); +int BN_set_word(BIGNUM *a, BN_ULONG w); +BN_ULONG BN_get_word(const BIGNUM *a); + +int BN_cmp(const BIGNUM *a, const BIGNUM *b); +void BN_free(BIGNUM *a); +int BN_is_bit_set(const BIGNUM *a, int n); +int BN_lshift(BIGNUM *r, const BIGNUM *a, int n); +int BN_lshift1(BIGNUM *r, const BIGNUM *a); +int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); + +int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); +int BN_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); +int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *in_mont); +int BN_mod_exp_mont_word(BIGNUM *r, BN_ULONG a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); +int BN_mod_exp2_mont(BIGNUM *r, const BIGNUM *a1, const BIGNUM *p1, + const BIGNUM *a2, const BIGNUM *p2, const BIGNUM *m, + BN_CTX *ctx, BN_MONT_CTX *m_ctx); +int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); + +int BN_mask_bits(BIGNUM *a, int n); +# ifndef OPENSSL_NO_FP_API +int BN_print_fp(FILE *fp, const BIGNUM *a); +# endif +# ifdef HEADER_BIO_H +int BN_print(BIO *fp, const BIGNUM *a); +# else +int BN_print(void *fp, const BIGNUM *a); +# endif +int BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx); +int BN_rshift(BIGNUM *r, const BIGNUM *a, int n); +int BN_rshift1(BIGNUM *r, const BIGNUM *a); +void BN_clear(BIGNUM *a); +BIGNUM *BN_dup(const BIGNUM *a); +int BN_ucmp(const BIGNUM *a, const BIGNUM *b); +int BN_set_bit(BIGNUM *a, int n); +int BN_clear_bit(BIGNUM *a, int n); +char *BN_bn2hex(const BIGNUM *a); +char *BN_bn2dec(const BIGNUM *a); +int BN_hex2bn(BIGNUM **a, const char *str); +int BN_dec2bn(BIGNUM **a, const char *str); +int BN_asc2bn(BIGNUM **a, const char *str); +int BN_gcd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); +int BN_kronecker(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); /* returns + * -2 for + * error */ +BIGNUM *BN_mod_inverse(BIGNUM *ret, + const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx); +BIGNUM *BN_mod_sqrt(BIGNUM *ret, + const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx); + +void BN_consttime_swap(BN_ULONG swap, BIGNUM *a, BIGNUM *b, int nwords); + +/* Deprecated versions */ +# ifndef OPENSSL_NO_DEPRECATED +BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe, + const BIGNUM *add, const BIGNUM *rem, + void (*callback) (int, int, void *), void *cb_arg); +int BN_is_prime(const BIGNUM *p, int nchecks, + void (*callback) (int, int, void *), + BN_CTX *ctx, void *cb_arg); +int BN_is_prime_fasttest(const BIGNUM *p, int nchecks, + void (*callback) (int, int, void *), BN_CTX *ctx, + void *cb_arg, int do_trial_division); +# endif /* !defined(OPENSSL_NO_DEPRECATED) */ + +/* Newer versions */ +int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add, + const BIGNUM *rem, BN_GENCB *cb); +int BN_is_prime_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx, BN_GENCB *cb); +int BN_is_prime_fasttest_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx, + int do_trial_division, BN_GENCB *cb); + +int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx); + +int BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, + const BIGNUM *Xp, const BIGNUM *Xp1, + const BIGNUM *Xp2, const BIGNUM *e, BN_CTX *ctx, + BN_GENCB *cb); +int BN_X931_generate_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, BIGNUM *Xp1, + BIGNUM *Xp2, const BIGNUM *Xp, const BIGNUM *e, + BN_CTX *ctx, BN_GENCB *cb); + +BN_MONT_CTX *BN_MONT_CTX_new(void); +void BN_MONT_CTX_init(BN_MONT_CTX *ctx); +int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + BN_MONT_CTX *mont, BN_CTX *ctx); +# define BN_to_montgomery(r,a,mont,ctx) BN_mod_mul_montgomery(\ + (r),(a),&((mont)->RR),(mont),(ctx)) +int BN_from_montgomery(BIGNUM *r, const BIGNUM *a, + BN_MONT_CTX *mont, BN_CTX *ctx); +void BN_MONT_CTX_free(BN_MONT_CTX *mont); +int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx); +BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from); +BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock, + const BIGNUM *mod, BN_CTX *ctx); + +/* BN_BLINDING flags */ +# define BN_BLINDING_NO_UPDATE 0x00000001 +# define BN_BLINDING_NO_RECREATE 0x00000002 + +BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod); +void BN_BLINDING_free(BN_BLINDING *b); +int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx); +int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx); +int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx); +int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *); +int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, + BN_CTX *); +# ifndef OPENSSL_NO_DEPRECATED +unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *); +void BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned long); +# endif +CRYPTO_THREADID *BN_BLINDING_thread_id(BN_BLINDING *); +unsigned long BN_BLINDING_get_flags(const BN_BLINDING *); +void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long); +BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b, + const BIGNUM *e, BIGNUM *m, BN_CTX *ctx, + int (*bn_mod_exp) (BIGNUM *r, + const BIGNUM *a, + const BIGNUM *p, + const BIGNUM *m, + BN_CTX *ctx, + BN_MONT_CTX *m_ctx), + BN_MONT_CTX *m_ctx); + +# ifndef OPENSSL_NO_DEPRECATED +void BN_set_params(int mul, int high, int low, int mont); +int BN_get_params(int which); /* 0, mul, 1 high, 2 low, 3 mont */ +# endif + +void BN_RECP_CTX_init(BN_RECP_CTX *recp); +BN_RECP_CTX *BN_RECP_CTX_new(void); +void BN_RECP_CTX_free(BN_RECP_CTX *recp); +int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *rdiv, BN_CTX *ctx); +int BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y, + BN_RECP_CTX *recp, BN_CTX *ctx); +int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); +int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, + BN_RECP_CTX *recp, BN_CTX *ctx); + +# ifndef OPENSSL_NO_EC2M + +/* + * Functions for arithmetic over binary polynomials represented by BIGNUMs. + * The BIGNUM::neg property of BIGNUMs representing binary polynomials is + * ignored. Note that input arguments are not const so that their bit arrays + * can be expanded to the appropriate size if needed. + */ + +/* + * r = a + b + */ +int BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +# define BN_GF2m_sub(r, a, b) BN_GF2m_add(r, a, b) +/* + * r=a mod p + */ +int BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p); +/* r = (a * b) mod p */ +int BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *p, BN_CTX *ctx); +/* r = (a * a) mod p */ +int BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +/* r = (1 / b) mod p */ +int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx); +/* r = (a / b) mod p */ +int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *p, BN_CTX *ctx); +/* r = (a ^ b) mod p */ +int BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *p, BN_CTX *ctx); +/* r = sqrt(a) mod p */ +int BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx); +/* r^2 + r = a mod p */ +int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx); +# define BN_GF2m_cmp(a, b) BN_ucmp((a), (b)) +/*- + * Some functions allow for representation of the irreducible polynomials + * as an unsigned int[], say p. The irreducible f(t) is then of the form: + * t^p[0] + t^p[1] + ... + t^p[k] + * where m = p[0] > p[1] > ... > p[k] = 0. + */ +/* r = a mod p */ +int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[]); +/* r = (a * b) mod p */ +int BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const int p[], BN_CTX *ctx); +/* r = (a * a) mod p */ +int BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const int p[], + BN_CTX *ctx); +/* r = (1 / b) mod p */ +int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *b, const int p[], + BN_CTX *ctx); +/* r = (a / b) mod p */ +int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const int p[], BN_CTX *ctx); +/* r = (a ^ b) mod p */ +int BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const int p[], BN_CTX *ctx); +/* r = sqrt(a) mod p */ +int BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a, + const int p[], BN_CTX *ctx); +/* r^2 + r = a mod p */ +int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a, + const int p[], BN_CTX *ctx); +int BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max); +int BN_GF2m_arr2poly(const int p[], BIGNUM *a); + +# endif + +/* + * faster mod functions for the 'NIST primes' 0 <= a < p^2 + */ +int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); + +const BIGNUM *BN_get0_nist_prime_192(void); +const BIGNUM *BN_get0_nist_prime_224(void); +const BIGNUM *BN_get0_nist_prime_256(void); +const BIGNUM *BN_get0_nist_prime_384(void); +const BIGNUM *BN_get0_nist_prime_521(void); + +/* library internal functions */ + +# define bn_expand(a,bits) \ + ( \ + bits > (INT_MAX - BN_BITS2 + 1) ? \ + NULL \ + : \ + (((bits+BN_BITS2-1)/BN_BITS2) <= (a)->dmax) ? \ + (a) \ + : \ + bn_expand2((a),(bits+BN_BITS2-1)/BN_BITS2) \ + ) + +# define bn_wexpand(a,words) (((words) <= (a)->dmax)?(a):bn_expand2((a),(words))) +BIGNUM *bn_expand2(BIGNUM *a, int words); +# ifndef OPENSSL_NO_DEPRECATED +BIGNUM *bn_dup_expand(const BIGNUM *a, int words); /* unused */ +# endif + +/*- + * Bignum consistency macros + * There is one "API" macro, bn_fix_top(), for stripping leading zeroes from + * bignum data after direct manipulations on the data. There is also an + * "internal" macro, bn_check_top(), for verifying that there are no leading + * zeroes. Unfortunately, some auditing is required due to the fact that + * bn_fix_top() has become an overabused duct-tape because bignum data is + * occasionally passed around in an inconsistent state. So the following + * changes have been made to sort this out; + * - bn_fix_top()s implementation has been moved to bn_correct_top() + * - if BN_DEBUG isn't defined, bn_fix_top() maps to bn_correct_top(), and + * bn_check_top() is as before. + * - if BN_DEBUG *is* defined; + * - bn_check_top() tries to pollute unused words even if the bignum 'top' is + * consistent. (ed: only if BN_DEBUG_RAND is defined) + * - bn_fix_top() maps to bn_check_top() rather than "fixing" anything. + * The idea is to have debug builds flag up inconsistent bignums when they + * occur. If that occurs in a bn_fix_top(), we examine the code in question; if + * the use of bn_fix_top() was appropriate (ie. it follows directly after code + * that manipulates the bignum) it is converted to bn_correct_top(), and if it + * was not appropriate, we convert it permanently to bn_check_top() and track + * down the cause of the bug. Eventually, no internal code should be using the + * bn_fix_top() macro. External applications and libraries should try this with + * their own code too, both in terms of building against the openssl headers + * with BN_DEBUG defined *and* linking with a version of OpenSSL built with it + * defined. This not only improves external code, it provides more test + * coverage for openssl's own code. + */ + +# ifdef BN_DEBUG + +/* We only need assert() when debugging */ +# include + +# ifdef BN_DEBUG_RAND +/* To avoid "make update" cvs wars due to BN_DEBUG, use some tricks */ +# ifndef RAND_pseudo_bytes +int RAND_pseudo_bytes(unsigned char *buf, int num); +# define BN_DEBUG_TRIX +# endif +# define bn_pollute(a) \ + do { \ + const BIGNUM *_bnum1 = (a); \ + if(_bnum1->top < _bnum1->dmax) { \ + unsigned char _tmp_char; \ + /* We cast away const without the compiler knowing, any \ + * *genuinely* constant variables that aren't mutable \ + * wouldn't be constructed with top!=dmax. */ \ + BN_ULONG *_not_const; \ + memcpy(&_not_const, &_bnum1->d, sizeof(BN_ULONG*)); \ + /* Debug only - safe to ignore error return */ \ + RAND_pseudo_bytes(&_tmp_char, 1); \ + memset((unsigned char *)(_not_const + _bnum1->top), _tmp_char, \ + (_bnum1->dmax - _bnum1->top) * sizeof(BN_ULONG)); \ + } \ + } while(0) +# ifdef BN_DEBUG_TRIX +# undef RAND_pseudo_bytes +# endif +# else +# define bn_pollute(a) +# endif +# define bn_check_top(a) \ + do { \ + const BIGNUM *_bnum2 = (a); \ + if (_bnum2 != NULL) { \ + assert((_bnum2->top == 0) || \ + (_bnum2->d[_bnum2->top - 1] != 0)); \ + bn_pollute(_bnum2); \ + } \ + } while(0) + +# define bn_fix_top(a) bn_check_top(a) + +# define bn_check_size(bn, bits) bn_wcheck_size(bn, ((bits+BN_BITS2-1))/BN_BITS2) +# define bn_wcheck_size(bn, words) \ + do { \ + const BIGNUM *_bnum2 = (bn); \ + assert((words) <= (_bnum2)->dmax && (words) >= (_bnum2)->top); \ + /* avoid unused variable warning with NDEBUG */ \ + (void)(_bnum2); \ + } while(0) + +# else /* !BN_DEBUG */ + +# define bn_pollute(a) +# define bn_check_top(a) +# define bn_fix_top(a) bn_correct_top(a) +# define bn_check_size(bn, bits) +# define bn_wcheck_size(bn, words) + +# endif + +# define bn_correct_top(a) \ + { \ + BN_ULONG *ftl; \ + int tmp_top = (a)->top; \ + if (tmp_top > 0) \ + { \ + for (ftl= &((a)->d[tmp_top-1]); tmp_top > 0; tmp_top--) \ + if (*(ftl--)) break; \ + (a)->top = tmp_top; \ + } \ + bn_pollute(a); \ + } + +BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, + BN_ULONG w); +BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w); +void bn_sqr_words(BN_ULONG *rp, const BN_ULONG *ap, int num); +BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d); +BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + int num); +BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + int num); + +/* Primes from RFC 2409 */ +BIGNUM *get_rfc2409_prime_768(BIGNUM *bn); +BIGNUM *get_rfc2409_prime_1024(BIGNUM *bn); + +/* Primes from RFC 3526 */ +BIGNUM *get_rfc3526_prime_1536(BIGNUM *bn); +BIGNUM *get_rfc3526_prime_2048(BIGNUM *bn); +BIGNUM *get_rfc3526_prime_3072(BIGNUM *bn); +BIGNUM *get_rfc3526_prime_4096(BIGNUM *bn); +BIGNUM *get_rfc3526_prime_6144(BIGNUM *bn); +BIGNUM *get_rfc3526_prime_8192(BIGNUM *bn); + +int BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_BN_strings(void); + +/* Error codes for the BN functions. */ + +/* Function codes. */ +# define BN_F_BNRAND 127 +# define BN_F_BN_BLINDING_CONVERT_EX 100 +# define BN_F_BN_BLINDING_CREATE_PARAM 128 +# define BN_F_BN_BLINDING_INVERT_EX 101 +# define BN_F_BN_BLINDING_NEW 102 +# define BN_F_BN_BLINDING_UPDATE 103 +# define BN_F_BN_BN2DEC 104 +# define BN_F_BN_BN2HEX 105 +# define BN_F_BN_CTX_GET 116 +# define BN_F_BN_CTX_NEW 106 +# define BN_F_BN_CTX_START 129 +# define BN_F_BN_DIV 107 +# define BN_F_BN_DIV_NO_BRANCH 138 +# define BN_F_BN_DIV_RECP 130 +# define BN_F_BN_EXP 123 +# define BN_F_BN_EXPAND2 108 +# define BN_F_BN_EXPAND_INTERNAL 120 +# define BN_F_BN_GF2M_MOD 131 +# define BN_F_BN_GF2M_MOD_EXP 132 +# define BN_F_BN_GF2M_MOD_MUL 133 +# define BN_F_BN_GF2M_MOD_SOLVE_QUAD 134 +# define BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR 135 +# define BN_F_BN_GF2M_MOD_SQR 136 +# define BN_F_BN_GF2M_MOD_SQRT 137 +# define BN_F_BN_LSHIFT 145 +# define BN_F_BN_MOD_EXP2_MONT 118 +# define BN_F_BN_MOD_EXP_MONT 109 +# define BN_F_BN_MOD_EXP_MONT_CONSTTIME 124 +# define BN_F_BN_MOD_EXP_MONT_WORD 117 +# define BN_F_BN_MOD_EXP_RECP 125 +# define BN_F_BN_MOD_EXP_SIMPLE 126 +# define BN_F_BN_MOD_INVERSE 110 +# define BN_F_BN_MOD_INVERSE_NO_BRANCH 139 +# define BN_F_BN_MOD_LSHIFT_QUICK 119 +# define BN_F_BN_MOD_MUL_RECIPROCAL 111 +# define BN_F_BN_MOD_SQRT 121 +# define BN_F_BN_MPI2BN 112 +# define BN_F_BN_NEW 113 +# define BN_F_BN_RAND 114 +# define BN_F_BN_RAND_RANGE 122 +# define BN_F_BN_RSHIFT 146 +# define BN_F_BN_USUB 115 + +/* Reason codes. */ +# define BN_R_ARG2_LT_ARG3 100 +# define BN_R_BAD_RECIPROCAL 101 +# define BN_R_BIGNUM_TOO_LONG 114 +# define BN_R_BITS_TOO_SMALL 118 +# define BN_R_CALLED_WITH_EVEN_MODULUS 102 +# define BN_R_DIV_BY_ZERO 103 +# define BN_R_ENCODING_ERROR 104 +# define BN_R_EXPAND_ON_STATIC_BIGNUM_DATA 105 +# define BN_R_INPUT_NOT_REDUCED 110 +# define BN_R_INVALID_LENGTH 106 +# define BN_R_INVALID_RANGE 115 +# define BN_R_INVALID_SHIFT 119 +# define BN_R_NOT_A_SQUARE 111 +# define BN_R_NOT_INITIALIZED 107 +# define BN_R_NO_INVERSE 108 +# define BN_R_NO_SOLUTION 116 +# define BN_R_P_IS_NOT_PRIME 112 +# define BN_R_TOO_MANY_ITERATIONS 113 +# define BN_R_TOO_MANY_TEMPORARY_VARIABLES 109 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/buffer.h b/OSlibs/ios/include/openssl/buffer.h new file mode 100755 index 000000000..efd240a5f --- /dev/null +++ b/OSlibs/ios/include/openssl/buffer.h @@ -0,0 +1,125 @@ +/* crypto/buffer/buffer.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_BUFFER_H +# define HEADER_BUFFER_H + +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# include + +# if !defined(NO_SYS_TYPES_H) +# include +# endif + +/* Already declared in ossl_typ.h */ +/* typedef struct buf_mem_st BUF_MEM; */ + +struct buf_mem_st { + size_t length; /* current number of bytes */ + char *data; + size_t max; /* size of buffer */ +}; + +BUF_MEM *BUF_MEM_new(void); +void BUF_MEM_free(BUF_MEM *a); +int BUF_MEM_grow(BUF_MEM *str, size_t len); +int BUF_MEM_grow_clean(BUF_MEM *str, size_t len); +size_t BUF_strnlen(const char *str, size_t maxlen); +char *BUF_strdup(const char *str); + +/* + * Like strndup, but in addition, explicitly guarantees to never read past the + * first |siz| bytes of |str|. + */ +char *BUF_strndup(const char *str, size_t siz); + +void *BUF_memdup(const void *data, size_t siz); +void BUF_reverse(unsigned char *out, const unsigned char *in, size_t siz); + +/* safe string functions */ +size_t BUF_strlcpy(char *dst, const char *src, size_t siz); +size_t BUF_strlcat(char *dst, const char *src, size_t siz); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_BUF_strings(void); + +/* Error codes for the BUF functions. */ + +/* Function codes. */ +# define BUF_F_BUF_MEMDUP 103 +# define BUF_F_BUF_MEM_GROW 100 +# define BUF_F_BUF_MEM_GROW_CLEAN 105 +# define BUF_F_BUF_MEM_NEW 101 +# define BUF_F_BUF_STRDUP 102 +# define BUF_F_BUF_STRNDUP 104 + +/* Reason codes. */ + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/camellia.h b/OSlibs/ios/include/openssl/camellia.h new file mode 100755 index 000000000..45e8d25b1 --- /dev/null +++ b/OSlibs/ios/include/openssl/camellia.h @@ -0,0 +1,132 @@ +/* crypto/camellia/camellia.h */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#ifndef HEADER_CAMELLIA_H +# define HEADER_CAMELLIA_H + +# include + +# ifdef OPENSSL_NO_CAMELLIA +# error CAMELLIA is disabled. +# endif + +# include + +# define CAMELLIA_ENCRYPT 1 +# define CAMELLIA_DECRYPT 0 + +/* + * Because array size can't be a const in C, the following two are macros. + * Both sizes are in bytes. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* This should be a hidden type, but EVP requires that the size be known */ + +# define CAMELLIA_BLOCK_SIZE 16 +# define CAMELLIA_TABLE_BYTE_LEN 272 +# define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4) + +typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN]; /* to match + * with WORD */ + +struct camellia_key_st { + union { + double d; /* ensures 64-bit align */ + KEY_TABLE_TYPE rd_key; + } u; + int grand_rounds; +}; +typedef struct camellia_key_st CAMELLIA_KEY; + +# ifdef OPENSSL_FIPS +int private_Camellia_set_key(const unsigned char *userKey, const int bits, + CAMELLIA_KEY *key); +# endif +int Camellia_set_key(const unsigned char *userKey, const int bits, + CAMELLIA_KEY *key); + +void Camellia_encrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key); +void Camellia_decrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key); + +void Camellia_ecb_encrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key, const int enc); +void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, const int enc); +void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num, const int enc); +void Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num, const int enc); +void Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num, const int enc); +void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num); +void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char ivec[CAMELLIA_BLOCK_SIZE], + unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE], + unsigned int *num); + +#ifdef __cplusplus +} +#endif + +#endif /* !HEADER_Camellia_H */ diff --git a/OSlibs/ios/include/openssl/cast.h b/OSlibs/ios/include/openssl/cast.h new file mode 100755 index 000000000..0003ec9c7 --- /dev/null +++ b/OSlibs/ios/include/openssl/cast.h @@ -0,0 +1,107 @@ +/* crypto/cast/cast.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_CAST_H +# define HEADER_CAST_H + +#ifdef __cplusplus +extern "C" { +#endif + +# include + +# ifdef OPENSSL_NO_CAST +# error CAST is disabled. +# endif + +# define CAST_ENCRYPT 1 +# define CAST_DECRYPT 0 + +# define CAST_LONG unsigned int + +# define CAST_BLOCK 8 +# define CAST_KEY_LENGTH 16 + +typedef struct cast_key_st { + CAST_LONG data[32]; + int short_key; /* Use reduced rounds for short key */ +} CAST_KEY; + +# ifdef OPENSSL_FIPS +void private_CAST_set_key(CAST_KEY *key, int len, const unsigned char *data); +# endif +void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data); +void CAST_ecb_encrypt(const unsigned char *in, unsigned char *out, + const CAST_KEY *key, int enc); +void CAST_encrypt(CAST_LONG *data, const CAST_KEY *key); +void CAST_decrypt(CAST_LONG *data, const CAST_KEY *key); +void CAST_cbc_encrypt(const unsigned char *in, unsigned char *out, + long length, const CAST_KEY *ks, unsigned char *iv, + int enc); +void CAST_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, const CAST_KEY *schedule, + unsigned char *ivec, int *num, int enc); +void CAST_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, const CAST_KEY *schedule, + unsigned char *ivec, int *num); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/OSlibs/ios/include/openssl/cmac.h b/OSlibs/ios/include/openssl/cmac.h new file mode 100755 index 000000000..175be8348 --- /dev/null +++ b/OSlibs/ios/include/openssl/cmac.h @@ -0,0 +1,82 @@ +/* crypto/cmac/cmac.h */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2010 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#ifndef HEADER_CMAC_H +# define HEADER_CMAC_H + +#ifdef __cplusplus +extern "C" { +#endif + +# include + +/* Opaque */ +typedef struct CMAC_CTX_st CMAC_CTX; + +CMAC_CTX *CMAC_CTX_new(void); +void CMAC_CTX_cleanup(CMAC_CTX *ctx); +void CMAC_CTX_free(CMAC_CTX *ctx); +EVP_CIPHER_CTX *CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx); +int CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in); + +int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen, + const EVP_CIPHER *cipher, ENGINE *impl); +int CMAC_Update(CMAC_CTX *ctx, const void *data, size_t dlen); +int CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen); +int CMAC_resume(CMAC_CTX *ctx); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/cms.h b/OSlibs/ios/include/openssl/cms.h new file mode 100755 index 000000000..e6c7f964b --- /dev/null +++ b/OSlibs/ios/include/openssl/cms.h @@ -0,0 +1,555 @@ +/* crypto/cms/cms.h */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#ifndef HEADER_CMS_H +# define HEADER_CMS_H + +# include + +# ifdef OPENSSL_NO_CMS +# error CMS is disabled. +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct CMS_ContentInfo_st CMS_ContentInfo; +typedef struct CMS_SignerInfo_st CMS_SignerInfo; +typedef struct CMS_CertificateChoices CMS_CertificateChoices; +typedef struct CMS_RevocationInfoChoice_st CMS_RevocationInfoChoice; +typedef struct CMS_RecipientInfo_st CMS_RecipientInfo; +typedef struct CMS_ReceiptRequest_st CMS_ReceiptRequest; +typedef struct CMS_Receipt_st CMS_Receipt; +typedef struct CMS_RecipientEncryptedKey_st CMS_RecipientEncryptedKey; +typedef struct CMS_OtherKeyAttribute_st CMS_OtherKeyAttribute; + +DECLARE_STACK_OF(CMS_SignerInfo) +DECLARE_STACK_OF(GENERAL_NAMES) +DECLARE_STACK_OF(CMS_RecipientEncryptedKey) +DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo) +DECLARE_ASN1_FUNCTIONS(CMS_ReceiptRequest) +DECLARE_ASN1_PRINT_FUNCTION(CMS_ContentInfo) + +# define CMS_SIGNERINFO_ISSUER_SERIAL 0 +# define CMS_SIGNERINFO_KEYIDENTIFIER 1 + +# define CMS_RECIPINFO_NONE -1 +# define CMS_RECIPINFO_TRANS 0 +# define CMS_RECIPINFO_AGREE 1 +# define CMS_RECIPINFO_KEK 2 +# define CMS_RECIPINFO_PASS 3 +# define CMS_RECIPINFO_OTHER 4 + +/* S/MIME related flags */ + +# define CMS_TEXT 0x1 +# define CMS_NOCERTS 0x2 +# define CMS_NO_CONTENT_VERIFY 0x4 +# define CMS_NO_ATTR_VERIFY 0x8 +# define CMS_NOSIGS \ + (CMS_NO_CONTENT_VERIFY|CMS_NO_ATTR_VERIFY) +# define CMS_NOINTERN 0x10 +# define CMS_NO_SIGNER_CERT_VERIFY 0x20 +# define CMS_NOVERIFY 0x20 +# define CMS_DETACHED 0x40 +# define CMS_BINARY 0x80 +# define CMS_NOATTR 0x100 +# define CMS_NOSMIMECAP 0x200 +# define CMS_NOOLDMIMETYPE 0x400 +# define CMS_CRLFEOL 0x800 +# define CMS_STREAM 0x1000 +# define CMS_NOCRL 0x2000 +# define CMS_PARTIAL 0x4000 +# define CMS_REUSE_DIGEST 0x8000 +# define CMS_USE_KEYID 0x10000 +# define CMS_DEBUG_DECRYPT 0x20000 +# define CMS_KEY_PARAM 0x40000 + +const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms); + +BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont); +int CMS_dataFinal(CMS_ContentInfo *cms, BIO *bio); + +ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms); +int CMS_is_detached(CMS_ContentInfo *cms); +int CMS_set_detached(CMS_ContentInfo *cms, int detached); + +# ifdef HEADER_PEM_H +DECLARE_PEM_rw_const(CMS, CMS_ContentInfo) +# endif +int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms); +CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms); +int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms); + +BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms); +int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags); +int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, + int flags); +CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont); +int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags); + +int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, + unsigned int flags); + +CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, + STACK_OF(X509) *certs, BIO *data, + unsigned int flags); + +CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si, + X509 *signcert, EVP_PKEY *pkey, + STACK_OF(X509) *certs, unsigned int flags); + +int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags); +CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags); + +int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out, + unsigned int flags); +CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md, + unsigned int flags); + +int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms, + const unsigned char *key, size_t keylen, + BIO *dcont, BIO *out, unsigned int flags); + +CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher, + const unsigned char *key, + size_t keylen, unsigned int flags); + +int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph, + const unsigned char *key, size_t keylen); + +int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, + X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags); + +int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms, + STACK_OF(X509) *certs, + X509_STORE *store, unsigned int flags); + +STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms); + +CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in, + const EVP_CIPHER *cipher, unsigned int flags); + +int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert, + BIO *dcont, BIO *out, unsigned int flags); + +int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert); +int CMS_decrypt_set1_key(CMS_ContentInfo *cms, + unsigned char *key, size_t keylen, + unsigned char *id, size_t idlen); +int CMS_decrypt_set1_password(CMS_ContentInfo *cms, + unsigned char *pass, ossl_ssize_t passlen); + +STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms); +int CMS_RecipientInfo_type(CMS_RecipientInfo *ri); +EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri); +CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher); +CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, + X509 *recip, unsigned int flags); +int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey); +int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert); +int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri, + EVP_PKEY **pk, X509 **recip, + X509_ALGOR **palg); +int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri, + ASN1_OCTET_STRING **keyid, + X509_NAME **issuer, + ASN1_INTEGER **sno); + +CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid, + unsigned char *key, size_t keylen, + unsigned char *id, size_t idlen, + ASN1_GENERALIZEDTIME *date, + ASN1_OBJECT *otherTypeId, + ASN1_TYPE *otherType); + +int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri, + X509_ALGOR **palg, + ASN1_OCTET_STRING **pid, + ASN1_GENERALIZEDTIME **pdate, + ASN1_OBJECT **potherid, + ASN1_TYPE **pothertype); + +int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, + unsigned char *key, size_t keylen); + +int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri, + const unsigned char *id, size_t idlen); + +int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri, + unsigned char *pass, + ossl_ssize_t passlen); + +CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, + int iter, int wrap_nid, + int pbe_nid, + unsigned char *pass, + ossl_ssize_t passlen, + const EVP_CIPHER *kekciph); + +int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri); +int CMS_RecipientInfo_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri); + +int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, + unsigned int flags); +CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags); + +int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid); +const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms); + +CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms); +int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert); +int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert); +STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms); + +CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms); +int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl); +int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl); +STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms); + +int CMS_SignedData_init(CMS_ContentInfo *cms); +CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, + X509 *signer, EVP_PKEY *pk, const EVP_MD *md, + unsigned int flags); +EVP_PKEY_CTX *CMS_SignerInfo_get0_pkey_ctx(CMS_SignerInfo *si); +EVP_MD_CTX *CMS_SignerInfo_get0_md_ctx(CMS_SignerInfo *si); +STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms); + +void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer); +int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si, + ASN1_OCTET_STRING **keyid, + X509_NAME **issuer, ASN1_INTEGER **sno); +int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert); +int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *certs, + unsigned int flags); +void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, + X509 **signer, X509_ALGOR **pdig, + X509_ALGOR **psig); +ASN1_OCTET_STRING *CMS_SignerInfo_get0_signature(CMS_SignerInfo *si); +int CMS_SignerInfo_sign(CMS_SignerInfo *si); +int CMS_SignerInfo_verify(CMS_SignerInfo *si); +int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain); + +int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs); +int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs, + int algnid, int keysize); +int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap); + +int CMS_signed_get_attr_count(const CMS_SignerInfo *si); +int CMS_signed_get_attr_by_NID(const CMS_SignerInfo *si, int nid, + int lastpos); +int CMS_signed_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj, + int lastpos); +X509_ATTRIBUTE *CMS_signed_get_attr(const CMS_SignerInfo *si, int loc); +X509_ATTRIBUTE *CMS_signed_delete_attr(CMS_SignerInfo *si, int loc); +int CMS_signed_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr); +int CMS_signed_add1_attr_by_OBJ(CMS_SignerInfo *si, + const ASN1_OBJECT *obj, int type, + const void *bytes, int len); +int CMS_signed_add1_attr_by_NID(CMS_SignerInfo *si, + int nid, int type, + const void *bytes, int len); +int CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si, + const char *attrname, int type, + const void *bytes, int len); +void *CMS_signed_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid, + int lastpos, int type); + +int CMS_unsigned_get_attr_count(const CMS_SignerInfo *si); +int CMS_unsigned_get_attr_by_NID(const CMS_SignerInfo *si, int nid, + int lastpos); +int CMS_unsigned_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj, + int lastpos); +X509_ATTRIBUTE *CMS_unsigned_get_attr(const CMS_SignerInfo *si, int loc); +X509_ATTRIBUTE *CMS_unsigned_delete_attr(CMS_SignerInfo *si, int loc); +int CMS_unsigned_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr); +int CMS_unsigned_add1_attr_by_OBJ(CMS_SignerInfo *si, + const ASN1_OBJECT *obj, int type, + const void *bytes, int len); +int CMS_unsigned_add1_attr_by_NID(CMS_SignerInfo *si, + int nid, int type, + const void *bytes, int len); +int CMS_unsigned_add1_attr_by_txt(CMS_SignerInfo *si, + const char *attrname, int type, + const void *bytes, int len); +void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid, + int lastpos, int type); + +# ifdef HEADER_X509V3_H + +int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr); +CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen, + int allorfirst, + STACK_OF(GENERAL_NAMES) + *receiptList, STACK_OF(GENERAL_NAMES) + *receiptsTo); +int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr); +void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr, + ASN1_STRING **pcid, + int *pallorfirst, + STACK_OF(GENERAL_NAMES) **plist, + STACK_OF(GENERAL_NAMES) **prto); +# endif +int CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo *ri, + X509_ALGOR **palg, + ASN1_OCTET_STRING **pukm); +STACK_OF(CMS_RecipientEncryptedKey) +*CMS_RecipientInfo_kari_get0_reks(CMS_RecipientInfo *ri); + +int CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo *ri, + X509_ALGOR **pubalg, + ASN1_BIT_STRING **pubkey, + ASN1_OCTET_STRING **keyid, + X509_NAME **issuer, + ASN1_INTEGER **sno); + +int CMS_RecipientInfo_kari_orig_id_cmp(CMS_RecipientInfo *ri, X509 *cert); + +int CMS_RecipientEncryptedKey_get0_id(CMS_RecipientEncryptedKey *rek, + ASN1_OCTET_STRING **keyid, + ASN1_GENERALIZEDTIME **tm, + CMS_OtherKeyAttribute **other, + X509_NAME **issuer, ASN1_INTEGER **sno); +int CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey *rek, + X509 *cert); +int CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pk); +EVP_CIPHER_CTX *CMS_RecipientInfo_kari_get0_ctx(CMS_RecipientInfo *ri); +int CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo *cms, + CMS_RecipientInfo *ri, + CMS_RecipientEncryptedKey *rek); + +int CMS_SharedInfo_encode(unsigned char **pder, X509_ALGOR *kekalg, + ASN1_OCTET_STRING *ukm, int keylen); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_CMS_strings(void); + +/* Error codes for the CMS functions. */ + +/* Function codes. */ +# define CMS_F_CHECK_CONTENT 99 +# define CMS_F_CMS_ADD0_CERT 164 +# define CMS_F_CMS_ADD0_RECIPIENT_KEY 100 +# define CMS_F_CMS_ADD0_RECIPIENT_PASSWORD 165 +# define CMS_F_CMS_ADD1_RECEIPTREQUEST 158 +# define CMS_F_CMS_ADD1_RECIPIENT_CERT 101 +# define CMS_F_CMS_ADD1_SIGNER 102 +# define CMS_F_CMS_ADD1_SIGNINGTIME 103 +# define CMS_F_CMS_COMPRESS 104 +# define CMS_F_CMS_COMPRESSEDDATA_CREATE 105 +# define CMS_F_CMS_COMPRESSEDDATA_INIT_BIO 106 +# define CMS_F_CMS_COPY_CONTENT 107 +# define CMS_F_CMS_COPY_MESSAGEDIGEST 108 +# define CMS_F_CMS_DATA 109 +# define CMS_F_CMS_DATAFINAL 110 +# define CMS_F_CMS_DATAINIT 111 +# define CMS_F_CMS_DECRYPT 112 +# define CMS_F_CMS_DECRYPT_SET1_KEY 113 +# define CMS_F_CMS_DECRYPT_SET1_PASSWORD 166 +# define CMS_F_CMS_DECRYPT_SET1_PKEY 114 +# define CMS_F_CMS_DIGESTALGORITHM_FIND_CTX 115 +# define CMS_F_CMS_DIGESTALGORITHM_INIT_BIO 116 +# define CMS_F_CMS_DIGESTEDDATA_DO_FINAL 117 +# define CMS_F_CMS_DIGEST_VERIFY 118 +# define CMS_F_CMS_ENCODE_RECEIPT 161 +# define CMS_F_CMS_ENCRYPT 119 +# define CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO 120 +# define CMS_F_CMS_ENCRYPTEDDATA_DECRYPT 121 +# define CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT 122 +# define CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY 123 +# define CMS_F_CMS_ENVELOPEDDATA_CREATE 124 +# define CMS_F_CMS_ENVELOPEDDATA_INIT_BIO 125 +# define CMS_F_CMS_ENVELOPED_DATA_INIT 126 +# define CMS_F_CMS_ENV_ASN1_CTRL 171 +# define CMS_F_CMS_FINAL 127 +# define CMS_F_CMS_GET0_CERTIFICATE_CHOICES 128 +# define CMS_F_CMS_GET0_CONTENT 129 +# define CMS_F_CMS_GET0_ECONTENT_TYPE 130 +# define CMS_F_CMS_GET0_ENVELOPED 131 +# define CMS_F_CMS_GET0_REVOCATION_CHOICES 132 +# define CMS_F_CMS_GET0_SIGNED 133 +# define CMS_F_CMS_MSGSIGDIGEST_ADD1 162 +# define CMS_F_CMS_RECEIPTREQUEST_CREATE0 159 +# define CMS_F_CMS_RECEIPT_VERIFY 160 +# define CMS_F_CMS_RECIPIENTINFO_DECRYPT 134 +# define CMS_F_CMS_RECIPIENTINFO_ENCRYPT 169 +# define CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT 178 +# define CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ALG 175 +# define CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ORIG_ID 173 +# define CMS_F_CMS_RECIPIENTINFO_KARI_GET0_REKS 172 +# define CMS_F_CMS_RECIPIENTINFO_KARI_ORIG_ID_CMP 174 +# define CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT 135 +# define CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT 136 +# define CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID 137 +# define CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP 138 +# define CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP 139 +# define CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT 140 +# define CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT 141 +# define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS 142 +# define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID 143 +# define CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT 167 +# define CMS_F_CMS_RECIPIENTINFO_SET0_KEY 144 +# define CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD 168 +# define CMS_F_CMS_RECIPIENTINFO_SET0_PKEY 145 +# define CMS_F_CMS_SD_ASN1_CTRL 170 +# define CMS_F_CMS_SET1_IAS 176 +# define CMS_F_CMS_SET1_KEYID 177 +# define CMS_F_CMS_SET1_SIGNERIDENTIFIER 146 +# define CMS_F_CMS_SET_DETACHED 147 +# define CMS_F_CMS_SIGN 148 +# define CMS_F_CMS_SIGNED_DATA_INIT 149 +# define CMS_F_CMS_SIGNERINFO_CONTENT_SIGN 150 +# define CMS_F_CMS_SIGNERINFO_SIGN 151 +# define CMS_F_CMS_SIGNERINFO_VERIFY 152 +# define CMS_F_CMS_SIGNERINFO_VERIFY_CERT 153 +# define CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT 154 +# define CMS_F_CMS_SIGN_RECEIPT 163 +# define CMS_F_CMS_STREAM 155 +# define CMS_F_CMS_UNCOMPRESS 156 +# define CMS_F_CMS_VERIFY 157 + +/* Reason codes. */ +# define CMS_R_ADD_SIGNER_ERROR 99 +# define CMS_R_CERTIFICATE_ALREADY_PRESENT 175 +# define CMS_R_CERTIFICATE_HAS_NO_KEYID 160 +# define CMS_R_CERTIFICATE_VERIFY_ERROR 100 +# define CMS_R_CIPHER_INITIALISATION_ERROR 101 +# define CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR 102 +# define CMS_R_CMS_DATAFINAL_ERROR 103 +# define CMS_R_CMS_LIB 104 +# define CMS_R_CONTENTIDENTIFIER_MISMATCH 170 +# define CMS_R_CONTENT_NOT_FOUND 105 +# define CMS_R_CONTENT_TYPE_MISMATCH 171 +# define CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA 106 +# define CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA 107 +# define CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA 108 +# define CMS_R_CONTENT_VERIFY_ERROR 109 +# define CMS_R_CTRL_ERROR 110 +# define CMS_R_CTRL_FAILURE 111 +# define CMS_R_DECRYPT_ERROR 112 +# define CMS_R_DIGEST_ERROR 161 +# define CMS_R_ERROR_GETTING_PUBLIC_KEY 113 +# define CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE 114 +# define CMS_R_ERROR_SETTING_KEY 115 +# define CMS_R_ERROR_SETTING_RECIPIENTINFO 116 +# define CMS_R_INVALID_ENCRYPTED_KEY_LENGTH 117 +# define CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER 176 +# define CMS_R_INVALID_KEY_LENGTH 118 +# define CMS_R_MD_BIO_INIT_ERROR 119 +# define CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH 120 +# define CMS_R_MESSAGEDIGEST_WRONG_LENGTH 121 +# define CMS_R_MSGSIGDIGEST_ERROR 172 +# define CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE 162 +# define CMS_R_MSGSIGDIGEST_WRONG_LENGTH 163 +# define CMS_R_NEED_ONE_SIGNER 164 +# define CMS_R_NOT_A_SIGNED_RECEIPT 165 +# define CMS_R_NOT_ENCRYPTED_DATA 122 +# define CMS_R_NOT_KEK 123 +# define CMS_R_NOT_KEY_AGREEMENT 181 +# define CMS_R_NOT_KEY_TRANSPORT 124 +# define CMS_R_NOT_PWRI 177 +# define CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 125 +# define CMS_R_NO_CIPHER 126 +# define CMS_R_NO_CONTENT 127 +# define CMS_R_NO_CONTENT_TYPE 173 +# define CMS_R_NO_DEFAULT_DIGEST 128 +# define CMS_R_NO_DIGEST_SET 129 +# define CMS_R_NO_KEY 130 +# define CMS_R_NO_KEY_OR_CERT 174 +# define CMS_R_NO_MATCHING_DIGEST 131 +# define CMS_R_NO_MATCHING_RECIPIENT 132 +# define CMS_R_NO_MATCHING_SIGNATURE 166 +# define CMS_R_NO_MSGSIGDIGEST 167 +# define CMS_R_NO_PASSWORD 178 +# define CMS_R_NO_PRIVATE_KEY 133 +# define CMS_R_NO_PUBLIC_KEY 134 +# define CMS_R_NO_RECEIPT_REQUEST 168 +# define CMS_R_NO_SIGNERS 135 +# define CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 136 +# define CMS_R_RECEIPT_DECODE_ERROR 169 +# define CMS_R_RECIPIENT_ERROR 137 +# define CMS_R_SIGNER_CERTIFICATE_NOT_FOUND 138 +# define CMS_R_SIGNFINAL_ERROR 139 +# define CMS_R_SMIME_TEXT_ERROR 140 +# define CMS_R_STORE_INIT_ERROR 141 +# define CMS_R_TYPE_NOT_COMPRESSED_DATA 142 +# define CMS_R_TYPE_NOT_DATA 143 +# define CMS_R_TYPE_NOT_DIGESTED_DATA 144 +# define CMS_R_TYPE_NOT_ENCRYPTED_DATA 145 +# define CMS_R_TYPE_NOT_ENVELOPED_DATA 146 +# define CMS_R_UNABLE_TO_FINALIZE_CONTEXT 147 +# define CMS_R_UNKNOWN_CIPHER 148 +# define CMS_R_UNKNOWN_DIGEST_ALGORIHM 149 +# define CMS_R_UNKNOWN_ID 150 +# define CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM 151 +# define CMS_R_UNSUPPORTED_CONTENT_TYPE 152 +# define CMS_R_UNSUPPORTED_KEK_ALGORITHM 153 +# define CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM 179 +# define CMS_R_UNSUPPORTED_RECIPIENT_TYPE 154 +# define CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE 155 +# define CMS_R_UNSUPPORTED_TYPE 156 +# define CMS_R_UNWRAP_ERROR 157 +# define CMS_R_UNWRAP_FAILURE 180 +# define CMS_R_VERIFICATION_FAILURE 158 +# define CMS_R_WRAP_ERROR 159 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/comp.h b/OSlibs/ios/include/openssl/comp.h new file mode 100755 index 000000000..60a073404 --- /dev/null +++ b/OSlibs/ios/include/openssl/comp.h @@ -0,0 +1,83 @@ + +#ifndef HEADER_COMP_H +# define HEADER_COMP_H + +# include + +# ifdef OPENSSL_NO_COMP +# error COMP is disabled. +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct comp_ctx_st COMP_CTX; + +typedef struct comp_method_st { + int type; /* NID for compression library */ + const char *name; /* A text string to identify the library */ + int (*init) (COMP_CTX *ctx); + void (*finish) (COMP_CTX *ctx); + int (*compress) (COMP_CTX *ctx, + unsigned char *out, unsigned int olen, + unsigned char *in, unsigned int ilen); + int (*expand) (COMP_CTX *ctx, + unsigned char *out, unsigned int olen, + unsigned char *in, unsigned int ilen); + /* + * The following two do NOTHING, but are kept for backward compatibility + */ + long (*ctrl) (void); + long (*callback_ctrl) (void); +} COMP_METHOD; + +struct comp_ctx_st { + COMP_METHOD *meth; + unsigned long compress_in; + unsigned long compress_out; + unsigned long expand_in; + unsigned long expand_out; + CRYPTO_EX_DATA ex_data; +}; + +COMP_CTX *COMP_CTX_new(COMP_METHOD *meth); +void COMP_CTX_free(COMP_CTX *ctx); +int COMP_compress_block(COMP_CTX *ctx, unsigned char *out, int olen, + unsigned char *in, int ilen); +int COMP_expand_block(COMP_CTX *ctx, unsigned char *out, int olen, + unsigned char *in, int ilen); +COMP_METHOD *COMP_rle(void); +COMP_METHOD *COMP_zlib(void); +void COMP_zlib_cleanup(void); + +# ifdef HEADER_BIO_H +# ifdef ZLIB +BIO_METHOD *BIO_f_zlib(void); +# endif +# endif + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_COMP_strings(void); + +/* Error codes for the COMP functions. */ + +/* Function codes. */ +# define COMP_F_BIO_ZLIB_FLUSH 99 +# define COMP_F_BIO_ZLIB_NEW 100 +# define COMP_F_BIO_ZLIB_READ 101 +# define COMP_F_BIO_ZLIB_WRITE 102 + +/* Reason codes. */ +# define COMP_R_ZLIB_DEFLATE_ERROR 99 +# define COMP_R_ZLIB_INFLATE_ERROR 100 +# define COMP_R_ZLIB_NOT_SUPPORTED 101 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/conf.h b/OSlibs/ios/include/openssl/conf.h new file mode 100755 index 000000000..8d926d5d8 --- /dev/null +++ b/OSlibs/ios/include/openssl/conf.h @@ -0,0 +1,267 @@ +/* crypto/conf/conf.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_CONF_H +# define HEADER_CONF_H + +# include +# include +# include +# include +# include + +# include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + char *section; + char *name; + char *value; +} CONF_VALUE; + +DECLARE_STACK_OF(CONF_VALUE) +DECLARE_LHASH_OF(CONF_VALUE); + +struct conf_st; +struct conf_method_st; +typedef struct conf_method_st CONF_METHOD; + +struct conf_method_st { + const char *name; + CONF *(*create) (CONF_METHOD *meth); + int (*init) (CONF *conf); + int (*destroy) (CONF *conf); + int (*destroy_data) (CONF *conf); + int (*load_bio) (CONF *conf, BIO *bp, long *eline); + int (*dump) (const CONF *conf, BIO *bp); + int (*is_number) (const CONF *conf, char c); + int (*to_int) (const CONF *conf, char c); + int (*load) (CONF *conf, const char *name, long *eline); +}; + +/* Module definitions */ + +typedef struct conf_imodule_st CONF_IMODULE; +typedef struct conf_module_st CONF_MODULE; + +DECLARE_STACK_OF(CONF_MODULE) +DECLARE_STACK_OF(CONF_IMODULE) + +/* DSO module function typedefs */ +typedef int conf_init_func (CONF_IMODULE *md, const CONF *cnf); +typedef void conf_finish_func (CONF_IMODULE *md); + +# define CONF_MFLAGS_IGNORE_ERRORS 0x1 +# define CONF_MFLAGS_IGNORE_RETURN_CODES 0x2 +# define CONF_MFLAGS_SILENT 0x4 +# define CONF_MFLAGS_NO_DSO 0x8 +# define CONF_MFLAGS_IGNORE_MISSING_FILE 0x10 +# define CONF_MFLAGS_DEFAULT_SECTION 0x20 + +int CONF_set_default_method(CONF_METHOD *meth); +void CONF_set_nconf(CONF *conf, LHASH_OF(CONF_VALUE) *hash); +LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf, const char *file, + long *eline); +# ifndef OPENSSL_NO_FP_API +LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp, + long *eline); +# endif +LHASH_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp, + long *eline); +STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf, + const char *section); +char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf, const char *group, + const char *name); +long CONF_get_number(LHASH_OF(CONF_VALUE) *conf, const char *group, + const char *name); +void CONF_free(LHASH_OF(CONF_VALUE) *conf); +int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out); +int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out); + +void OPENSSL_config(const char *config_name); +void OPENSSL_no_config(void); + +/* + * New conf code. The semantics are different from the functions above. If + * that wasn't the case, the above functions would have been replaced + */ + +struct conf_st { + CONF_METHOD *meth; + void *meth_data; + LHASH_OF(CONF_VALUE) *data; +}; + +CONF *NCONF_new(CONF_METHOD *meth); +CONF_METHOD *NCONF_default(void); +CONF_METHOD *NCONF_WIN32(void); +# if 0 /* Just to give you an idea of what I have in + * mind */ +CONF_METHOD *NCONF_XML(void); +# endif +void NCONF_free(CONF *conf); +void NCONF_free_data(CONF *conf); + +int NCONF_load(CONF *conf, const char *file, long *eline); +# ifndef OPENSSL_NO_FP_API +int NCONF_load_fp(CONF *conf, FILE *fp, long *eline); +# endif +int NCONF_load_bio(CONF *conf, BIO *bp, long *eline); +STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf, + const char *section); +char *NCONF_get_string(const CONF *conf, const char *group, const char *name); +int NCONF_get_number_e(const CONF *conf, const char *group, const char *name, + long *result); +int NCONF_dump_fp(const CONF *conf, FILE *out); +int NCONF_dump_bio(const CONF *conf, BIO *out); + +# if 0 /* The following function has no error + * checking, and should therefore be avoided */ +long NCONF_get_number(CONF *conf, char *group, char *name); +# else +# define NCONF_get_number(c,g,n,r) NCONF_get_number_e(c,g,n,r) +# endif + +/* Module functions */ + +int CONF_modules_load(const CONF *cnf, const char *appname, + unsigned long flags); +int CONF_modules_load_file(const char *filename, const char *appname, + unsigned long flags); +void CONF_modules_unload(int all); +void CONF_modules_finish(void); +void CONF_modules_free(void); +int CONF_module_add(const char *name, conf_init_func *ifunc, + conf_finish_func *ffunc); + +const char *CONF_imodule_get_name(const CONF_IMODULE *md); +const char *CONF_imodule_get_value(const CONF_IMODULE *md); +void *CONF_imodule_get_usr_data(const CONF_IMODULE *md); +void CONF_imodule_set_usr_data(CONF_IMODULE *md, void *usr_data); +CONF_MODULE *CONF_imodule_get_module(const CONF_IMODULE *md); +unsigned long CONF_imodule_get_flags(const CONF_IMODULE *md); +void CONF_imodule_set_flags(CONF_IMODULE *md, unsigned long flags); +void *CONF_module_get_usr_data(CONF_MODULE *pmod); +void CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data); + +char *CONF_get1_default_config_file(void); + +int CONF_parse_list(const char *list, int sep, int nospc, + int (*list_cb) (const char *elem, int len, void *usr), + void *arg); + +void OPENSSL_load_builtin_modules(void); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_CONF_strings(void); + +/* Error codes for the CONF functions. */ + +/* Function codes. */ +# define CONF_F_CONF_DUMP_FP 104 +# define CONF_F_CONF_LOAD 100 +# define CONF_F_CONF_LOAD_BIO 102 +# define CONF_F_CONF_LOAD_FP 103 +# define CONF_F_CONF_MODULES_LOAD 116 +# define CONF_F_CONF_PARSE_LIST 119 +# define CONF_F_DEF_LOAD 120 +# define CONF_F_DEF_LOAD_BIO 121 +# define CONF_F_MODULE_INIT 115 +# define CONF_F_MODULE_LOAD_DSO 117 +# define CONF_F_MODULE_RUN 118 +# define CONF_F_NCONF_DUMP_BIO 105 +# define CONF_F_NCONF_DUMP_FP 106 +# define CONF_F_NCONF_GET_NUMBER 107 +# define CONF_F_NCONF_GET_NUMBER_E 112 +# define CONF_F_NCONF_GET_SECTION 108 +# define CONF_F_NCONF_GET_STRING 109 +# define CONF_F_NCONF_LOAD 113 +# define CONF_F_NCONF_LOAD_BIO 110 +# define CONF_F_NCONF_LOAD_FP 114 +# define CONF_F_NCONF_NEW 111 +# define CONF_F_STR_COPY 101 + +/* Reason codes. */ +# define CONF_R_ERROR_LOADING_DSO 110 +# define CONF_R_LIST_CANNOT_BE_NULL 115 +# define CONF_R_MISSING_CLOSE_SQUARE_BRACKET 100 +# define CONF_R_MISSING_EQUAL_SIGN 101 +# define CONF_R_MISSING_FINISH_FUNCTION 111 +# define CONF_R_MISSING_INIT_FUNCTION 112 +# define CONF_R_MODULE_INITIALIZATION_ERROR 109 +# define CONF_R_NO_CLOSE_BRACE 102 +# define CONF_R_NO_CONF 105 +# define CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE 106 +# define CONF_R_NO_SECTION 107 +# define CONF_R_NO_SUCH_FILE 114 +# define CONF_R_NO_VALUE 108 +# define CONF_R_UNABLE_TO_CREATE_NEW_SECTION 103 +# define CONF_R_UNKNOWN_MODULE_NAME 113 +# define CONF_R_VARIABLE_HAS_NO_VALUE 104 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/conf_api.h b/OSlibs/ios/include/openssl/conf_api.h new file mode 100755 index 000000000..e478f7df4 --- /dev/null +++ b/OSlibs/ios/include/openssl/conf_api.h @@ -0,0 +1,89 @@ +/* conf_api.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_CONF_API_H +# define HEADER_CONF_API_H + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Up until OpenSSL 0.9.5a, this was new_section */ +CONF_VALUE *_CONF_new_section(CONF *conf, const char *section); +/* Up until OpenSSL 0.9.5a, this was get_section */ +CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section); +/* Up until OpenSSL 0.9.5a, this was CONF_get_section */ +STACK_OF(CONF_VALUE) *_CONF_get_section_values(const CONF *conf, + const char *section); + +int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value); +char *_CONF_get_string(const CONF *conf, const char *section, + const char *name); +long _CONF_get_number(const CONF *conf, const char *section, + const char *name); + +int _CONF_new_data(CONF *conf); +void _CONF_free_data(CONF *conf); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/crypto.h b/OSlibs/ios/include/openssl/crypto.h new file mode 100755 index 000000000..6c644ce12 --- /dev/null +++ b/OSlibs/ios/include/openssl/crypto.h @@ -0,0 +1,661 @@ +/* crypto/crypto.h */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECDH support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#ifndef HEADER_CRYPTO_H +# define HEADER_CRYPTO_H + +# include + +# include + +# ifndef OPENSSL_NO_FP_API +# include +# endif + +# include +# include +# include +# include + +# ifdef CHARSET_EBCDIC +# include +# endif + +/* + * Resolve problems on some operating systems with symbol names that clash + * one way or another + */ +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Backward compatibility to SSLeay */ +/* + * This is more to be used to check the correct DLL is being used in the MS + * world. + */ +# define SSLEAY_VERSION_NUMBER OPENSSL_VERSION_NUMBER +# define SSLEAY_VERSION 0 +/* #define SSLEAY_OPTIONS 1 no longer supported */ +# define SSLEAY_CFLAGS 2 +# define SSLEAY_BUILT_ON 3 +# define SSLEAY_PLATFORM 4 +# define SSLEAY_DIR 5 + +/* Already declared in ossl_typ.h */ +# if 0 +typedef struct crypto_ex_data_st CRYPTO_EX_DATA; +/* Called when a new object is created */ +typedef int CRYPTO_EX_new (void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp); +/* Called when an object is free()ed */ +typedef void CRYPTO_EX_free (void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp); +/* Called when we need to dup an object */ +typedef int CRYPTO_EX_dup (CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from, + void *from_d, int idx, long argl, void *argp); +# endif + +/* A generic structure to pass assorted data in a expandable way */ +typedef struct openssl_item_st { + int code; + void *value; /* Not used for flag attributes */ + size_t value_size; /* Max size of value for output, length for + * input */ + size_t *value_length; /* Returned length of value for output */ +} OPENSSL_ITEM; + +/* + * When changing the CRYPTO_LOCK_* list, be sure to maintin the text lock + * names in cryptlib.c + */ + +# define CRYPTO_LOCK_ERR 1 +# define CRYPTO_LOCK_EX_DATA 2 +# define CRYPTO_LOCK_X509 3 +# define CRYPTO_LOCK_X509_INFO 4 +# define CRYPTO_LOCK_X509_PKEY 5 +# define CRYPTO_LOCK_X509_CRL 6 +# define CRYPTO_LOCK_X509_REQ 7 +# define CRYPTO_LOCK_DSA 8 +# define CRYPTO_LOCK_RSA 9 +# define CRYPTO_LOCK_EVP_PKEY 10 +# define CRYPTO_LOCK_X509_STORE 11 +# define CRYPTO_LOCK_SSL_CTX 12 +# define CRYPTO_LOCK_SSL_CERT 13 +# define CRYPTO_LOCK_SSL_SESSION 14 +# define CRYPTO_LOCK_SSL_SESS_CERT 15 +# define CRYPTO_LOCK_SSL 16 +# define CRYPTO_LOCK_SSL_METHOD 17 +# define CRYPTO_LOCK_RAND 18 +# define CRYPTO_LOCK_RAND2 19 +# define CRYPTO_LOCK_MALLOC 20 +# define CRYPTO_LOCK_BIO 21 +# define CRYPTO_LOCK_GETHOSTBYNAME 22 +# define CRYPTO_LOCK_GETSERVBYNAME 23 +# define CRYPTO_LOCK_READDIR 24 +# define CRYPTO_LOCK_RSA_BLINDING 25 +# define CRYPTO_LOCK_DH 26 +# define CRYPTO_LOCK_MALLOC2 27 +# define CRYPTO_LOCK_DSO 28 +# define CRYPTO_LOCK_DYNLOCK 29 +# define CRYPTO_LOCK_ENGINE 30 +# define CRYPTO_LOCK_UI 31 +# define CRYPTO_LOCK_ECDSA 32 +# define CRYPTO_LOCK_EC 33 +# define CRYPTO_LOCK_ECDH 34 +# define CRYPTO_LOCK_BN 35 +# define CRYPTO_LOCK_EC_PRE_COMP 36 +# define CRYPTO_LOCK_STORE 37 +# define CRYPTO_LOCK_COMP 38 +# define CRYPTO_LOCK_FIPS 39 +# define CRYPTO_LOCK_FIPS2 40 +# define CRYPTO_NUM_LOCKS 41 + +# define CRYPTO_LOCK 1 +# define CRYPTO_UNLOCK 2 +# define CRYPTO_READ 4 +# define CRYPTO_WRITE 8 + +# ifndef OPENSSL_NO_LOCKING +# ifndef CRYPTO_w_lock +# define CRYPTO_w_lock(type) \ + CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,__FILE__,__LINE__) +# define CRYPTO_w_unlock(type) \ + CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,__FILE__,__LINE__) +# define CRYPTO_r_lock(type) \ + CRYPTO_lock(CRYPTO_LOCK|CRYPTO_READ,type,__FILE__,__LINE__) +# define CRYPTO_r_unlock(type) \ + CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_READ,type,__FILE__,__LINE__) +# define CRYPTO_add(addr,amount,type) \ + CRYPTO_add_lock(addr,amount,type,__FILE__,__LINE__) +# endif +# else +# define CRYPTO_w_lock(a) +# define CRYPTO_w_unlock(a) +# define CRYPTO_r_lock(a) +# define CRYPTO_r_unlock(a) +# define CRYPTO_add(a,b,c) ((*(a))+=(b)) +# endif + +/* + * Some applications as well as some parts of OpenSSL need to allocate and + * deallocate locks in a dynamic fashion. The following typedef makes this + * possible in a type-safe manner. + */ +/* struct CRYPTO_dynlock_value has to be defined by the application. */ +typedef struct { + int references; + struct CRYPTO_dynlock_value *data; +} CRYPTO_dynlock; + +/* + * The following can be used to detect memory leaks in the SSLeay library. It + * used, it turns on malloc checking + */ + +# define CRYPTO_MEM_CHECK_OFF 0x0/* an enume */ +# define CRYPTO_MEM_CHECK_ON 0x1/* a bit */ +# define CRYPTO_MEM_CHECK_ENABLE 0x2/* a bit */ +# define CRYPTO_MEM_CHECK_DISABLE 0x3/* an enume */ + +/* + * The following are bit values to turn on or off options connected to the + * malloc checking functionality + */ + +/* Adds time to the memory checking information */ +# define V_CRYPTO_MDEBUG_TIME 0x1/* a bit */ +/* Adds thread number to the memory checking information */ +# define V_CRYPTO_MDEBUG_THREAD 0x2/* a bit */ + +# define V_CRYPTO_MDEBUG_ALL (V_CRYPTO_MDEBUG_TIME | V_CRYPTO_MDEBUG_THREAD) + +/* predec of the BIO type */ +typedef struct bio_st BIO_dummy; + +struct crypto_ex_data_st { + STACK_OF(void) *sk; + /* gcc is screwing up this data structure :-( */ + int dummy; +}; +DECLARE_STACK_OF(void) + +/* + * This stuff is basically class callback functions The current classes are + * SSL_CTX, SSL, SSL_SESSION, and a few more + */ + +typedef struct crypto_ex_data_func_st { + long argl; /* Arbitary long */ + void *argp; /* Arbitary void * */ + CRYPTO_EX_new *new_func; + CRYPTO_EX_free *free_func; + CRYPTO_EX_dup *dup_func; +} CRYPTO_EX_DATA_FUNCS; + +DECLARE_STACK_OF(CRYPTO_EX_DATA_FUNCS) + +/* + * Per class, we have a STACK of CRYPTO_EX_DATA_FUNCS for each CRYPTO_EX_DATA + * entry. + */ + +# define CRYPTO_EX_INDEX_BIO 0 +# define CRYPTO_EX_INDEX_SSL 1 +# define CRYPTO_EX_INDEX_SSL_CTX 2 +# define CRYPTO_EX_INDEX_SSL_SESSION 3 +# define CRYPTO_EX_INDEX_X509_STORE 4 +# define CRYPTO_EX_INDEX_X509_STORE_CTX 5 +# define CRYPTO_EX_INDEX_RSA 6 +# define CRYPTO_EX_INDEX_DSA 7 +# define CRYPTO_EX_INDEX_DH 8 +# define CRYPTO_EX_INDEX_ENGINE 9 +# define CRYPTO_EX_INDEX_X509 10 +# define CRYPTO_EX_INDEX_UI 11 +# define CRYPTO_EX_INDEX_ECDSA 12 +# define CRYPTO_EX_INDEX_ECDH 13 +# define CRYPTO_EX_INDEX_COMP 14 +# define CRYPTO_EX_INDEX_STORE 15 + +/* + * Dynamically assigned indexes start from this value (don't use directly, + * use via CRYPTO_ex_data_new_class). + */ +# define CRYPTO_EX_INDEX_USER 100 + +/* + * This is the default callbacks, but we can have others as well: this is + * needed in Win32 where the application malloc and the library malloc may + * not be the same. + */ +# define CRYPTO_malloc_init() CRYPTO_set_mem_functions(\ + malloc, realloc, free) + +# if defined CRYPTO_MDEBUG_ALL || defined CRYPTO_MDEBUG_TIME || defined CRYPTO_MDEBUG_THREAD +# ifndef CRYPTO_MDEBUG /* avoid duplicate #define */ +# define CRYPTO_MDEBUG +# endif +# endif + +/* + * Set standard debugging functions (not done by default unless CRYPTO_MDEBUG + * is defined) + */ +# define CRYPTO_malloc_debug_init() do {\ + CRYPTO_set_mem_debug_functions(\ + CRYPTO_dbg_malloc,\ + CRYPTO_dbg_realloc,\ + CRYPTO_dbg_free,\ + CRYPTO_dbg_set_options,\ + CRYPTO_dbg_get_options);\ + } while(0) + +int CRYPTO_mem_ctrl(int mode); +int CRYPTO_is_mem_check_on(void); + +/* for applications */ +# define MemCheck_start() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON) +# define MemCheck_stop() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF) + +/* for library-internal use */ +# define MemCheck_on() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE) +# define MemCheck_off() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE) +# define is_MemCheck_on() CRYPTO_is_mem_check_on() + +# define OPENSSL_malloc(num) CRYPTO_malloc((int)num,__FILE__,__LINE__) +# define OPENSSL_strdup(str) CRYPTO_strdup((str),__FILE__,__LINE__) +# define OPENSSL_realloc(addr,num) \ + CRYPTO_realloc((char *)addr,(int)num,__FILE__,__LINE__) +# define OPENSSL_realloc_clean(addr,old_num,num) \ + CRYPTO_realloc_clean(addr,old_num,num,__FILE__,__LINE__) +# define OPENSSL_remalloc(addr,num) \ + CRYPTO_remalloc((char **)addr,(int)num,__FILE__,__LINE__) +# define OPENSSL_freeFunc CRYPTO_free +# define OPENSSL_free(addr) CRYPTO_free(addr) + +# define OPENSSL_malloc_locked(num) \ + CRYPTO_malloc_locked((int)num,__FILE__,__LINE__) +# define OPENSSL_free_locked(addr) CRYPTO_free_locked(addr) + +const char *SSLeay_version(int type); +unsigned long SSLeay(void); + +int OPENSSL_issetugid(void); + +/* An opaque type representing an implementation of "ex_data" support */ +typedef struct st_CRYPTO_EX_DATA_IMPL CRYPTO_EX_DATA_IMPL; +/* Return an opaque pointer to the current "ex_data" implementation */ +const CRYPTO_EX_DATA_IMPL *CRYPTO_get_ex_data_implementation(void); +/* Sets the "ex_data" implementation to be used (if it's not too late) */ +int CRYPTO_set_ex_data_implementation(const CRYPTO_EX_DATA_IMPL *i); +/* Get a new "ex_data" class, and return the corresponding "class_index" */ +int CRYPTO_ex_data_new_class(void); +/* Within a given class, get/register a new index */ +int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp, + CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); +/* + * Initialise/duplicate/free CRYPTO_EX_DATA variables corresponding to a + * given class (invokes whatever per-class callbacks are applicable) + */ +int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad); +int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, + CRYPTO_EX_DATA *from); +void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad); +/* + * Get/set data in a CRYPTO_EX_DATA variable corresponding to a particular + * index (relative to the class type involved) + */ +int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val); +void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx); +/* + * This function cleans up all "ex_data" state. It mustn't be called under + * potential race-conditions. + */ +void CRYPTO_cleanup_all_ex_data(void); + +int CRYPTO_get_new_lockid(char *name); + +int CRYPTO_num_locks(void); /* return CRYPTO_NUM_LOCKS (shared libs!) */ +void CRYPTO_lock(int mode, int type, const char *file, int line); +void CRYPTO_set_locking_callback(void (*func) (int mode, int type, + const char *file, int line)); +void (*CRYPTO_get_locking_callback(void)) (int mode, int type, + const char *file, int line); +void CRYPTO_set_add_lock_callback(int (*func) + (int *num, int mount, int type, + const char *file, int line)); +int (*CRYPTO_get_add_lock_callback(void)) (int *num, int mount, int type, + const char *file, int line); + +/* Don't use this structure directly. */ +typedef struct crypto_threadid_st { + void *ptr; + unsigned long val; +} CRYPTO_THREADID; +/* Only use CRYPTO_THREADID_set_[numeric|pointer]() within callbacks */ +void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val); +void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr); +int CRYPTO_THREADID_set_callback(void (*threadid_func) (CRYPTO_THREADID *)); +void (*CRYPTO_THREADID_get_callback(void)) (CRYPTO_THREADID *); +void CRYPTO_THREADID_current(CRYPTO_THREADID *id); +int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b); +void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src); +unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id); +# ifndef OPENSSL_NO_DEPRECATED +void CRYPTO_set_id_callback(unsigned long (*func) (void)); +unsigned long (*CRYPTO_get_id_callback(void)) (void); +unsigned long CRYPTO_thread_id(void); +# endif + +const char *CRYPTO_get_lock_name(int type); +int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file, + int line); + +int CRYPTO_get_new_dynlockid(void); +void CRYPTO_destroy_dynlockid(int i); +struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i); +void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value + *(*dyn_create_function) (const char + *file, + int line)); +void CRYPTO_set_dynlock_lock_callback(void (*dyn_lock_function) + (int mode, + struct CRYPTO_dynlock_value *l, + const char *file, int line)); +void CRYPTO_set_dynlock_destroy_callback(void (*dyn_destroy_function) + (struct CRYPTO_dynlock_value *l, + const char *file, int line)); +struct CRYPTO_dynlock_value +*(*CRYPTO_get_dynlock_create_callback(void)) (const char *file, int line); +void (*CRYPTO_get_dynlock_lock_callback(void)) (int mode, + struct CRYPTO_dynlock_value + *l, const char *file, + int line); +void (*CRYPTO_get_dynlock_destroy_callback(void)) (struct CRYPTO_dynlock_value + *l, const char *file, + int line); + +/* + * CRYPTO_set_mem_functions includes CRYPTO_set_locked_mem_functions -- call + * the latter last if you need different functions + */ +int CRYPTO_set_mem_functions(void *(*m) (size_t), void *(*r) (void *, size_t), + void (*f) (void *)); +int CRYPTO_set_locked_mem_functions(void *(*m) (size_t), + void (*free_func) (void *)); +int CRYPTO_set_mem_ex_functions(void *(*m) (size_t, const char *, int), + void *(*r) (void *, size_t, const char *, + int), void (*f) (void *)); +int CRYPTO_set_locked_mem_ex_functions(void *(*m) (size_t, const char *, int), + void (*free_func) (void *)); +int CRYPTO_set_mem_debug_functions(void (*m) + (void *, int, const char *, int, int), + void (*r) (void *, void *, int, + const char *, int, int), + void (*f) (void *, int), void (*so) (long), + long (*go) (void)); +void CRYPTO_get_mem_functions(void *(**m) (size_t), + void *(**r) (void *, size_t), + void (**f) (void *)); +void CRYPTO_get_locked_mem_functions(void *(**m) (size_t), + void (**f) (void *)); +void CRYPTO_get_mem_ex_functions(void *(**m) (size_t, const char *, int), + void *(**r) (void *, size_t, const char *, + int), void (**f) (void *)); +void CRYPTO_get_locked_mem_ex_functions(void + *(**m) (size_t, const char *, int), + void (**f) (void *)); +void CRYPTO_get_mem_debug_functions(void (**m) + (void *, int, const char *, int, int), + void (**r) (void *, void *, int, + const char *, int, int), + void (**f) (void *, int), + void (**so) (long), long (**go) (void)); + +void *CRYPTO_malloc_locked(int num, const char *file, int line); +void CRYPTO_free_locked(void *ptr); +void *CRYPTO_malloc(int num, const char *file, int line); +char *CRYPTO_strdup(const char *str, const char *file, int line); +void CRYPTO_free(void *ptr); +void *CRYPTO_realloc(void *addr, int num, const char *file, int line); +void *CRYPTO_realloc_clean(void *addr, int old_num, int num, const char *file, + int line); +void *CRYPTO_remalloc(void *addr, int num, const char *file, int line); + +void OPENSSL_cleanse(void *ptr, size_t len); + +void CRYPTO_set_mem_debug_options(long bits); +long CRYPTO_get_mem_debug_options(void); + +# define CRYPTO_push_info(info) \ + CRYPTO_push_info_(info, __FILE__, __LINE__); +int CRYPTO_push_info_(const char *info, const char *file, int line); +int CRYPTO_pop_info(void); +int CRYPTO_remove_all_info(void); + +/* + * Default debugging functions (enabled by CRYPTO_malloc_debug_init() macro; + * used as default in CRYPTO_MDEBUG compilations): + */ +/*- + * The last argument has the following significance: + * + * 0: called before the actual memory allocation has taken place + * 1: called after the actual memory allocation has taken place + */ +void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line, + int before_p); +void CRYPTO_dbg_realloc(void *addr1, void *addr2, int num, const char *file, + int line, int before_p); +void CRYPTO_dbg_free(void *addr, int before_p); +/*- + * Tell the debugging code about options. By default, the following values + * apply: + * + * 0: Clear all options. + * V_CRYPTO_MDEBUG_TIME (1): Set the "Show Time" option. + * V_CRYPTO_MDEBUG_THREAD (2): Set the "Show Thread Number" option. + * V_CRYPTO_MDEBUG_ALL (3): 1 + 2 + */ +void CRYPTO_dbg_set_options(long bits); +long CRYPTO_dbg_get_options(void); + +# ifndef OPENSSL_NO_FP_API +void CRYPTO_mem_leaks_fp(FILE *); +# endif +void CRYPTO_mem_leaks(struct bio_st *bio); +/* unsigned long order, char *file, int line, int num_bytes, char *addr */ +typedef void *CRYPTO_MEM_LEAK_CB (unsigned long, const char *, int, int, + void *); +void CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb); + +/* die if we have to */ +void OpenSSLDie(const char *file, int line, const char *assertion); +# define OPENSSL_assert(e) (void)((e) ? 0 : (OpenSSLDie(__FILE__, __LINE__, #e),1)) + +unsigned long *OPENSSL_ia32cap_loc(void); +# define OPENSSL_ia32cap (*(OPENSSL_ia32cap_loc())) +int OPENSSL_isservice(void); + +int FIPS_mode(void); +int FIPS_mode_set(int r); + +void OPENSSL_init(void); + +# define fips_md_init(alg) fips_md_init_ctx(alg, alg) + +# ifdef OPENSSL_FIPS +# define fips_md_init_ctx(alg, cx) \ + int alg##_Init(cx##_CTX *c) \ + { \ + if (FIPS_mode()) OpenSSLDie(__FILE__, __LINE__, \ + "Low level API call to digest " #alg " forbidden in FIPS mode!"); \ + return private_##alg##_Init(c); \ + } \ + int private_##alg##_Init(cx##_CTX *c) + +# define fips_cipher_abort(alg) \ + if (FIPS_mode()) OpenSSLDie(__FILE__, __LINE__, \ + "Low level API call to cipher " #alg " forbidden in FIPS mode!") + +# else +# define fips_md_init_ctx(alg, cx) \ + int alg##_Init(cx##_CTX *c) +# define fips_cipher_abort(alg) while(0) +# endif + +/* + * CRYPTO_memcmp returns zero iff the |len| bytes at |a| and |b| are equal. + * It takes an amount of time dependent on |len|, but independent of the + * contents of |a| and |b|. Unlike memcmp, it cannot be used to put elements + * into a defined order as the return value when a != b is undefined, other + * than to be non-zero. + */ +int CRYPTO_memcmp(const volatile void *a, const volatile void *b, size_t len); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_CRYPTO_strings(void); + +/* Error codes for the CRYPTO functions. */ + +/* Function codes. */ +# define CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX 100 +# define CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID 103 +# define CRYPTO_F_CRYPTO_GET_NEW_LOCKID 101 +# define CRYPTO_F_CRYPTO_SET_EX_DATA 102 +# define CRYPTO_F_DEF_ADD_INDEX 104 +# define CRYPTO_F_DEF_GET_CLASS 105 +# define CRYPTO_F_FIPS_MODE_SET 109 +# define CRYPTO_F_INT_DUP_EX_DATA 106 +# define CRYPTO_F_INT_FREE_EX_DATA 107 +# define CRYPTO_F_INT_NEW_EX_DATA 108 + +/* Reason codes. */ +# define CRYPTO_R_FIPS_MODE_NOT_SUPPORTED 101 +# define CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK 100 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/des.h b/OSlibs/ios/include/openssl/des.h new file mode 100755 index 000000000..1b40144e1 --- /dev/null +++ b/OSlibs/ios/include/openssl/des.h @@ -0,0 +1,257 @@ +/* crypto/des/des.h */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_NEW_DES_H +# define HEADER_NEW_DES_H + +# include /* OPENSSL_EXTERN, OPENSSL_NO_DES, DES_LONG + * (via openssl/opensslconf.h */ + +# ifdef OPENSSL_NO_DES +# error DES is disabled. +# endif + +# ifdef OPENSSL_BUILD_SHLIBCRYPTO +# undef OPENSSL_EXTERN +# define OPENSSL_EXTERN OPENSSL_EXPORT +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef unsigned char DES_cblock[8]; +typedef /* const */ unsigned char const_DES_cblock[8]; +/* + * With "const", gcc 2.8.1 on Solaris thinks that DES_cblock * and + * const_DES_cblock * are incompatible pointer types. + */ + +typedef struct DES_ks { + union { + DES_cblock cblock; + /* + * make sure things are correct size on machines with 8 byte longs + */ + DES_LONG deslong[2]; + } ks[16]; +} DES_key_schedule; + +# ifndef OPENSSL_DISABLE_OLD_DES_SUPPORT +# ifndef OPENSSL_ENABLE_OLD_DES_SUPPORT +# define OPENSSL_ENABLE_OLD_DES_SUPPORT +# endif +# endif + +# ifdef OPENSSL_ENABLE_OLD_DES_SUPPORT +# include +# endif + +# define DES_KEY_SZ (sizeof(DES_cblock)) +# define DES_SCHEDULE_SZ (sizeof(DES_key_schedule)) + +# define DES_ENCRYPT 1 +# define DES_DECRYPT 0 + +# define DES_CBC_MODE 0 +# define DES_PCBC_MODE 1 + +# define DES_ecb2_encrypt(i,o,k1,k2,e) \ + DES_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e)) + +# define DES_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \ + DES_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e)) + +# define DES_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \ + DES_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e)) + +# define DES_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \ + DES_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n)) + +OPENSSL_DECLARE_GLOBAL(int, DES_check_key); /* defaults to false */ +# define DES_check_key OPENSSL_GLOBAL_REF(DES_check_key) +OPENSSL_DECLARE_GLOBAL(int, DES_rw_mode); /* defaults to DES_PCBC_MODE */ +# define DES_rw_mode OPENSSL_GLOBAL_REF(DES_rw_mode) + +const char *DES_options(void); +void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output, + DES_key_schedule *ks1, DES_key_schedule *ks2, + DES_key_schedule *ks3, int enc); +DES_LONG DES_cbc_cksum(const unsigned char *input, DES_cblock *output, + long length, DES_key_schedule *schedule, + const_DES_cblock *ivec); +/* DES_cbc_encrypt does not update the IV! Use DES_ncbc_encrypt instead. */ +void DES_cbc_encrypt(const unsigned char *input, unsigned char *output, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int enc); +void DES_ncbc_encrypt(const unsigned char *input, unsigned char *output, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int enc); +void DES_xcbc_encrypt(const unsigned char *input, unsigned char *output, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, const_DES_cblock *inw, + const_DES_cblock *outw, int enc); +void DES_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int enc); +void DES_ecb_encrypt(const_DES_cblock *input, DES_cblock *output, + DES_key_schedule *ks, int enc); + +/* + * This is the DES encryption function that gets called by just about every + * other DES routine in the library. You should not use this function except + * to implement 'modes' of DES. I say this because the functions that call + * this routine do the conversion from 'char *' to long, and this needs to be + * done to make sure 'non-aligned' memory access do not occur. The + * characters are loaded 'little endian'. Data is a pointer to 2 unsigned + * long's and ks is the DES_key_schedule to use. enc, is non zero specifies + * encryption, zero if decryption. + */ +void DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc); + +/* + * This functions is the same as DES_encrypt1() except that the DES initial + * permutation (IP) and final permutation (FP) have been left out. As for + * DES_encrypt1(), you should not use this function. It is used by the + * routines in the library that implement triple DES. IP() DES_encrypt2() + * DES_encrypt2() DES_encrypt2() FP() is the same as DES_encrypt1() + * DES_encrypt1() DES_encrypt1() except faster :-). + */ +void DES_encrypt2(DES_LONG *data, DES_key_schedule *ks, int enc); + +void DES_encrypt3(DES_LONG *data, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3); +void DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3); +void DES_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output, + long length, + DES_key_schedule *ks1, DES_key_schedule *ks2, + DES_key_schedule *ks3, DES_cblock *ivec, int enc); +void DES_ede3_cbcm_encrypt(const unsigned char *in, unsigned char *out, + long length, + DES_key_schedule *ks1, DES_key_schedule *ks2, + DES_key_schedule *ks3, + DES_cblock *ivec1, DES_cblock *ivec2, int enc); +void DES_ede3_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3, + DES_cblock *ivec, int *num, int enc); +void DES_ede3_cfb_encrypt(const unsigned char *in, unsigned char *out, + int numbits, long length, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3, + DES_cblock *ivec, int enc); +void DES_ede3_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3, + DES_cblock *ivec, int *num); +# if 0 +void DES_xwhite_in2out(const_DES_cblock *DES_key, const_DES_cblock *in_white, + DES_cblock *out_white); +# endif + +int DES_enc_read(int fd, void *buf, int len, DES_key_schedule *sched, + DES_cblock *iv); +int DES_enc_write(int fd, const void *buf, int len, DES_key_schedule *sched, + DES_cblock *iv); +char *DES_fcrypt(const char *buf, const char *salt, char *ret); +char *DES_crypt(const char *buf, const char *salt); +void DES_ofb_encrypt(const unsigned char *in, unsigned char *out, int numbits, + long length, DES_key_schedule *schedule, + DES_cblock *ivec); +void DES_pcbc_encrypt(const unsigned char *input, unsigned char *output, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int enc); +DES_LONG DES_quad_cksum(const unsigned char *input, DES_cblock output[], + long length, int out_count, DES_cblock *seed); +int DES_random_key(DES_cblock *ret); +void DES_set_odd_parity(DES_cblock *key); +int DES_check_key_parity(const_DES_cblock *key); +int DES_is_weak_key(const_DES_cblock *key); +/* + * DES_set_key (= set_key = DES_key_sched = key_sched) calls + * DES_set_key_checked if global variable DES_check_key is set, + * DES_set_key_unchecked otherwise. + */ +int DES_set_key(const_DES_cblock *key, DES_key_schedule *schedule); +int DES_key_sched(const_DES_cblock *key, DES_key_schedule *schedule); +int DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule); +void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule); +# ifdef OPENSSL_FIPS +void private_DES_set_key_unchecked(const_DES_cblock *key, + DES_key_schedule *schedule); +# endif +void DES_string_to_key(const char *str, DES_cblock *key); +void DES_string_to_2keys(const char *str, DES_cblock *key1, DES_cblock *key2); +void DES_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int *num, int enc); +void DES_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int *num); + +int DES_read_password(DES_cblock *key, const char *prompt, int verify); +int DES_read_2passwords(DES_cblock *key1, DES_cblock *key2, + const char *prompt, int verify); + +# define DES_fixup_key_parity DES_set_odd_parity + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/OSlibs/ios/include/openssl/des_old.h b/OSlibs/ios/include/openssl/des_old.h new file mode 100755 index 000000000..ee7607a24 --- /dev/null +++ b/OSlibs/ios/include/openssl/des_old.h @@ -0,0 +1,497 @@ +/* crypto/des/des_old.h */ + +/*- + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + * + * The function names in here are deprecated and are only present to + * provide an interface compatible with openssl 0.9.6 and older as + * well as libdes. OpenSSL now provides functions where "des_" has + * been replaced with "DES_" in the names, to make it possible to + * make incompatible changes that are needed for C type security and + * other stuff. + * + * This include files has two compatibility modes: + * + * - If OPENSSL_DES_LIBDES_COMPATIBILITY is defined, you get an API + * that is compatible with libdes and SSLeay. + * - If OPENSSL_DES_LIBDES_COMPATIBILITY isn't defined, you get an + * API that is compatible with OpenSSL 0.9.5x to 0.9.6x. + * + * Note that these modes break earlier snapshots of OpenSSL, where + * libdes compatibility was the only available mode or (later on) the + * prefered compatibility mode. However, after much consideration + * (and more or less violent discussions with external parties), it + * was concluded that OpenSSL should be compatible with earlier versions + * of itself before anything else. Also, in all honesty, libdes is + * an old beast that shouldn't really be used any more. + * + * Please consider starting to use the DES_ functions rather than the + * des_ ones. The des_ functions will disappear completely before + * OpenSSL 1.0! + * + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + */ + +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_DES_H +# define HEADER_DES_H + +# include /* OPENSSL_EXTERN, OPENSSL_NO_DES, DES_LONG */ + +# ifdef OPENSSL_NO_DES +# error DES is disabled. +# endif + +# ifndef HEADER_NEW_DES_H +# error You must include des.h, not des_old.h directly. +# endif + +# ifdef _KERBEROS_DES_H +# error replaces . +# endif + +# include + +# ifdef OPENSSL_BUILD_SHLIBCRYPTO +# undef OPENSSL_EXTERN +# define OPENSSL_EXTERN OPENSSL_EXPORT +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +# ifdef _ +# undef _ +# endif + +typedef unsigned char _ossl_old_des_cblock[8]; +typedef struct _ossl_old_des_ks_struct { + union { + _ossl_old_des_cblock _; + /* + * make sure things are correct size on machines with 8 byte longs + */ + DES_LONG pad[2]; + } ks; +} _ossl_old_des_key_schedule[16]; + +# ifndef OPENSSL_DES_LIBDES_COMPATIBILITY +# define des_cblock DES_cblock +# define const_des_cblock const_DES_cblock +# define des_key_schedule DES_key_schedule +# define des_ecb3_encrypt(i,o,k1,k2,k3,e)\ + DES_ecb3_encrypt((i),(o),&(k1),&(k2),&(k3),(e)) +# define des_ede3_cbc_encrypt(i,o,l,k1,k2,k3,iv,e)\ + DES_ede3_cbc_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv),(e)) +# define des_ede3_cbcm_encrypt(i,o,l,k1,k2,k3,iv1,iv2,e)\ + DES_ede3_cbcm_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv1),(iv2),(e)) +# define des_ede3_cfb64_encrypt(i,o,l,k1,k2,k3,iv,n,e)\ + DES_ede3_cfb64_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv),(n),(e)) +# define des_ede3_ofb64_encrypt(i,o,l,k1,k2,k3,iv,n)\ + DES_ede3_ofb64_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv),(n)) +# define des_options()\ + DES_options() +# define des_cbc_cksum(i,o,l,k,iv)\ + DES_cbc_cksum((i),(o),(l),&(k),(iv)) +# define des_cbc_encrypt(i,o,l,k,iv,e)\ + DES_cbc_encrypt((i),(o),(l),&(k),(iv),(e)) +# define des_ncbc_encrypt(i,o,l,k,iv,e)\ + DES_ncbc_encrypt((i),(o),(l),&(k),(iv),(e)) +# define des_xcbc_encrypt(i,o,l,k,iv,inw,outw,e)\ + DES_xcbc_encrypt((i),(o),(l),&(k),(iv),(inw),(outw),(e)) +# define des_cfb_encrypt(i,o,n,l,k,iv,e)\ + DES_cfb_encrypt((i),(o),(n),(l),&(k),(iv),(e)) +# define des_ecb_encrypt(i,o,k,e)\ + DES_ecb_encrypt((i),(o),&(k),(e)) +# define des_encrypt1(d,k,e)\ + DES_encrypt1((d),&(k),(e)) +# define des_encrypt2(d,k,e)\ + DES_encrypt2((d),&(k),(e)) +# define des_encrypt3(d,k1,k2,k3)\ + DES_encrypt3((d),&(k1),&(k2),&(k3)) +# define des_decrypt3(d,k1,k2,k3)\ + DES_decrypt3((d),&(k1),&(k2),&(k3)) +# define des_xwhite_in2out(k,i,o)\ + DES_xwhite_in2out((k),(i),(o)) +# define des_enc_read(f,b,l,k,iv)\ + DES_enc_read((f),(b),(l),&(k),(iv)) +# define des_enc_write(f,b,l,k,iv)\ + DES_enc_write((f),(b),(l),&(k),(iv)) +# define des_fcrypt(b,s,r)\ + DES_fcrypt((b),(s),(r)) +# if 0 +# define des_crypt(b,s)\ + DES_crypt((b),(s)) +# if !defined(PERL5) && !defined(__FreeBSD__) && !defined(NeXT) && !defined(__OpenBSD__) +# define crypt(b,s)\ + DES_crypt((b),(s)) +# endif +# endif +# define des_ofb_encrypt(i,o,n,l,k,iv)\ + DES_ofb_encrypt((i),(o),(n),(l),&(k),(iv)) +# define des_pcbc_encrypt(i,o,l,k,iv,e)\ + DES_pcbc_encrypt((i),(o),(l),&(k),(iv),(e)) +# define des_quad_cksum(i,o,l,c,s)\ + DES_quad_cksum((i),(o),(l),(c),(s)) +# define des_random_seed(k)\ + _ossl_096_des_random_seed((k)) +# define des_random_key(r)\ + DES_random_key((r)) +# define des_read_password(k,p,v) \ + DES_read_password((k),(p),(v)) +# define des_read_2passwords(k1,k2,p,v) \ + DES_read_2passwords((k1),(k2),(p),(v)) +# define des_set_odd_parity(k)\ + DES_set_odd_parity((k)) +# define des_check_key_parity(k)\ + DES_check_key_parity((k)) +# define des_is_weak_key(k)\ + DES_is_weak_key((k)) +# define des_set_key(k,ks)\ + DES_set_key((k),&(ks)) +# define des_key_sched(k,ks)\ + DES_key_sched((k),&(ks)) +# define des_set_key_checked(k,ks)\ + DES_set_key_checked((k),&(ks)) +# define des_set_key_unchecked(k,ks)\ + DES_set_key_unchecked((k),&(ks)) +# define des_string_to_key(s,k)\ + DES_string_to_key((s),(k)) +# define des_string_to_2keys(s,k1,k2)\ + DES_string_to_2keys((s),(k1),(k2)) +# define des_cfb64_encrypt(i,o,l,ks,iv,n,e)\ + DES_cfb64_encrypt((i),(o),(l),&(ks),(iv),(n),(e)) +# define des_ofb64_encrypt(i,o,l,ks,iv,n)\ + DES_ofb64_encrypt((i),(o),(l),&(ks),(iv),(n)) + +# define des_ecb2_encrypt(i,o,k1,k2,e) \ + des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e)) + +# define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \ + des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e)) + +# define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \ + des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e)) + +# define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \ + des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n)) + +# define des_check_key DES_check_key +# define des_rw_mode DES_rw_mode +# else /* libdes compatibility */ +/* + * Map all symbol names to _ossl_old_des_* form, so we avoid all clashes with + * libdes + */ +# define des_cblock _ossl_old_des_cblock +# define des_key_schedule _ossl_old_des_key_schedule +# define des_ecb3_encrypt(i,o,k1,k2,k3,e)\ + _ossl_old_des_ecb3_encrypt((i),(o),(k1),(k2),(k3),(e)) +# define des_ede3_cbc_encrypt(i,o,l,k1,k2,k3,iv,e)\ + _ossl_old_des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k3),(iv),(e)) +# define des_ede3_cfb64_encrypt(i,o,l,k1,k2,k3,iv,n,e)\ + _ossl_old_des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k3),(iv),(n),(e)) +# define des_ede3_ofb64_encrypt(i,o,l,k1,k2,k3,iv,n)\ + _ossl_old_des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k3),(iv),(n)) +# define des_options()\ + _ossl_old_des_options() +# define des_cbc_cksum(i,o,l,k,iv)\ + _ossl_old_des_cbc_cksum((i),(o),(l),(k),(iv)) +# define des_cbc_encrypt(i,o,l,k,iv,e)\ + _ossl_old_des_cbc_encrypt((i),(o),(l),(k),(iv),(e)) +# define des_ncbc_encrypt(i,o,l,k,iv,e)\ + _ossl_old_des_ncbc_encrypt((i),(o),(l),(k),(iv),(e)) +# define des_xcbc_encrypt(i,o,l,k,iv,inw,outw,e)\ + _ossl_old_des_xcbc_encrypt((i),(o),(l),(k),(iv),(inw),(outw),(e)) +# define des_cfb_encrypt(i,o,n,l,k,iv,e)\ + _ossl_old_des_cfb_encrypt((i),(o),(n),(l),(k),(iv),(e)) +# define des_ecb_encrypt(i,o,k,e)\ + _ossl_old_des_ecb_encrypt((i),(o),(k),(e)) +# define des_encrypt(d,k,e)\ + _ossl_old_des_encrypt((d),(k),(e)) +# define des_encrypt2(d,k,e)\ + _ossl_old_des_encrypt2((d),(k),(e)) +# define des_encrypt3(d,k1,k2,k3)\ + _ossl_old_des_encrypt3((d),(k1),(k2),(k3)) +# define des_decrypt3(d,k1,k2,k3)\ + _ossl_old_des_decrypt3((d),(k1),(k2),(k3)) +# define des_xwhite_in2out(k,i,o)\ + _ossl_old_des_xwhite_in2out((k),(i),(o)) +# define des_enc_read(f,b,l,k,iv)\ + _ossl_old_des_enc_read((f),(b),(l),(k),(iv)) +# define des_enc_write(f,b,l,k,iv)\ + _ossl_old_des_enc_write((f),(b),(l),(k),(iv)) +# define des_fcrypt(b,s,r)\ + _ossl_old_des_fcrypt((b),(s),(r)) +# define des_crypt(b,s)\ + _ossl_old_des_crypt((b),(s)) +# if 0 +# define crypt(b,s)\ + _ossl_old_crypt((b),(s)) +# endif +# define des_ofb_encrypt(i,o,n,l,k,iv)\ + _ossl_old_des_ofb_encrypt((i),(o),(n),(l),(k),(iv)) +# define des_pcbc_encrypt(i,o,l,k,iv,e)\ + _ossl_old_des_pcbc_encrypt((i),(o),(l),(k),(iv),(e)) +# define des_quad_cksum(i,o,l,c,s)\ + _ossl_old_des_quad_cksum((i),(o),(l),(c),(s)) +# define des_random_seed(k)\ + _ossl_old_des_random_seed((k)) +# define des_random_key(r)\ + _ossl_old_des_random_key((r)) +# define des_read_password(k,p,v) \ + _ossl_old_des_read_password((k),(p),(v)) +# define des_read_2passwords(k1,k2,p,v) \ + _ossl_old_des_read_2passwords((k1),(k2),(p),(v)) +# define des_set_odd_parity(k)\ + _ossl_old_des_set_odd_parity((k)) +# define des_is_weak_key(k)\ + _ossl_old_des_is_weak_key((k)) +# define des_set_key(k,ks)\ + _ossl_old_des_set_key((k),(ks)) +# define des_key_sched(k,ks)\ + _ossl_old_des_key_sched((k),(ks)) +# define des_string_to_key(s,k)\ + _ossl_old_des_string_to_key((s),(k)) +# define des_string_to_2keys(s,k1,k2)\ + _ossl_old_des_string_to_2keys((s),(k1),(k2)) +# define des_cfb64_encrypt(i,o,l,ks,iv,n,e)\ + _ossl_old_des_cfb64_encrypt((i),(o),(l),(ks),(iv),(n),(e)) +# define des_ofb64_encrypt(i,o,l,ks,iv,n)\ + _ossl_old_des_ofb64_encrypt((i),(o),(l),(ks),(iv),(n)) + +# define des_ecb2_encrypt(i,o,k1,k2,e) \ + des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e)) + +# define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \ + des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e)) + +# define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \ + des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e)) + +# define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \ + des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n)) + +# define des_check_key DES_check_key +# define des_rw_mode DES_rw_mode +# endif + +const char *_ossl_old_des_options(void); +void _ossl_old_des_ecb3_encrypt(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, + _ossl_old_des_key_schedule ks1, + _ossl_old_des_key_schedule ks2, + _ossl_old_des_key_schedule ks3, int enc); +DES_LONG _ossl_old_des_cbc_cksum(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, long length, + _ossl_old_des_key_schedule schedule, + _ossl_old_des_cblock *ivec); +void _ossl_old_des_cbc_encrypt(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, long length, + _ossl_old_des_key_schedule schedule, + _ossl_old_des_cblock *ivec, int enc); +void _ossl_old_des_ncbc_encrypt(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, long length, + _ossl_old_des_key_schedule schedule, + _ossl_old_des_cblock *ivec, int enc); +void _ossl_old_des_xcbc_encrypt(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, long length, + _ossl_old_des_key_schedule schedule, + _ossl_old_des_cblock *ivec, + _ossl_old_des_cblock *inw, + _ossl_old_des_cblock *outw, int enc); +void _ossl_old_des_cfb_encrypt(unsigned char *in, unsigned char *out, + int numbits, long length, + _ossl_old_des_key_schedule schedule, + _ossl_old_des_cblock *ivec, int enc); +void _ossl_old_des_ecb_encrypt(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, + _ossl_old_des_key_schedule ks, int enc); +void _ossl_old_des_encrypt(DES_LONG *data, _ossl_old_des_key_schedule ks, + int enc); +void _ossl_old_des_encrypt2(DES_LONG *data, _ossl_old_des_key_schedule ks, + int enc); +void _ossl_old_des_encrypt3(DES_LONG *data, _ossl_old_des_key_schedule ks1, + _ossl_old_des_key_schedule ks2, + _ossl_old_des_key_schedule ks3); +void _ossl_old_des_decrypt3(DES_LONG *data, _ossl_old_des_key_schedule ks1, + _ossl_old_des_key_schedule ks2, + _ossl_old_des_key_schedule ks3); +void _ossl_old_des_ede3_cbc_encrypt(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, long length, + _ossl_old_des_key_schedule ks1, + _ossl_old_des_key_schedule ks2, + _ossl_old_des_key_schedule ks3, + _ossl_old_des_cblock *ivec, int enc); +void _ossl_old_des_ede3_cfb64_encrypt(unsigned char *in, unsigned char *out, + long length, + _ossl_old_des_key_schedule ks1, + _ossl_old_des_key_schedule ks2, + _ossl_old_des_key_schedule ks3, + _ossl_old_des_cblock *ivec, int *num, + int enc); +void _ossl_old_des_ede3_ofb64_encrypt(unsigned char *in, unsigned char *out, + long length, + _ossl_old_des_key_schedule ks1, + _ossl_old_des_key_schedule ks2, + _ossl_old_des_key_schedule ks3, + _ossl_old_des_cblock *ivec, int *num); +# if 0 +void _ossl_old_des_xwhite_in2out(_ossl_old_des_cblock (*des_key), + _ossl_old_des_cblock (*in_white), + _ossl_old_des_cblock (*out_white)); +# endif + +int _ossl_old_des_enc_read(int fd, char *buf, int len, + _ossl_old_des_key_schedule sched, + _ossl_old_des_cblock *iv); +int _ossl_old_des_enc_write(int fd, char *buf, int len, + _ossl_old_des_key_schedule sched, + _ossl_old_des_cblock *iv); +char *_ossl_old_des_fcrypt(const char *buf, const char *salt, char *ret); +char *_ossl_old_des_crypt(const char *buf, const char *salt); +# if !defined(PERL5) && !defined(NeXT) +char *_ossl_old_crypt(const char *buf, const char *salt); +# endif +void _ossl_old_des_ofb_encrypt(unsigned char *in, unsigned char *out, + int numbits, long length, + _ossl_old_des_key_schedule schedule, + _ossl_old_des_cblock *ivec); +void _ossl_old_des_pcbc_encrypt(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, long length, + _ossl_old_des_key_schedule schedule, + _ossl_old_des_cblock *ivec, int enc); +DES_LONG _ossl_old_des_quad_cksum(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, long length, + int out_count, _ossl_old_des_cblock *seed); +void _ossl_old_des_random_seed(_ossl_old_des_cblock key); +void _ossl_old_des_random_key(_ossl_old_des_cblock ret); +int _ossl_old_des_read_password(_ossl_old_des_cblock *key, const char *prompt, + int verify); +int _ossl_old_des_read_2passwords(_ossl_old_des_cblock *key1, + _ossl_old_des_cblock *key2, + const char *prompt, int verify); +void _ossl_old_des_set_odd_parity(_ossl_old_des_cblock *key); +int _ossl_old_des_is_weak_key(_ossl_old_des_cblock *key); +int _ossl_old_des_set_key(_ossl_old_des_cblock *key, + _ossl_old_des_key_schedule schedule); +int _ossl_old_des_key_sched(_ossl_old_des_cblock *key, + _ossl_old_des_key_schedule schedule); +void _ossl_old_des_string_to_key(char *str, _ossl_old_des_cblock *key); +void _ossl_old_des_string_to_2keys(char *str, _ossl_old_des_cblock *key1, + _ossl_old_des_cblock *key2); +void _ossl_old_des_cfb64_encrypt(unsigned char *in, unsigned char *out, + long length, + _ossl_old_des_key_schedule schedule, + _ossl_old_des_cblock *ivec, int *num, + int enc); +void _ossl_old_des_ofb64_encrypt(unsigned char *in, unsigned char *out, + long length, + _ossl_old_des_key_schedule schedule, + _ossl_old_des_cblock *ivec, int *num); + +void _ossl_096_des_random_seed(des_cblock *key); + +/* + * The following definitions provide compatibility with the MIT Kerberos + * library. The _ossl_old_des_key_schedule structure is not binary + * compatible. + */ + +# define _KERBEROS_DES_H + +# define KRBDES_ENCRYPT DES_ENCRYPT +# define KRBDES_DECRYPT DES_DECRYPT + +# ifdef KERBEROS +# define ENCRYPT DES_ENCRYPT +# define DECRYPT DES_DECRYPT +# endif + +# ifndef NCOMPAT +# define C_Block des_cblock +# define Key_schedule des_key_schedule +# define KEY_SZ DES_KEY_SZ +# define string_to_key des_string_to_key +# define read_pw_string des_read_pw_string +# define random_key des_random_key +# define pcbc_encrypt des_pcbc_encrypt +# define set_key des_set_key +# define key_sched des_key_sched +# define ecb_encrypt des_ecb_encrypt +# define cbc_encrypt des_cbc_encrypt +# define ncbc_encrypt des_ncbc_encrypt +# define xcbc_encrypt des_xcbc_encrypt +# define cbc_cksum des_cbc_cksum +# define quad_cksum des_quad_cksum +# define check_parity des_check_key_parity +# endif + +# define des_fixup_key_parity DES_fixup_key_parity + +#ifdef __cplusplus +} +#endif + +/* for DES_read_pw_string et al */ +# include + +#endif diff --git a/OSlibs/ios/include/openssl/dh.h b/OSlibs/ios/include/openssl/dh.h new file mode 100755 index 000000000..a5bd9016a --- /dev/null +++ b/OSlibs/ios/include/openssl/dh.h @@ -0,0 +1,393 @@ +/* crypto/dh/dh.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_DH_H +# define HEADER_DH_H + +# include + +# ifdef OPENSSL_NO_DH +# error DH is disabled. +# endif + +# ifndef OPENSSL_NO_BIO +# include +# endif +# include +# ifndef OPENSSL_NO_DEPRECATED +# include +# endif + +# ifndef OPENSSL_DH_MAX_MODULUS_BITS +# define OPENSSL_DH_MAX_MODULUS_BITS 10000 +# endif + +# define DH_FLAG_CACHE_MONT_P 0x01 + +/* + * new with 0.9.7h; the built-in DH + * implementation now uses constant time + * modular exponentiation for secret exponents + * by default. This flag causes the + * faster variable sliding window method to + * be used for all exponents. + */ +# define DH_FLAG_NO_EXP_CONSTTIME 0x02 + +/* + * If this flag is set the DH method is FIPS compliant and can be used in + * FIPS mode. This is set in the validated module method. If an application + * sets this flag in its own methods it is its reposibility to ensure the + * result is compliant. + */ + +# define DH_FLAG_FIPS_METHOD 0x0400 + +/* + * If this flag is set the operations normally disabled in FIPS mode are + * permitted it is then the applications responsibility to ensure that the + * usage is compliant. + */ + +# define DH_FLAG_NON_FIPS_ALLOW 0x0400 + +#ifdef __cplusplus +extern "C" { +#endif + +/* Already defined in ossl_typ.h */ +/* typedef struct dh_st DH; */ +/* typedef struct dh_method DH_METHOD; */ + +struct dh_method { + const char *name; + /* Methods here */ + int (*generate_key) (DH *dh); + int (*compute_key) (unsigned char *key, const BIGNUM *pub_key, DH *dh); + /* Can be null */ + int (*bn_mod_exp) (const DH *dh, BIGNUM *r, const BIGNUM *a, + const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx); + int (*init) (DH *dh); + int (*finish) (DH *dh); + int flags; + char *app_data; + /* If this is non-NULL, it will be used to generate parameters */ + int (*generate_params) (DH *dh, int prime_len, int generator, + BN_GENCB *cb); +}; + +struct dh_st { + /* + * This first argument is used to pick up errors when a DH is passed + * instead of a EVP_PKEY + */ + int pad; + int version; + BIGNUM *p; + BIGNUM *g; + long length; /* optional */ + BIGNUM *pub_key; /* g^x % p */ + BIGNUM *priv_key; /* x */ + int flags; + BN_MONT_CTX *method_mont_p; + /* Place holders if we want to do X9.42 DH */ + BIGNUM *q; + BIGNUM *j; + unsigned char *seed; + int seedlen; + BIGNUM *counter; + int references; + CRYPTO_EX_DATA ex_data; + const DH_METHOD *meth; + ENGINE *engine; +}; + +# define DH_GENERATOR_2 2 +/* #define DH_GENERATOR_3 3 */ +# define DH_GENERATOR_5 5 + +/* DH_check error codes */ +# define DH_CHECK_P_NOT_PRIME 0x01 +# define DH_CHECK_P_NOT_SAFE_PRIME 0x02 +# define DH_UNABLE_TO_CHECK_GENERATOR 0x04 +# define DH_NOT_SUITABLE_GENERATOR 0x08 +# define DH_CHECK_Q_NOT_PRIME 0x10 +# define DH_CHECK_INVALID_Q_VALUE 0x20 +# define DH_CHECK_INVALID_J_VALUE 0x40 + +/* DH_check_pub_key error codes */ +# define DH_CHECK_PUBKEY_TOO_SMALL 0x01 +# define DH_CHECK_PUBKEY_TOO_LARGE 0x02 +# define DH_CHECK_PUBKEY_INVALID 0x04 + +/* + * primes p where (p-1)/2 is prime too are called "safe"; we define this for + * backward compatibility: + */ +# define DH_CHECK_P_NOT_STRONG_PRIME DH_CHECK_P_NOT_SAFE_PRIME + +# define d2i_DHparams_fp(fp,x) (DH *)ASN1_d2i_fp((char *(*)())DH_new, \ + (char *(*)())d2i_DHparams,(fp),(unsigned char **)(x)) +# define i2d_DHparams_fp(fp,x) ASN1_i2d_fp(i2d_DHparams,(fp), \ + (unsigned char *)(x)) +# define d2i_DHparams_bio(bp,x) ASN1_d2i_bio_of(DH,DH_new,d2i_DHparams,bp,x) +# define i2d_DHparams_bio(bp,x) ASN1_i2d_bio_of_const(DH,i2d_DHparams,bp,x) + +DH *DHparams_dup(DH *); + +const DH_METHOD *DH_OpenSSL(void); + +void DH_set_default_method(const DH_METHOD *meth); +const DH_METHOD *DH_get_default_method(void); +int DH_set_method(DH *dh, const DH_METHOD *meth); +DH *DH_new_method(ENGINE *engine); + +DH *DH_new(void); +void DH_free(DH *dh); +int DH_up_ref(DH *dh); +int DH_size(const DH *dh); +int DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int DH_set_ex_data(DH *d, int idx, void *arg); +void *DH_get_ex_data(DH *d, int idx); + +/* Deprecated version */ +# ifndef OPENSSL_NO_DEPRECATED +DH *DH_generate_parameters(int prime_len, int generator, + void (*callback) (int, int, void *), void *cb_arg); +# endif /* !defined(OPENSSL_NO_DEPRECATED) */ + +/* New version */ +int DH_generate_parameters_ex(DH *dh, int prime_len, int generator, + BN_GENCB *cb); + +int DH_check(const DH *dh, int *codes); +int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *codes); +int DH_generate_key(DH *dh); +int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh); +int DH_compute_key_padded(unsigned char *key, const BIGNUM *pub_key, DH *dh); +DH *d2i_DHparams(DH **a, const unsigned char **pp, long length); +int i2d_DHparams(const DH *a, unsigned char **pp); +DH *d2i_DHxparams(DH **a, const unsigned char **pp, long length); +int i2d_DHxparams(const DH *a, unsigned char **pp); +# ifndef OPENSSL_NO_FP_API +int DHparams_print_fp(FILE *fp, const DH *x); +# endif +# ifndef OPENSSL_NO_BIO +int DHparams_print(BIO *bp, const DH *x); +# else +int DHparams_print(char *bp, const DH *x); +# endif + +/* RFC 5114 parameters */ +DH *DH_get_1024_160(void); +DH *DH_get_2048_224(void); +DH *DH_get_2048_256(void); + +/* RFC2631 KDF */ +int DH_KDF_X9_42(unsigned char *out, size_t outlen, + const unsigned char *Z, size_t Zlen, + ASN1_OBJECT *key_oid, + const unsigned char *ukm, size_t ukmlen, const EVP_MD *md); + +# define EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN, len, NULL) + +# define EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN, len, NULL) + +# define EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_PARAMGEN_TYPE, typ, NULL) + +# define EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, gen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR, gen, NULL) + +# define EVP_PKEY_CTX_set_dh_rfc5114(ctx, gen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_RFC5114, gen, NULL) + +# define EVP_PKEY_CTX_set_dhx_rfc5114(ctx, gen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_RFC5114, gen, NULL) + +# define EVP_PKEY_CTX_set_dh_kdf_type(ctx, kdf) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_DH_KDF_TYPE, kdf, NULL) + +# define EVP_PKEY_CTX_get_dh_kdf_type(ctx) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_DH_KDF_TYPE, -2, NULL) + +# define EVP_PKEY_CTX_set0_dh_kdf_oid(ctx, oid) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_DH_KDF_OID, 0, (void *)oid) + +# define EVP_PKEY_CTX_get0_dh_kdf_oid(ctx, poid) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_GET_DH_KDF_OID, 0, (void *)poid) + +# define EVP_PKEY_CTX_set_dh_kdf_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_DH_KDF_MD, 0, (void *)md) + +# define EVP_PKEY_CTX_get_dh_kdf_md(ctx, pmd) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_GET_DH_KDF_MD, 0, (void *)pmd) + +# define EVP_PKEY_CTX_set_dh_kdf_outlen(ctx, len) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_DH_KDF_OUTLEN, len, NULL) + +# define EVP_PKEY_CTX_get_dh_kdf_outlen(ctx, plen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN, 0, (void *)plen) + +# define EVP_PKEY_CTX_set0_dh_kdf_ukm(ctx, p, plen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_DH_KDF_UKM, plen, (void *)p) + +# define EVP_PKEY_CTX_get0_dh_kdf_ukm(ctx, p) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_GET_DH_KDF_UKM, 0, (void *)p) + +# define EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN (EVP_PKEY_ALG_CTRL + 1) +# define EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR (EVP_PKEY_ALG_CTRL + 2) +# define EVP_PKEY_CTRL_DH_RFC5114 (EVP_PKEY_ALG_CTRL + 3) +# define EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN (EVP_PKEY_ALG_CTRL + 4) +# define EVP_PKEY_CTRL_DH_PARAMGEN_TYPE (EVP_PKEY_ALG_CTRL + 5) +# define EVP_PKEY_CTRL_DH_KDF_TYPE (EVP_PKEY_ALG_CTRL + 6) +# define EVP_PKEY_CTRL_DH_KDF_MD (EVP_PKEY_ALG_CTRL + 7) +# define EVP_PKEY_CTRL_GET_DH_KDF_MD (EVP_PKEY_ALG_CTRL + 8) +# define EVP_PKEY_CTRL_DH_KDF_OUTLEN (EVP_PKEY_ALG_CTRL + 9) +# define EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN (EVP_PKEY_ALG_CTRL + 10) +# define EVP_PKEY_CTRL_DH_KDF_UKM (EVP_PKEY_ALG_CTRL + 11) +# define EVP_PKEY_CTRL_GET_DH_KDF_UKM (EVP_PKEY_ALG_CTRL + 12) +# define EVP_PKEY_CTRL_DH_KDF_OID (EVP_PKEY_ALG_CTRL + 13) +# define EVP_PKEY_CTRL_GET_DH_KDF_OID (EVP_PKEY_ALG_CTRL + 14) + +/* KDF types */ +# define EVP_PKEY_DH_KDF_NONE 1 +# define EVP_PKEY_DH_KDF_X9_42 2 + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_DH_strings(void); + +/* Error codes for the DH functions. */ + +/* Function codes. */ +# define DH_F_COMPUTE_KEY 102 +# define DH_F_DHPARAMS_PRINT_FP 101 +# define DH_F_DH_BUILTIN_GENPARAMS 106 +# define DH_F_DH_CMS_DECRYPT 117 +# define DH_F_DH_CMS_SET_PEERKEY 118 +# define DH_F_DH_CMS_SET_SHARED_INFO 119 +# define DH_F_DH_COMPUTE_KEY 114 +# define DH_F_DH_GENERATE_KEY 115 +# define DH_F_DH_GENERATE_PARAMETERS_EX 116 +# define DH_F_DH_NEW_METHOD 105 +# define DH_F_DH_PARAM_DECODE 107 +# define DH_F_DH_PRIV_DECODE 110 +# define DH_F_DH_PRIV_ENCODE 111 +# define DH_F_DH_PUB_DECODE 108 +# define DH_F_DH_PUB_ENCODE 109 +# define DH_F_DO_DH_PRINT 100 +# define DH_F_GENERATE_KEY 103 +# define DH_F_GENERATE_PARAMETERS 104 +# define DH_F_PKEY_DH_DERIVE 112 +# define DH_F_PKEY_DH_KEYGEN 113 + +/* Reason codes. */ +# define DH_R_BAD_GENERATOR 101 +# define DH_R_BN_DECODE_ERROR 109 +# define DH_R_BN_ERROR 106 +# define DH_R_DECODE_ERROR 104 +# define DH_R_INVALID_PUBKEY 102 +# define DH_R_KDF_PARAMETER_ERROR 112 +# define DH_R_KEYS_NOT_SET 108 +# define DH_R_KEY_SIZE_TOO_SMALL 110 +# define DH_R_MODULUS_TOO_LARGE 103 +# define DH_R_NON_FIPS_METHOD 111 +# define DH_R_NO_PARAMETERS_SET 107 +# define DH_R_NO_PRIVATE_VALUE 100 +# define DH_R_PARAMETER_ENCODING_ERROR 105 +# define DH_R_PEER_KEY_ERROR 113 +# define DH_R_SHARED_INFO_ERROR 114 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/dsa.h b/OSlibs/ios/include/openssl/dsa.h new file mode 100755 index 000000000..545358fd0 --- /dev/null +++ b/OSlibs/ios/include/openssl/dsa.h @@ -0,0 +1,332 @@ +/* crypto/dsa/dsa.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* + * The DSS routines are based on patches supplied by + * Steven Schoch . He basically did the + * work and I have just tweaked them a little to fit into my + * stylistic vision for SSLeay :-) */ + +#ifndef HEADER_DSA_H +# define HEADER_DSA_H + +# include + +# ifdef OPENSSL_NO_DSA +# error DSA is disabled. +# endif + +# ifndef OPENSSL_NO_BIO +# include +# endif +# include +# include + +# ifndef OPENSSL_NO_DEPRECATED +# include +# ifndef OPENSSL_NO_DH +# include +# endif +# endif + +# ifndef OPENSSL_DSA_MAX_MODULUS_BITS +# define OPENSSL_DSA_MAX_MODULUS_BITS 10000 +# endif + +# define DSA_FLAG_CACHE_MONT_P 0x01 +/* + * new with 0.9.7h; the built-in DSA implementation now uses constant time + * modular exponentiation for secret exponents by default. This flag causes + * the faster variable sliding window method to be used for all exponents. + */ +# define DSA_FLAG_NO_EXP_CONSTTIME 0x02 + +/* + * If this flag is set the DSA method is FIPS compliant and can be used in + * FIPS mode. This is set in the validated module method. If an application + * sets this flag in its own methods it is its reposibility to ensure the + * result is compliant. + */ + +# define DSA_FLAG_FIPS_METHOD 0x0400 + +/* + * If this flag is set the operations normally disabled in FIPS mode are + * permitted it is then the applications responsibility to ensure that the + * usage is compliant. + */ + +# define DSA_FLAG_NON_FIPS_ALLOW 0x0400 + +#ifdef __cplusplus +extern "C" { +#endif + +/* Already defined in ossl_typ.h */ +/* typedef struct dsa_st DSA; */ +/* typedef struct dsa_method DSA_METHOD; */ + +typedef struct DSA_SIG_st { + BIGNUM *r; + BIGNUM *s; +} DSA_SIG; + +struct dsa_method { + const char *name; + DSA_SIG *(*dsa_do_sign) (const unsigned char *dgst, int dlen, DSA *dsa); + int (*dsa_sign_setup) (DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, + BIGNUM **rp); + int (*dsa_do_verify) (const unsigned char *dgst, int dgst_len, + DSA_SIG *sig, DSA *dsa); + int (*dsa_mod_exp) (DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1, + BIGNUM *a2, BIGNUM *p2, BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *in_mont); + /* Can be null */ + int (*bn_mod_exp) (DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); + int (*init) (DSA *dsa); + int (*finish) (DSA *dsa); + int flags; + char *app_data; + /* If this is non-NULL, it is used to generate DSA parameters */ + int (*dsa_paramgen) (DSA *dsa, int bits, + const unsigned char *seed, int seed_len, + int *counter_ret, unsigned long *h_ret, + BN_GENCB *cb); + /* If this is non-NULL, it is used to generate DSA keys */ + int (*dsa_keygen) (DSA *dsa); +}; + +struct dsa_st { + /* + * This first variable is used to pick up errors where a DSA is passed + * instead of of a EVP_PKEY + */ + int pad; + long version; + int write_params; + BIGNUM *p; + BIGNUM *q; /* == 20 */ + BIGNUM *g; + BIGNUM *pub_key; /* y public key */ + BIGNUM *priv_key; /* x private key */ + BIGNUM *kinv; /* Signing pre-calc */ + BIGNUM *r; /* Signing pre-calc */ + int flags; + /* Normally used to cache montgomery values */ + BN_MONT_CTX *method_mont_p; + int references; + CRYPTO_EX_DATA ex_data; + const DSA_METHOD *meth; + /* functional reference if 'meth' is ENGINE-provided */ + ENGINE *engine; +}; + +# define d2i_DSAparams_fp(fp,x) (DSA *)ASN1_d2i_fp((char *(*)())DSA_new, \ + (char *(*)())d2i_DSAparams,(fp),(unsigned char **)(x)) +# define i2d_DSAparams_fp(fp,x) ASN1_i2d_fp(i2d_DSAparams,(fp), \ + (unsigned char *)(x)) +# define d2i_DSAparams_bio(bp,x) ASN1_d2i_bio_of(DSA,DSA_new,d2i_DSAparams,bp,x) +# define i2d_DSAparams_bio(bp,x) ASN1_i2d_bio_of_const(DSA,i2d_DSAparams,bp,x) + +DSA *DSAparams_dup(DSA *x); +DSA_SIG *DSA_SIG_new(void); +void DSA_SIG_free(DSA_SIG *a); +int i2d_DSA_SIG(const DSA_SIG *a, unsigned char **pp); +DSA_SIG *d2i_DSA_SIG(DSA_SIG **v, const unsigned char **pp, long length); + +DSA_SIG *DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa); +int DSA_do_verify(const unsigned char *dgst, int dgst_len, + DSA_SIG *sig, DSA *dsa); + +const DSA_METHOD *DSA_OpenSSL(void); + +void DSA_set_default_method(const DSA_METHOD *); +const DSA_METHOD *DSA_get_default_method(void); +int DSA_set_method(DSA *dsa, const DSA_METHOD *); + +DSA *DSA_new(void); +DSA *DSA_new_method(ENGINE *engine); +void DSA_free(DSA *r); +/* "up" the DSA object's reference count */ +int DSA_up_ref(DSA *r); +int DSA_size(const DSA *); + /* next 4 return -1 on error */ +int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp); +int DSA_sign(int type, const unsigned char *dgst, int dlen, + unsigned char *sig, unsigned int *siglen, DSA *dsa); +int DSA_verify(int type, const unsigned char *dgst, int dgst_len, + const unsigned char *sigbuf, int siglen, DSA *dsa); +int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int DSA_set_ex_data(DSA *d, int idx, void *arg); +void *DSA_get_ex_data(DSA *d, int idx); + +DSA *d2i_DSAPublicKey(DSA **a, const unsigned char **pp, long length); +DSA *d2i_DSAPrivateKey(DSA **a, const unsigned char **pp, long length); +DSA *d2i_DSAparams(DSA **a, const unsigned char **pp, long length); + +/* Deprecated version */ +# ifndef OPENSSL_NO_DEPRECATED +DSA *DSA_generate_parameters(int bits, + unsigned char *seed, int seed_len, + int *counter_ret, unsigned long *h_ret, void + (*callback) (int, int, void *), void *cb_arg); +# endif /* !defined(OPENSSL_NO_DEPRECATED) */ + +/* New version */ +int DSA_generate_parameters_ex(DSA *dsa, int bits, + const unsigned char *seed, int seed_len, + int *counter_ret, unsigned long *h_ret, + BN_GENCB *cb); + +int DSA_generate_key(DSA *a); +int i2d_DSAPublicKey(const DSA *a, unsigned char **pp); +int i2d_DSAPrivateKey(const DSA *a, unsigned char **pp); +int i2d_DSAparams(const DSA *a, unsigned char **pp); + +# ifndef OPENSSL_NO_BIO +int DSAparams_print(BIO *bp, const DSA *x); +int DSA_print(BIO *bp, const DSA *x, int off); +# endif +# ifndef OPENSSL_NO_FP_API +int DSAparams_print_fp(FILE *fp, const DSA *x); +int DSA_print_fp(FILE *bp, const DSA *x, int off); +# endif + +# define DSS_prime_checks 50 +/* + * Primality test according to FIPS PUB 186[-1], Appendix 2.1: 50 rounds of + * Rabin-Miller + */ +# define DSA_is_prime(n, callback, cb_arg) \ + BN_is_prime(n, DSS_prime_checks, callback, NULL, cb_arg) + +# ifndef OPENSSL_NO_DH +/* + * Convert DSA structure (key or just parameters) into DH structure (be + * careful to avoid small subgroup attacks when using this!) + */ +DH *DSA_dup_DH(const DSA *r); +# endif + +# define EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DSA_PARAMGEN_BITS, nbits, NULL) + +# define EVP_PKEY_CTRL_DSA_PARAMGEN_BITS (EVP_PKEY_ALG_CTRL + 1) +# define EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS (EVP_PKEY_ALG_CTRL + 2) +# define EVP_PKEY_CTRL_DSA_PARAMGEN_MD (EVP_PKEY_ALG_CTRL + 3) + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_DSA_strings(void); + +/* Error codes for the DSA functions. */ + +/* Function codes. */ +# define DSA_F_D2I_DSA_SIG 110 +# define DSA_F_DO_DSA_PRINT 104 +# define DSA_F_DSAPARAMS_PRINT 100 +# define DSA_F_DSAPARAMS_PRINT_FP 101 +# define DSA_F_DSA_BUILTIN_PARAMGEN2 126 +# define DSA_F_DSA_DO_SIGN 112 +# define DSA_F_DSA_DO_VERIFY 113 +# define DSA_F_DSA_GENERATE_KEY 124 +# define DSA_F_DSA_GENERATE_PARAMETERS_EX 123 +# define DSA_F_DSA_NEW_METHOD 103 +# define DSA_F_DSA_PARAM_DECODE 119 +# define DSA_F_DSA_PRINT_FP 105 +# define DSA_F_DSA_PRIV_DECODE 115 +# define DSA_F_DSA_PRIV_ENCODE 116 +# define DSA_F_DSA_PUB_DECODE 117 +# define DSA_F_DSA_PUB_ENCODE 118 +# define DSA_F_DSA_SIGN 106 +# define DSA_F_DSA_SIGN_SETUP 107 +# define DSA_F_DSA_SIG_NEW 109 +# define DSA_F_DSA_SIG_PRINT 125 +# define DSA_F_DSA_VERIFY 108 +# define DSA_F_I2D_DSA_SIG 111 +# define DSA_F_OLD_DSA_PRIV_DECODE 122 +# define DSA_F_PKEY_DSA_CTRL 120 +# define DSA_F_PKEY_DSA_KEYGEN 121 +# define DSA_F_SIG_CB 114 + +/* Reason codes. */ +# define DSA_R_BAD_Q_VALUE 102 +# define DSA_R_BN_DECODE_ERROR 108 +# define DSA_R_BN_ERROR 109 +# define DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 100 +# define DSA_R_DECODE_ERROR 104 +# define DSA_R_INVALID_DIGEST_TYPE 106 +# define DSA_R_INVALID_PARAMETERS 112 +# define DSA_R_MISSING_PARAMETERS 101 +# define DSA_R_MODULUS_TOO_LARGE 103 +# define DSA_R_NEED_NEW_SETUP_VALUES 110 +# define DSA_R_NON_FIPS_DSA_METHOD 111 +# define DSA_R_NO_PARAMETERS_SET 107 +# define DSA_R_PARAMETER_ENCODING_ERROR 105 +# define DSA_R_Q_NOT_PRIME 113 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/dso.h b/OSlibs/ios/include/openssl/dso.h new file mode 100755 index 000000000..c9013f5ce --- /dev/null +++ b/OSlibs/ios/include/openssl/dso.h @@ -0,0 +1,451 @@ +/* dso.h */ +/* + * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_DSO_H +# define HEADER_DSO_H + +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* These values are used as commands to DSO_ctrl() */ +# define DSO_CTRL_GET_FLAGS 1 +# define DSO_CTRL_SET_FLAGS 2 +# define DSO_CTRL_OR_FLAGS 3 + +/* + * By default, DSO_load() will translate the provided filename into a form + * typical for the platform (more specifically the DSO_METHOD) using the + * dso_name_converter function of the method. Eg. win32 will transform "blah" + * into "blah.dll", and dlfcn will transform it into "libblah.so". The + * behaviour can be overriden by setting the name_converter callback in the + * DSO object (using DSO_set_name_converter()). This callback could even + * utilise the DSO_METHOD's converter too if it only wants to override + * behaviour for one or two possible DSO methods. However, the following flag + * can be set in a DSO to prevent *any* native name-translation at all - eg. + * if the caller has prompted the user for a path to a driver library so the + * filename should be interpreted as-is. + */ +# define DSO_FLAG_NO_NAME_TRANSLATION 0x01 +/* + * An extra flag to give if only the extension should be added as + * translation. This is obviously only of importance on Unix and other + * operating systems where the translation also may prefix the name with + * something, like 'lib', and ignored everywhere else. This flag is also + * ignored if DSO_FLAG_NO_NAME_TRANSLATION is used at the same time. + */ +# define DSO_FLAG_NAME_TRANSLATION_EXT_ONLY 0x02 + +/* + * The following flag controls the translation of symbol names to upper case. + * This is currently only being implemented for OpenVMS. + */ +# define DSO_FLAG_UPCASE_SYMBOL 0x10 + +/* + * This flag loads the library with public symbols. Meaning: The exported + * symbols of this library are public to all libraries loaded after this + * library. At the moment only implemented in unix. + */ +# define DSO_FLAG_GLOBAL_SYMBOLS 0x20 + +typedef void (*DSO_FUNC_TYPE) (void); + +typedef struct dso_st DSO; + +/* + * The function prototype used for method functions (or caller-provided + * callbacks) that transform filenames. They are passed a DSO structure + * pointer (or NULL if they are to be used independantly of a DSO object) and + * a filename to transform. They should either return NULL (if there is an + * error condition) or a newly allocated string containing the transformed + * form that the caller will need to free with OPENSSL_free() when done. + */ +typedef char *(*DSO_NAME_CONVERTER_FUNC)(DSO *, const char *); +/* + * The function prototype used for method functions (or caller-provided + * callbacks) that merge two file specifications. They are passed a DSO + * structure pointer (or NULL if they are to be used independantly of a DSO + * object) and two file specifications to merge. They should either return + * NULL (if there is an error condition) or a newly allocated string + * containing the result of merging that the caller will need to free with + * OPENSSL_free() when done. Here, merging means that bits and pieces are + * taken from each of the file specifications and added together in whatever + * fashion that is sensible for the DSO method in question. The only rule + * that really applies is that if the two specification contain pieces of the + * same type, the copy from the first string takes priority. One could see + * it as the first specification is the one given by the user and the second + * being a bunch of defaults to add on if they're missing in the first. + */ +typedef char *(*DSO_MERGER_FUNC)(DSO *, const char *, const char *); + +typedef struct dso_meth_st { + const char *name; + /* + * Loads a shared library, NB: new DSO_METHODs must ensure that a + * successful load populates the loaded_filename field, and likewise a + * successful unload OPENSSL_frees and NULLs it out. + */ + int (*dso_load) (DSO *dso); + /* Unloads a shared library */ + int (*dso_unload) (DSO *dso); + /* Binds a variable */ + void *(*dso_bind_var) (DSO *dso, const char *symname); + /* + * Binds a function - assumes a return type of DSO_FUNC_TYPE. This should + * be cast to the real function prototype by the caller. Platforms that + * don't have compatible representations for different prototypes (this + * is possible within ANSI C) are highly unlikely to have shared + * libraries at all, let alone a DSO_METHOD implemented for them. + */ + DSO_FUNC_TYPE (*dso_bind_func) (DSO *dso, const char *symname); +/* I don't think this would actually be used in any circumstances. */ +# if 0 + /* Unbinds a variable */ + int (*dso_unbind_var) (DSO *dso, char *symname, void *symptr); + /* Unbinds a function */ + int (*dso_unbind_func) (DSO *dso, char *symname, DSO_FUNC_TYPE symptr); +# endif + /* + * The generic (yuck) "ctrl()" function. NB: Negative return values + * (rather than zero) indicate errors. + */ + long (*dso_ctrl) (DSO *dso, int cmd, long larg, void *parg); + /* + * The default DSO_METHOD-specific function for converting filenames to a + * canonical native form. + */ + DSO_NAME_CONVERTER_FUNC dso_name_converter; + /* + * The default DSO_METHOD-specific function for converting filenames to a + * canonical native form. + */ + DSO_MERGER_FUNC dso_merger; + /* [De]Initialisation handlers. */ + int (*init) (DSO *dso); + int (*finish) (DSO *dso); + /* Return pathname of the module containing location */ + int (*pathbyaddr) (void *addr, char *path, int sz); + /* Perform global symbol lookup, i.e. among *all* modules */ + void *(*globallookup) (const char *symname); +} DSO_METHOD; + +/**********************************************************************/ +/* The low-level handle type used to refer to a loaded shared library */ + +struct dso_st { + DSO_METHOD *meth; + /* + * Standard dlopen uses a (void *). Win32 uses a HANDLE. VMS doesn't use + * anything but will need to cache the filename for use in the dso_bind + * handler. All in all, let each method control its own destiny. + * "Handles" and such go in a STACK. + */ + STACK_OF(void) *meth_data; + int references; + int flags; + /* + * For use by applications etc ... use this for your bits'n'pieces, don't + * touch meth_data! + */ + CRYPTO_EX_DATA ex_data; + /* + * If this callback function pointer is set to non-NULL, then it will be + * used in DSO_load() in place of meth->dso_name_converter. NB: This + * should normally set using DSO_set_name_converter(). + */ + DSO_NAME_CONVERTER_FUNC name_converter; + /* + * If this callback function pointer is set to non-NULL, then it will be + * used in DSO_load() in place of meth->dso_merger. NB: This should + * normally set using DSO_set_merger(). + */ + DSO_MERGER_FUNC merger; + /* + * This is populated with (a copy of) the platform-independant filename + * used for this DSO. + */ + char *filename; + /* + * This is populated with (a copy of) the translated filename by which + * the DSO was actually loaded. It is NULL iff the DSO is not currently + * loaded. NB: This is here because the filename translation process may + * involve a callback being invoked more than once not only to convert to + * a platform-specific form, but also to try different filenames in the + * process of trying to perform a load. As such, this variable can be + * used to indicate (a) whether this DSO structure corresponds to a + * loaded library or not, and (b) the filename with which it was actually + * loaded. + */ + char *loaded_filename; +}; + +DSO *DSO_new(void); +DSO *DSO_new_method(DSO_METHOD *method); +int DSO_free(DSO *dso); +int DSO_flags(DSO *dso); +int DSO_up_ref(DSO *dso); +long DSO_ctrl(DSO *dso, int cmd, long larg, void *parg); + +/* + * This function sets the DSO's name_converter callback. If it is non-NULL, + * then it will be used instead of the associated DSO_METHOD's function. If + * oldcb is non-NULL then it is set to the function pointer value being + * replaced. Return value is non-zero for success. + */ +int DSO_set_name_converter(DSO *dso, DSO_NAME_CONVERTER_FUNC cb, + DSO_NAME_CONVERTER_FUNC *oldcb); +/* + * These functions can be used to get/set the platform-independant filename + * used for a DSO. NB: set will fail if the DSO is already loaded. + */ +const char *DSO_get_filename(DSO *dso); +int DSO_set_filename(DSO *dso, const char *filename); +/* + * This function will invoke the DSO's name_converter callback to translate a + * filename, or if the callback isn't set it will instead use the DSO_METHOD's + * converter. If "filename" is NULL, the "filename" in the DSO itself will be + * used. If the DSO_FLAG_NO_NAME_TRANSLATION flag is set, then the filename is + * simply duplicated. NB: This function is usually called from within a + * DSO_METHOD during the processing of a DSO_load() call, and is exposed so + * that caller-created DSO_METHODs can do the same thing. A non-NULL return + * value will need to be OPENSSL_free()'d. + */ +char *DSO_convert_filename(DSO *dso, const char *filename); +/* + * This function will invoke the DSO's merger callback to merge two file + * specifications, or if the callback isn't set it will instead use the + * DSO_METHOD's merger. A non-NULL return value will need to be + * OPENSSL_free()'d. + */ +char *DSO_merge(DSO *dso, const char *filespec1, const char *filespec2); +/* + * If the DSO is currently loaded, this returns the filename that it was + * loaded under, otherwise it returns NULL. So it is also useful as a test as + * to whether the DSO is currently loaded. NB: This will not necessarily + * return the same value as DSO_convert_filename(dso, dso->filename), because + * the DSO_METHOD's load function may have tried a variety of filenames (with + * and/or without the aid of the converters) before settling on the one it + * actually loaded. + */ +const char *DSO_get_loaded_filename(DSO *dso); + +void DSO_set_default_method(DSO_METHOD *meth); +DSO_METHOD *DSO_get_default_method(void); +DSO_METHOD *DSO_get_method(DSO *dso); +DSO_METHOD *DSO_set_method(DSO *dso, DSO_METHOD *meth); + +/* + * The all-singing all-dancing load function, you normally pass NULL for the + * first and third parameters. Use DSO_up and DSO_free for subsequent + * reference count handling. Any flags passed in will be set in the + * constructed DSO after its init() function but before the load operation. + * If 'dso' is non-NULL, 'flags' is ignored. + */ +DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags); + +/* This function binds to a variable inside a shared library. */ +void *DSO_bind_var(DSO *dso, const char *symname); + +/* This function binds to a function inside a shared library. */ +DSO_FUNC_TYPE DSO_bind_func(DSO *dso, const char *symname); + +/* + * This method is the default, but will beg, borrow, or steal whatever method + * should be the default on any particular platform (including + * DSO_METH_null() if necessary). + */ +DSO_METHOD *DSO_METHOD_openssl(void); + +/* + * This method is defined for all platforms - if a platform has no DSO + * support then this will be the only method! + */ +DSO_METHOD *DSO_METHOD_null(void); + +/* + * If DSO_DLFCN is defined, the standard dlfcn.h-style functions (dlopen, + * dlclose, dlsym, etc) will be used and incorporated into this method. If + * not, this method will return NULL. + */ +DSO_METHOD *DSO_METHOD_dlfcn(void); + +/* + * If DSO_DL is defined, the standard dl.h-style functions (shl_load, + * shl_unload, shl_findsym, etc) will be used and incorporated into this + * method. If not, this method will return NULL. + */ +DSO_METHOD *DSO_METHOD_dl(void); + +/* If WIN32 is defined, use DLLs. If not, return NULL. */ +DSO_METHOD *DSO_METHOD_win32(void); + +/* If VMS is defined, use shared images. If not, return NULL. */ +DSO_METHOD *DSO_METHOD_vms(void); + +/* + * This function writes null-terminated pathname of DSO module containing + * 'addr' into 'sz' large caller-provided 'path' and returns the number of + * characters [including trailing zero] written to it. If 'sz' is 0 or + * negative, 'path' is ignored and required amount of charachers [including + * trailing zero] to accomodate pathname is returned. If 'addr' is NULL, then + * pathname of cryptolib itself is returned. Negative or zero return value + * denotes error. + */ +int DSO_pathbyaddr(void *addr, char *path, int sz); + +/* + * This function should be used with caution! It looks up symbols in *all* + * loaded modules and if module gets unloaded by somebody else attempt to + * dereference the pointer is doomed to have fatal consequences. Primary + * usage for this function is to probe *core* system functionality, e.g. + * check if getnameinfo(3) is available at run-time without bothering about + * OS-specific details such as libc.so.versioning or where does it actually + * reside: in libc itself or libsocket. + */ +void *DSO_global_lookup(const char *name); + +/* If BeOS is defined, use shared images. If not, return NULL. */ +DSO_METHOD *DSO_METHOD_beos(void); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_DSO_strings(void); + +/* Error codes for the DSO functions. */ + +/* Function codes. */ +# define DSO_F_BEOS_BIND_FUNC 144 +# define DSO_F_BEOS_BIND_VAR 145 +# define DSO_F_BEOS_LOAD 146 +# define DSO_F_BEOS_NAME_CONVERTER 147 +# define DSO_F_BEOS_UNLOAD 148 +# define DSO_F_DLFCN_BIND_FUNC 100 +# define DSO_F_DLFCN_BIND_VAR 101 +# define DSO_F_DLFCN_LOAD 102 +# define DSO_F_DLFCN_MERGER 130 +# define DSO_F_DLFCN_NAME_CONVERTER 123 +# define DSO_F_DLFCN_UNLOAD 103 +# define DSO_F_DL_BIND_FUNC 104 +# define DSO_F_DL_BIND_VAR 105 +# define DSO_F_DL_LOAD 106 +# define DSO_F_DL_MERGER 131 +# define DSO_F_DL_NAME_CONVERTER 124 +# define DSO_F_DL_UNLOAD 107 +# define DSO_F_DSO_BIND_FUNC 108 +# define DSO_F_DSO_BIND_VAR 109 +# define DSO_F_DSO_CONVERT_FILENAME 126 +# define DSO_F_DSO_CTRL 110 +# define DSO_F_DSO_FREE 111 +# define DSO_F_DSO_GET_FILENAME 127 +# define DSO_F_DSO_GET_LOADED_FILENAME 128 +# define DSO_F_DSO_GLOBAL_LOOKUP 139 +# define DSO_F_DSO_LOAD 112 +# define DSO_F_DSO_MERGE 132 +# define DSO_F_DSO_NEW_METHOD 113 +# define DSO_F_DSO_PATHBYADDR 140 +# define DSO_F_DSO_SET_FILENAME 129 +# define DSO_F_DSO_SET_NAME_CONVERTER 122 +# define DSO_F_DSO_UP_REF 114 +# define DSO_F_GLOBAL_LOOKUP_FUNC 138 +# define DSO_F_PATHBYADDR 137 +# define DSO_F_VMS_BIND_SYM 115 +# define DSO_F_VMS_LOAD 116 +# define DSO_F_VMS_MERGER 133 +# define DSO_F_VMS_UNLOAD 117 +# define DSO_F_WIN32_BIND_FUNC 118 +# define DSO_F_WIN32_BIND_VAR 119 +# define DSO_F_WIN32_GLOBALLOOKUP 142 +# define DSO_F_WIN32_GLOBALLOOKUP_FUNC 143 +# define DSO_F_WIN32_JOINER 135 +# define DSO_F_WIN32_LOAD 120 +# define DSO_F_WIN32_MERGER 134 +# define DSO_F_WIN32_NAME_CONVERTER 125 +# define DSO_F_WIN32_PATHBYADDR 141 +# define DSO_F_WIN32_SPLITTER 136 +# define DSO_F_WIN32_UNLOAD 121 + +/* Reason codes. */ +# define DSO_R_CTRL_FAILED 100 +# define DSO_R_DSO_ALREADY_LOADED 110 +# define DSO_R_EMPTY_FILE_STRUCTURE 113 +# define DSO_R_FAILURE 114 +# define DSO_R_FILENAME_TOO_BIG 101 +# define DSO_R_FINISH_FAILED 102 +# define DSO_R_INCORRECT_FILE_SYNTAX 115 +# define DSO_R_LOAD_FAILED 103 +# define DSO_R_NAME_TRANSLATION_FAILED 109 +# define DSO_R_NO_FILENAME 111 +# define DSO_R_NO_FILE_SPECIFICATION 116 +# define DSO_R_NULL_HANDLE 104 +# define DSO_R_SET_FILENAME_FAILED 112 +# define DSO_R_STACK_ERROR 105 +# define DSO_R_SYM_FAILURE 106 +# define DSO_R_UNLOAD_FAILED 107 +# define DSO_R_UNSUPPORTED 108 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/dtls1.h b/OSlibs/ios/include/openssl/dtls1.h new file mode 100755 index 000000000..30bbcf278 --- /dev/null +++ b/OSlibs/ios/include/openssl/dtls1.h @@ -0,0 +1,272 @@ +/* ssl/dtls1.h */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_DTLS1_H +# define HEADER_DTLS1_H + +# include +# include +# ifdef OPENSSL_SYS_VMS +# include +# include +# endif +# ifdef OPENSSL_SYS_WIN32 +/* Needed for struct timeval */ +# include +# elif defined(OPENSSL_SYS_NETWARE) && !defined(_WINSOCK2API_) +# include +# else +# if defined(OPENSSL_SYS_VXWORKS) +# include +# else +# include +# endif +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +# define DTLS1_VERSION 0xFEFF +# define DTLS1_2_VERSION 0xFEFD +# define DTLS_MAX_VERSION DTLS1_2_VERSION +# define DTLS1_VERSION_MAJOR 0xFE + +# define DTLS1_BAD_VER 0x0100 + +/* Special value for method supporting multiple versions */ +# define DTLS_ANY_VERSION 0x1FFFF + +# if 0 +/* this alert description is not specified anywhere... */ +# define DTLS1_AD_MISSING_HANDSHAKE_MESSAGE 110 +# endif + +/* lengths of messages */ +# define DTLS1_COOKIE_LENGTH 256 + +# define DTLS1_RT_HEADER_LENGTH 13 + +# define DTLS1_HM_HEADER_LENGTH 12 + +# define DTLS1_HM_BAD_FRAGMENT -2 +# define DTLS1_HM_FRAGMENT_RETRY -3 + +# define DTLS1_CCS_HEADER_LENGTH 1 + +# ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE +# define DTLS1_AL_HEADER_LENGTH 7 +# else +# define DTLS1_AL_HEADER_LENGTH 2 +# endif + +# ifndef OPENSSL_NO_SSL_INTERN + +# ifndef OPENSSL_NO_SCTP +# define DTLS1_SCTP_AUTH_LABEL "EXPORTER_DTLS_OVER_SCTP" +# endif + +/* Max MTU overhead we know about so far is 40 for IPv6 + 8 for UDP */ +# define DTLS1_MAX_MTU_OVERHEAD 48 + +typedef struct dtls1_bitmap_st { + unsigned long map; /* track 32 packets on 32-bit systems and 64 + * - on 64-bit systems */ + unsigned char max_seq_num[8]; /* max record number seen so far, 64-bit + * value in big-endian encoding */ +} DTLS1_BITMAP; + +struct dtls1_retransmit_state { + EVP_CIPHER_CTX *enc_write_ctx; /* cryptographic state */ + EVP_MD_CTX *write_hash; /* used for mac generation */ +# ifndef OPENSSL_NO_COMP + COMP_CTX *compress; /* compression */ +# else + char *compress; +# endif + SSL_SESSION *session; + unsigned short epoch; +}; + +struct hm_header_st { + unsigned char type; + unsigned long msg_len; + unsigned short seq; + unsigned long frag_off; + unsigned long frag_len; + unsigned int is_ccs; + struct dtls1_retransmit_state saved_retransmit_state; +}; + +struct ccs_header_st { + unsigned char type; + unsigned short seq; +}; + +struct dtls1_timeout_st { + /* Number of read timeouts so far */ + unsigned int read_timeouts; + /* Number of write timeouts so far */ + unsigned int write_timeouts; + /* Number of alerts received so far */ + unsigned int num_alerts; +}; + +typedef struct record_pqueue_st { + unsigned short epoch; + pqueue q; +} record_pqueue; + +typedef struct hm_fragment_st { + struct hm_header_st msg_header; + unsigned char *fragment; + unsigned char *reassembly; +} hm_fragment; + +typedef struct dtls1_state_st { + unsigned int send_cookie; + unsigned char cookie[DTLS1_COOKIE_LENGTH]; + unsigned char rcvd_cookie[DTLS1_COOKIE_LENGTH]; + unsigned int cookie_len; + /* + * The current data and handshake epoch. This is initially + * undefined, and starts at zero once the initial handshake is + * completed + */ + unsigned short r_epoch; + unsigned short w_epoch; + /* records being received in the current epoch */ + DTLS1_BITMAP bitmap; + /* renegotiation starts a new set of sequence numbers */ + DTLS1_BITMAP next_bitmap; + /* handshake message numbers */ + unsigned short handshake_write_seq; + unsigned short next_handshake_write_seq; + unsigned short handshake_read_seq; + /* save last sequence number for retransmissions */ + unsigned char last_write_sequence[8]; + /* Received handshake records (processed and unprocessed) */ + record_pqueue unprocessed_rcds; + record_pqueue processed_rcds; + /* Buffered handshake messages */ + pqueue buffered_messages; + /* Buffered (sent) handshake records */ + pqueue sent_messages; + /* + * Buffered application records. Only for records between CCS and + * Finished to prevent either protocol violation or unnecessary message + * loss. + */ + record_pqueue buffered_app_data; + /* Is set when listening for new connections with dtls1_listen() */ + unsigned int listen; + unsigned int link_mtu; /* max on-the-wire DTLS packet size */ + unsigned int mtu; /* max DTLS packet size */ + struct hm_header_st w_msg_hdr; + struct hm_header_st r_msg_hdr; + struct dtls1_timeout_st timeout; + /* + * Indicates when the last handshake msg or heartbeat sent will timeout + */ + struct timeval next_timeout; + /* Timeout duration */ + unsigned short timeout_duration; + /* + * storage for Alert/Handshake protocol data received but not yet + * processed by ssl3_read_bytes: + */ + unsigned char alert_fragment[DTLS1_AL_HEADER_LENGTH]; + unsigned int alert_fragment_len; + unsigned char handshake_fragment[DTLS1_HM_HEADER_LENGTH]; + unsigned int handshake_fragment_len; + unsigned int retransmitting; + /* + * Set when the handshake is ready to process peer's ChangeCipherSpec message. + * Cleared after the message has been processed. + */ + unsigned int change_cipher_spec_ok; +# ifndef OPENSSL_NO_SCTP + /* used when SSL_ST_XX_FLUSH is entered */ + int next_state; + int shutdown_received; +# endif +} DTLS1_STATE; + +typedef struct dtls1_record_data_st { + unsigned char *packet; + unsigned int packet_length; + SSL3_BUFFER rbuf; + SSL3_RECORD rrec; +# ifndef OPENSSL_NO_SCTP + struct bio_dgram_sctp_rcvinfo recordinfo; +# endif +} DTLS1_RECORD_DATA; + +# endif + +/* Timeout multipliers (timeout slice is defined in apps/timeouts.h */ +# define DTLS1_TMO_READ_COUNT 2 +# define DTLS1_TMO_WRITE_COUNT 2 + +# define DTLS1_TMO_ALERT_COUNT 12 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/e_os2.h b/OSlibs/ios/include/openssl/e_os2.h new file mode 100755 index 000000000..7be9989ac --- /dev/null +++ b/OSlibs/ios/include/openssl/e_os2.h @@ -0,0 +1,328 @@ +/* e_os2.h */ +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#ifndef HEADER_E_OS2_H +# define HEADER_E_OS2_H + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************************************** + * Detect operating systems. This probably needs completing. + * The result is that at least one OPENSSL_SYS_os macro should be defined. + * However, if none is defined, Unix is assumed. + **/ + +# define OPENSSL_SYS_UNIX + +/* ---------------------- Macintosh, before MacOS X ----------------------- */ +# if defined(__MWERKS__) && defined(macintosh) || defined(OPENSSL_SYSNAME_MAC) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_MACINTOSH_CLASSIC +# endif + +/* ---------------------- NetWare ----------------------------------------- */ +# if defined(NETWARE) || defined(OPENSSL_SYSNAME_NETWARE) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_NETWARE +# endif + +/* --------------------- Microsoft operating systems ---------------------- */ + +/* + * Note that MSDOS actually denotes 32-bit environments running on top of + * MS-DOS, such as DJGPP one. + */ +# if defined(OPENSSL_SYSNAME_MSDOS) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_MSDOS +# endif + +/* + * For 32 bit environment, there seems to be the CygWin environment and then + * all the others that try to do the same thing Microsoft does... + */ +# if defined(OPENSSL_SYSNAME_UWIN) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_WIN32_UWIN +# else +# if defined(__CYGWIN__) || defined(OPENSSL_SYSNAME_CYGWIN) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_WIN32_CYGWIN +# else +# if defined(_WIN32) || defined(OPENSSL_SYSNAME_WIN32) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_WIN32 +# endif +# if defined(_WIN64) || defined(OPENSSL_SYSNAME_WIN64) +# undef OPENSSL_SYS_UNIX +# if !defined(OPENSSL_SYS_WIN64) +# define OPENSSL_SYS_WIN64 +# endif +# endif +# if defined(OPENSSL_SYSNAME_WINNT) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_WINNT +# endif +# if defined(OPENSSL_SYSNAME_WINCE) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_WINCE +# endif +# endif +# endif + +/* Anything that tries to look like Microsoft is "Windows" */ +# if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN64) || defined(OPENSSL_SYS_WINNT) || defined(OPENSSL_SYS_WINCE) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_WINDOWS +# ifndef OPENSSL_SYS_MSDOS +# define OPENSSL_SYS_MSDOS +# endif +# endif + +/* + * DLL settings. This part is a bit tough, because it's up to the + * application implementor how he or she will link the application, so it + * requires some macro to be used. + */ +# ifdef OPENSSL_SYS_WINDOWS +# ifndef OPENSSL_OPT_WINDLL +# if defined(_WINDLL) /* This is used when building OpenSSL to + * indicate that DLL linkage should be used */ +# define OPENSSL_OPT_WINDLL +# endif +# endif +# endif + +/* ------------------------------- OpenVMS -------------------------------- */ +# if defined(__VMS) || defined(VMS) || defined(OPENSSL_SYSNAME_VMS) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_VMS +# if defined(__DECC) +# define OPENSSL_SYS_VMS_DECC +# elif defined(__DECCXX) +# define OPENSSL_SYS_VMS_DECC +# define OPENSSL_SYS_VMS_DECCXX +# else +# define OPENSSL_SYS_VMS_NODECC +# endif +# endif + +/* -------------------------------- OS/2 ---------------------------------- */ +# if defined(__EMX__) || defined(__OS2__) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_OS2 +# endif + +/* -------------------------------- Unix ---------------------------------- */ +# ifdef OPENSSL_SYS_UNIX +# if defined(linux) || defined(__linux__) || defined(OPENSSL_SYSNAME_LINUX) +# define OPENSSL_SYS_LINUX +# endif +# ifdef OPENSSL_SYSNAME_MPE +# define OPENSSL_SYS_MPE +# endif +# ifdef OPENSSL_SYSNAME_SNI +# define OPENSSL_SYS_SNI +# endif +# ifdef OPENSSL_SYSNAME_ULTRASPARC +# define OPENSSL_SYS_ULTRASPARC +# endif +# ifdef OPENSSL_SYSNAME_NEWS4 +# define OPENSSL_SYS_NEWS4 +# endif +# ifdef OPENSSL_SYSNAME_MACOSX +# define OPENSSL_SYS_MACOSX +# endif +# ifdef OPENSSL_SYSNAME_MACOSX_RHAPSODY +# define OPENSSL_SYS_MACOSX_RHAPSODY +# define OPENSSL_SYS_MACOSX +# endif +# ifdef OPENSSL_SYSNAME_SUNOS +# define OPENSSL_SYS_SUNOS +# endif +# if defined(_CRAY) || defined(OPENSSL_SYSNAME_CRAY) +# define OPENSSL_SYS_CRAY +# endif +# if defined(_AIX) || defined(OPENSSL_SYSNAME_AIX) +# define OPENSSL_SYS_AIX +# endif +# endif + +/* -------------------------------- VOS ----------------------------------- */ +# if defined(__VOS__) || defined(OPENSSL_SYSNAME_VOS) +# define OPENSSL_SYS_VOS +# ifdef __HPPA__ +# define OPENSSL_SYS_VOS_HPPA +# endif +# ifdef __IA32__ +# define OPENSSL_SYS_VOS_IA32 +# endif +# endif + +/* ------------------------------ VxWorks --------------------------------- */ +# ifdef OPENSSL_SYSNAME_VXWORKS +# define OPENSSL_SYS_VXWORKS +# endif + +/* -------------------------------- BeOS ---------------------------------- */ +# if defined(__BEOS__) +# define OPENSSL_SYS_BEOS +# include +# if defined(BONE_VERSION) +# define OPENSSL_SYS_BEOS_BONE +# else +# define OPENSSL_SYS_BEOS_R5 +# endif +# endif + +/** + * That's it for OS-specific stuff + *****************************************************************************/ + +/* Specials for I/O an exit */ +# ifdef OPENSSL_SYS_MSDOS +# define OPENSSL_UNISTD_IO +# define OPENSSL_DECLARE_EXIT extern void exit(int); +# else +# define OPENSSL_UNISTD_IO OPENSSL_UNISTD +# define OPENSSL_DECLARE_EXIT /* declared in unistd.h */ +# endif + +/*- + * Definitions of OPENSSL_GLOBAL and OPENSSL_EXTERN, to define and declare + * certain global symbols that, with some compilers under VMS, have to be + * defined and declared explicitely with globaldef and globalref. + * Definitions of OPENSSL_EXPORT and OPENSSL_IMPORT, to define and declare + * DLL exports and imports for compilers under Win32. These are a little + * more complicated to use. Basically, for any library that exports some + * global variables, the following code must be present in the header file + * that declares them, before OPENSSL_EXTERN is used: + * + * #ifdef SOME_BUILD_FLAG_MACRO + * # undef OPENSSL_EXTERN + * # define OPENSSL_EXTERN OPENSSL_EXPORT + * #endif + * + * The default is to have OPENSSL_EXPORT, OPENSSL_IMPORT and OPENSSL_GLOBAL + * have some generally sensible values, and for OPENSSL_EXTERN to have the + * value OPENSSL_IMPORT. + */ + +# if defined(OPENSSL_SYS_VMS_NODECC) +# define OPENSSL_EXPORT globalref +# define OPENSSL_IMPORT globalref +# define OPENSSL_GLOBAL globaldef +# elif defined(OPENSSL_SYS_WINDOWS) && defined(OPENSSL_OPT_WINDLL) +# define OPENSSL_EXPORT extern __declspec(dllexport) +# define OPENSSL_IMPORT extern __declspec(dllimport) +# define OPENSSL_GLOBAL +# else +# define OPENSSL_EXPORT extern +# define OPENSSL_IMPORT extern +# define OPENSSL_GLOBAL +# endif +# define OPENSSL_EXTERN OPENSSL_IMPORT + +/*- + * Macros to allow global variables to be reached through function calls when + * required (if a shared library version requires it, for example. + * The way it's done allows definitions like this: + * + * // in foobar.c + * OPENSSL_IMPLEMENT_GLOBAL(int,foobar,0) + * // in foobar.h + * OPENSSL_DECLARE_GLOBAL(int,foobar); + * #define foobar OPENSSL_GLOBAL_REF(foobar) + */ +# ifdef OPENSSL_EXPORT_VAR_AS_FUNCTION +# define OPENSSL_IMPLEMENT_GLOBAL(type,name,value) \ + type *_shadow_##name(void) \ + { static type _hide_##name=value; return &_hide_##name; } +# define OPENSSL_DECLARE_GLOBAL(type,name) type *_shadow_##name(void) +# define OPENSSL_GLOBAL_REF(name) (*(_shadow_##name())) +# else +# define OPENSSL_IMPLEMENT_GLOBAL(type,name,value) OPENSSL_GLOBAL type _shadow_##name=value; +# define OPENSSL_DECLARE_GLOBAL(type,name) OPENSSL_EXPORT type _shadow_##name +# define OPENSSL_GLOBAL_REF(name) _shadow_##name +# endif + +# if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) && macintosh==1 && !defined(MAC_OS_GUSI_SOURCE) +# define ossl_ssize_t long +# endif + +# ifdef OPENSSL_SYS_MSDOS +# define ossl_ssize_t long +# endif + +# if defined(NeXT) || defined(OPENSSL_SYS_NEWS4) || defined(OPENSSL_SYS_SUNOS) +# define ssize_t int +# endif + +# if defined(__ultrix) && !defined(ssize_t) +# define ossl_ssize_t int +# endif + +# ifndef ossl_ssize_t +# define ossl_ssize_t ssize_t +# endif + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/ebcdic.h b/OSlibs/ios/include/openssl/ebcdic.h new file mode 100755 index 000000000..4cbdfeb7a --- /dev/null +++ b/OSlibs/ios/include/openssl/ebcdic.h @@ -0,0 +1,26 @@ +/* crypto/ebcdic.h */ + +#ifndef HEADER_EBCDIC_H +# define HEADER_EBCDIC_H + +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Avoid name clashes with other applications */ +# define os_toascii _openssl_os_toascii +# define os_toebcdic _openssl_os_toebcdic +# define ebcdic2ascii _openssl_ebcdic2ascii +# define ascii2ebcdic _openssl_ascii2ebcdic + +extern const unsigned char os_toascii[256]; +extern const unsigned char os_toebcdic[256]; +void *ebcdic2ascii(void *dest, const void *srce, size_t count); +void *ascii2ebcdic(void *dest, const void *srce, size_t count); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/ec.h b/OSlibs/ios/include/openssl/ec.h new file mode 100755 index 000000000..81e6faf6c --- /dev/null +++ b/OSlibs/ios/include/openssl/ec.h @@ -0,0 +1,1282 @@ +/* crypto/ec/ec.h */ +/* + * Originally written by Bodo Moeller for the OpenSSL project. + */ +/** + * \file crypto/ec/ec.h Include file for the OpenSSL EC functions + * \author Originally written by Bodo Moeller for the OpenSSL project + */ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * The elliptic curve binary polynomial software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. + * + */ + +#ifndef HEADER_EC_H +# define HEADER_EC_H + +# include + +# ifdef OPENSSL_NO_EC +# error EC is disabled. +# endif + +# include +# include +# ifndef OPENSSL_NO_DEPRECATED +# include +# endif + +# ifdef __cplusplus +extern "C" { +# elif defined(__SUNPRO_C) +# if __SUNPRO_C >= 0x520 +# pragma error_messages (off,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE) +# endif +# endif + +# ifndef OPENSSL_ECC_MAX_FIELD_BITS +# define OPENSSL_ECC_MAX_FIELD_BITS 661 +# endif + +/** Enum for the point conversion form as defined in X9.62 (ECDSA) + * for the encoding of a elliptic curve point (x,y) */ +typedef enum { + /** the point is encoded as z||x, where the octet z specifies + * which solution of the quadratic equation y is */ + POINT_CONVERSION_COMPRESSED = 2, + /** the point is encoded as z||x||y, where z is the octet 0x04 */ + POINT_CONVERSION_UNCOMPRESSED = 4, + /** the point is encoded as z||x||y, where the octet z specifies + * which solution of the quadratic equation y is */ + POINT_CONVERSION_HYBRID = 6 +} point_conversion_form_t; + +typedef struct ec_method_st EC_METHOD; + +typedef struct ec_group_st + /*- + EC_METHOD *meth; + -- field definition + -- curve coefficients + -- optional generator with associated information (order, cofactor) + -- optional extra data (precomputed table for fast computation of multiples of generator) + -- ASN1 stuff + */ + EC_GROUP; + +typedef struct ec_point_st EC_POINT; + +/********************************************************************/ +/* EC_METHODs for curves over GF(p) */ +/********************************************************************/ + +/** Returns the basic GFp ec methods which provides the basis for the + * optimized methods. + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_simple_method(void); + +/** Returns GFp methods using montgomery multiplication. + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_mont_method(void); + +/** Returns GFp methods using optimized methods for NIST recommended curves + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_nist_method(void); + +# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 +/** Returns 64-bit optimized methods for nistp224 + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_nistp224_method(void); + +/** Returns 64-bit optimized methods for nistp256 + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_nistp256_method(void); + +/** Returns 64-bit optimized methods for nistp521 + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_nistp521_method(void); +# endif + +# ifndef OPENSSL_NO_EC2M +/********************************************************************/ +/* EC_METHOD for curves over GF(2^m) */ +/********************************************************************/ + +/** Returns the basic GF2m ec method + * \return EC_METHOD object + */ +const EC_METHOD *EC_GF2m_simple_method(void); + +# endif + +/********************************************************************/ +/* EC_GROUP functions */ +/********************************************************************/ + +/** Creates a new EC_GROUP object + * \param meth EC_METHOD to use + * \return newly created EC_GROUP object or NULL in case of an error. + */ +EC_GROUP *EC_GROUP_new(const EC_METHOD *meth); + +/** Frees a EC_GROUP object + * \param group EC_GROUP object to be freed. + */ +void EC_GROUP_free(EC_GROUP *group); + +/** Clears and frees a EC_GROUP object + * \param group EC_GROUP object to be cleared and freed. + */ +void EC_GROUP_clear_free(EC_GROUP *group); + +/** Copies EC_GROUP objects. Note: both EC_GROUPs must use the same EC_METHOD. + * \param dst destination EC_GROUP object + * \param src source EC_GROUP object + * \return 1 on success and 0 if an error occurred. + */ +int EC_GROUP_copy(EC_GROUP *dst, const EC_GROUP *src); + +/** Creates a new EC_GROUP object and copies the copies the content + * form src to the newly created EC_KEY object + * \param src source EC_GROUP object + * \return newly created EC_GROUP object or NULL in case of an error. + */ +EC_GROUP *EC_GROUP_dup(const EC_GROUP *src); + +/** Returns the EC_METHOD of the EC_GROUP object. + * \param group EC_GROUP object + * \return EC_METHOD used in this EC_GROUP object. + */ +const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group); + +/** Returns the field type of the EC_METHOD. + * \param meth EC_METHOD object + * \return NID of the underlying field type OID. + */ +int EC_METHOD_get_field_type(const EC_METHOD *meth); + +/** Sets the generator and it's order/cofactor of a EC_GROUP object. + * \param group EC_GROUP object + * \param generator EC_POINT object with the generator. + * \param order the order of the group generated by the generator. + * \param cofactor the index of the sub-group generated by the generator + * in the group of all points on the elliptic curve. + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, + const BIGNUM *order, const BIGNUM *cofactor); + +/** Returns the generator of a EC_GROUP object. + * \param group EC_GROUP object + * \return the currently used generator (possibly NULL). + */ +const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group); + +/** Returns the montgomery data for order(Generator) + * \param group EC_GROUP object + * \return the currently used generator (possibly NULL). +*/ +BN_MONT_CTX *EC_GROUP_get_mont_data(const EC_GROUP *group); + +/** Gets the order of a EC_GROUP + * \param group EC_GROUP object + * \param order BIGNUM to which the order is copied + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx); + +/** Gets the cofactor of a EC_GROUP + * \param group EC_GROUP object + * \param cofactor BIGNUM to which the cofactor is copied + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, + BN_CTX *ctx); + +/** Sets the name of a EC_GROUP object + * \param group EC_GROUP object + * \param nid NID of the curve name OID + */ +void EC_GROUP_set_curve_name(EC_GROUP *group, int nid); + +/** Returns the curve name of a EC_GROUP object + * \param group EC_GROUP object + * \return NID of the curve name OID or 0 if not set. + */ +int EC_GROUP_get_curve_name(const EC_GROUP *group); + +void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag); +int EC_GROUP_get_asn1_flag(const EC_GROUP *group); + +void EC_GROUP_set_point_conversion_form(EC_GROUP *group, + point_conversion_form_t form); +point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *); + +unsigned char *EC_GROUP_get0_seed(const EC_GROUP *x); +size_t EC_GROUP_get_seed_len(const EC_GROUP *); +size_t EC_GROUP_set_seed(EC_GROUP *, const unsigned char *, size_t len); + +/** Sets the parameter of a ec over GFp defined by y^2 = x^3 + a*x + b + * \param group EC_GROUP object + * \param p BIGNUM with the prime number + * \param a BIGNUM with parameter a of the equation + * \param b BIGNUM with parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx); + +/** Gets the parameter of the ec over GFp defined by y^2 = x^3 + a*x + b + * \param group EC_GROUP object + * \param p BIGNUM for the prime number + * \param a BIGNUM for parameter a of the equation + * \param b BIGNUM for parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, + BIGNUM *b, BN_CTX *ctx); + +# ifndef OPENSSL_NO_EC2M +/** Sets the parameter of a ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b + * \param group EC_GROUP object + * \param p BIGNUM with the polynomial defining the underlying field + * \param a BIGNUM with parameter a of the equation + * \param b BIGNUM with parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx); + +/** Gets the parameter of the ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b + * \param group EC_GROUP object + * \param p BIGNUM for the polynomial defining the underlying field + * \param a BIGNUM for parameter a of the equation + * \param b BIGNUM for parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, + BIGNUM *b, BN_CTX *ctx); +# endif +/** Returns the number of bits needed to represent a field element + * \param group EC_GROUP object + * \return number of bits needed to represent a field element + */ +int EC_GROUP_get_degree(const EC_GROUP *group); + +/** Checks whether the parameter in the EC_GROUP define a valid ec group + * \param group EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 1 if group is a valid ec group and 0 otherwise + */ +int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx); + +/** Checks whether the discriminant of the elliptic curve is zero or not + * \param group EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 1 if the discriminant is not zero and 0 otherwise + */ +int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx); + +/** Compares two EC_GROUP objects + * \param a first EC_GROUP object + * \param b second EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 0 if both groups are equal and 1 otherwise + */ +int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx); + +/* + * EC_GROUP_new_GF*() calls EC_GROUP_new() and EC_GROUP_set_GF*() after + * choosing an appropriate EC_METHOD + */ + +/** Creates a new EC_GROUP object with the specified parameters defined + * over GFp (defined by the equation y^2 = x^3 + a*x + b) + * \param p BIGNUM with the prime number + * \param a BIGNUM with the parameter a of the equation + * \param b BIGNUM with the parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return newly created EC_GROUP object with the specified parameters + */ +EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx); +# ifndef OPENSSL_NO_EC2M +/** Creates a new EC_GROUP object with the specified parameters defined + * over GF2m (defined by the equation y^2 + x*y = x^3 + a*x^2 + b) + * \param p BIGNUM with the polynomial defining the underlying field + * \param a BIGNUM with the parameter a of the equation + * \param b BIGNUM with the parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return newly created EC_GROUP object with the specified parameters + */ +EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx); +# endif +/** Creates a EC_GROUP object with a curve specified by a NID + * \param nid NID of the OID of the curve name + * \return newly created EC_GROUP object with specified curve or NULL + * if an error occurred + */ +EC_GROUP *EC_GROUP_new_by_curve_name(int nid); + +/********************************************************************/ +/* handling of internal curves */ +/********************************************************************/ + +typedef struct { + int nid; + const char *comment; +} EC_builtin_curve; + +/* + * EC_builtin_curves(EC_builtin_curve *r, size_t size) returns number of all + * available curves or zero if a error occurred. In case r ist not zero + * nitems EC_builtin_curve structures are filled with the data of the first + * nitems internal groups + */ +size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems); + +const char *EC_curve_nid2nist(int nid); +int EC_curve_nist2nid(const char *name); + +/********************************************************************/ +/* EC_POINT functions */ +/********************************************************************/ + +/** Creates a new EC_POINT object for the specified EC_GROUP + * \param group EC_GROUP the underlying EC_GROUP object + * \return newly created EC_POINT object or NULL if an error occurred + */ +EC_POINT *EC_POINT_new(const EC_GROUP *group); + +/** Frees a EC_POINT object + * \param point EC_POINT object to be freed + */ +void EC_POINT_free(EC_POINT *point); + +/** Clears and frees a EC_POINT object + * \param point EC_POINT object to be cleared and freed + */ +void EC_POINT_clear_free(EC_POINT *point); + +/** Copies EC_POINT object + * \param dst destination EC_POINT object + * \param src source EC_POINT object + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_copy(EC_POINT *dst, const EC_POINT *src); + +/** Creates a new EC_POINT object and copies the content of the supplied + * EC_POINT + * \param src source EC_POINT object + * \param group underlying the EC_GROUP object + * \return newly created EC_POINT object or NULL if an error occurred + */ +EC_POINT *EC_POINT_dup(const EC_POINT *src, const EC_GROUP *group); + +/** Returns the EC_METHOD used in EC_POINT object + * \param point EC_POINT object + * \return the EC_METHOD used + */ +const EC_METHOD *EC_POINT_method_of(const EC_POINT *point); + +/** Sets a point to infinity (neutral element) + * \param group underlying EC_GROUP object + * \param point EC_POINT to set to infinity + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point); + +/** Sets the jacobian projective coordinates of a EC_POINT over GFp + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with the x-coordinate + * \param y BIGNUM with the y-coordinate + * \param z BIGNUM with the z-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, + EC_POINT *p, const BIGNUM *x, + const BIGNUM *y, const BIGNUM *z, + BN_CTX *ctx); + +/** Gets the jacobian projective coordinates of a EC_POINT over GFp + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM for the x-coordinate + * \param y BIGNUM for the y-coordinate + * \param z BIGNUM for the z-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group, + const EC_POINT *p, BIGNUM *x, + BIGNUM *y, BIGNUM *z, + BN_CTX *ctx); + +/** Sets the affine coordinates of a EC_POINT over GFp + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with the x-coordinate + * \param y BIGNUM with the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *p, + const BIGNUM *x, const BIGNUM *y, + BN_CTX *ctx); + +/** Gets the affine coordinates of a EC_POINT over GFp + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM for the x-coordinate + * \param y BIGNUM for the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, + const EC_POINT *p, BIGNUM *x, + BIGNUM *y, BN_CTX *ctx); + +/** Sets the x9.62 compressed coordinates of a EC_POINT over GFp + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with x-coordinate + * \param y_bit integer with the y-Bit (either 0 or 1) + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, + EC_POINT *p, const BIGNUM *x, + int y_bit, BN_CTX *ctx); +# ifndef OPENSSL_NO_EC2M +/** Sets the affine coordinates of a EC_POINT over GF2m + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with the x-coordinate + * \param y BIGNUM with the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *p, + const BIGNUM *x, const BIGNUM *y, + BN_CTX *ctx); + +/** Gets the affine coordinates of a EC_POINT over GF2m + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM for the x-coordinate + * \param y BIGNUM for the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group, + const EC_POINT *p, BIGNUM *x, + BIGNUM *y, BN_CTX *ctx); + +/** Sets the x9.62 compressed coordinates of a EC_POINT over GF2m + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with x-coordinate + * \param y_bit integer with the y-Bit (either 0 or 1) + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, + EC_POINT *p, const BIGNUM *x, + int y_bit, BN_CTX *ctx); +# endif +/** Encodes a EC_POINT object to a octet string + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param form point conversion form + * \param buf memory buffer for the result. If NULL the function returns + * required buffer size. + * \param len length of the memory buffer + * \param ctx BN_CTX object (optional) + * \return the length of the encoded octet string or 0 if an error occurred + */ +size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *p, + point_conversion_form_t form, + unsigned char *buf, size_t len, BN_CTX *ctx); + +/** Decodes a EC_POINT from a octet string + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param buf memory buffer with the encoded ec point + * \param len length of the encoded ec point + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *p, + const unsigned char *buf, size_t len, BN_CTX *ctx); + +/* other interfaces to point2oct/oct2point: */ +BIGNUM *EC_POINT_point2bn(const EC_GROUP *, const EC_POINT *, + point_conversion_form_t form, BIGNUM *, BN_CTX *); +EC_POINT *EC_POINT_bn2point(const EC_GROUP *, const BIGNUM *, + EC_POINT *, BN_CTX *); +char *EC_POINT_point2hex(const EC_GROUP *, const EC_POINT *, + point_conversion_form_t form, BN_CTX *); +EC_POINT *EC_POINT_hex2point(const EC_GROUP *, const char *, + EC_POINT *, BN_CTX *); + +/********************************************************************/ +/* functions for doing EC_POINT arithmetic */ +/********************************************************************/ + +/** Computes the sum of two EC_POINT + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result (r = a + b) + * \param a EC_POINT object with the first summand + * \param b EC_POINT object with the second summand + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, + const EC_POINT *b, BN_CTX *ctx); + +/** Computes the double of a EC_POINT + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result (r = 2 * a) + * \param a EC_POINT object + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, + BN_CTX *ctx); + +/** Computes the inverse of a EC_POINT + * \param group underlying EC_GROUP object + * \param a EC_POINT object to be inverted (it's used for the result as well) + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx); + +/** Checks whether the point is the neutral element of the group + * \param group the underlying EC_GROUP object + * \param p EC_POINT object + * \return 1 if the point is the neutral element and 0 otherwise + */ +int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *p); + +/** Checks whether the point is on the curve + * \param group underlying EC_GROUP object + * \param point EC_POINT object to check + * \param ctx BN_CTX object (optional) + * \return 1 if point if on the curve and 0 otherwise + */ +int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, + BN_CTX *ctx); + +/** Compares two EC_POINTs + * \param group underlying EC_GROUP object + * \param a first EC_POINT object + * \param b second EC_POINT object + * \param ctx BN_CTX object (optional) + * \return 0 if both points are equal and a value != 0 otherwise + */ +int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, + BN_CTX *ctx); + +int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx); +int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, + EC_POINT *points[], BN_CTX *ctx); + +/** Computes r = generator * n sum_{i=0}^{num-1} p[i] * m[i] + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result + * \param n BIGNUM with the multiplier for the group generator (optional) + * \param num number futher summands + * \param p array of size num of EC_POINT objects + * \param m array of size num of BIGNUM objects + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, + size_t num, const EC_POINT *p[], const BIGNUM *m[], + BN_CTX *ctx); + +/** Computes r = generator * n + q * m + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result + * \param n BIGNUM with the multiplier for the group generator (optional) + * \param q EC_POINT object with the first factor of the second summand + * \param m BIGNUM with the second factor of the second summand + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, + const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx); + +/** Stores multiples of generator for faster point multiplication + * \param group EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx); + +/** Reports whether a precomputation has been done + * \param group EC_GROUP object + * \return 1 if a pre-computation has been done and 0 otherwise + */ +int EC_GROUP_have_precompute_mult(const EC_GROUP *group); + +/********************************************************************/ +/* ASN1 stuff */ +/********************************************************************/ + +/* + * EC_GROUP_get_basis_type() returns the NID of the basis type used to + * represent the field elements + */ +int EC_GROUP_get_basis_type(const EC_GROUP *); +# ifndef OPENSSL_NO_EC2M +int EC_GROUP_get_trinomial_basis(const EC_GROUP *, unsigned int *k); +int EC_GROUP_get_pentanomial_basis(const EC_GROUP *, unsigned int *k1, + unsigned int *k2, unsigned int *k3); +# endif + +# define OPENSSL_EC_NAMED_CURVE 0x001 + +typedef struct ecpk_parameters_st ECPKPARAMETERS; + +EC_GROUP *d2i_ECPKParameters(EC_GROUP **, const unsigned char **in, long len); +int i2d_ECPKParameters(const EC_GROUP *, unsigned char **out); + +# define d2i_ECPKParameters_bio(bp,x) ASN1_d2i_bio_of(EC_GROUP,NULL,d2i_ECPKParameters,bp,x) +# define i2d_ECPKParameters_bio(bp,x) ASN1_i2d_bio_of_const(EC_GROUP,i2d_ECPKParameters,bp,x) +# define d2i_ECPKParameters_fp(fp,x) (EC_GROUP *)ASN1_d2i_fp(NULL, \ + (char *(*)())d2i_ECPKParameters,(fp),(unsigned char **)(x)) +# define i2d_ECPKParameters_fp(fp,x) ASN1_i2d_fp(i2d_ECPKParameters,(fp), \ + (unsigned char *)(x)) + +# ifndef OPENSSL_NO_BIO +int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off); +# endif +# ifndef OPENSSL_NO_FP_API +int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off); +# endif + +/********************************************************************/ +/* EC_KEY functions */ +/********************************************************************/ + +typedef struct ec_key_st EC_KEY; + +/* some values for the encoding_flag */ +# define EC_PKEY_NO_PARAMETERS 0x001 +# define EC_PKEY_NO_PUBKEY 0x002 + +/* some values for the flags field */ +# define EC_FLAG_NON_FIPS_ALLOW 0x1 +# define EC_FLAG_FIPS_CHECKED 0x2 + +/** Creates a new EC_KEY object. + * \return EC_KEY object or NULL if an error occurred. + */ +EC_KEY *EC_KEY_new(void); + +int EC_KEY_get_flags(const EC_KEY *key); + +void EC_KEY_set_flags(EC_KEY *key, int flags); + +void EC_KEY_clear_flags(EC_KEY *key, int flags); + +/** Creates a new EC_KEY object using a named curve as underlying + * EC_GROUP object. + * \param nid NID of the named curve. + * \return EC_KEY object or NULL if an error occurred. + */ +EC_KEY *EC_KEY_new_by_curve_name(int nid); + +/** Frees a EC_KEY object. + * \param key EC_KEY object to be freed. + */ +void EC_KEY_free(EC_KEY *key); + +/** Copies a EC_KEY object. + * \param dst destination EC_KEY object + * \param src src EC_KEY object + * \return dst or NULL if an error occurred. + */ +EC_KEY *EC_KEY_copy(EC_KEY *dst, const EC_KEY *src); + +/** Creates a new EC_KEY object and copies the content from src to it. + * \param src the source EC_KEY object + * \return newly created EC_KEY object or NULL if an error occurred. + */ +EC_KEY *EC_KEY_dup(const EC_KEY *src); + +/** Increases the internal reference count of a EC_KEY object. + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_up_ref(EC_KEY *key); + +/** Returns the EC_GROUP object of a EC_KEY object + * \param key EC_KEY object + * \return the EC_GROUP object (possibly NULL). + */ +const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key); + +/** Sets the EC_GROUP of a EC_KEY object. + * \param key EC_KEY object + * \param group EC_GROUP to use in the EC_KEY object (note: the EC_KEY + * object will use an own copy of the EC_GROUP). + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group); + +/** Returns the private key of a EC_KEY object. + * \param key EC_KEY object + * \return a BIGNUM with the private key (possibly NULL). + */ +const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key); + +/** Sets the private key of a EC_KEY object. + * \param key EC_KEY object + * \param prv BIGNUM with the private key (note: the EC_KEY object + * will use an own copy of the BIGNUM). + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *prv); + +/** Returns the public key of a EC_KEY object. + * \param key the EC_KEY object + * \return a EC_POINT object with the public key (possibly NULL) + */ +const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key); + +/** Sets the public key of a EC_KEY object. + * \param key EC_KEY object + * \param pub EC_POINT object with the public key (note: the EC_KEY object + * will use an own copy of the EC_POINT object). + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub); + +unsigned EC_KEY_get_enc_flags(const EC_KEY *key); +void EC_KEY_set_enc_flags(EC_KEY *eckey, unsigned int flags); +point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key); +void EC_KEY_set_conv_form(EC_KEY *eckey, point_conversion_form_t cform); +/* functions to set/get method specific data */ +void *EC_KEY_get_key_method_data(EC_KEY *key, + void *(*dup_func) (void *), + void (*free_func) (void *), + void (*clear_free_func) (void *)); +/** Sets the key method data of an EC_KEY object, if none has yet been set. + * \param key EC_KEY object + * \param data opaque data to install. + * \param dup_func a function that duplicates |data|. + * \param free_func a function that frees |data|. + * \param clear_free_func a function that wipes and frees |data|. + * \return the previously set data pointer, or NULL if |data| was inserted. + */ +void *EC_KEY_insert_key_method_data(EC_KEY *key, void *data, + void *(*dup_func) (void *), + void (*free_func) (void *), + void (*clear_free_func) (void *)); +/* wrapper functions for the underlying EC_GROUP object */ +void EC_KEY_set_asn1_flag(EC_KEY *eckey, int asn1_flag); + +/** Creates a table of pre-computed multiples of the generator to + * accelerate further EC_KEY operations. + * \param key EC_KEY object + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx); + +/** Creates a new ec private (and optional a new public) key. + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_generate_key(EC_KEY *key); + +/** Verifies that a private and/or public key is valid. + * \param key the EC_KEY object + * \return 1 on success and 0 otherwise. + */ +int EC_KEY_check_key(const EC_KEY *key); + +/** Sets a public key from affine coordindates performing + * neccessary NIST PKV tests. + * \param key the EC_KEY object + * \param x public key x coordinate + * \param y public key y coordinate + * \return 1 on success and 0 otherwise. + */ +int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, + BIGNUM *y); + +/********************************************************************/ +/* de- and encoding functions for SEC1 ECPrivateKey */ +/********************************************************************/ + +/** Decodes a private key from a memory buffer. + * \param key a pointer to a EC_KEY object which should be used (or NULL) + * \param in pointer to memory with the DER encoded private key + * \param len length of the DER encoded private key + * \return the decoded private key or NULL if an error occurred. + */ +EC_KEY *d2i_ECPrivateKey(EC_KEY **key, const unsigned char **in, long len); + +/** Encodes a private key object and stores the result in a buffer. + * \param key the EC_KEY object to encode + * \param out the buffer for the result (if NULL the function returns number + * of bytes needed). + * \return 1 on success and 0 if an error occurred. + */ +int i2d_ECPrivateKey(EC_KEY *key, unsigned char **out); + +/********************************************************************/ +/* de- and encoding functions for EC parameters */ +/********************************************************************/ + +/** Decodes ec parameter from a memory buffer. + * \param key a pointer to a EC_KEY object which should be used (or NULL) + * \param in pointer to memory with the DER encoded ec parameters + * \param len length of the DER encoded ec parameters + * \return a EC_KEY object with the decoded parameters or NULL if an error + * occurred. + */ +EC_KEY *d2i_ECParameters(EC_KEY **key, const unsigned char **in, long len); + +/** Encodes ec parameter and stores the result in a buffer. + * \param key the EC_KEY object with ec paramters to encode + * \param out the buffer for the result (if NULL the function returns number + * of bytes needed). + * \return 1 on success and 0 if an error occurred. + */ +int i2d_ECParameters(EC_KEY *key, unsigned char **out); + +/********************************************************************/ +/* de- and encoding functions for EC public key */ +/* (octet string, not DER -- hence 'o2i' and 'i2o') */ +/********************************************************************/ + +/** Decodes a ec public key from a octet string. + * \param key a pointer to a EC_KEY object which should be used + * \param in memory buffer with the encoded public key + * \param len length of the encoded public key + * \return EC_KEY object with decoded public key or NULL if an error + * occurred. + */ +EC_KEY *o2i_ECPublicKey(EC_KEY **key, const unsigned char **in, long len); + +/** Encodes a ec public key in an octet string. + * \param key the EC_KEY object with the public key + * \param out the buffer for the result (if NULL the function returns number + * of bytes needed). + * \return 1 on success and 0 if an error occurred + */ +int i2o_ECPublicKey(EC_KEY *key, unsigned char **out); + +# ifndef OPENSSL_NO_BIO +/** Prints out the ec parameters on human readable form. + * \param bp BIO object to which the information is printed + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred + */ +int ECParameters_print(BIO *bp, const EC_KEY *key); + +/** Prints out the contents of a EC_KEY object + * \param bp BIO object to which the information is printed + * \param key EC_KEY object + * \param off line offset + * \return 1 on success and 0 if an error occurred + */ +int EC_KEY_print(BIO *bp, const EC_KEY *key, int off); + +# endif +# ifndef OPENSSL_NO_FP_API +/** Prints out the ec parameters on human readable form. + * \param fp file descriptor to which the information is printed + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred + */ +int ECParameters_print_fp(FILE *fp, const EC_KEY *key); + +/** Prints out the contents of a EC_KEY object + * \param fp file descriptor to which the information is printed + * \param key EC_KEY object + * \param off line offset + * \return 1 on success and 0 if an error occurred + */ +int EC_KEY_print_fp(FILE *fp, const EC_KEY *key, int off); + +# endif + +# define ECParameters_dup(x) ASN1_dup_of(EC_KEY,i2d_ECParameters,d2i_ECParameters,x) + +# ifndef __cplusplus +# if defined(__SUNPRO_C) +# if __SUNPRO_C >= 0x520 +# pragma error_messages (default,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE) +# endif +# endif +# endif + +# define EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_PARAMGEN|EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, nid, NULL) + +# define EVP_PKEY_CTX_set_ec_param_enc(ctx, flag) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_PARAMGEN|EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_EC_PARAM_ENC, flag, NULL) + +# define EVP_PKEY_CTX_set_ecdh_cofactor_mode(ctx, flag) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_ECDH_COFACTOR, flag, NULL) + +# define EVP_PKEY_CTX_get_ecdh_cofactor_mode(ctx) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_ECDH_COFACTOR, -2, NULL) + +# define EVP_PKEY_CTX_set_ecdh_kdf_type(ctx, kdf) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_KDF_TYPE, kdf, NULL) + +# define EVP_PKEY_CTX_get_ecdh_kdf_type(ctx) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_KDF_TYPE, -2, NULL) + +# define EVP_PKEY_CTX_set_ecdh_kdf_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_KDF_MD, 0, (void *)md) + +# define EVP_PKEY_CTX_get_ecdh_kdf_md(ctx, pmd) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_GET_EC_KDF_MD, 0, (void *)pmd) + +# define EVP_PKEY_CTX_set_ecdh_kdf_outlen(ctx, len) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_KDF_OUTLEN, len, NULL) + +# define EVP_PKEY_CTX_get_ecdh_kdf_outlen(ctx, plen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN, 0, (void *)plen) + +# define EVP_PKEY_CTX_set0_ecdh_kdf_ukm(ctx, p, plen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_KDF_UKM, plen, (void *)p) + +# define EVP_PKEY_CTX_get0_ecdh_kdf_ukm(ctx, p) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_GET_EC_KDF_UKM, 0, (void *)p) + +# define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID (EVP_PKEY_ALG_CTRL + 1) +# define EVP_PKEY_CTRL_EC_PARAM_ENC (EVP_PKEY_ALG_CTRL + 2) +# define EVP_PKEY_CTRL_EC_ECDH_COFACTOR (EVP_PKEY_ALG_CTRL + 3) +# define EVP_PKEY_CTRL_EC_KDF_TYPE (EVP_PKEY_ALG_CTRL + 4) +# define EVP_PKEY_CTRL_EC_KDF_MD (EVP_PKEY_ALG_CTRL + 5) +# define EVP_PKEY_CTRL_GET_EC_KDF_MD (EVP_PKEY_ALG_CTRL + 6) +# define EVP_PKEY_CTRL_EC_KDF_OUTLEN (EVP_PKEY_ALG_CTRL + 7) +# define EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN (EVP_PKEY_ALG_CTRL + 8) +# define EVP_PKEY_CTRL_EC_KDF_UKM (EVP_PKEY_ALG_CTRL + 9) +# define EVP_PKEY_CTRL_GET_EC_KDF_UKM (EVP_PKEY_ALG_CTRL + 10) +/* KDF types */ +# define EVP_PKEY_ECDH_KDF_NONE 1 +# define EVP_PKEY_ECDH_KDF_X9_62 2 + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_EC_strings(void); + +/* Error codes for the EC functions. */ + +/* Function codes. */ +# define EC_F_BN_TO_FELEM 224 +# define EC_F_COMPUTE_WNAF 143 +# define EC_F_D2I_ECPARAMETERS 144 +# define EC_F_D2I_ECPKPARAMETERS 145 +# define EC_F_D2I_ECPRIVATEKEY 146 +# define EC_F_DO_EC_KEY_PRINT 221 +# define EC_F_ECDH_CMS_DECRYPT 238 +# define EC_F_ECDH_CMS_SET_SHARED_INFO 239 +# define EC_F_ECKEY_PARAM2TYPE 223 +# define EC_F_ECKEY_PARAM_DECODE 212 +# define EC_F_ECKEY_PRIV_DECODE 213 +# define EC_F_ECKEY_PRIV_ENCODE 214 +# define EC_F_ECKEY_PUB_DECODE 215 +# define EC_F_ECKEY_PUB_ENCODE 216 +# define EC_F_ECKEY_TYPE2PARAM 220 +# define EC_F_ECPARAMETERS_PRINT 147 +# define EC_F_ECPARAMETERS_PRINT_FP 148 +# define EC_F_ECPKPARAMETERS_PRINT 149 +# define EC_F_ECPKPARAMETERS_PRINT_FP 150 +# define EC_F_ECP_NISTZ256_GET_AFFINE 240 +# define EC_F_ECP_NISTZ256_MULT_PRECOMPUTE 243 +# define EC_F_ECP_NISTZ256_POINTS_MUL 241 +# define EC_F_ECP_NISTZ256_PRE_COMP_NEW 244 +# define EC_F_ECP_NISTZ256_SET_WORDS 245 +# define EC_F_ECP_NISTZ256_WINDOWED_MUL 242 +# define EC_F_ECP_NIST_MOD_192 203 +# define EC_F_ECP_NIST_MOD_224 204 +# define EC_F_ECP_NIST_MOD_256 205 +# define EC_F_ECP_NIST_MOD_521 206 +# define EC_F_EC_ASN1_GROUP2CURVE 153 +# define EC_F_EC_ASN1_GROUP2FIELDID 154 +# define EC_F_EC_ASN1_GROUP2PARAMETERS 155 +# define EC_F_EC_ASN1_GROUP2PKPARAMETERS 156 +# define EC_F_EC_ASN1_PARAMETERS2GROUP 157 +# define EC_F_EC_ASN1_PKPARAMETERS2GROUP 158 +# define EC_F_EC_EX_DATA_SET_DATA 211 +# define EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY 208 +# define EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT 159 +# define EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE 195 +# define EC_F_EC_GF2M_SIMPLE_OCT2POINT 160 +# define EC_F_EC_GF2M_SIMPLE_POINT2OCT 161 +# define EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES 162 +# define EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES 163 +# define EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES 164 +# define EC_F_EC_GFP_MONT_FIELD_DECODE 133 +# define EC_F_EC_GFP_MONT_FIELD_ENCODE 134 +# define EC_F_EC_GFP_MONT_FIELD_MUL 131 +# define EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE 209 +# define EC_F_EC_GFP_MONT_FIELD_SQR 132 +# define EC_F_EC_GFP_MONT_GROUP_SET_CURVE 189 +# define EC_F_EC_GFP_MONT_GROUP_SET_CURVE_GFP 135 +# define EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE 225 +# define EC_F_EC_GFP_NISTP224_POINTS_MUL 228 +# define EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES 226 +# define EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE 230 +# define EC_F_EC_GFP_NISTP256_POINTS_MUL 231 +# define EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES 232 +# define EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE 233 +# define EC_F_EC_GFP_NISTP521_POINTS_MUL 234 +# define EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES 235 +# define EC_F_EC_GFP_NIST_FIELD_MUL 200 +# define EC_F_EC_GFP_NIST_FIELD_SQR 201 +# define EC_F_EC_GFP_NIST_GROUP_SET_CURVE 202 +# define EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT 165 +# define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE 166 +# define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP 100 +# define EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR 101 +# define EC_F_EC_GFP_SIMPLE_MAKE_AFFINE 102 +# define EC_F_EC_GFP_SIMPLE_OCT2POINT 103 +# define EC_F_EC_GFP_SIMPLE_POINT2OCT 104 +# define EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE 137 +# define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES 167 +# define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP 105 +# define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES 168 +# define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP 128 +# define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES 169 +# define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP 129 +# define EC_F_EC_GROUP_CHECK 170 +# define EC_F_EC_GROUP_CHECK_DISCRIMINANT 171 +# define EC_F_EC_GROUP_COPY 106 +# define EC_F_EC_GROUP_GET0_GENERATOR 139 +# define EC_F_EC_GROUP_GET_COFACTOR 140 +# define EC_F_EC_GROUP_GET_CURVE_GF2M 172 +# define EC_F_EC_GROUP_GET_CURVE_GFP 130 +# define EC_F_EC_GROUP_GET_DEGREE 173 +# define EC_F_EC_GROUP_GET_ORDER 141 +# define EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS 193 +# define EC_F_EC_GROUP_GET_TRINOMIAL_BASIS 194 +# define EC_F_EC_GROUP_NEW 108 +# define EC_F_EC_GROUP_NEW_BY_CURVE_NAME 174 +# define EC_F_EC_GROUP_NEW_FROM_DATA 175 +# define EC_F_EC_GROUP_PRECOMPUTE_MULT 142 +# define EC_F_EC_GROUP_SET_CURVE_GF2M 176 +# define EC_F_EC_GROUP_SET_CURVE_GFP 109 +# define EC_F_EC_GROUP_SET_EXTRA_DATA 110 +# define EC_F_EC_GROUP_SET_GENERATOR 111 +# define EC_F_EC_KEY_CHECK_KEY 177 +# define EC_F_EC_KEY_COPY 178 +# define EC_F_EC_KEY_GENERATE_KEY 179 +# define EC_F_EC_KEY_NEW 182 +# define EC_F_EC_KEY_PRINT 180 +# define EC_F_EC_KEY_PRINT_FP 181 +# define EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES 229 +# define EC_F_EC_POINTS_MAKE_AFFINE 136 +# define EC_F_EC_POINT_ADD 112 +# define EC_F_EC_POINT_CMP 113 +# define EC_F_EC_POINT_COPY 114 +# define EC_F_EC_POINT_DBL 115 +# define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M 183 +# define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP 116 +# define EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP 117 +# define EC_F_EC_POINT_INVERT 210 +# define EC_F_EC_POINT_IS_AT_INFINITY 118 +# define EC_F_EC_POINT_IS_ON_CURVE 119 +# define EC_F_EC_POINT_MAKE_AFFINE 120 +# define EC_F_EC_POINT_MUL 184 +# define EC_F_EC_POINT_NEW 121 +# define EC_F_EC_POINT_OCT2POINT 122 +# define EC_F_EC_POINT_POINT2OCT 123 +# define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M 185 +# define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP 124 +# define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M 186 +# define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP 125 +# define EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP 126 +# define EC_F_EC_POINT_SET_TO_INFINITY 127 +# define EC_F_EC_PRE_COMP_DUP 207 +# define EC_F_EC_PRE_COMP_NEW 196 +# define EC_F_EC_WNAF_MUL 187 +# define EC_F_EC_WNAF_PRECOMPUTE_MULT 188 +# define EC_F_I2D_ECPARAMETERS 190 +# define EC_F_I2D_ECPKPARAMETERS 191 +# define EC_F_I2D_ECPRIVATEKEY 192 +# define EC_F_I2O_ECPUBLICKEY 151 +# define EC_F_NISTP224_PRE_COMP_NEW 227 +# define EC_F_NISTP256_PRE_COMP_NEW 236 +# define EC_F_NISTP521_PRE_COMP_NEW 237 +# define EC_F_O2I_ECPUBLICKEY 152 +# define EC_F_OLD_EC_PRIV_DECODE 222 +# define EC_F_PKEY_EC_CTRL 197 +# define EC_F_PKEY_EC_CTRL_STR 198 +# define EC_F_PKEY_EC_DERIVE 217 +# define EC_F_PKEY_EC_KEYGEN 199 +# define EC_F_PKEY_EC_PARAMGEN 219 +# define EC_F_PKEY_EC_SIGN 218 + +/* Reason codes. */ +# define EC_R_ASN1_ERROR 115 +# define EC_R_ASN1_UNKNOWN_FIELD 116 +# define EC_R_BIGNUM_OUT_OF_RANGE 144 +# define EC_R_BUFFER_TOO_SMALL 100 +# define EC_R_COORDINATES_OUT_OF_RANGE 146 +# define EC_R_D2I_ECPKPARAMETERS_FAILURE 117 +# define EC_R_DECODE_ERROR 142 +# define EC_R_DISCRIMINANT_IS_ZERO 118 +# define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE 119 +# define EC_R_FIELD_TOO_LARGE 143 +# define EC_R_GF2M_NOT_SUPPORTED 147 +# define EC_R_GROUP2PKPARAMETERS_FAILURE 120 +# define EC_R_I2D_ECPKPARAMETERS_FAILURE 121 +# define EC_R_INCOMPATIBLE_OBJECTS 101 +# define EC_R_INVALID_ARGUMENT 112 +# define EC_R_INVALID_COMPRESSED_POINT 110 +# define EC_R_INVALID_COMPRESSION_BIT 109 +# define EC_R_INVALID_CURVE 141 +# define EC_R_INVALID_DIGEST 151 +# define EC_R_INVALID_DIGEST_TYPE 138 +# define EC_R_INVALID_ENCODING 102 +# define EC_R_INVALID_FIELD 103 +# define EC_R_INVALID_FORM 104 +# define EC_R_INVALID_GROUP_ORDER 122 +# define EC_R_INVALID_PENTANOMIAL_BASIS 132 +# define EC_R_INVALID_PRIVATE_KEY 123 +# define EC_R_INVALID_TRINOMIAL_BASIS 137 +# define EC_R_KDF_PARAMETER_ERROR 148 +# define EC_R_KEYS_NOT_SET 140 +# define EC_R_MISSING_PARAMETERS 124 +# define EC_R_MISSING_PRIVATE_KEY 125 +# define EC_R_NOT_A_NIST_PRIME 135 +# define EC_R_NOT_A_SUPPORTED_NIST_PRIME 136 +# define EC_R_NOT_IMPLEMENTED 126 +# define EC_R_NOT_INITIALIZED 111 +# define EC_R_NO_FIELD_MOD 133 +# define EC_R_NO_PARAMETERS_SET 139 +# define EC_R_PASSED_NULL_PARAMETER 134 +# define EC_R_PEER_KEY_ERROR 149 +# define EC_R_PKPARAMETERS2GROUP_FAILURE 127 +# define EC_R_POINT_AT_INFINITY 106 +# define EC_R_POINT_IS_NOT_ON_CURVE 107 +# define EC_R_SHARED_INFO_ERROR 150 +# define EC_R_SLOT_FULL 108 +# define EC_R_UNDEFINED_GENERATOR 113 +# define EC_R_UNDEFINED_ORDER 128 +# define EC_R_UNKNOWN_GROUP 129 +# define EC_R_UNKNOWN_ORDER 114 +# define EC_R_UNSUPPORTED_FIELD 131 +# define EC_R_WRONG_CURVE_PARAMETERS 145 +# define EC_R_WRONG_ORDER 130 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/ecdh.h b/OSlibs/ios/include/openssl/ecdh.h new file mode 100755 index 000000000..25348b30f --- /dev/null +++ b/OSlibs/ios/include/openssl/ecdh.h @@ -0,0 +1,134 @@ +/* crypto/ecdh/ecdh.h */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * The Elliptic Curve Public-Key Crypto Library (ECC Code) included + * herein is developed by SUN MICROSYSTEMS, INC., and is contributed + * to the OpenSSL project. + * + * The ECC Code is licensed pursuant to the OpenSSL open source + * license provided below. + * + * The ECDH software is originally written by Douglas Stebila of + * Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright (c) 2000-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef HEADER_ECDH_H +# define HEADER_ECDH_H + +# include + +# ifdef OPENSSL_NO_ECDH +# error ECDH is disabled. +# endif + +# include +# include +# ifndef OPENSSL_NO_DEPRECATED +# include +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +# define EC_FLAG_COFACTOR_ECDH 0x1000 + +const ECDH_METHOD *ECDH_OpenSSL(void); + +void ECDH_set_default_method(const ECDH_METHOD *); +const ECDH_METHOD *ECDH_get_default_method(void); +int ECDH_set_method(EC_KEY *, const ECDH_METHOD *); + +int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, + EC_KEY *ecdh, void *(*KDF) (const void *in, size_t inlen, + void *out, size_t *outlen)); + +int ECDH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new + *new_func, CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); +int ECDH_set_ex_data(EC_KEY *d, int idx, void *arg); +void *ECDH_get_ex_data(EC_KEY *d, int idx); + +int ECDH_KDF_X9_62(unsigned char *out, size_t outlen, + const unsigned char *Z, size_t Zlen, + const unsigned char *sinfo, size_t sinfolen, + const EVP_MD *md); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_ECDH_strings(void); + +/* Error codes for the ECDH functions. */ + +/* Function codes. */ +# define ECDH_F_ECDH_CHECK 102 +# define ECDH_F_ECDH_COMPUTE_KEY 100 +# define ECDH_F_ECDH_DATA_NEW_METHOD 101 + +/* Reason codes. */ +# define ECDH_R_KDF_FAILED 102 +# define ECDH_R_NON_FIPS_METHOD 103 +# define ECDH_R_NO_PRIVATE_VALUE 100 +# define ECDH_R_POINT_ARITHMETIC_FAILURE 101 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/ecdsa.h b/OSlibs/ios/include/openssl/ecdsa.h new file mode 100755 index 000000000..a6f0930f8 --- /dev/null +++ b/OSlibs/ios/include/openssl/ecdsa.h @@ -0,0 +1,335 @@ +/* crypto/ecdsa/ecdsa.h */ +/** + * \file crypto/ecdsa/ecdsa.h Include file for the OpenSSL ECDSA functions + * \author Written by Nils Larsch for the OpenSSL project + */ +/* ==================================================================== + * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef HEADER_ECDSA_H +# define HEADER_ECDSA_H + +# include + +# ifdef OPENSSL_NO_ECDSA +# error ECDSA is disabled. +# endif + +# include +# include +# ifndef OPENSSL_NO_DEPRECATED +# include +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct ECDSA_SIG_st { + BIGNUM *r; + BIGNUM *s; +} ECDSA_SIG; + +/** Allocates and initialize a ECDSA_SIG structure + * \return pointer to a ECDSA_SIG structure or NULL if an error occurred + */ +ECDSA_SIG *ECDSA_SIG_new(void); + +/** frees a ECDSA_SIG structure + * \param sig pointer to the ECDSA_SIG structure + */ +void ECDSA_SIG_free(ECDSA_SIG *sig); + +/** DER encode content of ECDSA_SIG object (note: this function modifies *pp + * (*pp += length of the DER encoded signature)). + * \param sig pointer to the ECDSA_SIG object + * \param pp pointer to a unsigned char pointer for the output or NULL + * \return the length of the DER encoded ECDSA_SIG object or 0 + */ +int i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **pp); + +/** Decodes a DER encoded ECDSA signature (note: this function changes *pp + * (*pp += len)). + * \param sig pointer to ECDSA_SIG pointer (may be NULL) + * \param pp memory buffer with the DER encoded signature + * \param len length of the buffer + * \return pointer to the decoded ECDSA_SIG structure (or NULL) + */ +ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **sig, const unsigned char **pp, long len); + +/** Computes the ECDSA signature of the given hash value using + * the supplied private key and returns the created signature. + * \param dgst pointer to the hash value + * \param dgst_len length of the hash value + * \param eckey EC_KEY object containing a private EC key + * \return pointer to a ECDSA_SIG structure or NULL if an error occurred + */ +ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst, int dgst_len, + EC_KEY *eckey); + +/** Computes ECDSA signature of a given hash value using the supplied + * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). + * \param dgst pointer to the hash value to sign + * \param dgstlen length of the hash value + * \param kinv BIGNUM with a pre-computed inverse k (optional) + * \param rp BIGNUM with a pre-computed rp value (optioanl), + * see ECDSA_sign_setup + * \param eckey EC_KEY object containing a private EC key + * \return pointer to a ECDSA_SIG structure or NULL if an error occurred + */ +ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dgstlen, + const BIGNUM *kinv, const BIGNUM *rp, + EC_KEY *eckey); + +/** Verifies that the supplied signature is a valid ECDSA + * signature of the supplied hash value using the supplied public key. + * \param dgst pointer to the hash value + * \param dgst_len length of the hash value + * \param sig ECDSA_SIG structure + * \param eckey EC_KEY object containing a public EC key + * \return 1 if the signature is valid, 0 if the signature is invalid + * and -1 on error + */ +int ECDSA_do_verify(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY *eckey); + +const ECDSA_METHOD *ECDSA_OpenSSL(void); + +/** Sets the default ECDSA method + * \param meth new default ECDSA_METHOD + */ +void ECDSA_set_default_method(const ECDSA_METHOD *meth); + +/** Returns the default ECDSA method + * \return pointer to ECDSA_METHOD structure containing the default method + */ +const ECDSA_METHOD *ECDSA_get_default_method(void); + +/** Sets method to be used for the ECDSA operations + * \param eckey EC_KEY object + * \param meth new method + * \return 1 on success and 0 otherwise + */ +int ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth); + +/** Returns the maximum length of the DER encoded signature + * \param eckey EC_KEY object + * \return numbers of bytes required for the DER encoded signature + */ +int ECDSA_size(const EC_KEY *eckey); + +/** Precompute parts of the signing operation + * \param eckey EC_KEY object containing a private EC key + * \param ctx BN_CTX object (optional) + * \param kinv BIGNUM pointer for the inverse of k + * \param rp BIGNUM pointer for x coordinate of k * generator + * \return 1 on success and 0 otherwise + */ +int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, BIGNUM **rp); + +/** Computes ECDSA signature of a given hash value using the supplied + * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). + * \param type this parameter is ignored + * \param dgst pointer to the hash value to sign + * \param dgstlen length of the hash value + * \param sig memory for the DER encoded created signature + * \param siglen pointer to the length of the returned signature + * \param eckey EC_KEY object containing a private EC key + * \return 1 on success and 0 otherwise + */ +int ECDSA_sign(int type, const unsigned char *dgst, int dgstlen, + unsigned char *sig, unsigned int *siglen, EC_KEY *eckey); + +/** Computes ECDSA signature of a given hash value using the supplied + * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). + * \param type this parameter is ignored + * \param dgst pointer to the hash value to sign + * \param dgstlen length of the hash value + * \param sig buffer to hold the DER encoded signature + * \param siglen pointer to the length of the returned signature + * \param kinv BIGNUM with a pre-computed inverse k (optional) + * \param rp BIGNUM with a pre-computed rp value (optioanl), + * see ECDSA_sign_setup + * \param eckey EC_KEY object containing a private EC key + * \return 1 on success and 0 otherwise + */ +int ECDSA_sign_ex(int type, const unsigned char *dgst, int dgstlen, + unsigned char *sig, unsigned int *siglen, + const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey); + +/** Verifies that the given signature is valid ECDSA signature + * of the supplied hash value using the specified public key. + * \param type this parameter is ignored + * \param dgst pointer to the hash value + * \param dgstlen length of the hash value + * \param sig pointer to the DER encoded signature + * \param siglen length of the DER encoded signature + * \param eckey EC_KEY object containing a public EC key + * \return 1 if the signature is valid, 0 if the signature is invalid + * and -1 on error + */ +int ECDSA_verify(int type, const unsigned char *dgst, int dgstlen, + const unsigned char *sig, int siglen, EC_KEY *eckey); + +/* the standard ex_data functions */ +int ECDSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new + *new_func, CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); +int ECDSA_set_ex_data(EC_KEY *d, int idx, void *arg); +void *ECDSA_get_ex_data(EC_KEY *d, int idx); + +/** Allocates and initialize a ECDSA_METHOD structure + * \param ecdsa_method pointer to ECDSA_METHOD to copy. (May be NULL) + * \return pointer to a ECDSA_METHOD structure or NULL if an error occurred + */ + +ECDSA_METHOD *ECDSA_METHOD_new(const ECDSA_METHOD *ecdsa_method); + +/** frees a ECDSA_METHOD structure + * \param ecdsa_method pointer to the ECDSA_METHOD structure + */ +void ECDSA_METHOD_free(ECDSA_METHOD *ecdsa_method); + +/** Sets application specific data in the ECDSA_METHOD + * \param ecdsa_method pointer to existing ECDSA_METHOD + * \param app application specific data to set + */ + +void ECDSA_METHOD_set_app_data(ECDSA_METHOD *ecdsa_method, void *app); + +/** Returns application specific data from a ECDSA_METHOD structure + * \param ecdsa_method pointer to ECDSA_METHOD structure + * \return pointer to application specific data. + */ + +void *ECDSA_METHOD_get_app_data(ECDSA_METHOD *ecdsa_method); + +/** Set the ECDSA_do_sign function in the ECDSA_METHOD + * \param ecdsa_method pointer to existing ECDSA_METHOD + * \param ecdsa_do_sign a funtion of type ECDSA_do_sign + */ + +void ECDSA_METHOD_set_sign(ECDSA_METHOD *ecdsa_method, + ECDSA_SIG *(*ecdsa_do_sign) (const unsigned char + *dgst, int dgst_len, + const BIGNUM *inv, + const BIGNUM *rp, + EC_KEY *eckey)); + +/** Set the ECDSA_sign_setup function in the ECDSA_METHOD + * \param ecdsa_method pointer to existing ECDSA_METHOD + * \param ecdsa_sign_setup a funtion of type ECDSA_sign_setup + */ + +void ECDSA_METHOD_set_sign_setup(ECDSA_METHOD *ecdsa_method, + int (*ecdsa_sign_setup) (EC_KEY *eckey, + BN_CTX *ctx, + BIGNUM **kinv, + BIGNUM **r)); + +/** Set the ECDSA_do_verify function in the ECDSA_METHOD + * \param ecdsa_method pointer to existing ECDSA_METHOD + * \param ecdsa_do_verify a funtion of type ECDSA_do_verify + */ + +void ECDSA_METHOD_set_verify(ECDSA_METHOD *ecdsa_method, + int (*ecdsa_do_verify) (const unsigned char + *dgst, int dgst_len, + const ECDSA_SIG *sig, + EC_KEY *eckey)); + +void ECDSA_METHOD_set_flags(ECDSA_METHOD *ecdsa_method, int flags); + +/** Set the flags field in the ECDSA_METHOD + * \param ecdsa_method pointer to existing ECDSA_METHOD + * \param flags flags value to set + */ + +void ECDSA_METHOD_set_name(ECDSA_METHOD *ecdsa_method, char *name); + +/** Set the name field in the ECDSA_METHOD + * \param ecdsa_method pointer to existing ECDSA_METHOD + * \param name name to set + */ + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_ECDSA_strings(void); + +/* Error codes for the ECDSA functions. */ + +/* Function codes. */ +# define ECDSA_F_ECDSA_CHECK 104 +# define ECDSA_F_ECDSA_DATA_NEW_METHOD 100 +# define ECDSA_F_ECDSA_DO_SIGN 101 +# define ECDSA_F_ECDSA_DO_VERIFY 102 +# define ECDSA_F_ECDSA_METHOD_NEW 105 +# define ECDSA_F_ECDSA_SIGN_SETUP 103 + +/* Reason codes. */ +# define ECDSA_R_BAD_SIGNATURE 100 +# define ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 101 +# define ECDSA_R_ERR_EC_LIB 102 +# define ECDSA_R_MISSING_PARAMETERS 103 +# define ECDSA_R_NEED_NEW_SETUP_VALUES 106 +# define ECDSA_R_NON_FIPS_METHOD 107 +# define ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED 104 +# define ECDSA_R_SIGNATURE_MALLOC_FAILED 105 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/engine.h b/OSlibs/ios/include/openssl/engine.h new file mode 100755 index 000000000..bd7b59144 --- /dev/null +++ b/OSlibs/ios/include/openssl/engine.h @@ -0,0 +1,960 @@ +/* openssl/engine.h */ +/* + * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECDH support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#ifndef HEADER_ENGINE_H +# define HEADER_ENGINE_H + +# include + +# ifdef OPENSSL_NO_ENGINE +# error ENGINE is disabled. +# endif + +# ifndef OPENSSL_NO_DEPRECATED +# include +# ifndef OPENSSL_NO_RSA +# include +# endif +# ifndef OPENSSL_NO_DSA +# include +# endif +# ifndef OPENSSL_NO_DH +# include +# endif +# ifndef OPENSSL_NO_ECDH +# include +# endif +# ifndef OPENSSL_NO_ECDSA +# include +# endif +# include +# include +# include +# endif + +# include +# include + +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * These flags are used to control combinations of algorithm (methods) by + * bitwise "OR"ing. + */ +# define ENGINE_METHOD_RSA (unsigned int)0x0001 +# define ENGINE_METHOD_DSA (unsigned int)0x0002 +# define ENGINE_METHOD_DH (unsigned int)0x0004 +# define ENGINE_METHOD_RAND (unsigned int)0x0008 +# define ENGINE_METHOD_ECDH (unsigned int)0x0010 +# define ENGINE_METHOD_ECDSA (unsigned int)0x0020 +# define ENGINE_METHOD_CIPHERS (unsigned int)0x0040 +# define ENGINE_METHOD_DIGESTS (unsigned int)0x0080 +# define ENGINE_METHOD_STORE (unsigned int)0x0100 +# define ENGINE_METHOD_PKEY_METHS (unsigned int)0x0200 +# define ENGINE_METHOD_PKEY_ASN1_METHS (unsigned int)0x0400 +/* Obvious all-or-nothing cases. */ +# define ENGINE_METHOD_ALL (unsigned int)0xFFFF +# define ENGINE_METHOD_NONE (unsigned int)0x0000 + +/* + * This(ese) flag(s) controls behaviour of the ENGINE_TABLE mechanism used + * internally to control registration of ENGINE implementations, and can be + * set by ENGINE_set_table_flags(). The "NOINIT" flag prevents attempts to + * initialise registered ENGINEs if they are not already initialised. + */ +# define ENGINE_TABLE_FLAG_NOINIT (unsigned int)0x0001 + +/* ENGINE flags that can be set by ENGINE_set_flags(). */ +/* Not used */ +/* #define ENGINE_FLAGS_MALLOCED 0x0001 */ + +/* + * This flag is for ENGINEs that wish to handle the various 'CMD'-related + * control commands on their own. Without this flag, ENGINE_ctrl() handles + * these control commands on behalf of the ENGINE using their "cmd_defns" + * data. + */ +# define ENGINE_FLAGS_MANUAL_CMD_CTRL (int)0x0002 + +/* + * This flag is for ENGINEs who return new duplicate structures when found + * via "ENGINE_by_id()". When an ENGINE must store state (eg. if + * ENGINE_ctrl() commands are called in sequence as part of some stateful + * process like key-generation setup and execution), it can set this flag - + * then each attempt to obtain the ENGINE will result in it being copied into + * a new structure. Normally, ENGINEs don't declare this flag so + * ENGINE_by_id() just increments the existing ENGINE's structural reference + * count. + */ +# define ENGINE_FLAGS_BY_ID_COPY (int)0x0004 + +/* + * This flag if for an ENGINE that does not want its methods registered as + * part of ENGINE_register_all_complete() for example if the methods are not + * usable as default methods. + */ + +# define ENGINE_FLAGS_NO_REGISTER_ALL (int)0x0008 + +/* + * ENGINEs can support their own command types, and these flags are used in + * ENGINE_CTRL_GET_CMD_FLAGS to indicate to the caller what kind of input + * each command expects. Currently only numeric and string input is + * supported. If a control command supports none of the _NUMERIC, _STRING, or + * _NO_INPUT options, then it is regarded as an "internal" control command - + * and not for use in config setting situations. As such, they're not + * available to the ENGINE_ctrl_cmd_string() function, only raw ENGINE_ctrl() + * access. Changes to this list of 'command types' should be reflected + * carefully in ENGINE_cmd_is_executable() and ENGINE_ctrl_cmd_string(). + */ + +/* accepts a 'long' input value (3rd parameter to ENGINE_ctrl) */ +# define ENGINE_CMD_FLAG_NUMERIC (unsigned int)0x0001 +/* + * accepts string input (cast from 'void*' to 'const char *', 4th parameter + * to ENGINE_ctrl) + */ +# define ENGINE_CMD_FLAG_STRING (unsigned int)0x0002 +/* + * Indicates that the control command takes *no* input. Ie. the control + * command is unparameterised. + */ +# define ENGINE_CMD_FLAG_NO_INPUT (unsigned int)0x0004 +/* + * Indicates that the control command is internal. This control command won't + * be shown in any output, and is only usable through the ENGINE_ctrl_cmd() + * function. + */ +# define ENGINE_CMD_FLAG_INTERNAL (unsigned int)0x0008 + +/* + * NB: These 3 control commands are deprecated and should not be used. + * ENGINEs relying on these commands should compile conditional support for + * compatibility (eg. if these symbols are defined) but should also migrate + * the same functionality to their own ENGINE-specific control functions that + * can be "discovered" by calling applications. The fact these control + * commands wouldn't be "executable" (ie. usable by text-based config) + * doesn't change the fact that application code can find and use them + * without requiring per-ENGINE hacking. + */ + +/* + * These flags are used to tell the ctrl function what should be done. All + * command numbers are shared between all engines, even if some don't make + * sense to some engines. In such a case, they do nothing but return the + * error ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED. + */ +# define ENGINE_CTRL_SET_LOGSTREAM 1 +# define ENGINE_CTRL_SET_PASSWORD_CALLBACK 2 +# define ENGINE_CTRL_HUP 3/* Close and reinitialise + * any handles/connections + * etc. */ +# define ENGINE_CTRL_SET_USER_INTERFACE 4/* Alternative to callback */ +# define ENGINE_CTRL_SET_CALLBACK_DATA 5/* User-specific data, used + * when calling the password + * callback and the user + * interface */ +# define ENGINE_CTRL_LOAD_CONFIGURATION 6/* Load a configuration, + * given a string that + * represents a file name + * or so */ +# define ENGINE_CTRL_LOAD_SECTION 7/* Load data from a given + * section in the already + * loaded configuration */ + +/* + * These control commands allow an application to deal with an arbitrary + * engine in a dynamic way. Warn: Negative return values indicate errors FOR + * THESE COMMANDS because zero is used to indicate 'end-of-list'. Other + * commands, including ENGINE-specific command types, return zero for an + * error. An ENGINE can choose to implement these ctrl functions, and can + * internally manage things however it chooses - it does so by setting the + * ENGINE_FLAGS_MANUAL_CMD_CTRL flag (using ENGINE_set_flags()). Otherwise + * the ENGINE_ctrl() code handles this on the ENGINE's behalf using the + * cmd_defns data (set using ENGINE_set_cmd_defns()). This means an ENGINE's + * ctrl() handler need only implement its own commands - the above "meta" + * commands will be taken care of. + */ + +/* + * Returns non-zero if the supplied ENGINE has a ctrl() handler. If "not", + * then all the remaining control commands will return failure, so it is + * worth checking this first if the caller is trying to "discover" the + * engine's capabilities and doesn't want errors generated unnecessarily. + */ +# define ENGINE_CTRL_HAS_CTRL_FUNCTION 10 +/* + * Returns a positive command number for the first command supported by the + * engine. Returns zero if no ctrl commands are supported. + */ +# define ENGINE_CTRL_GET_FIRST_CMD_TYPE 11 +/* + * The 'long' argument specifies a command implemented by the engine, and the + * return value is the next command supported, or zero if there are no more. + */ +# define ENGINE_CTRL_GET_NEXT_CMD_TYPE 12 +/* + * The 'void*' argument is a command name (cast from 'const char *'), and the + * return value is the command that corresponds to it. + */ +# define ENGINE_CTRL_GET_CMD_FROM_NAME 13 +/* + * The next two allow a command to be converted into its corresponding string + * form. In each case, the 'long' argument supplies the command. In the + * NAME_LEN case, the return value is the length of the command name (not + * counting a trailing EOL). In the NAME case, the 'void*' argument must be a + * string buffer large enough, and it will be populated with the name of the + * command (WITH a trailing EOL). + */ +# define ENGINE_CTRL_GET_NAME_LEN_FROM_CMD 14 +# define ENGINE_CTRL_GET_NAME_FROM_CMD 15 +/* The next two are similar but give a "short description" of a command. */ +# define ENGINE_CTRL_GET_DESC_LEN_FROM_CMD 16 +# define ENGINE_CTRL_GET_DESC_FROM_CMD 17 +/* + * With this command, the return value is the OR'd combination of + * ENGINE_CMD_FLAG_*** values that indicate what kind of input a given + * engine-specific ctrl command expects. + */ +# define ENGINE_CTRL_GET_CMD_FLAGS 18 + +/* + * ENGINE implementations should start the numbering of their own control + * commands from this value. (ie. ENGINE_CMD_BASE, ENGINE_CMD_BASE + 1, etc). + */ +# define ENGINE_CMD_BASE 200 + +/* + * NB: These 2 nCipher "chil" control commands are deprecated, and their + * functionality is now available through ENGINE-specific control commands + * (exposed through the above-mentioned 'CMD'-handling). Code using these 2 + * commands should be migrated to the more general command handling before + * these are removed. + */ + +/* Flags specific to the nCipher "chil" engine */ +# define ENGINE_CTRL_CHIL_SET_FORKCHECK 100 + /* + * Depending on the value of the (long)i argument, this sets or + * unsets the SimpleForkCheck flag in the CHIL API to enable or + * disable checking and workarounds for applications that fork(). + */ +# define ENGINE_CTRL_CHIL_NO_LOCKING 101 + /* + * This prevents the initialisation function from providing mutex + * callbacks to the nCipher library. + */ + +/* + * If an ENGINE supports its own specific control commands and wishes the + * framework to handle the above 'ENGINE_CMD_***'-manipulation commands on + * its behalf, it should supply a null-terminated array of ENGINE_CMD_DEFN + * entries to ENGINE_set_cmd_defns(). It should also implement a ctrl() + * handler that supports the stated commands (ie. the "cmd_num" entries as + * described by the array). NB: The array must be ordered in increasing order + * of cmd_num. "null-terminated" means that the last ENGINE_CMD_DEFN element + * has cmd_num set to zero and/or cmd_name set to NULL. + */ +typedef struct ENGINE_CMD_DEFN_st { + unsigned int cmd_num; /* The command number */ + const char *cmd_name; /* The command name itself */ + const char *cmd_desc; /* A short description of the command */ + unsigned int cmd_flags; /* The input the command expects */ +} ENGINE_CMD_DEFN; + +/* Generic function pointer */ +typedef int (*ENGINE_GEN_FUNC_PTR) (void); +/* Generic function pointer taking no arguments */ +typedef int (*ENGINE_GEN_INT_FUNC_PTR) (ENGINE *); +/* Specific control function pointer */ +typedef int (*ENGINE_CTRL_FUNC_PTR) (ENGINE *, int, long, void *, + void (*f) (void)); +/* Generic load_key function pointer */ +typedef EVP_PKEY *(*ENGINE_LOAD_KEY_PTR)(ENGINE *, const char *, + UI_METHOD *ui_method, + void *callback_data); +typedef int (*ENGINE_SSL_CLIENT_CERT_PTR) (ENGINE *, SSL *ssl, + STACK_OF(X509_NAME) *ca_dn, + X509 **pcert, EVP_PKEY **pkey, + STACK_OF(X509) **pother, + UI_METHOD *ui_method, + void *callback_data); +/*- + * These callback types are for an ENGINE's handler for cipher and digest logic. + * These handlers have these prototypes; + * int foo(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid); + * int foo(ENGINE *e, const EVP_MD **digest, const int **nids, int nid); + * Looking at how to implement these handlers in the case of cipher support, if + * the framework wants the EVP_CIPHER for 'nid', it will call; + * foo(e, &p_evp_cipher, NULL, nid); (return zero for failure) + * If the framework wants a list of supported 'nid's, it will call; + * foo(e, NULL, &p_nids, 0); (returns number of 'nids' or -1 for error) + */ +/* + * Returns to a pointer to the array of supported cipher 'nid's. If the + * second parameter is non-NULL it is set to the size of the returned array. + */ +typedef int (*ENGINE_CIPHERS_PTR) (ENGINE *, const EVP_CIPHER **, + const int **, int); +typedef int (*ENGINE_DIGESTS_PTR) (ENGINE *, const EVP_MD **, const int **, + int); +typedef int (*ENGINE_PKEY_METHS_PTR) (ENGINE *, EVP_PKEY_METHOD **, + const int **, int); +typedef int (*ENGINE_PKEY_ASN1_METHS_PTR) (ENGINE *, EVP_PKEY_ASN1_METHOD **, + const int **, int); +/* + * STRUCTURE functions ... all of these functions deal with pointers to + * ENGINE structures where the pointers have a "structural reference". This + * means that their reference is to allowed access to the structure but it + * does not imply that the structure is functional. To simply increment or + * decrement the structural reference count, use ENGINE_by_id and + * ENGINE_free. NB: This is not required when iterating using ENGINE_get_next + * as it will automatically decrement the structural reference count of the + * "current" ENGINE and increment the structural reference count of the + * ENGINE it returns (unless it is NULL). + */ + +/* Get the first/last "ENGINE" type available. */ +ENGINE *ENGINE_get_first(void); +ENGINE *ENGINE_get_last(void); +/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */ +ENGINE *ENGINE_get_next(ENGINE *e); +ENGINE *ENGINE_get_prev(ENGINE *e); +/* Add another "ENGINE" type into the array. */ +int ENGINE_add(ENGINE *e); +/* Remove an existing "ENGINE" type from the array. */ +int ENGINE_remove(ENGINE *e); +/* Retrieve an engine from the list by its unique "id" value. */ +ENGINE *ENGINE_by_id(const char *id); +/* Add all the built-in engines. */ +void ENGINE_load_openssl(void); +void ENGINE_load_dynamic(void); +# ifndef OPENSSL_NO_STATIC_ENGINE +void ENGINE_load_4758cca(void); +void ENGINE_load_aep(void); +void ENGINE_load_atalla(void); +void ENGINE_load_chil(void); +void ENGINE_load_cswift(void); +void ENGINE_load_nuron(void); +void ENGINE_load_sureware(void); +void ENGINE_load_ubsec(void); +void ENGINE_load_padlock(void); +void ENGINE_load_capi(void); +# ifndef OPENSSL_NO_GMP +void ENGINE_load_gmp(void); +# endif +# ifndef OPENSSL_NO_GOST +void ENGINE_load_gost(void); +# endif +# endif +void ENGINE_load_cryptodev(void); +void ENGINE_load_rdrand(void); +void ENGINE_load_builtin_engines(void); + +/* + * Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation + * "registry" handling. + */ +unsigned int ENGINE_get_table_flags(void); +void ENGINE_set_table_flags(unsigned int flags); + +/*- Manage registration of ENGINEs per "table". For each type, there are 3 + * functions; + * ENGINE_register_***(e) - registers the implementation from 'e' (if it has one) + * ENGINE_unregister_***(e) - unregister the implementation from 'e' + * ENGINE_register_all_***() - call ENGINE_register_***() for each 'e' in the list + * Cleanup is automatically registered from each table when required, so + * ENGINE_cleanup() will reverse any "register" operations. + */ + +int ENGINE_register_RSA(ENGINE *e); +void ENGINE_unregister_RSA(ENGINE *e); +void ENGINE_register_all_RSA(void); + +int ENGINE_register_DSA(ENGINE *e); +void ENGINE_unregister_DSA(ENGINE *e); +void ENGINE_register_all_DSA(void); + +int ENGINE_register_ECDH(ENGINE *e); +void ENGINE_unregister_ECDH(ENGINE *e); +void ENGINE_register_all_ECDH(void); + +int ENGINE_register_ECDSA(ENGINE *e); +void ENGINE_unregister_ECDSA(ENGINE *e); +void ENGINE_register_all_ECDSA(void); + +int ENGINE_register_DH(ENGINE *e); +void ENGINE_unregister_DH(ENGINE *e); +void ENGINE_register_all_DH(void); + +int ENGINE_register_RAND(ENGINE *e); +void ENGINE_unregister_RAND(ENGINE *e); +void ENGINE_register_all_RAND(void); + +int ENGINE_register_STORE(ENGINE *e); +void ENGINE_unregister_STORE(ENGINE *e); +void ENGINE_register_all_STORE(void); + +int ENGINE_register_ciphers(ENGINE *e); +void ENGINE_unregister_ciphers(ENGINE *e); +void ENGINE_register_all_ciphers(void); + +int ENGINE_register_digests(ENGINE *e); +void ENGINE_unregister_digests(ENGINE *e); +void ENGINE_register_all_digests(void); + +int ENGINE_register_pkey_meths(ENGINE *e); +void ENGINE_unregister_pkey_meths(ENGINE *e); +void ENGINE_register_all_pkey_meths(void); + +int ENGINE_register_pkey_asn1_meths(ENGINE *e); +void ENGINE_unregister_pkey_asn1_meths(ENGINE *e); +void ENGINE_register_all_pkey_asn1_meths(void); + +/* + * These functions register all support from the above categories. Note, use + * of these functions can result in static linkage of code your application + * may not need. If you only need a subset of functionality, consider using + * more selective initialisation. + */ +int ENGINE_register_complete(ENGINE *e); +int ENGINE_register_all_complete(void); + +/* + * Send parametrised control commands to the engine. The possibilities to + * send down an integer, a pointer to data or a function pointer are + * provided. Any of the parameters may or may not be NULL, depending on the + * command number. In actuality, this function only requires a structural + * (rather than functional) reference to an engine, but many control commands + * may require the engine be functional. The caller should be aware of trying + * commands that require an operational ENGINE, and only use functional + * references in such situations. + */ +int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)); + +/* + * This function tests if an ENGINE-specific command is usable as a + * "setting". Eg. in an application's config file that gets processed through + * ENGINE_ctrl_cmd_string(). If this returns zero, it is not available to + * ENGINE_ctrl_cmd_string(), only ENGINE_ctrl(). + */ +int ENGINE_cmd_is_executable(ENGINE *e, int cmd); + +/* + * This function works like ENGINE_ctrl() with the exception of taking a + * command name instead of a command number, and can handle optional + * commands. See the comment on ENGINE_ctrl_cmd_string() for an explanation + * on how to use the cmd_name and cmd_optional. + */ +int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name, + long i, void *p, void (*f) (void), int cmd_optional); + +/* + * This function passes a command-name and argument to an ENGINE. The + * cmd_name is converted to a command number and the control command is + * called using 'arg' as an argument (unless the ENGINE doesn't support such + * a command, in which case no control command is called). The command is + * checked for input flags, and if necessary the argument will be converted + * to a numeric value. If cmd_optional is non-zero, then if the ENGINE + * doesn't support the given cmd_name the return value will be success + * anyway. This function is intended for applications to use so that users + * (or config files) can supply engine-specific config data to the ENGINE at + * run-time to control behaviour of specific engines. As such, it shouldn't + * be used for calling ENGINE_ctrl() functions that return data, deal with + * binary data, or that are otherwise supposed to be used directly through + * ENGINE_ctrl() in application code. Any "return" data from an ENGINE_ctrl() + * operation in this function will be lost - the return value is interpreted + * as failure if the return value is zero, success otherwise, and this + * function returns a boolean value as a result. In other words, vendors of + * 'ENGINE'-enabled devices should write ENGINE implementations with + * parameterisations that work in this scheme, so that compliant ENGINE-based + * applications can work consistently with the same configuration for the + * same ENGINE-enabled devices, across applications. + */ +int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg, + int cmd_optional); + +/* + * These functions are useful for manufacturing new ENGINE structures. They + * don't address reference counting at all - one uses them to populate an + * ENGINE structure with personalised implementations of things prior to + * using it directly or adding it to the builtin ENGINE list in OpenSSL. + * These are also here so that the ENGINE structure doesn't have to be + * exposed and break binary compatibility! + */ +ENGINE *ENGINE_new(void); +int ENGINE_free(ENGINE *e); +int ENGINE_up_ref(ENGINE *e); +int ENGINE_set_id(ENGINE *e, const char *id); +int ENGINE_set_name(ENGINE *e, const char *name); +int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth); +int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth); +int ENGINE_set_ECDH(ENGINE *e, const ECDH_METHOD *ecdh_meth); +int ENGINE_set_ECDSA(ENGINE *e, const ECDSA_METHOD *ecdsa_meth); +int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth); +int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth); +int ENGINE_set_STORE(ENGINE *e, const STORE_METHOD *store_meth); +int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f); +int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f); +int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f); +int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f); +int ENGINE_set_load_privkey_function(ENGINE *e, + ENGINE_LOAD_KEY_PTR loadpriv_f); +int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f); +int ENGINE_set_load_ssl_client_cert_function(ENGINE *e, + ENGINE_SSL_CLIENT_CERT_PTR + loadssl_f); +int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f); +int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f); +int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f); +int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f); +int ENGINE_set_flags(ENGINE *e, int flags); +int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns); +/* These functions allow control over any per-structure ENGINE data. */ +int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); +int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg); +void *ENGINE_get_ex_data(const ENGINE *e, int idx); + +/* + * This function cleans up anything that needs it. Eg. the ENGINE_add() + * function automatically ensures the list cleanup function is registered to + * be called from ENGINE_cleanup(). Similarly, all ENGINE_register_*** + * functions ensure ENGINE_cleanup() will clean up after them. + */ +void ENGINE_cleanup(void); + +/* + * These return values from within the ENGINE structure. These can be useful + * with functional references as well as structural references - it depends + * which you obtained. Using the result for functional purposes if you only + * obtained a structural reference may be problematic! + */ +const char *ENGINE_get_id(const ENGINE *e); +const char *ENGINE_get_name(const ENGINE *e); +const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e); +const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e); +const ECDH_METHOD *ENGINE_get_ECDH(const ENGINE *e); +const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *e); +const DH_METHOD *ENGINE_get_DH(const ENGINE *e); +const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e); +const STORE_METHOD *ENGINE_get_STORE(const ENGINE *e); +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e); +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e); +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e); +ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e); +ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e); +ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e); +ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE + *e); +ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e); +ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e); +ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e); +ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e); +const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid); +const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid); +const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid); +const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid); +const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e, + const char *str, + int len); +const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe, + const char *str, + int len); +const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e); +int ENGINE_get_flags(const ENGINE *e); + +/* + * FUNCTIONAL functions. These functions deal with ENGINE structures that + * have (or will) be initialised for use. Broadly speaking, the structural + * functions are useful for iterating the list of available engine types, + * creating new engine types, and other "list" operations. These functions + * actually deal with ENGINEs that are to be used. As such these functions + * can fail (if applicable) when particular engines are unavailable - eg. if + * a hardware accelerator is not attached or not functioning correctly. Each + * ENGINE has 2 reference counts; structural and functional. Every time a + * functional reference is obtained or released, a corresponding structural + * reference is automatically obtained or released too. + */ + +/* + * Initialise a engine type for use (or up its reference count if it's + * already in use). This will fail if the engine is not currently operational + * and cannot initialise. + */ +int ENGINE_init(ENGINE *e); +/* + * Free a functional reference to a engine type. This does not require a + * corresponding call to ENGINE_free as it also releases a structural + * reference. + */ +int ENGINE_finish(ENGINE *e); + +/* + * The following functions handle keys that are stored in some secondary + * location, handled by the engine. The storage may be on a card or + * whatever. + */ +EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id, + UI_METHOD *ui_method, void *callback_data); +EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id, + UI_METHOD *ui_method, void *callback_data); +int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s, + STACK_OF(X509_NAME) *ca_dn, X509 **pcert, + EVP_PKEY **ppkey, STACK_OF(X509) **pother, + UI_METHOD *ui_method, void *callback_data); + +/* + * This returns a pointer for the current ENGINE structure that is (by + * default) performing any RSA operations. The value returned is an + * incremented reference, so it should be free'd (ENGINE_finish) before it is + * discarded. + */ +ENGINE *ENGINE_get_default_RSA(void); +/* Same for the other "methods" */ +ENGINE *ENGINE_get_default_DSA(void); +ENGINE *ENGINE_get_default_ECDH(void); +ENGINE *ENGINE_get_default_ECDSA(void); +ENGINE *ENGINE_get_default_DH(void); +ENGINE *ENGINE_get_default_RAND(void); +/* + * These functions can be used to get a functional reference to perform + * ciphering or digesting corresponding to "nid". + */ +ENGINE *ENGINE_get_cipher_engine(int nid); +ENGINE *ENGINE_get_digest_engine(int nid); +ENGINE *ENGINE_get_pkey_meth_engine(int nid); +ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid); + +/* + * This sets a new default ENGINE structure for performing RSA operations. If + * the result is non-zero (success) then the ENGINE structure will have had + * its reference count up'd so the caller should still free their own + * reference 'e'. + */ +int ENGINE_set_default_RSA(ENGINE *e); +int ENGINE_set_default_string(ENGINE *e, const char *def_list); +/* Same for the other "methods" */ +int ENGINE_set_default_DSA(ENGINE *e); +int ENGINE_set_default_ECDH(ENGINE *e); +int ENGINE_set_default_ECDSA(ENGINE *e); +int ENGINE_set_default_DH(ENGINE *e); +int ENGINE_set_default_RAND(ENGINE *e); +int ENGINE_set_default_ciphers(ENGINE *e); +int ENGINE_set_default_digests(ENGINE *e); +int ENGINE_set_default_pkey_meths(ENGINE *e); +int ENGINE_set_default_pkey_asn1_meths(ENGINE *e); + +/* + * The combination "set" - the flags are bitwise "OR"d from the + * ENGINE_METHOD_*** defines above. As with the "ENGINE_register_complete()" + * function, this function can result in unnecessary static linkage. If your + * application requires only specific functionality, consider using more + * selective functions. + */ +int ENGINE_set_default(ENGINE *e, unsigned int flags); + +void ENGINE_add_conf_module(void); + +/* Deprecated functions ... */ +/* int ENGINE_clear_defaults(void); */ + +/**************************/ +/* DYNAMIC ENGINE SUPPORT */ +/**************************/ + +/* Binary/behaviour compatibility levels */ +# define OSSL_DYNAMIC_VERSION (unsigned long)0x00020000 +/* + * Binary versions older than this are too old for us (whether we're a loader + * or a loadee) + */ +# define OSSL_DYNAMIC_OLDEST (unsigned long)0x00020000 + +/* + * When compiling an ENGINE entirely as an external shared library, loadable + * by the "dynamic" ENGINE, these types are needed. The 'dynamic_fns' + * structure type provides the calling application's (or library's) error + * functionality and memory management function pointers to the loaded + * library. These should be used/set in the loaded library code so that the + * loading application's 'state' will be used/changed in all operations. The + * 'static_state' pointer allows the loaded library to know if it shares the + * same static data as the calling application (or library), and thus whether + * these callbacks need to be set or not. + */ +typedef void *(*dyn_MEM_malloc_cb) (size_t); +typedef void *(*dyn_MEM_realloc_cb) (void *, size_t); +typedef void (*dyn_MEM_free_cb) (void *); +typedef struct st_dynamic_MEM_fns { + dyn_MEM_malloc_cb malloc_cb; + dyn_MEM_realloc_cb realloc_cb; + dyn_MEM_free_cb free_cb; +} dynamic_MEM_fns; +/* + * FIXME: Perhaps the memory and locking code (crypto.h) should declare and + * use these types so we (and any other dependant code) can simplify a bit?? + */ +typedef void (*dyn_lock_locking_cb) (int, int, const char *, int); +typedef int (*dyn_lock_add_lock_cb) (int *, int, int, const char *, int); +typedef struct CRYPTO_dynlock_value *(*dyn_dynlock_create_cb) (const char *, + int); +typedef void (*dyn_dynlock_lock_cb) (int, struct CRYPTO_dynlock_value *, + const char *, int); +typedef void (*dyn_dynlock_destroy_cb) (struct CRYPTO_dynlock_value *, + const char *, int); +typedef struct st_dynamic_LOCK_fns { + dyn_lock_locking_cb lock_locking_cb; + dyn_lock_add_lock_cb lock_add_lock_cb; + dyn_dynlock_create_cb dynlock_create_cb; + dyn_dynlock_lock_cb dynlock_lock_cb; + dyn_dynlock_destroy_cb dynlock_destroy_cb; +} dynamic_LOCK_fns; +/* The top-level structure */ +typedef struct st_dynamic_fns { + void *static_state; + const ERR_FNS *err_fns; + const CRYPTO_EX_DATA_IMPL *ex_data_fns; + dynamic_MEM_fns mem_fns; + dynamic_LOCK_fns lock_fns; +} dynamic_fns; + +/* + * The version checking function should be of this prototype. NB: The + * ossl_version value passed in is the OSSL_DYNAMIC_VERSION of the loading + * code. If this function returns zero, it indicates a (potential) version + * incompatibility and the loaded library doesn't believe it can proceed. + * Otherwise, the returned value is the (latest) version supported by the + * loading library. The loader may still decide that the loaded code's + * version is unsatisfactory and could veto the load. The function is + * expected to be implemented with the symbol name "v_check", and a default + * implementation can be fully instantiated with + * IMPLEMENT_DYNAMIC_CHECK_FN(). + */ +typedef unsigned long (*dynamic_v_check_fn) (unsigned long ossl_version); +# define IMPLEMENT_DYNAMIC_CHECK_FN() \ + OPENSSL_EXPORT unsigned long v_check(unsigned long v); \ + OPENSSL_EXPORT unsigned long v_check(unsigned long v) { \ + if(v >= OSSL_DYNAMIC_OLDEST) return OSSL_DYNAMIC_VERSION; \ + return 0; } + +/* + * This function is passed the ENGINE structure to initialise with its own + * function and command settings. It should not adjust the structural or + * functional reference counts. If this function returns zero, (a) the load + * will be aborted, (b) the previous ENGINE state will be memcpy'd back onto + * the structure, and (c) the shared library will be unloaded. So + * implementations should do their own internal cleanup in failure + * circumstances otherwise they could leak. The 'id' parameter, if non-NULL, + * represents the ENGINE id that the loader is looking for. If this is NULL, + * the shared library can choose to return failure or to initialise a + * 'default' ENGINE. If non-NULL, the shared library must initialise only an + * ENGINE matching the passed 'id'. The function is expected to be + * implemented with the symbol name "bind_engine". A standard implementation + * can be instantiated with IMPLEMENT_DYNAMIC_BIND_FN(fn) where the parameter + * 'fn' is a callback function that populates the ENGINE structure and + * returns an int value (zero for failure). 'fn' should have prototype; + * [static] int fn(ENGINE *e, const char *id); + */ +typedef int (*dynamic_bind_engine) (ENGINE *e, const char *id, + const dynamic_fns *fns); +# define IMPLEMENT_DYNAMIC_BIND_FN(fn) \ + OPENSSL_EXPORT \ + int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns); \ + OPENSSL_EXPORT \ + int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { \ + if(ENGINE_get_static_state() == fns->static_state) goto skip_cbs; \ + if(!CRYPTO_set_mem_functions(fns->mem_fns.malloc_cb, \ + fns->mem_fns.realloc_cb, fns->mem_fns.free_cb)) \ + return 0; \ + CRYPTO_set_locking_callback(fns->lock_fns.lock_locking_cb); \ + CRYPTO_set_add_lock_callback(fns->lock_fns.lock_add_lock_cb); \ + CRYPTO_set_dynlock_create_callback(fns->lock_fns.dynlock_create_cb); \ + CRYPTO_set_dynlock_lock_callback(fns->lock_fns.dynlock_lock_cb); \ + CRYPTO_set_dynlock_destroy_callback(fns->lock_fns.dynlock_destroy_cb); \ + if(!CRYPTO_set_ex_data_implementation(fns->ex_data_fns)) \ + return 0; \ + if(!ERR_set_implementation(fns->err_fns)) return 0; \ + skip_cbs: \ + if(!fn(e,id)) return 0; \ + return 1; } + +/* + * If the loading application (or library) and the loaded ENGINE library + * share the same static data (eg. they're both dynamically linked to the + * same libcrypto.so) we need a way to avoid trying to set system callbacks - + * this would fail, and for the same reason that it's unnecessary to try. If + * the loaded ENGINE has (or gets from through the loader) its own copy of + * the libcrypto static data, we will need to set the callbacks. The easiest + * way to detect this is to have a function that returns a pointer to some + * static data and let the loading application and loaded ENGINE compare + * their respective values. + */ +void *ENGINE_get_static_state(void); + +# if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV) +void ENGINE_setup_bsd_cryptodev(void); +# endif + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_ENGINE_strings(void); + +/* Error codes for the ENGINE functions. */ + +/* Function codes. */ +# define ENGINE_F_DYNAMIC_CTRL 180 +# define ENGINE_F_DYNAMIC_GET_DATA_CTX 181 +# define ENGINE_F_DYNAMIC_LOAD 182 +# define ENGINE_F_DYNAMIC_SET_DATA_CTX 183 +# define ENGINE_F_ENGINE_ADD 105 +# define ENGINE_F_ENGINE_BY_ID 106 +# define ENGINE_F_ENGINE_CMD_IS_EXECUTABLE 170 +# define ENGINE_F_ENGINE_CTRL 142 +# define ENGINE_F_ENGINE_CTRL_CMD 178 +# define ENGINE_F_ENGINE_CTRL_CMD_STRING 171 +# define ENGINE_F_ENGINE_FINISH 107 +# define ENGINE_F_ENGINE_FREE_UTIL 108 +# define ENGINE_F_ENGINE_GET_CIPHER 185 +# define ENGINE_F_ENGINE_GET_DEFAULT_TYPE 177 +# define ENGINE_F_ENGINE_GET_DIGEST 186 +# define ENGINE_F_ENGINE_GET_NEXT 115 +# define ENGINE_F_ENGINE_GET_PKEY_ASN1_METH 193 +# define ENGINE_F_ENGINE_GET_PKEY_METH 192 +# define ENGINE_F_ENGINE_GET_PREV 116 +# define ENGINE_F_ENGINE_INIT 119 +# define ENGINE_F_ENGINE_LIST_ADD 120 +# define ENGINE_F_ENGINE_LIST_REMOVE 121 +# define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY 150 +# define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY 151 +# define ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT 194 +# define ENGINE_F_ENGINE_NEW 122 +# define ENGINE_F_ENGINE_REMOVE 123 +# define ENGINE_F_ENGINE_SET_DEFAULT_STRING 189 +# define ENGINE_F_ENGINE_SET_DEFAULT_TYPE 126 +# define ENGINE_F_ENGINE_SET_ID 129 +# define ENGINE_F_ENGINE_SET_NAME 130 +# define ENGINE_F_ENGINE_TABLE_REGISTER 184 +# define ENGINE_F_ENGINE_UNLOAD_KEY 152 +# define ENGINE_F_ENGINE_UNLOCKED_FINISH 191 +# define ENGINE_F_ENGINE_UP_REF 190 +# define ENGINE_F_INT_CTRL_HELPER 172 +# define ENGINE_F_INT_ENGINE_CONFIGURE 188 +# define ENGINE_F_INT_ENGINE_MODULE_INIT 187 +# define ENGINE_F_LOG_MESSAGE 141 + +/* Reason codes. */ +# define ENGINE_R_ALREADY_LOADED 100 +# define ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER 133 +# define ENGINE_R_CMD_NOT_EXECUTABLE 134 +# define ENGINE_R_COMMAND_TAKES_INPUT 135 +# define ENGINE_R_COMMAND_TAKES_NO_INPUT 136 +# define ENGINE_R_CONFLICTING_ENGINE_ID 103 +# define ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED 119 +# define ENGINE_R_DH_NOT_IMPLEMENTED 139 +# define ENGINE_R_DSA_NOT_IMPLEMENTED 140 +# define ENGINE_R_DSO_FAILURE 104 +# define ENGINE_R_DSO_NOT_FOUND 132 +# define ENGINE_R_ENGINES_SECTION_ERROR 148 +# define ENGINE_R_ENGINE_CONFIGURATION_ERROR 102 +# define ENGINE_R_ENGINE_IS_NOT_IN_LIST 105 +# define ENGINE_R_ENGINE_SECTION_ERROR 149 +# define ENGINE_R_FAILED_LOADING_PRIVATE_KEY 128 +# define ENGINE_R_FAILED_LOADING_PUBLIC_KEY 129 +# define ENGINE_R_FINISH_FAILED 106 +# define ENGINE_R_GET_HANDLE_FAILED 107 +# define ENGINE_R_ID_OR_NAME_MISSING 108 +# define ENGINE_R_INIT_FAILED 109 +# define ENGINE_R_INTERNAL_LIST_ERROR 110 +# define ENGINE_R_INVALID_ARGUMENT 143 +# define ENGINE_R_INVALID_CMD_NAME 137 +# define ENGINE_R_INVALID_CMD_NUMBER 138 +# define ENGINE_R_INVALID_INIT_VALUE 151 +# define ENGINE_R_INVALID_STRING 150 +# define ENGINE_R_NOT_INITIALISED 117 +# define ENGINE_R_NOT_LOADED 112 +# define ENGINE_R_NO_CONTROL_FUNCTION 120 +# define ENGINE_R_NO_INDEX 144 +# define ENGINE_R_NO_LOAD_FUNCTION 125 +# define ENGINE_R_NO_REFERENCE 130 +# define ENGINE_R_NO_SUCH_ENGINE 116 +# define ENGINE_R_NO_UNLOAD_FUNCTION 126 +# define ENGINE_R_PROVIDE_PARAMETERS 113 +# define ENGINE_R_RSA_NOT_IMPLEMENTED 141 +# define ENGINE_R_UNIMPLEMENTED_CIPHER 146 +# define ENGINE_R_UNIMPLEMENTED_DIGEST 147 +# define ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD 101 +# define ENGINE_R_VERSION_INCOMPATIBILITY 145 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/err.h b/OSlibs/ios/include/openssl/err.h new file mode 100755 index 000000000..585aa8ba3 --- /dev/null +++ b/OSlibs/ios/include/openssl/err.h @@ -0,0 +1,389 @@ +/* crypto/err/err.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_ERR_H +# define HEADER_ERR_H + +# include + +# ifndef OPENSSL_NO_FP_API +# include +# include +# endif + +# include +# ifndef OPENSSL_NO_BIO +# include +# endif +# ifndef OPENSSL_NO_LHASH +# include +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +# ifndef OPENSSL_NO_ERR +# define ERR_PUT_error(a,b,c,d,e) ERR_put_error(a,b,c,d,e) +# else +# define ERR_PUT_error(a,b,c,d,e) ERR_put_error(a,b,c,NULL,0) +# endif + +# include + +# define ERR_TXT_MALLOCED 0x01 +# define ERR_TXT_STRING 0x02 + +# define ERR_FLAG_MARK 0x01 + +# define ERR_NUM_ERRORS 16 +typedef struct err_state_st { + CRYPTO_THREADID tid; + int err_flags[ERR_NUM_ERRORS]; + unsigned long err_buffer[ERR_NUM_ERRORS]; + char *err_data[ERR_NUM_ERRORS]; + int err_data_flags[ERR_NUM_ERRORS]; + const char *err_file[ERR_NUM_ERRORS]; + int err_line[ERR_NUM_ERRORS]; + int top, bottom; +} ERR_STATE; + +/* library */ +# define ERR_LIB_NONE 1 +# define ERR_LIB_SYS 2 +# define ERR_LIB_BN 3 +# define ERR_LIB_RSA 4 +# define ERR_LIB_DH 5 +# define ERR_LIB_EVP 6 +# define ERR_LIB_BUF 7 +# define ERR_LIB_OBJ 8 +# define ERR_LIB_PEM 9 +# define ERR_LIB_DSA 10 +# define ERR_LIB_X509 11 +/* #define ERR_LIB_METH 12 */ +# define ERR_LIB_ASN1 13 +# define ERR_LIB_CONF 14 +# define ERR_LIB_CRYPTO 15 +# define ERR_LIB_EC 16 +# define ERR_LIB_SSL 20 +/* #define ERR_LIB_SSL23 21 */ +/* #define ERR_LIB_SSL2 22 */ +/* #define ERR_LIB_SSL3 23 */ +/* #define ERR_LIB_RSAREF 30 */ +/* #define ERR_LIB_PROXY 31 */ +# define ERR_LIB_BIO 32 +# define ERR_LIB_PKCS7 33 +# define ERR_LIB_X509V3 34 +# define ERR_LIB_PKCS12 35 +# define ERR_LIB_RAND 36 +# define ERR_LIB_DSO 37 +# define ERR_LIB_ENGINE 38 +# define ERR_LIB_OCSP 39 +# define ERR_LIB_UI 40 +# define ERR_LIB_COMP 41 +# define ERR_LIB_ECDSA 42 +# define ERR_LIB_ECDH 43 +# define ERR_LIB_STORE 44 +# define ERR_LIB_FIPS 45 +# define ERR_LIB_CMS 46 +# define ERR_LIB_TS 47 +# define ERR_LIB_HMAC 48 +# define ERR_LIB_JPAKE 49 + +# define ERR_LIB_USER 128 + +# define SYSerr(f,r) ERR_PUT_error(ERR_LIB_SYS,(f),(r),__FILE__,__LINE__) +# define BNerr(f,r) ERR_PUT_error(ERR_LIB_BN,(f),(r),__FILE__,__LINE__) +# define RSAerr(f,r) ERR_PUT_error(ERR_LIB_RSA,(f),(r),__FILE__,__LINE__) +# define DHerr(f,r) ERR_PUT_error(ERR_LIB_DH,(f),(r),__FILE__,__LINE__) +# define EVPerr(f,r) ERR_PUT_error(ERR_LIB_EVP,(f),(r),__FILE__,__LINE__) +# define BUFerr(f,r) ERR_PUT_error(ERR_LIB_BUF,(f),(r),__FILE__,__LINE__) +# define OBJerr(f,r) ERR_PUT_error(ERR_LIB_OBJ,(f),(r),__FILE__,__LINE__) +# define PEMerr(f,r) ERR_PUT_error(ERR_LIB_PEM,(f),(r),__FILE__,__LINE__) +# define DSAerr(f,r) ERR_PUT_error(ERR_LIB_DSA,(f),(r),__FILE__,__LINE__) +# define X509err(f,r) ERR_PUT_error(ERR_LIB_X509,(f),(r),__FILE__,__LINE__) +# define ASN1err(f,r) ERR_PUT_error(ERR_LIB_ASN1,(f),(r),__FILE__,__LINE__) +# define CONFerr(f,r) ERR_PUT_error(ERR_LIB_CONF,(f),(r),__FILE__,__LINE__) +# define CRYPTOerr(f,r) ERR_PUT_error(ERR_LIB_CRYPTO,(f),(r),__FILE__,__LINE__) +# define ECerr(f,r) ERR_PUT_error(ERR_LIB_EC,(f),(r),__FILE__,__LINE__) +# define SSLerr(f,r) ERR_PUT_error(ERR_LIB_SSL,(f),(r),__FILE__,__LINE__) +# define BIOerr(f,r) ERR_PUT_error(ERR_LIB_BIO,(f),(r),__FILE__,__LINE__) +# define PKCS7err(f,r) ERR_PUT_error(ERR_LIB_PKCS7,(f),(r),__FILE__,__LINE__) +# define X509V3err(f,r) ERR_PUT_error(ERR_LIB_X509V3,(f),(r),__FILE__,__LINE__) +# define PKCS12err(f,r) ERR_PUT_error(ERR_LIB_PKCS12,(f),(r),__FILE__,__LINE__) +# define RANDerr(f,r) ERR_PUT_error(ERR_LIB_RAND,(f),(r),__FILE__,__LINE__) +# define DSOerr(f,r) ERR_PUT_error(ERR_LIB_DSO,(f),(r),__FILE__,__LINE__) +# define ENGINEerr(f,r) ERR_PUT_error(ERR_LIB_ENGINE,(f),(r),__FILE__,__LINE__) +# define OCSPerr(f,r) ERR_PUT_error(ERR_LIB_OCSP,(f),(r),__FILE__,__LINE__) +# define UIerr(f,r) ERR_PUT_error(ERR_LIB_UI,(f),(r),__FILE__,__LINE__) +# define COMPerr(f,r) ERR_PUT_error(ERR_LIB_COMP,(f),(r),__FILE__,__LINE__) +# define ECDSAerr(f,r) ERR_PUT_error(ERR_LIB_ECDSA,(f),(r),__FILE__,__LINE__) +# define ECDHerr(f,r) ERR_PUT_error(ERR_LIB_ECDH,(f),(r),__FILE__,__LINE__) +# define STOREerr(f,r) ERR_PUT_error(ERR_LIB_STORE,(f),(r),__FILE__,__LINE__) +# define FIPSerr(f,r) ERR_PUT_error(ERR_LIB_FIPS,(f),(r),__FILE__,__LINE__) +# define CMSerr(f,r) ERR_PUT_error(ERR_LIB_CMS,(f),(r),__FILE__,__LINE__) +# define TSerr(f,r) ERR_PUT_error(ERR_LIB_TS,(f),(r),__FILE__,__LINE__) +# define HMACerr(f,r) ERR_PUT_error(ERR_LIB_HMAC,(f),(r),__FILE__,__LINE__) +# define JPAKEerr(f,r) ERR_PUT_error(ERR_LIB_JPAKE,(f),(r),__FILE__,__LINE__) + +/* + * Borland C seems too stupid to be able to shift and do longs in the + * pre-processor :-( + */ +# define ERR_PACK(l,f,r) (((((unsigned long)l)&0xffL)*0x1000000)| \ + ((((unsigned long)f)&0xfffL)*0x1000)| \ + ((((unsigned long)r)&0xfffL))) +# define ERR_GET_LIB(l) (int)((((unsigned long)l)>>24L)&0xffL) +# define ERR_GET_FUNC(l) (int)((((unsigned long)l)>>12L)&0xfffL) +# define ERR_GET_REASON(l) (int)((l)&0xfffL) +# define ERR_FATAL_ERROR(l) (int)((l)&ERR_R_FATAL) + +/* OS functions */ +# define SYS_F_FOPEN 1 +# define SYS_F_CONNECT 2 +# define SYS_F_GETSERVBYNAME 3 +# define SYS_F_SOCKET 4 +# define SYS_F_IOCTLSOCKET 5 +# define SYS_F_BIND 6 +# define SYS_F_LISTEN 7 +# define SYS_F_ACCEPT 8 +# define SYS_F_WSASTARTUP 9/* Winsock stuff */ +# define SYS_F_OPENDIR 10 +# define SYS_F_FREAD 11 + +/* reasons */ +# define ERR_R_SYS_LIB ERR_LIB_SYS/* 2 */ +# define ERR_R_BN_LIB ERR_LIB_BN/* 3 */ +# define ERR_R_RSA_LIB ERR_LIB_RSA/* 4 */ +# define ERR_R_DH_LIB ERR_LIB_DH/* 5 */ +# define ERR_R_EVP_LIB ERR_LIB_EVP/* 6 */ +# define ERR_R_BUF_LIB ERR_LIB_BUF/* 7 */ +# define ERR_R_OBJ_LIB ERR_LIB_OBJ/* 8 */ +# define ERR_R_PEM_LIB ERR_LIB_PEM/* 9 */ +# define ERR_R_DSA_LIB ERR_LIB_DSA/* 10 */ +# define ERR_R_X509_LIB ERR_LIB_X509/* 11 */ +# define ERR_R_ASN1_LIB ERR_LIB_ASN1/* 13 */ +# define ERR_R_CONF_LIB ERR_LIB_CONF/* 14 */ +# define ERR_R_CRYPTO_LIB ERR_LIB_CRYPTO/* 15 */ +# define ERR_R_EC_LIB ERR_LIB_EC/* 16 */ +# define ERR_R_SSL_LIB ERR_LIB_SSL/* 20 */ +# define ERR_R_BIO_LIB ERR_LIB_BIO/* 32 */ +# define ERR_R_PKCS7_LIB ERR_LIB_PKCS7/* 33 */ +# define ERR_R_X509V3_LIB ERR_LIB_X509V3/* 34 */ +# define ERR_R_PKCS12_LIB ERR_LIB_PKCS12/* 35 */ +# define ERR_R_RAND_LIB ERR_LIB_RAND/* 36 */ +# define ERR_R_DSO_LIB ERR_LIB_DSO/* 37 */ +# define ERR_R_ENGINE_LIB ERR_LIB_ENGINE/* 38 */ +# define ERR_R_OCSP_LIB ERR_LIB_OCSP/* 39 */ +# define ERR_R_UI_LIB ERR_LIB_UI/* 40 */ +# define ERR_R_COMP_LIB ERR_LIB_COMP/* 41 */ +# define ERR_R_ECDSA_LIB ERR_LIB_ECDSA/* 42 */ +# define ERR_R_ECDH_LIB ERR_LIB_ECDH/* 43 */ +# define ERR_R_STORE_LIB ERR_LIB_STORE/* 44 */ +# define ERR_R_TS_LIB ERR_LIB_TS/* 45 */ + +# define ERR_R_NESTED_ASN1_ERROR 58 +# define ERR_R_BAD_ASN1_OBJECT_HEADER 59 +# define ERR_R_BAD_GET_ASN1_OBJECT_CALL 60 +# define ERR_R_EXPECTING_AN_ASN1_SEQUENCE 61 +# define ERR_R_ASN1_LENGTH_MISMATCH 62 +# define ERR_R_MISSING_ASN1_EOS 63 + +/* fatal error */ +# define ERR_R_FATAL 64 +# define ERR_R_MALLOC_FAILURE (1|ERR_R_FATAL) +# define ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED (2|ERR_R_FATAL) +# define ERR_R_PASSED_NULL_PARAMETER (3|ERR_R_FATAL) +# define ERR_R_INTERNAL_ERROR (4|ERR_R_FATAL) +# define ERR_R_DISABLED (5|ERR_R_FATAL) + +/* + * 99 is the maximum possible ERR_R_... code, higher values are reserved for + * the individual libraries + */ + +typedef struct ERR_string_data_st { + unsigned long error; + const char *string; +} ERR_STRING_DATA; + +void ERR_put_error(int lib, int func, int reason, const char *file, int line); +void ERR_set_error_data(char *data, int flags); + +unsigned long ERR_get_error(void); +unsigned long ERR_get_error_line(const char **file, int *line); +unsigned long ERR_get_error_line_data(const char **file, int *line, + const char **data, int *flags); +unsigned long ERR_peek_error(void); +unsigned long ERR_peek_error_line(const char **file, int *line); +unsigned long ERR_peek_error_line_data(const char **file, int *line, + const char **data, int *flags); +unsigned long ERR_peek_last_error(void); +unsigned long ERR_peek_last_error_line(const char **file, int *line); +unsigned long ERR_peek_last_error_line_data(const char **file, int *line, + const char **data, int *flags); +void ERR_clear_error(void); +char *ERR_error_string(unsigned long e, char *buf); +void ERR_error_string_n(unsigned long e, char *buf, size_t len); +const char *ERR_lib_error_string(unsigned long e); +const char *ERR_func_error_string(unsigned long e); +const char *ERR_reason_error_string(unsigned long e); +void ERR_print_errors_cb(int (*cb) (const char *str, size_t len, void *u), + void *u); +# ifndef OPENSSL_NO_FP_API +void ERR_print_errors_fp(FILE *fp); +# endif +# ifndef OPENSSL_NO_BIO +void ERR_print_errors(BIO *bp); +# endif +void ERR_add_error_data(int num, ...); +void ERR_add_error_vdata(int num, va_list args); +void ERR_load_strings(int lib, ERR_STRING_DATA str[]); +void ERR_unload_strings(int lib, ERR_STRING_DATA str[]); +void ERR_load_ERR_strings(void); +void ERR_load_crypto_strings(void); +void ERR_free_strings(void); + +void ERR_remove_thread_state(const CRYPTO_THREADID *tid); +# ifndef OPENSSL_NO_DEPRECATED +void ERR_remove_state(unsigned long pid); /* if zero we look it up */ +# endif +ERR_STATE *ERR_get_state(void); + +# ifndef OPENSSL_NO_LHASH +LHASH_OF(ERR_STRING_DATA) *ERR_get_string_table(void); +LHASH_OF(ERR_STATE) *ERR_get_err_state_table(void); +void ERR_release_err_state_table(LHASH_OF(ERR_STATE) **hash); +# endif + +int ERR_get_next_error_library(void); + +int ERR_set_mark(void); +int ERR_pop_to_mark(void); + +/* Already defined in ossl_typ.h */ +/* typedef struct st_ERR_FNS ERR_FNS; */ +/* + * An application can use this function and provide the return value to + * loaded modules that should use the application's ERR state/functionality + */ +const ERR_FNS *ERR_get_implementation(void); +/* + * A loaded module should call this function prior to any ERR operations + * using the application's "ERR_FNS". + */ +int ERR_set_implementation(const ERR_FNS *fns); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/OSlibs/ios/include/openssl/evp.h b/OSlibs/ios/include/openssl/evp.h new file mode 100755 index 000000000..39ab7937d --- /dev/null +++ b/OSlibs/ios/include/openssl/evp.h @@ -0,0 +1,1534 @@ +/* crypto/evp/evp.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_ENVELOPE_H +# define HEADER_ENVELOPE_H + +# ifdef OPENSSL_ALGORITHM_DEFINES +# include +# else +# define OPENSSL_ALGORITHM_DEFINES +# include +# undef OPENSSL_ALGORITHM_DEFINES +# endif + +# include + +# include + +# ifndef OPENSSL_NO_BIO +# include +# endif + +/*- +#define EVP_RC2_KEY_SIZE 16 +#define EVP_RC4_KEY_SIZE 16 +#define EVP_BLOWFISH_KEY_SIZE 16 +#define EVP_CAST5_KEY_SIZE 16 +#define EVP_RC5_32_12_16_KEY_SIZE 16 +*/ +# define EVP_MAX_MD_SIZE 64/* longest known is SHA512 */ +# define EVP_MAX_KEY_LENGTH 64 +# define EVP_MAX_IV_LENGTH 16 +# define EVP_MAX_BLOCK_LENGTH 32 + +# define PKCS5_SALT_LEN 8 +/* Default PKCS#5 iteration count */ +# define PKCS5_DEFAULT_ITER 2048 + +# include + +# define EVP_PK_RSA 0x0001 +# define EVP_PK_DSA 0x0002 +# define EVP_PK_DH 0x0004 +# define EVP_PK_EC 0x0008 +# define EVP_PKT_SIGN 0x0010 +# define EVP_PKT_ENC 0x0020 +# define EVP_PKT_EXCH 0x0040 +# define EVP_PKS_RSA 0x0100 +# define EVP_PKS_DSA 0x0200 +# define EVP_PKS_EC 0x0400 + +# define EVP_PKEY_NONE NID_undef +# define EVP_PKEY_RSA NID_rsaEncryption +# define EVP_PKEY_RSA2 NID_rsa +# define EVP_PKEY_DSA NID_dsa +# define EVP_PKEY_DSA1 NID_dsa_2 +# define EVP_PKEY_DSA2 NID_dsaWithSHA +# define EVP_PKEY_DSA3 NID_dsaWithSHA1 +# define EVP_PKEY_DSA4 NID_dsaWithSHA1_2 +# define EVP_PKEY_DH NID_dhKeyAgreement +# define EVP_PKEY_DHX NID_dhpublicnumber +# define EVP_PKEY_EC NID_X9_62_id_ecPublicKey +# define EVP_PKEY_HMAC NID_hmac +# define EVP_PKEY_CMAC NID_cmac + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Type needs to be a bit field Sub-type needs to be for variations on the + * method, as in, can it do arbitrary encryption.... + */ +struct evp_pkey_st { + int type; + int save_type; + int references; + const EVP_PKEY_ASN1_METHOD *ameth; + ENGINE *engine; + union { + char *ptr; +# ifndef OPENSSL_NO_RSA + struct rsa_st *rsa; /* RSA */ +# endif +# ifndef OPENSSL_NO_DSA + struct dsa_st *dsa; /* DSA */ +# endif +# ifndef OPENSSL_NO_DH + struct dh_st *dh; /* DH */ +# endif +# ifndef OPENSSL_NO_EC + struct ec_key_st *ec; /* ECC */ +# endif + } pkey; + int save_parameters; + STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */ +} /* EVP_PKEY */ ; + +# define EVP_PKEY_MO_SIGN 0x0001 +# define EVP_PKEY_MO_VERIFY 0x0002 +# define EVP_PKEY_MO_ENCRYPT 0x0004 +# define EVP_PKEY_MO_DECRYPT 0x0008 + +# ifndef EVP_MD +struct env_md_st { + int type; + int pkey_type; + int md_size; + unsigned long flags; + int (*init) (EVP_MD_CTX *ctx); + int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count); + int (*final) (EVP_MD_CTX *ctx, unsigned char *md); + int (*copy) (EVP_MD_CTX *to, const EVP_MD_CTX *from); + int (*cleanup) (EVP_MD_CTX *ctx); + /* FIXME: prototype these some day */ + int (*sign) (int type, const unsigned char *m, unsigned int m_length, + unsigned char *sigret, unsigned int *siglen, void *key); + int (*verify) (int type, const unsigned char *m, unsigned int m_length, + const unsigned char *sigbuf, unsigned int siglen, + void *key); + int required_pkey_type[5]; /* EVP_PKEY_xxx */ + int block_size; + int ctx_size; /* how big does the ctx->md_data need to be */ + /* control function */ + int (*md_ctrl) (EVP_MD_CTX *ctx, int cmd, int p1, void *p2); +} /* EVP_MD */ ; + +typedef int evp_sign_method(int type, const unsigned char *m, + unsigned int m_length, unsigned char *sigret, + unsigned int *siglen, void *key); +typedef int evp_verify_method(int type, const unsigned char *m, + unsigned int m_length, + const unsigned char *sigbuf, + unsigned int siglen, void *key); + +/* digest can only handle a single block */ +# define EVP_MD_FLAG_ONESHOT 0x0001 + +/* + * digest is a "clone" digest used + * which is a copy of an existing + * one for a specific public key type. + * EVP_dss1() etc + */ +# define EVP_MD_FLAG_PKEY_DIGEST 0x0002 + +/* Digest uses EVP_PKEY_METHOD for signing instead of MD specific signing */ + +# define EVP_MD_FLAG_PKEY_METHOD_SIGNATURE 0x0004 + +/* DigestAlgorithmIdentifier flags... */ + +# define EVP_MD_FLAG_DIGALGID_MASK 0x0018 + +/* NULL or absent parameter accepted. Use NULL */ + +# define EVP_MD_FLAG_DIGALGID_NULL 0x0000 + +/* NULL or absent parameter accepted. Use NULL for PKCS#1 otherwise absent */ + +# define EVP_MD_FLAG_DIGALGID_ABSENT 0x0008 + +/* Custom handling via ctrl */ + +# define EVP_MD_FLAG_DIGALGID_CUSTOM 0x0018 + +/* Note if suitable for use in FIPS mode */ +# define EVP_MD_FLAG_FIPS 0x0400 + +/* Digest ctrls */ + +# define EVP_MD_CTRL_DIGALGID 0x1 +# define EVP_MD_CTRL_MICALG 0x2 + +/* Minimum Algorithm specific ctrl value */ + +# define EVP_MD_CTRL_ALG_CTRL 0x1000 + +# define EVP_PKEY_NULL_method NULL,NULL,{0,0,0,0} + +# ifndef OPENSSL_NO_DSA +# define EVP_PKEY_DSA_method (evp_sign_method *)DSA_sign, \ + (evp_verify_method *)DSA_verify, \ + {EVP_PKEY_DSA,EVP_PKEY_DSA2,EVP_PKEY_DSA3, \ + EVP_PKEY_DSA4,0} +# else +# define EVP_PKEY_DSA_method EVP_PKEY_NULL_method +# endif + +# ifndef OPENSSL_NO_ECDSA +# define EVP_PKEY_ECDSA_method (evp_sign_method *)ECDSA_sign, \ + (evp_verify_method *)ECDSA_verify, \ + {EVP_PKEY_EC,0,0,0} +# else +# define EVP_PKEY_ECDSA_method EVP_PKEY_NULL_method +# endif + +# ifndef OPENSSL_NO_RSA +# define EVP_PKEY_RSA_method (evp_sign_method *)RSA_sign, \ + (evp_verify_method *)RSA_verify, \ + {EVP_PKEY_RSA,EVP_PKEY_RSA2,0,0} +# define EVP_PKEY_RSA_ASN1_OCTET_STRING_method \ + (evp_sign_method *)RSA_sign_ASN1_OCTET_STRING, \ + (evp_verify_method *)RSA_verify_ASN1_OCTET_STRING, \ + {EVP_PKEY_RSA,EVP_PKEY_RSA2,0,0} +# else +# define EVP_PKEY_RSA_method EVP_PKEY_NULL_method +# define EVP_PKEY_RSA_ASN1_OCTET_STRING_method EVP_PKEY_NULL_method +# endif + +# endif /* !EVP_MD */ + +struct env_md_ctx_st { + const EVP_MD *digest; + ENGINE *engine; /* functional reference if 'digest' is + * ENGINE-provided */ + unsigned long flags; + void *md_data; + /* Public key context for sign/verify */ + EVP_PKEY_CTX *pctx; + /* Update function: usually copied from EVP_MD */ + int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count); +} /* EVP_MD_CTX */ ; + +/* values for EVP_MD_CTX flags */ + +# define EVP_MD_CTX_FLAG_ONESHOT 0x0001/* digest update will be + * called once only */ +# define EVP_MD_CTX_FLAG_CLEANED 0x0002/* context has already been + * cleaned */ +# define EVP_MD_CTX_FLAG_REUSE 0x0004/* Don't free up ctx->md_data + * in EVP_MD_CTX_cleanup */ +/* + * FIPS and pad options are ignored in 1.0.0, definitions are here so we + * don't accidentally reuse the values for other purposes. + */ + +# define EVP_MD_CTX_FLAG_NON_FIPS_ALLOW 0x0008/* Allow use of non FIPS + * digest in FIPS mode */ + +/* + * The following PAD options are also currently ignored in 1.0.0, digest + * parameters are handled through EVP_DigestSign*() and EVP_DigestVerify*() + * instead. + */ +# define EVP_MD_CTX_FLAG_PAD_MASK 0xF0/* RSA mode to use */ +# define EVP_MD_CTX_FLAG_PAD_PKCS1 0x00/* PKCS#1 v1.5 mode */ +# define EVP_MD_CTX_FLAG_PAD_X931 0x10/* X9.31 mode */ +# define EVP_MD_CTX_FLAG_PAD_PSS 0x20/* PSS mode */ + +# define EVP_MD_CTX_FLAG_NO_INIT 0x0100/* Don't initialize md_data */ + +struct evp_cipher_st { + int nid; + int block_size; + /* Default value for variable length ciphers */ + int key_len; + int iv_len; + /* Various flags */ + unsigned long flags; + /* init key */ + int (*init) (EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); + /* encrypt/decrypt data */ + int (*do_cipher) (EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl); + /* cleanup ctx */ + int (*cleanup) (EVP_CIPHER_CTX *); + /* how big ctx->cipher_data needs to be */ + int ctx_size; + /* Populate a ASN1_TYPE with parameters */ + int (*set_asn1_parameters) (EVP_CIPHER_CTX *, ASN1_TYPE *); + /* Get parameters from a ASN1_TYPE */ + int (*get_asn1_parameters) (EVP_CIPHER_CTX *, ASN1_TYPE *); + /* Miscellaneous operations */ + int (*ctrl) (EVP_CIPHER_CTX *, int type, int arg, void *ptr); + /* Application data */ + void *app_data; +} /* EVP_CIPHER */ ; + +/* Values for cipher flags */ + +/* Modes for ciphers */ + +# define EVP_CIPH_STREAM_CIPHER 0x0 +# define EVP_CIPH_ECB_MODE 0x1 +# define EVP_CIPH_CBC_MODE 0x2 +# define EVP_CIPH_CFB_MODE 0x3 +# define EVP_CIPH_OFB_MODE 0x4 +# define EVP_CIPH_CTR_MODE 0x5 +# define EVP_CIPH_GCM_MODE 0x6 +# define EVP_CIPH_CCM_MODE 0x7 +# define EVP_CIPH_XTS_MODE 0x10001 +# define EVP_CIPH_WRAP_MODE 0x10002 +# define EVP_CIPH_MODE 0xF0007 +/* Set if variable length cipher */ +# define EVP_CIPH_VARIABLE_LENGTH 0x8 +/* Set if the iv handling should be done by the cipher itself */ +# define EVP_CIPH_CUSTOM_IV 0x10 +/* Set if the cipher's init() function should be called if key is NULL */ +# define EVP_CIPH_ALWAYS_CALL_INIT 0x20 +/* Call ctrl() to init cipher parameters */ +# define EVP_CIPH_CTRL_INIT 0x40 +/* Don't use standard key length function */ +# define EVP_CIPH_CUSTOM_KEY_LENGTH 0x80 +/* Don't use standard block padding */ +# define EVP_CIPH_NO_PADDING 0x100 +/* cipher handles random key generation */ +# define EVP_CIPH_RAND_KEY 0x200 +/* cipher has its own additional copying logic */ +# define EVP_CIPH_CUSTOM_COPY 0x400 +/* Allow use default ASN1 get/set iv */ +# define EVP_CIPH_FLAG_DEFAULT_ASN1 0x1000 +/* Buffer length in bits not bytes: CFB1 mode only */ +# define EVP_CIPH_FLAG_LENGTH_BITS 0x2000 +/* Note if suitable for use in FIPS mode */ +# define EVP_CIPH_FLAG_FIPS 0x4000 +/* Allow non FIPS cipher in FIPS mode */ +# define EVP_CIPH_FLAG_NON_FIPS_ALLOW 0x8000 +/* + * Cipher handles any and all padding logic as well as finalisation. + */ +# define EVP_CIPH_FLAG_CUSTOM_CIPHER 0x100000 +# define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000 +# define EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK 0x400000 + +/* + * Cipher context flag to indicate we can handle wrap mode: if allowed in + * older applications it could overflow buffers. + */ + +# define EVP_CIPHER_CTX_FLAG_WRAP_ALLOW 0x1 + +/* ctrl() values */ + +# define EVP_CTRL_INIT 0x0 +# define EVP_CTRL_SET_KEY_LENGTH 0x1 +# define EVP_CTRL_GET_RC2_KEY_BITS 0x2 +# define EVP_CTRL_SET_RC2_KEY_BITS 0x3 +# define EVP_CTRL_GET_RC5_ROUNDS 0x4 +# define EVP_CTRL_SET_RC5_ROUNDS 0x5 +# define EVP_CTRL_RAND_KEY 0x6 +# define EVP_CTRL_PBE_PRF_NID 0x7 +# define EVP_CTRL_COPY 0x8 +# define EVP_CTRL_GCM_SET_IVLEN 0x9 +# define EVP_CTRL_GCM_GET_TAG 0x10 +# define EVP_CTRL_GCM_SET_TAG 0x11 +# define EVP_CTRL_GCM_SET_IV_FIXED 0x12 +# define EVP_CTRL_GCM_IV_GEN 0x13 +# define EVP_CTRL_CCM_SET_IVLEN EVP_CTRL_GCM_SET_IVLEN +# define EVP_CTRL_CCM_GET_TAG EVP_CTRL_GCM_GET_TAG +# define EVP_CTRL_CCM_SET_TAG EVP_CTRL_GCM_SET_TAG +# define EVP_CTRL_CCM_SET_L 0x14 +# define EVP_CTRL_CCM_SET_MSGLEN 0x15 +/* + * AEAD cipher deduces payload length and returns number of bytes required to + * store MAC and eventual padding. Subsequent call to EVP_Cipher even + * appends/verifies MAC. + */ +# define EVP_CTRL_AEAD_TLS1_AAD 0x16 +/* Used by composite AEAD ciphers, no-op in GCM, CCM... */ +# define EVP_CTRL_AEAD_SET_MAC_KEY 0x17 +/* Set the GCM invocation field, decrypt only */ +# define EVP_CTRL_GCM_SET_IV_INV 0x18 + +# define EVP_CTRL_TLS1_1_MULTIBLOCK_AAD 0x19 +# define EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT 0x1a +# define EVP_CTRL_TLS1_1_MULTIBLOCK_DECRYPT 0x1b +# define EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE 0x1c + +/* RFC 5246 defines additional data to be 13 bytes in length */ +# define EVP_AEAD_TLS1_AAD_LEN 13 + +typedef struct { + unsigned char *out; + const unsigned char *inp; + size_t len; + unsigned int interleave; +} EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM; + +/* GCM TLS constants */ +/* Length of fixed part of IV derived from PRF */ +# define EVP_GCM_TLS_FIXED_IV_LEN 4 +/* Length of explicit part of IV part of TLS records */ +# define EVP_GCM_TLS_EXPLICIT_IV_LEN 8 +/* Length of tag for TLS */ +# define EVP_GCM_TLS_TAG_LEN 16 + +typedef struct evp_cipher_info_st { + const EVP_CIPHER *cipher; + unsigned char iv[EVP_MAX_IV_LENGTH]; +} EVP_CIPHER_INFO; + +struct evp_cipher_ctx_st { + const EVP_CIPHER *cipher; + ENGINE *engine; /* functional reference if 'cipher' is + * ENGINE-provided */ + int encrypt; /* encrypt or decrypt */ + int buf_len; /* number we have left */ + unsigned char oiv[EVP_MAX_IV_LENGTH]; /* original iv */ + unsigned char iv[EVP_MAX_IV_LENGTH]; /* working iv */ + unsigned char buf[EVP_MAX_BLOCK_LENGTH]; /* saved partial block */ + int num; /* used by cfb/ofb/ctr mode */ + void *app_data; /* application stuff */ + int key_len; /* May change for variable length cipher */ + unsigned long flags; /* Various flags */ + void *cipher_data; /* per EVP data */ + int final_used; + int block_mask; + unsigned char final[EVP_MAX_BLOCK_LENGTH]; /* possible final block */ +} /* EVP_CIPHER_CTX */ ; + +typedef struct evp_Encode_Ctx_st { + /* number saved in a partial encode/decode */ + int num; + /* + * The length is either the output line length (in input bytes) or the + * shortest input line length that is ok. Once decoding begins, the + * length is adjusted up each time a longer line is decoded + */ + int length; + /* data to encode */ + unsigned char enc_data[80]; + /* number read on current line */ + int line_num; + int expect_nl; +} EVP_ENCODE_CTX; + +/* Password based encryption function */ +typedef int (EVP_PBE_KEYGEN) (EVP_CIPHER_CTX *ctx, const char *pass, + int passlen, ASN1_TYPE *param, + const EVP_CIPHER *cipher, const EVP_MD *md, + int en_de); + +# ifndef OPENSSL_NO_RSA +# define EVP_PKEY_assign_RSA(pkey,rsa) EVP_PKEY_assign((pkey),EVP_PKEY_RSA,\ + (char *)(rsa)) +# endif + +# ifndef OPENSSL_NO_DSA +# define EVP_PKEY_assign_DSA(pkey,dsa) EVP_PKEY_assign((pkey),EVP_PKEY_DSA,\ + (char *)(dsa)) +# endif + +# ifndef OPENSSL_NO_DH +# define EVP_PKEY_assign_DH(pkey,dh) EVP_PKEY_assign((pkey),EVP_PKEY_DH,\ + (char *)(dh)) +# endif + +# ifndef OPENSSL_NO_EC +# define EVP_PKEY_assign_EC_KEY(pkey,eckey) EVP_PKEY_assign((pkey),EVP_PKEY_EC,\ + (char *)(eckey)) +# endif + +/* Add some extra combinations */ +# define EVP_get_digestbynid(a) EVP_get_digestbyname(OBJ_nid2sn(a)) +# define EVP_get_digestbyobj(a) EVP_get_digestbynid(OBJ_obj2nid(a)) +# define EVP_get_cipherbynid(a) EVP_get_cipherbyname(OBJ_nid2sn(a)) +# define EVP_get_cipherbyobj(a) EVP_get_cipherbynid(OBJ_obj2nid(a)) + +int EVP_MD_type(const EVP_MD *md); +# define EVP_MD_nid(e) EVP_MD_type(e) +# define EVP_MD_name(e) OBJ_nid2sn(EVP_MD_nid(e)) +int EVP_MD_pkey_type(const EVP_MD *md); +int EVP_MD_size(const EVP_MD *md); +int EVP_MD_block_size(const EVP_MD *md); +unsigned long EVP_MD_flags(const EVP_MD *md); + +const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx); +# define EVP_MD_CTX_size(e) EVP_MD_size(EVP_MD_CTX_md(e)) +# define EVP_MD_CTX_block_size(e) EVP_MD_block_size(EVP_MD_CTX_md(e)) +# define EVP_MD_CTX_type(e) EVP_MD_type(EVP_MD_CTX_md(e)) + +int EVP_CIPHER_nid(const EVP_CIPHER *cipher); +# define EVP_CIPHER_name(e) OBJ_nid2sn(EVP_CIPHER_nid(e)) +int EVP_CIPHER_block_size(const EVP_CIPHER *cipher); +int EVP_CIPHER_key_length(const EVP_CIPHER *cipher); +int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher); +unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher); +# define EVP_CIPHER_mode(e) (EVP_CIPHER_flags(e) & EVP_CIPH_MODE) + +const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in); +void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx); +void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data); +# define EVP_CIPHER_CTX_type(c) EVP_CIPHER_type(EVP_CIPHER_CTX_cipher(c)) +unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx); +# define EVP_CIPHER_CTX_mode(e) (EVP_CIPHER_CTX_flags(e) & EVP_CIPH_MODE) + +# define EVP_ENCODE_LENGTH(l) (((l+2)/3*4)+(l/48+1)*2+80) +# define EVP_DECODE_LENGTH(l) ((l+3)/4*3+80) + +# define EVP_SignInit_ex(a,b,c) EVP_DigestInit_ex(a,b,c) +# define EVP_SignInit(a,b) EVP_DigestInit(a,b) +# define EVP_SignUpdate(a,b,c) EVP_DigestUpdate(a,b,c) +# define EVP_VerifyInit_ex(a,b,c) EVP_DigestInit_ex(a,b,c) +# define EVP_VerifyInit(a,b) EVP_DigestInit(a,b) +# define EVP_VerifyUpdate(a,b,c) EVP_DigestUpdate(a,b,c) +# define EVP_OpenUpdate(a,b,c,d,e) EVP_DecryptUpdate(a,b,c,d,e) +# define EVP_SealUpdate(a,b,c,d,e) EVP_EncryptUpdate(a,b,c,d,e) +# define EVP_DigestSignUpdate(a,b,c) EVP_DigestUpdate(a,b,c) +# define EVP_DigestVerifyUpdate(a,b,c) EVP_DigestUpdate(a,b,c) + +# ifdef CONST_STRICT +void BIO_set_md(BIO *, const EVP_MD *md); +# else +# define BIO_set_md(b,md) BIO_ctrl(b,BIO_C_SET_MD,0,(char *)md) +# endif +# define BIO_get_md(b,mdp) BIO_ctrl(b,BIO_C_GET_MD,0,(char *)mdp) +# define BIO_get_md_ctx(b,mdcp) BIO_ctrl(b,BIO_C_GET_MD_CTX,0,(char *)mdcp) +# define BIO_set_md_ctx(b,mdcp) BIO_ctrl(b,BIO_C_SET_MD_CTX,0,(char *)mdcp) +# define BIO_get_cipher_status(b) BIO_ctrl(b,BIO_C_GET_CIPHER_STATUS,0,NULL) +# define BIO_get_cipher_ctx(b,c_pp) BIO_ctrl(b,BIO_C_GET_CIPHER_CTX,0,(char *)c_pp) + +int EVP_Cipher(EVP_CIPHER_CTX *c, + unsigned char *out, const unsigned char *in, unsigned int inl); + +# define EVP_add_cipher_alias(n,alias) \ + OBJ_NAME_add((alias),OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS,(n)) +# define EVP_add_digest_alias(n,alias) \ + OBJ_NAME_add((alias),OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,(n)) +# define EVP_delete_cipher_alias(alias) \ + OBJ_NAME_remove(alias,OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS); +# define EVP_delete_digest_alias(alias) \ + OBJ_NAME_remove(alias,OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS); + +void EVP_MD_CTX_init(EVP_MD_CTX *ctx); +int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx); +EVP_MD_CTX *EVP_MD_CTX_create(void); +void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx); +int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in); +void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags); +void EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags); +int EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, int flags); +int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl); +int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, size_t cnt); +int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s); +int EVP_Digest(const void *data, size_t count, + unsigned char *md, unsigned int *size, const EVP_MD *type, + ENGINE *impl); + +int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in); +int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type); +int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s); + +int EVP_read_pw_string(char *buf, int length, const char *prompt, int verify); +int EVP_read_pw_string_min(char *buf, int minlen, int maxlen, + const char *prompt, int verify); +void EVP_set_pw_prompt(const char *prompt); +char *EVP_get_pw_prompt(void); + +int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, + const unsigned char *salt, const unsigned char *data, + int datal, int count, unsigned char *key, + unsigned char *iv); + +void EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags); +void EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags); +int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags); + +int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv); +int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + ENGINE *impl, const unsigned char *key, + const unsigned char *iv); +int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl); +int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); +int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); + +int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv); +int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + ENGINE *impl, const unsigned char *key, + const unsigned char *iv); +int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl); +int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl); +int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl); + +int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv, + int enc); +int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + ENGINE *impl, const unsigned char *key, + const unsigned char *iv, int enc); +int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl); +int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl); +int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl); + +int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s, + EVP_PKEY *pkey); + +int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf, + unsigned int siglen, EVP_PKEY *pkey); + +int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); +int EVP_DigestSignFinal(EVP_MD_CTX *ctx, + unsigned char *sigret, size_t *siglen); + +int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); +int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, + const unsigned char *sig, size_t siglen); + +int EVP_OpenInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, + const unsigned char *ek, int ekl, const unsigned char *iv, + EVP_PKEY *priv); +int EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); + +int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, + unsigned char **ek, int *ekl, unsigned char *iv, + EVP_PKEY **pubk, int npubk); +int EVP_SealFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); + +void EVP_EncodeInit(EVP_ENCODE_CTX *ctx); +void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl); +void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl); +int EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int n); + +void EVP_DecodeInit(EVP_ENCODE_CTX *ctx); +int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl); +int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned + char *out, int *outl); +int EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n); + +void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *a); +int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a); +EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void); +void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *a); +int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen); +int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *c, int pad); +int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr); +int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key); + +# ifndef OPENSSL_NO_BIO +BIO_METHOD *BIO_f_md(void); +BIO_METHOD *BIO_f_base64(void); +BIO_METHOD *BIO_f_cipher(void); +BIO_METHOD *BIO_f_reliable(void); +void BIO_set_cipher(BIO *b, const EVP_CIPHER *c, const unsigned char *k, + const unsigned char *i, int enc); +# endif + +const EVP_MD *EVP_md_null(void); +# ifndef OPENSSL_NO_MD2 +const EVP_MD *EVP_md2(void); +# endif +# ifndef OPENSSL_NO_MD4 +const EVP_MD *EVP_md4(void); +# endif +# ifndef OPENSSL_NO_MD5 +const EVP_MD *EVP_md5(void); +# endif +# ifndef OPENSSL_NO_SHA +const EVP_MD *EVP_sha(void); +const EVP_MD *EVP_sha1(void); +const EVP_MD *EVP_dss(void); +const EVP_MD *EVP_dss1(void); +const EVP_MD *EVP_ecdsa(void); +# endif +# ifndef OPENSSL_NO_SHA256 +const EVP_MD *EVP_sha224(void); +const EVP_MD *EVP_sha256(void); +# endif +# ifndef OPENSSL_NO_SHA512 +const EVP_MD *EVP_sha384(void); +const EVP_MD *EVP_sha512(void); +# endif +# ifndef OPENSSL_NO_MDC2 +const EVP_MD *EVP_mdc2(void); +# endif +# ifndef OPENSSL_NO_RIPEMD +const EVP_MD *EVP_ripemd160(void); +# endif +# ifndef OPENSSL_NO_WHIRLPOOL +const EVP_MD *EVP_whirlpool(void); +# endif +const EVP_CIPHER *EVP_enc_null(void); /* does nothing :-) */ +# ifndef OPENSSL_NO_DES +const EVP_CIPHER *EVP_des_ecb(void); +const EVP_CIPHER *EVP_des_ede(void); +const EVP_CIPHER *EVP_des_ede3(void); +const EVP_CIPHER *EVP_des_ede_ecb(void); +const EVP_CIPHER *EVP_des_ede3_ecb(void); +const EVP_CIPHER *EVP_des_cfb64(void); +# define EVP_des_cfb EVP_des_cfb64 +const EVP_CIPHER *EVP_des_cfb1(void); +const EVP_CIPHER *EVP_des_cfb8(void); +const EVP_CIPHER *EVP_des_ede_cfb64(void); +# define EVP_des_ede_cfb EVP_des_ede_cfb64 +# if 0 +const EVP_CIPHER *EVP_des_ede_cfb1(void); +const EVP_CIPHER *EVP_des_ede_cfb8(void); +# endif +const EVP_CIPHER *EVP_des_ede3_cfb64(void); +# define EVP_des_ede3_cfb EVP_des_ede3_cfb64 +const EVP_CIPHER *EVP_des_ede3_cfb1(void); +const EVP_CIPHER *EVP_des_ede3_cfb8(void); +const EVP_CIPHER *EVP_des_ofb(void); +const EVP_CIPHER *EVP_des_ede_ofb(void); +const EVP_CIPHER *EVP_des_ede3_ofb(void); +const EVP_CIPHER *EVP_des_cbc(void); +const EVP_CIPHER *EVP_des_ede_cbc(void); +const EVP_CIPHER *EVP_des_ede3_cbc(void); +const EVP_CIPHER *EVP_desx_cbc(void); +const EVP_CIPHER *EVP_des_ede3_wrap(void); +/* + * This should now be supported through the dev_crypto ENGINE. But also, why + * are rc4 and md5 declarations made here inside a "NO_DES" precompiler + * branch? + */ +# if 0 +# ifdef OPENSSL_OPENBSD_DEV_CRYPTO +const EVP_CIPHER *EVP_dev_crypto_des_ede3_cbc(void); +const EVP_CIPHER *EVP_dev_crypto_rc4(void); +const EVP_MD *EVP_dev_crypto_md5(void); +# endif +# endif +# endif +# ifndef OPENSSL_NO_RC4 +const EVP_CIPHER *EVP_rc4(void); +const EVP_CIPHER *EVP_rc4_40(void); +# ifndef OPENSSL_NO_MD5 +const EVP_CIPHER *EVP_rc4_hmac_md5(void); +# endif +# endif +# ifndef OPENSSL_NO_IDEA +const EVP_CIPHER *EVP_idea_ecb(void); +const EVP_CIPHER *EVP_idea_cfb64(void); +# define EVP_idea_cfb EVP_idea_cfb64 +const EVP_CIPHER *EVP_idea_ofb(void); +const EVP_CIPHER *EVP_idea_cbc(void); +# endif +# ifndef OPENSSL_NO_RC2 +const EVP_CIPHER *EVP_rc2_ecb(void); +const EVP_CIPHER *EVP_rc2_cbc(void); +const EVP_CIPHER *EVP_rc2_40_cbc(void); +const EVP_CIPHER *EVP_rc2_64_cbc(void); +const EVP_CIPHER *EVP_rc2_cfb64(void); +# define EVP_rc2_cfb EVP_rc2_cfb64 +const EVP_CIPHER *EVP_rc2_ofb(void); +# endif +# ifndef OPENSSL_NO_BF +const EVP_CIPHER *EVP_bf_ecb(void); +const EVP_CIPHER *EVP_bf_cbc(void); +const EVP_CIPHER *EVP_bf_cfb64(void); +# define EVP_bf_cfb EVP_bf_cfb64 +const EVP_CIPHER *EVP_bf_ofb(void); +# endif +# ifndef OPENSSL_NO_CAST +const EVP_CIPHER *EVP_cast5_ecb(void); +const EVP_CIPHER *EVP_cast5_cbc(void); +const EVP_CIPHER *EVP_cast5_cfb64(void); +# define EVP_cast5_cfb EVP_cast5_cfb64 +const EVP_CIPHER *EVP_cast5_ofb(void); +# endif +# ifndef OPENSSL_NO_RC5 +const EVP_CIPHER *EVP_rc5_32_12_16_cbc(void); +const EVP_CIPHER *EVP_rc5_32_12_16_ecb(void); +const EVP_CIPHER *EVP_rc5_32_12_16_cfb64(void); +# define EVP_rc5_32_12_16_cfb EVP_rc5_32_12_16_cfb64 +const EVP_CIPHER *EVP_rc5_32_12_16_ofb(void); +# endif +# ifndef OPENSSL_NO_AES +const EVP_CIPHER *EVP_aes_128_ecb(void); +const EVP_CIPHER *EVP_aes_128_cbc(void); +const EVP_CIPHER *EVP_aes_128_cfb1(void); +const EVP_CIPHER *EVP_aes_128_cfb8(void); +const EVP_CIPHER *EVP_aes_128_cfb128(void); +# define EVP_aes_128_cfb EVP_aes_128_cfb128 +const EVP_CIPHER *EVP_aes_128_ofb(void); +const EVP_CIPHER *EVP_aes_128_ctr(void); +const EVP_CIPHER *EVP_aes_128_ccm(void); +const EVP_CIPHER *EVP_aes_128_gcm(void); +const EVP_CIPHER *EVP_aes_128_xts(void); +const EVP_CIPHER *EVP_aes_128_wrap(void); +const EVP_CIPHER *EVP_aes_192_ecb(void); +const EVP_CIPHER *EVP_aes_192_cbc(void); +const EVP_CIPHER *EVP_aes_192_cfb1(void); +const EVP_CIPHER *EVP_aes_192_cfb8(void); +const EVP_CIPHER *EVP_aes_192_cfb128(void); +# define EVP_aes_192_cfb EVP_aes_192_cfb128 +const EVP_CIPHER *EVP_aes_192_ofb(void); +const EVP_CIPHER *EVP_aes_192_ctr(void); +const EVP_CIPHER *EVP_aes_192_ccm(void); +const EVP_CIPHER *EVP_aes_192_gcm(void); +const EVP_CIPHER *EVP_aes_192_wrap(void); +const EVP_CIPHER *EVP_aes_256_ecb(void); +const EVP_CIPHER *EVP_aes_256_cbc(void); +const EVP_CIPHER *EVP_aes_256_cfb1(void); +const EVP_CIPHER *EVP_aes_256_cfb8(void); +const EVP_CIPHER *EVP_aes_256_cfb128(void); +# define EVP_aes_256_cfb EVP_aes_256_cfb128 +const EVP_CIPHER *EVP_aes_256_ofb(void); +const EVP_CIPHER *EVP_aes_256_ctr(void); +const EVP_CIPHER *EVP_aes_256_ccm(void); +const EVP_CIPHER *EVP_aes_256_gcm(void); +const EVP_CIPHER *EVP_aes_256_xts(void); +const EVP_CIPHER *EVP_aes_256_wrap(void); +# if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1) +const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void); +const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void); +# endif +# ifndef OPENSSL_NO_SHA256 +const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha256(void); +const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha256(void); +# endif +# endif +# ifndef OPENSSL_NO_CAMELLIA +const EVP_CIPHER *EVP_camellia_128_ecb(void); +const EVP_CIPHER *EVP_camellia_128_cbc(void); +const EVP_CIPHER *EVP_camellia_128_cfb1(void); +const EVP_CIPHER *EVP_camellia_128_cfb8(void); +const EVP_CIPHER *EVP_camellia_128_cfb128(void); +# define EVP_camellia_128_cfb EVP_camellia_128_cfb128 +const EVP_CIPHER *EVP_camellia_128_ofb(void); +const EVP_CIPHER *EVP_camellia_192_ecb(void); +const EVP_CIPHER *EVP_camellia_192_cbc(void); +const EVP_CIPHER *EVP_camellia_192_cfb1(void); +const EVP_CIPHER *EVP_camellia_192_cfb8(void); +const EVP_CIPHER *EVP_camellia_192_cfb128(void); +# define EVP_camellia_192_cfb EVP_camellia_192_cfb128 +const EVP_CIPHER *EVP_camellia_192_ofb(void); +const EVP_CIPHER *EVP_camellia_256_ecb(void); +const EVP_CIPHER *EVP_camellia_256_cbc(void); +const EVP_CIPHER *EVP_camellia_256_cfb1(void); +const EVP_CIPHER *EVP_camellia_256_cfb8(void); +const EVP_CIPHER *EVP_camellia_256_cfb128(void); +# define EVP_camellia_256_cfb EVP_camellia_256_cfb128 +const EVP_CIPHER *EVP_camellia_256_ofb(void); +# endif + +# ifndef OPENSSL_NO_SEED +const EVP_CIPHER *EVP_seed_ecb(void); +const EVP_CIPHER *EVP_seed_cbc(void); +const EVP_CIPHER *EVP_seed_cfb128(void); +# define EVP_seed_cfb EVP_seed_cfb128 +const EVP_CIPHER *EVP_seed_ofb(void); +# endif + +void OPENSSL_add_all_algorithms_noconf(void); +void OPENSSL_add_all_algorithms_conf(void); + +# ifdef OPENSSL_LOAD_CONF +# define OpenSSL_add_all_algorithms() \ + OPENSSL_add_all_algorithms_conf() +# else +# define OpenSSL_add_all_algorithms() \ + OPENSSL_add_all_algorithms_noconf() +# endif + +void OpenSSL_add_all_ciphers(void); +void OpenSSL_add_all_digests(void); +# define SSLeay_add_all_algorithms() OpenSSL_add_all_algorithms() +# define SSLeay_add_all_ciphers() OpenSSL_add_all_ciphers() +# define SSLeay_add_all_digests() OpenSSL_add_all_digests() + +int EVP_add_cipher(const EVP_CIPHER *cipher); +int EVP_add_digest(const EVP_MD *digest); + +const EVP_CIPHER *EVP_get_cipherbyname(const char *name); +const EVP_MD *EVP_get_digestbyname(const char *name); +void EVP_cleanup(void); + +void EVP_CIPHER_do_all(void (*fn) (const EVP_CIPHER *ciph, + const char *from, const char *to, void *x), + void *arg); +void EVP_CIPHER_do_all_sorted(void (*fn) + (const EVP_CIPHER *ciph, const char *from, + const char *to, void *x), void *arg); + +void EVP_MD_do_all(void (*fn) (const EVP_MD *ciph, + const char *from, const char *to, void *x), + void *arg); +void EVP_MD_do_all_sorted(void (*fn) + (const EVP_MD *ciph, const char *from, + const char *to, void *x), void *arg); + +int EVP_PKEY_decrypt_old(unsigned char *dec_key, + const unsigned char *enc_key, int enc_key_len, + EVP_PKEY *private_key); +int EVP_PKEY_encrypt_old(unsigned char *enc_key, + const unsigned char *key, int key_len, + EVP_PKEY *pub_key); +int EVP_PKEY_type(int type); +int EVP_PKEY_id(const EVP_PKEY *pkey); +int EVP_PKEY_base_id(const EVP_PKEY *pkey); +int EVP_PKEY_bits(EVP_PKEY *pkey); +int EVP_PKEY_size(EVP_PKEY *pkey); +int EVP_PKEY_set_type(EVP_PKEY *pkey, int type); +int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len); +int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key); +void *EVP_PKEY_get0(EVP_PKEY *pkey); + +# ifndef OPENSSL_NO_RSA +struct rsa_st; +int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, struct rsa_st *key); +struct rsa_st *EVP_PKEY_get1_RSA(EVP_PKEY *pkey); +# endif +# ifndef OPENSSL_NO_DSA +struct dsa_st; +int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, struct dsa_st *key); +struct dsa_st *EVP_PKEY_get1_DSA(EVP_PKEY *pkey); +# endif +# ifndef OPENSSL_NO_DH +struct dh_st; +int EVP_PKEY_set1_DH(EVP_PKEY *pkey, struct dh_st *key); +struct dh_st *EVP_PKEY_get1_DH(EVP_PKEY *pkey); +# endif +# ifndef OPENSSL_NO_EC +struct ec_key_st; +int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, struct ec_key_st *key); +struct ec_key_st *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey); +# endif + +EVP_PKEY *EVP_PKEY_new(void); +void EVP_PKEY_free(EVP_PKEY *pkey); + +EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp, + long length); +int i2d_PublicKey(EVP_PKEY *a, unsigned char **pp); + +EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, + long length); +EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp, + long length); +int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp); + +int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from); +int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey); +int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode); +int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b); + +int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b); + +int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx); +int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx); +int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx); + +int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid); + +int EVP_CIPHER_type(const EVP_CIPHER *ctx); + +/* calls methods */ +int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type); +int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type); + +/* These are used by EVP_CIPHER methods */ +int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type); +int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type); + +/* PKCS5 password based encryption */ +int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, + const EVP_MD *md, int en_de); +int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, + const unsigned char *salt, int saltlen, int iter, + int keylen, unsigned char *out); +int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, + const unsigned char *salt, int saltlen, int iter, + const EVP_MD *digest, int keylen, unsigned char *out); +int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, + const EVP_MD *md, int en_de); + +void PKCS5_PBE_add(void); + +int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen, + ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de); + +/* PBE type */ + +/* Can appear as the outermost AlgorithmIdentifier */ +# define EVP_PBE_TYPE_OUTER 0x0 +/* Is an PRF type OID */ +# define EVP_PBE_TYPE_PRF 0x1 + +int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid, + int md_nid, EVP_PBE_KEYGEN *keygen); +int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md, + EVP_PBE_KEYGEN *keygen); +int EVP_PBE_find(int type, int pbe_nid, int *pcnid, int *pmnid, + EVP_PBE_KEYGEN **pkeygen); +void EVP_PBE_cleanup(void); + +# define ASN1_PKEY_ALIAS 0x1 +# define ASN1_PKEY_DYNAMIC 0x2 +# define ASN1_PKEY_SIGPARAM_NULL 0x4 + +# define ASN1_PKEY_CTRL_PKCS7_SIGN 0x1 +# define ASN1_PKEY_CTRL_PKCS7_ENCRYPT 0x2 +# define ASN1_PKEY_CTRL_DEFAULT_MD_NID 0x3 +# define ASN1_PKEY_CTRL_CMS_SIGN 0x5 +# define ASN1_PKEY_CTRL_CMS_ENVELOPE 0x7 +# define ASN1_PKEY_CTRL_CMS_RI_TYPE 0x8 + +int EVP_PKEY_asn1_get_count(void); +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx); +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type); +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe, + const char *str, int len); +int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth); +int EVP_PKEY_asn1_add_alias(int to, int from); +int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *pkey_base_id, + int *ppkey_flags, const char **pinfo, + const char **ppem_str, + const EVP_PKEY_ASN1_METHOD *ameth); + +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_get0_asn1(EVP_PKEY *pkey); +EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_new(int id, int flags, + const char *pem_str, + const char *info); +void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst, + const EVP_PKEY_ASN1_METHOD *src); +void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth); +void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth, + int (*pub_decode) (EVP_PKEY *pk, + X509_PUBKEY *pub), + int (*pub_encode) (X509_PUBKEY *pub, + const EVP_PKEY *pk), + int (*pub_cmp) (const EVP_PKEY *a, + const EVP_PKEY *b), + int (*pub_print) (BIO *out, + const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx), + int (*pkey_size) (const EVP_PKEY *pk), + int (*pkey_bits) (const EVP_PKEY *pk)); +void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth, + int (*priv_decode) (EVP_PKEY *pk, + PKCS8_PRIV_KEY_INFO + *p8inf), + int (*priv_encode) (PKCS8_PRIV_KEY_INFO *p8, + const EVP_PKEY *pk), + int (*priv_print) (BIO *out, + const EVP_PKEY *pkey, + int indent, + ASN1_PCTX *pctx)); +void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth, + int (*param_decode) (EVP_PKEY *pkey, + const unsigned char **pder, + int derlen), + int (*param_encode) (const EVP_PKEY *pkey, + unsigned char **pder), + int (*param_missing) (const EVP_PKEY *pk), + int (*param_copy) (EVP_PKEY *to, + const EVP_PKEY *from), + int (*param_cmp) (const EVP_PKEY *a, + const EVP_PKEY *b), + int (*param_print) (BIO *out, + const EVP_PKEY *pkey, + int indent, + ASN1_PCTX *pctx)); + +void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth, + void (*pkey_free) (EVP_PKEY *pkey)); +void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth, + int (*pkey_ctrl) (EVP_PKEY *pkey, int op, + long arg1, void *arg2)); +void EVP_PKEY_asn1_set_item(EVP_PKEY_ASN1_METHOD *ameth, + int (*item_verify) (EVP_MD_CTX *ctx, + const ASN1_ITEM *it, + void *asn, + X509_ALGOR *a, + ASN1_BIT_STRING *sig, + EVP_PKEY *pkey), + int (*item_sign) (EVP_MD_CTX *ctx, + const ASN1_ITEM *it, + void *asn, + X509_ALGOR *alg1, + X509_ALGOR *alg2, + ASN1_BIT_STRING *sig)); + +# define EVP_PKEY_OP_UNDEFINED 0 +# define EVP_PKEY_OP_PARAMGEN (1<<1) +# define EVP_PKEY_OP_KEYGEN (1<<2) +# define EVP_PKEY_OP_SIGN (1<<3) +# define EVP_PKEY_OP_VERIFY (1<<4) +# define EVP_PKEY_OP_VERIFYRECOVER (1<<5) +# define EVP_PKEY_OP_SIGNCTX (1<<6) +# define EVP_PKEY_OP_VERIFYCTX (1<<7) +# define EVP_PKEY_OP_ENCRYPT (1<<8) +# define EVP_PKEY_OP_DECRYPT (1<<9) +# define EVP_PKEY_OP_DERIVE (1<<10) + +# define EVP_PKEY_OP_TYPE_SIG \ + (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY | EVP_PKEY_OP_VERIFYRECOVER \ + | EVP_PKEY_OP_SIGNCTX | EVP_PKEY_OP_VERIFYCTX) + +# define EVP_PKEY_OP_TYPE_CRYPT \ + (EVP_PKEY_OP_ENCRYPT | EVP_PKEY_OP_DECRYPT) + +# define EVP_PKEY_OP_TYPE_NOGEN \ + (EVP_PKEY_OP_SIG | EVP_PKEY_OP_CRYPT | EVP_PKEY_OP_DERIVE) + +# define EVP_PKEY_OP_TYPE_GEN \ + (EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN) + +# define EVP_PKEY_CTX_set_signature_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, \ + EVP_PKEY_CTRL_MD, 0, (void *)md) + +# define EVP_PKEY_CTX_get_signature_md(ctx, pmd) \ + EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, \ + EVP_PKEY_CTRL_GET_MD, 0, (void *)pmd) + +# define EVP_PKEY_CTRL_MD 1 +# define EVP_PKEY_CTRL_PEER_KEY 2 + +# define EVP_PKEY_CTRL_PKCS7_ENCRYPT 3 +# define EVP_PKEY_CTRL_PKCS7_DECRYPT 4 + +# define EVP_PKEY_CTRL_PKCS7_SIGN 5 + +# define EVP_PKEY_CTRL_SET_MAC_KEY 6 + +# define EVP_PKEY_CTRL_DIGESTINIT 7 + +/* Used by GOST key encryption in TLS */ +# define EVP_PKEY_CTRL_SET_IV 8 + +# define EVP_PKEY_CTRL_CMS_ENCRYPT 9 +# define EVP_PKEY_CTRL_CMS_DECRYPT 10 +# define EVP_PKEY_CTRL_CMS_SIGN 11 + +# define EVP_PKEY_CTRL_CIPHER 12 + +# define EVP_PKEY_CTRL_GET_MD 13 + +# define EVP_PKEY_ALG_CTRL 0x1000 + +# define EVP_PKEY_FLAG_AUTOARGLEN 2 +/* + * Method handles all operations: don't assume any digest related defaults. + */ +# define EVP_PKEY_FLAG_SIGCTX_CUSTOM 4 + +const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type); +EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags); +void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags, + const EVP_PKEY_METHOD *meth); +void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src); +void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth); +int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth); + +EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e); +EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e); +EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx); +void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx); + +int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, + int cmd, int p1, void *p2); +int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, + const char *value); + +int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx); +void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen); + +EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, + const unsigned char *key, int keylen); + +void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data); +void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx); +EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx); + +EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx); + +void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data); +void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx); + +int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen); +int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, + const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen); +int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, + unsigned char *rout, size_t *routlen, + const unsigned char *sig, size_t siglen); +int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); +int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); + +int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer); +int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); + +typedef int EVP_PKEY_gen_cb (EVP_PKEY_CTX *ctx); + +int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); +int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); + +void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb); +EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx); + +int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx); + +void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth, + int (*init) (EVP_PKEY_CTX *ctx)); + +void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth, + int (*copy) (EVP_PKEY_CTX *dst, + EVP_PKEY_CTX *src)); + +void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth, + void (*cleanup) (EVP_PKEY_CTX *ctx)); + +void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth, + int (*paramgen_init) (EVP_PKEY_CTX *ctx), + int (*paramgen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)); + +void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth, + int (*keygen_init) (EVP_PKEY_CTX *ctx), + int (*keygen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)); + +void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth, + int (*sign_init) (EVP_PKEY_CTX *ctx), + int (*sign) (EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth, + int (*verify_init) (EVP_PKEY_CTX *ctx), + int (*verify) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + size_t siglen, + const unsigned char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth, + int (*verify_recover_init) (EVP_PKEY_CTX + *ctx), + int (*verify_recover) (EVP_PKEY_CTX + *ctx, + unsigned char + *sig, + size_t *siglen, + const unsigned + char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth, + int (*signctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (*signctx) (EVP_PKEY_CTX *ctx, + unsigned char *sig, + size_t *siglen, + EVP_MD_CTX *mctx)); + +void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth, + int (*verifyctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (*verifyctx) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + int siglen, + EVP_MD_CTX *mctx)); + +void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth, + int (*encrypt_init) (EVP_PKEY_CTX *ctx), + int (*encryptfn) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)); + +void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth, + int (*decrypt_init) (EVP_PKEY_CTX *ctx), + int (*decrypt) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)); + +void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth, + int (*derive_init) (EVP_PKEY_CTX *ctx), + int (*derive) (EVP_PKEY_CTX *ctx, + unsigned char *key, + size_t *keylen)); + +void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth, + int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1, + void *p2), + int (*ctrl_str) (EVP_PKEY_CTX *ctx, + const char *type, + const char *value)); + +void EVP_add_alg_module(void); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_EVP_strings(void); + +/* Error codes for the EVP functions. */ + +/* Function codes. */ +# define EVP_F_AESNI_INIT_KEY 165 +# define EVP_F_AESNI_XTS_CIPHER 176 +# define EVP_F_AES_INIT_KEY 133 +# define EVP_F_AES_T4_INIT_KEY 178 +# define EVP_F_AES_XTS 172 +# define EVP_F_AES_XTS_CIPHER 175 +# define EVP_F_ALG_MODULE_INIT 177 +# define EVP_F_CAMELLIA_INIT_KEY 159 +# define EVP_F_CMAC_INIT 173 +# define EVP_F_CMLL_T4_INIT_KEY 179 +# define EVP_F_D2I_PKEY 100 +# define EVP_F_DO_SIGVER_INIT 161 +# define EVP_F_DSAPKEY2PKCS8 134 +# define EVP_F_DSA_PKEY2PKCS8 135 +# define EVP_F_ECDSA_PKEY2PKCS8 129 +# define EVP_F_ECKEY_PKEY2PKCS8 132 +# define EVP_F_EVP_CIPHERINIT_EX 123 +# define EVP_F_EVP_CIPHER_CTX_COPY 163 +# define EVP_F_EVP_CIPHER_CTX_CTRL 124 +# define EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH 122 +# define EVP_F_EVP_DECRYPTFINAL_EX 101 +# define EVP_F_EVP_DIGESTINIT_EX 128 +# define EVP_F_EVP_ENCRYPTFINAL_EX 127 +# define EVP_F_EVP_MD_CTX_COPY_EX 110 +# define EVP_F_EVP_MD_SIZE 162 +# define EVP_F_EVP_OPENINIT 102 +# define EVP_F_EVP_PBE_ALG_ADD 115 +# define EVP_F_EVP_PBE_ALG_ADD_TYPE 160 +# define EVP_F_EVP_PBE_CIPHERINIT 116 +# define EVP_F_EVP_PKCS82PKEY 111 +# define EVP_F_EVP_PKCS82PKEY_BROKEN 136 +# define EVP_F_EVP_PKEY2PKCS8_BROKEN 113 +# define EVP_F_EVP_PKEY_COPY_PARAMETERS 103 +# define EVP_F_EVP_PKEY_CTX_CTRL 137 +# define EVP_F_EVP_PKEY_CTX_CTRL_STR 150 +# define EVP_F_EVP_PKEY_CTX_DUP 156 +# define EVP_F_EVP_PKEY_DECRYPT 104 +# define EVP_F_EVP_PKEY_DECRYPT_INIT 138 +# define EVP_F_EVP_PKEY_DECRYPT_OLD 151 +# define EVP_F_EVP_PKEY_DERIVE 153 +# define EVP_F_EVP_PKEY_DERIVE_INIT 154 +# define EVP_F_EVP_PKEY_DERIVE_SET_PEER 155 +# define EVP_F_EVP_PKEY_ENCRYPT 105 +# define EVP_F_EVP_PKEY_ENCRYPT_INIT 139 +# define EVP_F_EVP_PKEY_ENCRYPT_OLD 152 +# define EVP_F_EVP_PKEY_GET1_DH 119 +# define EVP_F_EVP_PKEY_GET1_DSA 120 +# define EVP_F_EVP_PKEY_GET1_ECDSA 130 +# define EVP_F_EVP_PKEY_GET1_EC_KEY 131 +# define EVP_F_EVP_PKEY_GET1_RSA 121 +# define EVP_F_EVP_PKEY_KEYGEN 146 +# define EVP_F_EVP_PKEY_KEYGEN_INIT 147 +# define EVP_F_EVP_PKEY_NEW 106 +# define EVP_F_EVP_PKEY_PARAMGEN 148 +# define EVP_F_EVP_PKEY_PARAMGEN_INIT 149 +# define EVP_F_EVP_PKEY_SIGN 140 +# define EVP_F_EVP_PKEY_SIGN_INIT 141 +# define EVP_F_EVP_PKEY_VERIFY 142 +# define EVP_F_EVP_PKEY_VERIFY_INIT 143 +# define EVP_F_EVP_PKEY_VERIFY_RECOVER 144 +# define EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT 145 +# define EVP_F_EVP_RIJNDAEL 126 +# define EVP_F_EVP_SIGNFINAL 107 +# define EVP_F_EVP_VERIFYFINAL 108 +# define EVP_F_FIPS_CIPHERINIT 166 +# define EVP_F_FIPS_CIPHER_CTX_COPY 170 +# define EVP_F_FIPS_CIPHER_CTX_CTRL 167 +# define EVP_F_FIPS_CIPHER_CTX_SET_KEY_LENGTH 171 +# define EVP_F_FIPS_DIGESTINIT 168 +# define EVP_F_FIPS_MD_CTX_COPY 169 +# define EVP_F_HMAC_INIT_EX 174 +# define EVP_F_INT_CTX_NEW 157 +# define EVP_F_PKCS5_PBE_KEYIVGEN 117 +# define EVP_F_PKCS5_V2_PBE_KEYIVGEN 118 +# define EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN 164 +# define EVP_F_PKCS8_SET_BROKEN 112 +# define EVP_F_PKEY_SET_TYPE 158 +# define EVP_F_RC2_MAGIC_TO_METH 109 +# define EVP_F_RC5_CTRL 125 + +/* Reason codes. */ +# define EVP_R_AES_IV_SETUP_FAILED 162 +# define EVP_R_AES_KEY_SETUP_FAILED 143 +# define EVP_R_ASN1_LIB 140 +# define EVP_R_BAD_BLOCK_LENGTH 136 +# define EVP_R_BAD_DECRYPT 100 +# define EVP_R_BAD_KEY_LENGTH 137 +# define EVP_R_BN_DECODE_ERROR 112 +# define EVP_R_BN_PUBKEY_ERROR 113 +# define EVP_R_BUFFER_TOO_SMALL 155 +# define EVP_R_CAMELLIA_KEY_SETUP_FAILED 157 +# define EVP_R_CIPHER_PARAMETER_ERROR 122 +# define EVP_R_COMMAND_NOT_SUPPORTED 147 +# define EVP_R_CTRL_NOT_IMPLEMENTED 132 +# define EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED 133 +# define EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH 138 +# define EVP_R_DECODE_ERROR 114 +# define EVP_R_DIFFERENT_KEY_TYPES 101 +# define EVP_R_DIFFERENT_PARAMETERS 153 +# define EVP_R_DISABLED_FOR_FIPS 163 +# define EVP_R_ENCODE_ERROR 115 +# define EVP_R_ERROR_LOADING_SECTION 165 +# define EVP_R_ERROR_SETTING_FIPS_MODE 166 +# define EVP_R_EVP_PBE_CIPHERINIT_ERROR 119 +# define EVP_R_EXPECTING_AN_RSA_KEY 127 +# define EVP_R_EXPECTING_A_DH_KEY 128 +# define EVP_R_EXPECTING_A_DSA_KEY 129 +# define EVP_R_EXPECTING_A_ECDSA_KEY 141 +# define EVP_R_EXPECTING_A_EC_KEY 142 +# define EVP_R_FIPS_MODE_NOT_SUPPORTED 167 +# define EVP_R_INITIALIZATION_ERROR 134 +# define EVP_R_INPUT_NOT_INITIALIZED 111 +# define EVP_R_INVALID_DIGEST 152 +# define EVP_R_INVALID_FIPS_MODE 168 +# define EVP_R_INVALID_KEY_LENGTH 130 +# define EVP_R_INVALID_OPERATION 148 +# define EVP_R_IV_TOO_LARGE 102 +# define EVP_R_KEYGEN_FAILURE 120 +# define EVP_R_MESSAGE_DIGEST_IS_NULL 159 +# define EVP_R_METHOD_NOT_SUPPORTED 144 +# define EVP_R_MISSING_PARAMETERS 103 +# define EVP_R_NO_CIPHER_SET 131 +# define EVP_R_NO_DEFAULT_DIGEST 158 +# define EVP_R_NO_DIGEST_SET 139 +# define EVP_R_NO_DSA_PARAMETERS 116 +# define EVP_R_NO_KEY_SET 154 +# define EVP_R_NO_OPERATION_SET 149 +# define EVP_R_NO_SIGN_FUNCTION_CONFIGURED 104 +# define EVP_R_NO_VERIFY_FUNCTION_CONFIGURED 105 +# define EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 150 +# define EVP_R_OPERATON_NOT_INITIALIZED 151 +# define EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE 117 +# define EVP_R_PRIVATE_KEY_DECODE_ERROR 145 +# define EVP_R_PRIVATE_KEY_ENCODE_ERROR 146 +# define EVP_R_PUBLIC_KEY_NOT_RSA 106 +# define EVP_R_TOO_LARGE 164 +# define EVP_R_UNKNOWN_CIPHER 160 +# define EVP_R_UNKNOWN_DIGEST 161 +# define EVP_R_UNKNOWN_OPTION 169 +# define EVP_R_UNKNOWN_PBE_ALGORITHM 121 +# define EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS 135 +# define EVP_R_UNSUPPORTED_ALGORITHM 156 +# define EVP_R_UNSUPPORTED_CIPHER 107 +# define EVP_R_UNSUPPORTED_KEYLENGTH 123 +# define EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION 124 +# define EVP_R_UNSUPPORTED_KEY_SIZE 108 +# define EVP_R_UNSUPPORTED_PRF 125 +# define EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM 118 +# define EVP_R_UNSUPPORTED_SALT_TYPE 126 +# define EVP_R_WRAP_MODE_NOT_ALLOWED 170 +# define EVP_R_WRONG_FINAL_BLOCK_LENGTH 109 +# define EVP_R_WRONG_PUBLIC_KEY_TYPE 110 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/hmac.h b/OSlibs/ios/include/openssl/hmac.h new file mode 100755 index 000000000..b8b55cda7 --- /dev/null +++ b/OSlibs/ios/include/openssl/hmac.h @@ -0,0 +1,109 @@ +/* crypto/hmac/hmac.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +#ifndef HEADER_HMAC_H +# define HEADER_HMAC_H + +# include + +# ifdef OPENSSL_NO_HMAC +# error HMAC is disabled. +# endif + +# include + +# define HMAC_MAX_MD_CBLOCK 128/* largest known is SHA512 */ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct hmac_ctx_st { + const EVP_MD *md; + EVP_MD_CTX md_ctx; + EVP_MD_CTX i_ctx; + EVP_MD_CTX o_ctx; + unsigned int key_length; + unsigned char key[HMAC_MAX_MD_CBLOCK]; +} HMAC_CTX; + +# define HMAC_size(e) (EVP_MD_size((e)->md)) + +void HMAC_CTX_init(HMAC_CTX *ctx); +void HMAC_CTX_cleanup(HMAC_CTX *ctx); + +/* deprecated */ +# define HMAC_cleanup(ctx) HMAC_CTX_cleanup(ctx) + +/* deprecated */ +int HMAC_Init(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md); +int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, + const EVP_MD *md, ENGINE *impl); +int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len); +int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len); +unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len, + const unsigned char *d, size_t n, unsigned char *md, + unsigned int *md_len); +int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx); + +void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/OSlibs/ios/include/openssl/idea.h b/OSlibs/ios/include/openssl/idea.h new file mode 100755 index 000000000..607598403 --- /dev/null +++ b/OSlibs/ios/include/openssl/idea.h @@ -0,0 +1,105 @@ +/* crypto/idea/idea.h */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_IDEA_H +# define HEADER_IDEA_H + +# include /* IDEA_INT, OPENSSL_NO_IDEA */ + +# ifdef OPENSSL_NO_IDEA +# error IDEA is disabled. +# endif + +# define IDEA_ENCRYPT 1 +# define IDEA_DECRYPT 0 + +# define IDEA_BLOCK 8 +# define IDEA_KEY_LENGTH 16 + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct idea_key_st { + IDEA_INT data[9][6]; +} IDEA_KEY_SCHEDULE; + +const char *idea_options(void); +void idea_ecb_encrypt(const unsigned char *in, unsigned char *out, + IDEA_KEY_SCHEDULE *ks); +# ifdef OPENSSL_FIPS +void private_idea_set_encrypt_key(const unsigned char *key, + IDEA_KEY_SCHEDULE *ks); +# endif +void idea_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks); +void idea_set_decrypt_key(IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk); +void idea_cbc_encrypt(const unsigned char *in, unsigned char *out, + long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv, + int enc); +void idea_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv, + int *num, int enc); +void idea_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv, + int *num); +void idea_encrypt(unsigned long *in, IDEA_KEY_SCHEDULE *ks); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/OSlibs/ios/include/openssl/krb5_asn.h b/OSlibs/ios/include/openssl/krb5_asn.h new file mode 100755 index 000000000..9cf5a26dd --- /dev/null +++ b/OSlibs/ios/include/openssl/krb5_asn.h @@ -0,0 +1,240 @@ +/* krb5_asn.h */ +/* + * Written by Vern Staats for the OpenSSL project, ** + * using ocsp/{*.h,*asn*.c} as a starting point + */ + +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_KRB5_ASN_H +# define HEADER_KRB5_ASN_H + +/* + * #include + */ +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * ASN.1 from Kerberos RFC 1510 + */ + +/*- EncryptedData ::= SEQUENCE { + * etype[0] INTEGER, -- EncryptionType + * kvno[1] INTEGER OPTIONAL, + * cipher[2] OCTET STRING -- ciphertext + * } + */ +typedef struct krb5_encdata_st { + ASN1_INTEGER *etype; + ASN1_INTEGER *kvno; + ASN1_OCTET_STRING *cipher; +} KRB5_ENCDATA; + +DECLARE_STACK_OF(KRB5_ENCDATA) + +/*- PrincipalName ::= SEQUENCE { + * name-type[0] INTEGER, + * name-string[1] SEQUENCE OF GeneralString + * } + */ +typedef struct krb5_princname_st { + ASN1_INTEGER *nametype; + STACK_OF(ASN1_GENERALSTRING) *namestring; +} KRB5_PRINCNAME; + +DECLARE_STACK_OF(KRB5_PRINCNAME) + +/*- Ticket ::= [APPLICATION 1] SEQUENCE { + * tkt-vno[0] INTEGER, + * realm[1] Realm, + * sname[2] PrincipalName, + * enc-part[3] EncryptedData + * } + */ +typedef struct krb5_tktbody_st { + ASN1_INTEGER *tktvno; + ASN1_GENERALSTRING *realm; + KRB5_PRINCNAME *sname; + KRB5_ENCDATA *encdata; +} KRB5_TKTBODY; + +typedef STACK_OF(KRB5_TKTBODY) KRB5_TICKET; +DECLARE_STACK_OF(KRB5_TKTBODY) + +/*- AP-REQ ::= [APPLICATION 14] SEQUENCE { + * pvno[0] INTEGER, + * msg-type[1] INTEGER, + * ap-options[2] APOptions, + * ticket[3] Ticket, + * authenticator[4] EncryptedData + * } + * + * APOptions ::= BIT STRING { + * reserved(0), use-session-key(1), mutual-required(2) } + */ +typedef struct krb5_ap_req_st { + ASN1_INTEGER *pvno; + ASN1_INTEGER *msgtype; + ASN1_BIT_STRING *apoptions; + KRB5_TICKET *ticket; + KRB5_ENCDATA *authenticator; +} KRB5_APREQBODY; + +typedef STACK_OF(KRB5_APREQBODY) KRB5_APREQ; +DECLARE_STACK_OF(KRB5_APREQBODY) + +/* Authenticator Stuff */ + +/*- Checksum ::= SEQUENCE { + * cksumtype[0] INTEGER, + * checksum[1] OCTET STRING + * } + */ +typedef struct krb5_checksum_st { + ASN1_INTEGER *ctype; + ASN1_OCTET_STRING *checksum; +} KRB5_CHECKSUM; + +DECLARE_STACK_OF(KRB5_CHECKSUM) + +/*- EncryptionKey ::= SEQUENCE { + * keytype[0] INTEGER, + * keyvalue[1] OCTET STRING + * } + */ +typedef struct krb5_encryptionkey_st { + ASN1_INTEGER *ktype; + ASN1_OCTET_STRING *keyvalue; +} KRB5_ENCKEY; + +DECLARE_STACK_OF(KRB5_ENCKEY) + +/*- AuthorizationData ::= SEQUENCE OF SEQUENCE { + * ad-type[0] INTEGER, + * ad-data[1] OCTET STRING + * } + */ +typedef struct krb5_authorization_st { + ASN1_INTEGER *adtype; + ASN1_OCTET_STRING *addata; +} KRB5_AUTHDATA; + +DECLARE_STACK_OF(KRB5_AUTHDATA) + +/*- -- Unencrypted authenticator + * Authenticator ::= [APPLICATION 2] SEQUENCE { + * authenticator-vno[0] INTEGER, + * crealm[1] Realm, + * cname[2] PrincipalName, + * cksum[3] Checksum OPTIONAL, + * cusec[4] INTEGER, + * ctime[5] KerberosTime, + * subkey[6] EncryptionKey OPTIONAL, + * seq-number[7] INTEGER OPTIONAL, + * authorization-data[8] AuthorizationData OPTIONAL + * } + */ +typedef struct krb5_authenticator_st { + ASN1_INTEGER *avno; + ASN1_GENERALSTRING *crealm; + KRB5_PRINCNAME *cname; + KRB5_CHECKSUM *cksum; + ASN1_INTEGER *cusec; + ASN1_GENERALIZEDTIME *ctime; + KRB5_ENCKEY *subkey; + ASN1_INTEGER *seqnum; + KRB5_AUTHDATA *authorization; +} KRB5_AUTHENTBODY; + +typedef STACK_OF(KRB5_AUTHENTBODY) KRB5_AUTHENT; +DECLARE_STACK_OF(KRB5_AUTHENTBODY) + +/*- DECLARE_ASN1_FUNCTIONS(type) = DECLARE_ASN1_FUNCTIONS_name(type, type) = + * type *name##_new(void); + * void name##_free(type *a); + * DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name) = + * DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) = + * type *d2i_##name(type **a, const unsigned char **in, long len); + * int i2d_##name(type *a, unsigned char **out); + * DECLARE_ASN1_ITEM(itname) = OPENSSL_EXTERN const ASN1_ITEM itname##_it + */ + +DECLARE_ASN1_FUNCTIONS(KRB5_ENCDATA) +DECLARE_ASN1_FUNCTIONS(KRB5_PRINCNAME) +DECLARE_ASN1_FUNCTIONS(KRB5_TKTBODY) +DECLARE_ASN1_FUNCTIONS(KRB5_APREQBODY) +DECLARE_ASN1_FUNCTIONS(KRB5_TICKET) +DECLARE_ASN1_FUNCTIONS(KRB5_APREQ) + +DECLARE_ASN1_FUNCTIONS(KRB5_CHECKSUM) +DECLARE_ASN1_FUNCTIONS(KRB5_ENCKEY) +DECLARE_ASN1_FUNCTIONS(KRB5_AUTHDATA) +DECLARE_ASN1_FUNCTIONS(KRB5_AUTHENTBODY) +DECLARE_ASN1_FUNCTIONS(KRB5_AUTHENT) + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/kssl.h b/OSlibs/ios/include/openssl/kssl.h new file mode 100755 index 000000000..ae8a51f47 --- /dev/null +++ b/OSlibs/ios/include/openssl/kssl.h @@ -0,0 +1,197 @@ +/* ssl/kssl.h */ +/* + * Written by Vern Staats for the OpenSSL project + * 2000. project 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + ** 19990701 VRS Started. + */ + +#ifndef KSSL_H +# define KSSL_H + +# include + +# ifndef OPENSSL_NO_KRB5 + +# include +# include +# include +# ifdef OPENSSL_SYS_WIN32 +/* + * These can sometimes get redefined indirectly by krb5 header files after + * they get undefed in ossl_typ.h + */ +# undef X509_NAME +# undef X509_EXTENSIONS +# undef OCSP_REQUEST +# undef OCSP_RESPONSE +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Depending on which KRB5 implementation used, some types from + * the other may be missing. Resolve that here and now + */ +# ifdef KRB5_HEIMDAL +typedef unsigned char krb5_octet; +# define FAR +# else + +# ifndef FAR +# define FAR +# endif + +# endif + +/*- + * Uncomment this to debug kssl problems or + * to trace usage of the Kerberos session key + * + * #define KSSL_DEBUG + */ + +# ifndef KRB5SVC +# define KRB5SVC "host" +# endif + +# ifndef KRB5KEYTAB +# define KRB5KEYTAB "/etc/krb5.keytab" +# endif + +# ifndef KRB5SENDAUTH +# define KRB5SENDAUTH 1 +# endif + +# ifndef KRB5CHECKAUTH +# define KRB5CHECKAUTH 1 +# endif + +# ifndef KSSL_CLOCKSKEW +# define KSSL_CLOCKSKEW 300; +# endif + +# define KSSL_ERR_MAX 255 +typedef struct kssl_err_st { + int reason; + char text[KSSL_ERR_MAX + 1]; +} KSSL_ERR; + +/*- Context for passing + * (1) Kerberos session key to SSL, and + * (2) Config data between application and SSL lib + */ +typedef struct kssl_ctx_st { + /* used by: disposition: */ + char *service_name; /* C,S default ok (kssl) */ + char *service_host; /* C input, REQUIRED */ + char *client_princ; /* S output from krb5 ticket */ + char *keytab_file; /* S NULL (/etc/krb5.keytab) */ + char *cred_cache; /* C NULL (default) */ + krb5_enctype enctype; + int length; + krb5_octet FAR *key; +} KSSL_CTX; + +# define KSSL_CLIENT 1 +# define KSSL_SERVER 2 +# define KSSL_SERVICE 3 +# define KSSL_KEYTAB 4 + +# define KSSL_CTX_OK 0 +# define KSSL_CTX_ERR 1 +# define KSSL_NOMEM 2 + +/* Public (for use by applications that use OpenSSL with Kerberos 5 support */ +krb5_error_code kssl_ctx_setstring(KSSL_CTX *kssl_ctx, int which, char *text); +KSSL_CTX *kssl_ctx_new(void); +KSSL_CTX *kssl_ctx_free(KSSL_CTX *kssl_ctx); +void kssl_ctx_show(KSSL_CTX *kssl_ctx); +krb5_error_code kssl_ctx_setprinc(KSSL_CTX *kssl_ctx, int which, + krb5_data *realm, krb5_data *entity, + int nentities); +krb5_error_code kssl_cget_tkt(KSSL_CTX *kssl_ctx, krb5_data **enc_tktp, + krb5_data *authenp, KSSL_ERR *kssl_err); +krb5_error_code kssl_sget_tkt(KSSL_CTX *kssl_ctx, krb5_data *indata, + krb5_ticket_times *ttimes, KSSL_ERR *kssl_err); +krb5_error_code kssl_ctx_setkey(KSSL_CTX *kssl_ctx, krb5_keyblock *session); +void kssl_err_set(KSSL_ERR *kssl_err, int reason, char *text); +void kssl_krb5_free_data_contents(krb5_context context, krb5_data *data); +krb5_error_code kssl_build_principal_2(krb5_context context, + krb5_principal *princ, int rlen, + const char *realm, int slen, + const char *svc, int hlen, + const char *host); +krb5_error_code kssl_validate_times(krb5_timestamp atime, + krb5_ticket_times *ttimes); +krb5_error_code kssl_check_authent(KSSL_CTX *kssl_ctx, krb5_data *authentp, + krb5_timestamp *atimep, + KSSL_ERR *kssl_err); +unsigned char *kssl_skip_confound(krb5_enctype enctype, unsigned char *authn); + +void SSL_set0_kssl_ctx(SSL *s, KSSL_CTX *kctx); +KSSL_CTX *SSL_get0_kssl_ctx(SSL *s); +char *kssl_ctx_get0_client_princ(KSSL_CTX *kctx); + +#ifdef __cplusplus +} +#endif +# endif /* OPENSSL_NO_KRB5 */ +#endif /* KSSL_H */ diff --git a/OSlibs/ios/include/openssl/lhash.h b/OSlibs/ios/include/openssl/lhash.h new file mode 100755 index 000000000..b6c328bff --- /dev/null +++ b/OSlibs/ios/include/openssl/lhash.h @@ -0,0 +1,240 @@ +/* crypto/lhash/lhash.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* + * Header for dynamic hash table routines Author - Eric Young + */ + +#ifndef HEADER_LHASH_H +# define HEADER_LHASH_H + +# include +# ifndef OPENSSL_NO_FP_API +# include +# endif + +# ifndef OPENSSL_NO_BIO +# include +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct lhash_node_st { + void *data; + struct lhash_node_st *next; +# ifndef OPENSSL_NO_HASH_COMP + unsigned long hash; +# endif +} LHASH_NODE; + +typedef int (*LHASH_COMP_FN_TYPE) (const void *, const void *); +typedef unsigned long (*LHASH_HASH_FN_TYPE) (const void *); +typedef void (*LHASH_DOALL_FN_TYPE) (void *); +typedef void (*LHASH_DOALL_ARG_FN_TYPE) (void *, void *); + +/* + * Macros for declaring and implementing type-safe wrappers for LHASH + * callbacks. This way, callbacks can be provided to LHASH structures without + * function pointer casting and the macro-defined callbacks provide + * per-variable casting before deferring to the underlying type-specific + * callbacks. NB: It is possible to place a "static" in front of both the + * DECLARE and IMPLEMENT macros if the functions are strictly internal. + */ + +/* First: "hash" functions */ +# define DECLARE_LHASH_HASH_FN(name, o_type) \ + unsigned long name##_LHASH_HASH(const void *); +# define IMPLEMENT_LHASH_HASH_FN(name, o_type) \ + unsigned long name##_LHASH_HASH(const void *arg) { \ + const o_type *a = arg; \ + return name##_hash(a); } +# define LHASH_HASH_FN(name) name##_LHASH_HASH + +/* Second: "compare" functions */ +# define DECLARE_LHASH_COMP_FN(name, o_type) \ + int name##_LHASH_COMP(const void *, const void *); +# define IMPLEMENT_LHASH_COMP_FN(name, o_type) \ + int name##_LHASH_COMP(const void *arg1, const void *arg2) { \ + const o_type *a = arg1; \ + const o_type *b = arg2; \ + return name##_cmp(a,b); } +# define LHASH_COMP_FN(name) name##_LHASH_COMP + +/* Third: "doall" functions */ +# define DECLARE_LHASH_DOALL_FN(name, o_type) \ + void name##_LHASH_DOALL(void *); +# define IMPLEMENT_LHASH_DOALL_FN(name, o_type) \ + void name##_LHASH_DOALL(void *arg) { \ + o_type *a = arg; \ + name##_doall(a); } +# define LHASH_DOALL_FN(name) name##_LHASH_DOALL + +/* Fourth: "doall_arg" functions */ +# define DECLARE_LHASH_DOALL_ARG_FN(name, o_type, a_type) \ + void name##_LHASH_DOALL_ARG(void *, void *); +# define IMPLEMENT_LHASH_DOALL_ARG_FN(name, o_type, a_type) \ + void name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \ + o_type *a = arg1; \ + a_type *b = arg2; \ + name##_doall_arg(a, b); } +# define LHASH_DOALL_ARG_FN(name) name##_LHASH_DOALL_ARG + +typedef struct lhash_st { + LHASH_NODE **b; + LHASH_COMP_FN_TYPE comp; + LHASH_HASH_FN_TYPE hash; + unsigned int num_nodes; + unsigned int num_alloc_nodes; + unsigned int p; + unsigned int pmax; + unsigned long up_load; /* load times 256 */ + unsigned long down_load; /* load times 256 */ + unsigned long num_items; + unsigned long num_expands; + unsigned long num_expand_reallocs; + unsigned long num_contracts; + unsigned long num_contract_reallocs; + unsigned long num_hash_calls; + unsigned long num_comp_calls; + unsigned long num_insert; + unsigned long num_replace; + unsigned long num_delete; + unsigned long num_no_delete; + unsigned long num_retrieve; + unsigned long num_retrieve_miss; + unsigned long num_hash_comps; + int error; +} _LHASH; /* Do not use _LHASH directly, use LHASH_OF + * and friends */ + +# define LH_LOAD_MULT 256 + +/* + * Indicates a malloc() error in the last call, this is only bad in + * lh_insert(). + */ +# define lh_error(lh) ((lh)->error) + +_LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c); +void lh_free(_LHASH *lh); +void *lh_insert(_LHASH *lh, void *data); +void *lh_delete(_LHASH *lh, const void *data); +void *lh_retrieve(_LHASH *lh, const void *data); +void lh_doall(_LHASH *lh, LHASH_DOALL_FN_TYPE func); +void lh_doall_arg(_LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg); +unsigned long lh_strhash(const char *c); +unsigned long lh_num_items(const _LHASH *lh); + +# ifndef OPENSSL_NO_FP_API +void lh_stats(const _LHASH *lh, FILE *out); +void lh_node_stats(const _LHASH *lh, FILE *out); +void lh_node_usage_stats(const _LHASH *lh, FILE *out); +# endif + +# ifndef OPENSSL_NO_BIO +void lh_stats_bio(const _LHASH *lh, BIO *out); +void lh_node_stats_bio(const _LHASH *lh, BIO *out); +void lh_node_usage_stats_bio(const _LHASH *lh, BIO *out); +# endif + +/* Type checking... */ + +# define LHASH_OF(type) struct lhash_st_##type + +# define DECLARE_LHASH_OF(type) LHASH_OF(type) { int dummy; } + +# define CHECKED_LHASH_OF(type,lh) \ + ((_LHASH *)CHECKED_PTR_OF(LHASH_OF(type),lh)) + +/* Define wrapper functions. */ +# define LHM_lh_new(type, name) \ + ((LHASH_OF(type) *)lh_new(LHASH_HASH_FN(name), LHASH_COMP_FN(name))) +# define LHM_lh_error(type, lh) \ + lh_error(CHECKED_LHASH_OF(type,lh)) +# define LHM_lh_insert(type, lh, inst) \ + ((type *)lh_insert(CHECKED_LHASH_OF(type, lh), \ + CHECKED_PTR_OF(type, inst))) +# define LHM_lh_retrieve(type, lh, inst) \ + ((type *)lh_retrieve(CHECKED_LHASH_OF(type, lh), \ + CHECKED_PTR_OF(type, inst))) +# define LHM_lh_delete(type, lh, inst) \ + ((type *)lh_delete(CHECKED_LHASH_OF(type, lh), \ + CHECKED_PTR_OF(type, inst))) +# define LHM_lh_doall(type, lh,fn) lh_doall(CHECKED_LHASH_OF(type, lh), fn) +# define LHM_lh_doall_arg(type, lh, fn, arg_type, arg) \ + lh_doall_arg(CHECKED_LHASH_OF(type, lh), fn, CHECKED_PTR_OF(arg_type, arg)) +# define LHM_lh_num_items(type, lh) lh_num_items(CHECKED_LHASH_OF(type, lh)) +# define LHM_lh_down_load(type, lh) (CHECKED_LHASH_OF(type, lh)->down_load) +# define LHM_lh_node_stats_bio(type, lh, out) \ + lh_node_stats_bio(CHECKED_LHASH_OF(type, lh), out) +# define LHM_lh_node_usage_stats_bio(type, lh, out) \ + lh_node_usage_stats_bio(CHECKED_LHASH_OF(type, lh), out) +# define LHM_lh_stats_bio(type, lh, out) \ + lh_stats_bio(CHECKED_LHASH_OF(type, lh), out) +# define LHM_lh_free(type, lh) lh_free(CHECKED_LHASH_OF(type, lh)) + +DECLARE_LHASH_OF(OPENSSL_STRING); +DECLARE_LHASH_OF(OPENSSL_CSTRING); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/OSlibs/ios/include/openssl/md4.h b/OSlibs/ios/include/openssl/md4.h new file mode 100755 index 000000000..11fd71295 --- /dev/null +++ b/OSlibs/ios/include/openssl/md4.h @@ -0,0 +1,119 @@ +/* crypto/md4/md4.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_MD4_H +# define HEADER_MD4_H + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# ifdef OPENSSL_NO_MD4 +# error MD4 is disabled. +# endif + +/*- + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! MD4_LONG has to be at least 32 bits wide. If it's wider, then ! + * ! MD4_LONG_LOG2 has to be defined along. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ + +# if defined(__LP32__) +# define MD4_LONG unsigned long +# elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__) +# define MD4_LONG unsigned long +# define MD4_LONG_LOG2 3 +/* + * _CRAY note. I could declare short, but I have no idea what impact + * does it have on performance on none-T3E machines. I could declare + * int, but at least on C90 sizeof(int) can be chosen at compile time. + * So I've chosen long... + * + */ +# else +# define MD4_LONG unsigned int +# endif + +# define MD4_CBLOCK 64 +# define MD4_LBLOCK (MD4_CBLOCK/4) +# define MD4_DIGEST_LENGTH 16 + +typedef struct MD4state_st { + MD4_LONG A, B, C, D; + MD4_LONG Nl, Nh; + MD4_LONG data[MD4_LBLOCK]; + unsigned int num; +} MD4_CTX; + +# ifdef OPENSSL_FIPS +int private_MD4_Init(MD4_CTX *c); +# endif +int MD4_Init(MD4_CTX *c); +int MD4_Update(MD4_CTX *c, const void *data, size_t len); +int MD4_Final(unsigned char *md, MD4_CTX *c); +unsigned char *MD4(const unsigned char *d, size_t n, unsigned char *md); +void MD4_Transform(MD4_CTX *c, const unsigned char *b); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/OSlibs/ios/include/openssl/md5.h b/OSlibs/ios/include/openssl/md5.h new file mode 100755 index 000000000..2659038ab --- /dev/null +++ b/OSlibs/ios/include/openssl/md5.h @@ -0,0 +1,119 @@ +/* crypto/md5/md5.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_MD5_H +# define HEADER_MD5_H + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# ifdef OPENSSL_NO_MD5 +# error MD5 is disabled. +# endif + +/* + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! MD5_LONG has to be at least 32 bits wide. If it's wider, then ! + * ! MD5_LONG_LOG2 has to be defined along. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ + +# if defined(__LP32__) +# define MD5_LONG unsigned long +# elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__) +# define MD5_LONG unsigned long +# define MD5_LONG_LOG2 3 +/* + * _CRAY note. I could declare short, but I have no idea what impact + * does it have on performance on none-T3E machines. I could declare + * int, but at least on C90 sizeof(int) can be chosen at compile time. + * So I've chosen long... + * + */ +# else +# define MD5_LONG unsigned int +# endif + +# define MD5_CBLOCK 64 +# define MD5_LBLOCK (MD5_CBLOCK/4) +# define MD5_DIGEST_LENGTH 16 + +typedef struct MD5state_st { + MD5_LONG A, B, C, D; + MD5_LONG Nl, Nh; + MD5_LONG data[MD5_LBLOCK]; + unsigned int num; +} MD5_CTX; + +# ifdef OPENSSL_FIPS +int private_MD5_Init(MD5_CTX *c); +# endif +int MD5_Init(MD5_CTX *c); +int MD5_Update(MD5_CTX *c, const void *data, size_t len); +int MD5_Final(unsigned char *md, MD5_CTX *c); +unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md); +void MD5_Transform(MD5_CTX *c, const unsigned char *b); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/OSlibs/ios/include/openssl/mdc2.h b/OSlibs/ios/include/openssl/mdc2.h new file mode 100755 index 000000000..7efe53bc2 --- /dev/null +++ b/OSlibs/ios/include/openssl/mdc2.h @@ -0,0 +1,94 @@ +/* crypto/mdc2/mdc2.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_MDC2_H +# define HEADER_MDC2_H + +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# ifdef OPENSSL_NO_MDC2 +# error MDC2 is disabled. +# endif + +# define MDC2_BLOCK 8 +# define MDC2_DIGEST_LENGTH 16 + +typedef struct mdc2_ctx_st { + unsigned int num; + unsigned char data[MDC2_BLOCK]; + DES_cblock h, hh; + int pad_type; /* either 1 or 2, default 1 */ +} MDC2_CTX; + +# ifdef OPENSSL_FIPS +int private_MDC2_Init(MDC2_CTX *c); +# endif +int MDC2_Init(MDC2_CTX *c); +int MDC2_Update(MDC2_CTX *c, const unsigned char *data, size_t len); +int MDC2_Final(unsigned char *md, MDC2_CTX *c); +unsigned char *MDC2(const unsigned char *d, size_t n, unsigned char *md); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/OSlibs/ios/include/openssl/modes.h b/OSlibs/ios/include/openssl/modes.h new file mode 100755 index 000000000..fd488499a --- /dev/null +++ b/OSlibs/ios/include/openssl/modes.h @@ -0,0 +1,163 @@ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Rights for redistribution and usage in source and binary + * forms are granted according to the OpenSSL license. + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif +typedef void (*block128_f) (const unsigned char in[16], + unsigned char out[16], const void *key); + +typedef void (*cbc128_f) (const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], int enc); + +typedef void (*ctr128_f) (const unsigned char *in, unsigned char *out, + size_t blocks, const void *key, + const unsigned char ivec[16]); + +typedef void (*ccm128_f) (const unsigned char *in, unsigned char *out, + size_t blocks, const void *key, + const unsigned char ivec[16], + unsigned char cmac[16]); + +void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], block128_f block); +void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], block128_f block); + +void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], + unsigned char ecount_buf[16], unsigned int *num, + block128_f block); + +void CRYPTO_ctr128_encrypt_ctr32(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], + unsigned char ecount_buf[16], + unsigned int *num, ctr128_f ctr); + +void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], int *num, + block128_f block); + +void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], int *num, + int enc, block128_f block); +void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const void *key, + unsigned char ivec[16], int *num, + int enc, block128_f block); +void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out, + size_t bits, const void *key, + unsigned char ivec[16], int *num, + int enc, block128_f block); + +size_t CRYPTO_cts128_encrypt_block(const unsigned char *in, + unsigned char *out, size_t len, + const void *key, unsigned char ivec[16], + block128_f block); +size_t CRYPTO_cts128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], cbc128_f cbc); +size_t CRYPTO_cts128_decrypt_block(const unsigned char *in, + unsigned char *out, size_t len, + const void *key, unsigned char ivec[16], + block128_f block); +size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], cbc128_f cbc); + +size_t CRYPTO_nistcts128_encrypt_block(const unsigned char *in, + unsigned char *out, size_t len, + const void *key, + unsigned char ivec[16], + block128_f block); +size_t CRYPTO_nistcts128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], cbc128_f cbc); +size_t CRYPTO_nistcts128_decrypt_block(const unsigned char *in, + unsigned char *out, size_t len, + const void *key, + unsigned char ivec[16], + block128_f block); +size_t CRYPTO_nistcts128_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], cbc128_f cbc); + +typedef struct gcm128_context GCM128_CONTEXT; + +GCM128_CONTEXT *CRYPTO_gcm128_new(void *key, block128_f block); +void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key, block128_f block); +void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const unsigned char *iv, + size_t len); +int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const unsigned char *aad, + size_t len); +int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len); +int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len); +int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len, ctr128_f stream); +int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len, ctr128_f stream); +int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const unsigned char *tag, + size_t len); +void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, unsigned char *tag, size_t len); +void CRYPTO_gcm128_release(GCM128_CONTEXT *ctx); + +typedef struct ccm128_context CCM128_CONTEXT; + +void CRYPTO_ccm128_init(CCM128_CONTEXT *ctx, + unsigned int M, unsigned int L, void *key, + block128_f block); +int CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx, const unsigned char *nonce, + size_t nlen, size_t mlen); +void CRYPTO_ccm128_aad(CCM128_CONTEXT *ctx, const unsigned char *aad, + size_t alen); +int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx, const unsigned char *inp, + unsigned char *out, size_t len); +int CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx, const unsigned char *inp, + unsigned char *out, size_t len); +int CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT *ctx, const unsigned char *inp, + unsigned char *out, size_t len, + ccm128_f stream); +int CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT *ctx, const unsigned char *inp, + unsigned char *out, size_t len, + ccm128_f stream); +size_t CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx, unsigned char *tag, size_t len); + +typedef struct xts128_context XTS128_CONTEXT; + +int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, + const unsigned char iv[16], + const unsigned char *inp, unsigned char *out, + size_t len, int enc); + +size_t CRYPTO_128_wrap(void *key, const unsigned char *iv, + unsigned char *out, + const unsigned char *in, size_t inlen, + block128_f block); + +size_t CRYPTO_128_unwrap(void *key, const unsigned char *iv, + unsigned char *out, + const unsigned char *in, size_t inlen, + block128_f block); + +#ifdef __cplusplus +} +#endif diff --git a/OSlibs/ios/include/openssl/obj_mac.h b/OSlibs/ios/include/openssl/obj_mac.h new file mode 100755 index 000000000..779c309b8 --- /dev/null +++ b/OSlibs/ios/include/openssl/obj_mac.h @@ -0,0 +1,4194 @@ +/* crypto/objects/obj_mac.h */ + +/* + * THIS FILE IS GENERATED FROM objects.txt by objects.pl via the following + * command: perl objects.pl objects.txt obj_mac.num obj_mac.h + */ + +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#define SN_undef "UNDEF" +#define LN_undef "undefined" +#define NID_undef 0 +#define OBJ_undef 0L + +#define SN_itu_t "ITU-T" +#define LN_itu_t "itu-t" +#define NID_itu_t 645 +#define OBJ_itu_t 0L + +#define NID_ccitt 404 +#define OBJ_ccitt OBJ_itu_t + +#define SN_iso "ISO" +#define LN_iso "iso" +#define NID_iso 181 +#define OBJ_iso 1L + +#define SN_joint_iso_itu_t "JOINT-ISO-ITU-T" +#define LN_joint_iso_itu_t "joint-iso-itu-t" +#define NID_joint_iso_itu_t 646 +#define OBJ_joint_iso_itu_t 2L + +#define NID_joint_iso_ccitt 393 +#define OBJ_joint_iso_ccitt OBJ_joint_iso_itu_t + +#define SN_member_body "member-body" +#define LN_member_body "ISO Member Body" +#define NID_member_body 182 +#define OBJ_member_body OBJ_iso,2L + +#define SN_identified_organization "identified-organization" +#define NID_identified_organization 676 +#define OBJ_identified_organization OBJ_iso,3L + +#define SN_hmac_md5 "HMAC-MD5" +#define LN_hmac_md5 "hmac-md5" +#define NID_hmac_md5 780 +#define OBJ_hmac_md5 OBJ_identified_organization,6L,1L,5L,5L,8L,1L,1L + +#define SN_hmac_sha1 "HMAC-SHA1" +#define LN_hmac_sha1 "hmac-sha1" +#define NID_hmac_sha1 781 +#define OBJ_hmac_sha1 OBJ_identified_organization,6L,1L,5L,5L,8L,1L,2L + +#define SN_certicom_arc "certicom-arc" +#define NID_certicom_arc 677 +#define OBJ_certicom_arc OBJ_identified_organization,132L + +#define SN_international_organizations "international-organizations" +#define LN_international_organizations "International Organizations" +#define NID_international_organizations 647 +#define OBJ_international_organizations OBJ_joint_iso_itu_t,23L + +#define SN_wap "wap" +#define NID_wap 678 +#define OBJ_wap OBJ_international_organizations,43L + +#define SN_wap_wsg "wap-wsg" +#define NID_wap_wsg 679 +#define OBJ_wap_wsg OBJ_wap,1L + +#define SN_selected_attribute_types "selected-attribute-types" +#define LN_selected_attribute_types "Selected Attribute Types" +#define NID_selected_attribute_types 394 +#define OBJ_selected_attribute_types OBJ_joint_iso_itu_t,5L,1L,5L + +#define SN_clearance "clearance" +#define NID_clearance 395 +#define OBJ_clearance OBJ_selected_attribute_types,55L + +#define SN_ISO_US "ISO-US" +#define LN_ISO_US "ISO US Member Body" +#define NID_ISO_US 183 +#define OBJ_ISO_US OBJ_member_body,840L + +#define SN_X9_57 "X9-57" +#define LN_X9_57 "X9.57" +#define NID_X9_57 184 +#define OBJ_X9_57 OBJ_ISO_US,10040L + +#define SN_X9cm "X9cm" +#define LN_X9cm "X9.57 CM ?" +#define NID_X9cm 185 +#define OBJ_X9cm OBJ_X9_57,4L + +#define SN_dsa "DSA" +#define LN_dsa "dsaEncryption" +#define NID_dsa 116 +#define OBJ_dsa OBJ_X9cm,1L + +#define SN_dsaWithSHA1 "DSA-SHA1" +#define LN_dsaWithSHA1 "dsaWithSHA1" +#define NID_dsaWithSHA1 113 +#define OBJ_dsaWithSHA1 OBJ_X9cm,3L + +#define SN_ansi_X9_62 "ansi-X9-62" +#define LN_ansi_X9_62 "ANSI X9.62" +#define NID_ansi_X9_62 405 +#define OBJ_ansi_X9_62 OBJ_ISO_US,10045L + +#define OBJ_X9_62_id_fieldType OBJ_ansi_X9_62,1L + +#define SN_X9_62_prime_field "prime-field" +#define NID_X9_62_prime_field 406 +#define OBJ_X9_62_prime_field OBJ_X9_62_id_fieldType,1L + +#define SN_X9_62_characteristic_two_field "characteristic-two-field" +#define NID_X9_62_characteristic_two_field 407 +#define OBJ_X9_62_characteristic_two_field OBJ_X9_62_id_fieldType,2L + +#define SN_X9_62_id_characteristic_two_basis "id-characteristic-two-basis" +#define NID_X9_62_id_characteristic_two_basis 680 +#define OBJ_X9_62_id_characteristic_two_basis OBJ_X9_62_characteristic_two_field,3L + +#define SN_X9_62_onBasis "onBasis" +#define NID_X9_62_onBasis 681 +#define OBJ_X9_62_onBasis OBJ_X9_62_id_characteristic_two_basis,1L + +#define SN_X9_62_tpBasis "tpBasis" +#define NID_X9_62_tpBasis 682 +#define OBJ_X9_62_tpBasis OBJ_X9_62_id_characteristic_two_basis,2L + +#define SN_X9_62_ppBasis "ppBasis" +#define NID_X9_62_ppBasis 683 +#define OBJ_X9_62_ppBasis OBJ_X9_62_id_characteristic_two_basis,3L + +#define OBJ_X9_62_id_publicKeyType OBJ_ansi_X9_62,2L + +#define SN_X9_62_id_ecPublicKey "id-ecPublicKey" +#define NID_X9_62_id_ecPublicKey 408 +#define OBJ_X9_62_id_ecPublicKey OBJ_X9_62_id_publicKeyType,1L + +#define OBJ_X9_62_ellipticCurve OBJ_ansi_X9_62,3L + +#define OBJ_X9_62_c_TwoCurve OBJ_X9_62_ellipticCurve,0L + +#define SN_X9_62_c2pnb163v1 "c2pnb163v1" +#define NID_X9_62_c2pnb163v1 684 +#define OBJ_X9_62_c2pnb163v1 OBJ_X9_62_c_TwoCurve,1L + +#define SN_X9_62_c2pnb163v2 "c2pnb163v2" +#define NID_X9_62_c2pnb163v2 685 +#define OBJ_X9_62_c2pnb163v2 OBJ_X9_62_c_TwoCurve,2L + +#define SN_X9_62_c2pnb163v3 "c2pnb163v3" +#define NID_X9_62_c2pnb163v3 686 +#define OBJ_X9_62_c2pnb163v3 OBJ_X9_62_c_TwoCurve,3L + +#define SN_X9_62_c2pnb176v1 "c2pnb176v1" +#define NID_X9_62_c2pnb176v1 687 +#define OBJ_X9_62_c2pnb176v1 OBJ_X9_62_c_TwoCurve,4L + +#define SN_X9_62_c2tnb191v1 "c2tnb191v1" +#define NID_X9_62_c2tnb191v1 688 +#define OBJ_X9_62_c2tnb191v1 OBJ_X9_62_c_TwoCurve,5L + +#define SN_X9_62_c2tnb191v2 "c2tnb191v2" +#define NID_X9_62_c2tnb191v2 689 +#define OBJ_X9_62_c2tnb191v2 OBJ_X9_62_c_TwoCurve,6L + +#define SN_X9_62_c2tnb191v3 "c2tnb191v3" +#define NID_X9_62_c2tnb191v3 690 +#define OBJ_X9_62_c2tnb191v3 OBJ_X9_62_c_TwoCurve,7L + +#define SN_X9_62_c2onb191v4 "c2onb191v4" +#define NID_X9_62_c2onb191v4 691 +#define OBJ_X9_62_c2onb191v4 OBJ_X9_62_c_TwoCurve,8L + +#define SN_X9_62_c2onb191v5 "c2onb191v5" +#define NID_X9_62_c2onb191v5 692 +#define OBJ_X9_62_c2onb191v5 OBJ_X9_62_c_TwoCurve,9L + +#define SN_X9_62_c2pnb208w1 "c2pnb208w1" +#define NID_X9_62_c2pnb208w1 693 +#define OBJ_X9_62_c2pnb208w1 OBJ_X9_62_c_TwoCurve,10L + +#define SN_X9_62_c2tnb239v1 "c2tnb239v1" +#define NID_X9_62_c2tnb239v1 694 +#define OBJ_X9_62_c2tnb239v1 OBJ_X9_62_c_TwoCurve,11L + +#define SN_X9_62_c2tnb239v2 "c2tnb239v2" +#define NID_X9_62_c2tnb239v2 695 +#define OBJ_X9_62_c2tnb239v2 OBJ_X9_62_c_TwoCurve,12L + +#define SN_X9_62_c2tnb239v3 "c2tnb239v3" +#define NID_X9_62_c2tnb239v3 696 +#define OBJ_X9_62_c2tnb239v3 OBJ_X9_62_c_TwoCurve,13L + +#define SN_X9_62_c2onb239v4 "c2onb239v4" +#define NID_X9_62_c2onb239v4 697 +#define OBJ_X9_62_c2onb239v4 OBJ_X9_62_c_TwoCurve,14L + +#define SN_X9_62_c2onb239v5 "c2onb239v5" +#define NID_X9_62_c2onb239v5 698 +#define OBJ_X9_62_c2onb239v5 OBJ_X9_62_c_TwoCurve,15L + +#define SN_X9_62_c2pnb272w1 "c2pnb272w1" +#define NID_X9_62_c2pnb272w1 699 +#define OBJ_X9_62_c2pnb272w1 OBJ_X9_62_c_TwoCurve,16L + +#define SN_X9_62_c2pnb304w1 "c2pnb304w1" +#define NID_X9_62_c2pnb304w1 700 +#define OBJ_X9_62_c2pnb304w1 OBJ_X9_62_c_TwoCurve,17L + +#define SN_X9_62_c2tnb359v1 "c2tnb359v1" +#define NID_X9_62_c2tnb359v1 701 +#define OBJ_X9_62_c2tnb359v1 OBJ_X9_62_c_TwoCurve,18L + +#define SN_X9_62_c2pnb368w1 "c2pnb368w1" +#define NID_X9_62_c2pnb368w1 702 +#define OBJ_X9_62_c2pnb368w1 OBJ_X9_62_c_TwoCurve,19L + +#define SN_X9_62_c2tnb431r1 "c2tnb431r1" +#define NID_X9_62_c2tnb431r1 703 +#define OBJ_X9_62_c2tnb431r1 OBJ_X9_62_c_TwoCurve,20L + +#define OBJ_X9_62_primeCurve OBJ_X9_62_ellipticCurve,1L + +#define SN_X9_62_prime192v1 "prime192v1" +#define NID_X9_62_prime192v1 409 +#define OBJ_X9_62_prime192v1 OBJ_X9_62_primeCurve,1L + +#define SN_X9_62_prime192v2 "prime192v2" +#define NID_X9_62_prime192v2 410 +#define OBJ_X9_62_prime192v2 OBJ_X9_62_primeCurve,2L + +#define SN_X9_62_prime192v3 "prime192v3" +#define NID_X9_62_prime192v3 411 +#define OBJ_X9_62_prime192v3 OBJ_X9_62_primeCurve,3L + +#define SN_X9_62_prime239v1 "prime239v1" +#define NID_X9_62_prime239v1 412 +#define OBJ_X9_62_prime239v1 OBJ_X9_62_primeCurve,4L + +#define SN_X9_62_prime239v2 "prime239v2" +#define NID_X9_62_prime239v2 413 +#define OBJ_X9_62_prime239v2 OBJ_X9_62_primeCurve,5L + +#define SN_X9_62_prime239v3 "prime239v3" +#define NID_X9_62_prime239v3 414 +#define OBJ_X9_62_prime239v3 OBJ_X9_62_primeCurve,6L + +#define SN_X9_62_prime256v1 "prime256v1" +#define NID_X9_62_prime256v1 415 +#define OBJ_X9_62_prime256v1 OBJ_X9_62_primeCurve,7L + +#define OBJ_X9_62_id_ecSigType OBJ_ansi_X9_62,4L + +#define SN_ecdsa_with_SHA1 "ecdsa-with-SHA1" +#define NID_ecdsa_with_SHA1 416 +#define OBJ_ecdsa_with_SHA1 OBJ_X9_62_id_ecSigType,1L + +#define SN_ecdsa_with_Recommended "ecdsa-with-Recommended" +#define NID_ecdsa_with_Recommended 791 +#define OBJ_ecdsa_with_Recommended OBJ_X9_62_id_ecSigType,2L + +#define SN_ecdsa_with_Specified "ecdsa-with-Specified" +#define NID_ecdsa_with_Specified 792 +#define OBJ_ecdsa_with_Specified OBJ_X9_62_id_ecSigType,3L + +#define SN_ecdsa_with_SHA224 "ecdsa-with-SHA224" +#define NID_ecdsa_with_SHA224 793 +#define OBJ_ecdsa_with_SHA224 OBJ_ecdsa_with_Specified,1L + +#define SN_ecdsa_with_SHA256 "ecdsa-with-SHA256" +#define NID_ecdsa_with_SHA256 794 +#define OBJ_ecdsa_with_SHA256 OBJ_ecdsa_with_Specified,2L + +#define SN_ecdsa_with_SHA384 "ecdsa-with-SHA384" +#define NID_ecdsa_with_SHA384 795 +#define OBJ_ecdsa_with_SHA384 OBJ_ecdsa_with_Specified,3L + +#define SN_ecdsa_with_SHA512 "ecdsa-with-SHA512" +#define NID_ecdsa_with_SHA512 796 +#define OBJ_ecdsa_with_SHA512 OBJ_ecdsa_with_Specified,4L + +#define OBJ_secg_ellipticCurve OBJ_certicom_arc,0L + +#define SN_secp112r1 "secp112r1" +#define NID_secp112r1 704 +#define OBJ_secp112r1 OBJ_secg_ellipticCurve,6L + +#define SN_secp112r2 "secp112r2" +#define NID_secp112r2 705 +#define OBJ_secp112r2 OBJ_secg_ellipticCurve,7L + +#define SN_secp128r1 "secp128r1" +#define NID_secp128r1 706 +#define OBJ_secp128r1 OBJ_secg_ellipticCurve,28L + +#define SN_secp128r2 "secp128r2" +#define NID_secp128r2 707 +#define OBJ_secp128r2 OBJ_secg_ellipticCurve,29L + +#define SN_secp160k1 "secp160k1" +#define NID_secp160k1 708 +#define OBJ_secp160k1 OBJ_secg_ellipticCurve,9L + +#define SN_secp160r1 "secp160r1" +#define NID_secp160r1 709 +#define OBJ_secp160r1 OBJ_secg_ellipticCurve,8L + +#define SN_secp160r2 "secp160r2" +#define NID_secp160r2 710 +#define OBJ_secp160r2 OBJ_secg_ellipticCurve,30L + +#define SN_secp192k1 "secp192k1" +#define NID_secp192k1 711 +#define OBJ_secp192k1 OBJ_secg_ellipticCurve,31L + +#define SN_secp224k1 "secp224k1" +#define NID_secp224k1 712 +#define OBJ_secp224k1 OBJ_secg_ellipticCurve,32L + +#define SN_secp224r1 "secp224r1" +#define NID_secp224r1 713 +#define OBJ_secp224r1 OBJ_secg_ellipticCurve,33L + +#define SN_secp256k1 "secp256k1" +#define NID_secp256k1 714 +#define OBJ_secp256k1 OBJ_secg_ellipticCurve,10L + +#define SN_secp384r1 "secp384r1" +#define NID_secp384r1 715 +#define OBJ_secp384r1 OBJ_secg_ellipticCurve,34L + +#define SN_secp521r1 "secp521r1" +#define NID_secp521r1 716 +#define OBJ_secp521r1 OBJ_secg_ellipticCurve,35L + +#define SN_sect113r1 "sect113r1" +#define NID_sect113r1 717 +#define OBJ_sect113r1 OBJ_secg_ellipticCurve,4L + +#define SN_sect113r2 "sect113r2" +#define NID_sect113r2 718 +#define OBJ_sect113r2 OBJ_secg_ellipticCurve,5L + +#define SN_sect131r1 "sect131r1" +#define NID_sect131r1 719 +#define OBJ_sect131r1 OBJ_secg_ellipticCurve,22L + +#define SN_sect131r2 "sect131r2" +#define NID_sect131r2 720 +#define OBJ_sect131r2 OBJ_secg_ellipticCurve,23L + +#define SN_sect163k1 "sect163k1" +#define NID_sect163k1 721 +#define OBJ_sect163k1 OBJ_secg_ellipticCurve,1L + +#define SN_sect163r1 "sect163r1" +#define NID_sect163r1 722 +#define OBJ_sect163r1 OBJ_secg_ellipticCurve,2L + +#define SN_sect163r2 "sect163r2" +#define NID_sect163r2 723 +#define OBJ_sect163r2 OBJ_secg_ellipticCurve,15L + +#define SN_sect193r1 "sect193r1" +#define NID_sect193r1 724 +#define OBJ_sect193r1 OBJ_secg_ellipticCurve,24L + +#define SN_sect193r2 "sect193r2" +#define NID_sect193r2 725 +#define OBJ_sect193r2 OBJ_secg_ellipticCurve,25L + +#define SN_sect233k1 "sect233k1" +#define NID_sect233k1 726 +#define OBJ_sect233k1 OBJ_secg_ellipticCurve,26L + +#define SN_sect233r1 "sect233r1" +#define NID_sect233r1 727 +#define OBJ_sect233r1 OBJ_secg_ellipticCurve,27L + +#define SN_sect239k1 "sect239k1" +#define NID_sect239k1 728 +#define OBJ_sect239k1 OBJ_secg_ellipticCurve,3L + +#define SN_sect283k1 "sect283k1" +#define NID_sect283k1 729 +#define OBJ_sect283k1 OBJ_secg_ellipticCurve,16L + +#define SN_sect283r1 "sect283r1" +#define NID_sect283r1 730 +#define OBJ_sect283r1 OBJ_secg_ellipticCurve,17L + +#define SN_sect409k1 "sect409k1" +#define NID_sect409k1 731 +#define OBJ_sect409k1 OBJ_secg_ellipticCurve,36L + +#define SN_sect409r1 "sect409r1" +#define NID_sect409r1 732 +#define OBJ_sect409r1 OBJ_secg_ellipticCurve,37L + +#define SN_sect571k1 "sect571k1" +#define NID_sect571k1 733 +#define OBJ_sect571k1 OBJ_secg_ellipticCurve,38L + +#define SN_sect571r1 "sect571r1" +#define NID_sect571r1 734 +#define OBJ_sect571r1 OBJ_secg_ellipticCurve,39L + +#define OBJ_wap_wsg_idm_ecid OBJ_wap_wsg,4L + +#define SN_wap_wsg_idm_ecid_wtls1 "wap-wsg-idm-ecid-wtls1" +#define NID_wap_wsg_idm_ecid_wtls1 735 +#define OBJ_wap_wsg_idm_ecid_wtls1 OBJ_wap_wsg_idm_ecid,1L + +#define SN_wap_wsg_idm_ecid_wtls3 "wap-wsg-idm-ecid-wtls3" +#define NID_wap_wsg_idm_ecid_wtls3 736 +#define OBJ_wap_wsg_idm_ecid_wtls3 OBJ_wap_wsg_idm_ecid,3L + +#define SN_wap_wsg_idm_ecid_wtls4 "wap-wsg-idm-ecid-wtls4" +#define NID_wap_wsg_idm_ecid_wtls4 737 +#define OBJ_wap_wsg_idm_ecid_wtls4 OBJ_wap_wsg_idm_ecid,4L + +#define SN_wap_wsg_idm_ecid_wtls5 "wap-wsg-idm-ecid-wtls5" +#define NID_wap_wsg_idm_ecid_wtls5 738 +#define OBJ_wap_wsg_idm_ecid_wtls5 OBJ_wap_wsg_idm_ecid,5L + +#define SN_wap_wsg_idm_ecid_wtls6 "wap-wsg-idm-ecid-wtls6" +#define NID_wap_wsg_idm_ecid_wtls6 739 +#define OBJ_wap_wsg_idm_ecid_wtls6 OBJ_wap_wsg_idm_ecid,6L + +#define SN_wap_wsg_idm_ecid_wtls7 "wap-wsg-idm-ecid-wtls7" +#define NID_wap_wsg_idm_ecid_wtls7 740 +#define OBJ_wap_wsg_idm_ecid_wtls7 OBJ_wap_wsg_idm_ecid,7L + +#define SN_wap_wsg_idm_ecid_wtls8 "wap-wsg-idm-ecid-wtls8" +#define NID_wap_wsg_idm_ecid_wtls8 741 +#define OBJ_wap_wsg_idm_ecid_wtls8 OBJ_wap_wsg_idm_ecid,8L + +#define SN_wap_wsg_idm_ecid_wtls9 "wap-wsg-idm-ecid-wtls9" +#define NID_wap_wsg_idm_ecid_wtls9 742 +#define OBJ_wap_wsg_idm_ecid_wtls9 OBJ_wap_wsg_idm_ecid,9L + +#define SN_wap_wsg_idm_ecid_wtls10 "wap-wsg-idm-ecid-wtls10" +#define NID_wap_wsg_idm_ecid_wtls10 743 +#define OBJ_wap_wsg_idm_ecid_wtls10 OBJ_wap_wsg_idm_ecid,10L + +#define SN_wap_wsg_idm_ecid_wtls11 "wap-wsg-idm-ecid-wtls11" +#define NID_wap_wsg_idm_ecid_wtls11 744 +#define OBJ_wap_wsg_idm_ecid_wtls11 OBJ_wap_wsg_idm_ecid,11L + +#define SN_wap_wsg_idm_ecid_wtls12 "wap-wsg-idm-ecid-wtls12" +#define NID_wap_wsg_idm_ecid_wtls12 745 +#define OBJ_wap_wsg_idm_ecid_wtls12 OBJ_wap_wsg_idm_ecid,12L + +#define SN_cast5_cbc "CAST5-CBC" +#define LN_cast5_cbc "cast5-cbc" +#define NID_cast5_cbc 108 +#define OBJ_cast5_cbc OBJ_ISO_US,113533L,7L,66L,10L + +#define SN_cast5_ecb "CAST5-ECB" +#define LN_cast5_ecb "cast5-ecb" +#define NID_cast5_ecb 109 + +#define SN_cast5_cfb64 "CAST5-CFB" +#define LN_cast5_cfb64 "cast5-cfb" +#define NID_cast5_cfb64 110 + +#define SN_cast5_ofb64 "CAST5-OFB" +#define LN_cast5_ofb64 "cast5-ofb" +#define NID_cast5_ofb64 111 + +#define LN_pbeWithMD5AndCast5_CBC "pbeWithMD5AndCast5CBC" +#define NID_pbeWithMD5AndCast5_CBC 112 +#define OBJ_pbeWithMD5AndCast5_CBC OBJ_ISO_US,113533L,7L,66L,12L + +#define SN_id_PasswordBasedMAC "id-PasswordBasedMAC" +#define LN_id_PasswordBasedMAC "password based MAC" +#define NID_id_PasswordBasedMAC 782 +#define OBJ_id_PasswordBasedMAC OBJ_ISO_US,113533L,7L,66L,13L + +#define SN_id_DHBasedMac "id-DHBasedMac" +#define LN_id_DHBasedMac "Diffie-Hellman based MAC" +#define NID_id_DHBasedMac 783 +#define OBJ_id_DHBasedMac OBJ_ISO_US,113533L,7L,66L,30L + +#define SN_rsadsi "rsadsi" +#define LN_rsadsi "RSA Data Security, Inc." +#define NID_rsadsi 1 +#define OBJ_rsadsi OBJ_ISO_US,113549L + +#define SN_pkcs "pkcs" +#define LN_pkcs "RSA Data Security, Inc. PKCS" +#define NID_pkcs 2 +#define OBJ_pkcs OBJ_rsadsi,1L + +#define SN_pkcs1 "pkcs1" +#define NID_pkcs1 186 +#define OBJ_pkcs1 OBJ_pkcs,1L + +#define LN_rsaEncryption "rsaEncryption" +#define NID_rsaEncryption 6 +#define OBJ_rsaEncryption OBJ_pkcs1,1L + +#define SN_md2WithRSAEncryption "RSA-MD2" +#define LN_md2WithRSAEncryption "md2WithRSAEncryption" +#define NID_md2WithRSAEncryption 7 +#define OBJ_md2WithRSAEncryption OBJ_pkcs1,2L + +#define SN_md4WithRSAEncryption "RSA-MD4" +#define LN_md4WithRSAEncryption "md4WithRSAEncryption" +#define NID_md4WithRSAEncryption 396 +#define OBJ_md4WithRSAEncryption OBJ_pkcs1,3L + +#define SN_md5WithRSAEncryption "RSA-MD5" +#define LN_md5WithRSAEncryption "md5WithRSAEncryption" +#define NID_md5WithRSAEncryption 8 +#define OBJ_md5WithRSAEncryption OBJ_pkcs1,4L + +#define SN_sha1WithRSAEncryption "RSA-SHA1" +#define LN_sha1WithRSAEncryption "sha1WithRSAEncryption" +#define NID_sha1WithRSAEncryption 65 +#define OBJ_sha1WithRSAEncryption OBJ_pkcs1,5L + +#define SN_rsaesOaep "RSAES-OAEP" +#define LN_rsaesOaep "rsaesOaep" +#define NID_rsaesOaep 919 +#define OBJ_rsaesOaep OBJ_pkcs1,7L + +#define SN_mgf1 "MGF1" +#define LN_mgf1 "mgf1" +#define NID_mgf1 911 +#define OBJ_mgf1 OBJ_pkcs1,8L + +#define SN_pSpecified "PSPECIFIED" +#define LN_pSpecified "pSpecified" +#define NID_pSpecified 935 +#define OBJ_pSpecified OBJ_pkcs1,9L + +#define SN_rsassaPss "RSASSA-PSS" +#define LN_rsassaPss "rsassaPss" +#define NID_rsassaPss 912 +#define OBJ_rsassaPss OBJ_pkcs1,10L + +#define SN_sha256WithRSAEncryption "RSA-SHA256" +#define LN_sha256WithRSAEncryption "sha256WithRSAEncryption" +#define NID_sha256WithRSAEncryption 668 +#define OBJ_sha256WithRSAEncryption OBJ_pkcs1,11L + +#define SN_sha384WithRSAEncryption "RSA-SHA384" +#define LN_sha384WithRSAEncryption "sha384WithRSAEncryption" +#define NID_sha384WithRSAEncryption 669 +#define OBJ_sha384WithRSAEncryption OBJ_pkcs1,12L + +#define SN_sha512WithRSAEncryption "RSA-SHA512" +#define LN_sha512WithRSAEncryption "sha512WithRSAEncryption" +#define NID_sha512WithRSAEncryption 670 +#define OBJ_sha512WithRSAEncryption OBJ_pkcs1,13L + +#define SN_sha224WithRSAEncryption "RSA-SHA224" +#define LN_sha224WithRSAEncryption "sha224WithRSAEncryption" +#define NID_sha224WithRSAEncryption 671 +#define OBJ_sha224WithRSAEncryption OBJ_pkcs1,14L + +#define SN_pkcs3 "pkcs3" +#define NID_pkcs3 27 +#define OBJ_pkcs3 OBJ_pkcs,3L + +#define LN_dhKeyAgreement "dhKeyAgreement" +#define NID_dhKeyAgreement 28 +#define OBJ_dhKeyAgreement OBJ_pkcs3,1L + +#define SN_pkcs5 "pkcs5" +#define NID_pkcs5 187 +#define OBJ_pkcs5 OBJ_pkcs,5L + +#define SN_pbeWithMD2AndDES_CBC "PBE-MD2-DES" +#define LN_pbeWithMD2AndDES_CBC "pbeWithMD2AndDES-CBC" +#define NID_pbeWithMD2AndDES_CBC 9 +#define OBJ_pbeWithMD2AndDES_CBC OBJ_pkcs5,1L + +#define SN_pbeWithMD5AndDES_CBC "PBE-MD5-DES" +#define LN_pbeWithMD5AndDES_CBC "pbeWithMD5AndDES-CBC" +#define NID_pbeWithMD5AndDES_CBC 10 +#define OBJ_pbeWithMD5AndDES_CBC OBJ_pkcs5,3L + +#define SN_pbeWithMD2AndRC2_CBC "PBE-MD2-RC2-64" +#define LN_pbeWithMD2AndRC2_CBC "pbeWithMD2AndRC2-CBC" +#define NID_pbeWithMD2AndRC2_CBC 168 +#define OBJ_pbeWithMD2AndRC2_CBC OBJ_pkcs5,4L + +#define SN_pbeWithMD5AndRC2_CBC "PBE-MD5-RC2-64" +#define LN_pbeWithMD5AndRC2_CBC "pbeWithMD5AndRC2-CBC" +#define NID_pbeWithMD5AndRC2_CBC 169 +#define OBJ_pbeWithMD5AndRC2_CBC OBJ_pkcs5,6L + +#define SN_pbeWithSHA1AndDES_CBC "PBE-SHA1-DES" +#define LN_pbeWithSHA1AndDES_CBC "pbeWithSHA1AndDES-CBC" +#define NID_pbeWithSHA1AndDES_CBC 170 +#define OBJ_pbeWithSHA1AndDES_CBC OBJ_pkcs5,10L + +#define SN_pbeWithSHA1AndRC2_CBC "PBE-SHA1-RC2-64" +#define LN_pbeWithSHA1AndRC2_CBC "pbeWithSHA1AndRC2-CBC" +#define NID_pbeWithSHA1AndRC2_CBC 68 +#define OBJ_pbeWithSHA1AndRC2_CBC OBJ_pkcs5,11L + +#define LN_id_pbkdf2 "PBKDF2" +#define NID_id_pbkdf2 69 +#define OBJ_id_pbkdf2 OBJ_pkcs5,12L + +#define LN_pbes2 "PBES2" +#define NID_pbes2 161 +#define OBJ_pbes2 OBJ_pkcs5,13L + +#define LN_pbmac1 "PBMAC1" +#define NID_pbmac1 162 +#define OBJ_pbmac1 OBJ_pkcs5,14L + +#define SN_pkcs7 "pkcs7" +#define NID_pkcs7 20 +#define OBJ_pkcs7 OBJ_pkcs,7L + +#define LN_pkcs7_data "pkcs7-data" +#define NID_pkcs7_data 21 +#define OBJ_pkcs7_data OBJ_pkcs7,1L + +#define LN_pkcs7_signed "pkcs7-signedData" +#define NID_pkcs7_signed 22 +#define OBJ_pkcs7_signed OBJ_pkcs7,2L + +#define LN_pkcs7_enveloped "pkcs7-envelopedData" +#define NID_pkcs7_enveloped 23 +#define OBJ_pkcs7_enveloped OBJ_pkcs7,3L + +#define LN_pkcs7_signedAndEnveloped "pkcs7-signedAndEnvelopedData" +#define NID_pkcs7_signedAndEnveloped 24 +#define OBJ_pkcs7_signedAndEnveloped OBJ_pkcs7,4L + +#define LN_pkcs7_digest "pkcs7-digestData" +#define NID_pkcs7_digest 25 +#define OBJ_pkcs7_digest OBJ_pkcs7,5L + +#define LN_pkcs7_encrypted "pkcs7-encryptedData" +#define NID_pkcs7_encrypted 26 +#define OBJ_pkcs7_encrypted OBJ_pkcs7,6L + +#define SN_pkcs9 "pkcs9" +#define NID_pkcs9 47 +#define OBJ_pkcs9 OBJ_pkcs,9L + +#define LN_pkcs9_emailAddress "emailAddress" +#define NID_pkcs9_emailAddress 48 +#define OBJ_pkcs9_emailAddress OBJ_pkcs9,1L + +#define LN_pkcs9_unstructuredName "unstructuredName" +#define NID_pkcs9_unstructuredName 49 +#define OBJ_pkcs9_unstructuredName OBJ_pkcs9,2L + +#define LN_pkcs9_contentType "contentType" +#define NID_pkcs9_contentType 50 +#define OBJ_pkcs9_contentType OBJ_pkcs9,3L + +#define LN_pkcs9_messageDigest "messageDigest" +#define NID_pkcs9_messageDigest 51 +#define OBJ_pkcs9_messageDigest OBJ_pkcs9,4L + +#define LN_pkcs9_signingTime "signingTime" +#define NID_pkcs9_signingTime 52 +#define OBJ_pkcs9_signingTime OBJ_pkcs9,5L + +#define LN_pkcs9_countersignature "countersignature" +#define NID_pkcs9_countersignature 53 +#define OBJ_pkcs9_countersignature OBJ_pkcs9,6L + +#define LN_pkcs9_challengePassword "challengePassword" +#define NID_pkcs9_challengePassword 54 +#define OBJ_pkcs9_challengePassword OBJ_pkcs9,7L + +#define LN_pkcs9_unstructuredAddress "unstructuredAddress" +#define NID_pkcs9_unstructuredAddress 55 +#define OBJ_pkcs9_unstructuredAddress OBJ_pkcs9,8L + +#define LN_pkcs9_extCertAttributes "extendedCertificateAttributes" +#define NID_pkcs9_extCertAttributes 56 +#define OBJ_pkcs9_extCertAttributes OBJ_pkcs9,9L + +#define SN_ext_req "extReq" +#define LN_ext_req "Extension Request" +#define NID_ext_req 172 +#define OBJ_ext_req OBJ_pkcs9,14L + +#define SN_SMIMECapabilities "SMIME-CAPS" +#define LN_SMIMECapabilities "S/MIME Capabilities" +#define NID_SMIMECapabilities 167 +#define OBJ_SMIMECapabilities OBJ_pkcs9,15L + +#define SN_SMIME "SMIME" +#define LN_SMIME "S/MIME" +#define NID_SMIME 188 +#define OBJ_SMIME OBJ_pkcs9,16L + +#define SN_id_smime_mod "id-smime-mod" +#define NID_id_smime_mod 189 +#define OBJ_id_smime_mod OBJ_SMIME,0L + +#define SN_id_smime_ct "id-smime-ct" +#define NID_id_smime_ct 190 +#define OBJ_id_smime_ct OBJ_SMIME,1L + +#define SN_id_smime_aa "id-smime-aa" +#define NID_id_smime_aa 191 +#define OBJ_id_smime_aa OBJ_SMIME,2L + +#define SN_id_smime_alg "id-smime-alg" +#define NID_id_smime_alg 192 +#define OBJ_id_smime_alg OBJ_SMIME,3L + +#define SN_id_smime_cd "id-smime-cd" +#define NID_id_smime_cd 193 +#define OBJ_id_smime_cd OBJ_SMIME,4L + +#define SN_id_smime_spq "id-smime-spq" +#define NID_id_smime_spq 194 +#define OBJ_id_smime_spq OBJ_SMIME,5L + +#define SN_id_smime_cti "id-smime-cti" +#define NID_id_smime_cti 195 +#define OBJ_id_smime_cti OBJ_SMIME,6L + +#define SN_id_smime_mod_cms "id-smime-mod-cms" +#define NID_id_smime_mod_cms 196 +#define OBJ_id_smime_mod_cms OBJ_id_smime_mod,1L + +#define SN_id_smime_mod_ess "id-smime-mod-ess" +#define NID_id_smime_mod_ess 197 +#define OBJ_id_smime_mod_ess OBJ_id_smime_mod,2L + +#define SN_id_smime_mod_oid "id-smime-mod-oid" +#define NID_id_smime_mod_oid 198 +#define OBJ_id_smime_mod_oid OBJ_id_smime_mod,3L + +#define SN_id_smime_mod_msg_v3 "id-smime-mod-msg-v3" +#define NID_id_smime_mod_msg_v3 199 +#define OBJ_id_smime_mod_msg_v3 OBJ_id_smime_mod,4L + +#define SN_id_smime_mod_ets_eSignature_88 "id-smime-mod-ets-eSignature-88" +#define NID_id_smime_mod_ets_eSignature_88 200 +#define OBJ_id_smime_mod_ets_eSignature_88 OBJ_id_smime_mod,5L + +#define SN_id_smime_mod_ets_eSignature_97 "id-smime-mod-ets-eSignature-97" +#define NID_id_smime_mod_ets_eSignature_97 201 +#define OBJ_id_smime_mod_ets_eSignature_97 OBJ_id_smime_mod,6L + +#define SN_id_smime_mod_ets_eSigPolicy_88 "id-smime-mod-ets-eSigPolicy-88" +#define NID_id_smime_mod_ets_eSigPolicy_88 202 +#define OBJ_id_smime_mod_ets_eSigPolicy_88 OBJ_id_smime_mod,7L + +#define SN_id_smime_mod_ets_eSigPolicy_97 "id-smime-mod-ets-eSigPolicy-97" +#define NID_id_smime_mod_ets_eSigPolicy_97 203 +#define OBJ_id_smime_mod_ets_eSigPolicy_97 OBJ_id_smime_mod,8L + +#define SN_id_smime_ct_receipt "id-smime-ct-receipt" +#define NID_id_smime_ct_receipt 204 +#define OBJ_id_smime_ct_receipt OBJ_id_smime_ct,1L + +#define SN_id_smime_ct_authData "id-smime-ct-authData" +#define NID_id_smime_ct_authData 205 +#define OBJ_id_smime_ct_authData OBJ_id_smime_ct,2L + +#define SN_id_smime_ct_publishCert "id-smime-ct-publishCert" +#define NID_id_smime_ct_publishCert 206 +#define OBJ_id_smime_ct_publishCert OBJ_id_smime_ct,3L + +#define SN_id_smime_ct_TSTInfo "id-smime-ct-TSTInfo" +#define NID_id_smime_ct_TSTInfo 207 +#define OBJ_id_smime_ct_TSTInfo OBJ_id_smime_ct,4L + +#define SN_id_smime_ct_TDTInfo "id-smime-ct-TDTInfo" +#define NID_id_smime_ct_TDTInfo 208 +#define OBJ_id_smime_ct_TDTInfo OBJ_id_smime_ct,5L + +#define SN_id_smime_ct_contentInfo "id-smime-ct-contentInfo" +#define NID_id_smime_ct_contentInfo 209 +#define OBJ_id_smime_ct_contentInfo OBJ_id_smime_ct,6L + +#define SN_id_smime_ct_DVCSRequestData "id-smime-ct-DVCSRequestData" +#define NID_id_smime_ct_DVCSRequestData 210 +#define OBJ_id_smime_ct_DVCSRequestData OBJ_id_smime_ct,7L + +#define SN_id_smime_ct_DVCSResponseData "id-smime-ct-DVCSResponseData" +#define NID_id_smime_ct_DVCSResponseData 211 +#define OBJ_id_smime_ct_DVCSResponseData OBJ_id_smime_ct,8L + +#define SN_id_smime_ct_compressedData "id-smime-ct-compressedData" +#define NID_id_smime_ct_compressedData 786 +#define OBJ_id_smime_ct_compressedData OBJ_id_smime_ct,9L + +#define SN_id_ct_asciiTextWithCRLF "id-ct-asciiTextWithCRLF" +#define NID_id_ct_asciiTextWithCRLF 787 +#define OBJ_id_ct_asciiTextWithCRLF OBJ_id_smime_ct,27L + +#define SN_id_smime_aa_receiptRequest "id-smime-aa-receiptRequest" +#define NID_id_smime_aa_receiptRequest 212 +#define OBJ_id_smime_aa_receiptRequest OBJ_id_smime_aa,1L + +#define SN_id_smime_aa_securityLabel "id-smime-aa-securityLabel" +#define NID_id_smime_aa_securityLabel 213 +#define OBJ_id_smime_aa_securityLabel OBJ_id_smime_aa,2L + +#define SN_id_smime_aa_mlExpandHistory "id-smime-aa-mlExpandHistory" +#define NID_id_smime_aa_mlExpandHistory 214 +#define OBJ_id_smime_aa_mlExpandHistory OBJ_id_smime_aa,3L + +#define SN_id_smime_aa_contentHint "id-smime-aa-contentHint" +#define NID_id_smime_aa_contentHint 215 +#define OBJ_id_smime_aa_contentHint OBJ_id_smime_aa,4L + +#define SN_id_smime_aa_msgSigDigest "id-smime-aa-msgSigDigest" +#define NID_id_smime_aa_msgSigDigest 216 +#define OBJ_id_smime_aa_msgSigDigest OBJ_id_smime_aa,5L + +#define SN_id_smime_aa_encapContentType "id-smime-aa-encapContentType" +#define NID_id_smime_aa_encapContentType 217 +#define OBJ_id_smime_aa_encapContentType OBJ_id_smime_aa,6L + +#define SN_id_smime_aa_contentIdentifier "id-smime-aa-contentIdentifier" +#define NID_id_smime_aa_contentIdentifier 218 +#define OBJ_id_smime_aa_contentIdentifier OBJ_id_smime_aa,7L + +#define SN_id_smime_aa_macValue "id-smime-aa-macValue" +#define NID_id_smime_aa_macValue 219 +#define OBJ_id_smime_aa_macValue OBJ_id_smime_aa,8L + +#define SN_id_smime_aa_equivalentLabels "id-smime-aa-equivalentLabels" +#define NID_id_smime_aa_equivalentLabels 220 +#define OBJ_id_smime_aa_equivalentLabels OBJ_id_smime_aa,9L + +#define SN_id_smime_aa_contentReference "id-smime-aa-contentReference" +#define NID_id_smime_aa_contentReference 221 +#define OBJ_id_smime_aa_contentReference OBJ_id_smime_aa,10L + +#define SN_id_smime_aa_encrypKeyPref "id-smime-aa-encrypKeyPref" +#define NID_id_smime_aa_encrypKeyPref 222 +#define OBJ_id_smime_aa_encrypKeyPref OBJ_id_smime_aa,11L + +#define SN_id_smime_aa_signingCertificate "id-smime-aa-signingCertificate" +#define NID_id_smime_aa_signingCertificate 223 +#define OBJ_id_smime_aa_signingCertificate OBJ_id_smime_aa,12L + +#define SN_id_smime_aa_smimeEncryptCerts "id-smime-aa-smimeEncryptCerts" +#define NID_id_smime_aa_smimeEncryptCerts 224 +#define OBJ_id_smime_aa_smimeEncryptCerts OBJ_id_smime_aa,13L + +#define SN_id_smime_aa_timeStampToken "id-smime-aa-timeStampToken" +#define NID_id_smime_aa_timeStampToken 225 +#define OBJ_id_smime_aa_timeStampToken OBJ_id_smime_aa,14L + +#define SN_id_smime_aa_ets_sigPolicyId "id-smime-aa-ets-sigPolicyId" +#define NID_id_smime_aa_ets_sigPolicyId 226 +#define OBJ_id_smime_aa_ets_sigPolicyId OBJ_id_smime_aa,15L + +#define SN_id_smime_aa_ets_commitmentType "id-smime-aa-ets-commitmentType" +#define NID_id_smime_aa_ets_commitmentType 227 +#define OBJ_id_smime_aa_ets_commitmentType OBJ_id_smime_aa,16L + +#define SN_id_smime_aa_ets_signerLocation "id-smime-aa-ets-signerLocation" +#define NID_id_smime_aa_ets_signerLocation 228 +#define OBJ_id_smime_aa_ets_signerLocation OBJ_id_smime_aa,17L + +#define SN_id_smime_aa_ets_signerAttr "id-smime-aa-ets-signerAttr" +#define NID_id_smime_aa_ets_signerAttr 229 +#define OBJ_id_smime_aa_ets_signerAttr OBJ_id_smime_aa,18L + +#define SN_id_smime_aa_ets_otherSigCert "id-smime-aa-ets-otherSigCert" +#define NID_id_smime_aa_ets_otherSigCert 230 +#define OBJ_id_smime_aa_ets_otherSigCert OBJ_id_smime_aa,19L + +#define SN_id_smime_aa_ets_contentTimestamp "id-smime-aa-ets-contentTimestamp" +#define NID_id_smime_aa_ets_contentTimestamp 231 +#define OBJ_id_smime_aa_ets_contentTimestamp OBJ_id_smime_aa,20L + +#define SN_id_smime_aa_ets_CertificateRefs "id-smime-aa-ets-CertificateRefs" +#define NID_id_smime_aa_ets_CertificateRefs 232 +#define OBJ_id_smime_aa_ets_CertificateRefs OBJ_id_smime_aa,21L + +#define SN_id_smime_aa_ets_RevocationRefs "id-smime-aa-ets-RevocationRefs" +#define NID_id_smime_aa_ets_RevocationRefs 233 +#define OBJ_id_smime_aa_ets_RevocationRefs OBJ_id_smime_aa,22L + +#define SN_id_smime_aa_ets_certValues "id-smime-aa-ets-certValues" +#define NID_id_smime_aa_ets_certValues 234 +#define OBJ_id_smime_aa_ets_certValues OBJ_id_smime_aa,23L + +#define SN_id_smime_aa_ets_revocationValues "id-smime-aa-ets-revocationValues" +#define NID_id_smime_aa_ets_revocationValues 235 +#define OBJ_id_smime_aa_ets_revocationValues OBJ_id_smime_aa,24L + +#define SN_id_smime_aa_ets_escTimeStamp "id-smime-aa-ets-escTimeStamp" +#define NID_id_smime_aa_ets_escTimeStamp 236 +#define OBJ_id_smime_aa_ets_escTimeStamp OBJ_id_smime_aa,25L + +#define SN_id_smime_aa_ets_certCRLTimestamp "id-smime-aa-ets-certCRLTimestamp" +#define NID_id_smime_aa_ets_certCRLTimestamp 237 +#define OBJ_id_smime_aa_ets_certCRLTimestamp OBJ_id_smime_aa,26L + +#define SN_id_smime_aa_ets_archiveTimeStamp "id-smime-aa-ets-archiveTimeStamp" +#define NID_id_smime_aa_ets_archiveTimeStamp 238 +#define OBJ_id_smime_aa_ets_archiveTimeStamp OBJ_id_smime_aa,27L + +#define SN_id_smime_aa_signatureType "id-smime-aa-signatureType" +#define NID_id_smime_aa_signatureType 239 +#define OBJ_id_smime_aa_signatureType OBJ_id_smime_aa,28L + +#define SN_id_smime_aa_dvcs_dvc "id-smime-aa-dvcs-dvc" +#define NID_id_smime_aa_dvcs_dvc 240 +#define OBJ_id_smime_aa_dvcs_dvc OBJ_id_smime_aa,29L + +#define SN_id_smime_alg_ESDHwith3DES "id-smime-alg-ESDHwith3DES" +#define NID_id_smime_alg_ESDHwith3DES 241 +#define OBJ_id_smime_alg_ESDHwith3DES OBJ_id_smime_alg,1L + +#define SN_id_smime_alg_ESDHwithRC2 "id-smime-alg-ESDHwithRC2" +#define NID_id_smime_alg_ESDHwithRC2 242 +#define OBJ_id_smime_alg_ESDHwithRC2 OBJ_id_smime_alg,2L + +#define SN_id_smime_alg_3DESwrap "id-smime-alg-3DESwrap" +#define NID_id_smime_alg_3DESwrap 243 +#define OBJ_id_smime_alg_3DESwrap OBJ_id_smime_alg,3L + +#define SN_id_smime_alg_RC2wrap "id-smime-alg-RC2wrap" +#define NID_id_smime_alg_RC2wrap 244 +#define OBJ_id_smime_alg_RC2wrap OBJ_id_smime_alg,4L + +#define SN_id_smime_alg_ESDH "id-smime-alg-ESDH" +#define NID_id_smime_alg_ESDH 245 +#define OBJ_id_smime_alg_ESDH OBJ_id_smime_alg,5L + +#define SN_id_smime_alg_CMS3DESwrap "id-smime-alg-CMS3DESwrap" +#define NID_id_smime_alg_CMS3DESwrap 246 +#define OBJ_id_smime_alg_CMS3DESwrap OBJ_id_smime_alg,6L + +#define SN_id_smime_alg_CMSRC2wrap "id-smime-alg-CMSRC2wrap" +#define NID_id_smime_alg_CMSRC2wrap 247 +#define OBJ_id_smime_alg_CMSRC2wrap OBJ_id_smime_alg,7L + +#define SN_id_alg_PWRI_KEK "id-alg-PWRI-KEK" +#define NID_id_alg_PWRI_KEK 893 +#define OBJ_id_alg_PWRI_KEK OBJ_id_smime_alg,9L + +#define SN_id_smime_cd_ldap "id-smime-cd-ldap" +#define NID_id_smime_cd_ldap 248 +#define OBJ_id_smime_cd_ldap OBJ_id_smime_cd,1L + +#define SN_id_smime_spq_ets_sqt_uri "id-smime-spq-ets-sqt-uri" +#define NID_id_smime_spq_ets_sqt_uri 249 +#define OBJ_id_smime_spq_ets_sqt_uri OBJ_id_smime_spq,1L + +#define SN_id_smime_spq_ets_sqt_unotice "id-smime-spq-ets-sqt-unotice" +#define NID_id_smime_spq_ets_sqt_unotice 250 +#define OBJ_id_smime_spq_ets_sqt_unotice OBJ_id_smime_spq,2L + +#define SN_id_smime_cti_ets_proofOfOrigin "id-smime-cti-ets-proofOfOrigin" +#define NID_id_smime_cti_ets_proofOfOrigin 251 +#define OBJ_id_smime_cti_ets_proofOfOrigin OBJ_id_smime_cti,1L + +#define SN_id_smime_cti_ets_proofOfReceipt "id-smime-cti-ets-proofOfReceipt" +#define NID_id_smime_cti_ets_proofOfReceipt 252 +#define OBJ_id_smime_cti_ets_proofOfReceipt OBJ_id_smime_cti,2L + +#define SN_id_smime_cti_ets_proofOfDelivery "id-smime-cti-ets-proofOfDelivery" +#define NID_id_smime_cti_ets_proofOfDelivery 253 +#define OBJ_id_smime_cti_ets_proofOfDelivery OBJ_id_smime_cti,3L + +#define SN_id_smime_cti_ets_proofOfSender "id-smime-cti-ets-proofOfSender" +#define NID_id_smime_cti_ets_proofOfSender 254 +#define OBJ_id_smime_cti_ets_proofOfSender OBJ_id_smime_cti,4L + +#define SN_id_smime_cti_ets_proofOfApproval "id-smime-cti-ets-proofOfApproval" +#define NID_id_smime_cti_ets_proofOfApproval 255 +#define OBJ_id_smime_cti_ets_proofOfApproval OBJ_id_smime_cti,5L + +#define SN_id_smime_cti_ets_proofOfCreation "id-smime-cti-ets-proofOfCreation" +#define NID_id_smime_cti_ets_proofOfCreation 256 +#define OBJ_id_smime_cti_ets_proofOfCreation OBJ_id_smime_cti,6L + +#define LN_friendlyName "friendlyName" +#define NID_friendlyName 156 +#define OBJ_friendlyName OBJ_pkcs9,20L + +#define LN_localKeyID "localKeyID" +#define NID_localKeyID 157 +#define OBJ_localKeyID OBJ_pkcs9,21L + +#define SN_ms_csp_name "CSPName" +#define LN_ms_csp_name "Microsoft CSP Name" +#define NID_ms_csp_name 417 +#define OBJ_ms_csp_name 1L,3L,6L,1L,4L,1L,311L,17L,1L + +#define SN_LocalKeySet "LocalKeySet" +#define LN_LocalKeySet "Microsoft Local Key set" +#define NID_LocalKeySet 856 +#define OBJ_LocalKeySet 1L,3L,6L,1L,4L,1L,311L,17L,2L + +#define OBJ_certTypes OBJ_pkcs9,22L + +#define LN_x509Certificate "x509Certificate" +#define NID_x509Certificate 158 +#define OBJ_x509Certificate OBJ_certTypes,1L + +#define LN_sdsiCertificate "sdsiCertificate" +#define NID_sdsiCertificate 159 +#define OBJ_sdsiCertificate OBJ_certTypes,2L + +#define OBJ_crlTypes OBJ_pkcs9,23L + +#define LN_x509Crl "x509Crl" +#define NID_x509Crl 160 +#define OBJ_x509Crl OBJ_crlTypes,1L + +#define OBJ_pkcs12 OBJ_pkcs,12L + +#define OBJ_pkcs12_pbeids OBJ_pkcs12,1L + +#define SN_pbe_WithSHA1And128BitRC4 "PBE-SHA1-RC4-128" +#define LN_pbe_WithSHA1And128BitRC4 "pbeWithSHA1And128BitRC4" +#define NID_pbe_WithSHA1And128BitRC4 144 +#define OBJ_pbe_WithSHA1And128BitRC4 OBJ_pkcs12_pbeids,1L + +#define SN_pbe_WithSHA1And40BitRC4 "PBE-SHA1-RC4-40" +#define LN_pbe_WithSHA1And40BitRC4 "pbeWithSHA1And40BitRC4" +#define NID_pbe_WithSHA1And40BitRC4 145 +#define OBJ_pbe_WithSHA1And40BitRC4 OBJ_pkcs12_pbeids,2L + +#define SN_pbe_WithSHA1And3_Key_TripleDES_CBC "PBE-SHA1-3DES" +#define LN_pbe_WithSHA1And3_Key_TripleDES_CBC "pbeWithSHA1And3-KeyTripleDES-CBC" +#define NID_pbe_WithSHA1And3_Key_TripleDES_CBC 146 +#define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC OBJ_pkcs12_pbeids,3L + +#define SN_pbe_WithSHA1And2_Key_TripleDES_CBC "PBE-SHA1-2DES" +#define LN_pbe_WithSHA1And2_Key_TripleDES_CBC "pbeWithSHA1And2-KeyTripleDES-CBC" +#define NID_pbe_WithSHA1And2_Key_TripleDES_CBC 147 +#define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC OBJ_pkcs12_pbeids,4L + +#define SN_pbe_WithSHA1And128BitRC2_CBC "PBE-SHA1-RC2-128" +#define LN_pbe_WithSHA1And128BitRC2_CBC "pbeWithSHA1And128BitRC2-CBC" +#define NID_pbe_WithSHA1And128BitRC2_CBC 148 +#define OBJ_pbe_WithSHA1And128BitRC2_CBC OBJ_pkcs12_pbeids,5L + +#define SN_pbe_WithSHA1And40BitRC2_CBC "PBE-SHA1-RC2-40" +#define LN_pbe_WithSHA1And40BitRC2_CBC "pbeWithSHA1And40BitRC2-CBC" +#define NID_pbe_WithSHA1And40BitRC2_CBC 149 +#define OBJ_pbe_WithSHA1And40BitRC2_CBC OBJ_pkcs12_pbeids,6L + +#define OBJ_pkcs12_Version1 OBJ_pkcs12,10L + +#define OBJ_pkcs12_BagIds OBJ_pkcs12_Version1,1L + +#define LN_keyBag "keyBag" +#define NID_keyBag 150 +#define OBJ_keyBag OBJ_pkcs12_BagIds,1L + +#define LN_pkcs8ShroudedKeyBag "pkcs8ShroudedKeyBag" +#define NID_pkcs8ShroudedKeyBag 151 +#define OBJ_pkcs8ShroudedKeyBag OBJ_pkcs12_BagIds,2L + +#define LN_certBag "certBag" +#define NID_certBag 152 +#define OBJ_certBag OBJ_pkcs12_BagIds,3L + +#define LN_crlBag "crlBag" +#define NID_crlBag 153 +#define OBJ_crlBag OBJ_pkcs12_BagIds,4L + +#define LN_secretBag "secretBag" +#define NID_secretBag 154 +#define OBJ_secretBag OBJ_pkcs12_BagIds,5L + +#define LN_safeContentsBag "safeContentsBag" +#define NID_safeContentsBag 155 +#define OBJ_safeContentsBag OBJ_pkcs12_BagIds,6L + +#define SN_md2 "MD2" +#define LN_md2 "md2" +#define NID_md2 3 +#define OBJ_md2 OBJ_rsadsi,2L,2L + +#define SN_md4 "MD4" +#define LN_md4 "md4" +#define NID_md4 257 +#define OBJ_md4 OBJ_rsadsi,2L,4L + +#define SN_md5 "MD5" +#define LN_md5 "md5" +#define NID_md5 4 +#define OBJ_md5 OBJ_rsadsi,2L,5L + +#define SN_md5_sha1 "MD5-SHA1" +#define LN_md5_sha1 "md5-sha1" +#define NID_md5_sha1 114 + +#define LN_hmacWithMD5 "hmacWithMD5" +#define NID_hmacWithMD5 797 +#define OBJ_hmacWithMD5 OBJ_rsadsi,2L,6L + +#define LN_hmacWithSHA1 "hmacWithSHA1" +#define NID_hmacWithSHA1 163 +#define OBJ_hmacWithSHA1 OBJ_rsadsi,2L,7L + +#define LN_hmacWithSHA224 "hmacWithSHA224" +#define NID_hmacWithSHA224 798 +#define OBJ_hmacWithSHA224 OBJ_rsadsi,2L,8L + +#define LN_hmacWithSHA256 "hmacWithSHA256" +#define NID_hmacWithSHA256 799 +#define OBJ_hmacWithSHA256 OBJ_rsadsi,2L,9L + +#define LN_hmacWithSHA384 "hmacWithSHA384" +#define NID_hmacWithSHA384 800 +#define OBJ_hmacWithSHA384 OBJ_rsadsi,2L,10L + +#define LN_hmacWithSHA512 "hmacWithSHA512" +#define NID_hmacWithSHA512 801 +#define OBJ_hmacWithSHA512 OBJ_rsadsi,2L,11L + +#define SN_rc2_cbc "RC2-CBC" +#define LN_rc2_cbc "rc2-cbc" +#define NID_rc2_cbc 37 +#define OBJ_rc2_cbc OBJ_rsadsi,3L,2L + +#define SN_rc2_ecb "RC2-ECB" +#define LN_rc2_ecb "rc2-ecb" +#define NID_rc2_ecb 38 + +#define SN_rc2_cfb64 "RC2-CFB" +#define LN_rc2_cfb64 "rc2-cfb" +#define NID_rc2_cfb64 39 + +#define SN_rc2_ofb64 "RC2-OFB" +#define LN_rc2_ofb64 "rc2-ofb" +#define NID_rc2_ofb64 40 + +#define SN_rc2_40_cbc "RC2-40-CBC" +#define LN_rc2_40_cbc "rc2-40-cbc" +#define NID_rc2_40_cbc 98 + +#define SN_rc2_64_cbc "RC2-64-CBC" +#define LN_rc2_64_cbc "rc2-64-cbc" +#define NID_rc2_64_cbc 166 + +#define SN_rc4 "RC4" +#define LN_rc4 "rc4" +#define NID_rc4 5 +#define OBJ_rc4 OBJ_rsadsi,3L,4L + +#define SN_rc4_40 "RC4-40" +#define LN_rc4_40 "rc4-40" +#define NID_rc4_40 97 + +#define SN_des_ede3_cbc "DES-EDE3-CBC" +#define LN_des_ede3_cbc "des-ede3-cbc" +#define NID_des_ede3_cbc 44 +#define OBJ_des_ede3_cbc OBJ_rsadsi,3L,7L + +#define SN_rc5_cbc "RC5-CBC" +#define LN_rc5_cbc "rc5-cbc" +#define NID_rc5_cbc 120 +#define OBJ_rc5_cbc OBJ_rsadsi,3L,8L + +#define SN_rc5_ecb "RC5-ECB" +#define LN_rc5_ecb "rc5-ecb" +#define NID_rc5_ecb 121 + +#define SN_rc5_cfb64 "RC5-CFB" +#define LN_rc5_cfb64 "rc5-cfb" +#define NID_rc5_cfb64 122 + +#define SN_rc5_ofb64 "RC5-OFB" +#define LN_rc5_ofb64 "rc5-ofb" +#define NID_rc5_ofb64 123 + +#define SN_ms_ext_req "msExtReq" +#define LN_ms_ext_req "Microsoft Extension Request" +#define NID_ms_ext_req 171 +#define OBJ_ms_ext_req 1L,3L,6L,1L,4L,1L,311L,2L,1L,14L + +#define SN_ms_code_ind "msCodeInd" +#define LN_ms_code_ind "Microsoft Individual Code Signing" +#define NID_ms_code_ind 134 +#define OBJ_ms_code_ind 1L,3L,6L,1L,4L,1L,311L,2L,1L,21L + +#define SN_ms_code_com "msCodeCom" +#define LN_ms_code_com "Microsoft Commercial Code Signing" +#define NID_ms_code_com 135 +#define OBJ_ms_code_com 1L,3L,6L,1L,4L,1L,311L,2L,1L,22L + +#define SN_ms_ctl_sign "msCTLSign" +#define LN_ms_ctl_sign "Microsoft Trust List Signing" +#define NID_ms_ctl_sign 136 +#define OBJ_ms_ctl_sign 1L,3L,6L,1L,4L,1L,311L,10L,3L,1L + +#define SN_ms_sgc "msSGC" +#define LN_ms_sgc "Microsoft Server Gated Crypto" +#define NID_ms_sgc 137 +#define OBJ_ms_sgc 1L,3L,6L,1L,4L,1L,311L,10L,3L,3L + +#define SN_ms_efs "msEFS" +#define LN_ms_efs "Microsoft Encrypted File System" +#define NID_ms_efs 138 +#define OBJ_ms_efs 1L,3L,6L,1L,4L,1L,311L,10L,3L,4L + +#define SN_ms_smartcard_login "msSmartcardLogin" +#define LN_ms_smartcard_login "Microsoft Smartcardlogin" +#define NID_ms_smartcard_login 648 +#define OBJ_ms_smartcard_login 1L,3L,6L,1L,4L,1L,311L,20L,2L,2L + +#define SN_ms_upn "msUPN" +#define LN_ms_upn "Microsoft Universal Principal Name" +#define NID_ms_upn 649 +#define OBJ_ms_upn 1L,3L,6L,1L,4L,1L,311L,20L,2L,3L + +#define SN_idea_cbc "IDEA-CBC" +#define LN_idea_cbc "idea-cbc" +#define NID_idea_cbc 34 +#define OBJ_idea_cbc 1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L + +#define SN_idea_ecb "IDEA-ECB" +#define LN_idea_ecb "idea-ecb" +#define NID_idea_ecb 36 + +#define SN_idea_cfb64 "IDEA-CFB" +#define LN_idea_cfb64 "idea-cfb" +#define NID_idea_cfb64 35 + +#define SN_idea_ofb64 "IDEA-OFB" +#define LN_idea_ofb64 "idea-ofb" +#define NID_idea_ofb64 46 + +#define SN_bf_cbc "BF-CBC" +#define LN_bf_cbc "bf-cbc" +#define NID_bf_cbc 91 +#define OBJ_bf_cbc 1L,3L,6L,1L,4L,1L,3029L,1L,2L + +#define SN_bf_ecb "BF-ECB" +#define LN_bf_ecb "bf-ecb" +#define NID_bf_ecb 92 + +#define SN_bf_cfb64 "BF-CFB" +#define LN_bf_cfb64 "bf-cfb" +#define NID_bf_cfb64 93 + +#define SN_bf_ofb64 "BF-OFB" +#define LN_bf_ofb64 "bf-ofb" +#define NID_bf_ofb64 94 + +#define SN_id_pkix "PKIX" +#define NID_id_pkix 127 +#define OBJ_id_pkix 1L,3L,6L,1L,5L,5L,7L + +#define SN_id_pkix_mod "id-pkix-mod" +#define NID_id_pkix_mod 258 +#define OBJ_id_pkix_mod OBJ_id_pkix,0L + +#define SN_id_pe "id-pe" +#define NID_id_pe 175 +#define OBJ_id_pe OBJ_id_pkix,1L + +#define SN_id_qt "id-qt" +#define NID_id_qt 259 +#define OBJ_id_qt OBJ_id_pkix,2L + +#define SN_id_kp "id-kp" +#define NID_id_kp 128 +#define OBJ_id_kp OBJ_id_pkix,3L + +#define SN_id_it "id-it" +#define NID_id_it 260 +#define OBJ_id_it OBJ_id_pkix,4L + +#define SN_id_pkip "id-pkip" +#define NID_id_pkip 261 +#define OBJ_id_pkip OBJ_id_pkix,5L + +#define SN_id_alg "id-alg" +#define NID_id_alg 262 +#define OBJ_id_alg OBJ_id_pkix,6L + +#define SN_id_cmc "id-cmc" +#define NID_id_cmc 263 +#define OBJ_id_cmc OBJ_id_pkix,7L + +#define SN_id_on "id-on" +#define NID_id_on 264 +#define OBJ_id_on OBJ_id_pkix,8L + +#define SN_id_pda "id-pda" +#define NID_id_pda 265 +#define OBJ_id_pda OBJ_id_pkix,9L + +#define SN_id_aca "id-aca" +#define NID_id_aca 266 +#define OBJ_id_aca OBJ_id_pkix,10L + +#define SN_id_qcs "id-qcs" +#define NID_id_qcs 267 +#define OBJ_id_qcs OBJ_id_pkix,11L + +#define SN_id_cct "id-cct" +#define NID_id_cct 268 +#define OBJ_id_cct OBJ_id_pkix,12L + +#define SN_id_ppl "id-ppl" +#define NID_id_ppl 662 +#define OBJ_id_ppl OBJ_id_pkix,21L + +#define SN_id_ad "id-ad" +#define NID_id_ad 176 +#define OBJ_id_ad OBJ_id_pkix,48L + +#define SN_id_pkix1_explicit_88 "id-pkix1-explicit-88" +#define NID_id_pkix1_explicit_88 269 +#define OBJ_id_pkix1_explicit_88 OBJ_id_pkix_mod,1L + +#define SN_id_pkix1_implicit_88 "id-pkix1-implicit-88" +#define NID_id_pkix1_implicit_88 270 +#define OBJ_id_pkix1_implicit_88 OBJ_id_pkix_mod,2L + +#define SN_id_pkix1_explicit_93 "id-pkix1-explicit-93" +#define NID_id_pkix1_explicit_93 271 +#define OBJ_id_pkix1_explicit_93 OBJ_id_pkix_mod,3L + +#define SN_id_pkix1_implicit_93 "id-pkix1-implicit-93" +#define NID_id_pkix1_implicit_93 272 +#define OBJ_id_pkix1_implicit_93 OBJ_id_pkix_mod,4L + +#define SN_id_mod_crmf "id-mod-crmf" +#define NID_id_mod_crmf 273 +#define OBJ_id_mod_crmf OBJ_id_pkix_mod,5L + +#define SN_id_mod_cmc "id-mod-cmc" +#define NID_id_mod_cmc 274 +#define OBJ_id_mod_cmc OBJ_id_pkix_mod,6L + +#define SN_id_mod_kea_profile_88 "id-mod-kea-profile-88" +#define NID_id_mod_kea_profile_88 275 +#define OBJ_id_mod_kea_profile_88 OBJ_id_pkix_mod,7L + +#define SN_id_mod_kea_profile_93 "id-mod-kea-profile-93" +#define NID_id_mod_kea_profile_93 276 +#define OBJ_id_mod_kea_profile_93 OBJ_id_pkix_mod,8L + +#define SN_id_mod_cmp "id-mod-cmp" +#define NID_id_mod_cmp 277 +#define OBJ_id_mod_cmp OBJ_id_pkix_mod,9L + +#define SN_id_mod_qualified_cert_88 "id-mod-qualified-cert-88" +#define NID_id_mod_qualified_cert_88 278 +#define OBJ_id_mod_qualified_cert_88 OBJ_id_pkix_mod,10L + +#define SN_id_mod_qualified_cert_93 "id-mod-qualified-cert-93" +#define NID_id_mod_qualified_cert_93 279 +#define OBJ_id_mod_qualified_cert_93 OBJ_id_pkix_mod,11L + +#define SN_id_mod_attribute_cert "id-mod-attribute-cert" +#define NID_id_mod_attribute_cert 280 +#define OBJ_id_mod_attribute_cert OBJ_id_pkix_mod,12L + +#define SN_id_mod_timestamp_protocol "id-mod-timestamp-protocol" +#define NID_id_mod_timestamp_protocol 281 +#define OBJ_id_mod_timestamp_protocol OBJ_id_pkix_mod,13L + +#define SN_id_mod_ocsp "id-mod-ocsp" +#define NID_id_mod_ocsp 282 +#define OBJ_id_mod_ocsp OBJ_id_pkix_mod,14L + +#define SN_id_mod_dvcs "id-mod-dvcs" +#define NID_id_mod_dvcs 283 +#define OBJ_id_mod_dvcs OBJ_id_pkix_mod,15L + +#define SN_id_mod_cmp2000 "id-mod-cmp2000" +#define NID_id_mod_cmp2000 284 +#define OBJ_id_mod_cmp2000 OBJ_id_pkix_mod,16L + +#define SN_info_access "authorityInfoAccess" +#define LN_info_access "Authority Information Access" +#define NID_info_access 177 +#define OBJ_info_access OBJ_id_pe,1L + +#define SN_biometricInfo "biometricInfo" +#define LN_biometricInfo "Biometric Info" +#define NID_biometricInfo 285 +#define OBJ_biometricInfo OBJ_id_pe,2L + +#define SN_qcStatements "qcStatements" +#define NID_qcStatements 286 +#define OBJ_qcStatements OBJ_id_pe,3L + +#define SN_ac_auditEntity "ac-auditEntity" +#define NID_ac_auditEntity 287 +#define OBJ_ac_auditEntity OBJ_id_pe,4L + +#define SN_ac_targeting "ac-targeting" +#define NID_ac_targeting 288 +#define OBJ_ac_targeting OBJ_id_pe,5L + +#define SN_aaControls "aaControls" +#define NID_aaControls 289 +#define OBJ_aaControls OBJ_id_pe,6L + +#define SN_sbgp_ipAddrBlock "sbgp-ipAddrBlock" +#define NID_sbgp_ipAddrBlock 290 +#define OBJ_sbgp_ipAddrBlock OBJ_id_pe,7L + +#define SN_sbgp_autonomousSysNum "sbgp-autonomousSysNum" +#define NID_sbgp_autonomousSysNum 291 +#define OBJ_sbgp_autonomousSysNum OBJ_id_pe,8L + +#define SN_sbgp_routerIdentifier "sbgp-routerIdentifier" +#define NID_sbgp_routerIdentifier 292 +#define OBJ_sbgp_routerIdentifier OBJ_id_pe,9L + +#define SN_ac_proxying "ac-proxying" +#define NID_ac_proxying 397 +#define OBJ_ac_proxying OBJ_id_pe,10L + +#define SN_sinfo_access "subjectInfoAccess" +#define LN_sinfo_access "Subject Information Access" +#define NID_sinfo_access 398 +#define OBJ_sinfo_access OBJ_id_pe,11L + +#define SN_proxyCertInfo "proxyCertInfo" +#define LN_proxyCertInfo "Proxy Certificate Information" +#define NID_proxyCertInfo 663 +#define OBJ_proxyCertInfo OBJ_id_pe,14L + +#define SN_id_qt_cps "id-qt-cps" +#define LN_id_qt_cps "Policy Qualifier CPS" +#define NID_id_qt_cps 164 +#define OBJ_id_qt_cps OBJ_id_qt,1L + +#define SN_id_qt_unotice "id-qt-unotice" +#define LN_id_qt_unotice "Policy Qualifier User Notice" +#define NID_id_qt_unotice 165 +#define OBJ_id_qt_unotice OBJ_id_qt,2L + +#define SN_textNotice "textNotice" +#define NID_textNotice 293 +#define OBJ_textNotice OBJ_id_qt,3L + +#define SN_server_auth "serverAuth" +#define LN_server_auth "TLS Web Server Authentication" +#define NID_server_auth 129 +#define OBJ_server_auth OBJ_id_kp,1L + +#define SN_client_auth "clientAuth" +#define LN_client_auth "TLS Web Client Authentication" +#define NID_client_auth 130 +#define OBJ_client_auth OBJ_id_kp,2L + +#define SN_code_sign "codeSigning" +#define LN_code_sign "Code Signing" +#define NID_code_sign 131 +#define OBJ_code_sign OBJ_id_kp,3L + +#define SN_email_protect "emailProtection" +#define LN_email_protect "E-mail Protection" +#define NID_email_protect 132 +#define OBJ_email_protect OBJ_id_kp,4L + +#define SN_ipsecEndSystem "ipsecEndSystem" +#define LN_ipsecEndSystem "IPSec End System" +#define NID_ipsecEndSystem 294 +#define OBJ_ipsecEndSystem OBJ_id_kp,5L + +#define SN_ipsecTunnel "ipsecTunnel" +#define LN_ipsecTunnel "IPSec Tunnel" +#define NID_ipsecTunnel 295 +#define OBJ_ipsecTunnel OBJ_id_kp,6L + +#define SN_ipsecUser "ipsecUser" +#define LN_ipsecUser "IPSec User" +#define NID_ipsecUser 296 +#define OBJ_ipsecUser OBJ_id_kp,7L + +#define SN_time_stamp "timeStamping" +#define LN_time_stamp "Time Stamping" +#define NID_time_stamp 133 +#define OBJ_time_stamp OBJ_id_kp,8L + +#define SN_OCSP_sign "OCSPSigning" +#define LN_OCSP_sign "OCSP Signing" +#define NID_OCSP_sign 180 +#define OBJ_OCSP_sign OBJ_id_kp,9L + +#define SN_dvcs "DVCS" +#define LN_dvcs "dvcs" +#define NID_dvcs 297 +#define OBJ_dvcs OBJ_id_kp,10L + +#define SN_id_it_caProtEncCert "id-it-caProtEncCert" +#define NID_id_it_caProtEncCert 298 +#define OBJ_id_it_caProtEncCert OBJ_id_it,1L + +#define SN_id_it_signKeyPairTypes "id-it-signKeyPairTypes" +#define NID_id_it_signKeyPairTypes 299 +#define OBJ_id_it_signKeyPairTypes OBJ_id_it,2L + +#define SN_id_it_encKeyPairTypes "id-it-encKeyPairTypes" +#define NID_id_it_encKeyPairTypes 300 +#define OBJ_id_it_encKeyPairTypes OBJ_id_it,3L + +#define SN_id_it_preferredSymmAlg "id-it-preferredSymmAlg" +#define NID_id_it_preferredSymmAlg 301 +#define OBJ_id_it_preferredSymmAlg OBJ_id_it,4L + +#define SN_id_it_caKeyUpdateInfo "id-it-caKeyUpdateInfo" +#define NID_id_it_caKeyUpdateInfo 302 +#define OBJ_id_it_caKeyUpdateInfo OBJ_id_it,5L + +#define SN_id_it_currentCRL "id-it-currentCRL" +#define NID_id_it_currentCRL 303 +#define OBJ_id_it_currentCRL OBJ_id_it,6L + +#define SN_id_it_unsupportedOIDs "id-it-unsupportedOIDs" +#define NID_id_it_unsupportedOIDs 304 +#define OBJ_id_it_unsupportedOIDs OBJ_id_it,7L + +#define SN_id_it_subscriptionRequest "id-it-subscriptionRequest" +#define NID_id_it_subscriptionRequest 305 +#define OBJ_id_it_subscriptionRequest OBJ_id_it,8L + +#define SN_id_it_subscriptionResponse "id-it-subscriptionResponse" +#define NID_id_it_subscriptionResponse 306 +#define OBJ_id_it_subscriptionResponse OBJ_id_it,9L + +#define SN_id_it_keyPairParamReq "id-it-keyPairParamReq" +#define NID_id_it_keyPairParamReq 307 +#define OBJ_id_it_keyPairParamReq OBJ_id_it,10L + +#define SN_id_it_keyPairParamRep "id-it-keyPairParamRep" +#define NID_id_it_keyPairParamRep 308 +#define OBJ_id_it_keyPairParamRep OBJ_id_it,11L + +#define SN_id_it_revPassphrase "id-it-revPassphrase" +#define NID_id_it_revPassphrase 309 +#define OBJ_id_it_revPassphrase OBJ_id_it,12L + +#define SN_id_it_implicitConfirm "id-it-implicitConfirm" +#define NID_id_it_implicitConfirm 310 +#define OBJ_id_it_implicitConfirm OBJ_id_it,13L + +#define SN_id_it_confirmWaitTime "id-it-confirmWaitTime" +#define NID_id_it_confirmWaitTime 311 +#define OBJ_id_it_confirmWaitTime OBJ_id_it,14L + +#define SN_id_it_origPKIMessage "id-it-origPKIMessage" +#define NID_id_it_origPKIMessage 312 +#define OBJ_id_it_origPKIMessage OBJ_id_it,15L + +#define SN_id_it_suppLangTags "id-it-suppLangTags" +#define NID_id_it_suppLangTags 784 +#define OBJ_id_it_suppLangTags OBJ_id_it,16L + +#define SN_id_regCtrl "id-regCtrl" +#define NID_id_regCtrl 313 +#define OBJ_id_regCtrl OBJ_id_pkip,1L + +#define SN_id_regInfo "id-regInfo" +#define NID_id_regInfo 314 +#define OBJ_id_regInfo OBJ_id_pkip,2L + +#define SN_id_regCtrl_regToken "id-regCtrl-regToken" +#define NID_id_regCtrl_regToken 315 +#define OBJ_id_regCtrl_regToken OBJ_id_regCtrl,1L + +#define SN_id_regCtrl_authenticator "id-regCtrl-authenticator" +#define NID_id_regCtrl_authenticator 316 +#define OBJ_id_regCtrl_authenticator OBJ_id_regCtrl,2L + +#define SN_id_regCtrl_pkiPublicationInfo "id-regCtrl-pkiPublicationInfo" +#define NID_id_regCtrl_pkiPublicationInfo 317 +#define OBJ_id_regCtrl_pkiPublicationInfo OBJ_id_regCtrl,3L + +#define SN_id_regCtrl_pkiArchiveOptions "id-regCtrl-pkiArchiveOptions" +#define NID_id_regCtrl_pkiArchiveOptions 318 +#define OBJ_id_regCtrl_pkiArchiveOptions OBJ_id_regCtrl,4L + +#define SN_id_regCtrl_oldCertID "id-regCtrl-oldCertID" +#define NID_id_regCtrl_oldCertID 319 +#define OBJ_id_regCtrl_oldCertID OBJ_id_regCtrl,5L + +#define SN_id_regCtrl_protocolEncrKey "id-regCtrl-protocolEncrKey" +#define NID_id_regCtrl_protocolEncrKey 320 +#define OBJ_id_regCtrl_protocolEncrKey OBJ_id_regCtrl,6L + +#define SN_id_regInfo_utf8Pairs "id-regInfo-utf8Pairs" +#define NID_id_regInfo_utf8Pairs 321 +#define OBJ_id_regInfo_utf8Pairs OBJ_id_regInfo,1L + +#define SN_id_regInfo_certReq "id-regInfo-certReq" +#define NID_id_regInfo_certReq 322 +#define OBJ_id_regInfo_certReq OBJ_id_regInfo,2L + +#define SN_id_alg_des40 "id-alg-des40" +#define NID_id_alg_des40 323 +#define OBJ_id_alg_des40 OBJ_id_alg,1L + +#define SN_id_alg_noSignature "id-alg-noSignature" +#define NID_id_alg_noSignature 324 +#define OBJ_id_alg_noSignature OBJ_id_alg,2L + +#define SN_id_alg_dh_sig_hmac_sha1 "id-alg-dh-sig-hmac-sha1" +#define NID_id_alg_dh_sig_hmac_sha1 325 +#define OBJ_id_alg_dh_sig_hmac_sha1 OBJ_id_alg,3L + +#define SN_id_alg_dh_pop "id-alg-dh-pop" +#define NID_id_alg_dh_pop 326 +#define OBJ_id_alg_dh_pop OBJ_id_alg,4L + +#define SN_id_cmc_statusInfo "id-cmc-statusInfo" +#define NID_id_cmc_statusInfo 327 +#define OBJ_id_cmc_statusInfo OBJ_id_cmc,1L + +#define SN_id_cmc_identification "id-cmc-identification" +#define NID_id_cmc_identification 328 +#define OBJ_id_cmc_identification OBJ_id_cmc,2L + +#define SN_id_cmc_identityProof "id-cmc-identityProof" +#define NID_id_cmc_identityProof 329 +#define OBJ_id_cmc_identityProof OBJ_id_cmc,3L + +#define SN_id_cmc_dataReturn "id-cmc-dataReturn" +#define NID_id_cmc_dataReturn 330 +#define OBJ_id_cmc_dataReturn OBJ_id_cmc,4L + +#define SN_id_cmc_transactionId "id-cmc-transactionId" +#define NID_id_cmc_transactionId 331 +#define OBJ_id_cmc_transactionId OBJ_id_cmc,5L + +#define SN_id_cmc_senderNonce "id-cmc-senderNonce" +#define NID_id_cmc_senderNonce 332 +#define OBJ_id_cmc_senderNonce OBJ_id_cmc,6L + +#define SN_id_cmc_recipientNonce "id-cmc-recipientNonce" +#define NID_id_cmc_recipientNonce 333 +#define OBJ_id_cmc_recipientNonce OBJ_id_cmc,7L + +#define SN_id_cmc_addExtensions "id-cmc-addExtensions" +#define NID_id_cmc_addExtensions 334 +#define OBJ_id_cmc_addExtensions OBJ_id_cmc,8L + +#define SN_id_cmc_encryptedPOP "id-cmc-encryptedPOP" +#define NID_id_cmc_encryptedPOP 335 +#define OBJ_id_cmc_encryptedPOP OBJ_id_cmc,9L + +#define SN_id_cmc_decryptedPOP "id-cmc-decryptedPOP" +#define NID_id_cmc_decryptedPOP 336 +#define OBJ_id_cmc_decryptedPOP OBJ_id_cmc,10L + +#define SN_id_cmc_lraPOPWitness "id-cmc-lraPOPWitness" +#define NID_id_cmc_lraPOPWitness 337 +#define OBJ_id_cmc_lraPOPWitness OBJ_id_cmc,11L + +#define SN_id_cmc_getCert "id-cmc-getCert" +#define NID_id_cmc_getCert 338 +#define OBJ_id_cmc_getCert OBJ_id_cmc,15L + +#define SN_id_cmc_getCRL "id-cmc-getCRL" +#define NID_id_cmc_getCRL 339 +#define OBJ_id_cmc_getCRL OBJ_id_cmc,16L + +#define SN_id_cmc_revokeRequest "id-cmc-revokeRequest" +#define NID_id_cmc_revokeRequest 340 +#define OBJ_id_cmc_revokeRequest OBJ_id_cmc,17L + +#define SN_id_cmc_regInfo "id-cmc-regInfo" +#define NID_id_cmc_regInfo 341 +#define OBJ_id_cmc_regInfo OBJ_id_cmc,18L + +#define SN_id_cmc_responseInfo "id-cmc-responseInfo" +#define NID_id_cmc_responseInfo 342 +#define OBJ_id_cmc_responseInfo OBJ_id_cmc,19L + +#define SN_id_cmc_queryPending "id-cmc-queryPending" +#define NID_id_cmc_queryPending 343 +#define OBJ_id_cmc_queryPending OBJ_id_cmc,21L + +#define SN_id_cmc_popLinkRandom "id-cmc-popLinkRandom" +#define NID_id_cmc_popLinkRandom 344 +#define OBJ_id_cmc_popLinkRandom OBJ_id_cmc,22L + +#define SN_id_cmc_popLinkWitness "id-cmc-popLinkWitness" +#define NID_id_cmc_popLinkWitness 345 +#define OBJ_id_cmc_popLinkWitness OBJ_id_cmc,23L + +#define SN_id_cmc_confirmCertAcceptance "id-cmc-confirmCertAcceptance" +#define NID_id_cmc_confirmCertAcceptance 346 +#define OBJ_id_cmc_confirmCertAcceptance OBJ_id_cmc,24L + +#define SN_id_on_personalData "id-on-personalData" +#define NID_id_on_personalData 347 +#define OBJ_id_on_personalData OBJ_id_on,1L + +#define SN_id_on_permanentIdentifier "id-on-permanentIdentifier" +#define LN_id_on_permanentIdentifier "Permanent Identifier" +#define NID_id_on_permanentIdentifier 858 +#define OBJ_id_on_permanentIdentifier OBJ_id_on,3L + +#define SN_id_pda_dateOfBirth "id-pda-dateOfBirth" +#define NID_id_pda_dateOfBirth 348 +#define OBJ_id_pda_dateOfBirth OBJ_id_pda,1L + +#define SN_id_pda_placeOfBirth "id-pda-placeOfBirth" +#define NID_id_pda_placeOfBirth 349 +#define OBJ_id_pda_placeOfBirth OBJ_id_pda,2L + +#define SN_id_pda_gender "id-pda-gender" +#define NID_id_pda_gender 351 +#define OBJ_id_pda_gender OBJ_id_pda,3L + +#define SN_id_pda_countryOfCitizenship "id-pda-countryOfCitizenship" +#define NID_id_pda_countryOfCitizenship 352 +#define OBJ_id_pda_countryOfCitizenship OBJ_id_pda,4L + +#define SN_id_pda_countryOfResidence "id-pda-countryOfResidence" +#define NID_id_pda_countryOfResidence 353 +#define OBJ_id_pda_countryOfResidence OBJ_id_pda,5L + +#define SN_id_aca_authenticationInfo "id-aca-authenticationInfo" +#define NID_id_aca_authenticationInfo 354 +#define OBJ_id_aca_authenticationInfo OBJ_id_aca,1L + +#define SN_id_aca_accessIdentity "id-aca-accessIdentity" +#define NID_id_aca_accessIdentity 355 +#define OBJ_id_aca_accessIdentity OBJ_id_aca,2L + +#define SN_id_aca_chargingIdentity "id-aca-chargingIdentity" +#define NID_id_aca_chargingIdentity 356 +#define OBJ_id_aca_chargingIdentity OBJ_id_aca,3L + +#define SN_id_aca_group "id-aca-group" +#define NID_id_aca_group 357 +#define OBJ_id_aca_group OBJ_id_aca,4L + +#define SN_id_aca_role "id-aca-role" +#define NID_id_aca_role 358 +#define OBJ_id_aca_role OBJ_id_aca,5L + +#define SN_id_aca_encAttrs "id-aca-encAttrs" +#define NID_id_aca_encAttrs 399 +#define OBJ_id_aca_encAttrs OBJ_id_aca,6L + +#define SN_id_qcs_pkixQCSyntax_v1 "id-qcs-pkixQCSyntax-v1" +#define NID_id_qcs_pkixQCSyntax_v1 359 +#define OBJ_id_qcs_pkixQCSyntax_v1 OBJ_id_qcs,1L + +#define SN_id_cct_crs "id-cct-crs" +#define NID_id_cct_crs 360 +#define OBJ_id_cct_crs OBJ_id_cct,1L + +#define SN_id_cct_PKIData "id-cct-PKIData" +#define NID_id_cct_PKIData 361 +#define OBJ_id_cct_PKIData OBJ_id_cct,2L + +#define SN_id_cct_PKIResponse "id-cct-PKIResponse" +#define NID_id_cct_PKIResponse 362 +#define OBJ_id_cct_PKIResponse OBJ_id_cct,3L + +#define SN_id_ppl_anyLanguage "id-ppl-anyLanguage" +#define LN_id_ppl_anyLanguage "Any language" +#define NID_id_ppl_anyLanguage 664 +#define OBJ_id_ppl_anyLanguage OBJ_id_ppl,0L + +#define SN_id_ppl_inheritAll "id-ppl-inheritAll" +#define LN_id_ppl_inheritAll "Inherit all" +#define NID_id_ppl_inheritAll 665 +#define OBJ_id_ppl_inheritAll OBJ_id_ppl,1L + +#define SN_Independent "id-ppl-independent" +#define LN_Independent "Independent" +#define NID_Independent 667 +#define OBJ_Independent OBJ_id_ppl,2L + +#define SN_ad_OCSP "OCSP" +#define LN_ad_OCSP "OCSP" +#define NID_ad_OCSP 178 +#define OBJ_ad_OCSP OBJ_id_ad,1L + +#define SN_ad_ca_issuers "caIssuers" +#define LN_ad_ca_issuers "CA Issuers" +#define NID_ad_ca_issuers 179 +#define OBJ_ad_ca_issuers OBJ_id_ad,2L + +#define SN_ad_timeStamping "ad_timestamping" +#define LN_ad_timeStamping "AD Time Stamping" +#define NID_ad_timeStamping 363 +#define OBJ_ad_timeStamping OBJ_id_ad,3L + +#define SN_ad_dvcs "AD_DVCS" +#define LN_ad_dvcs "ad dvcs" +#define NID_ad_dvcs 364 +#define OBJ_ad_dvcs OBJ_id_ad,4L + +#define SN_caRepository "caRepository" +#define LN_caRepository "CA Repository" +#define NID_caRepository 785 +#define OBJ_caRepository OBJ_id_ad,5L + +#define OBJ_id_pkix_OCSP OBJ_ad_OCSP + +#define SN_id_pkix_OCSP_basic "basicOCSPResponse" +#define LN_id_pkix_OCSP_basic "Basic OCSP Response" +#define NID_id_pkix_OCSP_basic 365 +#define OBJ_id_pkix_OCSP_basic OBJ_id_pkix_OCSP,1L + +#define SN_id_pkix_OCSP_Nonce "Nonce" +#define LN_id_pkix_OCSP_Nonce "OCSP Nonce" +#define NID_id_pkix_OCSP_Nonce 366 +#define OBJ_id_pkix_OCSP_Nonce OBJ_id_pkix_OCSP,2L + +#define SN_id_pkix_OCSP_CrlID "CrlID" +#define LN_id_pkix_OCSP_CrlID "OCSP CRL ID" +#define NID_id_pkix_OCSP_CrlID 367 +#define OBJ_id_pkix_OCSP_CrlID OBJ_id_pkix_OCSP,3L + +#define SN_id_pkix_OCSP_acceptableResponses "acceptableResponses" +#define LN_id_pkix_OCSP_acceptableResponses "Acceptable OCSP Responses" +#define NID_id_pkix_OCSP_acceptableResponses 368 +#define OBJ_id_pkix_OCSP_acceptableResponses OBJ_id_pkix_OCSP,4L + +#define SN_id_pkix_OCSP_noCheck "noCheck" +#define LN_id_pkix_OCSP_noCheck "OCSP No Check" +#define NID_id_pkix_OCSP_noCheck 369 +#define OBJ_id_pkix_OCSP_noCheck OBJ_id_pkix_OCSP,5L + +#define SN_id_pkix_OCSP_archiveCutoff "archiveCutoff" +#define LN_id_pkix_OCSP_archiveCutoff "OCSP Archive Cutoff" +#define NID_id_pkix_OCSP_archiveCutoff 370 +#define OBJ_id_pkix_OCSP_archiveCutoff OBJ_id_pkix_OCSP,6L + +#define SN_id_pkix_OCSP_serviceLocator "serviceLocator" +#define LN_id_pkix_OCSP_serviceLocator "OCSP Service Locator" +#define NID_id_pkix_OCSP_serviceLocator 371 +#define OBJ_id_pkix_OCSP_serviceLocator OBJ_id_pkix_OCSP,7L + +#define SN_id_pkix_OCSP_extendedStatus "extendedStatus" +#define LN_id_pkix_OCSP_extendedStatus "Extended OCSP Status" +#define NID_id_pkix_OCSP_extendedStatus 372 +#define OBJ_id_pkix_OCSP_extendedStatus OBJ_id_pkix_OCSP,8L + +#define SN_id_pkix_OCSP_valid "valid" +#define NID_id_pkix_OCSP_valid 373 +#define OBJ_id_pkix_OCSP_valid OBJ_id_pkix_OCSP,9L + +#define SN_id_pkix_OCSP_path "path" +#define NID_id_pkix_OCSP_path 374 +#define OBJ_id_pkix_OCSP_path OBJ_id_pkix_OCSP,10L + +#define SN_id_pkix_OCSP_trustRoot "trustRoot" +#define LN_id_pkix_OCSP_trustRoot "Trust Root" +#define NID_id_pkix_OCSP_trustRoot 375 +#define OBJ_id_pkix_OCSP_trustRoot OBJ_id_pkix_OCSP,11L + +#define SN_algorithm "algorithm" +#define LN_algorithm "algorithm" +#define NID_algorithm 376 +#define OBJ_algorithm 1L,3L,14L,3L,2L + +#define SN_md5WithRSA "RSA-NP-MD5" +#define LN_md5WithRSA "md5WithRSA" +#define NID_md5WithRSA 104 +#define OBJ_md5WithRSA OBJ_algorithm,3L + +#define SN_des_ecb "DES-ECB" +#define LN_des_ecb "des-ecb" +#define NID_des_ecb 29 +#define OBJ_des_ecb OBJ_algorithm,6L + +#define SN_des_cbc "DES-CBC" +#define LN_des_cbc "des-cbc" +#define NID_des_cbc 31 +#define OBJ_des_cbc OBJ_algorithm,7L + +#define SN_des_ofb64 "DES-OFB" +#define LN_des_ofb64 "des-ofb" +#define NID_des_ofb64 45 +#define OBJ_des_ofb64 OBJ_algorithm,8L + +#define SN_des_cfb64 "DES-CFB" +#define LN_des_cfb64 "des-cfb" +#define NID_des_cfb64 30 +#define OBJ_des_cfb64 OBJ_algorithm,9L + +#define SN_rsaSignature "rsaSignature" +#define NID_rsaSignature 377 +#define OBJ_rsaSignature OBJ_algorithm,11L + +#define SN_dsa_2 "DSA-old" +#define LN_dsa_2 "dsaEncryption-old" +#define NID_dsa_2 67 +#define OBJ_dsa_2 OBJ_algorithm,12L + +#define SN_dsaWithSHA "DSA-SHA" +#define LN_dsaWithSHA "dsaWithSHA" +#define NID_dsaWithSHA 66 +#define OBJ_dsaWithSHA OBJ_algorithm,13L + +#define SN_shaWithRSAEncryption "RSA-SHA" +#define LN_shaWithRSAEncryption "shaWithRSAEncryption" +#define NID_shaWithRSAEncryption 42 +#define OBJ_shaWithRSAEncryption OBJ_algorithm,15L + +#define SN_des_ede_ecb "DES-EDE" +#define LN_des_ede_ecb "des-ede" +#define NID_des_ede_ecb 32 +#define OBJ_des_ede_ecb OBJ_algorithm,17L + +#define SN_des_ede3_ecb "DES-EDE3" +#define LN_des_ede3_ecb "des-ede3" +#define NID_des_ede3_ecb 33 + +#define SN_des_ede_cbc "DES-EDE-CBC" +#define LN_des_ede_cbc "des-ede-cbc" +#define NID_des_ede_cbc 43 + +#define SN_des_ede_cfb64 "DES-EDE-CFB" +#define LN_des_ede_cfb64 "des-ede-cfb" +#define NID_des_ede_cfb64 60 + +#define SN_des_ede3_cfb64 "DES-EDE3-CFB" +#define LN_des_ede3_cfb64 "des-ede3-cfb" +#define NID_des_ede3_cfb64 61 + +#define SN_des_ede_ofb64 "DES-EDE-OFB" +#define LN_des_ede_ofb64 "des-ede-ofb" +#define NID_des_ede_ofb64 62 + +#define SN_des_ede3_ofb64 "DES-EDE3-OFB" +#define LN_des_ede3_ofb64 "des-ede3-ofb" +#define NID_des_ede3_ofb64 63 + +#define SN_desx_cbc "DESX-CBC" +#define LN_desx_cbc "desx-cbc" +#define NID_desx_cbc 80 + +#define SN_sha "SHA" +#define LN_sha "sha" +#define NID_sha 41 +#define OBJ_sha OBJ_algorithm,18L + +#define SN_sha1 "SHA1" +#define LN_sha1 "sha1" +#define NID_sha1 64 +#define OBJ_sha1 OBJ_algorithm,26L + +#define SN_dsaWithSHA1_2 "DSA-SHA1-old" +#define LN_dsaWithSHA1_2 "dsaWithSHA1-old" +#define NID_dsaWithSHA1_2 70 +#define OBJ_dsaWithSHA1_2 OBJ_algorithm,27L + +#define SN_sha1WithRSA "RSA-SHA1-2" +#define LN_sha1WithRSA "sha1WithRSA" +#define NID_sha1WithRSA 115 +#define OBJ_sha1WithRSA OBJ_algorithm,29L + +#define SN_ripemd160 "RIPEMD160" +#define LN_ripemd160 "ripemd160" +#define NID_ripemd160 117 +#define OBJ_ripemd160 1L,3L,36L,3L,2L,1L + +#define SN_ripemd160WithRSA "RSA-RIPEMD160" +#define LN_ripemd160WithRSA "ripemd160WithRSA" +#define NID_ripemd160WithRSA 119 +#define OBJ_ripemd160WithRSA 1L,3L,36L,3L,3L,1L,2L + +#define SN_sxnet "SXNetID" +#define LN_sxnet "Strong Extranet ID" +#define NID_sxnet 143 +#define OBJ_sxnet 1L,3L,101L,1L,4L,1L + +#define SN_X500 "X500" +#define LN_X500 "directory services (X.500)" +#define NID_X500 11 +#define OBJ_X500 2L,5L + +#define SN_X509 "X509" +#define NID_X509 12 +#define OBJ_X509 OBJ_X500,4L + +#define SN_commonName "CN" +#define LN_commonName "commonName" +#define NID_commonName 13 +#define OBJ_commonName OBJ_X509,3L + +#define SN_surname "SN" +#define LN_surname "surname" +#define NID_surname 100 +#define OBJ_surname OBJ_X509,4L + +#define LN_serialNumber "serialNumber" +#define NID_serialNumber 105 +#define OBJ_serialNumber OBJ_X509,5L + +#define SN_countryName "C" +#define LN_countryName "countryName" +#define NID_countryName 14 +#define OBJ_countryName OBJ_X509,6L + +#define SN_localityName "L" +#define LN_localityName "localityName" +#define NID_localityName 15 +#define OBJ_localityName OBJ_X509,7L + +#define SN_stateOrProvinceName "ST" +#define LN_stateOrProvinceName "stateOrProvinceName" +#define NID_stateOrProvinceName 16 +#define OBJ_stateOrProvinceName OBJ_X509,8L + +#define SN_streetAddress "street" +#define LN_streetAddress "streetAddress" +#define NID_streetAddress 660 +#define OBJ_streetAddress OBJ_X509,9L + +#define SN_organizationName "O" +#define LN_organizationName "organizationName" +#define NID_organizationName 17 +#define OBJ_organizationName OBJ_X509,10L + +#define SN_organizationalUnitName "OU" +#define LN_organizationalUnitName "organizationalUnitName" +#define NID_organizationalUnitName 18 +#define OBJ_organizationalUnitName OBJ_X509,11L + +#define SN_title "title" +#define LN_title "title" +#define NID_title 106 +#define OBJ_title OBJ_X509,12L + +#define LN_description "description" +#define NID_description 107 +#define OBJ_description OBJ_X509,13L + +#define LN_searchGuide "searchGuide" +#define NID_searchGuide 859 +#define OBJ_searchGuide OBJ_X509,14L + +#define LN_businessCategory "businessCategory" +#define NID_businessCategory 860 +#define OBJ_businessCategory OBJ_X509,15L + +#define LN_postalAddress "postalAddress" +#define NID_postalAddress 861 +#define OBJ_postalAddress OBJ_X509,16L + +#define LN_postalCode "postalCode" +#define NID_postalCode 661 +#define OBJ_postalCode OBJ_X509,17L + +#define LN_postOfficeBox "postOfficeBox" +#define NID_postOfficeBox 862 +#define OBJ_postOfficeBox OBJ_X509,18L + +#define LN_physicalDeliveryOfficeName "physicalDeliveryOfficeName" +#define NID_physicalDeliveryOfficeName 863 +#define OBJ_physicalDeliveryOfficeName OBJ_X509,19L + +#define LN_telephoneNumber "telephoneNumber" +#define NID_telephoneNumber 864 +#define OBJ_telephoneNumber OBJ_X509,20L + +#define LN_telexNumber "telexNumber" +#define NID_telexNumber 865 +#define OBJ_telexNumber OBJ_X509,21L + +#define LN_teletexTerminalIdentifier "teletexTerminalIdentifier" +#define NID_teletexTerminalIdentifier 866 +#define OBJ_teletexTerminalIdentifier OBJ_X509,22L + +#define LN_facsimileTelephoneNumber "facsimileTelephoneNumber" +#define NID_facsimileTelephoneNumber 867 +#define OBJ_facsimileTelephoneNumber OBJ_X509,23L + +#define LN_x121Address "x121Address" +#define NID_x121Address 868 +#define OBJ_x121Address OBJ_X509,24L + +#define LN_internationaliSDNNumber "internationaliSDNNumber" +#define NID_internationaliSDNNumber 869 +#define OBJ_internationaliSDNNumber OBJ_X509,25L + +#define LN_registeredAddress "registeredAddress" +#define NID_registeredAddress 870 +#define OBJ_registeredAddress OBJ_X509,26L + +#define LN_destinationIndicator "destinationIndicator" +#define NID_destinationIndicator 871 +#define OBJ_destinationIndicator OBJ_X509,27L + +#define LN_preferredDeliveryMethod "preferredDeliveryMethod" +#define NID_preferredDeliveryMethod 872 +#define OBJ_preferredDeliveryMethod OBJ_X509,28L + +#define LN_presentationAddress "presentationAddress" +#define NID_presentationAddress 873 +#define OBJ_presentationAddress OBJ_X509,29L + +#define LN_supportedApplicationContext "supportedApplicationContext" +#define NID_supportedApplicationContext 874 +#define OBJ_supportedApplicationContext OBJ_X509,30L + +#define SN_member "member" +#define NID_member 875 +#define OBJ_member OBJ_X509,31L + +#define SN_owner "owner" +#define NID_owner 876 +#define OBJ_owner OBJ_X509,32L + +#define LN_roleOccupant "roleOccupant" +#define NID_roleOccupant 877 +#define OBJ_roleOccupant OBJ_X509,33L + +#define SN_seeAlso "seeAlso" +#define NID_seeAlso 878 +#define OBJ_seeAlso OBJ_X509,34L + +#define LN_userPassword "userPassword" +#define NID_userPassword 879 +#define OBJ_userPassword OBJ_X509,35L + +#define LN_userCertificate "userCertificate" +#define NID_userCertificate 880 +#define OBJ_userCertificate OBJ_X509,36L + +#define LN_cACertificate "cACertificate" +#define NID_cACertificate 881 +#define OBJ_cACertificate OBJ_X509,37L + +#define LN_authorityRevocationList "authorityRevocationList" +#define NID_authorityRevocationList 882 +#define OBJ_authorityRevocationList OBJ_X509,38L + +#define LN_certificateRevocationList "certificateRevocationList" +#define NID_certificateRevocationList 883 +#define OBJ_certificateRevocationList OBJ_X509,39L + +#define LN_crossCertificatePair "crossCertificatePair" +#define NID_crossCertificatePair 884 +#define OBJ_crossCertificatePair OBJ_X509,40L + +#define SN_name "name" +#define LN_name "name" +#define NID_name 173 +#define OBJ_name OBJ_X509,41L + +#define SN_givenName "GN" +#define LN_givenName "givenName" +#define NID_givenName 99 +#define OBJ_givenName OBJ_X509,42L + +#define SN_initials "initials" +#define LN_initials "initials" +#define NID_initials 101 +#define OBJ_initials OBJ_X509,43L + +#define LN_generationQualifier "generationQualifier" +#define NID_generationQualifier 509 +#define OBJ_generationQualifier OBJ_X509,44L + +#define LN_x500UniqueIdentifier "x500UniqueIdentifier" +#define NID_x500UniqueIdentifier 503 +#define OBJ_x500UniqueIdentifier OBJ_X509,45L + +#define SN_dnQualifier "dnQualifier" +#define LN_dnQualifier "dnQualifier" +#define NID_dnQualifier 174 +#define OBJ_dnQualifier OBJ_X509,46L + +#define LN_enhancedSearchGuide "enhancedSearchGuide" +#define NID_enhancedSearchGuide 885 +#define OBJ_enhancedSearchGuide OBJ_X509,47L + +#define LN_protocolInformation "protocolInformation" +#define NID_protocolInformation 886 +#define OBJ_protocolInformation OBJ_X509,48L + +#define LN_distinguishedName "distinguishedName" +#define NID_distinguishedName 887 +#define OBJ_distinguishedName OBJ_X509,49L + +#define LN_uniqueMember "uniqueMember" +#define NID_uniqueMember 888 +#define OBJ_uniqueMember OBJ_X509,50L + +#define LN_houseIdentifier "houseIdentifier" +#define NID_houseIdentifier 889 +#define OBJ_houseIdentifier OBJ_X509,51L + +#define LN_supportedAlgorithms "supportedAlgorithms" +#define NID_supportedAlgorithms 890 +#define OBJ_supportedAlgorithms OBJ_X509,52L + +#define LN_deltaRevocationList "deltaRevocationList" +#define NID_deltaRevocationList 891 +#define OBJ_deltaRevocationList OBJ_X509,53L + +#define SN_dmdName "dmdName" +#define NID_dmdName 892 +#define OBJ_dmdName OBJ_X509,54L + +#define LN_pseudonym "pseudonym" +#define NID_pseudonym 510 +#define OBJ_pseudonym OBJ_X509,65L + +#define SN_role "role" +#define LN_role "role" +#define NID_role 400 +#define OBJ_role OBJ_X509,72L + +#define SN_X500algorithms "X500algorithms" +#define LN_X500algorithms "directory services - algorithms" +#define NID_X500algorithms 378 +#define OBJ_X500algorithms OBJ_X500,8L + +#define SN_rsa "RSA" +#define LN_rsa "rsa" +#define NID_rsa 19 +#define OBJ_rsa OBJ_X500algorithms,1L,1L + +#define SN_mdc2WithRSA "RSA-MDC2" +#define LN_mdc2WithRSA "mdc2WithRSA" +#define NID_mdc2WithRSA 96 +#define OBJ_mdc2WithRSA OBJ_X500algorithms,3L,100L + +#define SN_mdc2 "MDC2" +#define LN_mdc2 "mdc2" +#define NID_mdc2 95 +#define OBJ_mdc2 OBJ_X500algorithms,3L,101L + +#define SN_id_ce "id-ce" +#define NID_id_ce 81 +#define OBJ_id_ce OBJ_X500,29L + +#define SN_subject_directory_attributes "subjectDirectoryAttributes" +#define LN_subject_directory_attributes "X509v3 Subject Directory Attributes" +#define NID_subject_directory_attributes 769 +#define OBJ_subject_directory_attributes OBJ_id_ce,9L + +#define SN_subject_key_identifier "subjectKeyIdentifier" +#define LN_subject_key_identifier "X509v3 Subject Key Identifier" +#define NID_subject_key_identifier 82 +#define OBJ_subject_key_identifier OBJ_id_ce,14L + +#define SN_key_usage "keyUsage" +#define LN_key_usage "X509v3 Key Usage" +#define NID_key_usage 83 +#define OBJ_key_usage OBJ_id_ce,15L + +#define SN_private_key_usage_period "privateKeyUsagePeriod" +#define LN_private_key_usage_period "X509v3 Private Key Usage Period" +#define NID_private_key_usage_period 84 +#define OBJ_private_key_usage_period OBJ_id_ce,16L + +#define SN_subject_alt_name "subjectAltName" +#define LN_subject_alt_name "X509v3 Subject Alternative Name" +#define NID_subject_alt_name 85 +#define OBJ_subject_alt_name OBJ_id_ce,17L + +#define SN_issuer_alt_name "issuerAltName" +#define LN_issuer_alt_name "X509v3 Issuer Alternative Name" +#define NID_issuer_alt_name 86 +#define OBJ_issuer_alt_name OBJ_id_ce,18L + +#define SN_basic_constraints "basicConstraints" +#define LN_basic_constraints "X509v3 Basic Constraints" +#define NID_basic_constraints 87 +#define OBJ_basic_constraints OBJ_id_ce,19L + +#define SN_crl_number "crlNumber" +#define LN_crl_number "X509v3 CRL Number" +#define NID_crl_number 88 +#define OBJ_crl_number OBJ_id_ce,20L + +#define SN_crl_reason "CRLReason" +#define LN_crl_reason "X509v3 CRL Reason Code" +#define NID_crl_reason 141 +#define OBJ_crl_reason OBJ_id_ce,21L + +#define SN_invalidity_date "invalidityDate" +#define LN_invalidity_date "Invalidity Date" +#define NID_invalidity_date 142 +#define OBJ_invalidity_date OBJ_id_ce,24L + +#define SN_delta_crl "deltaCRL" +#define LN_delta_crl "X509v3 Delta CRL Indicator" +#define NID_delta_crl 140 +#define OBJ_delta_crl OBJ_id_ce,27L + +#define SN_issuing_distribution_point "issuingDistributionPoint" +#define LN_issuing_distribution_point "X509v3 Issuing Distrubution Point" +#define NID_issuing_distribution_point 770 +#define OBJ_issuing_distribution_point OBJ_id_ce,28L + +#define SN_certificate_issuer "certificateIssuer" +#define LN_certificate_issuer "X509v3 Certificate Issuer" +#define NID_certificate_issuer 771 +#define OBJ_certificate_issuer OBJ_id_ce,29L + +#define SN_name_constraints "nameConstraints" +#define LN_name_constraints "X509v3 Name Constraints" +#define NID_name_constraints 666 +#define OBJ_name_constraints OBJ_id_ce,30L + +#define SN_crl_distribution_points "crlDistributionPoints" +#define LN_crl_distribution_points "X509v3 CRL Distribution Points" +#define NID_crl_distribution_points 103 +#define OBJ_crl_distribution_points OBJ_id_ce,31L + +#define SN_certificate_policies "certificatePolicies" +#define LN_certificate_policies "X509v3 Certificate Policies" +#define NID_certificate_policies 89 +#define OBJ_certificate_policies OBJ_id_ce,32L + +#define SN_any_policy "anyPolicy" +#define LN_any_policy "X509v3 Any Policy" +#define NID_any_policy 746 +#define OBJ_any_policy OBJ_certificate_policies,0L + +#define SN_policy_mappings "policyMappings" +#define LN_policy_mappings "X509v3 Policy Mappings" +#define NID_policy_mappings 747 +#define OBJ_policy_mappings OBJ_id_ce,33L + +#define SN_authority_key_identifier "authorityKeyIdentifier" +#define LN_authority_key_identifier "X509v3 Authority Key Identifier" +#define NID_authority_key_identifier 90 +#define OBJ_authority_key_identifier OBJ_id_ce,35L + +#define SN_policy_constraints "policyConstraints" +#define LN_policy_constraints "X509v3 Policy Constraints" +#define NID_policy_constraints 401 +#define OBJ_policy_constraints OBJ_id_ce,36L + +#define SN_ext_key_usage "extendedKeyUsage" +#define LN_ext_key_usage "X509v3 Extended Key Usage" +#define NID_ext_key_usage 126 +#define OBJ_ext_key_usage OBJ_id_ce,37L + +#define SN_freshest_crl "freshestCRL" +#define LN_freshest_crl "X509v3 Freshest CRL" +#define NID_freshest_crl 857 +#define OBJ_freshest_crl OBJ_id_ce,46L + +#define SN_inhibit_any_policy "inhibitAnyPolicy" +#define LN_inhibit_any_policy "X509v3 Inhibit Any Policy" +#define NID_inhibit_any_policy 748 +#define OBJ_inhibit_any_policy OBJ_id_ce,54L + +#define SN_target_information "targetInformation" +#define LN_target_information "X509v3 AC Targeting" +#define NID_target_information 402 +#define OBJ_target_information OBJ_id_ce,55L + +#define SN_no_rev_avail "noRevAvail" +#define LN_no_rev_avail "X509v3 No Revocation Available" +#define NID_no_rev_avail 403 +#define OBJ_no_rev_avail OBJ_id_ce,56L + +#define SN_anyExtendedKeyUsage "anyExtendedKeyUsage" +#define LN_anyExtendedKeyUsage "Any Extended Key Usage" +#define NID_anyExtendedKeyUsage 910 +#define OBJ_anyExtendedKeyUsage OBJ_ext_key_usage,0L + +#define SN_netscape "Netscape" +#define LN_netscape "Netscape Communications Corp." +#define NID_netscape 57 +#define OBJ_netscape 2L,16L,840L,1L,113730L + +#define SN_netscape_cert_extension "nsCertExt" +#define LN_netscape_cert_extension "Netscape Certificate Extension" +#define NID_netscape_cert_extension 58 +#define OBJ_netscape_cert_extension OBJ_netscape,1L + +#define SN_netscape_data_type "nsDataType" +#define LN_netscape_data_type "Netscape Data Type" +#define NID_netscape_data_type 59 +#define OBJ_netscape_data_type OBJ_netscape,2L + +#define SN_netscape_cert_type "nsCertType" +#define LN_netscape_cert_type "Netscape Cert Type" +#define NID_netscape_cert_type 71 +#define OBJ_netscape_cert_type OBJ_netscape_cert_extension,1L + +#define SN_netscape_base_url "nsBaseUrl" +#define LN_netscape_base_url "Netscape Base Url" +#define NID_netscape_base_url 72 +#define OBJ_netscape_base_url OBJ_netscape_cert_extension,2L + +#define SN_netscape_revocation_url "nsRevocationUrl" +#define LN_netscape_revocation_url "Netscape Revocation Url" +#define NID_netscape_revocation_url 73 +#define OBJ_netscape_revocation_url OBJ_netscape_cert_extension,3L + +#define SN_netscape_ca_revocation_url "nsCaRevocationUrl" +#define LN_netscape_ca_revocation_url "Netscape CA Revocation Url" +#define NID_netscape_ca_revocation_url 74 +#define OBJ_netscape_ca_revocation_url OBJ_netscape_cert_extension,4L + +#define SN_netscape_renewal_url "nsRenewalUrl" +#define LN_netscape_renewal_url "Netscape Renewal Url" +#define NID_netscape_renewal_url 75 +#define OBJ_netscape_renewal_url OBJ_netscape_cert_extension,7L + +#define SN_netscape_ca_policy_url "nsCaPolicyUrl" +#define LN_netscape_ca_policy_url "Netscape CA Policy Url" +#define NID_netscape_ca_policy_url 76 +#define OBJ_netscape_ca_policy_url OBJ_netscape_cert_extension,8L + +#define SN_netscape_ssl_server_name "nsSslServerName" +#define LN_netscape_ssl_server_name "Netscape SSL Server Name" +#define NID_netscape_ssl_server_name 77 +#define OBJ_netscape_ssl_server_name OBJ_netscape_cert_extension,12L + +#define SN_netscape_comment "nsComment" +#define LN_netscape_comment "Netscape Comment" +#define NID_netscape_comment 78 +#define OBJ_netscape_comment OBJ_netscape_cert_extension,13L + +#define SN_netscape_cert_sequence "nsCertSequence" +#define LN_netscape_cert_sequence "Netscape Certificate Sequence" +#define NID_netscape_cert_sequence 79 +#define OBJ_netscape_cert_sequence OBJ_netscape_data_type,5L + +#define SN_ns_sgc "nsSGC" +#define LN_ns_sgc "Netscape Server Gated Crypto" +#define NID_ns_sgc 139 +#define OBJ_ns_sgc OBJ_netscape,4L,1L + +#define SN_org "ORG" +#define LN_org "org" +#define NID_org 379 +#define OBJ_org OBJ_iso,3L + +#define SN_dod "DOD" +#define LN_dod "dod" +#define NID_dod 380 +#define OBJ_dod OBJ_org,6L + +#define SN_iana "IANA" +#define LN_iana "iana" +#define NID_iana 381 +#define OBJ_iana OBJ_dod,1L + +#define OBJ_internet OBJ_iana + +#define SN_Directory "directory" +#define LN_Directory "Directory" +#define NID_Directory 382 +#define OBJ_Directory OBJ_internet,1L + +#define SN_Management "mgmt" +#define LN_Management "Management" +#define NID_Management 383 +#define OBJ_Management OBJ_internet,2L + +#define SN_Experimental "experimental" +#define LN_Experimental "Experimental" +#define NID_Experimental 384 +#define OBJ_Experimental OBJ_internet,3L + +#define SN_Private "private" +#define LN_Private "Private" +#define NID_Private 385 +#define OBJ_Private OBJ_internet,4L + +#define SN_Security "security" +#define LN_Security "Security" +#define NID_Security 386 +#define OBJ_Security OBJ_internet,5L + +#define SN_SNMPv2 "snmpv2" +#define LN_SNMPv2 "SNMPv2" +#define NID_SNMPv2 387 +#define OBJ_SNMPv2 OBJ_internet,6L + +#define LN_Mail "Mail" +#define NID_Mail 388 +#define OBJ_Mail OBJ_internet,7L + +#define SN_Enterprises "enterprises" +#define LN_Enterprises "Enterprises" +#define NID_Enterprises 389 +#define OBJ_Enterprises OBJ_Private,1L + +#define SN_dcObject "dcobject" +#define LN_dcObject "dcObject" +#define NID_dcObject 390 +#define OBJ_dcObject OBJ_Enterprises,1466L,344L + +#define SN_mime_mhs "mime-mhs" +#define LN_mime_mhs "MIME MHS" +#define NID_mime_mhs 504 +#define OBJ_mime_mhs OBJ_Mail,1L + +#define SN_mime_mhs_headings "mime-mhs-headings" +#define LN_mime_mhs_headings "mime-mhs-headings" +#define NID_mime_mhs_headings 505 +#define OBJ_mime_mhs_headings OBJ_mime_mhs,1L + +#define SN_mime_mhs_bodies "mime-mhs-bodies" +#define LN_mime_mhs_bodies "mime-mhs-bodies" +#define NID_mime_mhs_bodies 506 +#define OBJ_mime_mhs_bodies OBJ_mime_mhs,2L + +#define SN_id_hex_partial_message "id-hex-partial-message" +#define LN_id_hex_partial_message "id-hex-partial-message" +#define NID_id_hex_partial_message 507 +#define OBJ_id_hex_partial_message OBJ_mime_mhs_headings,1L + +#define SN_id_hex_multipart_message "id-hex-multipart-message" +#define LN_id_hex_multipart_message "id-hex-multipart-message" +#define NID_id_hex_multipart_message 508 +#define OBJ_id_hex_multipart_message OBJ_mime_mhs_headings,2L + +#define SN_rle_compression "RLE" +#define LN_rle_compression "run length compression" +#define NID_rle_compression 124 +#define OBJ_rle_compression 1L,1L,1L,1L,666L,1L + +#define SN_zlib_compression "ZLIB" +#define LN_zlib_compression "zlib compression" +#define NID_zlib_compression 125 +#define OBJ_zlib_compression OBJ_id_smime_alg,8L + +#define OBJ_csor 2L,16L,840L,1L,101L,3L + +#define OBJ_nistAlgorithms OBJ_csor,4L + +#define OBJ_aes OBJ_nistAlgorithms,1L + +#define SN_aes_128_ecb "AES-128-ECB" +#define LN_aes_128_ecb "aes-128-ecb" +#define NID_aes_128_ecb 418 +#define OBJ_aes_128_ecb OBJ_aes,1L + +#define SN_aes_128_cbc "AES-128-CBC" +#define LN_aes_128_cbc "aes-128-cbc" +#define NID_aes_128_cbc 419 +#define OBJ_aes_128_cbc OBJ_aes,2L + +#define SN_aes_128_ofb128 "AES-128-OFB" +#define LN_aes_128_ofb128 "aes-128-ofb" +#define NID_aes_128_ofb128 420 +#define OBJ_aes_128_ofb128 OBJ_aes,3L + +#define SN_aes_128_cfb128 "AES-128-CFB" +#define LN_aes_128_cfb128 "aes-128-cfb" +#define NID_aes_128_cfb128 421 +#define OBJ_aes_128_cfb128 OBJ_aes,4L + +#define SN_id_aes128_wrap "id-aes128-wrap" +#define NID_id_aes128_wrap 788 +#define OBJ_id_aes128_wrap OBJ_aes,5L + +#define SN_aes_128_gcm "id-aes128-GCM" +#define LN_aes_128_gcm "aes-128-gcm" +#define NID_aes_128_gcm 895 +#define OBJ_aes_128_gcm OBJ_aes,6L + +#define SN_aes_128_ccm "id-aes128-CCM" +#define LN_aes_128_ccm "aes-128-ccm" +#define NID_aes_128_ccm 896 +#define OBJ_aes_128_ccm OBJ_aes,7L + +#define SN_id_aes128_wrap_pad "id-aes128-wrap-pad" +#define NID_id_aes128_wrap_pad 897 +#define OBJ_id_aes128_wrap_pad OBJ_aes,8L + +#define SN_aes_192_ecb "AES-192-ECB" +#define LN_aes_192_ecb "aes-192-ecb" +#define NID_aes_192_ecb 422 +#define OBJ_aes_192_ecb OBJ_aes,21L + +#define SN_aes_192_cbc "AES-192-CBC" +#define LN_aes_192_cbc "aes-192-cbc" +#define NID_aes_192_cbc 423 +#define OBJ_aes_192_cbc OBJ_aes,22L + +#define SN_aes_192_ofb128 "AES-192-OFB" +#define LN_aes_192_ofb128 "aes-192-ofb" +#define NID_aes_192_ofb128 424 +#define OBJ_aes_192_ofb128 OBJ_aes,23L + +#define SN_aes_192_cfb128 "AES-192-CFB" +#define LN_aes_192_cfb128 "aes-192-cfb" +#define NID_aes_192_cfb128 425 +#define OBJ_aes_192_cfb128 OBJ_aes,24L + +#define SN_id_aes192_wrap "id-aes192-wrap" +#define NID_id_aes192_wrap 789 +#define OBJ_id_aes192_wrap OBJ_aes,25L + +#define SN_aes_192_gcm "id-aes192-GCM" +#define LN_aes_192_gcm "aes-192-gcm" +#define NID_aes_192_gcm 898 +#define OBJ_aes_192_gcm OBJ_aes,26L + +#define SN_aes_192_ccm "id-aes192-CCM" +#define LN_aes_192_ccm "aes-192-ccm" +#define NID_aes_192_ccm 899 +#define OBJ_aes_192_ccm OBJ_aes,27L + +#define SN_id_aes192_wrap_pad "id-aes192-wrap-pad" +#define NID_id_aes192_wrap_pad 900 +#define OBJ_id_aes192_wrap_pad OBJ_aes,28L + +#define SN_aes_256_ecb "AES-256-ECB" +#define LN_aes_256_ecb "aes-256-ecb" +#define NID_aes_256_ecb 426 +#define OBJ_aes_256_ecb OBJ_aes,41L + +#define SN_aes_256_cbc "AES-256-CBC" +#define LN_aes_256_cbc "aes-256-cbc" +#define NID_aes_256_cbc 427 +#define OBJ_aes_256_cbc OBJ_aes,42L + +#define SN_aes_256_ofb128 "AES-256-OFB" +#define LN_aes_256_ofb128 "aes-256-ofb" +#define NID_aes_256_ofb128 428 +#define OBJ_aes_256_ofb128 OBJ_aes,43L + +#define SN_aes_256_cfb128 "AES-256-CFB" +#define LN_aes_256_cfb128 "aes-256-cfb" +#define NID_aes_256_cfb128 429 +#define OBJ_aes_256_cfb128 OBJ_aes,44L + +#define SN_id_aes256_wrap "id-aes256-wrap" +#define NID_id_aes256_wrap 790 +#define OBJ_id_aes256_wrap OBJ_aes,45L + +#define SN_aes_256_gcm "id-aes256-GCM" +#define LN_aes_256_gcm "aes-256-gcm" +#define NID_aes_256_gcm 901 +#define OBJ_aes_256_gcm OBJ_aes,46L + +#define SN_aes_256_ccm "id-aes256-CCM" +#define LN_aes_256_ccm "aes-256-ccm" +#define NID_aes_256_ccm 902 +#define OBJ_aes_256_ccm OBJ_aes,47L + +#define SN_id_aes256_wrap_pad "id-aes256-wrap-pad" +#define NID_id_aes256_wrap_pad 903 +#define OBJ_id_aes256_wrap_pad OBJ_aes,48L + +#define SN_aes_128_cfb1 "AES-128-CFB1" +#define LN_aes_128_cfb1 "aes-128-cfb1" +#define NID_aes_128_cfb1 650 + +#define SN_aes_192_cfb1 "AES-192-CFB1" +#define LN_aes_192_cfb1 "aes-192-cfb1" +#define NID_aes_192_cfb1 651 + +#define SN_aes_256_cfb1 "AES-256-CFB1" +#define LN_aes_256_cfb1 "aes-256-cfb1" +#define NID_aes_256_cfb1 652 + +#define SN_aes_128_cfb8 "AES-128-CFB8" +#define LN_aes_128_cfb8 "aes-128-cfb8" +#define NID_aes_128_cfb8 653 + +#define SN_aes_192_cfb8 "AES-192-CFB8" +#define LN_aes_192_cfb8 "aes-192-cfb8" +#define NID_aes_192_cfb8 654 + +#define SN_aes_256_cfb8 "AES-256-CFB8" +#define LN_aes_256_cfb8 "aes-256-cfb8" +#define NID_aes_256_cfb8 655 + +#define SN_aes_128_ctr "AES-128-CTR" +#define LN_aes_128_ctr "aes-128-ctr" +#define NID_aes_128_ctr 904 + +#define SN_aes_192_ctr "AES-192-CTR" +#define LN_aes_192_ctr "aes-192-ctr" +#define NID_aes_192_ctr 905 + +#define SN_aes_256_ctr "AES-256-CTR" +#define LN_aes_256_ctr "aes-256-ctr" +#define NID_aes_256_ctr 906 + +#define SN_aes_128_xts "AES-128-XTS" +#define LN_aes_128_xts "aes-128-xts" +#define NID_aes_128_xts 913 + +#define SN_aes_256_xts "AES-256-XTS" +#define LN_aes_256_xts "aes-256-xts" +#define NID_aes_256_xts 914 + +#define SN_des_cfb1 "DES-CFB1" +#define LN_des_cfb1 "des-cfb1" +#define NID_des_cfb1 656 + +#define SN_des_cfb8 "DES-CFB8" +#define LN_des_cfb8 "des-cfb8" +#define NID_des_cfb8 657 + +#define SN_des_ede3_cfb1 "DES-EDE3-CFB1" +#define LN_des_ede3_cfb1 "des-ede3-cfb1" +#define NID_des_ede3_cfb1 658 + +#define SN_des_ede3_cfb8 "DES-EDE3-CFB8" +#define LN_des_ede3_cfb8 "des-ede3-cfb8" +#define NID_des_ede3_cfb8 659 + +#define OBJ_nist_hashalgs OBJ_nistAlgorithms,2L + +#define SN_sha256 "SHA256" +#define LN_sha256 "sha256" +#define NID_sha256 672 +#define OBJ_sha256 OBJ_nist_hashalgs,1L + +#define SN_sha384 "SHA384" +#define LN_sha384 "sha384" +#define NID_sha384 673 +#define OBJ_sha384 OBJ_nist_hashalgs,2L + +#define SN_sha512 "SHA512" +#define LN_sha512 "sha512" +#define NID_sha512 674 +#define OBJ_sha512 OBJ_nist_hashalgs,3L + +#define SN_sha224 "SHA224" +#define LN_sha224 "sha224" +#define NID_sha224 675 +#define OBJ_sha224 OBJ_nist_hashalgs,4L + +#define OBJ_dsa_with_sha2 OBJ_nistAlgorithms,3L + +#define SN_dsa_with_SHA224 "dsa_with_SHA224" +#define NID_dsa_with_SHA224 802 +#define OBJ_dsa_with_SHA224 OBJ_dsa_with_sha2,1L + +#define SN_dsa_with_SHA256 "dsa_with_SHA256" +#define NID_dsa_with_SHA256 803 +#define OBJ_dsa_with_SHA256 OBJ_dsa_with_sha2,2L + +#define SN_hold_instruction_code "holdInstructionCode" +#define LN_hold_instruction_code "Hold Instruction Code" +#define NID_hold_instruction_code 430 +#define OBJ_hold_instruction_code OBJ_id_ce,23L + +#define OBJ_holdInstruction OBJ_X9_57,2L + +#define SN_hold_instruction_none "holdInstructionNone" +#define LN_hold_instruction_none "Hold Instruction None" +#define NID_hold_instruction_none 431 +#define OBJ_hold_instruction_none OBJ_holdInstruction,1L + +#define SN_hold_instruction_call_issuer "holdInstructionCallIssuer" +#define LN_hold_instruction_call_issuer "Hold Instruction Call Issuer" +#define NID_hold_instruction_call_issuer 432 +#define OBJ_hold_instruction_call_issuer OBJ_holdInstruction,2L + +#define SN_hold_instruction_reject "holdInstructionReject" +#define LN_hold_instruction_reject "Hold Instruction Reject" +#define NID_hold_instruction_reject 433 +#define OBJ_hold_instruction_reject OBJ_holdInstruction,3L + +#define SN_data "data" +#define NID_data 434 +#define OBJ_data OBJ_itu_t,9L + +#define SN_pss "pss" +#define NID_pss 435 +#define OBJ_pss OBJ_data,2342L + +#define SN_ucl "ucl" +#define NID_ucl 436 +#define OBJ_ucl OBJ_pss,19200300L + +#define SN_pilot "pilot" +#define NID_pilot 437 +#define OBJ_pilot OBJ_ucl,100L + +#define LN_pilotAttributeType "pilotAttributeType" +#define NID_pilotAttributeType 438 +#define OBJ_pilotAttributeType OBJ_pilot,1L + +#define LN_pilotAttributeSyntax "pilotAttributeSyntax" +#define NID_pilotAttributeSyntax 439 +#define OBJ_pilotAttributeSyntax OBJ_pilot,3L + +#define LN_pilotObjectClass "pilotObjectClass" +#define NID_pilotObjectClass 440 +#define OBJ_pilotObjectClass OBJ_pilot,4L + +#define LN_pilotGroups "pilotGroups" +#define NID_pilotGroups 441 +#define OBJ_pilotGroups OBJ_pilot,10L + +#define LN_iA5StringSyntax "iA5StringSyntax" +#define NID_iA5StringSyntax 442 +#define OBJ_iA5StringSyntax OBJ_pilotAttributeSyntax,4L + +#define LN_caseIgnoreIA5StringSyntax "caseIgnoreIA5StringSyntax" +#define NID_caseIgnoreIA5StringSyntax 443 +#define OBJ_caseIgnoreIA5StringSyntax OBJ_pilotAttributeSyntax,5L + +#define LN_pilotObject "pilotObject" +#define NID_pilotObject 444 +#define OBJ_pilotObject OBJ_pilotObjectClass,3L + +#define LN_pilotPerson "pilotPerson" +#define NID_pilotPerson 445 +#define OBJ_pilotPerson OBJ_pilotObjectClass,4L + +#define SN_account "account" +#define NID_account 446 +#define OBJ_account OBJ_pilotObjectClass,5L + +#define SN_document "document" +#define NID_document 447 +#define OBJ_document OBJ_pilotObjectClass,6L + +#define SN_room "room" +#define NID_room 448 +#define OBJ_room OBJ_pilotObjectClass,7L + +#define LN_documentSeries "documentSeries" +#define NID_documentSeries 449 +#define OBJ_documentSeries OBJ_pilotObjectClass,9L + +#define SN_Domain "domain" +#define LN_Domain "Domain" +#define NID_Domain 392 +#define OBJ_Domain OBJ_pilotObjectClass,13L + +#define LN_rFC822localPart "rFC822localPart" +#define NID_rFC822localPart 450 +#define OBJ_rFC822localPart OBJ_pilotObjectClass,14L + +#define LN_dNSDomain "dNSDomain" +#define NID_dNSDomain 451 +#define OBJ_dNSDomain OBJ_pilotObjectClass,15L + +#define LN_domainRelatedObject "domainRelatedObject" +#define NID_domainRelatedObject 452 +#define OBJ_domainRelatedObject OBJ_pilotObjectClass,17L + +#define LN_friendlyCountry "friendlyCountry" +#define NID_friendlyCountry 453 +#define OBJ_friendlyCountry OBJ_pilotObjectClass,18L + +#define LN_simpleSecurityObject "simpleSecurityObject" +#define NID_simpleSecurityObject 454 +#define OBJ_simpleSecurityObject OBJ_pilotObjectClass,19L + +#define LN_pilotOrganization "pilotOrganization" +#define NID_pilotOrganization 455 +#define OBJ_pilotOrganization OBJ_pilotObjectClass,20L + +#define LN_pilotDSA "pilotDSA" +#define NID_pilotDSA 456 +#define OBJ_pilotDSA OBJ_pilotObjectClass,21L + +#define LN_qualityLabelledData "qualityLabelledData" +#define NID_qualityLabelledData 457 +#define OBJ_qualityLabelledData OBJ_pilotObjectClass,22L + +#define SN_userId "UID" +#define LN_userId "userId" +#define NID_userId 458 +#define OBJ_userId OBJ_pilotAttributeType,1L + +#define LN_textEncodedORAddress "textEncodedORAddress" +#define NID_textEncodedORAddress 459 +#define OBJ_textEncodedORAddress OBJ_pilotAttributeType,2L + +#define SN_rfc822Mailbox "mail" +#define LN_rfc822Mailbox "rfc822Mailbox" +#define NID_rfc822Mailbox 460 +#define OBJ_rfc822Mailbox OBJ_pilotAttributeType,3L + +#define SN_info "info" +#define NID_info 461 +#define OBJ_info OBJ_pilotAttributeType,4L + +#define LN_favouriteDrink "favouriteDrink" +#define NID_favouriteDrink 462 +#define OBJ_favouriteDrink OBJ_pilotAttributeType,5L + +#define LN_roomNumber "roomNumber" +#define NID_roomNumber 463 +#define OBJ_roomNumber OBJ_pilotAttributeType,6L + +#define SN_photo "photo" +#define NID_photo 464 +#define OBJ_photo OBJ_pilotAttributeType,7L + +#define LN_userClass "userClass" +#define NID_userClass 465 +#define OBJ_userClass OBJ_pilotAttributeType,8L + +#define SN_host "host" +#define NID_host 466 +#define OBJ_host OBJ_pilotAttributeType,9L + +#define SN_manager "manager" +#define NID_manager 467 +#define OBJ_manager OBJ_pilotAttributeType,10L + +#define LN_documentIdentifier "documentIdentifier" +#define NID_documentIdentifier 468 +#define OBJ_documentIdentifier OBJ_pilotAttributeType,11L + +#define LN_documentTitle "documentTitle" +#define NID_documentTitle 469 +#define OBJ_documentTitle OBJ_pilotAttributeType,12L + +#define LN_documentVersion "documentVersion" +#define NID_documentVersion 470 +#define OBJ_documentVersion OBJ_pilotAttributeType,13L + +#define LN_documentAuthor "documentAuthor" +#define NID_documentAuthor 471 +#define OBJ_documentAuthor OBJ_pilotAttributeType,14L + +#define LN_documentLocation "documentLocation" +#define NID_documentLocation 472 +#define OBJ_documentLocation OBJ_pilotAttributeType,15L + +#define LN_homeTelephoneNumber "homeTelephoneNumber" +#define NID_homeTelephoneNumber 473 +#define OBJ_homeTelephoneNumber OBJ_pilotAttributeType,20L + +#define SN_secretary "secretary" +#define NID_secretary 474 +#define OBJ_secretary OBJ_pilotAttributeType,21L + +#define LN_otherMailbox "otherMailbox" +#define NID_otherMailbox 475 +#define OBJ_otherMailbox OBJ_pilotAttributeType,22L + +#define LN_lastModifiedTime "lastModifiedTime" +#define NID_lastModifiedTime 476 +#define OBJ_lastModifiedTime OBJ_pilotAttributeType,23L + +#define LN_lastModifiedBy "lastModifiedBy" +#define NID_lastModifiedBy 477 +#define OBJ_lastModifiedBy OBJ_pilotAttributeType,24L + +#define SN_domainComponent "DC" +#define LN_domainComponent "domainComponent" +#define NID_domainComponent 391 +#define OBJ_domainComponent OBJ_pilotAttributeType,25L + +#define LN_aRecord "aRecord" +#define NID_aRecord 478 +#define OBJ_aRecord OBJ_pilotAttributeType,26L + +#define LN_pilotAttributeType27 "pilotAttributeType27" +#define NID_pilotAttributeType27 479 +#define OBJ_pilotAttributeType27 OBJ_pilotAttributeType,27L + +#define LN_mXRecord "mXRecord" +#define NID_mXRecord 480 +#define OBJ_mXRecord OBJ_pilotAttributeType,28L + +#define LN_nSRecord "nSRecord" +#define NID_nSRecord 481 +#define OBJ_nSRecord OBJ_pilotAttributeType,29L + +#define LN_sOARecord "sOARecord" +#define NID_sOARecord 482 +#define OBJ_sOARecord OBJ_pilotAttributeType,30L + +#define LN_cNAMERecord "cNAMERecord" +#define NID_cNAMERecord 483 +#define OBJ_cNAMERecord OBJ_pilotAttributeType,31L + +#define LN_associatedDomain "associatedDomain" +#define NID_associatedDomain 484 +#define OBJ_associatedDomain OBJ_pilotAttributeType,37L + +#define LN_associatedName "associatedName" +#define NID_associatedName 485 +#define OBJ_associatedName OBJ_pilotAttributeType,38L + +#define LN_homePostalAddress "homePostalAddress" +#define NID_homePostalAddress 486 +#define OBJ_homePostalAddress OBJ_pilotAttributeType,39L + +#define LN_personalTitle "personalTitle" +#define NID_personalTitle 487 +#define OBJ_personalTitle OBJ_pilotAttributeType,40L + +#define LN_mobileTelephoneNumber "mobileTelephoneNumber" +#define NID_mobileTelephoneNumber 488 +#define OBJ_mobileTelephoneNumber OBJ_pilotAttributeType,41L + +#define LN_pagerTelephoneNumber "pagerTelephoneNumber" +#define NID_pagerTelephoneNumber 489 +#define OBJ_pagerTelephoneNumber OBJ_pilotAttributeType,42L + +#define LN_friendlyCountryName "friendlyCountryName" +#define NID_friendlyCountryName 490 +#define OBJ_friendlyCountryName OBJ_pilotAttributeType,43L + +#define LN_organizationalStatus "organizationalStatus" +#define NID_organizationalStatus 491 +#define OBJ_organizationalStatus OBJ_pilotAttributeType,45L + +#define LN_janetMailbox "janetMailbox" +#define NID_janetMailbox 492 +#define OBJ_janetMailbox OBJ_pilotAttributeType,46L + +#define LN_mailPreferenceOption "mailPreferenceOption" +#define NID_mailPreferenceOption 493 +#define OBJ_mailPreferenceOption OBJ_pilotAttributeType,47L + +#define LN_buildingName "buildingName" +#define NID_buildingName 494 +#define OBJ_buildingName OBJ_pilotAttributeType,48L + +#define LN_dSAQuality "dSAQuality" +#define NID_dSAQuality 495 +#define OBJ_dSAQuality OBJ_pilotAttributeType,49L + +#define LN_singleLevelQuality "singleLevelQuality" +#define NID_singleLevelQuality 496 +#define OBJ_singleLevelQuality OBJ_pilotAttributeType,50L + +#define LN_subtreeMinimumQuality "subtreeMinimumQuality" +#define NID_subtreeMinimumQuality 497 +#define OBJ_subtreeMinimumQuality OBJ_pilotAttributeType,51L + +#define LN_subtreeMaximumQuality "subtreeMaximumQuality" +#define NID_subtreeMaximumQuality 498 +#define OBJ_subtreeMaximumQuality OBJ_pilotAttributeType,52L + +#define LN_personalSignature "personalSignature" +#define NID_personalSignature 499 +#define OBJ_personalSignature OBJ_pilotAttributeType,53L + +#define LN_dITRedirect "dITRedirect" +#define NID_dITRedirect 500 +#define OBJ_dITRedirect OBJ_pilotAttributeType,54L + +#define SN_audio "audio" +#define NID_audio 501 +#define OBJ_audio OBJ_pilotAttributeType,55L + +#define LN_documentPublisher "documentPublisher" +#define NID_documentPublisher 502 +#define OBJ_documentPublisher OBJ_pilotAttributeType,56L + +#define SN_id_set "id-set" +#define LN_id_set "Secure Electronic Transactions" +#define NID_id_set 512 +#define OBJ_id_set OBJ_international_organizations,42L + +#define SN_set_ctype "set-ctype" +#define LN_set_ctype "content types" +#define NID_set_ctype 513 +#define OBJ_set_ctype OBJ_id_set,0L + +#define SN_set_msgExt "set-msgExt" +#define LN_set_msgExt "message extensions" +#define NID_set_msgExt 514 +#define OBJ_set_msgExt OBJ_id_set,1L + +#define SN_set_attr "set-attr" +#define NID_set_attr 515 +#define OBJ_set_attr OBJ_id_set,3L + +#define SN_set_policy "set-policy" +#define NID_set_policy 516 +#define OBJ_set_policy OBJ_id_set,5L + +#define SN_set_certExt "set-certExt" +#define LN_set_certExt "certificate extensions" +#define NID_set_certExt 517 +#define OBJ_set_certExt OBJ_id_set,7L + +#define SN_set_brand "set-brand" +#define NID_set_brand 518 +#define OBJ_set_brand OBJ_id_set,8L + +#define SN_setct_PANData "setct-PANData" +#define NID_setct_PANData 519 +#define OBJ_setct_PANData OBJ_set_ctype,0L + +#define SN_setct_PANToken "setct-PANToken" +#define NID_setct_PANToken 520 +#define OBJ_setct_PANToken OBJ_set_ctype,1L + +#define SN_setct_PANOnly "setct-PANOnly" +#define NID_setct_PANOnly 521 +#define OBJ_setct_PANOnly OBJ_set_ctype,2L + +#define SN_setct_OIData "setct-OIData" +#define NID_setct_OIData 522 +#define OBJ_setct_OIData OBJ_set_ctype,3L + +#define SN_setct_PI "setct-PI" +#define NID_setct_PI 523 +#define OBJ_setct_PI OBJ_set_ctype,4L + +#define SN_setct_PIData "setct-PIData" +#define NID_setct_PIData 524 +#define OBJ_setct_PIData OBJ_set_ctype,5L + +#define SN_setct_PIDataUnsigned "setct-PIDataUnsigned" +#define NID_setct_PIDataUnsigned 525 +#define OBJ_setct_PIDataUnsigned OBJ_set_ctype,6L + +#define SN_setct_HODInput "setct-HODInput" +#define NID_setct_HODInput 526 +#define OBJ_setct_HODInput OBJ_set_ctype,7L + +#define SN_setct_AuthResBaggage "setct-AuthResBaggage" +#define NID_setct_AuthResBaggage 527 +#define OBJ_setct_AuthResBaggage OBJ_set_ctype,8L + +#define SN_setct_AuthRevReqBaggage "setct-AuthRevReqBaggage" +#define NID_setct_AuthRevReqBaggage 528 +#define OBJ_setct_AuthRevReqBaggage OBJ_set_ctype,9L + +#define SN_setct_AuthRevResBaggage "setct-AuthRevResBaggage" +#define NID_setct_AuthRevResBaggage 529 +#define OBJ_setct_AuthRevResBaggage OBJ_set_ctype,10L + +#define SN_setct_CapTokenSeq "setct-CapTokenSeq" +#define NID_setct_CapTokenSeq 530 +#define OBJ_setct_CapTokenSeq OBJ_set_ctype,11L + +#define SN_setct_PInitResData "setct-PInitResData" +#define NID_setct_PInitResData 531 +#define OBJ_setct_PInitResData OBJ_set_ctype,12L + +#define SN_setct_PI_TBS "setct-PI-TBS" +#define NID_setct_PI_TBS 532 +#define OBJ_setct_PI_TBS OBJ_set_ctype,13L + +#define SN_setct_PResData "setct-PResData" +#define NID_setct_PResData 533 +#define OBJ_setct_PResData OBJ_set_ctype,14L + +#define SN_setct_AuthReqTBS "setct-AuthReqTBS" +#define NID_setct_AuthReqTBS 534 +#define OBJ_setct_AuthReqTBS OBJ_set_ctype,16L + +#define SN_setct_AuthResTBS "setct-AuthResTBS" +#define NID_setct_AuthResTBS 535 +#define OBJ_setct_AuthResTBS OBJ_set_ctype,17L + +#define SN_setct_AuthResTBSX "setct-AuthResTBSX" +#define NID_setct_AuthResTBSX 536 +#define OBJ_setct_AuthResTBSX OBJ_set_ctype,18L + +#define SN_setct_AuthTokenTBS "setct-AuthTokenTBS" +#define NID_setct_AuthTokenTBS 537 +#define OBJ_setct_AuthTokenTBS OBJ_set_ctype,19L + +#define SN_setct_CapTokenData "setct-CapTokenData" +#define NID_setct_CapTokenData 538 +#define OBJ_setct_CapTokenData OBJ_set_ctype,20L + +#define SN_setct_CapTokenTBS "setct-CapTokenTBS" +#define NID_setct_CapTokenTBS 539 +#define OBJ_setct_CapTokenTBS OBJ_set_ctype,21L + +#define SN_setct_AcqCardCodeMsg "setct-AcqCardCodeMsg" +#define NID_setct_AcqCardCodeMsg 540 +#define OBJ_setct_AcqCardCodeMsg OBJ_set_ctype,22L + +#define SN_setct_AuthRevReqTBS "setct-AuthRevReqTBS" +#define NID_setct_AuthRevReqTBS 541 +#define OBJ_setct_AuthRevReqTBS OBJ_set_ctype,23L + +#define SN_setct_AuthRevResData "setct-AuthRevResData" +#define NID_setct_AuthRevResData 542 +#define OBJ_setct_AuthRevResData OBJ_set_ctype,24L + +#define SN_setct_AuthRevResTBS "setct-AuthRevResTBS" +#define NID_setct_AuthRevResTBS 543 +#define OBJ_setct_AuthRevResTBS OBJ_set_ctype,25L + +#define SN_setct_CapReqTBS "setct-CapReqTBS" +#define NID_setct_CapReqTBS 544 +#define OBJ_setct_CapReqTBS OBJ_set_ctype,26L + +#define SN_setct_CapReqTBSX "setct-CapReqTBSX" +#define NID_setct_CapReqTBSX 545 +#define OBJ_setct_CapReqTBSX OBJ_set_ctype,27L + +#define SN_setct_CapResData "setct-CapResData" +#define NID_setct_CapResData 546 +#define OBJ_setct_CapResData OBJ_set_ctype,28L + +#define SN_setct_CapRevReqTBS "setct-CapRevReqTBS" +#define NID_setct_CapRevReqTBS 547 +#define OBJ_setct_CapRevReqTBS OBJ_set_ctype,29L + +#define SN_setct_CapRevReqTBSX "setct-CapRevReqTBSX" +#define NID_setct_CapRevReqTBSX 548 +#define OBJ_setct_CapRevReqTBSX OBJ_set_ctype,30L + +#define SN_setct_CapRevResData "setct-CapRevResData" +#define NID_setct_CapRevResData 549 +#define OBJ_setct_CapRevResData OBJ_set_ctype,31L + +#define SN_setct_CredReqTBS "setct-CredReqTBS" +#define NID_setct_CredReqTBS 550 +#define OBJ_setct_CredReqTBS OBJ_set_ctype,32L + +#define SN_setct_CredReqTBSX "setct-CredReqTBSX" +#define NID_setct_CredReqTBSX 551 +#define OBJ_setct_CredReqTBSX OBJ_set_ctype,33L + +#define SN_setct_CredResData "setct-CredResData" +#define NID_setct_CredResData 552 +#define OBJ_setct_CredResData OBJ_set_ctype,34L + +#define SN_setct_CredRevReqTBS "setct-CredRevReqTBS" +#define NID_setct_CredRevReqTBS 553 +#define OBJ_setct_CredRevReqTBS OBJ_set_ctype,35L + +#define SN_setct_CredRevReqTBSX "setct-CredRevReqTBSX" +#define NID_setct_CredRevReqTBSX 554 +#define OBJ_setct_CredRevReqTBSX OBJ_set_ctype,36L + +#define SN_setct_CredRevResData "setct-CredRevResData" +#define NID_setct_CredRevResData 555 +#define OBJ_setct_CredRevResData OBJ_set_ctype,37L + +#define SN_setct_PCertReqData "setct-PCertReqData" +#define NID_setct_PCertReqData 556 +#define OBJ_setct_PCertReqData OBJ_set_ctype,38L + +#define SN_setct_PCertResTBS "setct-PCertResTBS" +#define NID_setct_PCertResTBS 557 +#define OBJ_setct_PCertResTBS OBJ_set_ctype,39L + +#define SN_setct_BatchAdminReqData "setct-BatchAdminReqData" +#define NID_setct_BatchAdminReqData 558 +#define OBJ_setct_BatchAdminReqData OBJ_set_ctype,40L + +#define SN_setct_BatchAdminResData "setct-BatchAdminResData" +#define NID_setct_BatchAdminResData 559 +#define OBJ_setct_BatchAdminResData OBJ_set_ctype,41L + +#define SN_setct_CardCInitResTBS "setct-CardCInitResTBS" +#define NID_setct_CardCInitResTBS 560 +#define OBJ_setct_CardCInitResTBS OBJ_set_ctype,42L + +#define SN_setct_MeAqCInitResTBS "setct-MeAqCInitResTBS" +#define NID_setct_MeAqCInitResTBS 561 +#define OBJ_setct_MeAqCInitResTBS OBJ_set_ctype,43L + +#define SN_setct_RegFormResTBS "setct-RegFormResTBS" +#define NID_setct_RegFormResTBS 562 +#define OBJ_setct_RegFormResTBS OBJ_set_ctype,44L + +#define SN_setct_CertReqData "setct-CertReqData" +#define NID_setct_CertReqData 563 +#define OBJ_setct_CertReqData OBJ_set_ctype,45L + +#define SN_setct_CertReqTBS "setct-CertReqTBS" +#define NID_setct_CertReqTBS 564 +#define OBJ_setct_CertReqTBS OBJ_set_ctype,46L + +#define SN_setct_CertResData "setct-CertResData" +#define NID_setct_CertResData 565 +#define OBJ_setct_CertResData OBJ_set_ctype,47L + +#define SN_setct_CertInqReqTBS "setct-CertInqReqTBS" +#define NID_setct_CertInqReqTBS 566 +#define OBJ_setct_CertInqReqTBS OBJ_set_ctype,48L + +#define SN_setct_ErrorTBS "setct-ErrorTBS" +#define NID_setct_ErrorTBS 567 +#define OBJ_setct_ErrorTBS OBJ_set_ctype,49L + +#define SN_setct_PIDualSignedTBE "setct-PIDualSignedTBE" +#define NID_setct_PIDualSignedTBE 568 +#define OBJ_setct_PIDualSignedTBE OBJ_set_ctype,50L + +#define SN_setct_PIUnsignedTBE "setct-PIUnsignedTBE" +#define NID_setct_PIUnsignedTBE 569 +#define OBJ_setct_PIUnsignedTBE OBJ_set_ctype,51L + +#define SN_setct_AuthReqTBE "setct-AuthReqTBE" +#define NID_setct_AuthReqTBE 570 +#define OBJ_setct_AuthReqTBE OBJ_set_ctype,52L + +#define SN_setct_AuthResTBE "setct-AuthResTBE" +#define NID_setct_AuthResTBE 571 +#define OBJ_setct_AuthResTBE OBJ_set_ctype,53L + +#define SN_setct_AuthResTBEX "setct-AuthResTBEX" +#define NID_setct_AuthResTBEX 572 +#define OBJ_setct_AuthResTBEX OBJ_set_ctype,54L + +#define SN_setct_AuthTokenTBE "setct-AuthTokenTBE" +#define NID_setct_AuthTokenTBE 573 +#define OBJ_setct_AuthTokenTBE OBJ_set_ctype,55L + +#define SN_setct_CapTokenTBE "setct-CapTokenTBE" +#define NID_setct_CapTokenTBE 574 +#define OBJ_setct_CapTokenTBE OBJ_set_ctype,56L + +#define SN_setct_CapTokenTBEX "setct-CapTokenTBEX" +#define NID_setct_CapTokenTBEX 575 +#define OBJ_setct_CapTokenTBEX OBJ_set_ctype,57L + +#define SN_setct_AcqCardCodeMsgTBE "setct-AcqCardCodeMsgTBE" +#define NID_setct_AcqCardCodeMsgTBE 576 +#define OBJ_setct_AcqCardCodeMsgTBE OBJ_set_ctype,58L + +#define SN_setct_AuthRevReqTBE "setct-AuthRevReqTBE" +#define NID_setct_AuthRevReqTBE 577 +#define OBJ_setct_AuthRevReqTBE OBJ_set_ctype,59L + +#define SN_setct_AuthRevResTBE "setct-AuthRevResTBE" +#define NID_setct_AuthRevResTBE 578 +#define OBJ_setct_AuthRevResTBE OBJ_set_ctype,60L + +#define SN_setct_AuthRevResTBEB "setct-AuthRevResTBEB" +#define NID_setct_AuthRevResTBEB 579 +#define OBJ_setct_AuthRevResTBEB OBJ_set_ctype,61L + +#define SN_setct_CapReqTBE "setct-CapReqTBE" +#define NID_setct_CapReqTBE 580 +#define OBJ_setct_CapReqTBE OBJ_set_ctype,62L + +#define SN_setct_CapReqTBEX "setct-CapReqTBEX" +#define NID_setct_CapReqTBEX 581 +#define OBJ_setct_CapReqTBEX OBJ_set_ctype,63L + +#define SN_setct_CapResTBE "setct-CapResTBE" +#define NID_setct_CapResTBE 582 +#define OBJ_setct_CapResTBE OBJ_set_ctype,64L + +#define SN_setct_CapRevReqTBE "setct-CapRevReqTBE" +#define NID_setct_CapRevReqTBE 583 +#define OBJ_setct_CapRevReqTBE OBJ_set_ctype,65L + +#define SN_setct_CapRevReqTBEX "setct-CapRevReqTBEX" +#define NID_setct_CapRevReqTBEX 584 +#define OBJ_setct_CapRevReqTBEX OBJ_set_ctype,66L + +#define SN_setct_CapRevResTBE "setct-CapRevResTBE" +#define NID_setct_CapRevResTBE 585 +#define OBJ_setct_CapRevResTBE OBJ_set_ctype,67L + +#define SN_setct_CredReqTBE "setct-CredReqTBE" +#define NID_setct_CredReqTBE 586 +#define OBJ_setct_CredReqTBE OBJ_set_ctype,68L + +#define SN_setct_CredReqTBEX "setct-CredReqTBEX" +#define NID_setct_CredReqTBEX 587 +#define OBJ_setct_CredReqTBEX OBJ_set_ctype,69L + +#define SN_setct_CredResTBE "setct-CredResTBE" +#define NID_setct_CredResTBE 588 +#define OBJ_setct_CredResTBE OBJ_set_ctype,70L + +#define SN_setct_CredRevReqTBE "setct-CredRevReqTBE" +#define NID_setct_CredRevReqTBE 589 +#define OBJ_setct_CredRevReqTBE OBJ_set_ctype,71L + +#define SN_setct_CredRevReqTBEX "setct-CredRevReqTBEX" +#define NID_setct_CredRevReqTBEX 590 +#define OBJ_setct_CredRevReqTBEX OBJ_set_ctype,72L + +#define SN_setct_CredRevResTBE "setct-CredRevResTBE" +#define NID_setct_CredRevResTBE 591 +#define OBJ_setct_CredRevResTBE OBJ_set_ctype,73L + +#define SN_setct_BatchAdminReqTBE "setct-BatchAdminReqTBE" +#define NID_setct_BatchAdminReqTBE 592 +#define OBJ_setct_BatchAdminReqTBE OBJ_set_ctype,74L + +#define SN_setct_BatchAdminResTBE "setct-BatchAdminResTBE" +#define NID_setct_BatchAdminResTBE 593 +#define OBJ_setct_BatchAdminResTBE OBJ_set_ctype,75L + +#define SN_setct_RegFormReqTBE "setct-RegFormReqTBE" +#define NID_setct_RegFormReqTBE 594 +#define OBJ_setct_RegFormReqTBE OBJ_set_ctype,76L + +#define SN_setct_CertReqTBE "setct-CertReqTBE" +#define NID_setct_CertReqTBE 595 +#define OBJ_setct_CertReqTBE OBJ_set_ctype,77L + +#define SN_setct_CertReqTBEX "setct-CertReqTBEX" +#define NID_setct_CertReqTBEX 596 +#define OBJ_setct_CertReqTBEX OBJ_set_ctype,78L + +#define SN_setct_CertResTBE "setct-CertResTBE" +#define NID_setct_CertResTBE 597 +#define OBJ_setct_CertResTBE OBJ_set_ctype,79L + +#define SN_setct_CRLNotificationTBS "setct-CRLNotificationTBS" +#define NID_setct_CRLNotificationTBS 598 +#define OBJ_setct_CRLNotificationTBS OBJ_set_ctype,80L + +#define SN_setct_CRLNotificationResTBS "setct-CRLNotificationResTBS" +#define NID_setct_CRLNotificationResTBS 599 +#define OBJ_setct_CRLNotificationResTBS OBJ_set_ctype,81L + +#define SN_setct_BCIDistributionTBS "setct-BCIDistributionTBS" +#define NID_setct_BCIDistributionTBS 600 +#define OBJ_setct_BCIDistributionTBS OBJ_set_ctype,82L + +#define SN_setext_genCrypt "setext-genCrypt" +#define LN_setext_genCrypt "generic cryptogram" +#define NID_setext_genCrypt 601 +#define OBJ_setext_genCrypt OBJ_set_msgExt,1L + +#define SN_setext_miAuth "setext-miAuth" +#define LN_setext_miAuth "merchant initiated auth" +#define NID_setext_miAuth 602 +#define OBJ_setext_miAuth OBJ_set_msgExt,3L + +#define SN_setext_pinSecure "setext-pinSecure" +#define NID_setext_pinSecure 603 +#define OBJ_setext_pinSecure OBJ_set_msgExt,4L + +#define SN_setext_pinAny "setext-pinAny" +#define NID_setext_pinAny 604 +#define OBJ_setext_pinAny OBJ_set_msgExt,5L + +#define SN_setext_track2 "setext-track2" +#define NID_setext_track2 605 +#define OBJ_setext_track2 OBJ_set_msgExt,7L + +#define SN_setext_cv "setext-cv" +#define LN_setext_cv "additional verification" +#define NID_setext_cv 606 +#define OBJ_setext_cv OBJ_set_msgExt,8L + +#define SN_set_policy_root "set-policy-root" +#define NID_set_policy_root 607 +#define OBJ_set_policy_root OBJ_set_policy,0L + +#define SN_setCext_hashedRoot "setCext-hashedRoot" +#define NID_setCext_hashedRoot 608 +#define OBJ_setCext_hashedRoot OBJ_set_certExt,0L + +#define SN_setCext_certType "setCext-certType" +#define NID_setCext_certType 609 +#define OBJ_setCext_certType OBJ_set_certExt,1L + +#define SN_setCext_merchData "setCext-merchData" +#define NID_setCext_merchData 610 +#define OBJ_setCext_merchData OBJ_set_certExt,2L + +#define SN_setCext_cCertRequired "setCext-cCertRequired" +#define NID_setCext_cCertRequired 611 +#define OBJ_setCext_cCertRequired OBJ_set_certExt,3L + +#define SN_setCext_tunneling "setCext-tunneling" +#define NID_setCext_tunneling 612 +#define OBJ_setCext_tunneling OBJ_set_certExt,4L + +#define SN_setCext_setExt "setCext-setExt" +#define NID_setCext_setExt 613 +#define OBJ_setCext_setExt OBJ_set_certExt,5L + +#define SN_setCext_setQualf "setCext-setQualf" +#define NID_setCext_setQualf 614 +#define OBJ_setCext_setQualf OBJ_set_certExt,6L + +#define SN_setCext_PGWYcapabilities "setCext-PGWYcapabilities" +#define NID_setCext_PGWYcapabilities 615 +#define OBJ_setCext_PGWYcapabilities OBJ_set_certExt,7L + +#define SN_setCext_TokenIdentifier "setCext-TokenIdentifier" +#define NID_setCext_TokenIdentifier 616 +#define OBJ_setCext_TokenIdentifier OBJ_set_certExt,8L + +#define SN_setCext_Track2Data "setCext-Track2Data" +#define NID_setCext_Track2Data 617 +#define OBJ_setCext_Track2Data OBJ_set_certExt,9L + +#define SN_setCext_TokenType "setCext-TokenType" +#define NID_setCext_TokenType 618 +#define OBJ_setCext_TokenType OBJ_set_certExt,10L + +#define SN_setCext_IssuerCapabilities "setCext-IssuerCapabilities" +#define NID_setCext_IssuerCapabilities 619 +#define OBJ_setCext_IssuerCapabilities OBJ_set_certExt,11L + +#define SN_setAttr_Cert "setAttr-Cert" +#define NID_setAttr_Cert 620 +#define OBJ_setAttr_Cert OBJ_set_attr,0L + +#define SN_setAttr_PGWYcap "setAttr-PGWYcap" +#define LN_setAttr_PGWYcap "payment gateway capabilities" +#define NID_setAttr_PGWYcap 621 +#define OBJ_setAttr_PGWYcap OBJ_set_attr,1L + +#define SN_setAttr_TokenType "setAttr-TokenType" +#define NID_setAttr_TokenType 622 +#define OBJ_setAttr_TokenType OBJ_set_attr,2L + +#define SN_setAttr_IssCap "setAttr-IssCap" +#define LN_setAttr_IssCap "issuer capabilities" +#define NID_setAttr_IssCap 623 +#define OBJ_setAttr_IssCap OBJ_set_attr,3L + +#define SN_set_rootKeyThumb "set-rootKeyThumb" +#define NID_set_rootKeyThumb 624 +#define OBJ_set_rootKeyThumb OBJ_setAttr_Cert,0L + +#define SN_set_addPolicy "set-addPolicy" +#define NID_set_addPolicy 625 +#define OBJ_set_addPolicy OBJ_setAttr_Cert,1L + +#define SN_setAttr_Token_EMV "setAttr-Token-EMV" +#define NID_setAttr_Token_EMV 626 +#define OBJ_setAttr_Token_EMV OBJ_setAttr_TokenType,1L + +#define SN_setAttr_Token_B0Prime "setAttr-Token-B0Prime" +#define NID_setAttr_Token_B0Prime 627 +#define OBJ_setAttr_Token_B0Prime OBJ_setAttr_TokenType,2L + +#define SN_setAttr_IssCap_CVM "setAttr-IssCap-CVM" +#define NID_setAttr_IssCap_CVM 628 +#define OBJ_setAttr_IssCap_CVM OBJ_setAttr_IssCap,3L + +#define SN_setAttr_IssCap_T2 "setAttr-IssCap-T2" +#define NID_setAttr_IssCap_T2 629 +#define OBJ_setAttr_IssCap_T2 OBJ_setAttr_IssCap,4L + +#define SN_setAttr_IssCap_Sig "setAttr-IssCap-Sig" +#define NID_setAttr_IssCap_Sig 630 +#define OBJ_setAttr_IssCap_Sig OBJ_setAttr_IssCap,5L + +#define SN_setAttr_GenCryptgrm "setAttr-GenCryptgrm" +#define LN_setAttr_GenCryptgrm "generate cryptogram" +#define NID_setAttr_GenCryptgrm 631 +#define OBJ_setAttr_GenCryptgrm OBJ_setAttr_IssCap_CVM,1L + +#define SN_setAttr_T2Enc "setAttr-T2Enc" +#define LN_setAttr_T2Enc "encrypted track 2" +#define NID_setAttr_T2Enc 632 +#define OBJ_setAttr_T2Enc OBJ_setAttr_IssCap_T2,1L + +#define SN_setAttr_T2cleartxt "setAttr-T2cleartxt" +#define LN_setAttr_T2cleartxt "cleartext track 2" +#define NID_setAttr_T2cleartxt 633 +#define OBJ_setAttr_T2cleartxt OBJ_setAttr_IssCap_T2,2L + +#define SN_setAttr_TokICCsig "setAttr-TokICCsig" +#define LN_setAttr_TokICCsig "ICC or token signature" +#define NID_setAttr_TokICCsig 634 +#define OBJ_setAttr_TokICCsig OBJ_setAttr_IssCap_Sig,1L + +#define SN_setAttr_SecDevSig "setAttr-SecDevSig" +#define LN_setAttr_SecDevSig "secure device signature" +#define NID_setAttr_SecDevSig 635 +#define OBJ_setAttr_SecDevSig OBJ_setAttr_IssCap_Sig,2L + +#define SN_set_brand_IATA_ATA "set-brand-IATA-ATA" +#define NID_set_brand_IATA_ATA 636 +#define OBJ_set_brand_IATA_ATA OBJ_set_brand,1L + +#define SN_set_brand_Diners "set-brand-Diners" +#define NID_set_brand_Diners 637 +#define OBJ_set_brand_Diners OBJ_set_brand,30L + +#define SN_set_brand_AmericanExpress "set-brand-AmericanExpress" +#define NID_set_brand_AmericanExpress 638 +#define OBJ_set_brand_AmericanExpress OBJ_set_brand,34L + +#define SN_set_brand_JCB "set-brand-JCB" +#define NID_set_brand_JCB 639 +#define OBJ_set_brand_JCB OBJ_set_brand,35L + +#define SN_set_brand_Visa "set-brand-Visa" +#define NID_set_brand_Visa 640 +#define OBJ_set_brand_Visa OBJ_set_brand,4L + +#define SN_set_brand_MasterCard "set-brand-MasterCard" +#define NID_set_brand_MasterCard 641 +#define OBJ_set_brand_MasterCard OBJ_set_brand,5L + +#define SN_set_brand_Novus "set-brand-Novus" +#define NID_set_brand_Novus 642 +#define OBJ_set_brand_Novus OBJ_set_brand,6011L + +#define SN_des_cdmf "DES-CDMF" +#define LN_des_cdmf "des-cdmf" +#define NID_des_cdmf 643 +#define OBJ_des_cdmf OBJ_rsadsi,3L,10L + +#define SN_rsaOAEPEncryptionSET "rsaOAEPEncryptionSET" +#define NID_rsaOAEPEncryptionSET 644 +#define OBJ_rsaOAEPEncryptionSET OBJ_rsadsi,1L,1L,6L + +#define SN_ipsec3 "Oakley-EC2N-3" +#define LN_ipsec3 "ipsec3" +#define NID_ipsec3 749 + +#define SN_ipsec4 "Oakley-EC2N-4" +#define LN_ipsec4 "ipsec4" +#define NID_ipsec4 750 + +#define SN_whirlpool "whirlpool" +#define NID_whirlpool 804 +#define OBJ_whirlpool OBJ_iso,0L,10118L,3L,0L,55L + +#define SN_cryptopro "cryptopro" +#define NID_cryptopro 805 +#define OBJ_cryptopro OBJ_member_body,643L,2L,2L + +#define SN_cryptocom "cryptocom" +#define NID_cryptocom 806 +#define OBJ_cryptocom OBJ_member_body,643L,2L,9L + +#define SN_id_GostR3411_94_with_GostR3410_2001 "id-GostR3411-94-with-GostR3410-2001" +#define LN_id_GostR3411_94_with_GostR3410_2001 "GOST R 34.11-94 with GOST R 34.10-2001" +#define NID_id_GostR3411_94_with_GostR3410_2001 807 +#define OBJ_id_GostR3411_94_with_GostR3410_2001 OBJ_cryptopro,3L + +#define SN_id_GostR3411_94_with_GostR3410_94 "id-GostR3411-94-with-GostR3410-94" +#define LN_id_GostR3411_94_with_GostR3410_94 "GOST R 34.11-94 with GOST R 34.10-94" +#define NID_id_GostR3411_94_with_GostR3410_94 808 +#define OBJ_id_GostR3411_94_with_GostR3410_94 OBJ_cryptopro,4L + +#define SN_id_GostR3411_94 "md_gost94" +#define LN_id_GostR3411_94 "GOST R 34.11-94" +#define NID_id_GostR3411_94 809 +#define OBJ_id_GostR3411_94 OBJ_cryptopro,9L + +#define SN_id_HMACGostR3411_94 "id-HMACGostR3411-94" +#define LN_id_HMACGostR3411_94 "HMAC GOST 34.11-94" +#define NID_id_HMACGostR3411_94 810 +#define OBJ_id_HMACGostR3411_94 OBJ_cryptopro,10L + +#define SN_id_GostR3410_2001 "gost2001" +#define LN_id_GostR3410_2001 "GOST R 34.10-2001" +#define NID_id_GostR3410_2001 811 +#define OBJ_id_GostR3410_2001 OBJ_cryptopro,19L + +#define SN_id_GostR3410_94 "gost94" +#define LN_id_GostR3410_94 "GOST R 34.10-94" +#define NID_id_GostR3410_94 812 +#define OBJ_id_GostR3410_94 OBJ_cryptopro,20L + +#define SN_id_Gost28147_89 "gost89" +#define LN_id_Gost28147_89 "GOST 28147-89" +#define NID_id_Gost28147_89 813 +#define OBJ_id_Gost28147_89 OBJ_cryptopro,21L + +#define SN_gost89_cnt "gost89-cnt" +#define NID_gost89_cnt 814 + +#define SN_id_Gost28147_89_MAC "gost-mac" +#define LN_id_Gost28147_89_MAC "GOST 28147-89 MAC" +#define NID_id_Gost28147_89_MAC 815 +#define OBJ_id_Gost28147_89_MAC OBJ_cryptopro,22L + +#define SN_id_GostR3411_94_prf "prf-gostr3411-94" +#define LN_id_GostR3411_94_prf "GOST R 34.11-94 PRF" +#define NID_id_GostR3411_94_prf 816 +#define OBJ_id_GostR3411_94_prf OBJ_cryptopro,23L + +#define SN_id_GostR3410_2001DH "id-GostR3410-2001DH" +#define LN_id_GostR3410_2001DH "GOST R 34.10-2001 DH" +#define NID_id_GostR3410_2001DH 817 +#define OBJ_id_GostR3410_2001DH OBJ_cryptopro,98L + +#define SN_id_GostR3410_94DH "id-GostR3410-94DH" +#define LN_id_GostR3410_94DH "GOST R 34.10-94 DH" +#define NID_id_GostR3410_94DH 818 +#define OBJ_id_GostR3410_94DH OBJ_cryptopro,99L + +#define SN_id_Gost28147_89_CryptoPro_KeyMeshing "id-Gost28147-89-CryptoPro-KeyMeshing" +#define NID_id_Gost28147_89_CryptoPro_KeyMeshing 819 +#define OBJ_id_Gost28147_89_CryptoPro_KeyMeshing OBJ_cryptopro,14L,1L + +#define SN_id_Gost28147_89_None_KeyMeshing "id-Gost28147-89-None-KeyMeshing" +#define NID_id_Gost28147_89_None_KeyMeshing 820 +#define OBJ_id_Gost28147_89_None_KeyMeshing OBJ_cryptopro,14L,0L + +#define SN_id_GostR3411_94_TestParamSet "id-GostR3411-94-TestParamSet" +#define NID_id_GostR3411_94_TestParamSet 821 +#define OBJ_id_GostR3411_94_TestParamSet OBJ_cryptopro,30L,0L + +#define SN_id_GostR3411_94_CryptoProParamSet "id-GostR3411-94-CryptoProParamSet" +#define NID_id_GostR3411_94_CryptoProParamSet 822 +#define OBJ_id_GostR3411_94_CryptoProParamSet OBJ_cryptopro,30L,1L + +#define SN_id_Gost28147_89_TestParamSet "id-Gost28147-89-TestParamSet" +#define NID_id_Gost28147_89_TestParamSet 823 +#define OBJ_id_Gost28147_89_TestParamSet OBJ_cryptopro,31L,0L + +#define SN_id_Gost28147_89_CryptoPro_A_ParamSet "id-Gost28147-89-CryptoPro-A-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_A_ParamSet 824 +#define OBJ_id_Gost28147_89_CryptoPro_A_ParamSet OBJ_cryptopro,31L,1L + +#define SN_id_Gost28147_89_CryptoPro_B_ParamSet "id-Gost28147-89-CryptoPro-B-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_B_ParamSet 825 +#define OBJ_id_Gost28147_89_CryptoPro_B_ParamSet OBJ_cryptopro,31L,2L + +#define SN_id_Gost28147_89_CryptoPro_C_ParamSet "id-Gost28147-89-CryptoPro-C-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_C_ParamSet 826 +#define OBJ_id_Gost28147_89_CryptoPro_C_ParamSet OBJ_cryptopro,31L,3L + +#define SN_id_Gost28147_89_CryptoPro_D_ParamSet "id-Gost28147-89-CryptoPro-D-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_D_ParamSet 827 +#define OBJ_id_Gost28147_89_CryptoPro_D_ParamSet OBJ_cryptopro,31L,4L + +#define SN_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet 828 +#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet OBJ_cryptopro,31L,5L + +#define SN_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet 829 +#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet OBJ_cryptopro,31L,6L + +#define SN_id_Gost28147_89_CryptoPro_RIC_1_ParamSet "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet 830 +#define OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet OBJ_cryptopro,31L,7L + +#define SN_id_GostR3410_94_TestParamSet "id-GostR3410-94-TestParamSet" +#define NID_id_GostR3410_94_TestParamSet 831 +#define OBJ_id_GostR3410_94_TestParamSet OBJ_cryptopro,32L,0L + +#define SN_id_GostR3410_94_CryptoPro_A_ParamSet "id-GostR3410-94-CryptoPro-A-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_A_ParamSet 832 +#define OBJ_id_GostR3410_94_CryptoPro_A_ParamSet OBJ_cryptopro,32L,2L + +#define SN_id_GostR3410_94_CryptoPro_B_ParamSet "id-GostR3410-94-CryptoPro-B-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_B_ParamSet 833 +#define OBJ_id_GostR3410_94_CryptoPro_B_ParamSet OBJ_cryptopro,32L,3L + +#define SN_id_GostR3410_94_CryptoPro_C_ParamSet "id-GostR3410-94-CryptoPro-C-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_C_ParamSet 834 +#define OBJ_id_GostR3410_94_CryptoPro_C_ParamSet OBJ_cryptopro,32L,4L + +#define SN_id_GostR3410_94_CryptoPro_D_ParamSet "id-GostR3410-94-CryptoPro-D-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_D_ParamSet 835 +#define OBJ_id_GostR3410_94_CryptoPro_D_ParamSet OBJ_cryptopro,32L,5L + +#define SN_id_GostR3410_94_CryptoPro_XchA_ParamSet "id-GostR3410-94-CryptoPro-XchA-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_XchA_ParamSet 836 +#define OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet OBJ_cryptopro,33L,1L + +#define SN_id_GostR3410_94_CryptoPro_XchB_ParamSet "id-GostR3410-94-CryptoPro-XchB-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_XchB_ParamSet 837 +#define OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet OBJ_cryptopro,33L,2L + +#define SN_id_GostR3410_94_CryptoPro_XchC_ParamSet "id-GostR3410-94-CryptoPro-XchC-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_XchC_ParamSet 838 +#define OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet OBJ_cryptopro,33L,3L + +#define SN_id_GostR3410_2001_TestParamSet "id-GostR3410-2001-TestParamSet" +#define NID_id_GostR3410_2001_TestParamSet 839 +#define OBJ_id_GostR3410_2001_TestParamSet OBJ_cryptopro,35L,0L + +#define SN_id_GostR3410_2001_CryptoPro_A_ParamSet "id-GostR3410-2001-CryptoPro-A-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_A_ParamSet 840 +#define OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet OBJ_cryptopro,35L,1L + +#define SN_id_GostR3410_2001_CryptoPro_B_ParamSet "id-GostR3410-2001-CryptoPro-B-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_B_ParamSet 841 +#define OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet OBJ_cryptopro,35L,2L + +#define SN_id_GostR3410_2001_CryptoPro_C_ParamSet "id-GostR3410-2001-CryptoPro-C-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_C_ParamSet 842 +#define OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet OBJ_cryptopro,35L,3L + +#define SN_id_GostR3410_2001_CryptoPro_XchA_ParamSet "id-GostR3410-2001-CryptoPro-XchA-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet 843 +#define OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet OBJ_cryptopro,36L,0L + +#define SN_id_GostR3410_2001_CryptoPro_XchB_ParamSet "id-GostR3410-2001-CryptoPro-XchB-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet 844 +#define OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet OBJ_cryptopro,36L,1L + +#define SN_id_GostR3410_94_a "id-GostR3410-94-a" +#define NID_id_GostR3410_94_a 845 +#define OBJ_id_GostR3410_94_a OBJ_id_GostR3410_94,1L + +#define SN_id_GostR3410_94_aBis "id-GostR3410-94-aBis" +#define NID_id_GostR3410_94_aBis 846 +#define OBJ_id_GostR3410_94_aBis OBJ_id_GostR3410_94,2L + +#define SN_id_GostR3410_94_b "id-GostR3410-94-b" +#define NID_id_GostR3410_94_b 847 +#define OBJ_id_GostR3410_94_b OBJ_id_GostR3410_94,3L + +#define SN_id_GostR3410_94_bBis "id-GostR3410-94-bBis" +#define NID_id_GostR3410_94_bBis 848 +#define OBJ_id_GostR3410_94_bBis OBJ_id_GostR3410_94,4L + +#define SN_id_Gost28147_89_cc "id-Gost28147-89-cc" +#define LN_id_Gost28147_89_cc "GOST 28147-89 Cryptocom ParamSet" +#define NID_id_Gost28147_89_cc 849 +#define OBJ_id_Gost28147_89_cc OBJ_cryptocom,1L,6L,1L + +#define SN_id_GostR3410_94_cc "gost94cc" +#define LN_id_GostR3410_94_cc "GOST 34.10-94 Cryptocom" +#define NID_id_GostR3410_94_cc 850 +#define OBJ_id_GostR3410_94_cc OBJ_cryptocom,1L,5L,3L + +#define SN_id_GostR3410_2001_cc "gost2001cc" +#define LN_id_GostR3410_2001_cc "GOST 34.10-2001 Cryptocom" +#define NID_id_GostR3410_2001_cc 851 +#define OBJ_id_GostR3410_2001_cc OBJ_cryptocom,1L,5L,4L + +#define SN_id_GostR3411_94_with_GostR3410_94_cc "id-GostR3411-94-with-GostR3410-94-cc" +#define LN_id_GostR3411_94_with_GostR3410_94_cc "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom" +#define NID_id_GostR3411_94_with_GostR3410_94_cc 852 +#define OBJ_id_GostR3411_94_with_GostR3410_94_cc OBJ_cryptocom,1L,3L,3L + +#define SN_id_GostR3411_94_with_GostR3410_2001_cc "id-GostR3411-94-with-GostR3410-2001-cc" +#define LN_id_GostR3411_94_with_GostR3410_2001_cc "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom" +#define NID_id_GostR3411_94_with_GostR3410_2001_cc 853 +#define OBJ_id_GostR3411_94_with_GostR3410_2001_cc OBJ_cryptocom,1L,3L,4L + +#define SN_id_GostR3410_2001_ParamSet_cc "id-GostR3410-2001-ParamSet-cc" +#define LN_id_GostR3410_2001_ParamSet_cc "GOST R 3410-2001 Parameter Set Cryptocom" +#define NID_id_GostR3410_2001_ParamSet_cc 854 +#define OBJ_id_GostR3410_2001_ParamSet_cc OBJ_cryptocom,1L,8L,1L + +#define SN_camellia_128_cbc "CAMELLIA-128-CBC" +#define LN_camellia_128_cbc "camellia-128-cbc" +#define NID_camellia_128_cbc 751 +#define OBJ_camellia_128_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,2L + +#define SN_camellia_192_cbc "CAMELLIA-192-CBC" +#define LN_camellia_192_cbc "camellia-192-cbc" +#define NID_camellia_192_cbc 752 +#define OBJ_camellia_192_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,3L + +#define SN_camellia_256_cbc "CAMELLIA-256-CBC" +#define LN_camellia_256_cbc "camellia-256-cbc" +#define NID_camellia_256_cbc 753 +#define OBJ_camellia_256_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,4L + +#define SN_id_camellia128_wrap "id-camellia128-wrap" +#define NID_id_camellia128_wrap 907 +#define OBJ_id_camellia128_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,2L + +#define SN_id_camellia192_wrap "id-camellia192-wrap" +#define NID_id_camellia192_wrap 908 +#define OBJ_id_camellia192_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,3L + +#define SN_id_camellia256_wrap "id-camellia256-wrap" +#define NID_id_camellia256_wrap 909 +#define OBJ_id_camellia256_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,4L + +#define OBJ_ntt_ds 0L,3L,4401L,5L + +#define OBJ_camellia OBJ_ntt_ds,3L,1L,9L + +#define SN_camellia_128_ecb "CAMELLIA-128-ECB" +#define LN_camellia_128_ecb "camellia-128-ecb" +#define NID_camellia_128_ecb 754 +#define OBJ_camellia_128_ecb OBJ_camellia,1L + +#define SN_camellia_128_ofb128 "CAMELLIA-128-OFB" +#define LN_camellia_128_ofb128 "camellia-128-ofb" +#define NID_camellia_128_ofb128 766 +#define OBJ_camellia_128_ofb128 OBJ_camellia,3L + +#define SN_camellia_128_cfb128 "CAMELLIA-128-CFB" +#define LN_camellia_128_cfb128 "camellia-128-cfb" +#define NID_camellia_128_cfb128 757 +#define OBJ_camellia_128_cfb128 OBJ_camellia,4L + +#define SN_camellia_192_ecb "CAMELLIA-192-ECB" +#define LN_camellia_192_ecb "camellia-192-ecb" +#define NID_camellia_192_ecb 755 +#define OBJ_camellia_192_ecb OBJ_camellia,21L + +#define SN_camellia_192_ofb128 "CAMELLIA-192-OFB" +#define LN_camellia_192_ofb128 "camellia-192-ofb" +#define NID_camellia_192_ofb128 767 +#define OBJ_camellia_192_ofb128 OBJ_camellia,23L + +#define SN_camellia_192_cfb128 "CAMELLIA-192-CFB" +#define LN_camellia_192_cfb128 "camellia-192-cfb" +#define NID_camellia_192_cfb128 758 +#define OBJ_camellia_192_cfb128 OBJ_camellia,24L + +#define SN_camellia_256_ecb "CAMELLIA-256-ECB" +#define LN_camellia_256_ecb "camellia-256-ecb" +#define NID_camellia_256_ecb 756 +#define OBJ_camellia_256_ecb OBJ_camellia,41L + +#define SN_camellia_256_ofb128 "CAMELLIA-256-OFB" +#define LN_camellia_256_ofb128 "camellia-256-ofb" +#define NID_camellia_256_ofb128 768 +#define OBJ_camellia_256_ofb128 OBJ_camellia,43L + +#define SN_camellia_256_cfb128 "CAMELLIA-256-CFB" +#define LN_camellia_256_cfb128 "camellia-256-cfb" +#define NID_camellia_256_cfb128 759 +#define OBJ_camellia_256_cfb128 OBJ_camellia,44L + +#define SN_camellia_128_cfb1 "CAMELLIA-128-CFB1" +#define LN_camellia_128_cfb1 "camellia-128-cfb1" +#define NID_camellia_128_cfb1 760 + +#define SN_camellia_192_cfb1 "CAMELLIA-192-CFB1" +#define LN_camellia_192_cfb1 "camellia-192-cfb1" +#define NID_camellia_192_cfb1 761 + +#define SN_camellia_256_cfb1 "CAMELLIA-256-CFB1" +#define LN_camellia_256_cfb1 "camellia-256-cfb1" +#define NID_camellia_256_cfb1 762 + +#define SN_camellia_128_cfb8 "CAMELLIA-128-CFB8" +#define LN_camellia_128_cfb8 "camellia-128-cfb8" +#define NID_camellia_128_cfb8 763 + +#define SN_camellia_192_cfb8 "CAMELLIA-192-CFB8" +#define LN_camellia_192_cfb8 "camellia-192-cfb8" +#define NID_camellia_192_cfb8 764 + +#define SN_camellia_256_cfb8 "CAMELLIA-256-CFB8" +#define LN_camellia_256_cfb8 "camellia-256-cfb8" +#define NID_camellia_256_cfb8 765 + +#define SN_kisa "KISA" +#define LN_kisa "kisa" +#define NID_kisa 773 +#define OBJ_kisa OBJ_member_body,410L,200004L + +#define SN_seed_ecb "SEED-ECB" +#define LN_seed_ecb "seed-ecb" +#define NID_seed_ecb 776 +#define OBJ_seed_ecb OBJ_kisa,1L,3L + +#define SN_seed_cbc "SEED-CBC" +#define LN_seed_cbc "seed-cbc" +#define NID_seed_cbc 777 +#define OBJ_seed_cbc OBJ_kisa,1L,4L + +#define SN_seed_cfb128 "SEED-CFB" +#define LN_seed_cfb128 "seed-cfb" +#define NID_seed_cfb128 779 +#define OBJ_seed_cfb128 OBJ_kisa,1L,5L + +#define SN_seed_ofb128 "SEED-OFB" +#define LN_seed_ofb128 "seed-ofb" +#define NID_seed_ofb128 778 +#define OBJ_seed_ofb128 OBJ_kisa,1L,6L + +#define SN_hmac "HMAC" +#define LN_hmac "hmac" +#define NID_hmac 855 + +#define SN_cmac "CMAC" +#define LN_cmac "cmac" +#define NID_cmac 894 + +#define SN_rc4_hmac_md5 "RC4-HMAC-MD5" +#define LN_rc4_hmac_md5 "rc4-hmac-md5" +#define NID_rc4_hmac_md5 915 + +#define SN_aes_128_cbc_hmac_sha1 "AES-128-CBC-HMAC-SHA1" +#define LN_aes_128_cbc_hmac_sha1 "aes-128-cbc-hmac-sha1" +#define NID_aes_128_cbc_hmac_sha1 916 + +#define SN_aes_192_cbc_hmac_sha1 "AES-192-CBC-HMAC-SHA1" +#define LN_aes_192_cbc_hmac_sha1 "aes-192-cbc-hmac-sha1" +#define NID_aes_192_cbc_hmac_sha1 917 + +#define SN_aes_256_cbc_hmac_sha1 "AES-256-CBC-HMAC-SHA1" +#define LN_aes_256_cbc_hmac_sha1 "aes-256-cbc-hmac-sha1" +#define NID_aes_256_cbc_hmac_sha1 918 + +#define SN_aes_128_cbc_hmac_sha256 "AES-128-CBC-HMAC-SHA256" +#define LN_aes_128_cbc_hmac_sha256 "aes-128-cbc-hmac-sha256" +#define NID_aes_128_cbc_hmac_sha256 948 + +#define SN_aes_192_cbc_hmac_sha256 "AES-192-CBC-HMAC-SHA256" +#define LN_aes_192_cbc_hmac_sha256 "aes-192-cbc-hmac-sha256" +#define NID_aes_192_cbc_hmac_sha256 949 + +#define SN_aes_256_cbc_hmac_sha256 "AES-256-CBC-HMAC-SHA256" +#define LN_aes_256_cbc_hmac_sha256 "aes-256-cbc-hmac-sha256" +#define NID_aes_256_cbc_hmac_sha256 950 + +#define SN_dhpublicnumber "dhpublicnumber" +#define LN_dhpublicnumber "X9.42 DH" +#define NID_dhpublicnumber 920 +#define OBJ_dhpublicnumber OBJ_ISO_US,10046L,2L,1L + +#define SN_brainpoolP160r1 "brainpoolP160r1" +#define NID_brainpoolP160r1 921 +#define OBJ_brainpoolP160r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,1L + +#define SN_brainpoolP160t1 "brainpoolP160t1" +#define NID_brainpoolP160t1 922 +#define OBJ_brainpoolP160t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,2L + +#define SN_brainpoolP192r1 "brainpoolP192r1" +#define NID_brainpoolP192r1 923 +#define OBJ_brainpoolP192r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,3L + +#define SN_brainpoolP192t1 "brainpoolP192t1" +#define NID_brainpoolP192t1 924 +#define OBJ_brainpoolP192t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,4L + +#define SN_brainpoolP224r1 "brainpoolP224r1" +#define NID_brainpoolP224r1 925 +#define OBJ_brainpoolP224r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,5L + +#define SN_brainpoolP224t1 "brainpoolP224t1" +#define NID_brainpoolP224t1 926 +#define OBJ_brainpoolP224t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,6L + +#define SN_brainpoolP256r1 "brainpoolP256r1" +#define NID_brainpoolP256r1 927 +#define OBJ_brainpoolP256r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,7L + +#define SN_brainpoolP256t1 "brainpoolP256t1" +#define NID_brainpoolP256t1 928 +#define OBJ_brainpoolP256t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,8L + +#define SN_brainpoolP320r1 "brainpoolP320r1" +#define NID_brainpoolP320r1 929 +#define OBJ_brainpoolP320r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,9L + +#define SN_brainpoolP320t1 "brainpoolP320t1" +#define NID_brainpoolP320t1 930 +#define OBJ_brainpoolP320t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,10L + +#define SN_brainpoolP384r1 "brainpoolP384r1" +#define NID_brainpoolP384r1 931 +#define OBJ_brainpoolP384r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,11L + +#define SN_brainpoolP384t1 "brainpoolP384t1" +#define NID_brainpoolP384t1 932 +#define OBJ_brainpoolP384t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,12L + +#define SN_brainpoolP512r1 "brainpoolP512r1" +#define NID_brainpoolP512r1 933 +#define OBJ_brainpoolP512r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,13L + +#define SN_brainpoolP512t1 "brainpoolP512t1" +#define NID_brainpoolP512t1 934 +#define OBJ_brainpoolP512t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,14L + +#define OBJ_x9_63_scheme 1L,3L,133L,16L,840L,63L,0L + +#define OBJ_secg_scheme OBJ_certicom_arc,1L + +#define SN_dhSinglePass_stdDH_sha1kdf_scheme "dhSinglePass-stdDH-sha1kdf-scheme" +#define NID_dhSinglePass_stdDH_sha1kdf_scheme 936 +#define OBJ_dhSinglePass_stdDH_sha1kdf_scheme OBJ_x9_63_scheme,2L + +#define SN_dhSinglePass_stdDH_sha224kdf_scheme "dhSinglePass-stdDH-sha224kdf-scheme" +#define NID_dhSinglePass_stdDH_sha224kdf_scheme 937 +#define OBJ_dhSinglePass_stdDH_sha224kdf_scheme OBJ_secg_scheme,11L,0L + +#define SN_dhSinglePass_stdDH_sha256kdf_scheme "dhSinglePass-stdDH-sha256kdf-scheme" +#define NID_dhSinglePass_stdDH_sha256kdf_scheme 938 +#define OBJ_dhSinglePass_stdDH_sha256kdf_scheme OBJ_secg_scheme,11L,1L + +#define SN_dhSinglePass_stdDH_sha384kdf_scheme "dhSinglePass-stdDH-sha384kdf-scheme" +#define NID_dhSinglePass_stdDH_sha384kdf_scheme 939 +#define OBJ_dhSinglePass_stdDH_sha384kdf_scheme OBJ_secg_scheme,11L,2L + +#define SN_dhSinglePass_stdDH_sha512kdf_scheme "dhSinglePass-stdDH-sha512kdf-scheme" +#define NID_dhSinglePass_stdDH_sha512kdf_scheme 940 +#define OBJ_dhSinglePass_stdDH_sha512kdf_scheme OBJ_secg_scheme,11L,3L + +#define SN_dhSinglePass_cofactorDH_sha1kdf_scheme "dhSinglePass-cofactorDH-sha1kdf-scheme" +#define NID_dhSinglePass_cofactorDH_sha1kdf_scheme 941 +#define OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme OBJ_x9_63_scheme,3L + +#define SN_dhSinglePass_cofactorDH_sha224kdf_scheme "dhSinglePass-cofactorDH-sha224kdf-scheme" +#define NID_dhSinglePass_cofactorDH_sha224kdf_scheme 942 +#define OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme OBJ_secg_scheme,14L,0L + +#define SN_dhSinglePass_cofactorDH_sha256kdf_scheme "dhSinglePass-cofactorDH-sha256kdf-scheme" +#define NID_dhSinglePass_cofactorDH_sha256kdf_scheme 943 +#define OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme OBJ_secg_scheme,14L,1L + +#define SN_dhSinglePass_cofactorDH_sha384kdf_scheme "dhSinglePass-cofactorDH-sha384kdf-scheme" +#define NID_dhSinglePass_cofactorDH_sha384kdf_scheme 944 +#define OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme OBJ_secg_scheme,14L,2L + +#define SN_dhSinglePass_cofactorDH_sha512kdf_scheme "dhSinglePass-cofactorDH-sha512kdf-scheme" +#define NID_dhSinglePass_cofactorDH_sha512kdf_scheme 945 +#define OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme OBJ_secg_scheme,14L,3L + +#define SN_dh_std_kdf "dh-std-kdf" +#define NID_dh_std_kdf 946 + +#define SN_dh_cofactor_kdf "dh-cofactor-kdf" +#define NID_dh_cofactor_kdf 947 + +#define SN_ct_precert_scts "ct_precert_scts" +#define LN_ct_precert_scts "CT Precertificate SCTs" +#define NID_ct_precert_scts 951 +#define OBJ_ct_precert_scts 1L,3L,6L,1L,4L,1L,11129L,2L,4L,2L + +#define SN_ct_precert_poison "ct_precert_poison" +#define LN_ct_precert_poison "CT Precertificate Poison" +#define NID_ct_precert_poison 952 +#define OBJ_ct_precert_poison 1L,3L,6L,1L,4L,1L,11129L,2L,4L,3L + +#define SN_ct_precert_signer "ct_precert_signer" +#define LN_ct_precert_signer "CT Precertificate Signer" +#define NID_ct_precert_signer 953 +#define OBJ_ct_precert_signer 1L,3L,6L,1L,4L,1L,11129L,2L,4L,4L + +#define SN_ct_cert_scts "ct_cert_scts" +#define LN_ct_cert_scts "CT Certificate SCTs" +#define NID_ct_cert_scts 954 +#define OBJ_ct_cert_scts 1L,3L,6L,1L,4L,1L,11129L,2L,4L,5L + +#define SN_jurisdictionLocalityName "jurisdictionL" +#define LN_jurisdictionLocalityName "jurisdictionLocalityName" +#define NID_jurisdictionLocalityName 955 +#define OBJ_jurisdictionLocalityName 1L,3L,6L,1L,4L,1L,311L,60L,2L,1L,1L + +#define SN_jurisdictionStateOrProvinceName "jurisdictionST" +#define LN_jurisdictionStateOrProvinceName "jurisdictionStateOrProvinceName" +#define NID_jurisdictionStateOrProvinceName 956 +#define OBJ_jurisdictionStateOrProvinceName 1L,3L,6L,1L,4L,1L,311L,60L,2L,1L,2L + +#define SN_jurisdictionCountryName "jurisdictionC" +#define LN_jurisdictionCountryName "jurisdictionCountryName" +#define NID_jurisdictionCountryName 957 +#define OBJ_jurisdictionCountryName 1L,3L,6L,1L,4L,1L,311L,60L,2L,1L,3L diff --git a/OSlibs/ios/include/openssl/objects.h b/OSlibs/ios/include/openssl/objects.h new file mode 100755 index 000000000..b8dafa89c --- /dev/null +++ b/OSlibs/ios/include/openssl/objects.h @@ -0,0 +1,1143 @@ +/* crypto/objects/objects.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_OBJECTS_H +# define HEADER_OBJECTS_H + +# define USE_OBJ_MAC + +# ifdef USE_OBJ_MAC +# include +# else +# define SN_undef "UNDEF" +# define LN_undef "undefined" +# define NID_undef 0 +# define OBJ_undef 0L + +# define SN_Algorithm "Algorithm" +# define LN_algorithm "algorithm" +# define NID_algorithm 38 +# define OBJ_algorithm 1L,3L,14L,3L,2L + +# define LN_rsadsi "rsadsi" +# define NID_rsadsi 1 +# define OBJ_rsadsi 1L,2L,840L,113549L + +# define LN_pkcs "pkcs" +# define NID_pkcs 2 +# define OBJ_pkcs OBJ_rsadsi,1L + +# define SN_md2 "MD2" +# define LN_md2 "md2" +# define NID_md2 3 +# define OBJ_md2 OBJ_rsadsi,2L,2L + +# define SN_md5 "MD5" +# define LN_md5 "md5" +# define NID_md5 4 +# define OBJ_md5 OBJ_rsadsi,2L,5L + +# define SN_rc4 "RC4" +# define LN_rc4 "rc4" +# define NID_rc4 5 +# define OBJ_rc4 OBJ_rsadsi,3L,4L + +# define LN_rsaEncryption "rsaEncryption" +# define NID_rsaEncryption 6 +# define OBJ_rsaEncryption OBJ_pkcs,1L,1L + +# define SN_md2WithRSAEncryption "RSA-MD2" +# define LN_md2WithRSAEncryption "md2WithRSAEncryption" +# define NID_md2WithRSAEncryption 7 +# define OBJ_md2WithRSAEncryption OBJ_pkcs,1L,2L + +# define SN_md5WithRSAEncryption "RSA-MD5" +# define LN_md5WithRSAEncryption "md5WithRSAEncryption" +# define NID_md5WithRSAEncryption 8 +# define OBJ_md5WithRSAEncryption OBJ_pkcs,1L,4L + +# define SN_pbeWithMD2AndDES_CBC "PBE-MD2-DES" +# define LN_pbeWithMD2AndDES_CBC "pbeWithMD2AndDES-CBC" +# define NID_pbeWithMD2AndDES_CBC 9 +# define OBJ_pbeWithMD2AndDES_CBC OBJ_pkcs,5L,1L + +# define SN_pbeWithMD5AndDES_CBC "PBE-MD5-DES" +# define LN_pbeWithMD5AndDES_CBC "pbeWithMD5AndDES-CBC" +# define NID_pbeWithMD5AndDES_CBC 10 +# define OBJ_pbeWithMD5AndDES_CBC OBJ_pkcs,5L,3L + +# define LN_X500 "X500" +# define NID_X500 11 +# define OBJ_X500 2L,5L + +# define LN_X509 "X509" +# define NID_X509 12 +# define OBJ_X509 OBJ_X500,4L + +# define SN_commonName "CN" +# define LN_commonName "commonName" +# define NID_commonName 13 +# define OBJ_commonName OBJ_X509,3L + +# define SN_countryName "C" +# define LN_countryName "countryName" +# define NID_countryName 14 +# define OBJ_countryName OBJ_X509,6L + +# define SN_localityName "L" +# define LN_localityName "localityName" +# define NID_localityName 15 +# define OBJ_localityName OBJ_X509,7L + +/* Postal Address? PA */ + +/* should be "ST" (rfc1327) but MS uses 'S' */ +# define SN_stateOrProvinceName "ST" +# define LN_stateOrProvinceName "stateOrProvinceName" +# define NID_stateOrProvinceName 16 +# define OBJ_stateOrProvinceName OBJ_X509,8L + +# define SN_organizationName "O" +# define LN_organizationName "organizationName" +# define NID_organizationName 17 +# define OBJ_organizationName OBJ_X509,10L + +# define SN_organizationalUnitName "OU" +# define LN_organizationalUnitName "organizationalUnitName" +# define NID_organizationalUnitName 18 +# define OBJ_organizationalUnitName OBJ_X509,11L + +# define SN_rsa "RSA" +# define LN_rsa "rsa" +# define NID_rsa 19 +# define OBJ_rsa OBJ_X500,8L,1L,1L + +# define LN_pkcs7 "pkcs7" +# define NID_pkcs7 20 +# define OBJ_pkcs7 OBJ_pkcs,7L + +# define LN_pkcs7_data "pkcs7-data" +# define NID_pkcs7_data 21 +# define OBJ_pkcs7_data OBJ_pkcs7,1L + +# define LN_pkcs7_signed "pkcs7-signedData" +# define NID_pkcs7_signed 22 +# define OBJ_pkcs7_signed OBJ_pkcs7,2L + +# define LN_pkcs7_enveloped "pkcs7-envelopedData" +# define NID_pkcs7_enveloped 23 +# define OBJ_pkcs7_enveloped OBJ_pkcs7,3L + +# define LN_pkcs7_signedAndEnveloped "pkcs7-signedAndEnvelopedData" +# define NID_pkcs7_signedAndEnveloped 24 +# define OBJ_pkcs7_signedAndEnveloped OBJ_pkcs7,4L + +# define LN_pkcs7_digest "pkcs7-digestData" +# define NID_pkcs7_digest 25 +# define OBJ_pkcs7_digest OBJ_pkcs7,5L + +# define LN_pkcs7_encrypted "pkcs7-encryptedData" +# define NID_pkcs7_encrypted 26 +# define OBJ_pkcs7_encrypted OBJ_pkcs7,6L + +# define LN_pkcs3 "pkcs3" +# define NID_pkcs3 27 +# define OBJ_pkcs3 OBJ_pkcs,3L + +# define LN_dhKeyAgreement "dhKeyAgreement" +# define NID_dhKeyAgreement 28 +# define OBJ_dhKeyAgreement OBJ_pkcs3,1L + +# define SN_des_ecb "DES-ECB" +# define LN_des_ecb "des-ecb" +# define NID_des_ecb 29 +# define OBJ_des_ecb OBJ_algorithm,6L + +# define SN_des_cfb64 "DES-CFB" +# define LN_des_cfb64 "des-cfb" +# define NID_des_cfb64 30 +/* IV + num */ +# define OBJ_des_cfb64 OBJ_algorithm,9L + +# define SN_des_cbc "DES-CBC" +# define LN_des_cbc "des-cbc" +# define NID_des_cbc 31 +/* IV */ +# define OBJ_des_cbc OBJ_algorithm,7L + +# define SN_des_ede "DES-EDE" +# define LN_des_ede "des-ede" +# define NID_des_ede 32 +/* ?? */ +# define OBJ_des_ede OBJ_algorithm,17L + +# define SN_des_ede3 "DES-EDE3" +# define LN_des_ede3 "des-ede3" +# define NID_des_ede3 33 + +# define SN_idea_cbc "IDEA-CBC" +# define LN_idea_cbc "idea-cbc" +# define NID_idea_cbc 34 +# define OBJ_idea_cbc 1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L + +# define SN_idea_cfb64 "IDEA-CFB" +# define LN_idea_cfb64 "idea-cfb" +# define NID_idea_cfb64 35 + +# define SN_idea_ecb "IDEA-ECB" +# define LN_idea_ecb "idea-ecb" +# define NID_idea_ecb 36 + +# define SN_rc2_cbc "RC2-CBC" +# define LN_rc2_cbc "rc2-cbc" +# define NID_rc2_cbc 37 +# define OBJ_rc2_cbc OBJ_rsadsi,3L,2L + +# define SN_rc2_ecb "RC2-ECB" +# define LN_rc2_ecb "rc2-ecb" +# define NID_rc2_ecb 38 + +# define SN_rc2_cfb64 "RC2-CFB" +# define LN_rc2_cfb64 "rc2-cfb" +# define NID_rc2_cfb64 39 + +# define SN_rc2_ofb64 "RC2-OFB" +# define LN_rc2_ofb64 "rc2-ofb" +# define NID_rc2_ofb64 40 + +# define SN_sha "SHA" +# define LN_sha "sha" +# define NID_sha 41 +# define OBJ_sha OBJ_algorithm,18L + +# define SN_shaWithRSAEncryption "RSA-SHA" +# define LN_shaWithRSAEncryption "shaWithRSAEncryption" +# define NID_shaWithRSAEncryption 42 +# define OBJ_shaWithRSAEncryption OBJ_algorithm,15L + +# define SN_des_ede_cbc "DES-EDE-CBC" +# define LN_des_ede_cbc "des-ede-cbc" +# define NID_des_ede_cbc 43 + +# define SN_des_ede3_cbc "DES-EDE3-CBC" +# define LN_des_ede3_cbc "des-ede3-cbc" +# define NID_des_ede3_cbc 44 +# define OBJ_des_ede3_cbc OBJ_rsadsi,3L,7L + +# define SN_des_ofb64 "DES-OFB" +# define LN_des_ofb64 "des-ofb" +# define NID_des_ofb64 45 +# define OBJ_des_ofb64 OBJ_algorithm,8L + +# define SN_idea_ofb64 "IDEA-OFB" +# define LN_idea_ofb64 "idea-ofb" +# define NID_idea_ofb64 46 + +# define LN_pkcs9 "pkcs9" +# define NID_pkcs9 47 +# define OBJ_pkcs9 OBJ_pkcs,9L + +# define SN_pkcs9_emailAddress "Email" +# define LN_pkcs9_emailAddress "emailAddress" +# define NID_pkcs9_emailAddress 48 +# define OBJ_pkcs9_emailAddress OBJ_pkcs9,1L + +# define LN_pkcs9_unstructuredName "unstructuredName" +# define NID_pkcs9_unstructuredName 49 +# define OBJ_pkcs9_unstructuredName OBJ_pkcs9,2L + +# define LN_pkcs9_contentType "contentType" +# define NID_pkcs9_contentType 50 +# define OBJ_pkcs9_contentType OBJ_pkcs9,3L + +# define LN_pkcs9_messageDigest "messageDigest" +# define NID_pkcs9_messageDigest 51 +# define OBJ_pkcs9_messageDigest OBJ_pkcs9,4L + +# define LN_pkcs9_signingTime "signingTime" +# define NID_pkcs9_signingTime 52 +# define OBJ_pkcs9_signingTime OBJ_pkcs9,5L + +# define LN_pkcs9_countersignature "countersignature" +# define NID_pkcs9_countersignature 53 +# define OBJ_pkcs9_countersignature OBJ_pkcs9,6L + +# define LN_pkcs9_challengePassword "challengePassword" +# define NID_pkcs9_challengePassword 54 +# define OBJ_pkcs9_challengePassword OBJ_pkcs9,7L + +# define LN_pkcs9_unstructuredAddress "unstructuredAddress" +# define NID_pkcs9_unstructuredAddress 55 +# define OBJ_pkcs9_unstructuredAddress OBJ_pkcs9,8L + +# define LN_pkcs9_extCertAttributes "extendedCertificateAttributes" +# define NID_pkcs9_extCertAttributes 56 +# define OBJ_pkcs9_extCertAttributes OBJ_pkcs9,9L + +# define SN_netscape "Netscape" +# define LN_netscape "Netscape Communications Corp." +# define NID_netscape 57 +# define OBJ_netscape 2L,16L,840L,1L,113730L + +# define SN_netscape_cert_extension "nsCertExt" +# define LN_netscape_cert_extension "Netscape Certificate Extension" +# define NID_netscape_cert_extension 58 +# define OBJ_netscape_cert_extension OBJ_netscape,1L + +# define SN_netscape_data_type "nsDataType" +# define LN_netscape_data_type "Netscape Data Type" +# define NID_netscape_data_type 59 +# define OBJ_netscape_data_type OBJ_netscape,2L + +# define SN_des_ede_cfb64 "DES-EDE-CFB" +# define LN_des_ede_cfb64 "des-ede-cfb" +# define NID_des_ede_cfb64 60 + +# define SN_des_ede3_cfb64 "DES-EDE3-CFB" +# define LN_des_ede3_cfb64 "des-ede3-cfb" +# define NID_des_ede3_cfb64 61 + +# define SN_des_ede_ofb64 "DES-EDE-OFB" +# define LN_des_ede_ofb64 "des-ede-ofb" +# define NID_des_ede_ofb64 62 + +# define SN_des_ede3_ofb64 "DES-EDE3-OFB" +# define LN_des_ede3_ofb64 "des-ede3-ofb" +# define NID_des_ede3_ofb64 63 + +/* I'm not sure about the object ID */ +# define SN_sha1 "SHA1" +# define LN_sha1 "sha1" +# define NID_sha1 64 +# define OBJ_sha1 OBJ_algorithm,26L +/* 28 Jun 1996 - eay */ +/* #define OBJ_sha1 1L,3L,14L,2L,26L,05L <- wrong */ + +# define SN_sha1WithRSAEncryption "RSA-SHA1" +# define LN_sha1WithRSAEncryption "sha1WithRSAEncryption" +# define NID_sha1WithRSAEncryption 65 +# define OBJ_sha1WithRSAEncryption OBJ_pkcs,1L,5L + +# define SN_dsaWithSHA "DSA-SHA" +# define LN_dsaWithSHA "dsaWithSHA" +# define NID_dsaWithSHA 66 +# define OBJ_dsaWithSHA OBJ_algorithm,13L + +# define SN_dsa_2 "DSA-old" +# define LN_dsa_2 "dsaEncryption-old" +# define NID_dsa_2 67 +# define OBJ_dsa_2 OBJ_algorithm,12L + +/* proposed by microsoft to RSA */ +# define SN_pbeWithSHA1AndRC2_CBC "PBE-SHA1-RC2-64" +# define LN_pbeWithSHA1AndRC2_CBC "pbeWithSHA1AndRC2-CBC" +# define NID_pbeWithSHA1AndRC2_CBC 68 +# define OBJ_pbeWithSHA1AndRC2_CBC OBJ_pkcs,5L,11L + +/* + * proposed by microsoft to RSA as pbeWithSHA1AndRC4: it is now defined + * explicitly in PKCS#5 v2.0 as id-PBKDF2 which is something completely + * different. + */ +# define LN_id_pbkdf2 "PBKDF2" +# define NID_id_pbkdf2 69 +# define OBJ_id_pbkdf2 OBJ_pkcs,5L,12L + +# define SN_dsaWithSHA1_2 "DSA-SHA1-old" +# define LN_dsaWithSHA1_2 "dsaWithSHA1-old" +# define NID_dsaWithSHA1_2 70 +/* Got this one from 'sdn706r20.pdf' which is actually an NSA document :-) */ +# define OBJ_dsaWithSHA1_2 OBJ_algorithm,27L + +# define SN_netscape_cert_type "nsCertType" +# define LN_netscape_cert_type "Netscape Cert Type" +# define NID_netscape_cert_type 71 +# define OBJ_netscape_cert_type OBJ_netscape_cert_extension,1L + +# define SN_netscape_base_url "nsBaseUrl" +# define LN_netscape_base_url "Netscape Base Url" +# define NID_netscape_base_url 72 +# define OBJ_netscape_base_url OBJ_netscape_cert_extension,2L + +# define SN_netscape_revocation_url "nsRevocationUrl" +# define LN_netscape_revocation_url "Netscape Revocation Url" +# define NID_netscape_revocation_url 73 +# define OBJ_netscape_revocation_url OBJ_netscape_cert_extension,3L + +# define SN_netscape_ca_revocation_url "nsCaRevocationUrl" +# define LN_netscape_ca_revocation_url "Netscape CA Revocation Url" +# define NID_netscape_ca_revocation_url 74 +# define OBJ_netscape_ca_revocation_url OBJ_netscape_cert_extension,4L + +# define SN_netscape_renewal_url "nsRenewalUrl" +# define LN_netscape_renewal_url "Netscape Renewal Url" +# define NID_netscape_renewal_url 75 +# define OBJ_netscape_renewal_url OBJ_netscape_cert_extension,7L + +# define SN_netscape_ca_policy_url "nsCaPolicyUrl" +# define LN_netscape_ca_policy_url "Netscape CA Policy Url" +# define NID_netscape_ca_policy_url 76 +# define OBJ_netscape_ca_policy_url OBJ_netscape_cert_extension,8L + +# define SN_netscape_ssl_server_name "nsSslServerName" +# define LN_netscape_ssl_server_name "Netscape SSL Server Name" +# define NID_netscape_ssl_server_name 77 +# define OBJ_netscape_ssl_server_name OBJ_netscape_cert_extension,12L + +# define SN_netscape_comment "nsComment" +# define LN_netscape_comment "Netscape Comment" +# define NID_netscape_comment 78 +# define OBJ_netscape_comment OBJ_netscape_cert_extension,13L + +# define SN_netscape_cert_sequence "nsCertSequence" +# define LN_netscape_cert_sequence "Netscape Certificate Sequence" +# define NID_netscape_cert_sequence 79 +# define OBJ_netscape_cert_sequence OBJ_netscape_data_type,5L + +# define SN_desx_cbc "DESX-CBC" +# define LN_desx_cbc "desx-cbc" +# define NID_desx_cbc 80 + +# define SN_id_ce "id-ce" +# define NID_id_ce 81 +# define OBJ_id_ce 2L,5L,29L + +# define SN_subject_key_identifier "subjectKeyIdentifier" +# define LN_subject_key_identifier "X509v3 Subject Key Identifier" +# define NID_subject_key_identifier 82 +# define OBJ_subject_key_identifier OBJ_id_ce,14L + +# define SN_key_usage "keyUsage" +# define LN_key_usage "X509v3 Key Usage" +# define NID_key_usage 83 +# define OBJ_key_usage OBJ_id_ce,15L + +# define SN_private_key_usage_period "privateKeyUsagePeriod" +# define LN_private_key_usage_period "X509v3 Private Key Usage Period" +# define NID_private_key_usage_period 84 +# define OBJ_private_key_usage_period OBJ_id_ce,16L + +# define SN_subject_alt_name "subjectAltName" +# define LN_subject_alt_name "X509v3 Subject Alternative Name" +# define NID_subject_alt_name 85 +# define OBJ_subject_alt_name OBJ_id_ce,17L + +# define SN_issuer_alt_name "issuerAltName" +# define LN_issuer_alt_name "X509v3 Issuer Alternative Name" +# define NID_issuer_alt_name 86 +# define OBJ_issuer_alt_name OBJ_id_ce,18L + +# define SN_basic_constraints "basicConstraints" +# define LN_basic_constraints "X509v3 Basic Constraints" +# define NID_basic_constraints 87 +# define OBJ_basic_constraints OBJ_id_ce,19L + +# define SN_crl_number "crlNumber" +# define LN_crl_number "X509v3 CRL Number" +# define NID_crl_number 88 +# define OBJ_crl_number OBJ_id_ce,20L + +# define SN_certificate_policies "certificatePolicies" +# define LN_certificate_policies "X509v3 Certificate Policies" +# define NID_certificate_policies 89 +# define OBJ_certificate_policies OBJ_id_ce,32L + +# define SN_authority_key_identifier "authorityKeyIdentifier" +# define LN_authority_key_identifier "X509v3 Authority Key Identifier" +# define NID_authority_key_identifier 90 +# define OBJ_authority_key_identifier OBJ_id_ce,35L + +# define SN_bf_cbc "BF-CBC" +# define LN_bf_cbc "bf-cbc" +# define NID_bf_cbc 91 +# define OBJ_bf_cbc 1L,3L,6L,1L,4L,1L,3029L,1L,2L + +# define SN_bf_ecb "BF-ECB" +# define LN_bf_ecb "bf-ecb" +# define NID_bf_ecb 92 + +# define SN_bf_cfb64 "BF-CFB" +# define LN_bf_cfb64 "bf-cfb" +# define NID_bf_cfb64 93 + +# define SN_bf_ofb64 "BF-OFB" +# define LN_bf_ofb64 "bf-ofb" +# define NID_bf_ofb64 94 + +# define SN_mdc2 "MDC2" +# define LN_mdc2 "mdc2" +# define NID_mdc2 95 +# define OBJ_mdc2 2L,5L,8L,3L,101L +/* An alternative? 1L,3L,14L,3L,2L,19L */ + +# define SN_mdc2WithRSA "RSA-MDC2" +# define LN_mdc2WithRSA "mdc2withRSA" +# define NID_mdc2WithRSA 96 +# define OBJ_mdc2WithRSA 2L,5L,8L,3L,100L + +# define SN_rc4_40 "RC4-40" +# define LN_rc4_40 "rc4-40" +# define NID_rc4_40 97 + +# define SN_rc2_40_cbc "RC2-40-CBC" +# define LN_rc2_40_cbc "rc2-40-cbc" +# define NID_rc2_40_cbc 98 + +# define SN_givenName "G" +# define LN_givenName "givenName" +# define NID_givenName 99 +# define OBJ_givenName OBJ_X509,42L + +# define SN_surname "S" +# define LN_surname "surname" +# define NID_surname 100 +# define OBJ_surname OBJ_X509,4L + +# define SN_initials "I" +# define LN_initials "initials" +# define NID_initials 101 +# define OBJ_initials OBJ_X509,43L + +# define SN_uniqueIdentifier "UID" +# define LN_uniqueIdentifier "uniqueIdentifier" +# define NID_uniqueIdentifier 102 +# define OBJ_uniqueIdentifier OBJ_X509,45L + +# define SN_crl_distribution_points "crlDistributionPoints" +# define LN_crl_distribution_points "X509v3 CRL Distribution Points" +# define NID_crl_distribution_points 103 +# define OBJ_crl_distribution_points OBJ_id_ce,31L + +# define SN_md5WithRSA "RSA-NP-MD5" +# define LN_md5WithRSA "md5WithRSA" +# define NID_md5WithRSA 104 +# define OBJ_md5WithRSA OBJ_algorithm,3L + +# define SN_serialNumber "SN" +# define LN_serialNumber "serialNumber" +# define NID_serialNumber 105 +# define OBJ_serialNumber OBJ_X509,5L + +# define SN_title "T" +# define LN_title "title" +# define NID_title 106 +# define OBJ_title OBJ_X509,12L + +# define SN_description "D" +# define LN_description "description" +# define NID_description 107 +# define OBJ_description OBJ_X509,13L + +/* CAST5 is CAST-128, I'm just sticking with the documentation */ +# define SN_cast5_cbc "CAST5-CBC" +# define LN_cast5_cbc "cast5-cbc" +# define NID_cast5_cbc 108 +# define OBJ_cast5_cbc 1L,2L,840L,113533L,7L,66L,10L + +# define SN_cast5_ecb "CAST5-ECB" +# define LN_cast5_ecb "cast5-ecb" +# define NID_cast5_ecb 109 + +# define SN_cast5_cfb64 "CAST5-CFB" +# define LN_cast5_cfb64 "cast5-cfb" +# define NID_cast5_cfb64 110 + +# define SN_cast5_ofb64 "CAST5-OFB" +# define LN_cast5_ofb64 "cast5-ofb" +# define NID_cast5_ofb64 111 + +# define LN_pbeWithMD5AndCast5_CBC "pbeWithMD5AndCast5CBC" +# define NID_pbeWithMD5AndCast5_CBC 112 +# define OBJ_pbeWithMD5AndCast5_CBC 1L,2L,840L,113533L,7L,66L,12L + +/*- + * This is one sun will soon be using :-( + * id-dsa-with-sha1 ID ::= { + * iso(1) member-body(2) us(840) x9-57 (10040) x9cm(4) 3 } + */ +# define SN_dsaWithSHA1 "DSA-SHA1" +# define LN_dsaWithSHA1 "dsaWithSHA1" +# define NID_dsaWithSHA1 113 +# define OBJ_dsaWithSHA1 1L,2L,840L,10040L,4L,3L + +# define NID_md5_sha1 114 +# define SN_md5_sha1 "MD5-SHA1" +# define LN_md5_sha1 "md5-sha1" + +# define SN_sha1WithRSA "RSA-SHA1-2" +# define LN_sha1WithRSA "sha1WithRSA" +# define NID_sha1WithRSA 115 +# define OBJ_sha1WithRSA OBJ_algorithm,29L + +# define SN_dsa "DSA" +# define LN_dsa "dsaEncryption" +# define NID_dsa 116 +# define OBJ_dsa 1L,2L,840L,10040L,4L,1L + +# define SN_ripemd160 "RIPEMD160" +# define LN_ripemd160 "ripemd160" +# define NID_ripemd160 117 +# define OBJ_ripemd160 1L,3L,36L,3L,2L,1L + +/* + * The name should actually be rsaSignatureWithripemd160, but I'm going to + * continue using the convention I'm using with the other ciphers + */ +# define SN_ripemd160WithRSA "RSA-RIPEMD160" +# define LN_ripemd160WithRSA "ripemd160WithRSA" +# define NID_ripemd160WithRSA 119 +# define OBJ_ripemd160WithRSA 1L,3L,36L,3L,3L,1L,2L + +/*- + * Taken from rfc2040 + * RC5_CBC_Parameters ::= SEQUENCE { + * version INTEGER (v1_0(16)), + * rounds INTEGER (8..127), + * blockSizeInBits INTEGER (64, 128), + * iv OCTET STRING OPTIONAL + * } + */ +# define SN_rc5_cbc "RC5-CBC" +# define LN_rc5_cbc "rc5-cbc" +# define NID_rc5_cbc 120 +# define OBJ_rc5_cbc OBJ_rsadsi,3L,8L + +# define SN_rc5_ecb "RC5-ECB" +# define LN_rc5_ecb "rc5-ecb" +# define NID_rc5_ecb 121 + +# define SN_rc5_cfb64 "RC5-CFB" +# define LN_rc5_cfb64 "rc5-cfb" +# define NID_rc5_cfb64 122 + +# define SN_rc5_ofb64 "RC5-OFB" +# define LN_rc5_ofb64 "rc5-ofb" +# define NID_rc5_ofb64 123 + +# define SN_rle_compression "RLE" +# define LN_rle_compression "run length compression" +# define NID_rle_compression 124 +# define OBJ_rle_compression 1L,1L,1L,1L,666L,1L + +# define SN_zlib_compression "ZLIB" +# define LN_zlib_compression "zlib compression" +# define NID_zlib_compression 125 +# define OBJ_zlib_compression 1L,1L,1L,1L,666L,2L + +# define SN_ext_key_usage "extendedKeyUsage" +# define LN_ext_key_usage "X509v3 Extended Key Usage" +# define NID_ext_key_usage 126 +# define OBJ_ext_key_usage OBJ_id_ce,37 + +# define SN_id_pkix "PKIX" +# define NID_id_pkix 127 +# define OBJ_id_pkix 1L,3L,6L,1L,5L,5L,7L + +# define SN_id_kp "id-kp" +# define NID_id_kp 128 +# define OBJ_id_kp OBJ_id_pkix,3L + +/* PKIX extended key usage OIDs */ + +# define SN_server_auth "serverAuth" +# define LN_server_auth "TLS Web Server Authentication" +# define NID_server_auth 129 +# define OBJ_server_auth OBJ_id_kp,1L + +# define SN_client_auth "clientAuth" +# define LN_client_auth "TLS Web Client Authentication" +# define NID_client_auth 130 +# define OBJ_client_auth OBJ_id_kp,2L + +# define SN_code_sign "codeSigning" +# define LN_code_sign "Code Signing" +# define NID_code_sign 131 +# define OBJ_code_sign OBJ_id_kp,3L + +# define SN_email_protect "emailProtection" +# define LN_email_protect "E-mail Protection" +# define NID_email_protect 132 +# define OBJ_email_protect OBJ_id_kp,4L + +# define SN_time_stamp "timeStamping" +# define LN_time_stamp "Time Stamping" +# define NID_time_stamp 133 +# define OBJ_time_stamp OBJ_id_kp,8L + +/* Additional extended key usage OIDs: Microsoft */ + +# define SN_ms_code_ind "msCodeInd" +# define LN_ms_code_ind "Microsoft Individual Code Signing" +# define NID_ms_code_ind 134 +# define OBJ_ms_code_ind 1L,3L,6L,1L,4L,1L,311L,2L,1L,21L + +# define SN_ms_code_com "msCodeCom" +# define LN_ms_code_com "Microsoft Commercial Code Signing" +# define NID_ms_code_com 135 +# define OBJ_ms_code_com 1L,3L,6L,1L,4L,1L,311L,2L,1L,22L + +# define SN_ms_ctl_sign "msCTLSign" +# define LN_ms_ctl_sign "Microsoft Trust List Signing" +# define NID_ms_ctl_sign 136 +# define OBJ_ms_ctl_sign 1L,3L,6L,1L,4L,1L,311L,10L,3L,1L + +# define SN_ms_sgc "msSGC" +# define LN_ms_sgc "Microsoft Server Gated Crypto" +# define NID_ms_sgc 137 +# define OBJ_ms_sgc 1L,3L,6L,1L,4L,1L,311L,10L,3L,3L + +# define SN_ms_efs "msEFS" +# define LN_ms_efs "Microsoft Encrypted File System" +# define NID_ms_efs 138 +# define OBJ_ms_efs 1L,3L,6L,1L,4L,1L,311L,10L,3L,4L + +/* Additional usage: Netscape */ + +# define SN_ns_sgc "nsSGC" +# define LN_ns_sgc "Netscape Server Gated Crypto" +# define NID_ns_sgc 139 +# define OBJ_ns_sgc OBJ_netscape,4L,1L + +# define SN_delta_crl "deltaCRL" +# define LN_delta_crl "X509v3 Delta CRL Indicator" +# define NID_delta_crl 140 +# define OBJ_delta_crl OBJ_id_ce,27L + +# define SN_crl_reason "CRLReason" +# define LN_crl_reason "CRL Reason Code" +# define NID_crl_reason 141 +# define OBJ_crl_reason OBJ_id_ce,21L + +# define SN_invalidity_date "invalidityDate" +# define LN_invalidity_date "Invalidity Date" +# define NID_invalidity_date 142 +# define OBJ_invalidity_date OBJ_id_ce,24L + +# define SN_sxnet "SXNetID" +# define LN_sxnet "Strong Extranet ID" +# define NID_sxnet 143 +# define OBJ_sxnet 1L,3L,101L,1L,4L,1L + +/* PKCS12 and related OBJECT IDENTIFIERS */ + +# define OBJ_pkcs12 OBJ_pkcs,12L +# define OBJ_pkcs12_pbeids OBJ_pkcs12, 1 + +# define SN_pbe_WithSHA1And128BitRC4 "PBE-SHA1-RC4-128" +# define LN_pbe_WithSHA1And128BitRC4 "pbeWithSHA1And128BitRC4" +# define NID_pbe_WithSHA1And128BitRC4 144 +# define OBJ_pbe_WithSHA1And128BitRC4 OBJ_pkcs12_pbeids, 1L + +# define SN_pbe_WithSHA1And40BitRC4 "PBE-SHA1-RC4-40" +# define LN_pbe_WithSHA1And40BitRC4 "pbeWithSHA1And40BitRC4" +# define NID_pbe_WithSHA1And40BitRC4 145 +# define OBJ_pbe_WithSHA1And40BitRC4 OBJ_pkcs12_pbeids, 2L + +# define SN_pbe_WithSHA1And3_Key_TripleDES_CBC "PBE-SHA1-3DES" +# define LN_pbe_WithSHA1And3_Key_TripleDES_CBC "pbeWithSHA1And3-KeyTripleDES-CBC" +# define NID_pbe_WithSHA1And3_Key_TripleDES_CBC 146 +# define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC OBJ_pkcs12_pbeids, 3L + +# define SN_pbe_WithSHA1And2_Key_TripleDES_CBC "PBE-SHA1-2DES" +# define LN_pbe_WithSHA1And2_Key_TripleDES_CBC "pbeWithSHA1And2-KeyTripleDES-CBC" +# define NID_pbe_WithSHA1And2_Key_TripleDES_CBC 147 +# define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC OBJ_pkcs12_pbeids, 4L + +# define SN_pbe_WithSHA1And128BitRC2_CBC "PBE-SHA1-RC2-128" +# define LN_pbe_WithSHA1And128BitRC2_CBC "pbeWithSHA1And128BitRC2-CBC" +# define NID_pbe_WithSHA1And128BitRC2_CBC 148 +# define OBJ_pbe_WithSHA1And128BitRC2_CBC OBJ_pkcs12_pbeids, 5L + +# define SN_pbe_WithSHA1And40BitRC2_CBC "PBE-SHA1-RC2-40" +# define LN_pbe_WithSHA1And40BitRC2_CBC "pbeWithSHA1And40BitRC2-CBC" +# define NID_pbe_WithSHA1And40BitRC2_CBC 149 +# define OBJ_pbe_WithSHA1And40BitRC2_CBC OBJ_pkcs12_pbeids, 6L + +# define OBJ_pkcs12_Version1 OBJ_pkcs12, 10L + +# define OBJ_pkcs12_BagIds OBJ_pkcs12_Version1, 1L + +# define LN_keyBag "keyBag" +# define NID_keyBag 150 +# define OBJ_keyBag OBJ_pkcs12_BagIds, 1L + +# define LN_pkcs8ShroudedKeyBag "pkcs8ShroudedKeyBag" +# define NID_pkcs8ShroudedKeyBag 151 +# define OBJ_pkcs8ShroudedKeyBag OBJ_pkcs12_BagIds, 2L + +# define LN_certBag "certBag" +# define NID_certBag 152 +# define OBJ_certBag OBJ_pkcs12_BagIds, 3L + +# define LN_crlBag "crlBag" +# define NID_crlBag 153 +# define OBJ_crlBag OBJ_pkcs12_BagIds, 4L + +# define LN_secretBag "secretBag" +# define NID_secretBag 154 +# define OBJ_secretBag OBJ_pkcs12_BagIds, 5L + +# define LN_safeContentsBag "safeContentsBag" +# define NID_safeContentsBag 155 +# define OBJ_safeContentsBag OBJ_pkcs12_BagIds, 6L + +# define LN_friendlyName "friendlyName" +# define NID_friendlyName 156 +# define OBJ_friendlyName OBJ_pkcs9, 20L + +# define LN_localKeyID "localKeyID" +# define NID_localKeyID 157 +# define OBJ_localKeyID OBJ_pkcs9, 21L + +# define OBJ_certTypes OBJ_pkcs9, 22L + +# define LN_x509Certificate "x509Certificate" +# define NID_x509Certificate 158 +# define OBJ_x509Certificate OBJ_certTypes, 1L + +# define LN_sdsiCertificate "sdsiCertificate" +# define NID_sdsiCertificate 159 +# define OBJ_sdsiCertificate OBJ_certTypes, 2L + +# define OBJ_crlTypes OBJ_pkcs9, 23L + +# define LN_x509Crl "x509Crl" +# define NID_x509Crl 160 +# define OBJ_x509Crl OBJ_crlTypes, 1L + +/* PKCS#5 v2 OIDs */ + +# define LN_pbes2 "PBES2" +# define NID_pbes2 161 +# define OBJ_pbes2 OBJ_pkcs,5L,13L + +# define LN_pbmac1 "PBMAC1" +# define NID_pbmac1 162 +# define OBJ_pbmac1 OBJ_pkcs,5L,14L + +# define LN_hmacWithSHA1 "hmacWithSHA1" +# define NID_hmacWithSHA1 163 +# define OBJ_hmacWithSHA1 OBJ_rsadsi,2L,7L + +/* Policy Qualifier Ids */ + +# define LN_id_qt_cps "Policy Qualifier CPS" +# define SN_id_qt_cps "id-qt-cps" +# define NID_id_qt_cps 164 +# define OBJ_id_qt_cps OBJ_id_pkix,2L,1L + +# define LN_id_qt_unotice "Policy Qualifier User Notice" +# define SN_id_qt_unotice "id-qt-unotice" +# define NID_id_qt_unotice 165 +# define OBJ_id_qt_unotice OBJ_id_pkix,2L,2L + +# define SN_rc2_64_cbc "RC2-64-CBC" +# define LN_rc2_64_cbc "rc2-64-cbc" +# define NID_rc2_64_cbc 166 + +# define SN_SMIMECapabilities "SMIME-CAPS" +# define LN_SMIMECapabilities "S/MIME Capabilities" +# define NID_SMIMECapabilities 167 +# define OBJ_SMIMECapabilities OBJ_pkcs9,15L + +# define SN_pbeWithMD2AndRC2_CBC "PBE-MD2-RC2-64" +# define LN_pbeWithMD2AndRC2_CBC "pbeWithMD2AndRC2-CBC" +# define NID_pbeWithMD2AndRC2_CBC 168 +# define OBJ_pbeWithMD2AndRC2_CBC OBJ_pkcs,5L,4L + +# define SN_pbeWithMD5AndRC2_CBC "PBE-MD5-RC2-64" +# define LN_pbeWithMD5AndRC2_CBC "pbeWithMD5AndRC2-CBC" +# define NID_pbeWithMD5AndRC2_CBC 169 +# define OBJ_pbeWithMD5AndRC2_CBC OBJ_pkcs,5L,6L + +# define SN_pbeWithSHA1AndDES_CBC "PBE-SHA1-DES" +# define LN_pbeWithSHA1AndDES_CBC "pbeWithSHA1AndDES-CBC" +# define NID_pbeWithSHA1AndDES_CBC 170 +# define OBJ_pbeWithSHA1AndDES_CBC OBJ_pkcs,5L,10L + +/* Extension request OIDs */ + +# define LN_ms_ext_req "Microsoft Extension Request" +# define SN_ms_ext_req "msExtReq" +# define NID_ms_ext_req 171 +# define OBJ_ms_ext_req 1L,3L,6L,1L,4L,1L,311L,2L,1L,14L + +# define LN_ext_req "Extension Request" +# define SN_ext_req "extReq" +# define NID_ext_req 172 +# define OBJ_ext_req OBJ_pkcs9,14L + +# define SN_name "name" +# define LN_name "name" +# define NID_name 173 +# define OBJ_name OBJ_X509,41L + +# define SN_dnQualifier "dnQualifier" +# define LN_dnQualifier "dnQualifier" +# define NID_dnQualifier 174 +# define OBJ_dnQualifier OBJ_X509,46L + +# define SN_id_pe "id-pe" +# define NID_id_pe 175 +# define OBJ_id_pe OBJ_id_pkix,1L + +# define SN_id_ad "id-ad" +# define NID_id_ad 176 +# define OBJ_id_ad OBJ_id_pkix,48L + +# define SN_info_access "authorityInfoAccess" +# define LN_info_access "Authority Information Access" +# define NID_info_access 177 +# define OBJ_info_access OBJ_id_pe,1L + +# define SN_ad_OCSP "OCSP" +# define LN_ad_OCSP "OCSP" +# define NID_ad_OCSP 178 +# define OBJ_ad_OCSP OBJ_id_ad,1L + +# define SN_ad_ca_issuers "caIssuers" +# define LN_ad_ca_issuers "CA Issuers" +# define NID_ad_ca_issuers 179 +# define OBJ_ad_ca_issuers OBJ_id_ad,2L + +# define SN_OCSP_sign "OCSPSigning" +# define LN_OCSP_sign "OCSP Signing" +# define NID_OCSP_sign 180 +# define OBJ_OCSP_sign OBJ_id_kp,9L +# endif /* USE_OBJ_MAC */ + +# include +# include + +# define OBJ_NAME_TYPE_UNDEF 0x00 +# define OBJ_NAME_TYPE_MD_METH 0x01 +# define OBJ_NAME_TYPE_CIPHER_METH 0x02 +# define OBJ_NAME_TYPE_PKEY_METH 0x03 +# define OBJ_NAME_TYPE_COMP_METH 0x04 +# define OBJ_NAME_TYPE_NUM 0x05 + +# define OBJ_NAME_ALIAS 0x8000 + +# define OBJ_BSEARCH_VALUE_ON_NOMATCH 0x01 +# define OBJ_BSEARCH_FIRST_VALUE_ON_MATCH 0x02 + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct obj_name_st { + int type; + int alias; + const char *name; + const char *data; +} OBJ_NAME; + +# define OBJ_create_and_add_object(a,b,c) OBJ_create(a,b,c) + +int OBJ_NAME_init(void); +int OBJ_NAME_new_index(unsigned long (*hash_func) (const char *), + int (*cmp_func) (const char *, const char *), + void (*free_func) (const char *, int, const char *)); +const char *OBJ_NAME_get(const char *name, int type); +int OBJ_NAME_add(const char *name, int type, const char *data); +int OBJ_NAME_remove(const char *name, int type); +void OBJ_NAME_cleanup(int type); /* -1 for everything */ +void OBJ_NAME_do_all(int type, void (*fn) (const OBJ_NAME *, void *arg), + void *arg); +void OBJ_NAME_do_all_sorted(int type, + void (*fn) (const OBJ_NAME *, void *arg), + void *arg); + +ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o); +ASN1_OBJECT *OBJ_nid2obj(int n); +const char *OBJ_nid2ln(int n); +const char *OBJ_nid2sn(int n); +int OBJ_obj2nid(const ASN1_OBJECT *o); +ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name); +int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name); +int OBJ_txt2nid(const char *s); +int OBJ_ln2nid(const char *s); +int OBJ_sn2nid(const char *s); +int OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b); +const void *OBJ_bsearch_(const void *key, const void *base, int num, int size, + int (*cmp) (const void *, const void *)); +const void *OBJ_bsearch_ex_(const void *key, const void *base, int num, + int size, + int (*cmp) (const void *, const void *), + int flags); + +# define _DECLARE_OBJ_BSEARCH_CMP_FN(scope, type1, type2, nm) \ + static int nm##_cmp_BSEARCH_CMP_FN(const void *, const void *); \ + static int nm##_cmp(type1 const *, type2 const *); \ + scope type2 * OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) + +# define DECLARE_OBJ_BSEARCH_CMP_FN(type1, type2, cmp) \ + _DECLARE_OBJ_BSEARCH_CMP_FN(static, type1, type2, cmp) +# define DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(type1, type2, nm) \ + type2 * OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) + +/*- + * Unsolved problem: if a type is actually a pointer type, like + * nid_triple is, then its impossible to get a const where you need + * it. Consider: + * + * typedef int nid_triple[3]; + * const void *a_; + * const nid_triple const *a = a_; + * + * The assignement discards a const because what you really want is: + * + * const int const * const *a = a_; + * + * But if you do that, you lose the fact that a is an array of 3 ints, + * which breaks comparison functions. + * + * Thus we end up having to cast, sadly, or unpack the + * declarations. Or, as I finally did in this case, delcare nid_triple + * to be a struct, which it should have been in the first place. + * + * Ben, August 2008. + * + * Also, strictly speaking not all types need be const, but handling + * the non-constness means a lot of complication, and in practice + * comparison routines do always not touch their arguments. + */ + +# define IMPLEMENT_OBJ_BSEARCH_CMP_FN(type1, type2, nm) \ + static int nm##_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_) \ + { \ + type1 const *a = a_; \ + type2 const *b = b_; \ + return nm##_cmp(a,b); \ + } \ + static type2 *OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) \ + { \ + return (type2 *)OBJ_bsearch_(key, base, num, sizeof(type2), \ + nm##_cmp_BSEARCH_CMP_FN); \ + } \ + extern void dummy_prototype(void) + +# define IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(type1, type2, nm) \ + static int nm##_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_) \ + { \ + type1 const *a = a_; \ + type2 const *b = b_; \ + return nm##_cmp(a,b); \ + } \ + type2 *OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) \ + { \ + return (type2 *)OBJ_bsearch_(key, base, num, sizeof(type2), \ + nm##_cmp_BSEARCH_CMP_FN); \ + } \ + extern void dummy_prototype(void) + +# define OBJ_bsearch(type1,key,type2,base,num,cmp) \ + ((type2 *)OBJ_bsearch_(CHECKED_PTR_OF(type1,key),CHECKED_PTR_OF(type2,base), \ + num,sizeof(type2), \ + ((void)CHECKED_PTR_OF(type1,cmp##_type_1), \ + (void)CHECKED_PTR_OF(type2,cmp##_type_2), \ + cmp##_BSEARCH_CMP_FN))) + +# define OBJ_bsearch_ex(type1,key,type2,base,num,cmp,flags) \ + ((type2 *)OBJ_bsearch_ex_(CHECKED_PTR_OF(type1,key),CHECKED_PTR_OF(type2,base), \ + num,sizeof(type2), \ + ((void)CHECKED_PTR_OF(type1,cmp##_type_1), \ + (void)type_2=CHECKED_PTR_OF(type2,cmp##_type_2), \ + cmp##_BSEARCH_CMP_FN)),flags) + +int OBJ_new_nid(int num); +int OBJ_add_object(const ASN1_OBJECT *obj); +int OBJ_create(const char *oid, const char *sn, const char *ln); +void OBJ_cleanup(void); +int OBJ_create_objects(BIO *in); + +int OBJ_find_sigid_algs(int signid, int *pdig_nid, int *ppkey_nid); +int OBJ_find_sigid_by_algs(int *psignid, int dig_nid, int pkey_nid); +int OBJ_add_sigid(int signid, int dig_id, int pkey_id); +void OBJ_sigid_free(void); + +extern int obj_cleanup_defer; +void check_defer(int nid); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_OBJ_strings(void); + +/* Error codes for the OBJ functions. */ + +/* Function codes. */ +# define OBJ_F_OBJ_ADD_OBJECT 105 +# define OBJ_F_OBJ_CREATE 100 +# define OBJ_F_OBJ_DUP 101 +# define OBJ_F_OBJ_NAME_NEW_INDEX 106 +# define OBJ_F_OBJ_NID2LN 102 +# define OBJ_F_OBJ_NID2OBJ 103 +# define OBJ_F_OBJ_NID2SN 104 + +/* Reason codes. */ +# define OBJ_R_MALLOC_FAILURE 100 +# define OBJ_R_UNKNOWN_NID 101 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/ocsp.h b/OSlibs/ios/include/openssl/ocsp.h new file mode 100755 index 000000000..ca2ee76dc --- /dev/null +++ b/OSlibs/ios/include/openssl/ocsp.h @@ -0,0 +1,637 @@ +/* ocsp.h */ +/* + * Written by Tom Titchener for the OpenSSL + * project. + */ + +/* + * History: This file was transfered to Richard Levitte from CertCo by Kathy + * Weinhold in mid-spring 2000 to be included in OpenSSL or released as a + * patch kit. + */ + +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_OCSP_H +# define HEADER_OCSP_H + +# include +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Various flags and values */ + +# define OCSP_DEFAULT_NONCE_LENGTH 16 + +# define OCSP_NOCERTS 0x1 +# define OCSP_NOINTERN 0x2 +# define OCSP_NOSIGS 0x4 +# define OCSP_NOCHAIN 0x8 +# define OCSP_NOVERIFY 0x10 +# define OCSP_NOEXPLICIT 0x20 +# define OCSP_NOCASIGN 0x40 +# define OCSP_NODELEGATED 0x80 +# define OCSP_NOCHECKS 0x100 +# define OCSP_TRUSTOTHER 0x200 +# define OCSP_RESPID_KEY 0x400 +# define OCSP_NOTIME 0x800 + +/*- CertID ::= SEQUENCE { + * hashAlgorithm AlgorithmIdentifier, + * issuerNameHash OCTET STRING, -- Hash of Issuer's DN + * issuerKeyHash OCTET STRING, -- Hash of Issuers public key (excluding the tag & length fields) + * serialNumber CertificateSerialNumber } + */ +typedef struct ocsp_cert_id_st { + X509_ALGOR *hashAlgorithm; + ASN1_OCTET_STRING *issuerNameHash; + ASN1_OCTET_STRING *issuerKeyHash; + ASN1_INTEGER *serialNumber; +} OCSP_CERTID; + +DECLARE_STACK_OF(OCSP_CERTID) + +/*- Request ::= SEQUENCE { + * reqCert CertID, + * singleRequestExtensions [0] EXPLICIT Extensions OPTIONAL } + */ +typedef struct ocsp_one_request_st { + OCSP_CERTID *reqCert; + STACK_OF(X509_EXTENSION) *singleRequestExtensions; +} OCSP_ONEREQ; + +DECLARE_STACK_OF(OCSP_ONEREQ) +DECLARE_ASN1_SET_OF(OCSP_ONEREQ) + +/*- TBSRequest ::= SEQUENCE { + * version [0] EXPLICIT Version DEFAULT v1, + * requestorName [1] EXPLICIT GeneralName OPTIONAL, + * requestList SEQUENCE OF Request, + * requestExtensions [2] EXPLICIT Extensions OPTIONAL } + */ +typedef struct ocsp_req_info_st { + ASN1_INTEGER *version; + GENERAL_NAME *requestorName; + STACK_OF(OCSP_ONEREQ) *requestList; + STACK_OF(X509_EXTENSION) *requestExtensions; +} OCSP_REQINFO; + +/*- Signature ::= SEQUENCE { + * signatureAlgorithm AlgorithmIdentifier, + * signature BIT STRING, + * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL } + */ +typedef struct ocsp_signature_st { + X509_ALGOR *signatureAlgorithm; + ASN1_BIT_STRING *signature; + STACK_OF(X509) *certs; +} OCSP_SIGNATURE; + +/*- OCSPRequest ::= SEQUENCE { + * tbsRequest TBSRequest, + * optionalSignature [0] EXPLICIT Signature OPTIONAL } + */ +typedef struct ocsp_request_st { + OCSP_REQINFO *tbsRequest; + OCSP_SIGNATURE *optionalSignature; /* OPTIONAL */ +} OCSP_REQUEST; + +/*- OCSPResponseStatus ::= ENUMERATED { + * successful (0), --Response has valid confirmations + * malformedRequest (1), --Illegal confirmation request + * internalError (2), --Internal error in issuer + * tryLater (3), --Try again later + * --(4) is not used + * sigRequired (5), --Must sign the request + * unauthorized (6) --Request unauthorized + * } + */ +# define OCSP_RESPONSE_STATUS_SUCCESSFUL 0 +# define OCSP_RESPONSE_STATUS_MALFORMEDREQUEST 1 +# define OCSP_RESPONSE_STATUS_INTERNALERROR 2 +# define OCSP_RESPONSE_STATUS_TRYLATER 3 +# define OCSP_RESPONSE_STATUS_SIGREQUIRED 5 +# define OCSP_RESPONSE_STATUS_UNAUTHORIZED 6 + +/*- ResponseBytes ::= SEQUENCE { + * responseType OBJECT IDENTIFIER, + * response OCTET STRING } + */ +typedef struct ocsp_resp_bytes_st { + ASN1_OBJECT *responseType; + ASN1_OCTET_STRING *response; +} OCSP_RESPBYTES; + +/*- OCSPResponse ::= SEQUENCE { + * responseStatus OCSPResponseStatus, + * responseBytes [0] EXPLICIT ResponseBytes OPTIONAL } + */ +struct ocsp_response_st { + ASN1_ENUMERATED *responseStatus; + OCSP_RESPBYTES *responseBytes; +}; + +/*- ResponderID ::= CHOICE { + * byName [1] Name, + * byKey [2] KeyHash } + */ +# define V_OCSP_RESPID_NAME 0 +# define V_OCSP_RESPID_KEY 1 +struct ocsp_responder_id_st { + int type; + union { + X509_NAME *byName; + ASN1_OCTET_STRING *byKey; + } value; +}; + +DECLARE_STACK_OF(OCSP_RESPID) +DECLARE_ASN1_FUNCTIONS(OCSP_RESPID) + +/*- KeyHash ::= OCTET STRING --SHA-1 hash of responder's public key + * --(excluding the tag and length fields) + */ + +/*- RevokedInfo ::= SEQUENCE { + * revocationTime GeneralizedTime, + * revocationReason [0] EXPLICIT CRLReason OPTIONAL } + */ +typedef struct ocsp_revoked_info_st { + ASN1_GENERALIZEDTIME *revocationTime; + ASN1_ENUMERATED *revocationReason; +} OCSP_REVOKEDINFO; + +/*- CertStatus ::= CHOICE { + * good [0] IMPLICIT NULL, + * revoked [1] IMPLICIT RevokedInfo, + * unknown [2] IMPLICIT UnknownInfo } + */ +# define V_OCSP_CERTSTATUS_GOOD 0 +# define V_OCSP_CERTSTATUS_REVOKED 1 +# define V_OCSP_CERTSTATUS_UNKNOWN 2 +typedef struct ocsp_cert_status_st { + int type; + union { + ASN1_NULL *good; + OCSP_REVOKEDINFO *revoked; + ASN1_NULL *unknown; + } value; +} OCSP_CERTSTATUS; + +/*- SingleResponse ::= SEQUENCE { + * certID CertID, + * certStatus CertStatus, + * thisUpdate GeneralizedTime, + * nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL, + * singleExtensions [1] EXPLICIT Extensions OPTIONAL } + */ +typedef struct ocsp_single_response_st { + OCSP_CERTID *certId; + OCSP_CERTSTATUS *certStatus; + ASN1_GENERALIZEDTIME *thisUpdate; + ASN1_GENERALIZEDTIME *nextUpdate; + STACK_OF(X509_EXTENSION) *singleExtensions; +} OCSP_SINGLERESP; + +DECLARE_STACK_OF(OCSP_SINGLERESP) +DECLARE_ASN1_SET_OF(OCSP_SINGLERESP) + +/*- ResponseData ::= SEQUENCE { + * version [0] EXPLICIT Version DEFAULT v1, + * responderID ResponderID, + * producedAt GeneralizedTime, + * responses SEQUENCE OF SingleResponse, + * responseExtensions [1] EXPLICIT Extensions OPTIONAL } + */ +typedef struct ocsp_response_data_st { + ASN1_INTEGER *version; + OCSP_RESPID *responderId; + ASN1_GENERALIZEDTIME *producedAt; + STACK_OF(OCSP_SINGLERESP) *responses; + STACK_OF(X509_EXTENSION) *responseExtensions; +} OCSP_RESPDATA; + +/*- BasicOCSPResponse ::= SEQUENCE { + * tbsResponseData ResponseData, + * signatureAlgorithm AlgorithmIdentifier, + * signature BIT STRING, + * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL } + */ + /* + * Note 1: The value for "signature" is specified in the OCSP rfc2560 as + * follows: "The value for the signature SHALL be computed on the hash of + * the DER encoding ResponseData." This means that you must hash the + * DER-encoded tbsResponseData, and then run it through a crypto-signing + * function, which will (at least w/RSA) do a hash-'n'-private-encrypt + * operation. This seems a bit odd, but that's the spec. Also note that + * the data structures do not leave anywhere to independently specify the + * algorithm used for the initial hash. So, we look at the + * signature-specification algorithm, and try to do something intelligent. + * -- Kathy Weinhold, CertCo + */ + /* + * Note 2: It seems that the mentioned passage from RFC 2560 (section + * 4.2.1) is open for interpretation. I've done tests against another + * responder, and found that it doesn't do the double hashing that the RFC + * seems to say one should. Therefore, all relevant functions take a flag + * saying which variant should be used. -- Richard Levitte, OpenSSL team + * and CeloCom + */ +typedef struct ocsp_basic_response_st { + OCSP_RESPDATA *tbsResponseData; + X509_ALGOR *signatureAlgorithm; + ASN1_BIT_STRING *signature; + STACK_OF(X509) *certs; +} OCSP_BASICRESP; + +/*- + * CRLReason ::= ENUMERATED { + * unspecified (0), + * keyCompromise (1), + * cACompromise (2), + * affiliationChanged (3), + * superseded (4), + * cessationOfOperation (5), + * certificateHold (6), + * removeFromCRL (8) } + */ +# define OCSP_REVOKED_STATUS_NOSTATUS -1 +# define OCSP_REVOKED_STATUS_UNSPECIFIED 0 +# define OCSP_REVOKED_STATUS_KEYCOMPROMISE 1 +# define OCSP_REVOKED_STATUS_CACOMPROMISE 2 +# define OCSP_REVOKED_STATUS_AFFILIATIONCHANGED 3 +# define OCSP_REVOKED_STATUS_SUPERSEDED 4 +# define OCSP_REVOKED_STATUS_CESSATIONOFOPERATION 5 +# define OCSP_REVOKED_STATUS_CERTIFICATEHOLD 6 +# define OCSP_REVOKED_STATUS_REMOVEFROMCRL 8 + +/*- + * CrlID ::= SEQUENCE { + * crlUrl [0] EXPLICIT IA5String OPTIONAL, + * crlNum [1] EXPLICIT INTEGER OPTIONAL, + * crlTime [2] EXPLICIT GeneralizedTime OPTIONAL } + */ +typedef struct ocsp_crl_id_st { + ASN1_IA5STRING *crlUrl; + ASN1_INTEGER *crlNum; + ASN1_GENERALIZEDTIME *crlTime; +} OCSP_CRLID; + +/*- + * ServiceLocator ::= SEQUENCE { + * issuer Name, + * locator AuthorityInfoAccessSyntax OPTIONAL } + */ +typedef struct ocsp_service_locator_st { + X509_NAME *issuer; + STACK_OF(ACCESS_DESCRIPTION) *locator; +} OCSP_SERVICELOC; + +# define PEM_STRING_OCSP_REQUEST "OCSP REQUEST" +# define PEM_STRING_OCSP_RESPONSE "OCSP RESPONSE" + +# define d2i_OCSP_REQUEST_bio(bp,p) ASN1_d2i_bio_of(OCSP_REQUEST,OCSP_REQUEST_new,d2i_OCSP_REQUEST,bp,p) + +# define d2i_OCSP_RESPONSE_bio(bp,p) ASN1_d2i_bio_of(OCSP_RESPONSE,OCSP_RESPONSE_new,d2i_OCSP_RESPONSE,bp,p) + +# define PEM_read_bio_OCSP_REQUEST(bp,x,cb) (OCSP_REQUEST *)PEM_ASN1_read_bio( \ + (char *(*)())d2i_OCSP_REQUEST,PEM_STRING_OCSP_REQUEST,bp,(char **)x,cb,NULL) + +# define PEM_read_bio_OCSP_RESPONSE(bp,x,cb)(OCSP_RESPONSE *)PEM_ASN1_read_bio(\ + (char *(*)())d2i_OCSP_RESPONSE,PEM_STRING_OCSP_RESPONSE,bp,(char **)x,cb,NULL) + +# define PEM_write_bio_OCSP_REQUEST(bp,o) \ + PEM_ASN1_write_bio((int (*)())i2d_OCSP_REQUEST,PEM_STRING_OCSP_REQUEST,\ + bp,(char *)o, NULL,NULL,0,NULL,NULL) + +# define PEM_write_bio_OCSP_RESPONSE(bp,o) \ + PEM_ASN1_write_bio((int (*)())i2d_OCSP_RESPONSE,PEM_STRING_OCSP_RESPONSE,\ + bp,(char *)o, NULL,NULL,0,NULL,NULL) + +# define i2d_OCSP_RESPONSE_bio(bp,o) ASN1_i2d_bio_of(OCSP_RESPONSE,i2d_OCSP_RESPONSE,bp,o) + +# define i2d_OCSP_REQUEST_bio(bp,o) ASN1_i2d_bio_of(OCSP_REQUEST,i2d_OCSP_REQUEST,bp,o) + +# define OCSP_REQUEST_sign(o,pkey,md) \ + ASN1_item_sign(ASN1_ITEM_rptr(OCSP_REQINFO),\ + o->optionalSignature->signatureAlgorithm,NULL,\ + o->optionalSignature->signature,o->tbsRequest,pkey,md) + +# define OCSP_BASICRESP_sign(o,pkey,md,d) \ + ASN1_item_sign(ASN1_ITEM_rptr(OCSP_RESPDATA),o->signatureAlgorithm,NULL,\ + o->signature,o->tbsResponseData,pkey,md) + +# define OCSP_REQUEST_verify(a,r) ASN1_item_verify(ASN1_ITEM_rptr(OCSP_REQINFO),\ + a->optionalSignature->signatureAlgorithm,\ + a->optionalSignature->signature,a->tbsRequest,r) + +# define OCSP_BASICRESP_verify(a,r,d) ASN1_item_verify(ASN1_ITEM_rptr(OCSP_RESPDATA),\ + a->signatureAlgorithm,a->signature,a->tbsResponseData,r) + +# define ASN1_BIT_STRING_digest(data,type,md,len) \ + ASN1_item_digest(ASN1_ITEM_rptr(ASN1_BIT_STRING),type,data,md,len) + +# define OCSP_CERTSTATUS_dup(cs)\ + (OCSP_CERTSTATUS*)ASN1_dup((int(*)())i2d_OCSP_CERTSTATUS,\ + (char *(*)())d2i_OCSP_CERTSTATUS,(char *)(cs)) + +OCSP_CERTID *OCSP_CERTID_dup(OCSP_CERTID *id); + +OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, const char *path, OCSP_REQUEST *req); +OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, const char *path, OCSP_REQUEST *req, + int maxline); +int OCSP_REQ_CTX_nbio(OCSP_REQ_CTX *rctx); +int OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx); +OCSP_REQ_CTX *OCSP_REQ_CTX_new(BIO *io, int maxline); +void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx); +void OCSP_set_max_response_length(OCSP_REQ_CTX *rctx, unsigned long len); +int OCSP_REQ_CTX_i2d(OCSP_REQ_CTX *rctx, const ASN1_ITEM *it, + ASN1_VALUE *val); +int OCSP_REQ_CTX_nbio_d2i(OCSP_REQ_CTX *rctx, ASN1_VALUE **pval, + const ASN1_ITEM *it); +BIO *OCSP_REQ_CTX_get0_mem_bio(OCSP_REQ_CTX *rctx); +int OCSP_REQ_CTX_i2d(OCSP_REQ_CTX *rctx, const ASN1_ITEM *it, + ASN1_VALUE *val); +int OCSP_REQ_CTX_http(OCSP_REQ_CTX *rctx, const char *op, const char *path); +int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req); +int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx, + const char *name, const char *value); + +OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, X509 *subject, X509 *issuer); + +OCSP_CERTID *OCSP_cert_id_new(const EVP_MD *dgst, + X509_NAME *issuerName, + ASN1_BIT_STRING *issuerKey, + ASN1_INTEGER *serialNumber); + +OCSP_ONEREQ *OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid); + +int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len); +int OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len); +int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs); +int OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req); + +int OCSP_request_set1_name(OCSP_REQUEST *req, X509_NAME *nm); +int OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert); + +int OCSP_request_sign(OCSP_REQUEST *req, + X509 *signer, + EVP_PKEY *key, + const EVP_MD *dgst, + STACK_OF(X509) *certs, unsigned long flags); + +int OCSP_response_status(OCSP_RESPONSE *resp); +OCSP_BASICRESP *OCSP_response_get1_basic(OCSP_RESPONSE *resp); + +int OCSP_resp_count(OCSP_BASICRESP *bs); +OCSP_SINGLERESP *OCSP_resp_get0(OCSP_BASICRESP *bs, int idx); +int OCSP_resp_find(OCSP_BASICRESP *bs, OCSP_CERTID *id, int last); +int OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason, + ASN1_GENERALIZEDTIME **revtime, + ASN1_GENERALIZEDTIME **thisupd, + ASN1_GENERALIZEDTIME **nextupd); +int OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status, + int *reason, + ASN1_GENERALIZEDTIME **revtime, + ASN1_GENERALIZEDTIME **thisupd, + ASN1_GENERALIZEDTIME **nextupd); +int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd, + ASN1_GENERALIZEDTIME *nextupd, long sec, long maxsec); + +int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs, + X509_STORE *store, unsigned long flags); + +int OCSP_parse_url(const char *url, char **phost, char **pport, char **ppath, + int *pssl); + +int OCSP_id_issuer_cmp(OCSP_CERTID *a, OCSP_CERTID *b); +int OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b); + +int OCSP_request_onereq_count(OCSP_REQUEST *req); +OCSP_ONEREQ *OCSP_request_onereq_get0(OCSP_REQUEST *req, int i); +OCSP_CERTID *OCSP_onereq_get0_id(OCSP_ONEREQ *one); +int OCSP_id_get0_info(ASN1_OCTET_STRING **piNameHash, ASN1_OBJECT **pmd, + ASN1_OCTET_STRING **pikeyHash, + ASN1_INTEGER **pserial, OCSP_CERTID *cid); +int OCSP_request_is_signed(OCSP_REQUEST *req); +OCSP_RESPONSE *OCSP_response_create(int status, OCSP_BASICRESP *bs); +OCSP_SINGLERESP *OCSP_basic_add1_status(OCSP_BASICRESP *rsp, + OCSP_CERTID *cid, + int status, int reason, + ASN1_TIME *revtime, + ASN1_TIME *thisupd, + ASN1_TIME *nextupd); +int OCSP_basic_add1_cert(OCSP_BASICRESP *resp, X509 *cert); +int OCSP_basic_sign(OCSP_BASICRESP *brsp, + X509 *signer, EVP_PKEY *key, const EVP_MD *dgst, + STACK_OF(X509) *certs, unsigned long flags); + +X509_EXTENSION *OCSP_crlID_new(char *url, long *n, char *tim); + +X509_EXTENSION *OCSP_accept_responses_new(char **oids); + +X509_EXTENSION *OCSP_archive_cutoff_new(char *tim); + +X509_EXTENSION *OCSP_url_svcloc_new(X509_NAME *issuer, char **urls); + +int OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x); +int OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos); +int OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, ASN1_OBJECT *obj, + int lastpos); +int OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, int lastpos); +X509_EXTENSION *OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc); +X509_EXTENSION *OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc); +void *OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit, + int *idx); +int OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, int crit, + unsigned long flags); +int OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc); + +int OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x); +int OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos); +int OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, ASN1_OBJECT *obj, int lastpos); +int OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos); +X509_EXTENSION *OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc); +X509_EXTENSION *OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc); +void *OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx); +int OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit, + unsigned long flags); +int OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc); + +int OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x); +int OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos); +int OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, ASN1_OBJECT *obj, + int lastpos); +int OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit, + int lastpos); +X509_EXTENSION *OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc); +X509_EXTENSION *OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc); +void *OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit, + int *idx); +int OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value, + int crit, unsigned long flags); +int OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc); + +int OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x); +int OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, int lastpos); +int OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, ASN1_OBJECT *obj, + int lastpos); +int OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit, + int lastpos); +X509_EXTENSION *OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc); +X509_EXTENSION *OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc); +void *OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit, + int *idx); +int OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value, + int crit, unsigned long flags); +int OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc); + +DECLARE_ASN1_FUNCTIONS(OCSP_SINGLERESP) +DECLARE_ASN1_FUNCTIONS(OCSP_CERTSTATUS) +DECLARE_ASN1_FUNCTIONS(OCSP_REVOKEDINFO) +DECLARE_ASN1_FUNCTIONS(OCSP_BASICRESP) +DECLARE_ASN1_FUNCTIONS(OCSP_RESPDATA) +DECLARE_ASN1_FUNCTIONS(OCSP_RESPID) +DECLARE_ASN1_FUNCTIONS(OCSP_RESPONSE) +DECLARE_ASN1_FUNCTIONS(OCSP_RESPBYTES) +DECLARE_ASN1_FUNCTIONS(OCSP_ONEREQ) +DECLARE_ASN1_FUNCTIONS(OCSP_CERTID) +DECLARE_ASN1_FUNCTIONS(OCSP_REQUEST) +DECLARE_ASN1_FUNCTIONS(OCSP_SIGNATURE) +DECLARE_ASN1_FUNCTIONS(OCSP_REQINFO) +DECLARE_ASN1_FUNCTIONS(OCSP_CRLID) +DECLARE_ASN1_FUNCTIONS(OCSP_SERVICELOC) + +const char *OCSP_response_status_str(long s); +const char *OCSP_cert_status_str(long s); +const char *OCSP_crl_reason_str(long s); + +int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST *a, unsigned long flags); +int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE *o, unsigned long flags); + +int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, + X509_STORE *st, unsigned long flags); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_OCSP_strings(void); + +/* Error codes for the OCSP functions. */ + +/* Function codes. */ +# define OCSP_F_ASN1_STRING_ENCODE 100 +# define OCSP_F_D2I_OCSP_NONCE 102 +# define OCSP_F_OCSP_BASIC_ADD1_STATUS 103 +# define OCSP_F_OCSP_BASIC_SIGN 104 +# define OCSP_F_OCSP_BASIC_VERIFY 105 +# define OCSP_F_OCSP_CERT_ID_NEW 101 +# define OCSP_F_OCSP_CHECK_DELEGATED 106 +# define OCSP_F_OCSP_CHECK_IDS 107 +# define OCSP_F_OCSP_CHECK_ISSUER 108 +# define OCSP_F_OCSP_CHECK_VALIDITY 115 +# define OCSP_F_OCSP_MATCH_ISSUERID 109 +# define OCSP_F_OCSP_PARSE_URL 114 +# define OCSP_F_OCSP_REQUEST_SIGN 110 +# define OCSP_F_OCSP_REQUEST_VERIFY 116 +# define OCSP_F_OCSP_RESPONSE_GET1_BASIC 111 +# define OCSP_F_OCSP_SENDREQ_BIO 112 +# define OCSP_F_OCSP_SENDREQ_NBIO 117 +# define OCSP_F_PARSE_HTTP_LINE1 118 +# define OCSP_F_REQUEST_VERIFY 113 + +/* Reason codes. */ +# define OCSP_R_BAD_DATA 100 +# define OCSP_R_CERTIFICATE_VERIFY_ERROR 101 +# define OCSP_R_DIGEST_ERR 102 +# define OCSP_R_ERROR_IN_NEXTUPDATE_FIELD 122 +# define OCSP_R_ERROR_IN_THISUPDATE_FIELD 123 +# define OCSP_R_ERROR_PARSING_URL 121 +# define OCSP_R_MISSING_OCSPSIGNING_USAGE 103 +# define OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE 124 +# define OCSP_R_NOT_BASIC_RESPONSE 104 +# define OCSP_R_NO_CERTIFICATES_IN_CHAIN 105 +# define OCSP_R_NO_CONTENT 106 +# define OCSP_R_NO_PUBLIC_KEY 107 +# define OCSP_R_NO_RESPONSE_DATA 108 +# define OCSP_R_NO_REVOKED_TIME 109 +# define OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 110 +# define OCSP_R_REQUEST_NOT_SIGNED 128 +# define OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA 111 +# define OCSP_R_ROOT_CA_NOT_TRUSTED 112 +# define OCSP_R_SERVER_READ_ERROR 113 +# define OCSP_R_SERVER_RESPONSE_ERROR 114 +# define OCSP_R_SERVER_RESPONSE_PARSE_ERROR 115 +# define OCSP_R_SERVER_WRITE_ERROR 116 +# define OCSP_R_SIGNATURE_FAILURE 117 +# define OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND 118 +# define OCSP_R_STATUS_EXPIRED 125 +# define OCSP_R_STATUS_NOT_YET_VALID 126 +# define OCSP_R_STATUS_TOO_OLD 127 +# define OCSP_R_UNKNOWN_MESSAGE_DIGEST 119 +# define OCSP_R_UNKNOWN_NID 120 +# define OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE 129 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/opensslconf.h b/OSlibs/ios/include/openssl/opensslconf.h new file mode 100755 index 000000000..6f0c77d7f --- /dev/null +++ b/OSlibs/ios/include/openssl/opensslconf.h @@ -0,0 +1,277 @@ +/* opensslconf.h */ +/* WARNING: Generated automatically from opensslconf.h.in by Configure. */ + +#ifdef __cplusplus +extern "C" { +#endif +/* OpenSSL was configured with the following options: */ +#ifndef OPENSSL_SYSNAME_iOS +# define OPENSSL_SYSNAME_iOS +#endif +#ifndef OPENSSL_DOING_MAKEDEPEND + + +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 +# define OPENSSL_NO_EC_NISTP_64_GCC_128 +#endif +#ifndef OPENSSL_NO_GMP +# define OPENSSL_NO_GMP +#endif +#ifndef OPENSSL_NO_JPAKE +# define OPENSSL_NO_JPAKE +#endif +#ifndef OPENSSL_NO_KRB5 +# define OPENSSL_NO_KRB5 +#endif +#ifndef OPENSSL_NO_LIBUNBOUND +# define OPENSSL_NO_LIBUNBOUND +#endif +#ifndef OPENSSL_NO_MD2 +# define OPENSSL_NO_MD2 +#endif +#ifndef OPENSSL_NO_RC5 +# define OPENSSL_NO_RC5 +#endif +#ifndef OPENSSL_NO_RFC3779 +# define OPENSSL_NO_RFC3779 +#endif +#ifndef OPENSSL_NO_SCTP +# define OPENSSL_NO_SCTP +#endif +#ifndef OPENSSL_NO_SSL_TRACE +# define OPENSSL_NO_SSL_TRACE +#endif +#ifndef OPENSSL_NO_SSL2 +# define OPENSSL_NO_SSL2 +#endif +#ifndef OPENSSL_NO_STORE +# define OPENSSL_NO_STORE +#endif +#ifndef OPENSSL_NO_UNIT_TEST +# define OPENSSL_NO_UNIT_TEST +#endif +#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS +# define OPENSSL_NO_WEAK_SSL_CIPHERS +#endif + +#endif /* OPENSSL_DOING_MAKEDEPEND */ + +#ifndef OPENSSL_THREADS +# define OPENSSL_THREADS +#endif +#ifndef OPENSSL_NO_ASM +# define OPENSSL_NO_ASM +#endif +#ifndef OPENSSL_NO_DYNAMIC_ENGINE +# define OPENSSL_NO_DYNAMIC_ENGINE +#endif + +/* The OPENSSL_NO_* macros are also defined as NO_* if the application + asks for it. This is a transient feature that is provided for those + who haven't had the time to do the appropriate changes in their + applications. */ +#ifdef OPENSSL_ALGORITHM_DEFINES +# if defined(OPENSSL_NO_EC_NISTP_64_GCC_128) && !defined(NO_EC_NISTP_64_GCC_128) +# define NO_EC_NISTP_64_GCC_128 +# endif +# if defined(OPENSSL_NO_GMP) && !defined(NO_GMP) +# define NO_GMP +# endif +# if defined(OPENSSL_NO_JPAKE) && !defined(NO_JPAKE) +# define NO_JPAKE +# endif +# if defined(OPENSSL_NO_KRB5) && !defined(NO_KRB5) +# define NO_KRB5 +# endif +# if defined(OPENSSL_NO_LIBUNBOUND) && !defined(NO_LIBUNBOUND) +# define NO_LIBUNBOUND +# endif +# if defined(OPENSSL_NO_MD2) && !defined(NO_MD2) +# define NO_MD2 +# endif +# if defined(OPENSSL_NO_RC5) && !defined(NO_RC5) +# define NO_RC5 +# endif +# if defined(OPENSSL_NO_RFC3779) && !defined(NO_RFC3779) +# endif +# if defined(OPENSSL_NO_SSL2) && !defined(NO_SSL2) +# define NO_SSL2 +# endif +# if defined(OPENSSL_NO_STORE) && !defined(NO_STORE) +# define NO_STORE +# endif +# if defined(OPENSSL_NO_UNIT_TEST) && !defined(NO_UNIT_TEST) +# define NO_UNIT_TEST +# endif +# if defined(OPENSSL_NO_WEAK_SSL_CIPHERS) && !defined(NO_WEAK_SSL_CIPHERS) +# define NO_WEAK_SSL_CIPHERS +# endif +#endif + +/* crypto/opensslconf.h.in */ + +/* Generate 80386 code? */ +#undef I386_ONLY + +#if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */ +#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR) +#define ENGINESDIR "/tmp/build_openssl_469/armv7s/lib/engines" +#define OPENSSLDIR "/tmp/build_openssl_469/armv7s/ssl" +#endif +#endif + +#undef OPENSSL_UNISTD +#define OPENSSL_UNISTD + +#undef OPENSSL_EXPORT_VAR_AS_FUNCTION + +#if defined(HEADER_IDEA_H) && !defined(IDEA_INT) +#define IDEA_INT unsigned int +#endif + +#if defined(HEADER_MD2_H) && !defined(MD2_INT) +#define MD2_INT unsigned int +#endif + +#if defined(HEADER_RC2_H) && !defined(RC2_INT) +/* I need to put in a mod for the alpha - eay */ +#define RC2_INT unsigned int +#endif + +#if defined(HEADER_RC4_H) +#if !defined(RC4_INT) +/* using int types make the structure larger but make the code faster + * on most boxes I have tested - up to %20 faster. */ +/* + * I don't know what does "most" mean, but declaring "int" is a must on: + * - Intel P6 because partial register stalls are very expensive; + * - elder Alpha because it lacks byte load/store instructions; + */ +#define RC4_INT unsigned char +#endif +#if !defined(RC4_CHUNK) +/* + * This enables code handling data aligned at natural CPU word + * boundary. See crypto/rc4/rc4_enc.c for further details. + */ +#define RC4_CHUNK unsigned long +#endif +#endif + +#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG) +/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a + * %20 speed up (longs are 8 bytes, int's are 4). */ +#ifndef DES_LONG +#define DES_LONG unsigned long +#endif +#endif + +#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H) +#define CONFIG_HEADER_BN_H +#ifdef __LP64__ +#undef BN_LLONG +#else +#define BN_LLONG +#endif + +/* Should we define BN_DIV2W here? */ + +/* Only one for the following should be defined */ +#ifdef __LP64__ +#define SIXTY_FOUR_BIT_LONG +#undef SIXTY_FOUR_BIT +#undef THIRTY_TWO_BIT +#else +#undef SIXTY_FOUR_BIT_LONG +#undef SIXTY_FOUR_BIT +#define THIRTY_TWO_BIT +#endif +#endif + +#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H) +#define CONFIG_HEADER_RC4_LOCL_H +/* if this is defined data[i] is used instead of *data, this is a %20 + * speedup on x86 */ +#undef RC4_INDEX +#endif + +#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H) +#define CONFIG_HEADER_BF_LOCL_H +#define BF_PTR +#endif /* HEADER_BF_LOCL_H */ + +#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H) +#define CONFIG_HEADER_DES_LOCL_H +#ifndef DES_DEFAULT_OPTIONS +/* the following is tweaked from a config script, that is why it is a + * protected undef/define */ +#ifndef DES_PTR +#undef DES_PTR +#endif + +/* This helps C compiler generate the correct code for multiple functional + * units. It reduces register dependancies at the expense of 2 more + * registers */ +#ifndef DES_RISC1 +#undef DES_RISC1 +#endif + +#ifndef DES_RISC2 +#undef DES_RISC2 +#endif + +#if defined(DES_RISC1) && defined(DES_RISC2) +#error YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!! +#endif + +/* Unroll the inner loop, this sometimes helps, sometimes hinders. + * Very mucy CPU dependant */ +#ifndef DES_UNROLL +#define DES_UNROLL +#endif + +/* These default values were supplied by + * Peter Gutman + * They are only used if nothing else has been defined */ +#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL) +/* Special defines which change the way the code is built depending on the + CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find + even newer MIPS CPU's, but at the moment one size fits all for + optimization options. Older Sparc's work better with only UNROLL, but + there's no way to tell at compile time what it is you're running on */ + +#if defined( __sun ) || defined ( sun ) /* Newer Sparc's */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#elif defined( __ultrix ) /* Older MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined( __osf1__ ) /* Alpha */ +# define DES_PTR +# define DES_RISC2 +#elif defined ( _AIX ) /* RS6000 */ + /* Unknown */ +#elif defined( __hpux ) /* HP-PA */ + /* Unknown */ +#elif defined( __aux ) /* 68K */ + /* Unknown */ +#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */ +# define DES_UNROLL +#elif defined( __sgi ) /* Newer MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined(i386) || defined(__i386__) /* x86 boxes, should be gcc */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#endif /* Systems-specific speed defines */ +#endif + +#endif /* DES_DEFAULT_OPTIONS */ +#endif /* HEADER_DES_LOCL_H */ +#ifdef __cplusplus +} +#endif diff --git a/OSlibs/ios/include/openssl/opensslconf.h.orig b/OSlibs/ios/include/openssl/opensslconf.h.orig new file mode 100755 index 000000000..32e5cefb7 --- /dev/null +++ b/OSlibs/ios/include/openssl/opensslconf.h.orig @@ -0,0 +1,267 @@ +/* opensslconf.h */ +/* WARNING: Generated automatically from opensslconf.h.in by Configure. */ + +#ifdef __cplusplus +extern "C" { +#endif +/* OpenSSL was configured with the following options: */ +#ifndef OPENSSL_SYSNAME_iOS +# define OPENSSL_SYSNAME_iOS +#endif +#ifndef OPENSSL_DOING_MAKEDEPEND + + +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 +# define OPENSSL_NO_EC_NISTP_64_GCC_128 +#endif +#ifndef OPENSSL_NO_GMP +# define OPENSSL_NO_GMP +#endif +#ifndef OPENSSL_NO_JPAKE +# define OPENSSL_NO_JPAKE +#endif +#ifndef OPENSSL_NO_KRB5 +# define OPENSSL_NO_KRB5 +#endif +#ifndef OPENSSL_NO_LIBUNBOUND +# define OPENSSL_NO_LIBUNBOUND +#endif +#ifndef OPENSSL_NO_MD2 +# define OPENSSL_NO_MD2 +#endif +#ifndef OPENSSL_NO_RC5 +# define OPENSSL_NO_RC5 +#endif +#ifndef OPENSSL_NO_RFC3779 +# define OPENSSL_NO_RFC3779 +#endif +#ifndef OPENSSL_NO_SCTP +# define OPENSSL_NO_SCTP +#endif +#ifndef OPENSSL_NO_SSL_TRACE +# define OPENSSL_NO_SSL_TRACE +#endif +#ifndef OPENSSL_NO_SSL2 +# define OPENSSL_NO_SSL2 +#endif +#ifndef OPENSSL_NO_STORE +# define OPENSSL_NO_STORE +#endif +#ifndef OPENSSL_NO_UNIT_TEST +# define OPENSSL_NO_UNIT_TEST +#endif +#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS +# define OPENSSL_NO_WEAK_SSL_CIPHERS +#endif + +#endif /* OPENSSL_DOING_MAKEDEPEND */ + +#ifndef OPENSSL_THREADS +# define OPENSSL_THREADS +#endif +#ifndef OPENSSL_NO_ASM +# define OPENSSL_NO_ASM +#endif +#ifndef OPENSSL_NO_DYNAMIC_ENGINE +# define OPENSSL_NO_DYNAMIC_ENGINE +#endif + +/* The OPENSSL_NO_* macros are also defined as NO_* if the application + asks for it. This is a transient feature that is provided for those + who haven't had the time to do the appropriate changes in their + applications. */ +#ifdef OPENSSL_ALGORITHM_DEFINES +# if defined(OPENSSL_NO_EC_NISTP_64_GCC_128) && !defined(NO_EC_NISTP_64_GCC_128) +# define NO_EC_NISTP_64_GCC_128 +# endif +# if defined(OPENSSL_NO_GMP) && !defined(NO_GMP) +# define NO_GMP +# endif +# if defined(OPENSSL_NO_JPAKE) && !defined(NO_JPAKE) +# define NO_JPAKE +# endif +# if defined(OPENSSL_NO_KRB5) && !defined(NO_KRB5) +# define NO_KRB5 +# endif +# if defined(OPENSSL_NO_LIBUNBOUND) && !defined(NO_LIBUNBOUND) +# define NO_LIBUNBOUND +# endif +# if defined(OPENSSL_NO_MD2) && !defined(NO_MD2) +# define NO_MD2 +# endif +# if defined(OPENSSL_NO_RC5) && !defined(NO_RC5) +# define NO_RC5 +# endif +# if defined(OPENSSL_NO_RFC3779) && !defined(NO_RFC3779) +# endif +# if defined(OPENSSL_NO_SSL2) && !defined(NO_SSL2) +# define NO_SSL2 +# endif +# if defined(OPENSSL_NO_STORE) && !defined(NO_STORE) +# define NO_STORE +# endif +# if defined(OPENSSL_NO_UNIT_TEST) && !defined(NO_UNIT_TEST) +# define NO_UNIT_TEST +# endif +# if defined(OPENSSL_NO_WEAK_SSL_CIPHERS) && !defined(NO_WEAK_SSL_CIPHERS) +# define NO_WEAK_SSL_CIPHERS +# endif +#endif + +/* crypto/opensslconf.h.in */ + +/* Generate 80386 code? */ +#undef I386_ONLY + +#if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */ +#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR) +#define ENGINESDIR "/tmp/build_openssl_469/armv7s/lib/engines" +#define OPENSSLDIR "/tmp/build_openssl_469/armv7s/ssl" +#endif +#endif + +#undef OPENSSL_UNISTD +#define OPENSSL_UNISTD + +#undef OPENSSL_EXPORT_VAR_AS_FUNCTION + +#if defined(HEADER_IDEA_H) && !defined(IDEA_INT) +#define IDEA_INT unsigned int +#endif + +#if defined(HEADER_MD2_H) && !defined(MD2_INT) +#define MD2_INT unsigned int +#endif + +#if defined(HEADER_RC2_H) && !defined(RC2_INT) +/* I need to put in a mod for the alpha - eay */ +#define RC2_INT unsigned int +#endif + +#if defined(HEADER_RC4_H) +#if !defined(RC4_INT) +/* using int types make the structure larger but make the code faster + * on most boxes I have tested - up to %20 faster. */ +/* + * I don't know what does "most" mean, but declaring "int" is a must on: + * - Intel P6 because partial register stalls are very expensive; + * - elder Alpha because it lacks byte load/store instructions; + */ +#define RC4_INT unsigned char +#endif +#if !defined(RC4_CHUNK) +/* + * This enables code handling data aligned at natural CPU word + * boundary. See crypto/rc4/rc4_enc.c for further details. + */ +#define RC4_CHUNK unsigned long +#endif +#endif + +#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG) +/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a + * %20 speed up (longs are 8 bytes, int's are 4). */ +#ifndef DES_LONG +#define DES_LONG unsigned long +#endif +#endif + +#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H) +#define CONFIG_HEADER_BN_H +#define BN_LLONG + +/* Should we define BN_DIV2W here? */ + +/* Only one for the following should be defined */ +#undef SIXTY_FOUR_BIT_LONG +#undef SIXTY_FOUR_BIT +#define THIRTY_TWO_BIT +#endif + +#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H) +#define CONFIG_HEADER_RC4_LOCL_H +/* if this is defined data[i] is used instead of *data, this is a %20 + * speedup on x86 */ +#undef RC4_INDEX +#endif + +#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H) +#define CONFIG_HEADER_BF_LOCL_H +#define BF_PTR +#endif /* HEADER_BF_LOCL_H */ + +#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H) +#define CONFIG_HEADER_DES_LOCL_H +#ifndef DES_DEFAULT_OPTIONS +/* the following is tweaked from a config script, that is why it is a + * protected undef/define */ +#ifndef DES_PTR +#undef DES_PTR +#endif + +/* This helps C compiler generate the correct code for multiple functional + * units. It reduces register dependancies at the expense of 2 more + * registers */ +#ifndef DES_RISC1 +#undef DES_RISC1 +#endif + +#ifndef DES_RISC2 +#undef DES_RISC2 +#endif + +#if defined(DES_RISC1) && defined(DES_RISC2) +#error YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!! +#endif + +/* Unroll the inner loop, this sometimes helps, sometimes hinders. + * Very mucy CPU dependant */ +#ifndef DES_UNROLL +#define DES_UNROLL +#endif + +/* These default values were supplied by + * Peter Gutman + * They are only used if nothing else has been defined */ +#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL) +/* Special defines which change the way the code is built depending on the + CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find + even newer MIPS CPU's, but at the moment one size fits all for + optimization options. Older Sparc's work better with only UNROLL, but + there's no way to tell at compile time what it is you're running on */ + +#if defined( __sun ) || defined ( sun ) /* Newer Sparc's */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#elif defined( __ultrix ) /* Older MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined( __osf1__ ) /* Alpha */ +# define DES_PTR +# define DES_RISC2 +#elif defined ( _AIX ) /* RS6000 */ + /* Unknown */ +#elif defined( __hpux ) /* HP-PA */ + /* Unknown */ +#elif defined( __aux ) /* 68K */ + /* Unknown */ +#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */ +# define DES_UNROLL +#elif defined( __sgi ) /* Newer MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined(i386) || defined(__i386__) /* x86 boxes, should be gcc */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#endif /* Systems-specific speed defines */ +#endif + +#endif /* DES_DEFAULT_OPTIONS */ +#endif /* HEADER_DES_LOCL_H */ +#ifdef __cplusplus +} +#endif diff --git a/OSlibs/ios/include/openssl/opensslv.h b/OSlibs/ios/include/openssl/opensslv.h new file mode 100755 index 000000000..13fe44023 --- /dev/null +++ b/OSlibs/ios/include/openssl/opensslv.h @@ -0,0 +1,97 @@ +#ifndef HEADER_OPENSSLV_H +# define HEADER_OPENSSLV_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*- + * Numeric release version identifier: + * MNNFFPPS: major minor fix patch status + * The status nibble has one of the values 0 for development, 1 to e for betas + * 1 to 14, and f for release. The patch level is exactly that. + * For example: + * 0.9.3-dev 0x00903000 + * 0.9.3-beta1 0x00903001 + * 0.9.3-beta2-dev 0x00903002 + * 0.9.3-beta2 0x00903002 (same as ...beta2-dev) + * 0.9.3 0x0090300f + * 0.9.3a 0x0090301f + * 0.9.4 0x0090400f + * 1.2.3z 0x102031af + * + * For continuity reasons (because 0.9.5 is already out, and is coded + * 0x00905100), between 0.9.5 and 0.9.6 the coding of the patch level + * part is slightly different, by setting the highest bit. This means + * that 0.9.5a looks like this: 0x0090581f. At 0.9.6, we can start + * with 0x0090600S... + * + * (Prior to 0.9.3-dev a different scheme was used: 0.9.2b is 0x0922.) + * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for + * major minor fix final patch/beta) + */ +# define OPENSSL_VERSION_NUMBER 0x1000208fL +# ifdef OPENSSL_FIPS +# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2h-fips 3 May 2016" +# else +# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2h 3 May 2016" +# endif +# define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT + +/*- + * The macros below are to be used for shared library (.so, .dll, ...) + * versioning. That kind of versioning works a bit differently between + * operating systems. The most usual scheme is to set a major and a minor + * number, and have the runtime loader check that the major number is equal + * to what it was at application link time, while the minor number has to + * be greater or equal to what it was at application link time. With this + * scheme, the version number is usually part of the file name, like this: + * + * libcrypto.so.0.9 + * + * Some unixen also make a softlink with the major verson number only: + * + * libcrypto.so.0 + * + * On Tru64 and IRIX 6.x it works a little bit differently. There, the + * shared library version is stored in the file, and is actually a series + * of versions, separated by colons. The rightmost version present in the + * library when linking an application is stored in the application to be + * matched at run time. When the application is run, a check is done to + * see if the library version stored in the application matches any of the + * versions in the version string of the library itself. + * This version string can be constructed in any way, depending on what + * kind of matching is desired. However, to implement the same scheme as + * the one used in the other unixen, all compatible versions, from lowest + * to highest, should be part of the string. Consecutive builds would + * give the following versions strings: + * + * 3.0 + * 3.0:3.1 + * 3.0:3.1:3.2 + * 4.0 + * 4.0:4.1 + * + * Notice how version 4 is completely incompatible with version, and + * therefore give the breach you can see. + * + * There may be other schemes as well that I haven't yet discovered. + * + * So, here's the way it works here: first of all, the library version + * number doesn't need at all to match the overall OpenSSL version. + * However, it's nice and more understandable if it actually does. + * The current library version is stored in the macro SHLIB_VERSION_NUMBER, + * which is just a piece of text in the format "M.m.e" (Major, minor, edit). + * For the sake of Tru64, IRIX, and any other OS that behaves in similar ways, + * we need to keep a history of version numbers, which is done in the + * macro SHLIB_VERSION_HISTORY. The numbers are separated by colons and + * should only keep the versions that are binary compatible with the current. + */ +# define SHLIB_VERSION_HISTORY "" +# define SHLIB_VERSION_NUMBER "1.0.0" + + +#ifdef __cplusplus +} +#endif +#endif /* HEADER_OPENSSLV_H */ diff --git a/OSlibs/ios/include/openssl/ossl_typ.h b/OSlibs/ios/include/openssl/ossl_typ.h new file mode 100755 index 000000000..9144ea2cf --- /dev/null +++ b/OSlibs/ios/include/openssl/ossl_typ.h @@ -0,0 +1,211 @@ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_OPENSSL_TYPES_H +# define HEADER_OPENSSL_TYPES_H + +#ifdef __cplusplus +extern "C" { +#endif + +# include + +# ifdef NO_ASN1_TYPEDEFS +# define ASN1_INTEGER ASN1_STRING +# define ASN1_ENUMERATED ASN1_STRING +# define ASN1_BIT_STRING ASN1_STRING +# define ASN1_OCTET_STRING ASN1_STRING +# define ASN1_PRINTABLESTRING ASN1_STRING +# define ASN1_T61STRING ASN1_STRING +# define ASN1_IA5STRING ASN1_STRING +# define ASN1_UTCTIME ASN1_STRING +# define ASN1_GENERALIZEDTIME ASN1_STRING +# define ASN1_TIME ASN1_STRING +# define ASN1_GENERALSTRING ASN1_STRING +# define ASN1_UNIVERSALSTRING ASN1_STRING +# define ASN1_BMPSTRING ASN1_STRING +# define ASN1_VISIBLESTRING ASN1_STRING +# define ASN1_UTF8STRING ASN1_STRING +# define ASN1_BOOLEAN int +# define ASN1_NULL int +# else +typedef struct asn1_string_st ASN1_INTEGER; +typedef struct asn1_string_st ASN1_ENUMERATED; +typedef struct asn1_string_st ASN1_BIT_STRING; +typedef struct asn1_string_st ASN1_OCTET_STRING; +typedef struct asn1_string_st ASN1_PRINTABLESTRING; +typedef struct asn1_string_st ASN1_T61STRING; +typedef struct asn1_string_st ASN1_IA5STRING; +typedef struct asn1_string_st ASN1_GENERALSTRING; +typedef struct asn1_string_st ASN1_UNIVERSALSTRING; +typedef struct asn1_string_st ASN1_BMPSTRING; +typedef struct asn1_string_st ASN1_UTCTIME; +typedef struct asn1_string_st ASN1_TIME; +typedef struct asn1_string_st ASN1_GENERALIZEDTIME; +typedef struct asn1_string_st ASN1_VISIBLESTRING; +typedef struct asn1_string_st ASN1_UTF8STRING; +typedef struct asn1_string_st ASN1_STRING; +typedef int ASN1_BOOLEAN; +typedef int ASN1_NULL; +# endif + +typedef struct asn1_object_st ASN1_OBJECT; + +typedef struct ASN1_ITEM_st ASN1_ITEM; +typedef struct asn1_pctx_st ASN1_PCTX; + +# ifdef OPENSSL_SYS_WIN32 +# undef X509_NAME +# undef X509_EXTENSIONS +# undef X509_CERT_PAIR +# undef PKCS7_ISSUER_AND_SERIAL +# undef OCSP_REQUEST +# undef OCSP_RESPONSE +# endif + +# ifdef BIGNUM +# undef BIGNUM +# endif +typedef struct bignum_st BIGNUM; +typedef struct bignum_ctx BN_CTX; +typedef struct bn_blinding_st BN_BLINDING; +typedef struct bn_mont_ctx_st BN_MONT_CTX; +typedef struct bn_recp_ctx_st BN_RECP_CTX; +typedef struct bn_gencb_st BN_GENCB; + +typedef struct buf_mem_st BUF_MEM; + +typedef struct evp_cipher_st EVP_CIPHER; +typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX; +typedef struct env_md_st EVP_MD; +typedef struct env_md_ctx_st EVP_MD_CTX; +typedef struct evp_pkey_st EVP_PKEY; + +typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD; + +typedef struct evp_pkey_method_st EVP_PKEY_METHOD; +typedef struct evp_pkey_ctx_st EVP_PKEY_CTX; + +typedef struct dh_st DH; +typedef struct dh_method DH_METHOD; + +typedef struct dsa_st DSA; +typedef struct dsa_method DSA_METHOD; + +typedef struct rsa_st RSA; +typedef struct rsa_meth_st RSA_METHOD; + +typedef struct rand_meth_st RAND_METHOD; + +typedef struct ecdh_method ECDH_METHOD; +typedef struct ecdsa_method ECDSA_METHOD; + +typedef struct x509_st X509; +typedef struct X509_algor_st X509_ALGOR; +typedef struct X509_crl_st X509_CRL; +typedef struct x509_crl_method_st X509_CRL_METHOD; +typedef struct x509_revoked_st X509_REVOKED; +typedef struct X509_name_st X509_NAME; +typedef struct X509_pubkey_st X509_PUBKEY; +typedef struct x509_store_st X509_STORE; +typedef struct x509_store_ctx_st X509_STORE_CTX; + +typedef struct pkcs8_priv_key_info_st PKCS8_PRIV_KEY_INFO; + +typedef struct v3_ext_ctx X509V3_CTX; +typedef struct conf_st CONF; + +typedef struct store_st STORE; +typedef struct store_method_st STORE_METHOD; + +typedef struct ui_st UI; +typedef struct ui_method_st UI_METHOD; + +typedef struct st_ERR_FNS ERR_FNS; + +typedef struct engine_st ENGINE; +typedef struct ssl_st SSL; +typedef struct ssl_ctx_st SSL_CTX; + +typedef struct X509_POLICY_NODE_st X509_POLICY_NODE; +typedef struct X509_POLICY_LEVEL_st X509_POLICY_LEVEL; +typedef struct X509_POLICY_TREE_st X509_POLICY_TREE; +typedef struct X509_POLICY_CACHE_st X509_POLICY_CACHE; + +typedef struct AUTHORITY_KEYID_st AUTHORITY_KEYID; +typedef struct DIST_POINT_st DIST_POINT; +typedef struct ISSUING_DIST_POINT_st ISSUING_DIST_POINT; +typedef struct NAME_CONSTRAINTS_st NAME_CONSTRAINTS; + + /* If placed in pkcs12.h, we end up with a circular depency with pkcs7.h */ +# define DECLARE_PKCS12_STACK_OF(type)/* Nothing */ +# define IMPLEMENT_PKCS12_STACK_OF(type)/* Nothing */ + +typedef struct crypto_ex_data_st CRYPTO_EX_DATA; +/* Callback types for crypto.h */ +typedef int CRYPTO_EX_new (void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp); +typedef void CRYPTO_EX_free (void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp); +typedef int CRYPTO_EX_dup (CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from, + void *from_d, int idx, long argl, void *argp); + +typedef struct ocsp_req_ctx_st OCSP_REQ_CTX; +typedef struct ocsp_response_st OCSP_RESPONSE; +typedef struct ocsp_responder_id_st OCSP_RESPID; + +#ifdef __cplusplus +} +#endif +#endif /* def HEADER_OPENSSL_TYPES_H */ diff --git a/OSlibs/ios/include/openssl/pem.h b/OSlibs/ios/include/openssl/pem.h new file mode 100755 index 000000000..d3b23fc99 --- /dev/null +++ b/OSlibs/ios/include/openssl/pem.h @@ -0,0 +1,615 @@ +/* crypto/pem/pem.h */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_PEM_H +# define HEADER_PEM_H + +# include +# ifndef OPENSSL_NO_BIO +# include +# endif +# ifndef OPENSSL_NO_STACK +# include +# endif +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# define PEM_BUFSIZE 1024 + +# define PEM_OBJ_UNDEF 0 +# define PEM_OBJ_X509 1 +# define PEM_OBJ_X509_REQ 2 +# define PEM_OBJ_CRL 3 +# define PEM_OBJ_SSL_SESSION 4 +# define PEM_OBJ_PRIV_KEY 10 +# define PEM_OBJ_PRIV_RSA 11 +# define PEM_OBJ_PRIV_DSA 12 +# define PEM_OBJ_PRIV_DH 13 +# define PEM_OBJ_PUB_RSA 14 +# define PEM_OBJ_PUB_DSA 15 +# define PEM_OBJ_PUB_DH 16 +# define PEM_OBJ_DHPARAMS 17 +# define PEM_OBJ_DSAPARAMS 18 +# define PEM_OBJ_PRIV_RSA_PUBLIC 19 +# define PEM_OBJ_PRIV_ECDSA 20 +# define PEM_OBJ_PUB_ECDSA 21 +# define PEM_OBJ_ECPARAMETERS 22 + +# define PEM_ERROR 30 +# define PEM_DEK_DES_CBC 40 +# define PEM_DEK_IDEA_CBC 45 +# define PEM_DEK_DES_EDE 50 +# define PEM_DEK_DES_ECB 60 +# define PEM_DEK_RSA 70 +# define PEM_DEK_RSA_MD2 80 +# define PEM_DEK_RSA_MD5 90 + +# define PEM_MD_MD2 NID_md2 +# define PEM_MD_MD5 NID_md5 +# define PEM_MD_SHA NID_sha +# define PEM_MD_MD2_RSA NID_md2WithRSAEncryption +# define PEM_MD_MD5_RSA NID_md5WithRSAEncryption +# define PEM_MD_SHA_RSA NID_sha1WithRSAEncryption + +# define PEM_STRING_X509_OLD "X509 CERTIFICATE" +# define PEM_STRING_X509 "CERTIFICATE" +# define PEM_STRING_X509_PAIR "CERTIFICATE PAIR" +# define PEM_STRING_X509_TRUSTED "TRUSTED CERTIFICATE" +# define PEM_STRING_X509_REQ_OLD "NEW CERTIFICATE REQUEST" +# define PEM_STRING_X509_REQ "CERTIFICATE REQUEST" +# define PEM_STRING_X509_CRL "X509 CRL" +# define PEM_STRING_EVP_PKEY "ANY PRIVATE KEY" +# define PEM_STRING_PUBLIC "PUBLIC KEY" +# define PEM_STRING_RSA "RSA PRIVATE KEY" +# define PEM_STRING_RSA_PUBLIC "RSA PUBLIC KEY" +# define PEM_STRING_DSA "DSA PRIVATE KEY" +# define PEM_STRING_DSA_PUBLIC "DSA PUBLIC KEY" +# define PEM_STRING_PKCS7 "PKCS7" +# define PEM_STRING_PKCS7_SIGNED "PKCS #7 SIGNED DATA" +# define PEM_STRING_PKCS8 "ENCRYPTED PRIVATE KEY" +# define PEM_STRING_PKCS8INF "PRIVATE KEY" +# define PEM_STRING_DHPARAMS "DH PARAMETERS" +# define PEM_STRING_DHXPARAMS "X9.42 DH PARAMETERS" +# define PEM_STRING_SSL_SESSION "SSL SESSION PARAMETERS" +# define PEM_STRING_DSAPARAMS "DSA PARAMETERS" +# define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY" +# define PEM_STRING_ECPARAMETERS "EC PARAMETERS" +# define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY" +# define PEM_STRING_PARAMETERS "PARAMETERS" +# define PEM_STRING_CMS "CMS" + + /* + * Note that this structure is initialised by PEM_SealInit and cleaned up + * by PEM_SealFinal (at least for now) + */ +typedef struct PEM_Encode_Seal_st { + EVP_ENCODE_CTX encode; + EVP_MD_CTX md; + EVP_CIPHER_CTX cipher; +} PEM_ENCODE_SEAL_CTX; + +/* enc_type is one off */ +# define PEM_TYPE_ENCRYPTED 10 +# define PEM_TYPE_MIC_ONLY 20 +# define PEM_TYPE_MIC_CLEAR 30 +# define PEM_TYPE_CLEAR 40 + +typedef struct pem_recip_st { + char *name; + X509_NAME *dn; + int cipher; + int key_enc; + /* char iv[8]; unused and wrong size */ +} PEM_USER; + +typedef struct pem_ctx_st { + int type; /* what type of object */ + struct { + int version; + int mode; + } proc_type; + + char *domain; + + struct { + int cipher; + /*- + unused, and wrong size + unsigned char iv[8]; */ + } DEK_info; + + PEM_USER *originator; + + int num_recipient; + PEM_USER **recipient; +/*- + XXX(ben): don#t think this is used! + STACK *x509_chain; / * certificate chain */ + EVP_MD *md; /* signature type */ + + int md_enc; /* is the md encrypted or not? */ + int md_len; /* length of md_data */ + char *md_data; /* message digest, could be pkey encrypted */ + + EVP_CIPHER *dec; /* date encryption cipher */ + int key_len; /* key length */ + unsigned char *key; /* key */ + /*- + unused, and wrong size + unsigned char iv[8]; */ + + int data_enc; /* is the data encrypted */ + int data_len; + unsigned char *data; +} PEM_CTX; + +/* + * These macros make the PEM_read/PEM_write functions easier to maintain and + * write. Now they are all implemented with either: IMPLEMENT_PEM_rw(...) or + * IMPLEMENT_PEM_rw_cb(...) + */ + +# ifdef OPENSSL_NO_FP_API + +# define IMPLEMENT_PEM_read_fp(name, type, str, asn1) /**/ +# define IMPLEMENT_PEM_write_fp(name, type, str, asn1) /**/ +# define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) /**/ +# define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) /**/ +# define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) /**/ +# else + +# define IMPLEMENT_PEM_read_fp(name, type, str, asn1) \ +type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u)\ +{ \ +return PEM_ASN1_read((d2i_of_void *)d2i_##asn1, str,fp,(void **)x,cb,u); \ +} + +# define IMPLEMENT_PEM_write_fp(name, type, str, asn1) \ +int PEM_write_##name(FILE *fp, type *x) \ +{ \ +return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,NULL,NULL,0,NULL,NULL); \ +} + +# define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) \ +int PEM_write_##name(FILE *fp, const type *x) \ +{ \ +return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,(void *)x,NULL,NULL,0,NULL,NULL); \ +} + +# define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) \ +int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, \ + void *u) \ + { \ + return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \ + } + +# define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) \ +int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, \ + void *u) \ + { \ + return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \ + } + +# endif + +# define IMPLEMENT_PEM_read_bio(name, type, str, asn1) \ +type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u)\ +{ \ +return PEM_ASN1_read_bio((d2i_of_void *)d2i_##asn1, str,bp,(void **)x,cb,u); \ +} + +# define IMPLEMENT_PEM_write_bio(name, type, str, asn1) \ +int PEM_write_bio_##name(BIO *bp, type *x) \ +{ \ +return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,NULL,NULL,0,NULL,NULL); \ +} + +# define IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \ +int PEM_write_bio_##name(BIO *bp, const type *x) \ +{ \ +return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,NULL,NULL,0,NULL,NULL); \ +} + +# define IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \ +int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \ + { \ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,enc,kstr,klen,cb,u); \ + } + +# define IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \ +int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \ + { \ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,enc,kstr,klen,cb,u); \ + } + +# define IMPLEMENT_PEM_write(name, type, str, asn1) \ + IMPLEMENT_PEM_write_bio(name, type, str, asn1) \ + IMPLEMENT_PEM_write_fp(name, type, str, asn1) + +# define IMPLEMENT_PEM_write_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) + +# define IMPLEMENT_PEM_write_cb(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) + +# define IMPLEMENT_PEM_write_cb_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) + +# define IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_read_bio(name, type, str, asn1) \ + IMPLEMENT_PEM_read_fp(name, type, str, asn1) + +# define IMPLEMENT_PEM_rw(name, type, str, asn1) \ + IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_write(name, type, str, asn1) + +# define IMPLEMENT_PEM_rw_const(name, type, str, asn1) \ + IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_write_const(name, type, str, asn1) + +# define IMPLEMENT_PEM_rw_cb(name, type, str, asn1) \ + IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb(name, type, str, asn1) + +/* These are the same except they are for the declarations */ + +# if defined(OPENSSL_NO_FP_API) + +# define DECLARE_PEM_read_fp(name, type) /**/ +# define DECLARE_PEM_write_fp(name, type) /**/ +# define DECLARE_PEM_write_cb_fp(name, type) /**/ +# else + +# define DECLARE_PEM_read_fp(name, type) \ + type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u); + +# define DECLARE_PEM_write_fp(name, type) \ + int PEM_write_##name(FILE *fp, type *x); + +# define DECLARE_PEM_write_fp_const(name, type) \ + int PEM_write_##name(FILE *fp, const type *x); + +# define DECLARE_PEM_write_cb_fp(name, type) \ + int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u); + +# endif + +# ifndef OPENSSL_NO_BIO +# define DECLARE_PEM_read_bio(name, type) \ + type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u); + +# define DECLARE_PEM_write_bio(name, type) \ + int PEM_write_bio_##name(BIO *bp, type *x); + +# define DECLARE_PEM_write_bio_const(name, type) \ + int PEM_write_bio_##name(BIO *bp, const type *x); + +# define DECLARE_PEM_write_cb_bio(name, type) \ + int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u); + +# else + +# define DECLARE_PEM_read_bio(name, type) /**/ +# define DECLARE_PEM_write_bio(name, type) /**/ +# define DECLARE_PEM_write_bio_const(name, type) /**/ +# define DECLARE_PEM_write_cb_bio(name, type) /**/ +# endif +# define DECLARE_PEM_write(name, type) \ + DECLARE_PEM_write_bio(name, type) \ + DECLARE_PEM_write_fp(name, type) +# define DECLARE_PEM_write_const(name, type) \ + DECLARE_PEM_write_bio_const(name, type) \ + DECLARE_PEM_write_fp_const(name, type) +# define DECLARE_PEM_write_cb(name, type) \ + DECLARE_PEM_write_cb_bio(name, type) \ + DECLARE_PEM_write_cb_fp(name, type) +# define DECLARE_PEM_read(name, type) \ + DECLARE_PEM_read_bio(name, type) \ + DECLARE_PEM_read_fp(name, type) +# define DECLARE_PEM_rw(name, type) \ + DECLARE_PEM_read(name, type) \ + DECLARE_PEM_write(name, type) +# define DECLARE_PEM_rw_const(name, type) \ + DECLARE_PEM_read(name, type) \ + DECLARE_PEM_write_const(name, type) +# define DECLARE_PEM_rw_cb(name, type) \ + DECLARE_PEM_read(name, type) \ + DECLARE_PEM_write_cb(name, type) +# if 1 +/* "userdata": new with OpenSSL 0.9.4 */ +typedef int pem_password_cb (char *buf, int size, int rwflag, void *userdata); +# else +/* OpenSSL 0.9.3, 0.9.3a */ +typedef int pem_password_cb (char *buf, int size, int rwflag); +# endif + +int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher); +int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *len, + pem_password_cb *callback, void *u); + +# ifndef OPENSSL_NO_BIO +int PEM_read_bio(BIO *bp, char **name, char **header, + unsigned char **data, long *len); +int PEM_write_bio(BIO *bp, const char *name, const char *hdr, + const unsigned char *data, long len); +int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, + const char *name, BIO *bp, pem_password_cb *cb, + void *u); +void *PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, void **x, + pem_password_cb *cb, void *u); +int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, void *x, + const EVP_CIPHER *enc, unsigned char *kstr, int klen, + pem_password_cb *cb, void *u); + +STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, + pem_password_cb *cb, void *u); +int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cd, void *u); +# endif + +int PEM_read(FILE *fp, char **name, char **header, + unsigned char **data, long *len); +int PEM_write(FILE *fp, const char *name, const char *hdr, + const unsigned char *data, long len); +void *PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x, + pem_password_cb *cb, void *u); +int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp, + void *x, const EVP_CIPHER *enc, unsigned char *kstr, + int klen, pem_password_cb *callback, void *u); +STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, + pem_password_cb *cb, void *u); + +int PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type, + EVP_MD *md_type, unsigned char **ek, int *ekl, + unsigned char *iv, EVP_PKEY **pubk, int npubk); +void PEM_SealUpdate(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *out, int *outl, + unsigned char *in, int inl); +int PEM_SealFinal(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *sig, int *sigl, + unsigned char *out, int *outl, EVP_PKEY *priv); + +void PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type); +void PEM_SignUpdate(EVP_MD_CTX *ctx, unsigned char *d, unsigned int cnt); +int PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, + unsigned int *siglen, EVP_PKEY *pkey); + +int PEM_def_callback(char *buf, int num, int w, void *key); +void PEM_proc_type(char *buf, int type); +void PEM_dek_info(char *buf, const char *type, int len, char *str); + +# include + +DECLARE_PEM_rw(X509, X509) +DECLARE_PEM_rw(X509_AUX, X509) +DECLARE_PEM_rw(X509_CERT_PAIR, X509_CERT_PAIR) +DECLARE_PEM_rw(X509_REQ, X509_REQ) +DECLARE_PEM_write(X509_REQ_NEW, X509_REQ) +DECLARE_PEM_rw(X509_CRL, X509_CRL) +DECLARE_PEM_rw(PKCS7, PKCS7) +DECLARE_PEM_rw(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE) +DECLARE_PEM_rw(PKCS8, X509_SIG) +DECLARE_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO) +# ifndef OPENSSL_NO_RSA +DECLARE_PEM_rw_cb(RSAPrivateKey, RSA) +DECLARE_PEM_rw_const(RSAPublicKey, RSA) +DECLARE_PEM_rw(RSA_PUBKEY, RSA) +# endif +# ifndef OPENSSL_NO_DSA +DECLARE_PEM_rw_cb(DSAPrivateKey, DSA) +DECLARE_PEM_rw(DSA_PUBKEY, DSA) +DECLARE_PEM_rw_const(DSAparams, DSA) +# endif +# ifndef OPENSSL_NO_EC +DECLARE_PEM_rw_const(ECPKParameters, EC_GROUP) +DECLARE_PEM_rw_cb(ECPrivateKey, EC_KEY) +DECLARE_PEM_rw(EC_PUBKEY, EC_KEY) +# endif +# ifndef OPENSSL_NO_DH +DECLARE_PEM_rw_const(DHparams, DH) +DECLARE_PEM_write_const(DHxparams, DH) +# endif +DECLARE_PEM_rw_cb(PrivateKey, EVP_PKEY) +DECLARE_PEM_rw(PUBKEY, EVP_PKEY) + +int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u); +int PEM_write_bio_PKCS8PrivateKey(BIO *, EVP_PKEY *, const EVP_CIPHER *, + char *, int, pem_password_cb *, void *); +int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, + pem_password_cb *cb, void *u); +int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u); +EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, + void *u); + +int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, + pem_password_cb *cb, void *u); +int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u); +int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u); + +EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, + void *u); + +int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, pem_password_cb *cd, + void *u); + +EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x); +int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x); + +EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length); +EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length); +EVP_PKEY *b2i_PrivateKey_bio(BIO *in); +EVP_PKEY *b2i_PublicKey_bio(BIO *in); +int i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk); +int i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk); +# ifndef OPENSSL_NO_RC4 +EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u); +int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel, + pem_password_cb *cb, void *u); +# endif + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_PEM_strings(void); + +/* Error codes for the PEM functions. */ + +/* Function codes. */ +# define PEM_F_B2I_DSS 127 +# define PEM_F_B2I_PVK_BIO 128 +# define PEM_F_B2I_RSA 129 +# define PEM_F_CHECK_BITLEN_DSA 130 +# define PEM_F_CHECK_BITLEN_RSA 131 +# define PEM_F_D2I_PKCS8PRIVATEKEY_BIO 120 +# define PEM_F_D2I_PKCS8PRIVATEKEY_FP 121 +# define PEM_F_DO_B2I 132 +# define PEM_F_DO_B2I_BIO 133 +# define PEM_F_DO_BLOB_HEADER 134 +# define PEM_F_DO_PK8PKEY 126 +# define PEM_F_DO_PK8PKEY_FP 125 +# define PEM_F_DO_PVK_BODY 135 +# define PEM_F_DO_PVK_HEADER 136 +# define PEM_F_I2B_PVK 137 +# define PEM_F_I2B_PVK_BIO 138 +# define PEM_F_LOAD_IV 101 +# define PEM_F_PEM_ASN1_READ 102 +# define PEM_F_PEM_ASN1_READ_BIO 103 +# define PEM_F_PEM_ASN1_WRITE 104 +# define PEM_F_PEM_ASN1_WRITE_BIO 105 +# define PEM_F_PEM_DEF_CALLBACK 100 +# define PEM_F_PEM_DO_HEADER 106 +# define PEM_F_PEM_F_PEM_WRITE_PKCS8PRIVATEKEY 118 +# define PEM_F_PEM_GET_EVP_CIPHER_INFO 107 +# define PEM_F_PEM_PK8PKEY 119 +# define PEM_F_PEM_READ 108 +# define PEM_F_PEM_READ_BIO 109 +# define PEM_F_PEM_READ_BIO_DHPARAMS 141 +# define PEM_F_PEM_READ_BIO_PARAMETERS 140 +# define PEM_F_PEM_READ_BIO_PRIVATEKEY 123 +# define PEM_F_PEM_READ_DHPARAMS 142 +# define PEM_F_PEM_READ_PRIVATEKEY 124 +# define PEM_F_PEM_SEALFINAL 110 +# define PEM_F_PEM_SEALINIT 111 +# define PEM_F_PEM_SIGNFINAL 112 +# define PEM_F_PEM_WRITE 113 +# define PEM_F_PEM_WRITE_BIO 114 +# define PEM_F_PEM_WRITE_PRIVATEKEY 139 +# define PEM_F_PEM_X509_INFO_READ 115 +# define PEM_F_PEM_X509_INFO_READ_BIO 116 +# define PEM_F_PEM_X509_INFO_WRITE_BIO 117 + +/* Reason codes. */ +# define PEM_R_BAD_BASE64_DECODE 100 +# define PEM_R_BAD_DECRYPT 101 +# define PEM_R_BAD_END_LINE 102 +# define PEM_R_BAD_IV_CHARS 103 +# define PEM_R_BAD_MAGIC_NUMBER 116 +# define PEM_R_BAD_PASSWORD_READ 104 +# define PEM_R_BAD_VERSION_NUMBER 117 +# define PEM_R_BIO_WRITE_FAILURE 118 +# define PEM_R_CIPHER_IS_NULL 127 +# define PEM_R_ERROR_CONVERTING_PRIVATE_KEY 115 +# define PEM_R_EXPECTING_PRIVATE_KEY_BLOB 119 +# define PEM_R_EXPECTING_PUBLIC_KEY_BLOB 120 +# define PEM_R_INCONSISTENT_HEADER 121 +# define PEM_R_KEYBLOB_HEADER_PARSE_ERROR 122 +# define PEM_R_KEYBLOB_TOO_SHORT 123 +# define PEM_R_NOT_DEK_INFO 105 +# define PEM_R_NOT_ENCRYPTED 106 +# define PEM_R_NOT_PROC_TYPE 107 +# define PEM_R_NO_START_LINE 108 +# define PEM_R_PROBLEMS_GETTING_PASSWORD 109 +# define PEM_R_PUBLIC_KEY_NO_RSA 110 +# define PEM_R_PVK_DATA_TOO_SHORT 124 +# define PEM_R_PVK_TOO_SHORT 125 +# define PEM_R_READ_KEY 111 +# define PEM_R_SHORT_HEADER 112 +# define PEM_R_UNSUPPORTED_CIPHER 113 +# define PEM_R_UNSUPPORTED_ENCRYPTION 114 +# define PEM_R_UNSUPPORTED_KEY_COMPONENTS 126 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/pem2.h b/OSlibs/ios/include/openssl/pem2.h new file mode 100755 index 000000000..84897d5ec --- /dev/null +++ b/OSlibs/ios/include/openssl/pem2.h @@ -0,0 +1,70 @@ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * This header only exists to break a circular dependency between pem and err + * Ben 30 Jan 1999. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef HEADER_PEM_H +void ERR_load_PEM_strings(void); +#endif + +#ifdef __cplusplus +} +#endif diff --git a/OSlibs/ios/include/openssl/pkcs12.h b/OSlibs/ios/include/openssl/pkcs12.h new file mode 100755 index 000000000..a39adf5eb --- /dev/null +++ b/OSlibs/ios/include/openssl/pkcs12.h @@ -0,0 +1,342 @@ +/* pkcs12.h */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_PKCS12_H +# define HEADER_PKCS12_H + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# define PKCS12_KEY_ID 1 +# define PKCS12_IV_ID 2 +# define PKCS12_MAC_ID 3 + +/* Default iteration count */ +# ifndef PKCS12_DEFAULT_ITER +# define PKCS12_DEFAULT_ITER PKCS5_DEFAULT_ITER +# endif + +# define PKCS12_MAC_KEY_LENGTH 20 + +# define PKCS12_SALT_LEN 8 + +/* Uncomment out next line for unicode password and names, otherwise ASCII */ + +/* + * #define PBE_UNICODE + */ + +# ifdef PBE_UNICODE +# define PKCS12_key_gen PKCS12_key_gen_uni +# define PKCS12_add_friendlyname PKCS12_add_friendlyname_uni +# else +# define PKCS12_key_gen PKCS12_key_gen_asc +# define PKCS12_add_friendlyname PKCS12_add_friendlyname_asc +# endif + +/* MS key usage constants */ + +# define KEY_EX 0x10 +# define KEY_SIG 0x80 + +typedef struct { + X509_SIG *dinfo; + ASN1_OCTET_STRING *salt; + ASN1_INTEGER *iter; /* defaults to 1 */ +} PKCS12_MAC_DATA; + +typedef struct { + ASN1_INTEGER *version; + PKCS12_MAC_DATA *mac; + PKCS7 *authsafes; +} PKCS12; + +typedef struct { + ASN1_OBJECT *type; + union { + struct pkcs12_bag_st *bag; /* secret, crl and certbag */ + struct pkcs8_priv_key_info_st *keybag; /* keybag */ + X509_SIG *shkeybag; /* shrouded key bag */ + STACK_OF(PKCS12_SAFEBAG) *safes; + ASN1_TYPE *other; + } value; + STACK_OF(X509_ATTRIBUTE) *attrib; +} PKCS12_SAFEBAG; + +DECLARE_STACK_OF(PKCS12_SAFEBAG) +DECLARE_ASN1_SET_OF(PKCS12_SAFEBAG) +DECLARE_PKCS12_STACK_OF(PKCS12_SAFEBAG) + +typedef struct pkcs12_bag_st { + ASN1_OBJECT *type; + union { + ASN1_OCTET_STRING *x509cert; + ASN1_OCTET_STRING *x509crl; + ASN1_OCTET_STRING *octet; + ASN1_IA5STRING *sdsicert; + ASN1_TYPE *other; /* Secret or other bag */ + } value; +} PKCS12_BAGS; + +# define PKCS12_ERROR 0 +# define PKCS12_OK 1 + +/* Compatibility macros */ + +# define M_PKCS12_x5092certbag PKCS12_x5092certbag +# define M_PKCS12_x509crl2certbag PKCS12_x509crl2certbag + +# define M_PKCS12_certbag2x509 PKCS12_certbag2x509 +# define M_PKCS12_certbag2x509crl PKCS12_certbag2x509crl + +# define M_PKCS12_unpack_p7data PKCS12_unpack_p7data +# define M_PKCS12_pack_authsafes PKCS12_pack_authsafes +# define M_PKCS12_unpack_authsafes PKCS12_unpack_authsafes +# define M_PKCS12_unpack_p7encdata PKCS12_unpack_p7encdata + +# define M_PKCS12_decrypt_skey PKCS12_decrypt_skey +# define M_PKCS8_decrypt PKCS8_decrypt + +# define M_PKCS12_bag_type(bg) OBJ_obj2nid((bg)->type) +# define M_PKCS12_cert_bag_type(bg) OBJ_obj2nid((bg)->value.bag->type) +# define M_PKCS12_crl_bag_type M_PKCS12_cert_bag_type + +# define PKCS12_get_attr(bag, attr_nid) \ + PKCS12_get_attr_gen(bag->attrib, attr_nid) + +# define PKCS8_get_attr(p8, attr_nid) \ + PKCS12_get_attr_gen(p8->attributes, attr_nid) + +# define PKCS12_mac_present(p12) ((p12)->mac ? 1 : 0) + +PKCS12_SAFEBAG *PKCS12_x5092certbag(X509 *x509); +PKCS12_SAFEBAG *PKCS12_x509crl2certbag(X509_CRL *crl); +X509 *PKCS12_certbag2x509(PKCS12_SAFEBAG *bag); +X509_CRL *PKCS12_certbag2x509crl(PKCS12_SAFEBAG *bag); + +PKCS12_SAFEBAG *PKCS12_item_pack_safebag(void *obj, const ASN1_ITEM *it, + int nid1, int nid2); +PKCS12_SAFEBAG *PKCS12_MAKE_KEYBAG(PKCS8_PRIV_KEY_INFO *p8); +PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(X509_SIG *p8, const char *pass, + int passlen); +PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(PKCS12_SAFEBAG *bag, + const char *pass, int passlen); +X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, + const char *pass, int passlen, unsigned char *salt, + int saltlen, int iter, PKCS8_PRIV_KEY_INFO *p8); +PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, const char *pass, + int passlen, unsigned char *salt, + int saltlen, int iter, + PKCS8_PRIV_KEY_INFO *p8); +PKCS7 *PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG) *sk); +STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7); +PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen, + unsigned char *salt, int saltlen, int iter, + STACK_OF(PKCS12_SAFEBAG) *bags); +STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass, + int passlen); + +int PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes); +STACK_OF(PKCS7) *PKCS12_unpack_authsafes(PKCS12 *p12); + +int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name, + int namelen); +int PKCS12_add_friendlyname_asc(PKCS12_SAFEBAG *bag, const char *name, + int namelen); +int PKCS12_add_CSPName_asc(PKCS12_SAFEBAG *bag, const char *name, + int namelen); +int PKCS12_add_friendlyname_uni(PKCS12_SAFEBAG *bag, + const unsigned char *name, int namelen); +int PKCS8_add_keyusage(PKCS8_PRIV_KEY_INFO *p8, int usage); +ASN1_TYPE *PKCS12_get_attr_gen(STACK_OF(X509_ATTRIBUTE) *attrs, int attr_nid); +char *PKCS12_get_friendlyname(PKCS12_SAFEBAG *bag); +unsigned char *PKCS12_pbe_crypt(X509_ALGOR *algor, const char *pass, + int passlen, unsigned char *in, int inlen, + unsigned char **data, int *datalen, + int en_de); +void *PKCS12_item_decrypt_d2i(X509_ALGOR *algor, const ASN1_ITEM *it, + const char *pass, int passlen, + ASN1_OCTET_STRING *oct, int zbuf); +ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor, + const ASN1_ITEM *it, + const char *pass, int passlen, + void *obj, int zbuf); +PKCS12 *PKCS12_init(int mode); +int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt, + int saltlen, int id, int iter, int n, + unsigned char *out, const EVP_MD *md_type); +int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt, + int saltlen, int id, int iter, int n, + unsigned char *out, const EVP_MD *md_type); +int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, + const EVP_MD *md_type, int en_de); +int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen, + unsigned char *mac, unsigned int *maclen); +int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen); +int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen, + unsigned char *salt, int saltlen, int iter, + const EVP_MD *md_type); +int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, + int saltlen, const EVP_MD *md_type); +unsigned char *OPENSSL_asc2uni(const char *asc, int asclen, + unsigned char **uni, int *unilen); +char *OPENSSL_uni2asc(unsigned char *uni, int unilen); + +DECLARE_ASN1_FUNCTIONS(PKCS12) +DECLARE_ASN1_FUNCTIONS(PKCS12_MAC_DATA) +DECLARE_ASN1_FUNCTIONS(PKCS12_SAFEBAG) +DECLARE_ASN1_FUNCTIONS(PKCS12_BAGS) + +DECLARE_ASN1_ITEM(PKCS12_SAFEBAGS) +DECLARE_ASN1_ITEM(PKCS12_AUTHSAFES) + +void PKCS12_PBE_add(void); +int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, + STACK_OF(X509) **ca); +PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert, + STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter, + int mac_iter, int keytype); + +PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert); +PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags, + EVP_PKEY *key, int key_usage, int iter, + int key_nid, char *pass); +int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags, + int safe_nid, int iter, char *pass); +PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int p7_nid); + +int i2d_PKCS12_bio(BIO *bp, PKCS12 *p12); +int i2d_PKCS12_fp(FILE *fp, PKCS12 *p12); +PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **p12); +PKCS12 *d2i_PKCS12_fp(FILE *fp, PKCS12 **p12); +int PKCS12_newpass(PKCS12 *p12, char *oldpass, char *newpass); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_PKCS12_strings(void); + +/* Error codes for the PKCS12 functions. */ + +/* Function codes. */ +# define PKCS12_F_PARSE_BAG 129 +# define PKCS12_F_PARSE_BAGS 103 +# define PKCS12_F_PKCS12_ADD_FRIENDLYNAME 100 +# define PKCS12_F_PKCS12_ADD_FRIENDLYNAME_ASC 127 +# define PKCS12_F_PKCS12_ADD_FRIENDLYNAME_UNI 102 +# define PKCS12_F_PKCS12_ADD_LOCALKEYID 104 +# define PKCS12_F_PKCS12_CREATE 105 +# define PKCS12_F_PKCS12_GEN_MAC 107 +# define PKCS12_F_PKCS12_INIT 109 +# define PKCS12_F_PKCS12_ITEM_DECRYPT_D2I 106 +# define PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT 108 +# define PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG 117 +# define PKCS12_F_PKCS12_KEY_GEN_ASC 110 +# define PKCS12_F_PKCS12_KEY_GEN_UNI 111 +# define PKCS12_F_PKCS12_MAKE_KEYBAG 112 +# define PKCS12_F_PKCS12_MAKE_SHKEYBAG 113 +# define PKCS12_F_PKCS12_NEWPASS 128 +# define PKCS12_F_PKCS12_PACK_P7DATA 114 +# define PKCS12_F_PKCS12_PACK_P7ENCDATA 115 +# define PKCS12_F_PKCS12_PARSE 118 +# define PKCS12_F_PKCS12_PBE_CRYPT 119 +# define PKCS12_F_PKCS12_PBE_KEYIVGEN 120 +# define PKCS12_F_PKCS12_SETUP_MAC 122 +# define PKCS12_F_PKCS12_SET_MAC 123 +# define PKCS12_F_PKCS12_UNPACK_AUTHSAFES 130 +# define PKCS12_F_PKCS12_UNPACK_P7DATA 131 +# define PKCS12_F_PKCS12_VERIFY_MAC 126 +# define PKCS12_F_PKCS8_ADD_KEYUSAGE 124 +# define PKCS12_F_PKCS8_ENCRYPT 125 + +/* Reason codes. */ +# define PKCS12_R_CANT_PACK_STRUCTURE 100 +# define PKCS12_R_CONTENT_TYPE_NOT_DATA 121 +# define PKCS12_R_DECODE_ERROR 101 +# define PKCS12_R_ENCODE_ERROR 102 +# define PKCS12_R_ENCRYPT_ERROR 103 +# define PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE 120 +# define PKCS12_R_INVALID_NULL_ARGUMENT 104 +# define PKCS12_R_INVALID_NULL_PKCS12_POINTER 105 +# define PKCS12_R_IV_GEN_ERROR 106 +# define PKCS12_R_KEY_GEN_ERROR 107 +# define PKCS12_R_MAC_ABSENT 108 +# define PKCS12_R_MAC_GENERATION_ERROR 109 +# define PKCS12_R_MAC_SETUP_ERROR 110 +# define PKCS12_R_MAC_STRING_SET_ERROR 111 +# define PKCS12_R_MAC_VERIFY_ERROR 112 +# define PKCS12_R_MAC_VERIFY_FAILURE 113 +# define PKCS12_R_PARSE_ERROR 114 +# define PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR 115 +# define PKCS12_R_PKCS12_CIPHERFINAL_ERROR 116 +# define PKCS12_R_PKCS12_PBE_CRYPT_ERROR 117 +# define PKCS12_R_UNKNOWN_DIGEST_ALGORITHM 118 +# define PKCS12_R_UNSUPPORTED_PKCS12_MODE 119 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/pkcs7.h b/OSlibs/ios/include/openssl/pkcs7.h new file mode 100755 index 000000000..b51b3863e --- /dev/null +++ b/OSlibs/ios/include/openssl/pkcs7.h @@ -0,0 +1,481 @@ +/* crypto/pkcs7/pkcs7.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_PKCS7_H +# define HEADER_PKCS7_H + +# include +# include +# include + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# ifdef OPENSSL_SYS_WIN32 +/* Under Win32 thes are defined in wincrypt.h */ +# undef PKCS7_ISSUER_AND_SERIAL +# undef PKCS7_SIGNER_INFO +# endif + +/*- +Encryption_ID DES-CBC +Digest_ID MD5 +Digest_Encryption_ID rsaEncryption +Key_Encryption_ID rsaEncryption +*/ + +typedef struct pkcs7_issuer_and_serial_st { + X509_NAME *issuer; + ASN1_INTEGER *serial; +} PKCS7_ISSUER_AND_SERIAL; + +typedef struct pkcs7_signer_info_st { + ASN1_INTEGER *version; /* version 1 */ + PKCS7_ISSUER_AND_SERIAL *issuer_and_serial; + X509_ALGOR *digest_alg; + STACK_OF(X509_ATTRIBUTE) *auth_attr; /* [ 0 ] */ + X509_ALGOR *digest_enc_alg; + ASN1_OCTET_STRING *enc_digest; + STACK_OF(X509_ATTRIBUTE) *unauth_attr; /* [ 1 ] */ + /* The private key to sign with */ + EVP_PKEY *pkey; +} PKCS7_SIGNER_INFO; + +DECLARE_STACK_OF(PKCS7_SIGNER_INFO) +DECLARE_ASN1_SET_OF(PKCS7_SIGNER_INFO) + +typedef struct pkcs7_recip_info_st { + ASN1_INTEGER *version; /* version 0 */ + PKCS7_ISSUER_AND_SERIAL *issuer_and_serial; + X509_ALGOR *key_enc_algor; + ASN1_OCTET_STRING *enc_key; + X509 *cert; /* get the pub-key from this */ +} PKCS7_RECIP_INFO; + +DECLARE_STACK_OF(PKCS7_RECIP_INFO) +DECLARE_ASN1_SET_OF(PKCS7_RECIP_INFO) + +typedef struct pkcs7_signed_st { + ASN1_INTEGER *version; /* version 1 */ + STACK_OF(X509_ALGOR) *md_algs; /* md used */ + STACK_OF(X509) *cert; /* [ 0 ] */ + STACK_OF(X509_CRL) *crl; /* [ 1 ] */ + STACK_OF(PKCS7_SIGNER_INFO) *signer_info; + struct pkcs7_st *contents; +} PKCS7_SIGNED; +/* + * The above structure is very very similar to PKCS7_SIGN_ENVELOPE. How about + * merging the two + */ + +typedef struct pkcs7_enc_content_st { + ASN1_OBJECT *content_type; + X509_ALGOR *algorithm; + ASN1_OCTET_STRING *enc_data; /* [ 0 ] */ + const EVP_CIPHER *cipher; +} PKCS7_ENC_CONTENT; + +typedef struct pkcs7_enveloped_st { + ASN1_INTEGER *version; /* version 0 */ + STACK_OF(PKCS7_RECIP_INFO) *recipientinfo; + PKCS7_ENC_CONTENT *enc_data; +} PKCS7_ENVELOPE; + +typedef struct pkcs7_signedandenveloped_st { + ASN1_INTEGER *version; /* version 1 */ + STACK_OF(X509_ALGOR) *md_algs; /* md used */ + STACK_OF(X509) *cert; /* [ 0 ] */ + STACK_OF(X509_CRL) *crl; /* [ 1 ] */ + STACK_OF(PKCS7_SIGNER_INFO) *signer_info; + PKCS7_ENC_CONTENT *enc_data; + STACK_OF(PKCS7_RECIP_INFO) *recipientinfo; +} PKCS7_SIGN_ENVELOPE; + +typedef struct pkcs7_digest_st { + ASN1_INTEGER *version; /* version 0 */ + X509_ALGOR *md; /* md used */ + struct pkcs7_st *contents; + ASN1_OCTET_STRING *digest; +} PKCS7_DIGEST; + +typedef struct pkcs7_encrypted_st { + ASN1_INTEGER *version; /* version 0 */ + PKCS7_ENC_CONTENT *enc_data; +} PKCS7_ENCRYPT; + +typedef struct pkcs7_st { + /* + * The following is non NULL if it contains ASN1 encoding of this + * structure + */ + unsigned char *asn1; + long length; +# define PKCS7_S_HEADER 0 +# define PKCS7_S_BODY 1 +# define PKCS7_S_TAIL 2 + int state; /* used during processing */ + int detached; + ASN1_OBJECT *type; + /* content as defined by the type */ + /* + * all encryption/message digests are applied to the 'contents', leaving + * out the 'type' field. + */ + union { + char *ptr; + /* NID_pkcs7_data */ + ASN1_OCTET_STRING *data; + /* NID_pkcs7_signed */ + PKCS7_SIGNED *sign; + /* NID_pkcs7_enveloped */ + PKCS7_ENVELOPE *enveloped; + /* NID_pkcs7_signedAndEnveloped */ + PKCS7_SIGN_ENVELOPE *signed_and_enveloped; + /* NID_pkcs7_digest */ + PKCS7_DIGEST *digest; + /* NID_pkcs7_encrypted */ + PKCS7_ENCRYPT *encrypted; + /* Anything else */ + ASN1_TYPE *other; + } d; +} PKCS7; + +DECLARE_STACK_OF(PKCS7) +DECLARE_ASN1_SET_OF(PKCS7) +DECLARE_PKCS12_STACK_OF(PKCS7) + +# define PKCS7_OP_SET_DETACHED_SIGNATURE 1 +# define PKCS7_OP_GET_DETACHED_SIGNATURE 2 + +# define PKCS7_get_signed_attributes(si) ((si)->auth_attr) +# define PKCS7_get_attributes(si) ((si)->unauth_attr) + +# define PKCS7_type_is_signed(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_signed) +# define PKCS7_type_is_encrypted(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted) +# define PKCS7_type_is_enveloped(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_enveloped) +# define PKCS7_type_is_signedAndEnveloped(a) \ + (OBJ_obj2nid((a)->type) == NID_pkcs7_signedAndEnveloped) +# define PKCS7_type_is_data(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_data) +# define PKCS7_type_is_digest(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_digest) + +# define PKCS7_set_detached(p,v) \ + PKCS7_ctrl(p,PKCS7_OP_SET_DETACHED_SIGNATURE,v,NULL) +# define PKCS7_get_detached(p) \ + PKCS7_ctrl(p,PKCS7_OP_GET_DETACHED_SIGNATURE,0,NULL) + +# define PKCS7_is_detached(p7) (PKCS7_type_is_signed(p7) && PKCS7_get_detached(p7)) + +/* S/MIME related flags */ + +# define PKCS7_TEXT 0x1 +# define PKCS7_NOCERTS 0x2 +# define PKCS7_NOSIGS 0x4 +# define PKCS7_NOCHAIN 0x8 +# define PKCS7_NOINTERN 0x10 +# define PKCS7_NOVERIFY 0x20 +# define PKCS7_DETACHED 0x40 +# define PKCS7_BINARY 0x80 +# define PKCS7_NOATTR 0x100 +# define PKCS7_NOSMIMECAP 0x200 +# define PKCS7_NOOLDMIMETYPE 0x400 +# define PKCS7_CRLFEOL 0x800 +# define PKCS7_STREAM 0x1000 +# define PKCS7_NOCRL 0x2000 +# define PKCS7_PARTIAL 0x4000 +# define PKCS7_REUSE_DIGEST 0x8000 + +/* Flags: for compatibility with older code */ + +# define SMIME_TEXT PKCS7_TEXT +# define SMIME_NOCERTS PKCS7_NOCERTS +# define SMIME_NOSIGS PKCS7_NOSIGS +# define SMIME_NOCHAIN PKCS7_NOCHAIN +# define SMIME_NOINTERN PKCS7_NOINTERN +# define SMIME_NOVERIFY PKCS7_NOVERIFY +# define SMIME_DETACHED PKCS7_DETACHED +# define SMIME_BINARY PKCS7_BINARY +# define SMIME_NOATTR PKCS7_NOATTR + +DECLARE_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL) + +int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data, + const EVP_MD *type, unsigned char *md, + unsigned int *len); +# ifndef OPENSSL_NO_FP_API +PKCS7 *d2i_PKCS7_fp(FILE *fp, PKCS7 **p7); +int i2d_PKCS7_fp(FILE *fp, PKCS7 *p7); +# endif +PKCS7 *PKCS7_dup(PKCS7 *p7); +PKCS7 *d2i_PKCS7_bio(BIO *bp, PKCS7 **p7); +int i2d_PKCS7_bio(BIO *bp, PKCS7 *p7); +int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *in, int flags); +int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *in, int flags); + +DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNER_INFO) +DECLARE_ASN1_FUNCTIONS(PKCS7_RECIP_INFO) +DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNED) +DECLARE_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT) +DECLARE_ASN1_FUNCTIONS(PKCS7_ENVELOPE) +DECLARE_ASN1_FUNCTIONS(PKCS7_SIGN_ENVELOPE) +DECLARE_ASN1_FUNCTIONS(PKCS7_DIGEST) +DECLARE_ASN1_FUNCTIONS(PKCS7_ENCRYPT) +DECLARE_ASN1_FUNCTIONS(PKCS7) + +DECLARE_ASN1_ITEM(PKCS7_ATTR_SIGN) +DECLARE_ASN1_ITEM(PKCS7_ATTR_VERIFY) + +DECLARE_ASN1_NDEF_FUNCTION(PKCS7) +DECLARE_ASN1_PRINT_FUNCTION(PKCS7) + +long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg); + +int PKCS7_set_type(PKCS7 *p7, int type); +int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other); +int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data); +int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, + const EVP_MD *dgst); +int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si); +int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *p7i); +int PKCS7_add_certificate(PKCS7 *p7, X509 *x509); +int PKCS7_add_crl(PKCS7 *p7, X509_CRL *x509); +int PKCS7_content_new(PKCS7 *p7, int nid); +int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, + BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si); +int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, + X509 *x509); + +BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio); +int PKCS7_dataFinal(PKCS7 *p7, BIO *bio); +BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert); + +PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, + EVP_PKEY *pkey, const EVP_MD *dgst); +X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si); +int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md); +STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7); + +PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509); +void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk, + X509_ALGOR **pdig, X509_ALGOR **psig); +void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc); +int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri); +int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509); +int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher); +int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7); + +PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx); +ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk); +int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int type, + void *data); +int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, + void *value); +ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid); +ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid); +int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si, + STACK_OF(X509_ATTRIBUTE) *sk); +int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, + STACK_OF(X509_ATTRIBUTE) *sk); + +PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, + BIO *data, int flags); + +PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, + X509 *signcert, EVP_PKEY *pkey, + const EVP_MD *md, int flags); + +int PKCS7_final(PKCS7 *p7, BIO *data, int flags); +int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, + BIO *indata, BIO *out, int flags); +STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, + int flags); +PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, + int flags); +int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, + int flags); + +int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si, + STACK_OF(X509_ALGOR) *cap); +STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si); +int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg); + +int PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid); +int PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t); +int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si, + const unsigned char *md, int mdlen); + +int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags); +PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont); + +BIO *BIO_new_PKCS7(BIO *out, PKCS7 *p7); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_PKCS7_strings(void); + +/* Error codes for the PKCS7 functions. */ + +/* Function codes. */ +# define PKCS7_F_B64_READ_PKCS7 120 +# define PKCS7_F_B64_WRITE_PKCS7 121 +# define PKCS7_F_DO_PKCS7_SIGNED_ATTRIB 136 +# define PKCS7_F_I2D_PKCS7_BIO_STREAM 140 +# define PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME 135 +# define PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP 118 +# define PKCS7_F_PKCS7_ADD_CERTIFICATE 100 +# define PKCS7_F_PKCS7_ADD_CRL 101 +# define PKCS7_F_PKCS7_ADD_RECIPIENT_INFO 102 +# define PKCS7_F_PKCS7_ADD_SIGNATURE 131 +# define PKCS7_F_PKCS7_ADD_SIGNER 103 +# define PKCS7_F_PKCS7_BIO_ADD_DIGEST 125 +# define PKCS7_F_PKCS7_COPY_EXISTING_DIGEST 138 +# define PKCS7_F_PKCS7_CTRL 104 +# define PKCS7_F_PKCS7_DATADECODE 112 +# define PKCS7_F_PKCS7_DATAFINAL 128 +# define PKCS7_F_PKCS7_DATAINIT 105 +# define PKCS7_F_PKCS7_DATASIGN 106 +# define PKCS7_F_PKCS7_DATAVERIFY 107 +# define PKCS7_F_PKCS7_DECRYPT 114 +# define PKCS7_F_PKCS7_DECRYPT_RINFO 133 +# define PKCS7_F_PKCS7_ENCODE_RINFO 132 +# define PKCS7_F_PKCS7_ENCRYPT 115 +# define PKCS7_F_PKCS7_FINAL 134 +# define PKCS7_F_PKCS7_FIND_DIGEST 127 +# define PKCS7_F_PKCS7_GET0_SIGNERS 124 +# define PKCS7_F_PKCS7_RECIP_INFO_SET 130 +# define PKCS7_F_PKCS7_SET_CIPHER 108 +# define PKCS7_F_PKCS7_SET_CONTENT 109 +# define PKCS7_F_PKCS7_SET_DIGEST 126 +# define PKCS7_F_PKCS7_SET_TYPE 110 +# define PKCS7_F_PKCS7_SIGN 116 +# define PKCS7_F_PKCS7_SIGNATUREVERIFY 113 +# define PKCS7_F_PKCS7_SIGNER_INFO_SET 129 +# define PKCS7_F_PKCS7_SIGNER_INFO_SIGN 139 +# define PKCS7_F_PKCS7_SIGN_ADD_SIGNER 137 +# define PKCS7_F_PKCS7_SIMPLE_SMIMECAP 119 +# define PKCS7_F_PKCS7_VERIFY 117 +# define PKCS7_F_SMIME_READ_PKCS7 122 +# define PKCS7_F_SMIME_TEXT 123 + +/* Reason codes. */ +# define PKCS7_R_CERTIFICATE_VERIFY_ERROR 117 +# define PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 144 +# define PKCS7_R_CIPHER_NOT_INITIALIZED 116 +# define PKCS7_R_CONTENT_AND_DATA_PRESENT 118 +# define PKCS7_R_CTRL_ERROR 152 +# define PKCS7_R_DECODE_ERROR 130 +# define PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH 100 +# define PKCS7_R_DECRYPT_ERROR 119 +# define PKCS7_R_DIGEST_FAILURE 101 +# define PKCS7_R_ENCRYPTION_CTRL_FAILURE 149 +# define PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 150 +# define PKCS7_R_ERROR_ADDING_RECIPIENT 120 +# define PKCS7_R_ERROR_SETTING_CIPHER 121 +# define PKCS7_R_INVALID_MIME_TYPE 131 +# define PKCS7_R_INVALID_NULL_POINTER 143 +# define PKCS7_R_INVALID_SIGNED_DATA_TYPE 155 +# define PKCS7_R_MIME_NO_CONTENT_TYPE 132 +# define PKCS7_R_MIME_PARSE_ERROR 133 +# define PKCS7_R_MIME_SIG_PARSE_ERROR 134 +# define PKCS7_R_MISSING_CERIPEND_INFO 103 +# define PKCS7_R_NO_CONTENT 122 +# define PKCS7_R_NO_CONTENT_TYPE 135 +# define PKCS7_R_NO_DEFAULT_DIGEST 151 +# define PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND 154 +# define PKCS7_R_NO_MULTIPART_BODY_FAILURE 136 +# define PKCS7_R_NO_MULTIPART_BOUNDARY 137 +# define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE 115 +# define PKCS7_R_NO_RECIPIENT_MATCHES_KEY 146 +# define PKCS7_R_NO_SIGNATURES_ON_DATA 123 +# define PKCS7_R_NO_SIGNERS 142 +# define PKCS7_R_NO_SIG_CONTENT_TYPE 138 +# define PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE 104 +# define PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR 124 +# define PKCS7_R_PKCS7_ADD_SIGNER_ERROR 153 +# define PKCS7_R_PKCS7_DATAFINAL 126 +# define PKCS7_R_PKCS7_DATAFINAL_ERROR 125 +# define PKCS7_R_PKCS7_DATASIGN 145 +# define PKCS7_R_PKCS7_PARSE_ERROR 139 +# define PKCS7_R_PKCS7_SIG_PARSE_ERROR 140 +# define PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 127 +# define PKCS7_R_SIGNATURE_FAILURE 105 +# define PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND 128 +# define PKCS7_R_SIGNING_CTRL_FAILURE 147 +# define PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 148 +# define PKCS7_R_SIG_INVALID_MIME_TYPE 141 +# define PKCS7_R_SMIME_TEXT_ERROR 129 +# define PKCS7_R_UNABLE_TO_FIND_CERTIFICATE 106 +# define PKCS7_R_UNABLE_TO_FIND_MEM_BIO 107 +# define PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST 108 +# define PKCS7_R_UNKNOWN_DIGEST_TYPE 109 +# define PKCS7_R_UNKNOWN_OPERATION 110 +# define PKCS7_R_UNSUPPORTED_CIPHER_TYPE 111 +# define PKCS7_R_UNSUPPORTED_CONTENT_TYPE 112 +# define PKCS7_R_WRONG_CONTENT_TYPE 113 +# define PKCS7_R_WRONG_PKCS7_TYPE 114 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/pqueue.h b/OSlibs/ios/include/openssl/pqueue.h new file mode 100755 index 000000000..d40d9c7d8 --- /dev/null +++ b/OSlibs/ios/include/openssl/pqueue.h @@ -0,0 +1,99 @@ +/* crypto/pqueue/pqueue.h */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_PQUEUE_H +# define HEADER_PQUEUE_H + +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif +typedef struct _pqueue *pqueue; + +typedef struct _pitem { + unsigned char priority[8]; /* 64-bit value in big-endian encoding */ + void *data; + struct _pitem *next; +} pitem; + +typedef struct _pitem *piterator; + +pitem *pitem_new(unsigned char *prio64be, void *data); +void pitem_free(pitem *item); + +pqueue pqueue_new(void); +void pqueue_free(pqueue pq); + +pitem *pqueue_insert(pqueue pq, pitem *item); +pitem *pqueue_peek(pqueue pq); +pitem *pqueue_pop(pqueue pq); +pitem *pqueue_find(pqueue pq, unsigned char *prio64be); +pitem *pqueue_iterator(pqueue pq); +pitem *pqueue_next(piterator *iter); + +void pqueue_print(pqueue pq); +int pqueue_size(pqueue pq); + +#ifdef __cplusplus +} +#endif +#endif /* ! HEADER_PQUEUE_H */ diff --git a/OSlibs/ios/include/openssl/rand.h b/OSlibs/ios/include/openssl/rand.h new file mode 100755 index 000000000..2553afda2 --- /dev/null +++ b/OSlibs/ios/include/openssl/rand.h @@ -0,0 +1,150 @@ +/* crypto/rand/rand.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_RAND_H +# define HEADER_RAND_H + +# include +# include +# include + +# if defined(OPENSSL_SYS_WINDOWS) +# include +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +# if defined(OPENSSL_FIPS) +# define FIPS_RAND_SIZE_T size_t +# endif + +/* Already defined in ossl_typ.h */ +/* typedef struct rand_meth_st RAND_METHOD; */ + +struct rand_meth_st { + void (*seed) (const void *buf, int num); + int (*bytes) (unsigned char *buf, int num); + void (*cleanup) (void); + void (*add) (const void *buf, int num, double entropy); + int (*pseudorand) (unsigned char *buf, int num); + int (*status) (void); +}; + +# ifdef BN_DEBUG +extern int rand_predictable; +# endif + +int RAND_set_rand_method(const RAND_METHOD *meth); +const RAND_METHOD *RAND_get_rand_method(void); +# ifndef OPENSSL_NO_ENGINE +int RAND_set_rand_engine(ENGINE *engine); +# endif +RAND_METHOD *RAND_SSLeay(void); +void RAND_cleanup(void); +int RAND_bytes(unsigned char *buf, int num); +int RAND_pseudo_bytes(unsigned char *buf, int num); +void RAND_seed(const void *buf, int num); +void RAND_add(const void *buf, int num, double entropy); +int RAND_load_file(const char *file, long max_bytes); +int RAND_write_file(const char *file); +const char *RAND_file_name(char *file, size_t num); +int RAND_status(void); +int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes); +int RAND_egd(const char *path); +int RAND_egd_bytes(const char *path, int bytes); +int RAND_poll(void); + +# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) + +void RAND_screen(void); +int RAND_event(UINT, WPARAM, LPARAM); + +# endif + +# ifdef OPENSSL_FIPS +void RAND_set_fips_drbg_type(int type, int flags); +int RAND_init_fips(void); +# endif + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_RAND_strings(void); + +/* Error codes for the RAND functions. */ + +/* Function codes. */ +# define RAND_F_RAND_GET_RAND_METHOD 101 +# define RAND_F_RAND_INIT_FIPS 102 +# define RAND_F_SSLEAY_RAND_BYTES 100 + +/* Reason codes. */ +# define RAND_R_DUAL_EC_DRBG_DISABLED 104 +# define RAND_R_ERROR_INITIALISING_DRBG 102 +# define RAND_R_ERROR_INSTANTIATING_DRBG 103 +# define RAND_R_NO_FIPS_RANDOM_METHOD_SET 101 +# define RAND_R_PRNG_NOT_SEEDED 100 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/rc2.h b/OSlibs/ios/include/openssl/rc2.h new file mode 100755 index 000000000..29d02d732 --- /dev/null +++ b/OSlibs/ios/include/openssl/rc2.h @@ -0,0 +1,103 @@ +/* crypto/rc2/rc2.h */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_RC2_H +# define HEADER_RC2_H + +# include /* OPENSSL_NO_RC2, RC2_INT */ +# ifdef OPENSSL_NO_RC2 +# error RC2 is disabled. +# endif + +# define RC2_ENCRYPT 1 +# define RC2_DECRYPT 0 + +# define RC2_BLOCK 8 +# define RC2_KEY_LENGTH 16 + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct rc2_key_st { + RC2_INT data[64]; +} RC2_KEY; + +# ifdef OPENSSL_FIPS +void private_RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, + int bits); +# endif +void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits); +void RC2_ecb_encrypt(const unsigned char *in, unsigned char *out, + RC2_KEY *key, int enc); +void RC2_encrypt(unsigned long *data, RC2_KEY *key); +void RC2_decrypt(unsigned long *data, RC2_KEY *key); +void RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, + RC2_KEY *ks, unsigned char *iv, int enc); +void RC2_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, RC2_KEY *schedule, unsigned char *ivec, + int *num, int enc); +void RC2_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, RC2_KEY *schedule, unsigned char *ivec, + int *num); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/OSlibs/ios/include/openssl/rc4.h b/OSlibs/ios/include/openssl/rc4.h new file mode 100755 index 000000000..39162b164 --- /dev/null +++ b/OSlibs/ios/include/openssl/rc4.h @@ -0,0 +1,88 @@ +/* crypto/rc4/rc4.h */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_RC4_H +# define HEADER_RC4_H + +# include /* OPENSSL_NO_RC4, RC4_INT */ +# ifdef OPENSSL_NO_RC4 +# error RC4 is disabled. +# endif + +# include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct rc4_key_st { + RC4_INT x, y; + RC4_INT data[256]; +} RC4_KEY; + +const char *RC4_options(void); +void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data); +void private_RC4_set_key(RC4_KEY *key, int len, const unsigned char *data); +void RC4(RC4_KEY *key, size_t len, const unsigned char *indata, + unsigned char *outdata); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/OSlibs/ios/include/openssl/ripemd.h b/OSlibs/ios/include/openssl/ripemd.h new file mode 100755 index 000000000..b88ef25e7 --- /dev/null +++ b/OSlibs/ios/include/openssl/ripemd.h @@ -0,0 +1,105 @@ +/* crypto/ripemd/ripemd.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_RIPEMD_H +# define HEADER_RIPEMD_H + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# ifdef OPENSSL_NO_RIPEMD +# error RIPEMD is disabled. +# endif + +# if defined(__LP32__) +# define RIPEMD160_LONG unsigned long +# elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__) +# define RIPEMD160_LONG unsigned long +# define RIPEMD160_LONG_LOG2 3 +# else +# define RIPEMD160_LONG unsigned int +# endif + +# define RIPEMD160_CBLOCK 64 +# define RIPEMD160_LBLOCK (RIPEMD160_CBLOCK/4) +# define RIPEMD160_DIGEST_LENGTH 20 + +typedef struct RIPEMD160state_st { + RIPEMD160_LONG A, B, C, D, E; + RIPEMD160_LONG Nl, Nh; + RIPEMD160_LONG data[RIPEMD160_LBLOCK]; + unsigned int num; +} RIPEMD160_CTX; + +# ifdef OPENSSL_FIPS +int private_RIPEMD160_Init(RIPEMD160_CTX *c); +# endif +int RIPEMD160_Init(RIPEMD160_CTX *c); +int RIPEMD160_Update(RIPEMD160_CTX *c, const void *data, size_t len); +int RIPEMD160_Final(unsigned char *md, RIPEMD160_CTX *c); +unsigned char *RIPEMD160(const unsigned char *d, size_t n, unsigned char *md); +void RIPEMD160_Transform(RIPEMD160_CTX *c, const unsigned char *b); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/OSlibs/ios/include/openssl/rsa.h b/OSlibs/ios/include/openssl/rsa.h new file mode 100755 index 000000000..d2ee37406 --- /dev/null +++ b/OSlibs/ios/include/openssl/rsa.h @@ -0,0 +1,664 @@ +/* crypto/rsa/rsa.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_RSA_H +# define HEADER_RSA_H + +# include + +# ifndef OPENSSL_NO_BIO +# include +# endif +# include +# include +# ifndef OPENSSL_NO_DEPRECATED +# include +# endif + +# ifdef OPENSSL_NO_RSA +# error RSA is disabled. +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Declared already in ossl_typ.h */ +/* typedef struct rsa_st RSA; */ +/* typedef struct rsa_meth_st RSA_METHOD; */ + +struct rsa_meth_st { + const char *name; + int (*rsa_pub_enc) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); + int (*rsa_pub_dec) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); + int (*rsa_priv_enc) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); + int (*rsa_priv_dec) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); + /* Can be null */ + int (*rsa_mod_exp) (BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx); + /* Can be null */ + int (*bn_mod_exp) (BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); + /* called at new */ + int (*init) (RSA *rsa); + /* called at free */ + int (*finish) (RSA *rsa); + /* RSA_METHOD_FLAG_* things */ + int flags; + /* may be needed! */ + char *app_data; + /* + * New sign and verify functions: some libraries don't allow arbitrary + * data to be signed/verified: this allows them to be used. Note: for + * this to work the RSA_public_decrypt() and RSA_private_encrypt() should + * *NOT* be used RSA_sign(), RSA_verify() should be used instead. Note: + * for backwards compatibility this functionality is only enabled if the + * RSA_FLAG_SIGN_VER option is set in 'flags'. + */ + int (*rsa_sign) (int type, + const unsigned char *m, unsigned int m_length, + unsigned char *sigret, unsigned int *siglen, + const RSA *rsa); + int (*rsa_verify) (int dtype, const unsigned char *m, + unsigned int m_length, const unsigned char *sigbuf, + unsigned int siglen, const RSA *rsa); + /* + * If this callback is NULL, the builtin software RSA key-gen will be + * used. This is for behavioural compatibility whilst the code gets + * rewired, but one day it would be nice to assume there are no such + * things as "builtin software" implementations. + */ + int (*rsa_keygen) (RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb); +}; + +struct rsa_st { + /* + * The first parameter is used to pickup errors where this is passed + * instead of aEVP_PKEY, it is set to 0 + */ + int pad; + long version; + const RSA_METHOD *meth; + /* functional reference if 'meth' is ENGINE-provided */ + ENGINE *engine; + BIGNUM *n; + BIGNUM *e; + BIGNUM *d; + BIGNUM *p; + BIGNUM *q; + BIGNUM *dmp1; + BIGNUM *dmq1; + BIGNUM *iqmp; + /* be careful using this if the RSA structure is shared */ + CRYPTO_EX_DATA ex_data; + int references; + int flags; + /* Used to cache montgomery values */ + BN_MONT_CTX *_method_mod_n; + BN_MONT_CTX *_method_mod_p; + BN_MONT_CTX *_method_mod_q; + /* + * all BIGNUM values are actually in the following data, if it is not + * NULL + */ + char *bignum_data; + BN_BLINDING *blinding; + BN_BLINDING *mt_blinding; +}; + +# ifndef OPENSSL_RSA_MAX_MODULUS_BITS +# define OPENSSL_RSA_MAX_MODULUS_BITS 16384 +# endif + +# ifndef OPENSSL_RSA_SMALL_MODULUS_BITS +# define OPENSSL_RSA_SMALL_MODULUS_BITS 3072 +# endif +# ifndef OPENSSL_RSA_MAX_PUBEXP_BITS + +/* exponent limit enforced for "large" modulus only */ +# define OPENSSL_RSA_MAX_PUBEXP_BITS 64 +# endif + +# define RSA_3 0x3L +# define RSA_F4 0x10001L + +# define RSA_METHOD_FLAG_NO_CHECK 0x0001/* don't check pub/private + * match */ + +# define RSA_FLAG_CACHE_PUBLIC 0x0002 +# define RSA_FLAG_CACHE_PRIVATE 0x0004 +# define RSA_FLAG_BLINDING 0x0008 +# define RSA_FLAG_THREAD_SAFE 0x0010 +/* + * This flag means the private key operations will be handled by rsa_mod_exp + * and that they do not depend on the private key components being present: + * for example a key stored in external hardware. Without this flag + * bn_mod_exp gets called when private key components are absent. + */ +# define RSA_FLAG_EXT_PKEY 0x0020 + +/* + * This flag in the RSA_METHOD enables the new rsa_sign, rsa_verify + * functions. + */ +# define RSA_FLAG_SIGN_VER 0x0040 + +/* + * new with 0.9.6j and 0.9.7b; the built-in + * RSA implementation now uses blinding by + * default (ignoring RSA_FLAG_BLINDING), + * but other engines might not need it + */ +# define RSA_FLAG_NO_BLINDING 0x0080 +/* + * new with 0.9.8f; the built-in RSA + * implementation now uses constant time + * operations by default in private key operations, + * e.g., constant time modular exponentiation, + * modular inverse without leaking branches, + * division without leaking branches. This + * flag disables these constant time + * operations and results in faster RSA + * private key operations. + */ +# define RSA_FLAG_NO_CONSTTIME 0x0100 +# ifdef OPENSSL_USE_DEPRECATED +/* deprecated name for the flag*/ +/* + * new with 0.9.7h; the built-in RSA + * implementation now uses constant time + * modular exponentiation for secret exponents + * by default. This flag causes the + * faster variable sliding window method to + * be used for all exponents. + */ +# define RSA_FLAG_NO_EXP_CONSTTIME RSA_FLAG_NO_CONSTTIME +# endif + +# define EVP_PKEY_CTX_set_rsa_padding(ctx, pad) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_RSA_PADDING, \ + pad, NULL) + +# define EVP_PKEY_CTX_get_rsa_padding(ctx, ppad) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, \ + EVP_PKEY_CTRL_GET_RSA_PADDING, 0, ppad) + +# define EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, len) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \ + (EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), \ + EVP_PKEY_CTRL_RSA_PSS_SALTLEN, \ + len, NULL) + +# define EVP_PKEY_CTX_get_rsa_pss_saltlen(ctx, plen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \ + (EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), \ + EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN, \ + 0, plen) + +# define EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL) + +# define EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, pubexp) + +# define EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \ + EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, \ + EVP_PKEY_CTRL_RSA_MGF1_MD, 0, (void *)md) + +# define EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, \ + EVP_PKEY_CTRL_RSA_OAEP_MD, 0, (void *)md) + +# define EVP_PKEY_CTX_get_rsa_mgf1_md(ctx, pmd) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \ + EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, \ + EVP_PKEY_CTRL_GET_RSA_MGF1_MD, 0, (void *)pmd) + +# define EVP_PKEY_CTX_get_rsa_oaep_md(ctx, pmd) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, \ + EVP_PKEY_CTRL_GET_RSA_OAEP_MD, 0, (void *)pmd) + +# define EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, l, llen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, \ + EVP_PKEY_CTRL_RSA_OAEP_LABEL, llen, (void *)l) + +# define EVP_PKEY_CTX_get0_rsa_oaep_label(ctx, l) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, \ + EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL, 0, (void *)l) + +# define EVP_PKEY_CTRL_RSA_PADDING (EVP_PKEY_ALG_CTRL + 1) +# define EVP_PKEY_CTRL_RSA_PSS_SALTLEN (EVP_PKEY_ALG_CTRL + 2) + +# define EVP_PKEY_CTRL_RSA_KEYGEN_BITS (EVP_PKEY_ALG_CTRL + 3) +# define EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP (EVP_PKEY_ALG_CTRL + 4) +# define EVP_PKEY_CTRL_RSA_MGF1_MD (EVP_PKEY_ALG_CTRL + 5) + +# define EVP_PKEY_CTRL_GET_RSA_PADDING (EVP_PKEY_ALG_CTRL + 6) +# define EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN (EVP_PKEY_ALG_CTRL + 7) +# define EVP_PKEY_CTRL_GET_RSA_MGF1_MD (EVP_PKEY_ALG_CTRL + 8) + +# define EVP_PKEY_CTRL_RSA_OAEP_MD (EVP_PKEY_ALG_CTRL + 9) +# define EVP_PKEY_CTRL_RSA_OAEP_LABEL (EVP_PKEY_ALG_CTRL + 10) + +# define EVP_PKEY_CTRL_GET_RSA_OAEP_MD (EVP_PKEY_ALG_CTRL + 11) +# define EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL (EVP_PKEY_ALG_CTRL + 12) + +# define RSA_PKCS1_PADDING 1 +# define RSA_SSLV23_PADDING 2 +# define RSA_NO_PADDING 3 +# define RSA_PKCS1_OAEP_PADDING 4 +# define RSA_X931_PADDING 5 +/* EVP_PKEY_ only */ +# define RSA_PKCS1_PSS_PADDING 6 + +# define RSA_PKCS1_PADDING_SIZE 11 + +# define RSA_set_app_data(s,arg) RSA_set_ex_data(s,0,arg) +# define RSA_get_app_data(s) RSA_get_ex_data(s,0) + +RSA *RSA_new(void); +RSA *RSA_new_method(ENGINE *engine); +int RSA_size(const RSA *rsa); + +/* Deprecated version */ +# ifndef OPENSSL_NO_DEPRECATED +RSA *RSA_generate_key(int bits, unsigned long e, void + (*callback) (int, int, void *), void *cb_arg); +# endif /* !defined(OPENSSL_NO_DEPRECATED) */ + +/* New version */ +int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb); + +int RSA_check_key(const RSA *); + /* next 4 return -1 on error */ +int RSA_public_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +int RSA_private_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +int RSA_public_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +int RSA_private_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +void RSA_free(RSA *r); +/* "up" the RSA object's reference count */ +int RSA_up_ref(RSA *r); + +int RSA_flags(const RSA *r); + +void RSA_set_default_method(const RSA_METHOD *meth); +const RSA_METHOD *RSA_get_default_method(void); +const RSA_METHOD *RSA_get_method(const RSA *rsa); +int RSA_set_method(RSA *rsa, const RSA_METHOD *meth); + +/* This function needs the memory locking malloc callbacks to be installed */ +int RSA_memory_lock(RSA *r); + +/* these are the actual SSLeay RSA functions */ +const RSA_METHOD *RSA_PKCS1_SSLeay(void); + +const RSA_METHOD *RSA_null_method(void); + +DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPublicKey) +DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPrivateKey) + +typedef struct rsa_pss_params_st { + X509_ALGOR *hashAlgorithm; + X509_ALGOR *maskGenAlgorithm; + ASN1_INTEGER *saltLength; + ASN1_INTEGER *trailerField; +} RSA_PSS_PARAMS; + +DECLARE_ASN1_FUNCTIONS(RSA_PSS_PARAMS) + +typedef struct rsa_oaep_params_st { + X509_ALGOR *hashFunc; + X509_ALGOR *maskGenFunc; + X509_ALGOR *pSourceFunc; +} RSA_OAEP_PARAMS; + +DECLARE_ASN1_FUNCTIONS(RSA_OAEP_PARAMS) + +# ifndef OPENSSL_NO_FP_API +int RSA_print_fp(FILE *fp, const RSA *r, int offset); +# endif + +# ifndef OPENSSL_NO_BIO +int RSA_print(BIO *bp, const RSA *r, int offset); +# endif + +# ifndef OPENSSL_NO_RC4 +int i2d_RSA_NET(const RSA *a, unsigned char **pp, + int (*cb) (char *buf, int len, const char *prompt, + int verify), int sgckey); +RSA *d2i_RSA_NET(RSA **a, const unsigned char **pp, long length, + int (*cb) (char *buf, int len, const char *prompt, + int verify), int sgckey); + +int i2d_Netscape_RSA(const RSA *a, unsigned char **pp, + int (*cb) (char *buf, int len, const char *prompt, + int verify)); +RSA *d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length, + int (*cb) (char *buf, int len, const char *prompt, + int verify)); +# endif + +/* + * The following 2 functions sign and verify a X509_SIG ASN1 object inside + * PKCS#1 padded RSA encryption + */ +int RSA_sign(int type, const unsigned char *m, unsigned int m_length, + unsigned char *sigret, unsigned int *siglen, RSA *rsa); +int RSA_verify(int type, const unsigned char *m, unsigned int m_length, + const unsigned char *sigbuf, unsigned int siglen, RSA *rsa); + +/* + * The following 2 function sign and verify a ASN1_OCTET_STRING object inside + * PKCS#1 padded RSA encryption + */ +int RSA_sign_ASN1_OCTET_STRING(int type, + const unsigned char *m, unsigned int m_length, + unsigned char *sigret, unsigned int *siglen, + RSA *rsa); +int RSA_verify_ASN1_OCTET_STRING(int type, const unsigned char *m, + unsigned int m_length, unsigned char *sigbuf, + unsigned int siglen, RSA *rsa); + +int RSA_blinding_on(RSA *rsa, BN_CTX *ctx); +void RSA_blinding_off(RSA *rsa); +BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *ctx); + +int RSA_padding_add_PKCS1_type_1(unsigned char *to, int tlen, + const unsigned char *f, int fl); +int RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen, + const unsigned char *f, int fl, + int rsa_len); +int RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen, + const unsigned char *f, int fl); +int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen, + const unsigned char *f, int fl, + int rsa_len); +int PKCS1_MGF1(unsigned char *mask, long len, const unsigned char *seed, + long seedlen, const EVP_MD *dgst); +int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen, + const unsigned char *f, int fl, + const unsigned char *p, int pl); +int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen, + const unsigned char *f, int fl, int rsa_len, + const unsigned char *p, int pl); +int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, + const unsigned char *from, int flen, + const unsigned char *param, int plen, + const EVP_MD *md, const EVP_MD *mgf1md); +int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, + const unsigned char *from, int flen, + int num, const unsigned char *param, + int plen, const EVP_MD *md, + const EVP_MD *mgf1md); +int RSA_padding_add_SSLv23(unsigned char *to, int tlen, + const unsigned char *f, int fl); +int RSA_padding_check_SSLv23(unsigned char *to, int tlen, + const unsigned char *f, int fl, int rsa_len); +int RSA_padding_add_none(unsigned char *to, int tlen, const unsigned char *f, + int fl); +int RSA_padding_check_none(unsigned char *to, int tlen, + const unsigned char *f, int fl, int rsa_len); +int RSA_padding_add_X931(unsigned char *to, int tlen, const unsigned char *f, + int fl); +int RSA_padding_check_X931(unsigned char *to, int tlen, + const unsigned char *f, int fl, int rsa_len); +int RSA_X931_hash_id(int nid); + +int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash, + const EVP_MD *Hash, const unsigned char *EM, + int sLen); +int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM, + const unsigned char *mHash, const EVP_MD *Hash, + int sLen); + +int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash, + const EVP_MD *Hash, const EVP_MD *mgf1Hash, + const unsigned char *EM, int sLen); + +int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM, + const unsigned char *mHash, + const EVP_MD *Hash, const EVP_MD *mgf1Hash, + int sLen); + +int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int RSA_set_ex_data(RSA *r, int idx, void *arg); +void *RSA_get_ex_data(const RSA *r, int idx); + +RSA *RSAPublicKey_dup(RSA *rsa); +RSA *RSAPrivateKey_dup(RSA *rsa); + +/* + * If this flag is set the RSA method is FIPS compliant and can be used in + * FIPS mode. This is set in the validated module method. If an application + * sets this flag in its own methods it is its responsibility to ensure the + * result is compliant. + */ + +# define RSA_FLAG_FIPS_METHOD 0x0400 + +/* + * If this flag is set the operations normally disabled in FIPS mode are + * permitted it is then the applications responsibility to ensure that the + * usage is compliant. + */ + +# define RSA_FLAG_NON_FIPS_ALLOW 0x0400 +/* + * Application has decided PRNG is good enough to generate a key: don't + * check. + */ +# define RSA_FLAG_CHECKED 0x0800 + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_RSA_strings(void); + +/* Error codes for the RSA functions. */ + +/* Function codes. */ +# define RSA_F_CHECK_PADDING_MD 140 +# define RSA_F_DO_RSA_PRINT 146 +# define RSA_F_INT_RSA_VERIFY 145 +# define RSA_F_MEMORY_LOCK 100 +# define RSA_F_OLD_RSA_PRIV_DECODE 147 +# define RSA_F_PKEY_RSA_CTRL 143 +# define RSA_F_PKEY_RSA_CTRL_STR 144 +# define RSA_F_PKEY_RSA_SIGN 142 +# define RSA_F_PKEY_RSA_VERIFY 154 +# define RSA_F_PKEY_RSA_VERIFYRECOVER 141 +# define RSA_F_RSA_ALGOR_TO_MD 157 +# define RSA_F_RSA_BUILTIN_KEYGEN 129 +# define RSA_F_RSA_CHECK_KEY 123 +# define RSA_F_RSA_CMS_DECRYPT 158 +# define RSA_F_RSA_EAY_PRIVATE_DECRYPT 101 +# define RSA_F_RSA_EAY_PRIVATE_ENCRYPT 102 +# define RSA_F_RSA_EAY_PUBLIC_DECRYPT 103 +# define RSA_F_RSA_EAY_PUBLIC_ENCRYPT 104 +# define RSA_F_RSA_GENERATE_KEY 105 +# define RSA_F_RSA_GENERATE_KEY_EX 155 +# define RSA_F_RSA_ITEM_VERIFY 156 +# define RSA_F_RSA_MEMORY_LOCK 130 +# define RSA_F_RSA_MGF1_TO_MD 159 +# define RSA_F_RSA_NEW_METHOD 106 +# define RSA_F_RSA_NULL 124 +# define RSA_F_RSA_NULL_MOD_EXP 131 +# define RSA_F_RSA_NULL_PRIVATE_DECRYPT 132 +# define RSA_F_RSA_NULL_PRIVATE_ENCRYPT 133 +# define RSA_F_RSA_NULL_PUBLIC_DECRYPT 134 +# define RSA_F_RSA_NULL_PUBLIC_ENCRYPT 135 +# define RSA_F_RSA_PADDING_ADD_NONE 107 +# define RSA_F_RSA_PADDING_ADD_PKCS1_OAEP 121 +# define RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1 160 +# define RSA_F_RSA_PADDING_ADD_PKCS1_PSS 125 +# define RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1 148 +# define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1 108 +# define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2 109 +# define RSA_F_RSA_PADDING_ADD_SSLV23 110 +# define RSA_F_RSA_PADDING_ADD_X931 127 +# define RSA_F_RSA_PADDING_CHECK_NONE 111 +# define RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP 122 +# define RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1 161 +# define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1 112 +# define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2 113 +# define RSA_F_RSA_PADDING_CHECK_SSLV23 114 +# define RSA_F_RSA_PADDING_CHECK_X931 128 +# define RSA_F_RSA_PRINT 115 +# define RSA_F_RSA_PRINT_FP 116 +# define RSA_F_RSA_PRIVATE_DECRYPT 150 +# define RSA_F_RSA_PRIVATE_ENCRYPT 151 +# define RSA_F_RSA_PRIV_DECODE 137 +# define RSA_F_RSA_PRIV_ENCODE 138 +# define RSA_F_RSA_PSS_TO_CTX 162 +# define RSA_F_RSA_PUBLIC_DECRYPT 152 +# define RSA_F_RSA_PUBLIC_ENCRYPT 153 +# define RSA_F_RSA_PUB_DECODE 139 +# define RSA_F_RSA_SETUP_BLINDING 136 +# define RSA_F_RSA_SIGN 117 +# define RSA_F_RSA_SIGN_ASN1_OCTET_STRING 118 +# define RSA_F_RSA_VERIFY 119 +# define RSA_F_RSA_VERIFY_ASN1_OCTET_STRING 120 +# define RSA_F_RSA_VERIFY_PKCS1_PSS 126 +# define RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1 149 + +/* Reason codes. */ +# define RSA_R_ALGORITHM_MISMATCH 100 +# define RSA_R_BAD_E_VALUE 101 +# define RSA_R_BAD_FIXED_HEADER_DECRYPT 102 +# define RSA_R_BAD_PAD_BYTE_COUNT 103 +# define RSA_R_BAD_SIGNATURE 104 +# define RSA_R_BLOCK_TYPE_IS_NOT_01 106 +# define RSA_R_BLOCK_TYPE_IS_NOT_02 107 +# define RSA_R_DATA_GREATER_THAN_MOD_LEN 108 +# define RSA_R_DATA_TOO_LARGE 109 +# define RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 110 +# define RSA_R_DATA_TOO_LARGE_FOR_MODULUS 132 +# define RSA_R_DATA_TOO_SMALL 111 +# define RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE 122 +# define RSA_R_DIGEST_DOES_NOT_MATCH 166 +# define RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY 112 +# define RSA_R_DMP1_NOT_CONGRUENT_TO_D 124 +# define RSA_R_DMQ1_NOT_CONGRUENT_TO_D 125 +# define RSA_R_D_E_NOT_CONGRUENT_TO_1 123 +# define RSA_R_FIRST_OCTET_INVALID 133 +# define RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE 144 +# define RSA_R_INVALID_DIGEST 160 +# define RSA_R_INVALID_DIGEST_LENGTH 143 +# define RSA_R_INVALID_HEADER 137 +# define RSA_R_INVALID_KEYBITS 145 +# define RSA_R_INVALID_LABEL 161 +# define RSA_R_INVALID_MESSAGE_LENGTH 131 +# define RSA_R_INVALID_MGF1_MD 156 +# define RSA_R_INVALID_OAEP_PARAMETERS 162 +# define RSA_R_INVALID_PADDING 138 +# define RSA_R_INVALID_PADDING_MODE 141 +# define RSA_R_INVALID_PSS_PARAMETERS 149 +# define RSA_R_INVALID_PSS_SALTLEN 146 +# define RSA_R_INVALID_SALT_LENGTH 150 +# define RSA_R_INVALID_TRAILER 139 +# define RSA_R_INVALID_X931_DIGEST 142 +# define RSA_R_IQMP_NOT_INVERSE_OF_Q 126 +# define RSA_R_KEY_SIZE_TOO_SMALL 120 +# define RSA_R_LAST_OCTET_INVALID 134 +# define RSA_R_MODULUS_TOO_LARGE 105 +# define RSA_R_NON_FIPS_RSA_METHOD 157 +# define RSA_R_NO_PUBLIC_EXPONENT 140 +# define RSA_R_NULL_BEFORE_BLOCK_MISSING 113 +# define RSA_R_N_DOES_NOT_EQUAL_P_Q 127 +# define RSA_R_OAEP_DECODING_ERROR 121 +# define RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE 158 +# define RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 148 +# define RSA_R_PADDING_CHECK_FAILED 114 +# define RSA_R_PKCS_DECODING_ERROR 159 +# define RSA_R_P_NOT_PRIME 128 +# define RSA_R_Q_NOT_PRIME 129 +# define RSA_R_RSA_OPERATIONS_NOT_SUPPORTED 130 +# define RSA_R_SLEN_CHECK_FAILED 136 +# define RSA_R_SLEN_RECOVERY_FAILED 135 +# define RSA_R_SSLV3_ROLLBACK_ATTACK 115 +# define RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 116 +# define RSA_R_UNKNOWN_ALGORITHM_TYPE 117 +# define RSA_R_UNKNOWN_DIGEST 163 +# define RSA_R_UNKNOWN_MASK_DIGEST 151 +# define RSA_R_UNKNOWN_PADDING_TYPE 118 +# define RSA_R_UNKNOWN_PSS_DIGEST 152 +# define RSA_R_UNSUPPORTED_ENCRYPTION_TYPE 164 +# define RSA_R_UNSUPPORTED_LABEL_SOURCE 165 +# define RSA_R_UNSUPPORTED_MASK_ALGORITHM 153 +# define RSA_R_UNSUPPORTED_MASK_PARAMETER 154 +# define RSA_R_UNSUPPORTED_SIGNATURE_TYPE 155 +# define RSA_R_VALUE_MISSING 147 +# define RSA_R_WRONG_SIGNATURE_LENGTH 119 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/safestack.h b/OSlibs/ios/include/openssl/safestack.h new file mode 100755 index 000000000..1d4f87eab --- /dev/null +++ b/OSlibs/ios/include/openssl/safestack.h @@ -0,0 +1,2672 @@ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_SAFESTACK_H +# define HEADER_SAFESTACK_H + +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# ifndef CHECKED_PTR_OF +# define CHECKED_PTR_OF(type, p) \ + ((void*) (1 ? p : (type*)0)) +# endif + +/* + * In C++ we get problems because an explicit cast is needed from (void *) we + * use CHECKED_STACK_OF to ensure the correct type is passed in the macros + * below. + */ + +# define CHECKED_STACK_OF(type, p) \ + ((_STACK*) (1 ? p : (STACK_OF(type)*)0)) + +# define CHECKED_SK_COPY_FUNC(type, p) \ + ((void *(*)(void *)) ((1 ? p : (type *(*)(const type *))0))) + +# define CHECKED_SK_FREE_FUNC(type, p) \ + ((void (*)(void *)) ((1 ? p : (void (*)(type *))0))) + +# define CHECKED_SK_CMP_FUNC(type, p) \ + ((int (*)(const void *, const void *)) \ + ((1 ? p : (int (*)(const type * const *, const type * const *))0))) + +# define STACK_OF(type) struct stack_st_##type +# define PREDECLARE_STACK_OF(type) STACK_OF(type); + +# define DECLARE_STACK_OF(type) \ +STACK_OF(type) \ + { \ + _STACK stack; \ + }; +# define DECLARE_SPECIAL_STACK_OF(type, type2) \ +STACK_OF(type) \ + { \ + _STACK stack; \ + }; + +/* nada (obsolete in new safestack approach)*/ +# define IMPLEMENT_STACK_OF(type) + +/*- + * Strings are special: normally an lhash entry will point to a single + * (somewhat) mutable object. In the case of strings: + * + * a) Instead of a single char, there is an array of chars, NUL-terminated. + * b) The string may have be immutable. + * + * So, they need their own declarations. Especially important for + * type-checking tools, such as Deputy. + * + * In practice, however, it appears to be hard to have a const + * string. For now, I'm settling for dealing with the fact it is a + * string at all. + */ +typedef char *OPENSSL_STRING; + +typedef const char *OPENSSL_CSTRING; + +/* + * Confusingly, LHASH_OF(STRING) deals with char ** throughout, but + * STACK_OF(STRING) is really more like STACK_OF(char), only, as mentioned + * above, instead of a single char each entry is a NUL-terminated array of + * chars. So, we have to implement STRING specially for STACK_OF. This is + * dealt with in the autogenerated macros below. + */ + +DECLARE_SPECIAL_STACK_OF(OPENSSL_STRING, char) + +/* + * Similarly, we sometimes use a block of characters, NOT nul-terminated. + * These should also be distinguished from "normal" stacks. + */ +typedef void *OPENSSL_BLOCK; +DECLARE_SPECIAL_STACK_OF(OPENSSL_BLOCK, void) + +/* + * SKM_sk_... stack macros are internal to safestack.h: never use them + * directly, use sk__... instead + */ +# define SKM_sk_new(type, cmp) \ + ((STACK_OF(type) *)sk_new(CHECKED_SK_CMP_FUNC(type, cmp))) +# define SKM_sk_new_null(type) \ + ((STACK_OF(type) *)sk_new_null()) +# define SKM_sk_free(type, st) \ + sk_free(CHECKED_STACK_OF(type, st)) +# define SKM_sk_num(type, st) \ + sk_num(CHECKED_STACK_OF(type, st)) +# define SKM_sk_value(type, st,i) \ + ((type *)sk_value(CHECKED_STACK_OF(type, st), i)) +# define SKM_sk_set(type, st,i,val) \ + sk_set(CHECKED_STACK_OF(type, st), i, CHECKED_PTR_OF(type, val)) +# define SKM_sk_zero(type, st) \ + sk_zero(CHECKED_STACK_OF(type, st)) +# define SKM_sk_push(type, st, val) \ + sk_push(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val)) +# define SKM_sk_unshift(type, st, val) \ + sk_unshift(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val)) +# define SKM_sk_find(type, st, val) \ + sk_find(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val)) +# define SKM_sk_find_ex(type, st, val) \ + sk_find_ex(CHECKED_STACK_OF(type, st), \ + CHECKED_PTR_OF(type, val)) +# define SKM_sk_delete(type, st, i) \ + (type *)sk_delete(CHECKED_STACK_OF(type, st), i) +# define SKM_sk_delete_ptr(type, st, ptr) \ + (type *)sk_delete_ptr(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, ptr)) +# define SKM_sk_insert(type, st,val, i) \ + sk_insert(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val), i) +# define SKM_sk_set_cmp_func(type, st, cmp) \ + ((int (*)(const type * const *,const type * const *)) \ + sk_set_cmp_func(CHECKED_STACK_OF(type, st), CHECKED_SK_CMP_FUNC(type, cmp))) +# define SKM_sk_dup(type, st) \ + (STACK_OF(type) *)sk_dup(CHECKED_STACK_OF(type, st)) +# define SKM_sk_pop_free(type, st, free_func) \ + sk_pop_free(CHECKED_STACK_OF(type, st), CHECKED_SK_FREE_FUNC(type, free_func)) +# define SKM_sk_deep_copy(type, st, copy_func, free_func) \ + (STACK_OF(type) *)sk_deep_copy(CHECKED_STACK_OF(type, st), CHECKED_SK_COPY_FUNC(type, copy_func), CHECKED_SK_FREE_FUNC(type, free_func)) +# define SKM_sk_shift(type, st) \ + (type *)sk_shift(CHECKED_STACK_OF(type, st)) +# define SKM_sk_pop(type, st) \ + (type *)sk_pop(CHECKED_STACK_OF(type, st)) +# define SKM_sk_sort(type, st) \ + sk_sort(CHECKED_STACK_OF(type, st)) +# define SKM_sk_is_sorted(type, st) \ + sk_is_sorted(CHECKED_STACK_OF(type, st)) +# define SKM_ASN1_SET_OF_d2i(type, st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + (STACK_OF(type) *)d2i_ASN1_SET( \ + (STACK_OF(OPENSSL_BLOCK) **)CHECKED_PTR_OF(STACK_OF(type)*, st), \ + pp, length, \ + CHECKED_D2I_OF(type, d2i_func), \ + CHECKED_SK_FREE_FUNC(type, free_func), \ + ex_tag, ex_class) +# define SKM_ASN1_SET_OF_i2d(type, st, pp, i2d_func, ex_tag, ex_class, is_set) \ + i2d_ASN1_SET((STACK_OF(OPENSSL_BLOCK) *)CHECKED_STACK_OF(type, st), pp, \ + CHECKED_I2D_OF(type, i2d_func), \ + ex_tag, ex_class, is_set) +# define SKM_ASN1_seq_pack(type, st, i2d_func, buf, len) \ + ASN1_seq_pack(CHECKED_PTR_OF(STACK_OF(type), st), \ + CHECKED_I2D_OF(type, i2d_func), buf, len) +# define SKM_ASN1_seq_unpack(type, buf, len, d2i_func, free_func) \ + (STACK_OF(type) *)ASN1_seq_unpack(buf, len, CHECKED_D2I_OF(type, d2i_func), CHECKED_SK_FREE_FUNC(type, free_func)) +# define SKM_PKCS12_decrypt_d2i(type, algor, d2i_func, free_func, pass, passlen, oct, seq) \ + (STACK_OF(type) *)PKCS12_decrypt_d2i(algor, \ + CHECKED_D2I_OF(type, d2i_func), \ + CHECKED_SK_FREE_FUNC(type, free_func), \ + pass, passlen, oct, seq) +/* + * This block of defines is updated by util/mkstack.pl, please do not touch! + */ +# define sk_ACCESS_DESCRIPTION_new(cmp) SKM_sk_new(ACCESS_DESCRIPTION, (cmp)) +# define sk_ACCESS_DESCRIPTION_new_null() SKM_sk_new_null(ACCESS_DESCRIPTION) +# define sk_ACCESS_DESCRIPTION_free(st) SKM_sk_free(ACCESS_DESCRIPTION, (st)) +# define sk_ACCESS_DESCRIPTION_num(st) SKM_sk_num(ACCESS_DESCRIPTION, (st)) +# define sk_ACCESS_DESCRIPTION_value(st, i) SKM_sk_value(ACCESS_DESCRIPTION, (st), (i)) +# define sk_ACCESS_DESCRIPTION_set(st, i, val) SKM_sk_set(ACCESS_DESCRIPTION, (st), (i), (val)) +# define sk_ACCESS_DESCRIPTION_zero(st) SKM_sk_zero(ACCESS_DESCRIPTION, (st)) +# define sk_ACCESS_DESCRIPTION_push(st, val) SKM_sk_push(ACCESS_DESCRIPTION, (st), (val)) +# define sk_ACCESS_DESCRIPTION_unshift(st, val) SKM_sk_unshift(ACCESS_DESCRIPTION, (st), (val)) +# define sk_ACCESS_DESCRIPTION_find(st, val) SKM_sk_find(ACCESS_DESCRIPTION, (st), (val)) +# define sk_ACCESS_DESCRIPTION_find_ex(st, val) SKM_sk_find_ex(ACCESS_DESCRIPTION, (st), (val)) +# define sk_ACCESS_DESCRIPTION_delete(st, i) SKM_sk_delete(ACCESS_DESCRIPTION, (st), (i)) +# define sk_ACCESS_DESCRIPTION_delete_ptr(st, ptr) SKM_sk_delete_ptr(ACCESS_DESCRIPTION, (st), (ptr)) +# define sk_ACCESS_DESCRIPTION_insert(st, val, i) SKM_sk_insert(ACCESS_DESCRIPTION, (st), (val), (i)) +# define sk_ACCESS_DESCRIPTION_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ACCESS_DESCRIPTION, (st), (cmp)) +# define sk_ACCESS_DESCRIPTION_dup(st) SKM_sk_dup(ACCESS_DESCRIPTION, st) +# define sk_ACCESS_DESCRIPTION_pop_free(st, free_func) SKM_sk_pop_free(ACCESS_DESCRIPTION, (st), (free_func)) +# define sk_ACCESS_DESCRIPTION_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ACCESS_DESCRIPTION, (st), (copy_func), (free_func)) +# define sk_ACCESS_DESCRIPTION_shift(st) SKM_sk_shift(ACCESS_DESCRIPTION, (st)) +# define sk_ACCESS_DESCRIPTION_pop(st) SKM_sk_pop(ACCESS_DESCRIPTION, (st)) +# define sk_ACCESS_DESCRIPTION_sort(st) SKM_sk_sort(ACCESS_DESCRIPTION, (st)) +# define sk_ACCESS_DESCRIPTION_is_sorted(st) SKM_sk_is_sorted(ACCESS_DESCRIPTION, (st)) +# define sk_ASIdOrRange_new(cmp) SKM_sk_new(ASIdOrRange, (cmp)) +# define sk_ASIdOrRange_new_null() SKM_sk_new_null(ASIdOrRange) +# define sk_ASIdOrRange_free(st) SKM_sk_free(ASIdOrRange, (st)) +# define sk_ASIdOrRange_num(st) SKM_sk_num(ASIdOrRange, (st)) +# define sk_ASIdOrRange_value(st, i) SKM_sk_value(ASIdOrRange, (st), (i)) +# define sk_ASIdOrRange_set(st, i, val) SKM_sk_set(ASIdOrRange, (st), (i), (val)) +# define sk_ASIdOrRange_zero(st) SKM_sk_zero(ASIdOrRange, (st)) +# define sk_ASIdOrRange_push(st, val) SKM_sk_push(ASIdOrRange, (st), (val)) +# define sk_ASIdOrRange_unshift(st, val) SKM_sk_unshift(ASIdOrRange, (st), (val)) +# define sk_ASIdOrRange_find(st, val) SKM_sk_find(ASIdOrRange, (st), (val)) +# define sk_ASIdOrRange_find_ex(st, val) SKM_sk_find_ex(ASIdOrRange, (st), (val)) +# define sk_ASIdOrRange_delete(st, i) SKM_sk_delete(ASIdOrRange, (st), (i)) +# define sk_ASIdOrRange_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASIdOrRange, (st), (ptr)) +# define sk_ASIdOrRange_insert(st, val, i) SKM_sk_insert(ASIdOrRange, (st), (val), (i)) +# define sk_ASIdOrRange_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASIdOrRange, (st), (cmp)) +# define sk_ASIdOrRange_dup(st) SKM_sk_dup(ASIdOrRange, st) +# define sk_ASIdOrRange_pop_free(st, free_func) SKM_sk_pop_free(ASIdOrRange, (st), (free_func)) +# define sk_ASIdOrRange_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASIdOrRange, (st), (copy_func), (free_func)) +# define sk_ASIdOrRange_shift(st) SKM_sk_shift(ASIdOrRange, (st)) +# define sk_ASIdOrRange_pop(st) SKM_sk_pop(ASIdOrRange, (st)) +# define sk_ASIdOrRange_sort(st) SKM_sk_sort(ASIdOrRange, (st)) +# define sk_ASIdOrRange_is_sorted(st) SKM_sk_is_sorted(ASIdOrRange, (st)) +# define sk_ASN1_GENERALSTRING_new(cmp) SKM_sk_new(ASN1_GENERALSTRING, (cmp)) +# define sk_ASN1_GENERALSTRING_new_null() SKM_sk_new_null(ASN1_GENERALSTRING) +# define sk_ASN1_GENERALSTRING_free(st) SKM_sk_free(ASN1_GENERALSTRING, (st)) +# define sk_ASN1_GENERALSTRING_num(st) SKM_sk_num(ASN1_GENERALSTRING, (st)) +# define sk_ASN1_GENERALSTRING_value(st, i) SKM_sk_value(ASN1_GENERALSTRING, (st), (i)) +# define sk_ASN1_GENERALSTRING_set(st, i, val) SKM_sk_set(ASN1_GENERALSTRING, (st), (i), (val)) +# define sk_ASN1_GENERALSTRING_zero(st) SKM_sk_zero(ASN1_GENERALSTRING, (st)) +# define sk_ASN1_GENERALSTRING_push(st, val) SKM_sk_push(ASN1_GENERALSTRING, (st), (val)) +# define sk_ASN1_GENERALSTRING_unshift(st, val) SKM_sk_unshift(ASN1_GENERALSTRING, (st), (val)) +# define sk_ASN1_GENERALSTRING_find(st, val) SKM_sk_find(ASN1_GENERALSTRING, (st), (val)) +# define sk_ASN1_GENERALSTRING_find_ex(st, val) SKM_sk_find_ex(ASN1_GENERALSTRING, (st), (val)) +# define sk_ASN1_GENERALSTRING_delete(st, i) SKM_sk_delete(ASN1_GENERALSTRING, (st), (i)) +# define sk_ASN1_GENERALSTRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_GENERALSTRING, (st), (ptr)) +# define sk_ASN1_GENERALSTRING_insert(st, val, i) SKM_sk_insert(ASN1_GENERALSTRING, (st), (val), (i)) +# define sk_ASN1_GENERALSTRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_GENERALSTRING, (st), (cmp)) +# define sk_ASN1_GENERALSTRING_dup(st) SKM_sk_dup(ASN1_GENERALSTRING, st) +# define sk_ASN1_GENERALSTRING_pop_free(st, free_func) SKM_sk_pop_free(ASN1_GENERALSTRING, (st), (free_func)) +# define sk_ASN1_GENERALSTRING_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASN1_GENERALSTRING, (st), (copy_func), (free_func)) +# define sk_ASN1_GENERALSTRING_shift(st) SKM_sk_shift(ASN1_GENERALSTRING, (st)) +# define sk_ASN1_GENERALSTRING_pop(st) SKM_sk_pop(ASN1_GENERALSTRING, (st)) +# define sk_ASN1_GENERALSTRING_sort(st) SKM_sk_sort(ASN1_GENERALSTRING, (st)) +# define sk_ASN1_GENERALSTRING_is_sorted(st) SKM_sk_is_sorted(ASN1_GENERALSTRING, (st)) +# define sk_ASN1_INTEGER_new(cmp) SKM_sk_new(ASN1_INTEGER, (cmp)) +# define sk_ASN1_INTEGER_new_null() SKM_sk_new_null(ASN1_INTEGER) +# define sk_ASN1_INTEGER_free(st) SKM_sk_free(ASN1_INTEGER, (st)) +# define sk_ASN1_INTEGER_num(st) SKM_sk_num(ASN1_INTEGER, (st)) +# define sk_ASN1_INTEGER_value(st, i) SKM_sk_value(ASN1_INTEGER, (st), (i)) +# define sk_ASN1_INTEGER_set(st, i, val) SKM_sk_set(ASN1_INTEGER, (st), (i), (val)) +# define sk_ASN1_INTEGER_zero(st) SKM_sk_zero(ASN1_INTEGER, (st)) +# define sk_ASN1_INTEGER_push(st, val) SKM_sk_push(ASN1_INTEGER, (st), (val)) +# define sk_ASN1_INTEGER_unshift(st, val) SKM_sk_unshift(ASN1_INTEGER, (st), (val)) +# define sk_ASN1_INTEGER_find(st, val) SKM_sk_find(ASN1_INTEGER, (st), (val)) +# define sk_ASN1_INTEGER_find_ex(st, val) SKM_sk_find_ex(ASN1_INTEGER, (st), (val)) +# define sk_ASN1_INTEGER_delete(st, i) SKM_sk_delete(ASN1_INTEGER, (st), (i)) +# define sk_ASN1_INTEGER_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_INTEGER, (st), (ptr)) +# define sk_ASN1_INTEGER_insert(st, val, i) SKM_sk_insert(ASN1_INTEGER, (st), (val), (i)) +# define sk_ASN1_INTEGER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_INTEGER, (st), (cmp)) +# define sk_ASN1_INTEGER_dup(st) SKM_sk_dup(ASN1_INTEGER, st) +# define sk_ASN1_INTEGER_pop_free(st, free_func) SKM_sk_pop_free(ASN1_INTEGER, (st), (free_func)) +# define sk_ASN1_INTEGER_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASN1_INTEGER, (st), (copy_func), (free_func)) +# define sk_ASN1_INTEGER_shift(st) SKM_sk_shift(ASN1_INTEGER, (st)) +# define sk_ASN1_INTEGER_pop(st) SKM_sk_pop(ASN1_INTEGER, (st)) +# define sk_ASN1_INTEGER_sort(st) SKM_sk_sort(ASN1_INTEGER, (st)) +# define sk_ASN1_INTEGER_is_sorted(st) SKM_sk_is_sorted(ASN1_INTEGER, (st)) +# define sk_ASN1_OBJECT_new(cmp) SKM_sk_new(ASN1_OBJECT, (cmp)) +# define sk_ASN1_OBJECT_new_null() SKM_sk_new_null(ASN1_OBJECT) +# define sk_ASN1_OBJECT_free(st) SKM_sk_free(ASN1_OBJECT, (st)) +# define sk_ASN1_OBJECT_num(st) SKM_sk_num(ASN1_OBJECT, (st)) +# define sk_ASN1_OBJECT_value(st, i) SKM_sk_value(ASN1_OBJECT, (st), (i)) +# define sk_ASN1_OBJECT_set(st, i, val) SKM_sk_set(ASN1_OBJECT, (st), (i), (val)) +# define sk_ASN1_OBJECT_zero(st) SKM_sk_zero(ASN1_OBJECT, (st)) +# define sk_ASN1_OBJECT_push(st, val) SKM_sk_push(ASN1_OBJECT, (st), (val)) +# define sk_ASN1_OBJECT_unshift(st, val) SKM_sk_unshift(ASN1_OBJECT, (st), (val)) +# define sk_ASN1_OBJECT_find(st, val) SKM_sk_find(ASN1_OBJECT, (st), (val)) +# define sk_ASN1_OBJECT_find_ex(st, val) SKM_sk_find_ex(ASN1_OBJECT, (st), (val)) +# define sk_ASN1_OBJECT_delete(st, i) SKM_sk_delete(ASN1_OBJECT, (st), (i)) +# define sk_ASN1_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_OBJECT, (st), (ptr)) +# define sk_ASN1_OBJECT_insert(st, val, i) SKM_sk_insert(ASN1_OBJECT, (st), (val), (i)) +# define sk_ASN1_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_OBJECT, (st), (cmp)) +# define sk_ASN1_OBJECT_dup(st) SKM_sk_dup(ASN1_OBJECT, st) +# define sk_ASN1_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(ASN1_OBJECT, (st), (free_func)) +# define sk_ASN1_OBJECT_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASN1_OBJECT, (st), (copy_func), (free_func)) +# define sk_ASN1_OBJECT_shift(st) SKM_sk_shift(ASN1_OBJECT, (st)) +# define sk_ASN1_OBJECT_pop(st) SKM_sk_pop(ASN1_OBJECT, (st)) +# define sk_ASN1_OBJECT_sort(st) SKM_sk_sort(ASN1_OBJECT, (st)) +# define sk_ASN1_OBJECT_is_sorted(st) SKM_sk_is_sorted(ASN1_OBJECT, (st)) +# define sk_ASN1_STRING_TABLE_new(cmp) SKM_sk_new(ASN1_STRING_TABLE, (cmp)) +# define sk_ASN1_STRING_TABLE_new_null() SKM_sk_new_null(ASN1_STRING_TABLE) +# define sk_ASN1_STRING_TABLE_free(st) SKM_sk_free(ASN1_STRING_TABLE, (st)) +# define sk_ASN1_STRING_TABLE_num(st) SKM_sk_num(ASN1_STRING_TABLE, (st)) +# define sk_ASN1_STRING_TABLE_value(st, i) SKM_sk_value(ASN1_STRING_TABLE, (st), (i)) +# define sk_ASN1_STRING_TABLE_set(st, i, val) SKM_sk_set(ASN1_STRING_TABLE, (st), (i), (val)) +# define sk_ASN1_STRING_TABLE_zero(st) SKM_sk_zero(ASN1_STRING_TABLE, (st)) +# define sk_ASN1_STRING_TABLE_push(st, val) SKM_sk_push(ASN1_STRING_TABLE, (st), (val)) +# define sk_ASN1_STRING_TABLE_unshift(st, val) SKM_sk_unshift(ASN1_STRING_TABLE, (st), (val)) +# define sk_ASN1_STRING_TABLE_find(st, val) SKM_sk_find(ASN1_STRING_TABLE, (st), (val)) +# define sk_ASN1_STRING_TABLE_find_ex(st, val) SKM_sk_find_ex(ASN1_STRING_TABLE, (st), (val)) +# define sk_ASN1_STRING_TABLE_delete(st, i) SKM_sk_delete(ASN1_STRING_TABLE, (st), (i)) +# define sk_ASN1_STRING_TABLE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_STRING_TABLE, (st), (ptr)) +# define sk_ASN1_STRING_TABLE_insert(st, val, i) SKM_sk_insert(ASN1_STRING_TABLE, (st), (val), (i)) +# define sk_ASN1_STRING_TABLE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_STRING_TABLE, (st), (cmp)) +# define sk_ASN1_STRING_TABLE_dup(st) SKM_sk_dup(ASN1_STRING_TABLE, st) +# define sk_ASN1_STRING_TABLE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_STRING_TABLE, (st), (free_func)) +# define sk_ASN1_STRING_TABLE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASN1_STRING_TABLE, (st), (copy_func), (free_func)) +# define sk_ASN1_STRING_TABLE_shift(st) SKM_sk_shift(ASN1_STRING_TABLE, (st)) +# define sk_ASN1_STRING_TABLE_pop(st) SKM_sk_pop(ASN1_STRING_TABLE, (st)) +# define sk_ASN1_STRING_TABLE_sort(st) SKM_sk_sort(ASN1_STRING_TABLE, (st)) +# define sk_ASN1_STRING_TABLE_is_sorted(st) SKM_sk_is_sorted(ASN1_STRING_TABLE, (st)) +# define sk_ASN1_TYPE_new(cmp) SKM_sk_new(ASN1_TYPE, (cmp)) +# define sk_ASN1_TYPE_new_null() SKM_sk_new_null(ASN1_TYPE) +# define sk_ASN1_TYPE_free(st) SKM_sk_free(ASN1_TYPE, (st)) +# define sk_ASN1_TYPE_num(st) SKM_sk_num(ASN1_TYPE, (st)) +# define sk_ASN1_TYPE_value(st, i) SKM_sk_value(ASN1_TYPE, (st), (i)) +# define sk_ASN1_TYPE_set(st, i, val) SKM_sk_set(ASN1_TYPE, (st), (i), (val)) +# define sk_ASN1_TYPE_zero(st) SKM_sk_zero(ASN1_TYPE, (st)) +# define sk_ASN1_TYPE_push(st, val) SKM_sk_push(ASN1_TYPE, (st), (val)) +# define sk_ASN1_TYPE_unshift(st, val) SKM_sk_unshift(ASN1_TYPE, (st), (val)) +# define sk_ASN1_TYPE_find(st, val) SKM_sk_find(ASN1_TYPE, (st), (val)) +# define sk_ASN1_TYPE_find_ex(st, val) SKM_sk_find_ex(ASN1_TYPE, (st), (val)) +# define sk_ASN1_TYPE_delete(st, i) SKM_sk_delete(ASN1_TYPE, (st), (i)) +# define sk_ASN1_TYPE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_TYPE, (st), (ptr)) +# define sk_ASN1_TYPE_insert(st, val, i) SKM_sk_insert(ASN1_TYPE, (st), (val), (i)) +# define sk_ASN1_TYPE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_TYPE, (st), (cmp)) +# define sk_ASN1_TYPE_dup(st) SKM_sk_dup(ASN1_TYPE, st) +# define sk_ASN1_TYPE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_TYPE, (st), (free_func)) +# define sk_ASN1_TYPE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASN1_TYPE, (st), (copy_func), (free_func)) +# define sk_ASN1_TYPE_shift(st) SKM_sk_shift(ASN1_TYPE, (st)) +# define sk_ASN1_TYPE_pop(st) SKM_sk_pop(ASN1_TYPE, (st)) +# define sk_ASN1_TYPE_sort(st) SKM_sk_sort(ASN1_TYPE, (st)) +# define sk_ASN1_TYPE_is_sorted(st) SKM_sk_is_sorted(ASN1_TYPE, (st)) +# define sk_ASN1_UTF8STRING_new(cmp) SKM_sk_new(ASN1_UTF8STRING, (cmp)) +# define sk_ASN1_UTF8STRING_new_null() SKM_sk_new_null(ASN1_UTF8STRING) +# define sk_ASN1_UTF8STRING_free(st) SKM_sk_free(ASN1_UTF8STRING, (st)) +# define sk_ASN1_UTF8STRING_num(st) SKM_sk_num(ASN1_UTF8STRING, (st)) +# define sk_ASN1_UTF8STRING_value(st, i) SKM_sk_value(ASN1_UTF8STRING, (st), (i)) +# define sk_ASN1_UTF8STRING_set(st, i, val) SKM_sk_set(ASN1_UTF8STRING, (st), (i), (val)) +# define sk_ASN1_UTF8STRING_zero(st) SKM_sk_zero(ASN1_UTF8STRING, (st)) +# define sk_ASN1_UTF8STRING_push(st, val) SKM_sk_push(ASN1_UTF8STRING, (st), (val)) +# define sk_ASN1_UTF8STRING_unshift(st, val) SKM_sk_unshift(ASN1_UTF8STRING, (st), (val)) +# define sk_ASN1_UTF8STRING_find(st, val) SKM_sk_find(ASN1_UTF8STRING, (st), (val)) +# define sk_ASN1_UTF8STRING_find_ex(st, val) SKM_sk_find_ex(ASN1_UTF8STRING, (st), (val)) +# define sk_ASN1_UTF8STRING_delete(st, i) SKM_sk_delete(ASN1_UTF8STRING, (st), (i)) +# define sk_ASN1_UTF8STRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_UTF8STRING, (st), (ptr)) +# define sk_ASN1_UTF8STRING_insert(st, val, i) SKM_sk_insert(ASN1_UTF8STRING, (st), (val), (i)) +# define sk_ASN1_UTF8STRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_UTF8STRING, (st), (cmp)) +# define sk_ASN1_UTF8STRING_dup(st) SKM_sk_dup(ASN1_UTF8STRING, st) +# define sk_ASN1_UTF8STRING_pop_free(st, free_func) SKM_sk_pop_free(ASN1_UTF8STRING, (st), (free_func)) +# define sk_ASN1_UTF8STRING_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASN1_UTF8STRING, (st), (copy_func), (free_func)) +# define sk_ASN1_UTF8STRING_shift(st) SKM_sk_shift(ASN1_UTF8STRING, (st)) +# define sk_ASN1_UTF8STRING_pop(st) SKM_sk_pop(ASN1_UTF8STRING, (st)) +# define sk_ASN1_UTF8STRING_sort(st) SKM_sk_sort(ASN1_UTF8STRING, (st)) +# define sk_ASN1_UTF8STRING_is_sorted(st) SKM_sk_is_sorted(ASN1_UTF8STRING, (st)) +# define sk_ASN1_VALUE_new(cmp) SKM_sk_new(ASN1_VALUE, (cmp)) +# define sk_ASN1_VALUE_new_null() SKM_sk_new_null(ASN1_VALUE) +# define sk_ASN1_VALUE_free(st) SKM_sk_free(ASN1_VALUE, (st)) +# define sk_ASN1_VALUE_num(st) SKM_sk_num(ASN1_VALUE, (st)) +# define sk_ASN1_VALUE_value(st, i) SKM_sk_value(ASN1_VALUE, (st), (i)) +# define sk_ASN1_VALUE_set(st, i, val) SKM_sk_set(ASN1_VALUE, (st), (i), (val)) +# define sk_ASN1_VALUE_zero(st) SKM_sk_zero(ASN1_VALUE, (st)) +# define sk_ASN1_VALUE_push(st, val) SKM_sk_push(ASN1_VALUE, (st), (val)) +# define sk_ASN1_VALUE_unshift(st, val) SKM_sk_unshift(ASN1_VALUE, (st), (val)) +# define sk_ASN1_VALUE_find(st, val) SKM_sk_find(ASN1_VALUE, (st), (val)) +# define sk_ASN1_VALUE_find_ex(st, val) SKM_sk_find_ex(ASN1_VALUE, (st), (val)) +# define sk_ASN1_VALUE_delete(st, i) SKM_sk_delete(ASN1_VALUE, (st), (i)) +# define sk_ASN1_VALUE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_VALUE, (st), (ptr)) +# define sk_ASN1_VALUE_insert(st, val, i) SKM_sk_insert(ASN1_VALUE, (st), (val), (i)) +# define sk_ASN1_VALUE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_VALUE, (st), (cmp)) +# define sk_ASN1_VALUE_dup(st) SKM_sk_dup(ASN1_VALUE, st) +# define sk_ASN1_VALUE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_VALUE, (st), (free_func)) +# define sk_ASN1_VALUE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASN1_VALUE, (st), (copy_func), (free_func)) +# define sk_ASN1_VALUE_shift(st) SKM_sk_shift(ASN1_VALUE, (st)) +# define sk_ASN1_VALUE_pop(st) SKM_sk_pop(ASN1_VALUE, (st)) +# define sk_ASN1_VALUE_sort(st) SKM_sk_sort(ASN1_VALUE, (st)) +# define sk_ASN1_VALUE_is_sorted(st) SKM_sk_is_sorted(ASN1_VALUE, (st)) +# define sk_BIO_new(cmp) SKM_sk_new(BIO, (cmp)) +# define sk_BIO_new_null() SKM_sk_new_null(BIO) +# define sk_BIO_free(st) SKM_sk_free(BIO, (st)) +# define sk_BIO_num(st) SKM_sk_num(BIO, (st)) +# define sk_BIO_value(st, i) SKM_sk_value(BIO, (st), (i)) +# define sk_BIO_set(st, i, val) SKM_sk_set(BIO, (st), (i), (val)) +# define sk_BIO_zero(st) SKM_sk_zero(BIO, (st)) +# define sk_BIO_push(st, val) SKM_sk_push(BIO, (st), (val)) +# define sk_BIO_unshift(st, val) SKM_sk_unshift(BIO, (st), (val)) +# define sk_BIO_find(st, val) SKM_sk_find(BIO, (st), (val)) +# define sk_BIO_find_ex(st, val) SKM_sk_find_ex(BIO, (st), (val)) +# define sk_BIO_delete(st, i) SKM_sk_delete(BIO, (st), (i)) +# define sk_BIO_delete_ptr(st, ptr) SKM_sk_delete_ptr(BIO, (st), (ptr)) +# define sk_BIO_insert(st, val, i) SKM_sk_insert(BIO, (st), (val), (i)) +# define sk_BIO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BIO, (st), (cmp)) +# define sk_BIO_dup(st) SKM_sk_dup(BIO, st) +# define sk_BIO_pop_free(st, free_func) SKM_sk_pop_free(BIO, (st), (free_func)) +# define sk_BIO_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(BIO, (st), (copy_func), (free_func)) +# define sk_BIO_shift(st) SKM_sk_shift(BIO, (st)) +# define sk_BIO_pop(st) SKM_sk_pop(BIO, (st)) +# define sk_BIO_sort(st) SKM_sk_sort(BIO, (st)) +# define sk_BIO_is_sorted(st) SKM_sk_is_sorted(BIO, (st)) +# define sk_BY_DIR_ENTRY_new(cmp) SKM_sk_new(BY_DIR_ENTRY, (cmp)) +# define sk_BY_DIR_ENTRY_new_null() SKM_sk_new_null(BY_DIR_ENTRY) +# define sk_BY_DIR_ENTRY_free(st) SKM_sk_free(BY_DIR_ENTRY, (st)) +# define sk_BY_DIR_ENTRY_num(st) SKM_sk_num(BY_DIR_ENTRY, (st)) +# define sk_BY_DIR_ENTRY_value(st, i) SKM_sk_value(BY_DIR_ENTRY, (st), (i)) +# define sk_BY_DIR_ENTRY_set(st, i, val) SKM_sk_set(BY_DIR_ENTRY, (st), (i), (val)) +# define sk_BY_DIR_ENTRY_zero(st) SKM_sk_zero(BY_DIR_ENTRY, (st)) +# define sk_BY_DIR_ENTRY_push(st, val) SKM_sk_push(BY_DIR_ENTRY, (st), (val)) +# define sk_BY_DIR_ENTRY_unshift(st, val) SKM_sk_unshift(BY_DIR_ENTRY, (st), (val)) +# define sk_BY_DIR_ENTRY_find(st, val) SKM_sk_find(BY_DIR_ENTRY, (st), (val)) +# define sk_BY_DIR_ENTRY_find_ex(st, val) SKM_sk_find_ex(BY_DIR_ENTRY, (st), (val)) +# define sk_BY_DIR_ENTRY_delete(st, i) SKM_sk_delete(BY_DIR_ENTRY, (st), (i)) +# define sk_BY_DIR_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(BY_DIR_ENTRY, (st), (ptr)) +# define sk_BY_DIR_ENTRY_insert(st, val, i) SKM_sk_insert(BY_DIR_ENTRY, (st), (val), (i)) +# define sk_BY_DIR_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BY_DIR_ENTRY, (st), (cmp)) +# define sk_BY_DIR_ENTRY_dup(st) SKM_sk_dup(BY_DIR_ENTRY, st) +# define sk_BY_DIR_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(BY_DIR_ENTRY, (st), (free_func)) +# define sk_BY_DIR_ENTRY_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(BY_DIR_ENTRY, (st), (copy_func), (free_func)) +# define sk_BY_DIR_ENTRY_shift(st) SKM_sk_shift(BY_DIR_ENTRY, (st)) +# define sk_BY_DIR_ENTRY_pop(st) SKM_sk_pop(BY_DIR_ENTRY, (st)) +# define sk_BY_DIR_ENTRY_sort(st) SKM_sk_sort(BY_DIR_ENTRY, (st)) +# define sk_BY_DIR_ENTRY_is_sorted(st) SKM_sk_is_sorted(BY_DIR_ENTRY, (st)) +# define sk_BY_DIR_HASH_new(cmp) SKM_sk_new(BY_DIR_HASH, (cmp)) +# define sk_BY_DIR_HASH_new_null() SKM_sk_new_null(BY_DIR_HASH) +# define sk_BY_DIR_HASH_free(st) SKM_sk_free(BY_DIR_HASH, (st)) +# define sk_BY_DIR_HASH_num(st) SKM_sk_num(BY_DIR_HASH, (st)) +# define sk_BY_DIR_HASH_value(st, i) SKM_sk_value(BY_DIR_HASH, (st), (i)) +# define sk_BY_DIR_HASH_set(st, i, val) SKM_sk_set(BY_DIR_HASH, (st), (i), (val)) +# define sk_BY_DIR_HASH_zero(st) SKM_sk_zero(BY_DIR_HASH, (st)) +# define sk_BY_DIR_HASH_push(st, val) SKM_sk_push(BY_DIR_HASH, (st), (val)) +# define sk_BY_DIR_HASH_unshift(st, val) SKM_sk_unshift(BY_DIR_HASH, (st), (val)) +# define sk_BY_DIR_HASH_find(st, val) SKM_sk_find(BY_DIR_HASH, (st), (val)) +# define sk_BY_DIR_HASH_find_ex(st, val) SKM_sk_find_ex(BY_DIR_HASH, (st), (val)) +# define sk_BY_DIR_HASH_delete(st, i) SKM_sk_delete(BY_DIR_HASH, (st), (i)) +# define sk_BY_DIR_HASH_delete_ptr(st, ptr) SKM_sk_delete_ptr(BY_DIR_HASH, (st), (ptr)) +# define sk_BY_DIR_HASH_insert(st, val, i) SKM_sk_insert(BY_DIR_HASH, (st), (val), (i)) +# define sk_BY_DIR_HASH_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BY_DIR_HASH, (st), (cmp)) +# define sk_BY_DIR_HASH_dup(st) SKM_sk_dup(BY_DIR_HASH, st) +# define sk_BY_DIR_HASH_pop_free(st, free_func) SKM_sk_pop_free(BY_DIR_HASH, (st), (free_func)) +# define sk_BY_DIR_HASH_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(BY_DIR_HASH, (st), (copy_func), (free_func)) +# define sk_BY_DIR_HASH_shift(st) SKM_sk_shift(BY_DIR_HASH, (st)) +# define sk_BY_DIR_HASH_pop(st) SKM_sk_pop(BY_DIR_HASH, (st)) +# define sk_BY_DIR_HASH_sort(st) SKM_sk_sort(BY_DIR_HASH, (st)) +# define sk_BY_DIR_HASH_is_sorted(st) SKM_sk_is_sorted(BY_DIR_HASH, (st)) +# define sk_CMS_CertificateChoices_new(cmp) SKM_sk_new(CMS_CertificateChoices, (cmp)) +# define sk_CMS_CertificateChoices_new_null() SKM_sk_new_null(CMS_CertificateChoices) +# define sk_CMS_CertificateChoices_free(st) SKM_sk_free(CMS_CertificateChoices, (st)) +# define sk_CMS_CertificateChoices_num(st) SKM_sk_num(CMS_CertificateChoices, (st)) +# define sk_CMS_CertificateChoices_value(st, i) SKM_sk_value(CMS_CertificateChoices, (st), (i)) +# define sk_CMS_CertificateChoices_set(st, i, val) SKM_sk_set(CMS_CertificateChoices, (st), (i), (val)) +# define sk_CMS_CertificateChoices_zero(st) SKM_sk_zero(CMS_CertificateChoices, (st)) +# define sk_CMS_CertificateChoices_push(st, val) SKM_sk_push(CMS_CertificateChoices, (st), (val)) +# define sk_CMS_CertificateChoices_unshift(st, val) SKM_sk_unshift(CMS_CertificateChoices, (st), (val)) +# define sk_CMS_CertificateChoices_find(st, val) SKM_sk_find(CMS_CertificateChoices, (st), (val)) +# define sk_CMS_CertificateChoices_find_ex(st, val) SKM_sk_find_ex(CMS_CertificateChoices, (st), (val)) +# define sk_CMS_CertificateChoices_delete(st, i) SKM_sk_delete(CMS_CertificateChoices, (st), (i)) +# define sk_CMS_CertificateChoices_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_CertificateChoices, (st), (ptr)) +# define sk_CMS_CertificateChoices_insert(st, val, i) SKM_sk_insert(CMS_CertificateChoices, (st), (val), (i)) +# define sk_CMS_CertificateChoices_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_CertificateChoices, (st), (cmp)) +# define sk_CMS_CertificateChoices_dup(st) SKM_sk_dup(CMS_CertificateChoices, st) +# define sk_CMS_CertificateChoices_pop_free(st, free_func) SKM_sk_pop_free(CMS_CertificateChoices, (st), (free_func)) +# define sk_CMS_CertificateChoices_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CMS_CertificateChoices, (st), (copy_func), (free_func)) +# define sk_CMS_CertificateChoices_shift(st) SKM_sk_shift(CMS_CertificateChoices, (st)) +# define sk_CMS_CertificateChoices_pop(st) SKM_sk_pop(CMS_CertificateChoices, (st)) +# define sk_CMS_CertificateChoices_sort(st) SKM_sk_sort(CMS_CertificateChoices, (st)) +# define sk_CMS_CertificateChoices_is_sorted(st) SKM_sk_is_sorted(CMS_CertificateChoices, (st)) +# define sk_CMS_RecipientEncryptedKey_new(cmp) SKM_sk_new(CMS_RecipientEncryptedKey, (cmp)) +# define sk_CMS_RecipientEncryptedKey_new_null() SKM_sk_new_null(CMS_RecipientEncryptedKey) +# define sk_CMS_RecipientEncryptedKey_free(st) SKM_sk_free(CMS_RecipientEncryptedKey, (st)) +# define sk_CMS_RecipientEncryptedKey_num(st) SKM_sk_num(CMS_RecipientEncryptedKey, (st)) +# define sk_CMS_RecipientEncryptedKey_value(st, i) SKM_sk_value(CMS_RecipientEncryptedKey, (st), (i)) +# define sk_CMS_RecipientEncryptedKey_set(st, i, val) SKM_sk_set(CMS_RecipientEncryptedKey, (st), (i), (val)) +# define sk_CMS_RecipientEncryptedKey_zero(st) SKM_sk_zero(CMS_RecipientEncryptedKey, (st)) +# define sk_CMS_RecipientEncryptedKey_push(st, val) SKM_sk_push(CMS_RecipientEncryptedKey, (st), (val)) +# define sk_CMS_RecipientEncryptedKey_unshift(st, val) SKM_sk_unshift(CMS_RecipientEncryptedKey, (st), (val)) +# define sk_CMS_RecipientEncryptedKey_find(st, val) SKM_sk_find(CMS_RecipientEncryptedKey, (st), (val)) +# define sk_CMS_RecipientEncryptedKey_find_ex(st, val) SKM_sk_find_ex(CMS_RecipientEncryptedKey, (st), (val)) +# define sk_CMS_RecipientEncryptedKey_delete(st, i) SKM_sk_delete(CMS_RecipientEncryptedKey, (st), (i)) +# define sk_CMS_RecipientEncryptedKey_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_RecipientEncryptedKey, (st), (ptr)) +# define sk_CMS_RecipientEncryptedKey_insert(st, val, i) SKM_sk_insert(CMS_RecipientEncryptedKey, (st), (val), (i)) +# define sk_CMS_RecipientEncryptedKey_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_RecipientEncryptedKey, (st), (cmp)) +# define sk_CMS_RecipientEncryptedKey_dup(st) SKM_sk_dup(CMS_RecipientEncryptedKey, st) +# define sk_CMS_RecipientEncryptedKey_pop_free(st, free_func) SKM_sk_pop_free(CMS_RecipientEncryptedKey, (st), (free_func)) +# define sk_CMS_RecipientEncryptedKey_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CMS_RecipientEncryptedKey, (st), (copy_func), (free_func)) +# define sk_CMS_RecipientEncryptedKey_shift(st) SKM_sk_shift(CMS_RecipientEncryptedKey, (st)) +# define sk_CMS_RecipientEncryptedKey_pop(st) SKM_sk_pop(CMS_RecipientEncryptedKey, (st)) +# define sk_CMS_RecipientEncryptedKey_sort(st) SKM_sk_sort(CMS_RecipientEncryptedKey, (st)) +# define sk_CMS_RecipientEncryptedKey_is_sorted(st) SKM_sk_is_sorted(CMS_RecipientEncryptedKey, (st)) +# define sk_CMS_RecipientInfo_new(cmp) SKM_sk_new(CMS_RecipientInfo, (cmp)) +# define sk_CMS_RecipientInfo_new_null() SKM_sk_new_null(CMS_RecipientInfo) +# define sk_CMS_RecipientInfo_free(st) SKM_sk_free(CMS_RecipientInfo, (st)) +# define sk_CMS_RecipientInfo_num(st) SKM_sk_num(CMS_RecipientInfo, (st)) +# define sk_CMS_RecipientInfo_value(st, i) SKM_sk_value(CMS_RecipientInfo, (st), (i)) +# define sk_CMS_RecipientInfo_set(st, i, val) SKM_sk_set(CMS_RecipientInfo, (st), (i), (val)) +# define sk_CMS_RecipientInfo_zero(st) SKM_sk_zero(CMS_RecipientInfo, (st)) +# define sk_CMS_RecipientInfo_push(st, val) SKM_sk_push(CMS_RecipientInfo, (st), (val)) +# define sk_CMS_RecipientInfo_unshift(st, val) SKM_sk_unshift(CMS_RecipientInfo, (st), (val)) +# define sk_CMS_RecipientInfo_find(st, val) SKM_sk_find(CMS_RecipientInfo, (st), (val)) +# define sk_CMS_RecipientInfo_find_ex(st, val) SKM_sk_find_ex(CMS_RecipientInfo, (st), (val)) +# define sk_CMS_RecipientInfo_delete(st, i) SKM_sk_delete(CMS_RecipientInfo, (st), (i)) +# define sk_CMS_RecipientInfo_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_RecipientInfo, (st), (ptr)) +# define sk_CMS_RecipientInfo_insert(st, val, i) SKM_sk_insert(CMS_RecipientInfo, (st), (val), (i)) +# define sk_CMS_RecipientInfo_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_RecipientInfo, (st), (cmp)) +# define sk_CMS_RecipientInfo_dup(st) SKM_sk_dup(CMS_RecipientInfo, st) +# define sk_CMS_RecipientInfo_pop_free(st, free_func) SKM_sk_pop_free(CMS_RecipientInfo, (st), (free_func)) +# define sk_CMS_RecipientInfo_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CMS_RecipientInfo, (st), (copy_func), (free_func)) +# define sk_CMS_RecipientInfo_shift(st) SKM_sk_shift(CMS_RecipientInfo, (st)) +# define sk_CMS_RecipientInfo_pop(st) SKM_sk_pop(CMS_RecipientInfo, (st)) +# define sk_CMS_RecipientInfo_sort(st) SKM_sk_sort(CMS_RecipientInfo, (st)) +# define sk_CMS_RecipientInfo_is_sorted(st) SKM_sk_is_sorted(CMS_RecipientInfo, (st)) +# define sk_CMS_RevocationInfoChoice_new(cmp) SKM_sk_new(CMS_RevocationInfoChoice, (cmp)) +# define sk_CMS_RevocationInfoChoice_new_null() SKM_sk_new_null(CMS_RevocationInfoChoice) +# define sk_CMS_RevocationInfoChoice_free(st) SKM_sk_free(CMS_RevocationInfoChoice, (st)) +# define sk_CMS_RevocationInfoChoice_num(st) SKM_sk_num(CMS_RevocationInfoChoice, (st)) +# define sk_CMS_RevocationInfoChoice_value(st, i) SKM_sk_value(CMS_RevocationInfoChoice, (st), (i)) +# define sk_CMS_RevocationInfoChoice_set(st, i, val) SKM_sk_set(CMS_RevocationInfoChoice, (st), (i), (val)) +# define sk_CMS_RevocationInfoChoice_zero(st) SKM_sk_zero(CMS_RevocationInfoChoice, (st)) +# define sk_CMS_RevocationInfoChoice_push(st, val) SKM_sk_push(CMS_RevocationInfoChoice, (st), (val)) +# define sk_CMS_RevocationInfoChoice_unshift(st, val) SKM_sk_unshift(CMS_RevocationInfoChoice, (st), (val)) +# define sk_CMS_RevocationInfoChoice_find(st, val) SKM_sk_find(CMS_RevocationInfoChoice, (st), (val)) +# define sk_CMS_RevocationInfoChoice_find_ex(st, val) SKM_sk_find_ex(CMS_RevocationInfoChoice, (st), (val)) +# define sk_CMS_RevocationInfoChoice_delete(st, i) SKM_sk_delete(CMS_RevocationInfoChoice, (st), (i)) +# define sk_CMS_RevocationInfoChoice_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_RevocationInfoChoice, (st), (ptr)) +# define sk_CMS_RevocationInfoChoice_insert(st, val, i) SKM_sk_insert(CMS_RevocationInfoChoice, (st), (val), (i)) +# define sk_CMS_RevocationInfoChoice_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_RevocationInfoChoice, (st), (cmp)) +# define sk_CMS_RevocationInfoChoice_dup(st) SKM_sk_dup(CMS_RevocationInfoChoice, st) +# define sk_CMS_RevocationInfoChoice_pop_free(st, free_func) SKM_sk_pop_free(CMS_RevocationInfoChoice, (st), (free_func)) +# define sk_CMS_RevocationInfoChoice_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CMS_RevocationInfoChoice, (st), (copy_func), (free_func)) +# define sk_CMS_RevocationInfoChoice_shift(st) SKM_sk_shift(CMS_RevocationInfoChoice, (st)) +# define sk_CMS_RevocationInfoChoice_pop(st) SKM_sk_pop(CMS_RevocationInfoChoice, (st)) +# define sk_CMS_RevocationInfoChoice_sort(st) SKM_sk_sort(CMS_RevocationInfoChoice, (st)) +# define sk_CMS_RevocationInfoChoice_is_sorted(st) SKM_sk_is_sorted(CMS_RevocationInfoChoice, (st)) +# define sk_CMS_SignerInfo_new(cmp) SKM_sk_new(CMS_SignerInfo, (cmp)) +# define sk_CMS_SignerInfo_new_null() SKM_sk_new_null(CMS_SignerInfo) +# define sk_CMS_SignerInfo_free(st) SKM_sk_free(CMS_SignerInfo, (st)) +# define sk_CMS_SignerInfo_num(st) SKM_sk_num(CMS_SignerInfo, (st)) +# define sk_CMS_SignerInfo_value(st, i) SKM_sk_value(CMS_SignerInfo, (st), (i)) +# define sk_CMS_SignerInfo_set(st, i, val) SKM_sk_set(CMS_SignerInfo, (st), (i), (val)) +# define sk_CMS_SignerInfo_zero(st) SKM_sk_zero(CMS_SignerInfo, (st)) +# define sk_CMS_SignerInfo_push(st, val) SKM_sk_push(CMS_SignerInfo, (st), (val)) +# define sk_CMS_SignerInfo_unshift(st, val) SKM_sk_unshift(CMS_SignerInfo, (st), (val)) +# define sk_CMS_SignerInfo_find(st, val) SKM_sk_find(CMS_SignerInfo, (st), (val)) +# define sk_CMS_SignerInfo_find_ex(st, val) SKM_sk_find_ex(CMS_SignerInfo, (st), (val)) +# define sk_CMS_SignerInfo_delete(st, i) SKM_sk_delete(CMS_SignerInfo, (st), (i)) +# define sk_CMS_SignerInfo_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_SignerInfo, (st), (ptr)) +# define sk_CMS_SignerInfo_insert(st, val, i) SKM_sk_insert(CMS_SignerInfo, (st), (val), (i)) +# define sk_CMS_SignerInfo_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_SignerInfo, (st), (cmp)) +# define sk_CMS_SignerInfo_dup(st) SKM_sk_dup(CMS_SignerInfo, st) +# define sk_CMS_SignerInfo_pop_free(st, free_func) SKM_sk_pop_free(CMS_SignerInfo, (st), (free_func)) +# define sk_CMS_SignerInfo_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CMS_SignerInfo, (st), (copy_func), (free_func)) +# define sk_CMS_SignerInfo_shift(st) SKM_sk_shift(CMS_SignerInfo, (st)) +# define sk_CMS_SignerInfo_pop(st) SKM_sk_pop(CMS_SignerInfo, (st)) +# define sk_CMS_SignerInfo_sort(st) SKM_sk_sort(CMS_SignerInfo, (st)) +# define sk_CMS_SignerInfo_is_sorted(st) SKM_sk_is_sorted(CMS_SignerInfo, (st)) +# define sk_CONF_IMODULE_new(cmp) SKM_sk_new(CONF_IMODULE, (cmp)) +# define sk_CONF_IMODULE_new_null() SKM_sk_new_null(CONF_IMODULE) +# define sk_CONF_IMODULE_free(st) SKM_sk_free(CONF_IMODULE, (st)) +# define sk_CONF_IMODULE_num(st) SKM_sk_num(CONF_IMODULE, (st)) +# define sk_CONF_IMODULE_value(st, i) SKM_sk_value(CONF_IMODULE, (st), (i)) +# define sk_CONF_IMODULE_set(st, i, val) SKM_sk_set(CONF_IMODULE, (st), (i), (val)) +# define sk_CONF_IMODULE_zero(st) SKM_sk_zero(CONF_IMODULE, (st)) +# define sk_CONF_IMODULE_push(st, val) SKM_sk_push(CONF_IMODULE, (st), (val)) +# define sk_CONF_IMODULE_unshift(st, val) SKM_sk_unshift(CONF_IMODULE, (st), (val)) +# define sk_CONF_IMODULE_find(st, val) SKM_sk_find(CONF_IMODULE, (st), (val)) +# define sk_CONF_IMODULE_find_ex(st, val) SKM_sk_find_ex(CONF_IMODULE, (st), (val)) +# define sk_CONF_IMODULE_delete(st, i) SKM_sk_delete(CONF_IMODULE, (st), (i)) +# define sk_CONF_IMODULE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_IMODULE, (st), (ptr)) +# define sk_CONF_IMODULE_insert(st, val, i) SKM_sk_insert(CONF_IMODULE, (st), (val), (i)) +# define sk_CONF_IMODULE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_IMODULE, (st), (cmp)) +# define sk_CONF_IMODULE_dup(st) SKM_sk_dup(CONF_IMODULE, st) +# define sk_CONF_IMODULE_pop_free(st, free_func) SKM_sk_pop_free(CONF_IMODULE, (st), (free_func)) +# define sk_CONF_IMODULE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CONF_IMODULE, (st), (copy_func), (free_func)) +# define sk_CONF_IMODULE_shift(st) SKM_sk_shift(CONF_IMODULE, (st)) +# define sk_CONF_IMODULE_pop(st) SKM_sk_pop(CONF_IMODULE, (st)) +# define sk_CONF_IMODULE_sort(st) SKM_sk_sort(CONF_IMODULE, (st)) +# define sk_CONF_IMODULE_is_sorted(st) SKM_sk_is_sorted(CONF_IMODULE, (st)) +# define sk_CONF_MODULE_new(cmp) SKM_sk_new(CONF_MODULE, (cmp)) +# define sk_CONF_MODULE_new_null() SKM_sk_new_null(CONF_MODULE) +# define sk_CONF_MODULE_free(st) SKM_sk_free(CONF_MODULE, (st)) +# define sk_CONF_MODULE_num(st) SKM_sk_num(CONF_MODULE, (st)) +# define sk_CONF_MODULE_value(st, i) SKM_sk_value(CONF_MODULE, (st), (i)) +# define sk_CONF_MODULE_set(st, i, val) SKM_sk_set(CONF_MODULE, (st), (i), (val)) +# define sk_CONF_MODULE_zero(st) SKM_sk_zero(CONF_MODULE, (st)) +# define sk_CONF_MODULE_push(st, val) SKM_sk_push(CONF_MODULE, (st), (val)) +# define sk_CONF_MODULE_unshift(st, val) SKM_sk_unshift(CONF_MODULE, (st), (val)) +# define sk_CONF_MODULE_find(st, val) SKM_sk_find(CONF_MODULE, (st), (val)) +# define sk_CONF_MODULE_find_ex(st, val) SKM_sk_find_ex(CONF_MODULE, (st), (val)) +# define sk_CONF_MODULE_delete(st, i) SKM_sk_delete(CONF_MODULE, (st), (i)) +# define sk_CONF_MODULE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_MODULE, (st), (ptr)) +# define sk_CONF_MODULE_insert(st, val, i) SKM_sk_insert(CONF_MODULE, (st), (val), (i)) +# define sk_CONF_MODULE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_MODULE, (st), (cmp)) +# define sk_CONF_MODULE_dup(st) SKM_sk_dup(CONF_MODULE, st) +# define sk_CONF_MODULE_pop_free(st, free_func) SKM_sk_pop_free(CONF_MODULE, (st), (free_func)) +# define sk_CONF_MODULE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CONF_MODULE, (st), (copy_func), (free_func)) +# define sk_CONF_MODULE_shift(st) SKM_sk_shift(CONF_MODULE, (st)) +# define sk_CONF_MODULE_pop(st) SKM_sk_pop(CONF_MODULE, (st)) +# define sk_CONF_MODULE_sort(st) SKM_sk_sort(CONF_MODULE, (st)) +# define sk_CONF_MODULE_is_sorted(st) SKM_sk_is_sorted(CONF_MODULE, (st)) +# define sk_CONF_VALUE_new(cmp) SKM_sk_new(CONF_VALUE, (cmp)) +# define sk_CONF_VALUE_new_null() SKM_sk_new_null(CONF_VALUE) +# define sk_CONF_VALUE_free(st) SKM_sk_free(CONF_VALUE, (st)) +# define sk_CONF_VALUE_num(st) SKM_sk_num(CONF_VALUE, (st)) +# define sk_CONF_VALUE_value(st, i) SKM_sk_value(CONF_VALUE, (st), (i)) +# define sk_CONF_VALUE_set(st, i, val) SKM_sk_set(CONF_VALUE, (st), (i), (val)) +# define sk_CONF_VALUE_zero(st) SKM_sk_zero(CONF_VALUE, (st)) +# define sk_CONF_VALUE_push(st, val) SKM_sk_push(CONF_VALUE, (st), (val)) +# define sk_CONF_VALUE_unshift(st, val) SKM_sk_unshift(CONF_VALUE, (st), (val)) +# define sk_CONF_VALUE_find(st, val) SKM_sk_find(CONF_VALUE, (st), (val)) +# define sk_CONF_VALUE_find_ex(st, val) SKM_sk_find_ex(CONF_VALUE, (st), (val)) +# define sk_CONF_VALUE_delete(st, i) SKM_sk_delete(CONF_VALUE, (st), (i)) +# define sk_CONF_VALUE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_VALUE, (st), (ptr)) +# define sk_CONF_VALUE_insert(st, val, i) SKM_sk_insert(CONF_VALUE, (st), (val), (i)) +# define sk_CONF_VALUE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_VALUE, (st), (cmp)) +# define sk_CONF_VALUE_dup(st) SKM_sk_dup(CONF_VALUE, st) +# define sk_CONF_VALUE_pop_free(st, free_func) SKM_sk_pop_free(CONF_VALUE, (st), (free_func)) +# define sk_CONF_VALUE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CONF_VALUE, (st), (copy_func), (free_func)) +# define sk_CONF_VALUE_shift(st) SKM_sk_shift(CONF_VALUE, (st)) +# define sk_CONF_VALUE_pop(st) SKM_sk_pop(CONF_VALUE, (st)) +# define sk_CONF_VALUE_sort(st) SKM_sk_sort(CONF_VALUE, (st)) +# define sk_CONF_VALUE_is_sorted(st) SKM_sk_is_sorted(CONF_VALUE, (st)) +# define sk_CRYPTO_EX_DATA_FUNCS_new(cmp) SKM_sk_new(CRYPTO_EX_DATA_FUNCS, (cmp)) +# define sk_CRYPTO_EX_DATA_FUNCS_new_null() SKM_sk_new_null(CRYPTO_EX_DATA_FUNCS) +# define sk_CRYPTO_EX_DATA_FUNCS_free(st) SKM_sk_free(CRYPTO_EX_DATA_FUNCS, (st)) +# define sk_CRYPTO_EX_DATA_FUNCS_num(st) SKM_sk_num(CRYPTO_EX_DATA_FUNCS, (st)) +# define sk_CRYPTO_EX_DATA_FUNCS_value(st, i) SKM_sk_value(CRYPTO_EX_DATA_FUNCS, (st), (i)) +# define sk_CRYPTO_EX_DATA_FUNCS_set(st, i, val) SKM_sk_set(CRYPTO_EX_DATA_FUNCS, (st), (i), (val)) +# define sk_CRYPTO_EX_DATA_FUNCS_zero(st) SKM_sk_zero(CRYPTO_EX_DATA_FUNCS, (st)) +# define sk_CRYPTO_EX_DATA_FUNCS_push(st, val) SKM_sk_push(CRYPTO_EX_DATA_FUNCS, (st), (val)) +# define sk_CRYPTO_EX_DATA_FUNCS_unshift(st, val) SKM_sk_unshift(CRYPTO_EX_DATA_FUNCS, (st), (val)) +# define sk_CRYPTO_EX_DATA_FUNCS_find(st, val) SKM_sk_find(CRYPTO_EX_DATA_FUNCS, (st), (val)) +# define sk_CRYPTO_EX_DATA_FUNCS_find_ex(st, val) SKM_sk_find_ex(CRYPTO_EX_DATA_FUNCS, (st), (val)) +# define sk_CRYPTO_EX_DATA_FUNCS_delete(st, i) SKM_sk_delete(CRYPTO_EX_DATA_FUNCS, (st), (i)) +# define sk_CRYPTO_EX_DATA_FUNCS_delete_ptr(st, ptr) SKM_sk_delete_ptr(CRYPTO_EX_DATA_FUNCS, (st), (ptr)) +# define sk_CRYPTO_EX_DATA_FUNCS_insert(st, val, i) SKM_sk_insert(CRYPTO_EX_DATA_FUNCS, (st), (val), (i)) +# define sk_CRYPTO_EX_DATA_FUNCS_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CRYPTO_EX_DATA_FUNCS, (st), (cmp)) +# define sk_CRYPTO_EX_DATA_FUNCS_dup(st) SKM_sk_dup(CRYPTO_EX_DATA_FUNCS, st) +# define sk_CRYPTO_EX_DATA_FUNCS_pop_free(st, free_func) SKM_sk_pop_free(CRYPTO_EX_DATA_FUNCS, (st), (free_func)) +# define sk_CRYPTO_EX_DATA_FUNCS_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CRYPTO_EX_DATA_FUNCS, (st), (copy_func), (free_func)) +# define sk_CRYPTO_EX_DATA_FUNCS_shift(st) SKM_sk_shift(CRYPTO_EX_DATA_FUNCS, (st)) +# define sk_CRYPTO_EX_DATA_FUNCS_pop(st) SKM_sk_pop(CRYPTO_EX_DATA_FUNCS, (st)) +# define sk_CRYPTO_EX_DATA_FUNCS_sort(st) SKM_sk_sort(CRYPTO_EX_DATA_FUNCS, (st)) +# define sk_CRYPTO_EX_DATA_FUNCS_is_sorted(st) SKM_sk_is_sorted(CRYPTO_EX_DATA_FUNCS, (st)) +# define sk_CRYPTO_dynlock_new(cmp) SKM_sk_new(CRYPTO_dynlock, (cmp)) +# define sk_CRYPTO_dynlock_new_null() SKM_sk_new_null(CRYPTO_dynlock) +# define sk_CRYPTO_dynlock_free(st) SKM_sk_free(CRYPTO_dynlock, (st)) +# define sk_CRYPTO_dynlock_num(st) SKM_sk_num(CRYPTO_dynlock, (st)) +# define sk_CRYPTO_dynlock_value(st, i) SKM_sk_value(CRYPTO_dynlock, (st), (i)) +# define sk_CRYPTO_dynlock_set(st, i, val) SKM_sk_set(CRYPTO_dynlock, (st), (i), (val)) +# define sk_CRYPTO_dynlock_zero(st) SKM_sk_zero(CRYPTO_dynlock, (st)) +# define sk_CRYPTO_dynlock_push(st, val) SKM_sk_push(CRYPTO_dynlock, (st), (val)) +# define sk_CRYPTO_dynlock_unshift(st, val) SKM_sk_unshift(CRYPTO_dynlock, (st), (val)) +# define sk_CRYPTO_dynlock_find(st, val) SKM_sk_find(CRYPTO_dynlock, (st), (val)) +# define sk_CRYPTO_dynlock_find_ex(st, val) SKM_sk_find_ex(CRYPTO_dynlock, (st), (val)) +# define sk_CRYPTO_dynlock_delete(st, i) SKM_sk_delete(CRYPTO_dynlock, (st), (i)) +# define sk_CRYPTO_dynlock_delete_ptr(st, ptr) SKM_sk_delete_ptr(CRYPTO_dynlock, (st), (ptr)) +# define sk_CRYPTO_dynlock_insert(st, val, i) SKM_sk_insert(CRYPTO_dynlock, (st), (val), (i)) +# define sk_CRYPTO_dynlock_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CRYPTO_dynlock, (st), (cmp)) +# define sk_CRYPTO_dynlock_dup(st) SKM_sk_dup(CRYPTO_dynlock, st) +# define sk_CRYPTO_dynlock_pop_free(st, free_func) SKM_sk_pop_free(CRYPTO_dynlock, (st), (free_func)) +# define sk_CRYPTO_dynlock_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CRYPTO_dynlock, (st), (copy_func), (free_func)) +# define sk_CRYPTO_dynlock_shift(st) SKM_sk_shift(CRYPTO_dynlock, (st)) +# define sk_CRYPTO_dynlock_pop(st) SKM_sk_pop(CRYPTO_dynlock, (st)) +# define sk_CRYPTO_dynlock_sort(st) SKM_sk_sort(CRYPTO_dynlock, (st)) +# define sk_CRYPTO_dynlock_is_sorted(st) SKM_sk_is_sorted(CRYPTO_dynlock, (st)) +# define sk_DIST_POINT_new(cmp) SKM_sk_new(DIST_POINT, (cmp)) +# define sk_DIST_POINT_new_null() SKM_sk_new_null(DIST_POINT) +# define sk_DIST_POINT_free(st) SKM_sk_free(DIST_POINT, (st)) +# define sk_DIST_POINT_num(st) SKM_sk_num(DIST_POINT, (st)) +# define sk_DIST_POINT_value(st, i) SKM_sk_value(DIST_POINT, (st), (i)) +# define sk_DIST_POINT_set(st, i, val) SKM_sk_set(DIST_POINT, (st), (i), (val)) +# define sk_DIST_POINT_zero(st) SKM_sk_zero(DIST_POINT, (st)) +# define sk_DIST_POINT_push(st, val) SKM_sk_push(DIST_POINT, (st), (val)) +# define sk_DIST_POINT_unshift(st, val) SKM_sk_unshift(DIST_POINT, (st), (val)) +# define sk_DIST_POINT_find(st, val) SKM_sk_find(DIST_POINT, (st), (val)) +# define sk_DIST_POINT_find_ex(st, val) SKM_sk_find_ex(DIST_POINT, (st), (val)) +# define sk_DIST_POINT_delete(st, i) SKM_sk_delete(DIST_POINT, (st), (i)) +# define sk_DIST_POINT_delete_ptr(st, ptr) SKM_sk_delete_ptr(DIST_POINT, (st), (ptr)) +# define sk_DIST_POINT_insert(st, val, i) SKM_sk_insert(DIST_POINT, (st), (val), (i)) +# define sk_DIST_POINT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(DIST_POINT, (st), (cmp)) +# define sk_DIST_POINT_dup(st) SKM_sk_dup(DIST_POINT, st) +# define sk_DIST_POINT_pop_free(st, free_func) SKM_sk_pop_free(DIST_POINT, (st), (free_func)) +# define sk_DIST_POINT_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(DIST_POINT, (st), (copy_func), (free_func)) +# define sk_DIST_POINT_shift(st) SKM_sk_shift(DIST_POINT, (st)) +# define sk_DIST_POINT_pop(st) SKM_sk_pop(DIST_POINT, (st)) +# define sk_DIST_POINT_sort(st) SKM_sk_sort(DIST_POINT, (st)) +# define sk_DIST_POINT_is_sorted(st) SKM_sk_is_sorted(DIST_POINT, (st)) +# define sk_ENGINE_new(cmp) SKM_sk_new(ENGINE, (cmp)) +# define sk_ENGINE_new_null() SKM_sk_new_null(ENGINE) +# define sk_ENGINE_free(st) SKM_sk_free(ENGINE, (st)) +# define sk_ENGINE_num(st) SKM_sk_num(ENGINE, (st)) +# define sk_ENGINE_value(st, i) SKM_sk_value(ENGINE, (st), (i)) +# define sk_ENGINE_set(st, i, val) SKM_sk_set(ENGINE, (st), (i), (val)) +# define sk_ENGINE_zero(st) SKM_sk_zero(ENGINE, (st)) +# define sk_ENGINE_push(st, val) SKM_sk_push(ENGINE, (st), (val)) +# define sk_ENGINE_unshift(st, val) SKM_sk_unshift(ENGINE, (st), (val)) +# define sk_ENGINE_find(st, val) SKM_sk_find(ENGINE, (st), (val)) +# define sk_ENGINE_find_ex(st, val) SKM_sk_find_ex(ENGINE, (st), (val)) +# define sk_ENGINE_delete(st, i) SKM_sk_delete(ENGINE, (st), (i)) +# define sk_ENGINE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ENGINE, (st), (ptr)) +# define sk_ENGINE_insert(st, val, i) SKM_sk_insert(ENGINE, (st), (val), (i)) +# define sk_ENGINE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ENGINE, (st), (cmp)) +# define sk_ENGINE_dup(st) SKM_sk_dup(ENGINE, st) +# define sk_ENGINE_pop_free(st, free_func) SKM_sk_pop_free(ENGINE, (st), (free_func)) +# define sk_ENGINE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ENGINE, (st), (copy_func), (free_func)) +# define sk_ENGINE_shift(st) SKM_sk_shift(ENGINE, (st)) +# define sk_ENGINE_pop(st) SKM_sk_pop(ENGINE, (st)) +# define sk_ENGINE_sort(st) SKM_sk_sort(ENGINE, (st)) +# define sk_ENGINE_is_sorted(st) SKM_sk_is_sorted(ENGINE, (st)) +# define sk_ENGINE_CLEANUP_ITEM_new(cmp) SKM_sk_new(ENGINE_CLEANUP_ITEM, (cmp)) +# define sk_ENGINE_CLEANUP_ITEM_new_null() SKM_sk_new_null(ENGINE_CLEANUP_ITEM) +# define sk_ENGINE_CLEANUP_ITEM_free(st) SKM_sk_free(ENGINE_CLEANUP_ITEM, (st)) +# define sk_ENGINE_CLEANUP_ITEM_num(st) SKM_sk_num(ENGINE_CLEANUP_ITEM, (st)) +# define sk_ENGINE_CLEANUP_ITEM_value(st, i) SKM_sk_value(ENGINE_CLEANUP_ITEM, (st), (i)) +# define sk_ENGINE_CLEANUP_ITEM_set(st, i, val) SKM_sk_set(ENGINE_CLEANUP_ITEM, (st), (i), (val)) +# define sk_ENGINE_CLEANUP_ITEM_zero(st) SKM_sk_zero(ENGINE_CLEANUP_ITEM, (st)) +# define sk_ENGINE_CLEANUP_ITEM_push(st, val) SKM_sk_push(ENGINE_CLEANUP_ITEM, (st), (val)) +# define sk_ENGINE_CLEANUP_ITEM_unshift(st, val) SKM_sk_unshift(ENGINE_CLEANUP_ITEM, (st), (val)) +# define sk_ENGINE_CLEANUP_ITEM_find(st, val) SKM_sk_find(ENGINE_CLEANUP_ITEM, (st), (val)) +# define sk_ENGINE_CLEANUP_ITEM_find_ex(st, val) SKM_sk_find_ex(ENGINE_CLEANUP_ITEM, (st), (val)) +# define sk_ENGINE_CLEANUP_ITEM_delete(st, i) SKM_sk_delete(ENGINE_CLEANUP_ITEM, (st), (i)) +# define sk_ENGINE_CLEANUP_ITEM_delete_ptr(st, ptr) SKM_sk_delete_ptr(ENGINE_CLEANUP_ITEM, (st), (ptr)) +# define sk_ENGINE_CLEANUP_ITEM_insert(st, val, i) SKM_sk_insert(ENGINE_CLEANUP_ITEM, (st), (val), (i)) +# define sk_ENGINE_CLEANUP_ITEM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ENGINE_CLEANUP_ITEM, (st), (cmp)) +# define sk_ENGINE_CLEANUP_ITEM_dup(st) SKM_sk_dup(ENGINE_CLEANUP_ITEM, st) +# define sk_ENGINE_CLEANUP_ITEM_pop_free(st, free_func) SKM_sk_pop_free(ENGINE_CLEANUP_ITEM, (st), (free_func)) +# define sk_ENGINE_CLEANUP_ITEM_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ENGINE_CLEANUP_ITEM, (st), (copy_func), (free_func)) +# define sk_ENGINE_CLEANUP_ITEM_shift(st) SKM_sk_shift(ENGINE_CLEANUP_ITEM, (st)) +# define sk_ENGINE_CLEANUP_ITEM_pop(st) SKM_sk_pop(ENGINE_CLEANUP_ITEM, (st)) +# define sk_ENGINE_CLEANUP_ITEM_sort(st) SKM_sk_sort(ENGINE_CLEANUP_ITEM, (st)) +# define sk_ENGINE_CLEANUP_ITEM_is_sorted(st) SKM_sk_is_sorted(ENGINE_CLEANUP_ITEM, (st)) +# define sk_ESS_CERT_ID_new(cmp) SKM_sk_new(ESS_CERT_ID, (cmp)) +# define sk_ESS_CERT_ID_new_null() SKM_sk_new_null(ESS_CERT_ID) +# define sk_ESS_CERT_ID_free(st) SKM_sk_free(ESS_CERT_ID, (st)) +# define sk_ESS_CERT_ID_num(st) SKM_sk_num(ESS_CERT_ID, (st)) +# define sk_ESS_CERT_ID_value(st, i) SKM_sk_value(ESS_CERT_ID, (st), (i)) +# define sk_ESS_CERT_ID_set(st, i, val) SKM_sk_set(ESS_CERT_ID, (st), (i), (val)) +# define sk_ESS_CERT_ID_zero(st) SKM_sk_zero(ESS_CERT_ID, (st)) +# define sk_ESS_CERT_ID_push(st, val) SKM_sk_push(ESS_CERT_ID, (st), (val)) +# define sk_ESS_CERT_ID_unshift(st, val) SKM_sk_unshift(ESS_CERT_ID, (st), (val)) +# define sk_ESS_CERT_ID_find(st, val) SKM_sk_find(ESS_CERT_ID, (st), (val)) +# define sk_ESS_CERT_ID_find_ex(st, val) SKM_sk_find_ex(ESS_CERT_ID, (st), (val)) +# define sk_ESS_CERT_ID_delete(st, i) SKM_sk_delete(ESS_CERT_ID, (st), (i)) +# define sk_ESS_CERT_ID_delete_ptr(st, ptr) SKM_sk_delete_ptr(ESS_CERT_ID, (st), (ptr)) +# define sk_ESS_CERT_ID_insert(st, val, i) SKM_sk_insert(ESS_CERT_ID, (st), (val), (i)) +# define sk_ESS_CERT_ID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ESS_CERT_ID, (st), (cmp)) +# define sk_ESS_CERT_ID_dup(st) SKM_sk_dup(ESS_CERT_ID, st) +# define sk_ESS_CERT_ID_pop_free(st, free_func) SKM_sk_pop_free(ESS_CERT_ID, (st), (free_func)) +# define sk_ESS_CERT_ID_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ESS_CERT_ID, (st), (copy_func), (free_func)) +# define sk_ESS_CERT_ID_shift(st) SKM_sk_shift(ESS_CERT_ID, (st)) +# define sk_ESS_CERT_ID_pop(st) SKM_sk_pop(ESS_CERT_ID, (st)) +# define sk_ESS_CERT_ID_sort(st) SKM_sk_sort(ESS_CERT_ID, (st)) +# define sk_ESS_CERT_ID_is_sorted(st) SKM_sk_is_sorted(ESS_CERT_ID, (st)) +# define sk_EVP_MD_new(cmp) SKM_sk_new(EVP_MD, (cmp)) +# define sk_EVP_MD_new_null() SKM_sk_new_null(EVP_MD) +# define sk_EVP_MD_free(st) SKM_sk_free(EVP_MD, (st)) +# define sk_EVP_MD_num(st) SKM_sk_num(EVP_MD, (st)) +# define sk_EVP_MD_value(st, i) SKM_sk_value(EVP_MD, (st), (i)) +# define sk_EVP_MD_set(st, i, val) SKM_sk_set(EVP_MD, (st), (i), (val)) +# define sk_EVP_MD_zero(st) SKM_sk_zero(EVP_MD, (st)) +# define sk_EVP_MD_push(st, val) SKM_sk_push(EVP_MD, (st), (val)) +# define sk_EVP_MD_unshift(st, val) SKM_sk_unshift(EVP_MD, (st), (val)) +# define sk_EVP_MD_find(st, val) SKM_sk_find(EVP_MD, (st), (val)) +# define sk_EVP_MD_find_ex(st, val) SKM_sk_find_ex(EVP_MD, (st), (val)) +# define sk_EVP_MD_delete(st, i) SKM_sk_delete(EVP_MD, (st), (i)) +# define sk_EVP_MD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_MD, (st), (ptr)) +# define sk_EVP_MD_insert(st, val, i) SKM_sk_insert(EVP_MD, (st), (val), (i)) +# define sk_EVP_MD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_MD, (st), (cmp)) +# define sk_EVP_MD_dup(st) SKM_sk_dup(EVP_MD, st) +# define sk_EVP_MD_pop_free(st, free_func) SKM_sk_pop_free(EVP_MD, (st), (free_func)) +# define sk_EVP_MD_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(EVP_MD, (st), (copy_func), (free_func)) +# define sk_EVP_MD_shift(st) SKM_sk_shift(EVP_MD, (st)) +# define sk_EVP_MD_pop(st) SKM_sk_pop(EVP_MD, (st)) +# define sk_EVP_MD_sort(st) SKM_sk_sort(EVP_MD, (st)) +# define sk_EVP_MD_is_sorted(st) SKM_sk_is_sorted(EVP_MD, (st)) +# define sk_EVP_PBE_CTL_new(cmp) SKM_sk_new(EVP_PBE_CTL, (cmp)) +# define sk_EVP_PBE_CTL_new_null() SKM_sk_new_null(EVP_PBE_CTL) +# define sk_EVP_PBE_CTL_free(st) SKM_sk_free(EVP_PBE_CTL, (st)) +# define sk_EVP_PBE_CTL_num(st) SKM_sk_num(EVP_PBE_CTL, (st)) +# define sk_EVP_PBE_CTL_value(st, i) SKM_sk_value(EVP_PBE_CTL, (st), (i)) +# define sk_EVP_PBE_CTL_set(st, i, val) SKM_sk_set(EVP_PBE_CTL, (st), (i), (val)) +# define sk_EVP_PBE_CTL_zero(st) SKM_sk_zero(EVP_PBE_CTL, (st)) +# define sk_EVP_PBE_CTL_push(st, val) SKM_sk_push(EVP_PBE_CTL, (st), (val)) +# define sk_EVP_PBE_CTL_unshift(st, val) SKM_sk_unshift(EVP_PBE_CTL, (st), (val)) +# define sk_EVP_PBE_CTL_find(st, val) SKM_sk_find(EVP_PBE_CTL, (st), (val)) +# define sk_EVP_PBE_CTL_find_ex(st, val) SKM_sk_find_ex(EVP_PBE_CTL, (st), (val)) +# define sk_EVP_PBE_CTL_delete(st, i) SKM_sk_delete(EVP_PBE_CTL, (st), (i)) +# define sk_EVP_PBE_CTL_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PBE_CTL, (st), (ptr)) +# define sk_EVP_PBE_CTL_insert(st, val, i) SKM_sk_insert(EVP_PBE_CTL, (st), (val), (i)) +# define sk_EVP_PBE_CTL_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PBE_CTL, (st), (cmp)) +# define sk_EVP_PBE_CTL_dup(st) SKM_sk_dup(EVP_PBE_CTL, st) +# define sk_EVP_PBE_CTL_pop_free(st, free_func) SKM_sk_pop_free(EVP_PBE_CTL, (st), (free_func)) +# define sk_EVP_PBE_CTL_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(EVP_PBE_CTL, (st), (copy_func), (free_func)) +# define sk_EVP_PBE_CTL_shift(st) SKM_sk_shift(EVP_PBE_CTL, (st)) +# define sk_EVP_PBE_CTL_pop(st) SKM_sk_pop(EVP_PBE_CTL, (st)) +# define sk_EVP_PBE_CTL_sort(st) SKM_sk_sort(EVP_PBE_CTL, (st)) +# define sk_EVP_PBE_CTL_is_sorted(st) SKM_sk_is_sorted(EVP_PBE_CTL, (st)) +# define sk_EVP_PKEY_ASN1_METHOD_new(cmp) SKM_sk_new(EVP_PKEY_ASN1_METHOD, (cmp)) +# define sk_EVP_PKEY_ASN1_METHOD_new_null() SKM_sk_new_null(EVP_PKEY_ASN1_METHOD) +# define sk_EVP_PKEY_ASN1_METHOD_free(st) SKM_sk_free(EVP_PKEY_ASN1_METHOD, (st)) +# define sk_EVP_PKEY_ASN1_METHOD_num(st) SKM_sk_num(EVP_PKEY_ASN1_METHOD, (st)) +# define sk_EVP_PKEY_ASN1_METHOD_value(st, i) SKM_sk_value(EVP_PKEY_ASN1_METHOD, (st), (i)) +# define sk_EVP_PKEY_ASN1_METHOD_set(st, i, val) SKM_sk_set(EVP_PKEY_ASN1_METHOD, (st), (i), (val)) +# define sk_EVP_PKEY_ASN1_METHOD_zero(st) SKM_sk_zero(EVP_PKEY_ASN1_METHOD, (st)) +# define sk_EVP_PKEY_ASN1_METHOD_push(st, val) SKM_sk_push(EVP_PKEY_ASN1_METHOD, (st), (val)) +# define sk_EVP_PKEY_ASN1_METHOD_unshift(st, val) SKM_sk_unshift(EVP_PKEY_ASN1_METHOD, (st), (val)) +# define sk_EVP_PKEY_ASN1_METHOD_find(st, val) SKM_sk_find(EVP_PKEY_ASN1_METHOD, (st), (val)) +# define sk_EVP_PKEY_ASN1_METHOD_find_ex(st, val) SKM_sk_find_ex(EVP_PKEY_ASN1_METHOD, (st), (val)) +# define sk_EVP_PKEY_ASN1_METHOD_delete(st, i) SKM_sk_delete(EVP_PKEY_ASN1_METHOD, (st), (i)) +# define sk_EVP_PKEY_ASN1_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PKEY_ASN1_METHOD, (st), (ptr)) +# define sk_EVP_PKEY_ASN1_METHOD_insert(st, val, i) SKM_sk_insert(EVP_PKEY_ASN1_METHOD, (st), (val), (i)) +# define sk_EVP_PKEY_ASN1_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PKEY_ASN1_METHOD, (st), (cmp)) +# define sk_EVP_PKEY_ASN1_METHOD_dup(st) SKM_sk_dup(EVP_PKEY_ASN1_METHOD, st) +# define sk_EVP_PKEY_ASN1_METHOD_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY_ASN1_METHOD, (st), (free_func)) +# define sk_EVP_PKEY_ASN1_METHOD_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(EVP_PKEY_ASN1_METHOD, (st), (copy_func), (free_func)) +# define sk_EVP_PKEY_ASN1_METHOD_shift(st) SKM_sk_shift(EVP_PKEY_ASN1_METHOD, (st)) +# define sk_EVP_PKEY_ASN1_METHOD_pop(st) SKM_sk_pop(EVP_PKEY_ASN1_METHOD, (st)) +# define sk_EVP_PKEY_ASN1_METHOD_sort(st) SKM_sk_sort(EVP_PKEY_ASN1_METHOD, (st)) +# define sk_EVP_PKEY_ASN1_METHOD_is_sorted(st) SKM_sk_is_sorted(EVP_PKEY_ASN1_METHOD, (st)) +# define sk_EVP_PKEY_METHOD_new(cmp) SKM_sk_new(EVP_PKEY_METHOD, (cmp)) +# define sk_EVP_PKEY_METHOD_new_null() SKM_sk_new_null(EVP_PKEY_METHOD) +# define sk_EVP_PKEY_METHOD_free(st) SKM_sk_free(EVP_PKEY_METHOD, (st)) +# define sk_EVP_PKEY_METHOD_num(st) SKM_sk_num(EVP_PKEY_METHOD, (st)) +# define sk_EVP_PKEY_METHOD_value(st, i) SKM_sk_value(EVP_PKEY_METHOD, (st), (i)) +# define sk_EVP_PKEY_METHOD_set(st, i, val) SKM_sk_set(EVP_PKEY_METHOD, (st), (i), (val)) +# define sk_EVP_PKEY_METHOD_zero(st) SKM_sk_zero(EVP_PKEY_METHOD, (st)) +# define sk_EVP_PKEY_METHOD_push(st, val) SKM_sk_push(EVP_PKEY_METHOD, (st), (val)) +# define sk_EVP_PKEY_METHOD_unshift(st, val) SKM_sk_unshift(EVP_PKEY_METHOD, (st), (val)) +# define sk_EVP_PKEY_METHOD_find(st, val) SKM_sk_find(EVP_PKEY_METHOD, (st), (val)) +# define sk_EVP_PKEY_METHOD_find_ex(st, val) SKM_sk_find_ex(EVP_PKEY_METHOD, (st), (val)) +# define sk_EVP_PKEY_METHOD_delete(st, i) SKM_sk_delete(EVP_PKEY_METHOD, (st), (i)) +# define sk_EVP_PKEY_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PKEY_METHOD, (st), (ptr)) +# define sk_EVP_PKEY_METHOD_insert(st, val, i) SKM_sk_insert(EVP_PKEY_METHOD, (st), (val), (i)) +# define sk_EVP_PKEY_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PKEY_METHOD, (st), (cmp)) +# define sk_EVP_PKEY_METHOD_dup(st) SKM_sk_dup(EVP_PKEY_METHOD, st) +# define sk_EVP_PKEY_METHOD_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY_METHOD, (st), (free_func)) +# define sk_EVP_PKEY_METHOD_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(EVP_PKEY_METHOD, (st), (copy_func), (free_func)) +# define sk_EVP_PKEY_METHOD_shift(st) SKM_sk_shift(EVP_PKEY_METHOD, (st)) +# define sk_EVP_PKEY_METHOD_pop(st) SKM_sk_pop(EVP_PKEY_METHOD, (st)) +# define sk_EVP_PKEY_METHOD_sort(st) SKM_sk_sort(EVP_PKEY_METHOD, (st)) +# define sk_EVP_PKEY_METHOD_is_sorted(st) SKM_sk_is_sorted(EVP_PKEY_METHOD, (st)) +# define sk_GENERAL_NAME_new(cmp) SKM_sk_new(GENERAL_NAME, (cmp)) +# define sk_GENERAL_NAME_new_null() SKM_sk_new_null(GENERAL_NAME) +# define sk_GENERAL_NAME_free(st) SKM_sk_free(GENERAL_NAME, (st)) +# define sk_GENERAL_NAME_num(st) SKM_sk_num(GENERAL_NAME, (st)) +# define sk_GENERAL_NAME_value(st, i) SKM_sk_value(GENERAL_NAME, (st), (i)) +# define sk_GENERAL_NAME_set(st, i, val) SKM_sk_set(GENERAL_NAME, (st), (i), (val)) +# define sk_GENERAL_NAME_zero(st) SKM_sk_zero(GENERAL_NAME, (st)) +# define sk_GENERAL_NAME_push(st, val) SKM_sk_push(GENERAL_NAME, (st), (val)) +# define sk_GENERAL_NAME_unshift(st, val) SKM_sk_unshift(GENERAL_NAME, (st), (val)) +# define sk_GENERAL_NAME_find(st, val) SKM_sk_find(GENERAL_NAME, (st), (val)) +# define sk_GENERAL_NAME_find_ex(st, val) SKM_sk_find_ex(GENERAL_NAME, (st), (val)) +# define sk_GENERAL_NAME_delete(st, i) SKM_sk_delete(GENERAL_NAME, (st), (i)) +# define sk_GENERAL_NAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_NAME, (st), (ptr)) +# define sk_GENERAL_NAME_insert(st, val, i) SKM_sk_insert(GENERAL_NAME, (st), (val), (i)) +# define sk_GENERAL_NAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_NAME, (st), (cmp)) +# define sk_GENERAL_NAME_dup(st) SKM_sk_dup(GENERAL_NAME, st) +# define sk_GENERAL_NAME_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_NAME, (st), (free_func)) +# define sk_GENERAL_NAME_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(GENERAL_NAME, (st), (copy_func), (free_func)) +# define sk_GENERAL_NAME_shift(st) SKM_sk_shift(GENERAL_NAME, (st)) +# define sk_GENERAL_NAME_pop(st) SKM_sk_pop(GENERAL_NAME, (st)) +# define sk_GENERAL_NAME_sort(st) SKM_sk_sort(GENERAL_NAME, (st)) +# define sk_GENERAL_NAME_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAME, (st)) +# define sk_GENERAL_NAMES_new(cmp) SKM_sk_new(GENERAL_NAMES, (cmp)) +# define sk_GENERAL_NAMES_new_null() SKM_sk_new_null(GENERAL_NAMES) +# define sk_GENERAL_NAMES_free(st) SKM_sk_free(GENERAL_NAMES, (st)) +# define sk_GENERAL_NAMES_num(st) SKM_sk_num(GENERAL_NAMES, (st)) +# define sk_GENERAL_NAMES_value(st, i) SKM_sk_value(GENERAL_NAMES, (st), (i)) +# define sk_GENERAL_NAMES_set(st, i, val) SKM_sk_set(GENERAL_NAMES, (st), (i), (val)) +# define sk_GENERAL_NAMES_zero(st) SKM_sk_zero(GENERAL_NAMES, (st)) +# define sk_GENERAL_NAMES_push(st, val) SKM_sk_push(GENERAL_NAMES, (st), (val)) +# define sk_GENERAL_NAMES_unshift(st, val) SKM_sk_unshift(GENERAL_NAMES, (st), (val)) +# define sk_GENERAL_NAMES_find(st, val) SKM_sk_find(GENERAL_NAMES, (st), (val)) +# define sk_GENERAL_NAMES_find_ex(st, val) SKM_sk_find_ex(GENERAL_NAMES, (st), (val)) +# define sk_GENERAL_NAMES_delete(st, i) SKM_sk_delete(GENERAL_NAMES, (st), (i)) +# define sk_GENERAL_NAMES_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_NAMES, (st), (ptr)) +# define sk_GENERAL_NAMES_insert(st, val, i) SKM_sk_insert(GENERAL_NAMES, (st), (val), (i)) +# define sk_GENERAL_NAMES_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_NAMES, (st), (cmp)) +# define sk_GENERAL_NAMES_dup(st) SKM_sk_dup(GENERAL_NAMES, st) +# define sk_GENERAL_NAMES_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_NAMES, (st), (free_func)) +# define sk_GENERAL_NAMES_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(GENERAL_NAMES, (st), (copy_func), (free_func)) +# define sk_GENERAL_NAMES_shift(st) SKM_sk_shift(GENERAL_NAMES, (st)) +# define sk_GENERAL_NAMES_pop(st) SKM_sk_pop(GENERAL_NAMES, (st)) +# define sk_GENERAL_NAMES_sort(st) SKM_sk_sort(GENERAL_NAMES, (st)) +# define sk_GENERAL_NAMES_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAMES, (st)) +# define sk_GENERAL_SUBTREE_new(cmp) SKM_sk_new(GENERAL_SUBTREE, (cmp)) +# define sk_GENERAL_SUBTREE_new_null() SKM_sk_new_null(GENERAL_SUBTREE) +# define sk_GENERAL_SUBTREE_free(st) SKM_sk_free(GENERAL_SUBTREE, (st)) +# define sk_GENERAL_SUBTREE_num(st) SKM_sk_num(GENERAL_SUBTREE, (st)) +# define sk_GENERAL_SUBTREE_value(st, i) SKM_sk_value(GENERAL_SUBTREE, (st), (i)) +# define sk_GENERAL_SUBTREE_set(st, i, val) SKM_sk_set(GENERAL_SUBTREE, (st), (i), (val)) +# define sk_GENERAL_SUBTREE_zero(st) SKM_sk_zero(GENERAL_SUBTREE, (st)) +# define sk_GENERAL_SUBTREE_push(st, val) SKM_sk_push(GENERAL_SUBTREE, (st), (val)) +# define sk_GENERAL_SUBTREE_unshift(st, val) SKM_sk_unshift(GENERAL_SUBTREE, (st), (val)) +# define sk_GENERAL_SUBTREE_find(st, val) SKM_sk_find(GENERAL_SUBTREE, (st), (val)) +# define sk_GENERAL_SUBTREE_find_ex(st, val) SKM_sk_find_ex(GENERAL_SUBTREE, (st), (val)) +# define sk_GENERAL_SUBTREE_delete(st, i) SKM_sk_delete(GENERAL_SUBTREE, (st), (i)) +# define sk_GENERAL_SUBTREE_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_SUBTREE, (st), (ptr)) +# define sk_GENERAL_SUBTREE_insert(st, val, i) SKM_sk_insert(GENERAL_SUBTREE, (st), (val), (i)) +# define sk_GENERAL_SUBTREE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_SUBTREE, (st), (cmp)) +# define sk_GENERAL_SUBTREE_dup(st) SKM_sk_dup(GENERAL_SUBTREE, st) +# define sk_GENERAL_SUBTREE_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_SUBTREE, (st), (free_func)) +# define sk_GENERAL_SUBTREE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(GENERAL_SUBTREE, (st), (copy_func), (free_func)) +# define sk_GENERAL_SUBTREE_shift(st) SKM_sk_shift(GENERAL_SUBTREE, (st)) +# define sk_GENERAL_SUBTREE_pop(st) SKM_sk_pop(GENERAL_SUBTREE, (st)) +# define sk_GENERAL_SUBTREE_sort(st) SKM_sk_sort(GENERAL_SUBTREE, (st)) +# define sk_GENERAL_SUBTREE_is_sorted(st) SKM_sk_is_sorted(GENERAL_SUBTREE, (st)) +# define sk_IPAddressFamily_new(cmp) SKM_sk_new(IPAddressFamily, (cmp)) +# define sk_IPAddressFamily_new_null() SKM_sk_new_null(IPAddressFamily) +# define sk_IPAddressFamily_free(st) SKM_sk_free(IPAddressFamily, (st)) +# define sk_IPAddressFamily_num(st) SKM_sk_num(IPAddressFamily, (st)) +# define sk_IPAddressFamily_value(st, i) SKM_sk_value(IPAddressFamily, (st), (i)) +# define sk_IPAddressFamily_set(st, i, val) SKM_sk_set(IPAddressFamily, (st), (i), (val)) +# define sk_IPAddressFamily_zero(st) SKM_sk_zero(IPAddressFamily, (st)) +# define sk_IPAddressFamily_push(st, val) SKM_sk_push(IPAddressFamily, (st), (val)) +# define sk_IPAddressFamily_unshift(st, val) SKM_sk_unshift(IPAddressFamily, (st), (val)) +# define sk_IPAddressFamily_find(st, val) SKM_sk_find(IPAddressFamily, (st), (val)) +# define sk_IPAddressFamily_find_ex(st, val) SKM_sk_find_ex(IPAddressFamily, (st), (val)) +# define sk_IPAddressFamily_delete(st, i) SKM_sk_delete(IPAddressFamily, (st), (i)) +# define sk_IPAddressFamily_delete_ptr(st, ptr) SKM_sk_delete_ptr(IPAddressFamily, (st), (ptr)) +# define sk_IPAddressFamily_insert(st, val, i) SKM_sk_insert(IPAddressFamily, (st), (val), (i)) +# define sk_IPAddressFamily_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(IPAddressFamily, (st), (cmp)) +# define sk_IPAddressFamily_dup(st) SKM_sk_dup(IPAddressFamily, st) +# define sk_IPAddressFamily_pop_free(st, free_func) SKM_sk_pop_free(IPAddressFamily, (st), (free_func)) +# define sk_IPAddressFamily_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(IPAddressFamily, (st), (copy_func), (free_func)) +# define sk_IPAddressFamily_shift(st) SKM_sk_shift(IPAddressFamily, (st)) +# define sk_IPAddressFamily_pop(st) SKM_sk_pop(IPAddressFamily, (st)) +# define sk_IPAddressFamily_sort(st) SKM_sk_sort(IPAddressFamily, (st)) +# define sk_IPAddressFamily_is_sorted(st) SKM_sk_is_sorted(IPAddressFamily, (st)) +# define sk_IPAddressOrRange_new(cmp) SKM_sk_new(IPAddressOrRange, (cmp)) +# define sk_IPAddressOrRange_new_null() SKM_sk_new_null(IPAddressOrRange) +# define sk_IPAddressOrRange_free(st) SKM_sk_free(IPAddressOrRange, (st)) +# define sk_IPAddressOrRange_num(st) SKM_sk_num(IPAddressOrRange, (st)) +# define sk_IPAddressOrRange_value(st, i) SKM_sk_value(IPAddressOrRange, (st), (i)) +# define sk_IPAddressOrRange_set(st, i, val) SKM_sk_set(IPAddressOrRange, (st), (i), (val)) +# define sk_IPAddressOrRange_zero(st) SKM_sk_zero(IPAddressOrRange, (st)) +# define sk_IPAddressOrRange_push(st, val) SKM_sk_push(IPAddressOrRange, (st), (val)) +# define sk_IPAddressOrRange_unshift(st, val) SKM_sk_unshift(IPAddressOrRange, (st), (val)) +# define sk_IPAddressOrRange_find(st, val) SKM_sk_find(IPAddressOrRange, (st), (val)) +# define sk_IPAddressOrRange_find_ex(st, val) SKM_sk_find_ex(IPAddressOrRange, (st), (val)) +# define sk_IPAddressOrRange_delete(st, i) SKM_sk_delete(IPAddressOrRange, (st), (i)) +# define sk_IPAddressOrRange_delete_ptr(st, ptr) SKM_sk_delete_ptr(IPAddressOrRange, (st), (ptr)) +# define sk_IPAddressOrRange_insert(st, val, i) SKM_sk_insert(IPAddressOrRange, (st), (val), (i)) +# define sk_IPAddressOrRange_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(IPAddressOrRange, (st), (cmp)) +# define sk_IPAddressOrRange_dup(st) SKM_sk_dup(IPAddressOrRange, st) +# define sk_IPAddressOrRange_pop_free(st, free_func) SKM_sk_pop_free(IPAddressOrRange, (st), (free_func)) +# define sk_IPAddressOrRange_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(IPAddressOrRange, (st), (copy_func), (free_func)) +# define sk_IPAddressOrRange_shift(st) SKM_sk_shift(IPAddressOrRange, (st)) +# define sk_IPAddressOrRange_pop(st) SKM_sk_pop(IPAddressOrRange, (st)) +# define sk_IPAddressOrRange_sort(st) SKM_sk_sort(IPAddressOrRange, (st)) +# define sk_IPAddressOrRange_is_sorted(st) SKM_sk_is_sorted(IPAddressOrRange, (st)) +# define sk_KRB5_APREQBODY_new(cmp) SKM_sk_new(KRB5_APREQBODY, (cmp)) +# define sk_KRB5_APREQBODY_new_null() SKM_sk_new_null(KRB5_APREQBODY) +# define sk_KRB5_APREQBODY_free(st) SKM_sk_free(KRB5_APREQBODY, (st)) +# define sk_KRB5_APREQBODY_num(st) SKM_sk_num(KRB5_APREQBODY, (st)) +# define sk_KRB5_APREQBODY_value(st, i) SKM_sk_value(KRB5_APREQBODY, (st), (i)) +# define sk_KRB5_APREQBODY_set(st, i, val) SKM_sk_set(KRB5_APREQBODY, (st), (i), (val)) +# define sk_KRB5_APREQBODY_zero(st) SKM_sk_zero(KRB5_APREQBODY, (st)) +# define sk_KRB5_APREQBODY_push(st, val) SKM_sk_push(KRB5_APREQBODY, (st), (val)) +# define sk_KRB5_APREQBODY_unshift(st, val) SKM_sk_unshift(KRB5_APREQBODY, (st), (val)) +# define sk_KRB5_APREQBODY_find(st, val) SKM_sk_find(KRB5_APREQBODY, (st), (val)) +# define sk_KRB5_APREQBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_APREQBODY, (st), (val)) +# define sk_KRB5_APREQBODY_delete(st, i) SKM_sk_delete(KRB5_APREQBODY, (st), (i)) +# define sk_KRB5_APREQBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_APREQBODY, (st), (ptr)) +# define sk_KRB5_APREQBODY_insert(st, val, i) SKM_sk_insert(KRB5_APREQBODY, (st), (val), (i)) +# define sk_KRB5_APREQBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_APREQBODY, (st), (cmp)) +# define sk_KRB5_APREQBODY_dup(st) SKM_sk_dup(KRB5_APREQBODY, st) +# define sk_KRB5_APREQBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_APREQBODY, (st), (free_func)) +# define sk_KRB5_APREQBODY_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_APREQBODY, (st), (copy_func), (free_func)) +# define sk_KRB5_APREQBODY_shift(st) SKM_sk_shift(KRB5_APREQBODY, (st)) +# define sk_KRB5_APREQBODY_pop(st) SKM_sk_pop(KRB5_APREQBODY, (st)) +# define sk_KRB5_APREQBODY_sort(st) SKM_sk_sort(KRB5_APREQBODY, (st)) +# define sk_KRB5_APREQBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_APREQBODY, (st)) +# define sk_KRB5_AUTHDATA_new(cmp) SKM_sk_new(KRB5_AUTHDATA, (cmp)) +# define sk_KRB5_AUTHDATA_new_null() SKM_sk_new_null(KRB5_AUTHDATA) +# define sk_KRB5_AUTHDATA_free(st) SKM_sk_free(KRB5_AUTHDATA, (st)) +# define sk_KRB5_AUTHDATA_num(st) SKM_sk_num(KRB5_AUTHDATA, (st)) +# define sk_KRB5_AUTHDATA_value(st, i) SKM_sk_value(KRB5_AUTHDATA, (st), (i)) +# define sk_KRB5_AUTHDATA_set(st, i, val) SKM_sk_set(KRB5_AUTHDATA, (st), (i), (val)) +# define sk_KRB5_AUTHDATA_zero(st) SKM_sk_zero(KRB5_AUTHDATA, (st)) +# define sk_KRB5_AUTHDATA_push(st, val) SKM_sk_push(KRB5_AUTHDATA, (st), (val)) +# define sk_KRB5_AUTHDATA_unshift(st, val) SKM_sk_unshift(KRB5_AUTHDATA, (st), (val)) +# define sk_KRB5_AUTHDATA_find(st, val) SKM_sk_find(KRB5_AUTHDATA, (st), (val)) +# define sk_KRB5_AUTHDATA_find_ex(st, val) SKM_sk_find_ex(KRB5_AUTHDATA, (st), (val)) +# define sk_KRB5_AUTHDATA_delete(st, i) SKM_sk_delete(KRB5_AUTHDATA, (st), (i)) +# define sk_KRB5_AUTHDATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_AUTHDATA, (st), (ptr)) +# define sk_KRB5_AUTHDATA_insert(st, val, i) SKM_sk_insert(KRB5_AUTHDATA, (st), (val), (i)) +# define sk_KRB5_AUTHDATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_AUTHDATA, (st), (cmp)) +# define sk_KRB5_AUTHDATA_dup(st) SKM_sk_dup(KRB5_AUTHDATA, st) +# define sk_KRB5_AUTHDATA_pop_free(st, free_func) SKM_sk_pop_free(KRB5_AUTHDATA, (st), (free_func)) +# define sk_KRB5_AUTHDATA_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_AUTHDATA, (st), (copy_func), (free_func)) +# define sk_KRB5_AUTHDATA_shift(st) SKM_sk_shift(KRB5_AUTHDATA, (st)) +# define sk_KRB5_AUTHDATA_pop(st) SKM_sk_pop(KRB5_AUTHDATA, (st)) +# define sk_KRB5_AUTHDATA_sort(st) SKM_sk_sort(KRB5_AUTHDATA, (st)) +# define sk_KRB5_AUTHDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHDATA, (st)) +# define sk_KRB5_AUTHENTBODY_new(cmp) SKM_sk_new(KRB5_AUTHENTBODY, (cmp)) +# define sk_KRB5_AUTHENTBODY_new_null() SKM_sk_new_null(KRB5_AUTHENTBODY) +# define sk_KRB5_AUTHENTBODY_free(st) SKM_sk_free(KRB5_AUTHENTBODY, (st)) +# define sk_KRB5_AUTHENTBODY_num(st) SKM_sk_num(KRB5_AUTHENTBODY, (st)) +# define sk_KRB5_AUTHENTBODY_value(st, i) SKM_sk_value(KRB5_AUTHENTBODY, (st), (i)) +# define sk_KRB5_AUTHENTBODY_set(st, i, val) SKM_sk_set(KRB5_AUTHENTBODY, (st), (i), (val)) +# define sk_KRB5_AUTHENTBODY_zero(st) SKM_sk_zero(KRB5_AUTHENTBODY, (st)) +# define sk_KRB5_AUTHENTBODY_push(st, val) SKM_sk_push(KRB5_AUTHENTBODY, (st), (val)) +# define sk_KRB5_AUTHENTBODY_unshift(st, val) SKM_sk_unshift(KRB5_AUTHENTBODY, (st), (val)) +# define sk_KRB5_AUTHENTBODY_find(st, val) SKM_sk_find(KRB5_AUTHENTBODY, (st), (val)) +# define sk_KRB5_AUTHENTBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_AUTHENTBODY, (st), (val)) +# define sk_KRB5_AUTHENTBODY_delete(st, i) SKM_sk_delete(KRB5_AUTHENTBODY, (st), (i)) +# define sk_KRB5_AUTHENTBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_AUTHENTBODY, (st), (ptr)) +# define sk_KRB5_AUTHENTBODY_insert(st, val, i) SKM_sk_insert(KRB5_AUTHENTBODY, (st), (val), (i)) +# define sk_KRB5_AUTHENTBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_AUTHENTBODY, (st), (cmp)) +# define sk_KRB5_AUTHENTBODY_dup(st) SKM_sk_dup(KRB5_AUTHENTBODY, st) +# define sk_KRB5_AUTHENTBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_AUTHENTBODY, (st), (free_func)) +# define sk_KRB5_AUTHENTBODY_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_AUTHENTBODY, (st), (copy_func), (free_func)) +# define sk_KRB5_AUTHENTBODY_shift(st) SKM_sk_shift(KRB5_AUTHENTBODY, (st)) +# define sk_KRB5_AUTHENTBODY_pop(st) SKM_sk_pop(KRB5_AUTHENTBODY, (st)) +# define sk_KRB5_AUTHENTBODY_sort(st) SKM_sk_sort(KRB5_AUTHENTBODY, (st)) +# define sk_KRB5_AUTHENTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHENTBODY, (st)) +# define sk_KRB5_CHECKSUM_new(cmp) SKM_sk_new(KRB5_CHECKSUM, (cmp)) +# define sk_KRB5_CHECKSUM_new_null() SKM_sk_new_null(KRB5_CHECKSUM) +# define sk_KRB5_CHECKSUM_free(st) SKM_sk_free(KRB5_CHECKSUM, (st)) +# define sk_KRB5_CHECKSUM_num(st) SKM_sk_num(KRB5_CHECKSUM, (st)) +# define sk_KRB5_CHECKSUM_value(st, i) SKM_sk_value(KRB5_CHECKSUM, (st), (i)) +# define sk_KRB5_CHECKSUM_set(st, i, val) SKM_sk_set(KRB5_CHECKSUM, (st), (i), (val)) +# define sk_KRB5_CHECKSUM_zero(st) SKM_sk_zero(KRB5_CHECKSUM, (st)) +# define sk_KRB5_CHECKSUM_push(st, val) SKM_sk_push(KRB5_CHECKSUM, (st), (val)) +# define sk_KRB5_CHECKSUM_unshift(st, val) SKM_sk_unshift(KRB5_CHECKSUM, (st), (val)) +# define sk_KRB5_CHECKSUM_find(st, val) SKM_sk_find(KRB5_CHECKSUM, (st), (val)) +# define sk_KRB5_CHECKSUM_find_ex(st, val) SKM_sk_find_ex(KRB5_CHECKSUM, (st), (val)) +# define sk_KRB5_CHECKSUM_delete(st, i) SKM_sk_delete(KRB5_CHECKSUM, (st), (i)) +# define sk_KRB5_CHECKSUM_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_CHECKSUM, (st), (ptr)) +# define sk_KRB5_CHECKSUM_insert(st, val, i) SKM_sk_insert(KRB5_CHECKSUM, (st), (val), (i)) +# define sk_KRB5_CHECKSUM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_CHECKSUM, (st), (cmp)) +# define sk_KRB5_CHECKSUM_dup(st) SKM_sk_dup(KRB5_CHECKSUM, st) +# define sk_KRB5_CHECKSUM_pop_free(st, free_func) SKM_sk_pop_free(KRB5_CHECKSUM, (st), (free_func)) +# define sk_KRB5_CHECKSUM_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_CHECKSUM, (st), (copy_func), (free_func)) +# define sk_KRB5_CHECKSUM_shift(st) SKM_sk_shift(KRB5_CHECKSUM, (st)) +# define sk_KRB5_CHECKSUM_pop(st) SKM_sk_pop(KRB5_CHECKSUM, (st)) +# define sk_KRB5_CHECKSUM_sort(st) SKM_sk_sort(KRB5_CHECKSUM, (st)) +# define sk_KRB5_CHECKSUM_is_sorted(st) SKM_sk_is_sorted(KRB5_CHECKSUM, (st)) +# define sk_KRB5_ENCDATA_new(cmp) SKM_sk_new(KRB5_ENCDATA, (cmp)) +# define sk_KRB5_ENCDATA_new_null() SKM_sk_new_null(KRB5_ENCDATA) +# define sk_KRB5_ENCDATA_free(st) SKM_sk_free(KRB5_ENCDATA, (st)) +# define sk_KRB5_ENCDATA_num(st) SKM_sk_num(KRB5_ENCDATA, (st)) +# define sk_KRB5_ENCDATA_value(st, i) SKM_sk_value(KRB5_ENCDATA, (st), (i)) +# define sk_KRB5_ENCDATA_set(st, i, val) SKM_sk_set(KRB5_ENCDATA, (st), (i), (val)) +# define sk_KRB5_ENCDATA_zero(st) SKM_sk_zero(KRB5_ENCDATA, (st)) +# define sk_KRB5_ENCDATA_push(st, val) SKM_sk_push(KRB5_ENCDATA, (st), (val)) +# define sk_KRB5_ENCDATA_unshift(st, val) SKM_sk_unshift(KRB5_ENCDATA, (st), (val)) +# define sk_KRB5_ENCDATA_find(st, val) SKM_sk_find(KRB5_ENCDATA, (st), (val)) +# define sk_KRB5_ENCDATA_find_ex(st, val) SKM_sk_find_ex(KRB5_ENCDATA, (st), (val)) +# define sk_KRB5_ENCDATA_delete(st, i) SKM_sk_delete(KRB5_ENCDATA, (st), (i)) +# define sk_KRB5_ENCDATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_ENCDATA, (st), (ptr)) +# define sk_KRB5_ENCDATA_insert(st, val, i) SKM_sk_insert(KRB5_ENCDATA, (st), (val), (i)) +# define sk_KRB5_ENCDATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_ENCDATA, (st), (cmp)) +# define sk_KRB5_ENCDATA_dup(st) SKM_sk_dup(KRB5_ENCDATA, st) +# define sk_KRB5_ENCDATA_pop_free(st, free_func) SKM_sk_pop_free(KRB5_ENCDATA, (st), (free_func)) +# define sk_KRB5_ENCDATA_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_ENCDATA, (st), (copy_func), (free_func)) +# define sk_KRB5_ENCDATA_shift(st) SKM_sk_shift(KRB5_ENCDATA, (st)) +# define sk_KRB5_ENCDATA_pop(st) SKM_sk_pop(KRB5_ENCDATA, (st)) +# define sk_KRB5_ENCDATA_sort(st) SKM_sk_sort(KRB5_ENCDATA, (st)) +# define sk_KRB5_ENCDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCDATA, (st)) +# define sk_KRB5_ENCKEY_new(cmp) SKM_sk_new(KRB5_ENCKEY, (cmp)) +# define sk_KRB5_ENCKEY_new_null() SKM_sk_new_null(KRB5_ENCKEY) +# define sk_KRB5_ENCKEY_free(st) SKM_sk_free(KRB5_ENCKEY, (st)) +# define sk_KRB5_ENCKEY_num(st) SKM_sk_num(KRB5_ENCKEY, (st)) +# define sk_KRB5_ENCKEY_value(st, i) SKM_sk_value(KRB5_ENCKEY, (st), (i)) +# define sk_KRB5_ENCKEY_set(st, i, val) SKM_sk_set(KRB5_ENCKEY, (st), (i), (val)) +# define sk_KRB5_ENCKEY_zero(st) SKM_sk_zero(KRB5_ENCKEY, (st)) +# define sk_KRB5_ENCKEY_push(st, val) SKM_sk_push(KRB5_ENCKEY, (st), (val)) +# define sk_KRB5_ENCKEY_unshift(st, val) SKM_sk_unshift(KRB5_ENCKEY, (st), (val)) +# define sk_KRB5_ENCKEY_find(st, val) SKM_sk_find(KRB5_ENCKEY, (st), (val)) +# define sk_KRB5_ENCKEY_find_ex(st, val) SKM_sk_find_ex(KRB5_ENCKEY, (st), (val)) +# define sk_KRB5_ENCKEY_delete(st, i) SKM_sk_delete(KRB5_ENCKEY, (st), (i)) +# define sk_KRB5_ENCKEY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_ENCKEY, (st), (ptr)) +# define sk_KRB5_ENCKEY_insert(st, val, i) SKM_sk_insert(KRB5_ENCKEY, (st), (val), (i)) +# define sk_KRB5_ENCKEY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_ENCKEY, (st), (cmp)) +# define sk_KRB5_ENCKEY_dup(st) SKM_sk_dup(KRB5_ENCKEY, st) +# define sk_KRB5_ENCKEY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_ENCKEY, (st), (free_func)) +# define sk_KRB5_ENCKEY_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_ENCKEY, (st), (copy_func), (free_func)) +# define sk_KRB5_ENCKEY_shift(st) SKM_sk_shift(KRB5_ENCKEY, (st)) +# define sk_KRB5_ENCKEY_pop(st) SKM_sk_pop(KRB5_ENCKEY, (st)) +# define sk_KRB5_ENCKEY_sort(st) SKM_sk_sort(KRB5_ENCKEY, (st)) +# define sk_KRB5_ENCKEY_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCKEY, (st)) +# define sk_KRB5_PRINCNAME_new(cmp) SKM_sk_new(KRB5_PRINCNAME, (cmp)) +# define sk_KRB5_PRINCNAME_new_null() SKM_sk_new_null(KRB5_PRINCNAME) +# define sk_KRB5_PRINCNAME_free(st) SKM_sk_free(KRB5_PRINCNAME, (st)) +# define sk_KRB5_PRINCNAME_num(st) SKM_sk_num(KRB5_PRINCNAME, (st)) +# define sk_KRB5_PRINCNAME_value(st, i) SKM_sk_value(KRB5_PRINCNAME, (st), (i)) +# define sk_KRB5_PRINCNAME_set(st, i, val) SKM_sk_set(KRB5_PRINCNAME, (st), (i), (val)) +# define sk_KRB5_PRINCNAME_zero(st) SKM_sk_zero(KRB5_PRINCNAME, (st)) +# define sk_KRB5_PRINCNAME_push(st, val) SKM_sk_push(KRB5_PRINCNAME, (st), (val)) +# define sk_KRB5_PRINCNAME_unshift(st, val) SKM_sk_unshift(KRB5_PRINCNAME, (st), (val)) +# define sk_KRB5_PRINCNAME_find(st, val) SKM_sk_find(KRB5_PRINCNAME, (st), (val)) +# define sk_KRB5_PRINCNAME_find_ex(st, val) SKM_sk_find_ex(KRB5_PRINCNAME, (st), (val)) +# define sk_KRB5_PRINCNAME_delete(st, i) SKM_sk_delete(KRB5_PRINCNAME, (st), (i)) +# define sk_KRB5_PRINCNAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_PRINCNAME, (st), (ptr)) +# define sk_KRB5_PRINCNAME_insert(st, val, i) SKM_sk_insert(KRB5_PRINCNAME, (st), (val), (i)) +# define sk_KRB5_PRINCNAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_PRINCNAME, (st), (cmp)) +# define sk_KRB5_PRINCNAME_dup(st) SKM_sk_dup(KRB5_PRINCNAME, st) +# define sk_KRB5_PRINCNAME_pop_free(st, free_func) SKM_sk_pop_free(KRB5_PRINCNAME, (st), (free_func)) +# define sk_KRB5_PRINCNAME_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_PRINCNAME, (st), (copy_func), (free_func)) +# define sk_KRB5_PRINCNAME_shift(st) SKM_sk_shift(KRB5_PRINCNAME, (st)) +# define sk_KRB5_PRINCNAME_pop(st) SKM_sk_pop(KRB5_PRINCNAME, (st)) +# define sk_KRB5_PRINCNAME_sort(st) SKM_sk_sort(KRB5_PRINCNAME, (st)) +# define sk_KRB5_PRINCNAME_is_sorted(st) SKM_sk_is_sorted(KRB5_PRINCNAME, (st)) +# define sk_KRB5_TKTBODY_new(cmp) SKM_sk_new(KRB5_TKTBODY, (cmp)) +# define sk_KRB5_TKTBODY_new_null() SKM_sk_new_null(KRB5_TKTBODY) +# define sk_KRB5_TKTBODY_free(st) SKM_sk_free(KRB5_TKTBODY, (st)) +# define sk_KRB5_TKTBODY_num(st) SKM_sk_num(KRB5_TKTBODY, (st)) +# define sk_KRB5_TKTBODY_value(st, i) SKM_sk_value(KRB5_TKTBODY, (st), (i)) +# define sk_KRB5_TKTBODY_set(st, i, val) SKM_sk_set(KRB5_TKTBODY, (st), (i), (val)) +# define sk_KRB5_TKTBODY_zero(st) SKM_sk_zero(KRB5_TKTBODY, (st)) +# define sk_KRB5_TKTBODY_push(st, val) SKM_sk_push(KRB5_TKTBODY, (st), (val)) +# define sk_KRB5_TKTBODY_unshift(st, val) SKM_sk_unshift(KRB5_TKTBODY, (st), (val)) +# define sk_KRB5_TKTBODY_find(st, val) SKM_sk_find(KRB5_TKTBODY, (st), (val)) +# define sk_KRB5_TKTBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_TKTBODY, (st), (val)) +# define sk_KRB5_TKTBODY_delete(st, i) SKM_sk_delete(KRB5_TKTBODY, (st), (i)) +# define sk_KRB5_TKTBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_TKTBODY, (st), (ptr)) +# define sk_KRB5_TKTBODY_insert(st, val, i) SKM_sk_insert(KRB5_TKTBODY, (st), (val), (i)) +# define sk_KRB5_TKTBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_TKTBODY, (st), (cmp)) +# define sk_KRB5_TKTBODY_dup(st) SKM_sk_dup(KRB5_TKTBODY, st) +# define sk_KRB5_TKTBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_TKTBODY, (st), (free_func)) +# define sk_KRB5_TKTBODY_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_TKTBODY, (st), (copy_func), (free_func)) +# define sk_KRB5_TKTBODY_shift(st) SKM_sk_shift(KRB5_TKTBODY, (st)) +# define sk_KRB5_TKTBODY_pop(st) SKM_sk_pop(KRB5_TKTBODY, (st)) +# define sk_KRB5_TKTBODY_sort(st) SKM_sk_sort(KRB5_TKTBODY, (st)) +# define sk_KRB5_TKTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_TKTBODY, (st)) +# define sk_MEM_OBJECT_DATA_new(cmp) SKM_sk_new(MEM_OBJECT_DATA, (cmp)) +# define sk_MEM_OBJECT_DATA_new_null() SKM_sk_new_null(MEM_OBJECT_DATA) +# define sk_MEM_OBJECT_DATA_free(st) SKM_sk_free(MEM_OBJECT_DATA, (st)) +# define sk_MEM_OBJECT_DATA_num(st) SKM_sk_num(MEM_OBJECT_DATA, (st)) +# define sk_MEM_OBJECT_DATA_value(st, i) SKM_sk_value(MEM_OBJECT_DATA, (st), (i)) +# define sk_MEM_OBJECT_DATA_set(st, i, val) SKM_sk_set(MEM_OBJECT_DATA, (st), (i), (val)) +# define sk_MEM_OBJECT_DATA_zero(st) SKM_sk_zero(MEM_OBJECT_DATA, (st)) +# define sk_MEM_OBJECT_DATA_push(st, val) SKM_sk_push(MEM_OBJECT_DATA, (st), (val)) +# define sk_MEM_OBJECT_DATA_unshift(st, val) SKM_sk_unshift(MEM_OBJECT_DATA, (st), (val)) +# define sk_MEM_OBJECT_DATA_find(st, val) SKM_sk_find(MEM_OBJECT_DATA, (st), (val)) +# define sk_MEM_OBJECT_DATA_find_ex(st, val) SKM_sk_find_ex(MEM_OBJECT_DATA, (st), (val)) +# define sk_MEM_OBJECT_DATA_delete(st, i) SKM_sk_delete(MEM_OBJECT_DATA, (st), (i)) +# define sk_MEM_OBJECT_DATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(MEM_OBJECT_DATA, (st), (ptr)) +# define sk_MEM_OBJECT_DATA_insert(st, val, i) SKM_sk_insert(MEM_OBJECT_DATA, (st), (val), (i)) +# define sk_MEM_OBJECT_DATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MEM_OBJECT_DATA, (st), (cmp)) +# define sk_MEM_OBJECT_DATA_dup(st) SKM_sk_dup(MEM_OBJECT_DATA, st) +# define sk_MEM_OBJECT_DATA_pop_free(st, free_func) SKM_sk_pop_free(MEM_OBJECT_DATA, (st), (free_func)) +# define sk_MEM_OBJECT_DATA_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(MEM_OBJECT_DATA, (st), (copy_func), (free_func)) +# define sk_MEM_OBJECT_DATA_shift(st) SKM_sk_shift(MEM_OBJECT_DATA, (st)) +# define sk_MEM_OBJECT_DATA_pop(st) SKM_sk_pop(MEM_OBJECT_DATA, (st)) +# define sk_MEM_OBJECT_DATA_sort(st) SKM_sk_sort(MEM_OBJECT_DATA, (st)) +# define sk_MEM_OBJECT_DATA_is_sorted(st) SKM_sk_is_sorted(MEM_OBJECT_DATA, (st)) +# define sk_MIME_HEADER_new(cmp) SKM_sk_new(MIME_HEADER, (cmp)) +# define sk_MIME_HEADER_new_null() SKM_sk_new_null(MIME_HEADER) +# define sk_MIME_HEADER_free(st) SKM_sk_free(MIME_HEADER, (st)) +# define sk_MIME_HEADER_num(st) SKM_sk_num(MIME_HEADER, (st)) +# define sk_MIME_HEADER_value(st, i) SKM_sk_value(MIME_HEADER, (st), (i)) +# define sk_MIME_HEADER_set(st, i, val) SKM_sk_set(MIME_HEADER, (st), (i), (val)) +# define sk_MIME_HEADER_zero(st) SKM_sk_zero(MIME_HEADER, (st)) +# define sk_MIME_HEADER_push(st, val) SKM_sk_push(MIME_HEADER, (st), (val)) +# define sk_MIME_HEADER_unshift(st, val) SKM_sk_unshift(MIME_HEADER, (st), (val)) +# define sk_MIME_HEADER_find(st, val) SKM_sk_find(MIME_HEADER, (st), (val)) +# define sk_MIME_HEADER_find_ex(st, val) SKM_sk_find_ex(MIME_HEADER, (st), (val)) +# define sk_MIME_HEADER_delete(st, i) SKM_sk_delete(MIME_HEADER, (st), (i)) +# define sk_MIME_HEADER_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_HEADER, (st), (ptr)) +# define sk_MIME_HEADER_insert(st, val, i) SKM_sk_insert(MIME_HEADER, (st), (val), (i)) +# define sk_MIME_HEADER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_HEADER, (st), (cmp)) +# define sk_MIME_HEADER_dup(st) SKM_sk_dup(MIME_HEADER, st) +# define sk_MIME_HEADER_pop_free(st, free_func) SKM_sk_pop_free(MIME_HEADER, (st), (free_func)) +# define sk_MIME_HEADER_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(MIME_HEADER, (st), (copy_func), (free_func)) +# define sk_MIME_HEADER_shift(st) SKM_sk_shift(MIME_HEADER, (st)) +# define sk_MIME_HEADER_pop(st) SKM_sk_pop(MIME_HEADER, (st)) +# define sk_MIME_HEADER_sort(st) SKM_sk_sort(MIME_HEADER, (st)) +# define sk_MIME_HEADER_is_sorted(st) SKM_sk_is_sorted(MIME_HEADER, (st)) +# define sk_MIME_PARAM_new(cmp) SKM_sk_new(MIME_PARAM, (cmp)) +# define sk_MIME_PARAM_new_null() SKM_sk_new_null(MIME_PARAM) +# define sk_MIME_PARAM_free(st) SKM_sk_free(MIME_PARAM, (st)) +# define sk_MIME_PARAM_num(st) SKM_sk_num(MIME_PARAM, (st)) +# define sk_MIME_PARAM_value(st, i) SKM_sk_value(MIME_PARAM, (st), (i)) +# define sk_MIME_PARAM_set(st, i, val) SKM_sk_set(MIME_PARAM, (st), (i), (val)) +# define sk_MIME_PARAM_zero(st) SKM_sk_zero(MIME_PARAM, (st)) +# define sk_MIME_PARAM_push(st, val) SKM_sk_push(MIME_PARAM, (st), (val)) +# define sk_MIME_PARAM_unshift(st, val) SKM_sk_unshift(MIME_PARAM, (st), (val)) +# define sk_MIME_PARAM_find(st, val) SKM_sk_find(MIME_PARAM, (st), (val)) +# define sk_MIME_PARAM_find_ex(st, val) SKM_sk_find_ex(MIME_PARAM, (st), (val)) +# define sk_MIME_PARAM_delete(st, i) SKM_sk_delete(MIME_PARAM, (st), (i)) +# define sk_MIME_PARAM_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_PARAM, (st), (ptr)) +# define sk_MIME_PARAM_insert(st, val, i) SKM_sk_insert(MIME_PARAM, (st), (val), (i)) +# define sk_MIME_PARAM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_PARAM, (st), (cmp)) +# define sk_MIME_PARAM_dup(st) SKM_sk_dup(MIME_PARAM, st) +# define sk_MIME_PARAM_pop_free(st, free_func) SKM_sk_pop_free(MIME_PARAM, (st), (free_func)) +# define sk_MIME_PARAM_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(MIME_PARAM, (st), (copy_func), (free_func)) +# define sk_MIME_PARAM_shift(st) SKM_sk_shift(MIME_PARAM, (st)) +# define sk_MIME_PARAM_pop(st) SKM_sk_pop(MIME_PARAM, (st)) +# define sk_MIME_PARAM_sort(st) SKM_sk_sort(MIME_PARAM, (st)) +# define sk_MIME_PARAM_is_sorted(st) SKM_sk_is_sorted(MIME_PARAM, (st)) +# define sk_NAME_FUNCS_new(cmp) SKM_sk_new(NAME_FUNCS, (cmp)) +# define sk_NAME_FUNCS_new_null() SKM_sk_new_null(NAME_FUNCS) +# define sk_NAME_FUNCS_free(st) SKM_sk_free(NAME_FUNCS, (st)) +# define sk_NAME_FUNCS_num(st) SKM_sk_num(NAME_FUNCS, (st)) +# define sk_NAME_FUNCS_value(st, i) SKM_sk_value(NAME_FUNCS, (st), (i)) +# define sk_NAME_FUNCS_set(st, i, val) SKM_sk_set(NAME_FUNCS, (st), (i), (val)) +# define sk_NAME_FUNCS_zero(st) SKM_sk_zero(NAME_FUNCS, (st)) +# define sk_NAME_FUNCS_push(st, val) SKM_sk_push(NAME_FUNCS, (st), (val)) +# define sk_NAME_FUNCS_unshift(st, val) SKM_sk_unshift(NAME_FUNCS, (st), (val)) +# define sk_NAME_FUNCS_find(st, val) SKM_sk_find(NAME_FUNCS, (st), (val)) +# define sk_NAME_FUNCS_find_ex(st, val) SKM_sk_find_ex(NAME_FUNCS, (st), (val)) +# define sk_NAME_FUNCS_delete(st, i) SKM_sk_delete(NAME_FUNCS, (st), (i)) +# define sk_NAME_FUNCS_delete_ptr(st, ptr) SKM_sk_delete_ptr(NAME_FUNCS, (st), (ptr)) +# define sk_NAME_FUNCS_insert(st, val, i) SKM_sk_insert(NAME_FUNCS, (st), (val), (i)) +# define sk_NAME_FUNCS_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(NAME_FUNCS, (st), (cmp)) +# define sk_NAME_FUNCS_dup(st) SKM_sk_dup(NAME_FUNCS, st) +# define sk_NAME_FUNCS_pop_free(st, free_func) SKM_sk_pop_free(NAME_FUNCS, (st), (free_func)) +# define sk_NAME_FUNCS_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(NAME_FUNCS, (st), (copy_func), (free_func)) +# define sk_NAME_FUNCS_shift(st) SKM_sk_shift(NAME_FUNCS, (st)) +# define sk_NAME_FUNCS_pop(st) SKM_sk_pop(NAME_FUNCS, (st)) +# define sk_NAME_FUNCS_sort(st) SKM_sk_sort(NAME_FUNCS, (st)) +# define sk_NAME_FUNCS_is_sorted(st) SKM_sk_is_sorted(NAME_FUNCS, (st)) +# define sk_OCSP_CERTID_new(cmp) SKM_sk_new(OCSP_CERTID, (cmp)) +# define sk_OCSP_CERTID_new_null() SKM_sk_new_null(OCSP_CERTID) +# define sk_OCSP_CERTID_free(st) SKM_sk_free(OCSP_CERTID, (st)) +# define sk_OCSP_CERTID_num(st) SKM_sk_num(OCSP_CERTID, (st)) +# define sk_OCSP_CERTID_value(st, i) SKM_sk_value(OCSP_CERTID, (st), (i)) +# define sk_OCSP_CERTID_set(st, i, val) SKM_sk_set(OCSP_CERTID, (st), (i), (val)) +# define sk_OCSP_CERTID_zero(st) SKM_sk_zero(OCSP_CERTID, (st)) +# define sk_OCSP_CERTID_push(st, val) SKM_sk_push(OCSP_CERTID, (st), (val)) +# define sk_OCSP_CERTID_unshift(st, val) SKM_sk_unshift(OCSP_CERTID, (st), (val)) +# define sk_OCSP_CERTID_find(st, val) SKM_sk_find(OCSP_CERTID, (st), (val)) +# define sk_OCSP_CERTID_find_ex(st, val) SKM_sk_find_ex(OCSP_CERTID, (st), (val)) +# define sk_OCSP_CERTID_delete(st, i) SKM_sk_delete(OCSP_CERTID, (st), (i)) +# define sk_OCSP_CERTID_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_CERTID, (st), (ptr)) +# define sk_OCSP_CERTID_insert(st, val, i) SKM_sk_insert(OCSP_CERTID, (st), (val), (i)) +# define sk_OCSP_CERTID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_CERTID, (st), (cmp)) +# define sk_OCSP_CERTID_dup(st) SKM_sk_dup(OCSP_CERTID, st) +# define sk_OCSP_CERTID_pop_free(st, free_func) SKM_sk_pop_free(OCSP_CERTID, (st), (free_func)) +# define sk_OCSP_CERTID_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(OCSP_CERTID, (st), (copy_func), (free_func)) +# define sk_OCSP_CERTID_shift(st) SKM_sk_shift(OCSP_CERTID, (st)) +# define sk_OCSP_CERTID_pop(st) SKM_sk_pop(OCSP_CERTID, (st)) +# define sk_OCSP_CERTID_sort(st) SKM_sk_sort(OCSP_CERTID, (st)) +# define sk_OCSP_CERTID_is_sorted(st) SKM_sk_is_sorted(OCSP_CERTID, (st)) +# define sk_OCSP_ONEREQ_new(cmp) SKM_sk_new(OCSP_ONEREQ, (cmp)) +# define sk_OCSP_ONEREQ_new_null() SKM_sk_new_null(OCSP_ONEREQ) +# define sk_OCSP_ONEREQ_free(st) SKM_sk_free(OCSP_ONEREQ, (st)) +# define sk_OCSP_ONEREQ_num(st) SKM_sk_num(OCSP_ONEREQ, (st)) +# define sk_OCSP_ONEREQ_value(st, i) SKM_sk_value(OCSP_ONEREQ, (st), (i)) +# define sk_OCSP_ONEREQ_set(st, i, val) SKM_sk_set(OCSP_ONEREQ, (st), (i), (val)) +# define sk_OCSP_ONEREQ_zero(st) SKM_sk_zero(OCSP_ONEREQ, (st)) +# define sk_OCSP_ONEREQ_push(st, val) SKM_sk_push(OCSP_ONEREQ, (st), (val)) +# define sk_OCSP_ONEREQ_unshift(st, val) SKM_sk_unshift(OCSP_ONEREQ, (st), (val)) +# define sk_OCSP_ONEREQ_find(st, val) SKM_sk_find(OCSP_ONEREQ, (st), (val)) +# define sk_OCSP_ONEREQ_find_ex(st, val) SKM_sk_find_ex(OCSP_ONEREQ, (st), (val)) +# define sk_OCSP_ONEREQ_delete(st, i) SKM_sk_delete(OCSP_ONEREQ, (st), (i)) +# define sk_OCSP_ONEREQ_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_ONEREQ, (st), (ptr)) +# define sk_OCSP_ONEREQ_insert(st, val, i) SKM_sk_insert(OCSP_ONEREQ, (st), (val), (i)) +# define sk_OCSP_ONEREQ_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_ONEREQ, (st), (cmp)) +# define sk_OCSP_ONEREQ_dup(st) SKM_sk_dup(OCSP_ONEREQ, st) +# define sk_OCSP_ONEREQ_pop_free(st, free_func) SKM_sk_pop_free(OCSP_ONEREQ, (st), (free_func)) +# define sk_OCSP_ONEREQ_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(OCSP_ONEREQ, (st), (copy_func), (free_func)) +# define sk_OCSP_ONEREQ_shift(st) SKM_sk_shift(OCSP_ONEREQ, (st)) +# define sk_OCSP_ONEREQ_pop(st) SKM_sk_pop(OCSP_ONEREQ, (st)) +# define sk_OCSP_ONEREQ_sort(st) SKM_sk_sort(OCSP_ONEREQ, (st)) +# define sk_OCSP_ONEREQ_is_sorted(st) SKM_sk_is_sorted(OCSP_ONEREQ, (st)) +# define sk_OCSP_RESPID_new(cmp) SKM_sk_new(OCSP_RESPID, (cmp)) +# define sk_OCSP_RESPID_new_null() SKM_sk_new_null(OCSP_RESPID) +# define sk_OCSP_RESPID_free(st) SKM_sk_free(OCSP_RESPID, (st)) +# define sk_OCSP_RESPID_num(st) SKM_sk_num(OCSP_RESPID, (st)) +# define sk_OCSP_RESPID_value(st, i) SKM_sk_value(OCSP_RESPID, (st), (i)) +# define sk_OCSP_RESPID_set(st, i, val) SKM_sk_set(OCSP_RESPID, (st), (i), (val)) +# define sk_OCSP_RESPID_zero(st) SKM_sk_zero(OCSP_RESPID, (st)) +# define sk_OCSP_RESPID_push(st, val) SKM_sk_push(OCSP_RESPID, (st), (val)) +# define sk_OCSP_RESPID_unshift(st, val) SKM_sk_unshift(OCSP_RESPID, (st), (val)) +# define sk_OCSP_RESPID_find(st, val) SKM_sk_find(OCSP_RESPID, (st), (val)) +# define sk_OCSP_RESPID_find_ex(st, val) SKM_sk_find_ex(OCSP_RESPID, (st), (val)) +# define sk_OCSP_RESPID_delete(st, i) SKM_sk_delete(OCSP_RESPID, (st), (i)) +# define sk_OCSP_RESPID_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_RESPID, (st), (ptr)) +# define sk_OCSP_RESPID_insert(st, val, i) SKM_sk_insert(OCSP_RESPID, (st), (val), (i)) +# define sk_OCSP_RESPID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_RESPID, (st), (cmp)) +# define sk_OCSP_RESPID_dup(st) SKM_sk_dup(OCSP_RESPID, st) +# define sk_OCSP_RESPID_pop_free(st, free_func) SKM_sk_pop_free(OCSP_RESPID, (st), (free_func)) +# define sk_OCSP_RESPID_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(OCSP_RESPID, (st), (copy_func), (free_func)) +# define sk_OCSP_RESPID_shift(st) SKM_sk_shift(OCSP_RESPID, (st)) +# define sk_OCSP_RESPID_pop(st) SKM_sk_pop(OCSP_RESPID, (st)) +# define sk_OCSP_RESPID_sort(st) SKM_sk_sort(OCSP_RESPID, (st)) +# define sk_OCSP_RESPID_is_sorted(st) SKM_sk_is_sorted(OCSP_RESPID, (st)) +# define sk_OCSP_SINGLERESP_new(cmp) SKM_sk_new(OCSP_SINGLERESP, (cmp)) +# define sk_OCSP_SINGLERESP_new_null() SKM_sk_new_null(OCSP_SINGLERESP) +# define sk_OCSP_SINGLERESP_free(st) SKM_sk_free(OCSP_SINGLERESP, (st)) +# define sk_OCSP_SINGLERESP_num(st) SKM_sk_num(OCSP_SINGLERESP, (st)) +# define sk_OCSP_SINGLERESP_value(st, i) SKM_sk_value(OCSP_SINGLERESP, (st), (i)) +# define sk_OCSP_SINGLERESP_set(st, i, val) SKM_sk_set(OCSP_SINGLERESP, (st), (i), (val)) +# define sk_OCSP_SINGLERESP_zero(st) SKM_sk_zero(OCSP_SINGLERESP, (st)) +# define sk_OCSP_SINGLERESP_push(st, val) SKM_sk_push(OCSP_SINGLERESP, (st), (val)) +# define sk_OCSP_SINGLERESP_unshift(st, val) SKM_sk_unshift(OCSP_SINGLERESP, (st), (val)) +# define sk_OCSP_SINGLERESP_find(st, val) SKM_sk_find(OCSP_SINGLERESP, (st), (val)) +# define sk_OCSP_SINGLERESP_find_ex(st, val) SKM_sk_find_ex(OCSP_SINGLERESP, (st), (val)) +# define sk_OCSP_SINGLERESP_delete(st, i) SKM_sk_delete(OCSP_SINGLERESP, (st), (i)) +# define sk_OCSP_SINGLERESP_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_SINGLERESP, (st), (ptr)) +# define sk_OCSP_SINGLERESP_insert(st, val, i) SKM_sk_insert(OCSP_SINGLERESP, (st), (val), (i)) +# define sk_OCSP_SINGLERESP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_SINGLERESP, (st), (cmp)) +# define sk_OCSP_SINGLERESP_dup(st) SKM_sk_dup(OCSP_SINGLERESP, st) +# define sk_OCSP_SINGLERESP_pop_free(st, free_func) SKM_sk_pop_free(OCSP_SINGLERESP, (st), (free_func)) +# define sk_OCSP_SINGLERESP_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(OCSP_SINGLERESP, (st), (copy_func), (free_func)) +# define sk_OCSP_SINGLERESP_shift(st) SKM_sk_shift(OCSP_SINGLERESP, (st)) +# define sk_OCSP_SINGLERESP_pop(st) SKM_sk_pop(OCSP_SINGLERESP, (st)) +# define sk_OCSP_SINGLERESP_sort(st) SKM_sk_sort(OCSP_SINGLERESP, (st)) +# define sk_OCSP_SINGLERESP_is_sorted(st) SKM_sk_is_sorted(OCSP_SINGLERESP, (st)) +# define sk_PKCS12_SAFEBAG_new(cmp) SKM_sk_new(PKCS12_SAFEBAG, (cmp)) +# define sk_PKCS12_SAFEBAG_new_null() SKM_sk_new_null(PKCS12_SAFEBAG) +# define sk_PKCS12_SAFEBAG_free(st) SKM_sk_free(PKCS12_SAFEBAG, (st)) +# define sk_PKCS12_SAFEBAG_num(st) SKM_sk_num(PKCS12_SAFEBAG, (st)) +# define sk_PKCS12_SAFEBAG_value(st, i) SKM_sk_value(PKCS12_SAFEBAG, (st), (i)) +# define sk_PKCS12_SAFEBAG_set(st, i, val) SKM_sk_set(PKCS12_SAFEBAG, (st), (i), (val)) +# define sk_PKCS12_SAFEBAG_zero(st) SKM_sk_zero(PKCS12_SAFEBAG, (st)) +# define sk_PKCS12_SAFEBAG_push(st, val) SKM_sk_push(PKCS12_SAFEBAG, (st), (val)) +# define sk_PKCS12_SAFEBAG_unshift(st, val) SKM_sk_unshift(PKCS12_SAFEBAG, (st), (val)) +# define sk_PKCS12_SAFEBAG_find(st, val) SKM_sk_find(PKCS12_SAFEBAG, (st), (val)) +# define sk_PKCS12_SAFEBAG_find_ex(st, val) SKM_sk_find_ex(PKCS12_SAFEBAG, (st), (val)) +# define sk_PKCS12_SAFEBAG_delete(st, i) SKM_sk_delete(PKCS12_SAFEBAG, (st), (i)) +# define sk_PKCS12_SAFEBAG_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS12_SAFEBAG, (st), (ptr)) +# define sk_PKCS12_SAFEBAG_insert(st, val, i) SKM_sk_insert(PKCS12_SAFEBAG, (st), (val), (i)) +# define sk_PKCS12_SAFEBAG_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS12_SAFEBAG, (st), (cmp)) +# define sk_PKCS12_SAFEBAG_dup(st) SKM_sk_dup(PKCS12_SAFEBAG, st) +# define sk_PKCS12_SAFEBAG_pop_free(st, free_func) SKM_sk_pop_free(PKCS12_SAFEBAG, (st), (free_func)) +# define sk_PKCS12_SAFEBAG_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(PKCS12_SAFEBAG, (st), (copy_func), (free_func)) +# define sk_PKCS12_SAFEBAG_shift(st) SKM_sk_shift(PKCS12_SAFEBAG, (st)) +# define sk_PKCS12_SAFEBAG_pop(st) SKM_sk_pop(PKCS12_SAFEBAG, (st)) +# define sk_PKCS12_SAFEBAG_sort(st) SKM_sk_sort(PKCS12_SAFEBAG, (st)) +# define sk_PKCS12_SAFEBAG_is_sorted(st) SKM_sk_is_sorted(PKCS12_SAFEBAG, (st)) +# define sk_PKCS7_new(cmp) SKM_sk_new(PKCS7, (cmp)) +# define sk_PKCS7_new_null() SKM_sk_new_null(PKCS7) +# define sk_PKCS7_free(st) SKM_sk_free(PKCS7, (st)) +# define sk_PKCS7_num(st) SKM_sk_num(PKCS7, (st)) +# define sk_PKCS7_value(st, i) SKM_sk_value(PKCS7, (st), (i)) +# define sk_PKCS7_set(st, i, val) SKM_sk_set(PKCS7, (st), (i), (val)) +# define sk_PKCS7_zero(st) SKM_sk_zero(PKCS7, (st)) +# define sk_PKCS7_push(st, val) SKM_sk_push(PKCS7, (st), (val)) +# define sk_PKCS7_unshift(st, val) SKM_sk_unshift(PKCS7, (st), (val)) +# define sk_PKCS7_find(st, val) SKM_sk_find(PKCS7, (st), (val)) +# define sk_PKCS7_find_ex(st, val) SKM_sk_find_ex(PKCS7, (st), (val)) +# define sk_PKCS7_delete(st, i) SKM_sk_delete(PKCS7, (st), (i)) +# define sk_PKCS7_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7, (st), (ptr)) +# define sk_PKCS7_insert(st, val, i) SKM_sk_insert(PKCS7, (st), (val), (i)) +# define sk_PKCS7_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7, (st), (cmp)) +# define sk_PKCS7_dup(st) SKM_sk_dup(PKCS7, st) +# define sk_PKCS7_pop_free(st, free_func) SKM_sk_pop_free(PKCS7, (st), (free_func)) +# define sk_PKCS7_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(PKCS7, (st), (copy_func), (free_func)) +# define sk_PKCS7_shift(st) SKM_sk_shift(PKCS7, (st)) +# define sk_PKCS7_pop(st) SKM_sk_pop(PKCS7, (st)) +# define sk_PKCS7_sort(st) SKM_sk_sort(PKCS7, (st)) +# define sk_PKCS7_is_sorted(st) SKM_sk_is_sorted(PKCS7, (st)) +# define sk_PKCS7_RECIP_INFO_new(cmp) SKM_sk_new(PKCS7_RECIP_INFO, (cmp)) +# define sk_PKCS7_RECIP_INFO_new_null() SKM_sk_new_null(PKCS7_RECIP_INFO) +# define sk_PKCS7_RECIP_INFO_free(st) SKM_sk_free(PKCS7_RECIP_INFO, (st)) +# define sk_PKCS7_RECIP_INFO_num(st) SKM_sk_num(PKCS7_RECIP_INFO, (st)) +# define sk_PKCS7_RECIP_INFO_value(st, i) SKM_sk_value(PKCS7_RECIP_INFO, (st), (i)) +# define sk_PKCS7_RECIP_INFO_set(st, i, val) SKM_sk_set(PKCS7_RECIP_INFO, (st), (i), (val)) +# define sk_PKCS7_RECIP_INFO_zero(st) SKM_sk_zero(PKCS7_RECIP_INFO, (st)) +# define sk_PKCS7_RECIP_INFO_push(st, val) SKM_sk_push(PKCS7_RECIP_INFO, (st), (val)) +# define sk_PKCS7_RECIP_INFO_unshift(st, val) SKM_sk_unshift(PKCS7_RECIP_INFO, (st), (val)) +# define sk_PKCS7_RECIP_INFO_find(st, val) SKM_sk_find(PKCS7_RECIP_INFO, (st), (val)) +# define sk_PKCS7_RECIP_INFO_find_ex(st, val) SKM_sk_find_ex(PKCS7_RECIP_INFO, (st), (val)) +# define sk_PKCS7_RECIP_INFO_delete(st, i) SKM_sk_delete(PKCS7_RECIP_INFO, (st), (i)) +# define sk_PKCS7_RECIP_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7_RECIP_INFO, (st), (ptr)) +# define sk_PKCS7_RECIP_INFO_insert(st, val, i) SKM_sk_insert(PKCS7_RECIP_INFO, (st), (val), (i)) +# define sk_PKCS7_RECIP_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7_RECIP_INFO, (st), (cmp)) +# define sk_PKCS7_RECIP_INFO_dup(st) SKM_sk_dup(PKCS7_RECIP_INFO, st) +# define sk_PKCS7_RECIP_INFO_pop_free(st, free_func) SKM_sk_pop_free(PKCS7_RECIP_INFO, (st), (free_func)) +# define sk_PKCS7_RECIP_INFO_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(PKCS7_RECIP_INFO, (st), (copy_func), (free_func)) +# define sk_PKCS7_RECIP_INFO_shift(st) SKM_sk_shift(PKCS7_RECIP_INFO, (st)) +# define sk_PKCS7_RECIP_INFO_pop(st) SKM_sk_pop(PKCS7_RECIP_INFO, (st)) +# define sk_PKCS7_RECIP_INFO_sort(st) SKM_sk_sort(PKCS7_RECIP_INFO, (st)) +# define sk_PKCS7_RECIP_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_RECIP_INFO, (st)) +# define sk_PKCS7_SIGNER_INFO_new(cmp) SKM_sk_new(PKCS7_SIGNER_INFO, (cmp)) +# define sk_PKCS7_SIGNER_INFO_new_null() SKM_sk_new_null(PKCS7_SIGNER_INFO) +# define sk_PKCS7_SIGNER_INFO_free(st) SKM_sk_free(PKCS7_SIGNER_INFO, (st)) +# define sk_PKCS7_SIGNER_INFO_num(st) SKM_sk_num(PKCS7_SIGNER_INFO, (st)) +# define sk_PKCS7_SIGNER_INFO_value(st, i) SKM_sk_value(PKCS7_SIGNER_INFO, (st), (i)) +# define sk_PKCS7_SIGNER_INFO_set(st, i, val) SKM_sk_set(PKCS7_SIGNER_INFO, (st), (i), (val)) +# define sk_PKCS7_SIGNER_INFO_zero(st) SKM_sk_zero(PKCS7_SIGNER_INFO, (st)) +# define sk_PKCS7_SIGNER_INFO_push(st, val) SKM_sk_push(PKCS7_SIGNER_INFO, (st), (val)) +# define sk_PKCS7_SIGNER_INFO_unshift(st, val) SKM_sk_unshift(PKCS7_SIGNER_INFO, (st), (val)) +# define sk_PKCS7_SIGNER_INFO_find(st, val) SKM_sk_find(PKCS7_SIGNER_INFO, (st), (val)) +# define sk_PKCS7_SIGNER_INFO_find_ex(st, val) SKM_sk_find_ex(PKCS7_SIGNER_INFO, (st), (val)) +# define sk_PKCS7_SIGNER_INFO_delete(st, i) SKM_sk_delete(PKCS7_SIGNER_INFO, (st), (i)) +# define sk_PKCS7_SIGNER_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7_SIGNER_INFO, (st), (ptr)) +# define sk_PKCS7_SIGNER_INFO_insert(st, val, i) SKM_sk_insert(PKCS7_SIGNER_INFO, (st), (val), (i)) +# define sk_PKCS7_SIGNER_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7_SIGNER_INFO, (st), (cmp)) +# define sk_PKCS7_SIGNER_INFO_dup(st) SKM_sk_dup(PKCS7_SIGNER_INFO, st) +# define sk_PKCS7_SIGNER_INFO_pop_free(st, free_func) SKM_sk_pop_free(PKCS7_SIGNER_INFO, (st), (free_func)) +# define sk_PKCS7_SIGNER_INFO_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(PKCS7_SIGNER_INFO, (st), (copy_func), (free_func)) +# define sk_PKCS7_SIGNER_INFO_shift(st) SKM_sk_shift(PKCS7_SIGNER_INFO, (st)) +# define sk_PKCS7_SIGNER_INFO_pop(st) SKM_sk_pop(PKCS7_SIGNER_INFO, (st)) +# define sk_PKCS7_SIGNER_INFO_sort(st) SKM_sk_sort(PKCS7_SIGNER_INFO, (st)) +# define sk_PKCS7_SIGNER_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_SIGNER_INFO, (st)) +# define sk_POLICYINFO_new(cmp) SKM_sk_new(POLICYINFO, (cmp)) +# define sk_POLICYINFO_new_null() SKM_sk_new_null(POLICYINFO) +# define sk_POLICYINFO_free(st) SKM_sk_free(POLICYINFO, (st)) +# define sk_POLICYINFO_num(st) SKM_sk_num(POLICYINFO, (st)) +# define sk_POLICYINFO_value(st, i) SKM_sk_value(POLICYINFO, (st), (i)) +# define sk_POLICYINFO_set(st, i, val) SKM_sk_set(POLICYINFO, (st), (i), (val)) +# define sk_POLICYINFO_zero(st) SKM_sk_zero(POLICYINFO, (st)) +# define sk_POLICYINFO_push(st, val) SKM_sk_push(POLICYINFO, (st), (val)) +# define sk_POLICYINFO_unshift(st, val) SKM_sk_unshift(POLICYINFO, (st), (val)) +# define sk_POLICYINFO_find(st, val) SKM_sk_find(POLICYINFO, (st), (val)) +# define sk_POLICYINFO_find_ex(st, val) SKM_sk_find_ex(POLICYINFO, (st), (val)) +# define sk_POLICYINFO_delete(st, i) SKM_sk_delete(POLICYINFO, (st), (i)) +# define sk_POLICYINFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICYINFO, (st), (ptr)) +# define sk_POLICYINFO_insert(st, val, i) SKM_sk_insert(POLICYINFO, (st), (val), (i)) +# define sk_POLICYINFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICYINFO, (st), (cmp)) +# define sk_POLICYINFO_dup(st) SKM_sk_dup(POLICYINFO, st) +# define sk_POLICYINFO_pop_free(st, free_func) SKM_sk_pop_free(POLICYINFO, (st), (free_func)) +# define sk_POLICYINFO_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(POLICYINFO, (st), (copy_func), (free_func)) +# define sk_POLICYINFO_shift(st) SKM_sk_shift(POLICYINFO, (st)) +# define sk_POLICYINFO_pop(st) SKM_sk_pop(POLICYINFO, (st)) +# define sk_POLICYINFO_sort(st) SKM_sk_sort(POLICYINFO, (st)) +# define sk_POLICYINFO_is_sorted(st) SKM_sk_is_sorted(POLICYINFO, (st)) +# define sk_POLICYQUALINFO_new(cmp) SKM_sk_new(POLICYQUALINFO, (cmp)) +# define sk_POLICYQUALINFO_new_null() SKM_sk_new_null(POLICYQUALINFO) +# define sk_POLICYQUALINFO_free(st) SKM_sk_free(POLICYQUALINFO, (st)) +# define sk_POLICYQUALINFO_num(st) SKM_sk_num(POLICYQUALINFO, (st)) +# define sk_POLICYQUALINFO_value(st, i) SKM_sk_value(POLICYQUALINFO, (st), (i)) +# define sk_POLICYQUALINFO_set(st, i, val) SKM_sk_set(POLICYQUALINFO, (st), (i), (val)) +# define sk_POLICYQUALINFO_zero(st) SKM_sk_zero(POLICYQUALINFO, (st)) +# define sk_POLICYQUALINFO_push(st, val) SKM_sk_push(POLICYQUALINFO, (st), (val)) +# define sk_POLICYQUALINFO_unshift(st, val) SKM_sk_unshift(POLICYQUALINFO, (st), (val)) +# define sk_POLICYQUALINFO_find(st, val) SKM_sk_find(POLICYQUALINFO, (st), (val)) +# define sk_POLICYQUALINFO_find_ex(st, val) SKM_sk_find_ex(POLICYQUALINFO, (st), (val)) +# define sk_POLICYQUALINFO_delete(st, i) SKM_sk_delete(POLICYQUALINFO, (st), (i)) +# define sk_POLICYQUALINFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICYQUALINFO, (st), (ptr)) +# define sk_POLICYQUALINFO_insert(st, val, i) SKM_sk_insert(POLICYQUALINFO, (st), (val), (i)) +# define sk_POLICYQUALINFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICYQUALINFO, (st), (cmp)) +# define sk_POLICYQUALINFO_dup(st) SKM_sk_dup(POLICYQUALINFO, st) +# define sk_POLICYQUALINFO_pop_free(st, free_func) SKM_sk_pop_free(POLICYQUALINFO, (st), (free_func)) +# define sk_POLICYQUALINFO_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(POLICYQUALINFO, (st), (copy_func), (free_func)) +# define sk_POLICYQUALINFO_shift(st) SKM_sk_shift(POLICYQUALINFO, (st)) +# define sk_POLICYQUALINFO_pop(st) SKM_sk_pop(POLICYQUALINFO, (st)) +# define sk_POLICYQUALINFO_sort(st) SKM_sk_sort(POLICYQUALINFO, (st)) +# define sk_POLICYQUALINFO_is_sorted(st) SKM_sk_is_sorted(POLICYQUALINFO, (st)) +# define sk_POLICY_MAPPING_new(cmp) SKM_sk_new(POLICY_MAPPING, (cmp)) +# define sk_POLICY_MAPPING_new_null() SKM_sk_new_null(POLICY_MAPPING) +# define sk_POLICY_MAPPING_free(st) SKM_sk_free(POLICY_MAPPING, (st)) +# define sk_POLICY_MAPPING_num(st) SKM_sk_num(POLICY_MAPPING, (st)) +# define sk_POLICY_MAPPING_value(st, i) SKM_sk_value(POLICY_MAPPING, (st), (i)) +# define sk_POLICY_MAPPING_set(st, i, val) SKM_sk_set(POLICY_MAPPING, (st), (i), (val)) +# define sk_POLICY_MAPPING_zero(st) SKM_sk_zero(POLICY_MAPPING, (st)) +# define sk_POLICY_MAPPING_push(st, val) SKM_sk_push(POLICY_MAPPING, (st), (val)) +# define sk_POLICY_MAPPING_unshift(st, val) SKM_sk_unshift(POLICY_MAPPING, (st), (val)) +# define sk_POLICY_MAPPING_find(st, val) SKM_sk_find(POLICY_MAPPING, (st), (val)) +# define sk_POLICY_MAPPING_find_ex(st, val) SKM_sk_find_ex(POLICY_MAPPING, (st), (val)) +# define sk_POLICY_MAPPING_delete(st, i) SKM_sk_delete(POLICY_MAPPING, (st), (i)) +# define sk_POLICY_MAPPING_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICY_MAPPING, (st), (ptr)) +# define sk_POLICY_MAPPING_insert(st, val, i) SKM_sk_insert(POLICY_MAPPING, (st), (val), (i)) +# define sk_POLICY_MAPPING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICY_MAPPING, (st), (cmp)) +# define sk_POLICY_MAPPING_dup(st) SKM_sk_dup(POLICY_MAPPING, st) +# define sk_POLICY_MAPPING_pop_free(st, free_func) SKM_sk_pop_free(POLICY_MAPPING, (st), (free_func)) +# define sk_POLICY_MAPPING_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(POLICY_MAPPING, (st), (copy_func), (free_func)) +# define sk_POLICY_MAPPING_shift(st) SKM_sk_shift(POLICY_MAPPING, (st)) +# define sk_POLICY_MAPPING_pop(st) SKM_sk_pop(POLICY_MAPPING, (st)) +# define sk_POLICY_MAPPING_sort(st) SKM_sk_sort(POLICY_MAPPING, (st)) +# define sk_POLICY_MAPPING_is_sorted(st) SKM_sk_is_sorted(POLICY_MAPPING, (st)) +# define sk_SCT_new(cmp) SKM_sk_new(SCT, (cmp)) +# define sk_SCT_new_null() SKM_sk_new_null(SCT) +# define sk_SCT_free(st) SKM_sk_free(SCT, (st)) +# define sk_SCT_num(st) SKM_sk_num(SCT, (st)) +# define sk_SCT_value(st, i) SKM_sk_value(SCT, (st), (i)) +# define sk_SCT_set(st, i, val) SKM_sk_set(SCT, (st), (i), (val)) +# define sk_SCT_zero(st) SKM_sk_zero(SCT, (st)) +# define sk_SCT_push(st, val) SKM_sk_push(SCT, (st), (val)) +# define sk_SCT_unshift(st, val) SKM_sk_unshift(SCT, (st), (val)) +# define sk_SCT_find(st, val) SKM_sk_find(SCT, (st), (val)) +# define sk_SCT_find_ex(st, val) SKM_sk_find_ex(SCT, (st), (val)) +# define sk_SCT_delete(st, i) SKM_sk_delete(SCT, (st), (i)) +# define sk_SCT_delete_ptr(st, ptr) SKM_sk_delete_ptr(SCT, (st), (ptr)) +# define sk_SCT_insert(st, val, i) SKM_sk_insert(SCT, (st), (val), (i)) +# define sk_SCT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SCT, (st), (cmp)) +# define sk_SCT_dup(st) SKM_sk_dup(SCT, st) +# define sk_SCT_pop_free(st, free_func) SKM_sk_pop_free(SCT, (st), (free_func)) +# define sk_SCT_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SCT, (st), (copy_func), (free_func)) +# define sk_SCT_shift(st) SKM_sk_shift(SCT, (st)) +# define sk_SCT_pop(st) SKM_sk_pop(SCT, (st)) +# define sk_SCT_sort(st) SKM_sk_sort(SCT, (st)) +# define sk_SCT_is_sorted(st) SKM_sk_is_sorted(SCT, (st)) +# define sk_SRP_gN_new(cmp) SKM_sk_new(SRP_gN, (cmp)) +# define sk_SRP_gN_new_null() SKM_sk_new_null(SRP_gN) +# define sk_SRP_gN_free(st) SKM_sk_free(SRP_gN, (st)) +# define sk_SRP_gN_num(st) SKM_sk_num(SRP_gN, (st)) +# define sk_SRP_gN_value(st, i) SKM_sk_value(SRP_gN, (st), (i)) +# define sk_SRP_gN_set(st, i, val) SKM_sk_set(SRP_gN, (st), (i), (val)) +# define sk_SRP_gN_zero(st) SKM_sk_zero(SRP_gN, (st)) +# define sk_SRP_gN_push(st, val) SKM_sk_push(SRP_gN, (st), (val)) +# define sk_SRP_gN_unshift(st, val) SKM_sk_unshift(SRP_gN, (st), (val)) +# define sk_SRP_gN_find(st, val) SKM_sk_find(SRP_gN, (st), (val)) +# define sk_SRP_gN_find_ex(st, val) SKM_sk_find_ex(SRP_gN, (st), (val)) +# define sk_SRP_gN_delete(st, i) SKM_sk_delete(SRP_gN, (st), (i)) +# define sk_SRP_gN_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRP_gN, (st), (ptr)) +# define sk_SRP_gN_insert(st, val, i) SKM_sk_insert(SRP_gN, (st), (val), (i)) +# define sk_SRP_gN_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRP_gN, (st), (cmp)) +# define sk_SRP_gN_dup(st) SKM_sk_dup(SRP_gN, st) +# define sk_SRP_gN_pop_free(st, free_func) SKM_sk_pop_free(SRP_gN, (st), (free_func)) +# define sk_SRP_gN_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SRP_gN, (st), (copy_func), (free_func)) +# define sk_SRP_gN_shift(st) SKM_sk_shift(SRP_gN, (st)) +# define sk_SRP_gN_pop(st) SKM_sk_pop(SRP_gN, (st)) +# define sk_SRP_gN_sort(st) SKM_sk_sort(SRP_gN, (st)) +# define sk_SRP_gN_is_sorted(st) SKM_sk_is_sorted(SRP_gN, (st)) +# define sk_SRP_gN_cache_new(cmp) SKM_sk_new(SRP_gN_cache, (cmp)) +# define sk_SRP_gN_cache_new_null() SKM_sk_new_null(SRP_gN_cache) +# define sk_SRP_gN_cache_free(st) SKM_sk_free(SRP_gN_cache, (st)) +# define sk_SRP_gN_cache_num(st) SKM_sk_num(SRP_gN_cache, (st)) +# define sk_SRP_gN_cache_value(st, i) SKM_sk_value(SRP_gN_cache, (st), (i)) +# define sk_SRP_gN_cache_set(st, i, val) SKM_sk_set(SRP_gN_cache, (st), (i), (val)) +# define sk_SRP_gN_cache_zero(st) SKM_sk_zero(SRP_gN_cache, (st)) +# define sk_SRP_gN_cache_push(st, val) SKM_sk_push(SRP_gN_cache, (st), (val)) +# define sk_SRP_gN_cache_unshift(st, val) SKM_sk_unshift(SRP_gN_cache, (st), (val)) +# define sk_SRP_gN_cache_find(st, val) SKM_sk_find(SRP_gN_cache, (st), (val)) +# define sk_SRP_gN_cache_find_ex(st, val) SKM_sk_find_ex(SRP_gN_cache, (st), (val)) +# define sk_SRP_gN_cache_delete(st, i) SKM_sk_delete(SRP_gN_cache, (st), (i)) +# define sk_SRP_gN_cache_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRP_gN_cache, (st), (ptr)) +# define sk_SRP_gN_cache_insert(st, val, i) SKM_sk_insert(SRP_gN_cache, (st), (val), (i)) +# define sk_SRP_gN_cache_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRP_gN_cache, (st), (cmp)) +# define sk_SRP_gN_cache_dup(st) SKM_sk_dup(SRP_gN_cache, st) +# define sk_SRP_gN_cache_pop_free(st, free_func) SKM_sk_pop_free(SRP_gN_cache, (st), (free_func)) +# define sk_SRP_gN_cache_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SRP_gN_cache, (st), (copy_func), (free_func)) +# define sk_SRP_gN_cache_shift(st) SKM_sk_shift(SRP_gN_cache, (st)) +# define sk_SRP_gN_cache_pop(st) SKM_sk_pop(SRP_gN_cache, (st)) +# define sk_SRP_gN_cache_sort(st) SKM_sk_sort(SRP_gN_cache, (st)) +# define sk_SRP_gN_cache_is_sorted(st) SKM_sk_is_sorted(SRP_gN_cache, (st)) +# define sk_SRP_user_pwd_new(cmp) SKM_sk_new(SRP_user_pwd, (cmp)) +# define sk_SRP_user_pwd_new_null() SKM_sk_new_null(SRP_user_pwd) +# define sk_SRP_user_pwd_free(st) SKM_sk_free(SRP_user_pwd, (st)) +# define sk_SRP_user_pwd_num(st) SKM_sk_num(SRP_user_pwd, (st)) +# define sk_SRP_user_pwd_value(st, i) SKM_sk_value(SRP_user_pwd, (st), (i)) +# define sk_SRP_user_pwd_set(st, i, val) SKM_sk_set(SRP_user_pwd, (st), (i), (val)) +# define sk_SRP_user_pwd_zero(st) SKM_sk_zero(SRP_user_pwd, (st)) +# define sk_SRP_user_pwd_push(st, val) SKM_sk_push(SRP_user_pwd, (st), (val)) +# define sk_SRP_user_pwd_unshift(st, val) SKM_sk_unshift(SRP_user_pwd, (st), (val)) +# define sk_SRP_user_pwd_find(st, val) SKM_sk_find(SRP_user_pwd, (st), (val)) +# define sk_SRP_user_pwd_find_ex(st, val) SKM_sk_find_ex(SRP_user_pwd, (st), (val)) +# define sk_SRP_user_pwd_delete(st, i) SKM_sk_delete(SRP_user_pwd, (st), (i)) +# define sk_SRP_user_pwd_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRP_user_pwd, (st), (ptr)) +# define sk_SRP_user_pwd_insert(st, val, i) SKM_sk_insert(SRP_user_pwd, (st), (val), (i)) +# define sk_SRP_user_pwd_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRP_user_pwd, (st), (cmp)) +# define sk_SRP_user_pwd_dup(st) SKM_sk_dup(SRP_user_pwd, st) +# define sk_SRP_user_pwd_pop_free(st, free_func) SKM_sk_pop_free(SRP_user_pwd, (st), (free_func)) +# define sk_SRP_user_pwd_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SRP_user_pwd, (st), (copy_func), (free_func)) +# define sk_SRP_user_pwd_shift(st) SKM_sk_shift(SRP_user_pwd, (st)) +# define sk_SRP_user_pwd_pop(st) SKM_sk_pop(SRP_user_pwd, (st)) +# define sk_SRP_user_pwd_sort(st) SKM_sk_sort(SRP_user_pwd, (st)) +# define sk_SRP_user_pwd_is_sorted(st) SKM_sk_is_sorted(SRP_user_pwd, (st)) +# define sk_SRTP_PROTECTION_PROFILE_new(cmp) SKM_sk_new(SRTP_PROTECTION_PROFILE, (cmp)) +# define sk_SRTP_PROTECTION_PROFILE_new_null() SKM_sk_new_null(SRTP_PROTECTION_PROFILE) +# define sk_SRTP_PROTECTION_PROFILE_free(st) SKM_sk_free(SRTP_PROTECTION_PROFILE, (st)) +# define sk_SRTP_PROTECTION_PROFILE_num(st) SKM_sk_num(SRTP_PROTECTION_PROFILE, (st)) +# define sk_SRTP_PROTECTION_PROFILE_value(st, i) SKM_sk_value(SRTP_PROTECTION_PROFILE, (st), (i)) +# define sk_SRTP_PROTECTION_PROFILE_set(st, i, val) SKM_sk_set(SRTP_PROTECTION_PROFILE, (st), (i), (val)) +# define sk_SRTP_PROTECTION_PROFILE_zero(st) SKM_sk_zero(SRTP_PROTECTION_PROFILE, (st)) +# define sk_SRTP_PROTECTION_PROFILE_push(st, val) SKM_sk_push(SRTP_PROTECTION_PROFILE, (st), (val)) +# define sk_SRTP_PROTECTION_PROFILE_unshift(st, val) SKM_sk_unshift(SRTP_PROTECTION_PROFILE, (st), (val)) +# define sk_SRTP_PROTECTION_PROFILE_find(st, val) SKM_sk_find(SRTP_PROTECTION_PROFILE, (st), (val)) +# define sk_SRTP_PROTECTION_PROFILE_find_ex(st, val) SKM_sk_find_ex(SRTP_PROTECTION_PROFILE, (st), (val)) +# define sk_SRTP_PROTECTION_PROFILE_delete(st, i) SKM_sk_delete(SRTP_PROTECTION_PROFILE, (st), (i)) +# define sk_SRTP_PROTECTION_PROFILE_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRTP_PROTECTION_PROFILE, (st), (ptr)) +# define sk_SRTP_PROTECTION_PROFILE_insert(st, val, i) SKM_sk_insert(SRTP_PROTECTION_PROFILE, (st), (val), (i)) +# define sk_SRTP_PROTECTION_PROFILE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRTP_PROTECTION_PROFILE, (st), (cmp)) +# define sk_SRTP_PROTECTION_PROFILE_dup(st) SKM_sk_dup(SRTP_PROTECTION_PROFILE, st) +# define sk_SRTP_PROTECTION_PROFILE_pop_free(st, free_func) SKM_sk_pop_free(SRTP_PROTECTION_PROFILE, (st), (free_func)) +# define sk_SRTP_PROTECTION_PROFILE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SRTP_PROTECTION_PROFILE, (st), (copy_func), (free_func)) +# define sk_SRTP_PROTECTION_PROFILE_shift(st) SKM_sk_shift(SRTP_PROTECTION_PROFILE, (st)) +# define sk_SRTP_PROTECTION_PROFILE_pop(st) SKM_sk_pop(SRTP_PROTECTION_PROFILE, (st)) +# define sk_SRTP_PROTECTION_PROFILE_sort(st) SKM_sk_sort(SRTP_PROTECTION_PROFILE, (st)) +# define sk_SRTP_PROTECTION_PROFILE_is_sorted(st) SKM_sk_is_sorted(SRTP_PROTECTION_PROFILE, (st)) +# define sk_SSL_CIPHER_new(cmp) SKM_sk_new(SSL_CIPHER, (cmp)) +# define sk_SSL_CIPHER_new_null() SKM_sk_new_null(SSL_CIPHER) +# define sk_SSL_CIPHER_free(st) SKM_sk_free(SSL_CIPHER, (st)) +# define sk_SSL_CIPHER_num(st) SKM_sk_num(SSL_CIPHER, (st)) +# define sk_SSL_CIPHER_value(st, i) SKM_sk_value(SSL_CIPHER, (st), (i)) +# define sk_SSL_CIPHER_set(st, i, val) SKM_sk_set(SSL_CIPHER, (st), (i), (val)) +# define sk_SSL_CIPHER_zero(st) SKM_sk_zero(SSL_CIPHER, (st)) +# define sk_SSL_CIPHER_push(st, val) SKM_sk_push(SSL_CIPHER, (st), (val)) +# define sk_SSL_CIPHER_unshift(st, val) SKM_sk_unshift(SSL_CIPHER, (st), (val)) +# define sk_SSL_CIPHER_find(st, val) SKM_sk_find(SSL_CIPHER, (st), (val)) +# define sk_SSL_CIPHER_find_ex(st, val) SKM_sk_find_ex(SSL_CIPHER, (st), (val)) +# define sk_SSL_CIPHER_delete(st, i) SKM_sk_delete(SSL_CIPHER, (st), (i)) +# define sk_SSL_CIPHER_delete_ptr(st, ptr) SKM_sk_delete_ptr(SSL_CIPHER, (st), (ptr)) +# define sk_SSL_CIPHER_insert(st, val, i) SKM_sk_insert(SSL_CIPHER, (st), (val), (i)) +# define sk_SSL_CIPHER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SSL_CIPHER, (st), (cmp)) +# define sk_SSL_CIPHER_dup(st) SKM_sk_dup(SSL_CIPHER, st) +# define sk_SSL_CIPHER_pop_free(st, free_func) SKM_sk_pop_free(SSL_CIPHER, (st), (free_func)) +# define sk_SSL_CIPHER_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SSL_CIPHER, (st), (copy_func), (free_func)) +# define sk_SSL_CIPHER_shift(st) SKM_sk_shift(SSL_CIPHER, (st)) +# define sk_SSL_CIPHER_pop(st) SKM_sk_pop(SSL_CIPHER, (st)) +# define sk_SSL_CIPHER_sort(st) SKM_sk_sort(SSL_CIPHER, (st)) +# define sk_SSL_CIPHER_is_sorted(st) SKM_sk_is_sorted(SSL_CIPHER, (st)) +# define sk_SSL_COMP_new(cmp) SKM_sk_new(SSL_COMP, (cmp)) +# define sk_SSL_COMP_new_null() SKM_sk_new_null(SSL_COMP) +# define sk_SSL_COMP_free(st) SKM_sk_free(SSL_COMP, (st)) +# define sk_SSL_COMP_num(st) SKM_sk_num(SSL_COMP, (st)) +# define sk_SSL_COMP_value(st, i) SKM_sk_value(SSL_COMP, (st), (i)) +# define sk_SSL_COMP_set(st, i, val) SKM_sk_set(SSL_COMP, (st), (i), (val)) +# define sk_SSL_COMP_zero(st) SKM_sk_zero(SSL_COMP, (st)) +# define sk_SSL_COMP_push(st, val) SKM_sk_push(SSL_COMP, (st), (val)) +# define sk_SSL_COMP_unshift(st, val) SKM_sk_unshift(SSL_COMP, (st), (val)) +# define sk_SSL_COMP_find(st, val) SKM_sk_find(SSL_COMP, (st), (val)) +# define sk_SSL_COMP_find_ex(st, val) SKM_sk_find_ex(SSL_COMP, (st), (val)) +# define sk_SSL_COMP_delete(st, i) SKM_sk_delete(SSL_COMP, (st), (i)) +# define sk_SSL_COMP_delete_ptr(st, ptr) SKM_sk_delete_ptr(SSL_COMP, (st), (ptr)) +# define sk_SSL_COMP_insert(st, val, i) SKM_sk_insert(SSL_COMP, (st), (val), (i)) +# define sk_SSL_COMP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SSL_COMP, (st), (cmp)) +# define sk_SSL_COMP_dup(st) SKM_sk_dup(SSL_COMP, st) +# define sk_SSL_COMP_pop_free(st, free_func) SKM_sk_pop_free(SSL_COMP, (st), (free_func)) +# define sk_SSL_COMP_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SSL_COMP, (st), (copy_func), (free_func)) +# define sk_SSL_COMP_shift(st) SKM_sk_shift(SSL_COMP, (st)) +# define sk_SSL_COMP_pop(st) SKM_sk_pop(SSL_COMP, (st)) +# define sk_SSL_COMP_sort(st) SKM_sk_sort(SSL_COMP, (st)) +# define sk_SSL_COMP_is_sorted(st) SKM_sk_is_sorted(SSL_COMP, (st)) +# define sk_STACK_OF_X509_NAME_ENTRY_new(cmp) SKM_sk_new(STACK_OF_X509_NAME_ENTRY, (cmp)) +# define sk_STACK_OF_X509_NAME_ENTRY_new_null() SKM_sk_new_null(STACK_OF_X509_NAME_ENTRY) +# define sk_STACK_OF_X509_NAME_ENTRY_free(st) SKM_sk_free(STACK_OF_X509_NAME_ENTRY, (st)) +# define sk_STACK_OF_X509_NAME_ENTRY_num(st) SKM_sk_num(STACK_OF_X509_NAME_ENTRY, (st)) +# define sk_STACK_OF_X509_NAME_ENTRY_value(st, i) SKM_sk_value(STACK_OF_X509_NAME_ENTRY, (st), (i)) +# define sk_STACK_OF_X509_NAME_ENTRY_set(st, i, val) SKM_sk_set(STACK_OF_X509_NAME_ENTRY, (st), (i), (val)) +# define sk_STACK_OF_X509_NAME_ENTRY_zero(st) SKM_sk_zero(STACK_OF_X509_NAME_ENTRY, (st)) +# define sk_STACK_OF_X509_NAME_ENTRY_push(st, val) SKM_sk_push(STACK_OF_X509_NAME_ENTRY, (st), (val)) +# define sk_STACK_OF_X509_NAME_ENTRY_unshift(st, val) SKM_sk_unshift(STACK_OF_X509_NAME_ENTRY, (st), (val)) +# define sk_STACK_OF_X509_NAME_ENTRY_find(st, val) SKM_sk_find(STACK_OF_X509_NAME_ENTRY, (st), (val)) +# define sk_STACK_OF_X509_NAME_ENTRY_find_ex(st, val) SKM_sk_find_ex(STACK_OF_X509_NAME_ENTRY, (st), (val)) +# define sk_STACK_OF_X509_NAME_ENTRY_delete(st, i) SKM_sk_delete(STACK_OF_X509_NAME_ENTRY, (st), (i)) +# define sk_STACK_OF_X509_NAME_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(STACK_OF_X509_NAME_ENTRY, (st), (ptr)) +# define sk_STACK_OF_X509_NAME_ENTRY_insert(st, val, i) SKM_sk_insert(STACK_OF_X509_NAME_ENTRY, (st), (val), (i)) +# define sk_STACK_OF_X509_NAME_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STACK_OF_X509_NAME_ENTRY, (st), (cmp)) +# define sk_STACK_OF_X509_NAME_ENTRY_dup(st) SKM_sk_dup(STACK_OF_X509_NAME_ENTRY, st) +# define sk_STACK_OF_X509_NAME_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(STACK_OF_X509_NAME_ENTRY, (st), (free_func)) +# define sk_STACK_OF_X509_NAME_ENTRY_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(STACK_OF_X509_NAME_ENTRY, (st), (copy_func), (free_func)) +# define sk_STACK_OF_X509_NAME_ENTRY_shift(st) SKM_sk_shift(STACK_OF_X509_NAME_ENTRY, (st)) +# define sk_STACK_OF_X509_NAME_ENTRY_pop(st) SKM_sk_pop(STACK_OF_X509_NAME_ENTRY, (st)) +# define sk_STACK_OF_X509_NAME_ENTRY_sort(st) SKM_sk_sort(STACK_OF_X509_NAME_ENTRY, (st)) +# define sk_STACK_OF_X509_NAME_ENTRY_is_sorted(st) SKM_sk_is_sorted(STACK_OF_X509_NAME_ENTRY, (st)) +# define sk_STORE_ATTR_INFO_new(cmp) SKM_sk_new(STORE_ATTR_INFO, (cmp)) +# define sk_STORE_ATTR_INFO_new_null() SKM_sk_new_null(STORE_ATTR_INFO) +# define sk_STORE_ATTR_INFO_free(st) SKM_sk_free(STORE_ATTR_INFO, (st)) +# define sk_STORE_ATTR_INFO_num(st) SKM_sk_num(STORE_ATTR_INFO, (st)) +# define sk_STORE_ATTR_INFO_value(st, i) SKM_sk_value(STORE_ATTR_INFO, (st), (i)) +# define sk_STORE_ATTR_INFO_set(st, i, val) SKM_sk_set(STORE_ATTR_INFO, (st), (i), (val)) +# define sk_STORE_ATTR_INFO_zero(st) SKM_sk_zero(STORE_ATTR_INFO, (st)) +# define sk_STORE_ATTR_INFO_push(st, val) SKM_sk_push(STORE_ATTR_INFO, (st), (val)) +# define sk_STORE_ATTR_INFO_unshift(st, val) SKM_sk_unshift(STORE_ATTR_INFO, (st), (val)) +# define sk_STORE_ATTR_INFO_find(st, val) SKM_sk_find(STORE_ATTR_INFO, (st), (val)) +# define sk_STORE_ATTR_INFO_find_ex(st, val) SKM_sk_find_ex(STORE_ATTR_INFO, (st), (val)) +# define sk_STORE_ATTR_INFO_delete(st, i) SKM_sk_delete(STORE_ATTR_INFO, (st), (i)) +# define sk_STORE_ATTR_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(STORE_ATTR_INFO, (st), (ptr)) +# define sk_STORE_ATTR_INFO_insert(st, val, i) SKM_sk_insert(STORE_ATTR_INFO, (st), (val), (i)) +# define sk_STORE_ATTR_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STORE_ATTR_INFO, (st), (cmp)) +# define sk_STORE_ATTR_INFO_dup(st) SKM_sk_dup(STORE_ATTR_INFO, st) +# define sk_STORE_ATTR_INFO_pop_free(st, free_func) SKM_sk_pop_free(STORE_ATTR_INFO, (st), (free_func)) +# define sk_STORE_ATTR_INFO_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(STORE_ATTR_INFO, (st), (copy_func), (free_func)) +# define sk_STORE_ATTR_INFO_shift(st) SKM_sk_shift(STORE_ATTR_INFO, (st)) +# define sk_STORE_ATTR_INFO_pop(st) SKM_sk_pop(STORE_ATTR_INFO, (st)) +# define sk_STORE_ATTR_INFO_sort(st) SKM_sk_sort(STORE_ATTR_INFO, (st)) +# define sk_STORE_ATTR_INFO_is_sorted(st) SKM_sk_is_sorted(STORE_ATTR_INFO, (st)) +# define sk_STORE_OBJECT_new(cmp) SKM_sk_new(STORE_OBJECT, (cmp)) +# define sk_STORE_OBJECT_new_null() SKM_sk_new_null(STORE_OBJECT) +# define sk_STORE_OBJECT_free(st) SKM_sk_free(STORE_OBJECT, (st)) +# define sk_STORE_OBJECT_num(st) SKM_sk_num(STORE_OBJECT, (st)) +# define sk_STORE_OBJECT_value(st, i) SKM_sk_value(STORE_OBJECT, (st), (i)) +# define sk_STORE_OBJECT_set(st, i, val) SKM_sk_set(STORE_OBJECT, (st), (i), (val)) +# define sk_STORE_OBJECT_zero(st) SKM_sk_zero(STORE_OBJECT, (st)) +# define sk_STORE_OBJECT_push(st, val) SKM_sk_push(STORE_OBJECT, (st), (val)) +# define sk_STORE_OBJECT_unshift(st, val) SKM_sk_unshift(STORE_OBJECT, (st), (val)) +# define sk_STORE_OBJECT_find(st, val) SKM_sk_find(STORE_OBJECT, (st), (val)) +# define sk_STORE_OBJECT_find_ex(st, val) SKM_sk_find_ex(STORE_OBJECT, (st), (val)) +# define sk_STORE_OBJECT_delete(st, i) SKM_sk_delete(STORE_OBJECT, (st), (i)) +# define sk_STORE_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(STORE_OBJECT, (st), (ptr)) +# define sk_STORE_OBJECT_insert(st, val, i) SKM_sk_insert(STORE_OBJECT, (st), (val), (i)) +# define sk_STORE_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STORE_OBJECT, (st), (cmp)) +# define sk_STORE_OBJECT_dup(st) SKM_sk_dup(STORE_OBJECT, st) +# define sk_STORE_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(STORE_OBJECT, (st), (free_func)) +# define sk_STORE_OBJECT_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(STORE_OBJECT, (st), (copy_func), (free_func)) +# define sk_STORE_OBJECT_shift(st) SKM_sk_shift(STORE_OBJECT, (st)) +# define sk_STORE_OBJECT_pop(st) SKM_sk_pop(STORE_OBJECT, (st)) +# define sk_STORE_OBJECT_sort(st) SKM_sk_sort(STORE_OBJECT, (st)) +# define sk_STORE_OBJECT_is_sorted(st) SKM_sk_is_sorted(STORE_OBJECT, (st)) +# define sk_SXNETID_new(cmp) SKM_sk_new(SXNETID, (cmp)) +# define sk_SXNETID_new_null() SKM_sk_new_null(SXNETID) +# define sk_SXNETID_free(st) SKM_sk_free(SXNETID, (st)) +# define sk_SXNETID_num(st) SKM_sk_num(SXNETID, (st)) +# define sk_SXNETID_value(st, i) SKM_sk_value(SXNETID, (st), (i)) +# define sk_SXNETID_set(st, i, val) SKM_sk_set(SXNETID, (st), (i), (val)) +# define sk_SXNETID_zero(st) SKM_sk_zero(SXNETID, (st)) +# define sk_SXNETID_push(st, val) SKM_sk_push(SXNETID, (st), (val)) +# define sk_SXNETID_unshift(st, val) SKM_sk_unshift(SXNETID, (st), (val)) +# define sk_SXNETID_find(st, val) SKM_sk_find(SXNETID, (st), (val)) +# define sk_SXNETID_find_ex(st, val) SKM_sk_find_ex(SXNETID, (st), (val)) +# define sk_SXNETID_delete(st, i) SKM_sk_delete(SXNETID, (st), (i)) +# define sk_SXNETID_delete_ptr(st, ptr) SKM_sk_delete_ptr(SXNETID, (st), (ptr)) +# define sk_SXNETID_insert(st, val, i) SKM_sk_insert(SXNETID, (st), (val), (i)) +# define sk_SXNETID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SXNETID, (st), (cmp)) +# define sk_SXNETID_dup(st) SKM_sk_dup(SXNETID, st) +# define sk_SXNETID_pop_free(st, free_func) SKM_sk_pop_free(SXNETID, (st), (free_func)) +# define sk_SXNETID_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SXNETID, (st), (copy_func), (free_func)) +# define sk_SXNETID_shift(st) SKM_sk_shift(SXNETID, (st)) +# define sk_SXNETID_pop(st) SKM_sk_pop(SXNETID, (st)) +# define sk_SXNETID_sort(st) SKM_sk_sort(SXNETID, (st)) +# define sk_SXNETID_is_sorted(st) SKM_sk_is_sorted(SXNETID, (st)) +# define sk_UI_STRING_new(cmp) SKM_sk_new(UI_STRING, (cmp)) +# define sk_UI_STRING_new_null() SKM_sk_new_null(UI_STRING) +# define sk_UI_STRING_free(st) SKM_sk_free(UI_STRING, (st)) +# define sk_UI_STRING_num(st) SKM_sk_num(UI_STRING, (st)) +# define sk_UI_STRING_value(st, i) SKM_sk_value(UI_STRING, (st), (i)) +# define sk_UI_STRING_set(st, i, val) SKM_sk_set(UI_STRING, (st), (i), (val)) +# define sk_UI_STRING_zero(st) SKM_sk_zero(UI_STRING, (st)) +# define sk_UI_STRING_push(st, val) SKM_sk_push(UI_STRING, (st), (val)) +# define sk_UI_STRING_unshift(st, val) SKM_sk_unshift(UI_STRING, (st), (val)) +# define sk_UI_STRING_find(st, val) SKM_sk_find(UI_STRING, (st), (val)) +# define sk_UI_STRING_find_ex(st, val) SKM_sk_find_ex(UI_STRING, (st), (val)) +# define sk_UI_STRING_delete(st, i) SKM_sk_delete(UI_STRING, (st), (i)) +# define sk_UI_STRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(UI_STRING, (st), (ptr)) +# define sk_UI_STRING_insert(st, val, i) SKM_sk_insert(UI_STRING, (st), (val), (i)) +# define sk_UI_STRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(UI_STRING, (st), (cmp)) +# define sk_UI_STRING_dup(st) SKM_sk_dup(UI_STRING, st) +# define sk_UI_STRING_pop_free(st, free_func) SKM_sk_pop_free(UI_STRING, (st), (free_func)) +# define sk_UI_STRING_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(UI_STRING, (st), (copy_func), (free_func)) +# define sk_UI_STRING_shift(st) SKM_sk_shift(UI_STRING, (st)) +# define sk_UI_STRING_pop(st) SKM_sk_pop(UI_STRING, (st)) +# define sk_UI_STRING_sort(st) SKM_sk_sort(UI_STRING, (st)) +# define sk_UI_STRING_is_sorted(st) SKM_sk_is_sorted(UI_STRING, (st)) +# define sk_X509_new(cmp) SKM_sk_new(X509, (cmp)) +# define sk_X509_new_null() SKM_sk_new_null(X509) +# define sk_X509_free(st) SKM_sk_free(X509, (st)) +# define sk_X509_num(st) SKM_sk_num(X509, (st)) +# define sk_X509_value(st, i) SKM_sk_value(X509, (st), (i)) +# define sk_X509_set(st, i, val) SKM_sk_set(X509, (st), (i), (val)) +# define sk_X509_zero(st) SKM_sk_zero(X509, (st)) +# define sk_X509_push(st, val) SKM_sk_push(X509, (st), (val)) +# define sk_X509_unshift(st, val) SKM_sk_unshift(X509, (st), (val)) +# define sk_X509_find(st, val) SKM_sk_find(X509, (st), (val)) +# define sk_X509_find_ex(st, val) SKM_sk_find_ex(X509, (st), (val)) +# define sk_X509_delete(st, i) SKM_sk_delete(X509, (st), (i)) +# define sk_X509_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509, (st), (ptr)) +# define sk_X509_insert(st, val, i) SKM_sk_insert(X509, (st), (val), (i)) +# define sk_X509_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509, (st), (cmp)) +# define sk_X509_dup(st) SKM_sk_dup(X509, st) +# define sk_X509_pop_free(st, free_func) SKM_sk_pop_free(X509, (st), (free_func)) +# define sk_X509_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509, (st), (copy_func), (free_func)) +# define sk_X509_shift(st) SKM_sk_shift(X509, (st)) +# define sk_X509_pop(st) SKM_sk_pop(X509, (st)) +# define sk_X509_sort(st) SKM_sk_sort(X509, (st)) +# define sk_X509_is_sorted(st) SKM_sk_is_sorted(X509, (st)) +# define sk_X509V3_EXT_METHOD_new(cmp) SKM_sk_new(X509V3_EXT_METHOD, (cmp)) +# define sk_X509V3_EXT_METHOD_new_null() SKM_sk_new_null(X509V3_EXT_METHOD) +# define sk_X509V3_EXT_METHOD_free(st) SKM_sk_free(X509V3_EXT_METHOD, (st)) +# define sk_X509V3_EXT_METHOD_num(st) SKM_sk_num(X509V3_EXT_METHOD, (st)) +# define sk_X509V3_EXT_METHOD_value(st, i) SKM_sk_value(X509V3_EXT_METHOD, (st), (i)) +# define sk_X509V3_EXT_METHOD_set(st, i, val) SKM_sk_set(X509V3_EXT_METHOD, (st), (i), (val)) +# define sk_X509V3_EXT_METHOD_zero(st) SKM_sk_zero(X509V3_EXT_METHOD, (st)) +# define sk_X509V3_EXT_METHOD_push(st, val) SKM_sk_push(X509V3_EXT_METHOD, (st), (val)) +# define sk_X509V3_EXT_METHOD_unshift(st, val) SKM_sk_unshift(X509V3_EXT_METHOD, (st), (val)) +# define sk_X509V3_EXT_METHOD_find(st, val) SKM_sk_find(X509V3_EXT_METHOD, (st), (val)) +# define sk_X509V3_EXT_METHOD_find_ex(st, val) SKM_sk_find_ex(X509V3_EXT_METHOD, (st), (val)) +# define sk_X509V3_EXT_METHOD_delete(st, i) SKM_sk_delete(X509V3_EXT_METHOD, (st), (i)) +# define sk_X509V3_EXT_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509V3_EXT_METHOD, (st), (ptr)) +# define sk_X509V3_EXT_METHOD_insert(st, val, i) SKM_sk_insert(X509V3_EXT_METHOD, (st), (val), (i)) +# define sk_X509V3_EXT_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509V3_EXT_METHOD, (st), (cmp)) +# define sk_X509V3_EXT_METHOD_dup(st) SKM_sk_dup(X509V3_EXT_METHOD, st) +# define sk_X509V3_EXT_METHOD_pop_free(st, free_func) SKM_sk_pop_free(X509V3_EXT_METHOD, (st), (free_func)) +# define sk_X509V3_EXT_METHOD_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509V3_EXT_METHOD, (st), (copy_func), (free_func)) +# define sk_X509V3_EXT_METHOD_shift(st) SKM_sk_shift(X509V3_EXT_METHOD, (st)) +# define sk_X509V3_EXT_METHOD_pop(st) SKM_sk_pop(X509V3_EXT_METHOD, (st)) +# define sk_X509V3_EXT_METHOD_sort(st) SKM_sk_sort(X509V3_EXT_METHOD, (st)) +# define sk_X509V3_EXT_METHOD_is_sorted(st) SKM_sk_is_sorted(X509V3_EXT_METHOD, (st)) +# define sk_X509_ALGOR_new(cmp) SKM_sk_new(X509_ALGOR, (cmp)) +# define sk_X509_ALGOR_new_null() SKM_sk_new_null(X509_ALGOR) +# define sk_X509_ALGOR_free(st) SKM_sk_free(X509_ALGOR, (st)) +# define sk_X509_ALGOR_num(st) SKM_sk_num(X509_ALGOR, (st)) +# define sk_X509_ALGOR_value(st, i) SKM_sk_value(X509_ALGOR, (st), (i)) +# define sk_X509_ALGOR_set(st, i, val) SKM_sk_set(X509_ALGOR, (st), (i), (val)) +# define sk_X509_ALGOR_zero(st) SKM_sk_zero(X509_ALGOR, (st)) +# define sk_X509_ALGOR_push(st, val) SKM_sk_push(X509_ALGOR, (st), (val)) +# define sk_X509_ALGOR_unshift(st, val) SKM_sk_unshift(X509_ALGOR, (st), (val)) +# define sk_X509_ALGOR_find(st, val) SKM_sk_find(X509_ALGOR, (st), (val)) +# define sk_X509_ALGOR_find_ex(st, val) SKM_sk_find_ex(X509_ALGOR, (st), (val)) +# define sk_X509_ALGOR_delete(st, i) SKM_sk_delete(X509_ALGOR, (st), (i)) +# define sk_X509_ALGOR_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_ALGOR, (st), (ptr)) +# define sk_X509_ALGOR_insert(st, val, i) SKM_sk_insert(X509_ALGOR, (st), (val), (i)) +# define sk_X509_ALGOR_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_ALGOR, (st), (cmp)) +# define sk_X509_ALGOR_dup(st) SKM_sk_dup(X509_ALGOR, st) +# define sk_X509_ALGOR_pop_free(st, free_func) SKM_sk_pop_free(X509_ALGOR, (st), (free_func)) +# define sk_X509_ALGOR_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_ALGOR, (st), (copy_func), (free_func)) +# define sk_X509_ALGOR_shift(st) SKM_sk_shift(X509_ALGOR, (st)) +# define sk_X509_ALGOR_pop(st) SKM_sk_pop(X509_ALGOR, (st)) +# define sk_X509_ALGOR_sort(st) SKM_sk_sort(X509_ALGOR, (st)) +# define sk_X509_ALGOR_is_sorted(st) SKM_sk_is_sorted(X509_ALGOR, (st)) +# define sk_X509_ATTRIBUTE_new(cmp) SKM_sk_new(X509_ATTRIBUTE, (cmp)) +# define sk_X509_ATTRIBUTE_new_null() SKM_sk_new_null(X509_ATTRIBUTE) +# define sk_X509_ATTRIBUTE_free(st) SKM_sk_free(X509_ATTRIBUTE, (st)) +# define sk_X509_ATTRIBUTE_num(st) SKM_sk_num(X509_ATTRIBUTE, (st)) +# define sk_X509_ATTRIBUTE_value(st, i) SKM_sk_value(X509_ATTRIBUTE, (st), (i)) +# define sk_X509_ATTRIBUTE_set(st, i, val) SKM_sk_set(X509_ATTRIBUTE, (st), (i), (val)) +# define sk_X509_ATTRIBUTE_zero(st) SKM_sk_zero(X509_ATTRIBUTE, (st)) +# define sk_X509_ATTRIBUTE_push(st, val) SKM_sk_push(X509_ATTRIBUTE, (st), (val)) +# define sk_X509_ATTRIBUTE_unshift(st, val) SKM_sk_unshift(X509_ATTRIBUTE, (st), (val)) +# define sk_X509_ATTRIBUTE_find(st, val) SKM_sk_find(X509_ATTRIBUTE, (st), (val)) +# define sk_X509_ATTRIBUTE_find_ex(st, val) SKM_sk_find_ex(X509_ATTRIBUTE, (st), (val)) +# define sk_X509_ATTRIBUTE_delete(st, i) SKM_sk_delete(X509_ATTRIBUTE, (st), (i)) +# define sk_X509_ATTRIBUTE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_ATTRIBUTE, (st), (ptr)) +# define sk_X509_ATTRIBUTE_insert(st, val, i) SKM_sk_insert(X509_ATTRIBUTE, (st), (val), (i)) +# define sk_X509_ATTRIBUTE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_ATTRIBUTE, (st), (cmp)) +# define sk_X509_ATTRIBUTE_dup(st) SKM_sk_dup(X509_ATTRIBUTE, st) +# define sk_X509_ATTRIBUTE_pop_free(st, free_func) SKM_sk_pop_free(X509_ATTRIBUTE, (st), (free_func)) +# define sk_X509_ATTRIBUTE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_ATTRIBUTE, (st), (copy_func), (free_func)) +# define sk_X509_ATTRIBUTE_shift(st) SKM_sk_shift(X509_ATTRIBUTE, (st)) +# define sk_X509_ATTRIBUTE_pop(st) SKM_sk_pop(X509_ATTRIBUTE, (st)) +# define sk_X509_ATTRIBUTE_sort(st) SKM_sk_sort(X509_ATTRIBUTE, (st)) +# define sk_X509_ATTRIBUTE_is_sorted(st) SKM_sk_is_sorted(X509_ATTRIBUTE, (st)) +# define sk_X509_CRL_new(cmp) SKM_sk_new(X509_CRL, (cmp)) +# define sk_X509_CRL_new_null() SKM_sk_new_null(X509_CRL) +# define sk_X509_CRL_free(st) SKM_sk_free(X509_CRL, (st)) +# define sk_X509_CRL_num(st) SKM_sk_num(X509_CRL, (st)) +# define sk_X509_CRL_value(st, i) SKM_sk_value(X509_CRL, (st), (i)) +# define sk_X509_CRL_set(st, i, val) SKM_sk_set(X509_CRL, (st), (i), (val)) +# define sk_X509_CRL_zero(st) SKM_sk_zero(X509_CRL, (st)) +# define sk_X509_CRL_push(st, val) SKM_sk_push(X509_CRL, (st), (val)) +# define sk_X509_CRL_unshift(st, val) SKM_sk_unshift(X509_CRL, (st), (val)) +# define sk_X509_CRL_find(st, val) SKM_sk_find(X509_CRL, (st), (val)) +# define sk_X509_CRL_find_ex(st, val) SKM_sk_find_ex(X509_CRL, (st), (val)) +# define sk_X509_CRL_delete(st, i) SKM_sk_delete(X509_CRL, (st), (i)) +# define sk_X509_CRL_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_CRL, (st), (ptr)) +# define sk_X509_CRL_insert(st, val, i) SKM_sk_insert(X509_CRL, (st), (val), (i)) +# define sk_X509_CRL_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_CRL, (st), (cmp)) +# define sk_X509_CRL_dup(st) SKM_sk_dup(X509_CRL, st) +# define sk_X509_CRL_pop_free(st, free_func) SKM_sk_pop_free(X509_CRL, (st), (free_func)) +# define sk_X509_CRL_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_CRL, (st), (copy_func), (free_func)) +# define sk_X509_CRL_shift(st) SKM_sk_shift(X509_CRL, (st)) +# define sk_X509_CRL_pop(st) SKM_sk_pop(X509_CRL, (st)) +# define sk_X509_CRL_sort(st) SKM_sk_sort(X509_CRL, (st)) +# define sk_X509_CRL_is_sorted(st) SKM_sk_is_sorted(X509_CRL, (st)) +# define sk_X509_EXTENSION_new(cmp) SKM_sk_new(X509_EXTENSION, (cmp)) +# define sk_X509_EXTENSION_new_null() SKM_sk_new_null(X509_EXTENSION) +# define sk_X509_EXTENSION_free(st) SKM_sk_free(X509_EXTENSION, (st)) +# define sk_X509_EXTENSION_num(st) SKM_sk_num(X509_EXTENSION, (st)) +# define sk_X509_EXTENSION_value(st, i) SKM_sk_value(X509_EXTENSION, (st), (i)) +# define sk_X509_EXTENSION_set(st, i, val) SKM_sk_set(X509_EXTENSION, (st), (i), (val)) +# define sk_X509_EXTENSION_zero(st) SKM_sk_zero(X509_EXTENSION, (st)) +# define sk_X509_EXTENSION_push(st, val) SKM_sk_push(X509_EXTENSION, (st), (val)) +# define sk_X509_EXTENSION_unshift(st, val) SKM_sk_unshift(X509_EXTENSION, (st), (val)) +# define sk_X509_EXTENSION_find(st, val) SKM_sk_find(X509_EXTENSION, (st), (val)) +# define sk_X509_EXTENSION_find_ex(st, val) SKM_sk_find_ex(X509_EXTENSION, (st), (val)) +# define sk_X509_EXTENSION_delete(st, i) SKM_sk_delete(X509_EXTENSION, (st), (i)) +# define sk_X509_EXTENSION_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_EXTENSION, (st), (ptr)) +# define sk_X509_EXTENSION_insert(st, val, i) SKM_sk_insert(X509_EXTENSION, (st), (val), (i)) +# define sk_X509_EXTENSION_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_EXTENSION, (st), (cmp)) +# define sk_X509_EXTENSION_dup(st) SKM_sk_dup(X509_EXTENSION, st) +# define sk_X509_EXTENSION_pop_free(st, free_func) SKM_sk_pop_free(X509_EXTENSION, (st), (free_func)) +# define sk_X509_EXTENSION_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_EXTENSION, (st), (copy_func), (free_func)) +# define sk_X509_EXTENSION_shift(st) SKM_sk_shift(X509_EXTENSION, (st)) +# define sk_X509_EXTENSION_pop(st) SKM_sk_pop(X509_EXTENSION, (st)) +# define sk_X509_EXTENSION_sort(st) SKM_sk_sort(X509_EXTENSION, (st)) +# define sk_X509_EXTENSION_is_sorted(st) SKM_sk_is_sorted(X509_EXTENSION, (st)) +# define sk_X509_INFO_new(cmp) SKM_sk_new(X509_INFO, (cmp)) +# define sk_X509_INFO_new_null() SKM_sk_new_null(X509_INFO) +# define sk_X509_INFO_free(st) SKM_sk_free(X509_INFO, (st)) +# define sk_X509_INFO_num(st) SKM_sk_num(X509_INFO, (st)) +# define sk_X509_INFO_value(st, i) SKM_sk_value(X509_INFO, (st), (i)) +# define sk_X509_INFO_set(st, i, val) SKM_sk_set(X509_INFO, (st), (i), (val)) +# define sk_X509_INFO_zero(st) SKM_sk_zero(X509_INFO, (st)) +# define sk_X509_INFO_push(st, val) SKM_sk_push(X509_INFO, (st), (val)) +# define sk_X509_INFO_unshift(st, val) SKM_sk_unshift(X509_INFO, (st), (val)) +# define sk_X509_INFO_find(st, val) SKM_sk_find(X509_INFO, (st), (val)) +# define sk_X509_INFO_find_ex(st, val) SKM_sk_find_ex(X509_INFO, (st), (val)) +# define sk_X509_INFO_delete(st, i) SKM_sk_delete(X509_INFO, (st), (i)) +# define sk_X509_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_INFO, (st), (ptr)) +# define sk_X509_INFO_insert(st, val, i) SKM_sk_insert(X509_INFO, (st), (val), (i)) +# define sk_X509_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_INFO, (st), (cmp)) +# define sk_X509_INFO_dup(st) SKM_sk_dup(X509_INFO, st) +# define sk_X509_INFO_pop_free(st, free_func) SKM_sk_pop_free(X509_INFO, (st), (free_func)) +# define sk_X509_INFO_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_INFO, (st), (copy_func), (free_func)) +# define sk_X509_INFO_shift(st) SKM_sk_shift(X509_INFO, (st)) +# define sk_X509_INFO_pop(st) SKM_sk_pop(X509_INFO, (st)) +# define sk_X509_INFO_sort(st) SKM_sk_sort(X509_INFO, (st)) +# define sk_X509_INFO_is_sorted(st) SKM_sk_is_sorted(X509_INFO, (st)) +# define sk_X509_LOOKUP_new(cmp) SKM_sk_new(X509_LOOKUP, (cmp)) +# define sk_X509_LOOKUP_new_null() SKM_sk_new_null(X509_LOOKUP) +# define sk_X509_LOOKUP_free(st) SKM_sk_free(X509_LOOKUP, (st)) +# define sk_X509_LOOKUP_num(st) SKM_sk_num(X509_LOOKUP, (st)) +# define sk_X509_LOOKUP_value(st, i) SKM_sk_value(X509_LOOKUP, (st), (i)) +# define sk_X509_LOOKUP_set(st, i, val) SKM_sk_set(X509_LOOKUP, (st), (i), (val)) +# define sk_X509_LOOKUP_zero(st) SKM_sk_zero(X509_LOOKUP, (st)) +# define sk_X509_LOOKUP_push(st, val) SKM_sk_push(X509_LOOKUP, (st), (val)) +# define sk_X509_LOOKUP_unshift(st, val) SKM_sk_unshift(X509_LOOKUP, (st), (val)) +# define sk_X509_LOOKUP_find(st, val) SKM_sk_find(X509_LOOKUP, (st), (val)) +# define sk_X509_LOOKUP_find_ex(st, val) SKM_sk_find_ex(X509_LOOKUP, (st), (val)) +# define sk_X509_LOOKUP_delete(st, i) SKM_sk_delete(X509_LOOKUP, (st), (i)) +# define sk_X509_LOOKUP_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_LOOKUP, (st), (ptr)) +# define sk_X509_LOOKUP_insert(st, val, i) SKM_sk_insert(X509_LOOKUP, (st), (val), (i)) +# define sk_X509_LOOKUP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_LOOKUP, (st), (cmp)) +# define sk_X509_LOOKUP_dup(st) SKM_sk_dup(X509_LOOKUP, st) +# define sk_X509_LOOKUP_pop_free(st, free_func) SKM_sk_pop_free(X509_LOOKUP, (st), (free_func)) +# define sk_X509_LOOKUP_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_LOOKUP, (st), (copy_func), (free_func)) +# define sk_X509_LOOKUP_shift(st) SKM_sk_shift(X509_LOOKUP, (st)) +# define sk_X509_LOOKUP_pop(st) SKM_sk_pop(X509_LOOKUP, (st)) +# define sk_X509_LOOKUP_sort(st) SKM_sk_sort(X509_LOOKUP, (st)) +# define sk_X509_LOOKUP_is_sorted(st) SKM_sk_is_sorted(X509_LOOKUP, (st)) +# define sk_X509_NAME_new(cmp) SKM_sk_new(X509_NAME, (cmp)) +# define sk_X509_NAME_new_null() SKM_sk_new_null(X509_NAME) +# define sk_X509_NAME_free(st) SKM_sk_free(X509_NAME, (st)) +# define sk_X509_NAME_num(st) SKM_sk_num(X509_NAME, (st)) +# define sk_X509_NAME_value(st, i) SKM_sk_value(X509_NAME, (st), (i)) +# define sk_X509_NAME_set(st, i, val) SKM_sk_set(X509_NAME, (st), (i), (val)) +# define sk_X509_NAME_zero(st) SKM_sk_zero(X509_NAME, (st)) +# define sk_X509_NAME_push(st, val) SKM_sk_push(X509_NAME, (st), (val)) +# define sk_X509_NAME_unshift(st, val) SKM_sk_unshift(X509_NAME, (st), (val)) +# define sk_X509_NAME_find(st, val) SKM_sk_find(X509_NAME, (st), (val)) +# define sk_X509_NAME_find_ex(st, val) SKM_sk_find_ex(X509_NAME, (st), (val)) +# define sk_X509_NAME_delete(st, i) SKM_sk_delete(X509_NAME, (st), (i)) +# define sk_X509_NAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_NAME, (st), (ptr)) +# define sk_X509_NAME_insert(st, val, i) SKM_sk_insert(X509_NAME, (st), (val), (i)) +# define sk_X509_NAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_NAME, (st), (cmp)) +# define sk_X509_NAME_dup(st) SKM_sk_dup(X509_NAME, st) +# define sk_X509_NAME_pop_free(st, free_func) SKM_sk_pop_free(X509_NAME, (st), (free_func)) +# define sk_X509_NAME_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_NAME, (st), (copy_func), (free_func)) +# define sk_X509_NAME_shift(st) SKM_sk_shift(X509_NAME, (st)) +# define sk_X509_NAME_pop(st) SKM_sk_pop(X509_NAME, (st)) +# define sk_X509_NAME_sort(st) SKM_sk_sort(X509_NAME, (st)) +# define sk_X509_NAME_is_sorted(st) SKM_sk_is_sorted(X509_NAME, (st)) +# define sk_X509_NAME_ENTRY_new(cmp) SKM_sk_new(X509_NAME_ENTRY, (cmp)) +# define sk_X509_NAME_ENTRY_new_null() SKM_sk_new_null(X509_NAME_ENTRY) +# define sk_X509_NAME_ENTRY_free(st) SKM_sk_free(X509_NAME_ENTRY, (st)) +# define sk_X509_NAME_ENTRY_num(st) SKM_sk_num(X509_NAME_ENTRY, (st)) +# define sk_X509_NAME_ENTRY_value(st, i) SKM_sk_value(X509_NAME_ENTRY, (st), (i)) +# define sk_X509_NAME_ENTRY_set(st, i, val) SKM_sk_set(X509_NAME_ENTRY, (st), (i), (val)) +# define sk_X509_NAME_ENTRY_zero(st) SKM_sk_zero(X509_NAME_ENTRY, (st)) +# define sk_X509_NAME_ENTRY_push(st, val) SKM_sk_push(X509_NAME_ENTRY, (st), (val)) +# define sk_X509_NAME_ENTRY_unshift(st, val) SKM_sk_unshift(X509_NAME_ENTRY, (st), (val)) +# define sk_X509_NAME_ENTRY_find(st, val) SKM_sk_find(X509_NAME_ENTRY, (st), (val)) +# define sk_X509_NAME_ENTRY_find_ex(st, val) SKM_sk_find_ex(X509_NAME_ENTRY, (st), (val)) +# define sk_X509_NAME_ENTRY_delete(st, i) SKM_sk_delete(X509_NAME_ENTRY, (st), (i)) +# define sk_X509_NAME_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_NAME_ENTRY, (st), (ptr)) +# define sk_X509_NAME_ENTRY_insert(st, val, i) SKM_sk_insert(X509_NAME_ENTRY, (st), (val), (i)) +# define sk_X509_NAME_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_NAME_ENTRY, (st), (cmp)) +# define sk_X509_NAME_ENTRY_dup(st) SKM_sk_dup(X509_NAME_ENTRY, st) +# define sk_X509_NAME_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(X509_NAME_ENTRY, (st), (free_func)) +# define sk_X509_NAME_ENTRY_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_NAME_ENTRY, (st), (copy_func), (free_func)) +# define sk_X509_NAME_ENTRY_shift(st) SKM_sk_shift(X509_NAME_ENTRY, (st)) +# define sk_X509_NAME_ENTRY_pop(st) SKM_sk_pop(X509_NAME_ENTRY, (st)) +# define sk_X509_NAME_ENTRY_sort(st) SKM_sk_sort(X509_NAME_ENTRY, (st)) +# define sk_X509_NAME_ENTRY_is_sorted(st) SKM_sk_is_sorted(X509_NAME_ENTRY, (st)) +# define sk_X509_OBJECT_new(cmp) SKM_sk_new(X509_OBJECT, (cmp)) +# define sk_X509_OBJECT_new_null() SKM_sk_new_null(X509_OBJECT) +# define sk_X509_OBJECT_free(st) SKM_sk_free(X509_OBJECT, (st)) +# define sk_X509_OBJECT_num(st) SKM_sk_num(X509_OBJECT, (st)) +# define sk_X509_OBJECT_value(st, i) SKM_sk_value(X509_OBJECT, (st), (i)) +# define sk_X509_OBJECT_set(st, i, val) SKM_sk_set(X509_OBJECT, (st), (i), (val)) +# define sk_X509_OBJECT_zero(st) SKM_sk_zero(X509_OBJECT, (st)) +# define sk_X509_OBJECT_push(st, val) SKM_sk_push(X509_OBJECT, (st), (val)) +# define sk_X509_OBJECT_unshift(st, val) SKM_sk_unshift(X509_OBJECT, (st), (val)) +# define sk_X509_OBJECT_find(st, val) SKM_sk_find(X509_OBJECT, (st), (val)) +# define sk_X509_OBJECT_find_ex(st, val) SKM_sk_find_ex(X509_OBJECT, (st), (val)) +# define sk_X509_OBJECT_delete(st, i) SKM_sk_delete(X509_OBJECT, (st), (i)) +# define sk_X509_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_OBJECT, (st), (ptr)) +# define sk_X509_OBJECT_insert(st, val, i) SKM_sk_insert(X509_OBJECT, (st), (val), (i)) +# define sk_X509_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_OBJECT, (st), (cmp)) +# define sk_X509_OBJECT_dup(st) SKM_sk_dup(X509_OBJECT, st) +# define sk_X509_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(X509_OBJECT, (st), (free_func)) +# define sk_X509_OBJECT_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_OBJECT, (st), (copy_func), (free_func)) +# define sk_X509_OBJECT_shift(st) SKM_sk_shift(X509_OBJECT, (st)) +# define sk_X509_OBJECT_pop(st) SKM_sk_pop(X509_OBJECT, (st)) +# define sk_X509_OBJECT_sort(st) SKM_sk_sort(X509_OBJECT, (st)) +# define sk_X509_OBJECT_is_sorted(st) SKM_sk_is_sorted(X509_OBJECT, (st)) +# define sk_X509_POLICY_DATA_new(cmp) SKM_sk_new(X509_POLICY_DATA, (cmp)) +# define sk_X509_POLICY_DATA_new_null() SKM_sk_new_null(X509_POLICY_DATA) +# define sk_X509_POLICY_DATA_free(st) SKM_sk_free(X509_POLICY_DATA, (st)) +# define sk_X509_POLICY_DATA_num(st) SKM_sk_num(X509_POLICY_DATA, (st)) +# define sk_X509_POLICY_DATA_value(st, i) SKM_sk_value(X509_POLICY_DATA, (st), (i)) +# define sk_X509_POLICY_DATA_set(st, i, val) SKM_sk_set(X509_POLICY_DATA, (st), (i), (val)) +# define sk_X509_POLICY_DATA_zero(st) SKM_sk_zero(X509_POLICY_DATA, (st)) +# define sk_X509_POLICY_DATA_push(st, val) SKM_sk_push(X509_POLICY_DATA, (st), (val)) +# define sk_X509_POLICY_DATA_unshift(st, val) SKM_sk_unshift(X509_POLICY_DATA, (st), (val)) +# define sk_X509_POLICY_DATA_find(st, val) SKM_sk_find(X509_POLICY_DATA, (st), (val)) +# define sk_X509_POLICY_DATA_find_ex(st, val) SKM_sk_find_ex(X509_POLICY_DATA, (st), (val)) +# define sk_X509_POLICY_DATA_delete(st, i) SKM_sk_delete(X509_POLICY_DATA, (st), (i)) +# define sk_X509_POLICY_DATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_DATA, (st), (ptr)) +# define sk_X509_POLICY_DATA_insert(st, val, i) SKM_sk_insert(X509_POLICY_DATA, (st), (val), (i)) +# define sk_X509_POLICY_DATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_DATA, (st), (cmp)) +# define sk_X509_POLICY_DATA_dup(st) SKM_sk_dup(X509_POLICY_DATA, st) +# define sk_X509_POLICY_DATA_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_DATA, (st), (free_func)) +# define sk_X509_POLICY_DATA_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_POLICY_DATA, (st), (copy_func), (free_func)) +# define sk_X509_POLICY_DATA_shift(st) SKM_sk_shift(X509_POLICY_DATA, (st)) +# define sk_X509_POLICY_DATA_pop(st) SKM_sk_pop(X509_POLICY_DATA, (st)) +# define sk_X509_POLICY_DATA_sort(st) SKM_sk_sort(X509_POLICY_DATA, (st)) +# define sk_X509_POLICY_DATA_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_DATA, (st)) +# define sk_X509_POLICY_NODE_new(cmp) SKM_sk_new(X509_POLICY_NODE, (cmp)) +# define sk_X509_POLICY_NODE_new_null() SKM_sk_new_null(X509_POLICY_NODE) +# define sk_X509_POLICY_NODE_free(st) SKM_sk_free(X509_POLICY_NODE, (st)) +# define sk_X509_POLICY_NODE_num(st) SKM_sk_num(X509_POLICY_NODE, (st)) +# define sk_X509_POLICY_NODE_value(st, i) SKM_sk_value(X509_POLICY_NODE, (st), (i)) +# define sk_X509_POLICY_NODE_set(st, i, val) SKM_sk_set(X509_POLICY_NODE, (st), (i), (val)) +# define sk_X509_POLICY_NODE_zero(st) SKM_sk_zero(X509_POLICY_NODE, (st)) +# define sk_X509_POLICY_NODE_push(st, val) SKM_sk_push(X509_POLICY_NODE, (st), (val)) +# define sk_X509_POLICY_NODE_unshift(st, val) SKM_sk_unshift(X509_POLICY_NODE, (st), (val)) +# define sk_X509_POLICY_NODE_find(st, val) SKM_sk_find(X509_POLICY_NODE, (st), (val)) +# define sk_X509_POLICY_NODE_find_ex(st, val) SKM_sk_find_ex(X509_POLICY_NODE, (st), (val)) +# define sk_X509_POLICY_NODE_delete(st, i) SKM_sk_delete(X509_POLICY_NODE, (st), (i)) +# define sk_X509_POLICY_NODE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_NODE, (st), (ptr)) +# define sk_X509_POLICY_NODE_insert(st, val, i) SKM_sk_insert(X509_POLICY_NODE, (st), (val), (i)) +# define sk_X509_POLICY_NODE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_NODE, (st), (cmp)) +# define sk_X509_POLICY_NODE_dup(st) SKM_sk_dup(X509_POLICY_NODE, st) +# define sk_X509_POLICY_NODE_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_NODE, (st), (free_func)) +# define sk_X509_POLICY_NODE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_POLICY_NODE, (st), (copy_func), (free_func)) +# define sk_X509_POLICY_NODE_shift(st) SKM_sk_shift(X509_POLICY_NODE, (st)) +# define sk_X509_POLICY_NODE_pop(st) SKM_sk_pop(X509_POLICY_NODE, (st)) +# define sk_X509_POLICY_NODE_sort(st) SKM_sk_sort(X509_POLICY_NODE, (st)) +# define sk_X509_POLICY_NODE_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_NODE, (st)) +# define sk_X509_PURPOSE_new(cmp) SKM_sk_new(X509_PURPOSE, (cmp)) +# define sk_X509_PURPOSE_new_null() SKM_sk_new_null(X509_PURPOSE) +# define sk_X509_PURPOSE_free(st) SKM_sk_free(X509_PURPOSE, (st)) +# define sk_X509_PURPOSE_num(st) SKM_sk_num(X509_PURPOSE, (st)) +# define sk_X509_PURPOSE_value(st, i) SKM_sk_value(X509_PURPOSE, (st), (i)) +# define sk_X509_PURPOSE_set(st, i, val) SKM_sk_set(X509_PURPOSE, (st), (i), (val)) +# define sk_X509_PURPOSE_zero(st) SKM_sk_zero(X509_PURPOSE, (st)) +# define sk_X509_PURPOSE_push(st, val) SKM_sk_push(X509_PURPOSE, (st), (val)) +# define sk_X509_PURPOSE_unshift(st, val) SKM_sk_unshift(X509_PURPOSE, (st), (val)) +# define sk_X509_PURPOSE_find(st, val) SKM_sk_find(X509_PURPOSE, (st), (val)) +# define sk_X509_PURPOSE_find_ex(st, val) SKM_sk_find_ex(X509_PURPOSE, (st), (val)) +# define sk_X509_PURPOSE_delete(st, i) SKM_sk_delete(X509_PURPOSE, (st), (i)) +# define sk_X509_PURPOSE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_PURPOSE, (st), (ptr)) +# define sk_X509_PURPOSE_insert(st, val, i) SKM_sk_insert(X509_PURPOSE, (st), (val), (i)) +# define sk_X509_PURPOSE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_PURPOSE, (st), (cmp)) +# define sk_X509_PURPOSE_dup(st) SKM_sk_dup(X509_PURPOSE, st) +# define sk_X509_PURPOSE_pop_free(st, free_func) SKM_sk_pop_free(X509_PURPOSE, (st), (free_func)) +# define sk_X509_PURPOSE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_PURPOSE, (st), (copy_func), (free_func)) +# define sk_X509_PURPOSE_shift(st) SKM_sk_shift(X509_PURPOSE, (st)) +# define sk_X509_PURPOSE_pop(st) SKM_sk_pop(X509_PURPOSE, (st)) +# define sk_X509_PURPOSE_sort(st) SKM_sk_sort(X509_PURPOSE, (st)) +# define sk_X509_PURPOSE_is_sorted(st) SKM_sk_is_sorted(X509_PURPOSE, (st)) +# define sk_X509_REVOKED_new(cmp) SKM_sk_new(X509_REVOKED, (cmp)) +# define sk_X509_REVOKED_new_null() SKM_sk_new_null(X509_REVOKED) +# define sk_X509_REVOKED_free(st) SKM_sk_free(X509_REVOKED, (st)) +# define sk_X509_REVOKED_num(st) SKM_sk_num(X509_REVOKED, (st)) +# define sk_X509_REVOKED_value(st, i) SKM_sk_value(X509_REVOKED, (st), (i)) +# define sk_X509_REVOKED_set(st, i, val) SKM_sk_set(X509_REVOKED, (st), (i), (val)) +# define sk_X509_REVOKED_zero(st) SKM_sk_zero(X509_REVOKED, (st)) +# define sk_X509_REVOKED_push(st, val) SKM_sk_push(X509_REVOKED, (st), (val)) +# define sk_X509_REVOKED_unshift(st, val) SKM_sk_unshift(X509_REVOKED, (st), (val)) +# define sk_X509_REVOKED_find(st, val) SKM_sk_find(X509_REVOKED, (st), (val)) +# define sk_X509_REVOKED_find_ex(st, val) SKM_sk_find_ex(X509_REVOKED, (st), (val)) +# define sk_X509_REVOKED_delete(st, i) SKM_sk_delete(X509_REVOKED, (st), (i)) +# define sk_X509_REVOKED_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_REVOKED, (st), (ptr)) +# define sk_X509_REVOKED_insert(st, val, i) SKM_sk_insert(X509_REVOKED, (st), (val), (i)) +# define sk_X509_REVOKED_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_REVOKED, (st), (cmp)) +# define sk_X509_REVOKED_dup(st) SKM_sk_dup(X509_REVOKED, st) +# define sk_X509_REVOKED_pop_free(st, free_func) SKM_sk_pop_free(X509_REVOKED, (st), (free_func)) +# define sk_X509_REVOKED_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_REVOKED, (st), (copy_func), (free_func)) +# define sk_X509_REVOKED_shift(st) SKM_sk_shift(X509_REVOKED, (st)) +# define sk_X509_REVOKED_pop(st) SKM_sk_pop(X509_REVOKED, (st)) +# define sk_X509_REVOKED_sort(st) SKM_sk_sort(X509_REVOKED, (st)) +# define sk_X509_REVOKED_is_sorted(st) SKM_sk_is_sorted(X509_REVOKED, (st)) +# define sk_X509_TRUST_new(cmp) SKM_sk_new(X509_TRUST, (cmp)) +# define sk_X509_TRUST_new_null() SKM_sk_new_null(X509_TRUST) +# define sk_X509_TRUST_free(st) SKM_sk_free(X509_TRUST, (st)) +# define sk_X509_TRUST_num(st) SKM_sk_num(X509_TRUST, (st)) +# define sk_X509_TRUST_value(st, i) SKM_sk_value(X509_TRUST, (st), (i)) +# define sk_X509_TRUST_set(st, i, val) SKM_sk_set(X509_TRUST, (st), (i), (val)) +# define sk_X509_TRUST_zero(st) SKM_sk_zero(X509_TRUST, (st)) +# define sk_X509_TRUST_push(st, val) SKM_sk_push(X509_TRUST, (st), (val)) +# define sk_X509_TRUST_unshift(st, val) SKM_sk_unshift(X509_TRUST, (st), (val)) +# define sk_X509_TRUST_find(st, val) SKM_sk_find(X509_TRUST, (st), (val)) +# define sk_X509_TRUST_find_ex(st, val) SKM_sk_find_ex(X509_TRUST, (st), (val)) +# define sk_X509_TRUST_delete(st, i) SKM_sk_delete(X509_TRUST, (st), (i)) +# define sk_X509_TRUST_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_TRUST, (st), (ptr)) +# define sk_X509_TRUST_insert(st, val, i) SKM_sk_insert(X509_TRUST, (st), (val), (i)) +# define sk_X509_TRUST_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_TRUST, (st), (cmp)) +# define sk_X509_TRUST_dup(st) SKM_sk_dup(X509_TRUST, st) +# define sk_X509_TRUST_pop_free(st, free_func) SKM_sk_pop_free(X509_TRUST, (st), (free_func)) +# define sk_X509_TRUST_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_TRUST, (st), (copy_func), (free_func)) +# define sk_X509_TRUST_shift(st) SKM_sk_shift(X509_TRUST, (st)) +# define sk_X509_TRUST_pop(st) SKM_sk_pop(X509_TRUST, (st)) +# define sk_X509_TRUST_sort(st) SKM_sk_sort(X509_TRUST, (st)) +# define sk_X509_TRUST_is_sorted(st) SKM_sk_is_sorted(X509_TRUST, (st)) +# define sk_X509_VERIFY_PARAM_new(cmp) SKM_sk_new(X509_VERIFY_PARAM, (cmp)) +# define sk_X509_VERIFY_PARAM_new_null() SKM_sk_new_null(X509_VERIFY_PARAM) +# define sk_X509_VERIFY_PARAM_free(st) SKM_sk_free(X509_VERIFY_PARAM, (st)) +# define sk_X509_VERIFY_PARAM_num(st) SKM_sk_num(X509_VERIFY_PARAM, (st)) +# define sk_X509_VERIFY_PARAM_value(st, i) SKM_sk_value(X509_VERIFY_PARAM, (st), (i)) +# define sk_X509_VERIFY_PARAM_set(st, i, val) SKM_sk_set(X509_VERIFY_PARAM, (st), (i), (val)) +# define sk_X509_VERIFY_PARAM_zero(st) SKM_sk_zero(X509_VERIFY_PARAM, (st)) +# define sk_X509_VERIFY_PARAM_push(st, val) SKM_sk_push(X509_VERIFY_PARAM, (st), (val)) +# define sk_X509_VERIFY_PARAM_unshift(st, val) SKM_sk_unshift(X509_VERIFY_PARAM, (st), (val)) +# define sk_X509_VERIFY_PARAM_find(st, val) SKM_sk_find(X509_VERIFY_PARAM, (st), (val)) +# define sk_X509_VERIFY_PARAM_find_ex(st, val) SKM_sk_find_ex(X509_VERIFY_PARAM, (st), (val)) +# define sk_X509_VERIFY_PARAM_delete(st, i) SKM_sk_delete(X509_VERIFY_PARAM, (st), (i)) +# define sk_X509_VERIFY_PARAM_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_VERIFY_PARAM, (st), (ptr)) +# define sk_X509_VERIFY_PARAM_insert(st, val, i) SKM_sk_insert(X509_VERIFY_PARAM, (st), (val), (i)) +# define sk_X509_VERIFY_PARAM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_VERIFY_PARAM, (st), (cmp)) +# define sk_X509_VERIFY_PARAM_dup(st) SKM_sk_dup(X509_VERIFY_PARAM, st) +# define sk_X509_VERIFY_PARAM_pop_free(st, free_func) SKM_sk_pop_free(X509_VERIFY_PARAM, (st), (free_func)) +# define sk_X509_VERIFY_PARAM_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_VERIFY_PARAM, (st), (copy_func), (free_func)) +# define sk_X509_VERIFY_PARAM_shift(st) SKM_sk_shift(X509_VERIFY_PARAM, (st)) +# define sk_X509_VERIFY_PARAM_pop(st) SKM_sk_pop(X509_VERIFY_PARAM, (st)) +# define sk_X509_VERIFY_PARAM_sort(st) SKM_sk_sort(X509_VERIFY_PARAM, (st)) +# define sk_X509_VERIFY_PARAM_is_sorted(st) SKM_sk_is_sorted(X509_VERIFY_PARAM, (st)) +# define sk_nid_triple_new(cmp) SKM_sk_new(nid_triple, (cmp)) +# define sk_nid_triple_new_null() SKM_sk_new_null(nid_triple) +# define sk_nid_triple_free(st) SKM_sk_free(nid_triple, (st)) +# define sk_nid_triple_num(st) SKM_sk_num(nid_triple, (st)) +# define sk_nid_triple_value(st, i) SKM_sk_value(nid_triple, (st), (i)) +# define sk_nid_triple_set(st, i, val) SKM_sk_set(nid_triple, (st), (i), (val)) +# define sk_nid_triple_zero(st) SKM_sk_zero(nid_triple, (st)) +# define sk_nid_triple_push(st, val) SKM_sk_push(nid_triple, (st), (val)) +# define sk_nid_triple_unshift(st, val) SKM_sk_unshift(nid_triple, (st), (val)) +# define sk_nid_triple_find(st, val) SKM_sk_find(nid_triple, (st), (val)) +# define sk_nid_triple_find_ex(st, val) SKM_sk_find_ex(nid_triple, (st), (val)) +# define sk_nid_triple_delete(st, i) SKM_sk_delete(nid_triple, (st), (i)) +# define sk_nid_triple_delete_ptr(st, ptr) SKM_sk_delete_ptr(nid_triple, (st), (ptr)) +# define sk_nid_triple_insert(st, val, i) SKM_sk_insert(nid_triple, (st), (val), (i)) +# define sk_nid_triple_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(nid_triple, (st), (cmp)) +# define sk_nid_triple_dup(st) SKM_sk_dup(nid_triple, st) +# define sk_nid_triple_pop_free(st, free_func) SKM_sk_pop_free(nid_triple, (st), (free_func)) +# define sk_nid_triple_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(nid_triple, (st), (copy_func), (free_func)) +# define sk_nid_triple_shift(st) SKM_sk_shift(nid_triple, (st)) +# define sk_nid_triple_pop(st) SKM_sk_pop(nid_triple, (st)) +# define sk_nid_triple_sort(st) SKM_sk_sort(nid_triple, (st)) +# define sk_nid_triple_is_sorted(st) SKM_sk_is_sorted(nid_triple, (st)) +# define sk_void_new(cmp) SKM_sk_new(void, (cmp)) +# define sk_void_new_null() SKM_sk_new_null(void) +# define sk_void_free(st) SKM_sk_free(void, (st)) +# define sk_void_num(st) SKM_sk_num(void, (st)) +# define sk_void_value(st, i) SKM_sk_value(void, (st), (i)) +# define sk_void_set(st, i, val) SKM_sk_set(void, (st), (i), (val)) +# define sk_void_zero(st) SKM_sk_zero(void, (st)) +# define sk_void_push(st, val) SKM_sk_push(void, (st), (val)) +# define sk_void_unshift(st, val) SKM_sk_unshift(void, (st), (val)) +# define sk_void_find(st, val) SKM_sk_find(void, (st), (val)) +# define sk_void_find_ex(st, val) SKM_sk_find_ex(void, (st), (val)) +# define sk_void_delete(st, i) SKM_sk_delete(void, (st), (i)) +# define sk_void_delete_ptr(st, ptr) SKM_sk_delete_ptr(void, (st), (ptr)) +# define sk_void_insert(st, val, i) SKM_sk_insert(void, (st), (val), (i)) +# define sk_void_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(void, (st), (cmp)) +# define sk_void_dup(st) SKM_sk_dup(void, st) +# define sk_void_pop_free(st, free_func) SKM_sk_pop_free(void, (st), (free_func)) +# define sk_void_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(void, (st), (copy_func), (free_func)) +# define sk_void_shift(st) SKM_sk_shift(void, (st)) +# define sk_void_pop(st) SKM_sk_pop(void, (st)) +# define sk_void_sort(st) SKM_sk_sort(void, (st)) +# define sk_void_is_sorted(st) SKM_sk_is_sorted(void, (st)) +# define sk_OPENSSL_STRING_new(cmp) ((STACK_OF(OPENSSL_STRING) *)sk_new(CHECKED_SK_CMP_FUNC(char, cmp))) +# define sk_OPENSSL_STRING_new_null() ((STACK_OF(OPENSSL_STRING) *)sk_new_null()) +# define sk_OPENSSL_STRING_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val)) +# define sk_OPENSSL_STRING_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val)) +# define sk_OPENSSL_STRING_value(st, i) ((OPENSSL_STRING)sk_value(CHECKED_STACK_OF(OPENSSL_STRING, st), i)) +# define sk_OPENSSL_STRING_num(st) SKM_sk_num(OPENSSL_STRING, st) +# define sk_OPENSSL_STRING_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_SK_FREE_FUNC(char, free_func)) +# define sk_OPENSSL_STRING_deep_copy(st, copy_func, free_func) ((STACK_OF(OPENSSL_STRING) *)sk_deep_copy(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_SK_COPY_FUNC(char, copy_func), CHECKED_SK_FREE_FUNC(char, free_func))) +# define sk_OPENSSL_STRING_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val), i) +# define sk_OPENSSL_STRING_free(st) SKM_sk_free(OPENSSL_STRING, st) +# define sk_OPENSSL_STRING_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_STRING, st), i, CHECKED_PTR_OF(char, val)) +# define sk_OPENSSL_STRING_zero(st) SKM_sk_zero(OPENSSL_STRING, (st)) +# define sk_OPENSSL_STRING_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val)) +# define sk_OPENSSL_STRING_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_CONST_PTR_OF(char, val)) +# define sk_OPENSSL_STRING_delete(st, i) SKM_sk_delete(OPENSSL_STRING, (st), (i)) +# define sk_OPENSSL_STRING_delete_ptr(st, ptr) (OPENSSL_STRING *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, ptr)) +# define sk_OPENSSL_STRING_set_cmp_func(st, cmp) \ + ((int (*)(const char * const *,const char * const *)) \ + sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_SK_CMP_FUNC(char, cmp))) +# define sk_OPENSSL_STRING_dup(st) SKM_sk_dup(OPENSSL_STRING, st) +# define sk_OPENSSL_STRING_shift(st) SKM_sk_shift(OPENSSL_STRING, (st)) +# define sk_OPENSSL_STRING_pop(st) (char *)sk_pop(CHECKED_STACK_OF(OPENSSL_STRING, st)) +# define sk_OPENSSL_STRING_sort(st) SKM_sk_sort(OPENSSL_STRING, (st)) +# define sk_OPENSSL_STRING_is_sorted(st) SKM_sk_is_sorted(OPENSSL_STRING, (st)) +# define sk_OPENSSL_BLOCK_new(cmp) ((STACK_OF(OPENSSL_BLOCK) *)sk_new(CHECKED_SK_CMP_FUNC(void, cmp))) +# define sk_OPENSSL_BLOCK_new_null() ((STACK_OF(OPENSSL_BLOCK) *)sk_new_null()) +# define sk_OPENSSL_BLOCK_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val)) +# define sk_OPENSSL_BLOCK_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val)) +# define sk_OPENSSL_BLOCK_value(st, i) ((OPENSSL_BLOCK)sk_value(CHECKED_STACK_OF(OPENSSL_BLOCK, st), i)) +# define sk_OPENSSL_BLOCK_num(st) SKM_sk_num(OPENSSL_BLOCK, st) +# define sk_OPENSSL_BLOCK_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_SK_FREE_FUNC(void, free_func)) +# define sk_OPENSSL_BLOCK_deep_copy(st, copy_func, free_func) ((STACK_OF(OPENSSL_BLOCK) *)sk_deep_copy(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_SK_COPY_FUNC(void, copy_func), CHECKED_SK_FREE_FUNC(void, free_func))) +# define sk_OPENSSL_BLOCK_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val), i) +# define sk_OPENSSL_BLOCK_free(st) SKM_sk_free(OPENSSL_BLOCK, st) +# define sk_OPENSSL_BLOCK_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_BLOCK, st), i, CHECKED_PTR_OF(void, val)) +# define sk_OPENSSL_BLOCK_zero(st) SKM_sk_zero(OPENSSL_BLOCK, (st)) +# define sk_OPENSSL_BLOCK_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val)) +# define sk_OPENSSL_BLOCK_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_CONST_PTR_OF(void, val)) +# define sk_OPENSSL_BLOCK_delete(st, i) SKM_sk_delete(OPENSSL_BLOCK, (st), (i)) +# define sk_OPENSSL_BLOCK_delete_ptr(st, ptr) (OPENSSL_BLOCK *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, ptr)) +# define sk_OPENSSL_BLOCK_set_cmp_func(st, cmp) \ + ((int (*)(const void * const *,const void * const *)) \ + sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_SK_CMP_FUNC(void, cmp))) +# define sk_OPENSSL_BLOCK_dup(st) SKM_sk_dup(OPENSSL_BLOCK, st) +# define sk_OPENSSL_BLOCK_shift(st) SKM_sk_shift(OPENSSL_BLOCK, (st)) +# define sk_OPENSSL_BLOCK_pop(st) (void *)sk_pop(CHECKED_STACK_OF(OPENSSL_BLOCK, st)) +# define sk_OPENSSL_BLOCK_sort(st) SKM_sk_sort(OPENSSL_BLOCK, (st)) +# define sk_OPENSSL_BLOCK_is_sorted(st) SKM_sk_is_sorted(OPENSSL_BLOCK, (st)) +# define sk_OPENSSL_PSTRING_new(cmp) ((STACK_OF(OPENSSL_PSTRING) *)sk_new(CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp))) +# define sk_OPENSSL_PSTRING_new_null() ((STACK_OF(OPENSSL_PSTRING) *)sk_new_null()) +# define sk_OPENSSL_PSTRING_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val)) +# define sk_OPENSSL_PSTRING_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val)) +# define sk_OPENSSL_PSTRING_value(st, i) ((OPENSSL_PSTRING)sk_value(CHECKED_STACK_OF(OPENSSL_PSTRING, st), i)) +# define sk_OPENSSL_PSTRING_num(st) SKM_sk_num(OPENSSL_PSTRING, st) +# define sk_OPENSSL_PSTRING_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_SK_FREE_FUNC(OPENSSL_STRING, free_func)) +# define sk_OPENSSL_PSTRING_deep_copy(st, copy_func, free_func) ((STACK_OF(OPENSSL_PSTRING) *)sk_deep_copy(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_SK_COPY_FUNC(OPENSSL_STRING, copy_func), CHECKED_SK_FREE_FUNC(OPENSSL_STRING, free_func))) +# define sk_OPENSSL_PSTRING_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val), i) +# define sk_OPENSSL_PSTRING_free(st) SKM_sk_free(OPENSSL_PSTRING, st) +# define sk_OPENSSL_PSTRING_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_PSTRING, st), i, CHECKED_PTR_OF(OPENSSL_STRING, val)) +# define sk_OPENSSL_PSTRING_zero(st) SKM_sk_zero(OPENSSL_PSTRING, (st)) +# define sk_OPENSSL_PSTRING_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val)) +# define sk_OPENSSL_PSTRING_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_CONST_PTR_OF(OPENSSL_STRING, val)) +# define sk_OPENSSL_PSTRING_delete(st, i) SKM_sk_delete(OPENSSL_PSTRING, (st), (i)) +# define sk_OPENSSL_PSTRING_delete_ptr(st, ptr) (OPENSSL_PSTRING *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, ptr)) +# define sk_OPENSSL_PSTRING_set_cmp_func(st, cmp) \ + ((int (*)(const OPENSSL_STRING * const *,const OPENSSL_STRING * const *)) \ + sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp))) +# define sk_OPENSSL_PSTRING_dup(st) SKM_sk_dup(OPENSSL_PSTRING, st) +# define sk_OPENSSL_PSTRING_shift(st) SKM_sk_shift(OPENSSL_PSTRING, (st)) +# define sk_OPENSSL_PSTRING_pop(st) (OPENSSL_STRING *)sk_pop(CHECKED_STACK_OF(OPENSSL_PSTRING, st)) +# define sk_OPENSSL_PSTRING_sort(st) SKM_sk_sort(OPENSSL_PSTRING, (st)) +# define sk_OPENSSL_PSTRING_is_sorted(st) SKM_sk_is_sorted(OPENSSL_PSTRING, (st)) +# define d2i_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(ACCESS_DESCRIPTION, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(ACCESS_DESCRIPTION, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_ACCESS_DESCRIPTION(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(ACCESS_DESCRIPTION, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_ACCESS_DESCRIPTION(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(ACCESS_DESCRIPTION, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_ASN1_INTEGER(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(ASN1_INTEGER, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_ASN1_INTEGER(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(ASN1_INTEGER, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_ASN1_INTEGER(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(ASN1_INTEGER, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_ASN1_INTEGER(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(ASN1_INTEGER, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_ASN1_OBJECT(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(ASN1_OBJECT, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_ASN1_OBJECT(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(ASN1_OBJECT, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_ASN1_OBJECT(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(ASN1_OBJECT, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_ASN1_OBJECT(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(ASN1_OBJECT, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_ASN1_TYPE(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(ASN1_TYPE, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_ASN1_TYPE(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(ASN1_TYPE, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_ASN1_TYPE(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(ASN1_TYPE, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_ASN1_TYPE(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(ASN1_TYPE, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_ASN1_UTF8STRING(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(ASN1_UTF8STRING, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_ASN1_UTF8STRING(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(ASN1_UTF8STRING, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_ASN1_UTF8STRING(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(ASN1_UTF8STRING, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_ASN1_UTF8STRING(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(ASN1_UTF8STRING, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_DIST_POINT(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(DIST_POINT, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_DIST_POINT(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(DIST_POINT, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_DIST_POINT(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(DIST_POINT, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_DIST_POINT(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(DIST_POINT, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_ESS_CERT_ID(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(ESS_CERT_ID, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_ESS_CERT_ID(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(ESS_CERT_ID, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_ESS_CERT_ID(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(ESS_CERT_ID, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_ESS_CERT_ID(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(ESS_CERT_ID, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_EVP_MD(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(EVP_MD, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_EVP_MD(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(EVP_MD, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_EVP_MD(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(EVP_MD, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_EVP_MD(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(EVP_MD, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_GENERAL_NAME(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(GENERAL_NAME, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_GENERAL_NAME(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(GENERAL_NAME, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_GENERAL_NAME(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(GENERAL_NAME, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_GENERAL_NAME(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(GENERAL_NAME, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_OCSP_ONEREQ(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(OCSP_ONEREQ, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_OCSP_ONEREQ(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(OCSP_ONEREQ, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_OCSP_ONEREQ(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(OCSP_ONEREQ, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_OCSP_ONEREQ(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(OCSP_ONEREQ, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_OCSP_SINGLERESP(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(OCSP_SINGLERESP, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_OCSP_SINGLERESP(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(OCSP_SINGLERESP, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_OCSP_SINGLERESP(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(OCSP_SINGLERESP, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_OCSP_SINGLERESP(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(OCSP_SINGLERESP, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_PKCS12_SAFEBAG(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(PKCS12_SAFEBAG, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_PKCS12_SAFEBAG(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(PKCS12_SAFEBAG, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_PKCS12_SAFEBAG(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(PKCS12_SAFEBAG, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_PKCS12_SAFEBAG(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(PKCS12_SAFEBAG, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_PKCS7(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(PKCS7, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_PKCS7(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(PKCS7, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_PKCS7(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(PKCS7, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_PKCS7(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(PKCS7, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_PKCS7_RECIP_INFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(PKCS7_RECIP_INFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_PKCS7_RECIP_INFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(PKCS7_RECIP_INFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_PKCS7_RECIP_INFO(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(PKCS7_RECIP_INFO, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_PKCS7_RECIP_INFO(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(PKCS7_RECIP_INFO, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(PKCS7_SIGNER_INFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(PKCS7_SIGNER_INFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_PKCS7_SIGNER_INFO(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(PKCS7_SIGNER_INFO, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_PKCS7_SIGNER_INFO(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(PKCS7_SIGNER_INFO, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_POLICYINFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(POLICYINFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_POLICYINFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(POLICYINFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_POLICYINFO(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(POLICYINFO, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_POLICYINFO(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(POLICYINFO, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_POLICYQUALINFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(POLICYQUALINFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_POLICYQUALINFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(POLICYQUALINFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_POLICYQUALINFO(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(POLICYQUALINFO, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_POLICYQUALINFO(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(POLICYQUALINFO, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_SXNETID(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(SXNETID, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_SXNETID(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(SXNETID, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_SXNETID(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(SXNETID, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_SXNETID(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(SXNETID, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_X509(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(X509, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_X509(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(X509, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_X509(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(X509, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_X509(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(X509, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_X509_ALGOR(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(X509_ALGOR, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_X509_ALGOR(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(X509_ALGOR, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_X509_ALGOR(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(X509_ALGOR, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_X509_ALGOR(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(X509_ALGOR, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_X509_ATTRIBUTE(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(X509_ATTRIBUTE, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_X509_ATTRIBUTE(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(X509_ATTRIBUTE, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_X509_ATTRIBUTE(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(X509_ATTRIBUTE, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_X509_ATTRIBUTE(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(X509_ATTRIBUTE, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_X509_CRL(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(X509_CRL, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_X509_CRL(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(X509_CRL, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_X509_CRL(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(X509_CRL, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_X509_CRL(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(X509_CRL, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_X509_EXTENSION(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(X509_EXTENSION, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_X509_EXTENSION(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(X509_EXTENSION, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_X509_EXTENSION(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(X509_EXTENSION, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_X509_EXTENSION(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(X509_EXTENSION, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_X509_NAME_ENTRY(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(X509_NAME_ENTRY, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_X509_NAME_ENTRY(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(X509_NAME_ENTRY, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_X509_NAME_ENTRY(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(X509_NAME_ENTRY, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_X509_NAME_ENTRY(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(X509_NAME_ENTRY, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_X509_REVOKED(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(X509_REVOKED, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_X509_REVOKED(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(X509_REVOKED, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_X509_REVOKED(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(X509_REVOKED, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_X509_REVOKED(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(X509_REVOKED, (buf), (len), (d2i_func), (free_func)) +# define PKCS12_decrypt_d2i_PKCS12_SAFEBAG(algor, d2i_func, free_func, pass, passlen, oct, seq) \ + SKM_PKCS12_decrypt_d2i(PKCS12_SAFEBAG, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq)) +# define PKCS12_decrypt_d2i_PKCS7(algor, d2i_func, free_func, pass, passlen, oct, seq) \ + SKM_PKCS12_decrypt_d2i(PKCS7, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq)) +# define lh_ADDED_OBJ_new() LHM_lh_new(ADDED_OBJ,added_obj) +# define lh_ADDED_OBJ_insert(lh,inst) LHM_lh_insert(ADDED_OBJ,lh,inst) +# define lh_ADDED_OBJ_retrieve(lh,inst) LHM_lh_retrieve(ADDED_OBJ,lh,inst) +# define lh_ADDED_OBJ_delete(lh,inst) LHM_lh_delete(ADDED_OBJ,lh,inst) +# define lh_ADDED_OBJ_doall(lh,fn) LHM_lh_doall(ADDED_OBJ,lh,fn) +# define lh_ADDED_OBJ_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(ADDED_OBJ,lh,fn,arg_type,arg) +# define lh_ADDED_OBJ_error(lh) LHM_lh_error(ADDED_OBJ,lh) +# define lh_ADDED_OBJ_num_items(lh) LHM_lh_num_items(ADDED_OBJ,lh) +# define lh_ADDED_OBJ_down_load(lh) LHM_lh_down_load(ADDED_OBJ,lh) +# define lh_ADDED_OBJ_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(ADDED_OBJ,lh,out) +# define lh_ADDED_OBJ_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(ADDED_OBJ,lh,out) +# define lh_ADDED_OBJ_stats_bio(lh,out) \ + LHM_lh_stats_bio(ADDED_OBJ,lh,out) +# define lh_ADDED_OBJ_free(lh) LHM_lh_free(ADDED_OBJ,lh) +# define lh_APP_INFO_new() LHM_lh_new(APP_INFO,app_info) +# define lh_APP_INFO_insert(lh,inst) LHM_lh_insert(APP_INFO,lh,inst) +# define lh_APP_INFO_retrieve(lh,inst) LHM_lh_retrieve(APP_INFO,lh,inst) +# define lh_APP_INFO_delete(lh,inst) LHM_lh_delete(APP_INFO,lh,inst) +# define lh_APP_INFO_doall(lh,fn) LHM_lh_doall(APP_INFO,lh,fn) +# define lh_APP_INFO_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(APP_INFO,lh,fn,arg_type,arg) +# define lh_APP_INFO_error(lh) LHM_lh_error(APP_INFO,lh) +# define lh_APP_INFO_num_items(lh) LHM_lh_num_items(APP_INFO,lh) +# define lh_APP_INFO_down_load(lh) LHM_lh_down_load(APP_INFO,lh) +# define lh_APP_INFO_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(APP_INFO,lh,out) +# define lh_APP_INFO_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(APP_INFO,lh,out) +# define lh_APP_INFO_stats_bio(lh,out) \ + LHM_lh_stats_bio(APP_INFO,lh,out) +# define lh_APP_INFO_free(lh) LHM_lh_free(APP_INFO,lh) +# define lh_CONF_VALUE_new() LHM_lh_new(CONF_VALUE,conf_value) +# define lh_CONF_VALUE_insert(lh,inst) LHM_lh_insert(CONF_VALUE,lh,inst) +# define lh_CONF_VALUE_retrieve(lh,inst) LHM_lh_retrieve(CONF_VALUE,lh,inst) +# define lh_CONF_VALUE_delete(lh,inst) LHM_lh_delete(CONF_VALUE,lh,inst) +# define lh_CONF_VALUE_doall(lh,fn) LHM_lh_doall(CONF_VALUE,lh,fn) +# define lh_CONF_VALUE_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(CONF_VALUE,lh,fn,arg_type,arg) +# define lh_CONF_VALUE_error(lh) LHM_lh_error(CONF_VALUE,lh) +# define lh_CONF_VALUE_num_items(lh) LHM_lh_num_items(CONF_VALUE,lh) +# define lh_CONF_VALUE_down_load(lh) LHM_lh_down_load(CONF_VALUE,lh) +# define lh_CONF_VALUE_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(CONF_VALUE,lh,out) +# define lh_CONF_VALUE_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(CONF_VALUE,lh,out) +# define lh_CONF_VALUE_stats_bio(lh,out) \ + LHM_lh_stats_bio(CONF_VALUE,lh,out) +# define lh_CONF_VALUE_free(lh) LHM_lh_free(CONF_VALUE,lh) +# define lh_ENGINE_PILE_new() LHM_lh_new(ENGINE_PILE,engine_pile) +# define lh_ENGINE_PILE_insert(lh,inst) LHM_lh_insert(ENGINE_PILE,lh,inst) +# define lh_ENGINE_PILE_retrieve(lh,inst) LHM_lh_retrieve(ENGINE_PILE,lh,inst) +# define lh_ENGINE_PILE_delete(lh,inst) LHM_lh_delete(ENGINE_PILE,lh,inst) +# define lh_ENGINE_PILE_doall(lh,fn) LHM_lh_doall(ENGINE_PILE,lh,fn) +# define lh_ENGINE_PILE_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(ENGINE_PILE,lh,fn,arg_type,arg) +# define lh_ENGINE_PILE_error(lh) LHM_lh_error(ENGINE_PILE,lh) +# define lh_ENGINE_PILE_num_items(lh) LHM_lh_num_items(ENGINE_PILE,lh) +# define lh_ENGINE_PILE_down_load(lh) LHM_lh_down_load(ENGINE_PILE,lh) +# define lh_ENGINE_PILE_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(ENGINE_PILE,lh,out) +# define lh_ENGINE_PILE_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(ENGINE_PILE,lh,out) +# define lh_ENGINE_PILE_stats_bio(lh,out) \ + LHM_lh_stats_bio(ENGINE_PILE,lh,out) +# define lh_ENGINE_PILE_free(lh) LHM_lh_free(ENGINE_PILE,lh) +# define lh_ERR_STATE_new() LHM_lh_new(ERR_STATE,err_state) +# define lh_ERR_STATE_insert(lh,inst) LHM_lh_insert(ERR_STATE,lh,inst) +# define lh_ERR_STATE_retrieve(lh,inst) LHM_lh_retrieve(ERR_STATE,lh,inst) +# define lh_ERR_STATE_delete(lh,inst) LHM_lh_delete(ERR_STATE,lh,inst) +# define lh_ERR_STATE_doall(lh,fn) LHM_lh_doall(ERR_STATE,lh,fn) +# define lh_ERR_STATE_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(ERR_STATE,lh,fn,arg_type,arg) +# define lh_ERR_STATE_error(lh) LHM_lh_error(ERR_STATE,lh) +# define lh_ERR_STATE_num_items(lh) LHM_lh_num_items(ERR_STATE,lh) +# define lh_ERR_STATE_down_load(lh) LHM_lh_down_load(ERR_STATE,lh) +# define lh_ERR_STATE_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(ERR_STATE,lh,out) +# define lh_ERR_STATE_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(ERR_STATE,lh,out) +# define lh_ERR_STATE_stats_bio(lh,out) \ + LHM_lh_stats_bio(ERR_STATE,lh,out) +# define lh_ERR_STATE_free(lh) LHM_lh_free(ERR_STATE,lh) +# define lh_ERR_STRING_DATA_new() LHM_lh_new(ERR_STRING_DATA,err_string_data) +# define lh_ERR_STRING_DATA_insert(lh,inst) LHM_lh_insert(ERR_STRING_DATA,lh,inst) +# define lh_ERR_STRING_DATA_retrieve(lh,inst) LHM_lh_retrieve(ERR_STRING_DATA,lh,inst) +# define lh_ERR_STRING_DATA_delete(lh,inst) LHM_lh_delete(ERR_STRING_DATA,lh,inst) +# define lh_ERR_STRING_DATA_doall(lh,fn) LHM_lh_doall(ERR_STRING_DATA,lh,fn) +# define lh_ERR_STRING_DATA_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(ERR_STRING_DATA,lh,fn,arg_type,arg) +# define lh_ERR_STRING_DATA_error(lh) LHM_lh_error(ERR_STRING_DATA,lh) +# define lh_ERR_STRING_DATA_num_items(lh) LHM_lh_num_items(ERR_STRING_DATA,lh) +# define lh_ERR_STRING_DATA_down_load(lh) LHM_lh_down_load(ERR_STRING_DATA,lh) +# define lh_ERR_STRING_DATA_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(ERR_STRING_DATA,lh,out) +# define lh_ERR_STRING_DATA_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(ERR_STRING_DATA,lh,out) +# define lh_ERR_STRING_DATA_stats_bio(lh,out) \ + LHM_lh_stats_bio(ERR_STRING_DATA,lh,out) +# define lh_ERR_STRING_DATA_free(lh) LHM_lh_free(ERR_STRING_DATA,lh) +# define lh_EX_CLASS_ITEM_new() LHM_lh_new(EX_CLASS_ITEM,ex_class_item) +# define lh_EX_CLASS_ITEM_insert(lh,inst) LHM_lh_insert(EX_CLASS_ITEM,lh,inst) +# define lh_EX_CLASS_ITEM_retrieve(lh,inst) LHM_lh_retrieve(EX_CLASS_ITEM,lh,inst) +# define lh_EX_CLASS_ITEM_delete(lh,inst) LHM_lh_delete(EX_CLASS_ITEM,lh,inst) +# define lh_EX_CLASS_ITEM_doall(lh,fn) LHM_lh_doall(EX_CLASS_ITEM,lh,fn) +# define lh_EX_CLASS_ITEM_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(EX_CLASS_ITEM,lh,fn,arg_type,arg) +# define lh_EX_CLASS_ITEM_error(lh) LHM_lh_error(EX_CLASS_ITEM,lh) +# define lh_EX_CLASS_ITEM_num_items(lh) LHM_lh_num_items(EX_CLASS_ITEM,lh) +# define lh_EX_CLASS_ITEM_down_load(lh) LHM_lh_down_load(EX_CLASS_ITEM,lh) +# define lh_EX_CLASS_ITEM_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(EX_CLASS_ITEM,lh,out) +# define lh_EX_CLASS_ITEM_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(EX_CLASS_ITEM,lh,out) +# define lh_EX_CLASS_ITEM_stats_bio(lh,out) \ + LHM_lh_stats_bio(EX_CLASS_ITEM,lh,out) +# define lh_EX_CLASS_ITEM_free(lh) LHM_lh_free(EX_CLASS_ITEM,lh) +# define lh_FUNCTION_new() LHM_lh_new(FUNCTION,function) +# define lh_FUNCTION_insert(lh,inst) LHM_lh_insert(FUNCTION,lh,inst) +# define lh_FUNCTION_retrieve(lh,inst) LHM_lh_retrieve(FUNCTION,lh,inst) +# define lh_FUNCTION_delete(lh,inst) LHM_lh_delete(FUNCTION,lh,inst) +# define lh_FUNCTION_doall(lh,fn) LHM_lh_doall(FUNCTION,lh,fn) +# define lh_FUNCTION_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(FUNCTION,lh,fn,arg_type,arg) +# define lh_FUNCTION_error(lh) LHM_lh_error(FUNCTION,lh) +# define lh_FUNCTION_num_items(lh) LHM_lh_num_items(FUNCTION,lh) +# define lh_FUNCTION_down_load(lh) LHM_lh_down_load(FUNCTION,lh) +# define lh_FUNCTION_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(FUNCTION,lh,out) +# define lh_FUNCTION_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(FUNCTION,lh,out) +# define lh_FUNCTION_stats_bio(lh,out) \ + LHM_lh_stats_bio(FUNCTION,lh,out) +# define lh_FUNCTION_free(lh) LHM_lh_free(FUNCTION,lh) +# define lh_MEM_new() LHM_lh_new(MEM,mem) +# define lh_MEM_insert(lh,inst) LHM_lh_insert(MEM,lh,inst) +# define lh_MEM_retrieve(lh,inst) LHM_lh_retrieve(MEM,lh,inst) +# define lh_MEM_delete(lh,inst) LHM_lh_delete(MEM,lh,inst) +# define lh_MEM_doall(lh,fn) LHM_lh_doall(MEM,lh,fn) +# define lh_MEM_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(MEM,lh,fn,arg_type,arg) +# define lh_MEM_error(lh) LHM_lh_error(MEM,lh) +# define lh_MEM_num_items(lh) LHM_lh_num_items(MEM,lh) +# define lh_MEM_down_load(lh) LHM_lh_down_load(MEM,lh) +# define lh_MEM_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(MEM,lh,out) +# define lh_MEM_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(MEM,lh,out) +# define lh_MEM_stats_bio(lh,out) \ + LHM_lh_stats_bio(MEM,lh,out) +# define lh_MEM_free(lh) LHM_lh_free(MEM,lh) +# define lh_OBJ_NAME_new() LHM_lh_new(OBJ_NAME,obj_name) +# define lh_OBJ_NAME_insert(lh,inst) LHM_lh_insert(OBJ_NAME,lh,inst) +# define lh_OBJ_NAME_retrieve(lh,inst) LHM_lh_retrieve(OBJ_NAME,lh,inst) +# define lh_OBJ_NAME_delete(lh,inst) LHM_lh_delete(OBJ_NAME,lh,inst) +# define lh_OBJ_NAME_doall(lh,fn) LHM_lh_doall(OBJ_NAME,lh,fn) +# define lh_OBJ_NAME_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(OBJ_NAME,lh,fn,arg_type,arg) +# define lh_OBJ_NAME_error(lh) LHM_lh_error(OBJ_NAME,lh) +# define lh_OBJ_NAME_num_items(lh) LHM_lh_num_items(OBJ_NAME,lh) +# define lh_OBJ_NAME_down_load(lh) LHM_lh_down_load(OBJ_NAME,lh) +# define lh_OBJ_NAME_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(OBJ_NAME,lh,out) +# define lh_OBJ_NAME_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(OBJ_NAME,lh,out) +# define lh_OBJ_NAME_stats_bio(lh,out) \ + LHM_lh_stats_bio(OBJ_NAME,lh,out) +# define lh_OBJ_NAME_free(lh) LHM_lh_free(OBJ_NAME,lh) +# define lh_OPENSSL_CSTRING_new() LHM_lh_new(OPENSSL_CSTRING,openssl_cstring) +# define lh_OPENSSL_CSTRING_insert(lh,inst) LHM_lh_insert(OPENSSL_CSTRING,lh,inst) +# define lh_OPENSSL_CSTRING_retrieve(lh,inst) LHM_lh_retrieve(OPENSSL_CSTRING,lh,inst) +# define lh_OPENSSL_CSTRING_delete(lh,inst) LHM_lh_delete(OPENSSL_CSTRING,lh,inst) +# define lh_OPENSSL_CSTRING_doall(lh,fn) LHM_lh_doall(OPENSSL_CSTRING,lh,fn) +# define lh_OPENSSL_CSTRING_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(OPENSSL_CSTRING,lh,fn,arg_type,arg) +# define lh_OPENSSL_CSTRING_error(lh) LHM_lh_error(OPENSSL_CSTRING,lh) +# define lh_OPENSSL_CSTRING_num_items(lh) LHM_lh_num_items(OPENSSL_CSTRING,lh) +# define lh_OPENSSL_CSTRING_down_load(lh) LHM_lh_down_load(OPENSSL_CSTRING,lh) +# define lh_OPENSSL_CSTRING_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(OPENSSL_CSTRING,lh,out) +# define lh_OPENSSL_CSTRING_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(OPENSSL_CSTRING,lh,out) +# define lh_OPENSSL_CSTRING_stats_bio(lh,out) \ + LHM_lh_stats_bio(OPENSSL_CSTRING,lh,out) +# define lh_OPENSSL_CSTRING_free(lh) LHM_lh_free(OPENSSL_CSTRING,lh) +# define lh_OPENSSL_STRING_new() LHM_lh_new(OPENSSL_STRING,openssl_string) +# define lh_OPENSSL_STRING_insert(lh,inst) LHM_lh_insert(OPENSSL_STRING,lh,inst) +# define lh_OPENSSL_STRING_retrieve(lh,inst) LHM_lh_retrieve(OPENSSL_STRING,lh,inst) +# define lh_OPENSSL_STRING_delete(lh,inst) LHM_lh_delete(OPENSSL_STRING,lh,inst) +# define lh_OPENSSL_STRING_doall(lh,fn) LHM_lh_doall(OPENSSL_STRING,lh,fn) +# define lh_OPENSSL_STRING_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(OPENSSL_STRING,lh,fn,arg_type,arg) +# define lh_OPENSSL_STRING_error(lh) LHM_lh_error(OPENSSL_STRING,lh) +# define lh_OPENSSL_STRING_num_items(lh) LHM_lh_num_items(OPENSSL_STRING,lh) +# define lh_OPENSSL_STRING_down_load(lh) LHM_lh_down_load(OPENSSL_STRING,lh) +# define lh_OPENSSL_STRING_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(OPENSSL_STRING,lh,out) +# define lh_OPENSSL_STRING_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(OPENSSL_STRING,lh,out) +# define lh_OPENSSL_STRING_stats_bio(lh,out) \ + LHM_lh_stats_bio(OPENSSL_STRING,lh,out) +# define lh_OPENSSL_STRING_free(lh) LHM_lh_free(OPENSSL_STRING,lh) +# define lh_SSL_SESSION_new() LHM_lh_new(SSL_SESSION,ssl_session) +# define lh_SSL_SESSION_insert(lh,inst) LHM_lh_insert(SSL_SESSION,lh,inst) +# define lh_SSL_SESSION_retrieve(lh,inst) LHM_lh_retrieve(SSL_SESSION,lh,inst) +# define lh_SSL_SESSION_delete(lh,inst) LHM_lh_delete(SSL_SESSION,lh,inst) +# define lh_SSL_SESSION_doall(lh,fn) LHM_lh_doall(SSL_SESSION,lh,fn) +# define lh_SSL_SESSION_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(SSL_SESSION,lh,fn,arg_type,arg) +# define lh_SSL_SESSION_error(lh) LHM_lh_error(SSL_SESSION,lh) +# define lh_SSL_SESSION_num_items(lh) LHM_lh_num_items(SSL_SESSION,lh) +# define lh_SSL_SESSION_down_load(lh) LHM_lh_down_load(SSL_SESSION,lh) +# define lh_SSL_SESSION_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(SSL_SESSION,lh,out) +# define lh_SSL_SESSION_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(SSL_SESSION,lh,out) +# define lh_SSL_SESSION_stats_bio(lh,out) \ + LHM_lh_stats_bio(SSL_SESSION,lh,out) +# define lh_SSL_SESSION_free(lh) LHM_lh_free(SSL_SESSION,lh) +#ifdef __cplusplus +} +#endif +#endif /* !defined HEADER_SAFESTACK_H */ diff --git a/OSlibs/ios/include/openssl/seed.h b/OSlibs/ios/include/openssl/seed.h new file mode 100755 index 000000000..8cbf0d928 --- /dev/null +++ b/OSlibs/ios/include/openssl/seed.h @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2007 KISA(Korea Information Security Agency). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Neither the name of author nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_SEED_H +# define HEADER_SEED_H + +# include +# include +# include + +# ifdef OPENSSL_NO_SEED +# error SEED is disabled. +# endif + +/* look whether we need 'long' to get 32 bits */ +# ifdef AES_LONG +# ifndef SEED_LONG +# define SEED_LONG 1 +# endif +# endif + +# if !defined(NO_SYS_TYPES_H) +# include +# endif + +# define SEED_BLOCK_SIZE 16 +# define SEED_KEY_LENGTH 16 + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct seed_key_st { +# ifdef SEED_LONG + unsigned long data[32]; +# else + unsigned int data[32]; +# endif +} SEED_KEY_SCHEDULE; + +# ifdef OPENSSL_FIPS +void private_SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH], + SEED_KEY_SCHEDULE *ks); +# endif +void SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH], + SEED_KEY_SCHEDULE *ks); + +void SEED_encrypt(const unsigned char s[SEED_BLOCK_SIZE], + unsigned char d[SEED_BLOCK_SIZE], + const SEED_KEY_SCHEDULE *ks); +void SEED_decrypt(const unsigned char s[SEED_BLOCK_SIZE], + unsigned char d[SEED_BLOCK_SIZE], + const SEED_KEY_SCHEDULE *ks); + +void SEED_ecb_encrypt(const unsigned char *in, unsigned char *out, + const SEED_KEY_SCHEDULE *ks, int enc); +void SEED_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t len, + const SEED_KEY_SCHEDULE *ks, + unsigned char ivec[SEED_BLOCK_SIZE], int enc); +void SEED_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const SEED_KEY_SCHEDULE *ks, + unsigned char ivec[SEED_BLOCK_SIZE], int *num, + int enc); +void SEED_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const SEED_KEY_SCHEDULE *ks, + unsigned char ivec[SEED_BLOCK_SIZE], int *num); + +#ifdef __cplusplus +} +#endif + +#endif /* HEADER_SEED_H */ diff --git a/OSlibs/ios/include/openssl/sha.h b/OSlibs/ios/include/openssl/sha.h new file mode 100755 index 000000000..e5169e4fe --- /dev/null +++ b/OSlibs/ios/include/openssl/sha.h @@ -0,0 +1,214 @@ +/* crypto/sha/sha.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_SHA_H +# define HEADER_SHA_H + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# if defined(OPENSSL_NO_SHA) || (defined(OPENSSL_NO_SHA0) && defined(OPENSSL_NO_SHA1)) +# error SHA is disabled. +# endif + +# if defined(OPENSSL_FIPS) +# define FIPS_SHA_SIZE_T size_t +# endif + +/*- + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! SHA_LONG has to be at least 32 bits wide. If it's wider, then ! + * ! SHA_LONG_LOG2 has to be defined along. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ + +# if defined(__LP32__) +# define SHA_LONG unsigned long +# elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__) +# define SHA_LONG unsigned long +# define SHA_LONG_LOG2 3 +# else +# define SHA_LONG unsigned int +# endif + +# define SHA_LBLOCK 16 +# define SHA_CBLOCK (SHA_LBLOCK*4)/* SHA treats input data as a + * contiguous array of 32 bit wide + * big-endian values. */ +# define SHA_LAST_BLOCK (SHA_CBLOCK-8) +# define SHA_DIGEST_LENGTH 20 + +typedef struct SHAstate_st { + SHA_LONG h0, h1, h2, h3, h4; + SHA_LONG Nl, Nh; + SHA_LONG data[SHA_LBLOCK]; + unsigned int num; +} SHA_CTX; + +# ifndef OPENSSL_NO_SHA0 +# ifdef OPENSSL_FIPS +int private_SHA_Init(SHA_CTX *c); +# endif +int SHA_Init(SHA_CTX *c); +int SHA_Update(SHA_CTX *c, const void *data, size_t len); +int SHA_Final(unsigned char *md, SHA_CTX *c); +unsigned char *SHA(const unsigned char *d, size_t n, unsigned char *md); +void SHA_Transform(SHA_CTX *c, const unsigned char *data); +# endif +# ifndef OPENSSL_NO_SHA1 +# ifdef OPENSSL_FIPS +int private_SHA1_Init(SHA_CTX *c); +# endif +int SHA1_Init(SHA_CTX *c); +int SHA1_Update(SHA_CTX *c, const void *data, size_t len); +int SHA1_Final(unsigned char *md, SHA_CTX *c); +unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md); +void SHA1_Transform(SHA_CTX *c, const unsigned char *data); +# endif + +# define SHA256_CBLOCK (SHA_LBLOCK*4)/* SHA-256 treats input data as a + * contiguous array of 32 bit wide + * big-endian values. */ +# define SHA224_DIGEST_LENGTH 28 +# define SHA256_DIGEST_LENGTH 32 + +typedef struct SHA256state_st { + SHA_LONG h[8]; + SHA_LONG Nl, Nh; + SHA_LONG data[SHA_LBLOCK]; + unsigned int num, md_len; +} SHA256_CTX; + +# ifndef OPENSSL_NO_SHA256 +# ifdef OPENSSL_FIPS +int private_SHA224_Init(SHA256_CTX *c); +int private_SHA256_Init(SHA256_CTX *c); +# endif +int SHA224_Init(SHA256_CTX *c); +int SHA224_Update(SHA256_CTX *c, const void *data, size_t len); +int SHA224_Final(unsigned char *md, SHA256_CTX *c); +unsigned char *SHA224(const unsigned char *d, size_t n, unsigned char *md); +int SHA256_Init(SHA256_CTX *c); +int SHA256_Update(SHA256_CTX *c, const void *data, size_t len); +int SHA256_Final(unsigned char *md, SHA256_CTX *c); +unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md); +void SHA256_Transform(SHA256_CTX *c, const unsigned char *data); +# endif + +# define SHA384_DIGEST_LENGTH 48 +# define SHA512_DIGEST_LENGTH 64 + +# ifndef OPENSSL_NO_SHA512 +/* + * Unlike 32-bit digest algorithms, SHA-512 *relies* on SHA_LONG64 + * being exactly 64-bit wide. See Implementation Notes in sha512.c + * for further details. + */ +/* + * SHA-512 treats input data as a + * contiguous array of 64 bit + * wide big-endian values. + */ +# define SHA512_CBLOCK (SHA_LBLOCK*8) +# if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) +# define SHA_LONG64 unsigned __int64 +# define U64(C) C##UI64 +# elif defined(__arch64__) +# define SHA_LONG64 unsigned long +# define U64(C) C##UL +# else +# define SHA_LONG64 unsigned long long +# define U64(C) C##ULL +# endif + +typedef struct SHA512state_st { + SHA_LONG64 h[8]; + SHA_LONG64 Nl, Nh; + union { + SHA_LONG64 d[SHA_LBLOCK]; + unsigned char p[SHA512_CBLOCK]; + } u; + unsigned int num, md_len; +} SHA512_CTX; +# endif + +# ifndef OPENSSL_NO_SHA512 +# ifdef OPENSSL_FIPS +int private_SHA384_Init(SHA512_CTX *c); +int private_SHA512_Init(SHA512_CTX *c); +# endif +int SHA384_Init(SHA512_CTX *c); +int SHA384_Update(SHA512_CTX *c, const void *data, size_t len); +int SHA384_Final(unsigned char *md, SHA512_CTX *c); +unsigned char *SHA384(const unsigned char *d, size_t n, unsigned char *md); +int SHA512_Init(SHA512_CTX *c); +int SHA512_Update(SHA512_CTX *c, const void *data, size_t len); +int SHA512_Final(unsigned char *md, SHA512_CTX *c); +unsigned char *SHA512(const unsigned char *d, size_t n, unsigned char *md); +void SHA512_Transform(SHA512_CTX *c, const unsigned char *data); +# endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/OSlibs/ios/include/openssl/srp.h b/OSlibs/ios/include/openssl/srp.h new file mode 100755 index 000000000..028892a1f --- /dev/null +++ b/OSlibs/ios/include/openssl/srp.h @@ -0,0 +1,179 @@ +/* crypto/srp/srp.h */ +/* + * Written by Christophe Renou (christophe.renou@edelweb.fr) with the + * precious help of Peter Sylvester (peter.sylvester@edelweb.fr) for the + * EdelKey project and contributed to the OpenSSL project 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef __SRP_H__ +# define __SRP_H__ + +# ifndef OPENSSL_NO_SRP + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# include +# include +# include + +typedef struct SRP_gN_cache_st { + char *b64_bn; + BIGNUM *bn; +} SRP_gN_cache; + + +DECLARE_STACK_OF(SRP_gN_cache) + +typedef struct SRP_user_pwd_st { + /* Owned by us. */ + char *id; + BIGNUM *s; + BIGNUM *v; + /* Not owned by us. */ + const BIGNUM *g; + const BIGNUM *N; + /* Owned by us. */ + char *info; +} SRP_user_pwd; + +DECLARE_STACK_OF(SRP_user_pwd) + +void SRP_user_pwd_free(SRP_user_pwd *user_pwd); + +typedef struct SRP_VBASE_st { + STACK_OF(SRP_user_pwd) *users_pwd; + STACK_OF(SRP_gN_cache) *gN_cache; +/* to simulate a user */ + char *seed_key; + BIGNUM *default_g; + BIGNUM *default_N; +} SRP_VBASE; + +/* + * Structure interne pour retenir les couples N et g + */ +typedef struct SRP_gN_st { + char *id; + BIGNUM *g; + BIGNUM *N; +} SRP_gN; + +DECLARE_STACK_OF(SRP_gN) + +SRP_VBASE *SRP_VBASE_new(char *seed_key); +int SRP_VBASE_free(SRP_VBASE *vb); +int SRP_VBASE_init(SRP_VBASE *vb, char *verifier_file); + +/* This method ignores the configured seed and fails for an unknown user. */ +SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username); +/* NOTE: unlike in SRP_VBASE_get_by_user, caller owns the returned pointer.*/ +SRP_user_pwd *SRP_VBASE_get1_by_user(SRP_VBASE *vb, char *username); + +char *SRP_create_verifier(const char *user, const char *pass, char **salt, + char **verifier, const char *N, const char *g); +int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt, + BIGNUM **verifier, BIGNUM *N, BIGNUM *g); + +# define SRP_NO_ERROR 0 +# define SRP_ERR_VBASE_INCOMPLETE_FILE 1 +# define SRP_ERR_VBASE_BN_LIB 2 +# define SRP_ERR_OPEN_FILE 3 +# define SRP_ERR_MEMORY 4 + +# define DB_srptype 0 +# define DB_srpverifier 1 +# define DB_srpsalt 2 +# define DB_srpid 3 +# define DB_srpgN 4 +# define DB_srpinfo 5 +# undef DB_NUMBER +# define DB_NUMBER 6 + +# define DB_SRP_INDEX 'I' +# define DB_SRP_VALID 'V' +# define DB_SRP_REVOKED 'R' +# define DB_SRP_MODIF 'v' + +/* see srp.c */ +char *SRP_check_known_gN_param(BIGNUM *g, BIGNUM *N); +SRP_gN *SRP_get_default_gN(const char *id); + +/* server side .... */ +BIGNUM *SRP_Calc_server_key(BIGNUM *A, BIGNUM *v, BIGNUM *u, BIGNUM *b, + BIGNUM *N); +BIGNUM *SRP_Calc_B(BIGNUM *b, BIGNUM *N, BIGNUM *g, BIGNUM *v); +int SRP_Verify_A_mod_N(BIGNUM *A, BIGNUM *N); +BIGNUM *SRP_Calc_u(BIGNUM *A, BIGNUM *B, BIGNUM *N); + +/* client side .... */ +BIGNUM *SRP_Calc_x(BIGNUM *s, const char *user, const char *pass); +BIGNUM *SRP_Calc_A(BIGNUM *a, BIGNUM *N, BIGNUM *g); +BIGNUM *SRP_Calc_client_key(BIGNUM *N, BIGNUM *B, BIGNUM *g, BIGNUM *x, + BIGNUM *a, BIGNUM *u); +int SRP_Verify_B_mod_N(BIGNUM *B, BIGNUM *N); + +# define SRP_MINIMAL_N 1024 + +#ifdef __cplusplus +} +#endif + +# endif +#endif diff --git a/OSlibs/ios/include/openssl/srtp.h b/OSlibs/ios/include/openssl/srtp.h new file mode 100755 index 000000000..2279c32b8 --- /dev/null +++ b/OSlibs/ios/include/openssl/srtp.h @@ -0,0 +1,147 @@ +/* ssl/srtp.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* + * DTLS code by Eric Rescorla + * + * Copyright (C) 2006, Network Resonance, Inc. Copyright (C) 2011, RTFM, Inc. + */ + +#ifndef HEADER_D1_SRTP_H +# define HEADER_D1_SRTP_H + +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# define SRTP_AES128_CM_SHA1_80 0x0001 +# define SRTP_AES128_CM_SHA1_32 0x0002 +# define SRTP_AES128_F8_SHA1_80 0x0003 +# define SRTP_AES128_F8_SHA1_32 0x0004 +# define SRTP_NULL_SHA1_80 0x0005 +# define SRTP_NULL_SHA1_32 0x0006 + +# ifndef OPENSSL_NO_SRTP + +int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles); +int SSL_set_tlsext_use_srtp(SSL *ctx, const char *profiles); + +STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *ssl); +SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s); + +# endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/OSlibs/ios/include/openssl/ssl.h b/OSlibs/ios/include/openssl/ssl.h new file mode 100755 index 000000000..5ef56faa5 --- /dev/null +++ b/OSlibs/ios/include/openssl/ssl.h @@ -0,0 +1,3169 @@ +/* ssl/ssl.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#ifndef HEADER_SSL_H +# define HEADER_SSL_H + +# include + +# ifndef OPENSSL_NO_COMP +# include +# endif +# ifndef OPENSSL_NO_BIO +# include +# endif +# ifndef OPENSSL_NO_DEPRECATED +# ifndef OPENSSL_NO_X509 +# include +# endif +# include +# include +# include +# endif +# include +# include + +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* SSLeay version number for ASN.1 encoding of the session information */ +/*- + * Version 0 - initial version + * Version 1 - added the optional peer certificate + */ +# define SSL_SESSION_ASN1_VERSION 0x0001 + +/* text strings for the ciphers */ +# define SSL_TXT_NULL_WITH_MD5 SSL2_TXT_NULL_WITH_MD5 +# define SSL_TXT_RC4_128_WITH_MD5 SSL2_TXT_RC4_128_WITH_MD5 +# define SSL_TXT_RC4_128_EXPORT40_WITH_MD5 SSL2_TXT_RC4_128_EXPORT40_WITH_MD5 +# define SSL_TXT_RC2_128_CBC_WITH_MD5 SSL2_TXT_RC2_128_CBC_WITH_MD5 +# define SSL_TXT_RC2_128_CBC_EXPORT40_WITH_MD5 SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5 +# define SSL_TXT_IDEA_128_CBC_WITH_MD5 SSL2_TXT_IDEA_128_CBC_WITH_MD5 +# define SSL_TXT_DES_64_CBC_WITH_MD5 SSL2_TXT_DES_64_CBC_WITH_MD5 +# define SSL_TXT_DES_64_CBC_WITH_SHA SSL2_TXT_DES_64_CBC_WITH_SHA +# define SSL_TXT_DES_192_EDE3_CBC_WITH_MD5 SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5 +# define SSL_TXT_DES_192_EDE3_CBC_WITH_SHA SSL2_TXT_DES_192_EDE3_CBC_WITH_SHA + +/* + * VRS Additional Kerberos5 entries + */ +# define SSL_TXT_KRB5_DES_64_CBC_SHA SSL3_TXT_KRB5_DES_64_CBC_SHA +# define SSL_TXT_KRB5_DES_192_CBC3_SHA SSL3_TXT_KRB5_DES_192_CBC3_SHA +# define SSL_TXT_KRB5_RC4_128_SHA SSL3_TXT_KRB5_RC4_128_SHA +# define SSL_TXT_KRB5_IDEA_128_CBC_SHA SSL3_TXT_KRB5_IDEA_128_CBC_SHA +# define SSL_TXT_KRB5_DES_64_CBC_MD5 SSL3_TXT_KRB5_DES_64_CBC_MD5 +# define SSL_TXT_KRB5_DES_192_CBC3_MD5 SSL3_TXT_KRB5_DES_192_CBC3_MD5 +# define SSL_TXT_KRB5_RC4_128_MD5 SSL3_TXT_KRB5_RC4_128_MD5 +# define SSL_TXT_KRB5_IDEA_128_CBC_MD5 SSL3_TXT_KRB5_IDEA_128_CBC_MD5 + +# define SSL_TXT_KRB5_DES_40_CBC_SHA SSL3_TXT_KRB5_DES_40_CBC_SHA +# define SSL_TXT_KRB5_RC2_40_CBC_SHA SSL3_TXT_KRB5_RC2_40_CBC_SHA +# define SSL_TXT_KRB5_RC4_40_SHA SSL3_TXT_KRB5_RC4_40_SHA +# define SSL_TXT_KRB5_DES_40_CBC_MD5 SSL3_TXT_KRB5_DES_40_CBC_MD5 +# define SSL_TXT_KRB5_RC2_40_CBC_MD5 SSL3_TXT_KRB5_RC2_40_CBC_MD5 +# define SSL_TXT_KRB5_RC4_40_MD5 SSL3_TXT_KRB5_RC4_40_MD5 + +# define SSL_TXT_KRB5_DES_40_CBC_SHA SSL3_TXT_KRB5_DES_40_CBC_SHA +# define SSL_TXT_KRB5_DES_40_CBC_MD5 SSL3_TXT_KRB5_DES_40_CBC_MD5 +# define SSL_TXT_KRB5_DES_64_CBC_SHA SSL3_TXT_KRB5_DES_64_CBC_SHA +# define SSL_TXT_KRB5_DES_64_CBC_MD5 SSL3_TXT_KRB5_DES_64_CBC_MD5 +# define SSL_TXT_KRB5_DES_192_CBC3_SHA SSL3_TXT_KRB5_DES_192_CBC3_SHA +# define SSL_TXT_KRB5_DES_192_CBC3_MD5 SSL3_TXT_KRB5_DES_192_CBC3_MD5 +# define SSL_MAX_KRB5_PRINCIPAL_LENGTH 256 + +# define SSL_MAX_SSL_SESSION_ID_LENGTH 32 +# define SSL_MAX_SID_CTX_LENGTH 32 + +# define SSL_MIN_RSA_MODULUS_LENGTH_IN_BYTES (512/8) +# define SSL_MAX_KEY_ARG_LENGTH 8 +# define SSL_MAX_MASTER_KEY_LENGTH 48 + +/* These are used to specify which ciphers to use and not to use */ + +# define SSL_TXT_EXP40 "EXPORT40" +# define SSL_TXT_EXP56 "EXPORT56" +# define SSL_TXT_LOW "LOW" +# define SSL_TXT_MEDIUM "MEDIUM" +# define SSL_TXT_HIGH "HIGH" +# define SSL_TXT_FIPS "FIPS" + +# define SSL_TXT_kFZA "kFZA"/* unused! */ +# define SSL_TXT_aFZA "aFZA"/* unused! */ +# define SSL_TXT_eFZA "eFZA"/* unused! */ +# define SSL_TXT_FZA "FZA"/* unused! */ + +# define SSL_TXT_aNULL "aNULL" +# define SSL_TXT_eNULL "eNULL" +# define SSL_TXT_NULL "NULL" + +# define SSL_TXT_kRSA "kRSA" +# define SSL_TXT_kDHr "kDHr" +# define SSL_TXT_kDHd "kDHd" +# define SSL_TXT_kDH "kDH" +# define SSL_TXT_kEDH "kEDH" +# define SSL_TXT_kDHE "kDHE"/* alias for kEDH */ +# define SSL_TXT_kKRB5 "kKRB5" +# define SSL_TXT_kECDHr "kECDHr" +# define SSL_TXT_kECDHe "kECDHe" +# define SSL_TXT_kECDH "kECDH" +# define SSL_TXT_kEECDH "kEECDH" +# define SSL_TXT_kECDHE "kECDHE"/* alias for kEECDH */ +# define SSL_TXT_kPSK "kPSK" +# define SSL_TXT_kGOST "kGOST" +# define SSL_TXT_kSRP "kSRP" + +# define SSL_TXT_aRSA "aRSA" +# define SSL_TXT_aDSS "aDSS" +# define SSL_TXT_aDH "aDH" +# define SSL_TXT_aECDH "aECDH" +# define SSL_TXT_aKRB5 "aKRB5" +# define SSL_TXT_aECDSA "aECDSA" +# define SSL_TXT_aPSK "aPSK" +# define SSL_TXT_aGOST94 "aGOST94" +# define SSL_TXT_aGOST01 "aGOST01" +# define SSL_TXT_aGOST "aGOST" +# define SSL_TXT_aSRP "aSRP" + +# define SSL_TXT_DSS "DSS" +# define SSL_TXT_DH "DH" +# define SSL_TXT_EDH "EDH"/* same as "kEDH:-ADH" */ +# define SSL_TXT_DHE "DHE"/* alias for EDH */ +# define SSL_TXT_ADH "ADH" +# define SSL_TXT_RSA "RSA" +# define SSL_TXT_ECDH "ECDH" +# define SSL_TXT_EECDH "EECDH"/* same as "kEECDH:-AECDH" */ +# define SSL_TXT_ECDHE "ECDHE"/* alias for ECDHE" */ +# define SSL_TXT_AECDH "AECDH" +# define SSL_TXT_ECDSA "ECDSA" +# define SSL_TXT_KRB5 "KRB5" +# define SSL_TXT_PSK "PSK" +# define SSL_TXT_SRP "SRP" + +# define SSL_TXT_DES "DES" +# define SSL_TXT_3DES "3DES" +# define SSL_TXT_RC4 "RC4" +# define SSL_TXT_RC2 "RC2" +# define SSL_TXT_IDEA "IDEA" +# define SSL_TXT_SEED "SEED" +# define SSL_TXT_AES128 "AES128" +# define SSL_TXT_AES256 "AES256" +# define SSL_TXT_AES "AES" +# define SSL_TXT_AES_GCM "AESGCM" +# define SSL_TXT_CAMELLIA128 "CAMELLIA128" +# define SSL_TXT_CAMELLIA256 "CAMELLIA256" +# define SSL_TXT_CAMELLIA "CAMELLIA" + +# define SSL_TXT_MD5 "MD5" +# define SSL_TXT_SHA1 "SHA1" +# define SSL_TXT_SHA "SHA"/* same as "SHA1" */ +# define SSL_TXT_GOST94 "GOST94" +# define SSL_TXT_GOST89MAC "GOST89MAC" +# define SSL_TXT_SHA256 "SHA256" +# define SSL_TXT_SHA384 "SHA384" + +# define SSL_TXT_SSLV2 "SSLv2" +# define SSL_TXT_SSLV3 "SSLv3" +# define SSL_TXT_TLSV1 "TLSv1" +# define SSL_TXT_TLSV1_1 "TLSv1.1" +# define SSL_TXT_TLSV1_2 "TLSv1.2" + +# define SSL_TXT_EXP "EXP" +# define SSL_TXT_EXPORT "EXPORT" + +# define SSL_TXT_ALL "ALL" + +/*- + * COMPLEMENTOF* definitions. These identifiers are used to (de-select) + * ciphers normally not being used. + * Example: "RC4" will activate all ciphers using RC4 including ciphers + * without authentication, which would normally disabled by DEFAULT (due + * the "!ADH" being part of default). Therefore "RC4:!COMPLEMENTOFDEFAULT" + * will make sure that it is also disabled in the specific selection. + * COMPLEMENTOF* identifiers are portable between version, as adjustments + * to the default cipher setup will also be included here. + * + * COMPLEMENTOFDEFAULT does not experience the same special treatment that + * DEFAULT gets, as only selection is being done and no sorting as needed + * for DEFAULT. + */ +# define SSL_TXT_CMPALL "COMPLEMENTOFALL" +# define SSL_TXT_CMPDEF "COMPLEMENTOFDEFAULT" + +/* + * The following cipher list is used by default. It also is substituted when + * an application-defined cipher list string starts with 'DEFAULT'. + */ +# define SSL_DEFAULT_CIPHER_LIST "ALL:!EXPORT:!LOW:!aNULL:!eNULL:!SSLv2" +/* + * As of OpenSSL 1.0.0, ssl_create_cipher_list() in ssl/ssl_ciph.c always + * starts with a reasonable order, and all we have to do for DEFAULT is + * throwing out anonymous and unencrypted ciphersuites! (The latter are not + * actually enabled by ALL, but "ALL:RSA" would enable some of them.) + */ + +/* Used in SSL_set_shutdown()/SSL_get_shutdown(); */ +# define SSL_SENT_SHUTDOWN 1 +# define SSL_RECEIVED_SHUTDOWN 2 + +#ifdef __cplusplus +} +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +# if (defined(OPENSSL_NO_RSA) || defined(OPENSSL_NO_MD5)) && !defined(OPENSSL_NO_SSL2) +# define OPENSSL_NO_SSL2 +# endif + +# define SSL_FILETYPE_ASN1 X509_FILETYPE_ASN1 +# define SSL_FILETYPE_PEM X509_FILETYPE_PEM + +/* + * This is needed to stop compilers complaining about the 'struct ssl_st *' + * function parameters used to prototype callbacks in SSL_CTX. + */ +typedef struct ssl_st *ssl_crock_st; +typedef struct tls_session_ticket_ext_st TLS_SESSION_TICKET_EXT; +typedef struct ssl_method_st SSL_METHOD; +typedef struct ssl_cipher_st SSL_CIPHER; +typedef struct ssl_session_st SSL_SESSION; +typedef struct tls_sigalgs_st TLS_SIGALGS; +typedef struct ssl_conf_ctx_st SSL_CONF_CTX; + +DECLARE_STACK_OF(SSL_CIPHER) + +/* SRTP protection profiles for use with the use_srtp extension (RFC 5764)*/ +typedef struct srtp_protection_profile_st { + const char *name; + unsigned long id; +} SRTP_PROTECTION_PROFILE; + +DECLARE_STACK_OF(SRTP_PROTECTION_PROFILE) + +typedef int (*tls_session_ticket_ext_cb_fn) (SSL *s, + const unsigned char *data, + int len, void *arg); +typedef int (*tls_session_secret_cb_fn) (SSL *s, void *secret, + int *secret_len, + STACK_OF(SSL_CIPHER) *peer_ciphers, + SSL_CIPHER **cipher, void *arg); + +# ifndef OPENSSL_NO_TLSEXT + +/* Typedefs for handling custom extensions */ + +typedef int (*custom_ext_add_cb) (SSL *s, unsigned int ext_type, + const unsigned char **out, + size_t *outlen, int *al, void *add_arg); + +typedef void (*custom_ext_free_cb) (SSL *s, unsigned int ext_type, + const unsigned char *out, void *add_arg); + +typedef int (*custom_ext_parse_cb) (SSL *s, unsigned int ext_type, + const unsigned char *in, + size_t inlen, int *al, void *parse_arg); + +# endif + +# ifndef OPENSSL_NO_SSL_INTERN + +/* used to hold info on the particular ciphers used */ +struct ssl_cipher_st { + int valid; + const char *name; /* text name */ + unsigned long id; /* id, 4 bytes, first is version */ + /* + * changed in 0.9.9: these four used to be portions of a single value + * 'algorithms' + */ + unsigned long algorithm_mkey; /* key exchange algorithm */ + unsigned long algorithm_auth; /* server authentication */ + unsigned long algorithm_enc; /* symmetric encryption */ + unsigned long algorithm_mac; /* symmetric authentication */ + unsigned long algorithm_ssl; /* (major) protocol version */ + unsigned long algo_strength; /* strength and export flags */ + unsigned long algorithm2; /* Extra flags */ + int strength_bits; /* Number of bits really used */ + int alg_bits; /* Number of bits for algorithm */ +}; + +/* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */ +struct ssl_method_st { + int version; + int (*ssl_new) (SSL *s); + void (*ssl_clear) (SSL *s); + void (*ssl_free) (SSL *s); + int (*ssl_accept) (SSL *s); + int (*ssl_connect) (SSL *s); + int (*ssl_read) (SSL *s, void *buf, int len); + int (*ssl_peek) (SSL *s, void *buf, int len); + int (*ssl_write) (SSL *s, const void *buf, int len); + int (*ssl_shutdown) (SSL *s); + int (*ssl_renegotiate) (SSL *s); + int (*ssl_renegotiate_check) (SSL *s); + long (*ssl_get_message) (SSL *s, int st1, int stn, int mt, long + max, int *ok); + int (*ssl_read_bytes) (SSL *s, int type, unsigned char *buf, int len, + int peek); + int (*ssl_write_bytes) (SSL *s, int type, const void *buf_, int len); + int (*ssl_dispatch_alert) (SSL *s); + long (*ssl_ctrl) (SSL *s, int cmd, long larg, void *parg); + long (*ssl_ctx_ctrl) (SSL_CTX *ctx, int cmd, long larg, void *parg); + const SSL_CIPHER *(*get_cipher_by_char) (const unsigned char *ptr); + int (*put_cipher_by_char) (const SSL_CIPHER *cipher, unsigned char *ptr); + int (*ssl_pending) (const SSL *s); + int (*num_ciphers) (void); + const SSL_CIPHER *(*get_cipher) (unsigned ncipher); + const struct ssl_method_st *(*get_ssl_method) (int version); + long (*get_timeout) (void); + struct ssl3_enc_method *ssl3_enc; /* Extra SSLv3/TLS stuff */ + int (*ssl_version) (void); + long (*ssl_callback_ctrl) (SSL *s, int cb_id, void (*fp) (void)); + long (*ssl_ctx_callback_ctrl) (SSL_CTX *s, int cb_id, void (*fp) (void)); +}; + +/*- + * Lets make this into an ASN.1 type structure as follows + * SSL_SESSION_ID ::= SEQUENCE { + * version INTEGER, -- structure version number + * SSLversion INTEGER, -- SSL version number + * Cipher OCTET STRING, -- the 3 byte cipher ID + * Session_ID OCTET STRING, -- the Session ID + * Master_key OCTET STRING, -- the master key + * KRB5_principal OCTET STRING -- optional Kerberos principal + * Key_Arg [ 0 ] IMPLICIT OCTET STRING, -- the optional Key argument + * Time [ 1 ] EXPLICIT INTEGER, -- optional Start Time + * Timeout [ 2 ] EXPLICIT INTEGER, -- optional Timeout ins seconds + * Peer [ 3 ] EXPLICIT X509, -- optional Peer Certificate + * Session_ID_context [ 4 ] EXPLICIT OCTET STRING, -- the Session ID context + * Verify_result [ 5 ] EXPLICIT INTEGER, -- X509_V_... code for `Peer' + * HostName [ 6 ] EXPLICIT OCTET STRING, -- optional HostName from servername TLS extension + * PSK_identity_hint [ 7 ] EXPLICIT OCTET STRING, -- optional PSK identity hint + * PSK_identity [ 8 ] EXPLICIT OCTET STRING, -- optional PSK identity + * Ticket_lifetime_hint [9] EXPLICIT INTEGER, -- server's lifetime hint for session ticket + * Ticket [10] EXPLICIT OCTET STRING, -- session ticket (clients only) + * Compression_meth [11] EXPLICIT OCTET STRING, -- optional compression method + * SRP_username [ 12 ] EXPLICIT OCTET STRING -- optional SRP username + * } + * Look in ssl/ssl_asn1.c for more details + * I'm using EXPLICIT tags so I can read the damn things using asn1parse :-). + */ +struct ssl_session_st { + int ssl_version; /* what ssl version session info is being + * kept in here? */ + /* only really used in SSLv2 */ + unsigned int key_arg_length; + unsigned char key_arg[SSL_MAX_KEY_ARG_LENGTH]; + int master_key_length; + unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH]; + /* session_id - valid? */ + unsigned int session_id_length; + unsigned char session_id[SSL_MAX_SSL_SESSION_ID_LENGTH]; + /* + * this is used to determine whether the session is being reused in the + * appropriate context. It is up to the application to set this, via + * SSL_new + */ + unsigned int sid_ctx_length; + unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH]; +# ifndef OPENSSL_NO_KRB5 + unsigned int krb5_client_princ_len; + unsigned char krb5_client_princ[SSL_MAX_KRB5_PRINCIPAL_LENGTH]; +# endif /* OPENSSL_NO_KRB5 */ +# ifndef OPENSSL_NO_PSK + char *psk_identity_hint; + char *psk_identity; +# endif + /* + * Used to indicate that session resumption is not allowed. Applications + * can also set this bit for a new session via not_resumable_session_cb + * to disable session caching and tickets. + */ + int not_resumable; + /* The cert is the certificate used to establish this connection */ + struct sess_cert_st /* SESS_CERT */ *sess_cert; + /* + * This is the cert for the other end. On clients, it will be the same as + * sess_cert->peer_key->x509 (the latter is not enough as sess_cert is + * not retained in the external representation of sessions, see + * ssl_asn1.c). + */ + X509 *peer; + /* + * when app_verify_callback accepts a session where the peer's + * certificate is not ok, we must remember the error for session reuse: + */ + long verify_result; /* only for servers */ + int references; + long timeout; + long time; + unsigned int compress_meth; /* Need to lookup the method */ + const SSL_CIPHER *cipher; + unsigned long cipher_id; /* when ASN.1 loaded, this needs to be used + * to load the 'cipher' structure */ + STACK_OF(SSL_CIPHER) *ciphers; /* shared ciphers? */ + CRYPTO_EX_DATA ex_data; /* application specific data */ + /* + * These are used to make removal of session-ids more efficient and to + * implement a maximum cache size. + */ + struct ssl_session_st *prev, *next; +# ifndef OPENSSL_NO_TLSEXT + char *tlsext_hostname; +# ifndef OPENSSL_NO_EC + size_t tlsext_ecpointformatlist_length; + unsigned char *tlsext_ecpointformatlist; /* peer's list */ + size_t tlsext_ellipticcurvelist_length; + unsigned char *tlsext_ellipticcurvelist; /* peer's list */ +# endif /* OPENSSL_NO_EC */ + /* RFC4507 info */ + unsigned char *tlsext_tick; /* Session ticket */ + size_t tlsext_ticklen; /* Session ticket length */ + long tlsext_tick_lifetime_hint; /* Session lifetime hint in seconds */ +# endif +# ifndef OPENSSL_NO_SRP + char *srp_username; +# endif +}; + +# endif + +# define SSL_OP_MICROSOFT_SESS_ID_BUG 0x00000001L +# define SSL_OP_NETSCAPE_CHALLENGE_BUG 0x00000002L +/* Allow initial connection to servers that don't support RI */ +# define SSL_OP_LEGACY_SERVER_CONNECT 0x00000004L +# define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG 0x00000008L +# define SSL_OP_TLSEXT_PADDING 0x00000010L +# define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER 0x00000020L +# define SSL_OP_SAFARI_ECDHE_ECDSA_BUG 0x00000040L +# define SSL_OP_SSLEAY_080_CLIENT_DH_BUG 0x00000080L +# define SSL_OP_TLS_D5_BUG 0x00000100L +# define SSL_OP_TLS_BLOCK_PADDING_BUG 0x00000200L + +/* Hasn't done anything since OpenSSL 0.9.7h, retained for compatibility */ +# define SSL_OP_MSIE_SSLV2_RSA_PADDING 0x0 +/* Refers to ancient SSLREF and SSLv2, retained for compatibility */ +# define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0x0 + +/* + * Disable SSL 3.0/TLS 1.0 CBC vulnerability workaround that was added in + * OpenSSL 0.9.6d. Usually (depending on the application protocol) the + * workaround is not needed. Unfortunately some broken SSL/TLS + * implementations cannot handle it at all, which is why we include it in + * SSL_OP_ALL. + */ +/* added in 0.9.6e */ +# define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS 0x00000800L + +/* + * SSL_OP_ALL: various bug workarounds that should be rather harmless. This + * used to be 0x000FFFFFL before 0.9.7. + */ +# define SSL_OP_ALL 0x80000BFFL + +/* DTLS options */ +# define SSL_OP_NO_QUERY_MTU 0x00001000L +/* Turn on Cookie Exchange (on relevant for servers) */ +# define SSL_OP_COOKIE_EXCHANGE 0x00002000L +/* Don't use RFC4507 ticket extension */ +# define SSL_OP_NO_TICKET 0x00004000L +/* Use Cisco's "speshul" version of DTLS_BAD_VER (as client) */ +# define SSL_OP_CISCO_ANYCONNECT 0x00008000L + +/* As server, disallow session resumption on renegotiation */ +# define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0x00010000L +/* Don't use compression even if supported */ +# define SSL_OP_NO_COMPRESSION 0x00020000L +/* Permit unsafe legacy renegotiation */ +# define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0x00040000L +/* If set, always create a new key when using tmp_ecdh parameters */ +# define SSL_OP_SINGLE_ECDH_USE 0x00080000L +/* Does nothing: retained for compatibility */ +# define SSL_OP_SINGLE_DH_USE 0x00100000L +/* Does nothing: retained for compatibiity */ +# define SSL_OP_EPHEMERAL_RSA 0x0 +/* + * Set on servers to choose the cipher according to the server's preferences + */ +# define SSL_OP_CIPHER_SERVER_PREFERENCE 0x00400000L +/* + * If set, a server will allow a client to issue a SSLv3.0 version number as + * latest version supported in the premaster secret, even when TLSv1.0 + * (version 3.1) was announced in the client hello. Normally this is + * forbidden to prevent version rollback attacks. + */ +# define SSL_OP_TLS_ROLLBACK_BUG 0x00800000L + +# define SSL_OP_NO_SSLv2 0x01000000L +# define SSL_OP_NO_SSLv3 0x02000000L +# define SSL_OP_NO_TLSv1 0x04000000L +# define SSL_OP_NO_TLSv1_2 0x08000000L +# define SSL_OP_NO_TLSv1_1 0x10000000L + +# define SSL_OP_NO_DTLSv1 0x04000000L +# define SSL_OP_NO_DTLSv1_2 0x08000000L + +# define SSL_OP_NO_SSL_MASK (SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|\ + SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_1|SSL_OP_NO_TLSv1_2) + +/* + * These next two were never actually used for anything since SSLeay zap so + * we have some more flags. + */ +/* + * The next flag deliberately changes the ciphertest, this is a check for the + * PKCS#1 attack + */ +# define SSL_OP_PKCS1_CHECK_1 0x0 +# define SSL_OP_PKCS1_CHECK_2 0x0 + +# define SSL_OP_NETSCAPE_CA_DN_BUG 0x20000000L +# define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG 0x40000000L +/* + * Make server add server-hello extension from early version of cryptopro + * draft, when GOST ciphersuite is negotiated. Required for interoperability + * with CryptoPro CSP 3.x + */ +# define SSL_OP_CRYPTOPRO_TLSEXT_BUG 0x80000000L + +/* + * Allow SSL_write(..., n) to return r with 0 < r < n (i.e. report success + * when just a single record has been written): + */ +# define SSL_MODE_ENABLE_PARTIAL_WRITE 0x00000001L +/* + * Make it possible to retry SSL_write() with changed buffer location (buffer + * contents must stay the same!); this is not the default to avoid the + * misconception that non-blocking SSL_write() behaves like non-blocking + * write(): + */ +# define SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER 0x00000002L +/* + * Never bother the application with retries if the transport is blocking: + */ +# define SSL_MODE_AUTO_RETRY 0x00000004L +/* Don't attempt to automatically build certificate chain */ +# define SSL_MODE_NO_AUTO_CHAIN 0x00000008L +/* + * Save RAM by releasing read and write buffers when they're empty. (SSL3 and + * TLS only.) "Released" buffers are put onto a free-list in the context or + * just freed (depending on the context's setting for freelist_max_len). + */ +# define SSL_MODE_RELEASE_BUFFERS 0x00000010L +/* + * Send the current time in the Random fields of the ClientHello and + * ServerHello records for compatibility with hypothetical implementations + * that require it. + */ +# define SSL_MODE_SEND_CLIENTHELLO_TIME 0x00000020L +# define SSL_MODE_SEND_SERVERHELLO_TIME 0x00000040L +/* + * Send TLS_FALLBACK_SCSV in the ClientHello. To be set only by applications + * that reconnect with a downgraded protocol version; see + * draft-ietf-tls-downgrade-scsv-00 for details. DO NOT ENABLE THIS if your + * application attempts a normal handshake. Only use this in explicit + * fallback retries, following the guidance in + * draft-ietf-tls-downgrade-scsv-00. + */ +# define SSL_MODE_SEND_FALLBACK_SCSV 0x00000080L + +/* Cert related flags */ +/* + * Many implementations ignore some aspects of the TLS standards such as + * enforcing certifcate chain algorithms. When this is set we enforce them. + */ +# define SSL_CERT_FLAG_TLS_STRICT 0x00000001L + +/* Suite B modes, takes same values as certificate verify flags */ +# define SSL_CERT_FLAG_SUITEB_128_LOS_ONLY 0x10000 +/* Suite B 192 bit only mode */ +# define SSL_CERT_FLAG_SUITEB_192_LOS 0x20000 +/* Suite B 128 bit mode allowing 192 bit algorithms */ +# define SSL_CERT_FLAG_SUITEB_128_LOS 0x30000 + +/* Perform all sorts of protocol violations for testing purposes */ +# define SSL_CERT_FLAG_BROKEN_PROTOCOL 0x10000000 + +/* Flags for building certificate chains */ +/* Treat any existing certificates as untrusted CAs */ +# define SSL_BUILD_CHAIN_FLAG_UNTRUSTED 0x1 +/* Don't include root CA in chain */ +# define SSL_BUILD_CHAIN_FLAG_NO_ROOT 0x2 +/* Just check certificates already there */ +# define SSL_BUILD_CHAIN_FLAG_CHECK 0x4 +/* Ignore verification errors */ +# define SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR 0x8 +/* Clear verification errors from queue */ +# define SSL_BUILD_CHAIN_FLAG_CLEAR_ERROR 0x10 + +/* Flags returned by SSL_check_chain */ +/* Certificate can be used with this session */ +# define CERT_PKEY_VALID 0x1 +/* Certificate can also be used for signing */ +# define CERT_PKEY_SIGN 0x2 +/* EE certificate signing algorithm OK */ +# define CERT_PKEY_EE_SIGNATURE 0x10 +/* CA signature algorithms OK */ +# define CERT_PKEY_CA_SIGNATURE 0x20 +/* EE certificate parameters OK */ +# define CERT_PKEY_EE_PARAM 0x40 +/* CA certificate parameters OK */ +# define CERT_PKEY_CA_PARAM 0x80 +/* Signing explicitly allowed as opposed to SHA1 fallback */ +# define CERT_PKEY_EXPLICIT_SIGN 0x100 +/* Client CA issuer names match (always set for server cert) */ +# define CERT_PKEY_ISSUER_NAME 0x200 +/* Cert type matches client types (always set for server cert) */ +# define CERT_PKEY_CERT_TYPE 0x400 +/* Cert chain suitable to Suite B */ +# define CERT_PKEY_SUITEB 0x800 + +# define SSL_CONF_FLAG_CMDLINE 0x1 +# define SSL_CONF_FLAG_FILE 0x2 +# define SSL_CONF_FLAG_CLIENT 0x4 +# define SSL_CONF_FLAG_SERVER 0x8 +# define SSL_CONF_FLAG_SHOW_ERRORS 0x10 +# define SSL_CONF_FLAG_CERTIFICATE 0x20 +/* Configuration value types */ +# define SSL_CONF_TYPE_UNKNOWN 0x0 +# define SSL_CONF_TYPE_STRING 0x1 +# define SSL_CONF_TYPE_FILE 0x2 +# define SSL_CONF_TYPE_DIR 0x3 + +/* + * Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value, they + * cannot be used to clear bits. + */ + +# define SSL_CTX_set_options(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,(op),NULL) +# define SSL_CTX_clear_options(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_OPTIONS,(op),NULL) +# define SSL_CTX_get_options(ctx) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,0,NULL) +# define SSL_set_options(ssl,op) \ + SSL_ctrl((ssl),SSL_CTRL_OPTIONS,(op),NULL) +# define SSL_clear_options(ssl,op) \ + SSL_ctrl((ssl),SSL_CTRL_CLEAR_OPTIONS,(op),NULL) +# define SSL_get_options(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_OPTIONS,0,NULL) + +# define SSL_CTX_set_mode(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,(op),NULL) +# define SSL_CTX_clear_mode(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_MODE,(op),NULL) +# define SSL_CTX_get_mode(ctx) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,0,NULL) +# define SSL_clear_mode(ssl,op) \ + SSL_ctrl((ssl),SSL_CTRL_CLEAR_MODE,(op),NULL) +# define SSL_set_mode(ssl,op) \ + SSL_ctrl((ssl),SSL_CTRL_MODE,(op),NULL) +# define SSL_get_mode(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_MODE,0,NULL) +# define SSL_set_mtu(ssl, mtu) \ + SSL_ctrl((ssl),SSL_CTRL_SET_MTU,(mtu),NULL) +# define DTLS_set_link_mtu(ssl, mtu) \ + SSL_ctrl((ssl),DTLS_CTRL_SET_LINK_MTU,(mtu),NULL) +# define DTLS_get_link_min_mtu(ssl) \ + SSL_ctrl((ssl),DTLS_CTRL_GET_LINK_MIN_MTU,0,NULL) + +# define SSL_get_secure_renegotiation_support(ssl) \ + SSL_ctrl((ssl), SSL_CTRL_GET_RI_SUPPORT, 0, NULL) + +# ifndef OPENSSL_NO_HEARTBEATS +# define SSL_heartbeat(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_TLS_EXT_SEND_HEARTBEAT,0,NULL) +# endif + +# define SSL_CTX_set_cert_flags(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_CERT_FLAGS,(op),NULL) +# define SSL_set_cert_flags(s,op) \ + SSL_ctrl((s),SSL_CTRL_CERT_FLAGS,(op),NULL) +# define SSL_CTX_clear_cert_flags(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_CERT_FLAGS,(op),NULL) +# define SSL_clear_cert_flags(s,op) \ + SSL_ctrl((s),SSL_CTRL_CLEAR_CERT_FLAGS,(op),NULL) + +void SSL_CTX_set_msg_callback(SSL_CTX *ctx, + void (*cb) (int write_p, int version, + int content_type, const void *buf, + size_t len, SSL *ssl, void *arg)); +void SSL_set_msg_callback(SSL *ssl, + void (*cb) (int write_p, int version, + int content_type, const void *buf, + size_t len, SSL *ssl, void *arg)); +# define SSL_CTX_set_msg_callback_arg(ctx, arg) SSL_CTX_ctrl((ctx), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg)) +# define SSL_set_msg_callback_arg(ssl, arg) SSL_ctrl((ssl), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg)) + +# ifndef OPENSSL_NO_SRP + +# ifndef OPENSSL_NO_SSL_INTERN + +typedef struct srp_ctx_st { + /* param for all the callbacks */ + void *SRP_cb_arg; + /* set client Hello login callback */ + int (*TLS_ext_srp_username_callback) (SSL *, int *, void *); + /* set SRP N/g param callback for verification */ + int (*SRP_verify_param_callback) (SSL *, void *); + /* set SRP client passwd callback */ + char *(*SRP_give_srp_client_pwd_callback) (SSL *, void *); + char *login; + BIGNUM *N, *g, *s, *B, *A; + BIGNUM *a, *b, *v; + char *info; + int strength; + unsigned long srp_Mask; +} SRP_CTX; + +# endif + +/* see tls_srp.c */ +int SSL_SRP_CTX_init(SSL *s); +int SSL_CTX_SRP_CTX_init(SSL_CTX *ctx); +int SSL_SRP_CTX_free(SSL *ctx); +int SSL_CTX_SRP_CTX_free(SSL_CTX *ctx); +int SSL_srp_server_param_with_username(SSL *s, int *ad); +int SRP_generate_server_master_secret(SSL *s, unsigned char *master_key); +int SRP_Calc_A_param(SSL *s); +int SRP_generate_client_master_secret(SSL *s, unsigned char *master_key); + +# endif + +# if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN32) +# define SSL_MAX_CERT_LIST_DEFAULT 1024*30 + /* 30k max cert list :-) */ +# else +# define SSL_MAX_CERT_LIST_DEFAULT 1024*100 + /* 100k max cert list :-) */ +# endif + +# define SSL_SESSION_CACHE_MAX_SIZE_DEFAULT (1024*20) + +/* + * This callback type is used inside SSL_CTX, SSL, and in the functions that + * set them. It is used to override the generation of SSL/TLS session IDs in + * a server. Return value should be zero on an error, non-zero to proceed. + * Also, callbacks should themselves check if the id they generate is unique + * otherwise the SSL handshake will fail with an error - callbacks can do + * this using the 'ssl' value they're passed by; + * SSL_has_matching_session_id(ssl, id, *id_len) The length value passed in + * is set at the maximum size the session ID can be. In SSLv2 this is 16 + * bytes, whereas SSLv3/TLSv1 it is 32 bytes. The callback can alter this + * length to be less if desired, but under SSLv2 session IDs are supposed to + * be fixed at 16 bytes so the id will be padded after the callback returns + * in this case. It is also an error for the callback to set the size to + * zero. + */ +typedef int (*GEN_SESSION_CB) (const SSL *ssl, unsigned char *id, + unsigned int *id_len); + +typedef struct ssl_comp_st SSL_COMP; + +# ifndef OPENSSL_NO_SSL_INTERN + +struct ssl_comp_st { + int id; + const char *name; +# ifndef OPENSSL_NO_COMP + COMP_METHOD *method; +# else + char *method; +# endif +}; + +DECLARE_STACK_OF(SSL_COMP) +DECLARE_LHASH_OF(SSL_SESSION); + +struct ssl_ctx_st { + const SSL_METHOD *method; + STACK_OF(SSL_CIPHER) *cipher_list; + /* same as above but sorted for lookup */ + STACK_OF(SSL_CIPHER) *cipher_list_by_id; + struct x509_store_st /* X509_STORE */ *cert_store; + LHASH_OF(SSL_SESSION) *sessions; + /* + * Most session-ids that will be cached, default is + * SSL_SESSION_CACHE_MAX_SIZE_DEFAULT. 0 is unlimited. + */ + unsigned long session_cache_size; + struct ssl_session_st *session_cache_head; + struct ssl_session_st *session_cache_tail; + /* + * This can have one of 2 values, ored together, SSL_SESS_CACHE_CLIENT, + * SSL_SESS_CACHE_SERVER, Default is SSL_SESSION_CACHE_SERVER, which + * means only SSL_accept which cache SSL_SESSIONS. + */ + int session_cache_mode; + /* + * If timeout is not 0, it is the default timeout value set when + * SSL_new() is called. This has been put in to make life easier to set + * things up + */ + long session_timeout; + /* + * If this callback is not null, it will be called each time a session id + * is added to the cache. If this function returns 1, it means that the + * callback will do a SSL_SESSION_free() when it has finished using it. + * Otherwise, on 0, it means the callback has finished with it. If + * remove_session_cb is not null, it will be called when a session-id is + * removed from the cache. After the call, OpenSSL will + * SSL_SESSION_free() it. + */ + int (*new_session_cb) (struct ssl_st *ssl, SSL_SESSION *sess); + void (*remove_session_cb) (struct ssl_ctx_st *ctx, SSL_SESSION *sess); + SSL_SESSION *(*get_session_cb) (struct ssl_st *ssl, + unsigned char *data, int len, int *copy); + struct { + int sess_connect; /* SSL new conn - started */ + int sess_connect_renegotiate; /* SSL reneg - requested */ + int sess_connect_good; /* SSL new conne/reneg - finished */ + int sess_accept; /* SSL new accept - started */ + int sess_accept_renegotiate; /* SSL reneg - requested */ + int sess_accept_good; /* SSL accept/reneg - finished */ + int sess_miss; /* session lookup misses */ + int sess_timeout; /* reuse attempt on timeouted session */ + int sess_cache_full; /* session removed due to full cache */ + int sess_hit; /* session reuse actually done */ + int sess_cb_hit; /* session-id that was not in the cache was + * passed back via the callback. This + * indicates that the application is + * supplying session-id's from other + * processes - spooky :-) */ + } stats; + + int references; + + /* if defined, these override the X509_verify_cert() calls */ + int (*app_verify_callback) (X509_STORE_CTX *, void *); + void *app_verify_arg; + /* + * before OpenSSL 0.9.7, 'app_verify_arg' was ignored + * ('app_verify_callback' was called with just one argument) + */ + + /* Default password callback. */ + pem_password_cb *default_passwd_callback; + + /* Default password callback user data. */ + void *default_passwd_callback_userdata; + + /* get client cert callback */ + int (*client_cert_cb) (SSL *ssl, X509 **x509, EVP_PKEY **pkey); + + /* cookie generate callback */ + int (*app_gen_cookie_cb) (SSL *ssl, unsigned char *cookie, + unsigned int *cookie_len); + + /* verify cookie callback */ + int (*app_verify_cookie_cb) (SSL *ssl, unsigned char *cookie, + unsigned int cookie_len); + + CRYPTO_EX_DATA ex_data; + + const EVP_MD *rsa_md5; /* For SSLv2 - name is 'ssl2-md5' */ + const EVP_MD *md5; /* For SSLv3/TLSv1 'ssl3-md5' */ + const EVP_MD *sha1; /* For SSLv3/TLSv1 'ssl3->sha1' */ + + STACK_OF(X509) *extra_certs; + STACK_OF(SSL_COMP) *comp_methods; /* stack of SSL_COMP, SSLv3/TLSv1 */ + + /* Default values used when no per-SSL value is defined follow */ + + /* used if SSL's info_callback is NULL */ + void (*info_callback) (const SSL *ssl, int type, int val); + + /* what we put in client cert requests */ + STACK_OF(X509_NAME) *client_CA; + + /* + * Default values to use in SSL structures follow (these are copied by + * SSL_new) + */ + + unsigned long options; + unsigned long mode; + long max_cert_list; + + struct cert_st /* CERT */ *cert; + int read_ahead; + + /* callback that allows applications to peek at protocol messages */ + void (*msg_callback) (int write_p, int version, int content_type, + const void *buf, size_t len, SSL *ssl, void *arg); + void *msg_callback_arg; + + int verify_mode; + unsigned int sid_ctx_length; + unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH]; + /* called 'verify_callback' in the SSL */ + int (*default_verify_callback) (int ok, X509_STORE_CTX *ctx); + + /* Default generate session ID callback. */ + GEN_SESSION_CB generate_session_id; + + X509_VERIFY_PARAM *param; + +# if 0 + int purpose; /* Purpose setting */ + int trust; /* Trust setting */ +# endif + + int quiet_shutdown; + + /* + * Maximum amount of data to send in one fragment. actual record size can + * be more than this due to padding and MAC overheads. + */ + unsigned int max_send_fragment; + +# ifndef OPENSSL_NO_ENGINE + /* + * Engine to pass requests for client certs to + */ + ENGINE *client_cert_engine; +# endif + +# ifndef OPENSSL_NO_TLSEXT + /* TLS extensions servername callback */ + int (*tlsext_servername_callback) (SSL *, int *, void *); + void *tlsext_servername_arg; + /* RFC 4507 session ticket keys */ + unsigned char tlsext_tick_key_name[16]; + unsigned char tlsext_tick_hmac_key[16]; + unsigned char tlsext_tick_aes_key[16]; + /* Callback to support customisation of ticket key setting */ + int (*tlsext_ticket_key_cb) (SSL *ssl, + unsigned char *name, unsigned char *iv, + EVP_CIPHER_CTX *ectx, + HMAC_CTX *hctx, int enc); + + /* certificate status request info */ + /* Callback for status request */ + int (*tlsext_status_cb) (SSL *ssl, void *arg); + void *tlsext_status_arg; + + /* draft-rescorla-tls-opaque-prf-input-00.txt information */ + int (*tlsext_opaque_prf_input_callback) (SSL *, void *peerinput, + size_t len, void *arg); + void *tlsext_opaque_prf_input_callback_arg; +# endif + +# ifndef OPENSSL_NO_PSK + char *psk_identity_hint; + unsigned int (*psk_client_callback) (SSL *ssl, const char *hint, + char *identity, + unsigned int max_identity_len, + unsigned char *psk, + unsigned int max_psk_len); + unsigned int (*psk_server_callback) (SSL *ssl, const char *identity, + unsigned char *psk, + unsigned int max_psk_len); +# endif + +# ifndef OPENSSL_NO_BUF_FREELISTS +# define SSL_MAX_BUF_FREELIST_LEN_DEFAULT 32 + unsigned int freelist_max_len; + struct ssl3_buf_freelist_st *wbuf_freelist; + struct ssl3_buf_freelist_st *rbuf_freelist; +# endif +# ifndef OPENSSL_NO_SRP + SRP_CTX srp_ctx; /* ctx for SRP authentication */ +# endif + +# ifndef OPENSSL_NO_TLSEXT + +# ifndef OPENSSL_NO_NEXTPROTONEG + /* Next protocol negotiation information */ + /* (for experimental NPN extension). */ + + /* + * For a server, this contains a callback function by which the set of + * advertised protocols can be provided. + */ + int (*next_protos_advertised_cb) (SSL *s, const unsigned char **buf, + unsigned int *len, void *arg); + void *next_protos_advertised_cb_arg; + /* + * For a client, this contains a callback function that selects the next + * protocol from the list provided by the server. + */ + int (*next_proto_select_cb) (SSL *s, unsigned char **out, + unsigned char *outlen, + const unsigned char *in, + unsigned int inlen, void *arg); + void *next_proto_select_cb_arg; +# endif + /* SRTP profiles we are willing to do from RFC 5764 */ + STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles; + + /* + * ALPN information (we are in the process of transitioning from NPN to + * ALPN.) + */ + + /*- + * For a server, this contains a callback function that allows the + * server to select the protocol for the connection. + * out: on successful return, this must point to the raw protocol + * name (without the length prefix). + * outlen: on successful return, this contains the length of |*out|. + * in: points to the client's list of supported protocols in + * wire-format. + * inlen: the length of |in|. + */ + int (*alpn_select_cb) (SSL *s, + const unsigned char **out, + unsigned char *outlen, + const unsigned char *in, + unsigned int inlen, void *arg); + void *alpn_select_cb_arg; + + /* + * For a client, this contains the list of supported protocols in wire + * format. + */ + unsigned char *alpn_client_proto_list; + unsigned alpn_client_proto_list_len; + +# ifndef OPENSSL_NO_EC + /* EC extension values inherited by SSL structure */ + size_t tlsext_ecpointformatlist_length; + unsigned char *tlsext_ecpointformatlist; + size_t tlsext_ellipticcurvelist_length; + unsigned char *tlsext_ellipticcurvelist; +# endif /* OPENSSL_NO_EC */ +# endif +}; + +# endif + +# define SSL_SESS_CACHE_OFF 0x0000 +# define SSL_SESS_CACHE_CLIENT 0x0001 +# define SSL_SESS_CACHE_SERVER 0x0002 +# define SSL_SESS_CACHE_BOTH (SSL_SESS_CACHE_CLIENT|SSL_SESS_CACHE_SERVER) +# define SSL_SESS_CACHE_NO_AUTO_CLEAR 0x0080 +/* enough comments already ... see SSL_CTX_set_session_cache_mode(3) */ +# define SSL_SESS_CACHE_NO_INTERNAL_LOOKUP 0x0100 +# define SSL_SESS_CACHE_NO_INTERNAL_STORE 0x0200 +# define SSL_SESS_CACHE_NO_INTERNAL \ + (SSL_SESS_CACHE_NO_INTERNAL_LOOKUP|SSL_SESS_CACHE_NO_INTERNAL_STORE) + +LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx); +# define SSL_CTX_sess_number(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_NUMBER,0,NULL) +# define SSL_CTX_sess_connect(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT,0,NULL) +# define SSL_CTX_sess_connect_good(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT_GOOD,0,NULL) +# define SSL_CTX_sess_connect_renegotiate(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT_RENEGOTIATE,0,NULL) +# define SSL_CTX_sess_accept(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT,0,NULL) +# define SSL_CTX_sess_accept_renegotiate(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT_RENEGOTIATE,0,NULL) +# define SSL_CTX_sess_accept_good(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT_GOOD,0,NULL) +# define SSL_CTX_sess_hits(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_HIT,0,NULL) +# define SSL_CTX_sess_cb_hits(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CB_HIT,0,NULL) +# define SSL_CTX_sess_misses(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_MISSES,0,NULL) +# define SSL_CTX_sess_timeouts(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_TIMEOUTS,0,NULL) +# define SSL_CTX_sess_cache_full(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CACHE_FULL,0,NULL) + +void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx, + int (*new_session_cb) (struct ssl_st *ssl, + SSL_SESSION *sess)); +int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx)) (struct ssl_st *ssl, + SSL_SESSION *sess); +void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx, + void (*remove_session_cb) (struct ssl_ctx_st + *ctx, + SSL_SESSION + *sess)); +void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx)) (struct ssl_ctx_st *ctx, + SSL_SESSION *sess); +void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx, + SSL_SESSION *(*get_session_cb) (struct ssl_st + *ssl, + unsigned char + *data, int len, + int *copy)); +SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx)) (struct ssl_st *ssl, + unsigned char *Data, + int len, int *copy); +void SSL_CTX_set_info_callback(SSL_CTX *ctx, + void (*cb) (const SSL *ssl, int type, + int val)); +void (*SSL_CTX_get_info_callback(SSL_CTX *ctx)) (const SSL *ssl, int type, + int val); +void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, + int (*client_cert_cb) (SSL *ssl, X509 **x509, + EVP_PKEY **pkey)); +int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx)) (SSL *ssl, X509 **x509, + EVP_PKEY **pkey); +# ifndef OPENSSL_NO_ENGINE +int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e); +# endif +void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, + int (*app_gen_cookie_cb) (SSL *ssl, + unsigned char + *cookie, + unsigned int + *cookie_len)); +void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, + int (*app_verify_cookie_cb) (SSL *ssl, + unsigned char + *cookie, + unsigned int + cookie_len)); +# ifndef OPENSSL_NO_NEXTPROTONEG +void SSL_CTX_set_next_protos_advertised_cb(SSL_CTX *s, + int (*cb) (SSL *ssl, + const unsigned char + **out, + unsigned int *outlen, + void *arg), void *arg); +void SSL_CTX_set_next_proto_select_cb(SSL_CTX *s, + int (*cb) (SSL *ssl, + unsigned char **out, + unsigned char *outlen, + const unsigned char *in, + unsigned int inlen, + void *arg), void *arg); +void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data, + unsigned *len); +# endif + +# ifndef OPENSSL_NO_TLSEXT +int SSL_select_next_proto(unsigned char **out, unsigned char *outlen, + const unsigned char *in, unsigned int inlen, + const unsigned char *client, + unsigned int client_len); +# endif + +# define OPENSSL_NPN_UNSUPPORTED 0 +# define OPENSSL_NPN_NEGOTIATED 1 +# define OPENSSL_NPN_NO_OVERLAP 2 + +int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos, + unsigned protos_len); +int SSL_set_alpn_protos(SSL *ssl, const unsigned char *protos, + unsigned protos_len); +void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx, + int (*cb) (SSL *ssl, + const unsigned char **out, + unsigned char *outlen, + const unsigned char *in, + unsigned int inlen, + void *arg), void *arg); +void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data, + unsigned *len); + +# ifndef OPENSSL_NO_PSK +/* + * the maximum length of the buffer given to callbacks containing the + * resulting identity/psk + */ +# define PSK_MAX_IDENTITY_LEN 128 +# define PSK_MAX_PSK_LEN 256 +void SSL_CTX_set_psk_client_callback(SSL_CTX *ctx, + unsigned int (*psk_client_callback) (SSL + *ssl, + const + char + *hint, + char + *identity, + unsigned + int + max_identity_len, + unsigned + char + *psk, + unsigned + int + max_psk_len)); +void SSL_set_psk_client_callback(SSL *ssl, + unsigned int (*psk_client_callback) (SSL + *ssl, + const + char + *hint, + char + *identity, + unsigned + int + max_identity_len, + unsigned + char + *psk, + unsigned + int + max_psk_len)); +void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx, + unsigned int (*psk_server_callback) (SSL + *ssl, + const + char + *identity, + unsigned + char + *psk, + unsigned + int + max_psk_len)); +void SSL_set_psk_server_callback(SSL *ssl, + unsigned int (*psk_server_callback) (SSL + *ssl, + const + char + *identity, + unsigned + char + *psk, + unsigned + int + max_psk_len)); +int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint); +int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint); +const char *SSL_get_psk_identity_hint(const SSL *s); +const char *SSL_get_psk_identity(const SSL *s); +# endif + +# ifndef OPENSSL_NO_TLSEXT +/* Register callbacks to handle custom TLS Extensions for client or server. */ + +int SSL_CTX_add_client_custom_ext(SSL_CTX *ctx, unsigned int ext_type, + custom_ext_add_cb add_cb, + custom_ext_free_cb free_cb, + void *add_arg, + custom_ext_parse_cb parse_cb, + void *parse_arg); + +int SSL_CTX_add_server_custom_ext(SSL_CTX *ctx, unsigned int ext_type, + custom_ext_add_cb add_cb, + custom_ext_free_cb free_cb, + void *add_arg, + custom_ext_parse_cb parse_cb, + void *parse_arg); + +int SSL_extension_supported(unsigned int ext_type); + +# endif + +# define SSL_NOTHING 1 +# define SSL_WRITING 2 +# define SSL_READING 3 +# define SSL_X509_LOOKUP 4 + +/* These will only be used when doing non-blocking IO */ +# define SSL_want_nothing(s) (SSL_want(s) == SSL_NOTHING) +# define SSL_want_read(s) (SSL_want(s) == SSL_READING) +# define SSL_want_write(s) (SSL_want(s) == SSL_WRITING) +# define SSL_want_x509_lookup(s) (SSL_want(s) == SSL_X509_LOOKUP) + +# define SSL_MAC_FLAG_READ_MAC_STREAM 1 +# define SSL_MAC_FLAG_WRITE_MAC_STREAM 2 + +# ifndef OPENSSL_NO_SSL_INTERN + +struct ssl_st { + /* + * protocol version (one of SSL2_VERSION, SSL3_VERSION, TLS1_VERSION, + * DTLS1_VERSION) + */ + int version; + /* SSL_ST_CONNECT or SSL_ST_ACCEPT */ + int type; + /* SSLv3 */ + const SSL_METHOD *method; + /* + * There are 2 BIO's even though they are normally both the same. This + * is so data can be read and written to different handlers + */ +# ifndef OPENSSL_NO_BIO + /* used by SSL_read */ + BIO *rbio; + /* used by SSL_write */ + BIO *wbio; + /* used during session-id reuse to concatenate messages */ + BIO *bbio; +# else + /* used by SSL_read */ + char *rbio; + /* used by SSL_write */ + char *wbio; + char *bbio; +# endif + /* + * This holds a variable that indicates what we were doing when a 0 or -1 + * is returned. This is needed for non-blocking IO so we know what + * request needs re-doing when in SSL_accept or SSL_connect + */ + int rwstate; + /* true when we are actually in SSL_accept() or SSL_connect() */ + int in_handshake; + int (*handshake_func) (SSL *); + /* + * Imagine that here's a boolean member "init" that is switched as soon + * as SSL_set_{accept/connect}_state is called for the first time, so + * that "state" and "handshake_func" are properly initialized. But as + * handshake_func is == 0 until then, we use this test instead of an + * "init" member. + */ + /* are we the server side? - mostly used by SSL_clear */ + int server; + /* + * Generate a new session or reuse an old one. + * NB: For servers, the 'new' session may actually be a previously + * cached session or even the previous session unless + * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is set + */ + int new_session; + /* don't send shutdown packets */ + int quiet_shutdown; + /* we have shut things down, 0x01 sent, 0x02 for received */ + int shutdown; + /* where we are */ + int state; + /* where we are when reading */ + int rstate; + BUF_MEM *init_buf; /* buffer used during init */ + void *init_msg; /* pointer to handshake message body, set by + * ssl3_get_message() */ + int init_num; /* amount read/written */ + int init_off; /* amount read/written */ + /* used internally to point at a raw packet */ + unsigned char *packet; + unsigned int packet_length; + struct ssl2_state_st *s2; /* SSLv2 variables */ + struct ssl3_state_st *s3; /* SSLv3 variables */ + struct dtls1_state_st *d1; /* DTLSv1 variables */ + int read_ahead; /* Read as many input bytes as possible (for + * non-blocking reads) */ + /* callback that allows applications to peek at protocol messages */ + void (*msg_callback) (int write_p, int version, int content_type, + const void *buf, size_t len, SSL *ssl, void *arg); + void *msg_callback_arg; + int hit; /* reusing a previous session */ + X509_VERIFY_PARAM *param; +# if 0 + int purpose; /* Purpose setting */ + int trust; /* Trust setting */ +# endif + /* crypto */ + STACK_OF(SSL_CIPHER) *cipher_list; + STACK_OF(SSL_CIPHER) *cipher_list_by_id; + /* + * These are the ones being used, the ones in SSL_SESSION are the ones to + * be 'copied' into these ones + */ + int mac_flags; + EVP_CIPHER_CTX *enc_read_ctx; /* cryptographic state */ + EVP_MD_CTX *read_hash; /* used for mac generation */ +# ifndef OPENSSL_NO_COMP + COMP_CTX *expand; /* uncompress */ +# else + char *expand; +# endif + EVP_CIPHER_CTX *enc_write_ctx; /* cryptographic state */ + EVP_MD_CTX *write_hash; /* used for mac generation */ +# ifndef OPENSSL_NO_COMP + COMP_CTX *compress; /* compression */ +# else + char *compress; +# endif + /* session info */ + /* client cert? */ + /* This is used to hold the server certificate used */ + struct cert_st /* CERT */ *cert; + /* + * the session_id_context is used to ensure sessions are only reused in + * the appropriate context + */ + unsigned int sid_ctx_length; + unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH]; + /* This can also be in the session once a session is established */ + SSL_SESSION *session; + /* Default generate session ID callback. */ + GEN_SESSION_CB generate_session_id; + /* Used in SSL2 and SSL3 */ + /* + * 0 don't care about verify failure. + * 1 fail if verify fails + */ + int verify_mode; + /* fail if callback returns 0 */ + int (*verify_callback) (int ok, X509_STORE_CTX *ctx); + /* optional informational callback */ + void (*info_callback) (const SSL *ssl, int type, int val); + /* error bytes to be written */ + int error; + /* actual code */ + int error_code; +# ifndef OPENSSL_NO_KRB5 + /* Kerberos 5 context */ + KSSL_CTX *kssl_ctx; +# endif /* OPENSSL_NO_KRB5 */ +# ifndef OPENSSL_NO_PSK + unsigned int (*psk_client_callback) (SSL *ssl, const char *hint, + char *identity, + unsigned int max_identity_len, + unsigned char *psk, + unsigned int max_psk_len); + unsigned int (*psk_server_callback) (SSL *ssl, const char *identity, + unsigned char *psk, + unsigned int max_psk_len); +# endif + SSL_CTX *ctx; + /* + * set this flag to 1 and a sleep(1) is put into all SSL_read() and + * SSL_write() calls, good for nbio debuging :-) + */ + int debug; + /* extra application data */ + long verify_result; + CRYPTO_EX_DATA ex_data; + /* for server side, keep the list of CA_dn we can use */ + STACK_OF(X509_NAME) *client_CA; + int references; + /* protocol behaviour */ + unsigned long options; + /* API behaviour */ + unsigned long mode; + long max_cert_list; + int first_packet; + /* what was passed, used for SSLv3/TLS rollback check */ + int client_version; + unsigned int max_send_fragment; +# ifndef OPENSSL_NO_TLSEXT + /* TLS extension debug callback */ + void (*tlsext_debug_cb) (SSL *s, int client_server, int type, + unsigned char *data, int len, void *arg); + void *tlsext_debug_arg; + char *tlsext_hostname; + /*- + * no further mod of servername + * 0 : call the servername extension callback. + * 1 : prepare 2, allow last ack just after in server callback. + * 2 : don't call servername callback, no ack in server hello + */ + int servername_done; + /* certificate status request info */ + /* Status type or -1 if no status type */ + int tlsext_status_type; + /* Expect OCSP CertificateStatus message */ + int tlsext_status_expected; + /* OCSP status request only */ + STACK_OF(OCSP_RESPID) *tlsext_ocsp_ids; + X509_EXTENSIONS *tlsext_ocsp_exts; + /* OCSP response received or to be sent */ + unsigned char *tlsext_ocsp_resp; + int tlsext_ocsp_resplen; + /* RFC4507 session ticket expected to be received or sent */ + int tlsext_ticket_expected; +# ifndef OPENSSL_NO_EC + size_t tlsext_ecpointformatlist_length; + /* our list */ + unsigned char *tlsext_ecpointformatlist; + size_t tlsext_ellipticcurvelist_length; + /* our list */ + unsigned char *tlsext_ellipticcurvelist; +# endif /* OPENSSL_NO_EC */ + /* + * draft-rescorla-tls-opaque-prf-input-00.txt information to be used for + * handshakes + */ + void *tlsext_opaque_prf_input; + size_t tlsext_opaque_prf_input_len; + /* TLS Session Ticket extension override */ + TLS_SESSION_TICKET_EXT *tlsext_session_ticket; + /* TLS Session Ticket extension callback */ + tls_session_ticket_ext_cb_fn tls_session_ticket_ext_cb; + void *tls_session_ticket_ext_cb_arg; + /* TLS pre-shared secret session resumption */ + tls_session_secret_cb_fn tls_session_secret_cb; + void *tls_session_secret_cb_arg; + SSL_CTX *initial_ctx; /* initial ctx, used to store sessions */ +# ifndef OPENSSL_NO_NEXTPROTONEG + /* + * Next protocol negotiation. For the client, this is the protocol that + * we sent in NextProtocol and is set when handling ServerHello + * extensions. For a server, this is the client's selected_protocol from + * NextProtocol and is set when handling the NextProtocol message, before + * the Finished message. + */ + unsigned char *next_proto_negotiated; + unsigned char next_proto_negotiated_len; +# endif +# define session_ctx initial_ctx + /* What we'll do */ + STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles; + /* What's been chosen */ + SRTP_PROTECTION_PROFILE *srtp_profile; + /*- + * Is use of the Heartbeat extension negotiated? + * 0: disabled + * 1: enabled + * 2: enabled, but not allowed to send Requests + */ + unsigned int tlsext_heartbeat; + /* Indicates if a HeartbeatRequest is in flight */ + unsigned int tlsext_hb_pending; + /* HeartbeatRequest sequence number */ + unsigned int tlsext_hb_seq; +# else +# define session_ctx ctx +# endif /* OPENSSL_NO_TLSEXT */ + /*- + * 1 if we are renegotiating. + * 2 if we are a server and are inside a handshake + * (i.e. not just sending a HelloRequest) + */ + int renegotiate; +# ifndef OPENSSL_NO_SRP + /* ctx for SRP authentication */ + SRP_CTX srp_ctx; +# endif +# ifndef OPENSSL_NO_TLSEXT + /* + * For a client, this contains the list of supported protocols in wire + * format. + */ + unsigned char *alpn_client_proto_list; + unsigned alpn_client_proto_list_len; +# endif /* OPENSSL_NO_TLSEXT */ +}; + +# endif + +#ifdef __cplusplus +} +#endif + +# include +# include +# include /* This is mostly sslv3 with a few tweaks */ +# include /* Datagram TLS */ +# include +# include /* Support for the use_srtp extension */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* compatibility */ +# define SSL_set_app_data(s,arg) (SSL_set_ex_data(s,0,(char *)arg)) +# define SSL_get_app_data(s) (SSL_get_ex_data(s,0)) +# define SSL_SESSION_set_app_data(s,a) (SSL_SESSION_set_ex_data(s,0,(char *)a)) +# define SSL_SESSION_get_app_data(s) (SSL_SESSION_get_ex_data(s,0)) +# define SSL_CTX_get_app_data(ctx) (SSL_CTX_get_ex_data(ctx,0)) +# define SSL_CTX_set_app_data(ctx,arg) (SSL_CTX_set_ex_data(ctx,0,(char *)arg)) + +/* + * The following are the possible values for ssl->state are are used to + * indicate where we are up to in the SSL connection establishment. The + * macros that follow are about the only things you should need to use and + * even then, only when using non-blocking IO. It can also be useful to work + * out where you were when the connection failed + */ + +# define SSL_ST_CONNECT 0x1000 +# define SSL_ST_ACCEPT 0x2000 +# define SSL_ST_MASK 0x0FFF +# define SSL_ST_INIT (SSL_ST_CONNECT|SSL_ST_ACCEPT) +# define SSL_ST_BEFORE 0x4000 +# define SSL_ST_OK 0x03 +# define SSL_ST_RENEGOTIATE (0x04|SSL_ST_INIT) +# define SSL_ST_ERR 0x05 + +# define SSL_CB_LOOP 0x01 +# define SSL_CB_EXIT 0x02 +# define SSL_CB_READ 0x04 +# define SSL_CB_WRITE 0x08 +# define SSL_CB_ALERT 0x4000/* used in callback */ +# define SSL_CB_READ_ALERT (SSL_CB_ALERT|SSL_CB_READ) +# define SSL_CB_WRITE_ALERT (SSL_CB_ALERT|SSL_CB_WRITE) +# define SSL_CB_ACCEPT_LOOP (SSL_ST_ACCEPT|SSL_CB_LOOP) +# define SSL_CB_ACCEPT_EXIT (SSL_ST_ACCEPT|SSL_CB_EXIT) +# define SSL_CB_CONNECT_LOOP (SSL_ST_CONNECT|SSL_CB_LOOP) +# define SSL_CB_CONNECT_EXIT (SSL_ST_CONNECT|SSL_CB_EXIT) +# define SSL_CB_HANDSHAKE_START 0x10 +# define SSL_CB_HANDSHAKE_DONE 0x20 + +/* Is the SSL_connection established? */ +# define SSL_get_state(a) SSL_state(a) +# define SSL_is_init_finished(a) (SSL_state(a) == SSL_ST_OK) +# define SSL_in_init(a) (SSL_state(a)&SSL_ST_INIT) +# define SSL_in_before(a) (SSL_state(a)&SSL_ST_BEFORE) +# define SSL_in_connect_init(a) (SSL_state(a)&SSL_ST_CONNECT) +# define SSL_in_accept_init(a) (SSL_state(a)&SSL_ST_ACCEPT) + +/* + * The following 2 states are kept in ssl->rstate when reads fail, you should + * not need these + */ +# define SSL_ST_READ_HEADER 0xF0 +# define SSL_ST_READ_BODY 0xF1 +# define SSL_ST_READ_DONE 0xF2 + +/*- + * Obtain latest Finished message + * -- that we sent (SSL_get_finished) + * -- that we expected from peer (SSL_get_peer_finished). + * Returns length (0 == no Finished so far), copies up to 'count' bytes. + */ +size_t SSL_get_finished(const SSL *s, void *buf, size_t count); +size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count); + +/* + * use either SSL_VERIFY_NONE or SSL_VERIFY_PEER, the last 2 options are + * 'ored' with SSL_VERIFY_PEER if they are desired + */ +# define SSL_VERIFY_NONE 0x00 +# define SSL_VERIFY_PEER 0x01 +# define SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02 +# define SSL_VERIFY_CLIENT_ONCE 0x04 + +# define OpenSSL_add_ssl_algorithms() SSL_library_init() +# define SSLeay_add_ssl_algorithms() SSL_library_init() + +/* this is for backward compatibility */ +# if 0 /* NEW_SSLEAY */ +# define SSL_CTX_set_default_verify(a,b,c) SSL_CTX_set_verify(a,b,c) +# define SSL_set_pref_cipher(c,n) SSL_set_cipher_list(c,n) +# define SSL_add_session(a,b) SSL_CTX_add_session((a),(b)) +# define SSL_remove_session(a,b) SSL_CTX_remove_session((a),(b)) +# define SSL_flush_sessions(a,b) SSL_CTX_flush_sessions((a),(b)) +# endif +/* More backward compatibility */ +# define SSL_get_cipher(s) \ + SSL_CIPHER_get_name(SSL_get_current_cipher(s)) +# define SSL_get_cipher_bits(s,np) \ + SSL_CIPHER_get_bits(SSL_get_current_cipher(s),np) +# define SSL_get_cipher_version(s) \ + SSL_CIPHER_get_version(SSL_get_current_cipher(s)) +# define SSL_get_cipher_name(s) \ + SSL_CIPHER_get_name(SSL_get_current_cipher(s)) +# define SSL_get_time(a) SSL_SESSION_get_time(a) +# define SSL_set_time(a,b) SSL_SESSION_set_time((a),(b)) +# define SSL_get_timeout(a) SSL_SESSION_get_timeout(a) +# define SSL_set_timeout(a,b) SSL_SESSION_set_timeout((a),(b)) + +# define d2i_SSL_SESSION_bio(bp,s_id) ASN1_d2i_bio_of(SSL_SESSION,SSL_SESSION_new,d2i_SSL_SESSION,bp,s_id) +# define i2d_SSL_SESSION_bio(bp,s_id) ASN1_i2d_bio_of(SSL_SESSION,i2d_SSL_SESSION,bp,s_id) + +DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) +# define SSL_AD_REASON_OFFSET 1000/* offset to get SSL_R_... value + * from SSL_AD_... */ +/* These alert types are for SSLv3 and TLSv1 */ +# define SSL_AD_CLOSE_NOTIFY SSL3_AD_CLOSE_NOTIFY +/* fatal */ +# define SSL_AD_UNEXPECTED_MESSAGE SSL3_AD_UNEXPECTED_MESSAGE +/* fatal */ +# define SSL_AD_BAD_RECORD_MAC SSL3_AD_BAD_RECORD_MAC +# define SSL_AD_DECRYPTION_FAILED TLS1_AD_DECRYPTION_FAILED +# define SSL_AD_RECORD_OVERFLOW TLS1_AD_RECORD_OVERFLOW +/* fatal */ +# define SSL_AD_DECOMPRESSION_FAILURE SSL3_AD_DECOMPRESSION_FAILURE +/* fatal */ +# define SSL_AD_HANDSHAKE_FAILURE SSL3_AD_HANDSHAKE_FAILURE +/* Not for TLS */ +# define SSL_AD_NO_CERTIFICATE SSL3_AD_NO_CERTIFICATE +# define SSL_AD_BAD_CERTIFICATE SSL3_AD_BAD_CERTIFICATE +# define SSL_AD_UNSUPPORTED_CERTIFICATE SSL3_AD_UNSUPPORTED_CERTIFICATE +# define SSL_AD_CERTIFICATE_REVOKED SSL3_AD_CERTIFICATE_REVOKED +# define SSL_AD_CERTIFICATE_EXPIRED SSL3_AD_CERTIFICATE_EXPIRED +# define SSL_AD_CERTIFICATE_UNKNOWN SSL3_AD_CERTIFICATE_UNKNOWN +/* fatal */ +# define SSL_AD_ILLEGAL_PARAMETER SSL3_AD_ILLEGAL_PARAMETER +/* fatal */ +# define SSL_AD_UNKNOWN_CA TLS1_AD_UNKNOWN_CA +/* fatal */ +# define SSL_AD_ACCESS_DENIED TLS1_AD_ACCESS_DENIED +/* fatal */ +# define SSL_AD_DECODE_ERROR TLS1_AD_DECODE_ERROR +# define SSL_AD_DECRYPT_ERROR TLS1_AD_DECRYPT_ERROR +/* fatal */ +# define SSL_AD_EXPORT_RESTRICTION TLS1_AD_EXPORT_RESTRICTION +/* fatal */ +# define SSL_AD_PROTOCOL_VERSION TLS1_AD_PROTOCOL_VERSION +/* fatal */ +# define SSL_AD_INSUFFICIENT_SECURITY TLS1_AD_INSUFFICIENT_SECURITY +/* fatal */ +# define SSL_AD_INTERNAL_ERROR TLS1_AD_INTERNAL_ERROR +# define SSL_AD_USER_CANCELLED TLS1_AD_USER_CANCELLED +# define SSL_AD_NO_RENEGOTIATION TLS1_AD_NO_RENEGOTIATION +# define SSL_AD_UNSUPPORTED_EXTENSION TLS1_AD_UNSUPPORTED_EXTENSION +# define SSL_AD_CERTIFICATE_UNOBTAINABLE TLS1_AD_CERTIFICATE_UNOBTAINABLE +# define SSL_AD_UNRECOGNIZED_NAME TLS1_AD_UNRECOGNIZED_NAME +# define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE +# define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE +/* fatal */ +# define SSL_AD_UNKNOWN_PSK_IDENTITY TLS1_AD_UNKNOWN_PSK_IDENTITY +/* fatal */ +# define SSL_AD_INAPPROPRIATE_FALLBACK TLS1_AD_INAPPROPRIATE_FALLBACK +# define SSL_ERROR_NONE 0 +# define SSL_ERROR_SSL 1 +# define SSL_ERROR_WANT_READ 2 +# define SSL_ERROR_WANT_WRITE 3 +# define SSL_ERROR_WANT_X509_LOOKUP 4 +# define SSL_ERROR_SYSCALL 5/* look at error stack/return + * value/errno */ +# define SSL_ERROR_ZERO_RETURN 6 +# define SSL_ERROR_WANT_CONNECT 7 +# define SSL_ERROR_WANT_ACCEPT 8 +# define SSL_CTRL_NEED_TMP_RSA 1 +# define SSL_CTRL_SET_TMP_RSA 2 +# define SSL_CTRL_SET_TMP_DH 3 +# define SSL_CTRL_SET_TMP_ECDH 4 +# define SSL_CTRL_SET_TMP_RSA_CB 5 +# define SSL_CTRL_SET_TMP_DH_CB 6 +# define SSL_CTRL_SET_TMP_ECDH_CB 7 +# define SSL_CTRL_GET_SESSION_REUSED 8 +# define SSL_CTRL_GET_CLIENT_CERT_REQUEST 9 +# define SSL_CTRL_GET_NUM_RENEGOTIATIONS 10 +# define SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS 11 +# define SSL_CTRL_GET_TOTAL_RENEGOTIATIONS 12 +# define SSL_CTRL_GET_FLAGS 13 +# define SSL_CTRL_EXTRA_CHAIN_CERT 14 +# define SSL_CTRL_SET_MSG_CALLBACK 15 +# define SSL_CTRL_SET_MSG_CALLBACK_ARG 16 +/* only applies to datagram connections */ +# define SSL_CTRL_SET_MTU 17 +/* Stats */ +# define SSL_CTRL_SESS_NUMBER 20 +# define SSL_CTRL_SESS_CONNECT 21 +# define SSL_CTRL_SESS_CONNECT_GOOD 22 +# define SSL_CTRL_SESS_CONNECT_RENEGOTIATE 23 +# define SSL_CTRL_SESS_ACCEPT 24 +# define SSL_CTRL_SESS_ACCEPT_GOOD 25 +# define SSL_CTRL_SESS_ACCEPT_RENEGOTIATE 26 +# define SSL_CTRL_SESS_HIT 27 +# define SSL_CTRL_SESS_CB_HIT 28 +# define SSL_CTRL_SESS_MISSES 29 +# define SSL_CTRL_SESS_TIMEOUTS 30 +# define SSL_CTRL_SESS_CACHE_FULL 31 +# define SSL_CTRL_OPTIONS 32 +# define SSL_CTRL_MODE 33 +# define SSL_CTRL_GET_READ_AHEAD 40 +# define SSL_CTRL_SET_READ_AHEAD 41 +# define SSL_CTRL_SET_SESS_CACHE_SIZE 42 +# define SSL_CTRL_GET_SESS_CACHE_SIZE 43 +# define SSL_CTRL_SET_SESS_CACHE_MODE 44 +# define SSL_CTRL_GET_SESS_CACHE_MODE 45 +# define SSL_CTRL_GET_MAX_CERT_LIST 50 +# define SSL_CTRL_SET_MAX_CERT_LIST 51 +# define SSL_CTRL_SET_MAX_SEND_FRAGMENT 52 +/* see tls1.h for macros based on these */ +# ifndef OPENSSL_NO_TLSEXT +# define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB 53 +# define SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG 54 +# define SSL_CTRL_SET_TLSEXT_HOSTNAME 55 +# define SSL_CTRL_SET_TLSEXT_DEBUG_CB 56 +# define SSL_CTRL_SET_TLSEXT_DEBUG_ARG 57 +# define SSL_CTRL_GET_TLSEXT_TICKET_KEYS 58 +# define SSL_CTRL_SET_TLSEXT_TICKET_KEYS 59 +# define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT 60 +# define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB 61 +# define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG 62 +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB 63 +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG 64 +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE 65 +# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS 66 +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS 67 +# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS 68 +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS 69 +# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP 70 +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP 71 +# define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB 72 +# define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB 75 +# define SSL_CTRL_SET_SRP_VERIFY_PARAM_CB 76 +# define SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB 77 +# define SSL_CTRL_SET_SRP_ARG 78 +# define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME 79 +# define SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH 80 +# define SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD 81 +# ifndef OPENSSL_NO_HEARTBEATS +# define SSL_CTRL_TLS_EXT_SEND_HEARTBEAT 85 +# define SSL_CTRL_GET_TLS_EXT_HEARTBEAT_PENDING 86 +# define SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS 87 +# endif +# endif /* OPENSSL_NO_TLSEXT */ +# define DTLS_CTRL_GET_TIMEOUT 73 +# define DTLS_CTRL_HANDLE_TIMEOUT 74 +# define DTLS_CTRL_LISTEN 75 +# define SSL_CTRL_GET_RI_SUPPORT 76 +# define SSL_CTRL_CLEAR_OPTIONS 77 +# define SSL_CTRL_CLEAR_MODE 78 +# define SSL_CTRL_GET_EXTRA_CHAIN_CERTS 82 +# define SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS 83 +# define SSL_CTRL_CHAIN 88 +# define SSL_CTRL_CHAIN_CERT 89 +# define SSL_CTRL_GET_CURVES 90 +# define SSL_CTRL_SET_CURVES 91 +# define SSL_CTRL_SET_CURVES_LIST 92 +# define SSL_CTRL_GET_SHARED_CURVE 93 +# define SSL_CTRL_SET_ECDH_AUTO 94 +# define SSL_CTRL_SET_SIGALGS 97 +# define SSL_CTRL_SET_SIGALGS_LIST 98 +# define SSL_CTRL_CERT_FLAGS 99 +# define SSL_CTRL_CLEAR_CERT_FLAGS 100 +# define SSL_CTRL_SET_CLIENT_SIGALGS 101 +# define SSL_CTRL_SET_CLIENT_SIGALGS_LIST 102 +# define SSL_CTRL_GET_CLIENT_CERT_TYPES 103 +# define SSL_CTRL_SET_CLIENT_CERT_TYPES 104 +# define SSL_CTRL_BUILD_CERT_CHAIN 105 +# define SSL_CTRL_SET_VERIFY_CERT_STORE 106 +# define SSL_CTRL_SET_CHAIN_CERT_STORE 107 +# define SSL_CTRL_GET_PEER_SIGNATURE_NID 108 +# define SSL_CTRL_GET_SERVER_TMP_KEY 109 +# define SSL_CTRL_GET_RAW_CIPHERLIST 110 +# define SSL_CTRL_GET_EC_POINT_FORMATS 111 +# define SSL_CTRL_GET_CHAIN_CERTS 115 +# define SSL_CTRL_SELECT_CURRENT_CERT 116 +# define SSL_CTRL_SET_CURRENT_CERT 117 +# define SSL_CTRL_CHECK_PROTO_VERSION 119 +# define DTLS_CTRL_SET_LINK_MTU 120 +# define DTLS_CTRL_GET_LINK_MIN_MTU 121 +# define SSL_CERT_SET_FIRST 1 +# define SSL_CERT_SET_NEXT 2 +# define SSL_CERT_SET_SERVER 3 +# define DTLSv1_get_timeout(ssl, arg) \ + SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)arg) +# define DTLSv1_handle_timeout(ssl) \ + SSL_ctrl(ssl,DTLS_CTRL_HANDLE_TIMEOUT,0, NULL) +# define DTLSv1_listen(ssl, peer) \ + SSL_ctrl(ssl,DTLS_CTRL_LISTEN,0, (void *)peer) +# define SSL_session_reused(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_GET_SESSION_REUSED,0,NULL) +# define SSL_num_renegotiations(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_GET_NUM_RENEGOTIATIONS,0,NULL) +# define SSL_clear_num_renegotiations(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS,0,NULL) +# define SSL_total_renegotiations(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_GET_TOTAL_RENEGOTIATIONS,0,NULL) +# define SSL_CTX_need_tmp_RSA(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_NEED_TMP_RSA,0,NULL) +# define SSL_CTX_set_tmp_rsa(ctx,rsa) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_RSA,0,(char *)rsa) +# define SSL_CTX_set_tmp_dh(ctx,dh) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_DH,0,(char *)dh) +# define SSL_CTX_set_tmp_ecdh(ctx,ecdh) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh) +# define SSL_need_tmp_RSA(ssl) \ + SSL_ctrl(ssl,SSL_CTRL_NEED_TMP_RSA,0,NULL) +# define SSL_set_tmp_rsa(ssl,rsa) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TMP_RSA,0,(char *)rsa) +# define SSL_set_tmp_dh(ssl,dh) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TMP_DH,0,(char *)dh) +# define SSL_set_tmp_ecdh(ssl,ecdh) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh) +# define SSL_CTX_add_extra_chain_cert(ctx,x509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_EXTRA_CHAIN_CERT,0,(char *)x509) +# define SSL_CTX_get_extra_chain_certs(ctx,px509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_EXTRA_CHAIN_CERTS,0,px509) +# define SSL_CTX_get_extra_chain_certs_only(ctx,px509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_EXTRA_CHAIN_CERTS,1,px509) +# define SSL_CTX_clear_extra_chain_certs(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS,0,NULL) +# define SSL_CTX_set0_chain(ctx,sk) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN,0,(char *)sk) +# define SSL_CTX_set1_chain(ctx,sk) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN,1,(char *)sk) +# define SSL_CTX_add0_chain_cert(ctx,x509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN_CERT,0,(char *)x509) +# define SSL_CTX_add1_chain_cert(ctx,x509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN_CERT,1,(char *)x509) +# define SSL_CTX_get0_chain_certs(ctx,px509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_CHAIN_CERTS,0,px509) +# define SSL_CTX_clear_chain_certs(ctx) \ + SSL_CTX_set0_chain(ctx,NULL) +# define SSL_CTX_build_cert_chain(ctx, flags) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_BUILD_CERT_CHAIN, flags, NULL) +# define SSL_CTX_select_current_cert(ctx,x509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SELECT_CURRENT_CERT,0,(char *)x509) +# define SSL_CTX_set_current_cert(ctx, op) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CURRENT_CERT, op, NULL) +# define SSL_CTX_set0_verify_cert_store(ctx,st) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_VERIFY_CERT_STORE,0,(char *)st) +# define SSL_CTX_set1_verify_cert_store(ctx,st) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_VERIFY_CERT_STORE,1,(char *)st) +# define SSL_CTX_set0_chain_cert_store(ctx,st) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CHAIN_CERT_STORE,0,(char *)st) +# define SSL_CTX_set1_chain_cert_store(ctx,st) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CHAIN_CERT_STORE,1,(char *)st) +# define SSL_set0_chain(ctx,sk) \ + SSL_ctrl(ctx,SSL_CTRL_CHAIN,0,(char *)sk) +# define SSL_set1_chain(ctx,sk) \ + SSL_ctrl(ctx,SSL_CTRL_CHAIN,1,(char *)sk) +# define SSL_add0_chain_cert(ctx,x509) \ + SSL_ctrl(ctx,SSL_CTRL_CHAIN_CERT,0,(char *)x509) +# define SSL_add1_chain_cert(ctx,x509) \ + SSL_ctrl(ctx,SSL_CTRL_CHAIN_CERT,1,(char *)x509) +# define SSL_get0_chain_certs(ctx,px509) \ + SSL_ctrl(ctx,SSL_CTRL_GET_CHAIN_CERTS,0,px509) +# define SSL_clear_chain_certs(ctx) \ + SSL_set0_chain(ctx,NULL) +# define SSL_build_cert_chain(s, flags) \ + SSL_ctrl(s,SSL_CTRL_BUILD_CERT_CHAIN, flags, NULL) +# define SSL_select_current_cert(ctx,x509) \ + SSL_ctrl(ctx,SSL_CTRL_SELECT_CURRENT_CERT,0,(char *)x509) +# define SSL_set_current_cert(ctx,op) \ + SSL_ctrl(ctx,SSL_CTRL_SET_CURRENT_CERT, op, NULL) +# define SSL_set0_verify_cert_store(s,st) \ + SSL_ctrl(s,SSL_CTRL_SET_VERIFY_CERT_STORE,0,(char *)st) +# define SSL_set1_verify_cert_store(s,st) \ + SSL_ctrl(s,SSL_CTRL_SET_VERIFY_CERT_STORE,1,(char *)st) +# define SSL_set0_chain_cert_store(s,st) \ + SSL_ctrl(s,SSL_CTRL_SET_CHAIN_CERT_STORE,0,(char *)st) +# define SSL_set1_chain_cert_store(s,st) \ + SSL_ctrl(s,SSL_CTRL_SET_CHAIN_CERT_STORE,1,(char *)st) +# define SSL_get1_curves(ctx, s) \ + SSL_ctrl(ctx,SSL_CTRL_GET_CURVES,0,(char *)s) +# define SSL_CTX_set1_curves(ctx, clist, clistlen) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CURVES,clistlen,(char *)clist) +# define SSL_CTX_set1_curves_list(ctx, s) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CURVES_LIST,0,(char *)s) +# define SSL_set1_curves(ctx, clist, clistlen) \ + SSL_ctrl(ctx,SSL_CTRL_SET_CURVES,clistlen,(char *)clist) +# define SSL_set1_curves_list(ctx, s) \ + SSL_ctrl(ctx,SSL_CTRL_SET_CURVES_LIST,0,(char *)s) +# define SSL_get_shared_curve(s, n) \ + SSL_ctrl(s,SSL_CTRL_GET_SHARED_CURVE,n,NULL) +# define SSL_CTX_set_ecdh_auto(ctx, onoff) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_ECDH_AUTO,onoff,NULL) +# define SSL_set_ecdh_auto(s, onoff) \ + SSL_ctrl(s,SSL_CTRL_SET_ECDH_AUTO,onoff,NULL) +# define SSL_CTX_set1_sigalgs(ctx, slist, slistlen) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SIGALGS,slistlen,(int *)slist) +# define SSL_CTX_set1_sigalgs_list(ctx, s) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SIGALGS_LIST,0,(char *)s) +# define SSL_set1_sigalgs(ctx, slist, slistlen) \ + SSL_ctrl(ctx,SSL_CTRL_SET_SIGALGS,slistlen,(int *)slist) +# define SSL_set1_sigalgs_list(ctx, s) \ + SSL_ctrl(ctx,SSL_CTRL_SET_SIGALGS_LIST,0,(char *)s) +# define SSL_CTX_set1_client_sigalgs(ctx, slist, slistlen) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS,slistlen,(int *)slist) +# define SSL_CTX_set1_client_sigalgs_list(ctx, s) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS_LIST,0,(char *)s) +# define SSL_set1_client_sigalgs(ctx, slist, slistlen) \ + SSL_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS,clistlen,(int *)slist) +# define SSL_set1_client_sigalgs_list(ctx, s) \ + SSL_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS_LIST,0,(char *)s) +# define SSL_get0_certificate_types(s, clist) \ + SSL_ctrl(s, SSL_CTRL_GET_CLIENT_CERT_TYPES, 0, (char *)clist) +# define SSL_CTX_set1_client_certificate_types(ctx, clist, clistlen) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CLIENT_CERT_TYPES,clistlen,(char *)clist) +# define SSL_set1_client_certificate_types(s, clist, clistlen) \ + SSL_ctrl(s,SSL_CTRL_SET_CLIENT_CERT_TYPES,clistlen,(char *)clist) +# define SSL_get_peer_signature_nid(s, pn) \ + SSL_ctrl(s,SSL_CTRL_GET_PEER_SIGNATURE_NID,0,pn) +# define SSL_get_server_tmp_key(s, pk) \ + SSL_ctrl(s,SSL_CTRL_GET_SERVER_TMP_KEY,0,pk) +# define SSL_get0_raw_cipherlist(s, plst) \ + SSL_ctrl(s,SSL_CTRL_GET_RAW_CIPHERLIST,0,(char *)plst) +# define SSL_get0_ec_point_formats(s, plst) \ + SSL_ctrl(s,SSL_CTRL_GET_EC_POINT_FORMATS,0,(char *)plst) +# ifndef OPENSSL_NO_BIO +BIO_METHOD *BIO_f_ssl(void); +BIO *BIO_new_ssl(SSL_CTX *ctx, int client); +BIO *BIO_new_ssl_connect(SSL_CTX *ctx); +BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx); +int BIO_ssl_copy_session_id(BIO *to, BIO *from); +void BIO_ssl_shutdown(BIO *ssl_bio); + +# endif + +int SSL_CTX_set_cipher_list(SSL_CTX *, const char *str); +SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth); +void SSL_CTX_free(SSL_CTX *); +long SSL_CTX_set_timeout(SSL_CTX *ctx, long t); +long SSL_CTX_get_timeout(const SSL_CTX *ctx); +X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *); +void SSL_CTX_set_cert_store(SSL_CTX *, X509_STORE *); +int SSL_want(const SSL *s); +int SSL_clear(SSL *s); + +void SSL_CTX_flush_sessions(SSL_CTX *ctx, long tm); + +const SSL_CIPHER *SSL_get_current_cipher(const SSL *s); +int SSL_CIPHER_get_bits(const SSL_CIPHER *c, int *alg_bits); +char *SSL_CIPHER_get_version(const SSL_CIPHER *c); +const char *SSL_CIPHER_get_name(const SSL_CIPHER *c); +unsigned long SSL_CIPHER_get_id(const SSL_CIPHER *c); + +int SSL_get_fd(const SSL *s); +int SSL_get_rfd(const SSL *s); +int SSL_get_wfd(const SSL *s); +const char *SSL_get_cipher_list(const SSL *s, int n); +char *SSL_get_shared_ciphers(const SSL *s, char *buf, int len); +int SSL_get_read_ahead(const SSL *s); +int SSL_pending(const SSL *s); +# ifndef OPENSSL_NO_SOCK +int SSL_set_fd(SSL *s, int fd); +int SSL_set_rfd(SSL *s, int fd); +int SSL_set_wfd(SSL *s, int fd); +# endif +# ifndef OPENSSL_NO_BIO +void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio); +BIO *SSL_get_rbio(const SSL *s); +BIO *SSL_get_wbio(const SSL *s); +# endif +int SSL_set_cipher_list(SSL *s, const char *str); +void SSL_set_read_ahead(SSL *s, int yes); +int SSL_get_verify_mode(const SSL *s); +int SSL_get_verify_depth(const SSL *s); +int (*SSL_get_verify_callback(const SSL *s)) (int, X509_STORE_CTX *); +void SSL_set_verify(SSL *s, int mode, + int (*callback) (int ok, X509_STORE_CTX *ctx)); +void SSL_set_verify_depth(SSL *s, int depth); +void SSL_set_cert_cb(SSL *s, int (*cb) (SSL *ssl, void *arg), void *arg); +# ifndef OPENSSL_NO_RSA +int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa); +# endif +int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, unsigned char *d, long len); +int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey); +int SSL_use_PrivateKey_ASN1(int pk, SSL *ssl, const unsigned char *d, + long len); +int SSL_use_certificate(SSL *ssl, X509 *x); +int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len); + +# ifndef OPENSSL_NO_TLSEXT +/* Set serverinfo data for the current active cert. */ +int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo, + size_t serverinfo_length); +# ifndef OPENSSL_NO_STDIO +int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file); +# endif /* NO_STDIO */ + +# endif + +# ifndef OPENSSL_NO_STDIO +int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type); +int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type); +int SSL_use_certificate_file(SSL *ssl, const char *file, int type); +int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type); +int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type); +int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type); +/* PEM type */ +int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file); +STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file); +int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs, + const char *file); +# ifndef OPENSSL_SYS_VMS +/* XXXXX: Better scheme needed! [was: #ifndef MAC_OS_pre_X] */ +# ifndef OPENSSL_SYS_MACINTOSH_CLASSIC +int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs, + const char *dir); +# endif +# endif + +# endif + +void SSL_load_error_strings(void); +const char *SSL_state_string(const SSL *s); +const char *SSL_rstate_string(const SSL *s); +const char *SSL_state_string_long(const SSL *s); +const char *SSL_rstate_string_long(const SSL *s); +long SSL_SESSION_get_time(const SSL_SESSION *s); +long SSL_SESSION_set_time(SSL_SESSION *s, long t); +long SSL_SESSION_get_timeout(const SSL_SESSION *s); +long SSL_SESSION_set_timeout(SSL_SESSION *s, long t); +void SSL_copy_session_id(SSL *to, const SSL *from); +X509 *SSL_SESSION_get0_peer(SSL_SESSION *s); +int SSL_SESSION_set1_id_context(SSL_SESSION *s, const unsigned char *sid_ctx, + unsigned int sid_ctx_len); + +SSL_SESSION *SSL_SESSION_new(void); +const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, + unsigned int *len); +unsigned int SSL_SESSION_get_compress_id(const SSL_SESSION *s); +# ifndef OPENSSL_NO_FP_API +int SSL_SESSION_print_fp(FILE *fp, const SSL_SESSION *ses); +# endif +# ifndef OPENSSL_NO_BIO +int SSL_SESSION_print(BIO *fp, const SSL_SESSION *ses); +# endif +void SSL_SESSION_free(SSL_SESSION *ses); +int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp); +int SSL_set_session(SSL *to, SSL_SESSION *session); +int SSL_CTX_add_session(SSL_CTX *s, SSL_SESSION *c); +int SSL_CTX_remove_session(SSL_CTX *, SSL_SESSION *c); +int SSL_CTX_set_generate_session_id(SSL_CTX *, GEN_SESSION_CB); +int SSL_set_generate_session_id(SSL *, GEN_SESSION_CB); +int SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id, + unsigned int id_len); +SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, + long length); + +# ifdef HEADER_X509_H +X509 *SSL_get_peer_certificate(const SSL *s); +# endif + +STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s); + +int SSL_CTX_get_verify_mode(const SSL_CTX *ctx); +int SSL_CTX_get_verify_depth(const SSL_CTX *ctx); +int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx)) (int, + X509_STORE_CTX *); +void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, + int (*callback) (int, X509_STORE_CTX *)); +void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth); +void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, + int (*cb) (X509_STORE_CTX *, void *), + void *arg); +void SSL_CTX_set_cert_cb(SSL_CTX *c, int (*cb) (SSL *ssl, void *arg), + void *arg); +# ifndef OPENSSL_NO_RSA +int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa); +# endif +int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, + long len); +int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey); +int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, + const unsigned char *d, long len); +int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x); +int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, + const unsigned char *d); + +void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb); +void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u); + +int SSL_CTX_check_private_key(const SSL_CTX *ctx); +int SSL_check_private_key(const SSL *ctx); + +int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const unsigned char *sid_ctx, + unsigned int sid_ctx_len); + +SSL *SSL_new(SSL_CTX *ctx); +int SSL_set_session_id_context(SSL *ssl, const unsigned char *sid_ctx, + unsigned int sid_ctx_len); + +int SSL_CTX_set_purpose(SSL_CTX *s, int purpose); +int SSL_set_purpose(SSL *s, int purpose); +int SSL_CTX_set_trust(SSL_CTX *s, int trust); +int SSL_set_trust(SSL *s, int trust); + +int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm); +int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm); + +X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx); +X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl); + +# ifndef OPENSSL_NO_SRP +int SSL_CTX_set_srp_username(SSL_CTX *ctx, char *name); +int SSL_CTX_set_srp_password(SSL_CTX *ctx, char *password); +int SSL_CTX_set_srp_strength(SSL_CTX *ctx, int strength); +int SSL_CTX_set_srp_client_pwd_callback(SSL_CTX *ctx, + char *(*cb) (SSL *, void *)); +int SSL_CTX_set_srp_verify_param_callback(SSL_CTX *ctx, + int (*cb) (SSL *, void *)); +int SSL_CTX_set_srp_username_callback(SSL_CTX *ctx, + int (*cb) (SSL *, int *, void *)); +int SSL_CTX_set_srp_cb_arg(SSL_CTX *ctx, void *arg); + +int SSL_set_srp_server_param(SSL *s, const BIGNUM *N, const BIGNUM *g, + BIGNUM *sa, BIGNUM *v, char *info); +int SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass, + const char *grp); + +BIGNUM *SSL_get_srp_g(SSL *s); +BIGNUM *SSL_get_srp_N(SSL *s); + +char *SSL_get_srp_username(SSL *s); +char *SSL_get_srp_userinfo(SSL *s); +# endif + +void SSL_certs_clear(SSL *s); +void SSL_free(SSL *ssl); +int SSL_accept(SSL *ssl); +int SSL_connect(SSL *ssl); +int SSL_read(SSL *ssl, void *buf, int num); +int SSL_peek(SSL *ssl, void *buf, int num); +int SSL_write(SSL *ssl, const void *buf, int num); +long SSL_ctrl(SSL *ssl, int cmd, long larg, void *parg); +long SSL_callback_ctrl(SSL *, int, void (*)(void)); +long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg); +long SSL_CTX_callback_ctrl(SSL_CTX *, int, void (*)(void)); + +int SSL_get_error(const SSL *s, int ret_code); +const char *SSL_get_version(const SSL *s); + +/* This sets the 'default' SSL version that SSL_new() will create */ +int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth); + +# ifndef OPENSSL_NO_SSL2_METHOD +const SSL_METHOD *SSLv2_method(void); /* SSLv2 */ +const SSL_METHOD *SSLv2_server_method(void); /* SSLv2 */ +const SSL_METHOD *SSLv2_client_method(void); /* SSLv2 */ +# endif + +# ifndef OPENSSL_NO_SSL3_METHOD +const SSL_METHOD *SSLv3_method(void); /* SSLv3 */ +const SSL_METHOD *SSLv3_server_method(void); /* SSLv3 */ +const SSL_METHOD *SSLv3_client_method(void); /* SSLv3 */ +# endif + +const SSL_METHOD *SSLv23_method(void); /* Negotiate highest available SSL/TLS + * version */ +const SSL_METHOD *SSLv23_server_method(void); /* Negotiate highest available + * SSL/TLS version */ +const SSL_METHOD *SSLv23_client_method(void); /* Negotiate highest available + * SSL/TLS version */ + +const SSL_METHOD *TLSv1_method(void); /* TLSv1.0 */ +const SSL_METHOD *TLSv1_server_method(void); /* TLSv1.0 */ +const SSL_METHOD *TLSv1_client_method(void); /* TLSv1.0 */ + +const SSL_METHOD *TLSv1_1_method(void); /* TLSv1.1 */ +const SSL_METHOD *TLSv1_1_server_method(void); /* TLSv1.1 */ +const SSL_METHOD *TLSv1_1_client_method(void); /* TLSv1.1 */ + +const SSL_METHOD *TLSv1_2_method(void); /* TLSv1.2 */ +const SSL_METHOD *TLSv1_2_server_method(void); /* TLSv1.2 */ +const SSL_METHOD *TLSv1_2_client_method(void); /* TLSv1.2 */ + +const SSL_METHOD *DTLSv1_method(void); /* DTLSv1.0 */ +const SSL_METHOD *DTLSv1_server_method(void); /* DTLSv1.0 */ +const SSL_METHOD *DTLSv1_client_method(void); /* DTLSv1.0 */ + +const SSL_METHOD *DTLSv1_2_method(void); /* DTLSv1.2 */ +const SSL_METHOD *DTLSv1_2_server_method(void); /* DTLSv1.2 */ +const SSL_METHOD *DTLSv1_2_client_method(void); /* DTLSv1.2 */ + +const SSL_METHOD *DTLS_method(void); /* DTLS 1.0 and 1.2 */ +const SSL_METHOD *DTLS_server_method(void); /* DTLS 1.0 and 1.2 */ +const SSL_METHOD *DTLS_client_method(void); /* DTLS 1.0 and 1.2 */ + +STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s); + +int SSL_do_handshake(SSL *s); +int SSL_renegotiate(SSL *s); +int SSL_renegotiate_abbreviated(SSL *s); +int SSL_renegotiate_pending(SSL *s); +int SSL_shutdown(SSL *s); + +const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx); +const SSL_METHOD *SSL_get_ssl_method(SSL *s); +int SSL_set_ssl_method(SSL *s, const SSL_METHOD *method); +const char *SSL_alert_type_string_long(int value); +const char *SSL_alert_type_string(int value); +const char *SSL_alert_desc_string_long(int value); +const char *SSL_alert_desc_string(int value); + +void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list); +void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list); +STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s); +STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *s); +int SSL_add_client_CA(SSL *ssl, X509 *x); +int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x); + +void SSL_set_connect_state(SSL *s); +void SSL_set_accept_state(SSL *s); + +long SSL_get_default_timeout(const SSL *s); + +int SSL_library_init(void); + +char *SSL_CIPHER_description(const SSL_CIPHER *, char *buf, int size); +STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk); + +SSL *SSL_dup(SSL *ssl); + +X509 *SSL_get_certificate(const SSL *ssl); +/* + * EVP_PKEY + */ struct evp_pkey_st *SSL_get_privatekey(const SSL *ssl); + +X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx); +EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx); + +void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode); +int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx); +void SSL_set_quiet_shutdown(SSL *ssl, int mode); +int SSL_get_quiet_shutdown(const SSL *ssl); +void SSL_set_shutdown(SSL *ssl, int mode); +int SSL_get_shutdown(const SSL *ssl); +int SSL_version(const SSL *ssl); +int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx); +int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, + const char *CApath); +# define SSL_get0_session SSL_get_session/* just peek at pointer */ +SSL_SESSION *SSL_get_session(const SSL *ssl); +SSL_SESSION *SSL_get1_session(SSL *ssl); /* obtain a reference count */ +SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl); +SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx); +void SSL_set_info_callback(SSL *ssl, + void (*cb) (const SSL *ssl, int type, int val)); +void (*SSL_get_info_callback(const SSL *ssl)) (const SSL *ssl, int type, + int val); +int SSL_state(const SSL *ssl); +void SSL_set_state(SSL *ssl, int state); + +void SSL_set_verify_result(SSL *ssl, long v); +long SSL_get_verify_result(const SSL *ssl); + +int SSL_set_ex_data(SSL *ssl, int idx, void *data); +void *SSL_get_ex_data(const SSL *ssl, int idx); +int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); + +int SSL_SESSION_set_ex_data(SSL_SESSION *ss, int idx, void *data); +void *SSL_SESSION_get_ex_data(const SSL_SESSION *ss, int idx); +int SSL_SESSION_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); + +int SSL_CTX_set_ex_data(SSL_CTX *ssl, int idx, void *data); +void *SSL_CTX_get_ex_data(const SSL_CTX *ssl, int idx); +int SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); + +int SSL_get_ex_data_X509_STORE_CTX_idx(void); + +# define SSL_CTX_sess_set_cache_size(ctx,t) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_SIZE,t,NULL) +# define SSL_CTX_sess_get_cache_size(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_SIZE,0,NULL) +# define SSL_CTX_set_session_cache_mode(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_MODE,m,NULL) +# define SSL_CTX_get_session_cache_mode(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_MODE,0,NULL) + +# define SSL_CTX_get_default_read_ahead(ctx) SSL_CTX_get_read_ahead(ctx) +# define SSL_CTX_set_default_read_ahead(ctx,m) SSL_CTX_set_read_ahead(ctx,m) +# define SSL_CTX_get_read_ahead(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_READ_AHEAD,0,NULL) +# define SSL_CTX_set_read_ahead(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_READ_AHEAD,m,NULL) +# define SSL_CTX_get_max_cert_list(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL) +# define SSL_CTX_set_max_cert_list(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL) +# define SSL_get_max_cert_list(ssl) \ + SSL_ctrl(ssl,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL) +# define SSL_set_max_cert_list(ssl,m) \ + SSL_ctrl(ssl,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL) + +# define SSL_CTX_set_max_send_fragment(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL) +# define SSL_set_max_send_fragment(ssl,m) \ + SSL_ctrl(ssl,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL) + + /* NB: the keylength is only applicable when is_export is true */ +# ifndef OPENSSL_NO_RSA +void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx, + RSA *(*cb) (SSL *ssl, int is_export, + int keylength)); + +void SSL_set_tmp_rsa_callback(SSL *ssl, + RSA *(*cb) (SSL *ssl, int is_export, + int keylength)); +# endif +# ifndef OPENSSL_NO_DH +void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx, + DH *(*dh) (SSL *ssl, int is_export, + int keylength)); +void SSL_set_tmp_dh_callback(SSL *ssl, + DH *(*dh) (SSL *ssl, int is_export, + int keylength)); +# endif +# ifndef OPENSSL_NO_ECDH +void SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx, + EC_KEY *(*ecdh) (SSL *ssl, int is_export, + int keylength)); +void SSL_set_tmp_ecdh_callback(SSL *ssl, + EC_KEY *(*ecdh) (SSL *ssl, int is_export, + int keylength)); +# endif + +# ifndef OPENSSL_NO_COMP +const COMP_METHOD *SSL_get_current_compression(SSL *s); +const COMP_METHOD *SSL_get_current_expansion(SSL *s); +const char *SSL_COMP_get_name(const COMP_METHOD *comp); +STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void); +STACK_OF(SSL_COMP) *SSL_COMP_set0_compression_methods(STACK_OF(SSL_COMP) + *meths); +void SSL_COMP_free_compression_methods(void); +int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm); +# else +const void *SSL_get_current_compression(SSL *s); +const void *SSL_get_current_expansion(SSL *s); +const char *SSL_COMP_get_name(const void *comp); +void *SSL_COMP_get_compression_methods(void); +int SSL_COMP_add_compression_method(int id, void *cm); +# endif + +const SSL_CIPHER *SSL_CIPHER_find(SSL *ssl, const unsigned char *ptr); + +/* TLS extensions functions */ +int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len); + +int SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb, + void *arg); + +/* Pre-shared secret session resumption functions */ +int SSL_set_session_secret_cb(SSL *s, + tls_session_secret_cb_fn tls_session_secret_cb, + void *arg); + +void SSL_set_debug(SSL *s, int debug); +int SSL_cache_hit(SSL *s); +int SSL_is_server(SSL *s); + +SSL_CONF_CTX *SSL_CONF_CTX_new(void); +int SSL_CONF_CTX_finish(SSL_CONF_CTX *cctx); +void SSL_CONF_CTX_free(SSL_CONF_CTX *cctx); +unsigned int SSL_CONF_CTX_set_flags(SSL_CONF_CTX *cctx, unsigned int flags); +unsigned int SSL_CONF_CTX_clear_flags(SSL_CONF_CTX *cctx, unsigned int flags); +int SSL_CONF_CTX_set1_prefix(SSL_CONF_CTX *cctx, const char *pre); + +void SSL_CONF_CTX_set_ssl(SSL_CONF_CTX *cctx, SSL *ssl); +void SSL_CONF_CTX_set_ssl_ctx(SSL_CONF_CTX *cctx, SSL_CTX *ctx); + +int SSL_CONF_cmd(SSL_CONF_CTX *cctx, const char *cmd, const char *value); +int SSL_CONF_cmd_argv(SSL_CONF_CTX *cctx, int *pargc, char ***pargv); +int SSL_CONF_cmd_value_type(SSL_CONF_CTX *cctx, const char *cmd); + +# ifndef OPENSSL_NO_SSL_TRACE +void SSL_trace(int write_p, int version, int content_type, + const void *buf, size_t len, SSL *ssl, void *arg); +const char *SSL_CIPHER_standard_name(const SSL_CIPHER *c); +# endif + +# ifndef OPENSSL_NO_UNIT_TEST +const struct openssl_ssl_test_functions *SSL_test_functions(void); +# endif + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_SSL_strings(void); + +/* Error codes for the SSL functions. */ + +/* Function codes. */ +# define SSL_F_CHECK_SUITEB_CIPHER_LIST 331 +# define SSL_F_CLIENT_CERTIFICATE 100 +# define SSL_F_CLIENT_FINISHED 167 +# define SSL_F_CLIENT_HELLO 101 +# define SSL_F_CLIENT_MASTER_KEY 102 +# define SSL_F_D2I_SSL_SESSION 103 +# define SSL_F_DO_DTLS1_WRITE 245 +# define SSL_F_DO_SSL3_WRITE 104 +# define SSL_F_DTLS1_ACCEPT 246 +# define SSL_F_DTLS1_ADD_CERT_TO_BUF 295 +# define SSL_F_DTLS1_BUFFER_RECORD 247 +# define SSL_F_DTLS1_CHECK_TIMEOUT_NUM 316 +# define SSL_F_DTLS1_CLIENT_HELLO 248 +# define SSL_F_DTLS1_CONNECT 249 +# define SSL_F_DTLS1_ENC 250 +# define SSL_F_DTLS1_GET_HELLO_VERIFY 251 +# define SSL_F_DTLS1_GET_MESSAGE 252 +# define SSL_F_DTLS1_GET_MESSAGE_FRAGMENT 253 +# define SSL_F_DTLS1_GET_RECORD 254 +# define SSL_F_DTLS1_HANDLE_TIMEOUT 297 +# define SSL_F_DTLS1_HEARTBEAT 305 +# define SSL_F_DTLS1_OUTPUT_CERT_CHAIN 255 +# define SSL_F_DTLS1_PREPROCESS_FRAGMENT 288 +# define SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE 256 +# define SSL_F_DTLS1_PROCESS_RECORD 257 +# define SSL_F_DTLS1_READ_BYTES 258 +# define SSL_F_DTLS1_READ_FAILED 259 +# define SSL_F_DTLS1_SEND_CERTIFICATE_REQUEST 260 +# define SSL_F_DTLS1_SEND_CLIENT_CERTIFICATE 261 +# define SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE 262 +# define SSL_F_DTLS1_SEND_CLIENT_VERIFY 263 +# define SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST 264 +# define SSL_F_DTLS1_SEND_SERVER_CERTIFICATE 265 +# define SSL_F_DTLS1_SEND_SERVER_HELLO 266 +# define SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE 267 +# define SSL_F_DTLS1_WRITE_APP_DATA_BYTES 268 +# define SSL_F_GET_CLIENT_FINISHED 105 +# define SSL_F_GET_CLIENT_HELLO 106 +# define SSL_F_GET_CLIENT_MASTER_KEY 107 +# define SSL_F_GET_SERVER_FINISHED 108 +# define SSL_F_GET_SERVER_HELLO 109 +# define SSL_F_GET_SERVER_STATIC_DH_KEY 340 +# define SSL_F_GET_SERVER_VERIFY 110 +# define SSL_F_I2D_SSL_SESSION 111 +# define SSL_F_READ_N 112 +# define SSL_F_REQUEST_CERTIFICATE 113 +# define SSL_F_SERVER_FINISH 239 +# define SSL_F_SERVER_HELLO 114 +# define SSL_F_SERVER_VERIFY 240 +# define SSL_F_SSL23_ACCEPT 115 +# define SSL_F_SSL23_CLIENT_HELLO 116 +# define SSL_F_SSL23_CONNECT 117 +# define SSL_F_SSL23_GET_CLIENT_HELLO 118 +# define SSL_F_SSL23_GET_SERVER_HELLO 119 +# define SSL_F_SSL23_PEEK 237 +# define SSL_F_SSL23_READ 120 +# define SSL_F_SSL23_WRITE 121 +# define SSL_F_SSL2_ACCEPT 122 +# define SSL_F_SSL2_CONNECT 123 +# define SSL_F_SSL2_ENC_INIT 124 +# define SSL_F_SSL2_GENERATE_KEY_MATERIAL 241 +# define SSL_F_SSL2_PEEK 234 +# define SSL_F_SSL2_READ 125 +# define SSL_F_SSL2_READ_INTERNAL 236 +# define SSL_F_SSL2_SET_CERTIFICATE 126 +# define SSL_F_SSL2_WRITE 127 +# define SSL_F_SSL3_ACCEPT 128 +# define SSL_F_SSL3_ADD_CERT_TO_BUF 296 +# define SSL_F_SSL3_CALLBACK_CTRL 233 +# define SSL_F_SSL3_CHANGE_CIPHER_STATE 129 +# define SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM 130 +# define SSL_F_SSL3_CHECK_CLIENT_HELLO 304 +# define SSL_F_SSL3_CHECK_FINISHED 339 +# define SSL_F_SSL3_CLIENT_HELLO 131 +# define SSL_F_SSL3_CONNECT 132 +# define SSL_F_SSL3_CTRL 213 +# define SSL_F_SSL3_CTX_CTRL 133 +# define SSL_F_SSL3_DIGEST_CACHED_RECORDS 293 +# define SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC 292 +# define SSL_F_SSL3_ENC 134 +# define SSL_F_SSL3_GENERATE_KEY_BLOCK 238 +# define SSL_F_SSL3_GENERATE_MASTER_SECRET 388 +# define SSL_F_SSL3_GET_CERTIFICATE_REQUEST 135 +# define SSL_F_SSL3_GET_CERT_STATUS 289 +# define SSL_F_SSL3_GET_CERT_VERIFY 136 +# define SSL_F_SSL3_GET_CLIENT_CERTIFICATE 137 +# define SSL_F_SSL3_GET_CLIENT_HELLO 138 +# define SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE 139 +# define SSL_F_SSL3_GET_FINISHED 140 +# define SSL_F_SSL3_GET_KEY_EXCHANGE 141 +# define SSL_F_SSL3_GET_MESSAGE 142 +# define SSL_F_SSL3_GET_NEW_SESSION_TICKET 283 +# define SSL_F_SSL3_GET_NEXT_PROTO 306 +# define SSL_F_SSL3_GET_RECORD 143 +# define SSL_F_SSL3_GET_SERVER_CERTIFICATE 144 +# define SSL_F_SSL3_GET_SERVER_DONE 145 +# define SSL_F_SSL3_GET_SERVER_HELLO 146 +# define SSL_F_SSL3_HANDSHAKE_MAC 285 +# define SSL_F_SSL3_NEW_SESSION_TICKET 287 +# define SSL_F_SSL3_OUTPUT_CERT_CHAIN 147 +# define SSL_F_SSL3_PEEK 235 +# define SSL_F_SSL3_READ_BYTES 148 +# define SSL_F_SSL3_READ_N 149 +# define SSL_F_SSL3_SEND_CERTIFICATE_REQUEST 150 +# define SSL_F_SSL3_SEND_CLIENT_CERTIFICATE 151 +# define SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE 152 +# define SSL_F_SSL3_SEND_CLIENT_VERIFY 153 +# define SSL_F_SSL3_SEND_SERVER_CERTIFICATE 154 +# define SSL_F_SSL3_SEND_SERVER_HELLO 242 +# define SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE 155 +# define SSL_F_SSL3_SETUP_KEY_BLOCK 157 +# define SSL_F_SSL3_SETUP_READ_BUFFER 156 +# define SSL_F_SSL3_SETUP_WRITE_BUFFER 291 +# define SSL_F_SSL3_WRITE_BYTES 158 +# define SSL_F_SSL3_WRITE_PENDING 159 +# define SSL_F_SSL_ADD_CERT_CHAIN 318 +# define SSL_F_SSL_ADD_CERT_TO_BUF 319 +# define SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT 298 +# define SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT 277 +# define SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT 307 +# define SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK 215 +# define SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK 216 +# define SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT 299 +# define SSL_F_SSL_ADD_SERVERHELLO_TLSEXT 278 +# define SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT 308 +# define SSL_F_SSL_BAD_METHOD 160 +# define SSL_F_SSL_BUILD_CERT_CHAIN 332 +# define SSL_F_SSL_BYTES_TO_CIPHER_LIST 161 +# define SSL_F_SSL_CERT_DUP 221 +# define SSL_F_SSL_CERT_INST 222 +# define SSL_F_SSL_CERT_INSTANTIATE 214 +# define SSL_F_SSL_CERT_NEW 162 +# define SSL_F_SSL_CHECK_PRIVATE_KEY 163 +# define SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT 280 +# define SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG 279 +# define SSL_F_SSL_CIPHER_PROCESS_RULESTR 230 +# define SSL_F_SSL_CIPHER_STRENGTH_SORT 231 +# define SSL_F_SSL_CLEAR 164 +# define SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD 165 +# define SSL_F_SSL_CONF_CMD 334 +# define SSL_F_SSL_CREATE_CIPHER_LIST 166 +# define SSL_F_SSL_CTRL 232 +# define SSL_F_SSL_CTX_CHECK_PRIVATE_KEY 168 +# define SSL_F_SSL_CTX_MAKE_PROFILES 309 +# define SSL_F_SSL_CTX_NEW 169 +# define SSL_F_SSL_CTX_SET_CIPHER_LIST 269 +# define SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE 290 +# define SSL_F_SSL_CTX_SET_PURPOSE 226 +# define SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT 219 +# define SSL_F_SSL_CTX_SET_SSL_VERSION 170 +# define SSL_F_SSL_CTX_SET_TRUST 229 +# define SSL_F_SSL_CTX_USE_CERTIFICATE 171 +# define SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1 172 +# define SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE 220 +# define SSL_F_SSL_CTX_USE_CERTIFICATE_FILE 173 +# define SSL_F_SSL_CTX_USE_PRIVATEKEY 174 +# define SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1 175 +# define SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE 176 +# define SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT 272 +# define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY 177 +# define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1 178 +# define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE 179 +# define SSL_F_SSL_CTX_USE_SERVERINFO 336 +# define SSL_F_SSL_CTX_USE_SERVERINFO_FILE 337 +# define SSL_F_SSL_DO_HANDSHAKE 180 +# define SSL_F_SSL_GET_NEW_SESSION 181 +# define SSL_F_SSL_GET_PREV_SESSION 217 +# define SSL_F_SSL_GET_SERVER_CERT_INDEX 322 +# define SSL_F_SSL_GET_SERVER_SEND_CERT 182 +# define SSL_F_SSL_GET_SERVER_SEND_PKEY 317 +# define SSL_F_SSL_GET_SIGN_PKEY 183 +# define SSL_F_SSL_INIT_WBIO_BUFFER 184 +# define SSL_F_SSL_LOAD_CLIENT_CA_FILE 185 +# define SSL_F_SSL_NEW 186 +# define SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT 300 +# define SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT 302 +# define SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT 310 +# define SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT 301 +# define SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT 303 +# define SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT 311 +# define SSL_F_SSL_PEEK 270 +# define SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT 281 +# define SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT 282 +# define SSL_F_SSL_READ 223 +# define SSL_F_SSL_RSA_PRIVATE_DECRYPT 187 +# define SSL_F_SSL_RSA_PUBLIC_ENCRYPT 188 +# define SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT 320 +# define SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT 321 +# define SSL_F_SSL_SESSION_DUP 348 +# define SSL_F_SSL_SESSION_NEW 189 +# define SSL_F_SSL_SESSION_PRINT_FP 190 +# define SSL_F_SSL_SESSION_SET1_ID_CONTEXT 312 +# define SSL_F_SSL_SESS_CERT_NEW 225 +# define SSL_F_SSL_SET_CERT 191 +# define SSL_F_SSL_SET_CIPHER_LIST 271 +# define SSL_F_SSL_SET_FD 192 +# define SSL_F_SSL_SET_PKEY 193 +# define SSL_F_SSL_SET_PURPOSE 227 +# define SSL_F_SSL_SET_RFD 194 +# define SSL_F_SSL_SET_SESSION 195 +# define SSL_F_SSL_SET_SESSION_ID_CONTEXT 218 +# define SSL_F_SSL_SET_SESSION_TICKET_EXT 294 +# define SSL_F_SSL_SET_TRUST 228 +# define SSL_F_SSL_SET_WFD 196 +# define SSL_F_SSL_SHUTDOWN 224 +# define SSL_F_SSL_SRP_CTX_INIT 313 +# define SSL_F_SSL_UNDEFINED_CONST_FUNCTION 243 +# define SSL_F_SSL_UNDEFINED_FUNCTION 197 +# define SSL_F_SSL_UNDEFINED_VOID_FUNCTION 244 +# define SSL_F_SSL_USE_CERTIFICATE 198 +# define SSL_F_SSL_USE_CERTIFICATE_ASN1 199 +# define SSL_F_SSL_USE_CERTIFICATE_FILE 200 +# define SSL_F_SSL_USE_PRIVATEKEY 201 +# define SSL_F_SSL_USE_PRIVATEKEY_ASN1 202 +# define SSL_F_SSL_USE_PRIVATEKEY_FILE 203 +# define SSL_F_SSL_USE_PSK_IDENTITY_HINT 273 +# define SSL_F_SSL_USE_RSAPRIVATEKEY 204 +# define SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1 205 +# define SSL_F_SSL_USE_RSAPRIVATEKEY_FILE 206 +# define SSL_F_SSL_VERIFY_CERT_CHAIN 207 +# define SSL_F_SSL_WRITE 208 +# define SSL_F_TLS12_CHECK_PEER_SIGALG 333 +# define SSL_F_TLS1_CERT_VERIFY_MAC 286 +# define SSL_F_TLS1_CHANGE_CIPHER_STATE 209 +# define SSL_F_TLS1_CHECK_SERVERHELLO_TLSEXT 274 +# define SSL_F_TLS1_ENC 210 +# define SSL_F_TLS1_EXPORT_KEYING_MATERIAL 314 +# define SSL_F_TLS1_GET_CURVELIST 338 +# define SSL_F_TLS1_HEARTBEAT 315 +# define SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT 275 +# define SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT 276 +# define SSL_F_TLS1_PRF 284 +# define SSL_F_TLS1_SETUP_KEY_BLOCK 211 +# define SSL_F_TLS1_SET_SERVER_SIGALGS 335 +# define SSL_F_WRITE_PENDING 212 + +/* Reason codes. */ +# define SSL_R_APP_DATA_IN_HANDSHAKE 100 +# define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 272 +# define SSL_R_BAD_ALERT_RECORD 101 +# define SSL_R_BAD_AUTHENTICATION_TYPE 102 +# define SSL_R_BAD_CHANGE_CIPHER_SPEC 103 +# define SSL_R_BAD_CHECKSUM 104 +# define SSL_R_BAD_DATA 390 +# define SSL_R_BAD_DATA_RETURNED_BY_CALLBACK 106 +# define SSL_R_BAD_DECOMPRESSION 107 +# define SSL_R_BAD_DH_G_LENGTH 108 +# define SSL_R_BAD_DH_G_VALUE 375 +# define SSL_R_BAD_DH_PUB_KEY_LENGTH 109 +# define SSL_R_BAD_DH_PUB_KEY_VALUE 393 +# define SSL_R_BAD_DH_P_LENGTH 110 +# define SSL_R_BAD_DH_P_VALUE 395 +# define SSL_R_BAD_DIGEST_LENGTH 111 +# define SSL_R_BAD_DSA_SIGNATURE 112 +# define SSL_R_BAD_ECC_CERT 304 +# define SSL_R_BAD_ECDSA_SIGNATURE 305 +# define SSL_R_BAD_ECPOINT 306 +# define SSL_R_BAD_HANDSHAKE_LENGTH 332 +# define SSL_R_BAD_HELLO_REQUEST 105 +# define SSL_R_BAD_LENGTH 271 +# define SSL_R_BAD_MAC_DECODE 113 +# define SSL_R_BAD_MAC_LENGTH 333 +# define SSL_R_BAD_MESSAGE_TYPE 114 +# define SSL_R_BAD_PACKET_LENGTH 115 +# define SSL_R_BAD_PROTOCOL_VERSION_NUMBER 116 +# define SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH 316 +# define SSL_R_BAD_RESPONSE_ARGUMENT 117 +# define SSL_R_BAD_RSA_DECRYPT 118 +# define SSL_R_BAD_RSA_ENCRYPT 119 +# define SSL_R_BAD_RSA_E_LENGTH 120 +# define SSL_R_BAD_RSA_MODULUS_LENGTH 121 +# define SSL_R_BAD_RSA_SIGNATURE 122 +# define SSL_R_BAD_SIGNATURE 123 +# define SSL_R_BAD_SRP_A_LENGTH 347 +# define SSL_R_BAD_SRP_B_LENGTH 348 +# define SSL_R_BAD_SRP_G_LENGTH 349 +# define SSL_R_BAD_SRP_N_LENGTH 350 +# define SSL_R_BAD_SRP_PARAMETERS 371 +# define SSL_R_BAD_SRP_S_LENGTH 351 +# define SSL_R_BAD_SRTP_MKI_VALUE 352 +# define SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST 353 +# define SSL_R_BAD_SSL_FILETYPE 124 +# define SSL_R_BAD_SSL_SESSION_ID_LENGTH 125 +# define SSL_R_BAD_STATE 126 +# define SSL_R_BAD_VALUE 384 +# define SSL_R_BAD_WRITE_RETRY 127 +# define SSL_R_BIO_NOT_SET 128 +# define SSL_R_BLOCK_CIPHER_PAD_IS_WRONG 129 +# define SSL_R_BN_LIB 130 +# define SSL_R_CA_DN_LENGTH_MISMATCH 131 +# define SSL_R_CA_DN_TOO_LONG 132 +# define SSL_R_CCS_RECEIVED_EARLY 133 +# define SSL_R_CERTIFICATE_VERIFY_FAILED 134 +# define SSL_R_CERT_CB_ERROR 377 +# define SSL_R_CERT_LENGTH_MISMATCH 135 +# define SSL_R_CHALLENGE_IS_DIFFERENT 136 +# define SSL_R_CIPHER_CODE_WRONG_LENGTH 137 +# define SSL_R_CIPHER_OR_HASH_UNAVAILABLE 138 +# define SSL_R_CIPHER_TABLE_SRC_ERROR 139 +# define SSL_R_CLIENTHELLO_TLSEXT 226 +# define SSL_R_COMPRESSED_LENGTH_TOO_LONG 140 +# define SSL_R_COMPRESSION_DISABLED 343 +# define SSL_R_COMPRESSION_FAILURE 141 +# define SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE 307 +# define SSL_R_COMPRESSION_LIBRARY_ERROR 142 +# define SSL_R_CONNECTION_ID_IS_DIFFERENT 143 +# define SSL_R_CONNECTION_TYPE_NOT_SET 144 +# define SSL_R_COOKIE_MISMATCH 308 +# define SSL_R_DATA_BETWEEN_CCS_AND_FINISHED 145 +# define SSL_R_DATA_LENGTH_TOO_LONG 146 +# define SSL_R_DECRYPTION_FAILED 147 +# define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC 281 +# define SSL_R_DH_KEY_TOO_SMALL 372 +# define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG 148 +# define SSL_R_DIGEST_CHECK_FAILED 149 +# define SSL_R_DTLS_MESSAGE_TOO_BIG 334 +# define SSL_R_DUPLICATE_COMPRESSION_ID 309 +# define SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT 317 +# define SSL_R_ECC_CERT_NOT_FOR_SIGNING 318 +# define SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE 322 +# define SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE 323 +# define SSL_R_ECDH_REQUIRED_FOR_SUITEB_MODE 374 +# define SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER 310 +# define SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST 354 +# define SSL_R_ENCRYPTED_LENGTH_TOO_LONG 150 +# define SSL_R_ERROR_GENERATING_TMP_RSA_KEY 282 +# define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST 151 +# define SSL_R_EXCESSIVE_MESSAGE_SIZE 152 +# define SSL_R_EXTRA_DATA_IN_MESSAGE 153 +# define SSL_R_GOT_A_FIN_BEFORE_A_CCS 154 +# define SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS 355 +# define SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION 356 +# define SSL_R_HTTPS_PROXY_REQUEST 155 +# define SSL_R_HTTP_REQUEST 156 +# define SSL_R_ILLEGAL_PADDING 283 +# define SSL_R_ILLEGAL_SUITEB_DIGEST 380 +# define SSL_R_INAPPROPRIATE_FALLBACK 373 +# define SSL_R_INCONSISTENT_COMPRESSION 340 +# define SSL_R_INVALID_CHALLENGE_LENGTH 158 +# define SSL_R_INVALID_COMMAND 280 +# define SSL_R_INVALID_COMPRESSION_ALGORITHM 341 +# define SSL_R_INVALID_NULL_CMD_NAME 385 +# define SSL_R_INVALID_PURPOSE 278 +# define SSL_R_INVALID_SERVERINFO_DATA 388 +# define SSL_R_INVALID_SRP_USERNAME 357 +# define SSL_R_INVALID_STATUS_RESPONSE 328 +# define SSL_R_INVALID_TICKET_KEYS_LENGTH 325 +# define SSL_R_INVALID_TRUST 279 +# define SSL_R_KEY_ARG_TOO_LONG 284 +# define SSL_R_KRB5 285 +# define SSL_R_KRB5_C_CC_PRINC 286 +# define SSL_R_KRB5_C_GET_CRED 287 +# define SSL_R_KRB5_C_INIT 288 +# define SSL_R_KRB5_C_MK_REQ 289 +# define SSL_R_KRB5_S_BAD_TICKET 290 +# define SSL_R_KRB5_S_INIT 291 +# define SSL_R_KRB5_S_RD_REQ 292 +# define SSL_R_KRB5_S_TKT_EXPIRED 293 +# define SSL_R_KRB5_S_TKT_NYV 294 +# define SSL_R_KRB5_S_TKT_SKEW 295 +# define SSL_R_LENGTH_MISMATCH 159 +# define SSL_R_LENGTH_TOO_SHORT 160 +# define SSL_R_LIBRARY_BUG 274 +# define SSL_R_LIBRARY_HAS_NO_CIPHERS 161 +# define SSL_R_MESSAGE_TOO_LONG 296 +# define SSL_R_MISSING_DH_DSA_CERT 162 +# define SSL_R_MISSING_DH_KEY 163 +# define SSL_R_MISSING_DH_RSA_CERT 164 +# define SSL_R_MISSING_DSA_SIGNING_CERT 165 +# define SSL_R_MISSING_ECDH_CERT 382 +# define SSL_R_MISSING_ECDSA_SIGNING_CERT 381 +# define SSL_R_MISSING_EXPORT_TMP_DH_KEY 166 +# define SSL_R_MISSING_EXPORT_TMP_RSA_KEY 167 +# define SSL_R_MISSING_RSA_CERTIFICATE 168 +# define SSL_R_MISSING_RSA_ENCRYPTING_CERT 169 +# define SSL_R_MISSING_RSA_SIGNING_CERT 170 +# define SSL_R_MISSING_SRP_PARAM 358 +# define SSL_R_MISSING_TMP_DH_KEY 171 +# define SSL_R_MISSING_TMP_ECDH_KEY 311 +# define SSL_R_MISSING_TMP_RSA_KEY 172 +# define SSL_R_MISSING_TMP_RSA_PKEY 173 +# define SSL_R_MISSING_VERIFY_MESSAGE 174 +# define SSL_R_MULTIPLE_SGC_RESTARTS 346 +# define SSL_R_NON_SSLV2_INITIAL_PACKET 175 +# define SSL_R_NO_CERTIFICATES_RETURNED 176 +# define SSL_R_NO_CERTIFICATE_ASSIGNED 177 +# define SSL_R_NO_CERTIFICATE_RETURNED 178 +# define SSL_R_NO_CERTIFICATE_SET 179 +# define SSL_R_NO_CERTIFICATE_SPECIFIED 180 +# define SSL_R_NO_CIPHERS_AVAILABLE 181 +# define SSL_R_NO_CIPHERS_PASSED 182 +# define SSL_R_NO_CIPHERS_SPECIFIED 183 +# define SSL_R_NO_CIPHER_LIST 184 +# define SSL_R_NO_CIPHER_MATCH 185 +# define SSL_R_NO_CLIENT_CERT_METHOD 331 +# define SSL_R_NO_CLIENT_CERT_RECEIVED 186 +# define SSL_R_NO_COMPRESSION_SPECIFIED 187 +# define SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER 330 +# define SSL_R_NO_METHOD_SPECIFIED 188 +# define SSL_R_NO_PEM_EXTENSIONS 389 +# define SSL_R_NO_PRIVATEKEY 189 +# define SSL_R_NO_PRIVATE_KEY_ASSIGNED 190 +# define SSL_R_NO_PROTOCOLS_AVAILABLE 191 +# define SSL_R_NO_PUBLICKEY 192 +# define SSL_R_NO_RENEGOTIATION 339 +# define SSL_R_NO_REQUIRED_DIGEST 324 +# define SSL_R_NO_SHARED_CIPHER 193 +# define SSL_R_NO_SHARED_SIGATURE_ALGORITHMS 376 +# define SSL_R_NO_SRTP_PROFILES 359 +# define SSL_R_NO_VERIFY_CALLBACK 194 +# define SSL_R_NULL_SSL_CTX 195 +# define SSL_R_NULL_SSL_METHOD_PASSED 196 +# define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED 197 +# define SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED 344 +# define SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE 387 +# define SSL_R_ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE 379 +# define SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE 297 +# define SSL_R_OPAQUE_PRF_INPUT_TOO_LONG 327 +# define SSL_R_PACKET_LENGTH_TOO_LONG 198 +# define SSL_R_PARSE_TLSEXT 227 +# define SSL_R_PATH_TOO_LONG 270 +# define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE 199 +# define SSL_R_PEER_ERROR 200 +# define SSL_R_PEER_ERROR_CERTIFICATE 201 +# define SSL_R_PEER_ERROR_NO_CERTIFICATE 202 +# define SSL_R_PEER_ERROR_NO_CIPHER 203 +# define SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE 204 +# define SSL_R_PEM_NAME_BAD_PREFIX 391 +# define SSL_R_PEM_NAME_TOO_SHORT 392 +# define SSL_R_PRE_MAC_LENGTH_TOO_LONG 205 +# define SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS 206 +# define SSL_R_PROTOCOL_IS_SHUTDOWN 207 +# define SSL_R_PSK_IDENTITY_NOT_FOUND 223 +# define SSL_R_PSK_NO_CLIENT_CB 224 +# define SSL_R_PSK_NO_SERVER_CB 225 +# define SSL_R_PUBLIC_KEY_ENCRYPT_ERROR 208 +# define SSL_R_PUBLIC_KEY_IS_NOT_RSA 209 +# define SSL_R_PUBLIC_KEY_NOT_RSA 210 +# define SSL_R_READ_BIO_NOT_SET 211 +# define SSL_R_READ_TIMEOUT_EXPIRED 312 +# define SSL_R_READ_WRONG_PACKET_TYPE 212 +# define SSL_R_RECORD_LENGTH_MISMATCH 213 +# define SSL_R_RECORD_TOO_LARGE 214 +# define SSL_R_RECORD_TOO_SMALL 298 +# define SSL_R_RENEGOTIATE_EXT_TOO_LONG 335 +# define SSL_R_RENEGOTIATION_ENCODING_ERR 336 +# define SSL_R_RENEGOTIATION_MISMATCH 337 +# define SSL_R_REQUIRED_CIPHER_MISSING 215 +# define SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING 342 +# define SSL_R_REUSE_CERT_LENGTH_NOT_ZERO 216 +# define SSL_R_REUSE_CERT_TYPE_NOT_ZERO 217 +# define SSL_R_REUSE_CIPHER_LIST_NOT_ZERO 218 +# define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING 345 +# define SSL_R_SERVERHELLO_TLSEXT 275 +# define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 277 +# define SSL_R_SHORT_READ 219 +# define SSL_R_SHUTDOWN_WHILE_IN_INIT 407 +# define SSL_R_SIGNATURE_ALGORITHMS_ERROR 360 +# define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE 220 +# define SSL_R_SRP_A_CALC 361 +# define SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES 362 +# define SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG 363 +# define SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE 364 +# define SSL_R_SSL23_DOING_SESSION_ID_REUSE 221 +# define SSL_R_SSL2_CONNECTION_ID_TOO_LONG 299 +# define SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT 321 +# define SSL_R_SSL3_EXT_INVALID_SERVERNAME 319 +# define SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE 320 +# define SSL_R_SSL3_SESSION_ID_TOO_LONG 300 +# define SSL_R_SSL3_SESSION_ID_TOO_SHORT 222 +# define SSL_R_SSLV3_ALERT_BAD_CERTIFICATE 1042 +# define SSL_R_SSLV3_ALERT_BAD_RECORD_MAC 1020 +# define SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED 1045 +# define SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED 1044 +# define SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN 1046 +# define SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE 1030 +# define SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE 1040 +# define SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER 1047 +# define SSL_R_SSLV3_ALERT_NO_CERTIFICATE 1041 +# define SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE 1010 +# define SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE 1043 +# define SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION 228 +# define SSL_R_SSL_HANDSHAKE_FAILURE 229 +# define SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS 230 +# define SSL_R_SSL_SESSION_ID_CALLBACK_FAILED 301 +# define SSL_R_SSL_SESSION_ID_CONFLICT 302 +# define SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG 273 +# define SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH 303 +# define SSL_R_SSL_SESSION_ID_IS_DIFFERENT 231 +# define SSL_R_TLSV1_ALERT_ACCESS_DENIED 1049 +# define SSL_R_TLSV1_ALERT_DECODE_ERROR 1050 +# define SSL_R_TLSV1_ALERT_DECRYPTION_FAILED 1021 +# define SSL_R_TLSV1_ALERT_DECRYPT_ERROR 1051 +# define SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION 1060 +# define SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK 1086 +# define SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY 1071 +# define SSL_R_TLSV1_ALERT_INTERNAL_ERROR 1080 +# define SSL_R_TLSV1_ALERT_NO_RENEGOTIATION 1100 +# define SSL_R_TLSV1_ALERT_PROTOCOL_VERSION 1070 +# define SSL_R_TLSV1_ALERT_RECORD_OVERFLOW 1022 +# define SSL_R_TLSV1_ALERT_UNKNOWN_CA 1048 +# define SSL_R_TLSV1_ALERT_USER_CANCELLED 1090 +# define SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE 1114 +# define SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE 1113 +# define SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE 1111 +# define SSL_R_TLSV1_UNRECOGNIZED_NAME 1112 +# define SSL_R_TLSV1_UNSUPPORTED_EXTENSION 1110 +# define SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER 232 +# define SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT 365 +# define SSL_R_TLS_HEARTBEAT_PENDING 366 +# define SSL_R_TLS_ILLEGAL_EXPORTER_LABEL 367 +# define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST 157 +# define SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST 233 +# define SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG 234 +# define SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER 235 +# define SSL_R_UNABLE_TO_DECODE_DH_CERTS 236 +# define SSL_R_UNABLE_TO_DECODE_ECDH_CERTS 313 +# define SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY 237 +# define SSL_R_UNABLE_TO_FIND_DH_PARAMETERS 238 +# define SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS 314 +# define SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS 239 +# define SSL_R_UNABLE_TO_FIND_SSL_METHOD 240 +# define SSL_R_UNABLE_TO_LOAD_SSL2_MD5_ROUTINES 241 +# define SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES 242 +# define SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES 243 +# define SSL_R_UNEXPECTED_MESSAGE 244 +# define SSL_R_UNEXPECTED_RECORD 245 +# define SSL_R_UNINITIALIZED 276 +# define SSL_R_UNKNOWN_ALERT_TYPE 246 +# define SSL_R_UNKNOWN_CERTIFICATE_TYPE 247 +# define SSL_R_UNKNOWN_CIPHER_RETURNED 248 +# define SSL_R_UNKNOWN_CIPHER_TYPE 249 +# define SSL_R_UNKNOWN_CMD_NAME 386 +# define SSL_R_UNKNOWN_DIGEST 368 +# define SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE 250 +# define SSL_R_UNKNOWN_PKEY_TYPE 251 +# define SSL_R_UNKNOWN_PROTOCOL 252 +# define SSL_R_UNKNOWN_REMOTE_ERROR_TYPE 253 +# define SSL_R_UNKNOWN_SSL_VERSION 254 +# define SSL_R_UNKNOWN_STATE 255 +# define SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED 338 +# define SSL_R_UNSUPPORTED_CIPHER 256 +# define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM 257 +# define SSL_R_UNSUPPORTED_DIGEST_TYPE 326 +# define SSL_R_UNSUPPORTED_ELLIPTIC_CURVE 315 +# define SSL_R_UNSUPPORTED_PROTOCOL 258 +# define SSL_R_UNSUPPORTED_SSL_VERSION 259 +# define SSL_R_UNSUPPORTED_STATUS_TYPE 329 +# define SSL_R_USE_SRTP_NOT_NEGOTIATED 369 +# define SSL_R_WRITE_BIO_NOT_SET 260 +# define SSL_R_WRONG_CERTIFICATE_TYPE 383 +# define SSL_R_WRONG_CIPHER_RETURNED 261 +# define SSL_R_WRONG_CURVE 378 +# define SSL_R_WRONG_MESSAGE_TYPE 262 +# define SSL_R_WRONG_NUMBER_OF_KEY_BITS 263 +# define SSL_R_WRONG_SIGNATURE_LENGTH 264 +# define SSL_R_WRONG_SIGNATURE_SIZE 265 +# define SSL_R_WRONG_SIGNATURE_TYPE 370 +# define SSL_R_WRONG_SSL_VERSION 266 +# define SSL_R_WRONG_VERSION_NUMBER 267 +# define SSL_R_X509_LIB 268 +# define SSL_R_X509_VERIFICATION_SETUP_PROBLEMS 269 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/ssl2.h b/OSlibs/ios/include/openssl/ssl2.h new file mode 100755 index 000000000..03c7dd8ca --- /dev/null +++ b/OSlibs/ios/include/openssl/ssl2.h @@ -0,0 +1,265 @@ +/* ssl/ssl2.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_SSL2_H +# define HEADER_SSL2_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Protocol Version Codes */ +# define SSL2_VERSION 0x0002 +# define SSL2_VERSION_MAJOR 0x00 +# define SSL2_VERSION_MINOR 0x02 +/* #define SSL2_CLIENT_VERSION 0x0002 */ +/* #define SSL2_SERVER_VERSION 0x0002 */ + +/* Protocol Message Codes */ +# define SSL2_MT_ERROR 0 +# define SSL2_MT_CLIENT_HELLO 1 +# define SSL2_MT_CLIENT_MASTER_KEY 2 +# define SSL2_MT_CLIENT_FINISHED 3 +# define SSL2_MT_SERVER_HELLO 4 +# define SSL2_MT_SERVER_VERIFY 5 +# define SSL2_MT_SERVER_FINISHED 6 +# define SSL2_MT_REQUEST_CERTIFICATE 7 +# define SSL2_MT_CLIENT_CERTIFICATE 8 + +/* Error Message Codes */ +# define SSL2_PE_UNDEFINED_ERROR 0x0000 +# define SSL2_PE_NO_CIPHER 0x0001 +# define SSL2_PE_NO_CERTIFICATE 0x0002 +# define SSL2_PE_BAD_CERTIFICATE 0x0004 +# define SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE 0x0006 + +/* Cipher Kind Values */ +# define SSL2_CK_NULL_WITH_MD5 0x02000000/* v3 */ +# define SSL2_CK_RC4_128_WITH_MD5 0x02010080 +# define SSL2_CK_RC4_128_EXPORT40_WITH_MD5 0x02020080 +# define SSL2_CK_RC2_128_CBC_WITH_MD5 0x02030080 +# define SSL2_CK_RC2_128_CBC_EXPORT40_WITH_MD5 0x02040080 +# define SSL2_CK_IDEA_128_CBC_WITH_MD5 0x02050080 +# define SSL2_CK_DES_64_CBC_WITH_MD5 0x02060040 +# define SSL2_CK_DES_64_CBC_WITH_SHA 0x02060140/* v3 */ +# define SSL2_CK_DES_192_EDE3_CBC_WITH_MD5 0x020700c0 +# define SSL2_CK_DES_192_EDE3_CBC_WITH_SHA 0x020701c0/* v3 */ +# define SSL2_CK_RC4_64_WITH_MD5 0x02080080/* MS hack */ + +# define SSL2_CK_DES_64_CFB64_WITH_MD5_1 0x02ff0800/* SSLeay */ +# define SSL2_CK_NULL 0x02ff0810/* SSLeay */ + +# define SSL2_TXT_DES_64_CFB64_WITH_MD5_1 "DES-CFB-M1" +# define SSL2_TXT_NULL_WITH_MD5 "NULL-MD5" +# define SSL2_TXT_RC4_128_WITH_MD5 "RC4-MD5" +# define SSL2_TXT_RC4_128_EXPORT40_WITH_MD5 "EXP-RC4-MD5" +# define SSL2_TXT_RC2_128_CBC_WITH_MD5 "RC2-CBC-MD5" +# define SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5 "EXP-RC2-CBC-MD5" +# define SSL2_TXT_IDEA_128_CBC_WITH_MD5 "IDEA-CBC-MD5" +# define SSL2_TXT_DES_64_CBC_WITH_MD5 "DES-CBC-MD5" +# define SSL2_TXT_DES_64_CBC_WITH_SHA "DES-CBC-SHA" +# define SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5 "DES-CBC3-MD5" +# define SSL2_TXT_DES_192_EDE3_CBC_WITH_SHA "DES-CBC3-SHA" +# define SSL2_TXT_RC4_64_WITH_MD5 "RC4-64-MD5" + +# define SSL2_TXT_NULL "NULL" + +/* Flags for the SSL_CIPHER.algorithm2 field */ +# define SSL2_CF_5_BYTE_ENC 0x01 +# define SSL2_CF_8_BYTE_ENC 0x02 + +/* Certificate Type Codes */ +# define SSL2_CT_X509_CERTIFICATE 0x01 + +/* Authentication Type Code */ +# define SSL2_AT_MD5_WITH_RSA_ENCRYPTION 0x01 + +# define SSL2_MAX_SSL_SESSION_ID_LENGTH 32 + +/* Upper/Lower Bounds */ +# define SSL2_MAX_MASTER_KEY_LENGTH_IN_BITS 256 +# ifdef OPENSSL_SYS_MPE +# define SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER 29998u +# else +# define SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER 32767u + /* 2^15-1 */ +# endif +# define SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER 16383/* 2^14-1 */ + +# define SSL2_CHALLENGE_LENGTH 16 +/* + * #define SSL2_CHALLENGE_LENGTH 32 + */ +# define SSL2_MIN_CHALLENGE_LENGTH 16 +# define SSL2_MAX_CHALLENGE_LENGTH 32 +# define SSL2_CONNECTION_ID_LENGTH 16 +# define SSL2_MAX_CONNECTION_ID_LENGTH 16 +# define SSL2_SSL_SESSION_ID_LENGTH 16 +# define SSL2_MAX_CERT_CHALLENGE_LENGTH 32 +# define SSL2_MIN_CERT_CHALLENGE_LENGTH 16 +# define SSL2_MAX_KEY_MATERIAL_LENGTH 24 + +# ifndef HEADER_SSL_LOCL_H +# define CERT char +# endif + +# ifndef OPENSSL_NO_SSL_INTERN + +typedef struct ssl2_state_st { + int three_byte_header; + int clear_text; /* clear text */ + int escape; /* not used in SSLv2 */ + int ssl2_rollback; /* used if SSLv23 rolled back to SSLv2 */ + /* + * non-blocking io info, used to make sure the same args were passwd + */ + unsigned int wnum; /* number of bytes sent so far */ + int wpend_tot; + const unsigned char *wpend_buf; + int wpend_off; /* offset to data to write */ + int wpend_len; /* number of bytes passwd to write */ + int wpend_ret; /* number of bytes to return to caller */ + /* buffer raw data */ + int rbuf_left; + int rbuf_offs; + unsigned char *rbuf; + unsigned char *wbuf; + unsigned char *write_ptr; /* used to point to the start due to 2/3 byte + * header. */ + unsigned int padding; + unsigned int rlength; /* passed to ssl2_enc */ + int ract_data_length; /* Set when things are encrypted. */ + unsigned int wlength; /* passed to ssl2_enc */ + int wact_data_length; /* Set when things are decrypted. */ + unsigned char *ract_data; + unsigned char *wact_data; + unsigned char *mac_data; + unsigned char *read_key; + unsigned char *write_key; + /* Stuff specifically to do with this SSL session */ + unsigned int challenge_length; + unsigned char challenge[SSL2_MAX_CHALLENGE_LENGTH]; + unsigned int conn_id_length; + unsigned char conn_id[SSL2_MAX_CONNECTION_ID_LENGTH]; + unsigned int key_material_length; + unsigned char key_material[SSL2_MAX_KEY_MATERIAL_LENGTH * 2]; + unsigned long read_sequence; + unsigned long write_sequence; + struct { + unsigned int conn_id_length; + unsigned int cert_type; + unsigned int cert_length; + unsigned int csl; + unsigned int clear; + unsigned int enc; + unsigned char ccl[SSL2_MAX_CERT_CHALLENGE_LENGTH]; + unsigned int cipher_spec_length; + unsigned int session_id_length; + unsigned int clen; + unsigned int rlen; + } tmp; +} SSL2_STATE; + +# endif + +/* SSLv2 */ +/* client */ +# define SSL2_ST_SEND_CLIENT_HELLO_A (0x10|SSL_ST_CONNECT) +# define SSL2_ST_SEND_CLIENT_HELLO_B (0x11|SSL_ST_CONNECT) +# define SSL2_ST_GET_SERVER_HELLO_A (0x20|SSL_ST_CONNECT) +# define SSL2_ST_GET_SERVER_HELLO_B (0x21|SSL_ST_CONNECT) +# define SSL2_ST_SEND_CLIENT_MASTER_KEY_A (0x30|SSL_ST_CONNECT) +# define SSL2_ST_SEND_CLIENT_MASTER_KEY_B (0x31|SSL_ST_CONNECT) +# define SSL2_ST_SEND_CLIENT_FINISHED_A (0x40|SSL_ST_CONNECT) +# define SSL2_ST_SEND_CLIENT_FINISHED_B (0x41|SSL_ST_CONNECT) +# define SSL2_ST_SEND_CLIENT_CERTIFICATE_A (0x50|SSL_ST_CONNECT) +# define SSL2_ST_SEND_CLIENT_CERTIFICATE_B (0x51|SSL_ST_CONNECT) +# define SSL2_ST_SEND_CLIENT_CERTIFICATE_C (0x52|SSL_ST_CONNECT) +# define SSL2_ST_SEND_CLIENT_CERTIFICATE_D (0x53|SSL_ST_CONNECT) +# define SSL2_ST_GET_SERVER_VERIFY_A (0x60|SSL_ST_CONNECT) +# define SSL2_ST_GET_SERVER_VERIFY_B (0x61|SSL_ST_CONNECT) +# define SSL2_ST_GET_SERVER_FINISHED_A (0x70|SSL_ST_CONNECT) +# define SSL2_ST_GET_SERVER_FINISHED_B (0x71|SSL_ST_CONNECT) +# define SSL2_ST_CLIENT_START_ENCRYPTION (0x80|SSL_ST_CONNECT) +# define SSL2_ST_X509_GET_CLIENT_CERTIFICATE (0x90|SSL_ST_CONNECT) +/* server */ +# define SSL2_ST_GET_CLIENT_HELLO_A (0x10|SSL_ST_ACCEPT) +# define SSL2_ST_GET_CLIENT_HELLO_B (0x11|SSL_ST_ACCEPT) +# define SSL2_ST_GET_CLIENT_HELLO_C (0x12|SSL_ST_ACCEPT) +# define SSL2_ST_SEND_SERVER_HELLO_A (0x20|SSL_ST_ACCEPT) +# define SSL2_ST_SEND_SERVER_HELLO_B (0x21|SSL_ST_ACCEPT) +# define SSL2_ST_GET_CLIENT_MASTER_KEY_A (0x30|SSL_ST_ACCEPT) +# define SSL2_ST_GET_CLIENT_MASTER_KEY_B (0x31|SSL_ST_ACCEPT) +# define SSL2_ST_SEND_SERVER_VERIFY_A (0x40|SSL_ST_ACCEPT) +# define SSL2_ST_SEND_SERVER_VERIFY_B (0x41|SSL_ST_ACCEPT) +# define SSL2_ST_SEND_SERVER_VERIFY_C (0x42|SSL_ST_ACCEPT) +# define SSL2_ST_GET_CLIENT_FINISHED_A (0x50|SSL_ST_ACCEPT) +# define SSL2_ST_GET_CLIENT_FINISHED_B (0x51|SSL_ST_ACCEPT) +# define SSL2_ST_SEND_SERVER_FINISHED_A (0x60|SSL_ST_ACCEPT) +# define SSL2_ST_SEND_SERVER_FINISHED_B (0x61|SSL_ST_ACCEPT) +# define SSL2_ST_SEND_REQUEST_CERTIFICATE_A (0x70|SSL_ST_ACCEPT) +# define SSL2_ST_SEND_REQUEST_CERTIFICATE_B (0x71|SSL_ST_ACCEPT) +# define SSL2_ST_SEND_REQUEST_CERTIFICATE_C (0x72|SSL_ST_ACCEPT) +# define SSL2_ST_SEND_REQUEST_CERTIFICATE_D (0x73|SSL_ST_ACCEPT) +# define SSL2_ST_SERVER_START_ENCRYPTION (0x80|SSL_ST_ACCEPT) +# define SSL2_ST_X509_GET_SERVER_CERTIFICATE (0x90|SSL_ST_ACCEPT) + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/ssl23.h b/OSlibs/ios/include/openssl/ssl23.h new file mode 100755 index 000000000..9de4685af --- /dev/null +++ b/OSlibs/ios/include/openssl/ssl23.h @@ -0,0 +1,84 @@ +/* ssl/ssl23.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_SSL23_H +# define HEADER_SSL23_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * client + */ +/* write to server */ +# define SSL23_ST_CW_CLNT_HELLO_A (0x210|SSL_ST_CONNECT) +# define SSL23_ST_CW_CLNT_HELLO_B (0x211|SSL_ST_CONNECT) +/* read from server */ +# define SSL23_ST_CR_SRVR_HELLO_A (0x220|SSL_ST_CONNECT) +# define SSL23_ST_CR_SRVR_HELLO_B (0x221|SSL_ST_CONNECT) + +/* server */ +/* read from client */ +# define SSL23_ST_SR_CLNT_HELLO_A (0x210|SSL_ST_ACCEPT) +# define SSL23_ST_SR_CLNT_HELLO_B (0x211|SSL_ST_ACCEPT) + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/ssl3.h b/OSlibs/ios/include/openssl/ssl3.h new file mode 100755 index 000000000..e681d50a9 --- /dev/null +++ b/OSlibs/ios/include/openssl/ssl3.h @@ -0,0 +1,774 @@ +/* ssl/ssl3.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#ifndef HEADER_SSL3_H +# define HEADER_SSL3_H + +# ifndef OPENSSL_NO_COMP +# include +# endif +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Signalling cipher suite value from RFC 5746 + * (TLS_EMPTY_RENEGOTIATION_INFO_SCSV) + */ +# define SSL3_CK_SCSV 0x030000FF + +/* + * Signalling cipher suite value from draft-ietf-tls-downgrade-scsv-00 + * (TLS_FALLBACK_SCSV) + */ +# define SSL3_CK_FALLBACK_SCSV 0x03005600 + +# define SSL3_CK_RSA_NULL_MD5 0x03000001 +# define SSL3_CK_RSA_NULL_SHA 0x03000002 +# define SSL3_CK_RSA_RC4_40_MD5 0x03000003 +# define SSL3_CK_RSA_RC4_128_MD5 0x03000004 +# define SSL3_CK_RSA_RC4_128_SHA 0x03000005 +# define SSL3_CK_RSA_RC2_40_MD5 0x03000006 +# define SSL3_CK_RSA_IDEA_128_SHA 0x03000007 +# define SSL3_CK_RSA_DES_40_CBC_SHA 0x03000008 +# define SSL3_CK_RSA_DES_64_CBC_SHA 0x03000009 +# define SSL3_CK_RSA_DES_192_CBC3_SHA 0x0300000A + +# define SSL3_CK_DH_DSS_DES_40_CBC_SHA 0x0300000B +# define SSL3_CK_DH_DSS_DES_64_CBC_SHA 0x0300000C +# define SSL3_CK_DH_DSS_DES_192_CBC3_SHA 0x0300000D +# define SSL3_CK_DH_RSA_DES_40_CBC_SHA 0x0300000E +# define SSL3_CK_DH_RSA_DES_64_CBC_SHA 0x0300000F +# define SSL3_CK_DH_RSA_DES_192_CBC3_SHA 0x03000010 + +# define SSL3_CK_EDH_DSS_DES_40_CBC_SHA 0x03000011 +# define SSL3_CK_DHE_DSS_DES_40_CBC_SHA SSL3_CK_EDH_DSS_DES_40_CBC_SHA +# define SSL3_CK_EDH_DSS_DES_64_CBC_SHA 0x03000012 +# define SSL3_CK_DHE_DSS_DES_64_CBC_SHA SSL3_CK_EDH_DSS_DES_64_CBC_SHA +# define SSL3_CK_EDH_DSS_DES_192_CBC3_SHA 0x03000013 +# define SSL3_CK_DHE_DSS_DES_192_CBC3_SHA SSL3_CK_EDH_DSS_DES_192_CBC3_SHA +# define SSL3_CK_EDH_RSA_DES_40_CBC_SHA 0x03000014 +# define SSL3_CK_DHE_RSA_DES_40_CBC_SHA SSL3_CK_EDH_RSA_DES_40_CBC_SHA +# define SSL3_CK_EDH_RSA_DES_64_CBC_SHA 0x03000015 +# define SSL3_CK_DHE_RSA_DES_64_CBC_SHA SSL3_CK_EDH_RSA_DES_64_CBC_SHA +# define SSL3_CK_EDH_RSA_DES_192_CBC3_SHA 0x03000016 +# define SSL3_CK_DHE_RSA_DES_192_CBC3_SHA SSL3_CK_EDH_RSA_DES_192_CBC3_SHA + +# define SSL3_CK_ADH_RC4_40_MD5 0x03000017 +# define SSL3_CK_ADH_RC4_128_MD5 0x03000018 +# define SSL3_CK_ADH_DES_40_CBC_SHA 0x03000019 +# define SSL3_CK_ADH_DES_64_CBC_SHA 0x0300001A +# define SSL3_CK_ADH_DES_192_CBC_SHA 0x0300001B + +# if 0 +# define SSL3_CK_FZA_DMS_NULL_SHA 0x0300001C +# define SSL3_CK_FZA_DMS_FZA_SHA 0x0300001D +# if 0 /* Because it clashes with KRB5, is never + * used any more, and is safe to remove + * according to David Hopwood + * of the + * ietf-tls list */ +# define SSL3_CK_FZA_DMS_RC4_SHA 0x0300001E +# endif +# endif + +/* + * VRS Additional Kerberos5 entries + */ +# define SSL3_CK_KRB5_DES_64_CBC_SHA 0x0300001E +# define SSL3_CK_KRB5_DES_192_CBC3_SHA 0x0300001F +# define SSL3_CK_KRB5_RC4_128_SHA 0x03000020 +# define SSL3_CK_KRB5_IDEA_128_CBC_SHA 0x03000021 +# define SSL3_CK_KRB5_DES_64_CBC_MD5 0x03000022 +# define SSL3_CK_KRB5_DES_192_CBC3_MD5 0x03000023 +# define SSL3_CK_KRB5_RC4_128_MD5 0x03000024 +# define SSL3_CK_KRB5_IDEA_128_CBC_MD5 0x03000025 + +# define SSL3_CK_KRB5_DES_40_CBC_SHA 0x03000026 +# define SSL3_CK_KRB5_RC2_40_CBC_SHA 0x03000027 +# define SSL3_CK_KRB5_RC4_40_SHA 0x03000028 +# define SSL3_CK_KRB5_DES_40_CBC_MD5 0x03000029 +# define SSL3_CK_KRB5_RC2_40_CBC_MD5 0x0300002A +# define SSL3_CK_KRB5_RC4_40_MD5 0x0300002B + +# define SSL3_TXT_RSA_NULL_MD5 "NULL-MD5" +# define SSL3_TXT_RSA_NULL_SHA "NULL-SHA" +# define SSL3_TXT_RSA_RC4_40_MD5 "EXP-RC4-MD5" +# define SSL3_TXT_RSA_RC4_128_MD5 "RC4-MD5" +# define SSL3_TXT_RSA_RC4_128_SHA "RC4-SHA" +# define SSL3_TXT_RSA_RC2_40_MD5 "EXP-RC2-CBC-MD5" +# define SSL3_TXT_RSA_IDEA_128_SHA "IDEA-CBC-SHA" +# define SSL3_TXT_RSA_DES_40_CBC_SHA "EXP-DES-CBC-SHA" +# define SSL3_TXT_RSA_DES_64_CBC_SHA "DES-CBC-SHA" +# define SSL3_TXT_RSA_DES_192_CBC3_SHA "DES-CBC3-SHA" + +# define SSL3_TXT_DH_DSS_DES_40_CBC_SHA "EXP-DH-DSS-DES-CBC-SHA" +# define SSL3_TXT_DH_DSS_DES_64_CBC_SHA "DH-DSS-DES-CBC-SHA" +# define SSL3_TXT_DH_DSS_DES_192_CBC3_SHA "DH-DSS-DES-CBC3-SHA" +# define SSL3_TXT_DH_RSA_DES_40_CBC_SHA "EXP-DH-RSA-DES-CBC-SHA" +# define SSL3_TXT_DH_RSA_DES_64_CBC_SHA "DH-RSA-DES-CBC-SHA" +# define SSL3_TXT_DH_RSA_DES_192_CBC3_SHA "DH-RSA-DES-CBC3-SHA" + +# define SSL3_TXT_DHE_DSS_DES_40_CBC_SHA "EXP-DHE-DSS-DES-CBC-SHA" +# define SSL3_TXT_DHE_DSS_DES_64_CBC_SHA "DHE-DSS-DES-CBC-SHA" +# define SSL3_TXT_DHE_DSS_DES_192_CBC3_SHA "DHE-DSS-DES-CBC3-SHA" +# define SSL3_TXT_DHE_RSA_DES_40_CBC_SHA "EXP-DHE-RSA-DES-CBC-SHA" +# define SSL3_TXT_DHE_RSA_DES_64_CBC_SHA "DHE-RSA-DES-CBC-SHA" +# define SSL3_TXT_DHE_RSA_DES_192_CBC3_SHA "DHE-RSA-DES-CBC3-SHA" + +/* + * This next block of six "EDH" labels is for backward compatibility with + * older versions of OpenSSL. New code should use the six "DHE" labels above + * instead: + */ +# define SSL3_TXT_EDH_DSS_DES_40_CBC_SHA "EXP-EDH-DSS-DES-CBC-SHA" +# define SSL3_TXT_EDH_DSS_DES_64_CBC_SHA "EDH-DSS-DES-CBC-SHA" +# define SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA "EDH-DSS-DES-CBC3-SHA" +# define SSL3_TXT_EDH_RSA_DES_40_CBC_SHA "EXP-EDH-RSA-DES-CBC-SHA" +# define SSL3_TXT_EDH_RSA_DES_64_CBC_SHA "EDH-RSA-DES-CBC-SHA" +# define SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA "EDH-RSA-DES-CBC3-SHA" + +# define SSL3_TXT_ADH_RC4_40_MD5 "EXP-ADH-RC4-MD5" +# define SSL3_TXT_ADH_RC4_128_MD5 "ADH-RC4-MD5" +# define SSL3_TXT_ADH_DES_40_CBC_SHA "EXP-ADH-DES-CBC-SHA" +# define SSL3_TXT_ADH_DES_64_CBC_SHA "ADH-DES-CBC-SHA" +# define SSL3_TXT_ADH_DES_192_CBC_SHA "ADH-DES-CBC3-SHA" + +# if 0 +# define SSL3_TXT_FZA_DMS_NULL_SHA "FZA-NULL-SHA" +# define SSL3_TXT_FZA_DMS_FZA_SHA "FZA-FZA-CBC-SHA" +# define SSL3_TXT_FZA_DMS_RC4_SHA "FZA-RC4-SHA" +# endif + +# define SSL3_TXT_KRB5_DES_64_CBC_SHA "KRB5-DES-CBC-SHA" +# define SSL3_TXT_KRB5_DES_192_CBC3_SHA "KRB5-DES-CBC3-SHA" +# define SSL3_TXT_KRB5_RC4_128_SHA "KRB5-RC4-SHA" +# define SSL3_TXT_KRB5_IDEA_128_CBC_SHA "KRB5-IDEA-CBC-SHA" +# define SSL3_TXT_KRB5_DES_64_CBC_MD5 "KRB5-DES-CBC-MD5" +# define SSL3_TXT_KRB5_DES_192_CBC3_MD5 "KRB5-DES-CBC3-MD5" +# define SSL3_TXT_KRB5_RC4_128_MD5 "KRB5-RC4-MD5" +# define SSL3_TXT_KRB5_IDEA_128_CBC_MD5 "KRB5-IDEA-CBC-MD5" + +# define SSL3_TXT_KRB5_DES_40_CBC_SHA "EXP-KRB5-DES-CBC-SHA" +# define SSL3_TXT_KRB5_RC2_40_CBC_SHA "EXP-KRB5-RC2-CBC-SHA" +# define SSL3_TXT_KRB5_RC4_40_SHA "EXP-KRB5-RC4-SHA" +# define SSL3_TXT_KRB5_DES_40_CBC_MD5 "EXP-KRB5-DES-CBC-MD5" +# define SSL3_TXT_KRB5_RC2_40_CBC_MD5 "EXP-KRB5-RC2-CBC-MD5" +# define SSL3_TXT_KRB5_RC4_40_MD5 "EXP-KRB5-RC4-MD5" + +# define SSL3_SSL_SESSION_ID_LENGTH 32 +# define SSL3_MAX_SSL_SESSION_ID_LENGTH 32 + +# define SSL3_MASTER_SECRET_SIZE 48 +# define SSL3_RANDOM_SIZE 32 +# define SSL3_SESSION_ID_SIZE 32 +# define SSL3_RT_HEADER_LENGTH 5 + +# define SSL3_HM_HEADER_LENGTH 4 + +# ifndef SSL3_ALIGN_PAYLOAD + /* + * Some will argue that this increases memory footprint, but it's not + * actually true. Point is that malloc has to return at least 64-bit aligned + * pointers, meaning that allocating 5 bytes wastes 3 bytes in either case. + * Suggested pre-gaping simply moves these wasted bytes from the end of + * allocated region to its front, but makes data payload aligned, which + * improves performance:-) + */ +# define SSL3_ALIGN_PAYLOAD 8 +# else +# if (SSL3_ALIGN_PAYLOAD&(SSL3_ALIGN_PAYLOAD-1))!=0 +# error "insane SSL3_ALIGN_PAYLOAD" +# undef SSL3_ALIGN_PAYLOAD +# endif +# endif + +/* + * This is the maximum MAC (digest) size used by the SSL library. Currently + * maximum of 20 is used by SHA1, but we reserve for future extension for + * 512-bit hashes. + */ + +# define SSL3_RT_MAX_MD_SIZE 64 + +/* + * Maximum block size used in all ciphersuites. Currently 16 for AES. + */ + +# define SSL_RT_MAX_CIPHER_BLOCK_SIZE 16 + +# define SSL3_RT_MAX_EXTRA (16384) + +/* Maximum plaintext length: defined by SSL/TLS standards */ +# define SSL3_RT_MAX_PLAIN_LENGTH 16384 +/* Maximum compression overhead: defined by SSL/TLS standards */ +# define SSL3_RT_MAX_COMPRESSED_OVERHEAD 1024 + +/* + * The standards give a maximum encryption overhead of 1024 bytes. In + * practice the value is lower than this. The overhead is the maximum number + * of padding bytes (256) plus the mac size. + */ +# define SSL3_RT_MAX_ENCRYPTED_OVERHEAD (256 + SSL3_RT_MAX_MD_SIZE) + +/* + * OpenSSL currently only uses a padding length of at most one block so the + * send overhead is smaller. + */ + +# define SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD \ + (SSL_RT_MAX_CIPHER_BLOCK_SIZE + SSL3_RT_MAX_MD_SIZE) + +/* If compression isn't used don't include the compression overhead */ + +# ifdef OPENSSL_NO_COMP +# define SSL3_RT_MAX_COMPRESSED_LENGTH SSL3_RT_MAX_PLAIN_LENGTH +# else +# define SSL3_RT_MAX_COMPRESSED_LENGTH \ + (SSL3_RT_MAX_PLAIN_LENGTH+SSL3_RT_MAX_COMPRESSED_OVERHEAD) +# endif +# define SSL3_RT_MAX_ENCRYPTED_LENGTH \ + (SSL3_RT_MAX_ENCRYPTED_OVERHEAD+SSL3_RT_MAX_COMPRESSED_LENGTH) +# define SSL3_RT_MAX_PACKET_SIZE \ + (SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH) + +# define SSL3_MD_CLIENT_FINISHED_CONST "\x43\x4C\x4E\x54" +# define SSL3_MD_SERVER_FINISHED_CONST "\x53\x52\x56\x52" + +# define SSL3_VERSION 0x0300 +# define SSL3_VERSION_MAJOR 0x03 +# define SSL3_VERSION_MINOR 0x00 + +# define SSL3_RT_CHANGE_CIPHER_SPEC 20 +# define SSL3_RT_ALERT 21 +# define SSL3_RT_HANDSHAKE 22 +# define SSL3_RT_APPLICATION_DATA 23 +# define TLS1_RT_HEARTBEAT 24 + +/* Pseudo content types to indicate additional parameters */ +# define TLS1_RT_CRYPTO 0x1000 +# define TLS1_RT_CRYPTO_PREMASTER (TLS1_RT_CRYPTO | 0x1) +# define TLS1_RT_CRYPTO_CLIENT_RANDOM (TLS1_RT_CRYPTO | 0x2) +# define TLS1_RT_CRYPTO_SERVER_RANDOM (TLS1_RT_CRYPTO | 0x3) +# define TLS1_RT_CRYPTO_MASTER (TLS1_RT_CRYPTO | 0x4) + +# define TLS1_RT_CRYPTO_READ 0x0000 +# define TLS1_RT_CRYPTO_WRITE 0x0100 +# define TLS1_RT_CRYPTO_MAC (TLS1_RT_CRYPTO | 0x5) +# define TLS1_RT_CRYPTO_KEY (TLS1_RT_CRYPTO | 0x6) +# define TLS1_RT_CRYPTO_IV (TLS1_RT_CRYPTO | 0x7) +# define TLS1_RT_CRYPTO_FIXED_IV (TLS1_RT_CRYPTO | 0x8) + +/* Pseudo content type for SSL/TLS header info */ +# define SSL3_RT_HEADER 0x100 + +# define SSL3_AL_WARNING 1 +# define SSL3_AL_FATAL 2 + +# define SSL3_AD_CLOSE_NOTIFY 0 +# define SSL3_AD_UNEXPECTED_MESSAGE 10/* fatal */ +# define SSL3_AD_BAD_RECORD_MAC 20/* fatal */ +# define SSL3_AD_DECOMPRESSION_FAILURE 30/* fatal */ +# define SSL3_AD_HANDSHAKE_FAILURE 40/* fatal */ +# define SSL3_AD_NO_CERTIFICATE 41 +# define SSL3_AD_BAD_CERTIFICATE 42 +# define SSL3_AD_UNSUPPORTED_CERTIFICATE 43 +# define SSL3_AD_CERTIFICATE_REVOKED 44 +# define SSL3_AD_CERTIFICATE_EXPIRED 45 +# define SSL3_AD_CERTIFICATE_UNKNOWN 46 +# define SSL3_AD_ILLEGAL_PARAMETER 47/* fatal */ + +# define TLS1_HB_REQUEST 1 +# define TLS1_HB_RESPONSE 2 + +# ifndef OPENSSL_NO_SSL_INTERN + +typedef struct ssl3_record_st { + /* type of record */ + /* + * r + */ int type; + /* How many bytes available */ + /* + * rw + */ unsigned int length; + /* read/write offset into 'buf' */ + /* + * r + */ unsigned int off; + /* pointer to the record data */ + /* + * rw + */ unsigned char *data; + /* where the decode bytes are */ + /* + * rw + */ unsigned char *input; + /* only used with decompression - malloc()ed */ + /* + * r + */ unsigned char *comp; + /* epoch number, needed by DTLS1 */ + /* + * r + */ unsigned long epoch; + /* sequence number, needed by DTLS1 */ + /* + * r + */ unsigned char seq_num[8]; +} SSL3_RECORD; + +typedef struct ssl3_buffer_st { + /* at least SSL3_RT_MAX_PACKET_SIZE bytes, see ssl3_setup_buffers() */ + unsigned char *buf; + /* buffer size */ + size_t len; + /* where to 'copy from' */ + int offset; + /* how many bytes left */ + int left; +} SSL3_BUFFER; + +# endif + +# define SSL3_CT_RSA_SIGN 1 +# define SSL3_CT_DSS_SIGN 2 +# define SSL3_CT_RSA_FIXED_DH 3 +# define SSL3_CT_DSS_FIXED_DH 4 +# define SSL3_CT_RSA_EPHEMERAL_DH 5 +# define SSL3_CT_DSS_EPHEMERAL_DH 6 +# define SSL3_CT_FORTEZZA_DMS 20 +/* + * SSL3_CT_NUMBER is used to size arrays and it must be large enough to + * contain all of the cert types defined either for SSLv3 and TLSv1. + */ +# define SSL3_CT_NUMBER 9 + +# define SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS 0x0001 +# define SSL3_FLAGS_DELAY_CLIENT_FINISHED 0x0002 +# define SSL3_FLAGS_POP_BUFFER 0x0004 +# define TLS1_FLAGS_TLS_PADDING_BUG 0x0008 +# define TLS1_FLAGS_SKIP_CERT_VERIFY 0x0010 +# define TLS1_FLAGS_KEEP_HANDSHAKE 0x0020 +/* + * Set when the handshake is ready to process peer's ChangeCipherSpec message. + * Cleared after the message has been processed. + */ +# define SSL3_FLAGS_CCS_OK 0x0080 + +/* SSL3_FLAGS_SGC_RESTART_DONE is no longer used */ +# define SSL3_FLAGS_SGC_RESTART_DONE 0x0040 + +# ifndef OPENSSL_NO_SSL_INTERN + +typedef struct ssl3_state_st { + long flags; + int delay_buf_pop_ret; + unsigned char read_sequence[8]; + int read_mac_secret_size; + unsigned char read_mac_secret[EVP_MAX_MD_SIZE]; + unsigned char write_sequence[8]; + int write_mac_secret_size; + unsigned char write_mac_secret[EVP_MAX_MD_SIZE]; + unsigned char server_random[SSL3_RANDOM_SIZE]; + unsigned char client_random[SSL3_RANDOM_SIZE]; + /* flags for countermeasure against known-IV weakness */ + int need_empty_fragments; + int empty_fragment_done; + /* The value of 'extra' when the buffers were initialized */ + int init_extra; + SSL3_BUFFER rbuf; /* read IO goes into here */ + SSL3_BUFFER wbuf; /* write IO goes into here */ + SSL3_RECORD rrec; /* each decoded record goes in here */ + SSL3_RECORD wrec; /* goes out from here */ + /* + * storage for Alert/Handshake protocol data received but not yet + * processed by ssl3_read_bytes: + */ + unsigned char alert_fragment[2]; + unsigned int alert_fragment_len; + unsigned char handshake_fragment[4]; + unsigned int handshake_fragment_len; + /* partial write - check the numbers match */ + unsigned int wnum; /* number of bytes sent so far */ + int wpend_tot; /* number bytes written */ + int wpend_type; + int wpend_ret; /* number of bytes submitted */ + const unsigned char *wpend_buf; + /* used during startup, digest all incoming/outgoing packets */ + BIO *handshake_buffer; + /* + * When set of handshake digests is determined, buffer is hashed and + * freed and MD_CTX-es for all required digests are stored in this array + */ + EVP_MD_CTX **handshake_dgst; + /* + * Set whenever an expected ChangeCipherSpec message is processed. + * Unset when the peer's Finished message is received. + * Unexpected ChangeCipherSpec messages trigger a fatal alert. + */ + int change_cipher_spec; + int warn_alert; + int fatal_alert; + /* + * we allow one fatal and one warning alert to be outstanding, send close + * alert via the warning alert + */ + int alert_dispatch; + unsigned char send_alert[2]; + /* + * This flag is set when we should renegotiate ASAP, basically when there + * is no more data in the read or write buffers + */ + int renegotiate; + int total_renegotiations; + int num_renegotiations; + int in_read_app_data; + /* + * Opaque PRF input as used for the current handshake. These fields are + * used only if TLSEXT_TYPE_opaque_prf_input is defined (otherwise, they + * are merely present to improve binary compatibility) + */ + void *client_opaque_prf_input; + size_t client_opaque_prf_input_len; + void *server_opaque_prf_input; + size_t server_opaque_prf_input_len; + struct { + /* actually only needs to be 16+20 */ + unsigned char cert_verify_md[EVP_MAX_MD_SIZE * 2]; + /* actually only need to be 16+20 for SSLv3 and 12 for TLS */ + unsigned char finish_md[EVP_MAX_MD_SIZE * 2]; + int finish_md_len; + unsigned char peer_finish_md[EVP_MAX_MD_SIZE * 2]; + int peer_finish_md_len; + unsigned long message_size; + int message_type; + /* used to hold the new cipher we are going to use */ + const SSL_CIPHER *new_cipher; +# ifndef OPENSSL_NO_DH + DH *dh; +# endif +# ifndef OPENSSL_NO_ECDH + EC_KEY *ecdh; /* holds short lived ECDH key */ +# endif + /* used when SSL_ST_FLUSH_DATA is entered */ + int next_state; + int reuse_message; + /* used for certificate requests */ + int cert_req; + int ctype_num; + char ctype[SSL3_CT_NUMBER]; + STACK_OF(X509_NAME) *ca_names; + int use_rsa_tmp; + int key_block_length; + unsigned char *key_block; + const EVP_CIPHER *new_sym_enc; + const EVP_MD *new_hash; + int new_mac_pkey_type; + int new_mac_secret_size; +# ifndef OPENSSL_NO_COMP + const SSL_COMP *new_compression; +# else + char *new_compression; +# endif + int cert_request; + } tmp; + + /* Connection binding to prevent renegotiation attacks */ + unsigned char previous_client_finished[EVP_MAX_MD_SIZE]; + unsigned char previous_client_finished_len; + unsigned char previous_server_finished[EVP_MAX_MD_SIZE]; + unsigned char previous_server_finished_len; + int send_connection_binding; /* TODOEKR */ + +# ifndef OPENSSL_NO_NEXTPROTONEG + /* + * Set if we saw the Next Protocol Negotiation extension from our peer. + */ + int next_proto_neg_seen; +# endif + +# ifndef OPENSSL_NO_TLSEXT +# ifndef OPENSSL_NO_EC + /* + * This is set to true if we believe that this is a version of Safari + * running on OS X 10.6 or newer. We wish to know this because Safari on + * 10.8 .. 10.8.3 has broken ECDHE-ECDSA support. + */ + char is_probably_safari; +# endif /* !OPENSSL_NO_EC */ + + /* + * ALPN information (we are in the process of transitioning from NPN to + * ALPN.) + */ + + /* + * In a server these point to the selected ALPN protocol after the + * ClientHello has been processed. In a client these contain the protocol + * that the server selected once the ServerHello has been processed. + */ + unsigned char *alpn_selected; + unsigned alpn_selected_len; +# endif /* OPENSSL_NO_TLSEXT */ +} SSL3_STATE; + +# endif + +/* SSLv3 */ +/* + * client + */ +/* extra state */ +# define SSL3_ST_CW_FLUSH (0x100|SSL_ST_CONNECT) +# ifndef OPENSSL_NO_SCTP +# define DTLS1_SCTP_ST_CW_WRITE_SOCK (0x310|SSL_ST_CONNECT) +# define DTLS1_SCTP_ST_CR_READ_SOCK (0x320|SSL_ST_CONNECT) +# endif +/* write to server */ +# define SSL3_ST_CW_CLNT_HELLO_A (0x110|SSL_ST_CONNECT) +# define SSL3_ST_CW_CLNT_HELLO_B (0x111|SSL_ST_CONNECT) +/* read from server */ +# define SSL3_ST_CR_SRVR_HELLO_A (0x120|SSL_ST_CONNECT) +# define SSL3_ST_CR_SRVR_HELLO_B (0x121|SSL_ST_CONNECT) +# define DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A (0x126|SSL_ST_CONNECT) +# define DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B (0x127|SSL_ST_CONNECT) +# define SSL3_ST_CR_CERT_A (0x130|SSL_ST_CONNECT) +# define SSL3_ST_CR_CERT_B (0x131|SSL_ST_CONNECT) +# define SSL3_ST_CR_KEY_EXCH_A (0x140|SSL_ST_CONNECT) +# define SSL3_ST_CR_KEY_EXCH_B (0x141|SSL_ST_CONNECT) +# define SSL3_ST_CR_CERT_REQ_A (0x150|SSL_ST_CONNECT) +# define SSL3_ST_CR_CERT_REQ_B (0x151|SSL_ST_CONNECT) +# define SSL3_ST_CR_SRVR_DONE_A (0x160|SSL_ST_CONNECT) +# define SSL3_ST_CR_SRVR_DONE_B (0x161|SSL_ST_CONNECT) +/* write to server */ +# define SSL3_ST_CW_CERT_A (0x170|SSL_ST_CONNECT) +# define SSL3_ST_CW_CERT_B (0x171|SSL_ST_CONNECT) +# define SSL3_ST_CW_CERT_C (0x172|SSL_ST_CONNECT) +# define SSL3_ST_CW_CERT_D (0x173|SSL_ST_CONNECT) +# define SSL3_ST_CW_KEY_EXCH_A (0x180|SSL_ST_CONNECT) +# define SSL3_ST_CW_KEY_EXCH_B (0x181|SSL_ST_CONNECT) +# define SSL3_ST_CW_CERT_VRFY_A (0x190|SSL_ST_CONNECT) +# define SSL3_ST_CW_CERT_VRFY_B (0x191|SSL_ST_CONNECT) +# define SSL3_ST_CW_CHANGE_A (0x1A0|SSL_ST_CONNECT) +# define SSL3_ST_CW_CHANGE_B (0x1A1|SSL_ST_CONNECT) +# ifndef OPENSSL_NO_NEXTPROTONEG +# define SSL3_ST_CW_NEXT_PROTO_A (0x200|SSL_ST_CONNECT) +# define SSL3_ST_CW_NEXT_PROTO_B (0x201|SSL_ST_CONNECT) +# endif +# define SSL3_ST_CW_FINISHED_A (0x1B0|SSL_ST_CONNECT) +# define SSL3_ST_CW_FINISHED_B (0x1B1|SSL_ST_CONNECT) +/* read from server */ +# define SSL3_ST_CR_CHANGE_A (0x1C0|SSL_ST_CONNECT) +# define SSL3_ST_CR_CHANGE_B (0x1C1|SSL_ST_CONNECT) +# define SSL3_ST_CR_FINISHED_A (0x1D0|SSL_ST_CONNECT) +# define SSL3_ST_CR_FINISHED_B (0x1D1|SSL_ST_CONNECT) +# define SSL3_ST_CR_SESSION_TICKET_A (0x1E0|SSL_ST_CONNECT) +# define SSL3_ST_CR_SESSION_TICKET_B (0x1E1|SSL_ST_CONNECT) +# define SSL3_ST_CR_CERT_STATUS_A (0x1F0|SSL_ST_CONNECT) +# define SSL3_ST_CR_CERT_STATUS_B (0x1F1|SSL_ST_CONNECT) + +/* server */ +/* extra state */ +# define SSL3_ST_SW_FLUSH (0x100|SSL_ST_ACCEPT) +# ifndef OPENSSL_NO_SCTP +# define DTLS1_SCTP_ST_SW_WRITE_SOCK (0x310|SSL_ST_ACCEPT) +# define DTLS1_SCTP_ST_SR_READ_SOCK (0x320|SSL_ST_ACCEPT) +# endif +/* read from client */ +/* Do not change the number values, they do matter */ +# define SSL3_ST_SR_CLNT_HELLO_A (0x110|SSL_ST_ACCEPT) +# define SSL3_ST_SR_CLNT_HELLO_B (0x111|SSL_ST_ACCEPT) +# define SSL3_ST_SR_CLNT_HELLO_C (0x112|SSL_ST_ACCEPT) +# define SSL3_ST_SR_CLNT_HELLO_D (0x115|SSL_ST_ACCEPT) +/* write to client */ +# define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A (0x113|SSL_ST_ACCEPT) +# define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B (0x114|SSL_ST_ACCEPT) +# define SSL3_ST_SW_HELLO_REQ_A (0x120|SSL_ST_ACCEPT) +# define SSL3_ST_SW_HELLO_REQ_B (0x121|SSL_ST_ACCEPT) +# define SSL3_ST_SW_HELLO_REQ_C (0x122|SSL_ST_ACCEPT) +# define SSL3_ST_SW_SRVR_HELLO_A (0x130|SSL_ST_ACCEPT) +# define SSL3_ST_SW_SRVR_HELLO_B (0x131|SSL_ST_ACCEPT) +# define SSL3_ST_SW_CERT_A (0x140|SSL_ST_ACCEPT) +# define SSL3_ST_SW_CERT_B (0x141|SSL_ST_ACCEPT) +# define SSL3_ST_SW_KEY_EXCH_A (0x150|SSL_ST_ACCEPT) +# define SSL3_ST_SW_KEY_EXCH_B (0x151|SSL_ST_ACCEPT) +# define SSL3_ST_SW_CERT_REQ_A (0x160|SSL_ST_ACCEPT) +# define SSL3_ST_SW_CERT_REQ_B (0x161|SSL_ST_ACCEPT) +# define SSL3_ST_SW_SRVR_DONE_A (0x170|SSL_ST_ACCEPT) +# define SSL3_ST_SW_SRVR_DONE_B (0x171|SSL_ST_ACCEPT) +/* read from client */ +# define SSL3_ST_SR_CERT_A (0x180|SSL_ST_ACCEPT) +# define SSL3_ST_SR_CERT_B (0x181|SSL_ST_ACCEPT) +# define SSL3_ST_SR_KEY_EXCH_A (0x190|SSL_ST_ACCEPT) +# define SSL3_ST_SR_KEY_EXCH_B (0x191|SSL_ST_ACCEPT) +# define SSL3_ST_SR_CERT_VRFY_A (0x1A0|SSL_ST_ACCEPT) +# define SSL3_ST_SR_CERT_VRFY_B (0x1A1|SSL_ST_ACCEPT) +# define SSL3_ST_SR_CHANGE_A (0x1B0|SSL_ST_ACCEPT) +# define SSL3_ST_SR_CHANGE_B (0x1B1|SSL_ST_ACCEPT) +# ifndef OPENSSL_NO_NEXTPROTONEG +# define SSL3_ST_SR_NEXT_PROTO_A (0x210|SSL_ST_ACCEPT) +# define SSL3_ST_SR_NEXT_PROTO_B (0x211|SSL_ST_ACCEPT) +# endif +# define SSL3_ST_SR_FINISHED_A (0x1C0|SSL_ST_ACCEPT) +# define SSL3_ST_SR_FINISHED_B (0x1C1|SSL_ST_ACCEPT) +/* write to client */ +# define SSL3_ST_SW_CHANGE_A (0x1D0|SSL_ST_ACCEPT) +# define SSL3_ST_SW_CHANGE_B (0x1D1|SSL_ST_ACCEPT) +# define SSL3_ST_SW_FINISHED_A (0x1E0|SSL_ST_ACCEPT) +# define SSL3_ST_SW_FINISHED_B (0x1E1|SSL_ST_ACCEPT) +# define SSL3_ST_SW_SESSION_TICKET_A (0x1F0|SSL_ST_ACCEPT) +# define SSL3_ST_SW_SESSION_TICKET_B (0x1F1|SSL_ST_ACCEPT) +# define SSL3_ST_SW_CERT_STATUS_A (0x200|SSL_ST_ACCEPT) +# define SSL3_ST_SW_CERT_STATUS_B (0x201|SSL_ST_ACCEPT) + +# define SSL3_MT_HELLO_REQUEST 0 +# define SSL3_MT_CLIENT_HELLO 1 +# define SSL3_MT_SERVER_HELLO 2 +# define SSL3_MT_NEWSESSION_TICKET 4 +# define SSL3_MT_CERTIFICATE 11 +# define SSL3_MT_SERVER_KEY_EXCHANGE 12 +# define SSL3_MT_CERTIFICATE_REQUEST 13 +# define SSL3_MT_SERVER_DONE 14 +# define SSL3_MT_CERTIFICATE_VERIFY 15 +# define SSL3_MT_CLIENT_KEY_EXCHANGE 16 +# define SSL3_MT_FINISHED 20 +# define SSL3_MT_CERTIFICATE_STATUS 22 +# ifndef OPENSSL_NO_NEXTPROTONEG +# define SSL3_MT_NEXT_PROTO 67 +# endif +# define DTLS1_MT_HELLO_VERIFY_REQUEST 3 + +# define SSL3_MT_CCS 1 + +/* These are used when changing over to a new cipher */ +# define SSL3_CC_READ 0x01 +# define SSL3_CC_WRITE 0x02 +# define SSL3_CC_CLIENT 0x10 +# define SSL3_CC_SERVER 0x20 +# define SSL3_CHANGE_CIPHER_CLIENT_WRITE (SSL3_CC_CLIENT|SSL3_CC_WRITE) +# define SSL3_CHANGE_CIPHER_SERVER_READ (SSL3_CC_SERVER|SSL3_CC_READ) +# define SSL3_CHANGE_CIPHER_CLIENT_READ (SSL3_CC_CLIENT|SSL3_CC_READ) +# define SSL3_CHANGE_CIPHER_SERVER_WRITE (SSL3_CC_SERVER|SSL3_CC_WRITE) + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/stack.h b/OSlibs/ios/include/openssl/stack.h new file mode 100755 index 000000000..eb0721665 --- /dev/null +++ b/OSlibs/ios/include/openssl/stack.h @@ -0,0 +1,107 @@ +/* crypto/stack/stack.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_STACK_H +# define HEADER_STACK_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct stack_st { + int num; + char **data; + int sorted; + int num_alloc; + int (*comp) (const void *, const void *); +} _STACK; /* Use STACK_OF(...) instead */ + +# define M_sk_num(sk) ((sk) ? (sk)->num:-1) +# define M_sk_value(sk,n) ((sk) ? (sk)->data[n] : NULL) + +int sk_num(const _STACK *); +void *sk_value(const _STACK *, int); + +void *sk_set(_STACK *, int, void *); + +_STACK *sk_new(int (*cmp) (const void *, const void *)); +_STACK *sk_new_null(void); +void sk_free(_STACK *); +void sk_pop_free(_STACK *st, void (*func) (void *)); +_STACK *sk_deep_copy(_STACK *, void *(*)(void *), void (*)(void *)); +int sk_insert(_STACK *sk, void *data, int where); +void *sk_delete(_STACK *st, int loc); +void *sk_delete_ptr(_STACK *st, void *p); +int sk_find(_STACK *st, void *data); +int sk_find_ex(_STACK *st, void *data); +int sk_push(_STACK *st, void *data); +int sk_unshift(_STACK *st, void *data); +void *sk_shift(_STACK *st); +void *sk_pop(_STACK *st); +void sk_zero(_STACK *st); +int (*sk_set_cmp_func(_STACK *sk, int (*c) (const void *, const void *))) + (const void *, const void *); +_STACK *sk_dup(_STACK *st); +void sk_sort(_STACK *st); +int sk_is_sorted(const _STACK *st); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/OSlibs/ios/include/openssl/symhacks.h b/OSlibs/ios/include/openssl/symhacks.h new file mode 100755 index 000000000..239fa4fb1 --- /dev/null +++ b/OSlibs/ios/include/openssl/symhacks.h @@ -0,0 +1,516 @@ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_SYMHACKS_H +# define HEADER_SYMHACKS_H + +# include + +/* + * Hacks to solve the problem with linkers incapable of handling very long + * symbol names. In the case of VMS, the limit is 31 characters on VMS for + * VAX. + */ +/* + * Note that this affects util/libeay.num and util/ssleay.num... you may + * change those manually, but that's not recommended, as those files are + * controlled centrally and updated on Unix, and the central definition may + * disagree with yours, which in turn may come with shareable library + * incompatibilities. + */ +# ifdef OPENSSL_SYS_VMS + +/* Hack a long name in crypto/ex_data.c */ +# undef CRYPTO_get_ex_data_implementation +# define CRYPTO_get_ex_data_implementation CRYPTO_get_ex_data_impl +# undef CRYPTO_set_ex_data_implementation +# define CRYPTO_set_ex_data_implementation CRYPTO_set_ex_data_impl + +/* Hack a long name in crypto/asn1/a_mbstr.c */ +# undef ASN1_STRING_set_default_mask_asc +# define ASN1_STRING_set_default_mask_asc ASN1_STRING_set_def_mask_asc + +# if 0 /* No longer needed, since safestack macro + * magic does the job */ +/* Hack the names created with DECLARE_ASN1_SET_OF(PKCS7_SIGNER_INFO) */ +# undef i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO +# define i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO i2d_ASN1_SET_OF_PKCS7_SIGINF +# undef d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO +# define d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO d2i_ASN1_SET_OF_PKCS7_SIGINF +# endif + +# if 0 /* No longer needed, since safestack macro + * magic does the job */ +/* Hack the names created with DECLARE_ASN1_SET_OF(PKCS7_RECIP_INFO) */ +# undef i2d_ASN1_SET_OF_PKCS7_RECIP_INFO +# define i2d_ASN1_SET_OF_PKCS7_RECIP_INFO i2d_ASN1_SET_OF_PKCS7_RECINF +# undef d2i_ASN1_SET_OF_PKCS7_RECIP_INFO +# define d2i_ASN1_SET_OF_PKCS7_RECIP_INFO d2i_ASN1_SET_OF_PKCS7_RECINF +# endif + +# if 0 /* No longer needed, since safestack macro + * magic does the job */ +/* Hack the names created with DECLARE_ASN1_SET_OF(ACCESS_DESCRIPTION) */ +# undef i2d_ASN1_SET_OF_ACCESS_DESCRIPTION +# define i2d_ASN1_SET_OF_ACCESS_DESCRIPTION i2d_ASN1_SET_OF_ACC_DESC +# undef d2i_ASN1_SET_OF_ACCESS_DESCRIPTION +# define d2i_ASN1_SET_OF_ACCESS_DESCRIPTION d2i_ASN1_SET_OF_ACC_DESC +# endif + +/* Hack the names created with DECLARE_PEM_rw(NETSCAPE_CERT_SEQUENCE) */ +# undef PEM_read_NETSCAPE_CERT_SEQUENCE +# define PEM_read_NETSCAPE_CERT_SEQUENCE PEM_read_NS_CERT_SEQ +# undef PEM_write_NETSCAPE_CERT_SEQUENCE +# define PEM_write_NETSCAPE_CERT_SEQUENCE PEM_write_NS_CERT_SEQ +# undef PEM_read_bio_NETSCAPE_CERT_SEQUENCE +# define PEM_read_bio_NETSCAPE_CERT_SEQUENCE PEM_read_bio_NS_CERT_SEQ +# undef PEM_write_bio_NETSCAPE_CERT_SEQUENCE +# define PEM_write_bio_NETSCAPE_CERT_SEQUENCE PEM_write_bio_NS_CERT_SEQ +# undef PEM_write_cb_bio_NETSCAPE_CERT_SEQUENCE +# define PEM_write_cb_bio_NETSCAPE_CERT_SEQUENCE PEM_write_cb_bio_NS_CERT_SEQ + +/* Hack the names created with DECLARE_PEM_rw(PKCS8_PRIV_KEY_INFO) */ +# undef PEM_read_PKCS8_PRIV_KEY_INFO +# define PEM_read_PKCS8_PRIV_KEY_INFO PEM_read_P8_PRIV_KEY_INFO +# undef PEM_write_PKCS8_PRIV_KEY_INFO +# define PEM_write_PKCS8_PRIV_KEY_INFO PEM_write_P8_PRIV_KEY_INFO +# undef PEM_read_bio_PKCS8_PRIV_KEY_INFO +# define PEM_read_bio_PKCS8_PRIV_KEY_INFO PEM_read_bio_P8_PRIV_KEY_INFO +# undef PEM_write_bio_PKCS8_PRIV_KEY_INFO +# define PEM_write_bio_PKCS8_PRIV_KEY_INFO PEM_write_bio_P8_PRIV_KEY_INFO +# undef PEM_write_cb_bio_PKCS8_PRIV_KEY_INFO +# define PEM_write_cb_bio_PKCS8_PRIV_KEY_INFO PEM_wrt_cb_bio_P8_PRIV_KEY_INFO + +/* Hack other PEM names */ +# undef PEM_write_bio_PKCS8PrivateKey_nid +# define PEM_write_bio_PKCS8PrivateKey_nid PEM_write_bio_PKCS8PrivKey_nid + +/* Hack some long X509 names */ +# undef X509_REVOKED_get_ext_by_critical +# define X509_REVOKED_get_ext_by_critical X509_REVOKED_get_ext_by_critic +# undef X509_policy_tree_get0_user_policies +# define X509_policy_tree_get0_user_policies X509_pcy_tree_get0_usr_policies +# undef X509_policy_node_get0_qualifiers +# define X509_policy_node_get0_qualifiers X509_pcy_node_get0_qualifiers +# undef X509_STORE_CTX_get_explicit_policy +# define X509_STORE_CTX_get_explicit_policy X509_STORE_CTX_get_expl_policy +# undef X509_STORE_CTX_get0_current_issuer +# define X509_STORE_CTX_get0_current_issuer X509_STORE_CTX_get0_cur_issuer + +/* Hack some long CRYPTO names */ +# undef CRYPTO_set_dynlock_destroy_callback +# define CRYPTO_set_dynlock_destroy_callback CRYPTO_set_dynlock_destroy_cb +# undef CRYPTO_set_dynlock_create_callback +# define CRYPTO_set_dynlock_create_callback CRYPTO_set_dynlock_create_cb +# undef CRYPTO_set_dynlock_lock_callback +# define CRYPTO_set_dynlock_lock_callback CRYPTO_set_dynlock_lock_cb +# undef CRYPTO_get_dynlock_lock_callback +# define CRYPTO_get_dynlock_lock_callback CRYPTO_get_dynlock_lock_cb +# undef CRYPTO_get_dynlock_destroy_callback +# define CRYPTO_get_dynlock_destroy_callback CRYPTO_get_dynlock_destroy_cb +# undef CRYPTO_get_dynlock_create_callback +# define CRYPTO_get_dynlock_create_callback CRYPTO_get_dynlock_create_cb +# undef CRYPTO_set_locked_mem_ex_functions +# define CRYPTO_set_locked_mem_ex_functions CRYPTO_set_locked_mem_ex_funcs +# undef CRYPTO_get_locked_mem_ex_functions +# define CRYPTO_get_locked_mem_ex_functions CRYPTO_get_locked_mem_ex_funcs + +/* Hack some long SSL/TLS names */ +# undef SSL_CTX_set_default_verify_paths +# define SSL_CTX_set_default_verify_paths SSL_CTX_set_def_verify_paths +# undef SSL_get_ex_data_X509_STORE_CTX_idx +# define SSL_get_ex_data_X509_STORE_CTX_idx SSL_get_ex_d_X509_STORE_CTX_idx +# undef SSL_add_file_cert_subjects_to_stack +# define SSL_add_file_cert_subjects_to_stack SSL_add_file_cert_subjs_to_stk +# undef SSL_add_dir_cert_subjects_to_stack +# define SSL_add_dir_cert_subjects_to_stack SSL_add_dir_cert_subjs_to_stk +# undef SSL_CTX_use_certificate_chain_file +# define SSL_CTX_use_certificate_chain_file SSL_CTX_use_cert_chain_file +# undef SSL_CTX_set_cert_verify_callback +# define SSL_CTX_set_cert_verify_callback SSL_CTX_set_cert_verify_cb +# undef SSL_CTX_set_default_passwd_cb_userdata +# define SSL_CTX_set_default_passwd_cb_userdata SSL_CTX_set_def_passwd_cb_ud +# undef SSL_COMP_get_compression_methods +# define SSL_COMP_get_compression_methods SSL_COMP_get_compress_methods +# undef SSL_COMP_set0_compression_methods +# define SSL_COMP_set0_compression_methods SSL_COMP_set0_compress_methods +# undef SSL_COMP_free_compression_methods +# define SSL_COMP_free_compression_methods SSL_COMP_free_compress_methods +# undef ssl_add_clienthello_renegotiate_ext +# define ssl_add_clienthello_renegotiate_ext ssl_add_clienthello_reneg_ext +# undef ssl_add_serverhello_renegotiate_ext +# define ssl_add_serverhello_renegotiate_ext ssl_add_serverhello_reneg_ext +# undef ssl_parse_clienthello_renegotiate_ext +# define ssl_parse_clienthello_renegotiate_ext ssl_parse_clienthello_reneg_ext +# undef ssl_parse_serverhello_renegotiate_ext +# define ssl_parse_serverhello_renegotiate_ext ssl_parse_serverhello_reneg_ext +# undef SSL_srp_server_param_with_username +# define SSL_srp_server_param_with_username SSL_srp_server_param_with_un +# undef SSL_CTX_set_srp_client_pwd_callback +# define SSL_CTX_set_srp_client_pwd_callback SSL_CTX_set_srp_client_pwd_cb +# undef SSL_CTX_set_srp_verify_param_callback +# define SSL_CTX_set_srp_verify_param_callback SSL_CTX_set_srp_vfy_param_cb +# undef SSL_CTX_set_srp_username_callback +# define SSL_CTX_set_srp_username_callback SSL_CTX_set_srp_un_cb +# undef ssl_add_clienthello_use_srtp_ext +# define ssl_add_clienthello_use_srtp_ext ssl_add_clihello_use_srtp_ext +# undef ssl_add_serverhello_use_srtp_ext +# define ssl_add_serverhello_use_srtp_ext ssl_add_serhello_use_srtp_ext +# undef ssl_parse_clienthello_use_srtp_ext +# define ssl_parse_clienthello_use_srtp_ext ssl_parse_clihello_use_srtp_ext +# undef ssl_parse_serverhello_use_srtp_ext +# define ssl_parse_serverhello_use_srtp_ext ssl_parse_serhello_use_srtp_ext +# undef SSL_CTX_set_next_protos_advertised_cb +# define SSL_CTX_set_next_protos_advertised_cb SSL_CTX_set_next_protos_adv_cb +# undef SSL_CTX_set_next_proto_select_cb +# define SSL_CTX_set_next_proto_select_cb SSL_CTX_set_next_proto_sel_cb + +# undef tls1_send_server_supplemental_data +# define tls1_send_server_supplemental_data tls1_send_server_suppl_data +# undef tls1_send_client_supplemental_data +# define tls1_send_client_supplemental_data tls1_send_client_suppl_data +# undef tls1_get_server_supplemental_data +# define tls1_get_server_supplemental_data tls1_get_server_suppl_data +# undef tls1_get_client_supplemental_data +# define tls1_get_client_supplemental_data tls1_get_client_suppl_data + +# undef ssl3_cbc_record_digest_supported +# define ssl3_cbc_record_digest_supported ssl3_cbc_record_digest_support +# undef ssl_check_clienthello_tlsext_late +# define ssl_check_clienthello_tlsext_late ssl_check_clihello_tlsext_late +# undef ssl_check_clienthello_tlsext_early +# define ssl_check_clienthello_tlsext_early ssl_check_clihello_tlsext_early + +/* Hack some RSA long names */ +# undef RSA_padding_check_PKCS1_OAEP_mgf1 +# define RSA_padding_check_PKCS1_OAEP_mgf1 RSA_pad_check_PKCS1_OAEP_mgf1 + +/* Hack some ENGINE long names */ +# undef ENGINE_get_default_BN_mod_exp_crt +# define ENGINE_get_default_BN_mod_exp_crt ENGINE_get_def_BN_mod_exp_crt +# undef ENGINE_set_default_BN_mod_exp_crt +# define ENGINE_set_default_BN_mod_exp_crt ENGINE_set_def_BN_mod_exp_crt +# undef ENGINE_set_load_privkey_function +# define ENGINE_set_load_privkey_function ENGINE_set_load_privkey_fn +# undef ENGINE_get_load_privkey_function +# define ENGINE_get_load_privkey_function ENGINE_get_load_privkey_fn +# undef ENGINE_unregister_pkey_asn1_meths +# define ENGINE_unregister_pkey_asn1_meths ENGINE_unreg_pkey_asn1_meths +# undef ENGINE_register_all_pkey_asn1_meths +# define ENGINE_register_all_pkey_asn1_meths ENGINE_reg_all_pkey_asn1_meths +# undef ENGINE_set_default_pkey_asn1_meths +# define ENGINE_set_default_pkey_asn1_meths ENGINE_set_def_pkey_asn1_meths +# undef ENGINE_get_pkey_asn1_meth_engine +# define ENGINE_get_pkey_asn1_meth_engine ENGINE_get_pkey_asn1_meth_eng +# undef ENGINE_set_load_ssl_client_cert_function +# define ENGINE_set_load_ssl_client_cert_function \ + ENGINE_set_ld_ssl_clnt_cert_fn +# undef ENGINE_get_ssl_client_cert_function +# define ENGINE_get_ssl_client_cert_function ENGINE_get_ssl_client_cert_fn + +/* Hack some long OCSP names */ +# undef OCSP_REQUEST_get_ext_by_critical +# define OCSP_REQUEST_get_ext_by_critical OCSP_REQUEST_get_ext_by_crit +# undef OCSP_BASICRESP_get_ext_by_critical +# define OCSP_BASICRESP_get_ext_by_critical OCSP_BASICRESP_get_ext_by_crit +# undef OCSP_SINGLERESP_get_ext_by_critical +# define OCSP_SINGLERESP_get_ext_by_critical OCSP_SINGLERESP_get_ext_by_crit + +/* Hack some long DES names */ +# undef _ossl_old_des_ede3_cfb64_encrypt +# define _ossl_old_des_ede3_cfb64_encrypt _ossl_odes_ede3_cfb64_encrypt +# undef _ossl_old_des_ede3_ofb64_encrypt +# define _ossl_old_des_ede3_ofb64_encrypt _ossl_odes_ede3_ofb64_encrypt + +/* Hack some long EVP names */ +# undef OPENSSL_add_all_algorithms_noconf +# define OPENSSL_add_all_algorithms_noconf OPENSSL_add_all_algo_noconf +# undef OPENSSL_add_all_algorithms_conf +# define OPENSSL_add_all_algorithms_conf OPENSSL_add_all_algo_conf +# undef EVP_PKEY_meth_set_verify_recover +# define EVP_PKEY_meth_set_verify_recover EVP_PKEY_meth_set_vrfy_recover + +/* Hack some long EC names */ +# undef EC_GROUP_set_point_conversion_form +# define EC_GROUP_set_point_conversion_form EC_GROUP_set_point_conv_form +# undef EC_GROUP_get_point_conversion_form +# define EC_GROUP_get_point_conversion_form EC_GROUP_get_point_conv_form +# undef EC_GROUP_clear_free_all_extra_data +# define EC_GROUP_clear_free_all_extra_data EC_GROUP_clr_free_all_xtra_data +# undef EC_KEY_set_public_key_affine_coordinates +# define EC_KEY_set_public_key_affine_coordinates \ + EC_KEY_set_pub_key_aff_coords +# undef EC_POINT_set_Jprojective_coordinates_GFp +# define EC_POINT_set_Jprojective_coordinates_GFp \ + EC_POINT_set_Jproj_coords_GFp +# undef EC_POINT_get_Jprojective_coordinates_GFp +# define EC_POINT_get_Jprojective_coordinates_GFp \ + EC_POINT_get_Jproj_coords_GFp +# undef EC_POINT_set_affine_coordinates_GFp +# define EC_POINT_set_affine_coordinates_GFp EC_POINT_set_affine_coords_GFp +# undef EC_POINT_get_affine_coordinates_GFp +# define EC_POINT_get_affine_coordinates_GFp EC_POINT_get_affine_coords_GFp +# undef EC_POINT_set_compressed_coordinates_GFp +# define EC_POINT_set_compressed_coordinates_GFp EC_POINT_set_compr_coords_GFp +# undef EC_POINT_set_affine_coordinates_GF2m +# define EC_POINT_set_affine_coordinates_GF2m EC_POINT_set_affine_coords_GF2m +# undef EC_POINT_get_affine_coordinates_GF2m +# define EC_POINT_get_affine_coordinates_GF2m EC_POINT_get_affine_coords_GF2m +# undef EC_POINT_set_compressed_coordinates_GF2m +# define EC_POINT_set_compressed_coordinates_GF2m \ + EC_POINT_set_compr_coords_GF2m +# undef ec_GF2m_simple_group_clear_finish +# define ec_GF2m_simple_group_clear_finish ec_GF2m_simple_grp_clr_finish +# undef ec_GF2m_simple_group_check_discriminant +# define ec_GF2m_simple_group_check_discriminant ec_GF2m_simple_grp_chk_discrim +# undef ec_GF2m_simple_point_clear_finish +# define ec_GF2m_simple_point_clear_finish ec_GF2m_simple_pt_clr_finish +# undef ec_GF2m_simple_point_set_to_infinity +# define ec_GF2m_simple_point_set_to_infinity ec_GF2m_simple_pt_set_to_inf +# undef ec_GF2m_simple_points_make_affine +# define ec_GF2m_simple_points_make_affine ec_GF2m_simple_pts_make_affine +# undef ec_GF2m_simple_point_set_affine_coordinates +# define ec_GF2m_simple_point_set_affine_coordinates \ + ec_GF2m_smp_pt_set_af_coords +# undef ec_GF2m_simple_point_get_affine_coordinates +# define ec_GF2m_simple_point_get_affine_coordinates \ + ec_GF2m_smp_pt_get_af_coords +# undef ec_GF2m_simple_set_compressed_coordinates +# define ec_GF2m_simple_set_compressed_coordinates \ + ec_GF2m_smp_set_compr_coords +# undef ec_GFp_simple_group_set_curve_GFp +# define ec_GFp_simple_group_set_curve_GFp ec_GFp_simple_grp_set_curve_GFp +# undef ec_GFp_simple_group_get_curve_GFp +# define ec_GFp_simple_group_get_curve_GFp ec_GFp_simple_grp_get_curve_GFp +# undef ec_GFp_simple_group_clear_finish +# define ec_GFp_simple_group_clear_finish ec_GFp_simple_grp_clear_finish +# undef ec_GFp_simple_group_set_generator +# define ec_GFp_simple_group_set_generator ec_GFp_simple_grp_set_generator +# undef ec_GFp_simple_group_get0_generator +# define ec_GFp_simple_group_get0_generator ec_GFp_simple_grp_gt0_generator +# undef ec_GFp_simple_group_get_cofactor +# define ec_GFp_simple_group_get_cofactor ec_GFp_simple_grp_get_cofactor +# undef ec_GFp_simple_point_clear_finish +# define ec_GFp_simple_point_clear_finish ec_GFp_simple_pt_clear_finish +# undef ec_GFp_simple_point_set_to_infinity +# define ec_GFp_simple_point_set_to_infinity ec_GFp_simple_pt_set_to_inf +# undef ec_GFp_simple_points_make_affine +# define ec_GFp_simple_points_make_affine ec_GFp_simple_pts_make_affine +# undef ec_GFp_simple_set_Jprojective_coordinates_GFp +# define ec_GFp_simple_set_Jprojective_coordinates_GFp \ + ec_GFp_smp_set_Jproj_coords_GFp +# undef ec_GFp_simple_get_Jprojective_coordinates_GFp +# define ec_GFp_simple_get_Jprojective_coordinates_GFp \ + ec_GFp_smp_get_Jproj_coords_GFp +# undef ec_GFp_simple_point_set_affine_coordinates_GFp +# define ec_GFp_simple_point_set_affine_coordinates_GFp \ + ec_GFp_smp_pt_set_af_coords_GFp +# undef ec_GFp_simple_point_get_affine_coordinates_GFp +# define ec_GFp_simple_point_get_affine_coordinates_GFp \ + ec_GFp_smp_pt_get_af_coords_GFp +# undef ec_GFp_simple_set_compressed_coordinates_GFp +# define ec_GFp_simple_set_compressed_coordinates_GFp \ + ec_GFp_smp_set_compr_coords_GFp +# undef ec_GFp_simple_point_set_affine_coordinates +# define ec_GFp_simple_point_set_affine_coordinates \ + ec_GFp_smp_pt_set_af_coords +# undef ec_GFp_simple_point_get_affine_coordinates +# define ec_GFp_simple_point_get_affine_coordinates \ + ec_GFp_smp_pt_get_af_coords +# undef ec_GFp_simple_set_compressed_coordinates +# define ec_GFp_simple_set_compressed_coordinates \ + ec_GFp_smp_set_compr_coords +# undef ec_GFp_simple_group_check_discriminant +# define ec_GFp_simple_group_check_discriminant ec_GFp_simple_grp_chk_discrim + +/* Hack som long STORE names */ +# undef STORE_method_set_initialise_function +# define STORE_method_set_initialise_function STORE_meth_set_initialise_fn +# undef STORE_method_set_cleanup_function +# define STORE_method_set_cleanup_function STORE_meth_set_cleanup_fn +# undef STORE_method_set_generate_function +# define STORE_method_set_generate_function STORE_meth_set_generate_fn +# undef STORE_method_set_modify_function +# define STORE_method_set_modify_function STORE_meth_set_modify_fn +# undef STORE_method_set_revoke_function +# define STORE_method_set_revoke_function STORE_meth_set_revoke_fn +# undef STORE_method_set_delete_function +# define STORE_method_set_delete_function STORE_meth_set_delete_fn +# undef STORE_method_set_list_start_function +# define STORE_method_set_list_start_function STORE_meth_set_list_start_fn +# undef STORE_method_set_list_next_function +# define STORE_method_set_list_next_function STORE_meth_set_list_next_fn +# undef STORE_method_set_list_end_function +# define STORE_method_set_list_end_function STORE_meth_set_list_end_fn +# undef STORE_method_set_update_store_function +# define STORE_method_set_update_store_function STORE_meth_set_update_store_fn +# undef STORE_method_set_lock_store_function +# define STORE_method_set_lock_store_function STORE_meth_set_lock_store_fn +# undef STORE_method_set_unlock_store_function +# define STORE_method_set_unlock_store_function STORE_meth_set_unlock_store_fn +# undef STORE_method_get_initialise_function +# define STORE_method_get_initialise_function STORE_meth_get_initialise_fn +# undef STORE_method_get_cleanup_function +# define STORE_method_get_cleanup_function STORE_meth_get_cleanup_fn +# undef STORE_method_get_generate_function +# define STORE_method_get_generate_function STORE_meth_get_generate_fn +# undef STORE_method_get_modify_function +# define STORE_method_get_modify_function STORE_meth_get_modify_fn +# undef STORE_method_get_revoke_function +# define STORE_method_get_revoke_function STORE_meth_get_revoke_fn +# undef STORE_method_get_delete_function +# define STORE_method_get_delete_function STORE_meth_get_delete_fn +# undef STORE_method_get_list_start_function +# define STORE_method_get_list_start_function STORE_meth_get_list_start_fn +# undef STORE_method_get_list_next_function +# define STORE_method_get_list_next_function STORE_meth_get_list_next_fn +# undef STORE_method_get_list_end_function +# define STORE_method_get_list_end_function STORE_meth_get_list_end_fn +# undef STORE_method_get_update_store_function +# define STORE_method_get_update_store_function STORE_meth_get_update_store_fn +# undef STORE_method_get_lock_store_function +# define STORE_method_get_lock_store_function STORE_meth_get_lock_store_fn +# undef STORE_method_get_unlock_store_function +# define STORE_method_get_unlock_store_function STORE_meth_get_unlock_store_fn + +/* Hack some long TS names */ +# undef TS_RESP_CTX_set_status_info_cond +# define TS_RESP_CTX_set_status_info_cond TS_RESP_CTX_set_stat_info_cond +# undef TS_RESP_CTX_set_clock_precision_digits +# define TS_RESP_CTX_set_clock_precision_digits TS_RESP_CTX_set_clk_prec_digits +# undef TS_CONF_set_clock_precision_digits +# define TS_CONF_set_clock_precision_digits TS_CONF_set_clk_prec_digits + +/* Hack some long CMS names */ +# undef CMS_RecipientInfo_ktri_get0_algs +# define CMS_RecipientInfo_ktri_get0_algs CMS_RecipInfo_ktri_get0_algs +# undef CMS_RecipientInfo_ktri_get0_signer_id +# define CMS_RecipientInfo_ktri_get0_signer_id CMS_RecipInfo_ktri_get0_sigr_id +# undef CMS_OtherRevocationInfoFormat_it +# define CMS_OtherRevocationInfoFormat_it CMS_OtherRevocInfoFormat_it +# undef CMS_KeyAgreeRecipientIdentifier_it +# define CMS_KeyAgreeRecipientIdentifier_it CMS_KeyAgreeRecipIdentifier_it +# undef CMS_OriginatorIdentifierOrKey_it +# define CMS_OriginatorIdentifierOrKey_it CMS_OriginatorIdOrKey_it +# undef cms_SignerIdentifier_get0_signer_id +# define cms_SignerIdentifier_get0_signer_id cms_SignerId_get0_signer_id +# undef CMS_RecipientInfo_kari_get0_orig_id +# define CMS_RecipientInfo_kari_get0_orig_id CMS_RecipInfo_kari_get0_orig_id +# undef CMS_RecipientInfo_kari_get0_reks +# define CMS_RecipientInfo_kari_get0_reks CMS_RecipInfo_kari_get0_reks +# undef CMS_RecipientEncryptedKey_cert_cmp +# define CMS_RecipientEncryptedKey_cert_cmp CMS_RecipEncryptedKey_cert_cmp +# undef CMS_RecipientInfo_kari_set0_pkey +# define CMS_RecipientInfo_kari_set0_pkey CMS_RecipInfo_kari_set0_pkey +# undef CMS_RecipientEncryptedKey_get0_id +# define CMS_RecipientEncryptedKey_get0_id CMS_RecipEncryptedKey_get0_id +# undef CMS_RecipientInfo_kari_orig_id_cmp +# define CMS_RecipientInfo_kari_orig_id_cmp CMS_RecipInfo_kari_orig_id_cmp + +/* Hack some long DTLS1 names */ +# undef dtls1_retransmit_buffered_messages +# define dtls1_retransmit_buffered_messages dtls1_retransmit_buffered_msgs + +/* Hack some long SRP names */ +# undef SRP_generate_server_master_secret +# define SRP_generate_server_master_secret SRP_gen_server_master_secret +# undef SRP_generate_client_master_secret +# define SRP_generate_client_master_secret SRP_gen_client_master_secret + +/* Hack some long UI names */ +# undef UI_method_get_prompt_constructor +# define UI_method_get_prompt_constructor UI_method_get_prompt_constructr +# undef UI_method_set_prompt_constructor +# define UI_method_set_prompt_constructor UI_method_set_prompt_constructr + +# endif /* defined OPENSSL_SYS_VMS */ + +/* Case insensitive linking causes problems.... */ +# if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) +# undef ERR_load_CRYPTO_strings +# define ERR_load_CRYPTO_strings ERR_load_CRYPTOlib_strings +# undef OCSP_crlID_new +# define OCSP_crlID_new OCSP_crlID2_new + +# undef d2i_ECPARAMETERS +# define d2i_ECPARAMETERS d2i_UC_ECPARAMETERS +# undef i2d_ECPARAMETERS +# define i2d_ECPARAMETERS i2d_UC_ECPARAMETERS +# undef d2i_ECPKPARAMETERS +# define d2i_ECPKPARAMETERS d2i_UC_ECPKPARAMETERS +# undef i2d_ECPKPARAMETERS +# define i2d_ECPKPARAMETERS i2d_UC_ECPKPARAMETERS + +/* + * These functions do not seem to exist! However, I'm paranoid... Original + * command in x509v3.h: These functions are being redefined in another + * directory, and clash when the linker is case-insensitive, so let's hide + * them a little, by giving them an extra 'o' at the beginning of the name... + */ +# undef X509v3_cleanup_extensions +# define X509v3_cleanup_extensions oX509v3_cleanup_extensions +# undef X509v3_add_extension +# define X509v3_add_extension oX509v3_add_extension +# undef X509v3_add_netscape_extensions +# define X509v3_add_netscape_extensions oX509v3_add_netscape_extensions +# undef X509v3_add_standard_extensions +# define X509v3_add_standard_extensions oX509v3_add_standard_extensions + +/* This one clashes with CMS_data_create */ +# undef cms_Data_create +# define cms_Data_create priv_cms_Data_create + +# endif + +#endif /* ! defined HEADER_VMS_IDHACKS_H */ diff --git a/OSlibs/ios/include/openssl/tls1.h b/OSlibs/ios/include/openssl/tls1.h new file mode 100755 index 000000000..7e237d063 --- /dev/null +++ b/OSlibs/ios/include/openssl/tls1.h @@ -0,0 +1,810 @@ +/* ssl/tls1.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * ECC cipher suite support in OpenSSL originally written by + * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#ifndef HEADER_TLS1_H +# define HEADER_TLS1_H + +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# define TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES 0 + +# define TLS1_VERSION 0x0301 +# define TLS1_1_VERSION 0x0302 +# define TLS1_2_VERSION 0x0303 +# define TLS_MAX_VERSION TLS1_2_VERSION + +# define TLS1_VERSION_MAJOR 0x03 +# define TLS1_VERSION_MINOR 0x01 + +# define TLS1_1_VERSION_MAJOR 0x03 +# define TLS1_1_VERSION_MINOR 0x02 + +# define TLS1_2_VERSION_MAJOR 0x03 +# define TLS1_2_VERSION_MINOR 0x03 + +# define TLS1_get_version(s) \ + ((s->version >> 8) == TLS1_VERSION_MAJOR ? s->version : 0) + +# define TLS1_get_client_version(s) \ + ((s->client_version >> 8) == TLS1_VERSION_MAJOR ? s->client_version : 0) + +# define TLS1_AD_DECRYPTION_FAILED 21 +# define TLS1_AD_RECORD_OVERFLOW 22 +# define TLS1_AD_UNKNOWN_CA 48/* fatal */ +# define TLS1_AD_ACCESS_DENIED 49/* fatal */ +# define TLS1_AD_DECODE_ERROR 50/* fatal */ +# define TLS1_AD_DECRYPT_ERROR 51 +# define TLS1_AD_EXPORT_RESTRICTION 60/* fatal */ +# define TLS1_AD_PROTOCOL_VERSION 70/* fatal */ +# define TLS1_AD_INSUFFICIENT_SECURITY 71/* fatal */ +# define TLS1_AD_INTERNAL_ERROR 80/* fatal */ +# define TLS1_AD_INAPPROPRIATE_FALLBACK 86/* fatal */ +# define TLS1_AD_USER_CANCELLED 90 +# define TLS1_AD_NO_RENEGOTIATION 100 +/* codes 110-114 are from RFC3546 */ +# define TLS1_AD_UNSUPPORTED_EXTENSION 110 +# define TLS1_AD_CERTIFICATE_UNOBTAINABLE 111 +# define TLS1_AD_UNRECOGNIZED_NAME 112 +# define TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE 113 +# define TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 114 +# define TLS1_AD_UNKNOWN_PSK_IDENTITY 115/* fatal */ + +/* ExtensionType values from RFC3546 / RFC4366 / RFC6066 */ +# define TLSEXT_TYPE_server_name 0 +# define TLSEXT_TYPE_max_fragment_length 1 +# define TLSEXT_TYPE_client_certificate_url 2 +# define TLSEXT_TYPE_trusted_ca_keys 3 +# define TLSEXT_TYPE_truncated_hmac 4 +# define TLSEXT_TYPE_status_request 5 +/* ExtensionType values from RFC4681 */ +# define TLSEXT_TYPE_user_mapping 6 +/* ExtensionType values from RFC5878 */ +# define TLSEXT_TYPE_client_authz 7 +# define TLSEXT_TYPE_server_authz 8 +/* ExtensionType values from RFC6091 */ +# define TLSEXT_TYPE_cert_type 9 + +/* ExtensionType values from RFC4492 */ +# define TLSEXT_TYPE_elliptic_curves 10 +# define TLSEXT_TYPE_ec_point_formats 11 + +/* ExtensionType value from RFC5054 */ +# define TLSEXT_TYPE_srp 12 + +/* ExtensionType values from RFC5246 */ +# define TLSEXT_TYPE_signature_algorithms 13 + +/* ExtensionType value from RFC5764 */ +# define TLSEXT_TYPE_use_srtp 14 + +/* ExtensionType value from RFC5620 */ +# define TLSEXT_TYPE_heartbeat 15 + +/* ExtensionType value from RFC7301 */ +# define TLSEXT_TYPE_application_layer_protocol_negotiation 16 + +/* + * ExtensionType value for TLS padding extension. + * http://tools.ietf.org/html/draft-agl-tls-padding + */ +# define TLSEXT_TYPE_padding 21 + +/* ExtensionType value from RFC4507 */ +# define TLSEXT_TYPE_session_ticket 35 + +/* ExtensionType value from draft-rescorla-tls-opaque-prf-input-00.txt */ +# if 0 +/* + * will have to be provided externally for now , + * i.e. build with -DTLSEXT_TYPE_opaque_prf_input=38183 + * using whatever extension number you'd like to try + */ +# define TLSEXT_TYPE_opaque_prf_input ?? +# endif + +/* Temporary extension type */ +# define TLSEXT_TYPE_renegotiate 0xff01 + +# ifndef OPENSSL_NO_NEXTPROTONEG +/* This is not an IANA defined extension number */ +# define TLSEXT_TYPE_next_proto_neg 13172 +# endif + +/* NameType value from RFC3546 */ +# define TLSEXT_NAMETYPE_host_name 0 +/* status request value from RFC3546 */ +# define TLSEXT_STATUSTYPE_ocsp 1 + +/* ECPointFormat values from RFC4492 */ +# define TLSEXT_ECPOINTFORMAT_first 0 +# define TLSEXT_ECPOINTFORMAT_uncompressed 0 +# define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime 1 +# define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2 2 +# define TLSEXT_ECPOINTFORMAT_last 2 + +/* Signature and hash algorithms from RFC5246 */ +# define TLSEXT_signature_anonymous 0 +# define TLSEXT_signature_rsa 1 +# define TLSEXT_signature_dsa 2 +# define TLSEXT_signature_ecdsa 3 + +/* Total number of different signature algorithms */ +# define TLSEXT_signature_num 4 + +# define TLSEXT_hash_none 0 +# define TLSEXT_hash_md5 1 +# define TLSEXT_hash_sha1 2 +# define TLSEXT_hash_sha224 3 +# define TLSEXT_hash_sha256 4 +# define TLSEXT_hash_sha384 5 +# define TLSEXT_hash_sha512 6 + +/* Total number of different digest algorithms */ + +# define TLSEXT_hash_num 7 + +/* Flag set for unrecognised algorithms */ +# define TLSEXT_nid_unknown 0x1000000 + +/* ECC curves */ + +# define TLSEXT_curve_P_256 23 +# define TLSEXT_curve_P_384 24 + +# ifndef OPENSSL_NO_TLSEXT + +# define TLSEXT_MAXLEN_host_name 255 + +const char *SSL_get_servername(const SSL *s, const int type); +int SSL_get_servername_type(const SSL *s); +/* + * SSL_export_keying_material exports a value derived from the master secret, + * as specified in RFC 5705. It writes |olen| bytes to |out| given a label and + * optional context. (Since a zero length context is allowed, the |use_context| + * flag controls whether a context is included.) It returns 1 on success and + * zero otherwise. + */ +int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, + const char *label, size_t llen, + const unsigned char *p, size_t plen, + int use_context); + +int SSL_get_sigalgs(SSL *s, int idx, + int *psign, int *phash, int *psignandhash, + unsigned char *rsig, unsigned char *rhash); + +int SSL_get_shared_sigalgs(SSL *s, int idx, + int *psign, int *phash, int *psignandhash, + unsigned char *rsig, unsigned char *rhash); + +int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain); + +# define SSL_set_tlsext_host_name(s,name) \ +SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_HOSTNAME,TLSEXT_NAMETYPE_host_name,(char *)name) + +# define SSL_set_tlsext_debug_callback(ssl, cb) \ +SSL_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_CB,(void (*)(void))cb) + +# define SSL_set_tlsext_debug_arg(ssl, arg) \ +SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_ARG,0, (void *)arg) + +# define SSL_set_tlsext_status_type(ssl, type) \ +SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE,type, NULL) + +# define SSL_get_tlsext_status_exts(ssl, arg) \ +SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS,0, (void *)arg) + +# define SSL_set_tlsext_status_exts(ssl, arg) \ +SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS,0, (void *)arg) + +# define SSL_get_tlsext_status_ids(ssl, arg) \ +SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS,0, (void *)arg) + +# define SSL_set_tlsext_status_ids(ssl, arg) \ +SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS,0, (void *)arg) + +# define SSL_get_tlsext_status_ocsp_resp(ssl, arg) \ +SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP,0, (void *)arg) + +# define SSL_set_tlsext_status_ocsp_resp(ssl, arg, arglen) \ +SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP,arglen, (void *)arg) + +# define SSL_CTX_set_tlsext_servername_callback(ctx, cb) \ +SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_CB,(void (*)(void))cb) + +# define SSL_TLSEXT_ERR_OK 0 +# define SSL_TLSEXT_ERR_ALERT_WARNING 1 +# define SSL_TLSEXT_ERR_ALERT_FATAL 2 +# define SSL_TLSEXT_ERR_NOACK 3 + +# define SSL_CTX_set_tlsext_servername_arg(ctx, arg) \ +SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG,0, (void *)arg) + +# define SSL_CTX_get_tlsext_ticket_keys(ctx, keys, keylen) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_GET_TLSEXT_TICKET_KEYS,(keylen),(keys)) +# define SSL_CTX_set_tlsext_ticket_keys(ctx, keys, keylen) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_SET_TLSEXT_TICKET_KEYS,(keylen),(keys)) + +# define SSL_CTX_set_tlsext_status_cb(ssl, cb) \ +SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB,(void (*)(void))cb) + +# define SSL_CTX_set_tlsext_status_arg(ssl, arg) \ +SSL_CTX_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG,0, (void *)arg) + +# define SSL_set_tlsext_opaque_prf_input(s, src, len) \ +SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT, len, src) +# define SSL_CTX_set_tlsext_opaque_prf_input_callback(ctx, cb) \ +SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB, (void (*)(void))cb) +# define SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(ctx, arg) \ +SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG, 0, arg) + +# define SSL_CTX_set_tlsext_ticket_key_cb(ssl, cb) \ +SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb) + +# ifndef OPENSSL_NO_HEARTBEATS +# define SSL_TLSEXT_HB_ENABLED 0x01 +# define SSL_TLSEXT_HB_DONT_SEND_REQUESTS 0x02 +# define SSL_TLSEXT_HB_DONT_RECV_REQUESTS 0x04 + +# define SSL_get_tlsext_heartbeat_pending(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_GET_TLS_EXT_HEARTBEAT_PENDING,0,NULL) +# define SSL_set_tlsext_heartbeat_no_requests(ssl, arg) \ + SSL_ctrl((ssl),SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS,arg,NULL) +# endif +# endif + +/* PSK ciphersuites from 4279 */ +# define TLS1_CK_PSK_WITH_RC4_128_SHA 0x0300008A +# define TLS1_CK_PSK_WITH_3DES_EDE_CBC_SHA 0x0300008B +# define TLS1_CK_PSK_WITH_AES_128_CBC_SHA 0x0300008C +# define TLS1_CK_PSK_WITH_AES_256_CBC_SHA 0x0300008D + +/* + * Additional TLS ciphersuites from expired Internet Draft + * draft-ietf-tls-56-bit-ciphersuites-01.txt (available if + * TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES is defined, see s3_lib.c). We + * actually treat them like SSL 3.0 ciphers, which we probably shouldn't. + * Note that the first two are actually not in the IDs. + */ +# define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_MD5 0x03000060/* not in + * ID */ +# define TLS1_CK_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5 0x03000061/* not in + * ID */ +# define TLS1_CK_RSA_EXPORT1024_WITH_DES_CBC_SHA 0x03000062 +# define TLS1_CK_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA 0x03000063 +# define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_SHA 0x03000064 +# define TLS1_CK_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA 0x03000065 +# define TLS1_CK_DHE_DSS_WITH_RC4_128_SHA 0x03000066 + +/* AES ciphersuites from RFC3268 */ +# define TLS1_CK_RSA_WITH_AES_128_SHA 0x0300002F +# define TLS1_CK_DH_DSS_WITH_AES_128_SHA 0x03000030 +# define TLS1_CK_DH_RSA_WITH_AES_128_SHA 0x03000031 +# define TLS1_CK_DHE_DSS_WITH_AES_128_SHA 0x03000032 +# define TLS1_CK_DHE_RSA_WITH_AES_128_SHA 0x03000033 +# define TLS1_CK_ADH_WITH_AES_128_SHA 0x03000034 + +# define TLS1_CK_RSA_WITH_AES_256_SHA 0x03000035 +# define TLS1_CK_DH_DSS_WITH_AES_256_SHA 0x03000036 +# define TLS1_CK_DH_RSA_WITH_AES_256_SHA 0x03000037 +# define TLS1_CK_DHE_DSS_WITH_AES_256_SHA 0x03000038 +# define TLS1_CK_DHE_RSA_WITH_AES_256_SHA 0x03000039 +# define TLS1_CK_ADH_WITH_AES_256_SHA 0x0300003A + +/* TLS v1.2 ciphersuites */ +# define TLS1_CK_RSA_WITH_NULL_SHA256 0x0300003B +# define TLS1_CK_RSA_WITH_AES_128_SHA256 0x0300003C +# define TLS1_CK_RSA_WITH_AES_256_SHA256 0x0300003D +# define TLS1_CK_DH_DSS_WITH_AES_128_SHA256 0x0300003E +# define TLS1_CK_DH_RSA_WITH_AES_128_SHA256 0x0300003F +# define TLS1_CK_DHE_DSS_WITH_AES_128_SHA256 0x03000040 + +/* Camellia ciphersuites from RFC4132 */ +# define TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA 0x03000041 +# define TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA 0x03000042 +# define TLS1_CK_DH_RSA_WITH_CAMELLIA_128_CBC_SHA 0x03000043 +# define TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA 0x03000044 +# define TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA 0x03000045 +# define TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA 0x03000046 + +/* TLS v1.2 ciphersuites */ +# define TLS1_CK_DHE_RSA_WITH_AES_128_SHA256 0x03000067 +# define TLS1_CK_DH_DSS_WITH_AES_256_SHA256 0x03000068 +# define TLS1_CK_DH_RSA_WITH_AES_256_SHA256 0x03000069 +# define TLS1_CK_DHE_DSS_WITH_AES_256_SHA256 0x0300006A +# define TLS1_CK_DHE_RSA_WITH_AES_256_SHA256 0x0300006B +# define TLS1_CK_ADH_WITH_AES_128_SHA256 0x0300006C +# define TLS1_CK_ADH_WITH_AES_256_SHA256 0x0300006D + +/* Camellia ciphersuites from RFC4132 */ +# define TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000084 +# define TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA 0x03000085 +# define TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000086 +# define TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA 0x03000087 +# define TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000088 +# define TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA 0x03000089 + +/* SEED ciphersuites from RFC4162 */ +# define TLS1_CK_RSA_WITH_SEED_SHA 0x03000096 +# define TLS1_CK_DH_DSS_WITH_SEED_SHA 0x03000097 +# define TLS1_CK_DH_RSA_WITH_SEED_SHA 0x03000098 +# define TLS1_CK_DHE_DSS_WITH_SEED_SHA 0x03000099 +# define TLS1_CK_DHE_RSA_WITH_SEED_SHA 0x0300009A +# define TLS1_CK_ADH_WITH_SEED_SHA 0x0300009B + +/* TLS v1.2 GCM ciphersuites from RFC5288 */ +# define TLS1_CK_RSA_WITH_AES_128_GCM_SHA256 0x0300009C +# define TLS1_CK_RSA_WITH_AES_256_GCM_SHA384 0x0300009D +# define TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256 0x0300009E +# define TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384 0x0300009F +# define TLS1_CK_DH_RSA_WITH_AES_128_GCM_SHA256 0x030000A0 +# define TLS1_CK_DH_RSA_WITH_AES_256_GCM_SHA384 0x030000A1 +# define TLS1_CK_DHE_DSS_WITH_AES_128_GCM_SHA256 0x030000A2 +# define TLS1_CK_DHE_DSS_WITH_AES_256_GCM_SHA384 0x030000A3 +# define TLS1_CK_DH_DSS_WITH_AES_128_GCM_SHA256 0x030000A4 +# define TLS1_CK_DH_DSS_WITH_AES_256_GCM_SHA384 0x030000A5 +# define TLS1_CK_ADH_WITH_AES_128_GCM_SHA256 0x030000A6 +# define TLS1_CK_ADH_WITH_AES_256_GCM_SHA384 0x030000A7 + +/* + * ECC ciphersuites from draft-ietf-tls-ecc-12.txt with changes soon to be in + * draft 13 + */ +# define TLS1_CK_ECDH_ECDSA_WITH_NULL_SHA 0x0300C001 +# define TLS1_CK_ECDH_ECDSA_WITH_RC4_128_SHA 0x0300C002 +# define TLS1_CK_ECDH_ECDSA_WITH_DES_192_CBC3_SHA 0x0300C003 +# define TLS1_CK_ECDH_ECDSA_WITH_AES_128_CBC_SHA 0x0300C004 +# define TLS1_CK_ECDH_ECDSA_WITH_AES_256_CBC_SHA 0x0300C005 + +# define TLS1_CK_ECDHE_ECDSA_WITH_NULL_SHA 0x0300C006 +# define TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA 0x0300C007 +# define TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA 0x0300C008 +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 0x0300C009 +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 0x0300C00A + +# define TLS1_CK_ECDH_RSA_WITH_NULL_SHA 0x0300C00B +# define TLS1_CK_ECDH_RSA_WITH_RC4_128_SHA 0x0300C00C +# define TLS1_CK_ECDH_RSA_WITH_DES_192_CBC3_SHA 0x0300C00D +# define TLS1_CK_ECDH_RSA_WITH_AES_128_CBC_SHA 0x0300C00E +# define TLS1_CK_ECDH_RSA_WITH_AES_256_CBC_SHA 0x0300C00F + +# define TLS1_CK_ECDHE_RSA_WITH_NULL_SHA 0x0300C010 +# define TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA 0x0300C011 +# define TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA 0x0300C012 +# define TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA 0x0300C013 +# define TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA 0x0300C014 + +# define TLS1_CK_ECDH_anon_WITH_NULL_SHA 0x0300C015 +# define TLS1_CK_ECDH_anon_WITH_RC4_128_SHA 0x0300C016 +# define TLS1_CK_ECDH_anon_WITH_DES_192_CBC3_SHA 0x0300C017 +# define TLS1_CK_ECDH_anon_WITH_AES_128_CBC_SHA 0x0300C018 +# define TLS1_CK_ECDH_anon_WITH_AES_256_CBC_SHA 0x0300C019 + +/* SRP ciphersuites from RFC 5054 */ +# define TLS1_CK_SRP_SHA_WITH_3DES_EDE_CBC_SHA 0x0300C01A +# define TLS1_CK_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA 0x0300C01B +# define TLS1_CK_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA 0x0300C01C +# define TLS1_CK_SRP_SHA_WITH_AES_128_CBC_SHA 0x0300C01D +# define TLS1_CK_SRP_SHA_RSA_WITH_AES_128_CBC_SHA 0x0300C01E +# define TLS1_CK_SRP_SHA_DSS_WITH_AES_128_CBC_SHA 0x0300C01F +# define TLS1_CK_SRP_SHA_WITH_AES_256_CBC_SHA 0x0300C020 +# define TLS1_CK_SRP_SHA_RSA_WITH_AES_256_CBC_SHA 0x0300C021 +# define TLS1_CK_SRP_SHA_DSS_WITH_AES_256_CBC_SHA 0x0300C022 + +/* ECDH HMAC based ciphersuites from RFC5289 */ + +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256 0x0300C023 +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384 0x0300C024 +# define TLS1_CK_ECDH_ECDSA_WITH_AES_128_SHA256 0x0300C025 +# define TLS1_CK_ECDH_ECDSA_WITH_AES_256_SHA384 0x0300C026 +# define TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256 0x0300C027 +# define TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384 0x0300C028 +# define TLS1_CK_ECDH_RSA_WITH_AES_128_SHA256 0x0300C029 +# define TLS1_CK_ECDH_RSA_WITH_AES_256_SHA384 0x0300C02A + +/* ECDH GCM based ciphersuites from RFC5289 */ +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 0x0300C02B +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 0x0300C02C +# define TLS1_CK_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 0x0300C02D +# define TLS1_CK_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 0x0300C02E +# define TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0x0300C02F +# define TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384 0x0300C030 +# define TLS1_CK_ECDH_RSA_WITH_AES_128_GCM_SHA256 0x0300C031 +# define TLS1_CK_ECDH_RSA_WITH_AES_256_GCM_SHA384 0x0300C032 + +/* + * XXX * Backward compatibility alert: + * Older versions of OpenSSL gave + * some DHE ciphers names with "EDH" + * instead of "DHE". Going forward, we + * should be using DHE + * everywhere, though we may indefinitely maintain + * aliases for users + * or configurations that used "EDH" + + */ +# define TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_MD5 "EXP1024-RC4-MD5" +# define TLS1_TXT_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5 "EXP1024-RC2-CBC-MD5" +# define TLS1_TXT_RSA_EXPORT1024_WITH_DES_CBC_SHA "EXP1024-DES-CBC-SHA" +# define TLS1_TXT_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA "EXP1024-DHE-DSS-DES-CBC-SHA" +# define TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_SHA "EXP1024-RC4-SHA" +# define TLS1_TXT_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA "EXP1024-DHE-DSS-RC4-SHA" +# define TLS1_TXT_DHE_DSS_WITH_RC4_128_SHA "DHE-DSS-RC4-SHA" + +/* AES ciphersuites from RFC3268 */ +# define TLS1_TXT_RSA_WITH_AES_128_SHA "AES128-SHA" +# define TLS1_TXT_DH_DSS_WITH_AES_128_SHA "DH-DSS-AES128-SHA" +# define TLS1_TXT_DH_RSA_WITH_AES_128_SHA "DH-RSA-AES128-SHA" +# define TLS1_TXT_DHE_DSS_WITH_AES_128_SHA "DHE-DSS-AES128-SHA" +# define TLS1_TXT_DHE_RSA_WITH_AES_128_SHA "DHE-RSA-AES128-SHA" +# define TLS1_TXT_ADH_WITH_AES_128_SHA "ADH-AES128-SHA" + +# define TLS1_TXT_RSA_WITH_AES_256_SHA "AES256-SHA" +# define TLS1_TXT_DH_DSS_WITH_AES_256_SHA "DH-DSS-AES256-SHA" +# define TLS1_TXT_DH_RSA_WITH_AES_256_SHA "DH-RSA-AES256-SHA" +# define TLS1_TXT_DHE_DSS_WITH_AES_256_SHA "DHE-DSS-AES256-SHA" +# define TLS1_TXT_DHE_RSA_WITH_AES_256_SHA "DHE-RSA-AES256-SHA" +# define TLS1_TXT_ADH_WITH_AES_256_SHA "ADH-AES256-SHA" + +/* ECC ciphersuites from RFC4492 */ +# define TLS1_TXT_ECDH_ECDSA_WITH_NULL_SHA "ECDH-ECDSA-NULL-SHA" +# define TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA "ECDH-ECDSA-RC4-SHA" +# define TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA "ECDH-ECDSA-DES-CBC3-SHA" +# define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA "ECDH-ECDSA-AES128-SHA" +# define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA "ECDH-ECDSA-AES256-SHA" + +# define TLS1_TXT_ECDHE_ECDSA_WITH_NULL_SHA "ECDHE-ECDSA-NULL-SHA" +# define TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA "ECDHE-ECDSA-RC4-SHA" +# define TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA "ECDHE-ECDSA-DES-CBC3-SHA" +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA "ECDHE-ECDSA-AES128-SHA" +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA "ECDHE-ECDSA-AES256-SHA" + +# define TLS1_TXT_ECDH_RSA_WITH_NULL_SHA "ECDH-RSA-NULL-SHA" +# define TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA "ECDH-RSA-RC4-SHA" +# define TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA "ECDH-RSA-DES-CBC3-SHA" +# define TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA "ECDH-RSA-AES128-SHA" +# define TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA "ECDH-RSA-AES256-SHA" + +# define TLS1_TXT_ECDHE_RSA_WITH_NULL_SHA "ECDHE-RSA-NULL-SHA" +# define TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA "ECDHE-RSA-RC4-SHA" +# define TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA "ECDHE-RSA-DES-CBC3-SHA" +# define TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA "ECDHE-RSA-AES128-SHA" +# define TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA "ECDHE-RSA-AES256-SHA" + +# define TLS1_TXT_ECDH_anon_WITH_NULL_SHA "AECDH-NULL-SHA" +# define TLS1_TXT_ECDH_anon_WITH_RC4_128_SHA "AECDH-RC4-SHA" +# define TLS1_TXT_ECDH_anon_WITH_DES_192_CBC3_SHA "AECDH-DES-CBC3-SHA" +# define TLS1_TXT_ECDH_anon_WITH_AES_128_CBC_SHA "AECDH-AES128-SHA" +# define TLS1_TXT_ECDH_anon_WITH_AES_256_CBC_SHA "AECDH-AES256-SHA" + +/* PSK ciphersuites from RFC 4279 */ +# define TLS1_TXT_PSK_WITH_RC4_128_SHA "PSK-RC4-SHA" +# define TLS1_TXT_PSK_WITH_3DES_EDE_CBC_SHA "PSK-3DES-EDE-CBC-SHA" +# define TLS1_TXT_PSK_WITH_AES_128_CBC_SHA "PSK-AES128-CBC-SHA" +# define TLS1_TXT_PSK_WITH_AES_256_CBC_SHA "PSK-AES256-CBC-SHA" + +/* SRP ciphersuite from RFC 5054 */ +# define TLS1_TXT_SRP_SHA_WITH_3DES_EDE_CBC_SHA "SRP-3DES-EDE-CBC-SHA" +# define TLS1_TXT_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA "SRP-RSA-3DES-EDE-CBC-SHA" +# define TLS1_TXT_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA "SRP-DSS-3DES-EDE-CBC-SHA" +# define TLS1_TXT_SRP_SHA_WITH_AES_128_CBC_SHA "SRP-AES-128-CBC-SHA" +# define TLS1_TXT_SRP_SHA_RSA_WITH_AES_128_CBC_SHA "SRP-RSA-AES-128-CBC-SHA" +# define TLS1_TXT_SRP_SHA_DSS_WITH_AES_128_CBC_SHA "SRP-DSS-AES-128-CBC-SHA" +# define TLS1_TXT_SRP_SHA_WITH_AES_256_CBC_SHA "SRP-AES-256-CBC-SHA" +# define TLS1_TXT_SRP_SHA_RSA_WITH_AES_256_CBC_SHA "SRP-RSA-AES-256-CBC-SHA" +# define TLS1_TXT_SRP_SHA_DSS_WITH_AES_256_CBC_SHA "SRP-DSS-AES-256-CBC-SHA" + +/* Camellia ciphersuites from RFC4132 */ +# define TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA "CAMELLIA128-SHA" +# define TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA "DH-DSS-CAMELLIA128-SHA" +# define TLS1_TXT_DH_RSA_WITH_CAMELLIA_128_CBC_SHA "DH-RSA-CAMELLIA128-SHA" +# define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA "DHE-DSS-CAMELLIA128-SHA" +# define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA "DHE-RSA-CAMELLIA128-SHA" +# define TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA "ADH-CAMELLIA128-SHA" + +# define TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA "CAMELLIA256-SHA" +# define TLS1_TXT_DH_DSS_WITH_CAMELLIA_256_CBC_SHA "DH-DSS-CAMELLIA256-SHA" +# define TLS1_TXT_DH_RSA_WITH_CAMELLIA_256_CBC_SHA "DH-RSA-CAMELLIA256-SHA" +# define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA "DHE-DSS-CAMELLIA256-SHA" +# define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA "DHE-RSA-CAMELLIA256-SHA" +# define TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA "ADH-CAMELLIA256-SHA" + +/* SEED ciphersuites from RFC4162 */ +# define TLS1_TXT_RSA_WITH_SEED_SHA "SEED-SHA" +# define TLS1_TXT_DH_DSS_WITH_SEED_SHA "DH-DSS-SEED-SHA" +# define TLS1_TXT_DH_RSA_WITH_SEED_SHA "DH-RSA-SEED-SHA" +# define TLS1_TXT_DHE_DSS_WITH_SEED_SHA "DHE-DSS-SEED-SHA" +# define TLS1_TXT_DHE_RSA_WITH_SEED_SHA "DHE-RSA-SEED-SHA" +# define TLS1_TXT_ADH_WITH_SEED_SHA "ADH-SEED-SHA" + +/* TLS v1.2 ciphersuites */ +# define TLS1_TXT_RSA_WITH_NULL_SHA256 "NULL-SHA256" +# define TLS1_TXT_RSA_WITH_AES_128_SHA256 "AES128-SHA256" +# define TLS1_TXT_RSA_WITH_AES_256_SHA256 "AES256-SHA256" +# define TLS1_TXT_DH_DSS_WITH_AES_128_SHA256 "DH-DSS-AES128-SHA256" +# define TLS1_TXT_DH_RSA_WITH_AES_128_SHA256 "DH-RSA-AES128-SHA256" +# define TLS1_TXT_DHE_DSS_WITH_AES_128_SHA256 "DHE-DSS-AES128-SHA256" +# define TLS1_TXT_DHE_RSA_WITH_AES_128_SHA256 "DHE-RSA-AES128-SHA256" +# define TLS1_TXT_DH_DSS_WITH_AES_256_SHA256 "DH-DSS-AES256-SHA256" +# define TLS1_TXT_DH_RSA_WITH_AES_256_SHA256 "DH-RSA-AES256-SHA256" +# define TLS1_TXT_DHE_DSS_WITH_AES_256_SHA256 "DHE-DSS-AES256-SHA256" +# define TLS1_TXT_DHE_RSA_WITH_AES_256_SHA256 "DHE-RSA-AES256-SHA256" +# define TLS1_TXT_ADH_WITH_AES_128_SHA256 "ADH-AES128-SHA256" +# define TLS1_TXT_ADH_WITH_AES_256_SHA256 "ADH-AES256-SHA256" + +/* TLS v1.2 GCM ciphersuites from RFC5288 */ +# define TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256 "AES128-GCM-SHA256" +# define TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384 "AES256-GCM-SHA384" +# define TLS1_TXT_DHE_RSA_WITH_AES_128_GCM_SHA256 "DHE-RSA-AES128-GCM-SHA256" +# define TLS1_TXT_DHE_RSA_WITH_AES_256_GCM_SHA384 "DHE-RSA-AES256-GCM-SHA384" +# define TLS1_TXT_DH_RSA_WITH_AES_128_GCM_SHA256 "DH-RSA-AES128-GCM-SHA256" +# define TLS1_TXT_DH_RSA_WITH_AES_256_GCM_SHA384 "DH-RSA-AES256-GCM-SHA384" +# define TLS1_TXT_DHE_DSS_WITH_AES_128_GCM_SHA256 "DHE-DSS-AES128-GCM-SHA256" +# define TLS1_TXT_DHE_DSS_WITH_AES_256_GCM_SHA384 "DHE-DSS-AES256-GCM-SHA384" +# define TLS1_TXT_DH_DSS_WITH_AES_128_GCM_SHA256 "DH-DSS-AES128-GCM-SHA256" +# define TLS1_TXT_DH_DSS_WITH_AES_256_GCM_SHA384 "DH-DSS-AES256-GCM-SHA384" +# define TLS1_TXT_ADH_WITH_AES_128_GCM_SHA256 "ADH-AES128-GCM-SHA256" +# define TLS1_TXT_ADH_WITH_AES_256_GCM_SHA384 "ADH-AES256-GCM-SHA384" + +/* ECDH HMAC based ciphersuites from RFC5289 */ + +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_SHA256 "ECDHE-ECDSA-AES128-SHA256" +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_SHA384 "ECDHE-ECDSA-AES256-SHA384" +# define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_SHA256 "ECDH-ECDSA-AES128-SHA256" +# define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_SHA384 "ECDH-ECDSA-AES256-SHA384" +# define TLS1_TXT_ECDHE_RSA_WITH_AES_128_SHA256 "ECDHE-RSA-AES128-SHA256" +# define TLS1_TXT_ECDHE_RSA_WITH_AES_256_SHA384 "ECDHE-RSA-AES256-SHA384" +# define TLS1_TXT_ECDH_RSA_WITH_AES_128_SHA256 "ECDH-RSA-AES128-SHA256" +# define TLS1_TXT_ECDH_RSA_WITH_AES_256_SHA384 "ECDH-RSA-AES256-SHA384" + +/* ECDH GCM based ciphersuites from RFC5289 */ +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 "ECDHE-ECDSA-AES128-GCM-SHA256" +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 "ECDHE-ECDSA-AES256-GCM-SHA384" +# define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 "ECDH-ECDSA-AES128-GCM-SHA256" +# define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 "ECDH-ECDSA-AES256-GCM-SHA384" +# define TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256 "ECDHE-RSA-AES128-GCM-SHA256" +# define TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384 "ECDHE-RSA-AES256-GCM-SHA384" +# define TLS1_TXT_ECDH_RSA_WITH_AES_128_GCM_SHA256 "ECDH-RSA-AES128-GCM-SHA256" +# define TLS1_TXT_ECDH_RSA_WITH_AES_256_GCM_SHA384 "ECDH-RSA-AES256-GCM-SHA384" + +# define TLS_CT_RSA_SIGN 1 +# define TLS_CT_DSS_SIGN 2 +# define TLS_CT_RSA_FIXED_DH 3 +# define TLS_CT_DSS_FIXED_DH 4 +# define TLS_CT_ECDSA_SIGN 64 +# define TLS_CT_RSA_FIXED_ECDH 65 +# define TLS_CT_ECDSA_FIXED_ECDH 66 +# define TLS_CT_GOST94_SIGN 21 +# define TLS_CT_GOST01_SIGN 22 +/* + * when correcting this number, correct also SSL3_CT_NUMBER in ssl3.h (see + * comment there) + */ +# define TLS_CT_NUMBER 9 + +# define TLS1_FINISH_MAC_LENGTH 12 + +# define TLS_MD_MAX_CONST_SIZE 20 +# define TLS_MD_CLIENT_FINISH_CONST "client finished" +# define TLS_MD_CLIENT_FINISH_CONST_SIZE 15 +# define TLS_MD_SERVER_FINISH_CONST "server finished" +# define TLS_MD_SERVER_FINISH_CONST_SIZE 15 +# define TLS_MD_SERVER_WRITE_KEY_CONST "server write key" +# define TLS_MD_SERVER_WRITE_KEY_CONST_SIZE 16 +# define TLS_MD_KEY_EXPANSION_CONST "key expansion" +# define TLS_MD_KEY_EXPANSION_CONST_SIZE 13 +# define TLS_MD_CLIENT_WRITE_KEY_CONST "client write key" +# define TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE 16 +# define TLS_MD_SERVER_WRITE_KEY_CONST "server write key" +# define TLS_MD_SERVER_WRITE_KEY_CONST_SIZE 16 +# define TLS_MD_IV_BLOCK_CONST "IV block" +# define TLS_MD_IV_BLOCK_CONST_SIZE 8 +# define TLS_MD_MASTER_SECRET_CONST "master secret" +# define TLS_MD_MASTER_SECRET_CONST_SIZE 13 + +# ifdef CHARSET_EBCDIC +# undef TLS_MD_CLIENT_FINISH_CONST +/* + * client finished + */ +# define TLS_MD_CLIENT_FINISH_CONST "\x63\x6c\x69\x65\x6e\x74\x20\x66\x69\x6e\x69\x73\x68\x65\x64" + +# undef TLS_MD_SERVER_FINISH_CONST +/* + * server finished + */ +# define TLS_MD_SERVER_FINISH_CONST "\x73\x65\x72\x76\x65\x72\x20\x66\x69\x6e\x69\x73\x68\x65\x64" + +# undef TLS_MD_SERVER_WRITE_KEY_CONST +/* + * server write key + */ +# define TLS_MD_SERVER_WRITE_KEY_CONST "\x73\x65\x72\x76\x65\x72\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79" + +# undef TLS_MD_KEY_EXPANSION_CONST +/* + * key expansion + */ +# define TLS_MD_KEY_EXPANSION_CONST "\x6b\x65\x79\x20\x65\x78\x70\x61\x6e\x73\x69\x6f\x6e" + +# undef TLS_MD_CLIENT_WRITE_KEY_CONST +/* + * client write key + */ +# define TLS_MD_CLIENT_WRITE_KEY_CONST "\x63\x6c\x69\x65\x6e\x74\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79" + +# undef TLS_MD_SERVER_WRITE_KEY_CONST +/* + * server write key + */ +# define TLS_MD_SERVER_WRITE_KEY_CONST "\x73\x65\x72\x76\x65\x72\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79" + +# undef TLS_MD_IV_BLOCK_CONST +/* + * IV block + */ +# define TLS_MD_IV_BLOCK_CONST "\x49\x56\x20\x62\x6c\x6f\x63\x6b" + +# undef TLS_MD_MASTER_SECRET_CONST +/* + * master secret + */ +# define TLS_MD_MASTER_SECRET_CONST "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74" +# endif + +/* TLS Session Ticket extension struct */ +struct tls_session_ticket_ext_st { + unsigned short length; + void *data; +}; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/ts.h b/OSlibs/ios/include/openssl/ts.h new file mode 100755 index 000000000..16eccbb38 --- /dev/null +++ b/OSlibs/ios/include/openssl/ts.h @@ -0,0 +1,862 @@ +/* crypto/ts/ts.h */ +/* + * Written by Zoltan Glozik (zglozik@opentsa.org) for the OpenSSL project + * 2002, 2003, 2004. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_TS_H +# define HEADER_TS_H + +# include +# include +# ifndef OPENSSL_NO_BUFFER +# include +# endif +# ifndef OPENSSL_NO_EVP +# include +# endif +# ifndef OPENSSL_NO_BIO +# include +# endif +# include +# include +# include + +# ifndef OPENSSL_NO_RSA +# include +# endif + +# ifndef OPENSSL_NO_DSA +# include +# endif + +# ifndef OPENSSL_NO_DH +# include +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +# ifdef WIN32 +/* Under Win32 this is defined in wincrypt.h */ +# undef X509_NAME +# endif + +# include +# include + +/*- +MessageImprint ::= SEQUENCE { + hashAlgorithm AlgorithmIdentifier, + hashedMessage OCTET STRING } +*/ + +typedef struct TS_msg_imprint_st { + X509_ALGOR *hash_algo; + ASN1_OCTET_STRING *hashed_msg; +} TS_MSG_IMPRINT; + +/*- +TimeStampReq ::= SEQUENCE { + version INTEGER { v1(1) }, + messageImprint MessageImprint, + --a hash algorithm OID and the hash value of the data to be + --time-stamped + reqPolicy TSAPolicyId OPTIONAL, + nonce INTEGER OPTIONAL, + certReq BOOLEAN DEFAULT FALSE, + extensions [0] IMPLICIT Extensions OPTIONAL } +*/ + +typedef struct TS_req_st { + ASN1_INTEGER *version; + TS_MSG_IMPRINT *msg_imprint; + ASN1_OBJECT *policy_id; /* OPTIONAL */ + ASN1_INTEGER *nonce; /* OPTIONAL */ + ASN1_BOOLEAN cert_req; /* DEFAULT FALSE */ + STACK_OF(X509_EXTENSION) *extensions; /* [0] OPTIONAL */ +} TS_REQ; + +/*- +Accuracy ::= SEQUENCE { + seconds INTEGER OPTIONAL, + millis [0] INTEGER (1..999) OPTIONAL, + micros [1] INTEGER (1..999) OPTIONAL } +*/ + +typedef struct TS_accuracy_st { + ASN1_INTEGER *seconds; + ASN1_INTEGER *millis; + ASN1_INTEGER *micros; +} TS_ACCURACY; + +/*- +TSTInfo ::= SEQUENCE { + version INTEGER { v1(1) }, + policy TSAPolicyId, + messageImprint MessageImprint, + -- MUST have the same value as the similar field in + -- TimeStampReq + serialNumber INTEGER, + -- Time-Stamping users MUST be ready to accommodate integers + -- up to 160 bits. + genTime GeneralizedTime, + accuracy Accuracy OPTIONAL, + ordering BOOLEAN DEFAULT FALSE, + nonce INTEGER OPTIONAL, + -- MUST be present if the similar field was present + -- in TimeStampReq. In that case it MUST have the same value. + tsa [0] GeneralName OPTIONAL, + extensions [1] IMPLICIT Extensions OPTIONAL } +*/ + +typedef struct TS_tst_info_st { + ASN1_INTEGER *version; + ASN1_OBJECT *policy_id; + TS_MSG_IMPRINT *msg_imprint; + ASN1_INTEGER *serial; + ASN1_GENERALIZEDTIME *time; + TS_ACCURACY *accuracy; + ASN1_BOOLEAN ordering; + ASN1_INTEGER *nonce; + GENERAL_NAME *tsa; + STACK_OF(X509_EXTENSION) *extensions; +} TS_TST_INFO; + +/*- +PKIStatusInfo ::= SEQUENCE { + status PKIStatus, + statusString PKIFreeText OPTIONAL, + failInfo PKIFailureInfo OPTIONAL } + +From RFC 1510 - section 3.1.1: +PKIFreeText ::= SEQUENCE SIZE (1..MAX) OF UTF8String + -- text encoded as UTF-8 String (note: each UTF8String SHOULD + -- include an RFC 1766 language tag to indicate the language + -- of the contained text) +*/ + +/* Possible values for status. See ts_resp_print.c && ts_resp_verify.c. */ + +# define TS_STATUS_GRANTED 0 +# define TS_STATUS_GRANTED_WITH_MODS 1 +# define TS_STATUS_REJECTION 2 +# define TS_STATUS_WAITING 3 +# define TS_STATUS_REVOCATION_WARNING 4 +# define TS_STATUS_REVOCATION_NOTIFICATION 5 + +/* + * Possible values for failure_info. See ts_resp_print.c && ts_resp_verify.c + */ + +# define TS_INFO_BAD_ALG 0 +# define TS_INFO_BAD_REQUEST 2 +# define TS_INFO_BAD_DATA_FORMAT 5 +# define TS_INFO_TIME_NOT_AVAILABLE 14 +# define TS_INFO_UNACCEPTED_POLICY 15 +# define TS_INFO_UNACCEPTED_EXTENSION 16 +# define TS_INFO_ADD_INFO_NOT_AVAILABLE 17 +# define TS_INFO_SYSTEM_FAILURE 25 + +typedef struct TS_status_info_st { + ASN1_INTEGER *status; + STACK_OF(ASN1_UTF8STRING) *text; + ASN1_BIT_STRING *failure_info; +} TS_STATUS_INFO; + +DECLARE_STACK_OF(ASN1_UTF8STRING) +DECLARE_ASN1_SET_OF(ASN1_UTF8STRING) + +/*- +TimeStampResp ::= SEQUENCE { + status PKIStatusInfo, + timeStampToken TimeStampToken OPTIONAL } +*/ + +typedef struct TS_resp_st { + TS_STATUS_INFO *status_info; + PKCS7 *token; + TS_TST_INFO *tst_info; +} TS_RESP; + +/* The structure below would belong to the ESS component. */ + +/*- +IssuerSerial ::= SEQUENCE { + issuer GeneralNames, + serialNumber CertificateSerialNumber + } +*/ + +typedef struct ESS_issuer_serial { + STACK_OF(GENERAL_NAME) *issuer; + ASN1_INTEGER *serial; +} ESS_ISSUER_SERIAL; + +/*- +ESSCertID ::= SEQUENCE { + certHash Hash, + issuerSerial IssuerSerial OPTIONAL +} +*/ + +typedef struct ESS_cert_id { + ASN1_OCTET_STRING *hash; /* Always SHA-1 digest. */ + ESS_ISSUER_SERIAL *issuer_serial; +} ESS_CERT_ID; + +DECLARE_STACK_OF(ESS_CERT_ID) +DECLARE_ASN1_SET_OF(ESS_CERT_ID) + +/*- +SigningCertificate ::= SEQUENCE { + certs SEQUENCE OF ESSCertID, + policies SEQUENCE OF PolicyInformation OPTIONAL +} +*/ + +typedef struct ESS_signing_cert { + STACK_OF(ESS_CERT_ID) *cert_ids; + STACK_OF(POLICYINFO) *policy_info; +} ESS_SIGNING_CERT; + +TS_REQ *TS_REQ_new(void); +void TS_REQ_free(TS_REQ *a); +int i2d_TS_REQ(const TS_REQ *a, unsigned char **pp); +TS_REQ *d2i_TS_REQ(TS_REQ **a, const unsigned char **pp, long length); + +TS_REQ *TS_REQ_dup(TS_REQ *a); + +TS_REQ *d2i_TS_REQ_fp(FILE *fp, TS_REQ **a); +int i2d_TS_REQ_fp(FILE *fp, TS_REQ *a); +TS_REQ *d2i_TS_REQ_bio(BIO *fp, TS_REQ **a); +int i2d_TS_REQ_bio(BIO *fp, TS_REQ *a); + +TS_MSG_IMPRINT *TS_MSG_IMPRINT_new(void); +void TS_MSG_IMPRINT_free(TS_MSG_IMPRINT *a); +int i2d_TS_MSG_IMPRINT(const TS_MSG_IMPRINT *a, unsigned char **pp); +TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT(TS_MSG_IMPRINT **a, + const unsigned char **pp, long length); + +TS_MSG_IMPRINT *TS_MSG_IMPRINT_dup(TS_MSG_IMPRINT *a); + +TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT **a); +int i2d_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT *a); +TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_bio(BIO *fp, TS_MSG_IMPRINT **a); +int i2d_TS_MSG_IMPRINT_bio(BIO *fp, TS_MSG_IMPRINT *a); + +TS_RESP *TS_RESP_new(void); +void TS_RESP_free(TS_RESP *a); +int i2d_TS_RESP(const TS_RESP *a, unsigned char **pp); +TS_RESP *d2i_TS_RESP(TS_RESP **a, const unsigned char **pp, long length); +TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token); +TS_RESP *TS_RESP_dup(TS_RESP *a); + +TS_RESP *d2i_TS_RESP_fp(FILE *fp, TS_RESP **a); +int i2d_TS_RESP_fp(FILE *fp, TS_RESP *a); +TS_RESP *d2i_TS_RESP_bio(BIO *fp, TS_RESP **a); +int i2d_TS_RESP_bio(BIO *fp, TS_RESP *a); + +TS_STATUS_INFO *TS_STATUS_INFO_new(void); +void TS_STATUS_INFO_free(TS_STATUS_INFO *a); +int i2d_TS_STATUS_INFO(const TS_STATUS_INFO *a, unsigned char **pp); +TS_STATUS_INFO *d2i_TS_STATUS_INFO(TS_STATUS_INFO **a, + const unsigned char **pp, long length); +TS_STATUS_INFO *TS_STATUS_INFO_dup(TS_STATUS_INFO *a); + +TS_TST_INFO *TS_TST_INFO_new(void); +void TS_TST_INFO_free(TS_TST_INFO *a); +int i2d_TS_TST_INFO(const TS_TST_INFO *a, unsigned char **pp); +TS_TST_INFO *d2i_TS_TST_INFO(TS_TST_INFO **a, const unsigned char **pp, + long length); +TS_TST_INFO *TS_TST_INFO_dup(TS_TST_INFO *a); + +TS_TST_INFO *d2i_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO **a); +int i2d_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO *a); +TS_TST_INFO *d2i_TS_TST_INFO_bio(BIO *fp, TS_TST_INFO **a); +int i2d_TS_TST_INFO_bio(BIO *fp, TS_TST_INFO *a); + +TS_ACCURACY *TS_ACCURACY_new(void); +void TS_ACCURACY_free(TS_ACCURACY *a); +int i2d_TS_ACCURACY(const TS_ACCURACY *a, unsigned char **pp); +TS_ACCURACY *d2i_TS_ACCURACY(TS_ACCURACY **a, const unsigned char **pp, + long length); +TS_ACCURACY *TS_ACCURACY_dup(TS_ACCURACY *a); + +ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_new(void); +void ESS_ISSUER_SERIAL_free(ESS_ISSUER_SERIAL *a); +int i2d_ESS_ISSUER_SERIAL(const ESS_ISSUER_SERIAL *a, unsigned char **pp); +ESS_ISSUER_SERIAL *d2i_ESS_ISSUER_SERIAL(ESS_ISSUER_SERIAL **a, + const unsigned char **pp, + long length); +ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_dup(ESS_ISSUER_SERIAL *a); + +ESS_CERT_ID *ESS_CERT_ID_new(void); +void ESS_CERT_ID_free(ESS_CERT_ID *a); +int i2d_ESS_CERT_ID(const ESS_CERT_ID *a, unsigned char **pp); +ESS_CERT_ID *d2i_ESS_CERT_ID(ESS_CERT_ID **a, const unsigned char **pp, + long length); +ESS_CERT_ID *ESS_CERT_ID_dup(ESS_CERT_ID *a); + +ESS_SIGNING_CERT *ESS_SIGNING_CERT_new(void); +void ESS_SIGNING_CERT_free(ESS_SIGNING_CERT *a); +int i2d_ESS_SIGNING_CERT(const ESS_SIGNING_CERT *a, unsigned char **pp); +ESS_SIGNING_CERT *d2i_ESS_SIGNING_CERT(ESS_SIGNING_CERT **a, + const unsigned char **pp, long length); +ESS_SIGNING_CERT *ESS_SIGNING_CERT_dup(ESS_SIGNING_CERT *a); + +void ERR_load_TS_strings(void); + +int TS_REQ_set_version(TS_REQ *a, long version); +long TS_REQ_get_version(const TS_REQ *a); + +int TS_REQ_set_msg_imprint(TS_REQ *a, TS_MSG_IMPRINT *msg_imprint); +TS_MSG_IMPRINT *TS_REQ_get_msg_imprint(TS_REQ *a); + +int TS_MSG_IMPRINT_set_algo(TS_MSG_IMPRINT *a, X509_ALGOR *alg); +X509_ALGOR *TS_MSG_IMPRINT_get_algo(TS_MSG_IMPRINT *a); + +int TS_MSG_IMPRINT_set_msg(TS_MSG_IMPRINT *a, unsigned char *d, int len); +ASN1_OCTET_STRING *TS_MSG_IMPRINT_get_msg(TS_MSG_IMPRINT *a); + +int TS_REQ_set_policy_id(TS_REQ *a, ASN1_OBJECT *policy); +ASN1_OBJECT *TS_REQ_get_policy_id(TS_REQ *a); + +int TS_REQ_set_nonce(TS_REQ *a, const ASN1_INTEGER *nonce); +const ASN1_INTEGER *TS_REQ_get_nonce(const TS_REQ *a); + +int TS_REQ_set_cert_req(TS_REQ *a, int cert_req); +int TS_REQ_get_cert_req(const TS_REQ *a); + +STACK_OF(X509_EXTENSION) *TS_REQ_get_exts(TS_REQ *a); +void TS_REQ_ext_free(TS_REQ *a); +int TS_REQ_get_ext_count(TS_REQ *a); +int TS_REQ_get_ext_by_NID(TS_REQ *a, int nid, int lastpos); +int TS_REQ_get_ext_by_OBJ(TS_REQ *a, ASN1_OBJECT *obj, int lastpos); +int TS_REQ_get_ext_by_critical(TS_REQ *a, int crit, int lastpos); +X509_EXTENSION *TS_REQ_get_ext(TS_REQ *a, int loc); +X509_EXTENSION *TS_REQ_delete_ext(TS_REQ *a, int loc); +int TS_REQ_add_ext(TS_REQ *a, X509_EXTENSION *ex, int loc); +void *TS_REQ_get_ext_d2i(TS_REQ *a, int nid, int *crit, int *idx); + +/* Function declarations for TS_REQ defined in ts/ts_req_print.c */ + +int TS_REQ_print_bio(BIO *bio, TS_REQ *a); + +/* Function declarations for TS_RESP defined in ts/ts_resp_utils.c */ + +int TS_RESP_set_status_info(TS_RESP *a, TS_STATUS_INFO *info); +TS_STATUS_INFO *TS_RESP_get_status_info(TS_RESP *a); + +/* Caller loses ownership of PKCS7 and TS_TST_INFO objects. */ +void TS_RESP_set_tst_info(TS_RESP *a, PKCS7 *p7, TS_TST_INFO *tst_info); +PKCS7 *TS_RESP_get_token(TS_RESP *a); +TS_TST_INFO *TS_RESP_get_tst_info(TS_RESP *a); + +int TS_TST_INFO_set_version(TS_TST_INFO *a, long version); +long TS_TST_INFO_get_version(const TS_TST_INFO *a); + +int TS_TST_INFO_set_policy_id(TS_TST_INFO *a, ASN1_OBJECT *policy_id); +ASN1_OBJECT *TS_TST_INFO_get_policy_id(TS_TST_INFO *a); + +int TS_TST_INFO_set_msg_imprint(TS_TST_INFO *a, TS_MSG_IMPRINT *msg_imprint); +TS_MSG_IMPRINT *TS_TST_INFO_get_msg_imprint(TS_TST_INFO *a); + +int TS_TST_INFO_set_serial(TS_TST_INFO *a, const ASN1_INTEGER *serial); +const ASN1_INTEGER *TS_TST_INFO_get_serial(const TS_TST_INFO *a); + +int TS_TST_INFO_set_time(TS_TST_INFO *a, const ASN1_GENERALIZEDTIME *gtime); +const ASN1_GENERALIZEDTIME *TS_TST_INFO_get_time(const TS_TST_INFO *a); + +int TS_TST_INFO_set_accuracy(TS_TST_INFO *a, TS_ACCURACY *accuracy); +TS_ACCURACY *TS_TST_INFO_get_accuracy(TS_TST_INFO *a); + +int TS_ACCURACY_set_seconds(TS_ACCURACY *a, const ASN1_INTEGER *seconds); +const ASN1_INTEGER *TS_ACCURACY_get_seconds(const TS_ACCURACY *a); + +int TS_ACCURACY_set_millis(TS_ACCURACY *a, const ASN1_INTEGER *millis); +const ASN1_INTEGER *TS_ACCURACY_get_millis(const TS_ACCURACY *a); + +int TS_ACCURACY_set_micros(TS_ACCURACY *a, const ASN1_INTEGER *micros); +const ASN1_INTEGER *TS_ACCURACY_get_micros(const TS_ACCURACY *a); + +int TS_TST_INFO_set_ordering(TS_TST_INFO *a, int ordering); +int TS_TST_INFO_get_ordering(const TS_TST_INFO *a); + +int TS_TST_INFO_set_nonce(TS_TST_INFO *a, const ASN1_INTEGER *nonce); +const ASN1_INTEGER *TS_TST_INFO_get_nonce(const TS_TST_INFO *a); + +int TS_TST_INFO_set_tsa(TS_TST_INFO *a, GENERAL_NAME *tsa); +GENERAL_NAME *TS_TST_INFO_get_tsa(TS_TST_INFO *a); + +STACK_OF(X509_EXTENSION) *TS_TST_INFO_get_exts(TS_TST_INFO *a); +void TS_TST_INFO_ext_free(TS_TST_INFO *a); +int TS_TST_INFO_get_ext_count(TS_TST_INFO *a); +int TS_TST_INFO_get_ext_by_NID(TS_TST_INFO *a, int nid, int lastpos); +int TS_TST_INFO_get_ext_by_OBJ(TS_TST_INFO *a, ASN1_OBJECT *obj, int lastpos); +int TS_TST_INFO_get_ext_by_critical(TS_TST_INFO *a, int crit, int lastpos); +X509_EXTENSION *TS_TST_INFO_get_ext(TS_TST_INFO *a, int loc); +X509_EXTENSION *TS_TST_INFO_delete_ext(TS_TST_INFO *a, int loc); +int TS_TST_INFO_add_ext(TS_TST_INFO *a, X509_EXTENSION *ex, int loc); +void *TS_TST_INFO_get_ext_d2i(TS_TST_INFO *a, int nid, int *crit, int *idx); + +/* + * Declarations related to response generation, defined in ts/ts_resp_sign.c. + */ + +/* Optional flags for response generation. */ + +/* Don't include the TSA name in response. */ +# define TS_TSA_NAME 0x01 + +/* Set ordering to true in response. */ +# define TS_ORDERING 0x02 + +/* + * Include the signer certificate and the other specified certificates in + * the ESS signing certificate attribute beside the PKCS7 signed data. + * Only the signer certificates is included by default. + */ +# define TS_ESS_CERT_ID_CHAIN 0x04 + +/* Forward declaration. */ +struct TS_resp_ctx; + +/* This must return a unique number less than 160 bits long. */ +typedef ASN1_INTEGER *(*TS_serial_cb) (struct TS_resp_ctx *, void *); + +/* + * This must return the seconds and microseconds since Jan 1, 1970 in the sec + * and usec variables allocated by the caller. Return non-zero for success + * and zero for failure. + */ +typedef int (*TS_time_cb) (struct TS_resp_ctx *, void *, long *sec, + long *usec); + +/* + * This must process the given extension. It can modify the TS_TST_INFO + * object of the context. Return values: !0 (processed), 0 (error, it must + * set the status info/failure info of the response). + */ +typedef int (*TS_extension_cb) (struct TS_resp_ctx *, X509_EXTENSION *, + void *); + +typedef struct TS_resp_ctx { + X509 *signer_cert; + EVP_PKEY *signer_key; + STACK_OF(X509) *certs; /* Certs to include in signed data. */ + STACK_OF(ASN1_OBJECT) *policies; /* Acceptable policies. */ + ASN1_OBJECT *default_policy; /* It may appear in policies, too. */ + STACK_OF(EVP_MD) *mds; /* Acceptable message digests. */ + ASN1_INTEGER *seconds; /* accuracy, 0 means not specified. */ + ASN1_INTEGER *millis; /* accuracy, 0 means not specified. */ + ASN1_INTEGER *micros; /* accuracy, 0 means not specified. */ + unsigned clock_precision_digits; /* fraction of seconds in time stamp + * token. */ + unsigned flags; /* Optional info, see values above. */ + /* Callback functions. */ + TS_serial_cb serial_cb; + void *serial_cb_data; /* User data for serial_cb. */ + TS_time_cb time_cb; + void *time_cb_data; /* User data for time_cb. */ + TS_extension_cb extension_cb; + void *extension_cb_data; /* User data for extension_cb. */ + /* These members are used only while creating the response. */ + TS_REQ *request; + TS_RESP *response; + TS_TST_INFO *tst_info; +} TS_RESP_CTX; + +DECLARE_STACK_OF(EVP_MD) +DECLARE_ASN1_SET_OF(EVP_MD) + +/* Creates a response context that can be used for generating responses. */ +TS_RESP_CTX *TS_RESP_CTX_new(void); +void TS_RESP_CTX_free(TS_RESP_CTX *ctx); + +/* This parameter must be set. */ +int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer); + +/* This parameter must be set. */ +int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key); + +/* This parameter must be set. */ +int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *def_policy); + +/* No additional certs are included in the response by default. */ +int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs); + +/* + * Adds a new acceptable policy, only the default policy is accepted by + * default. + */ +int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *policy); + +/* + * Adds a new acceptable message digest. Note that no message digests are + * accepted by default. The md argument is shared with the caller. + */ +int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md); + +/* Accuracy is not included by default. */ +int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx, + int secs, int millis, int micros); + +/* + * Clock precision digits, i.e. the number of decimal digits: '0' means sec, + * '3' msec, '6' usec, and so on. Default is 0. + */ +int TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx, + unsigned clock_precision_digits); +/* At most we accept usec precision. */ +# define TS_MAX_CLOCK_PRECISION_DIGITS 6 + +/* No flags are set by default. */ +void TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags); + +/* Default callback always returns a constant. */ +void TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data); + +/* Default callback uses the gettimeofday() and gmtime() system calls. */ +void TS_RESP_CTX_set_time_cb(TS_RESP_CTX *ctx, TS_time_cb cb, void *data); + +/* + * Default callback rejects all extensions. The extension callback is called + * when the TS_TST_INFO object is already set up and not signed yet. + */ +/* FIXME: extension handling is not tested yet. */ +void TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx, + TS_extension_cb cb, void *data); + +/* The following methods can be used in the callbacks. */ +int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx, + int status, const char *text); + +/* Sets the status info only if it is still TS_STATUS_GRANTED. */ +int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx, + int status, const char *text); + +int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure); + +/* The get methods below can be used in the extension callback. */ +TS_REQ *TS_RESP_CTX_get_request(TS_RESP_CTX *ctx); + +TS_TST_INFO *TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx); + +/* + * Creates the signed TS_TST_INFO and puts it in TS_RESP. + * In case of errors it sets the status info properly. + * Returns NULL only in case of memory allocation/fatal error. + */ +TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio); + +/* + * Declarations related to response verification, + * they are defined in ts/ts_resp_verify.c. + */ + +int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs, + X509_STORE *store, X509 **signer_out); + +/* Context structure for the generic verify method. */ + +/* Verify the signer's certificate and the signature of the response. */ +# define TS_VFY_SIGNATURE (1u << 0) +/* Verify the version number of the response. */ +# define TS_VFY_VERSION (1u << 1) +/* Verify if the policy supplied by the user matches the policy of the TSA. */ +# define TS_VFY_POLICY (1u << 2) +/* + * Verify the message imprint provided by the user. This flag should not be + * specified with TS_VFY_DATA. + */ +# define TS_VFY_IMPRINT (1u << 3) +/* + * Verify the message imprint computed by the verify method from the user + * provided data and the MD algorithm of the response. This flag should not + * be specified with TS_VFY_IMPRINT. + */ +# define TS_VFY_DATA (1u << 4) +/* Verify the nonce value. */ +# define TS_VFY_NONCE (1u << 5) +/* Verify if the TSA name field matches the signer certificate. */ +# define TS_VFY_SIGNER (1u << 6) +/* Verify if the TSA name field equals to the user provided name. */ +# define TS_VFY_TSA_NAME (1u << 7) + +/* You can use the following convenience constants. */ +# define TS_VFY_ALL_IMPRINT (TS_VFY_SIGNATURE \ + | TS_VFY_VERSION \ + | TS_VFY_POLICY \ + | TS_VFY_IMPRINT \ + | TS_VFY_NONCE \ + | TS_VFY_SIGNER \ + | TS_VFY_TSA_NAME) +# define TS_VFY_ALL_DATA (TS_VFY_SIGNATURE \ + | TS_VFY_VERSION \ + | TS_VFY_POLICY \ + | TS_VFY_DATA \ + | TS_VFY_NONCE \ + | TS_VFY_SIGNER \ + | TS_VFY_TSA_NAME) + +typedef struct TS_verify_ctx { + /* Set this to the union of TS_VFY_... flags you want to carry out. */ + unsigned flags; + /* Must be set only with TS_VFY_SIGNATURE. certs is optional. */ + X509_STORE *store; + STACK_OF(X509) *certs; + /* Must be set only with TS_VFY_POLICY. */ + ASN1_OBJECT *policy; + /* + * Must be set only with TS_VFY_IMPRINT. If md_alg is NULL, the + * algorithm from the response is used. + */ + X509_ALGOR *md_alg; + unsigned char *imprint; + unsigned imprint_len; + /* Must be set only with TS_VFY_DATA. */ + BIO *data; + /* Must be set only with TS_VFY_TSA_NAME. */ + ASN1_INTEGER *nonce; + /* Must be set only with TS_VFY_TSA_NAME. */ + GENERAL_NAME *tsa_name; +} TS_VERIFY_CTX; + +int TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response); +int TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token); + +/* + * Declarations related to response verification context, + * they are defined in ts/ts_verify_ctx.c. + */ + +/* Set all fields to zero. */ +TS_VERIFY_CTX *TS_VERIFY_CTX_new(void); +void TS_VERIFY_CTX_init(TS_VERIFY_CTX *ctx); +void TS_VERIFY_CTX_free(TS_VERIFY_CTX *ctx); +void TS_VERIFY_CTX_cleanup(TS_VERIFY_CTX *ctx); + +/*- + * If ctx is NULL, it allocates and returns a new object, otherwise + * it returns ctx. It initialises all the members as follows: + * flags = TS_VFY_ALL_IMPRINT & ~(TS_VFY_TSA_NAME | TS_VFY_SIGNATURE) + * certs = NULL + * store = NULL + * policy = policy from the request or NULL if absent (in this case + * TS_VFY_POLICY is cleared from flags as well) + * md_alg = MD algorithm from request + * imprint, imprint_len = imprint from request + * data = NULL + * nonce, nonce_len = nonce from the request or NULL if absent (in this case + * TS_VFY_NONCE is cleared from flags as well) + * tsa_name = NULL + * Important: after calling this method TS_VFY_SIGNATURE should be added! + */ +TS_VERIFY_CTX *TS_REQ_to_TS_VERIFY_CTX(TS_REQ *req, TS_VERIFY_CTX *ctx); + +/* Function declarations for TS_RESP defined in ts/ts_resp_print.c */ + +int TS_RESP_print_bio(BIO *bio, TS_RESP *a); +int TS_STATUS_INFO_print_bio(BIO *bio, TS_STATUS_INFO *a); +int TS_TST_INFO_print_bio(BIO *bio, TS_TST_INFO *a); + +/* Common utility functions defined in ts/ts_lib.c */ + +int TS_ASN1_INTEGER_print_bio(BIO *bio, const ASN1_INTEGER *num); +int TS_OBJ_print_bio(BIO *bio, const ASN1_OBJECT *obj); +int TS_ext_print_bio(BIO *bio, const STACK_OF(X509_EXTENSION) *extensions); +int TS_X509_ALGOR_print_bio(BIO *bio, const X509_ALGOR *alg); +int TS_MSG_IMPRINT_print_bio(BIO *bio, TS_MSG_IMPRINT *msg); + +/* + * Function declarations for handling configuration options, defined in + * ts/ts_conf.c + */ + +X509 *TS_CONF_load_cert(const char *file); +STACK_OF(X509) *TS_CONF_load_certs(const char *file); +EVP_PKEY *TS_CONF_load_key(const char *file, const char *pass); +const char *TS_CONF_get_tsa_section(CONF *conf, const char *section); +int TS_CONF_set_serial(CONF *conf, const char *section, TS_serial_cb cb, + TS_RESP_CTX *ctx); +int TS_CONF_set_crypto_device(CONF *conf, const char *section, + const char *device); +int TS_CONF_set_default_engine(const char *name); +int TS_CONF_set_signer_cert(CONF *conf, const char *section, + const char *cert, TS_RESP_CTX *ctx); +int TS_CONF_set_certs(CONF *conf, const char *section, const char *certs, + TS_RESP_CTX *ctx); +int TS_CONF_set_signer_key(CONF *conf, const char *section, + const char *key, const char *pass, + TS_RESP_CTX *ctx); +int TS_CONF_set_def_policy(CONF *conf, const char *section, + const char *policy, TS_RESP_CTX *ctx); +int TS_CONF_set_policies(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_digests(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_accuracy(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_clock_precision_digits(CONF *conf, const char *section, + TS_RESP_CTX *ctx); +int TS_CONF_set_ordering(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_tsa_name(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_ess_cert_id_chain(CONF *conf, const char *section, + TS_RESP_CTX *ctx); + +/* -------------------------------------------------- */ +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_TS_strings(void); + +/* Error codes for the TS functions. */ + +/* Function codes. */ +# define TS_F_D2I_TS_RESP 147 +# define TS_F_DEF_SERIAL_CB 110 +# define TS_F_DEF_TIME_CB 111 +# define TS_F_ESS_ADD_SIGNING_CERT 112 +# define TS_F_ESS_CERT_ID_NEW_INIT 113 +# define TS_F_ESS_SIGNING_CERT_NEW_INIT 114 +# define TS_F_INT_TS_RESP_VERIFY_TOKEN 149 +# define TS_F_PKCS7_TO_TS_TST_INFO 148 +# define TS_F_TS_ACCURACY_SET_MICROS 115 +# define TS_F_TS_ACCURACY_SET_MILLIS 116 +# define TS_F_TS_ACCURACY_SET_SECONDS 117 +# define TS_F_TS_CHECK_IMPRINTS 100 +# define TS_F_TS_CHECK_NONCES 101 +# define TS_F_TS_CHECK_POLICY 102 +# define TS_F_TS_CHECK_SIGNING_CERTS 103 +# define TS_F_TS_CHECK_STATUS_INFO 104 +# define TS_F_TS_COMPUTE_IMPRINT 145 +# define TS_F_TS_CONF_SET_DEFAULT_ENGINE 146 +# define TS_F_TS_GET_STATUS_TEXT 105 +# define TS_F_TS_MSG_IMPRINT_SET_ALGO 118 +# define TS_F_TS_REQ_SET_MSG_IMPRINT 119 +# define TS_F_TS_REQ_SET_NONCE 120 +# define TS_F_TS_REQ_SET_POLICY_ID 121 +# define TS_F_TS_RESP_CREATE_RESPONSE 122 +# define TS_F_TS_RESP_CREATE_TST_INFO 123 +# define TS_F_TS_RESP_CTX_ADD_FAILURE_INFO 124 +# define TS_F_TS_RESP_CTX_ADD_MD 125 +# define TS_F_TS_RESP_CTX_ADD_POLICY 126 +# define TS_F_TS_RESP_CTX_NEW 127 +# define TS_F_TS_RESP_CTX_SET_ACCURACY 128 +# define TS_F_TS_RESP_CTX_SET_CERTS 129 +# define TS_F_TS_RESP_CTX_SET_DEF_POLICY 130 +# define TS_F_TS_RESP_CTX_SET_SIGNER_CERT 131 +# define TS_F_TS_RESP_CTX_SET_STATUS_INFO 132 +# define TS_F_TS_RESP_GET_POLICY 133 +# define TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION 134 +# define TS_F_TS_RESP_SET_STATUS_INFO 135 +# define TS_F_TS_RESP_SET_TST_INFO 150 +# define TS_F_TS_RESP_SIGN 136 +# define TS_F_TS_RESP_VERIFY_SIGNATURE 106 +# define TS_F_TS_RESP_VERIFY_TOKEN 107 +# define TS_F_TS_TST_INFO_SET_ACCURACY 137 +# define TS_F_TS_TST_INFO_SET_MSG_IMPRINT 138 +# define TS_F_TS_TST_INFO_SET_NONCE 139 +# define TS_F_TS_TST_INFO_SET_POLICY_ID 140 +# define TS_F_TS_TST_INFO_SET_SERIAL 141 +# define TS_F_TS_TST_INFO_SET_TIME 142 +# define TS_F_TS_TST_INFO_SET_TSA 143 +# define TS_F_TS_VERIFY 108 +# define TS_F_TS_VERIFY_CERT 109 +# define TS_F_TS_VERIFY_CTX_NEW 144 + +/* Reason codes. */ +# define TS_R_BAD_PKCS7_TYPE 132 +# define TS_R_BAD_TYPE 133 +# define TS_R_CERTIFICATE_VERIFY_ERROR 100 +# define TS_R_COULD_NOT_SET_ENGINE 127 +# define TS_R_COULD_NOT_SET_TIME 115 +# define TS_R_D2I_TS_RESP_INT_FAILED 128 +# define TS_R_DETACHED_CONTENT 134 +# define TS_R_ESS_ADD_SIGNING_CERT_ERROR 116 +# define TS_R_ESS_SIGNING_CERTIFICATE_ERROR 101 +# define TS_R_INVALID_NULL_POINTER 102 +# define TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE 117 +# define TS_R_MESSAGE_IMPRINT_MISMATCH 103 +# define TS_R_NONCE_MISMATCH 104 +# define TS_R_NONCE_NOT_RETURNED 105 +# define TS_R_NO_CONTENT 106 +# define TS_R_NO_TIME_STAMP_TOKEN 107 +# define TS_R_PKCS7_ADD_SIGNATURE_ERROR 118 +# define TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR 119 +# define TS_R_PKCS7_TO_TS_TST_INFO_FAILED 129 +# define TS_R_POLICY_MISMATCH 108 +# define TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 120 +# define TS_R_RESPONSE_SETUP_ERROR 121 +# define TS_R_SIGNATURE_FAILURE 109 +# define TS_R_THERE_MUST_BE_ONE_SIGNER 110 +# define TS_R_TIME_SYSCALL_ERROR 122 +# define TS_R_TOKEN_NOT_PRESENT 130 +# define TS_R_TOKEN_PRESENT 131 +# define TS_R_TSA_NAME_MISMATCH 111 +# define TS_R_TSA_UNTRUSTED 112 +# define TS_R_TST_INFO_SETUP_ERROR 123 +# define TS_R_TS_DATASIGN 124 +# define TS_R_UNACCEPTABLE_POLICY 125 +# define TS_R_UNSUPPORTED_MD_ALGORITHM 126 +# define TS_R_UNSUPPORTED_VERSION 113 +# define TS_R_WRONG_CONTENT_TYPE 114 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/txt_db.h b/OSlibs/ios/include/openssl/txt_db.h new file mode 100755 index 000000000..98e23a200 --- /dev/null +++ b/OSlibs/ios/include/openssl/txt_db.h @@ -0,0 +1,112 @@ +/* crypto/txt_db/txt_db.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_TXT_DB_H +# define HEADER_TXT_DB_H + +# include +# ifndef OPENSSL_NO_BIO +# include +# endif +# include +# include + +# define DB_ERROR_OK 0 +# define DB_ERROR_MALLOC 1 +# define DB_ERROR_INDEX_CLASH 2 +# define DB_ERROR_INDEX_OUT_OF_RANGE 3 +# define DB_ERROR_NO_INDEX 4 +# define DB_ERROR_INSERT_INDEX_CLASH 5 + +#ifdef __cplusplus +extern "C" { +#endif + +typedef OPENSSL_STRING *OPENSSL_PSTRING; +DECLARE_SPECIAL_STACK_OF(OPENSSL_PSTRING, OPENSSL_STRING) + +typedef struct txt_db_st { + int num_fields; + STACK_OF(OPENSSL_PSTRING) *data; + LHASH_OF(OPENSSL_STRING) **index; + int (**qual) (OPENSSL_STRING *); + long error; + long arg1; + long arg2; + OPENSSL_STRING *arg_row; +} TXT_DB; + +# ifndef OPENSSL_NO_BIO +TXT_DB *TXT_DB_read(BIO *in, int num); +long TXT_DB_write(BIO *out, TXT_DB *db); +# else +TXT_DB *TXT_DB_read(char *in, int num); +long TXT_DB_write(char *out, TXT_DB *db); +# endif +int TXT_DB_create_index(TXT_DB *db, int field, int (*qual) (OPENSSL_STRING *), + LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp); +void TXT_DB_free(TXT_DB *db); +OPENSSL_STRING *TXT_DB_get_by_index(TXT_DB *db, int idx, + OPENSSL_STRING *value); +int TXT_DB_insert(TXT_DB *db, OPENSSL_STRING *value); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/OSlibs/ios/include/openssl/ui.h b/OSlibs/ios/include/openssl/ui.h new file mode 100755 index 000000000..0dc16330b --- /dev/null +++ b/OSlibs/ios/include/openssl/ui.h @@ -0,0 +1,415 @@ +/* crypto/ui/ui.h */ +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_UI_H +# define HEADER_UI_H + +# ifndef OPENSSL_NO_DEPRECATED +# include +# endif +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Declared already in ossl_typ.h */ +/* typedef struct ui_st UI; */ +/* typedef struct ui_method_st UI_METHOD; */ + +/* + * All the following functions return -1 or NULL on error and in some cases + * (UI_process()) -2 if interrupted or in some other way cancelled. When + * everything is fine, they return 0, a positive value or a non-NULL pointer, + * all depending on their purpose. + */ + +/* Creators and destructor. */ +UI *UI_new(void); +UI *UI_new_method(const UI_METHOD *method); +void UI_free(UI *ui); + +/*- + The following functions are used to add strings to be printed and prompt + strings to prompt for data. The names are UI_{add,dup}__string + and UI_{add,dup}_input_boolean. + + UI_{add,dup}__string have the following meanings: + add add a text or prompt string. The pointers given to these + functions are used verbatim, no copying is done. + dup make a copy of the text or prompt string, then add the copy + to the collection of strings in the user interface. + + The function is a name for the functionality that the given + string shall be used for. It can be one of: + input use the string as data prompt. + verify use the string as verification prompt. This + is used to verify a previous input. + info use the string for informational output. + error use the string for error output. + Honestly, there's currently no difference between info and error for the + moment. + + UI_{add,dup}_input_boolean have the same semantics for "add" and "dup", + and are typically used when one wants to prompt for a yes/no response. + + All of the functions in this group take a UI and a prompt string. + The string input and verify addition functions also take a flag argument, + a buffer for the result to end up with, a minimum input size and a maximum + input size (the result buffer MUST be large enough to be able to contain + the maximum number of characters). Additionally, the verify addition + functions takes another buffer to compare the result against. + The boolean input functions take an action description string (which should + be safe to ignore if the expected user action is obvious, for example with + a dialog box with an OK button and a Cancel button), a string of acceptable + characters to mean OK and to mean Cancel. The two last strings are checked + to make sure they don't have common characters. Additionally, the same + flag argument as for the string input is taken, as well as a result buffer. + The result buffer is required to be at least one byte long. Depending on + the answer, the first character from the OK or the Cancel character strings + will be stored in the first byte of the result buffer. No NUL will be + added, so the result is *not* a string. + + On success, the all return an index of the added information. That index + is usefull when retrieving results with UI_get0_result(). */ +int UI_add_input_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize); +int UI_dup_input_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize); +int UI_add_verify_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize, + const char *test_buf); +int UI_dup_verify_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize, + const char *test_buf); +int UI_add_input_boolean(UI *ui, const char *prompt, const char *action_desc, + const char *ok_chars, const char *cancel_chars, + int flags, char *result_buf); +int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc, + const char *ok_chars, const char *cancel_chars, + int flags, char *result_buf); +int UI_add_info_string(UI *ui, const char *text); +int UI_dup_info_string(UI *ui, const char *text); +int UI_add_error_string(UI *ui, const char *text); +int UI_dup_error_string(UI *ui, const char *text); + +/* These are the possible flags. They can be or'ed together. */ +/* Use to have echoing of input */ +# define UI_INPUT_FLAG_ECHO 0x01 +/* + * Use a default password. Where that password is found is completely up to + * the application, it might for example be in the user data set with + * UI_add_user_data(). It is not recommended to have more than one input in + * each UI being marked with this flag, or the application might get + * confused. + */ +# define UI_INPUT_FLAG_DEFAULT_PWD 0x02 + +/*- + * The user of these routines may want to define flags of their own. The core + * UI won't look at those, but will pass them on to the method routines. They + * must use higher bits so they don't get confused with the UI bits above. + * UI_INPUT_FLAG_USER_BASE tells which is the lowest bit to use. A good + * example of use is this: + * + * #define MY_UI_FLAG1 (0x01 << UI_INPUT_FLAG_USER_BASE) + * +*/ +# define UI_INPUT_FLAG_USER_BASE 16 + +/*- + * The following function helps construct a prompt. object_desc is a + * textual short description of the object, for example "pass phrase", + * and object_name is the name of the object (might be a card name or + * a file name. + * The returned string shall always be allocated on the heap with + * OPENSSL_malloc(), and need to be free'd with OPENSSL_free(). + * + * If the ui_method doesn't contain a pointer to a user-defined prompt + * constructor, a default string is built, looking like this: + * + * "Enter {object_desc} for {object_name}:" + * + * So, if object_desc has the value "pass phrase" and object_name has + * the value "foo.key", the resulting string is: + * + * "Enter pass phrase for foo.key:" +*/ +char *UI_construct_prompt(UI *ui_method, + const char *object_desc, const char *object_name); + +/* + * The following function is used to store a pointer to user-specific data. + * Any previous such pointer will be returned and replaced. + * + * For callback purposes, this function makes a lot more sense than using + * ex_data, since the latter requires that different parts of OpenSSL or + * applications share the same ex_data index. + * + * Note that the UI_OpenSSL() method completely ignores the user data. Other + * methods may not, however. + */ +void *UI_add_user_data(UI *ui, void *user_data); +/* We need a user data retrieving function as well. */ +void *UI_get0_user_data(UI *ui); + +/* Return the result associated with a prompt given with the index i. */ +const char *UI_get0_result(UI *ui, int i); + +/* When all strings have been added, process the whole thing. */ +int UI_process(UI *ui); + +/* + * Give a user interface parametrised control commands. This can be used to + * send down an integer, a data pointer or a function pointer, as well as be + * used to get information from a UI. + */ +int UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f) (void)); + +/* The commands */ +/* + * Use UI_CONTROL_PRINT_ERRORS with the value 1 to have UI_process print the + * OpenSSL error stack before printing any info or added error messages and + * before any prompting. + */ +# define UI_CTRL_PRINT_ERRORS 1 +/* + * Check if a UI_process() is possible to do again with the same instance of + * a user interface. This makes UI_ctrl() return 1 if it is redoable, and 0 + * if not. + */ +# define UI_CTRL_IS_REDOABLE 2 + +/* Some methods may use extra data */ +# define UI_set_app_data(s,arg) UI_set_ex_data(s,0,arg) +# define UI_get_app_data(s) UI_get_ex_data(s,0) +int UI_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int UI_set_ex_data(UI *r, int idx, void *arg); +void *UI_get_ex_data(UI *r, int idx); + +/* Use specific methods instead of the built-in one */ +void UI_set_default_method(const UI_METHOD *meth); +const UI_METHOD *UI_get_default_method(void); +const UI_METHOD *UI_get_method(UI *ui); +const UI_METHOD *UI_set_method(UI *ui, const UI_METHOD *meth); + +/* The method with all the built-in thingies */ +UI_METHOD *UI_OpenSSL(void); + +/* ---------- For method writers ---------- */ +/*- + A method contains a number of functions that implement the low level + of the User Interface. The functions are: + + an opener This function starts a session, maybe by opening + a channel to a tty, or by opening a window. + a writer This function is called to write a given string, + maybe to the tty, maybe as a field label in a + window. + a flusher This function is called to flush everything that + has been output so far. It can be used to actually + display a dialog box after it has been built. + a reader This function is called to read a given prompt, + maybe from the tty, maybe from a field in a + window. Note that it's called wth all string + structures, not only the prompt ones, so it must + check such things itself. + a closer This function closes the session, maybe by closing + the channel to the tty, or closing the window. + + All these functions are expected to return: + + 0 on error. + 1 on success. + -1 on out-of-band events, for example if some prompting has + been canceled (by pressing Ctrl-C, for example). This is + only checked when returned by the flusher or the reader. + + The way this is used, the opener is first called, then the writer for all + strings, then the flusher, then the reader for all strings and finally the + closer. Note that if you want to prompt from a terminal or other command + line interface, the best is to have the reader also write the prompts + instead of having the writer do it. If you want to prompt from a dialog + box, the writer can be used to build up the contents of the box, and the + flusher to actually display the box and run the event loop until all data + has been given, after which the reader only grabs the given data and puts + them back into the UI strings. + + All method functions take a UI as argument. Additionally, the writer and + the reader take a UI_STRING. +*/ + +/* + * The UI_STRING type is the data structure that contains all the needed info + * about a string or a prompt, including test data for a verification prompt. + */ +typedef struct ui_string_st UI_STRING; +DECLARE_STACK_OF(UI_STRING) + +/* + * The different types of strings that are currently supported. This is only + * needed by method authors. + */ +enum UI_string_types { + UIT_NONE = 0, + UIT_PROMPT, /* Prompt for a string */ + UIT_VERIFY, /* Prompt for a string and verify */ + UIT_BOOLEAN, /* Prompt for a yes/no response */ + UIT_INFO, /* Send info to the user */ + UIT_ERROR /* Send an error message to the user */ +}; + +/* Create and manipulate methods */ +UI_METHOD *UI_create_method(char *name); +void UI_destroy_method(UI_METHOD *ui_method); +int UI_method_set_opener(UI_METHOD *method, int (*opener) (UI *ui)); +int UI_method_set_writer(UI_METHOD *method, + int (*writer) (UI *ui, UI_STRING *uis)); +int UI_method_set_flusher(UI_METHOD *method, int (*flusher) (UI *ui)); +int UI_method_set_reader(UI_METHOD *method, + int (*reader) (UI *ui, UI_STRING *uis)); +int UI_method_set_closer(UI_METHOD *method, int (*closer) (UI *ui)); +int UI_method_set_prompt_constructor(UI_METHOD *method, + char *(*prompt_constructor) (UI *ui, + const char + *object_desc, + const char + *object_name)); +int (*UI_method_get_opener(UI_METHOD *method)) (UI *); +int (*UI_method_get_writer(UI_METHOD *method)) (UI *, UI_STRING *); +int (*UI_method_get_flusher(UI_METHOD *method)) (UI *); +int (*UI_method_get_reader(UI_METHOD *method)) (UI *, UI_STRING *); +int (*UI_method_get_closer(UI_METHOD *method)) (UI *); +char *(*UI_method_get_prompt_constructor(UI_METHOD *method)) (UI *, + const char *, + const char *); + +/* + * The following functions are helpers for method writers to access relevant + * data from a UI_STRING. + */ + +/* Return type of the UI_STRING */ +enum UI_string_types UI_get_string_type(UI_STRING *uis); +/* Return input flags of the UI_STRING */ +int UI_get_input_flags(UI_STRING *uis); +/* Return the actual string to output (the prompt, info or error) */ +const char *UI_get0_output_string(UI_STRING *uis); +/* + * Return the optional action string to output (the boolean promtp + * instruction) + */ +const char *UI_get0_action_string(UI_STRING *uis); +/* Return the result of a prompt */ +const char *UI_get0_result_string(UI_STRING *uis); +/* + * Return the string to test the result against. Only useful with verifies. + */ +const char *UI_get0_test_string(UI_STRING *uis); +/* Return the required minimum size of the result */ +int UI_get_result_minsize(UI_STRING *uis); +/* Return the required maximum size of the result */ +int UI_get_result_maxsize(UI_STRING *uis); +/* Set the result of a UI_STRING. */ +int UI_set_result(UI *ui, UI_STRING *uis, const char *result); + +/* A couple of popular utility functions */ +int UI_UTIL_read_pw_string(char *buf, int length, const char *prompt, + int verify); +int UI_UTIL_read_pw(char *buf, char *buff, int size, const char *prompt, + int verify); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_UI_strings(void); + +/* Error codes for the UI functions. */ + +/* Function codes. */ +# define UI_F_GENERAL_ALLOCATE_BOOLEAN 108 +# define UI_F_GENERAL_ALLOCATE_PROMPT 109 +# define UI_F_GENERAL_ALLOCATE_STRING 100 +# define UI_F_UI_CTRL 111 +# define UI_F_UI_DUP_ERROR_STRING 101 +# define UI_F_UI_DUP_INFO_STRING 102 +# define UI_F_UI_DUP_INPUT_BOOLEAN 110 +# define UI_F_UI_DUP_INPUT_STRING 103 +# define UI_F_UI_DUP_VERIFY_STRING 106 +# define UI_F_UI_GET0_RESULT 107 +# define UI_F_UI_NEW_METHOD 104 +# define UI_F_UI_SET_RESULT 105 + +/* Reason codes. */ +# define UI_R_COMMON_OK_AND_CANCEL_CHARACTERS 104 +# define UI_R_INDEX_TOO_LARGE 102 +# define UI_R_INDEX_TOO_SMALL 103 +# define UI_R_NO_RESULT_BUFFER 105 +# define UI_R_RESULT_TOO_LARGE 100 +# define UI_R_RESULT_TOO_SMALL 101 +# define UI_R_UNKNOWN_CONTROL_COMMAND 106 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/ui_compat.h b/OSlibs/ios/include/openssl/ui_compat.h new file mode 100755 index 000000000..bf541542c --- /dev/null +++ b/OSlibs/ios/include/openssl/ui_compat.h @@ -0,0 +1,88 @@ +/* crypto/ui/ui.h */ +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_UI_COMPAT_H +# define HEADER_UI_COMPAT_H + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The following functions were previously part of the DES section, and are + * provided here for backward compatibility reasons. + */ + +# define des_read_pw_string(b,l,p,v) \ + _ossl_old_des_read_pw_string((b),(l),(p),(v)) +# define des_read_pw(b,bf,s,p,v) \ + _ossl_old_des_read_pw((b),(bf),(s),(p),(v)) + +int _ossl_old_des_read_pw_string(char *buf, int length, const char *prompt, + int verify); +int _ossl_old_des_read_pw(char *buf, char *buff, int size, const char *prompt, + int verify); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/whrlpool.h b/OSlibs/ios/include/openssl/whrlpool.h new file mode 100755 index 000000000..73c749da8 --- /dev/null +++ b/OSlibs/ios/include/openssl/whrlpool.h @@ -0,0 +1,41 @@ +#ifndef HEADER_WHRLPOOL_H +# define HEADER_WHRLPOOL_H + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# define WHIRLPOOL_DIGEST_LENGTH (512/8) +# define WHIRLPOOL_BBLOCK 512 +# define WHIRLPOOL_COUNTER (256/8) + +typedef struct { + union { + unsigned char c[WHIRLPOOL_DIGEST_LENGTH]; + /* double q is here to ensure 64-bit alignment */ + double q[WHIRLPOOL_DIGEST_LENGTH / sizeof(double)]; + } H; + unsigned char data[WHIRLPOOL_BBLOCK / 8]; + unsigned int bitoff; + size_t bitlen[WHIRLPOOL_COUNTER / sizeof(size_t)]; +} WHIRLPOOL_CTX; + +# ifndef OPENSSL_NO_WHIRLPOOL +# ifdef OPENSSL_FIPS +int private_WHIRLPOOL_Init(WHIRLPOOL_CTX *c); +# endif +int WHIRLPOOL_Init(WHIRLPOOL_CTX *c); +int WHIRLPOOL_Update(WHIRLPOOL_CTX *c, const void *inp, size_t bytes); +void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c, const void *inp, size_t bits); +int WHIRLPOOL_Final(unsigned char *md, WHIRLPOOL_CTX *c); +unsigned char *WHIRLPOOL(const void *inp, size_t bytes, unsigned char *md); +# endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/OSlibs/ios/include/openssl/x509.h b/OSlibs/ios/include/openssl/x509.h new file mode 100755 index 000000000..fc613ce63 --- /dev/null +++ b/OSlibs/ios/include/openssl/x509.h @@ -0,0 +1,1328 @@ +/* crypto/x509/x509.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECDH support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#ifndef HEADER_X509_H +# define HEADER_X509_H + +# include +# include +# ifndef OPENSSL_NO_BUFFER +# include +# endif +# ifndef OPENSSL_NO_EVP +# include +# endif +# ifndef OPENSSL_NO_BIO +# include +# endif +# include +# include +# include + +# ifndef OPENSSL_NO_EC +# include +# endif + +# ifndef OPENSSL_NO_ECDSA +# include +# endif + +# ifndef OPENSSL_NO_ECDH +# include +# endif + +# ifndef OPENSSL_NO_DEPRECATED +# ifndef OPENSSL_NO_RSA +# include +# endif +# ifndef OPENSSL_NO_DSA +# include +# endif +# ifndef OPENSSL_NO_DH +# include +# endif +# endif + +# ifndef OPENSSL_NO_SHA +# include +# endif +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# ifdef OPENSSL_SYS_WIN32 +/* Under Win32 these are defined in wincrypt.h */ +# undef X509_NAME +# undef X509_CERT_PAIR +# undef X509_EXTENSIONS +# endif + +# define X509_FILETYPE_PEM 1 +# define X509_FILETYPE_ASN1 2 +# define X509_FILETYPE_DEFAULT 3 + +# define X509v3_KU_DIGITAL_SIGNATURE 0x0080 +# define X509v3_KU_NON_REPUDIATION 0x0040 +# define X509v3_KU_KEY_ENCIPHERMENT 0x0020 +# define X509v3_KU_DATA_ENCIPHERMENT 0x0010 +# define X509v3_KU_KEY_AGREEMENT 0x0008 +# define X509v3_KU_KEY_CERT_SIGN 0x0004 +# define X509v3_KU_CRL_SIGN 0x0002 +# define X509v3_KU_ENCIPHER_ONLY 0x0001 +# define X509v3_KU_DECIPHER_ONLY 0x8000 +# define X509v3_KU_UNDEF 0xffff + +typedef struct X509_objects_st { + int nid; + int (*a2i) (void); + int (*i2a) (void); +} X509_OBJECTS; + +struct X509_algor_st { + ASN1_OBJECT *algorithm; + ASN1_TYPE *parameter; +} /* X509_ALGOR */ ; + +DECLARE_ASN1_SET_OF(X509_ALGOR) + +typedef STACK_OF(X509_ALGOR) X509_ALGORS; + +typedef struct X509_val_st { + ASN1_TIME *notBefore; + ASN1_TIME *notAfter; +} X509_VAL; + +struct X509_pubkey_st { + X509_ALGOR *algor; + ASN1_BIT_STRING *public_key; + EVP_PKEY *pkey; +}; + +typedef struct X509_sig_st { + X509_ALGOR *algor; + ASN1_OCTET_STRING *digest; +} X509_SIG; + +typedef struct X509_name_entry_st { + ASN1_OBJECT *object; + ASN1_STRING *value; + int set; + int size; /* temp variable */ +} X509_NAME_ENTRY; + +DECLARE_STACK_OF(X509_NAME_ENTRY) +DECLARE_ASN1_SET_OF(X509_NAME_ENTRY) + +/* we always keep X509_NAMEs in 2 forms. */ +struct X509_name_st { + STACK_OF(X509_NAME_ENTRY) *entries; + int modified; /* true if 'bytes' needs to be built */ +# ifndef OPENSSL_NO_BUFFER + BUF_MEM *bytes; +# else + char *bytes; +# endif +/* unsigned long hash; Keep the hash around for lookups */ + unsigned char *canon_enc; + int canon_enclen; +} /* X509_NAME */ ; + +DECLARE_STACK_OF(X509_NAME) + +# define X509_EX_V_NETSCAPE_HACK 0x8000 +# define X509_EX_V_INIT 0x0001 +typedef struct X509_extension_st { + ASN1_OBJECT *object; + ASN1_BOOLEAN critical; + ASN1_OCTET_STRING *value; +} X509_EXTENSION; + +typedef STACK_OF(X509_EXTENSION) X509_EXTENSIONS; + +DECLARE_STACK_OF(X509_EXTENSION) +DECLARE_ASN1_SET_OF(X509_EXTENSION) + +/* a sequence of these are used */ +typedef struct x509_attributes_st { + ASN1_OBJECT *object; + int single; /* 0 for a set, 1 for a single item (which is + * wrong) */ + union { + char *ptr; + /* + * 0 + */ STACK_OF(ASN1_TYPE) *set; + /* + * 1 + */ ASN1_TYPE *single; + } value; +} X509_ATTRIBUTE; + +DECLARE_STACK_OF(X509_ATTRIBUTE) +DECLARE_ASN1_SET_OF(X509_ATTRIBUTE) + +typedef struct X509_req_info_st { + ASN1_ENCODING enc; + ASN1_INTEGER *version; + X509_NAME *subject; + X509_PUBKEY *pubkey; + /* d=2 hl=2 l= 0 cons: cont: 00 */ + STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */ +} X509_REQ_INFO; + +typedef struct X509_req_st { + X509_REQ_INFO *req_info; + X509_ALGOR *sig_alg; + ASN1_BIT_STRING *signature; + int references; +} X509_REQ; + +typedef struct x509_cinf_st { + ASN1_INTEGER *version; /* [ 0 ] default of v1 */ + ASN1_INTEGER *serialNumber; + X509_ALGOR *signature; + X509_NAME *issuer; + X509_VAL *validity; + X509_NAME *subject; + X509_PUBKEY *key; + ASN1_BIT_STRING *issuerUID; /* [ 1 ] optional in v2 */ + ASN1_BIT_STRING *subjectUID; /* [ 2 ] optional in v2 */ + STACK_OF(X509_EXTENSION) *extensions; /* [ 3 ] optional in v3 */ + ASN1_ENCODING enc; +} X509_CINF; + +/* + * This stuff is certificate "auxiliary info" it contains details which are + * useful in certificate stores and databases. When used this is tagged onto + * the end of the certificate itself + */ + +typedef struct x509_cert_aux_st { + STACK_OF(ASN1_OBJECT) *trust; /* trusted uses */ + STACK_OF(ASN1_OBJECT) *reject; /* rejected uses */ + ASN1_UTF8STRING *alias; /* "friendly name" */ + ASN1_OCTET_STRING *keyid; /* key id of private key */ + STACK_OF(X509_ALGOR) *other; /* other unspecified info */ +} X509_CERT_AUX; + +struct x509_st { + X509_CINF *cert_info; + X509_ALGOR *sig_alg; + ASN1_BIT_STRING *signature; + int valid; + int references; + char *name; + CRYPTO_EX_DATA ex_data; + /* These contain copies of various extension values */ + long ex_pathlen; + long ex_pcpathlen; + unsigned long ex_flags; + unsigned long ex_kusage; + unsigned long ex_xkusage; + unsigned long ex_nscert; + ASN1_OCTET_STRING *skid; + AUTHORITY_KEYID *akid; + X509_POLICY_CACHE *policy_cache; + STACK_OF(DIST_POINT) *crldp; + STACK_OF(GENERAL_NAME) *altname; + NAME_CONSTRAINTS *nc; +# ifndef OPENSSL_NO_RFC3779 + STACK_OF(IPAddressFamily) *rfc3779_addr; + struct ASIdentifiers_st *rfc3779_asid; +# endif +# ifndef OPENSSL_NO_SHA + unsigned char sha1_hash[SHA_DIGEST_LENGTH]; +# endif + X509_CERT_AUX *aux; +} /* X509 */ ; + +DECLARE_STACK_OF(X509) +DECLARE_ASN1_SET_OF(X509) + +/* This is used for a table of trust checking functions */ + +typedef struct x509_trust_st { + int trust; + int flags; + int (*check_trust) (struct x509_trust_st *, X509 *, int); + char *name; + int arg1; + void *arg2; +} X509_TRUST; + +DECLARE_STACK_OF(X509_TRUST) + +typedef struct x509_cert_pair_st { + X509 *forward; + X509 *reverse; +} X509_CERT_PAIR; + +/* standard trust ids */ + +# define X509_TRUST_DEFAULT -1/* Only valid in purpose settings */ + +# define X509_TRUST_COMPAT 1 +# define X509_TRUST_SSL_CLIENT 2 +# define X509_TRUST_SSL_SERVER 3 +# define X509_TRUST_EMAIL 4 +# define X509_TRUST_OBJECT_SIGN 5 +# define X509_TRUST_OCSP_SIGN 6 +# define X509_TRUST_OCSP_REQUEST 7 +# define X509_TRUST_TSA 8 + +/* Keep these up to date! */ +# define X509_TRUST_MIN 1 +# define X509_TRUST_MAX 8 + +/* trust_flags values */ +# define X509_TRUST_DYNAMIC 1 +# define X509_TRUST_DYNAMIC_NAME 2 + +/* check_trust return codes */ + +# define X509_TRUST_TRUSTED 1 +# define X509_TRUST_REJECTED 2 +# define X509_TRUST_UNTRUSTED 3 + +/* Flags for X509_print_ex() */ + +# define X509_FLAG_COMPAT 0 +# define X509_FLAG_NO_HEADER 1L +# define X509_FLAG_NO_VERSION (1L << 1) +# define X509_FLAG_NO_SERIAL (1L << 2) +# define X509_FLAG_NO_SIGNAME (1L << 3) +# define X509_FLAG_NO_ISSUER (1L << 4) +# define X509_FLAG_NO_VALIDITY (1L << 5) +# define X509_FLAG_NO_SUBJECT (1L << 6) +# define X509_FLAG_NO_PUBKEY (1L << 7) +# define X509_FLAG_NO_EXTENSIONS (1L << 8) +# define X509_FLAG_NO_SIGDUMP (1L << 9) +# define X509_FLAG_NO_AUX (1L << 10) +# define X509_FLAG_NO_ATTRIBUTES (1L << 11) +# define X509_FLAG_NO_IDS (1L << 12) + +/* Flags specific to X509_NAME_print_ex() */ + +/* The field separator information */ + +# define XN_FLAG_SEP_MASK (0xf << 16) + +# define XN_FLAG_COMPAT 0/* Traditional SSLeay: use old + * X509_NAME_print */ +# define XN_FLAG_SEP_COMMA_PLUS (1 << 16)/* RFC2253 ,+ */ +# define XN_FLAG_SEP_CPLUS_SPC (2 << 16)/* ,+ spaced: more readable */ +# define XN_FLAG_SEP_SPLUS_SPC (3 << 16)/* ;+ spaced */ +# define XN_FLAG_SEP_MULTILINE (4 << 16)/* One line per field */ + +# define XN_FLAG_DN_REV (1 << 20)/* Reverse DN order */ + +/* How the field name is shown */ + +# define XN_FLAG_FN_MASK (0x3 << 21) + +# define XN_FLAG_FN_SN 0/* Object short name */ +# define XN_FLAG_FN_LN (1 << 21)/* Object long name */ +# define XN_FLAG_FN_OID (2 << 21)/* Always use OIDs */ +# define XN_FLAG_FN_NONE (3 << 21)/* No field names */ + +# define XN_FLAG_SPC_EQ (1 << 23)/* Put spaces round '=' */ + +/* + * This determines if we dump fields we don't recognise: RFC2253 requires + * this. + */ + +# define XN_FLAG_DUMP_UNKNOWN_FIELDS (1 << 24) + +# define XN_FLAG_FN_ALIGN (1 << 25)/* Align field names to 20 + * characters */ + +/* Complete set of RFC2253 flags */ + +# define XN_FLAG_RFC2253 (ASN1_STRFLGS_RFC2253 | \ + XN_FLAG_SEP_COMMA_PLUS | \ + XN_FLAG_DN_REV | \ + XN_FLAG_FN_SN | \ + XN_FLAG_DUMP_UNKNOWN_FIELDS) + +/* readable oneline form */ + +# define XN_FLAG_ONELINE (ASN1_STRFLGS_RFC2253 | \ + ASN1_STRFLGS_ESC_QUOTE | \ + XN_FLAG_SEP_CPLUS_SPC | \ + XN_FLAG_SPC_EQ | \ + XN_FLAG_FN_SN) + +/* readable multiline form */ + +# define XN_FLAG_MULTILINE (ASN1_STRFLGS_ESC_CTRL | \ + ASN1_STRFLGS_ESC_MSB | \ + XN_FLAG_SEP_MULTILINE | \ + XN_FLAG_SPC_EQ | \ + XN_FLAG_FN_LN | \ + XN_FLAG_FN_ALIGN) + +struct x509_revoked_st { + ASN1_INTEGER *serialNumber; + ASN1_TIME *revocationDate; + STACK_OF(X509_EXTENSION) /* optional */ *extensions; + /* Set up if indirect CRL */ + STACK_OF(GENERAL_NAME) *issuer; + /* Revocation reason */ + int reason; + int sequence; /* load sequence */ +}; + +DECLARE_STACK_OF(X509_REVOKED) +DECLARE_ASN1_SET_OF(X509_REVOKED) + +typedef struct X509_crl_info_st { + ASN1_INTEGER *version; + X509_ALGOR *sig_alg; + X509_NAME *issuer; + ASN1_TIME *lastUpdate; + ASN1_TIME *nextUpdate; + STACK_OF(X509_REVOKED) *revoked; + STACK_OF(X509_EXTENSION) /* [0] */ *extensions; + ASN1_ENCODING enc; +} X509_CRL_INFO; + +struct X509_crl_st { + /* actual signature */ + X509_CRL_INFO *crl; + X509_ALGOR *sig_alg; + ASN1_BIT_STRING *signature; + int references; + int flags; + /* Copies of various extensions */ + AUTHORITY_KEYID *akid; + ISSUING_DIST_POINT *idp; + /* Convenient breakdown of IDP */ + int idp_flags; + int idp_reasons; + /* CRL and base CRL numbers for delta processing */ + ASN1_INTEGER *crl_number; + ASN1_INTEGER *base_crl_number; +# ifndef OPENSSL_NO_SHA + unsigned char sha1_hash[SHA_DIGEST_LENGTH]; +# endif + STACK_OF(GENERAL_NAMES) *issuers; + const X509_CRL_METHOD *meth; + void *meth_data; +} /* X509_CRL */ ; + +DECLARE_STACK_OF(X509_CRL) +DECLARE_ASN1_SET_OF(X509_CRL) + +typedef struct private_key_st { + int version; + /* The PKCS#8 data types */ + X509_ALGOR *enc_algor; + ASN1_OCTET_STRING *enc_pkey; /* encrypted pub key */ + /* When decrypted, the following will not be NULL */ + EVP_PKEY *dec_pkey; + /* used to encrypt and decrypt */ + int key_length; + char *key_data; + int key_free; /* true if we should auto free key_data */ + /* expanded version of 'enc_algor' */ + EVP_CIPHER_INFO cipher; + int references; +} X509_PKEY; + +# ifndef OPENSSL_NO_EVP +typedef struct X509_info_st { + X509 *x509; + X509_CRL *crl; + X509_PKEY *x_pkey; + EVP_CIPHER_INFO enc_cipher; + int enc_len; + char *enc_data; + int references; +} X509_INFO; + +DECLARE_STACK_OF(X509_INFO) +# endif + +/* + * The next 2 structures and their 8 routines were sent to me by Pat Richard + * and are used to manipulate Netscapes spki structures - + * useful if you are writing a CA web page + */ +typedef struct Netscape_spkac_st { + X509_PUBKEY *pubkey; + ASN1_IA5STRING *challenge; /* challenge sent in atlas >= PR2 */ +} NETSCAPE_SPKAC; + +typedef struct Netscape_spki_st { + NETSCAPE_SPKAC *spkac; /* signed public key and challenge */ + X509_ALGOR *sig_algor; + ASN1_BIT_STRING *signature; +} NETSCAPE_SPKI; + +/* Netscape certificate sequence structure */ +typedef struct Netscape_certificate_sequence { + ASN1_OBJECT *type; + STACK_OF(X509) *certs; +} NETSCAPE_CERT_SEQUENCE; + +/*- Unused (and iv length is wrong) +typedef struct CBCParameter_st + { + unsigned char iv[8]; + } CBC_PARAM; +*/ + +/* Password based encryption structure */ + +typedef struct PBEPARAM_st { + ASN1_OCTET_STRING *salt; + ASN1_INTEGER *iter; +} PBEPARAM; + +/* Password based encryption V2 structures */ + +typedef struct PBE2PARAM_st { + X509_ALGOR *keyfunc; + X509_ALGOR *encryption; +} PBE2PARAM; + +typedef struct PBKDF2PARAM_st { +/* Usually OCTET STRING but could be anything */ + ASN1_TYPE *salt; + ASN1_INTEGER *iter; + ASN1_INTEGER *keylength; + X509_ALGOR *prf; +} PBKDF2PARAM; + +/* PKCS#8 private key info structure */ + +struct pkcs8_priv_key_info_st { + /* Flag for various broken formats */ + int broken; +# define PKCS8_OK 0 +# define PKCS8_NO_OCTET 1 +# define PKCS8_EMBEDDED_PARAM 2 +# define PKCS8_NS_DB 3 +# define PKCS8_NEG_PRIVKEY 4 + ASN1_INTEGER *version; + X509_ALGOR *pkeyalg; + /* Should be OCTET STRING but some are broken */ + ASN1_TYPE *pkey; + STACK_OF(X509_ATTRIBUTE) *attributes; +}; + +#ifdef __cplusplus +} +#endif + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# define X509_EXT_PACK_UNKNOWN 1 +# define X509_EXT_PACK_STRING 2 + +# define X509_get_version(x) ASN1_INTEGER_get((x)->cert_info->version) +/* #define X509_get_serialNumber(x) ((x)->cert_info->serialNumber) */ +# define X509_get_notBefore(x) ((x)->cert_info->validity->notBefore) +# define X509_get_notAfter(x) ((x)->cert_info->validity->notAfter) +# define X509_extract_key(x) X509_get_pubkey(x)/*****/ +# define X509_REQ_get_version(x) ASN1_INTEGER_get((x)->req_info->version) +# define X509_REQ_get_subject_name(x) ((x)->req_info->subject) +# define X509_REQ_extract_key(a) X509_REQ_get_pubkey(a) +# define X509_name_cmp(a,b) X509_NAME_cmp((a),(b)) +# define X509_get_signature_type(x) EVP_PKEY_type(OBJ_obj2nid((x)->sig_alg->algorithm)) + +# define X509_CRL_get_version(x) ASN1_INTEGER_get((x)->crl->version) +# define X509_CRL_get_lastUpdate(x) ((x)->crl->lastUpdate) +# define X509_CRL_get_nextUpdate(x) ((x)->crl->nextUpdate) +# define X509_CRL_get_issuer(x) ((x)->crl->issuer) +# define X509_CRL_get_REVOKED(x) ((x)->crl->revoked) + +void X509_CRL_set_default_method(const X509_CRL_METHOD *meth); +X509_CRL_METHOD *X509_CRL_METHOD_new(int (*crl_init) (X509_CRL *crl), + int (*crl_free) (X509_CRL *crl), + int (*crl_lookup) (X509_CRL *crl, + X509_REVOKED **ret, + ASN1_INTEGER *ser, + X509_NAME *issuer), + int (*crl_verify) (X509_CRL *crl, + EVP_PKEY *pk)); +void X509_CRL_METHOD_free(X509_CRL_METHOD *m); + +void X509_CRL_set_meth_data(X509_CRL *crl, void *dat); +void *X509_CRL_get_meth_data(X509_CRL *crl); + +/* + * This one is only used so that a binary form can output, as in + * i2d_X509_NAME(X509_get_X509_PUBKEY(x),&buf) + */ +# define X509_get_X509_PUBKEY(x) ((x)->cert_info->key) + +const char *X509_verify_cert_error_string(long n); + +# ifndef OPENSSL_NO_EVP +int X509_verify(X509 *a, EVP_PKEY *r); + +int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r); +int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r); +int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r); + +NETSCAPE_SPKI *NETSCAPE_SPKI_b64_decode(const char *str, int len); +char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *x); +EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x); +int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey); + +int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki); + +int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent); +int X509_signature_print(BIO *bp, X509_ALGOR *alg, ASN1_STRING *sig); + +int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md); +int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx); +int X509_http_nbio(OCSP_REQ_CTX *rctx, X509 **pcert); +int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md); +int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx); +int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md); +int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx); +int X509_CRL_http_nbio(OCSP_REQ_CTX *rctx, X509_CRL **pcrl); +int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md); + +int X509_pubkey_digest(const X509 *data, const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_digest(const X509 *data, const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type, + unsigned char *md, unsigned int *len); +# endif + +# ifndef OPENSSL_NO_FP_API +X509 *d2i_X509_fp(FILE *fp, X509 **x509); +int i2d_X509_fp(FILE *fp, X509 *x509); +X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl); +int i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl); +X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req); +int i2d_X509_REQ_fp(FILE *fp, X509_REQ *req); +# ifndef OPENSSL_NO_RSA +RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa); +int i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa); +RSA *d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa); +int i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa); +RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa); +int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa); +# endif +# ifndef OPENSSL_NO_DSA +DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa); +int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa); +DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa); +int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa); +# endif +# ifndef OPENSSL_NO_EC +EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey); +int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey); +EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey); +int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey); +# endif +X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8); +int i2d_PKCS8_fp(FILE *fp, X509_SIG *p8); +PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, + PKCS8_PRIV_KEY_INFO **p8inf); +int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO *p8inf); +int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key); +int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a); +int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a); +# endif + +# ifndef OPENSSL_NO_BIO +X509 *d2i_X509_bio(BIO *bp, X509 **x509); +int i2d_X509_bio(BIO *bp, X509 *x509); +X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl); +int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl); +X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req); +int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req); +# ifndef OPENSSL_NO_RSA +RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa); +int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa); +RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa); +int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa); +RSA *d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa); +int i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa); +# endif +# ifndef OPENSSL_NO_DSA +DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa); +int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa); +DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa); +int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa); +# endif +# ifndef OPENSSL_NO_EC +EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey); +int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *eckey); +EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey); +int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey); +# endif +X509_SIG *d2i_PKCS8_bio(BIO *bp, X509_SIG **p8); +int i2d_PKCS8_bio(BIO *bp, X509_SIG *p8); +PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, + PKCS8_PRIV_KEY_INFO **p8inf); +int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO *p8inf); +int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key); +int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a); +int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a); +# endif + +X509 *X509_dup(X509 *x509); +X509_ATTRIBUTE *X509_ATTRIBUTE_dup(X509_ATTRIBUTE *xa); +X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *ex); +X509_CRL *X509_CRL_dup(X509_CRL *crl); +X509_REVOKED *X509_REVOKED_dup(X509_REVOKED *rev); +X509_REQ *X509_REQ_dup(X509_REQ *req); +X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn); +int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, + void *pval); +void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval, + X509_ALGOR *algor); +void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md); +int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b); + +X509_NAME *X509_NAME_dup(X509_NAME *xn); +X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne); + +int X509_cmp_time(const ASN1_TIME *s, time_t *t); +int X509_cmp_current_time(const ASN1_TIME *s); +ASN1_TIME *X509_time_adj(ASN1_TIME *s, long adj, time_t *t); +ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s, + int offset_day, long offset_sec, time_t *t); +ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj); + +const char *X509_get_default_cert_area(void); +const char *X509_get_default_cert_dir(void); +const char *X509_get_default_cert_file(void); +const char *X509_get_default_cert_dir_env(void); +const char *X509_get_default_cert_file_env(void); +const char *X509_get_default_private_dir(void); + +X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md); +X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey); + +DECLARE_ASN1_FUNCTIONS(X509_ALGOR) +DECLARE_ASN1_ENCODE_FUNCTIONS(X509_ALGORS, X509_ALGORS, X509_ALGORS) +DECLARE_ASN1_FUNCTIONS(X509_VAL) + +DECLARE_ASN1_FUNCTIONS(X509_PUBKEY) + +int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey); +EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key); +int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain); +int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp); +EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length); +# ifndef OPENSSL_NO_RSA +int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp); +RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length); +# endif +# ifndef OPENSSL_NO_DSA +int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp); +DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length); +# endif +# ifndef OPENSSL_NO_EC +int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp); +EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length); +# endif + +DECLARE_ASN1_FUNCTIONS(X509_SIG) +DECLARE_ASN1_FUNCTIONS(X509_REQ_INFO) +DECLARE_ASN1_FUNCTIONS(X509_REQ) + +DECLARE_ASN1_FUNCTIONS(X509_ATTRIBUTE) +X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value); + +DECLARE_ASN1_FUNCTIONS(X509_EXTENSION) +DECLARE_ASN1_ENCODE_FUNCTIONS(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS) + +DECLARE_ASN1_FUNCTIONS(X509_NAME_ENTRY) + +DECLARE_ASN1_FUNCTIONS(X509_NAME) + +int X509_NAME_set(X509_NAME **xn, X509_NAME *name); + +DECLARE_ASN1_FUNCTIONS(X509_CINF) + +DECLARE_ASN1_FUNCTIONS(X509) +DECLARE_ASN1_FUNCTIONS(X509_CERT_AUX) + +DECLARE_ASN1_FUNCTIONS(X509_CERT_PAIR) + +int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int X509_set_ex_data(X509 *r, int idx, void *arg); +void *X509_get_ex_data(X509 *r, int idx); +int i2d_X509_AUX(X509 *a, unsigned char **pp); +X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length); + +int i2d_re_X509_tbs(X509 *x, unsigned char **pp); + +void X509_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg, + const X509 *x); +int X509_get_signature_nid(const X509 *x); + +int X509_alias_set1(X509 *x, unsigned char *name, int len); +int X509_keyid_set1(X509 *x, unsigned char *id, int len); +unsigned char *X509_alias_get0(X509 *x, int *len); +unsigned char *X509_keyid_get0(X509 *x, int *len); +int (*X509_TRUST_set_default(int (*trust) (int, X509 *, int))) (int, X509 *, + int); +int X509_TRUST_set(int *t, int trust); +int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj); +int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj); +void X509_trust_clear(X509 *x); +void X509_reject_clear(X509 *x); + +DECLARE_ASN1_FUNCTIONS(X509_REVOKED) +DECLARE_ASN1_FUNCTIONS(X509_CRL_INFO) +DECLARE_ASN1_FUNCTIONS(X509_CRL) + +int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev); +int X509_CRL_get0_by_serial(X509_CRL *crl, + X509_REVOKED **ret, ASN1_INTEGER *serial); +int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x); + +X509_PKEY *X509_PKEY_new(void); +void X509_PKEY_free(X509_PKEY *a); +int i2d_X509_PKEY(X509_PKEY *a, unsigned char **pp); +X509_PKEY *d2i_X509_PKEY(X509_PKEY **a, const unsigned char **pp, + long length); + +DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKI) +DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKAC) +DECLARE_ASN1_FUNCTIONS(NETSCAPE_CERT_SEQUENCE) + +# ifndef OPENSSL_NO_EVP +X509_INFO *X509_INFO_new(void); +void X509_INFO_free(X509_INFO *a); +char *X509_NAME_oneline(X509_NAME *a, char *buf, int size); + +int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *algor1, + ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey); + +int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data, + unsigned char *md, unsigned int *len); + +int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, + X509_ALGOR *algor2, ASN1_BIT_STRING *signature, + char *data, EVP_PKEY *pkey, const EVP_MD *type); + +int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *data, + unsigned char *md, unsigned int *len); + +int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *algor1, + ASN1_BIT_STRING *signature, void *data, EVP_PKEY *pkey); + +int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, + X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *data, + EVP_PKEY *pkey, const EVP_MD *type); +int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, + X509_ALGOR *algor2, ASN1_BIT_STRING *signature, + void *asn, EVP_MD_CTX *ctx); +# endif + +int X509_set_version(X509 *x, long version); +int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial); +ASN1_INTEGER *X509_get_serialNumber(X509 *x); +int X509_set_issuer_name(X509 *x, X509_NAME *name); +X509_NAME *X509_get_issuer_name(X509 *a); +int X509_set_subject_name(X509 *x, X509_NAME *name); +X509_NAME *X509_get_subject_name(X509 *a); +int X509_set_notBefore(X509 *x, const ASN1_TIME *tm); +int X509_set_notAfter(X509 *x, const ASN1_TIME *tm); +int X509_set_pubkey(X509 *x, EVP_PKEY *pkey); +EVP_PKEY *X509_get_pubkey(X509 *x); +ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x); +int X509_certificate_type(X509 *x, EVP_PKEY *pubkey /* optional */ ); + +int X509_REQ_set_version(X509_REQ *x, long version); +int X509_REQ_set_subject_name(X509_REQ *req, X509_NAME *name); +int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey); +EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req); +int X509_REQ_extension_nid(int nid); +int *X509_REQ_get_extension_nids(void); +void X509_REQ_set_extension_nids(int *nids); +STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req); +int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts, + int nid); +int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts); +int X509_REQ_get_attr_count(const X509_REQ *req); +int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos); +int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj, + int lastpos); +X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc); +X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc); +int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr); +int X509_REQ_add1_attr_by_OBJ(X509_REQ *req, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len); +int X509_REQ_add1_attr_by_NID(X509_REQ *req, + int nid, int type, + const unsigned char *bytes, int len); +int X509_REQ_add1_attr_by_txt(X509_REQ *req, + const char *attrname, int type, + const unsigned char *bytes, int len); + +int X509_CRL_set_version(X509_CRL *x, long version); +int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name); +int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm); +int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm); +int X509_CRL_sort(X509_CRL *crl); + +int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial); +int X509_REVOKED_set_revocationDate(X509_REVOKED *r, ASN1_TIME *tm); + +X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer, + EVP_PKEY *skey, const EVP_MD *md, unsigned int flags); + +int X509_REQ_check_private_key(X509_REQ *x509, EVP_PKEY *pkey); + +int X509_check_private_key(X509 *x509, EVP_PKEY *pkey); +int X509_chain_check_suiteb(int *perror_depth, + X509 *x, STACK_OF(X509) *chain, + unsigned long flags); +int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags); +STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain); + +int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b); +unsigned long X509_issuer_and_serial_hash(X509 *a); + +int X509_issuer_name_cmp(const X509 *a, const X509 *b); +unsigned long X509_issuer_name_hash(X509 *a); + +int X509_subject_name_cmp(const X509 *a, const X509 *b); +unsigned long X509_subject_name_hash(X509 *x); + +# ifndef OPENSSL_NO_MD5 +unsigned long X509_issuer_name_hash_old(X509 *a); +unsigned long X509_subject_name_hash_old(X509 *x); +# endif + +int X509_cmp(const X509 *a, const X509 *b); +int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b); +unsigned long X509_NAME_hash(X509_NAME *x); +unsigned long X509_NAME_hash_old(X509_NAME *x); + +int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b); +int X509_CRL_match(const X509_CRL *a, const X509_CRL *b); +# ifndef OPENSSL_NO_FP_API +int X509_print_ex_fp(FILE *bp, X509 *x, unsigned long nmflag, + unsigned long cflag); +int X509_print_fp(FILE *bp, X509 *x); +int X509_CRL_print_fp(FILE *bp, X509_CRL *x); +int X509_REQ_print_fp(FILE *bp, X509_REQ *req); +int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent, + unsigned long flags); +# endif + +# ifndef OPENSSL_NO_BIO +int X509_NAME_print(BIO *bp, X509_NAME *name, int obase); +int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent, + unsigned long flags); +int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflag, + unsigned long cflag); +int X509_print(BIO *bp, X509 *x); +int X509_ocspid_print(BIO *bp, X509 *x); +int X509_CERT_AUX_print(BIO *bp, X509_CERT_AUX *x, int indent); +int X509_CRL_print(BIO *bp, X509_CRL *x); +int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflag, + unsigned long cflag); +int X509_REQ_print(BIO *bp, X509_REQ *req); +# endif + +int X509_NAME_entry_count(X509_NAME *name); +int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len); +int X509_NAME_get_text_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, + char *buf, int len); + +/* + * NOTE: you should be passsing -1, not 0 as lastpos. The functions that use + * lastpos, search after that position on. + */ +int X509_NAME_get_index_by_NID(X509_NAME *name, int nid, int lastpos); +int X509_NAME_get_index_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, + int lastpos); +X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc); +X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc); +int X509_NAME_add_entry(X509_NAME *name, X509_NAME_ENTRY *ne, + int loc, int set); +int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type, + unsigned char *bytes, int len, int loc, + int set); +int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, + unsigned char *bytes, int len, int loc, + int set); +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, + const char *field, int type, + const unsigned char *bytes, + int len); +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, + int type, unsigned char *bytes, + int len); +int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type, + const unsigned char *bytes, int len, int loc, + int set); +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, + ASN1_OBJECT *obj, int type, + const unsigned char *bytes, + int len); +int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, ASN1_OBJECT *obj); +int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, + const unsigned char *bytes, int len); +ASN1_OBJECT *X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne); +ASN1_STRING *X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne); + +int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x); +int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, + int nid, int lastpos); +int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *x, + ASN1_OBJECT *obj, int lastpos); +int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *x, + int crit, int lastpos); +X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc); +X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc); +STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x, + X509_EXTENSION *ex, int loc); + +int X509_get_ext_count(X509 *x); +int X509_get_ext_by_NID(X509 *x, int nid, int lastpos); +int X509_get_ext_by_OBJ(X509 *x, ASN1_OBJECT *obj, int lastpos); +int X509_get_ext_by_critical(X509 *x, int crit, int lastpos); +X509_EXTENSION *X509_get_ext(X509 *x, int loc); +X509_EXTENSION *X509_delete_ext(X509 *x, int loc); +int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc); +void *X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx); +int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit, + unsigned long flags); + +int X509_CRL_get_ext_count(X509_CRL *x); +int X509_CRL_get_ext_by_NID(X509_CRL *x, int nid, int lastpos); +int X509_CRL_get_ext_by_OBJ(X509_CRL *x, ASN1_OBJECT *obj, int lastpos); +int X509_CRL_get_ext_by_critical(X509_CRL *x, int crit, int lastpos); +X509_EXTENSION *X509_CRL_get_ext(X509_CRL *x, int loc); +X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc); +int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc); +void *X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx); +int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit, + unsigned long flags); + +int X509_REVOKED_get_ext_count(X509_REVOKED *x); +int X509_REVOKED_get_ext_by_NID(X509_REVOKED *x, int nid, int lastpos); +int X509_REVOKED_get_ext_by_OBJ(X509_REVOKED *x, ASN1_OBJECT *obj, + int lastpos); +int X509_REVOKED_get_ext_by_critical(X509_REVOKED *x, int crit, int lastpos); +X509_EXTENSION *X509_REVOKED_get_ext(X509_REVOKED *x, int loc); +X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc); +int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc); +void *X509_REVOKED_get_ext_d2i(X509_REVOKED *x, int nid, int *crit, int *idx); +int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit, + unsigned long flags); + +X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, + int nid, int crit, + ASN1_OCTET_STRING *data); +X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex, + ASN1_OBJECT *obj, int crit, + ASN1_OCTET_STRING *data); +int X509_EXTENSION_set_object(X509_EXTENSION *ex, ASN1_OBJECT *obj); +int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit); +int X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data); +ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex); +ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ne); +int X509_EXTENSION_get_critical(X509_EXTENSION *ex); + +int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x); +int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid, + int lastpos); +int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, + ASN1_OBJECT *obj, int lastpos); +X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc); +X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x, + X509_ATTRIBUTE *attr); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) + **x, const ASN1_OBJECT *obj, + int type, + const unsigned char *bytes, + int len); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) + **x, int nid, int type, + const unsigned char *bytes, + int len); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) + **x, const char *attrname, + int type, + const unsigned char *bytes, + int len); +void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x, ASN1_OBJECT *obj, + int lastpos, int type); +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid, + int atrtype, const void *data, + int len); +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr, + const ASN1_OBJECT *obj, + int atrtype, const void *data, + int len); +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr, + const char *atrname, int type, + const unsigned char *bytes, + int len); +int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj); +int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, + const void *data, int len); +void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, int atrtype, + void *data); +int X509_ATTRIBUTE_count(X509_ATTRIBUTE *attr); +ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr); +ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx); + +int EVP_PKEY_get_attr_count(const EVP_PKEY *key); +int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid, int lastpos); +int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, ASN1_OBJECT *obj, + int lastpos); +X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc); +X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc); +int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr); +int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len); +int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key, + int nid, int type, + const unsigned char *bytes, int len); +int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key, + const char *attrname, int type, + const unsigned char *bytes, int len); + +int X509_verify_cert(X509_STORE_CTX *ctx); + +/* lookup a cert from a X509 STACK */ +X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name, + ASN1_INTEGER *serial); +X509 *X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name); + +DECLARE_ASN1_FUNCTIONS(PBEPARAM) +DECLARE_ASN1_FUNCTIONS(PBE2PARAM) +DECLARE_ASN1_FUNCTIONS(PBKDF2PARAM) + +int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter, + const unsigned char *salt, int saltlen); + +X509_ALGOR *PKCS5_pbe_set(int alg, int iter, + const unsigned char *salt, int saltlen); +X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter, + unsigned char *salt, int saltlen); +X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter, + unsigned char *salt, int saltlen, + unsigned char *aiv, int prf_nid); + +X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen, + int prf_nid, int keylen); + +/* PKCS#8 utilities */ + +DECLARE_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO) + +EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8); +PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey); +PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken); +PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken); + +int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj, + int version, int ptype, void *pval, + unsigned char *penc, int penclen); +int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg, + const unsigned char **pk, int *ppklen, + X509_ALGOR **pa, PKCS8_PRIV_KEY_INFO *p8); + +int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj, + int ptype, void *pval, + unsigned char *penc, int penclen); +int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg, + const unsigned char **pk, int *ppklen, + X509_ALGOR **pa, X509_PUBKEY *pub); + +int X509_check_trust(X509 *x, int id, int flags); +int X509_TRUST_get_count(void); +X509_TRUST *X509_TRUST_get0(int idx); +int X509_TRUST_get_by_id(int id); +int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int), + char *name, int arg1, void *arg2); +void X509_TRUST_cleanup(void); +int X509_TRUST_get_flags(X509_TRUST *xp); +char *X509_TRUST_get0_name(X509_TRUST *xp); +int X509_TRUST_get_trust(X509_TRUST *xp); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_X509_strings(void); + +/* Error codes for the X509 functions. */ + +/* Function codes. */ +# define X509_F_ADD_CERT_DIR 100 +# define X509_F_BY_FILE_CTRL 101 +# define X509_F_CHECK_POLICY 145 +# define X509_F_DIR_CTRL 102 +# define X509_F_GET_CERT_BY_SUBJECT 103 +# define X509_F_NETSCAPE_SPKI_B64_DECODE 129 +# define X509_F_NETSCAPE_SPKI_B64_ENCODE 130 +# define X509_F_X509AT_ADD1_ATTR 135 +# define X509_F_X509V3_ADD_EXT 104 +# define X509_F_X509_ATTRIBUTE_CREATE_BY_NID 136 +# define X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ 137 +# define X509_F_X509_ATTRIBUTE_CREATE_BY_TXT 140 +# define X509_F_X509_ATTRIBUTE_GET0_DATA 139 +# define X509_F_X509_ATTRIBUTE_SET1_DATA 138 +# define X509_F_X509_CHECK_PRIVATE_KEY 128 +# define X509_F_X509_CRL_DIFF 105 +# define X509_F_X509_CRL_PRINT_FP 147 +# define X509_F_X509_EXTENSION_CREATE_BY_NID 108 +# define X509_F_X509_EXTENSION_CREATE_BY_OBJ 109 +# define X509_F_X509_GET_PUBKEY_PARAMETERS 110 +# define X509_F_X509_LOAD_CERT_CRL_FILE 132 +# define X509_F_X509_LOAD_CERT_FILE 111 +# define X509_F_X509_LOAD_CRL_FILE 112 +# define X509_F_X509_NAME_ADD_ENTRY 113 +# define X509_F_X509_NAME_ENTRY_CREATE_BY_NID 114 +# define X509_F_X509_NAME_ENTRY_CREATE_BY_TXT 131 +# define X509_F_X509_NAME_ENTRY_SET_OBJECT 115 +# define X509_F_X509_NAME_ONELINE 116 +# define X509_F_X509_NAME_PRINT 117 +# define X509_F_X509_PRINT_EX_FP 118 +# define X509_F_X509_PUBKEY_GET 119 +# define X509_F_X509_PUBKEY_SET 120 +# define X509_F_X509_REQ_CHECK_PRIVATE_KEY 144 +# define X509_F_X509_REQ_PRINT_EX 121 +# define X509_F_X509_REQ_PRINT_FP 122 +# define X509_F_X509_REQ_TO_X509 123 +# define X509_F_X509_STORE_ADD_CERT 124 +# define X509_F_X509_STORE_ADD_CRL 125 +# define X509_F_X509_STORE_CTX_GET1_ISSUER 146 +# define X509_F_X509_STORE_CTX_INIT 143 +# define X509_F_X509_STORE_CTX_NEW 142 +# define X509_F_X509_STORE_CTX_PURPOSE_INHERIT 134 +# define X509_F_X509_TO_X509_REQ 126 +# define X509_F_X509_TRUST_ADD 133 +# define X509_F_X509_TRUST_SET 141 +# define X509_F_X509_VERIFY_CERT 127 + +/* Reason codes. */ +# define X509_R_AKID_MISMATCH 110 +# define X509_R_BAD_X509_FILETYPE 100 +# define X509_R_BASE64_DECODE_ERROR 118 +# define X509_R_CANT_CHECK_DH_KEY 114 +# define X509_R_CERT_ALREADY_IN_HASH_TABLE 101 +# define X509_R_CRL_ALREADY_DELTA 127 +# define X509_R_CRL_VERIFY_FAILURE 131 +# define X509_R_ERR_ASN1_LIB 102 +# define X509_R_IDP_MISMATCH 128 +# define X509_R_INVALID_DIRECTORY 113 +# define X509_R_INVALID_FIELD_NAME 119 +# define X509_R_INVALID_TRUST 123 +# define X509_R_ISSUER_MISMATCH 129 +# define X509_R_KEY_TYPE_MISMATCH 115 +# define X509_R_KEY_VALUES_MISMATCH 116 +# define X509_R_LOADING_CERT_DIR 103 +# define X509_R_LOADING_DEFAULTS 104 +# define X509_R_METHOD_NOT_SUPPORTED 124 +# define X509_R_NAME_TOO_LONG 134 +# define X509_R_NEWER_CRL_NOT_NEWER 132 +# define X509_R_NO_CERT_SET_FOR_US_TO_VERIFY 105 +# define X509_R_NO_CRL_NUMBER 130 +# define X509_R_PUBLIC_KEY_DECODE_ERROR 125 +# define X509_R_PUBLIC_KEY_ENCODE_ERROR 126 +# define X509_R_SHOULD_RETRY 106 +# define X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN 107 +# define X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY 108 +# define X509_R_UNKNOWN_KEY_TYPE 117 +# define X509_R_UNKNOWN_NID 109 +# define X509_R_UNKNOWN_PURPOSE_ID 121 +# define X509_R_UNKNOWN_TRUST_ID 120 +# define X509_R_UNSUPPORTED_ALGORITHM 111 +# define X509_R_WRONG_LOOKUP_TYPE 112 +# define X509_R_WRONG_TYPE 122 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/x509_vfy.h b/OSlibs/ios/include/openssl/x509_vfy.h new file mode 100755 index 000000000..2663e1c0a --- /dev/null +++ b/OSlibs/ios/include/openssl/x509_vfy.h @@ -0,0 +1,647 @@ +/* crypto/x509/x509_vfy.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_X509_H +# include +/* + * openssl/x509.h ends up #include-ing this file at about the only + * appropriate moment. + */ +#endif + +#ifndef HEADER_X509_VFY_H +# define HEADER_X509_VFY_H + +# include +# ifndef OPENSSL_NO_LHASH +# include +# endif +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# if 0 +/* Outer object */ +typedef struct x509_hash_dir_st { + int num_dirs; + char **dirs; + int *dirs_type; + int num_dirs_alloced; +} X509_HASH_DIR_CTX; +# endif + +typedef struct x509_file_st { + int num_paths; /* number of paths to files or directories */ + int num_alloced; + char **paths; /* the list of paths or directories */ + int *path_type; +} X509_CERT_FILE_CTX; + +/*******************************/ +/*- +SSL_CTX -> X509_STORE + -> X509_LOOKUP + ->X509_LOOKUP_METHOD + -> X509_LOOKUP + ->X509_LOOKUP_METHOD + +SSL -> X509_STORE_CTX + ->X509_STORE + +The X509_STORE holds the tables etc for verification stuff. +A X509_STORE_CTX is used while validating a single certificate. +The X509_STORE has X509_LOOKUPs for looking up certs. +The X509_STORE then calls a function to actually verify the +certificate chain. +*/ + +# define X509_LU_RETRY -1 +# define X509_LU_FAIL 0 +# define X509_LU_X509 1 +# define X509_LU_CRL 2 +# define X509_LU_PKEY 3 + +typedef struct x509_object_st { + /* one of the above types */ + int type; + union { + char *ptr; + X509 *x509; + X509_CRL *crl; + EVP_PKEY *pkey; + } data; +} X509_OBJECT; + +typedef struct x509_lookup_st X509_LOOKUP; + +DECLARE_STACK_OF(X509_LOOKUP) +DECLARE_STACK_OF(X509_OBJECT) + +/* This is a static that defines the function interface */ +typedef struct x509_lookup_method_st { + const char *name; + int (*new_item) (X509_LOOKUP *ctx); + void (*free) (X509_LOOKUP *ctx); + int (*init) (X509_LOOKUP *ctx); + int (*shutdown) (X509_LOOKUP *ctx); + int (*ctrl) (X509_LOOKUP *ctx, int cmd, const char *argc, long argl, + char **ret); + int (*get_by_subject) (X509_LOOKUP *ctx, int type, X509_NAME *name, + X509_OBJECT *ret); + int (*get_by_issuer_serial) (X509_LOOKUP *ctx, int type, X509_NAME *name, + ASN1_INTEGER *serial, X509_OBJECT *ret); + int (*get_by_fingerprint) (X509_LOOKUP *ctx, int type, + unsigned char *bytes, int len, + X509_OBJECT *ret); + int (*get_by_alias) (X509_LOOKUP *ctx, int type, char *str, int len, + X509_OBJECT *ret); +} X509_LOOKUP_METHOD; + +typedef struct X509_VERIFY_PARAM_ID_st X509_VERIFY_PARAM_ID; + +/* + * This structure hold all parameters associated with a verify operation by + * including an X509_VERIFY_PARAM structure in related structures the + * parameters used can be customized + */ + +typedef struct X509_VERIFY_PARAM_st { + char *name; + time_t check_time; /* Time to use */ + unsigned long inh_flags; /* Inheritance flags */ + unsigned long flags; /* Various verify flags */ + int purpose; /* purpose to check untrusted certificates */ + int trust; /* trust setting to check */ + int depth; /* Verify depth */ + STACK_OF(ASN1_OBJECT) *policies; /* Permissible policies */ + X509_VERIFY_PARAM_ID *id; /* opaque ID data */ +} X509_VERIFY_PARAM; + +DECLARE_STACK_OF(X509_VERIFY_PARAM) + +/* + * This is used to hold everything. It is used for all certificate + * validation. Once we have a certificate chain, the 'verify' function is + * then called to actually check the cert chain. + */ +struct x509_store_st { + /* The following is a cache of trusted certs */ + int cache; /* if true, stash any hits */ + STACK_OF(X509_OBJECT) *objs; /* Cache of all objects */ + /* These are external lookup methods */ + STACK_OF(X509_LOOKUP) *get_cert_methods; + X509_VERIFY_PARAM *param; + /* Callbacks for various operations */ + /* called to verify a certificate */ + int (*verify) (X509_STORE_CTX *ctx); + /* error callback */ + int (*verify_cb) (int ok, X509_STORE_CTX *ctx); + /* get issuers cert from ctx */ + int (*get_issuer) (X509 **issuer, X509_STORE_CTX *ctx, X509 *x); + /* check issued */ + int (*check_issued) (X509_STORE_CTX *ctx, X509 *x, X509 *issuer); + /* Check revocation status of chain */ + int (*check_revocation) (X509_STORE_CTX *ctx); + /* retrieve CRL */ + int (*get_crl) (X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); + /* Check CRL validity */ + int (*check_crl) (X509_STORE_CTX *ctx, X509_CRL *crl); + /* Check certificate against CRL */ + int (*cert_crl) (X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); + STACK_OF(X509) *(*lookup_certs) (X509_STORE_CTX *ctx, X509_NAME *nm); + STACK_OF(X509_CRL) *(*lookup_crls) (X509_STORE_CTX *ctx, X509_NAME *nm); + int (*cleanup) (X509_STORE_CTX *ctx); + CRYPTO_EX_DATA ex_data; + int references; +} /* X509_STORE */ ; + +int X509_STORE_set_depth(X509_STORE *store, int depth); + +# define X509_STORE_set_verify_cb_func(ctx,func) ((ctx)->verify_cb=(func)) +# define X509_STORE_set_verify_func(ctx,func) ((ctx)->verify=(func)) + +/* This is the functions plus an instance of the local variables. */ +struct x509_lookup_st { + int init; /* have we been started */ + int skip; /* don't use us. */ + X509_LOOKUP_METHOD *method; /* the functions */ + char *method_data; /* method data */ + X509_STORE *store_ctx; /* who owns us */ +} /* X509_LOOKUP */ ; + +/* + * This is a used when verifying cert chains. Since the gathering of the + * cert chain can take some time (and have to be 'retried', this needs to be + * kept and passed around. + */ +struct x509_store_ctx_st { /* X509_STORE_CTX */ + X509_STORE *ctx; + /* used when looking up certs */ + int current_method; + /* The following are set by the caller */ + /* The cert to check */ + X509 *cert; + /* chain of X509s - untrusted - passed in */ + STACK_OF(X509) *untrusted; + /* set of CRLs passed in */ + STACK_OF(X509_CRL) *crls; + X509_VERIFY_PARAM *param; + /* Other info for use with get_issuer() */ + void *other_ctx; + /* Callbacks for various operations */ + /* called to verify a certificate */ + int (*verify) (X509_STORE_CTX *ctx); + /* error callback */ + int (*verify_cb) (int ok, X509_STORE_CTX *ctx); + /* get issuers cert from ctx */ + int (*get_issuer) (X509 **issuer, X509_STORE_CTX *ctx, X509 *x); + /* check issued */ + int (*check_issued) (X509_STORE_CTX *ctx, X509 *x, X509 *issuer); + /* Check revocation status of chain */ + int (*check_revocation) (X509_STORE_CTX *ctx); + /* retrieve CRL */ + int (*get_crl) (X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); + /* Check CRL validity */ + int (*check_crl) (X509_STORE_CTX *ctx, X509_CRL *crl); + /* Check certificate against CRL */ + int (*cert_crl) (X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); + int (*check_policy) (X509_STORE_CTX *ctx); + STACK_OF(X509) *(*lookup_certs) (X509_STORE_CTX *ctx, X509_NAME *nm); + STACK_OF(X509_CRL) *(*lookup_crls) (X509_STORE_CTX *ctx, X509_NAME *nm); + int (*cleanup) (X509_STORE_CTX *ctx); + /* The following is built up */ + /* if 0, rebuild chain */ + int valid; + /* index of last untrusted cert */ + int last_untrusted; + /* chain of X509s - built up and trusted */ + STACK_OF(X509) *chain; + /* Valid policy tree */ + X509_POLICY_TREE *tree; + /* Require explicit policy value */ + int explicit_policy; + /* When something goes wrong, this is why */ + int error_depth; + int error; + X509 *current_cert; + /* cert currently being tested as valid issuer */ + X509 *current_issuer; + /* current CRL */ + X509_CRL *current_crl; + /* score of current CRL */ + int current_crl_score; + /* Reason mask */ + unsigned int current_reasons; + /* For CRL path validation: parent context */ + X509_STORE_CTX *parent; + CRYPTO_EX_DATA ex_data; +} /* X509_STORE_CTX */ ; + +void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth); + +# define X509_STORE_CTX_set_app_data(ctx,data) \ + X509_STORE_CTX_set_ex_data(ctx,0,data) +# define X509_STORE_CTX_get_app_data(ctx) \ + X509_STORE_CTX_get_ex_data(ctx,0) + +# define X509_L_FILE_LOAD 1 +# define X509_L_ADD_DIR 2 + +# define X509_LOOKUP_load_file(x,name,type) \ + X509_LOOKUP_ctrl((x),X509_L_FILE_LOAD,(name),(long)(type),NULL) + +# define X509_LOOKUP_add_dir(x,name,type) \ + X509_LOOKUP_ctrl((x),X509_L_ADD_DIR,(name),(long)(type),NULL) + +# define X509_V_OK 0 +# define X509_V_ERR_UNSPECIFIED 1 + +# define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT 2 +# define X509_V_ERR_UNABLE_TO_GET_CRL 3 +# define X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE 4 +# define X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE 5 +# define X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY 6 +# define X509_V_ERR_CERT_SIGNATURE_FAILURE 7 +# define X509_V_ERR_CRL_SIGNATURE_FAILURE 8 +# define X509_V_ERR_CERT_NOT_YET_VALID 9 +# define X509_V_ERR_CERT_HAS_EXPIRED 10 +# define X509_V_ERR_CRL_NOT_YET_VALID 11 +# define X509_V_ERR_CRL_HAS_EXPIRED 12 +# define X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD 13 +# define X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD 14 +# define X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD 15 +# define X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD 16 +# define X509_V_ERR_OUT_OF_MEM 17 +# define X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT 18 +# define X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN 19 +# define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY 20 +# define X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE 21 +# define X509_V_ERR_CERT_CHAIN_TOO_LONG 22 +# define X509_V_ERR_CERT_REVOKED 23 +# define X509_V_ERR_INVALID_CA 24 +# define X509_V_ERR_PATH_LENGTH_EXCEEDED 25 +# define X509_V_ERR_INVALID_PURPOSE 26 +# define X509_V_ERR_CERT_UNTRUSTED 27 +# define X509_V_ERR_CERT_REJECTED 28 +/* These are 'informational' when looking for issuer cert */ +# define X509_V_ERR_SUBJECT_ISSUER_MISMATCH 29 +# define X509_V_ERR_AKID_SKID_MISMATCH 30 +# define X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH 31 +# define X509_V_ERR_KEYUSAGE_NO_CERTSIGN 32 + +# define X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER 33 +# define X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION 34 +# define X509_V_ERR_KEYUSAGE_NO_CRL_SIGN 35 +# define X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION 36 +# define X509_V_ERR_INVALID_NON_CA 37 +# define X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED 38 +# define X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE 39 +# define X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED 40 + +# define X509_V_ERR_INVALID_EXTENSION 41 +# define X509_V_ERR_INVALID_POLICY_EXTENSION 42 +# define X509_V_ERR_NO_EXPLICIT_POLICY 43 +# define X509_V_ERR_DIFFERENT_CRL_SCOPE 44 +# define X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE 45 + +# define X509_V_ERR_UNNESTED_RESOURCE 46 + +# define X509_V_ERR_PERMITTED_VIOLATION 47 +# define X509_V_ERR_EXCLUDED_VIOLATION 48 +# define X509_V_ERR_SUBTREE_MINMAX 49 +# define X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE 51 +# define X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX 52 +# define X509_V_ERR_UNSUPPORTED_NAME_SYNTAX 53 +# define X509_V_ERR_CRL_PATH_VALIDATION_ERROR 54 + +/* Suite B mode algorithm violation */ +# define X509_V_ERR_SUITE_B_INVALID_VERSION 56 +# define X509_V_ERR_SUITE_B_INVALID_ALGORITHM 57 +# define X509_V_ERR_SUITE_B_INVALID_CURVE 58 +# define X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM 59 +# define X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED 60 +# define X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 61 + +/* Host, email and IP check errors */ +# define X509_V_ERR_HOSTNAME_MISMATCH 62 +# define X509_V_ERR_EMAIL_MISMATCH 63 +# define X509_V_ERR_IP_ADDRESS_MISMATCH 64 + +/* The application is not happy */ +# define X509_V_ERR_APPLICATION_VERIFICATION 50 + +/* Certificate verify flags */ + +/* Send issuer+subject checks to verify_cb */ +# define X509_V_FLAG_CB_ISSUER_CHECK 0x1 +/* Use check time instead of current time */ +# define X509_V_FLAG_USE_CHECK_TIME 0x2 +/* Lookup CRLs */ +# define X509_V_FLAG_CRL_CHECK 0x4 +/* Lookup CRLs for whole chain */ +# define X509_V_FLAG_CRL_CHECK_ALL 0x8 +/* Ignore unhandled critical extensions */ +# define X509_V_FLAG_IGNORE_CRITICAL 0x10 +/* Disable workarounds for broken certificates */ +# define X509_V_FLAG_X509_STRICT 0x20 +/* Enable proxy certificate validation */ +# define X509_V_FLAG_ALLOW_PROXY_CERTS 0x40 +/* Enable policy checking */ +# define X509_V_FLAG_POLICY_CHECK 0x80 +/* Policy variable require-explicit-policy */ +# define X509_V_FLAG_EXPLICIT_POLICY 0x100 +/* Policy variable inhibit-any-policy */ +# define X509_V_FLAG_INHIBIT_ANY 0x200 +/* Policy variable inhibit-policy-mapping */ +# define X509_V_FLAG_INHIBIT_MAP 0x400 +/* Notify callback that policy is OK */ +# define X509_V_FLAG_NOTIFY_POLICY 0x800 +/* Extended CRL features such as indirect CRLs, alternate CRL signing keys */ +# define X509_V_FLAG_EXTENDED_CRL_SUPPORT 0x1000 +/* Delta CRL support */ +# define X509_V_FLAG_USE_DELTAS 0x2000 +/* Check selfsigned CA signature */ +# define X509_V_FLAG_CHECK_SS_SIGNATURE 0x4000 +/* Use trusted store first */ +# define X509_V_FLAG_TRUSTED_FIRST 0x8000 +/* Suite B 128 bit only mode: not normally used */ +# define X509_V_FLAG_SUITEB_128_LOS_ONLY 0x10000 +/* Suite B 192 bit only mode */ +# define X509_V_FLAG_SUITEB_192_LOS 0x20000 +/* Suite B 128 bit mode allowing 192 bit algorithms */ +# define X509_V_FLAG_SUITEB_128_LOS 0x30000 + +/* Allow partial chains if at least one certificate is in trusted store */ +# define X509_V_FLAG_PARTIAL_CHAIN 0x80000 +/* + * If the initial chain is not trusted, do not attempt to build an alternative + * chain. Alternate chain checking was introduced in 1.0.2b. Setting this flag + * will force the behaviour to match that of previous versions. + */ +# define X509_V_FLAG_NO_ALT_CHAINS 0x100000 + +# define X509_VP_FLAG_DEFAULT 0x1 +# define X509_VP_FLAG_OVERWRITE 0x2 +# define X509_VP_FLAG_RESET_FLAGS 0x4 +# define X509_VP_FLAG_LOCKED 0x8 +# define X509_VP_FLAG_ONCE 0x10 + +/* Internal use: mask of policy related options */ +# define X509_V_FLAG_POLICY_MASK (X509_V_FLAG_POLICY_CHECK \ + | X509_V_FLAG_EXPLICIT_POLICY \ + | X509_V_FLAG_INHIBIT_ANY \ + | X509_V_FLAG_INHIBIT_MAP) + +int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, + X509_NAME *name); +X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, + int type, X509_NAME *name); +X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, + X509_OBJECT *x); +void X509_OBJECT_up_ref_count(X509_OBJECT *a); +void X509_OBJECT_free_contents(X509_OBJECT *a); +X509_STORE *X509_STORE_new(void); +void X509_STORE_free(X509_STORE *v); + +STACK_OF(X509) *X509_STORE_get1_certs(X509_STORE_CTX *st, X509_NAME *nm); +STACK_OF(X509_CRL) *X509_STORE_get1_crls(X509_STORE_CTX *st, X509_NAME *nm); +int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags); +int X509_STORE_set_purpose(X509_STORE *ctx, int purpose); +int X509_STORE_set_trust(X509_STORE *ctx, int trust); +int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *pm); + +void X509_STORE_set_verify_cb(X509_STORE *ctx, + int (*verify_cb) (int, X509_STORE_CTX *)); + +void X509_STORE_set_lookup_crls_cb(X509_STORE *ctx, + STACK_OF(X509_CRL) *(*cb) (X509_STORE_CTX + *ctx, + X509_NAME *nm)); + +X509_STORE_CTX *X509_STORE_CTX_new(void); + +int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); + +void X509_STORE_CTX_free(X509_STORE_CTX *ctx); +int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, + X509 *x509, STACK_OF(X509) *chain); +void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); +void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx); + +X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx); + +X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m); + +X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void); +X509_LOOKUP_METHOD *X509_LOOKUP_file(void); + +int X509_STORE_add_cert(X509_STORE *ctx, X509 *x); +int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x); + +int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name, + X509_OBJECT *ret); + +int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, + long argl, char **ret); + +# ifndef OPENSSL_NO_STDIO +int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type); +int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type); +int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type); +# endif + +X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method); +void X509_LOOKUP_free(X509_LOOKUP *ctx); +int X509_LOOKUP_init(X509_LOOKUP *ctx); +int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name, + X509_OBJECT *ret); +int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name, + ASN1_INTEGER *serial, X509_OBJECT *ret); +int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type, + unsigned char *bytes, int len, + X509_OBJECT *ret); +int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, int len, + X509_OBJECT *ret); +int X509_LOOKUP_shutdown(X509_LOOKUP *ctx); + +# ifndef OPENSSL_NO_STDIO +int X509_STORE_load_locations(X509_STORE *ctx, + const char *file, const char *dir); +int X509_STORE_set_default_paths(X509_STORE *ctx); +# endif + +int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); +int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data); +void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx); +int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int s); +int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx); +X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx); +X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx); +X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx); +X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx); +STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx); +STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set_cert(X509_STORE_CTX *c, X509 *x); +void X509_STORE_CTX_set_chain(X509_STORE_CTX *c, STACK_OF(X509) *sk); +void X509_STORE_CTX_set0_crls(X509_STORE_CTX *c, STACK_OF(X509_CRL) *sk); +int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose); +int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust); +int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose, + int purpose, int trust); +void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags); +void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, + time_t t); +void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, + int (*verify_cb) (int, X509_STORE_CTX *)); + +X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx); +int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx); + +X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param); +int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name); + +/* X509_VERIFY_PARAM functions */ + +X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void); +void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param); +int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *to, + const X509_VERIFY_PARAM *from); +int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, + const X509_VERIFY_PARAM *from); +int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name); +int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, + unsigned long flags); +int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, + unsigned long flags); +unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param); +int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose); +int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust); +void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth); +void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t); +int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, + ASN1_OBJECT *policy); +int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, + STACK_OF(ASN1_OBJECT) *policies); + +int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, + const char *name, size_t namelen); +int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param, + const char *name, size_t namelen); +void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, + unsigned int flags); +char *X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *); +int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, + const char *email, size_t emaillen); +int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, + const unsigned char *ip, size_t iplen); +int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, + const char *ipasc); + +int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param); +const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param); + +int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param); +int X509_VERIFY_PARAM_get_count(void); +const X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id); +const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name); +void X509_VERIFY_PARAM_table_cleanup(void); + +int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy, + STACK_OF(X509) *certs, + STACK_OF(ASN1_OBJECT) *policy_oids, unsigned int flags); + +void X509_policy_tree_free(X509_POLICY_TREE *tree); + +int X509_policy_tree_level_count(const X509_POLICY_TREE *tree); +X509_POLICY_LEVEL *X509_policy_tree_get0_level(const X509_POLICY_TREE *tree, + int i); + +STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_policies(const + X509_POLICY_TREE + *tree); + +STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_user_policies(const + X509_POLICY_TREE + *tree); + +int X509_policy_level_node_count(X509_POLICY_LEVEL *level); + +X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level, + int i); + +const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node); + +STACK_OF(POLICYQUALINFO) *X509_policy_node_get0_qualifiers(const + X509_POLICY_NODE + *node); +const X509_POLICY_NODE *X509_policy_node_get0_parent(const X509_POLICY_NODE + *node); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/include/openssl/x509v3.h b/OSlibs/ios/include/openssl/x509v3.h new file mode 100755 index 000000000..f5c61560a --- /dev/null +++ b/OSlibs/ios/include/openssl/x509v3.h @@ -0,0 +1,1055 @@ +/* x509v3.h */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef HEADER_X509V3_H +# define HEADER_X509V3_H + +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# ifdef OPENSSL_SYS_WIN32 +/* Under Win32 these are defined in wincrypt.h */ +# undef X509_NAME +# undef X509_CERT_PAIR +# undef X509_EXTENSIONS +# endif + +/* Forward reference */ +struct v3_ext_method; +struct v3_ext_ctx; + +/* Useful typedefs */ + +typedef void *(*X509V3_EXT_NEW)(void); +typedef void (*X509V3_EXT_FREE) (void *); +typedef void *(*X509V3_EXT_D2I)(void *, const unsigned char **, long); +typedef int (*X509V3_EXT_I2D) (void *, unsigned char **); +typedef STACK_OF(CONF_VALUE) * + (*X509V3_EXT_I2V) (const struct v3_ext_method *method, void *ext, + STACK_OF(CONF_VALUE) *extlist); +typedef void *(*X509V3_EXT_V2I)(const struct v3_ext_method *method, + struct v3_ext_ctx *ctx, + STACK_OF(CONF_VALUE) *values); +typedef char *(*X509V3_EXT_I2S)(const struct v3_ext_method *method, + void *ext); +typedef void *(*X509V3_EXT_S2I)(const struct v3_ext_method *method, + struct v3_ext_ctx *ctx, const char *str); +typedef int (*X509V3_EXT_I2R) (const struct v3_ext_method *method, void *ext, + BIO *out, int indent); +typedef void *(*X509V3_EXT_R2I)(const struct v3_ext_method *method, + struct v3_ext_ctx *ctx, const char *str); + +/* V3 extension structure */ + +struct v3_ext_method { + int ext_nid; + int ext_flags; +/* If this is set the following four fields are ignored */ + ASN1_ITEM_EXP *it; +/* Old style ASN1 calls */ + X509V3_EXT_NEW ext_new; + X509V3_EXT_FREE ext_free; + X509V3_EXT_D2I d2i; + X509V3_EXT_I2D i2d; +/* The following pair is used for string extensions */ + X509V3_EXT_I2S i2s; + X509V3_EXT_S2I s2i; +/* The following pair is used for multi-valued extensions */ + X509V3_EXT_I2V i2v; + X509V3_EXT_V2I v2i; +/* The following are used for raw extensions */ + X509V3_EXT_I2R i2r; + X509V3_EXT_R2I r2i; + void *usr_data; /* Any extension specific data */ +}; + +typedef struct X509V3_CONF_METHOD_st { + char *(*get_string) (void *db, char *section, char *value); + STACK_OF(CONF_VALUE) *(*get_section) (void *db, char *section); + void (*free_string) (void *db, char *string); + void (*free_section) (void *db, STACK_OF(CONF_VALUE) *section); +} X509V3_CONF_METHOD; + +/* Context specific info */ +struct v3_ext_ctx { +# define CTX_TEST 0x1 + int flags; + X509 *issuer_cert; + X509 *subject_cert; + X509_REQ *subject_req; + X509_CRL *crl; + X509V3_CONF_METHOD *db_meth; + void *db; +/* Maybe more here */ +}; + +typedef struct v3_ext_method X509V3_EXT_METHOD; + +DECLARE_STACK_OF(X509V3_EXT_METHOD) + +/* ext_flags values */ +# define X509V3_EXT_DYNAMIC 0x1 +# define X509V3_EXT_CTX_DEP 0x2 +# define X509V3_EXT_MULTILINE 0x4 + +typedef BIT_STRING_BITNAME ENUMERATED_NAMES; + +typedef struct BASIC_CONSTRAINTS_st { + int ca; + ASN1_INTEGER *pathlen; +} BASIC_CONSTRAINTS; + +typedef struct PKEY_USAGE_PERIOD_st { + ASN1_GENERALIZEDTIME *notBefore; + ASN1_GENERALIZEDTIME *notAfter; +} PKEY_USAGE_PERIOD; + +typedef struct otherName_st { + ASN1_OBJECT *type_id; + ASN1_TYPE *value; +} OTHERNAME; + +typedef struct EDIPartyName_st { + ASN1_STRING *nameAssigner; + ASN1_STRING *partyName; +} EDIPARTYNAME; + +typedef struct GENERAL_NAME_st { +# define GEN_OTHERNAME 0 +# define GEN_EMAIL 1 +# define GEN_DNS 2 +# define GEN_X400 3 +# define GEN_DIRNAME 4 +# define GEN_EDIPARTY 5 +# define GEN_URI 6 +# define GEN_IPADD 7 +# define GEN_RID 8 + int type; + union { + char *ptr; + OTHERNAME *otherName; /* otherName */ + ASN1_IA5STRING *rfc822Name; + ASN1_IA5STRING *dNSName; + ASN1_TYPE *x400Address; + X509_NAME *directoryName; + EDIPARTYNAME *ediPartyName; + ASN1_IA5STRING *uniformResourceIdentifier; + ASN1_OCTET_STRING *iPAddress; + ASN1_OBJECT *registeredID; + /* Old names */ + ASN1_OCTET_STRING *ip; /* iPAddress */ + X509_NAME *dirn; /* dirn */ + ASN1_IA5STRING *ia5; /* rfc822Name, dNSName, + * uniformResourceIdentifier */ + ASN1_OBJECT *rid; /* registeredID */ + ASN1_TYPE *other; /* x400Address */ + } d; +} GENERAL_NAME; + +typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES; + +typedef struct ACCESS_DESCRIPTION_st { + ASN1_OBJECT *method; + GENERAL_NAME *location; +} ACCESS_DESCRIPTION; + +typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; + +typedef STACK_OF(ASN1_OBJECT) EXTENDED_KEY_USAGE; + +DECLARE_STACK_OF(GENERAL_NAME) +DECLARE_ASN1_SET_OF(GENERAL_NAME) + +DECLARE_STACK_OF(ACCESS_DESCRIPTION) +DECLARE_ASN1_SET_OF(ACCESS_DESCRIPTION) + +typedef struct DIST_POINT_NAME_st { + int type; + union { + GENERAL_NAMES *fullname; + STACK_OF(X509_NAME_ENTRY) *relativename; + } name; +/* If relativename then this contains the full distribution point name */ + X509_NAME *dpname; +} DIST_POINT_NAME; +/* All existing reasons */ +# define CRLDP_ALL_REASONS 0x807f + +# define CRL_REASON_NONE -1 +# define CRL_REASON_UNSPECIFIED 0 +# define CRL_REASON_KEY_COMPROMISE 1 +# define CRL_REASON_CA_COMPROMISE 2 +# define CRL_REASON_AFFILIATION_CHANGED 3 +# define CRL_REASON_SUPERSEDED 4 +# define CRL_REASON_CESSATION_OF_OPERATION 5 +# define CRL_REASON_CERTIFICATE_HOLD 6 +# define CRL_REASON_REMOVE_FROM_CRL 8 +# define CRL_REASON_PRIVILEGE_WITHDRAWN 9 +# define CRL_REASON_AA_COMPROMISE 10 + +struct DIST_POINT_st { + DIST_POINT_NAME *distpoint; + ASN1_BIT_STRING *reasons; + GENERAL_NAMES *CRLissuer; + int dp_reasons; +}; + +typedef STACK_OF(DIST_POINT) CRL_DIST_POINTS; + +DECLARE_STACK_OF(DIST_POINT) +DECLARE_ASN1_SET_OF(DIST_POINT) + +struct AUTHORITY_KEYID_st { + ASN1_OCTET_STRING *keyid; + GENERAL_NAMES *issuer; + ASN1_INTEGER *serial; +}; + +/* Strong extranet structures */ + +typedef struct SXNET_ID_st { + ASN1_INTEGER *zone; + ASN1_OCTET_STRING *user; +} SXNETID; + +DECLARE_STACK_OF(SXNETID) +DECLARE_ASN1_SET_OF(SXNETID) + +typedef struct SXNET_st { + ASN1_INTEGER *version; + STACK_OF(SXNETID) *ids; +} SXNET; + +typedef struct NOTICEREF_st { + ASN1_STRING *organization; + STACK_OF(ASN1_INTEGER) *noticenos; +} NOTICEREF; + +typedef struct USERNOTICE_st { + NOTICEREF *noticeref; + ASN1_STRING *exptext; +} USERNOTICE; + +typedef struct POLICYQUALINFO_st { + ASN1_OBJECT *pqualid; + union { + ASN1_IA5STRING *cpsuri; + USERNOTICE *usernotice; + ASN1_TYPE *other; + } d; +} POLICYQUALINFO; + +DECLARE_STACK_OF(POLICYQUALINFO) +DECLARE_ASN1_SET_OF(POLICYQUALINFO) + +typedef struct POLICYINFO_st { + ASN1_OBJECT *policyid; + STACK_OF(POLICYQUALINFO) *qualifiers; +} POLICYINFO; + +typedef STACK_OF(POLICYINFO) CERTIFICATEPOLICIES; + +DECLARE_STACK_OF(POLICYINFO) +DECLARE_ASN1_SET_OF(POLICYINFO) + +typedef struct POLICY_MAPPING_st { + ASN1_OBJECT *issuerDomainPolicy; + ASN1_OBJECT *subjectDomainPolicy; +} POLICY_MAPPING; + +DECLARE_STACK_OF(POLICY_MAPPING) + +typedef STACK_OF(POLICY_MAPPING) POLICY_MAPPINGS; + +typedef struct GENERAL_SUBTREE_st { + GENERAL_NAME *base; + ASN1_INTEGER *minimum; + ASN1_INTEGER *maximum; +} GENERAL_SUBTREE; + +DECLARE_STACK_OF(GENERAL_SUBTREE) + +struct NAME_CONSTRAINTS_st { + STACK_OF(GENERAL_SUBTREE) *permittedSubtrees; + STACK_OF(GENERAL_SUBTREE) *excludedSubtrees; +}; + +typedef struct POLICY_CONSTRAINTS_st { + ASN1_INTEGER *requireExplicitPolicy; + ASN1_INTEGER *inhibitPolicyMapping; +} POLICY_CONSTRAINTS; + +/* Proxy certificate structures, see RFC 3820 */ +typedef struct PROXY_POLICY_st { + ASN1_OBJECT *policyLanguage; + ASN1_OCTET_STRING *policy; +} PROXY_POLICY; + +typedef struct PROXY_CERT_INFO_EXTENSION_st { + ASN1_INTEGER *pcPathLengthConstraint; + PROXY_POLICY *proxyPolicy; +} PROXY_CERT_INFO_EXTENSION; + +DECLARE_ASN1_FUNCTIONS(PROXY_POLICY) +DECLARE_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION) + +struct ISSUING_DIST_POINT_st { + DIST_POINT_NAME *distpoint; + int onlyuser; + int onlyCA; + ASN1_BIT_STRING *onlysomereasons; + int indirectCRL; + int onlyattr; +}; + +/* Values in idp_flags field */ +/* IDP present */ +# define IDP_PRESENT 0x1 +/* IDP values inconsistent */ +# define IDP_INVALID 0x2 +/* onlyuser true */ +# define IDP_ONLYUSER 0x4 +/* onlyCA true */ +# define IDP_ONLYCA 0x8 +/* onlyattr true */ +# define IDP_ONLYATTR 0x10 +/* indirectCRL true */ +# define IDP_INDIRECT 0x20 +/* onlysomereasons present */ +# define IDP_REASONS 0x40 + +# define X509V3_conf_err(val) ERR_add_error_data(6, "section:", val->section, \ +",name:", val->name, ",value:", val->value); + +# define X509V3_set_ctx_test(ctx) \ + X509V3_set_ctx(ctx, NULL, NULL, NULL, NULL, CTX_TEST) +# define X509V3_set_ctx_nodb(ctx) (ctx)->db = NULL; + +# define EXT_BITSTRING(nid, table) { nid, 0, ASN1_ITEM_ref(ASN1_BIT_STRING), \ + 0,0,0,0, \ + 0,0, \ + (X509V3_EXT_I2V)i2v_ASN1_BIT_STRING, \ + (X509V3_EXT_V2I)v2i_ASN1_BIT_STRING, \ + NULL, NULL, \ + table} + +# define EXT_IA5STRING(nid) { nid, 0, ASN1_ITEM_ref(ASN1_IA5STRING), \ + 0,0,0,0, \ + (X509V3_EXT_I2S)i2s_ASN1_IA5STRING, \ + (X509V3_EXT_S2I)s2i_ASN1_IA5STRING, \ + 0,0,0,0, \ + NULL} + +# define EXT_END { -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + +/* X509_PURPOSE stuff */ + +# define EXFLAG_BCONS 0x1 +# define EXFLAG_KUSAGE 0x2 +# define EXFLAG_XKUSAGE 0x4 +# define EXFLAG_NSCERT 0x8 + +# define EXFLAG_CA 0x10 +/* Really self issued not necessarily self signed */ +# define EXFLAG_SI 0x20 +# define EXFLAG_V1 0x40 +# define EXFLAG_INVALID 0x80 +# define EXFLAG_SET 0x100 +# define EXFLAG_CRITICAL 0x200 +# define EXFLAG_PROXY 0x400 + +# define EXFLAG_INVALID_POLICY 0x800 +# define EXFLAG_FRESHEST 0x1000 +/* Self signed */ +# define EXFLAG_SS 0x2000 + +# define KU_DIGITAL_SIGNATURE 0x0080 +# define KU_NON_REPUDIATION 0x0040 +# define KU_KEY_ENCIPHERMENT 0x0020 +# define KU_DATA_ENCIPHERMENT 0x0010 +# define KU_KEY_AGREEMENT 0x0008 +# define KU_KEY_CERT_SIGN 0x0004 +# define KU_CRL_SIGN 0x0002 +# define KU_ENCIPHER_ONLY 0x0001 +# define KU_DECIPHER_ONLY 0x8000 + +# define NS_SSL_CLIENT 0x80 +# define NS_SSL_SERVER 0x40 +# define NS_SMIME 0x20 +# define NS_OBJSIGN 0x10 +# define NS_SSL_CA 0x04 +# define NS_SMIME_CA 0x02 +# define NS_OBJSIGN_CA 0x01 +# define NS_ANY_CA (NS_SSL_CA|NS_SMIME_CA|NS_OBJSIGN_CA) + +# define XKU_SSL_SERVER 0x1 +# define XKU_SSL_CLIENT 0x2 +# define XKU_SMIME 0x4 +# define XKU_CODE_SIGN 0x8 +# define XKU_SGC 0x10 +# define XKU_OCSP_SIGN 0x20 +# define XKU_TIMESTAMP 0x40 +# define XKU_DVCS 0x80 +# define XKU_ANYEKU 0x100 + +# define X509_PURPOSE_DYNAMIC 0x1 +# define X509_PURPOSE_DYNAMIC_NAME 0x2 + +typedef struct x509_purpose_st { + int purpose; + int trust; /* Default trust ID */ + int flags; + int (*check_purpose) (const struct x509_purpose_st *, const X509 *, int); + char *name; + char *sname; + void *usr_data; +} X509_PURPOSE; + +# define X509_PURPOSE_SSL_CLIENT 1 +# define X509_PURPOSE_SSL_SERVER 2 +# define X509_PURPOSE_NS_SSL_SERVER 3 +# define X509_PURPOSE_SMIME_SIGN 4 +# define X509_PURPOSE_SMIME_ENCRYPT 5 +# define X509_PURPOSE_CRL_SIGN 6 +# define X509_PURPOSE_ANY 7 +# define X509_PURPOSE_OCSP_HELPER 8 +# define X509_PURPOSE_TIMESTAMP_SIGN 9 + +# define X509_PURPOSE_MIN 1 +# define X509_PURPOSE_MAX 9 + +/* Flags for X509V3_EXT_print() */ + +# define X509V3_EXT_UNKNOWN_MASK (0xfL << 16) +/* Return error for unknown extensions */ +# define X509V3_EXT_DEFAULT 0 +/* Print error for unknown extensions */ +# define X509V3_EXT_ERROR_UNKNOWN (1L << 16) +/* ASN1 parse unknown extensions */ +# define X509V3_EXT_PARSE_UNKNOWN (2L << 16) +/* BIO_dump unknown extensions */ +# define X509V3_EXT_DUMP_UNKNOWN (3L << 16) + +/* Flags for X509V3_add1_i2d */ + +# define X509V3_ADD_OP_MASK 0xfL +# define X509V3_ADD_DEFAULT 0L +# define X509V3_ADD_APPEND 1L +# define X509V3_ADD_REPLACE 2L +# define X509V3_ADD_REPLACE_EXISTING 3L +# define X509V3_ADD_KEEP_EXISTING 4L +# define X509V3_ADD_DELETE 5L +# define X509V3_ADD_SILENT 0x10 + +DECLARE_STACK_OF(X509_PURPOSE) + +DECLARE_ASN1_FUNCTIONS(BASIC_CONSTRAINTS) + +DECLARE_ASN1_FUNCTIONS(SXNET) +DECLARE_ASN1_FUNCTIONS(SXNETID) + +int SXNET_add_id_asc(SXNET **psx, char *zone, char *user, int userlen); +int SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, char *user, + int userlen); +int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *izone, char *user, + int userlen); + +ASN1_OCTET_STRING *SXNET_get_id_asc(SXNET *sx, char *zone); +ASN1_OCTET_STRING *SXNET_get_id_ulong(SXNET *sx, unsigned long lzone); +ASN1_OCTET_STRING *SXNET_get_id_INTEGER(SXNET *sx, ASN1_INTEGER *zone); + +DECLARE_ASN1_FUNCTIONS(AUTHORITY_KEYID) + +DECLARE_ASN1_FUNCTIONS(PKEY_USAGE_PERIOD) + +DECLARE_ASN1_FUNCTIONS(GENERAL_NAME) +GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a); +int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b); + +ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval); +STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, + ASN1_BIT_STRING *bits, + STACK_OF(CONF_VALUE) *extlist); + +STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, + GENERAL_NAME *gen, + STACK_OF(CONF_VALUE) *ret); +int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen); + +DECLARE_ASN1_FUNCTIONS(GENERAL_NAMES) + +STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, + GENERAL_NAMES *gen, + STACK_OF(CONF_VALUE) *extlist); +GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); + +DECLARE_ASN1_FUNCTIONS(OTHERNAME) +DECLARE_ASN1_FUNCTIONS(EDIPARTYNAME) +int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b); +void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value); +void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype); +int GENERAL_NAME_set0_othername(GENERAL_NAME *gen, + ASN1_OBJECT *oid, ASN1_TYPE *value); +int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen, + ASN1_OBJECT **poid, ASN1_TYPE **pvalue); + +char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, + ASN1_OCTET_STRING *ia5); +ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *str); + +DECLARE_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE) +int i2a_ACCESS_DESCRIPTION(BIO *bp, ACCESS_DESCRIPTION *a); + +DECLARE_ASN1_FUNCTIONS(CERTIFICATEPOLICIES) +DECLARE_ASN1_FUNCTIONS(POLICYINFO) +DECLARE_ASN1_FUNCTIONS(POLICYQUALINFO) +DECLARE_ASN1_FUNCTIONS(USERNOTICE) +DECLARE_ASN1_FUNCTIONS(NOTICEREF) + +DECLARE_ASN1_FUNCTIONS(CRL_DIST_POINTS) +DECLARE_ASN1_FUNCTIONS(DIST_POINT) +DECLARE_ASN1_FUNCTIONS(DIST_POINT_NAME) +DECLARE_ASN1_FUNCTIONS(ISSUING_DIST_POINT) + +int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname); + +int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc); + +DECLARE_ASN1_FUNCTIONS(ACCESS_DESCRIPTION) +DECLARE_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS) + +DECLARE_ASN1_ITEM(POLICY_MAPPING) +DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING) +DECLARE_ASN1_ITEM(POLICY_MAPPINGS) + +DECLARE_ASN1_ITEM(GENERAL_SUBTREE) +DECLARE_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE) + +DECLARE_ASN1_ITEM(NAME_CONSTRAINTS) +DECLARE_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS) + +DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS) +DECLARE_ASN1_ITEM(POLICY_CONSTRAINTS) + +GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, + const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, int gen_type, char *value, + int is_nc); + +# ifdef HEADER_CONF_H +GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, CONF_VALUE *cnf); +GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, + const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, CONF_VALUE *cnf, + int is_nc); +void X509V3_conf_free(CONF_VALUE *val); + +X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, + char *value); +X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name, + char *value); +int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section, + STACK_OF(X509_EXTENSION) **sk); +int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, + X509 *cert); +int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, + X509_REQ *req); +int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, + X509_CRL *crl); + +X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, + X509V3_CTX *ctx, int ext_nid, + char *value); +X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + char *name, char *value); +int X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + char *section, X509 *cert); +int X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + char *section, X509_REQ *req); +int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + char *section, X509_CRL *crl); + +int X509V3_add_value_bool_nf(char *name, int asn1_bool, + STACK_OF(CONF_VALUE) **extlist); +int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool); +int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint); +void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf); +void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash); +# endif + +char *X509V3_get_string(X509V3_CTX *ctx, char *name, char *section); +STACK_OF(CONF_VALUE) *X509V3_get_section(X509V3_CTX *ctx, char *section); +void X509V3_string_free(X509V3_CTX *ctx, char *str); +void X509V3_section_free(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section); +void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subject, + X509_REQ *req, X509_CRL *crl, int flags); + +int X509V3_add_value(const char *name, const char *value, + STACK_OF(CONF_VALUE) **extlist); +int X509V3_add_value_uchar(const char *name, const unsigned char *value, + STACK_OF(CONF_VALUE) **extlist); +int X509V3_add_value_bool(const char *name, int asn1_bool, + STACK_OF(CONF_VALUE) **extlist); +int X509V3_add_value_int(const char *name, ASN1_INTEGER *aint, + STACK_OF(CONF_VALUE) **extlist); +char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *meth, ASN1_INTEGER *aint); +ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *meth, char *value); +char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *meth, ASN1_ENUMERATED *aint); +char *i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *meth, + ASN1_ENUMERATED *aint); +int X509V3_EXT_add(X509V3_EXT_METHOD *ext); +int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist); +int X509V3_EXT_add_alias(int nid_to, int nid_from); +void X509V3_EXT_cleanup(void); + +const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext); +const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid); +int X509V3_add_standard_extensions(void); +STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line); +void *X509V3_EXT_d2i(X509_EXTENSION *ext); +void *X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit, + int *idx); +int X509V3_EXT_free(int nid, void *ext_data); + +X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc); +int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, + int crit, unsigned long flags); + +char *hex_to_string(const unsigned char *buffer, long len); +unsigned char *string_to_hex(const char *str, long *len); +int name_cmp(const char *name, const char *cmp); + +void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent, + int ml); +int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, + int indent); +int X509V3_EXT_print_fp(FILE *out, X509_EXTENSION *ext, int flag, int indent); + +int X509V3_extensions_print(BIO *out, char *title, + STACK_OF(X509_EXTENSION) *exts, + unsigned long flag, int indent); + +int X509_check_ca(X509 *x); +int X509_check_purpose(X509 *x, int id, int ca); +int X509_supported_extension(X509_EXTENSION *ex); +int X509_PURPOSE_set(int *p, int purpose); +int X509_check_issued(X509 *issuer, X509 *subject); +int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid); +int X509_PURPOSE_get_count(void); +X509_PURPOSE *X509_PURPOSE_get0(int idx); +int X509_PURPOSE_get_by_sname(char *sname); +int X509_PURPOSE_get_by_id(int id); +int X509_PURPOSE_add(int id, int trust, int flags, + int (*ck) (const X509_PURPOSE *, const X509 *, int), + char *name, char *sname, void *arg); +char *X509_PURPOSE_get0_name(X509_PURPOSE *xp); +char *X509_PURPOSE_get0_sname(X509_PURPOSE *xp); +int X509_PURPOSE_get_trust(X509_PURPOSE *xp); +void X509_PURPOSE_cleanup(void); +int X509_PURPOSE_get_id(X509_PURPOSE *); + +STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x); +STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x); +void X509_email_free(STACK_OF(OPENSSL_STRING) *sk); +STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x); +/* Flags for X509_check_* functions */ + +/* + * Always check subject name for host match even if subject alt names present + */ +# define X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT 0x1 +/* Disable wildcard matching for dnsName fields and common name. */ +# define X509_CHECK_FLAG_NO_WILDCARDS 0x2 +/* Wildcards must not match a partial label. */ +# define X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS 0x4 +/* Allow (non-partial) wildcards to match multiple labels. */ +# define X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS 0x8 +/* Constraint verifier subdomain patterns to match a single labels. */ +# define X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS 0x10 +/* + * Match reference identifiers starting with "." to any sub-domain. + * This is a non-public flag, turned on implicitly when the subject + * reference identity is a DNS name. + */ +# define _X509_CHECK_FLAG_DOT_SUBDOMAINS 0x8000 + +int X509_check_host(X509 *x, const char *chk, size_t chklen, + unsigned int flags, char **peername); +int X509_check_email(X509 *x, const char *chk, size_t chklen, + unsigned int flags); +int X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen, + unsigned int flags); +int X509_check_ip_asc(X509 *x, const char *ipasc, unsigned int flags); + +ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc); +ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc); +int a2i_ipadd(unsigned char *ipout, const char *ipasc); +int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE) *dn_sk, + unsigned long chtype); + +void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent); +DECLARE_STACK_OF(X509_POLICY_NODE) + +# ifndef OPENSSL_NO_RFC3779 + +typedef struct ASRange_st { + ASN1_INTEGER *min, *max; +} ASRange; + +# define ASIdOrRange_id 0 +# define ASIdOrRange_range 1 + +typedef struct ASIdOrRange_st { + int type; + union { + ASN1_INTEGER *id; + ASRange *range; + } u; +} ASIdOrRange; + +typedef STACK_OF(ASIdOrRange) ASIdOrRanges; +DECLARE_STACK_OF(ASIdOrRange) + +# define ASIdentifierChoice_inherit 0 +# define ASIdentifierChoice_asIdsOrRanges 1 + +typedef struct ASIdentifierChoice_st { + int type; + union { + ASN1_NULL *inherit; + ASIdOrRanges *asIdsOrRanges; + } u; +} ASIdentifierChoice; + +typedef struct ASIdentifiers_st { + ASIdentifierChoice *asnum, *rdi; +} ASIdentifiers; + +DECLARE_ASN1_FUNCTIONS(ASRange) +DECLARE_ASN1_FUNCTIONS(ASIdOrRange) +DECLARE_ASN1_FUNCTIONS(ASIdentifierChoice) +DECLARE_ASN1_FUNCTIONS(ASIdentifiers) + +typedef struct IPAddressRange_st { + ASN1_BIT_STRING *min, *max; +} IPAddressRange; + +# define IPAddressOrRange_addressPrefix 0 +# define IPAddressOrRange_addressRange 1 + +typedef struct IPAddressOrRange_st { + int type; + union { + ASN1_BIT_STRING *addressPrefix; + IPAddressRange *addressRange; + } u; +} IPAddressOrRange; + +typedef STACK_OF(IPAddressOrRange) IPAddressOrRanges; +DECLARE_STACK_OF(IPAddressOrRange) + +# define IPAddressChoice_inherit 0 +# define IPAddressChoice_addressesOrRanges 1 + +typedef struct IPAddressChoice_st { + int type; + union { + ASN1_NULL *inherit; + IPAddressOrRanges *addressesOrRanges; + } u; +} IPAddressChoice; + +typedef struct IPAddressFamily_st { + ASN1_OCTET_STRING *addressFamily; + IPAddressChoice *ipAddressChoice; +} IPAddressFamily; + +typedef STACK_OF(IPAddressFamily) IPAddrBlocks; +DECLARE_STACK_OF(IPAddressFamily) + +DECLARE_ASN1_FUNCTIONS(IPAddressRange) +DECLARE_ASN1_FUNCTIONS(IPAddressOrRange) +DECLARE_ASN1_FUNCTIONS(IPAddressChoice) +DECLARE_ASN1_FUNCTIONS(IPAddressFamily) + +/* + * API tag for elements of the ASIdentifer SEQUENCE. + */ +# define V3_ASID_ASNUM 0 +# define V3_ASID_RDI 1 + +/* + * AFI values, assigned by IANA. It'd be nice to make the AFI + * handling code totally generic, but there are too many little things + * that would need to be defined for other address families for it to + * be worth the trouble. + */ +# define IANA_AFI_IPV4 1 +# define IANA_AFI_IPV6 2 + +/* + * Utilities to construct and extract values from RFC3779 extensions, + * since some of the encodings (particularly for IP address prefixes + * and ranges) are a bit tedious to work with directly. + */ +int v3_asid_add_inherit(ASIdentifiers *asid, int which); +int v3_asid_add_id_or_range(ASIdentifiers *asid, int which, + ASN1_INTEGER *min, ASN1_INTEGER *max); +int v3_addr_add_inherit(IPAddrBlocks *addr, + const unsigned afi, const unsigned *safi); +int v3_addr_add_prefix(IPAddrBlocks *addr, + const unsigned afi, const unsigned *safi, + unsigned char *a, const int prefixlen); +int v3_addr_add_range(IPAddrBlocks *addr, + const unsigned afi, const unsigned *safi, + unsigned char *min, unsigned char *max); +unsigned v3_addr_get_afi(const IPAddressFamily *f); +int v3_addr_get_range(IPAddressOrRange *aor, const unsigned afi, + unsigned char *min, unsigned char *max, + const int length); + +/* + * Canonical forms. + */ +int v3_asid_is_canonical(ASIdentifiers *asid); +int v3_addr_is_canonical(IPAddrBlocks *addr); +int v3_asid_canonize(ASIdentifiers *asid); +int v3_addr_canonize(IPAddrBlocks *addr); + +/* + * Tests for inheritance and containment. + */ +int v3_asid_inherits(ASIdentifiers *asid); +int v3_addr_inherits(IPAddrBlocks *addr); +int v3_asid_subset(ASIdentifiers *a, ASIdentifiers *b); +int v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b); + +/* + * Check whether RFC 3779 extensions nest properly in chains. + */ +int v3_asid_validate_path(X509_STORE_CTX *); +int v3_addr_validate_path(X509_STORE_CTX *); +int v3_asid_validate_resource_set(STACK_OF(X509) *chain, + ASIdentifiers *ext, int allow_inheritance); +int v3_addr_validate_resource_set(STACK_OF(X509) *chain, + IPAddrBlocks *ext, int allow_inheritance); + +# endif /* OPENSSL_NO_RFC3779 */ + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_X509V3_strings(void); + +/* Error codes for the X509V3 functions. */ + +/* Function codes. */ +# define X509V3_F_A2I_GENERAL_NAME 164 +# define X509V3_F_ASIDENTIFIERCHOICE_CANONIZE 161 +# define X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL 162 +# define X509V3_F_COPY_EMAIL 122 +# define X509V3_F_COPY_ISSUER 123 +# define X509V3_F_DO_DIRNAME 144 +# define X509V3_F_DO_EXT_CONF 124 +# define X509V3_F_DO_EXT_I2D 135 +# define X509V3_F_DO_EXT_NCONF 151 +# define X509V3_F_DO_I2V_NAME_CONSTRAINTS 148 +# define X509V3_F_GNAMES_FROM_SECTNAME 156 +# define X509V3_F_HEX_TO_STRING 111 +# define X509V3_F_I2S_ASN1_ENUMERATED 121 +# define X509V3_F_I2S_ASN1_IA5STRING 149 +# define X509V3_F_I2S_ASN1_INTEGER 120 +# define X509V3_F_I2V_AUTHORITY_INFO_ACCESS 138 +# define X509V3_F_NOTICE_SECTION 132 +# define X509V3_F_NREF_NOS 133 +# define X509V3_F_POLICY_SECTION 131 +# define X509V3_F_PROCESS_PCI_VALUE 150 +# define X509V3_F_R2I_CERTPOL 130 +# define X509V3_F_R2I_PCI 155 +# define X509V3_F_S2I_ASN1_IA5STRING 100 +# define X509V3_F_S2I_ASN1_INTEGER 108 +# define X509V3_F_S2I_ASN1_OCTET_STRING 112 +# define X509V3_F_S2I_ASN1_SKEY_ID 114 +# define X509V3_F_S2I_SKEY_ID 115 +# define X509V3_F_SET_DIST_POINT_NAME 158 +# define X509V3_F_STRING_TO_HEX 113 +# define X509V3_F_SXNET_ADD_ID_ASC 125 +# define X509V3_F_SXNET_ADD_ID_INTEGER 126 +# define X509V3_F_SXNET_ADD_ID_ULONG 127 +# define X509V3_F_SXNET_GET_ID_ASC 128 +# define X509V3_F_SXNET_GET_ID_ULONG 129 +# define X509V3_F_V2I_ASIDENTIFIERS 163 +# define X509V3_F_V2I_ASN1_BIT_STRING 101 +# define X509V3_F_V2I_AUTHORITY_INFO_ACCESS 139 +# define X509V3_F_V2I_AUTHORITY_KEYID 119 +# define X509V3_F_V2I_BASIC_CONSTRAINTS 102 +# define X509V3_F_V2I_CRLD 134 +# define X509V3_F_V2I_EXTENDED_KEY_USAGE 103 +# define X509V3_F_V2I_GENERAL_NAMES 118 +# define X509V3_F_V2I_GENERAL_NAME_EX 117 +# define X509V3_F_V2I_IDP 157 +# define X509V3_F_V2I_IPADDRBLOCKS 159 +# define X509V3_F_V2I_ISSUER_ALT 153 +# define X509V3_F_V2I_NAME_CONSTRAINTS 147 +# define X509V3_F_V2I_POLICY_CONSTRAINTS 146 +# define X509V3_F_V2I_POLICY_MAPPINGS 145 +# define X509V3_F_V2I_SUBJECT_ALT 154 +# define X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL 160 +# define X509V3_F_V3_GENERIC_EXTENSION 116 +# define X509V3_F_X509V3_ADD1_I2D 140 +# define X509V3_F_X509V3_ADD_VALUE 105 +# define X509V3_F_X509V3_EXT_ADD 104 +# define X509V3_F_X509V3_EXT_ADD_ALIAS 106 +# define X509V3_F_X509V3_EXT_CONF 107 +# define X509V3_F_X509V3_EXT_FREE 165 +# define X509V3_F_X509V3_EXT_I2D 136 +# define X509V3_F_X509V3_EXT_NCONF 152 +# define X509V3_F_X509V3_GET_SECTION 142 +# define X509V3_F_X509V3_GET_STRING 143 +# define X509V3_F_X509V3_GET_VALUE_BOOL 110 +# define X509V3_F_X509V3_PARSE_LIST 109 +# define X509V3_F_X509_PURPOSE_ADD 137 +# define X509V3_F_X509_PURPOSE_SET 141 + +/* Reason codes. */ +# define X509V3_R_BAD_IP_ADDRESS 118 +# define X509V3_R_BAD_OBJECT 119 +# define X509V3_R_BN_DEC2BN_ERROR 100 +# define X509V3_R_BN_TO_ASN1_INTEGER_ERROR 101 +# define X509V3_R_CANNOT_FIND_FREE_FUNCTION 168 +# define X509V3_R_DIRNAME_ERROR 149 +# define X509V3_R_DISTPOINT_ALREADY_SET 160 +# define X509V3_R_DUPLICATE_ZONE_ID 133 +# define X509V3_R_ERROR_CONVERTING_ZONE 131 +# define X509V3_R_ERROR_CREATING_EXTENSION 144 +# define X509V3_R_ERROR_IN_EXTENSION 128 +# define X509V3_R_EXPECTED_A_SECTION_NAME 137 +# define X509V3_R_EXTENSION_EXISTS 145 +# define X509V3_R_EXTENSION_NAME_ERROR 115 +# define X509V3_R_EXTENSION_NOT_FOUND 102 +# define X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED 103 +# define X509V3_R_EXTENSION_VALUE_ERROR 116 +# define X509V3_R_ILLEGAL_EMPTY_EXTENSION 151 +# define X509V3_R_ILLEGAL_HEX_DIGIT 113 +# define X509V3_R_INCORRECT_POLICY_SYNTAX_TAG 152 +# define X509V3_R_INVALID_ASNUMBER 162 +# define X509V3_R_INVALID_ASRANGE 163 +# define X509V3_R_INVALID_BOOLEAN_STRING 104 +# define X509V3_R_INVALID_EXTENSION_STRING 105 +# define X509V3_R_INVALID_INHERITANCE 165 +# define X509V3_R_INVALID_IPADDRESS 166 +# define X509V3_R_INVALID_MULTIPLE_RDNS 161 +# define X509V3_R_INVALID_NAME 106 +# define X509V3_R_INVALID_NULL_ARGUMENT 107 +# define X509V3_R_INVALID_NULL_NAME 108 +# define X509V3_R_INVALID_NULL_VALUE 109 +# define X509V3_R_INVALID_NUMBER 140 +# define X509V3_R_INVALID_NUMBERS 141 +# define X509V3_R_INVALID_OBJECT_IDENTIFIER 110 +# define X509V3_R_INVALID_OPTION 138 +# define X509V3_R_INVALID_POLICY_IDENTIFIER 134 +# define X509V3_R_INVALID_PROXY_POLICY_SETTING 153 +# define X509V3_R_INVALID_PURPOSE 146 +# define X509V3_R_INVALID_SAFI 164 +# define X509V3_R_INVALID_SECTION 135 +# define X509V3_R_INVALID_SYNTAX 143 +# define X509V3_R_ISSUER_DECODE_ERROR 126 +# define X509V3_R_MISSING_VALUE 124 +# define X509V3_R_NEED_ORGANIZATION_AND_NUMBERS 142 +# define X509V3_R_NO_CONFIG_DATABASE 136 +# define X509V3_R_NO_ISSUER_CERTIFICATE 121 +# define X509V3_R_NO_ISSUER_DETAILS 127 +# define X509V3_R_NO_POLICY_IDENTIFIER 139 +# define X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED 154 +# define X509V3_R_NO_PUBLIC_KEY 114 +# define X509V3_R_NO_SUBJECT_DETAILS 125 +# define X509V3_R_ODD_NUMBER_OF_DIGITS 112 +# define X509V3_R_OPERATION_NOT_DEFINED 148 +# define X509V3_R_OTHERNAME_ERROR 147 +# define X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED 155 +# define X509V3_R_POLICY_PATH_LENGTH 156 +# define X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED 157 +# define X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED 158 +# define X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY 159 +# define X509V3_R_SECTION_NOT_FOUND 150 +# define X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS 122 +# define X509V3_R_UNABLE_TO_GET_ISSUER_KEYID 123 +# define X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT 111 +# define X509V3_R_UNKNOWN_EXTENSION 129 +# define X509V3_R_UNKNOWN_EXTENSION_NAME 130 +# define X509V3_R_UNKNOWN_OPTION 120 +# define X509V3_R_UNSUPPORTED_OPTION 117 +# define X509V3_R_UNSUPPORTED_TYPE 167 +# define X509V3_R_USER_TOO_LONG 132 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OSlibs/ios/lib/libcrypto.a b/OSlibs/ios/lib/libcrypto.a new file mode 100644 index 000000000..3e9849e14 Binary files /dev/null and b/OSlibs/ios/lib/libcrypto.a differ diff --git a/OSlibs/ios/lib/libcurl.a b/OSlibs/ios/lib/libcurl.a new file mode 100644 index 000000000..07109972f Binary files /dev/null and b/OSlibs/ios/lib/libcurl.a differ diff --git a/OSlibs/ios/lib/libssl.a b/OSlibs/ios/lib/libssl.a new file mode 100644 index 000000000..646b0ad20 Binary files /dev/null and b/OSlibs/ios/lib/libssl.a differ diff --git a/osx/libcrypto.a b/OSlibs/osx/libcrypto.a similarity index 100% rename from osx/libcrypto.a rename to OSlibs/osx/libcrypto.a diff --git a/osx/libcurl.a b/OSlibs/osx/libcurl.a similarity index 100% rename from osx/libcurl.a rename to OSlibs/osx/libcurl.a diff --git a/osx/libgmp.a b/OSlibs/osx/libgmp.a similarity index 100% rename from osx/libgmp.a rename to OSlibs/osx/libgmp.a diff --git a/osx/libsecp256k1.a b/OSlibs/osx/libsecp256k1.a similarity index 100% rename from osx/libsecp256k1.a rename to OSlibs/osx/libsecp256k1.a diff --git a/osx/libssl.a b/OSlibs/osx/libssl.a similarity index 100% rename from osx/libssl.a rename to OSlibs/osx/libssl.a diff --git a/win/libcrypto.a b/OSlibs/win/libcrypto.a similarity index 100% rename from win/libcrypto.a rename to OSlibs/win/libcrypto.a diff --git a/win/libcurl.a b/OSlibs/win/libcurl.a similarity index 100% rename from win/libcurl.a rename to OSlibs/win/libcurl.a diff --git a/win/libcurldll.a b/OSlibs/win/libcurldll.a similarity index 100% rename from win/libcurldll.a rename to OSlibs/win/libcurldll.a diff --git a/OSlibs/win/libpthreadGC2.a b/OSlibs/win/libpthreadGC2.a new file mode 100755 index 000000000..ff267089b Binary files /dev/null and b/OSlibs/win/libpthreadGC2.a differ diff --git a/win/libpthreadGC2_64.a b/OSlibs/win/libpthreadGC2_64.a similarity index 100% rename from win/libpthreadGC2_64.a rename to OSlibs/win/libpthreadGC2_64.a diff --git a/win/libsecp256k1.a b/OSlibs/win/libsecp256k1.a similarity index 100% rename from win/libsecp256k1.a rename to OSlibs/win/libsecp256k1.a diff --git a/win/libssl.a b/OSlibs/win/libssl.a similarity index 100% rename from win/libssl.a rename to OSlibs/win/libssl.a diff --git a/win/mingw.c b/OSlibs/win/mingw.c similarity index 100% rename from win/mingw.c rename to OSlibs/win/mingw.c diff --git a/OSlibs/win/mingw.h b/OSlibs/win/mingw.h new file mode 100755 index 000000000..1a80c56dc --- /dev/null +++ b/OSlibs/win/mingw.h @@ -0,0 +1,76 @@ +#ifndef MINGW_H +#define MINGW_H + +#include + +#define _USE_W32_SOCKETS 1 +#include +#include "pthread.h" + +#define ENOTCONN WSAENOTCONN +#define EWOULDBLOCK WSAEWOULDBLOCK +#define ENOBUFS WSAENOBUFS +#define ECONNRESET WSAECONNRESET +#define ESHUTDOWN WSAESHUTDOWN +#define EAFNOSUPPORT WSAEAFNOSUPPORT +#define EPROTONOSUPPORT WSAEPROTONOSUPPORT +#define EINPROGRESS WSAEINPROGRESS +#define EISCONN WSAEISCONN +#define ECONNREFUSED WSAECONNREFUSED +#define EHOSTUNREACH WSAEHOSTUNREACH + + +/* winsock doesn't feature poll(), so there is a version implemented + * in terms of select() in mingw.c. The following definitions + * are copied from linux man pages. A poll() macro is defined to + * call the version in mingw.c. + */ +#define POLLIN 0x0001 /* There is data to read */ +#define POLLPRI 0x0002 /* There is urgent data to read */ +#define POLLOUT 0x0004 /* Writing now will not block */ +#define POLLERR 0x0008 /* Error condition */ +#define POLLHUP 0x0010 /* Hung up */ +#define POLLNVAL 0x0020 /* Invalid request: fd not open */ +struct pollfd { + SOCKET fd; /* file descriptor */ + short events; /* requested events */ + short revents; /* returned events */ +}; +#define poll(x, y, z) win32_poll(x, y, z) + +/* These wrappers do nothing special except set the global errno variable if + * an error occurs (winsock doesn't do this by default). They set errno + * to unix-like values (i.e. WSAEWOULDBLOCK is mapped to EAGAIN), so code + * outside of this file "shouldn't" have to worry about winsock specific error + * handling. + */ +//#define socket(x, y, z) win32_socket(x, y, z) +//#define connect(x, y, z) win32_connect(x, y, z) +//#define accept(x, y, z) win32_accept(x, y, z) +//#define shutdown(x, y) win32_shutdown(x, y) +//#define read(x, y, z) win32_read_socket(x, y, z) +//#define write(x, y, z) win32_write_socket(x, y, z) + +/* Winsock uses int instead of the usual socklen_t */ +typedef int socklen_t; + +int win32_poll(struct pollfd *, unsigned int, int); +//SOCKET win32_socket(int, int, int); +//int win32_connect(SOCKET, struct sockaddr*, socklen_t); +//SOCKET win32_accept(SOCKET, struct sockaddr*, socklen_t *); +//int win32_shutdown(SOCKET, int); +//int win32_close_socket(SOCKET fd); + +//#define strtok_r(x, y, z) win32_strtok_r(x, y, z) +//#define strsep(x,y) win32_strsep(x,y) + +char *win32_strtok_r(char *s, const char *delim, char **lasts); +char *win32_strsep(char **stringp, const char *delim); + +ssize_t win32_read_socket(SOCKET fd, void *buf, int n); +ssize_t win32_write_socket(SOCKET fd, void *buf, int n); + +//static inline void sleep(unsigned ms) { Sleep(ms*1000); } + +#endif + diff --git a/win/mman.h b/OSlibs/win/mman.h similarity index 100% rename from win/mman.h rename to OSlibs/win/mman.h diff --git a/OSlibs/win/pthread.h b/OSlibs/win/pthread.h new file mode 100644 index 000000000..7da6eb4b4 --- /dev/null +++ b/OSlibs/win/pthread.h @@ -0,0 +1,1368 @@ +/* This is an implementation of the threads API of POSIX 1003.1-2001. + * + * -------------------------------------------------------------------------- + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#if !defined( PTHREAD_H ) +#define PTHREAD_H + +/* + * See the README file for an explanation of the pthreads-win32 version + * numbering scheme and how the DLL is named etc. + */ +#define PTW32_VERSION 2,9,1,0 +#define PTW32_VERSION_STRING "2, 9, 1, 0\0" + +/* There are three implementations of cancel cleanup. + * Note that pthread.h is included in both application + * compilation units and also internally for the library. + * The code here and within the library aims to work + * for all reasonable combinations of environments. + * + * The three implementations are: + * + * WIN32 SEH + * C + * C++ + * + * Please note that exiting a push/pop block via + * "return", "exit", "break", or "continue" will + * lead to different behaviour amongst applications + * depending upon whether the library was built + * using SEH, C++, or C. For example, a library built + * with SEH will call the cleanup routine, while both + * C++ and C built versions will not. + */ + +/* + * Define defaults for cleanup code. + * Note: Unless the build explicitly defines one of the following, then + * we default to standard C style cleanup. This style uses setjmp/longjmp + * in the cancelation and thread exit implementations and therefore won't + * do stack unwinding if linked to applications that have it (e.g. + * C++ apps). This is currently consistent with most/all commercial Unix + * POSIX threads implementations. + */ +#if !defined( __CLEANUP_SEH ) && !defined( __CLEANUP_CXX ) && !defined( __CLEANUP_C ) +# define __CLEANUP_C +#endif + +#if defined( __CLEANUP_SEH ) && ( !defined( _MSC_VER ) && !defined(PTW32_RC_MSC)) +#error ERROR [__FILE__, line __LINE__]: SEH is not supported for this compiler. +#endif + +/* + * Stop here if we are being included by the resource compiler. + */ +#if !defined(RC_INVOKED) + +#undef PTW32_LEVEL + +#if defined(_POSIX_SOURCE) +#define PTW32_LEVEL 0 +/* Early POSIX */ +#endif + +#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 +#undef PTW32_LEVEL +#define PTW32_LEVEL 1 +/* Include 1b, 1c and 1d */ +#endif + +#if defined(INCLUDE_NP) +#undef PTW32_LEVEL +#define PTW32_LEVEL 2 +/* Include Non-Portable extensions */ +#endif + +#define PTW32_LEVEL_MAX 3 + +#if ( defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112 ) || !defined(PTW32_LEVEL) +#define PTW32_LEVEL PTW32_LEVEL_MAX +/* Include everything */ +#endif + +#if defined(_UWIN) +# define HAVE_STRUCT_TIMESPEC 1 +# define HAVE_SIGNAL_H 1 +# undef HAVE_PTW32_CONFIG_H +# pragma comment(lib, "pthread") +#endif + +/* + * ------------------------------------------------------------- + * + * + * Module: pthread.h + * + * Purpose: + * Provides an implementation of PThreads based upon the + * standard: + * + * POSIX 1003.1-2001 + * and + * The Single Unix Specification version 3 + * + * (these two are equivalent) + * + * in order to enhance code portability between Windows, + * various commercial Unix implementations, and Linux. + * + * See the ANNOUNCE file for a full list of conforming + * routines and defined constants, and a list of missing + * routines and constants not defined in this implementation. + * + * Authors: + * There have been many contributors to this library. + * The initial implementation was contributed by + * John Bossom, and several others have provided major + * sections or revisions of parts of the implementation. + * Often significant effort has been contributed to + * find and fix important bugs and other problems to + * improve the reliability of the library, which sometimes + * is not reflected in the amount of code which changed as + * result. + * As much as possible, the contributors are acknowledged + * in the ChangeLog file in the source code distribution + * where their changes are noted in detail. + * + * Contributors are listed in the CONTRIBUTORS file. + * + * As usual, all bouquets go to the contributors, and all + * brickbats go to the project maintainer. + * + * Maintainer: + * The code base for this project is coordinated and + * eventually pre-tested, packaged, and made available by + * + * Ross Johnson + * + * QA Testers: + * Ultimately, the library is tested in the real world by + * a host of competent and demanding scientists and + * engineers who report bugs and/or provide solutions + * which are then fixed or incorporated into subsequent + * versions of the library. Each time a bug is fixed, a + * test case is written to prove the fix and ensure + * that later changes to the code don't reintroduce the + * same error. The number of test cases is slowly growing + * and therefore so is the code reliability. + * + * Compliance: + * See the file ANNOUNCE for the list of implemented + * and not-implemented routines and defined options. + * Of course, these are all defined is this file as well. + * + * Web site: + * The source code and other information about this library + * are available from + * + * http://sources.redhat.com/pthreads-win32/ + * + * ------------------------------------------------------------- + */ + +/* Try to avoid including windows.h */ +#if (defined(__MINGW64__) || defined(__MINGW32__)) && defined(__cplusplus) +#define PTW32_INCLUDE_WINDOWS_H +#endif + +#if defined(PTW32_INCLUDE_WINDOWS_H) +#include +#endif + +#if defined(_MSC_VER) && _MSC_VER < 1300 || defined(__DMC__) +/* + * VC++6.0 or early compiler's header has no DWORD_PTR type. + */ +typedef unsigned long DWORD_PTR; +typedef unsigned long ULONG_PTR; +#endif +/* + * ----------------- + * autoconf switches + * ----------------- + */ + +#if defined(HAVE_PTW32_CONFIG_H) +#include "config.h" +#endif /* HAVE_PTW32_CONFIG_H */ + +#if !defined(NEED_FTIME) +#include +#else /* NEED_FTIME */ +/* use native WIN32 time API */ +#endif /* NEED_FTIME */ + +#if defined(HAVE_SIGNAL_H) +#include +#endif /* HAVE_SIGNAL_H */ + +#include + +/* + * Boolean values to make us independent of system includes. + */ +enum { + PTW32_FALSE = 0, + PTW32_TRUE = (! PTW32_FALSE) +}; + +/* + * This is a duplicate of what is in the autoconf config.h, + * which is only used when building the pthread-win32 libraries. + */ + +#if !defined(PTW32_CONFIG_H) +# if defined(WINCE) +# define NEED_ERRNO +# define NEED_SEM +# endif +# if defined(__MINGW64__) +# define HAVE_STRUCT_TIMESPEC +# define HAVE_MODE_T +# elif defined(_UWIN) || defined(__MINGW32__) +# define HAVE_MODE_T +# endif +#endif + +/* + * + */ + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX +#if defined(NEED_ERRNO) +#include "need_errno.h" +#else +#include +#endif +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +/* + * Several systems don't define some error numbers. + */ +#if !defined(ENOTSUP) +# define ENOTSUP 48 /* This is the value in Solaris. */ +#endif + +#if !defined(ETIMEDOUT) +# define ETIMEDOUT 10060 /* Same as WSAETIMEDOUT */ +#endif + +#if !defined(ENOSYS) +# define ENOSYS 140 /* Semi-arbitrary value */ +#endif + +#if !defined(EDEADLK) +# if defined(EDEADLOCK) +# define EDEADLK EDEADLOCK +# else +# define EDEADLK 36 /* This is the value in MSVC. */ +# endif +#endif + +/* POSIX 2008 - related to robust mutexes */ +#if !defined(EOWNERDEAD) +# define EOWNERDEAD 43 +#endif +#if !defined(ENOTRECOVERABLE) +# define ENOTRECOVERABLE 44 +#endif + +#include "sched.h" + +/* + * To avoid including windows.h we define only those things that we + * actually need from it. + */ +#if !defined(PTW32_INCLUDE_WINDOWS_H) +#if !defined(HANDLE) +# define PTW32__HANDLE_DEF +# define HANDLE void * +#endif +#if !defined(DWORD) +# define PTW32__DWORD_DEF +# define DWORD unsigned long +#endif +#endif + +#if !defined(HAVE_STRUCT_TIMESPEC) +#define HAVE_STRUCT_TIMESPEC +#if !defined(_TIMESPEC_DEFINED) +#define _TIMESPEC_DEFINED +struct timespec { + time_t tv_sec; + long tv_nsec; +}; +#endif /* _TIMESPEC_DEFINED */ +#endif /* HAVE_STRUCT_TIMESPEC */ + +#if !defined(SIG_BLOCK) +#define SIG_BLOCK 0 +#endif /* SIG_BLOCK */ + +#if !defined(SIG_UNBLOCK) +#define SIG_UNBLOCK 1 +#endif /* SIG_UNBLOCK */ + +#if !defined(SIG_SETMASK) +#define SIG_SETMASK 2 +#endif /* SIG_SETMASK */ + +#if defined(__cplusplus) +extern "C" +{ +#endif /* __cplusplus */ + +/* + * ------------------------------------------------------------- + * + * POSIX 1003.1-2001 Options + * ========================= + * + * Options are normally set in , which is not provided + * with pthreads-win32. + * + * For conformance with the Single Unix Specification (version 3), all of the + * options below are defined, and have a value of either -1 (not supported) + * or 200112L (supported). + * + * These options can neither be left undefined nor have a value of 0, because + * either indicates that sysconf(), which is not implemented, may be used at + * runtime to check the status of the option. + * + * _POSIX_THREADS (== 200112L) + * If == 200112L, you can use threads + * + * _POSIX_THREAD_ATTR_STACKSIZE (== 200112L) + * If == 200112L, you can control the size of a thread's + * stack + * pthread_attr_getstacksize + * pthread_attr_setstacksize + * + * _POSIX_THREAD_ATTR_STACKADDR (== -1) + * If == 200112L, you can allocate and control a thread's + * stack. If not supported, the following functions + * will return ENOSYS, indicating they are not + * supported: + * pthread_attr_getstackaddr + * pthread_attr_setstackaddr + * + * _POSIX_THREAD_PRIORITY_SCHEDULING (== -1) + * If == 200112L, you can use realtime scheduling. + * This option indicates that the behaviour of some + * implemented functions conforms to the additional TPS + * requirements in the standard. E.g. rwlocks favour + * writers over readers when threads have equal priority. + * + * _POSIX_THREAD_PRIO_INHERIT (== -1) + * If == 200112L, you can create priority inheritance + * mutexes. + * pthread_mutexattr_getprotocol + + * pthread_mutexattr_setprotocol + + * + * _POSIX_THREAD_PRIO_PROTECT (== -1) + * If == 200112L, you can create priority ceiling mutexes + * Indicates the availability of: + * pthread_mutex_getprioceiling + * pthread_mutex_setprioceiling + * pthread_mutexattr_getprioceiling + * pthread_mutexattr_getprotocol + + * pthread_mutexattr_setprioceiling + * pthread_mutexattr_setprotocol + + * + * _POSIX_THREAD_PROCESS_SHARED (== -1) + * If set, you can create mutexes and condition + * variables that can be shared with another + * process.If set, indicates the availability + * of: + * pthread_mutexattr_getpshared + * pthread_mutexattr_setpshared + * pthread_condattr_getpshared + * pthread_condattr_setpshared + * + * _POSIX_THREAD_SAFE_FUNCTIONS (== 200112L) + * If == 200112L you can use the special *_r library + * functions that provide thread-safe behaviour + * + * _POSIX_READER_WRITER_LOCKS (== 200112L) + * If == 200112L, you can use read/write locks + * + * _POSIX_SPIN_LOCKS (== 200112L) + * If == 200112L, you can use spin locks + * + * _POSIX_BARRIERS (== 200112L) + * If == 200112L, you can use barriers + * + * + These functions provide both 'inherit' and/or + * 'protect' protocol, based upon these macro + * settings. + * + * ------------------------------------------------------------- + */ + +/* + * POSIX Options + */ +#undef _POSIX_THREADS +#define _POSIX_THREADS 200809L + +#undef _POSIX_READER_WRITER_LOCKS +#define _POSIX_READER_WRITER_LOCKS 200809L + +#undef _POSIX_SPIN_LOCKS +#define _POSIX_SPIN_LOCKS 200809L + +#undef _POSIX_BARRIERS +#define _POSIX_BARRIERS 200809L + +#undef _POSIX_THREAD_SAFE_FUNCTIONS +#define _POSIX_THREAD_SAFE_FUNCTIONS 200809L + +#undef _POSIX_THREAD_ATTR_STACKSIZE +#define _POSIX_THREAD_ATTR_STACKSIZE 200809L + +/* + * The following options are not supported + */ +#undef _POSIX_THREAD_ATTR_STACKADDR +#define _POSIX_THREAD_ATTR_STACKADDR -1 + +#undef _POSIX_THREAD_PRIO_INHERIT +#define _POSIX_THREAD_PRIO_INHERIT -1 + +#undef _POSIX_THREAD_PRIO_PROTECT +#define _POSIX_THREAD_PRIO_PROTECT -1 + +/* TPS is not fully supported. */ +#undef _POSIX_THREAD_PRIORITY_SCHEDULING +#define _POSIX_THREAD_PRIORITY_SCHEDULING -1 + +#undef _POSIX_THREAD_PROCESS_SHARED +#define _POSIX_THREAD_PROCESS_SHARED -1 + + +/* + * POSIX 1003.1-2001 Limits + * =========================== + * + * These limits are normally set in , which is not provided with + * pthreads-win32. + * + * PTHREAD_DESTRUCTOR_ITERATIONS + * Maximum number of attempts to destroy + * a thread's thread-specific data on + * termination (must be at least 4) + * + * PTHREAD_KEYS_MAX + * Maximum number of thread-specific data keys + * available per process (must be at least 128) + * + * PTHREAD_STACK_MIN + * Minimum supported stack size for a thread + * + * PTHREAD_THREADS_MAX + * Maximum number of threads supported per + * process (must be at least 64). + * + * SEM_NSEMS_MAX + * The maximum number of semaphores a process can have. + * (must be at least 256) + * + * SEM_VALUE_MAX + * The maximum value a semaphore can have. + * (must be at least 32767) + * + */ +#undef _POSIX_THREAD_DESTRUCTOR_ITERATIONS +#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4 + +#undef PTHREAD_DESTRUCTOR_ITERATIONS +#define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS + +#undef _POSIX_THREAD_KEYS_MAX +#define _POSIX_THREAD_KEYS_MAX 128 + +#undef PTHREAD_KEYS_MAX +#define PTHREAD_KEYS_MAX _POSIX_THREAD_KEYS_MAX + +#undef PTHREAD_STACK_MIN +#define PTHREAD_STACK_MIN 0 + +#undef _POSIX_THREAD_THREADS_MAX +#define _POSIX_THREAD_THREADS_MAX 64 + + /* Arbitrary value */ +#undef PTHREAD_THREADS_MAX +#define PTHREAD_THREADS_MAX 2019 + +#undef _POSIX_SEM_NSEMS_MAX +#define _POSIX_SEM_NSEMS_MAX 256 + + /* Arbitrary value */ +#undef SEM_NSEMS_MAX +#define SEM_NSEMS_MAX 1024 + +#undef _POSIX_SEM_VALUE_MAX +#define _POSIX_SEM_VALUE_MAX 32767 + +#undef SEM_VALUE_MAX +#define SEM_VALUE_MAX INT_MAX + + +#if defined(__GNUC__) && !defined(__declspec) +# error Please upgrade your GNU compiler to one that supports __declspec. +#endif + +/* + * When building the library, you should define PTW32_BUILD so that + * the variables/functions are exported correctly. When using the library, + * do NOT define PTW32_BUILD, and then the variables/functions will + * be imported correctly. + */ +#if !defined(PTW32_STATIC_LIB) +# if defined(PTW32_BUILD) +# define PTW32_DLLPORT __declspec (dllexport) +# else +# define PTW32_DLLPORT __declspec (dllimport) +# endif +#else +# define PTW32_DLLPORT +#endif + +/* + * The Open Watcom C/C++ compiler uses a non-standard calling convention + * that passes function args in registers unless __cdecl is explicitly specified + * in exposed function prototypes. + * + * We force all calls to cdecl even though this could slow Watcom code down + * slightly. If you know that the Watcom compiler will be used to build both + * the DLL and application, then you can probably define this as a null string. + * Remember that pthread.h (this file) is used for both the DLL and application builds. + */ +#define PTW32_CDECL __cdecl + +#if defined(_UWIN) && PTW32_LEVEL >= PTW32_LEVEL_MAX +# include +#else +/* + * Generic handle type - intended to extend uniqueness beyond + * that available with a simple pointer. It should scale for either + * IA-32 or IA-64. + */ +typedef struct { + void * p; /* Pointer to actual object */ + unsigned int x; /* Extra information - reuse count etc */ +} ptw32_handle_t; + +typedef ptw32_handle_t pthread_t; +typedef struct pthread_attr_t_ * pthread_attr_t; +typedef struct pthread_once_t_ pthread_once_t; +typedef struct pthread_key_t_ * pthread_key_t; +typedef struct pthread_mutex_t_ * pthread_mutex_t; +typedef struct pthread_mutexattr_t_ * pthread_mutexattr_t; +typedef struct pthread_cond_t_ * pthread_cond_t; +typedef struct pthread_condattr_t_ * pthread_condattr_t; +#endif +typedef struct pthread_rwlock_t_ * pthread_rwlock_t; +typedef struct pthread_rwlockattr_t_ * pthread_rwlockattr_t; +typedef struct pthread_spinlock_t_ * pthread_spinlock_t; +typedef struct pthread_barrier_t_ * pthread_barrier_t; +typedef struct pthread_barrierattr_t_ * pthread_barrierattr_t; + +/* + * ==================== + * ==================== + * POSIX Threads + * ==================== + * ==================== + */ + +enum { +/* + * pthread_attr_{get,set}detachstate + */ + PTHREAD_CREATE_JOINABLE = 0, /* Default */ + PTHREAD_CREATE_DETACHED = 1, + +/* + * pthread_attr_{get,set}inheritsched + */ + PTHREAD_INHERIT_SCHED = 0, + PTHREAD_EXPLICIT_SCHED = 1, /* Default */ + +/* + * pthread_{get,set}scope + */ + PTHREAD_SCOPE_PROCESS = 0, + PTHREAD_SCOPE_SYSTEM = 1, /* Default */ + +/* + * pthread_setcancelstate paramters + */ + PTHREAD_CANCEL_ENABLE = 0, /* Default */ + PTHREAD_CANCEL_DISABLE = 1, + +/* + * pthread_setcanceltype parameters + */ + PTHREAD_CANCEL_ASYNCHRONOUS = 0, + PTHREAD_CANCEL_DEFERRED = 1, /* Default */ + +/* + * pthread_mutexattr_{get,set}pshared + * pthread_condattr_{get,set}pshared + */ + PTHREAD_PROCESS_PRIVATE = 0, + PTHREAD_PROCESS_SHARED = 1, + +/* + * pthread_mutexattr_{get,set}robust + */ + PTHREAD_MUTEX_STALLED = 0, /* Default */ + PTHREAD_MUTEX_ROBUST = 1, + +/* + * pthread_barrier_wait + */ + PTHREAD_BARRIER_SERIAL_THREAD = -1 +}; + +/* + * ==================== + * ==================== + * Cancelation + * ==================== + * ==================== + */ +#define PTHREAD_CANCELED ((void *)(size_t) -1) + + +/* + * ==================== + * ==================== + * Once Key + * ==================== + * ==================== + */ +#define PTHREAD_ONCE_INIT { PTW32_FALSE, 0, 0, 0} + +struct pthread_once_t_ +{ + int done; /* indicates if user function has been executed */ + void * lock; + int reserved1; + int reserved2; +}; + + +/* + * ==================== + * ==================== + * Object initialisers + * ==================== + * ==================== + */ +#define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t)(size_t) -1) +#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER ((pthread_mutex_t)(size_t) -2) +#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER ((pthread_mutex_t)(size_t) -3) + +/* + * Compatibility with LinuxThreads + */ +#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP PTHREAD_RECURSIVE_MUTEX_INITIALIZER +#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP PTHREAD_ERRORCHECK_MUTEX_INITIALIZER + +#define PTHREAD_COND_INITIALIZER ((pthread_cond_t)(size_t) -1) + +#define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t)(size_t) -1) + +#define PTHREAD_SPINLOCK_INITIALIZER ((pthread_spinlock_t)(size_t) -1) + + +/* + * Mutex types. + */ +enum +{ + /* Compatibility with LinuxThreads */ + PTHREAD_MUTEX_FAST_NP, + PTHREAD_MUTEX_RECURSIVE_NP, + PTHREAD_MUTEX_ERRORCHECK_NP, + PTHREAD_MUTEX_TIMED_NP = PTHREAD_MUTEX_FAST_NP, + PTHREAD_MUTEX_ADAPTIVE_NP = PTHREAD_MUTEX_FAST_NP, + /* For compatibility with POSIX */ + PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_FAST_NP, + PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP, + PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP, + PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL +}; + + +typedef struct ptw32_cleanup_t ptw32_cleanup_t; + +#if defined(_MSC_VER) +/* Disable MSVC 'anachronism used' warning */ +#pragma warning( disable : 4229 ) +#endif + +typedef void (* PTW32_CDECL ptw32_cleanup_callback_t)(void *); + +#if defined(_MSC_VER) +#pragma warning( default : 4229 ) +#endif + +struct ptw32_cleanup_t +{ + ptw32_cleanup_callback_t routine; + void *arg; + struct ptw32_cleanup_t *prev; +}; + +#if defined(__CLEANUP_SEH) + /* + * WIN32 SEH version of cancel cleanup. + */ + +#define pthread_cleanup_push( _rout, _arg ) \ + { \ + ptw32_cleanup_t _cleanup; \ + \ + _cleanup.routine = (ptw32_cleanup_callback_t)(_rout); \ + _cleanup.arg = (_arg); \ + __try \ + { \ + +#define pthread_cleanup_pop( _execute ) \ + } \ + __finally \ + { \ + if( _execute || AbnormalTermination()) \ + { \ + (*(_cleanup.routine))( _cleanup.arg ); \ + } \ + } \ + } + +#else /* __CLEANUP_SEH */ + +#if defined(__CLEANUP_C) + + /* + * C implementation of PThreads cancel cleanup + */ + +#define pthread_cleanup_push( _rout, _arg ) \ + { \ + ptw32_cleanup_t _cleanup; \ + \ + ptw32_push_cleanup( &_cleanup, (ptw32_cleanup_callback_t) (_rout), (_arg) ); \ + +#define pthread_cleanup_pop( _execute ) \ + (void) ptw32_pop_cleanup( _execute ); \ + } + +#else /* __CLEANUP_C */ + +#if defined(__CLEANUP_CXX) + + /* + * C++ version of cancel cleanup. + * - John E. Bossom. + */ + + class PThreadCleanup { + /* + * PThreadCleanup + * + * Purpose + * This class is a C++ helper class that is + * used to implement pthread_cleanup_push/ + * pthread_cleanup_pop. + * The destructor of this class automatically + * pops the pushed cleanup routine regardless + * of how the code exits the scope + * (i.e. such as by an exception) + */ + ptw32_cleanup_callback_t cleanUpRout; + void * obj; + int executeIt; + + public: + PThreadCleanup() : + cleanUpRout( 0 ), + obj( 0 ), + executeIt( 0 ) + /* + * No cleanup performed + */ + { + } + + PThreadCleanup( + ptw32_cleanup_callback_t routine, + void * arg ) : + cleanUpRout( routine ), + obj( arg ), + executeIt( 1 ) + /* + * Registers a cleanup routine for 'arg' + */ + { + } + + ~PThreadCleanup() + { + if ( executeIt && ((void *) cleanUpRout != (void *) 0) ) + { + (void) (*cleanUpRout)( obj ); + } + } + + void execute( int exec ) + { + executeIt = exec; + } + }; + + /* + * C++ implementation of PThreads cancel cleanup; + * This implementation takes advantage of a helper + * class who's destructor automatically calls the + * cleanup routine if we exit our scope weirdly + */ +#define pthread_cleanup_push( _rout, _arg ) \ + { \ + PThreadCleanup cleanup((ptw32_cleanup_callback_t)(_rout), \ + (void *) (_arg) ); + +#define pthread_cleanup_pop( _execute ) \ + cleanup.execute( _execute ); \ + } + +#else + +#error ERROR [__FILE__, line __LINE__]: Cleanup type undefined. + +#endif /* __CLEANUP_CXX */ + +#endif /* __CLEANUP_C */ + +#endif /* __CLEANUP_SEH */ + +/* + * =============== + * =============== + * Methods + * =============== + * =============== + */ + +/* + * PThread Attribute Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_attr_init (pthread_attr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_destroy (pthread_attr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getdetachstate (const pthread_attr_t * attr, + int *detachstate); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstackaddr (const pthread_attr_t * attr, + void **stackaddr); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstacksize (const pthread_attr_t * attr, + size_t * stacksize); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setdetachstate (pthread_attr_t * attr, + int detachstate); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstackaddr (pthread_attr_t * attr, + void *stackaddr); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstacksize (pthread_attr_t * attr, + size_t stacksize); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedparam (const pthread_attr_t *attr, + struct sched_param *param); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedparam (pthread_attr_t *attr, + const struct sched_param *param); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedpolicy (pthread_attr_t *, + int); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedpolicy (const pthread_attr_t *, + int *); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setinheritsched(pthread_attr_t * attr, + int inheritsched); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getinheritsched(const pthread_attr_t * attr, + int * inheritsched); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setscope (pthread_attr_t *, + int); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getscope (const pthread_attr_t *, + int *); + +/* + * PThread Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_create (pthread_t * tid, + const pthread_attr_t * attr, + void *(PTW32_CDECL *start) (void *), + void *arg); + +PTW32_DLLPORT int PTW32_CDECL pthread_detach (pthread_t tid); + +PTW32_DLLPORT int PTW32_CDECL pthread_equal (pthread_t t1, + pthread_t t2); + +PTW32_DLLPORT void PTW32_CDECL pthread_exit (void *value_ptr); + +PTW32_DLLPORT int PTW32_CDECL pthread_join (pthread_t thread, + void **value_ptr); + +PTW32_DLLPORT pthread_t PTW32_CDECL pthread_self (void); + +PTW32_DLLPORT int PTW32_CDECL pthread_cancel (pthread_t thread); + +PTW32_DLLPORT int PTW32_CDECL pthread_setcancelstate (int state, + int *oldstate); + +PTW32_DLLPORT int PTW32_CDECL pthread_setcanceltype (int type, + int *oldtype); + +PTW32_DLLPORT void PTW32_CDECL pthread_testcancel (void); + +PTW32_DLLPORT int PTW32_CDECL pthread_once (pthread_once_t * once_control, + void (PTW32_CDECL *init_routine) (void)); + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX +PTW32_DLLPORT ptw32_cleanup_t * PTW32_CDECL ptw32_pop_cleanup (int execute); + +PTW32_DLLPORT void PTW32_CDECL ptw32_push_cleanup (ptw32_cleanup_t * cleanup, + ptw32_cleanup_callback_t routine, + void *arg); +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +/* + * Thread Specific Data Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_key_create (pthread_key_t * key, + void (PTW32_CDECL *destructor) (void *)); + +PTW32_DLLPORT int PTW32_CDECL pthread_key_delete (pthread_key_t key); + +PTW32_DLLPORT int PTW32_CDECL pthread_setspecific (pthread_key_t key, + const void *value); + +PTW32_DLLPORT void * PTW32_CDECL pthread_getspecific (pthread_key_t key); + + +/* + * Mutex Attribute Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_init (pthread_mutexattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_destroy (pthread_mutexattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getpshared (const pthread_mutexattr_t + * attr, + int *pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setpshared (pthread_mutexattr_t * attr, + int pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_settype (pthread_mutexattr_t * attr, int kind); +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_gettype (const pthread_mutexattr_t * attr, int *kind); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setrobust( + pthread_mutexattr_t *attr, + int robust); +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getrobust( + const pthread_mutexattr_t * attr, + int * robust); + +/* + * Barrier Attribute Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_init (pthread_barrierattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_destroy (pthread_barrierattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_getpshared (const pthread_barrierattr_t + * attr, + int *pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_setpshared (pthread_barrierattr_t * attr, + int pshared); + +/* + * Mutex Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_init (pthread_mutex_t * mutex, + const pthread_mutexattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_destroy (pthread_mutex_t * mutex); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_lock (pthread_mutex_t * mutex); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_timedlock(pthread_mutex_t * mutex, + const struct timespec *abstime); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_trylock (pthread_mutex_t * mutex); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_unlock (pthread_mutex_t * mutex); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_consistent (pthread_mutex_t * mutex); + +/* + * Spinlock Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_spin_init (pthread_spinlock_t * lock, int pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_spin_destroy (pthread_spinlock_t * lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_spin_lock (pthread_spinlock_t * lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_spin_trylock (pthread_spinlock_t * lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_spin_unlock (pthread_spinlock_t * lock); + +/* + * Barrier Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_barrier_init (pthread_barrier_t * barrier, + const pthread_barrierattr_t * attr, + unsigned int count); + +PTW32_DLLPORT int PTW32_CDECL pthread_barrier_destroy (pthread_barrier_t * barrier); + +PTW32_DLLPORT int PTW32_CDECL pthread_barrier_wait (pthread_barrier_t * barrier); + +/* + * Condition Variable Attribute Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_condattr_init (pthread_condattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_condattr_destroy (pthread_condattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_condattr_getpshared (const pthread_condattr_t * attr, + int *pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_condattr_setpshared (pthread_condattr_t * attr, + int pshared); + +/* + * Condition Variable Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_cond_init (pthread_cond_t * cond, + const pthread_condattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_cond_destroy (pthread_cond_t * cond); + +PTW32_DLLPORT int PTW32_CDECL pthread_cond_wait (pthread_cond_t * cond, + pthread_mutex_t * mutex); + +PTW32_DLLPORT int PTW32_CDECL pthread_cond_timedwait (pthread_cond_t * cond, + pthread_mutex_t * mutex, + const struct timespec *abstime); + +PTW32_DLLPORT int PTW32_CDECL pthread_cond_signal (pthread_cond_t * cond); + +PTW32_DLLPORT int PTW32_CDECL pthread_cond_broadcast (pthread_cond_t * cond); + +/* + * Scheduling + */ +PTW32_DLLPORT int PTW32_CDECL pthread_setschedparam (pthread_t thread, + int policy, + const struct sched_param *param); + +PTW32_DLLPORT int PTW32_CDECL pthread_getschedparam (pthread_t thread, + int *policy, + struct sched_param *param); + +PTW32_DLLPORT int PTW32_CDECL pthread_setconcurrency (int); + +PTW32_DLLPORT int PTW32_CDECL pthread_getconcurrency (void); + +/* + * Read-Write Lock Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_init(pthread_rwlock_t *lock, + const pthread_rwlockattr_t *attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_destroy(pthread_rwlock_t *lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_tryrdlock(pthread_rwlock_t *); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_trywrlock(pthread_rwlock_t *); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_rdlock(pthread_rwlock_t *lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedrdlock(pthread_rwlock_t *lock, + const struct timespec *abstime); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_wrlock(pthread_rwlock_t *lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedwrlock(pthread_rwlock_t *lock, + const struct timespec *abstime); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_unlock(pthread_rwlock_t *lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_init (pthread_rwlockattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_destroy (pthread_rwlockattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_getpshared (const pthread_rwlockattr_t * attr, + int *pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_setpshared (pthread_rwlockattr_t * attr, + int pshared); + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 + +/* + * Signal Functions. Should be defined in but MSVC and MinGW32 + * already have signal.h that don't define these. + */ +PTW32_DLLPORT int PTW32_CDECL pthread_kill(pthread_t thread, int sig); + +/* + * Non-portable functions + */ + +/* + * Compatibility with Linux. + */ +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setkind_np(pthread_mutexattr_t * attr, + int kind); +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getkind_np(pthread_mutexattr_t * attr, + int *kind); + +/* + * Possibly supported by other POSIX threads implementations + */ +PTW32_DLLPORT int PTW32_CDECL pthread_delay_np (struct timespec * interval); +PTW32_DLLPORT int PTW32_CDECL pthread_num_processors_np(void); +PTW32_DLLPORT unsigned __int64 PTW32_CDECL pthread_getunique_np(pthread_t thread); + +/* + * Useful if an application wants to statically link + * the lib rather than load the DLL at run-time. + */ +PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_attach_np(void); +PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_detach_np(void); +PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_attach_np(void); +PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_detach_np(void); + +/* + * Features that are auto-detected at load/run time. + */ +PTW32_DLLPORT int PTW32_CDECL pthread_win32_test_features_np(int); +enum ptw32_features { + PTW32_SYSTEM_INTERLOCKED_COMPARE_EXCHANGE = 0x0001, /* System provides it. */ + PTW32_ALERTABLE_ASYNC_CANCEL = 0x0002 /* Can cancel blocked threads. */ +}; + +/* + * Register a system time change with the library. + * Causes the library to perform various functions + * in response to the change. Should be called whenever + * the application's top level window receives a + * WM_TIMECHANGE message. It can be passed directly to + * pthread_create() as a new thread if desired. + */ +PTW32_DLLPORT void * PTW32_CDECL pthread_timechange_handler_np(void *); + +#endif /*PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 */ + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX + +/* + * Returns the Win32 HANDLE for the POSIX thread. + */ +PTW32_DLLPORT HANDLE PTW32_CDECL pthread_getw32threadhandle_np(pthread_t thread); +/* + * Returns the win32 thread ID for POSIX thread. + */ +PTW32_DLLPORT DWORD PTW32_CDECL pthread_getw32threadid_np (pthread_t thread); + + +/* + * Protected Methods + * + * This function blocks until the given WIN32 handle + * is signaled or pthread_cancel had been called. + * This function allows the caller to hook into the + * PThreads cancel mechanism. It is implemented using + * + * WaitForMultipleObjects + * + * on 'waitHandle' and a manually reset WIN32 Event + * used to implement pthread_cancel. The 'timeout' + * argument to TimedWait is simply passed to + * WaitForMultipleObjects. + */ +PTW32_DLLPORT int PTW32_CDECL pthreadCancelableWait (HANDLE waitHandle); +PTW32_DLLPORT int PTW32_CDECL pthreadCancelableTimedWait (HANDLE waitHandle, + DWORD timeout); + +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +/* + * Thread-Safe C Runtime Library Mappings. + */ +#if !defined(_UWIN) +# if defined(NEED_ERRNO) + PTW32_DLLPORT int * PTW32_CDECL _errno( void ); +# else +# if !defined(errno) +# if (defined(_MT) || defined(_DLL)) + __declspec(dllimport) extern int * __cdecl _errno(void); +# define errno (*_errno()) +# endif +# endif +# endif +#endif + +/* + * Some compiler environments don't define some things. + */ +#if defined(__BORLANDC__) +# define _ftime ftime +# define _timeb timeb +#endif + +#if defined(__cplusplus) + +/* + * Internal exceptions + */ +class ptw32_exception {}; +class ptw32_exception_cancel : public ptw32_exception {}; +class ptw32_exception_exit : public ptw32_exception {}; + +#endif + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX + +/* FIXME: This is only required if the library was built using SEH */ +/* + * Get internal SEH tag + */ +PTW32_DLLPORT DWORD PTW32_CDECL ptw32_get_exception_services_code(void); + +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +#if !defined(PTW32_BUILD) + +#if defined(__CLEANUP_SEH) + +/* + * Redefine the SEH __except keyword to ensure that applications + * propagate our internal exceptions up to the library's internal handlers. + */ +#define __except( E ) \ + __except( ( GetExceptionCode() == ptw32_get_exception_services_code() ) \ + ? EXCEPTION_CONTINUE_SEARCH : ( E ) ) + +#endif /* __CLEANUP_SEH */ + +#if defined(__CLEANUP_CXX) + +/* + * Redefine the C++ catch keyword to ensure that applications + * propagate our internal exceptions up to the library's internal handlers. + */ +#if defined(_MSC_VER) + /* + * WARNING: Replace any 'catch( ... )' with 'PtW32CatchAll' + * if you want Pthread-Win32 cancelation and pthread_exit to work. + */ + +#if !defined(PtW32NoCatchWarn) + +#pragma message("Specify \"/DPtW32NoCatchWarn\" compiler flag to skip this message.") +#pragma message("------------------------------------------------------------------") +#pragma message("When compiling applications with MSVC++ and C++ exception handling:") +#pragma message(" Replace any 'catch( ... )' in routines called from POSIX threads") +#pragma message(" with 'PtW32CatchAll' or 'CATCHALL' if you want POSIX thread") +#pragma message(" cancelation and pthread_exit to work. For example:") +#pragma message("") +#pragma message(" #if defined(PtW32CatchAll)") +#pragma message(" PtW32CatchAll") +#pragma message(" #else") +#pragma message(" catch(...)") +#pragma message(" #endif") +#pragma message(" {") +#pragma message(" /* Catchall block processing */") +#pragma message(" }") +#pragma message("------------------------------------------------------------------") + +#endif + +#define PtW32CatchAll \ + catch( ptw32_exception & ) { throw; } \ + catch( ... ) + +#else /* _MSC_VER */ + +#define catch( E ) \ + catch( ptw32_exception & ) { throw; } \ + catch( E ) + +#endif /* _MSC_VER */ + +#endif /* __CLEANUP_CXX */ + +#endif /* ! PTW32_BUILD */ + +#if defined(__cplusplus) +} /* End of extern "C" */ +#endif /* __cplusplus */ + +#if defined(PTW32__HANDLE_DEF) +# undef HANDLE +#endif +#if defined(PTW32__DWORD_DEF) +# undef DWORD +#endif + +#undef PTW32_LEVEL +#undef PTW32_LEVEL_MAX + +#endif /* ! RC_INVOKED */ + +#endif /* PTHREAD_H */ diff --git a/win/pthreadGC2.dll b/OSlibs/win/pthreadGC2.dll similarity index 100% rename from win/pthreadGC2.dll rename to OSlibs/win/pthreadGC2.dll diff --git a/win/pthreadGC2_64.dll b/OSlibs/win/pthreadGC2_64.dll similarity index 100% rename from win/pthreadGC2_64.dll rename to OSlibs/win/pthreadGC2_64.dll diff --git a/win/sched.h b/OSlibs/win/sched.h similarity index 100% rename from win/sched.h rename to OSlibs/win/sched.h diff --git a/win/semaphore.h b/OSlibs/win/semaphore.h similarity index 100% rename from win/semaphore.h rename to OSlibs/win/semaphore.h diff --git a/OSlibs/win/x64/libpthreadGC2.a b/OSlibs/win/x64/libpthreadGC2.a new file mode 100644 index 000000000..96f31306b Binary files /dev/null and b/OSlibs/win/x64/libpthreadGC2.a differ diff --git a/README.md b/README.md index 4c1fe8141..98dda7232 100755 --- a/README.md +++ b/README.md @@ -1,8 +1,30 @@ #SuperNET Client "iguana" +OS | Build Status +-------------|------ +Unix (Ubuntu 14.04) | [![Build Status](https://jenkinsmaster.sprnt.pw/buildStatus/icon?job=Unix-jl777)](https://jenkinsmaster.sprnt.pw/job/Unix-jl777) +Chrome | [![Build Status](https://jenkinsmaster.sprnt.pw/buildStatus/icon?job=PNaCl-jl777)](https://jenkinsmaster.sprnt.pw/job/PNaCl-jl777/) +Android | [![Build Status](https://jenkinsmaster.sprnt.pw/buildStatus/icon?job=Android)](https://jenkinsmaster.sprnt.pw/job/Android/) +iOS | [![Build Status](https://jenkinsmaster.sprnt.pw/buildStatus/icon?job=iOS)](https://jenkinsmaster.sprnt.pw/job/iOS/) +Windows 32 Bit | [![Build Status](https://jenkinsmaster.sprnt.pw/job/Win32/badge/icon)](https://jenkinsmaster.sprnt.pw/job/Win32/) +Windows 64 Bit | [![Build Status](https://jenkinsmaster.sprnt.pw/job/Win64-jl777/badge/icon)](https://jenkinsmaster.sprnt.pw/job/Win64-jl777/) +docs.supernet.org | [![Build Status](https://jenkinsmaster.sprnt.pw/buildStatus/icon?job=docs.supernet.org-updating)](https://jenkinsmaster.sprnt.pw/job/docs.supernet.org-updating/) + +--- + +Codebase is going under radical changes now and versions from mid-May should be used unless you are doing advanced testing. There will be four layers: + +gecko: abstracted bitcoin compatible blockchains that run via basilisk lite mode or as iguana core full network peers. I will try to get a geckochain to simultaneously have both virtual basilisk nodes and private iguana nodes, but at first will probably need to choose which mode a new chain will be and transition between the two via special suspend and resume functions that allow migration from virtual to physical. Each specific geckochain will be able to be enhanced into a datachain. + +basilisk: abstracted crypto transactions layer, which has a reference implementation for bitcoin protocol via the iguana nodes, but can be expanded to support any coin protocol that can support the required functions. Since it works with bitcoin protocol, any 2.0 coin with at least bitcoin level functionality should be able to create a basilisk interface. + +iguana: most efficient bitcoin core implementation that can simultaneously be full peers for multiple bitcoin blockchains. Special support being added to virtualize blockchains so all can share the same peers. The iguana peers identify as a supernet node, regardless of which coin, so by having nodes that support multiple coins, supernet peers are propagated across all coins. non-iguana peers wont get any non-standard packets so it is interoperable with all the existing bitcoin and bitcoin clone networks + +komodo: this is the top secret project I cant talk about publicly yet + > #TL;DR# > -> ```sudo apt-get update; sudo apt-get git install build-essential; git clone https://github.com/jl777/SuperNET; cd SuperNET; ./m_onetime m_unix;``` +> ```sudo apt-get update; sudo apt-get install git build-essential; git clone https://github.com/jl777/SuperNET; cd SuperNET; ./m_onetime m_unix;``` > > The above one line gets SuperNET installed, built and launched for unix. > @@ -13,12 +35,6 @@ *** all external dependencies have been removed, except for -lpthread and -lm -#DEPENDENCIES# -##for native (unix, osx)## -Just make sure you have the dev versions of openssl and curl installed: - -```sudo apt-get install libcurl4-gnutls-dev libssl-dev``` - ##For native (win32, win64)## TOOL_DIR := /usr/local/gcc-4.8.0-qt-4.8.4-for-mingw32/win32-gcc/bin MINGW := i586-mingw32 @@ -26,7 +42,7 @@ The above two definitions need to be changed to match the mingw install on your ##For chrome app## You need to make sure the nacl sdk is properly installed and you are able to build the examples. -Now you will need to get the external libs, which can be built from scratch using naclports or there use the reference builds of libssl.a, libcrypto.a, libcurl.a and libz.a in the SuperNET/crypto777/pnacl_libs. You can just copy those over into $(NACL_SDK_ROOT)//lib/pnacl. +Now you will need to get the external libs, which can be built from scratch using naclports or there use the reference builds of libcurl.a and libz.a in the SuperNET/crypto777/pnacl_libs. You can just copy those over into $(NACL_SDK_ROOT)//lib/pnacl. #ONETIME# @@ -130,7 +146,7 @@ During the syncing, I have many, many messages like this: >> cant create.(tmp/BTC/252000/.tmpmarker) errno.24 Too many open files >> cant create.(tmp/BTC/18000/.tmpmarker) errno.24 Too many open files >> -Loretta:/Users/volker/SuperNET # ulimit -n 2048 +Loretta:/Users/volker/SuperNET # ulimit -n 100000 ##### tests diff --git a/SuperNET/SuperNET.c b/SuperNET/SuperNET.c deleted file mode 100755 index 5f807e552..000000000 --- a/SuperNET/SuperNET.c +++ /dev/null @@ -1,736 +0,0 @@ -/****************************************************************************** - * Copyright © 2014-2015 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - -#include "SuperNET.h" -#define IGUANA_FORMS "[ \ -\ -{\"disp\":\"simple explorer\",\"agent\":\"ramchain\",\"method\":\"explore\",\"fields\":[{\"skip\":1,\"field\":\"search\",\"cols\":65,\"rows\":1}]}, \ -{\"disp\":\"block height\",\"agent\":\"ramchain\",\"method\":\"block\",\"fields\":[{\"field\":\"height\",\"cols\":10,\"rows\":1}]}, \ -{\"disp\":\"block hash\",\"agent\":\"ramchain\",\"method\":\"block\",\"fields\":[{\"field\":\"hash\",\"cols\":65,\"rows\":1}]}, \ -{\"disp\":\"txid\",\"agent\":\"ramchain\",\"method\":\"txid\",\"fields\":[{\"skip\":1,\"field\":\"hash\",\"cols\":65,\"rows\":1}]}, \ -{\"disp\":\"status\",\"agent\":\"ramchain\",\"method\":\"status\",\"fields\":[{\"skip\":1,\"field\":\"coin\",\"cols\":1,\"rows\":1}]}, \ -{\"disp\":\"bundleinfo\",\"agent\":\"ramchain\",\"method\":\"bundleinfo\",\"fields\":[{\"skip\":1,\"field\":\"height\",\"cols\":12,\"rows\":1}]}, \ -\ -{\"disp\":\"addcoin\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"fields\":[{\"skip\":1,\"field\":\"coin\",\"cols\":8,\"rows\":1}]}, \ -{\"disp\":\"pausecoin\",\"agent\":\"iguana\",\"method\":\"pausecoin\",\"fields\":[{\"skip\":1,\"field\":\"coin\",\"cols\":1,\"rows\":1}]}, \ -{\"disp\":\"startcoin\",\"agent\":\"iguana\",\"method\":\"startcoin\",\"fields\":[{\"skip\":1,\"field\":\"coin\",\"cols\":1,\"rows\":1}]}, \ -{\"disp\":\"addnode\",\"agent\":\"iguana\",\"method\":\"addnode\",\"fields\":[{\"skip\":1,\"field\":\"ipaddr\",\"cols\":32,\"rows\":1}]}, \ -{\"disp\":\"maxpeers\",\"agent\":\"iguana\",\"method\":\"maxpeers\",\"fields\":[{\"skip\":1,\"field\":\"max\",\"cols\":8,\"rows\":1}]}, \ -{\"disp\":\"peers\",\"agent\":\"iguana\",\"method\":\"peers\",\"fields\":[{\"field\":\"coin\",\"cols\":16,\"rows\":1}]}, \ -{\"disp\":\"nodestatus\",\"agent\":\"iguana\",\"method\":\"nodestatus\",\"fields\":[{\"skip\":1,\"field\":\"ipaddr\",\"cols\":32,\"rows\":1}]}, \ -\ -{\"disp\":\"rates\",\"agent\":\"PAX\",\"method\":\"rates\",\"fields\":[{\"skip\":1,\"field\":\"peg\",\"cols\":16,\"rows\":1}]},\ -{\"disp\":\"prices\",\"agent\":\"PAX\",\"method\":\"prices\",\"fields\":[{\"skip\":1,\"field\":\"peg\",\"cols\":16,\"rows\":1}]},\ -{\"agent\":\"PAX\",\"method\":\"lock\",\"fields\":[{\"skip\":1,\"field\":\"peg\",\"cols\":16,\"rows\":1},{\"skip\":1,\"field\":\"lockdays\",\"cols\":6,\"rows\":1},{\"skip\":1,\"field\":\"units\",\"cols\":12,\"rows\":1}]}, \ -{\"agent\":\"PAX\",\"method\":\"redeem\",\"fields\":[{\"skip\":1,\"field\":\"txid\",\"cols\":65,\"rows\":1},{\"skip\":1,\"field\":\"dest\",\"cols\":65,\"rows\":1}]},\ -{\"disp\":\"balance\",\"agent\":\"PAX\",\"method\":\"balance\",\"fields\":[{\"skip\":1,\"field\":\"address\",\"cols\":44,\"rows\":1}]},\ -{\"agent\":\"PAX\",\"method\":\"rollover\",\"fields\":[{\"skip\":1,\"field\":\"txid\",\"cols\":16,\"rows\":1},{\"skip\":1,\"field\":\"newpeg\",\"cols\":16,\"rows\":1},{\"skip\":1,\"field\":\"newlockdays\",\"cols\":6,\"rows\":1}]},\ -{\"agent\":\"PAX\",\"method\":\"swap\",\"fields\":[{\"skip\":1,\"field\":\"txid\",\"cols\":16,\"rows\":1},{\"skip\":1,\"field\":\"othertxid\",\"cols\":16,\"rows\":1}]},\ -{\"agent\":\"PAX\",\"method\":\"bet\",\"fields\":[{\"skip\":1,\"field\":\"peg\",\"cols\":16,\"rows\":1},{\"skip\":1,\"field\":\"price\",\"cols\":16,\"rows\":1},{\"skip\":1,\"field\":\"amount\",\"cols\":16,\"rows\":1}]},\ -\ -{\"agent\":\"InstantDEX\",\"method\":\"placebid\",\"fields\":[{\"skip\":1,\"field\":\"base\",\"cols\":8,\"rows\":1},{\"skip\":1,\"field\":\"rel\",\"cols\":8,\"rows\":1},{\"skip\":1,\"field\":\"exchange\",\"cols\":16,\"rows\":1},{\"field\":\"price\",\"cols\":16,\"rows\":1},{\"field\":\"volume\",\"cols\":16,\"rows\":1}]}, \ -{\"agent\":\"InstantDEX\",\"method\":\"placeask\",\"fields\":[{\"skip\":1,\"field\":\"base\",\"cols\":8,\"rows\":1},{\"skip\":1,\"field\":\"rel\",\"cols\":8,\"rows\":1},{\"skip\":1,\"field\":\"exchange\",\"cols\":16,\"rows\":1},{\"field\":\"price\",\"cols\":16,\"rows\":1},{\"field\":\"volume\",\"cols\":16,\"rows\":1}]}, \ -{\"agent\":\"InstantDEX\",\"method\":\"orderbook\",\"fields\":[{\"skip\":1,\"field\":\"base\",\"cols\":8,\"rows\":1},{\"skip\":1,\"field\":\"rel\",\"cols\":8,\"rows\":1},{\"skip\":1,\"field\":\"exchange\",\"cols\":16,\"rows\":1}]}, \ -{\"disp\":\"orderstatus\",\"agent\":\"InstantDEX\",\"method\":\"orderstatus\",\"fields\":[{\"skip\":1,\"field\":\"orderid\",\"cols\":32,\"rows\":1}]}, \ -{\"disp\":\"cancelorder\",\"agent\":\"InstantDEX\",\"method\":\"cancelorder\",\"fields\":[{\"skip\":1,\"field\":\"orderid\",\"cols\":32,\"rows\":1}]}, \ -{\"disp\":\"balance\",\"agent\":\"InstantDEX\",\"method\":\"balance\",\"fields\":[{\"skip\":1,\"field\":\"exchange\",\"cols\":16,\"rows\":1}]}, \ -{\"newline\":0,\"disp\":\"allorderbooks\",\"agent\":\"InstantDEX\",\"method\":\"allorderbooks\",\"fields\":[{\"skip\":1,\"field\":\"allorderbooks\",\"cols\":1,\"rows\":1}]}, \ -{\"newline\":0,\"disp\":\"openorders\",\"agent\":\"InstantDEX\",\"method\":\"openorders\",\"fields\":[{\"skip\":1,\"field\":\"openorders\",\"cols\":1,\"rows\":1}]}, \ -{\"newline\":0,\"disp\":\"tradehistory\",\"agent\":\"InstantDEX\",\"method\":\"tradehistory\",\"fields\":[{\"skip\":1,\"field\":\"tradehistory\",\"cols\":1,\"rows\":1}]}, \ -{\"disp\":\"allexchanges\",\"agent\":\"InstantDEX\",\"method\":\"allexchanges\",\"fields\":[{\"skip\":1,\"field\":\"allexchanges\",\"cols\":1,\"rows\":1}]}, \ -\ -{\"agent\":\"pangea\",\"method\":\"bet\",\"fields\":[{\"skip\":1,\"field\":\"tableid\",\"cols\":24,\"rows\":1},{\"skip\":1,\"field\":\"amount\",\"cols\":24,\"rows\":1}]}, \ -{\"disp\":\"call\",\"agent\":\"pangea\",\"method\":\"call\",\"fields\":[{\"skip\":1,\"field\":\"tableid\",\"cols\":1,\"rows\":1}]}, \ -{\"disp\":\"fold\",\"agent\":\"pangea\",\"method\":\"fold\",\"fields\":[{\"skip\":1,\"field\":\"tableid\",\"cols\":1,\"rows\":1}]}, \ -{\"disp\":\"status\",\"agent\":\"pangea\",\"method\":\"status\",\"fields\":[{\"skip\":1,\"field\":\"tableid\",\"cols\":1,\"rows\":1}]}, \ -{\"disp\":\"hand history\",\"agent\":\"pangea\",\"method\":\"handhistory\",\"fields\":[{\"skip\":1,\"field\":\"tableid\",\"cols\":1,\"rows\":1}]}, \ -{\"disp\":\"history\",\"agent\":\"pangea\",\"method\":\"history\",\"fields\":[{\"skip\":1,\"field\":\"coin\",\"cols\":1,\"rows\":1}]}, \ -{\"disp\":\"follow\",\"agent\":\"pangea\",\"method\":\"follow\",\"fields\":[{\"skip\":1,\"field\":\"tableid\",\"cols\":24,\"rows\":1}]}, \ -{\"disp\":\"lobby\",\"agent\":\"pangea\",\"method\":\"lobby\",\"fields\":[{\"skip\":1,\"field\":\"coin\",\"cols\":8,\"rows\":1}]}, \ -{\"disp\":\"join\",\"agent\":\"pangea\",\"method\":\"join\",\"fields\":[{\"skip\":1,\"field\":\"tableid\",\"cols\":24,\"rows\":1}]}, \ -{\"agent\":\"pangea\",\"method\":\"buyin\",\"fields\":[{\"skip\":1,\"field\":\"coin\",\"cols\":8,\"rows\":1},{\"skip\":1,\"field\":\"tableid\",\"cols\":24,\"rows\":1},{\"skip\":1,\"field\":\"amount\",\"cols\":12,\"rows\":1}]}, \ -{\"agent\":\"pangea\",\"method\":\"newtournament\",\"fields\":[{\"field\":\"mintables\",\"cols\":8,\"rows\":1},{\"field\":\"maxtables\",\"cols\":4,\"rows\":1},{\"field\":\"starttime\",\"cols\":16,\"rows\":1},{\"field\":\"prizefund\",\"cols\":12,\"rows\":1},{\"field\":\"coin\",\"cols\":12,\"rows\":1}]}, \ -{\"agent\":\"pangea\",\"method\":\"newtable\",\"fields\":[{\"field\":\"minplayers\",\"cols\":4,\"rows\":1},{\"field\":\"maxplayers\",\"cols\":4,\"rows\":1},{\"field\":\"rake\",\"cols\":4,\"rows\":1},{\"field\":\"bigblind\",\"cols\":12,\"rows\":1},{\"field\":\"ante\",\"cols\":12,\"rows\":1},{\"field\":\"minbuyin\",\"cols\":12,\"rows\":1},{\"field\":\"maxbuyin\",\"cols\":12,\"rows\":1}]}, \ -{\"disp\":\"leave\",\"agent\":\"pangea\",\"method\":\"leave\",\"fields\":[{\"skip\":1,\"field\":\"tableid\",\"cols\":8,\"rows\":1}]}, \ -\ -{\"agent\":\"jumblr\",\"method\":\"send\",\"fields\":[{\"skip\":1,\"field\":\"coin\",\"cols\":8,\"rows\":1},{\"skip\":1,\"field\":\"amount\",\"cols\":13,\"rows\":1},{\"skip\":1,\"field\":\"address\",\"cols\":8,\"rows\":1}]}, \ -{\"agent\":\"jumblr\",\"method\":\"invoice\",\"fields\":[{\"skip\":1,\"field\":\"coin\",\"cols\":8,\"rows\":1},{\"skip\":1,\"field\":\"amount\",\"cols\":13,\"rows\":1},{\"skip\":1,\"field\":\"address\",\"cols\":8,\"rows\":1}]}, \ -{\"agent\":\"jumblr\",\"method\":\"shuffle\",\"fields\":[{\"skip\":1,\"field\":\"coin\",\"cols\":8,\"rows\":1},{\"skip\":1,\"field\":\"amount\",\"cols\":13,\"rows\":1}]}, \ -{\"agent\":\"jumblr\",\"method\":\"balance\",\"fields\":[{\"skip\":1,\"field\":\"coin\",\"cols\":8,\"rows\":1},{\"skip\":1,\"field\":\"address\",\"cols\":13,\"rows\":1}]}, \ -\ -{\"newline\":0,\"disp\":\"InstantDEX\",\"agent\":\"iguana\",\"method\":\"setagent\",\"fields\":[{\"field\":\"InstantDEX\",\"cols\":1,\"rows\":1}]}, \ -{\"newline\":0,\"disp\":\"PAX\",\"agent\":\"iguana\",\"method\":\"setagent\",\"fields\":[{\"field\":\"PAX\",\"cols\":1,\"rows\":1}]}, \ -{\"newline\":0,\"disp\":\"pangea\",\"agent\":\"iguana\",\"method\":\"setagent\",\"fields\":[{\"field\":\"pangea\",\"cols\":1,\"rows\":1}]}, \ -{\"newline\":0,\"disp\":\"jumblr\",\"agent\":\"iguana\",\"method\":\"setagent\",\"fields\":[{\"field\":\"jumblr\",\"cols\":1,\"rows\":1}]}, \ -{\"disp\":\"ramchain\",\"agent\":\"iguana\",\"method\":\"setagent\",\"fields\":[{\"field\":\"ramchain\",\"cols\":1,\"rows\":1}]}, \ -{\"newline\":0,\"disp\":\"iguana\",\"agent\":\"iguana\",\"method\":\"setagent\",\"fields\":[{\"field\":\"iguana\",\"cols\":1,\"rows\":1}]}, \ -\ -{\"agent\":\"hash\",\"method\":\"NXT\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":100,\"rows\":1}]}, \ -{\"agent\":\"hash\",\"method\":\"curve25519\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ -{\"agent\":\"hash\",\"method\":\"rmd160_sha256\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ -{\"agent\":\"hash\",\"method\":\"sha256_sha256\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ -{\"agent\":\"hash\",\"method\":\"base64_encode\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ -{\"agent\":\"hash\",\"method\":\"base64_decode\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ -{\"agent\":\"hash\",\"method\":\"crc32\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ -{\"agent\":\"hash\",\"method\":\"sha512\",\"fields\":[{\"skip\":1,\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ -{\"agent\":\"hash\",\"method\":\"sha384\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ -{\"agent\":\"hash\",\"method\":\"sha256\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ -{\"agent\":\"hash\",\"method\":\"sha224\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ -{\"agent\":\"hash\",\"method\":\"rmd320\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ -{\"agent\":\"hash\",\"method\":\"rmd256\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ -{\"agent\":\"hash\",\"method\":\"rmd160\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ -{\"agent\":\"hash\",\"method\":\"rmd128\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ -{\"agent\":\"hash\",\"method\":\"sha1\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ -{\"agent\":\"hash\",\"method\":\"md2\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ -{\"agent\":\"hash\",\"method\":\"md4\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ -{\"agent\":\"hash\",\"method\":\"md5\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ -{\"agent\":\"hash\",\"method\":\"tiger\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ -{\"agent\":\"hash\",\"method\":\"whirlpool\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ -{\"agent\":\"hash\",\"method\":\"hmac_sha512\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ -{\"agent\":\"hash\",\"method\":\"hmac_sha384\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ -{\"agent\":\"hash\",\"method\":\"hmac_sha256\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ -{\"agent\":\"hash\",\"method\":\"hmac_sha224\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ -{\"agent\":\"hash\",\"method\":\"hmac_rmd320\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ -{\"agent\":\"hash\",\"method\":\"hmac_rmd256\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ -{\"agent\":\"hash\",\"method\":\"hmac_rmd160\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ -{\"agent\":\"hash\",\"method\":\"hmac_rmd128\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ -{\"agent\":\"hash\",\"method\":\"hmac_sha1\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ -{\"agent\":\"hash\",\"method\":\"hmac_md2\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ -{\"agent\":\"hash\",\"method\":\"hmac_md4\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ -{\"agent\":\"hash\",\"method\":\"hmac_md5\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ -{\"agent\":\"hash\",\"method\":\"hmac_tiger\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ -{\"agent\":\"hash\",\"method\":\"hmac_whirlpool\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}\ -]" - -char *HTMLheader = -" \ - \ - \ - \ - \ -iguana \ - \ - \ -\ - \ -"; - -// Link - -char *HTMLfooter = -" \ -\ - \ - \ -\ - \ - \ - \ - \ - \ - \ - \ -\ - \ -"; - -#define HTML_EMIT(str) if ( (str) != 0 && (str)[0] != 0 ) strcpy(&retbuf[size],str), size += (int32_t)strlen(str) - -/* -struct endpoint find_epbits(struct relay_info *list,uint32_t ipbits,uint16_t port,int32_t type) -{ - int32_t i; struct endpoint epbits; - memset(&epbits,0,sizeof(epbits)); - if ( list != 0 && list->num > 0 ) - { - if ( type >= 0 ) - type = nn_portoffset(type); - for (i=0; inum&&i<(int32_t)(sizeof(list->connections)/sizeof(*list->connections)); i++) - if ( list->connections[i].ipbits == ipbits && (port == 0 || port == list->connections[i].port) && (type < 0 || type == list->connections[i].nn) ) - return(list->connections[i]); - } - return(epbits); -} - -int32_t add_relay(struct relay_info *list,struct endpoint epbits) -{ - list->connections[list->num % (sizeof(list->connections)/sizeof(*list->connections))] = epbits, list->num++; - if ( list->num > (sizeof(list->connections)/sizeof(*list->connections)) ) - printf("add_relay warning num.%d > %ld\n",list->num,(long)(sizeof(list->connections)/sizeof(*list->connections))); - return(list->num); -} - -int32_t nn_add_lbservers(struct supernet_info *myinfo,uint16_t port,uint16_t globalport,uint16_t relaysport,int32_t priority,int32_t sock,char servers[][MAX_SERVERNAME],int32_t num) -{ - int32_t i; char endpoint[512],pubendpoint[512]; struct endpoint epbits; uint32_t ipbits; - if ( num > 0 && servers != 0 && nn_setsockopt(sock,NN_SOL_SOCKET,NN_SNDPRIO,&priority,sizeof(priority)) >= 0 ) - { - for (i=0; i= 0 ) - { - printf("+R%s ",endpoint); - add_relay(&myinfo->active,epbits); - } - if ( myinfo->subclient >= 0 ) - { - if ( myinfo->iamrelay != 0 ) - { - epbits = calc_epbits("tcp",ipbits,relaysport,NN_PUB); - expand_epbits(pubendpoint,epbits); - if ( nn_connect(myinfo->subclient,pubendpoint) >= 0 ) - printf("+P%s ",pubendpoint); - } - epbits = calc_epbits("tcp",ipbits,globalport,NN_PUB); - expand_epbits(pubendpoint,epbits); - if ( nn_connect(myinfo->subclient,pubendpoint) >= 0 ) - printf("+P%s ",pubendpoint); - } - } - } - printf("added priority.%d\n",priority); - priority++; - } else printf("error setting priority.%d (%s)\n",priority,nn_errstr()); - return(priority); -} - -int32_t _lb_socket(struct supernet_info *myinfo,uint16_t port,uint16_t globalport,uint16_t relaysport,int32_t maxmillis,char servers[][MAX_SERVERNAME],int32_t num,char backups[][MAX_SERVERNAME],int32_t numbacks,char failsafes[][MAX_SERVERNAME],int32_t numfailsafes) -{ - int32_t lbsock,timeout,retrymillis,priority = 1; - if ( (lbsock= nn_socket(AF_SP,NN_REQ)) >= 0 ) - { - retrymillis = (maxmillis / 30) + 1; - printf("!!!!!!!!!!!! lbsock.%d !!!!!!!!!!!\n",lbsock); - if ( nn_setsockopt(lbsock,NN_SOL_SOCKET,NN_RECONNECT_IVL,&retrymillis,sizeof(retrymillis)) < 0 ) - printf("error setting NN_REQ NN_RECONNECT_IVL_MAX socket %s\n",nn_errstr()); - else if ( nn_setsockopt(lbsock,NN_SOL_SOCKET,NN_RECONNECT_IVL_MAX,&maxmillis,sizeof(maxmillis)) < 0 ) - fprintf(stderr,"error setting NN_REQ NN_RECONNECT_IVL_MAX socket %s\n",nn_errstr()); - timeout = SUPERNET_NETWORKTIMEOUT; - if ( 1 && nn_setsockopt(lbsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)) < 0 ) - printf("error setting NN_SOL_SOCKET NN_RCVTIMEO socket %s\n",nn_errstr()); - timeout = 100; - if ( 1 && nn_setsockopt(lbsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)) < 0 ) - printf("error setting NN_SOL_SOCKET NN_SNDTIMEO socket %s\n",nn_errstr()); - if ( num > 0 ) - priority = nn_add_lbservers(myinfo,port,globalport,relaysport,priority,lbsock,servers,num); - if ( numbacks > 0 ) - priority = nn_add_lbservers(myinfo,port,globalport,relaysport,priority,lbsock,backups,numbacks); - if ( numfailsafes > 0 ) - priority = nn_add_lbservers(myinfo,port,globalport,relaysport,priority,lbsock,failsafes,numfailsafes); - } else printf("error getting req socket %s\n",nn_errstr()); - //printf("myinfo->lb.num %d\n",myinfo->lb.num); - return(lbsock); -} - -int32_t nn_lbsocket(struct supernet_info *myinfo,int32_t maxmillis,int32_t port,uint16_t globalport,uint16_t relaysport) -{ - char Cservers[32][MAX_SERVERNAME],Bservers[32][MAX_SERVERNAME],failsafes[4][MAX_SERVERNAME]; - int32_t n,m,lbsock,numfailsafes = 0; - printf("redo lbsocket()\n"), exit(-1); - //strcpy(failsafes[numfailsafes++],"5.9.56.103"); - //strcpy(failsafes[numfailsafes++],"5.9.102.210"); - // n = crackfoo_servers(Cservers,sizeof(Cservers)/sizeof(*Cservers),port); - // m = badass_servers(Bservers,sizeof(Bservers)/sizeof(*Bservers),port); - lbsock = _lb_socket(myinfo,port,globalport,relaysport,maxmillis,Bservers,m,Cservers,n*0,failsafes,numfailsafes); - return(lbsock); -} - -void add_standard_fields(char *request) -{ - cJSON *json; uint64_t tag; - if ( (json= cJSON_Parse(request)) != 0 ) - { - if ( get_API_nxt64bits(cJSON_GetObjectItem(json,"NXT")) == 0 ) - { - randombytes((void *)&tag,sizeof(tag)); - sprintf(request + strlen(request) - 1,",\"NXT\":\"%s\",\"tag\":\"%llu\"}",myinfo->NXTADDR,(long long)tag); - if ( myinfo->iamrelay != 0 && (myinfo->hostname[0] != 0 || myinfo->ipaddr[0] != 0) ) - sprintf(request + strlen(request) - 1,",\"iamrelay\":\"%s\"}",myinfo->hostname[0]!=0?myinfo->hostname:myinfo->myipaddr); - } - free_json(json); - } -} - -char *nn_loadbalanced(struct supernet_info *myinfo,uint8_t *data,int32_t len) -{ - char *msg,*jsonstr = 0; - int32_t sendlen,i,lbsock,recvlen = 0; - if ( (lbsock= myinfo->lbclient) < 0 ) - return(clonestr("{\"error\":\"invalid load balanced socket\"}")); - for (i=0; i<10; i++) - if ( (nn_socket_status(lbsock,1) & NN_POLLOUT) != 0 ) - break; - if ( myinfo->Debuglevel > 2 ) - printf("sock.%d NN_LBSEND.(%s)\n",lbsock,data); - //fprintf(stderr,"send to network\n"); - if ( (sendlen= nn_send(lbsock,data,len,0)) == len ) - { - for (i=0; i<10; i++) - if ( (nn_socket_status(lbsock,1) & NN_POLLIN) != 0 ) - break; - if ( (recvlen= nn_recv(lbsock,&msg,NN_MSG,0)) > 0 ) - { - if ( myinfo->Debuglevel > 2 ) - printf("LBRECV.(%s)\n",msg); - jsonstr = clonestr((char *)msg); - nn_freemsg(msg); - } - else - { - printf("nn_loadbalanced got recvlen.%d %s\n",recvlen,nn_errstr()); - jsonstr = clonestr("{\"error\":\"lb recv error, probably timeout\"}"); - } - } else printf("got sendlen.%d instead of %d %s\n",sendlen,len,nn_errstr()), jsonstr = clonestr("{\"error\":\"lb send error\"}"); - return(jsonstr); -} - -cJSON *relay_json(struct relay_info *list) -{ - cJSON *json,*array; char endpoint[512]; int32_t i; - if ( list == 0 || list->num == 0 ) - return(0); - array = cJSON_CreateArray(); - for (i=0; inum&&i<(int32_t)(sizeof(list->connections)/sizeof(*list->connections)); i++) - { - expand_epbits(endpoint,list->connections[i]); - jaddistr(array,endpoint); - } - json = cJSON_CreateObject(); - jadd(json,"endpoints",array); - //cJSON_AddItemToObject(json,"type",cJSON_CreateString(nn_typestr(list->mytype))); - //cJSON_AddItemToObject(json,"dest",cJSON_CreateString(nn_typestr(list->desttype))); - jaddnum(json,"total",list->num); - return(json); -} - -char *relays_jsonstr(struct supernet_info *myinfo,char *jsonstr,cJSON *argjson) -{ - cJSON *json; - if ( myinfo->iamrelay != 0 && myinfo->ipaddr[0] != 0 ) - { - json = cJSON_CreateObject(); - jaddstr(json,"relay",myinfo->ipaddr); - if ( myinfo->active.num > 0 ) - jadd(json,"relays",relay_json(&myinfo->active)); - return(jprint(json,1)); - } - else return(clonestr("{\"error\":\"get relay list from relay\"}")); -} - -int32_t init_SUPERNET_pullsock(struct supernet_info *myinfo,int32_t sendtimeout,int32_t recvtimeout) -{ - char bindaddr[64],*transportstr; int32_t iter; - myinfo->pullsock = -1; - if ( (myinfo->pullsock= nn_socket(AF_SP,NN_PULL)) < 0 ) - { - printf("error creating pullsock %s\n",nn_strerror(nn_errno())); - return(-1); - } - printf("got pullsock.%d\n",myinfo->pullsock); - if ( nn_settimeouts(myinfo->pullsock,sendtimeout,recvtimeout) < 0 ) - { - printf("error settime pullsock timeouts %s\n",nn_strerror(nn_errno())); - return(-1); - } - printf("PULLsock.%d\n",myinfo->pullsock); - for (iter=0; iter<2; iter++) - { - transportstr = (iter == 0) ? "ipc" : "inproc"; - sprintf(bindaddr,"%s://SuperNET.agents",transportstr); - if ( nn_bind(myinfo->pullsock,bindaddr) < 0 ) - { - printf("error binding pullsock to (%s) %s\n",bindaddr,nn_strerror(nn_errno())); - return(-1); - } - } - return(0); -} - -void busdata_init(struct supernet_info *myinfo,int32_t sendtimeout,int32_t recvtimeout,int32_t firstiter) -{ - char endpoint[512]; int32_t i; - myinfo->servicesock = myinfo->pubglobal = myinfo->pubrelays = myinfo->lbserver = -1; - endpoint[0] = 0; - if ( (myinfo->subclient= nn_createsocket(myinfo,endpoint,0,"NN_SUB",NN_SUB,0,sendtimeout,recvtimeout)) >= 0 ) - { - myinfo->pfd[myinfo->numservers++].fd = myinfo->subclient, printf("numservers.%d\n",myinfo->numservers); - nn_setsockopt(myinfo->subclient,NN_SUB,NN_SUB_SUBSCRIBE,"",0); - } else printf("error creating subclient\n"); - myinfo->lbclient = nn_lbsocket(myinfo,SUPERNET_NETWORKTIMEOUT,SUPERNET_PORT + LB_OFFSET,myinfo->port + PUBGLOBALS_OFFSET,myinfo->port + PUBRELAYS_OFFSET); - printf("LBclient.%d port.%d\n",myinfo->lbclient,SUPERNET_PORT + LB_OFFSET); - sprintf(endpoint,"%s://%s:%u",myinfo->transport,myinfo->ipaddr,myinfo->serviceport); - if ( (myinfo->servicesock= nn_createsocket(myinfo,endpoint,1,"NN_REP",NN_REP,myinfo->serviceport,sendtimeout,recvtimeout)) >= 0 ) - myinfo->pfd[myinfo->numservers++].fd = myinfo->servicesock, printf("numservers.%d\n",myinfo->numservers); - else printf("error creating servicesock\n"); - for (i=0; inumservers; i++) - myinfo->pfd[i].events = NN_POLLIN | NN_POLLOUT; - printf("myinfo->iamrelay %d, numservers.%d ipaddr.(%s://%s) port.%d serviceport.%d\n",myinfo->iamrelay,myinfo->numservers,myinfo->transport,myinfo->ipaddr,myinfo->port,myinfo->serviceport); -} - -void SuperNET_init(struct supernet_info *myinfo,char *jsonstr) -{ - char *str; - if ( jsonstr != 0 && (str= SuperNET_JSON(myinfo,jsonstr)) != 0 ) - free(str); - busdata_init(myinfo,10,1,0); - init_SUPERNET_pullsock(myinfo,10,10); -}*/ - -int32_t Supernet_lineparse(char *key,int32_t keymax,char *value,int32_t valuemax,char *src) -{ - int32_t a,b,c,n = 0; - key[0] = value[0] = 0; - while ( (c= src[n]) == ' ' || c == '\t' || c == '\n' || c == '\t' ) - n++; - while ( (c= src[n]) != ':' && c != 0 ) - { - *key++ = c; - if ( ++n >= keymax-1 ) - { - *key = 0; - printf("lineparse overflow key.(%s)\n",src); - return(-1); - } - } - *key = 0; - if ( src[n] != ':' ) - return(n); - n++; - while ( (c= src[n]) == ' ' || c == '\t' ) - n++; - while ( (c= src[n]) != 0 && c != '\r' && c != '\n' ) - { - if ( c == '%' && (a= src[n+1]) != 0 && (b= src[n+2]) != 0 ) - c = ((unhex(a) << 4) | unhex(b)), n += 2; - *value++ = c; - n++; - if ( n >= valuemax-1 ) - { - *value = 0; - printf("lineparse overflow.(%s)\n",src); - return(-1); - } - } - *value = 0; - if ( src[n] != 0 ) - { - n++; - while ( (c= src[n]) == '\r' || c == '\n' ) - n++; - } - return(n); -} - -cJSON *SuperNET_urlconv(char *value,int32_t bufsize,char *urlstr) -{ - int32_t i,n,totallen,datalen,len = 0; cJSON *json,*array; char key[8192],*data; - json = cJSON_CreateObject(); - array = cJSON_CreateArray(); - totallen = (int32_t)strlen(urlstr); - while ( 1 ) - { - for (i=len; urlstr[i]!=0; i++) - if ( urlstr[i] == '\r' || urlstr[i] == '\n' ) - break; - if ( i == len && (urlstr[len] == '\r' || urlstr[len] == '\n') ) - { - len++; - continue; - } - urlstr[i] = 0; - if ( (n= Supernet_lineparse(key,sizeof(key),value,bufsize,&urlstr[len])) > 0 ) - { - if ( value[0] != 0 ) - jaddstr(json,key,value); - else jaddistr(array,key); - len += (n + 1); - if ( strcmp(key,"Content-Length") == 0 && (datalen= atoi(value)) > 0 ) - { - data = &urlstr[totallen - datalen]; - data[-1] = 0; - //printf("post.(%s) (%c)\n",data,data[0]); - jaddstr(json,"POST",data); - } - } else break; - } - jadd(json,"lines",array); - return(json); -} - -char *SuperNET_rpcparse(struct supernet_info *myinfo,char *retbuf,int32_t bufsize,int32_t *postflagp,char *urlstr,char *remoteaddr) -{ - cJSON *tokens,*argjson,*json = 0; char urlmethod[16],*data,url[1024],*retstr,*token = 0; int32_t i,j,n; - //printf("rpcparse.(%s)\n",urlstr); - for (i=0; i 0 ) - { - jaddstr(argjson,"agent",jstri(tokens,0)); - if ( n > 1 ) - jaddstr(argjson,"method",jstri(tokens,1)); - for (i=2; i (%s) postflag.%d (%s)\n",urlstr,cJSON_Print(json),*postflagp,jprint(argjson,0)); - return(retstr); - } - return(clonestr("{\"error\":\"couldnt process packet\"}")); -} - -#ifdef notyet -int32_t iguana_htmlgen(char *retbuf,int32_t bufsize,char *result,char *error,cJSON *json,char *tabname,char *origjsonstr) -{ - char *url = "http://127.0.0.1:7778"; - int i,j,m,size = 0,n,rows,cols; cJSON *array,*obj,*array2,*item,*tmp; - char formheader[512],formfooter[512],clickname[512],buf[512],fieldbuf[512],fieldindex[2],postjson[8192]; - char *disp,*fieldname,*button,*agent,*method,*str; - bufsize--; - HTML_EMIT("

"); - sprintf(buf,"
"); - //sprintf(buf,"
COIN: "); - //HTML_EMIT(buf); - //HTML_EMIT(" Agent: "); HTML_EMIT(Default_agent); - - HTML_EMIT("

"); - HTML_EMIT(origjsonstr); HTML_EMIT(" -> "); - HTML_EMIT(""); - formheader[0] = formfooter[0] = 0; - if ( (array= jarray(&n,json,"forms")) != 0 ) - { - for (i=0; i function click_%s()\n{\n",clickname); - HTML_EMIT(buf); - sprintf(postjson,"%s/%s",agent,method); - //printf("form.%s button.%s [%s]\n",formname,button,postjson); - if ( (array2= jarray(&m,item,"fields")) != 0 ) - { - //sprintf(buf,"COIN = document.COIN_NAME.value;\n"); - //sprintf(postjson+strlen(postjson),"/%s/' + %s + '","coin","COIN"); - for (j=0; j (%s)\n",j,jprint(obj,0)); - sprintf(fieldindex,"%c",'A'+j); - if ( (fieldname= jstr(obj,"field")) != 0 ) - { - sprintf(buf,"%s = document.%s.%s.value;\n",fieldindex,clickname,fieldname); - HTML_EMIT(buf); - //sprintf(postjson+strlen(postjson),",\"%s\":\"' + %s + '\"",fieldname,fieldindex); - if ( juint(obj,"skip") == 0 ) - sprintf(postjson+strlen(postjson),"/%s/' + %s + '",fieldname,fieldindex); - else sprintf(postjson+strlen(postjson),"/' + %s + '",fieldindex); - } - } - //strcat(postjson,"}"); - sprintf(&retbuf[size],"location.href = '%s/%s';\n}\r\n",url,postjson), size += strlen(&retbuf[size]); - sprintf(formheader,"
",clickname,url); - HTML_EMIT(formheader); - disp = jstr(item,"disp"); - for (j=0; j",fieldname); - else sprintf(buf,"",cols,rows,fieldname,cols == 1 ? "hidden" : ""); - str = disp==0?jstr(obj,"disp"):disp; - sprintf(&retbuf[size],"\r\n",str!=0?str:fieldname,buf), size += strlen(&retbuf[size]); - } - sprintf(formfooter,"\n
%s %s
",button,clickname); - HTML_EMIT(formfooter); - } - } - } - HTML_EMIT("

"); HTML_EMIT(""); HTML_EMIT("

"); - return((int32_t)strlen(retbuf)); -} -#undef HTML_EMIT - -char *SuperNET_htmlresponse(char *retbuf,int32_t bufsize,int32_t *remainsp,int32_t localaccess,char *retstr,int32_t freeflag) -{ - static char *html = " %s "; - char *result=0,*error=0; int32_t n; cJSON *json,*formsjson; - retbuf[0] = 0; - /*if ( localaccess == 0 ) - sprintf(retbuf+strlen(retbuf),"Access-Control-Allow-Origin: *\r\n"); - else sprintf(retbuf+strlen(retbuf),"Access-Control-Allow-Origin: null\r\n"); - sprintf(retbuf+strlen(retbuf),"Access-Control-Allow-Credentials: true\r\n"); - sprintf(retbuf+strlen(retbuf),"Access-Control-Allow-Headers: Authorization, Content-Type\r\n"); - sprintf(retbuf+strlen(retbuf),"Access-Control-Allow-Methods: GET, POST\r\n"); - sprintf(retbuf+strlen(retbuf),"Cache-Control: no-cache, no-store, must-revalidate\r\n"); - sprintf(retbuf+strlen(retbuf),"Content-type: text/html\r\n"); - sprintf(retbuf+strlen(retbuf),"Content-Length: %8d\r\n\r\n",n);*/ - sprintf(retbuf+strlen(retbuf),"\n\r"); - n = (int32_t)strlen(retbuf); - formsjson = cJSON_Parse(IGUANA_FORMS); - if ( (json= cJSON_Parse(retstr)) == 0 ) - json = cJSON_CreateObject(); - jadd(json,"forms",formsjson); - error = jstr(json,"error"); - result = jstr(json,"result"); - //printf("process.(%s)\n",jprint(formsjson,0)); - n = iguana_htmlgen(&retbuf[n],bufsize-n,result,error,json,"iguana",Currentjsonstr); - free_json(json); - if ( n == 0 ) - { - n = (int32_t)(strlen(html) + strlen(retstr) + 1); - sprintf(retbuf+strlen(retbuf),html,retstr); - } - if ( freeflag != 0 ) - free(retstr); - if ( n > bufsize ) - { - printf("htmlresponse overflowed buffer[%d] with %d\n",bufsize,n); - exit(-1); - } - *remainsp = n; - return(retbuf); -} -#endif diff --git a/SuperNET/main.c b/SuperNET/main.c deleted file mode 100755 index b429a8eab..000000000 --- a/SuperNET/main.c +++ /dev/null @@ -1,751 +0,0 @@ -/****************************************************************************** - * Copyright © 2014-2015 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - -#define CHROMEAPP_NAME SuperNET -#define CHROMEAPP_STR "SuperNET" -#define CHROMEAPP_CONF "SuperNET.conf" -#define CHROMEAPP_MAIN SuperNET_main -#define CHROMEAPP_JSON SuperNET_JSON -#define CHROMEAPP_HANDLER Handler_SuperNET - -#include "../pnacl_main.h" -#include "SuperNET.h" - -#ifndef MSG_NOSIGNAL -#define MSG_NOSIGNAL 0x4000 // Do not generate SIGPIPE -#endif - -// ALL globals must be here! - -int32_t nn_typelist[] = { NN_REP, NN_REQ, NN_RESPONDENT, NN_SURVEYOR, NN_PUB, NN_SUB, NN_PULL, NN_PUSH, NN_BUS, NN_PAIR }; -char *nn_transports[] = { "tcp", "ws", "ipc", "inproc", "tcpmux", "", "", "" }; - -void expand_epbits(char *endpoint,struct endpoint epbits) -{ - char ipaddr[64]; - if ( epbits.ipbits != 0 ) - expand_ipbits(ipaddr,epbits.ipbits); - else strcpy(ipaddr,"*"); - sprintf(endpoint,"%s://%s:%d",nn_transports[epbits.transport],ipaddr,epbits.port); -} - -struct endpoint calc_epbits(char *transport,uint32_t ipbits,uint16_t port,int32_t type) -{ - int32_t i; struct endpoint epbits; - memset(&epbits,0,sizeof(epbits)); - for (i=0; i<(int32_t)(sizeof(nn_transports)/sizeof(*nn_transports)); i++) - if ( strcmp(transport,nn_transports[i]) == 0 ) - { - epbits.ipbits = ipbits; - epbits.port = port; - epbits.transport = i; - epbits.nn = type; - break; - } - return(epbits); -} - -int32_t ismyaddress(struct supernet_info *myinfo,char *server) -{ - uint32_t ipbits; int32_t i,tlen; char str[64]; - for (i=0; iipaddr) == 0 || myinfo->ipbits == ipbits ) - { - printf("(%s) MATCHES me (%s)\n",server,myinfo->ipaddr); - return(1); - } - } - else if ( myinfo->my64bits == ipbits ) - return(1); - //printf("(%s) is not me (%s)\n",server,myipaddr); - return(0); -} - -char *nn_typestr(int32_t type) -{ - switch ( type ) - { - // Messages that need a response from the set of peers: SURVEY - case NN_SURVEYOR: return("NN_SURVEYOR"); break; - case NN_RESPONDENT: return("NN_RESPONDENT"); break; - // Messages that need a response, but only from one peer: REQ/REP - case NN_REQ: return("NN_REQ"); break; - case NN_REP: return("NN_REP"); break; - // One-way messages to one peer: PUSH/PULL - case NN_PUSH: return("NN_PUSH"); break; - case NN_PULL: return("NN_PULL"); break; - // One-way messages to all: PUB/SUB - case NN_PUB: return("NN_PUB"); break; - case NN_SUB: return("NN_SUB"); break; - case NN_BUS: return("NN_BUS"); break; - case NN_PAIR: return("NN_PAIR"); break; - } - return("NN_ERROR"); -} - -int32_t nn_oppotype(int32_t type) -{ - switch ( type ) - { - // Messages that need a response from the set of peers: SURVEY - case NN_SURVEYOR: return(NN_RESPONDENT); break; - case NN_RESPONDENT: return(NN_SURVEYOR); break; - // Messages that need a response, but only from one peer: REQ/REP - case NN_REQ: return(NN_REP); break; - case NN_REP: return(NN_REQ); break; - // One-way messages to one peer: PUSH/PULL - case NN_PUSH: return(NN_PULL); break; - case NN_PULL: return(NN_PUSH); break; - // One-way messages to all: PUB/SUB - case NN_PUB: return(NN_SUB); break; - case NN_SUB: return(NN_PUB); break; - case NN_BUS: return(NN_BUS); break; - case NN_PAIR: return(NN_PAIR); break; - } - return(-1); -} - -int32_t nn_portoffset(int32_t type) -{ - int32_t i; - for (i=0; i<(int32_t)(sizeof(nn_typelist)/sizeof(*nn_typelist)); i++) - if ( nn_typelist[i] == type ) - return(i + 2); - return(-1); -} - -int32_t nn_socket_status(int32_t nnsock,int32_t timeoutmillis) -{ - struct nn_pollfd pfd; - int32_t rc; - pfd.fd = nnsock; - pfd.events = NN_POLLIN | NN_POLLOUT; - if ( (rc= nn_poll(&pfd,1,timeoutmillis)) == 0 ) - return(pfd.revents); - else return(-1); -} - -int32_t SuperNET_msglen(struct supernet_msghdr *msg) -{ - return(msg->serlen[0] + ((int32_t)msg->serlen[1] << 8) + ((int32_t)msg->serlen[2] << 16)); -} - -int32_t SuperNET_msgvalidate(struct supernet_msghdr *msg) -{ - int32_t msglen = 0; - msglen = SuperNET_msglen(msg); - return(msglen); -} - -int32_t nn_settimeouts(int32_t sock,int32_t sendtimeout,int32_t recvtimeout) -{ - int32_t retrymillis,maxmillis; - if ( (maxmillis= SUPERNET_NETWORKTIMEOUT) == 0 ) - maxmillis = 3000; - retrymillis = maxmillis/40; - if ( nn_setsockopt(sock,NN_SOL_SOCKET,NN_RECONNECT_IVL,&retrymillis,sizeof(retrymillis)) < 0 ) - fprintf(stderr,"error setting NN_REQ NN_RECONNECT_IVL_MAX socket %s\n",nn_errstr()); - else if ( nn_setsockopt(sock,NN_SOL_SOCKET,NN_RECONNECT_IVL_MAX,&maxmillis,sizeof(maxmillis)) < 0 ) - fprintf(stderr,"error setting NN_REQ NN_RECONNECT_IVL_MAX socket %s\n",nn_errstr()); - else if ( sendtimeout > 0 && nn_setsockopt(sock,NN_SOL_SOCKET,NN_SNDTIMEO,&sendtimeout,sizeof(sendtimeout)) < 0 ) - fprintf(stderr,"error setting sendtimeout %s\n",nn_errstr()); - else if ( recvtimeout > 0 && nn_setsockopt(sock,NN_SOL_SOCKET,NN_RCVTIMEO,&recvtimeout,sizeof(recvtimeout)) < 0 ) - fprintf(stderr,"error setting sendtimeout %s\n",nn_errstr()); - else return(0); - return(-1); -} - -int32_t nn_createsocket(struct supernet_info *myinfo,char *endpoint,int32_t bindflag,char *name,int32_t type,uint16_t port,int32_t sendtimeout,int32_t recvtimeout) -{ - int32_t sock; - if ( (sock= nn_socket(AF_SP,type)) < 0 ) - fprintf(stderr,"error getting socket %s\n",nn_errstr()); - if ( bindflag != 0 ) - { - if ( endpoint[0] == 0 ) - expand_epbits(endpoint,calc_epbits(myinfo->transport,0,port,type)); - if ( nn_bind(sock,endpoint) < 0 ) - fprintf(stderr,"error binding to relaypoint sock.%d type.%d to (%s) (%s) %s\n",sock,type,name,endpoint,nn_errstr()); - else fprintf(stderr,"BIND.(%s) <- %s\n",endpoint,name); - } - else if ( bindflag == 0 && endpoint != 0 && endpoint[0] != 0 ) - { - if ( nn_connect(sock,endpoint) < 0 ) - fprintf(stderr,"error connecting to relaypoint sock.%d type.%d to (%s) (%s) %s\n",sock,type,name,endpoint,nn_errstr()); - else fprintf(stderr,"%s -> CONNECT.(%s)\n",name,endpoint); - } - if ( nn_settimeouts(sock,sendtimeout,recvtimeout) < 0 ) - { - fprintf(stderr,"nn_createsocket.(%s) %d\n",name,sock); - return(-1); - } - return(sock); -} - -bits256 SuperNET_OPRETURN(struct supernet_info *myinfo,char *symbol,double fee,uint8_t *buf,int32_t len) -{ - bits256 txid; - printf("send OPRETURN\n"); - return(txid); -} - -bits256 SuperNET_agentannounce(struct supernet_info *myinfo,struct supernet_agent *agent,cJSON *network) -{ - static const bits256 zero; - uint8_t buf[80 + sizeof(struct iguana_msghdr)],*data; - bits256 pubkey,sig; int32_t i,len=0; uint8_t netmagic[4]; char *sigstr,*announce,*pubkeystr; - memset(buf,0,sizeof(buf)); - data = &buf[sizeof(struct iguana_msghdr)]; - if ( (announce= jstr(network,"announce")) != 0 ) - { - data[len++] = SCRIPT_OPRETURN; - data[len++] = 75; - iguana_rwnum(1,&data[len],sizeof(myinfo->ipbits),&myinfo->ipbits); - for (i=0; i<7; i++) - if ( (data[len+i]= announce[i]) == 0 ) - break; - len = 13; - if ( (pubkeystr= jstr(network,"pubkey")) == 0 || strlen(pubkeystr) != sizeof(bits256)*2 ) - pubkeystr = GENESIS_PUBKEYSTR; - decode_hex(pubkey.bytes,sizeof(pubkey),pubkeystr); - len += iguana_rwbignum(1,&data[len],sizeof(pubkey),pubkey.bytes); // 45 bytes - if ( (sigstr= jstr(network,"sig")) != 0 && strlen(sigstr) == sizeof(bits256)*2 ) - { - sigstr = GENESIS_PUBKEYSTR; - len += iguana_rwbignum(1,&data[len],sizeof(sig),sig.bytes); // 77 bytes - } - decode_hex(netmagic,4,"e4c2d8e6"); - iguana_sethdr((struct iguana_msghdr *)buf,netmagic,"SuperNET",data,len); - return(SuperNET_OPRETURN(myinfo,"BTCD",.001,buf,len)); - } - printf("invalid SuperNET OPRETURN protocol.(%s)\n",announce!=0?announce:""); - return(zero); -} - -void Supernet_networkadd(struct supernet_info *myinfo,struct supernet_agent *agent,cJSON *network) -{ - int32_t sendtimeout=0,recvtimeout=0; - agent->pubpoint[0] = agent->reppoint[0] = 0; - if ( (agent->pubport= juint(network,"pubport")) > 1000 ) - { - agent->pubsock = nn_createsocket(myinfo,agent->pubpoint,1,"NN_PUB",NN_PUB,agent->pubport,sendtimeout,recvtimeout); - SuperNET_agentannounce(myinfo,agent,network); - } - else agent->pubport = -1; - if ( (agent->repport= juint(network,"repport")) > 1000 ) - agent->repsock = nn_createsocket(myinfo,agent->reppoint,1,"NN_REP",NN_REP,agent->repport,sendtimeout,recvtimeout); - else agent->repport = -1; - agent->subsock = nn_createsocket(myinfo,0,0,"NN_SUB",NN_SUB,0,sendtimeout,recvtimeout); - nn_setsockopt(agent->subsock,NN_SUB,NN_SUB_SUBSCRIBE,"",0); - agent->reqsock = nn_createsocket(myinfo,0,0,"NN_REQ",NN_REQ,0,sendtimeout,recvtimeout); -} - -int32_t SuperNET_agentcommand(struct supernet_info *myinfo,struct supernet_agent *agent,struct supernet_msghdr *H,uint8_t *buf,int32_t buflen) -{ - char *name; cJSON *json; int32_t i; - if ( strcmp(H->command,"register") == 0 ) - { - if ( (json= cJSON_Parse((char *)buf)) != 0 ) - { - if ( (name= jstr(json,"name")) != 0 ) - { - memset(agent->name,0,sizeof(agent->name)); - strncpy(agent->name,name,sizeof(agent->name)-1); - if ( (agent->networks= jarray(&agent->num,json,"networks")) != 0 ) - { - for (i=0; inum; i++) - Supernet_networkadd(myinfo,agent,jitem(agent->networks,i)); - } - } else free_json(json); - } - } - return(0); -} - -int32_t SuperNET_socket(int32_t bindflag,char *hostname,uint16_t port) -{ - int32_t opt,sock,result; uint32_t ipbits; char ipaddr[64]; struct timeval timeout; - struct sockaddr_in saddr; socklen_t addrlen; - addrlen = sizeof(saddr); - struct hostent *hostent = gethostbyname(hostname); - if ( hostent == NULL ) - { - printf("gethostbyname() returned error: %d",errno); - return(-1); - } - saddr.sin_family = AF_INET; - saddr.sin_port = htons(port); - memcpy(&saddr.sin_addr.s_addr,hostent->h_addr_list[0],hostent->h_length); - ipbits = (uint32_t)calc_ipbits(hostname); - //printf("ipbits.%08x vs %08x\n",ipbits,saddr.sin_addr.s_addr); - expand_ipbits(ipaddr,saddr.sin_addr.s_addr); - //if ( bindflag != 0 ) - // printf("iguana_socket.(%s:%d) bind.%d\n",ipaddr,port,bindflag), getchar(); - if ( strcmp(ipaddr,hostname) != 0 ) - printf("iguana_socket mismatch (%s) -> (%s)?\n",hostname,ipaddr); - if ( (sock= socket(AF_INET,SOCK_STREAM,0)) < 0 ) - { - if ( errno != ETIMEDOUT ) - printf("socket() failed: %s errno.%d", strerror(errno),errno); - return(-1); - } - if ( 0 && bindflag != 0 ) - { - timeout.tv_sec = 0; - timeout.tv_usec = 100000; - setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout,sizeof(timeout)); - } - opt = 1; - setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(void*)&opt,sizeof(opt)); -#ifdef __APPLE__ - setsockopt(sock,SOL_SOCKET,SO_NOSIGPIPE,&opt,sizeof(opt)); -#endif - result = (bindflag != 0) ? bind(sock,(struct sockaddr*)&saddr,addrlen) : connect(sock,(struct sockaddr *)&saddr,addrlen); - if ( result != 0 ) - { - if ( errno != ECONNRESET && errno != ENOTCONN && errno != ECONNREFUSED && errno != ETIMEDOUT && errno != EHOSTUNREACH ) - printf("connect(%s) port.%d failed: %s sock.%d. errno.%d\n",hostname,port,strerror(errno),sock,errno); - if ( sock >= 0 ) - close(sock); - return(-1); - } - if ( bindflag != 0 && listen(sock,3) != 0 ) - { - printf("listen(%s) port.%d failed: %s sock.%d. errno.%d\n",hostname,port,strerror(errno),sock,errno); - if ( sock >= 0 ) - close(sock); - return(-1); - } - return(sock); -} - -int32_t SuperNET_recv(int32_t sock,uint8_t *recvbuf,int32_t len) -{ - int32_t recvlen,remains = len; - while ( remains > 0 ) - { - if ( (recvlen= (int32_t)recv(sock,recvbuf,remains,0)) < 0 ) - { - if ( errno == EAGAIN ) - { - //printf("EAGAIN for len %d, remains.%d\n",len,remains); - usleep(10000); - } - else return(-errno); - } - else - { - if ( recvlen > 0 ) - { - remains -= recvlen; - recvbuf = &recvbuf[recvlen]; - } else usleep(10000); - } - } - return(len); -} - -int32_t SuperNET_send(struct supernet_info *myinfo,struct supernet_agent *agent,uint8_t *serialized,int32_t len) -{ - int32_t numsent,remains,sock; - if ( agent == 0 ) - return(-1); - if ( (sock= agent->sock) < 0 || agent->dead != 0 ) - { - return(-1); - } - remains = len; - while ( remains > 0 ) - { - if ( (numsent= (int32_t)send(sock,serialized,remains,MSG_NOSIGNAL)) < 0 ) - { - printf("send errno.%d %s\n",errno,strerror(errno)); - if ( errno != EAGAIN && errno != EWOULDBLOCK ) - { - printf("bad errno.%d %s zombify.%p\n",errno,strerror(errno),agent->name); - agent->dead = (uint32_t)time(NULL); - return(-errno); - } //else usleep(*sleeptimep), *sleeptimep *= 1.1; - } - else if ( remains > 0 ) - { - remains -= numsent; - serialized += numsent; - if ( remains > 0 ) - printf("SuperNET sent.%d remains.%d of len.%d\n",numsent,remains,len); - } - } - agent->totalsent += len; - //printf(" sent.%d bytes to %s\n",len,addr->ipaddr);// getchar(); - return(len); -} - -char *SuperNET_JSON(struct supernet_info *myinfo,cJSON *argjson,char *remoteaddr) -{ - char *agent,*method; - if ( (agent= jstr(argjson,"agent")) == 0 || (method= jstr(argjson,"method")) == 0 ) - return(clonestr("{\"error\":\"need both agent and method\"}")); -} - -void SuperNET_rpcloop(void *args) -{ - struct supernet_info *myinfo = args; - int32_t recvlen,bindsock,postflag,sock,remains,numsent,len; socklen_t clilen; - char remoteaddr[64],jsonbuf[8192],*buf,*retstr,*space;//,*retbuf; ,n,i,m - struct sockaddr_in cli_addr; uint32_t ipbits,i; uint16_t port; - int32_t size = 1024 * 1024 * 2; - port = SUPERNET_PORT; - bindsock = SuperNET_socket(1,"127.0.0.1",port); - printf("SuperNET_rpcloop 127.0.0.1:%d bind sock.%d\n",port,bindsock); - space = calloc(1,size); - while ( bindsock >= 0 ) - { - clilen = sizeof(cli_addr); - //printf("ACCEPT (%s:%d) on sock.%d\n","127.0.0.1",port,bindsock); - sock = accept(bindsock,(struct sockaddr *)&cli_addr,&clilen); - if ( sock < 0 ) - { - //printf("iguana_rpcloop ERROR on accept usock.%d\n",sock); - continue; - } - memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); - expand_ipbits(remoteaddr,ipbits); - memset(jsonbuf,0,sizeof(jsonbuf)); - remains = (int32_t)(sizeof(jsonbuf) - 1); - buf = jsonbuf; - recvlen = 0; - retstr = 0; - while ( remains > 0 ) - { - if ( (len= (int32_t)recv(sock,buf,remains,0)) < 0 ) - { - if ( errno == EAGAIN ) - { - printf("EAGAIN for len %d, remains.%d\n",len,remains); - usleep(10000); - } - break; - } - else - { - if ( len > 0 ) - { - remains -= len; - recvlen += len; - buf = &buf[len]; - retstr = SuperNET_rpcparse(myinfo,space,size,&postflag,jsonbuf,remoteaddr); - break; - } else usleep(10000); - } - } - if ( retstr != 0 ) - { - i = 0; - if ( postflag == 0 ) - { - //retstr = SuperNET_htmlresponse(space,size,&remains,1,retstr,1); - } - else remains = (int32_t)strlen(retstr); - printf("RETBUF.(%s)\n",retstr); - while ( remains > 0 ) - { - if ( (numsent= (int32_t)send(sock,&retstr[i],remains,MSG_NOSIGNAL)) < 0 ) - { - if ( errno != EAGAIN && errno != EWOULDBLOCK ) - { - //printf("%s: %s numsent.%d vs remains.%d len.%d errno.%d (%s) usock.%d\n",retstr,ipaddr,numsent,remains,recvlen,errno,strerror(errno),sock); - break; - } - } - else if ( remains > 0 ) - { - remains -= numsent; - i += numsent; - if ( remains > 0 ) - printf("iguana sent.%d remains.%d of len.%d\n",numsent,remains,recvlen); - } - } - if ( retstr != space ) - free(retstr); - } - //printf("done response sock.%d\n",sock); - closesocket(sock); - } -} - -int32_t SuperNET_msgrecv(struct supernet_info *myinfo,struct supernet_agent *agent,uint8_t *_buf,int32_t maxlen) -{ - int32_t len,recvlen; void *buf = _buf; struct supernet_msghdr H; - printf("got.(%s) from %s | sock.%d\n",H.command,agent->ipaddr,agent->sock); - memset(&H,0,sizeof(H)); - if ( (recvlen= (int32_t)SuperNET_recv(agent->sock,(uint8_t *)&H,sizeof(H))) == sizeof(H) ) - { - agent->totalrecv += recvlen; - if ( (len= SuperNET_msgvalidate(&H)) >= 0 ) - { - recvlen = 0; - if ( len > 0 ) - { - if ( len > maxlen ) - buf = calloc(1,len); - if ( (recvlen= SuperNET_recv(agent->sock,buf,len)) < 0 ) - { - printf("recv error on (%s) len.%d errno.%d (%s)\n",H.command,len,-recvlen,strerror(-recvlen)); - if ( buf != _buf ) - free(buf); - agent->dead = (uint32_t)time(NULL); - return(recvlen); - } else agent->totalrecv += recvlen; - } - printf("PROCESS.%c NNRECV(%s) recvlen.%d\n",H.type,H.command,recvlen); - if ( H.type == 'C' ) - SuperNET_agentcommand(myinfo,agent,&H,buf,recvlen); - else if ( agent->recvfunc != 0 ) - (*agent->recvfunc)(myinfo,agent,&H,buf,recvlen); - if ( buf != _buf ) - free(buf); - return(recvlen); - } - printf("invalid header received from (%s)\n",agent->ipaddr); - } - printf("%s recv error on hdr errno.%d (%s)\n",agent->ipaddr,-recvlen,strerror(-recvlen)); - return(-1); -} - -int32_t SuperNET_msgsend(struct supernet_info *myinfo,struct supernet_agent *agent,struct supernet_msghdr *msg) -{ - return(SuperNET_send(myinfo,agent,(uint8_t *)msg,SuperNET_msglen(msg) + sizeof(*msg))); -} - -int32_t SuperNET_nnsend(struct supernet_info *myinfo,struct supernet_endpoint *ptr,int32_t ind,struct supernet_msghdr *msg) -{ - return(nn_send(ptr->eps[ind].nnsock,(uint8_t *)msg,SuperNET_msglen(msg) + sizeof(*msg),0)); -} - -struct supernet_msghdr *SuperNET_msgpending(struct supernet_info *myinfo,struct supernet_agent *agent) -{ - return(queue_dequeue(&agent->recvQ,0)); -} - -struct supernet_msghdr *SuperNET_nnpending(struct supernet_info *myinfo,struct supernet_endpoint *ptr,int32_t ind) -{ - return(queue_dequeue(&ptr->eps[ind].nnrecvQ,0)); -} - -int32_t SuperNET_nnrecv(struct supernet_info *myinfo,struct supernet_endpoint *ptr,int32_t ind) -{ - void *msg; int32_t nnlen; - if ( (nnlen= nn_recv(ptr->eps[ind].nnsock,&msg,NN_MSG,0)) > 0 ) - { - printf("PROCESS NNRECV(%s)\n",msg); - if ( ptr->nnrecvfunc != 0 ) - (*ptr->nnrecvfunc)(myinfo,ptr,ind,msg,nnlen); - nn_freemsg(msg); - } - return(nnlen); -} - -int32_t Supernet_poll(struct supernet_info *myinfo,uint8_t *buf,int32_t bufsize,struct supernet_agent *agents,int32_t num,int32_t timeout) -{ - struct pollfd fds[SUPERNET_MAXAGENTS]; int32_t i,nonz,flag; struct supernet_msghdr *msg; struct supernet_agent *agent; - if ( num == 0 ) - return(0);; - memset(fds,0,sizeof(fds)); - flag = 0; - for (i=nonz=0; isock >= 0 ) - { - fds[i].fd = agent->sock; - fds[i].events = (POLLIN | POLLOUT); - nonz++; - } - } - if ( nonz != 0 && poll(fds,num,timeout) > 0 ) - { - for (i=0; isock < 0 ) - continue; - if ( (fds[i].revents & POLLIN) != 0 && SuperNET_msgrecv(myinfo,agent,buf,bufsize) >= 0 ) - flag++; - if ( (fds[i].revents & POLLOUT) != 0 ) - { - if ( (msg= SuperNET_msgpending(myinfo,agent)) != 0 && SuperNET_msgsend(myinfo,agent,msg) > 0 ) - flag++; - } - } - } - return(flag); -} - -int32_t Supernet_nnpoll(struct supernet_info *myinfo,uint8_t *buf,int32_t bufsize,struct supernet_endpoint **eps,int32_t num,int32_t timeout) -{ - struct nn_pollfd fds[1024]; int32_t i,j,n,k,r,starti,nonz,flag; struct supernet_msghdr *msg; struct supernet_endpoint *ptr; - if ( num == 0 ) - return(0); - memset(fds,0,sizeof(fds)); - flag = 0; - r = rand(); - for (j=k=nonz=n=0; jnum; k++,n++) - { - fds[n].fd = -1; - if ( ptr->eps[k].nnsock >= 0 ) - { - fds[n].fd = ptr->eps[k].nnsock; - fds[n].events = (POLLIN | POLLOUT); - nonz++; - } - } - } - if ( nonz != 0 && nn_poll(fds,num,timeout) > 0 ) - { - for (j=k=0; jnum; k++,n++) - { - if ( (fds[i].revents & POLLIN) != 0 && SuperNET_nnrecv(myinfo,ptr,n - starti) >= 0 ) - flag++; - if ( (fds[i].revents & POLLOUT) != 0 ) - { - if ( (msg= SuperNET_nnpending(myinfo,ptr,n - starti)) != 0 && SuperNET_nnsend(myinfo,ptr,n - starti,msg) > 0 ) - flag++; - } - } - } - } - return(flag); -} - -void SuperNET_acceptloop(void *args) -{ - int32_t bindsock,sock; struct supernet_agent *agent; struct supernet_info *myinfo = args; - socklen_t clilen; uint16_t agentport; struct sockaddr_in cli_addr; char ipaddr[64]; uint32_t ipbits; - bindsock = SuperNET_socket(1,"127.0.0.1",myinfo->acceptport); - printf("SuperNET_acceptloop 127.0.0.1:%d bind sock.%d\n",myinfo->acceptport,bindsock); - while ( bindsock >= 0 ) - { - clilen = sizeof(cli_addr); - printf("ACCEPT (%s:%d) on sock.%d\n","127.0.0.1",myinfo->acceptport,bindsock); - sock = accept(bindsock,(struct sockaddr *)&cli_addr,&clilen); - if ( sock < 0 ) - { - printf("ERROR on accept bindsock.%d errno.%d (%s)\n",bindsock,errno,strerror(errno)); - continue; - } - memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); - agentport = cli_addr.sin_port; - expand_ipbits(ipaddr,ipbits); - printf("NEWSOCK.%d for %x (%s:%u)\n",sock,ipbits,ipaddr,agentport); - agent = calloc(1,sizeof(*agent)); - strcpy(agent->ipaddr,ipaddr); - sprintf(agent->name,"%s:%d",ipaddr,agentport); - agent->ipbits = ipbits; - agent->sock = sock; - agent->port = myinfo->acceptport; - queue_enqueue("acceptQ",&myinfo->acceptQ,&agent->DL,0); - } -} - -int32_t SuperNET_acceptport(struct supernet_info *myinfo,uint16_t port) -{ - struct supernet_info *ptr; - ptr = calloc(1,sizeof(*myinfo)); - *ptr = *myinfo; - ptr->acceptport = port; - if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)SuperNET_acceptloop,(void *)ptr) != 0 ) - { - printf("error launching accept thread for port.%u\n",port); - return(-1); - } - return(0); -} - -void SuperNET_loop(struct supernet_info *myinfo) -{ - struct supernet_agent *ptr; char *buf; int32_t bufsize = 65536 * 32; - buf = calloc(1,bufsize); - while ( myinfo->dead == 0 ) - { - if ( (ptr= queue_dequeue(&myinfo->acceptQ,0)) != 0 ) - { - if ( myinfo->numagents < sizeof(myinfo->agents)/sizeof(*myinfo->agents)-1 ) - { - myinfo->agents[myinfo->numagents++] = *ptr; - free(ptr); - } - printf("SuperNET.[%d] got new socket %d for %s:%d\n",myinfo->numagents,ptr->sock,ptr->ipaddr,ptr->port); - } - else if ( Supernet_poll(myinfo,(uint8_t *)buf,bufsize,myinfo->agents,myinfo->numagents,myinfo->POLLTIMEOUT) <= 0 ) - usleep(10000); - } - free(buf); -} - -void SuperNET_main(void *arg) -{ - struct supernet_info MYINFO; int32_t i;//cJSON *json,*array; uint16_t port;,n = 0; - memset(&MYINFO,0,sizeof(MYINFO)); - if ( 1 ) - { - strcpy(MYINFO.transport,"tcp"); - strcpy(MYINFO.ipaddr,"127.0.0.1"); - MYINFO.acceptport = SUPERNET_PORT; MYINFO.serviceport = SUPERNET_PORT - 2; - // SuperNET_init(&MYINFO,arg); parse supernet.conf - if ( MYINFO.POLLTIMEOUT == 0 ) - MYINFO.POLLTIMEOUT = SUPERNET_POLLTIMEOUT; - } - /*if ( arg == 0 || (json= cJSON_Parse(arg)) == 0 ) - SuperNET_acceptport(&MYINFO,MYINFO.acceptport); - else - { - if ( (array= jarray(&n,json,"accept")) != 0 ) - { - for (i=0; i 0 ) + break; + } + iguana_rwnum(0,(void *)hash.uints,sizeof(basilisktag),&basilisktag); + iguana_rwnum(1,&data[-sizeof(basilisktag)],sizeof(basilisktag),&basilisktag); + char str[65],str2[65]; printf("found hash after numiters.%d %s vs %s basilisktag.%u\n",numiters,bits256_str(str,threshold),bits256_str(str2,hash2),basilisktag); + return(basilisktag); +} + +char *basilisk_addhexstr(char **ptrp,cJSON *valsobj,char *strbuf,int32_t strsize,uint8_t *data,int32_t datalen) +{ + *ptrp = 0; + if ( data != 0 && datalen > 0 ) + { + if ( valsobj != 0 && jobj(valsobj,"data") != 0 ) + { + printf("basilisk_addhexstr warning: already have data object\n"); + jdelete(valsobj,"data"); + } + if ( (datalen<<1)+1 > strsize ) + { + strbuf = calloc(1,(datalen << 1) + 1); + *ptrp = (void *)strbuf; + } + init_hexbytes_noT(strbuf,data,datalen); + if ( valsobj != 0 ) + jaddstr(valsobj,"data",strbuf); + } else return(0); + return(strbuf); +} + +uint8_t *get_dataptr(int32_t hdroffset,uint8_t **ptrp,int32_t *datalenp,uint8_t *space,int32_t spacesize,char *hexstr) +{ + *ptrp = 0; uint8_t *data = 0; + if ( hexstr != 0 && (*datalenp= is_hexstr(hexstr,0)) > 0 ) + { + *datalenp >>= 1; + if ( (*datalenp+hdroffset) <= spacesize ) + { + memset(space,0,hdroffset); + data = &space[hdroffset]; + } else *ptrp = data = calloc(1,*datalenp + hdroffset); + decode_hex(&data[hdroffset],*datalenp,hexstr); + } + if ( data != 0 ) + return(&data[hdroffset]); + else return(data); +} + +uint8_t *basilisk_jsondata(int32_t extraoffset,uint8_t **ptrp,uint8_t *space,int32_t spacesize,int32_t *datalenp,char *symbol,cJSON *sendjson,uint32_t basilisktag) +{ + char *sendstr,*hexstr=0; uint8_t *data,hexspace[8192],*allocptr=0,*hexdata; int32_t datalen,hexlen=0; + if ( jobj(sendjson,"symbol") == 0 ) + jaddstr(sendjson,"symbol",symbol); + if ( (hexstr= jstr(sendjson,"data")) != 0 ) + { + hexdata = get_dataptr(0,&allocptr,&hexlen,hexspace,sizeof(hexspace),hexstr); + //printf("delete data.%s from sendjson\n",hexstr); + jdelete(sendjson,"data"); + } + *ptrp = 0; + sendstr = jprint(sendjson,0); + datalen = (int32_t)strlen(sendstr) + 1; + if ( (datalen + extraoffset + BASILISK_HDROFFSET + hexlen) <= spacesize ) + data = space; + else + { + data = calloc(1,datalen + extraoffset + BASILISK_HDROFFSET + hexlen); + *ptrp = data; + } + data += extraoffset + BASILISK_HDROFFSET; + memcpy(data,sendstr,datalen); + //printf("jsondata.(%s) + hexlen.%d\n",sendstr,hexlen); + free(sendstr); + if ( hexlen > 0 ) + { + memcpy(&data[datalen],hexdata,hexlen); + datalen += hexlen; + } + *datalenp = datalen; + if ( allocptr != 0 ) + free(allocptr); + return(data); +} + +char *basilisk_finish(struct basilisk_item *ptr,int32_t besti,char *errstr) +{ + char *retstr = 0; struct basilisk_item *parent; + if ( ptr->retstr != 0 ) + return(ptr->retstr); + if ( besti >= 0 && besti < ptr->numresults ) + { + retstr = ptr->results[besti]; + ptr->results[besti] = 0; + } else printf("besti.%d vs numresults.%d retstr.%p\n",besti,ptr->numresults,retstr); + if ( retstr == 0 ) + retstr = clonestr(errstr); + ptr->retstr = retstr; + ptr->finished = (uint32_t)time(NULL); + if ( (parent= ptr->parent) != 0 ) + { + ptr->parent = 0; + parent->childrendone++; + } + return(retstr); +} + +struct basilisk_item *basilisk_itemcreate(struct supernet_info *myinfo,char *CMD,char *symbol,uint32_t basilisktag,int32_t minresults,cJSON *vals,int32_t timeoutmillis,void *metricfunc) +{ + struct basilisk_item *ptr; + ptr = calloc(1,sizeof(*ptr)); + ptr->basilisktag = basilisktag; + if ( (ptr->numrequired= minresults) == 0 ) + ptr->numrequired = 1; + if ( (ptr->metricfunc= metricfunc) != 0 ) + ptr->vals = jduplicate(vals); + strcpy(ptr->CMD,CMD); + safecopy(ptr->symbol,symbol,sizeof(ptr->symbol)); + ptr->expiration = OS_milliseconds() + timeoutmillis; + return(ptr); +} + +int32_t basilisk_sendcmd(struct supernet_info *myinfo,char *destipaddr,char *type,uint32_t *basilisktagp,int32_t encryptflag,int32_t delaymillis,uint8_t *data,int32_t datalen,int32_t fanout,uint32_t nBits) // data must be offset by sizeof(iguana_msghdr)+sizeof(basilisktag) +{ + int32_t i,r,l,s,val,n=0,retval = -1; char cmd[12]; struct iguana_info *coin,*tmp; struct iguana_peer *addr; bits256 hash; uint32_t *alreadysent; + if ( fanout <= 0 ) + fanout = BASILISK_MINFANOUT; + else if ( fanout > BASILISK_MAXFANOUT ) + fanout = BASILISK_MAXFANOUT; + if ( type == 0 ) + type = "BTCD"; + if ( strlen(type) > 3 ) + { + printf("basilisk_sendcmd illegal type(%s)\n",type); + return(-1); + } + if ( destipaddr != 0 ) + { + if ( destipaddr[0] == 0 ) + destipaddr = 0; // broadcast + else if ( strcmp(destipaddr,"127.0.0.1") == 0 ) + { + printf("return after locally basilisk_msgprocess\n"); + hash = GENESIS_PUBKEY; + basilisk_msgprocess(myinfo,0,0,type,*basilisktagp,data,datalen); + return(0); + } + } + alreadysent = calloc(IGUANA_MAXPEERS * IGUANA_MAXCOINS,sizeof(*alreadysent)); + iguana_rwnum(1,&data[-sizeof(*basilisktagp)],sizeof(*basilisktagp),basilisktagp); + if ( *basilisktagp == 0 ) + { + if ( nBits != 0 ) + *basilisktagp = basilisk_calcnonce(myinfo,data,datalen,nBits); + else *basilisktagp = rand(); + iguana_rwnum(1,&data[-sizeof(*basilisktagp)],sizeof(*basilisktagp),basilisktagp); + } + data -= sizeof(*basilisktagp), datalen += sizeof(*basilisktagp); + memset(cmd,0,sizeof(cmd)); + sprintf(cmd,"SuperNET%s",type); + r = rand(); + //portable_mutex_lock(&Allcoins_mutex); + HASH_ITER(hh,myinfo->allcoins,coin,tmp) + { + if ( coin->peers == 0 ) + continue; + if ( coin->RELAYNODE == 0 && coin->VALIDATENODE == 0 ) + cmd[0] = 's'; + else cmd[0] = 'S'; + for (l=0; lpeers->active[i]; + if ( addr->usock >= 0 ) + { + for (s=0; sipbits ) + break; + //printf("%s s.%d vs n.%d\n",addr->ipaddr,s,n); + if ( s == n && (addr->supernet != 0 || addr->basilisk != 0) && (destipaddr == 0 || strcmp(addr->ipaddr,destipaddr) == 0) ) + { + //printf("[%s].tag%d send %s.(%s) [%x] datalen.%d addr->supernet.%u basilisk.%u to (%s).%d destip.%s\n",cmd,*(uint32_t *)data,type,(char *)&data[4],*(int32_t *)&data[datalen-4],datalen,addr->supernet,addr->basilisk,addr->ipaddr,addr->A.port,destipaddr!=0?destipaddr:"broadcast"); + if ( encryptflag != 0 && bits256_nonz(addr->pubkey) != 0 ) + { + void *ptr; uint8_t *cipher,space[8192]; int32_t cipherlen; bits256 privkey; + cmd[6] = 'e', cmd[7] = 't'; + memset(privkey.bytes,0,sizeof(privkey)); + if ( (cipher= SuperNET_ciphercalc(&ptr,&cipherlen,&privkey,&addr->pubkey,data,datalen,space,sizeof(space))) != 0 ) + { + if ( (val= iguana_queue_send(addr,delaymillis,&cipher[-sizeof(struct iguana_msghdr)],cmd,cipherlen)) >= cipherlen ) + n++; + if ( ptr != 0 ) + free(ptr); + } + } + else + { + cmd[6] = 'E', cmd[7] = 'T'; + if ( (val= iguana_queue_send(addr,delaymillis,&data[-sizeof(struct iguana_msghdr)],cmd,datalen)) >= datalen ) + { + alreadysent[n++] = (uint32_t)addr->ipbits; + if ( n >= IGUANA_MAXPEERS*IGUANA_MAXCOINS ) + break; + } + } + if ( destipaddr != 0 || (fanout > 0 && n >= fanout) ) + { + free(alreadysent); + return(val); + } + else if ( val > retval ) + retval = val; + } + } + } + if ( n >= IGUANA_MAXPEERS*IGUANA_MAXCOINS ) + break; + } + //portable_mutex_unlock(&Allcoins_mutex); + free(alreadysent); + return(n); +} + +void basilisk_p2p(void *_myinfo,void *_addr,char *senderip,uint8_t *data,int32_t datalen,char *type,int32_t encrypted) +{ + uint32_t ipbits,basilisktag; int32_t msglen,len=0; void *ptr = 0; uint8_t space[8192]; bits256 senderpub; struct supernet_info *myinfo = _myinfo; + if ( encrypted != 0 ) + { + printf("encrypted p2p\n"); + memset(senderpub.bytes,0,sizeof(senderpub)); + if ( (data= SuperNET_deciphercalc(&ptr,&msglen,myinfo->privkey,senderpub,data,datalen,space,sizeof(space))) == 0 ) + { + printf("basilisk_p2p decrytion error\n"); + return; + } else datalen = msglen; + } + if ( senderip != 0 && senderip[0] != 0 && strcmp(senderip,"127.0.0.1") != 0 ) + ipbits = (uint32_t)calc_ipbits(senderip); + else ipbits = 0; + len += iguana_rwnum(0,data,sizeof(basilisktag),&basilisktag); + //int32_t i; for (i=0; ireceived.%d basilisk_p2p.(%s) from %s tag.%d\n",datalen,type,senderip!=0?senderip:"?",basilisktag); + basilisk_msgprocess(myinfo,_addr,ipbits,type,basilisktag,&data[len],datalen - len); + if ( ptr != 0 ) + free(ptr); +} + +void basilisk_sendback(struct supernet_info *myinfo,char *origCMD,char *symbol,char *remoteaddr,uint32_t basilisktag,char *retstr) +{ + uint8_t *data,space[4096],*allocptr; struct iguana_info *virt; cJSON *valsobj; int32_t datalen,encryptflag=0,delaymillis=0; + //printf("%s retstr.(%s) -> remote.(%s) basilisktag.%u\n",origCMD,retstr,remoteaddr,basilisktag); + if ( retstr != 0 && remoteaddr != 0 && remoteaddr[0] != 0 && strcmp(remoteaddr,"127.0.0.1") != 0 ) + { + if ( (valsobj= cJSON_Parse(retstr)) != 0 ) + { + jaddstr(valsobj,"origcmd",origCMD); + jaddstr(valsobj,"symbol",symbol); + if ( (virt= iguana_coinfind(symbol)) != 0 ) + { + jaddnum(valsobj,"hwm",virt->blocks.hwmchain.height); + jaddbits256(valsobj,"chaintip",virt->blocks.hwmchain.RO.hash2); + } + data = basilisk_jsondata(sizeof(struct iguana_msghdr),&allocptr,space,sizeof(space),&datalen,symbol,valsobj,basilisktag); + basilisk_sendcmd(myinfo,remoteaddr,"RET",&basilisktag,encryptflag,delaymillis,data,datalen,0,0); + if ( allocptr != 0 ) + free(allocptr); + free_json(valsobj); + } + } +} + +char *basilisk_waitresponse(struct supernet_info *myinfo,char *CMD,char *symbol,char *remoteaddr,struct basilisk_item *Lptr,struct basilisk_item *ptr) +{ + char *retstr = 0; + if ( ptr == Lptr ) + { + if ( (retstr= Lptr->retstr) == 0 ) + retstr = clonestr("{\"result\":\"null return from local basilisk_issuecmd\"}"); + ptr = basilisk_itemcreate(myinfo,CMD,symbol,Lptr->basilisktag,Lptr->numrequired,Lptr->vals,OS_milliseconds() - Lptr->expiration,Lptr->metricfunc); + queue_enqueue("submitQ",&myinfo->basilisks.submitQ,&ptr->DL,0); + } + else + { + queue_enqueue("submitQ",&myinfo->basilisks.submitQ,&ptr->DL,0); + while ( OS_milliseconds() < ptr->expiration ) + { + //if ( (retstr= basilisk_iscomplete(ptr)) != 0 ) + if ( (retstr= ptr->retstr) != 0 ) + break; + usleep(50000); + } + if ( retstr == 0 ) + retstr = basilisk_finish(ptr,-1,"{\"error\":\"basilisk timeout\"}"); + } + basilisk_sendback(myinfo,CMD,symbol,remoteaddr,ptr->basilisktag,retstr); + return(retstr); +} + +struct basilisk_item *basilisk_issueremote(struct supernet_info *myinfo,int32_t *numsentp,char *CMD,char *symbol,int32_t blockflag,cJSON *valsobj,int32_t fanout,int32_t minresults,uint32_t basilisktag,int32_t timeoutmillis,void *_metricfunc,char *retstr,int32_t encryptflag,int32_t delaymillis,uint32_t nBits) +{ + struct basilisk_item *ptr; uint8_t *allocptr,*data,space[4096]; int32_t datalen; basilisk_metricfunc metricfunc = _metricfunc; + ptr = basilisk_itemcreate(myinfo,CMD,symbol,basilisktag,minresults,valsobj,timeoutmillis,metricfunc); + ptr->nBits = nBits; + *numsentp = 0; + if ( retstr != 0 ) + { + ptr->results[0] = ptr->retstr = retstr; + ptr->numresults = ptr->numrequired; + ptr->metrics[0] = (*metricfunc)(myinfo,ptr,retstr); + ptr->finished = (uint32_t)time(NULL); + } + else + { + data = basilisk_jsondata(sizeof(struct iguana_msghdr),&allocptr,space,sizeof(space),&datalen,symbol,valsobj,basilisktag); + *numsentp = ptr->numsent = basilisk_sendcmd(myinfo,0,CMD,&ptr->basilisktag,encryptflag,delaymillis,data,datalen,1,ptr->nBits); + if ( blockflag != 0 ) + queue_enqueue("submitQ",&myinfo->basilisks.submitQ,&ptr->DL,0); + else ptr->finished = (uint32_t)time(NULL); + if ( allocptr != 0 ) + free(allocptr); + } + return(ptr); +} + +struct basilisk_item *basilisk_requestservice(struct supernet_info *myinfo,char *CMD,int32_t blockflag,cJSON *valsobj,bits256 hash,uint8_t *data,int32_t datalen,uint32_t nBits) +{ + int32_t minresults,timeoutmillis,numsent,delaymillis,encryptflag,fanout; struct basilisk_item *ptr; char buf[4096],*symbol,*str = 0; struct iguana_info *virt,*btcd; + if ( (btcd= iguana_coinfind("BTCD")) != 0 && btcd->RELAYNODE != 0 ) + jaddnum(valsobj,"iamrelay",1); + basilisk_addhexstr(&str,valsobj,buf,sizeof(buf),data,datalen); + if ( bits256_cmp(hash,GENESIS_PUBKEY) != 0 && bits256_nonz(hash) != 0 ) + { + if ( jobj(valsobj,"hash") != 0 ) + jdelete(valsobj,"hash"); + jaddbits256(valsobj,"hash",hash); + } + if ( (minresults= jint(valsobj,"minresults")) <= 0 ) + minresults = 1; + if ( (timeoutmillis= jint(valsobj,"timeout")) == 0 ) + timeoutmillis = BASILISK_TIMEOUT; + if ( jobj(valsobj,"fanout") == 0 ) + fanout = 1; + else fanout = jint(valsobj,"fanout"); + if ( (symbol= jstr(valsobj,"coin")) != 0 || (symbol= jstr(valsobj,"symbol")) != 0 ) + { + if ( (virt= iguana_coinfind(symbol)) != 0 ) + { + jaddstr(valsobj,"symbol",symbol); + jaddnum(valsobj,"longest",virt->longestchain); + jaddnum(valsobj,"hwm",virt->blocks.hwmchain.height); + } + } + encryptflag = jint(valsobj,"encrypt"); + delaymillis = jint(valsobj,"delay"); + ptr = basilisk_issueremote(myinfo,&numsent,CMD,"BTCD",blockflag,valsobj,fanout,minresults,0,timeoutmillis,0,0,encryptflag,delaymillis,nBits); + return(ptr); +} + +char *basilisk_standardservice(char *CMD,struct supernet_info *myinfo,bits256 hash,cJSON *valsobj,char *hexstr,int32_t blockflag) // client side +{ + uint32_t nBits = 0; uint8_t space[8192],*allocptr=0,*data = 0; struct basilisk_item *ptr,Lptr; int32_t datalen = 0; cJSON *retjson; + retjson = cJSON_CreateObject(); + data = get_dataptr(BASILISK_HDROFFSET,&allocptr,&datalen,space,sizeof(space),hexstr); + ptr = basilisk_requestservice(myinfo,CMD,blockflag,valsobj,hash,data,datalen,nBits); + if ( allocptr != 0 ) + free(allocptr); + if ( ptr != 0 ) + { + if ( blockflag != 0 ) + { + if ( ptr->expiration <= OS_milliseconds() ) + ptr->expiration = OS_milliseconds() + BASILISK_TIMEOUT; + ptr->vals = jduplicate(valsobj); + strcpy(ptr->symbol,"BTCD"); + strcpy(ptr->CMD,CMD); + return(basilisk_waitresponse(myinfo,CMD,"BTCD",0,&Lptr,ptr)); + } + else if ( ptr->numsent > 0 ) + { + queue_enqueue("submitQ",&myinfo->basilisks.submitQ,&ptr->DL,0); + jaddstr(retjson,"result","success"); + jaddnum(retjson,"numsent",ptr->numsent); + } else jaddstr(retjson,"error","didnt find any nodes to send to"); + } else jaddstr(retjson,"error","couldnt create basilisk item"); + return(jprint(retjson,1)); +} + +#include "basilisk_bitcoin.c" +#include "basilisk_nxt.c" +#include "basilisk_ether.c" +#include "basilisk_waves.c" +#include "basilisk_lisk.c" +#include "basilisk_CMD.c" + +void basilisk_functions(struct iguana_info *coin,int32_t protocol) +{ + coin->protocol = protocol; + switch ( protocol ) + { + case IGUANA_PROTOCOL_BITCOIN: + coin->basilisk_balances = basilisk_bitcoinbalances; + coin->basilisk_rawtx = basilisk_bitcoinrawtx; + coin->basilisk_rawtxmetric = basilisk_bitcoin_rawtxmetric; + coin->basilisk_value = basilisk_bitcoinvalue; + coin->basilisk_valuemetric = basilisk_bitcoin_valuemetric; + break; + /*case IGUANA_PROTOCOL_IOTA: + coin->basilisk_balances = basilisk_iotabalances; + coin->basilisk_rawtx = basilisk_iotarawtx; + break; + case IGUANA_PROTOCOL_NXT: + coin->basilisk_balances = basilisk_nxtbalances; + coin->basilisk_rawtx = basilisk_nxtrawtx; + break; + case IGUANA_PROTOCOL_ETHER: + coin->basilisk_balances = basilisk_etherbalances; + coin->basilisk_rawtx = basilisk_etherrawtx; + break; + case IGUANA_PROTOCOL_WAVES: + coin->basilisk_balances = basilisk_wavesbalances; + coin->basilisk_rawtx = basilisk_wavesrawtx; + break; + case IGUANA_PROTOCOL_LISK: + coin->basilisk_balances = basilisk_liskbalances; + coin->basilisk_rawtx = basilisk_liskrawtx; + break;*/ + } +} + +int32_t basilisk_besti(struct basilisk_item *ptr) +{ + int32_t i,besti = -1; double metric,bestmetric=-1.; + for (i=0; inumresults; i++) + { + if ( (metric= ptr->metrics[i]) > 0. ) + { + if ( (ptr->metricdir < 0 && (bestmetric < 0. || metric < bestmetric)) || (ptr->metricdir > 0 && (bestmetric < 0. || metric > bestmetric)) || (ptr->metricdir == 0 && bestmetric < 0.) ) + { + bestmetric = metric; + besti = i; + } + } + } + if ( besti >= 0 ) + { + for (ptr->numexact=i=0; inumresults; i++) + if ( fabs(ptr->metrics[i] - bestmetric) < SMALLVAL ) + ptr->numexact++; + } + return(besti); +} + +char *basilisk_iscomplete(struct basilisk_item *ptr) +{ + int32_t i,numvalid,besti=-1; char *errstr = 0,*retstr = 0; + if ( ptr->childrendone < ptr->numchildren ) + return(0); + if ( ptr->retstr != 0 || ptr->finished != 0 ) + return(ptr->retstr); + if ( (numvalid= ptr->numresults) >= ptr->numrequired ) + { + for (i=numvalid=0; inumresults; i++) + { + if ( ptr->metrics[i] != 0. ) + numvalid++; + } + } + if ( numvalid < ptr->numrequired ) + { + //printf("%u: numvalid.%d < required.%d m %f\n",ptr->basilisktag,numvalid,ptr->numrequired,ptr->metrics[0]); + return(0); + } + if ( ptr->uniqueflag == 0 && ptr->numexact != ptr->numresults && ptr->numexact < (ptr->numresults >> 1) ) + besti = -1, errstr = "{\"error\":\"basilisk non-consensus results\"}"; + else besti = basilisk_besti(ptr), errstr = "{\"error\":\"basilisk no valid results\"}"; + //printf("%u complete besti.%d\n",ptr->basilisktag,besti); + retstr = basilisk_finish(ptr,besti,errstr); + //printf("%u besti.%d numexact.%d numresults.%d -> (%s)\n",ptr->basilisktag,besti,ptr->numexact,ptr->numresults,retstr); + return(retstr); +} + +struct basilisk_item *basilisk_issuecmd(struct basilisk_item *Lptr,basilisk_func func,basilisk_metricfunc metricfunc,struct supernet_info *myinfo,char *remoteaddr,uint32_t basilisktag,char *symbol,int32_t timeoutmillis,cJSON *vals) +{ + struct iguana_info *coin; struct basilisk_item *ptr; + memset(Lptr,0,sizeof(*Lptr)); + if ( (coin= iguana_coinfind(symbol)) != 0 ) + { + if ( func != 0 ) + { + if ( (ptr= (*func)(Lptr,myinfo,coin,remoteaddr,basilisktag,timeoutmillis,vals)) != 0 ) + { + if ( (ptr->metricfunc= metricfunc) != 0 ) + ptr->vals = jduplicate(vals); + strcpy(ptr->symbol,symbol); + ptr->basilisktag = basilisktag; + ptr->expiration = OS_milliseconds() + timeoutmillis; + return(ptr); + } else Lptr->retstr = clonestr("{\"error\":\"error issuing basilisk command\"}"); + } else Lptr->retstr = clonestr("{\"error\":\"null basilisk function\"}"); + } else Lptr->retstr = clonestr("{\"error\":\"error missing coin\"}"); + return(Lptr); +} + +char *basilisk_check(int32_t *timeoutmillisp,uint32_t *basilisktagp,char *symbol,cJSON *vals) +{ + if ( symbol != 0 && symbol[0] != 0 && vals != 0 ) + { + if ( *basilisktagp == 0 ) + *basilisktagp = rand(); + if ( (*timeoutmillisp= jint(vals,"timeout")) < 0 ) + *timeoutmillisp = BASILISK_TIMEOUT; + return(0); + } else return(clonestr("{\"error\":\"missing activecoin or vals\"}")); +} + +char *basilisk_standardcmd(struct supernet_info *myinfo,char *CMD,char *activecoin,char *remoteaddr,uint32_t basilisktag,cJSON *vals,basilisk_func func,basilisk_metricfunc metric) +{ + char *retstr; struct basilisk_item *ptr,Lptr; int32_t timeoutmillis; struct iguana_info *coin; + if ( (retstr= basilisk_check(&timeoutmillis,&basilisktag,activecoin,vals)) == 0 ) + { + if ( (coin= iguana_coinfind(activecoin)) != 0 ) + { + if ( (ptr= basilisk_issuecmd(&Lptr,func,metric,myinfo,remoteaddr,basilisktag,activecoin,timeoutmillis,vals)) != 0 ) + { + return(basilisk_waitresponse(myinfo,CMD,coin->symbol,remoteaddr,&Lptr,ptr)); + } + else return(clonestr("{\"error\":\"null return from basilisk_issuecmd\"}")); + } else return(clonestr("{\"error\":\"couldnt get coin\"}")); + } else return(retstr); +} + +char *_basilisk_value(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen) +{ + return(basilisk_standardcmd(myinfo,"VAL",coin->symbol,remoteaddr,basilisktag,valsobj,coin->basilisk_value,coin->basilisk_valuemetric)); +} + +char *_basilisk_balances(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen) +{ + return(basilisk_standardcmd(myinfo,"BAL",coin->symbol,remoteaddr,basilisktag,valsobj,coin->basilisk_balances,coin->basilisk_balancesmetric)); +} + +char *_basilisk_rawtx(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen) +{ + char *retstr,strbuf[4096],*str = 0; + printf("remote rawtx.(%s)\n",jprint(valsobj,0)); + basilisk_addhexstr(&str,valsobj,strbuf,sizeof(strbuf),data,datalen); + retstr = basilisk_rawtx(myinfo,coin,0,remoteaddr,basilisktag,valsobj,coin->symbol); + if ( str != 0 ) + free(str); + return(retstr); +} + +char *_basilisk_result(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen) +{ + char strbuf[4096],*str = 0; + basilisk_addhexstr(&str,valsobj,strbuf,sizeof(strbuf),data,datalen); + return(basilisk_result(myinfo,coin,0,remoteaddr,basilisktag,valsobj)); +} + +char *basilisk_checkrawtx(int32_t *timeoutmillisp,uint32_t *basilisktagp,char *symbol,cJSON *vals) +{ + cJSON *addresses=0; char *changeaddr,*spendscriptstr; int32_t i,n; + *timeoutmillisp = -1; + changeaddr = jstr(vals,"changeaddr"); + spendscriptstr = jstr(vals,"spendscript"); + addresses = jarray(&n,vals,"addresses"); + if ( addresses == 0 || changeaddr == 0 || changeaddr[0] == 0 ) + return(clonestr("{\"error\":\"invalid addresses[] or changeaddr\"}")); + else + { + for (i=0; isymbol); + if ( (retstr= basilisk_standardservice(CMD,myinfo,hash,vals,hexstr,0)) != 0 ) + free(retstr); + free_json(vals); + if ( allocptr != 0 ) + free(allocptr); + } + return(0); + } else return(-1); +} + +#include "../includes/iguana_apidefs.h" +#include "../includes/iguana_apideclares.h" + +INT_ARRAY_STRING(basilisk,balances,basilisktag,vals,activecoin) +{ + return(basilisk_standardcmd(myinfo,"BAL",activecoin,remoteaddr,basilisktag,vals,coin->basilisk_balances,coin->basilisk_balancesmetric)); +} + +INT_ARRAY_STRING(basilisk,value,basilisktag,vals,activecoin) +{ + return(basilisk_standardcmd(myinfo,"VAL",activecoin,remoteaddr,basilisktag,vals,coin->basilisk_value,coin->basilisk_valuemetric)); +} + +INT_ARRAY_STRING(basilisk,rawtx,basilisktag,vals,activecoin) +{ + char *retstr; struct basilisk_item *ptr,Lptr; int32_t timeoutmillis; + if ( (retstr= basilisk_checkrawtx(&timeoutmillis,(uint32_t *)&basilisktag,activecoin,vals)) == 0 ) + { + coin = iguana_coinfind(activecoin); + if ( coin != 0 && (ptr= basilisk_issuecmd(&Lptr,coin->basilisk_rawtx,coin->basilisk_rawtxmetric,myinfo,remoteaddr,basilisktag,activecoin,timeoutmillis,vals)) != 0 ) + { + if ( (ptr->numrequired= juint(vals,"numrequired")) == 0 ) + ptr->numrequired = 1; + ptr->uniqueflag = 1; + ptr->metricdir = -1; + return(basilisk_waitresponse(myinfo,"RAW",coin->symbol,remoteaddr,&Lptr,ptr)); + } else return(clonestr("{\"error\":\"error issuing basilisk rawtx\"}")); + } else return(retstr); +} + +INT_AND_ARRAY(basilisk,result,basilisktag,vals) +{ + struct basilisk_item *ptr; + if ( vals != 0 ) + { + ptr = calloc(1,sizeof(*ptr)); + ptr->retstr = jprint(vals,0); + ptr->basilisktag = basilisktag; + strcpy(ptr->remoteaddr,remoteaddr); + safecopy(ptr->CMD,jstr(vals,"origcmd"),sizeof(ptr->CMD)); + printf("(%s) -> Q.%u results vals.(%s)\n",ptr->CMD,basilisktag,ptr->retstr); + queue_enqueue("resultsQ",&myinfo->basilisks.resultsQ,&ptr->DL,0); + return(clonestr("{\"result\":\"queued basilisk return\"}")); + } else printf("null vals.(%s) or no hexmsg.%p\n",jprint(vals,0),vals); + return(clonestr("{\"error\":\"no hexmsg to return\"}")); +} + +HASH_ARRAY_STRING(basilisk,addrelay,hash,vals,hexstr) +{ + return(basilisk_standardservice("ADD",myinfo,hash,vals,hexstr,1)); +} + +HASH_ARRAY_STRING(basilisk,relays,hash,vals,hexstr) +{ + return(basilisk_standardservice("RLY",myinfo,hash,vals,hexstr,1)); +} + +HASH_ARRAY_STRING(basilisk,dispatch,hash,vals,hexstr) +{ + return(basilisk_standardservice("RUN",myinfo,hash,vals,hexstr,1)); +} + +HASH_ARRAY_STRING(basilisk,publish,hash,vals,hexstr) +{ + return(basilisk_standardservice("PUB",myinfo,hash,vals,hexstr,1)); +} + +HASH_ARRAY_STRING(basilisk,subscribe,hash,vals,hexstr) +{ + return(basilisk_standardservice("SUB",myinfo,hash,vals,hexstr,1)); +} + +HASH_ARRAY_STRING(basilisk,forward,hash,vals,hexstr) +{ + return(basilisk_standardservice("HOP",myinfo,hash,vals,hexstr,0)); +} + +HASH_ARRAY_STRING(basilisk,mailbox,hash,vals,hexstr) +{ + return(basilisk_standardservice("BOX",myinfo,hash,vals,hexstr,1)); +} + +HASH_ARRAY_STRING(basilisk,VPNcreate,hash,vals,hexstr) +{ + return(basilisk_standardservice("VPN",myinfo,hash,vals,hexstr,1)); +} + +HASH_ARRAY_STRING(basilisk,VPNjoin,hash,vals,hexstr) +{ + return(basilisk_standardservice("ARC",myinfo,hash,vals,hexstr,1)); +} + +HASH_ARRAY_STRING(basilisk,VPNmessage,hash,vals,hexstr) +{ + return(basilisk_standardservice("GAB",myinfo,hash,vals,hexstr,0)); +} + +HASH_ARRAY_STRING(basilisk,VPNbroadcast,hash,vals,hexstr) +{ + return(basilisk_standardservice("SAY",myinfo,hash,vals,hexstr,0)); +} + +HASH_ARRAY_STRING(basilisk,VPNreceive,hash,vals,hexstr) +{ + return(basilisk_standardservice("EAR",myinfo,hash,vals,hexstr,1)); +} + +HASH_ARRAY_STRING(basilisk,VPNlogout,hash,vals,hexstr) +{ + return(basilisk_standardservice("END",myinfo,hash,vals,hexstr,0)); +} + +#include "../includes/iguana_apiundefs.h" + +// set hwm, get headers, then blocks + +void basilisk_geckoresult(struct supernet_info *myinfo,struct basilisk_item *ptr) +{ + uint8_t *data,space[16384],*allocptr = 0; struct iguana_info *virt; char *symbol,*str,*type; int32_t datalen; cJSON *retjson; bits256 hash2; + if ( (retjson= cJSON_Parse(ptr->retstr)) != 0 ) + { + if ( (symbol= jstr(retjson,"symbol")) != 0 && (virt= iguana_coinfind(symbol)) != 0 ) + { + if ( (data= get_dataptr(0,&allocptr,&datalen,space,sizeof(space),jstr(retjson,"data"))) != 0 ) + { + str = 0; + if ( (type= jstr(retjson,"type")) != 0 ) + { + hash2 = jbits256(retjson,"hash"); + if ( strcmp(type,"HDR") == 0 ) + str = gecko_headersarrived(myinfo,virt,ptr->remoteaddr,data,datalen,hash2); + else if ( strcmp(type,"MEM") == 0 ) + str = gecko_mempoolarrived(myinfo,virt,ptr->remoteaddr,data,datalen,hash2); + else if ( strcmp(type,"BLK") == 0 ) + str = gecko_blockarrived(myinfo,virt,ptr->remoteaddr,data,datalen,hash2); + else if ( strcmp(type,"GTX") == 0 ) + str = gecko_txarrived(myinfo,virt,ptr->remoteaddr,data,datalen,hash2); + } + if ( str != 0 ) + free(str); + if ( allocptr != 0 ) + free(allocptr); + } + } + free_json(retjson); + } +} + +void basilisk_pending_result(struct supernet_info *myinfo,struct basilisk_item *ptr,struct basilisk_item *pending) +{ + int32_t n; struct basilisk_item *parent; basilisk_metricfunc metricfunc; + if ( (n= pending->numresults) < sizeof(pending->results)/sizeof(*pending->results) ) + { + pending->numresults++; + if ( (metricfunc= pending->metricfunc) == 0 ) + pending->metrics[n] = n + 1; + else if ( (pending->metrics[n]= (*metricfunc)(myinfo,pending,ptr->retstr)) != 0. ) + pending->childrendone++; + printf("%s.%u Add results[%d] <- metric %f\n",pending->CMD,pending->basilisktag,n,pending->metrics[n]); + pending->results[n] = ptr->retstr, ptr->retstr = 0; + /*if ( strcmp(ptr->CMD,"SEQ") == 0 ) + { + if ( (retjson= cJSON_Parse(ptr->retstr)) != 0 ) + { + gecko_seqresult(myinfo,ptr->retstr); + free_json(retjson); + } + } + else*/ + if ( strcmp(ptr->CMD,"RET") == 0 || strcmp(ptr->CMD,"GET") == 0 ) + { + printf("got return for tag.%d parent.%p\n",pending->basilisktag,pending->parent); + if ( (parent= pending->parent) != 0 ) + { + pending->parent = 0; + parent->childrendone++; + } + if ( strcmp(ptr->CMD,"GET") == 0 ) + basilisk_geckoresult(myinfo,ptr); + } + } +} + +int32_t basilisk_issued_iteration(struct supernet_info *myinfo,struct basilisk_item *pending) +{ + basilisk_metricfunc metricfunc; struct basilisk_item *parent; int32_t i,flag = 0; + //printf("pending.%u numresults.%d m %f func.%p\n",pending->basilisktag,pending->numresults,pending->metrics[0],pending->metricfunc); + if ( (metricfunc= pending->metricfunc) != 0 ) + { + for (i=0; inumresults; i++) + if ( pending->metrics[i] == 0. && pending->results[i] != 0 ) + { + if ( (pending->metrics[i]= (*metricfunc)(myinfo,pending,pending->results[i])) != 0 ) + pending->childrendone++; + // printf("iter.%d %p.[%d] poll metrics.%u metric %f\n",iter,pending,i,pending->basilisktag,pending->metrics[i]); + flag++; + } + } + basilisk_iscomplete(pending); + if ( OS_milliseconds() > pending->expiration ) + { + if ( pending->finished == 0 ) + { + if ( (parent= pending->parent) != 0 ) + { + pending->parent = 0; + parent->childrendone++; + } + pending->finished = (uint32_t)time(NULL); + if ( pending->retstr == 0 ) + pending->retstr = clonestr("{\"error\":\"basilisk timeout\"}"); + fprintf(stderr,"timeout.%s call metrics.%u lag %f - %f\n",pending->CMD,pending->basilisktag,OS_milliseconds(),pending->expiration); + for (i=0; inumresults; i++) + if ( (metricfunc= pending->metricfunc) != 0 && pending->metrics[i] == 0. ) + pending->metrics[i] = (*metricfunc)(myinfo,pending,pending->results[i]); + flag++; + } + } + //fprintf(stderr,"c"); + if ( pending->finished != 0 && time(NULL) > pending->finished+60 ) + { + if ( pending->dependents == 0 || pending->childrendone >= pending->numchildren ) + { + HASH_DELETE(hh,myinfo->basilisks.issued,pending); + if ( pending->dependents != 0 ) + free(pending->dependents); + fprintf(stderr,"HASH_DELETE free ptr.%u refcount.%d\n",pending->basilisktag,pending->refcount); + for (i=0; inumresults; i++) + if ( pending->results[i] != 0 ) + free(pending->results[i]), pending->results[i] = 0; + if ( pending->vals != 0 ) + free_json(pending->vals), pending->vals = 0; + free(pending); + flag++; + } + } + return(flag); +} + +void basilisks_loop(void *arg) +{ + struct iguana_info *btcd,*virt,*hhtmp; struct basilisk_item *ptr,*tmp,*pending; int32_t iter,maxmillis,flag; struct supernet_info *myinfo = arg; + iter = 0; + while ( 1 ) + { + iter++; + if ( (ptr= queue_dequeue(&myinfo->basilisks.submitQ,0)) != 0 ) + HASH_ADD(hh,myinfo->basilisks.issued,basilisktag,sizeof(ptr->basilisktag),ptr); + //fprintf(stderr,"A"); + else if ( (ptr= queue_dequeue(&myinfo->basilisks.resultsQ,0)) != 0 ) + { + HASH_FIND(hh,myinfo->basilisks.issued,&ptr->basilisktag,sizeof(ptr->basilisktag),pending); + if ( pending != 0 ) + basilisk_pending_result(myinfo,ptr,pending); + else printf("couldnt find issued.%u\n",ptr->basilisktag); + free(ptr); + } + else + { + flag = 0; + HASH_ITER(hh,myinfo->basilisks.issued,pending,tmp) + { + flag += basilisk_issued_iteration(myinfo,pending); + } + if ( flag == 0 && myinfo->allcoins_numvirts > 0 && (btcd= iguana_coinfind("BTCD")) != 0 ) + { + maxmillis = (1000 / myinfo->allcoins_numvirts) + 1; + //portable_mutex_lock(&Allcoins_mutex); + HASH_ITER(hh,myinfo->allcoins,virt,hhtmp) + { + if ( virt->started != 0 && virt->active != 0 && virt->virtualchain != 0 ) + { + //fprintf(stderr,"h"); + gecko_iteration(myinfo,btcd,virt,maxmillis); + flag++; + } + } + //portable_mutex_unlock(&Allcoins_mutex); + } + } + //fprintf(stderr,"i "); + //for (i=0; iRELAYNODE == 0 && coin->VALIDATENODE == 0 && coin->active != 0 && coin->chain->userpass[0] != 0 && coin->MAXPEERS == 1 ) + // basilisk_bitcoinscan(coin,blockspace,&RAWMEM); + if ( flag == 0 ) + usleep(10000); + } +} + +void basilisks_init(struct supernet_info *myinfo) +{ + iguana_initQ(&myinfo->basilisks.submitQ,"submitQ"); + iguana_initQ(&myinfo->basilisks.resultsQ,"resultsQ"); + portable_mutex_init(&myinfo->allcoins_mutex); + portable_mutex_init(&myinfo->basilisk_mutex); + portable_mutex_init(&myinfo->gecko_mutex); + myinfo->basilisks.launched = iguana_launch(iguana_coinfind("BTCD"),"basilisks_loop",basilisks_loop,myinfo,IGUANA_PERMTHREAD); +} + +void basilisk_wait(struct supernet_info *myinfo,struct iguana_info *coin) +{ + if ( coin != 0 ) + { + while ( coin->basilisk_busy != 0 ) + usleep(1000); + } + else + { + while ( myinfo->basilisk_busy != 0 ) + usleep(1000); + } +} + +void basilisk_msgprocess(struct supernet_info *myinfo,void *_addr,uint32_t senderipbits,char *type,uint32_t basilisktag,uint8_t *data,int32_t datalen) +{ + cJSON *valsobj; char *symbol,*retstr=0,remoteaddr[64],CMD[4],cmd[4]; int32_t height,origlen,from_basilisk,i,timeoutmillis,flag,numrequired,jsonlen; uint8_t *origdata; struct iguana_info *coin=0; bits256 hash; struct iguana_peer *addr = _addr; + static basilisk_servicefunc *basilisk_services[][2] = + { + { (void *)"RUN", &basilisk_respond_dispatch }, // higher level protocol handler, pass through + { (void *)"BYE", &basilisk_respond_goodbye }, // disconnect + + // gecko chains + { (void *)"NEW", &basilisk_respond_newgeckochain }, // creates new virtual gecko chain + { (void *)"GEN", &basilisk_respond_geckogenesis }, // returns genesis list + { (void *)"GET", &basilisk_respond_geckoget }, // requests headers, block or tx + { (void *)"HDR", &basilisk_respond_geckoheaders }, // reports headers + { (void *)"BLK", &basilisk_respond_geckoblock }, // reports block + { (void *)"MEM", &basilisk_respond_mempool }, // reports mempool + { (void *)"GTX", &basilisk_respond_geckotx }, // reports tx + //{ (void *)"SEQ", &basilisk_respond_hashstamps }, // BTCD and BTC recent hashes from timestamp + + // unencrypted low level functions, used by higher level protocols and virtual network funcs + { (void *)"ADD", &basilisk_respond_addrelay }, // relays register with each other bus + { (void *)"RLY", &basilisk_respond_relays }, + { (void *)"DEX", &basilisk_respond_instantdex }, + + // encrypted data for jumblr + { (void *)"HOP", &basilisk_respond_forward }, // message forwarding + { (void *)"BOX", &basilisk_respond_mailbox }, // create/send/check mailbox pubkey + + // small virtual private network + { (void *)"VPN", &basilisk_respond_VPNcreate }, // create virtual network's hub via privkey + { (void *)"ARC", &basilisk_respond_VPNjoin }, // join + { (void *)"GAB", &basilisk_respond_VPNmessage }, // private message + { (void *)"SAY", &basilisk_respond_VPNbroadcast }, // broadcast + { (void *)"EAR", &basilisk_respond_VPNreceive }, // network receive (via poll) + { (void *)"END", &basilisk_respond_VPNlogout }, // logout + + // coin services + { (void *)"RAW", &_basilisk_rawtx }, + { (void *)"VAL", &_basilisk_value }, + }; + /*static basilisk_coinfunc *basilisk_coinservices[][2] = + { + { (void *)"RAW", &_basilisk_rawtx }, + { (void *)"VAL", &_basilisk_value }, + { (void *)"BAL", &_basilisk_balances }, + };*/ + symbol = "BTCD"; + if ( (valsobj= cJSON_Parse((char *)data)) != 0 ) + { + //printf("MSGVALS.(%s)\n",(char *)data); + if ( jobj(valsobj,"coin") != 0 ) + coin = iguana_coinfind(jstr(valsobj,"coin")); + else if ( jobj(valsobj,"symbol") != 0 ) + coin = iguana_coinfind(jstr(valsobj,"symbol")); + if ( coin != 0 ) + { + if ( (height= juint(valsobj,"hwm")) > 0 ) + { + if ( height > addr->height ) + addr->height = height; + if ( height > coin->longestchain ) + coin->longestchain = height; + } + } + if ( strcmp(type,"RET") == 0 ) + { + if ( (retstr= _basilisk_result(myinfo,coin,addr,remoteaddr,basilisktag,valsobj,data,datalen)) != 0 ) + free(retstr); + return; + } + } else return; + for (i=flag=0; ibasilisk_busy = 1; + if ( valsobj != 0 ) + { + jsonlen = (int32_t)strlen((char *)data) + 1; + if ( datalen > jsonlen ) + data += jsonlen, datalen -= jsonlen; + else data = 0, datalen = 0; + if ( coin == 0 ) + coin = iguana_coinfind("BTCD"); + if ( coin != 0 ) + { + symbol = coin->symbol; + coin->basilisk_busy = 1; + } + hash = jbits256(valsobj,"hash"); + timeoutmillis = jint(valsobj,"timeout"); + if ( (numrequired= jint(valsobj,"numrequired")) == 0 ) + numrequired = 1; + if ( senderipbits != 0 ) + expand_ipbits(remoteaddr,senderipbits); + else remoteaddr[0] = 0; + /*if ( valsobj != 0 && remoteaddr != 0 ) + { + if ( from_basilisk == 0 ) + { + if ( strcmp(CMD,"RLY") == 0 ) + { + printf("add relay path\n"); + if ( juint(valsobj,"iamrelay") != 0 ) + { + retstr = basilisk_respond_relays(myinfo,type,addr,remoteaddr,basilisktag,valsobj,data,datalen,hash,from_basilisk); + } + free_json(valsobj); + if ( coin != 0 ) + coin->basilisk_busy = 0; + myinfo->basilisk_busy = 0; + return; + } + else if ( (retstr= basilisk_addrelay_info(myinfo,0,(uint32_t)calc_ipbits(remoteaddr),GENESIS_PUBKEY)) != 0 ) + free(retstr); + } + }*/ + for (i=0; iIAMRELAY != 0 ) // iguana node + { + if ( 0 && from_basilisk != 0 ) + { + printf("echo to other relays\n"); + basilisk_sendcmd(myinfo,0,cmd,&basilisktag,0,0,origdata,origlen,-1,0); // to other iguanas + } + if ( (retstr= (*basilisk_services[i][1])(myinfo,type,addr,remoteaddr,basilisktag,valsobj,data,datalen,hash,from_basilisk)) != 0 ) + { + //printf("from_basilisk.%d ret.(%s)\n",from_basilisk,retstr); + if ( from_basilisk != 0 || strcmp(CMD,"GET") == 0 ) + basilisk_sendback(myinfo,CMD,symbol,remoteaddr,basilisktag,retstr); + if ( retstr != 0 ) + free(retstr); + } //else printf("services null return\n"); + } else printf("non-relay got unexpected.(%s)\n",type); + /*free_json(valsobj); + if ( coin != 0 ) + coin->basilisk_busy = 0; + myinfo->basilisk_busy = 0; + return;*/ + } + } + /*if ( coin != 0 ) + { + if ( coin->RELAYNODE != 0 || coin->VALIDATENODE != 0 ) // iguana node + { + if ( 0 && from_basilisk != 0 ) + { + printf("echo to other relays\n"); + basilisk_sendcmd(myinfo,0,cmd,&basilisktag,0,0,origdata,origlen,-1,0); // to other iguanas + } + for (i=0; ibasilisk_busy = 0; + myinfo->basilisk_busy = 0; +} + + diff --git a/basilisk/basilisk.c b/basilisk/basilisk.c new file mode 100755 index 000000000..28c03de01 --- /dev/null +++ b/basilisk/basilisk.c @@ -0,0 +1,974 @@ +/****************************************************************************** + * Copyright © 2014-2016 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#include "../iguana/iguana777.h" + +typedef char *basilisk_servicefunc(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk); + +int32_t basilisk_specialcmd(char *cmd) +{ + //&& strcmp(cmd,"DEX") != 0 && strcmp(cmd,"ACC") != 0 && strcmp(cmd,"RID") != 0 && + if ( strcmp(cmd,"PIN") != 0 && strcmp(cmd,"OUT") != 0 && strcmp(cmd,"MSG") != 0 ) + return(0); + else return(1); +} + +/*int32_t basilisk_specialrelay_CMD(char *CMD) +{ + if ( strcmp(CMD,"OUT") == 0 || strcmp(CMD,"MSG") == 0 || strcmp(CMD,"BLK") == 0 || strcmp(CMD,"MEM") == 0 || strcmp(CMD,"GTX") == 0 || strcmp(CMD,"RID") == 0 ) + return(1); + else return(0); +}*/ + +uint32_t basilisk_calcnonce(struct supernet_info *myinfo,uint8_t *data,int32_t datalen,uint32_t nBits) +{ + int32_t i,numiters = 0; bits256 hash,hash2,threshold; uint32_t basilisktag; + vcalc_sha256(0,hash.bytes,data,datalen); + if ( nBits >= GECKO_EASIESTDIFF ) + threshold = bits256_from_compact(GECKO_EASIESTDIFF); + else threshold = bits256_from_compact(nBits); + for (i=0; i 0 ) + break; + } + iguana_rwnum(0,(void *)hash.uints,sizeof(basilisktag),&basilisktag); + iguana_rwnum(1,&data[-sizeof(basilisktag)],sizeof(basilisktag),&basilisktag); + char str[65],str2[65]; printf("found hash after numiters.%d %s vs %s basilisktag.%u\n",numiters,bits256_str(str,threshold),bits256_str(str2,hash2),basilisktag); + return(basilisktag); +} + +char *basilisk_addhexstr(char **ptrp,cJSON *valsobj,char *strbuf,int32_t strsize,uint8_t *data,int32_t datalen) +{ + *ptrp = 0; + if ( data != 0 && datalen > 0 ) + { + if ( valsobj != 0 && jobj(valsobj,"data") != 0 ) + { + printf("basilisk_addhexstr warning: already have data object\n"); + jdelete(valsobj,"data"); + } + if ( (datalen<<1)+1 > strsize ) + { + strbuf = calloc(1,(datalen << 1) + 1); + *ptrp = (void *)strbuf; + } + init_hexbytes_noT(strbuf,data,datalen); + if ( valsobj != 0 ) + jaddstr(valsobj,"data",strbuf); + } else return(0); + return(strbuf); +} + +uint8_t *get_dataptr(int32_t hdroffset,uint8_t **ptrp,int32_t *datalenp,uint8_t *space,int32_t spacesize,char *hexstr) +{ + *ptrp = 0; uint8_t *data = 0; + if ( hexstr != 0 && (*datalenp= is_hexstr(hexstr,0)) > 0 ) + { + *datalenp >>= 1; + if ( (*datalenp+hdroffset) <= spacesize ) + { + memset(space,0,hdroffset); + data = &space[hdroffset]; + } else *ptrp = data = calloc(1,*datalenp + hdroffset); + decode_hex(&data[hdroffset],*datalenp,hexstr); + } + if ( data != 0 ) + return(&data[hdroffset]); + else return(data); +} + +uint8_t *basilisk_jsondata(int32_t extraoffset,uint8_t **ptrp,uint8_t *space,int32_t spacesize,int32_t *datalenp,char *symbol,cJSON *sendjson,uint32_t basilisktag) +{ + char *sendstr,*hexstr=0; uint8_t *data,hexspace[4096],*allocptr=0,*hexdata; int32_t datalen,hexlen=0; + if ( jobj(sendjson,"symbol") == 0 ) + jaddstr(sendjson,"symbol",symbol); + if ( (hexstr= jstr(sendjson,"data")) != 0 ) + { + hexdata = get_dataptr(0,&allocptr,&hexlen,hexspace,sizeof(hexspace),hexstr); + //printf("jsondata.%s from sendjson\n",hexstr); + jdelete(sendjson,"data"); + } + *ptrp = 0; + sendstr = jprint(sendjson,0); + datalen = (int32_t)strlen(sendstr) + 1; + if ( (datalen + extraoffset + BASILISK_HDROFFSET + hexlen) <= spacesize ) + data = space; + else + { + data = calloc(1,datalen + extraoffset + BASILISK_HDROFFSET + hexlen); + *ptrp = data; + } + data += extraoffset + BASILISK_HDROFFSET; + memcpy(data,sendstr,datalen); + //printf("jsondata.(%s) + hexlen.%d\n",sendstr,hexlen); + free(sendstr); + if ( hexlen > 0 ) + { + //int32_t i; for (i=0; ibasilisktag = basilisktag; + if ( (ptr->numrequired= minresults) == 0 ) + ptr->numrequired = 1; + strcpy(ptr->CMD,CMD); + safecopy(ptr->symbol,symbol,sizeof(ptr->symbol)); + ptr->expiration = OS_milliseconds() + timeoutmillis; + return(ptr); +} + +int32_t basilisk_sendcmd(struct supernet_info *myinfo,char *destipaddr,char *type,uint32_t *basilisktagp,int32_t encryptflag,int32_t delaymillis,uint8_t *data,int32_t datalen,int32_t fanout,uint32_t nBits) // data must be offset by sizeof(iguana_msghdr)+sizeof(basilisktag) +{ + int32_t i,l,s,valid,val,n=0,retval = -1; char cmd[12]; struct iguana_info *coin,*tmp; struct iguana_peer *addr; bits256 hash; uint32_t *alreadysent,r,r2; + if ( fanout <= 0 ) + fanout = sqrt(NUMRELAYS) + 1; + else if ( fanout > BASILISK_MAXFANOUT ) + fanout = BASILISK_MAXFANOUT; + if ( type == 0 ) + type = "BTCD"; + if ( strlen(type) > 3 ) + { + printf("basilisk_sendcmd illegal type(%s)\n",type); + return(-1); + } + if ( destipaddr != 0 ) + { + if ( destipaddr[0] == 0 ) + destipaddr = 0; // broadcast + else if ( strcmp(destipaddr,"127.0.0.1") == 0 || strcmp(destipaddr,myinfo->ipaddr) == 0 ) + { + printf("return after locally basilisk_msgprocess\n"); + hash = GENESIS_PUBKEY; + basilisk_msgprocess(myinfo,0,0,type,*basilisktagp,data,datalen); + return(0); + } + } + alreadysent = calloc(IGUANA_MAXPEERS * IGUANA_MAXCOINS,sizeof(*alreadysent)); + iguana_rwnum(1,&data[-sizeof(*basilisktagp)],sizeof(*basilisktagp),basilisktagp); + if ( *basilisktagp == 0 ) + { + if ( nBits != 0 ) + *basilisktagp = basilisk_calcnonce(myinfo,data,datalen,nBits); + else *basilisktagp = rand(); + iguana_rwnum(1,&data[-sizeof(*basilisktagp)],sizeof(*basilisktagp),basilisktagp); + } + data -= sizeof(*basilisktagp), datalen += sizeof(*basilisktagp); + memset(cmd,0,sizeof(cmd)); + sprintf(cmd,"SuperNET%s",type); + //portable_mutex_lock(&myinfo->allcoins_mutex); + HASH_ITER(hh,myinfo->allcoins,coin,tmp) + { + if ( coin->peers == 0 ) + continue; + if ( coin->FULLNODE == 0 && coin->VALIDATENODE == 0 ) + cmd[0] = 's'; + else cmd[0] = 'S'; + r = rand() % (coin->peers->numranked+1); + for (l=0; lpeers->active[i]; + if ( addr->supernet != 0 || addr->basilisk != 0 ) + valid = 1; + else valid = 0; + if ( addr->usock >= 0 ) + { + s = 0; + if ( NUMRELAYS > 0 && basilisk_specialcmd(type) != 0 ) + { + OS_randombytes((void *)&r2,sizeof(r2)); + if ( (r2 % NUMRELAYS) >= sqrt(NUMRELAYS) ) + { + //printf("fanout.%d s.%d n.%d skip %s\n",fanout,s,n,addr->ipaddr); + continue; + } + for (s=0; sipbits != myinfo->myaddr.myipbits && RELAYS[s].ipbits == addr->ipbits ) + break; + if ( s == NUMRELAYS ) + { + //printf("skip non-relay.(%s)\n",addr->ipaddr); + continue; + } + //printf("send to other relay.(%s)\n",addr->ipaddr); + valid = 1; + } + for (s=0; sipbits ) + { + printf("already sent to %s\n",addr->ipaddr); + continue; + } + if ( s == n && valid == 1 && (destipaddr == 0 || strcmp(addr->ipaddr,destipaddr) == 0) ) + { + //printf("n.%d/fanout.%d i.%d l.%d [%s].tag%d send %s.(%s) [%x] datalen.%d addr->supernet.%u basilisk.%u to (%s).%d destip.%s\n",n,fanout,i,l,cmd,*(uint32_t *)data,type,(char *)&data[4],*(int32_t *)&data[datalen-4],datalen,addr->supernet,addr->basilisk,addr->ipaddr,addr->A.port,destipaddr!=0?destipaddr:"broadcast"); + if ( encryptflag != 0 && bits256_nonz(addr->pubkey) != 0 ) + { + void *ptr; uint8_t *cipher,space[8192]; int32_t cipherlen; bits256 privkey; + cmd[6] = 'e', cmd[7] = 't'; + memset(privkey.bytes,0,sizeof(privkey)); + if ( (cipher= SuperNET_ciphercalc(&ptr,&cipherlen,&privkey,&addr->pubkey,data,datalen,space,sizeof(space))) != 0 ) + { + if ( (val= iguana_queue_send(addr,delaymillis,&cipher[-sizeof(struct iguana_msghdr)],cmd,cipherlen)) >= cipherlen ) + alreadysent[n++] = (uint32_t)addr->ipbits; + if ( ptr != 0 ) + free(ptr); + } + } + else + { + cmd[6] = 'E', cmd[7] = 'T'; + if ( (val= iguana_queue_send(addr,delaymillis,&data[-sizeof(struct iguana_msghdr)],cmd,datalen)) >= datalen ) + { + alreadysent[n++] = (uint32_t)addr->ipbits; + if ( n >= IGUANA_MAXPEERS*IGUANA_MAXCOINS ) + break; + } + } + if ( destipaddr != 0 || (fanout > 0 && n >= fanout) ) + { + free(alreadysent); + return(val); + } + else if ( val > retval ) + retval = val; + } + } + } + if ( n >= IGUANA_MAXPEERS*IGUANA_MAXCOINS ) + break; + } + //portable_mutex_unlock(&myinfo->allcoins_mutex); + free(alreadysent); + return(n); +} + +void basilisk_sendback(struct supernet_info *myinfo,char *origCMD,char *symbol,char *remoteaddr,uint32_t basilisktag,char *retstr) +{ + uint8_t *data,space[4096],*allocptr; struct iguana_info *virt; cJSON *valsobj; int32_t datalen,encryptflag=0,delaymillis=0; + //printf("%s retstr.(%s) -> remote.(%s) basilisktag.%u\n",origCMD,retstr,remoteaddr,basilisktag); + if ( retstr != 0 && remoteaddr != 0 && remoteaddr[0] != 0 && strcmp(remoteaddr,"127.0.0.1") != 0 ) + { + if ( (valsobj= cJSON_Parse(retstr)) != 0 ) + { + jaddstr(valsobj,"origcmd",origCMD); + jaddstr(valsobj,"symbol",symbol); + if ( myinfo->ipaddr[0] != 0 ) + jaddstr(valsobj,"relay",myinfo->ipaddr); + jaddnum(valsobj,"timestamp",(uint32_t)time(NULL)); + if ( (virt= iguana_coinfind(symbol)) != 0 ) + { + jaddnum(valsobj,"hwm",virt->blocks.hwmchain.height); + jaddbits256(valsobj,"chaintip",virt->blocks.hwmchain.RO.hash2); + } + data = basilisk_jsondata(sizeof(struct iguana_msghdr),&allocptr,space,sizeof(space),&datalen,symbol,valsobj,basilisktag); + //printf("sendback.%d -> %s\n",datalen,remoteaddr); + basilisk_sendcmd(myinfo,remoteaddr,"RET",&basilisktag,encryptflag,delaymillis,data,datalen,0,0); + if ( allocptr != 0 ) + free(allocptr); + free_json(valsobj); + } + } +} + +struct basilisk_item *basilisk_issueremote(struct supernet_info *myinfo,struct iguana_peer *addr,int32_t *numsentp,char *CMD,char *symbol,int32_t blockflag,cJSON *valsobj,int32_t fanout,int32_t minresults,uint32_t basilisktag,int32_t timeoutmillis,void *deprecated_dontuse,char *retstr,int32_t encryptflag,int32_t delaymillis,uint32_t nBits) +{ + struct basilisk_item *pending; uint8_t *allocptr,*data,space[4096]; int32_t datalen; cJSON *retarray; + pending = basilisk_itemcreate(myinfo,CMD,symbol,basilisktag,minresults,valsobj,timeoutmillis,0); + pending->nBits = nBits; + *numsentp = 0; + if ( retstr != 0 ) + { + pending->retstr = retstr; + pending->numresults = pending->numrequired; + } + else + { + valsobj = jduplicate(valsobj); + data = basilisk_jsondata(sizeof(struct iguana_msghdr),&allocptr,space,sizeof(space),&datalen,symbol,valsobj,basilisktag); + free_json(valsobj), valsobj = 0; + *numsentp = pending->numsent = basilisk_sendcmd(myinfo,addr != 0 ? addr->ipaddr : 0,CMD,&pending->basilisktag,encryptflag,delaymillis,data,datalen,fanout,pending->nBits); + if ( blockflag != 0 ) + { + portable_mutex_lock(&myinfo->basilisk_mutex); + //printf("HASH_ADD.%p\n",pending); + HASH_ADD(hh,myinfo->basilisks.issued,basilisktag,sizeof(basilisktag),pending); + portable_mutex_unlock(&myinfo->basilisk_mutex); + //queue_enqueue("issuedQ",&myinfo->basilisks.issued,&pending->DL,0); + if ( pending->expiration <= OS_milliseconds() ) + pending->expiration = OS_milliseconds() + BASILISK_TIMEOUT; + //ptr->vals = jduplicate(valsobj); + strcpy(pending->symbol,"BTCD"); + strcpy(pending->CMD,CMD); + while ( OS_milliseconds() < pending->expiration ) + { + if ( pending->numresults >= pending->numrequired )//|| (retstr= pending->retstr) != 0 ) + { + //printf("numresults.%d vs numrequired.%d\n",pending->numresults,pending->numrequired); + break; + } + usleep(10000); + } + if ( (retarray= pending->retarray) != 0 ) + { + pending->retstr = jprint(retarray,0); + pending->retarray = 0; + free_json(retarray); + } + //return(basilisk_waitresponse(myinfo,CMD,"BTCD",0,&Lptr,valsobj,ptr)); + } else free(pending), pending = 0; //ptr->finished = (uint32_t)time(NULL); + if ( allocptr != 0 ) + free(allocptr); + } + return(pending); +} + +struct basilisk_item *basilisk_requestservice(struct supernet_info *myinfo,struct iguana_peer *addr,char *CMD,int32_t blockflag,cJSON *valsobj,bits256 hash,uint8_t *data,int32_t datalen,uint32_t nBits) +{ + int32_t minfanout,numrequired,timeoutmillis,numsent,delaymillis,encryptflag,fanout; struct basilisk_item *ptr; char buf[4096],*symbol,*str = 0; struct iguana_info *virt; + //printf("request.(%s)\n",jprint(valsobj,0)); + basilisk_addhexstr(&str,valsobj,buf,sizeof(buf),data,datalen); + if ( bits256_cmp(hash,GENESIS_PUBKEY) != 0 && bits256_nonz(hash) != 0 ) + { + if ( jobj(valsobj,"hash") != 0 ) + jdelete(valsobj,"hash"); + jaddbits256(valsobj,"hash",hash); + } + if ( (numrequired= jint(valsobj,"numrequired")) <= 0 ) + numrequired = sqrt(NUMRELAYS); + if ( (timeoutmillis= jint(valsobj,"timeout")) == 0 ) + timeoutmillis = BASILISK_TIMEOUT; + minfanout = sqrt(NUMRELAYS)+1; + if ( jobj(valsobj,"fanout") == 0 ) + fanout = minfanout; + else fanout = jint(valsobj,"fanout"); + if ( fanout < minfanout ) + fanout = minfanout; + if ( (symbol= jstr(valsobj,"coin")) != 0 || (symbol= jstr(valsobj,"symbol")) != 0 ) + { + if ( (virt= iguana_coinfind(symbol)) != 0 ) + { + jaddstr(valsobj,"symbol",symbol); + jaddnum(valsobj,"longest",virt->longestchain); + jaddnum(valsobj,"hwm",virt->blocks.hwmchain.height); + } + } + if ( symbol == 0 ) + symbol = "BTCD"; + encryptflag = jint(valsobj,"encrypt"); + delaymillis = jint(valsobj,"delay"); + ptr = basilisk_issueremote(myinfo,addr,&numsent,CMD,symbol,blockflag,valsobj,fanout,numrequired,0,timeoutmillis,0,0,encryptflag,delaymillis,nBits); + return(ptr); +} + +char *basilisk_standardservice(char *CMD,struct supernet_info *myinfo,void *_addr,bits256 hash,cJSON *valsobj,char *hexstr,int32_t blockflag) // client side +{ + uint32_t nBits = 0; uint8_t space[4096],*allocptr=0,*data = 0; struct basilisk_item *ptr; int32_t datalen = 0; cJSON *retjson; char *retstr=0; + if ( RELAYID >= 0 && basilisk_specialcmd(CMD) == 0 ) + return(clonestr("{\"error\":\"unsupported special relay command\"}")); + data = get_dataptr(BASILISK_HDROFFSET,&allocptr,&datalen,space,sizeof(space),hexstr); + ptr = basilisk_requestservice(myinfo,_addr,CMD,blockflag,valsobj,hash,data,datalen,nBits); + if ( allocptr != 0 ) + free(allocptr); + if ( ptr != 0 ) + { + if ( ptr->retstr != 0 ) + retstr = ptr->retstr, ptr->retstr = 0; + else + { + retjson = cJSON_CreateObject(); + if ( ptr->numsent > 0 ) + { + //queue_enqueue("submitQ",&myinfo->basilisks.submitQ,&ptr->DL,0); + jaddstr(retjson,"result","success"); + jaddnum(retjson,"numsent",ptr->numsent); + } else jaddstr(retjson,"error","didnt find any nodes to send to"); + retstr = jprint(retjson,1); + } + ptr->finished = (uint32_t)time(NULL); + } + if ( 1 && strcmp("RID",CMD) != 0 && strcmp("BAL",CMD) != 0 && strcmp("MSG",CMD) != 0 ) + printf("%s.(%s) -> (%s)\n",CMD,jprint(valsobj,0),retstr!=0?retstr:""); + return(retstr); +} + +int32_t basilisk_relayid(struct supernet_info *myinfo,uint32_t ipbits) +{ + int32_t j; + for (j=0; jprotocol = protocol; + switch ( protocol ) + { + /*case IGUANA_PROTOCOL_BITCOIN: + coin->basilisk_balances = basilisk_bitcoinbalances; + coin->basilisk_rawtx = basilisk_bitcoinrawtx; + //coin->basilisk_rawtxmetric = basilisk_bitcoin_rawtxmetric; + coin->basilisk_value = basilisk_bitcoinvalue; + coin->basilisk_valuemetric = basilisk_bitcoin_valuemetric; + break; + case IGUANA_PROTOCOL_IOTA: + coin->basilisk_balances = basilisk_iotabalances; + coin->basilisk_rawtx = basilisk_iotarawtx; + break; + case IGUANA_PROTOCOL_NXT: + coin->basilisk_balances = basilisk_nxtbalances; + coin->basilisk_rawtx = basilisk_nxtrawtx; + break; + case IGUANA_PROTOCOL_ETHER: + coin->basilisk_balances = basilisk_etherbalances; + coin->basilisk_rawtx = basilisk_etherrawtx; + break; + case IGUANA_PROTOCOL_WAVES: + coin->basilisk_balances = basilisk_wavesbalances; + coin->basilisk_rawtx = basilisk_wavesrawtx; + break; + case IGUANA_PROTOCOL_LISK: + coin->basilisk_balances = basilisk_liskbalances; + coin->basilisk_rawtx = basilisk_liskrawtx; + break;*/ + } +} + +int32_t basilisk_hashes_send(struct supernet_info *myinfo,struct iguana_info *virt,struct iguana_peer *addr,char *CMD,bits256 *hashes,int32_t num) +{ + bits256 hash; uint8_t *serialized; int32_t i,len = 0; char *str=0,*retstr,*hexstr,*allocptr=0,space[4096]; bits256 txid; cJSON *vals; + if ( virt != 0 && addr != 0 ) + { + memset(hash.bytes,0,sizeof(hash)); + serialized = (void *)hashes; + for (i=0; isymbol); + if ( (retstr= basilisk_standardservice(CMD,myinfo,addr,hash,vals,hexstr,0)) != 0 ) + free(retstr); + free_json(vals); + if ( allocptr != 0 ) + free(allocptr); + } + return(0); + } else return(-1); +} + +void basilisk_geckoresult(struct supernet_info *myinfo,char *remoteaddr,char *retstr,uint8_t *data,int32_t datalen) +{ + struct iguana_info *virt; char *symbol,*str,*type; cJSON *retjson; bits256 hash2; + if ( retstr != 0 && (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( (symbol= jstr(retjson,"symbol")) != 0 && (virt= iguana_coinfind(symbol)) != 0 ) + { + if ( data != 0 ) + { + str = 0; + if ( (type= jstr(retjson,"type")) != 0 ) + { + hash2 = jbits256(retjson,"hash"); + if ( strcmp(type,"HDR") == 0 && virt->virtualchain != 0 ) + str = gecko_headersarrived(myinfo,virt,remoteaddr,data,datalen,hash2); + else if ( strcmp(type,"MEM") == 0 && virt->virtualchain != 0 ) + str = gecko_mempoolarrived(myinfo,virt,remoteaddr,data,datalen,hash2); + else if ( strcmp(type,"BLK") == 0 && virt->virtualchain != 0 ) + str = gecko_blockarrived(myinfo,virt,remoteaddr,data,datalen,hash2,0); + else if ( strcmp(type,"GTX") == 0 && virt->virtualchain != 0 ) + str = gecko_txarrived(myinfo,virt,remoteaddr,data,datalen,hash2); + } + if ( str != 0 ) + free(str); + } + } + free_json(retjson); + } +} + +void basilisk_result(struct supernet_info *myinfo,char *remoteaddr,uint32_t basilisktag,cJSON *vals,uint8_t *data,int32_t datalen) +{ + char *retstr,CMD[16]; struct basilisk_item *pending; cJSON *item; + if ( vals != 0 ) + { + retstr = jprint(vals,0); + safecopy(CMD,jstr(vals,"origcmd"),sizeof(CMD)); + if ( 0 && strcmp("RID",CMD) != 0 ) + printf("(%s) -> Q.%u results vals.(%s)\n",CMD,basilisktag,retstr); + if ( strcmp(CMD,"GET") == 0 ) + basilisk_geckoresult(myinfo,remoteaddr,retstr,data,datalen); + else + { + portable_mutex_lock(&myinfo->basilisk_mutex); + HASH_FIND(hh,myinfo->basilisks.issued,&basilisktag,sizeof(basilisktag),pending); + //printf("HASH_FIND.%p\n",pending); + portable_mutex_unlock(&myinfo->basilisk_mutex); + if ( pending != 0 && retstr != 0 ) + { + if ( (item= cJSON_Parse(retstr)) != 0 ) + { + if ( pending->retarray == 0 ) + pending->retarray = cJSON_CreateArray(); + if ( jobj(item,"myip") == 0 ) + jaddstr(item,"myip",myinfo->ipaddr); + jaddi(pending->retarray,item); + } else printf("couldnt parse.(%s)\n",retstr); + pending->numresults++; + } //else printf("couldnt find issued.%u\n",basilisktag); + } + } +} + +void basilisk_wait(struct supernet_info *myinfo,struct iguana_info *coin) +{ + if ( coin != 0 ) + { + while ( coin->basilisk_busy != 0 ) + usleep(1000); + } + else + { + while ( myinfo->basilisk_busy != 0 ) + usleep(1000); + } +} + +void basilisk_msgprocess(struct supernet_info *myinfo,void *_addr,uint32_t senderipbits,char *type,uint32_t basilisktag,uint8_t *data,int32_t datalen) +{ + cJSON *valsobj; char *symbol,*retstr=0,remoteaddr[64],CMD[4],cmd[4]; int32_t height,origlen,from_basilisk,i,timeoutmillis,flag,numrequired,jsonlen; uint8_t *origdata; struct iguana_info *coin=0; bits256 hash; struct iguana_peer *addr = _addr; + static basilisk_servicefunc *basilisk_services[][2] = + { + { (void *)"OUT", &basilisk_respond_OUT }, // send MSG to hash/id/num + { (void *)"MSG", &basilisk_respond_MSG }, // get MSG (hash, id, num) + { (void *)"ADD", &basilisk_respond_addrelay }, // relays register with each other bus + //{ (void *)"PIN", &basilisk_respond_PIN }, + // encrypted data for jumblr + { (void *)"HOP", &basilisk_respond_forward }, // message forwarding + { (void *)"BOX", &basilisk_respond_mailbox }, // create/send/check mailbox pubkey + + // small virtual private network + { (void *)"VPN", &basilisk_respond_VPNcreate }, // create virtual network's hub via privkey + { (void *)"ARC", &basilisk_respond_VPNjoin }, // join + { (void *)"GAB", &basilisk_respond_VPNmessage }, // private message + { (void *)"SAY", &basilisk_respond_VPNbroadcast }, // broadcast + { (void *)"EAR", &basilisk_respond_VPNreceive }, // network receive (via poll) + { (void *)"END", &basilisk_respond_VPNlogout }, // logout + + //{ (void *)"DEX", &basilisk_respond_DEX }, + //{ (void *)"RID", &basilisk_respond_RID }, + //{ (void *)"ACC", &basilisk_respond_ACC }, + { (void *)"BYE", &basilisk_respond_goodbye }, // disconnect + + // gecko chains + { (void *)"GET", &basilisk_respond_geckoget }, // requests headers, block or tx + { (void *)"HDR", &basilisk_respond_geckoheaders }, // reports headers + { (void *)"BLK", &basilisk_respond_geckoblock }, // reports virtchain block + { (void *)"MEM", &basilisk_respond_mempool }, // reports virtchain mempool + { (void *)"GTX", &basilisk_respond_geckotx }, // reports virtchain tx + + // coin services + { (void *)"VAL", &basilisk_respond_value }, + { (void *)"BAL", &basilisk_respond_balances }, + }; + strncpy(CMD,type,3), CMD[3] = cmd[3] = 0; + if ( isupper((int32_t)CMD[0]) != 0 && isupper((int32_t)CMD[1]) != 0 && isupper((int32_t)CMD[2]) != 0 ) + from_basilisk = 1; + else from_basilisk = 0; + origdata = data; + origlen = datalen; + for (i=0; i<3; i++) + { + CMD[i] = toupper((int32_t)CMD[i]); + cmd[i] = tolower((int32_t)CMD[i]); + } + //origcmd[0] = 0; + if ( RELAYID >= 0 ) + { + if ( basilisk_specialcmd(CMD) == 0 ) + return; + //printf("MSGPROCESS %s.(%s) tag.%d\n",CMD,(char *)data,basilisktag); + } + symbol = "BTCD"; + if ( senderipbits == 0 ) + expand_ipbits(remoteaddr,myinfo->myaddr.myipbits); + else expand_ipbits(remoteaddr,senderipbits); + if ( (valsobj= cJSON_Parse((char *)data)) != 0 ) + { + //if ( origcmd[0] != 0 ) + // jaddstr(valsobj,"origcmd",origcmd); + //printf("MSGVALS.(%s)\n",(char *)data); + if ( jobj(valsobj,"coin") != 0 ) + coin = iguana_coinfind(jstr(valsobj,"coin")); + else if ( jobj(valsobj,"symbol") != 0 ) + coin = iguana_coinfind(jstr(valsobj,"symbol")); + if ( coin != 0 ) + { + if ( (height= juint(valsobj,"hwm")) > 0 ) + { + if ( height > addr->height ) + addr->height = height; + if ( height > coin->longestchain ) + coin->longestchain = height; + } + } + if ( strcmp(type,"RET") == 0 ) + { + basilisk_result(myinfo,remoteaddr,basilisktag,valsobj,data,datalen); + return; + } + } + else + { + printf("unexpected binary packet datalen.%d\n",datalen); + return; + } + for (i=flag=0; ibasilisk_busy = 1; + if ( valsobj != 0 ) + { + jsonlen = (int32_t)strlen((char *)data) + 1; + if ( datalen > jsonlen ) + data += jsonlen, datalen -= jsonlen; + else data = 0, datalen = 0; + if ( coin == 0 ) + coin = iguana_coinfind("BTCD"); + if ( coin != 0 ) + { + symbol = coin->symbol; + coin->basilisk_busy = 1; + } + hash = jbits256(valsobj,"hash"); + timeoutmillis = jint(valsobj,"timeout"); + if ( (numrequired= jint(valsobj,"numrequired")) == 0 ) + numrequired = sqrt(NUMRELAYS); + if ( senderipbits != 0 ) + expand_ipbits(remoteaddr,senderipbits); + else remoteaddr[0] = 0; + for (i=0; iFULLNODE != 0 || RELAYID >= 0 ) // iguana node + { + //printf("services %s\n",type); + if ( (retstr= (*basilisk_services[i][1])(myinfo,type,addr,remoteaddr,basilisktag,valsobj,data,datalen,hash,from_basilisk)) != 0 ) + { + //printf("from_basilisk.%d ret.(%s)\n",from_basilisk,retstr); + //if ( from_basilisk != 0 || strcmp(CMD,"GET") == 0 ) + basilisk_sendback(myinfo,CMD,symbol,remoteaddr,basilisktag,retstr); + if ( retstr != 0 ) + free(retstr); + break; + } else printf("services null return\n"); + } else printf("non-relay got unhandled.(%s)\n",type); + } + } + free_json(valsobj); + } + if ( coin != 0 ) + coin->basilisk_busy = 0; + myinfo->basilisk_busy = 0; +} + +void basilisk_p2p(void *_myinfo,void *_addr,char *senderip,uint8_t *data,int32_t datalen,char *type,int32_t encrypted) +{ + uint32_t ipbits,basilisktag; int32_t msglen,len=0; void *ptr = 0; uint8_t space[4096]; bits256 senderpub; struct supernet_info *myinfo = _myinfo; + if ( encrypted != 0 ) + { + printf("encrypted p2p\n"); + memset(senderpub.bytes,0,sizeof(senderpub)); + if ( (data= SuperNET_deciphercalc(&ptr,&msglen,myinfo->privkey,senderpub,data,datalen,space,sizeof(space))) == 0 ) + { + printf("basilisk_p2p decrytion error\n"); + return; + } else datalen = msglen; + } + if ( senderip != 0 && senderip[0] != 0 && strcmp(senderip,"127.0.0.1") != 0 ) + ipbits = (uint32_t)calc_ipbits(senderip); + else ipbits = myinfo->myaddr.myipbits; + if ( type[0] == 'P' && type[1] == 'I' && type[2] == 'N' ) + { + if ( strcmp(type,"PIN") == 0 && RELAYID >= 0 ) + { + basilisk_ping_process(myinfo,_addr,ipbits,data,datalen); + } + } + else + { + len += iguana_rwnum(0,data,sizeof(basilisktag),&basilisktag); + //int32_t i; for (i=0; i= 0 ) + printf(" ->received.%d basilisk_p2p.(%s) from %s tag.%d\n",datalen,type,senderip!=0?senderip:"?",basilisktag); + basilisk_msgprocess(myinfo,_addr,ipbits,type,basilisktag,&data[len],datalen - len); + } + if ( ptr != 0 ) + free(ptr); +} + +void basilisk_requests_poll(struct supernet_info *myinfo) +{ + char *retstr; cJSON *outerarray; int32_t i,n; struct basilisk_request issueR; double hwm = 0.; + memset(&issueR,0,sizeof(issueR)); + if ( (retstr= InstantDEX_incoming(myinfo,0,0,0,0)) != 0 ) + { + //printf("poll.(%s)\n",retstr); + if ( (outerarray= cJSON_Parse(retstr)) != 0 ) + { + if ( is_cJSON_Array(outerarray) != 0 ) + { + n = cJSON_GetArraySize(outerarray); + for (i=0; i 0. ) + { + if ( bits256_cmp(myinfo->myaddr.persistent,issueR.hash) == 0 ) // my request + { + printf("my req hwm %f\n",hwm); + if ( (retstr= InstantDEX_accept(myinfo,0,0,0,issueR.requestid,issueR.quoteid)) != 0 ) + free(retstr); + if ( (retstr= basilisk_start(myinfo,&issueR,1)) != 0 ) + free(retstr); + } + else //if ( issueR.quoteid == 0 ) + { + printf("other req hwm %f\n",hwm); + issueR.quoteid = basilisk_quoteid(&issueR); + issueR.desthash = myinfo->myaddr.persistent; + if ( (retstr= basilisk_start(myinfo,&issueR,0)) != 0 ) + free(retstr); + } //else printf("basilisk_requests_poll unexpected hwm issueR\n"); + } +} + +void basilisks_loop(void *arg) +{ + struct iguana_info *virt,*tmpcoin,*coin,*btcd; struct basilisk_message *msg,*tmpmsg; struct basilisk_item *tmp,*pending; uint32_t now; int32_t iter,maxmillis,flag=0; struct supernet_info *myinfo = arg; + iter = 0; + while ( 1 ) + { + portable_mutex_lock(&myinfo->basilisk_mutex); + HASH_ITER(hh,myinfo->basilisks.issued,pending,tmp) + { + if ( pending != 0 && (pending->finished != 0 || OS_milliseconds() > pending->expiration+600000) ) + { + //printf("enable free for HASH_DELETE.(%p)\n",pending); + HASH_DELETE(hh,myinfo->basilisks.issued,pending); + memset(pending,0,sizeof(*pending)); + free(pending); + } + } + portable_mutex_unlock(&myinfo->basilisk_mutex); + if ( (btcd= iguana_coinfind("BTCD")) != 0 ) + { + maxmillis = (1000 / (myinfo->allcoins_numvirts + 1)) + 1; + //portable_mutex_lock(&myinfo->allcoins_mutex); + HASH_ITER(hh,myinfo->allcoins,virt,tmpcoin) + { + if ( virt->started != 0 && virt->active != 0 && virt->virtualchain != 0 ) + { + gecko_iteration(myinfo,btcd,virt,maxmillis), flag++; + } + } + //portable_mutex_unlock(&myinfo->allcoins_mutex); + if ( RELAYID >= 0 ) + { + basilisk_ping_send(myinfo,btcd); + } + } + HASH_ITER(hh,myinfo->allcoins,coin,tmpcoin) + { + if ( time(NULL) > coin->lastunspentsupdate+10 ) + { + //printf(">>>>>>>>>>>>> update\n"); + basilisk_unspents_update(myinfo,coin); + coin->lastunspentsupdate = (uint32_t)time(NULL); + } + } + if ( RELAYID < 0 ) + basilisk_requests_poll(myinfo); + now = (uint32_t)time(NULL); + portable_mutex_lock(&myinfo->messagemutex); + HASH_ITER(hh,myinfo->messagetable,msg,tmpmsg) + { + if ( now > msg->expiration ) + { + printf("delete expired message.%p QUEUEITEMS.%d\n",msg,QUEUEITEMS); + HASH_DELETE(hh,myinfo->messagetable,msg); + QUEUEITEMS--; + free(msg); + } + } + portable_mutex_unlock(&myinfo->messagemutex); + if ( RELAYID >= 0 ) + usleep(100000); + else sleep(1); + } +} + +void basilisks_init(struct supernet_info *myinfo) +{ + iguana_initQ(&myinfo->msgQ,"messageQ"); + portable_mutex_init(&myinfo->bu_mutex); + portable_mutex_init(&myinfo->allcoins_mutex); + portable_mutex_init(&myinfo->basilisk_mutex); + portable_mutex_init(&myinfo->DEX_mutex); + portable_mutex_init(&myinfo->DEX_swapmutex); + portable_mutex_init(&myinfo->DEX_reqmutex); + portable_mutex_init(&myinfo->gecko_mutex); + portable_mutex_init(&myinfo->messagemutex); + myinfo->basilisks.launched = iguana_launch(iguana_coinfind("BTCD"),"basilisks_loop",basilisks_loop,myinfo,IGUANA_PERMTHREAD); + printf("Basilisk initialized\n"); +} + +#include "../includes/iguana_apidefs.h" +#include "../includes/iguana_apideclares.h" +HASH_ARRAY_STRING(basilisk,balances,hash,vals,hexstr) +{ + char *retstr=0,*symbol; uint32_t basilisktag; struct basilisk_item *ptr,Lptr; int32_t timeoutmillis; + if ( RELAYID >= 0 ) + return(clonestr("{\"error\":\"special relays only do OUT and MSG\"}")); + if ( vals == 0 ) + return(clonestr("{\"error\":\"need vals object\"}")); + //if ( coin == 0 ) + { + if ( (symbol= jstr(vals,"symbol")) != 0 || (symbol= jstr(vals,"coin")) != 0 ) + coin = iguana_coinfind(symbol); + } + if ( jobj(vals,"fanout") == 0 ) + jaddnum(vals,"fanout",(int32_t)sqrt(NUMRELAYS)+1); + if ( jobj(vals,"numrequired") == 0 ) + jaddnum(vals,"numrequired",sqrt(NUMRELAYS)); + if ( coin != 0 ) + { + if ( jobj(vals,"addresses") == 0 ) + { + jadd(vals,"addresses",iguana_getaddressesbyaccount(myinfo,coin,"*")); + //printf("added all addresses: %s\n",jprint(vals,0)); + } //else printf("have addresses.(%s)\n",jprint(jobj(vals,"addresses"),0)); + if ( (basilisktag= juint(vals,"basilisktag")) == 0 ) + basilisktag = rand(); + if ( (timeoutmillis= juint(vals,"timeout")) <= 0 ) + timeoutmillis = BASILISK_TIMEOUT; + if ( (coin->FULLNODE != 0 || coin->VALIDATENODE != 0) && (ptr= basilisk_bitcoinbalances(&Lptr,myinfo,coin,remoteaddr,basilisktag,timeoutmillis,vals)) != 0 ) + { + retstr = ptr->retstr, ptr->retstr = 0; + ptr->finished = (uint32_t)time(NULL); + return(retstr); + } + } else printf("no coin\n"); + return(basilisk_standardservice("BAL",myinfo,0,hash,vals,hexstr,1)); +} + +HASH_ARRAY_STRING(basilisk,history,hash,vals,hexstr) +{ + struct basilisk_unspent *bu; int32_t i; int64_t totalspent=0,total = 0; struct iguana_waccount *wacct,*tmp; struct iguana_waddress *waddr,*tmp2; char *symbol; cJSON *retjson,*array; struct basilisk_spend *s; + if ( vals == 0 ) + return(clonestr("{\"error\":\"need vals object\"}")); + //if ( coin == 0 ) + { + if ( (symbol= jstr(vals,"symbol")) != 0 || (symbol= jstr(vals,"coin")) != 0 ) + coin = iguana_coinfind(symbol); + } + if ( coin == 0 ) + return(clonestr("{\"error\":\"couldnt find coin\"}")); + //printf("history for (%s)\n",coin->symbol); + basilisk_unspents_update(myinfo,coin); + array = cJSON_CreateArray(); + portable_mutex_lock(&myinfo->bu_mutex); + HASH_ITER(hh,myinfo->wallet,wacct,tmp) + { + HASH_ITER(hh,wacct->waddr,waddr,tmp2) + { + for (i=0; inumunspents; i++) + { + bu = &waddr->unspents[i]; + if ( strcmp(bu->symbol,coin->symbol) == 0 ) + { + bitcoin_address(waddr->coinaddr,coin->chain->pubtype,waddr->rmd160,sizeof(waddr->rmd160)); + jaddi(array,basilisk_history_item(coin,&total,waddr->coinaddr,bu->value,bu->timestamp,bu->txid,"vout",bu->vout,bu->height,"spentheight",bu->spentheight,bu->relaymask,-1)); + //printf("%s %s i.%d numunspents.%d\n",coin->symbol,waddr->coinaddr,i,waddr->numunspents); + } + } + } + } + if ( myinfo->numspends > 0 ) + { + //spends = cJSON_CreateArray(); + for (i=0; inumspends; i++) + { + s = &myinfo->spends[i]; + //struct basilisk_spend { bits256 txid; uint64_t relaymask,value; uint32_t timestamp; int32_t vini,height,unspentheight,ismine; char destaddr[64]; }; + if ( strcmp(s->symbol,coin->symbol) == 0 ) + jaddi(array,basilisk_history_item(coin,&totalspent,s->destaddr,s->value,s->timestamp,s->txid,"vin",s->vini,s->height,"unspentheight",s->unspentheight,s->relaymask,s->ismine)); + } + } + portable_mutex_unlock(&myinfo->bu_mutex); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jadd(retjson,"history",array); + jaddstr(retjson,"coin",coin->symbol); + jaddnum(retjson,"balance",dstr(total)); + return(jprint(retjson,1)); +} + +#include "../includes/iguana_apiundefs.h" diff --git a/basilisk/basilisk.h b/basilisk/basilisk.h new file mode 100755 index 000000000..3576eee12 --- /dev/null +++ b/basilisk/basilisk.h @@ -0,0 +1,124 @@ +/****************************************************************************** + * Copyright © 2014-2016 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#ifndef H_BASILISK_H +#define H_BASILISK_H + +#define BASILISK_DISABLETX + +#include "../iguana/iguana777.h" + +#define BASILISK_TIMEOUT 30000 +#define BASILISK_MINFANOUT 8 +#define BASILISK_MAXFANOUT 64 +#define BASILISK_DEFAULTDIFF 0x1effffff +#define BASILISK_MAXRELAYS 64 +#define BASILISK_DEXDURATION 180 +#define BASILISK_MSGDURATION 60 + +#define BASILISK_MAXFUTUREBLOCK 60 +//#define BASILISK_MAXBLOCKLAG 600 +#define BASILISK_HDROFFSET ((int32_t)(sizeof(bits256)+sizeof(struct iguana_msghdr)+sizeof(uint32_t))) + +#define INSTANTDEX_DECKSIZE 1000 +#define INSTANTDEX_LOCKTIME (3600*2 + 300*2) +#define INSTANTDEX_INSURANCEDIV 777 +#define INSTANTDEX_PUBKEY "03bc2c7ba671bae4a6fc835244c9762b41647b9827d4780a89a949b984a8ddcc06" +#define INSTANTDEX_RMD160 "ca1e04745e8ca0c60d8c5881531d51bec470743f" +#define TIERNOLAN_RMD160 "daedddd8dbe7a2439841ced40ba9c3d375f98146" +#define INSTANTDEX_BTC "1KRhTPvoxyJmVALwHFXZdeeWFbcJSbkFPu" +#define INSTANTDEX_BTCD "RThtXup6Zo7LZAi8kRWgjAyi1s4u6U9Cpf" + +struct basilisk_rawtx +{ + bits256 txid,signedtxid,actualtxid; + struct iguana_msgtx msgtx; + struct iguana_info *coin; + uint64_t amount,change,inputsum; + int32_t redeemlen,datalen,completed,vintype,vouttype,numconfirms,spendlen,secretstart,suppress_pubkeys; + uint32_t locktime; + char destaddr[64],name[32]; + uint8_t addrtype,pubkey33[33],spendscript[512],redeemscript[1024],rmd160[20]; + uint8_t *txbytes,extraspace[1024]; +}; + +struct basilisk_swap +{ + struct basilisk_request req; + struct supernet_info *myinfo; bits256 myhash,otherhash; + uint32_t statebits,otherstatebits,started,expiration,finished,dead,reftime,locktime; + struct iguana_info *bobcoin,*alicecoin; char bobstr[64],alicestr[64]; + int32_t bobconfirms,aliceconfirms,iambob,reclaimed; + uint64_t alicesatoshis,bobsatoshis,bobinsurance,aliceinsurance; + + bits256 privkeys[INSTANTDEX_DECKSIZE],myprivs[2],mypubs[2],otherpubs[2],pubA0,pubA1,pubB0,pubB1,privAm,pubAm,privBn,pubBn; + uint64_t otherdeck[INSTANTDEX_DECKSIZE][2],deck[INSTANTDEX_DECKSIZE][2]; + int32_t choosei,otherchoosei,cutverified,otherverifiedcut,numpubs,havestate,otherhavestate; + uint8_t secretAm[20],secretBn[20]; + + struct basilisk_rawtx bobdeposit,bobpayment,alicepayment,myfee,otherfee,aliceclaim,alicespend,bobreclaim,bobspend,bobrefund,alicereclaim; +}; + +struct basilisk_value { bits256 txid; int64_t value; int32_t height; int16_t vout; char coinaddr[64]; }; + +struct basilisk_item +{ + struct queueitem DL; UT_hash_handle hh; + double expiration; cJSON *retarray; + uint32_t submit,finished,basilisktag,numresults,numsent,numrequired,nBits; + char symbol[32],CMD[4],remoteaddr[64],*retstr; +}; + +#define BASILISK_KEYSIZE ((int32_t)(2*sizeof(bits256)+sizeof(uint32_t)*2)) +struct basilisk_message +{ + struct queueitem DL; UT_hash_handle hh; + uint32_t datalen,expiration,duration; + uint8_t key[BASILISK_KEYSIZE],keylen; + uint8_t data[]; +}; + +struct basilisk_info +{ + //queue_t resultsQ,submitQ; + void *launched; //portable_mutex_t *mutex; + struct basilisk_item *issued; + struct basilisk_value values[8192]; int32_t numvalues; +}; + +void basilisk_msgprocess(struct supernet_info *myinfo,void *addr,uint32_t senderipbits,char *type,uint32_t basilisktag,uint8_t *data,int32_t datalen); +int32_t basilisk_sendcmd(struct supernet_info *myinfo,char *destipaddr,char *type,uint32_t *basilisktagp,int32_t encryptflag,int32_t delaymillis,uint8_t *data,int32_t datalen,int32_t fanout,uint32_t nBits); // data must be offset by sizeof(iguana_msghdr)+sizeof(basilisktag) + +void basilisks_init(struct supernet_info *myinfo); +void basilisk_p2p(void *myinfo,void *_addr,char *ipaddr,uint8_t *data,int32_t datalen,char *type,int32_t encrypted); +uint8_t *basilisk_jsondata(int32_t extraoffset,uint8_t **ptrp,uint8_t *space,int32_t spacesize,int32_t *datalenp,char *symbol,cJSON *sendjson,uint32_t basilisktag); + +uint8_t *SuperNET_ciphercalc(void **ptrp,int32_t *cipherlenp,bits256 *privkeyp,bits256 *destpubkeyp,uint8_t *data,int32_t datalen,uint8_t *space2,int32_t space2size); +void *SuperNET_deciphercalc(void **ptrp,int32_t *msglenp,bits256 privkey,bits256 srcpubkey,uint8_t *cipher,int32_t cipherlen,uint8_t *buf,int32_t bufsize); +uint8_t *get_dataptr(int32_t hdroffset,uint8_t **ptrp,int32_t *datalenp,uint8_t *space,int32_t spacesize,char *hexstr); +char *basilisk_addhexstr(char **ptrp,cJSON *valsobj,char *strbuf,int32_t strsize,uint8_t *data,int32_t datalen); +char *basilisk_standardservice(char *CMD,struct supernet_info *myinfo,void *_addr,bits256 hash,cJSON *valsobj,char *hexstr,int32_t blockflag); // client side +char *basilisk_respond_mempool(struct supernet_info *myinfo,char *CMD,void *_addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk); +char *basilisk_addrelay_info(struct supernet_info *myinfo,uint8_t *pubkey33,uint32_t ipbits,bits256 pubkey); + +void basilisk_request_goodbye(struct supernet_info *myinfo); +int32_t basilisk_update(char *symbol,uint32_t reftimestamp); +void basilisk_seqresult(struct supernet_info *myinfo,char *retstr); +struct iguana_info *basilisk_geckochain(struct supernet_info *myinfo,char *symbol,char *chainname,cJSON *valsobj); +void basilisk_alicepayment(struct supernet_info *myinfo,struct iguana_info *coin,struct basilisk_rawtx *alicepayment,bits256 pubAm,bits256 pubBn); +void basilisk_rawtx_setparms(char *name,struct supernet_info *myinfo,struct basilisk_swap *swap,struct basilisk_rawtx *rawtx,struct iguana_info *coin,int32_t numconfirms,int32_t vintype,uint64_t satoshis,int32_t vouttype,uint8_t *pubkey33); +void basilisk_setmyid(struct supernet_info *myinfo); + +#endif diff --git a/basilisk/basilisk_CMD.c b/basilisk/basilisk_CMD.c new file mode 100755 index 000000000..695ee1c83 --- /dev/null +++ b/basilisk/basilisk_CMD.c @@ -0,0 +1,348 @@ +/****************************************************************************** + * Copyright © 2014-2016 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +// included from basilisk.c + +/*int32_t basilisk_relayid(struct supernet_info *myinfo,char *ipaddr) +{ + uint32_t i,ipbits = (uint32_t)calc_ipbits(ipaddr); + for (i=0; iisrelay = 1; + RELAYID = -1; + for (i=0; imyaddr.myipbits ) + { + RELAYID = i; + break; + } + iguana_launch(btcd,"addrelay",iguana_startconnection,addr,IGUANA_CONNTHREAD); + } else printf("error getting peerslot\n"); + } else addr->isrelay = 1; + return(addr); +} + +static int _increasing_ipbits(const void *a,const void *b) +{ +#define uint32_a (*(struct basilisk_relay *)a).ipbits +#define uint32_b (*(struct basilisk_relay *)b).ipbits + if ( uint32_b > uint32_a ) + return(-1); + else if ( uint32_b < uint32_a ) + return(1); + return(0); +#undef uint32_a +#undef uint32_b +} + +void basilisk_relay_remap(struct supernet_info *myinfo,struct basilisk_relay *rp) +{ + int32_t i; struct basilisk_relaystatus tmp[BASILISK_MAXRELAYS]; + // need to verify this works + for (i=0; ireported[i]; + for (i=0; ireported[RELAYS[i].relayid] = tmp[RELAYS[i].oldrelayid]; +} + +void basilisk_setmyid(struct supernet_info *myinfo) +{ + int32_t i; char ipaddr[64]; struct iguana_info *btcd = iguana_coinfind("BTCD"); + for (i=0; imyaddr.myipbits == RELAYS[i].ipbits ) + RELAYID = i; + basilisk_ensurerelay(myinfo,btcd,RELAYS[i].ipbits); + } +} + +char *basilisk_addrelay_info(struct supernet_info *myinfo,uint8_t *pubkey33,uint32_t ipbits,bits256 pubkey) +{ + int32_t i; struct basilisk_relay *rp; + for (i=0; iipbits ) + { + if ( bits256_cmp(GENESIS_PUBKEY,pubkey) != 0 && bits256_nonz(pubkey) != 0 ) + rp->pubkey = pubkey; + if ( pubkey33 != 0 && pubkey33[0] != 0 ) + memcpy(rp->pubkey33,pubkey33,33); + //printf("updated relay[%d] %x\n",i,ipbits); + return(clonestr("{\"error\":\"relay already there\"}")); + } + } + if ( i >= sizeof(RELAYS)/sizeof(*RELAYS) ) + i = (rand() % (sizeof(RELAYS)/sizeof(*RELAYS))); + printf("add relay[%d] <- %x\n",i,ipbits); + for (i=0; iipbits = ipbits; + rp->relayid = NUMRELAYS; + basilisk_ensurerelay(myinfo,iguana_coinfind("BTCD"),rp->ipbits); + if ( NUMRELAYS < sizeof(RELAYS)/sizeof(*RELAYS) ) + NUMRELAYS++; + qsort(RELAYS,NUMRELAYS,sizeof(RELAYS[0]),_increasing_ipbits); + for (i=0; idead = (uint32_t)time(NULL); + addr->rank = 0; + return(0); +} + +void basilisk_request_goodbye(struct supernet_info *myinfo) +{ + cJSON *valsobj = cJSON_CreateObject(); + jaddnum(valsobj,"timeout",-1); + basilisk_requestservice(myinfo,0,"BYE",0,valsobj,GENESIS_PUBKEY,0,0,0); + free_json(valsobj); +} + +char *basilisk_respond_addrelay(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) +{ + char *ipaddr,*retstr=0; + if ( (ipaddr= jstr(valsobj,"ipaddr")) != 0 ) + retstr = basilisk_addrelay_info(myinfo,0,(uint32_t)calc_ipbits(ipaddr),jbits256(valsobj,"pubkey")); + else retstr = clonestr("{\"error\":\"need rmd160, address and ipaddr\"}"); + return(retstr); +} + +char *basilisk_respond_forward(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) +{ + char *retstr=0; + return(retstr); +} + +char *basilisk_respond_mailbox(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) +{ + char *retstr=0; + return(retstr); +} + +char *basilisk_respond_VPNcreate(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) +{ + char *retstr=0; + return(retstr); +} + +char *basilisk_respond_VPNjoin(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) +{ + char *retstr=0; + return(retstr); +} + +char *basilisk_respond_VPNlogout(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) +{ + char *retstr=0; + return(retstr); +} + +char *basilisk_respond_VPNbroadcast(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) +{ + char *retstr=0; + return(retstr); +} + +char *basilisk_respond_VPNreceive(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) +{ + char *retstr=0; + return(retstr); +} + +char *basilisk_respond_VPNmessage(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) +{ + char *retstr=0; + return(retstr); +} + +/*char *basilisk_respond_rawtx(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) +{ + char *symbol,*retstr=0; struct basilisk_item Lptr,*ptr; int32_t timeoutmillis; struct iguana_info *coin = 0; + timeoutmillis = jint(valsobj,"timeout"); + if ( (symbol= jstr(valsobj,"coin")) != 0 || (symbol= jstr(valsobj,"symbol")) != 0 ) + coin = iguana_coinfind(symbol); + if ( coin != 0 && (ptr= basilisk_bitcoinrawtx(&Lptr,myinfo,coin,remoteaddr,basilisktag,timeoutmillis,valsobj)) != 0 ) + { + retstr = ptr->retstr; + ptr->finished = (uint32_t)time(NULL); + } else retstr = clonestr("{\"error\":\"no coin specified or error bitcoinrawtx\"}"); + return(retstr); +}*/ + +char *basilisk_respond_value(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) +{ + char *symbol,*retstr=0; struct basilisk_item Lptr,*ptr; int32_t timeoutmillis; struct iguana_info *coin = 0; + timeoutmillis = jint(valsobj,"timeout"); + if ( (symbol= jstr(valsobj,"coin")) != 0 || (symbol= jstr(valsobj,"symbol")) != 0 ) + coin = iguana_coinfind(symbol); + if ( coin != 0 && (ptr= basilisk_bitcoinvalue(&Lptr,myinfo,coin,remoteaddr,basilisktag,timeoutmillis,valsobj)) != 0 ) + { + retstr = ptr->retstr; + ptr->finished = (uint32_t)time(NULL); + } else retstr = clonestr("{\"error\":\"no coin specified or error bitcoinrawtx\"}"); + return(retstr); +} + +char *basilisk_respond_balances(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) +{ + char *symbol,*retstr=0; struct basilisk_item Lptr,*ptr; int32_t timeoutmillis; struct iguana_info *coin = 0; + timeoutmillis = jint(valsobj,"timeout"); + if ( (symbol= jstr(valsobj,"coin")) != 0 || (symbol= jstr(valsobj,"symbol")) != 0 ) + coin = iguana_coinfind(symbol); + if ( coin != 0 && (ptr= basilisk_bitcoinbalances(&Lptr,myinfo,coin,remoteaddr,basilisktag,timeoutmillis,valsobj)) != 0 ) + { + retstr = ptr->retstr; + ptr->finished = (uint32_t)time(NULL); + } else retstr = clonestr("{\"error\":\"no coin specified or error bitcoinrawtx\"}"); + return(retstr); +} + +#include "../includes/iguana_apidefs.h" +#include "../includes/iguana_apideclares.h" + +HASH_ARRAY_STRING(basilisk,addrelay,hash,vals,hexstr) +{ + return(basilisk_standardservice("ADD",myinfo,0,hash,vals,hexstr,1)); +} + +HASH_ARRAY_STRING(basilisk,relays,hash,vals,hexstr) +{ + return(basilisk_standardservice("RLY",myinfo,0,hash,vals,hexstr,1)); +} + +HASH_ARRAY_STRING(basilisk,dispatch,hash,vals,hexstr) +{ + return(basilisk_standardservice("RUN",myinfo,0,hash,vals,hexstr,1)); +} + +HASH_ARRAY_STRING(basilisk,publish,hash,vals,hexstr) +{ + return(basilisk_standardservice("PUB",myinfo,0,hash,vals,hexstr,1)); +} + +HASH_ARRAY_STRING(basilisk,subscribe,hash,vals,hexstr) +{ + return(basilisk_standardservice("SUB",myinfo,0,hash,vals,hexstr,1)); +} + +HASH_ARRAY_STRING(basilisk,forward,hash,vals,hexstr) +{ + return(basilisk_standardservice("HOP",myinfo,0,hash,vals,hexstr,0)); +} + +HASH_ARRAY_STRING(basilisk,mailbox,hash,vals,hexstr) +{ + return(basilisk_standardservice("BOX",myinfo,0,hash,vals,hexstr,1)); +} + +HASH_ARRAY_STRING(basilisk,VPNcreate,hash,vals,hexstr) +{ + return(basilisk_standardservice("VPN",myinfo,0,hash,vals,hexstr,1)); +} + +HASH_ARRAY_STRING(basilisk,VPNjoin,hash,vals,hexstr) +{ + return(basilisk_standardservice("ARC",myinfo,0,hash,vals,hexstr,1)); +} + +HASH_ARRAY_STRING(basilisk,VPNmessage,hash,vals,hexstr) +{ + return(basilisk_standardservice("GAB",myinfo,0,hash,vals,hexstr,0)); +} + +HASH_ARRAY_STRING(basilisk,VPNbroadcast,hash,vals,hexstr) +{ + return(basilisk_standardservice("SAY",myinfo,0,hash,vals,hexstr,0)); +} + +HASH_ARRAY_STRING(basilisk,VPNreceive,hash,vals,hexstr) +{ + return(basilisk_standardservice("EAR",myinfo,0,hash,vals,hexstr,1)); +} + +HASH_ARRAY_STRING(basilisk,VPNlogout,hash,vals,hexstr) +{ + return(basilisk_standardservice("END",myinfo,0,hash,vals,hexstr,0)); +} + +uint16_t basilisk_portavailable(struct supernet_info *myinfo,uint16_t port) +{ + struct iguana_info *coin,*tmp; + if ( port < 10000 ) + return(0); + HASH_ITER(hh,myinfo->allcoins,coin,tmp) + { + if ( port == coin->chain->portp2p || port == coin->chain->rpcport ) + return(0); + } + return(port); +} + +HASH_ARRAY_STRING(basilisk,genesis_opreturn,hash,vals,hexstr) +{ + int32_t len; uint16_t blocktime,port; uint8_t p2shval,wifval; uint8_t serialized[4096],tmp[4]; char hex[8192],*symbol,*name,*destaddr; uint64_t PoSvalue; uint32_t nBits; + symbol = jstr(vals,"symbol"); + name = jstr(vals,"name"); + destaddr = jstr(vals,"issuer"); + PoSvalue = jdouble(vals,"stake") * SATOSHIDEN; + if ( (blocktime= juint(vals,"blocktime")) == 0 ) + blocktime = 1; + p2shval = juint(vals,"p2sh"); + wifval = juint(vals,"wif"); + if ( (port= juint(vals,"port")) == 0 ) + while ( (port= basilisk_portavailable(myinfo,(rand() % 50000) + 10000)) == 0 ) + ; + if ( jstr(vals,"nBits") != 0 ) + { + decode_hex((void *)&tmp,sizeof(tmp),jstr(vals,"nBits")); + ((uint8_t *)&nBits)[0] = tmp[3]; + ((uint8_t *)&nBits)[1] = tmp[2]; + ((uint8_t *)&nBits)[2] = tmp[1]; + ((uint8_t *)&nBits)[3] = tmp[0]; + } else nBits = 0x1e00ffff; + len = datachain_opreturn_create(serialized,symbol,name,destaddr,PoSvalue,nBits,blocktime,port,p2shval,wifval); + init_hexbytes_noT(hex,serialized,len); + return(clonestr(hex)); +} + +#include "../includes/iguana_apiundefs.h" + diff --git a/basilisk/basilisk_DEX.c b/basilisk/basilisk_DEX.c new file mode 100755 index 000000000..4921dee2a --- /dev/null +++ b/basilisk/basilisk_DEX.c @@ -0,0 +1,553 @@ +/****************************************************************************** + * Copyright © 2014-2016 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +// included from basilisk.c +// requestid is invariant for a specific request +// quoteid is invariant for a specific request after dest fields are set + +#ifdef ENABLE_DEXPING +int32_t basilisk_ping_processDEX(struct supernet_info *myinfo,uint32_t senderipbits,uint8_t *data,int32_t datalen) +{ + int32_t i,n,len=0; struct basilisk_relay *relay; struct basilisk_request R; uint8_t clen,serialized[256]; uint16_t sn; uint32_t crc; + portable_mutex_lock(&myinfo->DEX_reqmutex); + len += iguana_rwnum(0,&data[len],sizeof(sn),&sn); + if ( (relay= basilisk_request_ensure(myinfo,senderipbits,sn)) != 0 ) + { + relay->numrequests = 0; + for (i=0; inumrequests < relay->maxrequests ) + { + memcpy(serialized,&data[len],clen); + //printf("ping processDEX\n"); + n = basilisk_rwDEXquote(0,serialized,&R); + if ( n != clen ) + printf("n.%d clen.%d\n",n,clen); + len += clen; + crc = basilisk_requestid(&R); + if ( crc == R.requestid ) + { + relay->requests[relay->numrequests++] = R; + //printf("[(%s %.8f) -> (%s %.8f) r.%u q.%u] ",R.src,dstr(R.srcamount),R.dest,dstr(R.destamount),R.requestid,R.quoteid); + } else printf("crc.%u error vs %u\n",crc,R.requestid); + } else printf("relay num.%d >= max.%d\n",relay->numrequests,relay->maxrequests); + } else len += clen; + } + } + else + { + for (i=0; iDEX_reqmutex); + return(len); +} + +int32_t basilisk_ping_genDEX(struct supernet_info *myinfo,uint8_t *data,int32_t maxlen) +{ + struct queueitem *item,*tmp; uint8_t clen; int32_t i,datalen = 0; uint16_t sn; uint32_t timestamp,now; + datalen += sizeof(uint16_t); + i = 0; + now = (uint32_t)time(NULL); + portable_mutex_lock(&myinfo->DEX_mutex); + DL_FOREACH_SAFE(myinfo->DEX_quotes,item,tmp) + { + memcpy(&clen,&item[1],sizeof(clen)); + if ( datalen+clen < maxlen ) + { + memcpy(&data[datalen],&item[1],clen+1), datalen += (clen + 1); + i++; + } + iguana_rwnum(0,(void *)((long)&item[1] + 1 + sizeof(uint32_t)),sizeof(timestamp),×tamp); + if ( now > timestamp + BASILISK_DEXDURATION ) + { + DL_DELETE(myinfo->DEX_quotes,item); + free(item); + } //else printf("now.%u vs timestamp.%u, lag.%d\n",now,timestamp,now-timestamp); + } + portable_mutex_unlock(&myinfo->DEX_mutex); + sn = i; + iguana_rwnum(1,data,sizeof(sn),&sn); // fill in at beginning + return(datalen); +} +#endif + +int32_t basilisk_rwDEXquote(int32_t rwflag,uint8_t *serialized,struct basilisk_request *rp) +{ + int32_t len = 0; + len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->requestid),&rp->requestid); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->timestamp),&rp->timestamp); // must be 2nd + len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->quoteid),&rp->quoteid); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->quotetime),&rp->quotetime); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->relaybits),&rp->relaybits); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->srcamount),&rp->srcamount); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->minamount),&rp->minamount); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(rp->hash),rp->hash.bytes); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(rp->desthash),rp->desthash.bytes); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(rp->destamount),&rp->destamount); + if ( rwflag != 0 ) + { + memcpy(&serialized[len],rp->src,sizeof(rp->src)), len += sizeof(rp->src); + memcpy(&serialized[len],rp->dest,sizeof(rp->dest)), len += sizeof(rp->dest); + } + else + { + memcpy(rp->src,&serialized[len],sizeof(rp->src)), len += sizeof(rp->src); + memcpy(rp->dest,&serialized[len],sizeof(rp->dest)), len += sizeof(rp->dest); + } + if ( rp->quoteid != 0 && basilisk_quoteid(rp) != rp->quoteid ) + printf("basilisk_rwDEXquote.%d: quoteid.%u mismatch calc %u\n",rwflag,rp->quoteid,basilisk_quoteid(rp)); + if ( basilisk_requestid(rp) != rp->requestid ) + printf("basilisk_rwDEXquote.%d: requestid.%u mismatch calc %u\n",rwflag,rp->requestid,basilisk_requestid(rp)); + return(len); +} + +uint32_t basilisk_request_enqueue(struct supernet_info *myinfo,struct basilisk_request *rp) +{ + uint8_t serialized[256]; int32_t len; struct queueitem *item; + len = basilisk_rwDEXquote(1,serialized+1,rp); + if ( (item= calloc(1,sizeof(*item) + len + 1)) != 0 ) + { + serialized[0] = len; + memcpy(&item[1],serialized,len + 1); + portable_mutex_lock(&myinfo->DEX_mutex); + DL_APPEND(myinfo->DEX_quotes,item); + portable_mutex_unlock(&myinfo->DEX_mutex); + printf("ENQUEUE.%u calc.%u\n",rp->requestid,basilisk_requestid(rp)); + return(rp->requestid); + } + return(0); +} + +cJSON *basilisk_requestjson(struct basilisk_request *rp) +{ + char ipaddr[64]; cJSON *item = cJSON_CreateObject(); + if ( rp->relaybits != 0 ) + { + expand_ipbits(ipaddr,rp->relaybits); + jaddstr(item,"relay",ipaddr); + } + jaddbits256(item,"hash",rp->hash); + if ( bits256_nonz(rp->desthash) != 0 ) + jaddbits256(item,"desthash",rp->desthash); + jaddstr(item,"src",rp->src); + if ( rp->srcamount != 0 ) + jadd64bits(item,"srcamount",rp->srcamount); + if ( rp->minamount != 0 ) + jadd64bits(item,"minamount",rp->minamount); + jaddstr(item,"dest",rp->dest); + if ( rp->destamount != 0 ) + jadd64bits(item,"destamount",rp->destamount); + jaddnum(item,"quotetime",rp->quotetime); + jaddnum(item,"timestamp",rp->timestamp); + jaddnum(item,"requestid",rp->requestid); + jaddnum(item,"quoteid",rp->quoteid); + if ( rp->quoteid != 0 && basilisk_quoteid(rp) != rp->quoteid ) + printf("quoteid mismatch %u vs %u\n",basilisk_quoteid(rp),rp->quoteid); + if ( basilisk_requestid(rp) != rp->requestid ) + printf("requestid mismatch %u vs calc %u\n",rp->requestid,basilisk_requestid(rp)); + { + int32_t i; struct basilisk_request R; + if ( basilisk_parsejson(&R,item) != 0 ) + { + if ( memcmp(&R,rp,sizeof(*rp)) != 0 ) + { + for (i=0; isrcamount= j64bits(valsobj,"satoshis")) != 0 ) + { + if ( (rp->destamount= j64bits(valsobj,"destsatoshis")) != 0 ) + { + rp->desthash = jbits256(valsobj,"desthash"); + for (i=0; i<4; i++) + if ( rp->desthash.ulongs[i] != 0 ) + break; + if ( i != 4 ) + rp->destamount = 0; + } + rp->minamount = j64bits(valsobj,"minamount"); + rp->timestamp = timestamp; + rp->hash = hash; + strncpy(rp->src,src,sizeof(rp->src)-1); + strncpy(rp->dest,dest,sizeof(rp->dest)-1); + rp->requestid = basilisk_requestid(rp); + if ( rp->destamount != 0 && bits256_nonz(rp->desthash) != 0 ) + { + rp->quoteid = basilisk_quoteid(rp); + printf("set quoteid.%u\n",rp->quoteid); + } + //printf("create.%u calc.%u\n",rp->requestid,basilisk_requestid(rp)); + return(0); + } + return(-1); +} + +char *basilisk_start(struct supernet_info *myinfo,struct basilisk_request *rp,uint32_t statebits) +{ + cJSON *retjson; + if ( (bits256_cmp(rp->hash,myinfo->myaddr.persistent) == 0 || bits256_cmp(rp->desthash,myinfo->myaddr.persistent) == 0) ) + { + printf("START thread to complete %u/%u for (%s %.8f) <-> (%s %.8f) q.%u\n",rp->requestid,rp->quoteid,rp->src,dstr(rp->srcamount),rp->dest,dstr(rp->destamount),rp->quoteid); + if ( basilisk_thread_start(myinfo,rp) != 0 ) + { + basilisk_request_enqueue(myinfo,rp); + return(clonestr("{\"result\":\"started atomic swap thread\"}")); + } + else return(clonestr("{\"error\":\"couldnt atomic swap thread\"}")); + } + else if ( myinfo->IAMLP != 0 ) + { + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","basilisk node needs to start atomic thread locally"); + return(jprint(retjson,1)); + } else return(clonestr("{\"error\":\"unexpected basilisk_start not mine and amrelay\"}")); +} + +struct basilisk_relay *basilisk_request_ensure(struct supernet_info *myinfo,uint32_t senderipbits,int32_t numrequests) +{ + int32_t j; struct basilisk_relay *relay = 0; + if ( (j= basilisk_relayid(myinfo,senderipbits)) >= 0 ) + { + relay = &RELAYS[j]; + if ( numrequests > relay->maxrequests ) + { + relay->maxrequests = numrequests; + relay->requests = realloc(relay->requests,sizeof(*relay->requests) * numrequests); + } + } + return(relay); +} + +static int _cmp_requests(const void *a,const void *b) +{ +#define uint32_a (*(struct basilisk_request *)a).requestid +#define uint32_b (*(struct basilisk_request *)b).requestid + if ( uint32_b > uint32_a ) + return(1); + else if ( uint32_b < uint32_a ) + return(-1); + else + { +#undef uint32_a +#undef uint32_b +#define uint32_a (*(struct basilisk_request *)a).quoteid +#define uint32_b (*(struct basilisk_request *)b).quoteid + if ( uint32_b > uint32_a ) + return(1); + else if ( uint32_b < uint32_a ) + return(-1); + } + return(0); +#undef uint32_a +#undef uint32_b +} + +struct basilisk_request *_basilisk_requests_uniq(struct supernet_info *myinfo,int32_t *nump,uint8_t *space,int32_t spacesize) +{ + int32_t i,j,n,k,m; struct basilisk_relay *relay; struct basilisk_request *requests,*rp; + for (j=m=0; jnumrequests) > 0 ) + { + for (i=0; irequests[i]; + for (k=0; kipbits; + requests[m++] = *rp; + } + } + } + } + qsort(requests,m,sizeof(*requests),_cmp_requests); + *nump = m; + return(requests); +} + +/*char *basilisk_respond_swapstatus(struct supernet_info *myinfo,bits256 hash,uint32_t requestid,uint32_t quoteid) +{ + cJSON *array,*retjson; + array = cJSON_CreateArray(); + retjson = cJSON_CreateObject(); + jadd(retjson,"result",array); + return(jprint(retjson,1)); +}*/ + +char *basilisk_respond_requests(struct supernet_info *myinfo,bits256 hash,uint32_t requestid,uint32_t quoteid) +{ + int32_t i,qflag,num=0; cJSON *retjson,*array; struct basilisk_request *requests,*rp; uint8_t space[4096]; + array = cJSON_CreateArray(); + portable_mutex_lock(&myinfo->DEX_reqmutex); + if ( (requests= _basilisk_requests_uniq(myinfo,&num,space,sizeof(space))) != 0 ) + { + //printf("numrequests.%d r.%u q.%u\n",num,requestid,quoteid); + for (i=0; iquoteid && (bits256_cmp(hash,rp->hash) == 0 || bits256_cmp(hash,rp->desthash) == 0)) ) + qflag = 1; + else qflag = 0; + if ( requestid == 0 || (rp->requestid == requestid && qflag != 0) ) + jaddi(array,basilisk_requestjson(rp)); + } + } + portable_mutex_unlock(&myinfo->DEX_reqmutex); + if ( requests != (void *)space ) + free(requests); + retjson = cJSON_CreateObject(); + jadd(retjson,"result",array); + return(jprint(retjson,1)); +} + +char *basilisk_respond_accept(struct supernet_info *myinfo,uint32_t requestid,uint32_t quoteid) +{ + int32_t i,num=0; char *retstr=0; struct basilisk_request *requests,*rp; uint8_t space[4096]; + portable_mutex_lock(&myinfo->DEX_reqmutex); + if ( (requests= _basilisk_requests_uniq(myinfo,&num,space,sizeof(space))) != 0 ) + { + for (i=0; irequestid == requestid && rp->quoteid == quoteid ) + { + printf("start from accept\n"); + retstr = basilisk_start(myinfo,rp,1); + break; + } + } + } + portable_mutex_unlock(&myinfo->DEX_reqmutex); + if ( requests != (void *)space ) + free(requests); + if ( retstr == 0 ) + retstr = clonestr("{\"error\":\"couldnt find to requestid to choose\"}"); + return(retstr); +} + +// respond to incoming RID, ACC, DEX, QST + +/*char *basilisk_respond_RID(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) +{ + return(basilisk_respond_requests(myinfo,hash,juint(valsobj,"requestid"),0)); +} + +char *basilisk_respond_SWP(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) +{ +return(basilisk_respond_swapstatus(myinfo,hash,juint(valsobj,"requestid"),juint(valsobj,"quoteid"))); +} + +char *basilisk_respond_ACC(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) +{ + uint32_t requestid,quoteid; + if ( (requestid= juint(valsobj,"requestid")) != 0 && (quoteid= juint(valsobj,"quoteid")) != 0 ) + return(basilisk_respond_accept(myinfo,requestid,quoteid)); + else return(clonestr("{\"error\":\"need nonzero requestid and quoteid\"}")); +} + +char *basilisk_respond_DEX(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) +{ + char *retstr=0,buf[256]; struct basilisk_request R; + if ( basilisk_request_create(&R,valsobj,hash,juint(valsobj,"timestamp")) == 0 ) + { + char str[65]; printf("DEX.(%s %.8f) -> %s %s\n",R.src,dstr(R.srcamount),R.dest,bits256_str(str,hash)); + if ( basilisk_request_enqueue(myinfo,&R) != 0 ) + { + sprintf(buf,"{\"result\":\"DEX request added\",\"requestid\":%u}",R.requestid); + retstr = clonestr(buf); + } else retstr = clonestr("{\"error\":\"DEX quote couldnt be created\"}"); + } else retstr = clonestr("{\"error\":\"missing or invalid fields\"}"); + return(retstr); +}*/ + +#include "../includes/iguana_apidefs.h" +#include "../includes/iguana_apideclares.h" + +THREE_STRINGS_AND_DOUBLE(tradebot,aveprice,comment,base,rel,basevolume) +{ + double retvals[4],aveprice; cJSON *retjson = cJSON_CreateObject(); + aveprice = instantdex_avehbla(myinfo,retvals,base,rel,basevolume); + jaddstr(retjson,"result","success"); + jaddnum(retjson,"aveprice",aveprice); + jaddnum(retjson,"avebid",retvals[0]); + jaddnum(retjson,"bidvol",retvals[1]); + jaddnum(retjson,"aveask",retvals[2]); + jaddnum(retjson,"askvol",retvals[3]); + return(jprint(retjson,1)); +} + +ZERO_ARGS(InstantDEX,allcoins) +{ + struct iguana_info *tmp; cJSON *basilisk,*virtual,*full,*retjson = cJSON_CreateObject(); + full = cJSON_CreateArray(); + basilisk = cJSON_CreateArray(); + virtual = cJSON_CreateArray(); + HASH_ITER(hh,myinfo->allcoins,coin,tmp) + { + if ( coin->virtualchain != 0 ) + jaddistr(virtual,coin->symbol); + if ( coin->FULLNODE != 0 || coin->VALIDATENODE != 0 ) + jaddistr(full,coin->symbol); + else jaddistr(basilisk,coin->symbol); + } + jadd(retjson,"basilisk",basilisk); + jadd(retjson,"full",full); + jadd(retjson,"virtual",virtual); + return(jprint(retjson,1)); +} + +STRING_ARG(InstantDEX,available,source) +{ + if ( source != 0 && source[0] != 0 && (coin= iguana_coinfind(source)) != 0 ) + { + if ( myinfo->expiration != 0 ) + return(bitcoinrpc_getbalance(myinfo,coin,json,remoteaddr,"*",coin->chain->minconfirms,1,1<<30)); + else return(clonestr("{\"error\":\"need to unlock wallet\"}")); + } else return(clonestr("{\"error\":\"specified coin is not active\"}")); +} + +HASH_ARRAY_STRING(InstantDEX,request,hash,vals,hexstr) +{ + uint8_t serialized[512]; struct basilisk_request R; cJSON *reqjson; uint32_t datalen=0,DEX_channel; + myinfo->DEXactive = (uint32_t)time(NULL) + INSTANTDEX_LOCKTIME; + jadd64bits(vals,"minamount",jdouble(vals,"minprice") * jdouble(vals,"amount") * SATOSHIDEN); + if ( jobj(vals,"desthash") == 0 ) + jaddbits256(vals,"desthash",hash); + jadd64bits(vals,"satoshis",jdouble(vals,"amount") * SATOSHIDEN); + jadd64bits(vals,"destsatoshis",jdouble(vals,"destamount") * SATOSHIDEN); + jaddnum(vals,"timestamp",time(NULL)); + hash = myinfo->myaddr.persistent; + printf("service.(%s)\n",jprint(vals,0)); + { + memset(&R,0,sizeof(R)); + if ( basilisk_request_create(&R,vals,hash,juint(vals,"timestamp")) == 0 ) + { + printf("R.requestid.%u vs calc %u, q.%u\n",R.requestid,basilisk_requestid(&R),R.quoteid); + if ( RELAYID >= 0 ) + R.relaybits = myinfo->myaddr.myipbits; + if ( (reqjson= basilisk_requestjson(&R)) != 0 ) + free_json(reqjson); + datalen = basilisk_rwDEXquote(1,serialized,&R); + printf("R.requestid.%u vs calc %u, q.%u datalen.%d\n",R.requestid,basilisk_requestid(&R),R.quoteid,datalen); + basilisk_rwDEXquote(0,serialized,&R); + } else printf("error creating request\n"); + } + if ( datalen > 0 ) + { + memset(hash.bytes,0,sizeof(hash)); + DEX_channel = 'D' + ((uint32_t)'E' << 8) + ((uint32_t)'X' << 16); + if ( basilisk_channelsend(myinfo,hash,DEX_channel,(uint32_t)time(NULL),serialized,datalen,30) == 0 ) + return(clonestr("{\"result\":\"DEX message sent\"}")); + else return(clonestr("{\"error\":\"DEX message couldnt be sent\"}")); + } + return(clonestr("{\"error\":\"DEX message not sent\"}")); + //return(basilisk_standardservice("DEX",myinfo,0,myinfo->myaddr.persistent,vals,"",1)); +} + +INT_ARG(InstantDEX,automatched,requestid) +{ + // return quoteid + myinfo->DEXactive = (uint32_t)time(NULL) + INSTANTDEX_LOCKTIME; + return(clonestr("{\"result\":\"automatched not yet\"}")); +} + +INT_ARG(InstantDEX,incoming,requestid) +{ + cJSON *vals; char *retstr; + myinfo->DEXactive = (uint32_t)time(NULL) + INSTANTDEX_LOCKTIME; + //if ( myinfo->IAMLP != 0 ) + // return(basilisk_respond_requests(myinfo,myinfo->myaddr.persistent,requestid,0)); + //else + { + vals = cJSON_CreateObject(); + jaddnum(vals,"requestid",(uint32_t)requestid); + jaddbits256(vals,"hash",myinfo->myaddr.persistent); + retstr = basilisk_standardservice("RID",myinfo,0,myinfo->myaddr.persistent,vals,"",1); + free_json(vals); + return(retstr); + } +} + +/*TWO_INTS(InstantDEX,swapstatus,requestid,quoteid) +{ + cJSON *vals; char *retstr; + myinfo->DEXactive = (uint32_t)time(NULL) + INSTANTDEX_LOCKTIME; + //if ( myinfo->IAMLP != 0 ) + // return(basilisk_respond_swapstatus(myinfo,myinfo->myaddr.persistent,requestid,quoteid)); + //else + { + vals = cJSON_CreateObject(); + jaddnum(vals,"requestid",(uint32_t)requestid); + jaddnum(vals,"quoteid",(uint32_t)quoteid); + jaddbits256(vals,"hash",myinfo->myaddr.persistent); + retstr = basilisk_standardservice("SWP",myinfo,0,myinfo->myaddr.persistent,vals,"",1); + free_json(vals); + return(retstr); + } +}*/ + +TWO_INTS(InstantDEX,accept,requestid,quoteid) +{ + cJSON *vals; char *retstr; + myinfo->DEXactive = (uint32_t)time(NULL) + INSTANTDEX_LOCKTIME; + //if ( myinfo->IAMLP != 0 ) + // return(basilisk_respond_accept(myinfo,requestid,quoteid)); + //else + { + vals = cJSON_CreateObject(); + jaddnum(vals,"quoteid",(uint32_t)quoteid); + jaddnum(vals,"requestid",(uint32_t)requestid); + retstr = basilisk_standardservice("ACC",myinfo,0,myinfo->myaddr.persistent,vals,"",1); + free_json(vals); + return(retstr); + } +} +#include "../includes/iguana_apiundefs.h" diff --git a/basilisk/basilisk_MSG.c b/basilisk/basilisk_MSG.c new file mode 100755 index 000000000..c64269041 --- /dev/null +++ b/basilisk/basilisk_MSG.c @@ -0,0 +1,290 @@ +/****************************************************************************** + * Copyright © 2014-2016 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +// included from basilisk.c + +char *basilisk_respond_addmessage(struct supernet_info *myinfo,uint8_t *key,int32_t keylen,uint8_t *data,int32_t datalen,int32_t sendping,uint32_t duration) +{ + struct basilisk_message *msg; int32_t i; + HASH_FIND(hh,myinfo->messagetable,key,keylen,msg); + if ( msg == 0 && keylen == BASILISK_KEYSIZE ) + { + msg = calloc(1,sizeof(*msg) + datalen); + if ( duration == 0 ) + duration = BASILISK_MSGDURATION; + else if ( duration > INSTANTDEX_LOCKTIME*2 ) + duration = INSTANTDEX_LOCKTIME*2; + msg->duration = duration; + msg->expiration = (uint32_t)time(NULL) + duration; + msg->keylen = keylen; + memcpy(msg->key,key,keylen); + msg->datalen = datalen; + memcpy(msg->data,data,datalen); + portable_mutex_lock(&myinfo->messagemutex); + HASH_ADD_KEYPTR(hh,myinfo->messagetable,msg->key,msg->keylen,msg); + for (i=0; imessagemutex); + if ( sendping != 0 ) + { + queue_enqueue("basilisk_message",&myinfo->msgQ,&msg->DL,0); + return(clonestr("{\"result\":\"message added to hashtable\"}")); + } else return(0); + } else return(0); +} + +cJSON *basilisk_respond_getmessage(struct supernet_info *myinfo,uint8_t *key,int32_t keylen) +{ + cJSON *msgjson=0; struct basilisk_message *msg; char *ptr = 0,strbuf[32768]; + portable_mutex_lock(&myinfo->messagemutex); + HASH_FIND(hh,myinfo->messagetable,key,keylen,msg); + if ( msg != 0 ) + { + msgjson = cJSON_CreateObject(); + if ( basilisk_addhexstr(&ptr,msgjson,strbuf,sizeof(strbuf),msg->data,msg->datalen) != 0 ) + { + //retjson = cJSON_CreateObject(); + jaddnum(msgjson,"expiration",msg->expiration); + jaddnum(msgjson,"duration",msg->duration); + //jadd(retjson,"message",msgjson); + printf("havemessage len.%d\n",msg->datalen); + } + else + { + //jaddstr(retjson,"error","couldnt add message"); + printf("couldnt add message\n"); + free_json(msgjson); + msgjson = 0; + } + } + portable_mutex_unlock(&myinfo->messagemutex); + return(msgjson); +} + +// respond to incoming OUT, MSG + +int32_t basilisk_messagekey(uint8_t *key,uint32_t channel,uint32_t msgid,bits256 srchash,bits256 desthash) +{ + int32_t keylen = 0; + keylen += iguana_rwnum(1,&key[keylen],sizeof(uint32_t),&channel); + keylen += iguana_rwnum(1,&key[keylen],sizeof(uint32_t),&msgid); + keylen += iguana_rwbignum(1,&key[keylen],sizeof(srchash),srchash.bytes); + keylen += iguana_rwbignum(1,&key[keylen],sizeof(desthash),desthash.bytes); + return(keylen); +} + +char *basilisk_respond_OUT(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) +{ + int32_t keylen,duration; uint8_t key[BASILISK_KEYSIZE]; bits256 senderhash; + senderhash = jbits256(valsobj,"sender"); + duration = juint(valsobj,"duration"); + keylen = basilisk_messagekey(key,juint(valsobj,"channel"),juint(valsobj,"msgid"),senderhash,hash); + if( bits256_nonz(senderhash) == 0 && bits256_nonz(hash) == 0 && duration > BASILISK_MSGDURATION ) + duration = BASILISK_MSGDURATION; + // printf("OUT keylen.%d datalen.%d\n",keylen,datalen); + // char str[65]; printf("add message.[%d] channel.%u msgid.%x %s\n",datalen,juint(valsobj,"channel"),juint(valsobj,"msgid"),bits256_str(str,hash)); + return(basilisk_respond_addmessage(myinfo,key,keylen,data,datalen,1,duration)); +} + +char *basilisk_iterate_MSG(struct supernet_info *myinfo,uint32_t channel,uint32_t msgid,bits256 srchash,bits256 desthash,int32_t width) +{ + uint8_t key[BASILISK_KEYSIZE]; int32_t i,keylen; cJSON *item,*retjson,*array; bits256 zero; + memset(zero.bytes,0,sizeof(zero)); + array = cJSON_CreateArray(); + if ( width > 3600 ) + width = 3600; + else if ( width < 1 ) + width = 1; + for (i=0; i 0 ) + { + if ( bits256_nonz(srchash) != 0 ) + { + keylen = basilisk_messagekey(key,channel,msgid,zero,desthash); + if ( (item= basilisk_respond_getmessage(myinfo,key,keylen)) != 0 ) + jaddi(array,item); + } + if ( bits256_nonz(desthash) != 0 ) + { + keylen = basilisk_messagekey(key,channel,msgid,srchash,zero); + if ( (item= basilisk_respond_getmessage(myinfo,key,keylen)) != 0 ) + jaddi(array,item); + } + if ( bits256_nonz(srchash) != 0 || bits256_nonz(desthash) != 0 ) + { + keylen = basilisk_messagekey(key,channel,msgid,zero,zero); + if ( (item= basilisk_respond_getmessage(myinfo,key,keylen)) != 0 ) + jaddi(array,item); + } + } + msgid--; + iguana_rwnum(1,&key[0],sizeof(uint32_t),&msgid); + } + if ( cJSON_GetArraySize(array) > 0 ) + { + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jadd(retjson,"messages",array); + return(jprint(retjson,1)); + } else return(clonestr("{\"error\":\"no messages\"}")); +} + +char *basilisk_respond_MSG(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) +{ + int32_t width; uint32_t msgid,channel; + width = juint(valsobj,"width"); + msgid = juint(valsobj,"msgid"); + channel = juint(valsobj,"channel"); + char str[65]; printf("%s channel.%u msgid.%x datalen.%d width.%d\n",bits256_str(str,hash),juint(valsobj,"channel"),msgid,datalen,width); + return(basilisk_iterate_MSG(myinfo,channel,msgid,jbits256(valsobj,"sender"),hash,width)); +} + +#include "../includes/iguana_apidefs.h" +#include "../includes/iguana_apideclares.h" + +HASH_ARRAY_STRING(basilisk,getmessage,hash,vals,hexstr) +{ + uint32_t msgid,width,channel; + if ( (msgid= juint(vals,"msgid")) == 0 ) + { + msgid = (uint32_t)time(NULL); + jdelete(vals,"msgid"); + jaddnum(vals,"msgid",msgid); + } + if ( RELAYID >= 0 ) + { + channel = juint(vals,"channel"); + width = juint(vals,"width"); + return(basilisk_iterate_MSG(myinfo,channel,msgid,hash,myinfo->myaddr.persistent,width)); + } else return(basilisk_standardservice("MSG",myinfo,0,myinfo->myaddr.persistent,vals,hexstr,1)); +} + +HASH_ARRAY_STRING(basilisk,sendmessage,hash,vals,hexstr) +{ + int32_t keylen,datalen; uint8_t key[BASILISK_KEYSIZE],space[16384],*data,*ptr = 0; char *retstr=0; + if ( RELAYID >= 0 ) + { + keylen = basilisk_messagekey(key,juint(vals,"channel"),juint(vals,"msgid"),jbits256(vals,"sender"),hash); + if ( (data= get_dataptr(BASILISK_HDROFFSET,&ptr,&datalen,space,sizeof(space),hexstr)) != 0 ) + retstr = basilisk_respond_addmessage(myinfo,key,keylen,data,datalen,0,juint(vals,"duration")); + if ( ptr != 0 ) + free(ptr); + if ( retstr != 0 ) + free(retstr); + } + if ( vals != 0 && juint(vals,"fanout") == 0 ) + jaddnum(vals,"fanout",(int32_t)sqrt(NUMRELAYS)+2); + return(basilisk_standardservice("OUT",myinfo,0,hash,vals,hexstr,0)); +} +#include "../includes/iguana_apiundefs.h" + +int32_t basilisk_channelsend(struct supernet_info *myinfo,bits256 hash,uint32_t channel,uint32_t msgid,uint8_t *data,int32_t datalen,uint32_t duration) +{ + char *retstr,*hexstr,strbuf[4096],*ptr = 0; int32_t retval = -1; cJSON *valsobj; + if ( (hexstr= basilisk_addhexstr(&ptr,0,strbuf,sizeof(strbuf),data,datalen)) != 0 ) + { + valsobj = cJSON_CreateObject(); + jaddnum(valsobj,"channel",channel); + if ( msgid == 0 ) + msgid = (uint32_t)time(NULL); + jaddnum(valsobj,"fanout",(int32_t)sqrt(NUMRELAYS)+2); + jaddnum(valsobj,"msgid",msgid); + jaddnum(valsobj,"duration",duration); + jaddbits256(valsobj,"sender",myinfo->myaddr.persistent); + char str[65]; printf("sendmessage.[%d] channel.%u msgid.%x -> %s numrelays.%d:%d\n",datalen,channel,msgid,bits256_str(str,hash),NUMRELAYS,juint(valsobj,"fanout")); + if ( (retstr= basilisk_sendmessage(myinfo,0,0,0,hash,valsobj,hexstr)) != 0 ) + free(retstr); + free_json(valsobj); + if ( ptr != 0 ) + free(ptr); + retval = 0; + } else printf("error adding hexstr datalen.%d\n",datalen); + return(retval); +} + +int32_t basilisk_message_returned(uint8_t *data,int32_t maxlen,cJSON *item) +{ + char *hexstr=0; cJSON *msgobj; int32_t datalen=0,retval = -1; + if ( (msgobj= jobj(item,"message")) != 0 ) + { + if ( (hexstr= jstr(msgobj,"data")) != 0 && (datalen= is_hexstr(hexstr,0)) > 0 ) + { + datalen >>= 1; + if ( datalen < maxlen ) + { + decode_hex(data,datalen,hexstr); + //printf("decoded hexstr.[%d]\n",datalen); + retval = datalen; + } else printf("datalen.%d < maxlen.%d\n",datalen,maxlen); + } else printf("no hexstr.%p or datalen.%d\n",hexstr,datalen); + } //else printf("no msgobj\n"); + return(retval); +} + +cJSON *basilisk_channelget(struct supernet_info *myinfo,bits256 hash,uint32_t channel,uint32_t msgid,int32_t width) +{ + char *retstr; cJSON *valsobj,*retarray=0,*item; + valsobj = cJSON_CreateObject(); + jaddnum(valsobj,"channel",channel); + if ( msgid == 0 ) + msgid = (uint32_t)time(NULL); + jaddnum(valsobj,"msgid",msgid); + jaddnum(valsobj,"width",width); + jaddnum(valsobj,"fanout",1); + if ( (retstr= basilisk_getmessage(myinfo,0,0,0,hash,valsobj,0)) != 0 ) + { + printf("channel.%u msgid.%u gotmessage.(%s)\n",channel,msgid,retstr); + if ( (retarray= cJSON_Parse(retstr)) != 0 ) + { + if ( is_cJSON_Array(retarray) == 0 ) + { + item = cJSON_CreateArray(); + jaddi(item,retarray); + retarray = item; + } + } + free(retstr); + } + free_json(valsobj); + return(retarray); +} + +int32_t basilisk_process_retarray(struct supernet_info *myinfo,void *ptr,int32_t (*process_func)(struct supernet_info *myinfo,void *ptr,int32_t (*internal_func)(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen),uint32_t channel,uint32_t msgid,uint8_t *data,int32_t datalen,uint32_t expiration,uint32_t duration),uint8_t *data,int32_t maxlen,uint32_t channel,uint32_t msgid,cJSON *retarray,int32_t (*internal_func)(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen)) +{ + cJSON *item; uint32_t duration,expiration; int32_t i,n,datalen,errs = 0; + if ( (n= cJSON_GetArraySize(retarray)) > 0 ) + { + for (i=0; i 0 ) + { + duration = juint(item,"duration"); + expiration = juint(item,"expiration"); + if ( (*process_func)(myinfo,ptr,internal_func,channel,msgid,data,datalen,expiration,duration) < 0 ) + errs++; + } + } + } + if ( errs > 0 ) + return(-errs); + else return(n); +} diff --git a/basilisk/basilisk_bitcoin.c b/basilisk/basilisk_bitcoin.c new file mode 100755 index 000000000..159e972c1 --- /dev/null +++ b/basilisk/basilisk_bitcoin.c @@ -0,0 +1,1130 @@ +/****************************************************************************** + * Copyright © 2014-2016 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +/*struct bitcoin_rawtxdependents +{ + int64_t spentsatoshis,outputsum,cost,change; + int32_t numptrs,numresults; + char **results,*coinaddrs; + struct basilisk_item *ptrs[]; +};*/ + +#ifdef bitcoincancalculatebalances +int64_t bitcoin_value(struct iguana_info *coin,bits256 txid,int16_t vout,char *coinaddr) +{ + char params[512],str[65]; char *curlstr; cJSON *txobj,*vouts,*item,*sobj,*addrs; int32_t j,m,n; int64_t value = 0; + sprintf(params,"[\"%s\", 1]",bits256_str(str,txid)); + if ( (curlstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"getrawtransaction",params)) != 0 ) + { + if ( (txobj= cJSON_Parse(curlstr)) != 0 ) + { + if ( (vouts= jarray(&n,txobj,"vout")) != 0 && vout < n ) + { + item = jitem(vouts,vout); + if ( (sobj= jobj(item,"scriptPubKey")) != 0 && (addrs= jarray(&m,sobj,"addresses")) != 0 ) + { + for (j=0; jsymbol,coin->chain->serverport,coin->chain->userpass,"getinfo",params)) != 0 ) + { + if ( (curljson= cJSON_Parse(curlstr)) != 0 ) + { + if ( (height= juint(curljson,"blocks")) > lastheight ) + maxconf = height - lastheight; + free_json(curljson); + } + free(curlstr); + } + sprintf(params,"%d, %d, [\"%s\"]",minconf,maxconf,coinaddr); + if ( (curlstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"listunspent",params)) != 0 ) + { + if ( (array= cJSON_Parse(curlstr)) != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; ichain->genesis_hashdata); + return(clonestr(numstr)); + } + } + return(0); + } + return(blockhashstr); +} + +int32_t basilisk_blockhashes(struct iguana_info *coin,int32_t height,int32_t n) +{ + char *blockhashstr; struct iguana_block *block,*checkblock; struct iguana_bundle *bp=0; int32_t bundlei,checki,h,i,num = 0; bits256 zero,hash2; + h = height; + for (i=0; iheight == h && block->mainchain != 0 ) + continue; + if ( (blockhashstr= basilisk_bitcoinblockhashstr(coin->symbol,coin->chain->serverport,coin->chain->userpass,h)) != 0 && bits256_nonz(hash2) != 0 ) + { + hash2 = bits256_conv(blockhashstr); + memset(zero.bytes,0,sizeof(zero)); + block = iguana_blockhashset("remote",coin,h,hash2,1); + if ( (bundlei= (h % coin->chain->bundlesize)) == 0 ) + bp = iguana_bundlecreate(coin,&checki,h,hash2,zero,1); + iguana_bundlehash2add(coin,&checkblock,bp,bundlei,hash2); + if ( block != checkblock ) + printf("bp.%p block mismatch %p %p at ht.%d bundlei.%d\n",bp,block,checkblock,h,bundlei); + else + { + block->mainchain = 1; + char str[65]; printf("%s ht.%d\n",bits256_str(str,hash2),h); + num++; + } + free(blockhashstr); + } + } + return(num); +} + +int32_t basilisk_blockheight(struct iguana_info *coin,bits256 hash2) +{ + char buf[128],str[65],*blocktxt; cJSON *blockjson; int32_t height=-1; + sprintf(buf,"\"%s\"",bits256_str(str,hash2)); + if ( (blocktxt= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"getblock",buf)) != 0 ) + { + if ( (blockjson= cJSON_Parse(blocktxt)) != 0 ) + { + height = jint(blockjson,"height"); + free_json(blockjson); + } + free(blocktxt); + } + return(height); +} + +cJSON *bitcoin_blockjson(int32_t *heightp,char *coinstr,char *serverport,char *userpass,char *blockhashstr,int32_t height) +{ + cJSON *json = 0; int32_t flag = 0; char buf[1024],*blocktxt = 0; + if ( blockhashstr == 0 ) + blockhashstr = basilisk_bitcoinblockhashstr(coinstr,serverport,userpass,height), flag = 1; + if ( blockhashstr != 0 ) + { + sprintf(buf,"\"%s\"",blockhashstr); + blocktxt = bitcoind_passthru(coinstr,serverport,userpass,"getblock",buf); + //printf("get_blockjson.(%d %s) %s\n",height,blockhashstr,blocktxt); + if ( blocktxt != 0 && blocktxt[0] != 0 && (json= cJSON_Parse(blocktxt)) != 0 && heightp != 0 ) + if ( (*heightp= juint(json,"height")) != height ) + *heightp = -1; + if ( flag != 0 && blockhashstr != 0 ) + free(blockhashstr); + if ( blocktxt != 0 ) + free(blocktxt); + } + return(json); +} + +int32_t basilisk_bitcoinscan(struct iguana_info *coin,uint8_t origblockspace[IGUANA_MAXPACKETSIZE],struct OS_memspace *rawmem) +{ + struct iguana_txblock txdata; struct iguana_block B; int32_t len,starti,h,num=0,loadheight,hexlen,datalen,n,i,numtxids,flag=0,j,height=-1; cJSON *curljson,*blockjson,*txids; char *bitstr,*curlstr,params[128],str[65]; struct iguana_msghdr H; struct iguana_msgblock *msg; uint8_t *blockspace,revbits[4],bitsbuf[4]; bits256 hash2,checkhash2; + strcpy(params,"[]"); + if ( (curlstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"getinfo",params)) != 0 ) + { + if ( (curljson= cJSON_Parse(curlstr)) != 0 ) + { + height = juint(curljson,"blocks"); + free_json(curljson); + } + free(curlstr); + } + loadheight = coin->blocks.hwmchain.height; + basilisk_blockhashes(coin,loadheight,coin->chain->bundlesize); + for (j=0; jchain->bundlesize; j++) + { + if ( loadheight == 0 ) + { + loadheight++; + continue; + } + basilisk_blockhashes(coin,loadheight,1); + flag = 0; + if ( (blockjson= bitcoin_blockjson(&h,coin->symbol,coin->chain->serverport,coin->chain->userpass,0,loadheight)) != 0 ) + { + blockspace = origblockspace; + memset(&B,0,sizeof(B)); + B.RO.version = juint(blockjson,"version"); + B.RO.prev_block = jbits256(blockjson,"previousblockhash"); + B.RO.merkle_root = jbits256(blockjson,"merkleroot"); + B.RO.timestamp = juint(blockjson,"time"); + if ( (bitstr= jstr(blockjson,"nBits")) != 0 ) + { + decode_hex(revbits,sizeof(uint32_t),bitstr); + for (i=0; i<4; i++) + bitsbuf[i] = revbits[3 - i]; + memcpy(&B.RO.bits,bitsbuf,sizeof(B.RO.bits)); + } + printf("need to handle zcash/auxpow\n"); + B.RO.nonce = juint(blockjson,"nonce"); + //char str[65],str2[65]; + //printf("v.%d t.%u bits.%08x nonce.%x %s %s\n",B.RO.version,B.RO.timestamp,B.RO.bits,B.RO.nonce,bits256_str(str,B.RO.prev_block),bits256_str(str2,B.RO.merkle_root)); + iguana_serialize_block(coin->chain,&checkhash2,blockspace,&B); + msg = (void *)blockspace; + //printf("(%s)\n",jprint(blockjson,0)); + checkhash2 = iguana_calcblockhash(coin->symbol,coin->chain->hashalgo,blockspace,sizeof(*msg)-4); + if ( jstr(blockjson,"hash") != 0 ) + hash2 = bits256_conv(jstr(blockjson,"hash")); + else memset(hash2.bytes,0,sizeof(hash2)); + //printf("%s vs %s %ld\n",bits256_str(str,hash2),bits256_str(str2,checkhash2),sizeof(*msg)-4); + datalen = 80; + if ( (txids= jarray(&numtxids,blockjson,"tx")) != 0 ) + { + msg->txn_count = numtxids; + if ( numtxids < 0xfd ) + blockspace[datalen++] = numtxids; + else + { + blockspace[datalen++] = 0xfd; + blockspace[datalen++] = numtxids & 0xff; + blockspace[datalen++] = numtxids >> 8; + } + starti = datalen; + for (i=0; isymbol,coin->chain->serverport,coin->chain->userpass,"getrawtransaction",params)) != 0 ) + { + //printf("%s txid.%d\n",curlstr,i); + if ( (hexlen= is_hexstr(curlstr,0)) > 1 ) + { + hexlen >>= 1; + decode_hex(&blockspace[datalen],hexlen,curlstr); + datalen += hexlen; + } + free(curlstr); + } + } + num++; + coin->blocks.pending++; + if ( rawmem->ptr == 0 ) + iguana_meminit(rawmem,"basilisk",0,IGUANA_MAXPACKETSIZE*3,0); + else iguana_memreset(rawmem); + memset(&txdata,0,sizeof(txdata)); + memset(&H,0,sizeof(H)); + if ( (n= iguana_gentxarray(coin,rawmem,&txdata,&len,blockspace,datalen)) == datalen || n == datalen-1 ) + { + len = n; + iguana_gotblockM(coin,0,&txdata,rawmem->ptr,&H,blockspace,datalen,0); + flag = 1; + //if ( (rand() % 1000) == 0 ) + printf("%s h.%-7d len.%-6d | HWM.%d\n",coin->symbol,h,datalen,coin->blocks.hwmchain.height); + } + else + { + printf(" parse error block.%d txn_count.%d, n.%d len.%d vs datalen.%d\n",loadheight,txdata.block.RO.txn_count,n,len,datalen); + } + } + free_json(blockjson); + } + loadheight++; + if ( flag == 0 ) + break; + } + if ( coin->blocks.pending > 0 ) + coin->blocks.pending--; + return(num); +} +#endif + +int32_t basilisk_bitcoinavail(struct iguana_info *coin) +{ + if ( coin->VALIDATENODE != 0 || coin->FULLNODE != 0 ) + return(1); + //else if ( coin->chain->serverport[0] != 0 ) + // return(1); + else return(0); +} + +void *basilisk_bitcoinbalances(struct basilisk_item *Lptr,struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,int32_t timeoutmillis,cJSON *vals) +{ + int64_t balance,total = 0; int32_t i,n,hist; cJSON *spends,*unspents,*retjson,*item,*addresses,*array = cJSON_CreateArray(); + spends = unspents = 0; + if ( (hist= juint(vals,"history")) != 0 ) + { + if ( (hist & 1) != 0 ) + unspents = cJSON_CreateArray(); + if ( (hist & 2) != 0 ) + spends = cJSON_CreateArray(); + } + //printf("hist.%d (%s) %p %p\n",hist,jprint(vals,0),unspents,spends); + if ( (addresses= jarray(&n,vals,"addresses")) != 0 ) + { + for (i=0; iRTheight > 0 ) + balance = iguana_addressreceived(myinfo,coin,vals,remoteaddr,0,0,unspents,spends,jstri(addresses,i),juint(vals,"minconf"),juint(vals,"firstheight")); + //else balance = 0; + item = cJSON_CreateObject(); + jaddnum(item,jstri(addresses,i),dstr(balance)); + jaddi(array,item); + total += balance; + //printf("%.8f ",dstr(balance)); + } + } + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"ipaddr",myinfo->ipaddr); + jaddnum(retjson,"total",dstr(total)); + jadd(retjson,"addresses",array); + if ( unspents != 0 ) + jadd(retjson,"unspents",unspents); + if ( spends != 0 ) + jadd(retjson,"spends",spends); + jaddnum(retjson,"RTheight",coin->RTheight); + jaddnum(retjson,"longest",coin->longestchain); + jaddnum(retjson,"lag",coin->longestchain- coin->RTheight); + Lptr->retstr = jprint(retjson,1); + return(Lptr); +} + +char *basilisk_valuestr(struct iguana_info *coin,char *coinaddr,uint64_t value,int32_t height,bits256 txid,int16_t vout) +{ + cJSON *retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"address",coinaddr); + jadd64bits(retjson,"satoshis",value); + jaddnum(retjson,"value",dstr(value)); + jaddnum(retjson,"height",height); + jaddnum(retjson,"numconfirms",coin->blocks.hwmchain.height - height + 1); + jaddbits256(retjson,"txid",txid); + jaddnum(retjson,"vout",vout); + jaddstr(retjson,"coin",coin->symbol); + return(jprint(retjson,1)); +} + +double basilisk_bitcoin_valuemetric(struct supernet_info *myinfo,struct basilisk_item *ptr,char *resultstr) +{ + struct basilisk_value *v; cJSON *resultarg; int32_t ind; + if ( (ind= myinfo->basilisks.numvalues) >= sizeof(myinfo->basilisks.values)/sizeof(*myinfo->basilisks.values) ) + ind = (rand() % (sizeof(myinfo->basilisks.values)/sizeof(*myinfo->basilisks.values))); + else myinfo->basilisks.numvalues++; + v = &myinfo->basilisks.values[ind]; + if ( (resultarg= cJSON_Parse(resultstr)) != 0 ) + { + safecopy(v->coinaddr,jstr(resultarg,"address"),sizeof(v->coinaddr)); + v->value = j64bits(resultarg,"satoshis"); + v->txid = jbits256(resultarg,"txid"); + v->vout = jint(resultarg,"vout"); + v->height = jint(resultarg,"height"); + } + return(ind + 1); +} + +void *basilisk_bitcoinvalue(struct basilisk_item *Lptr,struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,int32_t timeoutmillis,cJSON *valsobj) +{ + int32_t i,height,vout,numsent; struct basilisk_item *ptr; char coinaddr[64],str[64]; struct basilisk_value *v; uint64_t value = 0; bits256 txid; + if ( RELAYID >= 0 ) + return(0); + txid = jbits256(valsobj,"txid"); + vout = jint(valsobj,"vout"); + if ( coin != 0 && basilisk_bitcoinavail(coin) != 0 ) + { + if ( (coin->VALIDATENODE != 0 || coin->FULLNODE != 0) )//&& coinaddr != 0 && coinaddr[0] != 0 ) + { + if ( iguana_RTunspentindfind(myinfo,coin,coinaddr,0,0,&value,&height,txid,vout,coin->bundlescount,0) > 0 ) + { + //printf("bitcoinvalue found iguana\n"); + Lptr->retstr = basilisk_valuestr(coin,coinaddr,value,height,txid,vout); + return(Lptr); + } else printf("unspentind cant find %s vout.%d\n",bits256_str(str,txid),vout); + } //else return(bitcoin_value(coin,txid,vout,coinaddr)); + Lptr->retstr = clonestr("{\"error\":\"basilisk value missing address\"}"); + return(Lptr); + } + //printf("Scan basilisks values\n"); + if ( (v= myinfo->basilisks.values) != 0 ) + { + for (i=0; ibasilisks.numvalues; i++,v++) + { + if ( v->vout == vout && bits256_cmp(txid,v->txid) == 0 && strcmp(v->coinaddr,coinaddr) == 0 ) + { + printf("bitcoinvalue local ht.%d %s %.8f\n",v->height,v->coinaddr,dstr(v->value)); + ptr = basilisk_issueremote(myinfo,0,&numsent,"VAL",coin->symbol,1,valsobj,juint(valsobj,"fanout"),juint(valsobj,"minresults"),basilisktag,timeoutmillis,0,basilisk_valuestr(coin,v->coinaddr,v->value,v->height,txid,vout),0,0,BASILISK_DEFAULTDIFF); // this completes immediate + //queue_enqueue("submitQ",&myinfo->basilisks.submitQ,&ptr->DL,0); + return(ptr); + } + } + } + printf("bitcoinvalue issue remote tag.%u\n",basilisktag); + ptr = basilisk_issueremote(myinfo,0,&numsent,"VAL",coin->symbol,1,valsobj,juint(valsobj,"fanout"),juint(valsobj,"minresults"),basilisktag,timeoutmillis,0,0,0,0,BASILISK_DEFAULTDIFF); + //queue_enqueue("submitQ",&myinfo->basilisks.submitQ,&ptr->DL,0); + return(ptr); +} + +int32_t basilisk_voutvin_validate(struct iguana_info *coin,char *rawtx,uint64_t inputsum,uint64_t amount,uint64_t txfee) +{ + //static int counter; + //if ( counter++ < 10 ) + // printf("validate.(%s) vout's vin\n",rawtx); + if ( rawtx != 0 ) + { + return(0); // convert rawtx, add up outputs, verify totals + } + return(-1); +} + +int32_t basilisk_vins_validate(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *retjson,uint64_t amount,uint64_t txfee) +{ + cJSON *vins,*item,*argjson,*valuearray; uint64_t value,inputsum=0; int32_t j,i=-1,vout,retval=-1,numvins=0; bits256 txid; char *valstr; + if ( retjson != 0 ) + { + if ( (vins= jarray(&numvins,retjson,"vins")) != 0 ) + { + for (i=0; isymbol); + retval = -1; + if ( (valstr= basilisk_value(myinfo,coin,0,0,myinfo->myaddr.persistent,argjson,0)) != 0 ) + { + //printf("valstr.(%d) %s\n",i,valstr); + if ( (valuearray= cJSON_Parse(valstr)) != 0 ) + { + if ( is_cJSON_Array(valuearray) != 0 ) + { + for (j=0; j= 0 ) + return(clonestr("{\"error\":\"special relays only do OUT and MSG\"}")); + vins = 0; + changeaddr = jstr(valsobj,"changeaddr"); + if ( (amount= j64bits(valsobj,"satoshis")) == 0 ) + amount = jdouble(valsobj,"value") * SATOSHIDEN; + if ( (txfee= j64bits(valsobj,"txfee")) == 0 ) + txfee = coin->chain->txfee; + if ( txfee == 0 ) + txfee = 10000; + spendscriptstr = jstr(valsobj,"spendscript"); + minconf = juint(valsobj,"minconf"); + locktime = jint(valsobj,"locktime"); + if ( (addresses= jobj(valsobj,"addresses")) == 0 ) + { + addresses = iguana_getaddressesbyaccount(myinfo,coin,"*"); + jadd(valsobj,"addresses",addresses); + } + //printf("use addresses.(%s)\n",jprint(addresses,0)); + //printf("(%s) vals.(%s) change.(%s) spend.%s\n",coin->symbol,jprint(valsobj,0),changeaddr,spendscriptstr); + if ( changeaddr == 0 || changeaddr[0] == 0 || spendscriptstr == 0 || spendscriptstr[0] == 0 ) + return(clonestr("{\"error\":\"invalid changeaddr or spendscript or addresses\"}")); + if ( coin != 0 )//&& basilisk_bitcoinavail(coin) != 0 ) + { + if ( (txobj= bitcoin_txcreate(coin->chain->isPoS,locktime,locktime==0?coin->chain->normal_txversion:coin->chain->locktime_txversion)) != 0 ) + { + spendlen = (int32_t)strlen(spendscriptstr) >> 1; + decode_hex(buf,spendlen,spendscriptstr); + bitcoin_txoutput(txobj,buf,spendlen,amount); + burnamount = offset = oplen = 0; + if ( (opreturn= jstr(valsobj,"opreturn")) != 0 && (oplen= is_hexstr(opreturn,0)) > 0 ) + { + oplen >>= 1; + if ( (strcmp("BTC",coin->symbol) == 0 && oplen < 77) || coin->chain->do_opreturn == 0 ) + { + decode_hex(&buf[sizeof(buf) - oplen],oplen,opreturn); + spendlen = datachain_datascript(coin,buf,&buf[sizeof(buf) - oplen],oplen); + if ( (burnamount= SATOSHIDEN * jdouble(valsobj,"burn")) < 10000 ) + burnamount = 10000; + bitcoin_txoutput(txobj,buf,spendlen,burnamount); + oplen = 0; + } else oplen = datachain_opreturnscript(coin,buf,opreturn,oplen); + } + rawtx = iguana_calcrawtx(myinfo,coin,&vins,txobj,amount,changeaddr,txfee,addresses,minconf,oplen!=0?buf:0,oplen+offset,burnamount,remoteaddr); + //printf("generated.(%s) vins.(%s)\n",rawtx!=0?rawtx:"",vins!=0?jprint(vins,0):""); + } + if ( rawtx != 0 ) + { + if ( vins != 0 ) + { + free_json(txobj); + valsobj = cJSON_CreateObject(); + jadd(valsobj,"vins",vins); + jaddstr(valsobj,"rawtx",rawtx); + jaddstr(valsobj,"coin",coin->symbol); + free(rawtx); + return(jprint(valsobj,1)); + } else free(rawtx); + } + if ( txobj != 0 ) + free_json(txobj); + if ( vins != 0 ) + free_json(vins); + return(clonestr("{\"error\":\"couldnt create rawtx\"}")); + } + return(clonestr("{\"error\":\"dont have coin to create rawtx\"}")); + //return(basilisk_issueremote(myinfo,0,&numsent,"RAW",coin->symbol,1,valsobj,juint(valsobj,"fanout"),juint(valsobj,"minresults"),basilisktag,timeoutmillis,0,0,0,0,BASILISK_DEFAULTDIFF)); +} + +/* + both fees are standard payments: OP_DUP OP_HASH160 FEE_RMD160 OP_EQUALVERIFY OP_CHECKSIG + + Alice altpayment: OP_2 OP_2 OP_CHECKMULTISIG + + Bob deposit: + OP_IF + OP_CLTV OP_DROP OP_CHECKSIG + OP_ELSE + OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG + OP_ENDIF + + Bob paytx: + OP_IF + OP_CLTV OP_DROP OP_CHECKSIG + OP_ELSE + OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG + OP_ENDIF + + Naming convention are pubAi are alice's pubkeys (seems only pubA0 and not pubA1) + pubBi are Bob's pubkeys + + privN is Bob's privkey from the cut and choose deck as selected by Alice + privM is Alice's counterpart + pubN and pubM are the corresponding pubkeys for these chosen privkeys + + Alice timeout event is triggered if INSTANTDEX_LOCKTIME elapses from the start of a FSM instance. Bob timeout event is triggered after INSTANTDEX_LOCKTIME*2 + */ + + +#ifdef later + +int32_t instantdex_feetxverify(struct supernet_info *myinfo,struct iguana_info *coin,struct basilisk_swap *swap,cJSON *argjson) +{ + cJSON *txobj; bits256 txid; uint32_t n; int32_t i,retval = -1,extralen=65536; int64_t insurance; uint64_t r; + struct iguana_msgtx msgtx; uint8_t script[512],serialized[8192],*extraspace=0; char coinaddr[64]; + if ( swap->otherfee != 0 ) + { + extraspace = calloc(1,extralen); + if ( (txobj= bitcoin_hex2json(coin,&txid,&msgtx,swap->otherfee->txbytes,extraspace,extralen,serialized)) != 0 ) + { + r = swap->other.orderid; + if ( strcmp(coin->symbol,"BTC") == 0 ) + insurance = swap->insurance + swap->bobcoin->chain->txfee; + else insurance = swap->altinsurance + swap->alicecoin->chain->txfee; + n = instantdex_outputinsurance(coinaddr,coin->chain->pubtype,script,insurance,r,r * (strcmp("BTC",coin->symbol) == 0)); + if ( n == msgtx.vouts[0].pk_scriptlen ) + { + if ( memcmp(script,msgtx.vouts[0].pk_script,n) == 0 ) + { + printf("feetx script verified.(%s)\n",swap->otherfee->txbytes); + retval = 0; + } + else + { + for (i=0; iotherfee->txbytes); + } else printf("no feetx to verify\n"); + if ( extraspace != 0 ) + free(extraspace); + return(retval); +} + +struct bitcoin_statetx *instantdex_bobtx(struct supernet_info *myinfo,struct basilisk_swap *swap,struct iguana_info *coin,int64_t amount,int32_t depositflag) +{ + int32_t n,secretstart; struct bitcoin_statetx *ptr = 0; uint8_t script[1024]; uint32_t locktime; int64_t satoshis; char scriptstr[512]; + if ( coin == 0 ) + return(0); + satoshis = amount + depositflag*swap->insurance*100 + swap->bobcoin->chain->txfee; + n = instantdex_bobscript(script,0,&locktime,&secretstart,swap,depositflag); + if ( n < 0 ) + { + printf("instantdex_bobtx couldnt generate bobscript deposit.%d\n",depositflag); + return(0); + } + printf("locktime.%u amount %.8f satoshis %.8f\n",locktime,dstr(amount),dstr(satoshis)); + init_hexbytes_noT(scriptstr,script,n); + if ( (ptr= instantdex_signtx(depositflag != 0 ? "deposit" : "payment",myinfo,coin,locktime,scriptstr,satoshis,coin->txfee,swap->mine.minconfirms,swap->mine.offer.myside)) != 0 ) + { + bitcoin_address(ptr->destaddr,coin->chain->p2shtype,script,n); + printf("BOBTX.%d (%s) -> %s\n",depositflag,ptr->txbytes,ptr->destaddr); + } else printf("sign error for bottx\n"); + return(ptr); +} + +int32_t instantdex_paymentverify(struct supernet_info *myinfo,struct iguana_info *coin,struct basilisk_swap *swap,cJSON *argjson,int32_t depositflag) +{ + cJSON *txobj; bits256 txid; uint32_t n,locktime; int32_t i,secretstart,retval = -1,extralen=65536; uint64_t x; + struct iguana_msgtx msgtx; uint8_t script[512],serialized[8192],*extraspace=0; int64_t amount; + if ( coin != 0 && swap->deposit != 0 ) + { + amount = swap->BTCsatoshis + depositflag*swap->insurance*100 + swap->bobcoin->chain->txfee; + if ( (n= instantdex_bobscript(script,0,&locktime,&secretstart,swap,depositflag)) <= 0 ) + return(retval); + extraspace = calloc(1,extralen); + if ( (txobj= bitcoin_hex2json(coin,&txid,&msgtx,swap->deposit->txbytes,extraspace,extralen,serialized)) != 0 ) + { + memcpy(&script[secretstart],&msgtx.vouts[0].pk_script[secretstart],20); + printf("locktime.%u amount %.8f satoshis %.8f\n",locktime,dstr(amount),dstr(amount)); + if ( msgtx.lock_time == locktime && msgtx.vouts[0].value == amount && n == msgtx.vouts[0].pk_scriptlen ) + { + if ( memcmp(script,msgtx.vouts[0].pk_script,n) == 0 ) + { + iguana_rwnum(0,&script[secretstart],sizeof(x),&x); + printf("deposit script verified\n"); + if ( x == swap->otherdeck[swap->choosei][0] ) + retval = 0; + else printf("deposit script verified but secret mismatch x.%llx vs otherdeck %llx\n",(long long)x,(long long)swap->otherdeck[swap->choosei][0]); + } + else + { + for (i=0; ialtpayment != 0 && (altmsigaddr= jstr(argjson,"altmsigaddr")) != 0 ) + { + extraspace = calloc(1,extralen); + if ( (txobj= bitcoin_hex2json(coin,&txid,&msgtx,swap->altpayment->txbytes,extraspace,extralen,serialized)) != 0 ) + { + n = instantdex_alicescript(script,0,msigaddr,coin->chain->p2shtype,swap->pubAm,swap->pubBn); + if ( strcmp(msigaddr,altmsigaddr) == 0 && n == msgtx.vouts[0].pk_scriptlen ) + { + if ( memcmp(script,msgtx.vouts[0].pk_script,n) == 0 ) + { + printf("altpayment script verified\n"); + retval = 0; + } + else + { + for (i=0; ialtpayment,altmsigaddr!=0?altmsigaddr:""); + if ( extraspace != 0 ) + free(extraspace); + return(retval); +} + +struct bitcoin_statetx *instantdex_alicetx(struct supernet_info *myinfo,struct iguana_info *alicecoin,char *msigaddr,bits256 pubAm,bits256 pubBn,int64_t amount,struct basilisk_swap *swap) +{ + int32_t n; uint8_t script[1024]; char scriptstr[2048]; struct bitcoin_statetx *ptr = 0; + if ( alicecoin != 0 ) + { + if ( bits256_nonz(pubAm) == 0 || bits256_nonz(pubBn) == 0 ) + { + printf("instantdex_bobtx null pubAm.%llx or pubBn.%llx\n",(long long)pubAm.txid,(long long)pubBn.txid); + return(0); + } + n = instantdex_alicescript(script,0,msigaddr,alicecoin->chain->p2shtype,pubAm,pubBn); + init_hexbytes_noT(scriptstr,script,n); + if ( (ptr= instantdex_signtx("altpayment",myinfo,alicecoin,0,scriptstr,amount,alicecoin->txfee,swap->mine.minconfirms,swap->mine.offer.myside)) != 0 ) + { + strcpy(ptr->destaddr,msigaddr); + printf("ALICETX (%s) -> %s\n",ptr->txbytes,ptr->destaddr); + } + } + return(ptr); +} + +cJSON *BTC_makeclaimfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct basilisk_swap *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) +{ + int32_t got_payment=1,bob_reclaimed=0; + *serdatap = 0, *serdatalenp = 0; + if ( instantdex_isbob(swap) == 0 ) + { + // [BLOCKING: payfound] now Alice's turn to make sure payment is confrmed and send in claim or see bob's reclaim and reclaim + if ( got_payment != 0 ) + { + //swap->privAm = swap->privkeys[swap->otherchoosei]; + // sign if/else payment + } + else if ( bob_reclaimed != 0 ) + { + + } + } + else + { + // [BLOCKING: privM] Bob waits for privM either from Alice or alt blockchain + if ( bits256_nonz(swap->privAm) != 0 ) + { + // a multisig tx for alicecoin + } + } + return(newjson); +} +#endif + + +#include "../includes/iguana_apidefs.h" +#include "../includes/iguana_apideclares.h" + +HASH_ARRAY_STRING(basilisk,value,hash,vals,hexstr) +{ + char *retstr=0,*symbol; uint32_t basilisktag; struct basilisk_item *ptr,Lptr; int32_t timeoutmillis; + if ( RELAYID >= 0 ) + return(clonestr("{\"error\":\"special relays only do OUT and MSG\"}")); + //if ( coin == 0 ) + { + if ( (symbol= jstr(vals,"symbol")) != 0 || (symbol= jstr(vals,"coin")) != 0 ) + coin = iguana_coinfind(symbol); + } + if ( jobj(vals,"fanout") == 0 ) + jaddnum(vals,"fanout",(int32_t)sqrt(NUMRELAYS)+1); + if ( coin != 0 ) + { + if ( (basilisktag= juint(vals,"basilisktag")) == 0 ) + basilisktag = rand(); + if ( (timeoutmillis= juint(vals,"timeout")) <= 0 ) + timeoutmillis = BASILISK_TIMEOUT; + if ( coin->FULLNODE != 0 && (ptr= basilisk_bitcoinvalue(&Lptr,myinfo,coin,remoteaddr,basilisktag,timeoutmillis,vals)) != 0 ) + { + retstr = ptr->retstr, ptr->retstr = 0; + ptr->finished = (uint32_t)time(NULL); + return(retstr); + } + } + return(basilisk_standardservice("VAL",myinfo,0,hash,vals,hexstr,1)); +} + +/*HASH_ARRAY_STRING(basilisk,rawtx,hash,vals,hexstr) +{ + char *retstr=0,*symbol; uint32_t basilisktag; struct basilisk_item *ptr,Lptr; int32_t timeoutmillis,i,retval = -1; uint64_t amount,txfee; cJSON *retarray; + //if ( coin == 0 ) + { + if ( (symbol= jstr(vals,"symbol")) != 0 || (symbol= jstr(vals,"coin")) != 0 ) + coin = iguana_coinfind(symbol); + } + if ( jobj(vals,"numrequired") == 0 ) + jaddnum(vals,"numrequired",myinfo->numrelays); + if ( jobj(vals,"fanout") == 0 ) + jaddnum(vals,"fanout",(int32_t)sqrt(myinfo->numrelays)); + if ( coin != 0 ) + { + if ( juint(vals,"burn") == 0 ) + jaddnum(vals,"burn",0.0001); + if ( (basilisktag= juint(vals,"basilisktag")) == 0 ) + basilisktag = rand(); + if ( (timeoutmillis= juint(vals,"timeout")) <= 0 ) + timeoutmillis = BASILISK_TIMEOUT; + if ( (ptr= basilisk_bitcoinrawtx(&Lptr,myinfo,coin,remoteaddr,basilisktag,timeoutmillis,vals)) != 0 ) + { + if ( (retstr= ptr->retstr) != 0 ) + { + if ( (amount= j64bits(vals,"satoshis")) == 0 ) + amount = jdouble(vals,"value") * SATOSHIDEN; + if ( (txfee= j64bits(vals,"txfee")) == 0 ) + txfee = coin->chain->txfee; + if ( txfee == 0 ) + txfee = 10000; + retval = -1; + if ( (retarray= cJSON_Parse(retstr)) != 0 ) + { + if ( is_cJSON_Array(retarray) != 0 ) + { + for (i=0; iretstr = 0; + ptr->finished = (uint32_t)time(NULL); + } + } + } + return(retstr); +}*/ + +cJSON *basilisk_history_item(struct iguana_info *coin,int64_t *totalp,char *coinaddr,int64_t value,uint32_t timestamp,bits256 txid,char *vinvoutstr,int32_t vinvout,int32_t height,char *otherheightstr,int32_t otherheight,uint64_t relaymask,int32_t ismine) +{ + cJSON *item,*details; + item = cJSON_CreateObject(); + jaddstr(item,"address",coinaddr); + jaddnum(item,"amount",dstr(value)); + jaddnum(item,"numseconds",time(NULL) - timestamp); + details = cJSON_CreateObject(); + if ( ismine > 0 ) + { + jaddnum(details,"ismine",ismine); + if ( strcmp(vinvoutstr,"spentheight") == 0 ) + jaddstr(details,"category","sent"); + else jaddstr(details,"category","received"); + } + jaddbits256(details,"txid",txid); + jaddnum(details,vinvoutstr,vinvout); + jaddnum(details,"height",height); + if ( coin->blocks.hwmchain.height > 0 ) + jaddnum(details,"confirms",coin->blocks.hwmchain.height - height); + jaddnum(details,"height",height); + if ( otherheight != 0 ) + jaddnum(details,otherheightstr,otherheight); + else *totalp += value; + jaddnum(details,"relays",bitweight(relaymask)); + jadd(item,"details",details); + return(item); +} + +#include "../includes/iguana_apiundefs.h" + +int32_t basilisk_unspentfind(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,int32_t *voutp,uint8_t *spendscript,struct iguana_outpoint outpt,int64_t value) +{ + struct basilisk_unspent *bu; int32_t i,spendlen; struct iguana_waccount *wacct,*tmp; struct iguana_waddress *waddr,*tmp2; char str[65]; + memset(txidp,0,sizeof(*txidp)); + *voutp = -1; + portable_mutex_lock(&myinfo->bu_mutex); + HASH_ITER(hh,myinfo->wallet,wacct,tmp) + { + HASH_ITER(hh,wacct->waddr,waddr,tmp2) + { + for (i=0; inumunspents; i++) + { + bu = &waddr->unspents[i]; + if ( bu->hdrsi == outpt.hdrsi && bu->unspentind == outpt.unspentind && bu->value == value ) + { + if ( bu->status == 0 ) + { + *txidp = bu->txid; + *voutp = bu->vout; + memcpy(spendscript,bu->script,bu->spendlen); + spendlen = bu->spendlen; + portable_mutex_unlock(&myinfo->bu_mutex); + return(spendlen); + } else printf("unspentfind skip %s/v%d\n",bits256_str(str,bu->txid),bu->vout); + } + } + } + } + portable_mutex_unlock(&myinfo->bu_mutex); + return(-1); +} + +struct basilisk_spend *basilisk_addspend(struct supernet_info *myinfo,char *symbol,bits256 txid,uint16_t vout,int32_t addflag) +{ + int32_t i; struct basilisk_spend *s; + // mutex + if ( myinfo->numspends > 0 ) + { + for (i=0; inumspends; i++) + { + if ( myinfo->spends[i].vout == vout && bits256_cmp(txid,myinfo->spends[i].txid) == 0 ) + { + char str[65]; printf("found spend.%s v%d skip it\n",bits256_str(str,txid),vout); + return(&myinfo->spends[i]); + } + } + } + if ( addflag != 0 && i == myinfo->numspends ) + { + printf("realloc spends.[%d] %p\n",myinfo->numspends,myinfo->spends); + myinfo->spends = realloc(myinfo->spends,sizeof(*myinfo->spends) * (myinfo->numspends+1)); + printf("allocated spends.[%d] %p\n",myinfo->numspends+1,myinfo->spends); + s = &myinfo->spends[myinfo->numspends++]; + memset(s,0,sizeof(*s)); + s->txid = txid; + s->vout = vout; + strcpy(s->symbol,symbol); + //char str[65]; printf("ADDSPEND.%s %s/v%d\n",symbol,bits256_str(str,txid),vout); + // mutex + return(s); + } + // mutex + return(0); +} + +void basilisk_unspent_update(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *item,int32_t spentheight,int32_t relayid,int32_t RTheight) +{ + //{"txid":"4814dc8a357f93f16271eb43806a69416ec41ab1956b128d170402b0a1b37c7f","vout":2,"address":"RSyKVKNxrSDc1Vwvh4guYb9ZDEpvMFz2rm","scriptPubKey":"76a914c210f6711e98fe9971757ede2b2dcb0507f3f25e88ac","amount":9.99920000,"timestamp":1466684518,"height":1160306,"confirmations":22528,"checkind":1157,"spent":{"hdrsi":2320,"pkind":168,"unspentind":1157,"prevunspentind":0,"satoshis":"999920000","txidind":619,"vout":2,"type":2,"fileid":0,"scriptpos":0,"scriptlen":25},"spentheight":1161800,"dest":{"error":"couldnt find spent info"}} + int32_t i,n,j,m,already_spent=0; struct basilisk_unspent bu,bu2; char *address,*script=0,*destaddr; struct iguana_waccount *wacct; struct iguana_waddress *waddr=0; cJSON *dest,*vouts,*vitem; double ratio; + if ( (address= jstr(item,"address")) != 0 && (script= jstr(item,"scriptPubKey")) != 0 && (waddr= iguana_waddresssearch(myinfo,&wacct,address)) != 0 ) + { + if ( relayid >= 64 ) + relayid = 0; + memset(&bu,0,sizeof(bu)); + bu.spendlen = (int32_t)strlen(script) >> 1; + if ( bu.spendlen > sizeof(bu.script) ) + { + printf("spendscript too big.%d\n",bu.spendlen); + return; + } + strcpy(bu.symbol,coin->symbol); + bu.txid = jbits256(item,"txid"); + bu.vout = jint(item,"vout"); + bu.value = jdouble(item,"amount") * SATOSHIDEN; + bu.height = jint(item,"height"); + bu.hdrsi = (bu.height / coin->chain->bundlesize); + bu.unspentind = juint(item,"checkind"); + bu.timestamp = juint(item,"timestamp"); + decode_hex(bu.script,bu.spendlen,script); + //printf("unspentupdate.(%s)\n",jprint(item,0)); + n = waddr->numunspents; + for (i=0; iunspents[i]; + bu2.status = 0; + bu2.RTheight = bu2.spentheight = 0; + bu2.relaymask = 0; + if ( memcmp(&bu,&bu2,sizeof(bu)) == 0 ) + { + if ( waddr->unspents[i].RTheight > RTheight ) + RTheight = waddr->unspents[i].RTheight; + already_spent = waddr->unspents[i].spentheight; + bu.relaymask = waddr->unspents[i].relaymask; + if ( (bu.status= waddr->unspents[i].status) != 0 ) + { + //printf("mempool spend for %s/%d\n",bits256_str(str,bu.txid),bu.vout); + } + break; + } + } + bu.RTheight = RTheight; + bu.relaymask |= ((uint64_t)1 << relayid); + //printf("relayid.%d -> %llx wt.%d\n",relayid,(long long)bu.relaymask,bitweight(bu.relaymask)); + if ( spentheight != 0 ) + already_spent = spentheight; + if ( (bu.spentheight= already_spent) != 0 ) + bu.status = 1; + //printf("i.%d n.%d\n",i,n); + if ( i == n ) + { + if ( i >= waddr->maxunspents ) + { + waddr->maxunspents += 16; + waddr->unspents = realloc(waddr->unspents,sizeof(*waddr->unspents) * waddr->maxunspents); + //printf("allocate max.%d for %s\n",waddr->maxunspents,waddr->coinaddr); + } + waddr->numunspents++; + //printf("new unspent.%s %d script.%p [%d]\n",waddr->coinaddr,waddr->numunspents,bu.script,bu.spendlen); + } + waddr->unspents[i] = bu; + //PREVENT DOUBLE SPENDS!!! and use p2sh + if ( i == n && bu.spentheight != 0 && (dest= jobj(item,"dest")) != 0 ) + { + struct basilisk_spend *s; + //{"txid":"cd4fb72f871d481c534f15d7f639883958936d49e965f58276f0925798e762df","vin":1,"height":,"unspentheight":,"relays":2}}, + if ( (s= basilisk_addspend(myinfo,coin->symbol,bu.txid,bu.vout,1)) != 0 ) + { + s->spentfrom = jbits256(dest,"spentfrom"); + s->vini = jint(dest,"vin"); + s->height = bu.spentheight; + s->timestamp = juint(dest,"timestamp"); + s->unspentheight = bu.height; + s->relaymask = bu.relaymask; + ratio = jdouble(dest,"ratio"); + if ( (vouts= jobj(dest,"vouts")) != 0 && (m= cJSON_GetArraySize(vouts)) > 0 ) + { + for (j=0; jdestaddr,destaddr,sizeof(s->destaddr)); + s->ismine = (iguana_waddresssearch(myinfo,&wacct,destaddr) != 0); + s->value = jdouble(vitem,jfieldname(vitem)) * SATOSHIDEN; + //printf("(%s %.8f) ",s->destaddr,dstr(s->value)); + } + } + //char str[65]; printf("SPEND dest.(%s) ratio %.8f (%s/v%d)\n",jprint(dest,0),ratio,bits256_str(str,s->txid),s->vini); + } + } + } + } else printf("waddr.%p script.%p address.%p %s\n",waddr,script,address,address!=0?address:""); +} + +void basilisk_relay_unspentsprocess(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *relayjson) +{ + int32_t RTheight,relayid,num,j; cJSON *unspents,*spends; + RTheight = jint(relayjson,"RTheight"); + if ( (relayid= basilisk_relayid(myinfo,(uint32_t)calc_ipbits(jstr(relayjson,"relay")))) < BASILISK_MAXRELAYS ) + { + coin->relay_RTheights[relayid] = RTheight; + } + //printf("basilisk_relay_unspentsprocess relayid.%d RT.%d (%s)\n",relayid,RTheight,jprint(relayjson,0)); + if ( (unspents= jarray(&num,relayjson,"unspents")) != 0 ) + { + for (j=0; jFULLNODE == 0 && coin->VALIDATENODE == 0 ) + { + vals = cJSON_CreateObject(); + for (i=oldest=0; irelay_RTheights[i]) != 0 && (oldest == 0 || RTheight < oldest) ) + oldest = RTheight; + jaddnum(vals,"firstheight",oldest); + jaddnum(vals,"history",3); + jaddstr(vals,"coin",coin->symbol); + if ( (retstr= basilisk_balances(myinfo,coin,0,0,GENESIS_PUBKEY,vals,"")) != 0 ) + { + portable_mutex_lock(&myinfo->bu_mutex); + if ( (retarray= cJSON_Parse(retstr)) != 0 ) + { + //printf("%s UNSPENTS_UPDATE.(%s)\n",coin->symbol,retstr); + if ( jobj(retarray,"error") == 0 ) + { + if ( (jstr(retarray,"ipaddr") == 0 || strcmp(jstr(retarray,"ipaddr"),myinfo->ipaddr) != 0) && (n= cJSON_GetArraySize(retarray)) > 0 ) + { + for (i=0; ibu_mutex); + } + free_json(vals); + } +} diff --git a/basilisk/basilisk_ether.c b/basilisk/basilisk_ether.c new file mode 100755 index 000000000..e22d11e78 --- /dev/null +++ b/basilisk/basilisk_ether.c @@ -0,0 +1,19 @@ +/****************************************************************************** + * Copyright © 2014-2016 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +struct basilisk_item *basilisk_etherrawtx(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,cJSON **vinsp,uint32_t locktime,uint64_t satoshis,char *changeaddr,uint64_t txfee,cJSON *addresses,int32_t minconf,char *spendscriptstr,int32_t timeoutmillis) +{ + return(0); +} diff --git a/basilisk/basilisk_iota.c b/basilisk/basilisk_iota.c new file mode 100755 index 000000000..c239af0bb --- /dev/null +++ b/basilisk/basilisk_iota.c @@ -0,0 +1,41 @@ +/****************************************************************************** + * Copyright © 2014-2016 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +char *basilisk_iotarawtx(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,cJSON **vinsp,uint32_t locktime,uint64_t satoshis,char *changeaddr,uint64_t txfee,cJSON *addresses,int32_t minconf,char *spendscriptstr,int32_t timeoutmillis) +{ + cJSON *hexjson,*valsobj; char *retstr = 0; struct basilisk_item *ptr; + *argsjsonp = 0; + if ( addresses != 0 ) + { + valsobj = cJSON_CreateObject(); + jaddnum(valsobj,"basilisktag",basilisktag); + jaddstr(valsobj,"coin",symbol); + jadd64bits(valsobj,"amount",satoshis); + jadd64bits(valsobj,"txfee",txfee); + jaddnum(valsobj,"minconf",minconf); + jaddnum(valsobj,"locktime",locktime); + hexjson = cJSON_CreateObject(); + jaddstr(hexjson,"changeaddr",changeaddr); + jaddstr(hexjson,"spendscriptstr",spendscriptstr); + jadd(hexjson,"addresses",jduplicate(addresses)); + jadd(hexjson,"vals",valsobj); + jaddstr(hexjson,"agent","basilisk"); + jaddstr(hexjson,"method","rawtx"); + if ( (ptr= basilisk_issue(myinfo,hexjson,timeoutmillis,0,1,basilisktag)) != 0 ) + retstr = basilisk_finish(ptr,argsjsonp,0); + free_json(hexjson); + } + return(retstr); +} diff --git a/basilisk/basilisk_lisk.c b/basilisk/basilisk_lisk.c new file mode 100755 index 000000000..ee0d8b0a3 --- /dev/null +++ b/basilisk/basilisk_lisk.c @@ -0,0 +1,19 @@ +/****************************************************************************** + * Copyright © 2014-2016 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +struct basilisk_item *basilisk_liskrawtx(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,cJSON **vinsp,uint32_t locktime,uint64_t satoshis,char *changeaddr,uint64_t txfee,cJSON *addresses,int32_t minconf,char *spendscriptstr,int32_t timeoutmillis) +{ + return(0); +} diff --git a/basilisk/basilisk_nxt.c b/basilisk/basilisk_nxt.c new file mode 100755 index 000000000..9ccb39fb8 --- /dev/null +++ b/basilisk/basilisk_nxt.c @@ -0,0 +1,19 @@ +/****************************************************************************** + * Copyright © 2014-2016 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +struct basilisk_item *basilisk_nxtrawtx(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,cJSON **vinsp,uint32_t locktime,uint64_t satoshis,char *changeaddr,uint64_t txfee,cJSON *addresses,int32_t minconf,char *spendscriptstr,int32_t timeoutmillis) +{ + return(0); +} diff --git a/basilisk/basilisk_ping.c b/basilisk/basilisk_ping.c new file mode 100755 index 000000000..404bb7095 --- /dev/null +++ b/basilisk/basilisk_ping.c @@ -0,0 +1,306 @@ +/****************************************************************************** + * Copyright © 2014-2016 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +// included from basilisk.c + +#ifdef ENABLE_VIRTPING +int32_t basilisk_blocksend(struct supernet_info *myinfo,struct iguana_info *btcd,struct iguana_info *virt,struct iguana_peer *addr,int32_t height) +{ + int32_t blocklen; bits256 hash2; uint8_t *data = 0; char str[65],strbuf[4096],*blockstr,*allocptr = 0; struct iguana_block *block; + hash2 = iguana_blockhash(virt,height); + if ( (block= iguana_blockfind("bsend",virt,hash2)) != 0 ) + { + if ( block->height != height ) + { + printf("basilisk_blocksend: height.%d mismatch %d\n",block->height,height); + return(-1); + } + else if ( block->queued != 0 && block->req != 0 ) + { + memcpy(&blocklen,block->req,sizeof(blocklen)); + data = (uint8_t *)(void *)((long)block->req + sizeof(blocklen)); + } + } + if ( data == 0 ) + { + if ( (blocklen= iguana_peerblockrequest(virt,virt->blockspace,IGUANA_MAXPACKETSIZE,0,hash2,0)) > 0 ) + data = &virt->blockspace[sizeof(struct iguana_msghdr)]; + } + if ( data != 0 ) + { + blockstr = basilisk_addhexstr(&allocptr,0,strbuf,sizeof(strbuf),data,blocklen); + printf("RELAYID.%d send block.%d %s -> (%s) %s\n",myinfo->RELAYID,height,blockstr,addr->ipaddr,bits256_str(str,hash2)); + basilisk_blocksubmit(myinfo,btcd,virt,addr,blockstr,hash2,height); + if ( allocptr != 0 ) + free(allocptr); + return(0); + } else printf("blocklen.%d for hwm.%d height.%d %s\n",blocklen,virt->blocks.hwmchain.height,height,bits256_str(str,hash2)); + return(-1); +} + +int32_t basilisk_ping_processvirts(struct supernet_info *myinfo,struct iguana_info *btcd,struct iguana_peer *addr,uint8_t *data,int32_t datalen) +{ + int32_t diff,i,j,len = 0; struct iguana_info *virt; char symbol[7]; uint32_t numvirts,height; + len += iguana_rwvarint32(0,&data[len],&numvirts); + symbol[6] = 0; + for (i=0; i 0 && addr != 0 && (virt= iguana_coinfind(symbol)) != 0 ) + { + if ( height > virt->longestchain ) + virt->longestchain = height; + if ( NUMRELAYS > 0 && virt->blocks.hwmchain.height > height ) + { + diff = ((height % NUMRELAYS) - myinfo->RELAYID); + diff *= diff; + diff++; + if ( (rand() % diff) == 0 ) + { + for (j=1; height+jblocks.hwmchain.height && j<3; j++) + basilisk_blocksend(myinfo,btcd,virt,addr,height+j); + } + } + } + } + return(len); +} + +int32_t basilisk_ping_genvirts(struct supernet_info *myinfo,uint8_t *data,int32_t maxlen) +{ + struct iguana_info *virt,*tmpcoin; int32_t iter,datalen = 0; uint32_t n; + for (iter=n=0; iter<2; iter++) + { + HASH_ITER(hh,myinfo->allcoins,virt,tmpcoin) + { + if ( virt != 0 && virt->virtualchain != 0 ) + { + if ( iter == 0 ) + n++; + else + { + memcpy(&data[datalen],virt->symbol,6), datalen += 6; + datalen += iguana_rwvarint32(1,&data[datalen],(uint32_t *)&virt->blocks.hwmchain.height); + } + } + } + if ( iter == 0 ) + datalen += iguana_rwvarint32(1,&data[datalen],&n); + } + return(datalen); +} +#endif + +int32_t basilisk_ping_processMSG(struct supernet_info *myinfo,uint32_t senderipbits,uint8_t *data,int32_t datalen) +{ + int32_t i,msglen,len=0; uint8_t num,keylen,*msg,*key; uint32_t duration; + if ( (num= data[len++]) > 0 ) + { + //printf("processMSG num.%d datalen.%d\n",num,datalen); + for (i=0; i datalen ) + { + printf("processMSG overflow len.%d msglen.%d %d > %d\n",len,msglen,(int32_t)(len+sizeof(msglen)),datalen); + return(0); + } + len += iguana_rwnum(0,&data[len],sizeof(msglen),&msglen); + len += iguana_rwnum(0,&data[len],sizeof(duration),&duration); + msg = &data[len], len += msglen; + if ( msglen <= 0 || len > datalen ) + { + printf("illegal msglen.%d or len.%d > %d\n",msglen,len,datalen); + return(0); + } + //printf("i.%d: keylen.%d msglen.%d\n",i,keylen,msglen); + basilisk_respond_addmessage(myinfo,key,keylen,msg,msglen,0,duration); + } + } + return(len); +} + +int32_t basilisk_ping_genMSG(struct supernet_info *myinfo,uint8_t *data,int32_t maxlen) +{ + struct basilisk_message *msg; int32_t datalen = 0; + if ( maxlen > sizeof(msg->key) && (msg= queue_dequeue(&myinfo->msgQ,0)) != 0 ) // oneshot ping + { + data[datalen++] = 1; + data[datalen++] = msg->keylen; + memcpy(&data[datalen],msg->key,msg->keylen), datalen += msg->keylen; + datalen += iguana_rwnum(1,&data[datalen],sizeof(msg->datalen),&msg->datalen); + datalen += iguana_rwnum(1,&data[datalen],sizeof(msg->duration),&msg->duration); + if ( maxlen > datalen+msg->datalen ) + { + //printf("SEND keylen.%d msglen.%d\n",msg->keylen,msg->datalen); + memcpy(&data[datalen],msg->data,msg->datalen), datalen += msg->datalen; + } + else + { + printf("basilisk_ping_genMSG message doesnt fit %d vs %d\n",maxlen,datalen+msg->datalen); + datalen = 0; + } + //printf("\n-> "); + //int32_t i; + //for (i=0; iipbits),&rp->ipbits); + data[datalen++] = rp->direct.pingdelay; + return(datalen); +} + +int32_t baslisk_relay_report(struct supernet_info *myinfo,uint8_t *data,int32_t maxlen,struct basilisk_relaystatus *reported,uint8_t pingdelay) +{ + if ( reported != 0 ) + { + reported->pingdelay = pingdelay; + } + return(0); +} + +int32_t basilisk_ping_processrelay(struct supernet_info *myinfo,uint8_t *data,int32_t maxlen,struct basilisk_relay *rp,int32_t i) +{ + uint8_t pingdelay; int32_t j,datalen = 0; uint32_t ipbits; + ipbits = rp->ipbits; + if ( maxlen < sizeof(ipbits)+1 ) + { + printf("unping error maxlen.%d is too small\n",maxlen); + return(-1); + } + datalen = iguana_rwnum(1,&data[datalen],sizeof(ipbits),&ipbits); + pingdelay = data[datalen++]; + if ( (j= basilisk_relayid(myinfo,ipbits)) >= 0 ) + { + datalen += baslisk_relay_report(myinfo,&data[datalen],maxlen-datalen,&rp->reported[j],pingdelay); + return(datalen); + } + printf("notified about unknown relay\n"); // parse it to match bytes sent + datalen += baslisk_relay_report(myinfo,&data[datalen],maxlen-datalen,0,pingdelay); + return(datalen); +} + +void basilisk_ping_process(struct supernet_info *myinfo,struct iguana_peer *addr,uint32_t senderipbits,uint8_t *data,int32_t datalen) +{ + int32_t diff,i,n,len = 0; struct iguana_info *btcd; char ipbuf[64]; struct basilisk_relay *rp; uint8_t numrelays; uint16_t sn; uint32_t now = (uint32_t)time(NULL); + expand_ipbits(ipbuf,senderipbits); + btcd = iguana_coinfind("BTCD"); + for (i=0; idirect.pingdelay = 0; + if ( rp->ipbits == senderipbits ) + rp->lastping = now; + if ( rp->lastping == now ) + rp->direct.pingdelay = 1; + else + { + diff = (now - rp->lastping); + if ( diff < 0xff ) + rp->direct.pingdelay = diff; + } + } + numrelays = data[len++]; + //len += basilisk_ping_processvirts(myinfo,btcd,addr,&data[len],datalen - len); + for (i=0; i datalen ) + break; + if ( (n= basilisk_ping_processrelay(myinfo,&data[len],datalen-len,rp,i)) < 0 ) + break; + len += n; + } + if ( len <= datalen-sizeof(sn) ) + { + //len += basilisk_ping_processDEX(myinfo,senderipbits,&data[len],datalen-len); + len += basilisk_ping_processMSG(myinfo,senderipbits,&data[len],datalen-len); + } + //printf("PING got %d, processed.%d from (%s)\n",datalen,len,ipbuf); + //else printf("\n"); + //for (i=0; iRELAYID,QUEUEITEMS); +} + +int32_t basilisk_ping_gen(struct supernet_info *myinfo,uint8_t *data,int32_t maxlen) +{ + int32_t i,datalen = 0; + data[datalen++] = NUMRELAYS; + //datalen += basilisk_ping_genvirts(myinfo,&data[datalen],maxlen - datalen); + for (i=0; i>>>>>>>>> Q.%d\n",datalen,myinfo->RELAYID,QUEUEITEMS); + return(datalen); +} + +// encapsulate other messages inside msgQ for onetime ping +// filter out duplicates + +void basilisk_ping_send(struct supernet_info *myinfo,struct iguana_info *btcd) +{ + struct iguana_peer *addr; char ipaddr[64]; struct basilisk_relay *rp; uint32_t r; int32_t i,j,incr,datalen=0; uint64_t alreadysent; + if ( btcd == 0 || NUMRELAYS <= 0 ) + return; + if ( myinfo->pingbuf == 0 ) + myinfo->pingbuf = malloc(IGUANA_MAXPACKETSIZE); + datalen = basilisk_ping_gen(myinfo,&myinfo->pingbuf[sizeof(struct iguana_msghdr)],IGUANA_MAXPACKETSIZE-sizeof(struct iguana_msghdr)); + incr = sqrt(NUMRELAYS) + 1; + for (alreadysent=j=0; j<=incr; j++) + { + OS_randombytes((void *)&r,sizeof(r)); + i = (j == 0) ? RELAYID : (r % NUMRELAYS); + if ( j != 0 && i == RELAYID ) + i = (RELAYID + 1) % NUMRELAYS; + if ( (((uint64_t)1 << i) & alreadysent) != 0 ) + { + j--; + continue; + } + alreadysent |= ((uint64_t)1 << i); + rp = &RELAYS[i]; + addr = 0; + expand_ipbits(ipaddr,rp->ipbits); + if ( rp->ipbits == myinfo->myaddr.myipbits ) + basilisk_ping_process(myinfo,0,myinfo->myaddr.myipbits,&myinfo->pingbuf[sizeof(struct iguana_msghdr)],datalen); + else if ( (addr= iguana_peerfindipbits(btcd,rp->ipbits,1)) != 0 && addr->usock >= 0 ) + { + if ( iguana_queue_send(addr,0,myinfo->pingbuf,"SuperNETPIN",datalen) <= 0 ) + printf("error sending %d to (%s)\n",datalen,addr->ipaddr); + else if ( 0 && datalen > 200 ) + fprintf(stderr,"+(%s).%d ",ipaddr,i); + } //else fprintf(stderr,"-(%s).%d ",ipaddr,i); + } + //printf("my RELAYID.%d of %d\n",myinfo->RELAYID,NUMRELAYS); +} + diff --git a/basilisk/basilisk_swap.c b/basilisk/basilisk_swap.c new file mode 100755 index 000000000..625e9d4f0 --- /dev/null +++ b/basilisk/basilisk_swap.c @@ -0,0 +1,1439 @@ +/****************************************************************************** + * Copyright © 2014-2016 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +// included from basilisk.c +/* https://bitcointalk.org/index.php?topic=1340621.msg13828271#msg13828271 + https://bitcointalk.org/index.php?topic=1364951 + Tier Nolan's approach is followed with the following changes: + a) instead of cutting 1000 keypairs, only INSTANTDEX_DECKSIZE are a + b) instead of sending the entire 256 bits, it is truncated to 64 bits. With odds of collision being so low, it is dwarfed by the ~0.1% insurance factor. + c) D is set to 100x the insurance rate of 1/777 12.87% + BTC amount + d) insurance is added to Bob's payment, which is after the deposit and bailin + e) BEFORE Bob broadcasts deposit, Alice broadcasts BTC denominated fee in cltv so if trade isnt done fee is reclaimed + */ + +/* + both fees are standard payments: OP_DUP OP_HASH160 FEE_RMD160 OP_EQUALVERIFY OP_CHECKSIG + + Alice altpayment: OP_2 OP_2 OP_CHECKMULTISIG + + Bob deposit: + OP_IF + OP_CLTV OP_DROP OP_CHECKSIG + OP_ELSE + OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG + OP_ENDIF + + Bob paytx: + OP_IF + OP_CLTV OP_DROP OP_CHECKSIG + OP_ELSE + OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG + OP_ENDIF + + Naming convention are pubAi are alice's pubkeys (seems only pubA0 and not pubA1) + pubBi are Bob's pubkeys + + privN is Bob's privkey from the cut and choose deck as selected by Alice + privM is Alice's counterpart + pubN and pubM are the corresponding pubkeys for these chosen privkeys + + Alice timeout event is triggered if INSTANTDEX_LOCKTIME elapses from the start of a FSM instance. Bob timeout event is triggered after INSTANTDEX_LOCKTIME*2 + */ + +#define SCRIPT_OP_IF 0x63 +#define SCRIPT_OP_ELSE 0x67 +#define SCRIPT_OP_ENDIF 0x68 + +int32_t basilisk_bobscript(uint8_t *rmd160,uint8_t *redeemscript,int32_t *redeemlenp,uint8_t *script,int32_t n,uint32_t *locktimep,int32_t *secretstartp,struct basilisk_swap *swap,int32_t depositflag) +{ + uint8_t pubkeyA[33],pubkeyB[33],*secret160; bits256 cltvpub,destpub; int32_t i; + *locktimep = swap->locktime; + if ( depositflag != 0 ) + { + *locktimep += INSTANTDEX_LOCKTIME; + cltvpub = swap->pubA0; + destpub = swap->pubB0; + secret160 = swap->secretBn; + pubkeyA[0] = 0x02; + pubkeyB[0] = 0x03; + } + else + { + cltvpub = swap->pubB1; + destpub = swap->pubA0; + secret160 = swap->secretAm; + pubkeyA[0] = 0x03; + pubkeyB[0] = 0x02; + } + if ( bits256_nonz(cltvpub) == 0 || bits256_nonz(destpub) == 0 ) + return(-1); + for (i=0; i<20; i++) + if ( secret160[i] != 0 ) + break; + if ( i == 20 ) + return(-1); + memcpy(pubkeyA+1,cltvpub.bytes,sizeof(cltvpub)); + memcpy(pubkeyB+1,destpub.bytes,sizeof(destpub)); + redeemscript[n++] = SCRIPT_OP_IF; + n = bitcoin_checklocktimeverify(redeemscript,n,*locktimep); + n = bitcoin_pubkeyspend(redeemscript,n,pubkeyA); + redeemscript[n++] = SCRIPT_OP_ELSE; + if ( secretstartp != 0 ) + *secretstartp = n + 2; + n = bitcoin_revealsecret160(redeemscript,n,secret160); + n = bitcoin_pubkeyspend(redeemscript,n,pubkeyB); + redeemscript[n++] = SCRIPT_OP_ENDIF; + *redeemlenp = n; + calc_rmd160_sha256(rmd160,redeemscript,n); + n = bitcoin_p2shspend(script,0,rmd160); + for (i=0; i 0 && numconfirms >= 0 ) + return(numconfirms); + return(-1); +} + +int32_t basilisk_numconfirms(struct supernet_info *myinfo,struct basilisk_rawtx *rawtx) +{ + cJSON *argjson,*valuearray=0; char *valstr; int32_t i,n,retval = -1; +#ifdef BASILISK_DISABLETX + return(10); +#endif + argjson = cJSON_CreateObject(); + jaddbits256(argjson,"txid",rawtx->actualtxid); + jaddnum(argjson,"vout",0); + jaddstr(argjson,"coin",rawtx->coin->symbol); + if ( (valstr= basilisk_value(myinfo,rawtx->coin,0,0,myinfo->myaddr.persistent,argjson,0)) != 0 ) + { + //char str[65]; printf("%s %s valstr.(%s)\n",rawtx->name,bits256_str(str,rawtx->actualtxid),valstr); + if ( (valuearray= cJSON_Parse(valstr)) != 0 ) + { + if ( is_cJSON_Array(valuearray) != 0 ) + { + n = cJSON_GetArraySize(valuearray); + for (i=0; i= 0 ) + break; + } + } else retval = basilisk_confirmsobj(valuearray); + free_json(valuearray); + } else printf("parse error\n"); + free(valstr); + } + free_json(argjson); + return(retval); +} + +bits256 basilisk_swap_broadcast(char *name,struct supernet_info *myinfo,struct basilisk_swap *swap,struct iguana_info *coin,uint8_t *data,int32_t datalen) +{ + bits256 txid; char *signedtx; + memset(txid.bytes,0,sizeof(txid)); + if ( data != 0 && datalen != 0 ) + { + char str[65]; +#ifdef BASILISK_DISABLETX + txid = bits256_doublesha256(0,data,datalen); + printf("%s <- dont sendrawtransaction (%s)\n",name,bits256_str(str,txid)); + return(txid); +#endif + signedtx = malloc(datalen*2 + 1); + init_hexbytes_noT(signedtx,data,datalen); + txid = iguana_sendrawtransaction(myinfo,coin,signedtx); + printf("%s <- sendrawtransaction %s.(%s)\n",name,signedtx,bits256_str(str,txid)); + free(signedtx); + } + return(txid); +} + +int32_t basilisk_rawtx_sign(struct supernet_info *myinfo,int32_t height,struct basilisk_swap *swap,struct basilisk_rawtx *dest,struct basilisk_rawtx *rawtx,bits256 privkey,bits256 *privkey2,uint8_t *userdata,int32_t userdatalen) +{ + char *rawtxbytes,*signedtx,hexstr[999],wifstr[128]; cJSON *txobj,*vins,*item,*sobj,*privkeys; int32_t retval = -1; struct vin_info V; uint32_t locktime=0; + memset(&V,0,sizeof(V)); + if ( dest == &swap->aliceclaim ) + locktime = swap->locktime + INSTANTDEX_LOCKTIME; + V.signers[0].privkey = privkey; + bitcoin_pubkey33(myinfo->ctx,V.signers[0].pubkey,privkey); + privkeys = cJSON_CreateArray(); + bitcoin_priv2wif(wifstr,privkey,rawtx->coin->chain->wiftype); + jaddistr(privkeys,wifstr); + if ( privkey2 != 0 ) + { + V.signers[1].privkey = *privkey2; + bitcoin_pubkey33(myinfo->ctx,V.signers[1].pubkey,*privkey2); + bitcoin_priv2wif(wifstr,*privkey2,rawtx->coin->chain->wiftype); + jaddistr(privkeys,wifstr); + V.N = V.M = 2; + char str[65]; printf("add second privkey.(%s) %s\n",jprint(privkeys,0),bits256_str(str,*privkey2)); + } else V.N = V.M = 1; + V.suppress_pubkeys = dest->suppress_pubkeys; + if ( dest->redeemlen != 0 ) + memcpy(V.p2shscript,dest->redeemscript,dest->redeemlen), V.p2shlen = dest->redeemlen; + txobj = bitcoin_txcreate(rawtx->coin->chain->isPoS,locktime,rawtx->coin->chain->locktime_txversion); + vins = cJSON_CreateArray(); + item = cJSON_CreateObject(); + if ( userdata != 0 && userdatalen > 0 ) + { + memcpy(V.userdata,userdata,userdatalen); + V.userdatalen = userdatalen; + init_hexbytes_noT(hexstr,userdata,userdatalen); + jaddstr(item,"userdata",hexstr); + } + if ( bits256_nonz(rawtx->actualtxid) != 0 ) + jaddbits256(item,"txid",rawtx->actualtxid); + else jaddbits256(item,"txid",rawtx->signedtxid); + jaddnum(item,"vout",0); + sobj = cJSON_CreateObject(); + init_hexbytes_noT(hexstr,rawtx->spendscript,rawtx->spendlen); + jaddstr(sobj,"hex",hexstr); + jadd(item,"scriptPubKey",sobj); + jaddnum(item,"suppress",dest->suppress_pubkeys); + if ( locktime != 0 ) + jaddnum(item,"sequence",0); + if ( (dest->redeemlen= rawtx->redeemlen) != 0 ) + { + init_hexbytes_noT(hexstr,rawtx->redeemscript,rawtx->redeemlen); + memcpy(dest->redeemscript,rawtx->redeemscript,rawtx->redeemlen); + jaddstr(item,"redeemScript",hexstr); + } + jaddi(vins,item); + jdelete(txobj,"vin"); + jadd(txobj,"vin",vins); + printf("basilisk_rawtx_sign locktime.%u/%u for %s spendscript.%s -> %s, suppress.%d\n",rawtx->locktime,dest->locktime,rawtx->name,hexstr,dest->name,dest->suppress_pubkeys); + txobj = bitcoin_txoutput(txobj,dest->spendscript,dest->spendlen,dest->amount); + if ( (rawtxbytes= bitcoin_json2hex(myinfo,rawtx->coin,&dest->txid,txobj,&V)) != 0 ) + { + printf("(%s) spend.%s rawtx.(%s) userdatalen.%d p2shlen.%d\n",jprint(txobj,0),rawtx->name,rawtxbytes,userdatalen,dest->redeemlen); + if ( (signedtx= iguana_signrawtx(myinfo,rawtx->coin,height,&dest->signedtxid,&dest->completed,vins,rawtxbytes,privkeys,&V)) != 0 ) + { + printf("rawtx spend signedtx.(%s)\n",signedtx); + dest->datalen = (int32_t)strlen(signedtx) >> 1; + dest->txbytes = calloc(1,dest->datalen); + decode_hex(dest->txbytes,dest->datalen,signedtx); + free(signedtx); + retval = 0; + } else printf("error signing\n"); + free(rawtxbytes); + } else printf("error making rawtx\n"); + free_json(privkeys); + free_json(txobj); + return(retval); +} + +struct basilisk_rawtx *basilisk_swapdata_rawtx(struct supernet_info *myinfo,struct basilisk_swap *swap,uint8_t *data,int32_t maxlen,struct basilisk_rawtx *rawtx) +{ + if ( rawtx->txbytes != 0 && rawtx->datalen <= maxlen ) + { + memcpy(data,rawtx->txbytes,rawtx->datalen); + return(rawtx); + } + return(0); +} + +int32_t basilisk_verify_otherfee(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen) +{ + struct basilisk_swap *swap = ptr; + // add verification + swap->otherfee.txbytes = calloc(1,datalen); + memcpy(swap->otherfee.txbytes,data,datalen); + swap->otherfee.actualtxid = swap->otherfee.signedtxid = bits256_doublesha256(0,data,datalen); + return(0); +} + +int32_t basilisk_rawtx_spendscript(struct supernet_info *myinfo,int32_t height,struct basilisk_rawtx *rawtx,int32_t v,uint8_t *data,int32_t datalen,int32_t suppress_pubkeys) +{ + int32_t retval=-1,hexlen,n; cJSON *txobj,*skey,*vouts,*vout; char *hexstr; + if ( rawtx->txbytes == 0 ) + { + rawtx->txbytes = calloc(1,datalen); + memcpy(rawtx->txbytes,data,datalen); + rawtx->datalen = datalen; + } + else if ( datalen != rawtx->datalen || memcmp(rawtx->txbytes,data,datalen) != 0 ) + { + printf("%s rawtx data compare error, len %d vs %d\n",rawtx->name,rawtx->datalen,datalen); + return(-1); + } + if ( (txobj= bitcoin_data2json(rawtx->coin,height,&rawtx->signedtxid,&rawtx->msgtx,rawtx->extraspace,sizeof(rawtx->extraspace),rawtx->txbytes,rawtx->datalen,0,suppress_pubkeys)) != 0 ) + { + rawtx->actualtxid = rawtx->signedtxid; + char str[65]; printf("got txid.%s\n",bits256_str(str,rawtx->signedtxid)); + rawtx->locktime = rawtx->msgtx.lock_time; + if ( (vouts= jarray(&n,txobj,"vout")) != 0 && v < n ) + { + vout = jitem(vouts,v); + if ( j64bits(vout,"satoshis") == rawtx->amount && (skey= jobj(vout,"scriptPubKey")) != 0 && (hexstr= jstr(skey,"hex")) != 0 ) + { + if ( (hexlen= (int32_t)strlen(hexstr) >> 1) < sizeof(rawtx->spendscript) ) + { + decode_hex(rawtx->spendscript,hexlen,hexstr); + rawtx->spendlen = hexlen; + retval = 0; + } + } else printf("%s ERROR.(%s)\n",rawtx->name,jprint(txobj,0)); + } + free_json(txobj); + } + return(retval); +} + +int32_t basilisk_swapuserdata(uint8_t *userdata,int32_t pushpriv,bits256 privkey,uint8_t addrtype,bits256 pubkey,int32_t ifpath) +{ + int32_t i,len = 0; + if ( 0 ) + { + userdata[len++] = 33; + userdata[len++] = addrtype; + for (i=0; i if path, 0 -> else path + return(len); +} + +/* Bob deposit: + OP_IF + OP_CLTV OP_DROP OP_CHECKSIG + OP_ELSE + OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG + OP_ENDIF*/ + +int32_t basilisk_verify_bobdeposit(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen) +{ + uint8_t userdata[512]; int32_t len = 0; struct basilisk_swap *swap = ptr; + if ( basilisk_rawtx_spendscript(myinfo,swap->bobcoin->blocks.hwmchain.height,&swap->bobdeposit,0,data,datalen,0) == 0 ) + { + //len = basilisk_swapuserdata(userdata,0,GENESIS_PRIVKEY,0x02,swap->pubA0,1); + userdata[len++] = 0x51; + return(basilisk_rawtx_sign(myinfo,swap->bobcoin->blocks.hwmchain.height,swap,&swap->aliceclaim,&swap->bobdeposit,swap->myprivs[0],0,userdata,len)); + } + printf("error with bobdeposit\n"); + return(-1); +} + +int32_t basilisk_bobdeposit_refund(struct supernet_info *myinfo,struct basilisk_swap *swap) +{ + uint8_t userdata[512]; int32_t len = 0; + printf("basilisk_bobdeposit_refund\n"); + len = basilisk_swapuserdata(userdata,1,swap->privBn,0x03,swap->pubB0,0); + return(basilisk_rawtx_sign(myinfo,swap->bobcoin->blocks.hwmchain.height,swap,&swap->bobrefund,&swap->bobdeposit,swap->myprivs[0],0,userdata,len)); +} + +/*Bob paytx: + OP_IF + OP_CLTV OP_DROP OP_CHECKSIG + OP_ELSE + OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG + OP_ENDIF*/ + +int32_t basilisk_bobpayment_reclaim(struct supernet_info *myinfo,struct basilisk_swap *swap) +{ + uint8_t userdata[512]; int32_t len = 0; + printf("basilisk_bobpayment_reclaim\n"); + userdata[len++] = 0x51; + //len = basilisk_swapuserdata(userdata,0,GENESIS_PRIVKEY,0x03,swap->pubB1,1); + return(basilisk_rawtx_sign(myinfo,swap->bobcoin->blocks.hwmchain.height,swap,&swap->bobreclaim,&swap->bobpayment,swap->myprivs[1],0,userdata,len)); +} + +int32_t basilisk_verify_bobpaid(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen) +{ + uint8_t userdata[512]; int32_t len = 0; struct basilisk_swap *swap = ptr; + if ( basilisk_rawtx_spendscript(myinfo,swap->bobcoin->blocks.hwmchain.height,&swap->bobpayment,0,data,datalen,0) == 0 ) + { + len = basilisk_swapuserdata(userdata,1,swap->privAm,0x02,swap->pubA0,0); + char str[65]; printf("bobpaid.(%s)\n",bits256_str(str,swap->privAm)); + return(basilisk_rawtx_sign(myinfo,swap->bobcoin->blocks.hwmchain.height,swap,&swap->alicespend,&swap->bobpayment,swap->myprivs[0],0,userdata,len)); + } else return(-1); +} + +int32_t basilisk_alicepayment_spend(struct supernet_info *myinfo,struct basilisk_swap *swap,struct basilisk_rawtx *dest) +{ + printf("alicepayment_spend\n"); + return(basilisk_rawtx_sign(myinfo,swap->alicecoin->blocks.hwmchain.height,swap,dest,&swap->alicepayment,swap->privAm,&swap->privBn,0,0)); +} + +int32_t basilisk_verify_alicepaid(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen) +{ + struct basilisk_swap *swap = ptr; + if ( basilisk_rawtx_spendscript(myinfo,swap->alicecoin->blocks.hwmchain.height,&swap->alicepayment,0,data,datalen,0) == 0 ) + return(0); + else return(-1); +} + +int32_t basilisk_privAm_extract(struct supernet_info *myinfo,struct basilisk_swap *swap) +{ + // need to scan blockchain for alicespend of bobpayment + // search for swap->bobpayment.actualtxid in spends + if ( bits256_nonz(swap->privAm) != 0 && swap->bobspend.txbytes == 0 ) + { + char str[65]; printf("have privAm.%s\n",bits256_str(str,swap->privAm)); + return(basilisk_alicepayment_spend(myinfo,swap,&swap->bobspend)); + } + return(-1); +} + +int32_t basilisk_verify_pubpair(int32_t *wrongfirstbytep,struct basilisk_swap *swap,int32_t ind,uint8_t pub0,bits256 pubi,uint64_t txid) +{ + if ( pub0 != (swap->iambob ^ 1) + 0x02 ) + { + (*wrongfirstbytep)++; + printf("wrongfirstbyte[%d] %02x\n",ind,pub0); + return(-1); + } + else if ( swap->otherdeck[ind][1] != pubi.txid ) + { + printf("otherdeck[%d] priv ->pub mismatch %llx != %llx\n",ind,(long long)swap->otherdeck[ind][1],(long long)pubi.txid); + return(-1); + } + else if ( swap->otherdeck[ind][0] != txid ) + { + printf("otherdeck[%d] priv mismatch %llx != %llx\n",ind,(long long)swap->otherdeck[ind][0],(long long)txid); + return(-1); + } + return(0); +} + +int32_t basilisk_verify_privi(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen) +{ + int32_t j,wrongfirstbyte,len = 0; bits256 privkey,pubi; uint8_t secret160[20],pubkey33[33]; uint64_t txid; struct basilisk_swap *swap = ptr; + if ( datalen == sizeof(bits256) ) + { + for (j=0; j<32; j++) + privkey.bytes[j] = data[len++]; + calc_rmd160_sha256(secret160,privkey.bytes,sizeof(privkey)); + memcpy(&txid,secret160,sizeof(txid)); + pubi = bitcoin_pubkey33(myinfo->ctx,pubkey33,privkey); + if ( basilisk_verify_pubpair(&wrongfirstbyte,swap,swap->choosei,pubkey33[0],pubi,txid) == 0 ) + { + if ( swap->iambob != 0 ) + swap->privAm = privkey; + else swap->privBn = privkey; + char str[65]; printf("privi verified.(%s)\n",bits256_str(str,privkey)); + return(0); + } + } + return(-1); +} + +int32_t basilisk_process_swapget(struct supernet_info *myinfo,void *ptr,int32_t (*internal_func)(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen),uint32_t channel,uint32_t msgid,uint8_t *data,int32_t datalen,uint32_t expiration,uint32_t duration) +{ + struct basilisk_swap *swap = ptr; + return((*internal_func)(myinfo,swap,data,datalen)); +} + +int32_t basilisk_swapget(struct supernet_info *myinfo,struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t maxlen,int32_t (*basilisk_verify_func)(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen)) +{ + int32_t retval; cJSON *retarray; + if ( (retarray= basilisk_channelget(myinfo,myinfo->myaddr.persistent,swap->req.quoteid,msgbits,0)) != 0 ) + { + retval = basilisk_process_retarray(myinfo,swap,basilisk_process_swapget,data,maxlen,swap->req.quoteid,msgbits,retarray,basilisk_verify_func); + if ( retval > 0 ) + return(0); + //return((*basilisk_verify_func)(myinfo,swap,data,datalen)); + } + return(-1); +} + +int32_t basilisk_privBn_extract(struct supernet_info *myinfo,struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) +{ + // need to scan blockchain for bobrefund + // search for swap->bobrefund.actualtxid in spends + if ( basilisk_swapget(myinfo,swap,0x40000000,data,maxlen,basilisk_verify_privi) == 0 ) + { + if ( bits256_nonz(swap->privBn) != 0 && swap->alicereclaim.txbytes == 0 ) + { + char str[65]; printf("have privBn.%s\n",bits256_str(str,swap->privBn)); + return(basilisk_alicepayment_spend(myinfo,swap,&swap->alicereclaim)); + } + } + return(-1); +} +// end of coin protocol dependent + +bits256 instantdex_derivekeypair(struct supernet_info *myinfo,bits256 *newprivp,uint8_t pubkey[33],bits256 privkey,bits256 orderhash) +{ + bits256 sharedsecret; + sharedsecret = curve25519_shared(privkey,orderhash); + vcalc_sha256cat(newprivp->bytes,orderhash.bytes,sizeof(orderhash),sharedsecret.bytes,sizeof(sharedsecret)); + return(bitcoin_pubkey33(myinfo->ctx,pubkey,*newprivp)); +} + +int32_t instantdex_pubkeyargs(struct supernet_info *myinfo,struct basilisk_swap *swap,int32_t numpubs,bits256 privkey,bits256 hash,int32_t firstbyte) +{ + char buf[3]; int32_t i,n,m,len=0; bits256 pubi; uint64_t txid; uint8_t secret160[20],pubkey[33]; + sprintf(buf,"%c0",'A' - 0x02 + firstbyte); + if ( numpubs > 2 ) + { + if ( swap->numpubs+2 >= numpubs ) + return(numpubs); + printf(">>>>>> start generating %s\n",buf); + } + for (i=n=m=0; imypubs[n]) == 0 ) + { + swap->myprivs[n] = privkey; + memcpy(swap->mypubs[n].bytes,pubkey+1,sizeof(bits256)); + if ( swap->iambob != 0 ) + { + if ( n == 0 ) + swap->pubB0 = swap->mypubs[n]; + else if ( n == 1 ) + swap->pubB1 = swap->mypubs[n]; + } + else if ( swap->iambob == 0 ) + { + if ( n == 0 ) + swap->pubA0 = swap->mypubs[n]; + else if ( n == 1 ) + swap->pubA1 = swap->mypubs[n]; + } + } + } + if ( m < INSTANTDEX_DECKSIZE ) + { + swap->privkeys[m] = privkey; + calc_rmd160_sha256(secret160,privkey.bytes,sizeof(privkey)); + memcpy(&txid,secret160,sizeof(txid)); + len += iguana_rwnum(1,(uint8_t *)&swap->deck[m][0],sizeof(txid),&txid); + len += iguana_rwnum(1,(uint8_t *)&swap->deck[m][1],sizeof(pubi.txid),&pubi.txid); + m++; + if ( m > swap->numpubs ) + swap->numpubs = m; + } + n++; + } + if ( n > 2 || m > 2 ) + printf("n.%d m.%d len.%d numpubs.%d\n",n,m,len,swap->numpubs); + return(n); +} + +int32_t basilisk_rawtx_return(struct supernet_info *myinfo,int32_t height,struct basilisk_rawtx *rawtx,cJSON *item,cJSON *privkeyarray,int32_t lockinputs) +{ + char *signedtx,*txbytes; cJSON *vins; int32_t i,n,retval = -1; + if ( (txbytes= jstr(item,"rawtx")) != 0 && (vins= jobj(item,"vins")) != 0 ) + { + if ( (signedtx= iguana_signrawtx(myinfo,rawtx->coin,height,&rawtx->signedtxid,&rawtx->completed,vins,txbytes,privkeyarray,0)) != 0 ) + { + if ( lockinputs != 0 ) + { + iguana_RTunspentslock(myinfo,rawtx->coin,vins); + if ( (n= cJSON_GetArraySize(vins)) != 0 ) + { + bits256 txid; int32_t vout; + for (i=0; icoin->symbol,txid,vout,1); + } + } + } + } + rawtx->datalen = (int32_t)strlen(signedtx) >> 1; + rawtx->txbytes = calloc(1,rawtx->datalen); + decode_hex(rawtx->txbytes,rawtx->datalen,signedtx); + //printf("SIGNEDTX.(%s)\n",signedtx); + free(signedtx); + retval = 0; + } else printf("error signrawtx\n"); //do a very short timeout so it finishes via local poll + } + return(retval); +} + +int32_t basilisk_rawtx_gen(char *str,struct supernet_info *myinfo,int32_t iambob,int32_t lockinputs,struct basilisk_rawtx *rawtx,uint32_t locktime,uint8_t *script,int32_t scriptlen,int64_t txfee,int32_t minconf) +{ + struct iguana_waddress *waddr; struct iguana_waccount *wacct; char coinaddr[64],wifstr[64],*retstr,scriptstr[1024]; uint32_t basilisktag; int32_t flag,i,n,retval = -1; cJSON *valsobj,*retarray=0,*privkeyarray,*addresses; + //if ( (waddr= iguana_getaccountaddress(myinfo,rawtx->coin,0,0,rawtx->coin->changeaddr,"change")) == 0 ) + if ( rawtx->coin->changeaddr[0] == 0 ) + { + bitcoin_address(rawtx->coin->changeaddr,rawtx->coin->chain->pubtype,myinfo->persistent_pubkey33,33); + printf("set change address.(%s)\n",rawtx->coin->changeaddr); + } + init_hexbytes_noT(scriptstr,script,scriptlen); + privkeyarray = cJSON_CreateArray(); + addresses = cJSON_CreateArray(); + bitcoin_address(coinaddr,rawtx->coin->chain->pubtype,myinfo->persistent_pubkey33,33); + //printf("%s persistent.(%s) (%s) change.(%s) scriptstr.(%s)\n",coin->symbol,myinfo->myaddr.BTC,coinaddr,coin->changeaddr,scriptstr); + if ( (waddr= iguana_waddresssearch(myinfo,&wacct,coinaddr)) != 0 ) + { + bitcoin_priv2wif(wifstr,waddr->privkey,rawtx->coin->chain->wiftype); + jaddistr(privkeyarray,waddr->wifstr); + } + basilisktag = (uint32_t)rand(); + jaddistr(addresses,coinaddr); + valsobj = cJSON_CreateObject(); + //jadd(valsobj,"addresses",addresses); + jaddstr(valsobj,"coin",rawtx->coin->symbol); + jaddstr(valsobj,"spendscript",scriptstr); + jaddstr(valsobj,"changeaddr",rawtx->coin->changeaddr); + jadd64bits(valsobj,"satoshis",rawtx->amount); + jadd64bits(valsobj,"txfee",txfee); + jaddnum(valsobj,"minconf",minconf); + jaddnum(valsobj,"locktime",locktime); + jaddnum(valsobj,"timeout",30000); + rawtx->locktime = locktime; + printf("%s locktime.%u\n",rawtx->name,locktime); + if ( (retstr= basilisk_bitcoinrawtx(myinfo,rawtx->coin,"",basilisktag,jint(valsobj,"timeout"),valsobj)) != 0 ) + { + printf("%s got.(%s)\n",str,retstr); + flag = 0; + if ( (retarray= cJSON_Parse(retstr)) != 0 ) + { + if ( is_cJSON_Array(retarray) != 0 ) + { + n = cJSON_GetArraySize(retarray); + for (i=0; icoin->blocks.hwmchain.height,rawtx,jitem(retarray,i),privkeyarray,lockinputs)) == 0 ) + break; + } + } else retval = basilisk_rawtx_return(myinfo,rawtx->coin->blocks.hwmchain.height,rawtx,retarray,privkeyarray,lockinputs); + free(retarray); + } else printf("error parsing.(%s)\n",retstr); + free(retstr); + } else printf("error creating %s feetx\n",iambob != 0 ? "BOB" : "ALICE"); + free_json(privkeyarray); + free_json(valsobj); + printf("rawtx retval.%d\n",retval); + return(retval); +} + +void basilisk_rawtx_setparms(char *name,struct supernet_info *myinfo,struct basilisk_swap *swap,struct basilisk_rawtx *rawtx,struct iguana_info *coin,int32_t numconfirms,int32_t vintype,uint64_t satoshis,int32_t vouttype,uint8_t *pubkey33) +{ + strcpy(rawtx->name,name); + rawtx->coin = coin; + rawtx->numconfirms = numconfirms; + if ( (rawtx->amount= satoshis) < 10000 ) + rawtx->amount = 10000; + rawtx->vintype = vintype; // 0 -> std, 2 -> 2of2, 3 -> spend bobpayment, 4 -> spend bobdeposit + rawtx->vouttype = vouttype; // 0 -> fee, 1 -> std, 2 -> 2of2, 3 -> bobpayment, 4 -> bobdeposit + if ( rawtx->vouttype == 0 ) + { + if ( strcmp(coin->symbol,"BTC") == 0 && (swap->req.quoteid % 10) == 0 ) + decode_hex(rawtx->rmd160,20,TIERNOLAN_RMD160); + else decode_hex(rawtx->rmd160,20,INSTANTDEX_RMD160); + bitcoin_address(rawtx->destaddr,rawtx->coin->chain->pubtype,rawtx->rmd160,20); + } + if ( pubkey33 != 0 ) + { + memcpy(rawtx->pubkey33,pubkey33,33); + bitcoin_address(rawtx->destaddr,rawtx->coin->chain->pubtype,rawtx->pubkey33,33); + bitcoin_addr2rmd160(&rawtx->addrtype,rawtx->rmd160,rawtx->destaddr); + } + if ( rawtx->vouttype <= 1 && rawtx->destaddr[0] != 0 ) + { + rawtx->spendlen = bitcoin_standardspend(rawtx->spendscript,0,rawtx->rmd160); + printf("%s spendlen.%d %s <- %.8f\n",name,rawtx->spendlen,rawtx->destaddr,dstr(rawtx->amount)); + } else printf("%s vouttype.%d destaddr.(%s)\n",name,rawtx->vouttype,rawtx->destaddr); +} + +struct basilisk_swap *bitcoin_swapinit(struct supernet_info *myinfo,struct basilisk_swap *swap) +{ + struct iguana_info *coin; uint8_t *alicepub33=0,*bobpub33=0; int32_t x = -1; + if ( strcmp("BTC",swap->req.src) == 0 ) + { + swap->bobcoin = iguana_coinfind("BTC"); + swap->bobsatoshis = swap->req.srcamount; + swap->bobconfirms = (1 + sqrt(dstr(swap->bobsatoshis) * .1)); + swap->alicecoin = iguana_coinfind(swap->req.dest); + swap->alicesatoshis = swap->req.destamount; + swap->aliceconfirms = swap->bobconfirms * 3; + } + else if ( strcmp("BTC",swap->req.dest) == 0 ) + { + swap->bobcoin = iguana_coinfind("BTC"); + swap->bobsatoshis = swap->req.destamount; + swap->bobconfirms = (1 + sqrt(dstr(swap->bobsatoshis) * .1)); + swap->alicecoin = iguana_coinfind(swap->req.src); + swap->alicesatoshis = swap->req.srcamount; + swap->aliceconfirms = swap->bobconfirms * 3; + } + else + { + if ( (coin= iguana_coinfind(swap->req.src)) != 0 ) + { + if ( coin->chain->havecltv != 0 ) + { + swap->bobcoin = coin; + swap->bobsatoshis = swap->req.srcamount; + swap->alicecoin = iguana_coinfind(swap->req.dest); + swap->alicesatoshis = swap->req.destamount; + } + else if ( (coin= iguana_coinfind(swap->req.dest)) != 0 ) + { + if ( coin->chain->havecltv != 0 ) + { + swap->bobcoin = coin; + swap->bobsatoshis = swap->req.destamount; + swap->alicecoin = iguana_coinfind(swap->req.src); + swap->alicesatoshis = swap->req.srcamount; + } + } + } + } + if ( swap->bobcoin == 0 || swap->alicecoin == 0 ) + { + printf("missing BTC.%p or missing alicecoin.%p\n",swap->bobcoin,swap->alicecoin); + free(swap); + return(0); + } + if ( swap->bobconfirms == 0 ) + swap->bobconfirms = swap->bobcoin->chain->minconfirms; + if ( swap->aliceconfirms == 0 ) + swap->aliceconfirms = swap->alicecoin->chain->minconfirms; + if ( (swap->bobinsurance= (swap->bobsatoshis / INSTANTDEX_INSURANCEDIV)) < 10000 ) + swap->bobinsurance = 10000; + if ( (swap->aliceinsurance= (swap->alicesatoshis / INSTANTDEX_INSURANCEDIV)) < 10000 ) + swap->aliceinsurance = 10000; + strcpy(swap->bobstr,swap->bobcoin->symbol); + strcpy(swap->alicestr,swap->alicecoin->symbol); + swap->started = (uint32_t)time(NULL); + swap->expiration = swap->req.timestamp + INSTANTDEX_LOCKTIME*2; + swap->locktime = swap->req.timestamp + INSTANTDEX_LOCKTIME; + OS_randombytes((uint8_t *)&swap->choosei,sizeof(swap->choosei)); + if ( swap->choosei < 0 ) + swap->choosei = -swap->choosei; + swap->choosei %= INSTANTDEX_DECKSIZE; + swap->otherchoosei = -1; + swap->myhash = myinfo->myaddr.persistent; + if ( bits256_cmp(swap->myhash,swap->req.hash) == 0 ) + { + swap->otherhash = swap->req.desthash; + if ( strcmp(swap->req.src,swap->bobstr) == 0 ) + swap->iambob = 1; + else if ( strcmp(swap->req.dest,swap->alicestr) == 0 ) + { + printf("neither bob nor alice error\n"); + return(0); + } + } + else if ( bits256_cmp(swap->myhash,swap->req.desthash) == 0 ) + { + swap->otherhash = swap->req.hash; + if ( strcmp(swap->req.dest,swap->bobstr) == 0 ) + swap->iambob = 1; + else if ( strcmp(swap->req.src,swap->alicestr) != 0 ) + { + printf("neither alice nor bob error\n"); + return(0); + } + } + else + { + printf("neither src nor dest error\n"); + return(0); + } + if ( bits256_nonz(myinfo->persistent_priv) == 0 || (x= instantdex_pubkeyargs(myinfo,swap,2 + INSTANTDEX_DECKSIZE,myinfo->persistent_priv,swap->myhash,0x02+swap->iambob)) != 2 + INSTANTDEX_DECKSIZE ) + { + printf("couldnt generate privkeys %d\n",x); + return(0); + } + if ( swap->iambob != 0 ) + { + basilisk_rawtx_setparms("myfee",myinfo,swap,&swap->myfee,swap->bobcoin,0,0,swap->bobsatoshis/INSTANTDEX_DECKSIZE,0,0); + basilisk_rawtx_setparms("otherfee",myinfo,swap,&swap->otherfee,swap->alicecoin,0,0,swap->alicesatoshis/INSTANTDEX_DECKSIZE,0,0); + bobpub33 = myinfo->persistent_pubkey33; + } + else + { + basilisk_rawtx_setparms("otherfee",myinfo,swap,&swap->otherfee,swap->bobcoin,0,0,swap->bobsatoshis/INSTANTDEX_DECKSIZE,0,0); + basilisk_rawtx_setparms("myfee",myinfo,swap,&swap->myfee,swap->alicecoin,0,0,swap->alicesatoshis/INSTANTDEX_DECKSIZE,0,0); + alicepub33 = myinfo->persistent_pubkey33; + } + basilisk_rawtx_setparms("bobdeposit",myinfo,swap,&swap->bobdeposit,swap->bobcoin,swap->bobconfirms,0,swap->bobsatoshis*1.1,4,0); + basilisk_rawtx_setparms("bobrefund",myinfo,swap,&swap->bobrefund,swap->bobcoin,1,4,swap->bobsatoshis*1.1-swap->bobcoin->txfee,1,bobpub33); + swap->bobrefund.suppress_pubkeys = 1; + basilisk_rawtx_setparms("aliceclaim",myinfo,swap,&swap->aliceclaim,swap->bobcoin,1,4,swap->bobsatoshis*1.1-swap->bobcoin->txfee,1,alicepub33); + swap->aliceclaim.suppress_pubkeys = 1; + + basilisk_rawtx_setparms("bobpayment",myinfo,swap,&swap->bobpayment,swap->bobcoin,swap->bobconfirms,0,swap->bobsatoshis,3,0); + basilisk_rawtx_setparms("alicespend",myinfo,swap,&swap->alicespend,swap->bobcoin,swap->bobconfirms,3,swap->bobsatoshis - swap->bobcoin->txfee,1,alicepub33); + swap->alicespend.suppress_pubkeys = 1; + basilisk_rawtx_setparms("bobreclaim",myinfo,swap,&swap->bobreclaim,swap->bobcoin,swap->bobconfirms,3,swap->bobsatoshis - swap->bobcoin->txfee,1,bobpub33); + swap->bobreclaim.suppress_pubkeys = 1; + + basilisk_rawtx_setparms("alicepayment",myinfo,swap,&swap->alicepayment,swap->alicecoin,swap->aliceconfirms,0,swap->alicesatoshis,2,0); + basilisk_rawtx_setparms("bobspend",myinfo,swap,&swap->bobspend,swap->alicecoin,swap->aliceconfirms,2,swap->alicesatoshis-swap->alicecoin->txfee,1,bobpub33); + swap->bobspend.suppress_pubkeys = 1; + basilisk_rawtx_setparms("alicereclaim",myinfo,swap,&swap->alicereclaim,swap->alicecoin,swap->aliceconfirms,2,swap->alicesatoshis-swap->alicecoin->txfee,1,alicepub33); + swap->alicereclaim.suppress_pubkeys = 1; + return(swap); +} +// end of alice/bob code + +void basilisk_rawtx_purge(struct basilisk_rawtx *rawtx) +{ + if ( rawtx->txbytes != 0 ) + free(rawtx->txbytes), rawtx->txbytes = 0; +} + +void basilisk_swap_finished(struct supernet_info *myinfo,struct basilisk_swap *swap) +{ + swap->finished = (uint32_t)time(NULL); + // save to permanent storage + basilisk_rawtx_purge(&swap->bobdeposit); + basilisk_rawtx_purge(&swap->bobpayment); + basilisk_rawtx_purge(&swap->alicepayment); + basilisk_rawtx_purge(&swap->myfee); + basilisk_rawtx_purge(&swap->otherfee); + basilisk_rawtx_purge(&swap->alicereclaim); + basilisk_rawtx_purge(&swap->alicespend); + basilisk_rawtx_purge(&swap->bobreclaim); + basilisk_rawtx_purge(&swap->bobspend); + basilisk_rawtx_purge(&swap->bobrefund); +} + +void basilisk_swap_purge(struct supernet_info *myinfo,struct basilisk_swap *swap) +{ + int32_t i,n; + // while still in orderbook, wait + return; + portable_mutex_lock(&myinfo->DEX_swapmutex); + n = myinfo->numswaps; + for (i=0; iswaps[i] == swap ) + { + myinfo->swaps[i] = myinfo->swaps[--myinfo->numswaps]; + myinfo->swaps[myinfo->numswaps] = 0; + basilisk_swap_finished(myinfo,swap); + break; + } + portable_mutex_unlock(&myinfo->DEX_swapmutex); +} + +int32_t basilisk_verify_otherstatebits(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen) +{ + struct basilisk_swap *swap = ptr; + if ( datalen == sizeof(swap->otherstatebits) ) + return(iguana_rwnum(0,data,sizeof(swap->otherstatebits),&swap->otherstatebits)); + else return(-1); +} + +int32_t basilisk_verify_choosei(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen) +{ + int32_t otherchoosei=-1,i,len = 0; struct basilisk_swap *swap = ptr; + if ( datalen == sizeof(otherchoosei)+sizeof(bits256)*2 ) + { + len += iguana_rwnum(0,data,sizeof(otherchoosei),&otherchoosei); + if ( otherchoosei >= 0 && otherchoosei < INSTANTDEX_DECKSIZE ) + { + printf("otherchoosei.%d\n",otherchoosei); + swap->otherchoosei = otherchoosei; + if ( swap->iambob != 0 ) + { + for (i=0; i<32; i++) + swap->pubA0.bytes[i] = data[len++]; + for (i=0; i<32; i++) + swap->pubA1.bytes[i] = data[len++]; + char str[65]; printf("GOT pubA0/1 %s\n",bits256_str(str,swap->pubA0)); + } + else + { + for (i=0; i<32; i++) + swap->pubB0.bytes[i] = data[len++]; + for (i=0; i<32; i++) + swap->pubB1.bytes[i] = data[len++]; + } + return(0); + } + } + printf("illegal otherchoosei.%d datalen.%d vs %d\n",otherchoosei,datalen,(int32_t)(sizeof(otherchoosei)+sizeof(bits256)*2)); + return(-1); +} + +int32_t basilisk_swapdata_deck(struct supernet_info *myinfo,struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) +{ + int32_t i,datalen = 0; + for (i=0; ideck)/sizeof(swap->deck[0][0]); i++) + datalen += iguana_rwnum(1,&data[datalen],sizeof(swap->deck[i>>1][i&1]),&swap->deck[i>>1][i&1]); + return(datalen); +} + +int32_t basilisk_verify_otherdeck(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen) +{ + int32_t i,len = 0; struct basilisk_swap *swap = ptr; + for (i=0; iotherdeck)/sizeof(swap->otherdeck[0][0]); i++) + len += iguana_rwnum(0,&data[len],sizeof(swap->otherdeck[i>>1][i&1]),&swap->otherdeck[i>>1][i&1]); + return(0); +} + +int32_t basilisk_verify_privkeys(struct supernet_info *myinfo,void *ptr,uint8_t *data,int32_t datalen) +{ + int32_t i,j,wrongfirstbyte=0,errs=0,len = 0; bits256 otherpriv,pubi; uint8_t secret160[20],otherpubkey[33]; uint64_t txid; struct basilisk_swap *swap = ptr; + printf("verify privkeys choosei.%d otherchoosei.%d datalen.%d vs %d\n",swap->choosei,swap->otherchoosei,datalen,(int32_t)sizeof(swap->privkeys)+20+32); + if ( swap->cutverified == 0 && swap->otherchoosei >= 0 && datalen == sizeof(swap->privkeys)+20+32 ) + { + for (i=errs=0; iprivkeys)/sizeof(*swap->privkeys); i++) + { + for (j=0; j<32; j++) + otherpriv.bytes[j] = data[len++]; + if ( i != swap->choosei ) + { + pubi = bitcoin_pubkey33(myinfo->ctx,otherpubkey,otherpriv); + calc_rmd160_sha256(secret160,otherpriv.bytes,sizeof(otherpriv)); + memcpy(&txid,secret160,sizeof(txid)); + errs += basilisk_verify_pubpair(&wrongfirstbyte,swap,i,otherpubkey[0],pubi,txid); + } + } + if ( errs == 0 && wrongfirstbyte == 0 ) + { + swap->cutverified = 1, printf("CUT VERIFIED\n"); + if ( swap->iambob != 0 ) + { + for (i=0; i<32; i++) + swap->pubAm.bytes[i] = data[len++]; + for (i=0; i<20; i++) + swap->secretAm[i] = data[len++]; + } + else + { + for (i=0; i<32; i++) + swap->pubBn.bytes[i] = data[len++]; + for (i=0; i<20; i++) + swap->secretBn[i] = data[len++]; + } + } else printf("failed verification: wrong firstbyte.%d errs.%d\n",wrongfirstbyte,errs); + } + printf("privkeys errs.%d wrongfirstbyte.%d\n",errs,wrongfirstbyte); + return(errs); +} + +uint32_t basilisk_swapsend(struct supernet_info *myinfo,struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t datalen,uint32_t nextbits) +{ + if ( basilisk_channelsend(myinfo,swap->otherhash,swap->req.quoteid,msgbits,data,datalen,INSTANTDEX_LOCKTIME*2) == 0 ) + return(nextbits); + printf("ERROR basilisk_channelsend\n"); + return(0); +} + +uint32_t basilisk_swapdata_rawtxsend(struct supernet_info *myinfo,struct basilisk_swap *swap,uint32_t msgbits,uint8_t *data,int32_t maxlen,struct basilisk_rawtx *rawtx,uint32_t nextbits) +{ + if ( basilisk_swapdata_rawtx(myinfo,swap,data,maxlen,rawtx) != 0 ) + { + rawtx->actualtxid = basilisk_swap_broadcast(rawtx->name,myinfo,swap,rawtx->coin,rawtx->txbytes,rawtx->datalen); + char str[65],str2[65]; printf("rawtxsend %s vs %s\n",bits256_str(str,rawtx->signedtxid),bits256_str(str2,rawtx->actualtxid)); + if ( bits256_nonz(rawtx->actualtxid) != 0 && msgbits != 0 ) + return(basilisk_swapsend(myinfo,swap,msgbits,rawtx->txbytes,rawtx->datalen,nextbits)); + else return(nextbits); + } else printf("error from basilisk_swapdata_rawtx %p len.%d\n",rawtx->txbytes,rawtx->datalen); + return(0); +} + +void basilisk_sendpubkeys(struct supernet_info *myinfo,struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) +{ + int32_t datalen; + datalen = basilisk_swapdata_deck(myinfo,swap,data,maxlen); + printf("send deck.%d\n",datalen); + swap->statebits |= basilisk_swapsend(myinfo,swap,0x02,data,datalen,0x01); +} + +void basilisk_checkdeck(struct supernet_info *myinfo,struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) +{ + if ( (swap->statebits & 0x02) == 0 ) + { + printf("check for other deck\n"); + if ( basilisk_swapget(myinfo,swap,0x02,data,maxlen,basilisk_verify_otherdeck) == 0 ) + swap->statebits |= 0x02; + } +} + +void basilisk_sendstate(struct supernet_info *myinfo,struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) +{ + int32_t datalen; + datalen = iguana_rwnum(1,data,sizeof(swap->statebits),&swap->statebits); + basilisk_swapsend(myinfo,swap,0x80000000,data,datalen,0); +} + +void basilisk_sendchoosei(struct supernet_info *myinfo,struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) +{ + int32_t i,datalen; char str[65]; + datalen = iguana_rwnum(1,data,sizeof(swap->choosei),&swap->choosei); + if ( swap->iambob != 0 ) + { + for (i=0; i<32; i++) + data[datalen++] = swap->pubB0.bytes[i]; + for (i=0; i<32; i++) + data[datalen++] = swap->pubB1.bytes[i]; + printf("SEND pubB0/1 %s\n",bits256_str(str,swap->pubB0)); + } + else + { + for (i=0; i<32; i++) + data[datalen++] = swap->pubA0.bytes[i]; + for (i=0; i<32; i++) + data[datalen++] = swap->pubA1.bytes[i]; + printf("SEND pubA0/1 %s\n",bits256_str(str,swap->pubA0)); + } + swap->statebits |= basilisk_swapsend(myinfo,swap,0x08,data,datalen,0x04); +} + +void basilisk_waitchoosei(struct supernet_info *myinfo,struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) +{ + uint8_t pubkey33[33]; char str[65]; + printf("check otherchoosei\n"); + if ( basilisk_swapget(myinfo,swap,0x08,data,maxlen,basilisk_verify_choosei) == 0 ) + { + if ( swap->iambob != 0 ) + { + if ( bits256_nonz(swap->privBn) == 0 ) + { + swap->privBn = swap->privkeys[swap->otherchoosei]; + memset(&swap->privkeys[swap->otherchoosei],0,sizeof(swap->privkeys[swap->otherchoosei])); + calc_rmd160_sha256(swap->secretBn,swap->privBn.bytes,sizeof(swap->privBn)); + swap->pubBn = bitcoin_pubkey33(myinfo->ctx,pubkey33,swap->privBn); + printf("set privBn.%s\n",bits256_str(str,swap->privBn)); + } + } + else + { + if ( bits256_nonz(swap->privAm) == 0 ) + { + swap->privAm = swap->privkeys[swap->otherchoosei]; + memset(&swap->privkeys[swap->otherchoosei],0,sizeof(swap->privkeys[swap->otherchoosei])); + calc_rmd160_sha256(swap->secretAm,swap->privAm.bytes,sizeof(swap->privAm)); + swap->pubAm = bitcoin_pubkey33(myinfo->ctx,pubkey33,swap->privAm); + printf("set privAm.%s\n",bits256_str(str,swap->privAm)); + } + } + swap->statebits |= 0x08; + } +} + +void basilisk_sendmostprivs(struct supernet_info *myinfo,struct basilisk_swap *swap,uint8_t *data,int32_t maxlen) +{ + int32_t i,j,datalen; + datalen = 0; + for (i=0; iprivkeys)/sizeof(*swap->privkeys); i++) + { + for (j=0; j<32; j++) + data[datalen++] = (i == swap->otherchoosei) ? 0 : swap->privkeys[i].bytes[j]; + } + if ( swap->iambob != 0 ) + { + for (i=0; i<32; i++) + data[datalen++] = swap->pubBn.bytes[i]; + for (i=0; i<20; i++) + data[datalen++] = swap->secretBn[i]; + } + else + { + for (i=0; i<32; i++) + data[datalen++] = swap->pubAm.bytes[i]; + for (i=0; i<20; i++) + data[datalen++] = swap->secretAm[i]; + } + printf("send privkeys.%d\n",datalen); + swap->statebits |= basilisk_swapsend(myinfo,swap,0x20,data,datalen,0x10); +} + +void basilisk_alicepayment(struct supernet_info *myinfo,struct iguana_info *coin,struct basilisk_rawtx *alicepayment,bits256 pubAm,bits256 pubBn) +{ + alicepayment->spendlen = basilisk_alicescript(alicepayment->redeemscript,&alicepayment->redeemlen,alicepayment->spendscript,0,alicepayment->destaddr,coin->chain->p2shtype,pubAm,pubBn); + basilisk_rawtx_gen("alicepayment",myinfo,0,1,alicepayment,alicepayment->locktime,alicepayment->spendscript,alicepayment->spendlen,coin->chain->txfee,1); +} + +// detect insufficient funds/inputs +// mode to autocreate required outputs + +void basilisk_swaploop(void *_swap) +{ + uint8_t *data; uint32_t expiration; int32_t retval=0,i,j,maxlen,datalen; struct supernet_info *myinfo; struct basilisk_swap *swap = _swap; + myinfo = swap->myinfo; + fprintf(stderr,"start swap\n"); + maxlen = 1024*1024 + sizeof(*swap); + data = malloc(maxlen); + expiration = (uint32_t)time(NULL) + 300; + while ( time(NULL) < expiration ) + { + printf("A r%u/q%u swapstate.%x\n",swap->req.requestid,swap->req.quoteid,swap->statebits); + basilisk_sendpubkeys(myinfo,swap,data,maxlen); // send pubkeys + basilisk_checkdeck(myinfo,swap,data,maxlen); // check for other deck 0x02 + //if ( (swap->statebits & 0x02) != 0 ) + basilisk_sendchoosei(myinfo,swap,data,maxlen); + basilisk_waitchoosei(myinfo,swap,data,maxlen); // wait for choosei 0x08 + if ( (swap->statebits & (0x08|0x02)) == (0x08|0x02) ) + break; + sleep(3); + } + while ( time(NULL) < expiration ) + { + printf("B r%u/q%u swapstate.%x\n",swap->req.requestid,swap->req.quoteid,swap->statebits); + basilisk_sendmostprivs(myinfo,swap,data,maxlen); + if ( basilisk_swapget(myinfo,swap,0x20,data,maxlen,basilisk_verify_privkeys) == 0 ) + { + swap->statebits |= 0x20; + break; + } + sleep(3 + (swap->iambob == 0)*10); + } + if ( time(NULL) >= expiration ) + retval = -1; + printf("C r%u/q%u swapstate.%x\n",swap->req.requestid,swap->req.quoteid,swap->statebits); + if ( retval == 0 && (swap->statebits & 0x40) == 0 ) // send fee + { + basilisk_sendstate(myinfo,swap,data,maxlen); + basilisk_swapget(myinfo,swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits); + if ( swap->myfee.txbytes == 0 ) + { + for (i=0; i<20; i++) + printf("%02x",swap->secretAm[i]); + printf(" <- secretAm\n"); + for (i=0; i<32; i++) + printf("%02x",swap->pubAm.bytes[i]); + printf(" <- pubAm\n"); + for (i=0; i<20; i++) + printf("%02x",swap->secretBn[i]); + printf(" <- secretBn\n"); + for (i=0; i<32; i++) + printf("%02x",swap->pubBn.bytes[i]); + printf(" <- pubBn\n"); + for (i=0; i<32; i++) + printf("%02x",swap->pubA0.bytes[i]); + printf(" <- pubA0\n"); + for (i=0; i<32; i++) + printf("%02x",swap->pubA1.bytes[i]); + printf(" <- pubA1\n"); + for (i=0; i<32; i++) + printf("%02x",swap->pubB0.bytes[i]); + printf(" <- pubB0\n"); + for (i=0; i<32; i++) + printf("%02x",swap->pubB1.bytes[i]); + printf(" <- pubB1\n"); + swap->bobpayment.spendlen = basilisk_bobscript(swap->bobpayment.rmd160,swap->bobpayment.redeemscript,&swap->bobpayment.redeemlen,swap->bobpayment.spendscript,0,&swap->bobpayment.locktime,&swap->bobpayment.secretstart,swap,0); + swap->bobdeposit.spendlen = basilisk_bobscript(swap->bobdeposit.rmd160,swap->bobdeposit.redeemscript,&swap->bobdeposit.redeemlen,swap->bobdeposit.spendscript,0,&swap->bobdeposit.locktime,&swap->bobdeposit.secretstart,swap,1); + for (i=0; ibobpayment.redeemlen; i++) + printf("%02x",swap->bobpayment.redeemscript[i]); + printf(" <- bobpayment.%d\n",i); + for (i=0; ibobdeposit.redeemlen; i++) + printf("%02x",swap->bobdeposit.redeemscript[i]); + printf(" <- bobdeposit.%d\n",i); + if ( swap->iambob != 0 ) + { + basilisk_rawtx_gen("deposit",myinfo,1,1,&swap->bobdeposit,swap->bobdeposit.locktime,swap->bobdeposit.spendscript,swap->bobdeposit.spendlen,swap->bobdeposit.coin->chain->txfee,1); + basilisk_rawtx_gen("payment",myinfo,1,1,&swap->bobpayment,swap->bobpayment.locktime,swap->bobpayment.spendscript,swap->bobpayment.spendlen,swap->bobpayment.coin->chain->txfee,1); + if ( swap->bobdeposit.txbytes == 0 || swap->bobdeposit.spendlen == 0 || swap->bobpayment.txbytes == 0 || swap->bobpayment.spendlen == 0 ) + { + printf("error bob generating deposit.%d or payment.%d\n",swap->bobdeposit.spendlen,swap->bobpayment.spendlen); + retval = -2; + } + /*if ( basilisk_bobpayment_reclaim(myinfo,swap) < 0 || basilisk_bobdeposit_refund(myinfo,swap) < 0 ) + { + printf("error bob reclaiming\n"); + retval = -3; + }*/ + } + else + { + basilisk_alicepayment(myinfo,swap->alicepayment.coin,&swap->alicepayment,swap->pubAm,swap->pubBn); + if ( swap->alicepayment.txbytes == 0 || swap->alicepayment.spendlen == 0 ) + { + printf("error alice generating payment.%d\n",swap->alicepayment.spendlen); + retval = -4; + } + } + if ( basilisk_rawtx_gen("myfee",myinfo,swap->iambob,1,&swap->myfee,0,swap->myfee.spendscript,swap->myfee.spendlen,swap->myfee.coin->chain->txfee,1) == 0 ) + swap->statebits |= basilisk_swapdata_rawtxsend(myinfo,swap,0x80,data,maxlen,&swap->myfee,0x40); + else + { + printf("error creating myfee\n"); + retval = -6; + } + } + } + while ( retval == 0 && time(NULL) < swap->expiration ) + { + printf("D r%u/q%u swapstate.%x otherstate.%x\n",swap->req.requestid,swap->req.quoteid,swap->statebits,swap->otherstatebits); + if ( (swap->statebits & 0x80) == 0 ) // wait for fee + { + if ( basilisk_swapget(myinfo,swap,0x80,data,maxlen,basilisk_verify_otherfee) == 0 ) + { + // verify and submit otherfee + swap->statebits |= 0x80; + basilisk_sendstate(myinfo,swap,data,maxlen); + } + } + basilisk_sendstate(myinfo,swap,data,maxlen); + basilisk_swapget(myinfo,swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits); + if ( (swap->otherstatebits & 0x80) != 0 && (swap->statebits & 0x80) != 0 ) + break; + sleep(3 + (swap->iambob == 0)*10); + basilisk_swapget(myinfo,swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits); + basilisk_sendstate(myinfo,swap,data,maxlen); + if ( (swap->otherstatebits & 0x80) == 0 ) + basilisk_swapdata_rawtxsend(myinfo,swap,0x80,data,maxlen,&swap->myfee,0x40); + } + while ( retval == 0 && time(NULL) < swap->expiration ) // both sides have setup required data and paid txfee + { + printf("E r%u/q%u swapstate.%x otherstate.%x\n",swap->req.requestid,swap->req.quoteid,swap->statebits,swap->otherstatebits); + if ( swap->iambob != 0 ) + { + printf("BOB\n"); + if ( (swap->statebits & 0x100) == 0 ) + { + printf("send bobdeposit\n"); + swap->statebits |= basilisk_swapdata_rawtxsend(myinfo,swap,0x200,data,maxlen,&swap->bobdeposit,0x100); + } + // [BLOCKING: altfound] make sure altpayment is confirmed and send payment + else if ( (swap->statebits & 0x1000) == 0 ) + { + printf("check alicepayment\n"); + if ( basilisk_swapget(myinfo,swap,0x1000,data,maxlen,basilisk_verify_alicepaid) == 0 ) + { + swap->statebits |= 0x1000; + printf("got alicepayment\n"); + } + } + else if ( (swap->statebits & 0x2000) == 0 ) + { + if ( basilisk_numconfirms(myinfo,&swap->alicepayment) >= swap->aliceconfirms ) + { + swap->statebits |= 0x2000; + printf("alicepayment confirmed\n"); + } + } + else if ( (swap->statebits & 0x4000) == 0 ) + { + printf("send bobpayment\n"); + swap->statebits |= basilisk_swapdata_rawtxsend(myinfo,swap,0x8000,data,maxlen,&swap->bobpayment,0x4000); + } + // [BLOCKING: privM] Bob waits for privAm either from Alice or alice blockchain + else if ( (swap->statebits & 0x40000) == 0 ) + { + if ( basilisk_swapget(myinfo,swap,0x40000,data,maxlen,basilisk_verify_privi) == 0 || basilisk_privAm_extract(myinfo,swap) == 0 ) // divulges privAm + { + printf("got privi spend alicepayment\n"); + swap->statebits |= 0x40000; + basilisk_alicepayment_spend(myinfo,swap,&swap->bobspend); + if ( basilisk_swapdata_rawtxsend(myinfo,swap,0,data,maxlen,&swap->bobspend,0x40000) == 0 ) + printf("Bob error spending alice payment\n"); + else + { + basilisk_swap_balancingtrade(myinfo,swap,1); + printf("Bob spends alicepayment\n"); + } + break; + } + else if ( swap->bobpayment.locktime != 0 && time(NULL) > swap->bobpayment.locktime ) + { + // submit reclaim of payment + printf("bob reclaims bobpayment\n"); + swap->statebits |= (0x40000 | 0x80000); + if ( basilisk_swapdata_rawtxsend(myinfo,swap,0,data,maxlen,&swap->bobreclaim,0) == 0 ) + printf("Bob error reclaiming own payment after alice timed out\n"); + else printf("Bob reclaimed own payment\n"); + break; + } + } + else if ( (swap->statebits & 0x80000) == 0 ) + { + if ( basilisk_numconfirms(myinfo,&swap->bobspend) >= swap->aliceconfirms ) + { + printf("bobspend confirmed\n"); + swap->statebits |= 0x80000 | 0x100000; + printf("Bob confirms spend of Alice's payment\n"); + break; + } + } + else if ( (swap->statebits & 0x100000) == 0 ) + { + if ( basilisk_numconfirms(myinfo,&swap->bobreclaim) >= 1 ) + { + printf("bobreclaim confirmed\n"); + swap->statebits |= 0x100000; + printf("Bob confirms reclain of payment\n"); + break; + } + } + } + else + { + printf("ALICE\n"); + // [BLOCKING: depfound] Alice waits for deposit to confirm and sends altpayment + if ( (swap->statebits & 0x200) == 0 ) + { + printf("checkfor deposit\n"); + if ( basilisk_swapget(myinfo,swap,0x200,data,maxlen,basilisk_verify_bobdeposit) == 0 ) + { + // verify deposit and submit, set confirmed height + printf("got bobdeposit\n"); + swap->statebits |= 0x200; + } else printf("no valid deposit\n"); + } + else if ( (swap->statebits & 0x400) == 0 ) + { + if ( basilisk_numconfirms(myinfo,&swap->bobdeposit) >= swap->bobconfirms ) + { + printf("bobdeposit confirmed\n"); + swap->statebits |= 0x400; + } + } + else if ( (swap->statebits & 0x800) == 0 ) + { + printf("send alicepayment\n"); + swap->statebits |= basilisk_swapdata_rawtxsend(myinfo,swap,0x1000,data,maxlen,&swap->alicepayment,0x800); + } + // [BLOCKING: payfound] make sure payment is confrmed and send in spend or see bob's reclaim and claim + else if ( (swap->statebits & 0x8000) == 0 ) + { + if ( basilisk_swapget(myinfo,swap,0x8000,data,maxlen,basilisk_verify_bobpaid) == 0 ) + { + printf("got bobpayment\n"); + // verify payment and submit, set confirmed height + swap->statebits |= 0x8000; + } + } + else if ( (swap->statebits & 0x10000) == 0 ) + { + if ( basilisk_numconfirms(myinfo,&swap->bobpayment) >= swap->bobconfirms ) + { + printf("bobpayment confirmed\n"); + swap->statebits |= 0x10000; + } + } + else if ( (swap->statebits & 0x20000) == 0 ) + { + printf("alicespend bobpayment\n"); + if ( basilisk_swapdata_rawtxsend(myinfo,swap,0,data,maxlen,&swap->alicespend,0x20000) != 0 ) + { + // maybe wait for alicespend to be confirmed + for (j=datalen=0; j<32; j++) + data[datalen++] = swap->privAm.bytes[j]; + printf("send privAm\n"); + swap->statebits |= basilisk_swapsend(myinfo,swap,0x40000,data,datalen,0x20000); + basilisk_swap_balancingtrade(myinfo,swap,0); + } + } + else if ( (swap->statebits & 0x40000) == 0 ) + { + if ( basilisk_numconfirms(myinfo,&swap->alicespend) >= swap->bobconfirms ) + { + swap->statebits |= 0x40000; + printf("Alice confirms spend of Bob's payment\n"); + break; + } + } + if ( swap->bobdeposit.locktime != 0 && time(NULL) > swap->bobdeposit.locktime ) + { + printf("Alice claims deposit\n"); + if ( basilisk_swapdata_rawtxsend(myinfo,swap,0,data,maxlen,&swap->aliceclaim,0) == 0 ) + printf("Alice couldnt claim deposit\n"); + else printf("Alice claimed deposit\n"); + break; + } + else if ( basilisk_privBn_extract(myinfo,swap,data,maxlen) == 0 ) + { + printf("Alice reclaims her payment\n"); + swap->statebits |= 0x40000000; + if ( basilisk_swapdata_rawtxsend(myinfo,swap,0,data,maxlen,&swap->alicereclaim,0x40000000) == 0 ) + printf("Alice error sending alicereclaim\n"); + else printf("Alice reclaimed her payment\n"); + break; + } + } + printf("finished swapstate.%x other.%x\n",swap->statebits,swap->otherstatebits); + sleep(3 + (swap->iambob == 0)*10); + basilisk_sendstate(myinfo,swap,data,maxlen); + basilisk_swapget(myinfo,swap,0x80000000,data,maxlen,basilisk_verify_otherstatebits); + } + printf("end of atomic swap\n"); + if ( swap->iambob != 0 )//&& bits256_nonz(swap->bobdeposit.txid) != 0 ) + { + printf("BOB reclaims refund\n"); + basilisk_bobdeposit_refund(myinfo,swap); + if ( basilisk_swapdata_rawtxsend(myinfo,swap,0,data,maxlen,&swap->bobrefund,0x40000000) == 0 ) // use secretBn + { + printf("Bob submit error getting refund of deposit\n"); + } + // maybe wait for bobrefund to be confirmed + for (j=datalen=0; j<32; j++) + data[datalen++] = swap->privBn.bytes[j]; + basilisk_swapsend(myinfo,swap,0x40000000,data,datalen,0x40000000); + } + printf("%s swap finished statebits %x\n",swap->iambob!=0?"BOB":"ALICE",swap->statebits); + basilisk_swap_purge(myinfo,swap); +} + +struct basilisk_swap *basilisk_thread_start(struct supernet_info *myinfo,struct basilisk_request *rp) +{ + int32_t i; struct basilisk_swap *swap = 0; + portable_mutex_lock(&myinfo->DEX_swapmutex); + for (i=0; inumswaps; i++) + if ( myinfo->swaps[i]->req.requestid == rp->requestid ) + { + printf("basilisk_thread_start error trying to start requestid.%u which is already started\n",rp->requestid); + break; + } + if ( i == myinfo->numswaps && i < sizeof(myinfo->swaps)/sizeof(*myinfo->swaps) ) + { + swap = calloc(1,sizeof(*swap)); + swap->req = *rp; + swap->myinfo = myinfo; + printf("START swap requestid.%u\n",rp->requestid); + if ( bitcoin_swapinit(myinfo,swap) != 0 ) + { + fprintf(stderr,"launch.%d %d\n",myinfo->numswaps,(int32_t)(sizeof(myinfo->swaps)/sizeof(*myinfo->swaps))); + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)basilisk_swaploop,(void *)swap) != 0 ) + { + + } + myinfo->swaps[myinfo->numswaps++] = swap; + } + } + portable_mutex_unlock(&myinfo->DEX_swapmutex); + return(swap); +} diff --git a/basilisk/basilisk_tradebot.c b/basilisk/basilisk_tradebot.c new file mode 100755 index 000000000..f7d5dca16 --- /dev/null +++ b/basilisk/basilisk_tradebot.c @@ -0,0 +1,258 @@ +/****************************************************************************** + * Copyright © 2014-2016 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +// included from basilisk.c + +uint32_t basilisk_requestid(struct basilisk_request *rp) +{ + struct basilisk_request R; + R = *rp; + R.requestid = R.quoteid = R.quotetime = 0; + R.destamount = 0; + R.relaybits = 0; + memset(R.desthash.bytes,0,sizeof(R.desthash.bytes)); + if ( 0 ) + { + int32_t i; + for (i=0; i %s %.8f %s crc.%u\n",R.timestamp,R.requestid,R.quoteid,R.src,dstr(R.srcamount),bits256_str(str,R.hash),R.dest,dstr(R.destamount),bits256_str(str2,R.desthash),calc_crc32(0,(void *)&R,sizeof(R))); + } + return(calc_crc32(0,(void *)&R,sizeof(R))); +} + +uint32_t basilisk_quoteid(struct basilisk_request *rp) +{ + struct basilisk_request R; + R = *rp; + R.requestid = R.quoteid = R.relaybits = 0; + return(calc_crc32(0,(void *)&R,sizeof(R))); +} + +struct basilisk_request *basilisk_parsejson(struct basilisk_request *rp,cJSON *reqjson) +{ + uint32_t requestid,quoteid; + memset(rp,0,sizeof(*rp)); + rp->hash = jbits256(reqjson,"hash"); + rp->desthash = jbits256(reqjson,"desthash"); + rp->srcamount = j64bits(reqjson,"srcamount"); + rp->minamount = j64bits(reqjson,"minamount"); + rp->destamount = j64bits(reqjson,"destamount"); + requestid = juint(reqjson,"requestid"); + quoteid = juint(reqjson,"quoteid"); + if ( jstr(reqjson,"relay") != 0 ) + rp->relaybits = (uint32_t)calc_ipbits(jstr(reqjson,"relay")); + rp->timestamp = juint(reqjson,"timestamp"); + rp->quotetime = juint(reqjson,"quotetime"); + safecopy(rp->src,jstr(reqjson,"src"),sizeof(rp->src)); + safecopy(rp->dest,jstr(reqjson,"dest"),sizeof(rp->dest)); + if ( quoteid != 0 ) + { + rp->quoteid = basilisk_quoteid(rp); + if ( quoteid != rp->quoteid ) + printf("basilisk_parsejson quoteid.%u != %u error\n",quoteid,rp->quoteid); + } + rp->requestid = basilisk_requestid(rp); + if ( requestid != rp->requestid ) + printf("basilisk_parsejson requestid.%u != %u error\n",requestid,rp->requestid); + return(rp); +} + +void basilisk_swap_balancingtrade(struct supernet_info *myinfo,struct basilisk_swap *swap,int32_t iambob) +{ + // update balance, compare to target balance, issue balancing trade via central exchanges, if needed + if ( iambob != 0 ) + { + + } + else + { + + } +} + + +struct basilisk_swap *basilisk_request_started(struct supernet_info *myinfo,uint32_t requestid) +{ + int32_t i; struct basilisk_swap *active = 0; + portable_mutex_lock(&myinfo->DEX_swapmutex); + for (i=0; inumswaps; i++) + if ( myinfo->swaps[i]->req.requestid == requestid ) + { + //printf("REQUEST STARTED.[%d] <- req.%u\n",i,requestid); + active = myinfo->swaps[i]; + break; + } + portable_mutex_unlock(&myinfo->DEX_swapmutex); + return(active); +} + +int32_t basilisk_request_cmpref(struct basilisk_request *ref,struct basilisk_request *rp) +{ + if ( bits256_cmp(rp->hash,ref->hash) != 0 || memcmp(rp->src,ref->src,sizeof(ref->src)) != 0 || memcmp(rp->dest,ref->dest,sizeof(ref->dest)) != 0 || rp->srcamount != ref->srcamount || rp->timestamp != ref->timestamp ) + { + printf("basilisk_request_listprocess mismatched hash\n"); + return(-1); + } else return(0); +} + +void tradebot_liquidity_command(struct supernet_info *myinfo,char *base,bits256 hash,cJSON *vals) +{ + struct liquidity_info li,refli; int32_t i; + memset(&li,0,sizeof(li)); + strcpy(li.base,base), strcpy(li.rel,"BTC"); + li.profit = jdouble(vals,"profit"); + li.refprice = jdouble(vals,"refprice"); + for (i=0; ilinfos)/sizeof(*myinfo->linfos); i++) + { + refli = myinfo->linfos[i]; + if ( strcmp(li.rel,refli.base) == 0 && strcmp(li.base,refli.rel) == 0 ) + { + strcpy(li.base,refli.base); + strcpy(li.rel,refli.rel); + li.refprice = (1. / li.refprice); + printf("Set rev linfo[%d] (%s/%s) %.6f %.8f\n",i,li.base,li.rel,li.profit,li.refprice); + myinfo->linfos[i] = li; + return; + } + else if ( refli.base[0] == 0 || (strcmp(li.base,refli.base) == 0 && strcmp(li.rel,refli.rel) == 0) ) + { + myinfo->linfos[i] = li; + printf("Set linfo[%d] (%s/%s) %.6f %.8f\n",i,li.base,li.rel,li.profit,li.refprice); + return; + } + } + printf("ERROR: too many linfos %d\n",i); +} + +double tradebot_liquidity_active(struct supernet_info *myinfo,double *refpricep,char *base,char *rel) +{ + int32_t i; struct liquidity_info refli; + *refpricep = 0.; + for (i=0; ilinfos)/sizeof(*myinfo->linfos); i++) + { + refli = myinfo->linfos[i]; + if ( (strcmp(base,refli.base) == 0 && strcmp(rel,refli.rel) == 0) || (strcmp(rel,refli.base) == 0 && strcmp(base,refli.rel) == 0 )) + { + *refpricep = refli.refprice; + return(refli.profit); + } + } + return(0.); +} + +double basilisk_request_listprocess(struct supernet_info *myinfo,struct basilisk_request *issueR,struct basilisk_request *list,int32_t n) +{ + int32_t i,noquoteflag=0,havequoteflag=0,myrequest=0,maxi=-1; uint64_t destamount,minamount = 0,maxamount = 0; uint32_t pendingid=0; struct basilisk_swap *active; double metric = 0.; + memset(issueR,0,sizeof(*issueR)); + minamount = list[0].minamount; + printf("need to verify null quoteid is list[0] requestid.%u quoteid.%u\n",list[0].requestid,list[0].quoteid); + if ( (active= basilisk_request_started(myinfo,list[0].requestid)) != 0 ) + pendingid = active->req.quoteid; + if ( bits256_cmp(myinfo->myaddr.persistent,list[0].hash) == 0 ) // my request + myrequest = 1; + for (i=0; imyaddr.persistent,list[i].desthash) == 0 ) // my quoteid + myrequest |= 2; + havequoteflag++; + if ( pendingid == 0 ) + { + if ( list[i].destamount > maxamount ) + { + maxamount = list[i].destamount; + maxi = i; + } + } + else if ( active != 0 && pendingid == list[i].quoteid ) + { + } + } else noquoteflag++; + } + printf("myrequest.%d pendingid.%u noquoteflag.%d havequoteflag.%d maxi.%d %.8f\n",myrequest,pendingid,noquoteflag,havequoteflag,maxi,dstr(maxamount)); + double retvals[4],refprice,profitmargin,aveprice,balance=0.; cJSON *retjson; char *retstr; + if ( myinfo->IAMLP != 0 && myrequest == 0 && pendingid == 0 && noquoteflag != 0 && (profitmargin= tradebot_liquidity_active(myinfo,&refprice,list[0].src,list[0].dest)) > 0. ) + { + if ( (aveprice= instantdex_avehbla(myinfo,retvals,list[0].src,list[0].dest,1.3 * dstr(list[0].srcamount))) == 0. || refprice > aveprice ) + aveprice = refprice; + destamount = (1.0 - profitmargin) * aveprice * list[0].srcamount; + if ( (retstr= InstantDEX_available(myinfo,iguana_coinfind(list[0].dest),0,0,list[0].dest)) != 0 ) + { + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + balance = jdouble(retjson,"result"); + free_json(retjson); + } + free(retstr); + } + printf("balance %.8f destamount %.8f aveprice %.8f minamount %.8f\n",balance,dstr(destamount),aveprice,dstr(minamount)); + if ( balance > destamount && destamount > 0 && destamount >= maxamount && destamount >= minamount ) + { + metric = 1.; + *issueR = list[0]; + issueR->desthash = myinfo->myaddr.persistent; + issueR->destamount = destamount; + issueR->quotetime = (uint32_t)time(NULL); + } + } + else if ( myrequest != 0 && pendingid == 0 && maxi >= 0 ) // automatch best quote + { + if ( minamount != 0 && maxamount > minamount && time(NULL) > BASILISK_DEXDURATION/2 ) + { + printf("automatch quoteid.%u triggered %.8f > %.8f\n",list[maxi].quoteid,dstr(maxamount),dstr(minamount)); + *issueR = list[maxi]; + if ( minamount > 0 ) + metric = (dstr(maxamount) / dstr(minamount)) - 1.; + else metric = 1.; + } + } + return(metric); +} + +double basilisk_process_results(struct supernet_info *myinfo,struct basilisk_request *issueR,cJSON *retjson,double hwm) +{ + cJSON *array,*item; int32_t i,n,m; struct basilisk_request tmpR,R,refR,list[BASILISK_MAXRELAYS]; double metric=0.; + //printf("process_results.(%s)\n",jprint(retjson,0)); + if ( (array= jarray(&n,retjson,"result")) != 0 ) + { + for (i=m=0; i hwm ) + *issueR = tmpR, hwm = metric; + m = 0; + } + } + if ( m < sizeof(list)/sizeof(*list) ) + basilisk_parsejson(&list[m++],item); + } + if ( m > 0 && m < sizeof(list)/sizeof(*list) ) + if ( (metric= basilisk_request_listprocess(myinfo,&tmpR,list,m)) > hwm ) + *issueR = tmpR, hwm = metric; + } + return(hwm); +} diff --git a/basilisk/basilisk_waves.c b/basilisk/basilisk_waves.c new file mode 100755 index 000000000..ae4ef0aaf --- /dev/null +++ b/basilisk/basilisk_waves.c @@ -0,0 +1,19 @@ +/****************************************************************************** + * Copyright © 2014-2016 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +struct basilisk_item *basilisk_wavesrawtx(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,cJSON **vinsp,uint32_t locktime,uint64_t satoshis,char *changeaddr,uint64_t txfee,cJSON *addresses,int32_t minconf,char *spendscriptstr,int32_t timeoutmillis) +{ + return(0); +} diff --git a/crypto777/Makefile b/crypto777/Makefile index ba83510c4..e202396bf 100755 --- a/crypto777/Makefile +++ b/crypto777/Makefile @@ -11,7 +11,7 @@ NACL_SDK_ROOT ?= $(abspath $(CURDIR)) TARGET = crypto777 -EXTRA= -D__PNACL -O2 +EXTRA= -D__PNACL -O2 -DLIQUIDITY_PROVIDER=1 #include $(NACL_SDK_ROOT)/tools/common.mk include tools/common.mk diff --git a/crypto777/OS_nonportable.c b/crypto777/OS_nonportable.c index 4c2d3f5c1..7d148ff76 100755 --- a/crypto777/OS_nonportable.c +++ b/crypto777/OS_nonportable.c @@ -48,7 +48,7 @@ void *OS_nonportable_tmpalloc(char *dirname,char *name,struct OS_memspace *mem,l #include -#include "../win/mman.h" +#include "../OSlibs/win/mman.h" #ifndef FILE_MAP_EXECUTE #define FILE_MAP_EXECUTE 0x0020 @@ -520,7 +520,8 @@ void *OS_nonportable_mapfile(char *fname,uint64_t *filesizep,int32_t enablewrite _close(fd); if ( ptr == 0 || ptr == MAP_FAILED ) { - printf("map_file.write%d: mapping %s failed? mp %p\n",enablewrite,fname,ptr); + if ( enablewrite != 0 ) + printf("map_file.write%d: mapping %s failed? mp %p\n",enablewrite,fname,ptr); return(0); } *filesizep = filesize; diff --git a/crypto777/OS_portable.c b/crypto777/OS_portable.c index 96cc5c371..d59c1b1e9 100755 --- a/crypto777/OS_portable.c +++ b/crypto777/OS_portable.c @@ -127,7 +127,7 @@ int32_t OS_portable_removefile(char *fname) int32_t OS_portable_rmdir(char *dirname,int32_t diralso) { - char cmdstr[1024],tmp[512]; int32_t i; + char cmdstr[1024],tmp[512]; //int32_t i; strcpy(tmp,dirname); OS_portable_path(tmp); #ifdef _WIN32 @@ -141,17 +141,18 @@ int32_t OS_portable_rmdir(char *dirname,int32_t diralso) sprintf(cmdstr,"rm -rf %s",tmp); if ( system(cmdstr) != 0 ) printf("error deleting dir.(%s)\n",cmdstr); - sprintf(cmdstr,"mkdir %s",tmp); - if ( system(cmdstr) != 0 ) - printf("error deleting dir.(%s)\n",cmdstr); + //sprintf(cmdstr,"rmdir %s",tmp); + //if ( system(cmdstr) != 0 ) + // printf("error deleting dir.(%s)\n",cmdstr); } else { - for (i=0; i<=16; i++) + //for (i=0; i<=16; i++) { - if ( i < 16 ) - sprintf(cmdstr,"rm %s/%c*",tmp,i<10?'0'+i:'a'-10+i); - else sprintf(cmdstr,"rm %s/*",tmp); + //if ( i < 16 ) + // sprintf(cmdstr,"rm %s/%c*",tmp,i<10?'0'+i:'a'-10+i); + //else sprintf(cmdstr,"rm %s/*",tmp); + sprintf(cmdstr,"rm -rf %s",tmp); if ( system(cmdstr) != 0 ) printf("error deleting dir.(%s)\n",cmdstr); } diff --git a/crypto777/OS_portable.h b/crypto777/OS_portable.h index 6e51a5b9f..d1b6e579e 100755 --- a/crypto777/OS_portable.h +++ b/crypto777/OS_portable.h @@ -20,6 +20,7 @@ #include #include #include +#define HAVE_STRUCT_TIMESPEC #include #include #include @@ -31,16 +32,18 @@ #ifdef __MINGW #define sleep(x) Sleep(1000*(x)) -#include "../win/mingw.h" -#include "../win/mman.h" +#include "../OSlibs/win/mingw.h" +#include "../OSlibs/win/mman.h" +#include "../OSlibs/win/pthread.h" -//#define EADDRINUSE WSAEADDRINUSE +#define EADDRINUSE WSAEADDRINUSE #else //#include #include #include #include +#define HAVE_STRUCT_TIMESPEC #include //#include //#include "in.h" @@ -174,7 +177,7 @@ void *OS_nonportable_tmpalloc(char *dirname,char *name,struct OS_memspace *mem,l char *OS_portable_path(char *str); int32_t OS_nonportable_renamefile(char *fname,char *newfname); int32_t OS_nonportable_launch(char *args[]); -void OS_nonportable_randombytes(unsigned char *x,long xlen); +void OS_nonportable_randombytes(uint8_t *x,long xlen); int32_t OS_nonportable_init(); #endif @@ -182,7 +185,7 @@ void OS_portable_init(); void OS_init(); double OS_portable_milliseconds(); -void OS_portable_randombytes(unsigned char *x,long xlen); +void OS_portable_randombytes(uint8_t *x,long xlen); int32_t OS_portable_truncate(char *fname,long filesize); char *OS_portable_path(char *str); void OS_remove_directory(char *dirname); @@ -202,7 +205,7 @@ uint32_t OS_conv_datenum(int32_t datenum,int32_t hour,int32_t minute,int32_t sec int32_t OS_conv_unixtime(struct tai *t,int32_t *secondsp,time_t timestamp); double OS_milliseconds(); -void OS_randombytes(unsigned char *x,long xlen); +void OS_randombytes(uint8_t *x,long xlen); int32_t OS_truncate(char *fname,long filesize); char *OS_compatible_path(char *str); @@ -260,12 +263,12 @@ int32_t is_decimalstr(char *str); void tolowercase(char *str); char *clonestr(char *str); int32_t is_hexstr(char *str,int32_t n); -int32_t decode_hex(unsigned char *bytes,int32_t n,char *hex); +int32_t decode_hex(uint8_t *bytes,int32_t n,char *hex); void reverse_hexstr(char *str); int32_t init_hexbytes_noT(char *hexbytes,uint8_t *message,long len); uint16_t parse_ipaddr(char *ipaddr,char *ip_port); int32_t bitweight(uint64_t x); -unsigned char _decode_hex(char *hex); +uint8_t _decode_hex(char *hex); char *uppercase_str(char *buf,char *str); char *lowercase_str(char *buf,char *str); int32_t strsearch(char *strs[],int32_t num,char *name); @@ -355,20 +358,28 @@ uint8_t *iguana_varint32(int32_t rwflag,uint8_t *serialized,uint16_t *varint16p) uint8_t *iguana_varint64(int32_t rwflag,uint8_t *serialized,uint32_t *varint32p); int32_t iguana_rwvarint(int32_t rwflag,uint8_t *serialized,uint64_t *varint64p); int32_t iguana_rwvarint32(int32_t rwflag,uint8_t *serialized,uint32_t *int32p); -int32_t iguana_rwstr(int32_t rwflag,uint8_t *serialized,int32_t maxlen,char *endianedp); +int32_t iguana_rwvarstr(int32_t rwflag,uint8_t *serialized,int32_t maxlen,char *endianedp); int32_t iguana_rwmem(int32_t rwflag,uint8_t *serialized,int32_t len,void *endianedp); +bits256 bits256_ave(bits256 a,bits256 b); bits256 bits256_doublesha256(char *hashstr,uint8_t *data,int32_t datalen); char *bits256_str(char hexstr[65],bits256 x); char *bits256_lstr(char hexstr[65],bits256 x); bits256 bits256_add(bits256 a,bits256 b); int32_t bits256_cmp(bits256 a,bits256 b); bits256 bits256_lshift(bits256 x); +bits256 bits256_rshift(bits256 x); bits256 bits256_from_compact(uint32_t c); +uint32_t bits256_to_compact(bits256 x); bits256 bits256_conv(char *hexstr); int32_t btc_priv2pub(uint8_t pubkey[33],uint8_t privkey[32]); -void calc_shares(unsigned char *shares,unsigned char *secret,int32_t size,int32_t width,int32_t M,int32_t N,unsigned char *sharenrs); int32_t OS_portable_rmdir(char *dirname,int32_t diralso); +void calc_hmac_sha256(uint8_t *mac,int32_t maclen,uint8_t *key,int32_t key_size,uint8_t *message,int32_t len); +int32_t revsort32(uint32_t *buf,uint32_t num,int32_t size); + +bits256 bits256_sha256(bits256 data); +void bits256_rmd160(uint8_t rmd160[20],bits256 data); +void bits256_rmd160_sha256(uint8_t rmd160[20],bits256 data); extern char *Iguana_validcommands[]; extern bits256 GENESIS_PUBKEY,GENESIS_PRIVKEY; diff --git a/crypto777/OS_time.c b/crypto777/OS_time.c index d65f54350..0782c3f2a 100755 --- a/crypto777/OS_time.c +++ b/crypto777/OS_time.c @@ -45,9 +45,9 @@ struct tm *gmtime_r(const time_t *timep,struct tm *result) return(p); } -struct tm *_gmtime32(const time_t *timep,struct tm *result) { return(gmtime_r(timep,result)); } -time_t _time32(struct tm *tm) { return(time(NULL)); } -time_t _localtime32(struct tm *tm) { return(time(NULL)); } +//struct tm *_gmtime32(const time_t *timep,struct tm *result) { return(gmtime_r(timep,result)); } +//time_t _time32(struct tm *tm) { return(time(NULL)); } +//time_t _localtime32(struct tm *tm) { return(time(NULL)); } #include #include // portable: uint64_t MSVC: __int64 diff --git a/crypto777/SaM.c b/crypto777/SaM.c index 0f5d42a75..068862a67 100755 --- a/crypto777/SaM.c +++ b/crypto777/SaM.c @@ -242,13 +242,25 @@ int32_t bitweight(uint64_t x); #define GETBIT(bits,bitoffset) (((uint8_t *)bits)[(bitoffset) >> 3] & (1 << ((bitoffset) & 7))) #define CLEARBIT(bits,bitoffset) (((uint8_t *)bits)[(bitoffset) >> 3] &= ~(1 << ((bitoffset) & 7))) +double OS_milliseconds(); int32_t SaM_test() { int32_t i,j,wt,iter,totalset,totalclr,setcount[48*8],clrcount[48*8],histo[16]; bits256 seed; struct SaM_info state; - uint8_t buf[4096*2],bits[2][10][48]; - double startmilli = time(NULL) * 1000; + uint8_t buf[4096*2],bits[2][10][48]; char trits[243]; + double startmilli = OS_milliseconds(); + for (i=0; i #include @@ -199,7 +202,7 @@ try_again: free(s.ptr); return(0); } - else if ( numretries >= 2 ) + else if ( numretries >= 5 ) { printf("Maximum number of retries exceeded!\n"); free(s.ptr); @@ -306,7 +309,7 @@ void *curl_post(CURL **cHandlep,char *url,char *userpass,char *postfields,char * *cHandlep = cHandle = curl_easy_init(); else curl_easy_reset(cHandle); //#ifdef DEBUG - curl_easy_setopt(cHandle,CURLOPT_VERBOSE, 1); + //curl_easy_setopt(cHandle,CURLOPT_VERBOSE, 1); //#endif curl_easy_setopt(cHandle,CURLOPT_USERAGENT,"mozilla/4.0");//"Mozilla/4.0 (compatible; )"); curl_easy_setopt(cHandle,CURLOPT_SSL_VERIFYPEER,0); diff --git a/crypto777/cJSON.c b/crypto777/cJSON.c index a1d78f8fd..5035f9a9b 100755 --- a/crypto777/cJSON.c +++ b/crypto777/cJSON.c @@ -827,7 +827,25 @@ void jaddi64bits(cJSON *json,uint64_t nxt64bits) { char numstr[64]; sprintf(nums char *jstr(cJSON *json,char *field) { if ( json == 0 ) return(0); if ( field == 0 ) return(cJSON_str(json)); return(cJSON_str(cJSON_GetObjectItem(json,field))); } char *jstri(cJSON *json,int32_t i) { return(cJSON_str(cJSON_GetArrayItem(json,i))); } -char *jprint(cJSON *json,int32_t freeflag) { char *str; if ( json == 0 ) return(clonestr("{}")); str = cJSON_Print(json), _stripwhite(str,' '); if ( freeflag != 0 ) free_json(json); return(str); } +char *jprint(cJSON *json,int32_t freeflag) +{ + char *str; + /*static portable_mutex_t mutex; static int32_t initflag; + if ( initflag == 0 ) + { + portable_mutex_init(&mutex); + initflag = 1; + }*/ + if ( json == 0 ) + return(clonestr("{}")); + //portable_mutex_lock(&mutex); + //usleep(5000); + str = cJSON_Print(json), _stripwhite(str,' '); + if ( freeflag != 0 ) + free_json(json); + //portable_mutex_unlock(&mutex); + return(str); +} bits256 get_API_bits256(cJSON *obj) { diff --git a/crypto777/crypto777.sources b/crypto777/crypto777.sources index d9ce24dac..da4353e99 100755 --- a/crypto777/crypto777.sources +++ b/crypto777/crypto777.sources @@ -40,7 +40,7 @@ NANOMSG_TRANSPORTS = $(TRANSPORTS_UTILS) $(TRANSPORTS_TCP) $(TRANSPORTS_IPC) $( NANOMSG = $(NANOMSG_CORE) $(NANOMSG_AIO) $(NANOMSG_UTILS) $(NANOMSG_DEVICES) $(NANOMSG_TRANSPORTS) $(NANOMSG_PROTOCOLS) -JPEG_SRCS := ../crypto777/jpeg/jaricom.c ../crypto777/jpeg/jcapimin.c ../crypto777/jpeg/jcapistd.c ../crypto777/jpeg/jcarith.c ../crypto777/jpeg/jccoefct.c ../crypto777/jpeg/jccolor.c ../crypto777/jpeg/jcdctmgr.c ../crypto777/jpeg/jchuff.c ../crypto777/jpeg/jcinit.c ../crypto777/jpeg/jcmainct.c ../crypto777/jpeg/jcmarker.c ../crypto777/jpeg/jcmaster.c ../crypto777/jpeg/jcomapi.c ../crypto777/jpeg/jcparam.c ../crypto777/jpeg/jcprepct.c ../crypto777/jpeg/jcsample.c ../crypto777/jpeg/jctrans.c ../crypto777/jpeg/jdapimin.c ../crypto777/jpeg/jdapistd.c ../crypto777/jpeg/jdarith.c ../crypto777/jpeg/jdatadst.c ../crypto777/jpeg/jdatasrc.c ../crypto777/jpeg/jdcoefct.c ../crypto777/jpeg/jdcolor.c ../crypto777/jpeg/jddctmgr.c ../crypto777/jpeg/jdhuff.c ../crypto777/jpeg/jdinput.c ../crypto777/jpeg/jdmainct.c ../crypto777/jpeg/jdmarker.c ../crypto777/jpeg/jdmaster.c ../crypto777/jpeg/jdmerge.c ../crypto777/jpeg/jdpostct.c ../crypto777/jpeg/jdsample.c ../crypto777/jpeg/jdtrans.c ../crypto777/jpeg/jerror.c ../crypto777/jpeg/jfdctflt.c ../crypto777/jpeg/jfdctfst.c ../crypto777/jpeg/jfdctint.c ../crypto777/jpeg/jidctflt.c ../crypto777/jpeg/jidctfst.c ../crypto777/jpeg/jidctint.c ../crypto777/jpeg/jquant1.c ../crypto777/jpeg/jquant2.c ../crypto777/jpeg/jutils.c ../crypto777/jpeg/jmemmgr.c ../crypto777/jpeg/jmemnobs.c +JPEG_SRCS := ../crypto777/jpeg/jaricom.c ../crypto777/jpeg/jcapimin.c ../crypto777/jpeg/jcapistd.c ../crypto777/jpeg/jcarith.c ../crypto777/jpeg/jccoefct.c ../crypto777/jpeg/jccolor.c ../crypto777/jpeg/jcdctmgr.c ../crypto777/jpeg/jchuff.c ../crypto777/jpeg/jcinit.c ../crypto777/jpeg/jcmainct.c ../crypto777/jpeg/jcmarker.c ../crypto777/jpeg/jcmaster.c ../crypto777/jpeg/jcomapi.c ../crypto777/jpeg/jcparam.c ../crypto777/jpeg/jcprepct.c ../crypto777/jpeg/jcsample.c ../crypto777/jpeg/jctrans.c ../crypto777/jpeg/jdapimin.c ../crypto777/jpeg/jdapistd.c ../crypto777/jpeg/jdarith.c ../crypto777/jpeg/jdatadst.c ../crypto777/jpeg/jdatasrc.c ../crypto777/jpeg/jdcoefct.c ../crypto777/jpeg/jdcolor.c ../crypto777/jpeg/jddctmgr.c ../crypto777/jpeg/jdhuff.c ../crypto777/jpeg/jdinput.c ../crypto777/jpeg/jdmainct.c ../crypto777/jpeg/jdmarker.c ../crypto777/jpeg/jdmaster.c ../crypto777/jpeg/jdmerge.c ../crypto777/jpeg/jdpostct.c ../crypto777/jpeg/jdsample.c ../crypto777/jpeg/jdtrans.c ../crypto777/jpeg/jerror.c ../crypto777/jpeg/jfdctflt.c ../crypto777/jpeg/jfdctfst.c ../crypto777/jpeg/jfdctint.c ../crypto777/jpeg/jidctflt.c ../crypto777/jpeg/jidctfst.c ../crypto777/jpeg/jidctint.c ../crypto777/jpeg/jquant1.c ../crypto777/jpeg/jquant2.c ../crypto777/jpeg/jutils.c ../crypto777/jpeg/misc/jmemnobs.c ../crypto777/jpeg/jmemmgr.c -CRYPTO777_SRCS := ../crypto777/tweetnacl.c ../crypto777/bitcoind_RPC.c ../crypto777/cJSON.c ../crypto777/iguana_utils.c ../crypto777/OS_nonportable.c ../crypto777/curve25519-donna.c ../crypto777/inet.c ../crypto777/OS_portable.c ../crypto777/curve25519.c ../crypto777/libgfshare.c ../crypto777/OS_time.c ../crypto777/hmac_sha512.c ../crypto777/ramcoder.c ../crypto777/SaM.c ../crypto777/iguana_OS.c ../crypto777/iguana_serdes.c $(JPEG_SRCS) # $(NANOMSG) +CRYPTO777_SRCS := ../crypto777/tweetnacl.c ../crypto777/scrypt.c ../crypto777/bitcoind_RPC.c ../crypto777/cJSON.c ../crypto777/iguana_utils.c ../crypto777/OS_nonportable.c ../crypto777/curve25519-donna.c ../crypto777/inet.c ../crypto777/OS_portable.c ../crypto777/curve25519.c ../crypto777/OS_time.c ../crypto777/hmac_sha512.c ../crypto777/ramcoder.c ../crypto777/SaM.c ../crypto777/iguana_OS.c ../crypto777/iguana_serdes.c $(JPEG_SRCS) # $(NANOMSG) diff --git a/crypto777/curve25519.c b/crypto777/curve25519.c index e4dc45375..ec23175f8 100755 --- a/crypto777/curve25519.c +++ b/crypto777/curve25519.c @@ -1540,6 +1540,25 @@ void calc_rmd160(char hexstr[41],uint8_t buf[20],uint8_t *msg,int32_t len) init_hexbytes_noT(hexstr,buf,20); } +bits256 bits256_sha256(bits256 data) +{ + bits256 hash; + vcalc_sha256(0,hash.bytes,data.bytes,sizeof(data)); + return(hash); +} + +void bits256_rmd160(uint8_t rmd160[20],bits256 data) +{ + calc_rmd160(0,rmd160,data.bytes,sizeof(data)); +} + +void bits256_rmd160_sha256(uint8_t rmd160[20],bits256 data) +{ + bits256 hash; + hash = bits256_sha256(data); + bits256_rmd160(rmd160,hash); +} + #ifdef ENABLE_RMDTEST int rmd160_test(void) { @@ -1848,4 +1867,25 @@ uint64_t acct777_signtx(struct acct777_sig *sig,bits256 privkey,uint32_t timesta return(acct777_sign(sig,privkey,acct777_msgpubkey(data,datalen),timestamp,data,datalen)); }*/ +int32_t _SuperNET_cipher(uint8_t nonce[crypto_box_NONCEBYTES],uint8_t *cipher,uint8_t *message,int32_t len,bits256 destpub,bits256 srcpriv,uint8_t *buf) +{ + memset(cipher,0,len+crypto_box_ZEROBYTES); + memset(buf,0,crypto_box_ZEROBYTES); + memcpy(buf+crypto_box_ZEROBYTES,message,len); + crypto_box(cipher,buf,len+crypto_box_ZEROBYTES,nonce,destpub.bytes,srcpriv.bytes); + return(len + crypto_box_ZEROBYTES); +} + +uint8_t *_SuperNET_decipher(uint8_t nonce[crypto_box_NONCEBYTES],uint8_t *cipher,uint8_t *message,int32_t len,bits256 srcpub,bits256 mypriv) +{ + int32_t err; + if ( (err= crypto_box_open(message,cipher,len,nonce,srcpub.bytes,mypriv.bytes)) == 0 ) + { + message += crypto_box_ZEROBYTES; + len -= crypto_box_ZEROBYTES; + return(message); + } + return(0); +} + #undef force_inline diff --git a/crypto777/hmac/tomcrypt_custom.h b/crypto777/hmac/tomcrypt_custom.h index 7a8644cd2..c3d812906 100755 --- a/crypto777/hmac/tomcrypt_custom.h +++ b/crypto777/hmac/tomcrypt_custom.h @@ -371,8 +371,8 @@ /* THREAD management */ #ifdef LTC_PTHREAD - -//#include +#define HAVE_STRUCT_TIMESPEC +#include #define LTC_MUTEX_GLOBAL(x) pthread_mutex_t x = PTHREAD_MUTEX_INITIALIZER; #define LTC_MUTEX_PROTO(x) extern pthread_mutex_t x; diff --git a/crypto777/hmac_sha512.c b/crypto777/hmac_sha512.c index 43d92030c..68c428189 100755 --- a/crypto777/hmac_sha512.c +++ b/crypto777/hmac_sha512.c @@ -519,6 +519,12 @@ char *hmac_sha384_str(char *dest,char *key,int32_t key_size,char *message) return(dest); } +void calc_hmac_sha256(uint8_t *mac,int32_t maclen,uint8_t *key,int32_t key_size,uint8_t *message,int32_t len) +{ + unsigned long size = maclen; + hmac_memory(&sha256_desc,(void *)key,key_size,(void *)message,len,mac,&size); +} + char *hmac_sha256_str(char *dest,char *key,int32_t key_size,char *message) { unsigned char mac[1024]; unsigned long size = sizeof(mac); diff --git a/crypto777/iguana_OS.c b/crypto777/iguana_OS.c index 8c49ccdfa..342402e53 100755 --- a/crypto777/iguana_OS.c +++ b/crypto777/iguana_OS.c @@ -19,7 +19,11 @@ #include "OS_portable.h" #include + +#ifndef _WIN32 #include +#endif + #ifndef MAP_FILE #define MAP_FILE 0 #endif @@ -159,6 +163,11 @@ void _myfree(uint8_t type,int32_t origallocsize,void *origptr,int32_t allocsize) void myfree(void *_ptr,long allocsize) { struct allocitem *item = (void *)((long)_ptr - sizeof(struct allocitem)); + if ( allocsize == 0 ) + { + printf("myfree zero allocsize %p?\n",_ptr); + return; + } _myfree(item->type,item->allocsize,item,(uint32_t)allocsize); } @@ -345,7 +354,7 @@ void iguana_memreset(struct OS_memspace *mem) void iguana_mempurge(struct OS_memspace *mem) { - if ( mem->allocated != 0 && mem->ptr != 0 && mem->totalsize > 0 ) + if ( mem->allocated > 0 && mem->ptr != 0 && mem->totalsize > 0 ) myfree(mem->ptr,mem->totalsize), mem->ptr = 0; iguana_memreset(mem); mem->totalsize = 0; @@ -529,19 +538,20 @@ void OS_remove_directory(char *dirname) if ( (fp= fopen(OS_compatible_path(buf),"rb")) != 0 ) OS_removefile(buf,0); else fclose(fp); +//printf("skip rmdir.(%s)\n",dirname); +return; sprintf(buf,"rmdir %s",dirname); if ( system(buf) != 0 ) { //printf("error doing (%s)\n",buf); - sprintf(buf,"rm %s/*",dirname); + sprintf(buf,"rm -rf %s",dirname); if ( system(buf) != 0 ) - printf("error doing (%s)\n",buf); - else { - sprintf(buf,"rmdir %s",dirname); - if ( system(buf) != 0 ) - printf("second error doing (%s)\n",buf); + //printf("error doing (%s)\n",buf); } + //sprintf(buf,"rmdir %s",dirname); + //if ( system(buf) != 0 ) + // printf("second error doing (%s)\n",buf); } } diff --git a/crypto777/iguana_serdes.c b/crypto777/iguana_serdes.c index f8430ea2e..eff6f3e5f 100755 --- a/crypto777/iguana_serdes.c +++ b/crypto777/iguana_serdes.c @@ -186,7 +186,7 @@ int32_t iguana_rwvarint32(int32_t rwflag,uint8_t *serialized,uint32_t *int32p) return(len); } -int32_t iguana_rwstr(int32_t rwflag,uint8_t *serialized,int32_t maxlen,char *endianedp) +int32_t iguana_rwvarstr(int32_t rwflag,uint8_t *serialized,int32_t maxlen,char *endianedp) { int32_t vlen; uint64_t n; if ( rwflag == 0 ) diff --git a/crypto777/iguana_utils.c b/crypto777/iguana_utils.c index 5e9634294..3f963393a 100755 --- a/crypto777/iguana_utils.c +++ b/crypto777/iguana_utils.c @@ -90,16 +90,30 @@ bits256 bits256_add(bits256 a,bits256 b) int32_t bits256_cmp(bits256 a,bits256 b) { int32_t i; - for (i=0; i<4; i++) + for (i=3; i>=0; i--) { + //printf("%llx %llx, ",(long long)a.ulongs[i],(long long)b.ulongs[i]); if ( a.ulongs[i] > b.ulongs[i] ) return(1); else if ( a.ulongs[i] < b.ulongs[i] ) return(-1); } + //printf("thesame\n"); return(0); } +bits256 bits256_rshift(bits256 x) +{ + int32_t i; uint64_t carry,prevcarry = 0; + for (i=3; i>=0; i--) + { + carry = (1 & x.ulongs[i]) << 63; + x.ulongs[i] = prevcarry | (x.ulongs[i] >> 1); + prevcarry = carry; + } + return(x); +} + bits256 bits256_lshift(bits256 x) { int32_t i,carry,prevcarry = 0; uint64_t mask = (1LL << 63); @@ -112,18 +126,42 @@ bits256 bits256_lshift(bits256 x) return(x); } +bits256 bits256_ave(bits256 a,bits256 b) +{ + return(bits256_rshift(bits256_add(a,b))); +} + bits256 bits256_from_compact(uint32_t c) { + uint32_t nbytes,nbits,i; bits256 x; memset(x.bytes,0,sizeof(x)); nbytes = (c >> 24) & 0xFF; - nbits = (8 * (nbytes - 3)); - x.ulongs[0] = c & 0xFFFFFF; - for (i=0; i= 3 ) + { + nbits = (8 * (nbytes - 3)); + x.ulongs[0] = c & 0xFFFFFF; + for (i=0; i2; i--) + if ( x.bytes[i] != 0 ) + break; + if ( (x.bytes[i] & 0x80) != 0 ) + i++; + nbits = x.bytes[i] << 16; + nbits |= x.bytes[i-1] << 8; + nbits |= x.bytes[i-2]; + nbits |= ((i+1) << 24); + return(nbits); +} + int32_t bitweight(uint64_t x) { int i,wt = 0; @@ -236,9 +274,11 @@ void iguana_launcher(void *ptr) void iguana_terminate(struct iguana_thread *t) { int32_t retval; +#ifndef _WIN32 retval = pthread_join(t->handle,NULL); if ( retval != 0 ) printf("error.%d terminating t.%p thread.%s\n",retval,t,t->name); +#endif myfree(t,sizeof(*t)); } @@ -296,13 +336,11 @@ int32_t is_hexstr(char *str,int32_t n) if ( n > 0 && i >= n ) break; if ( _unhex(str[i]) < 0 ) - { - if ( n == 0 ) - return(i); - return(0); - } + break; } - return(n); + if ( n == 0 ) + return(i); + return(i == n); } int32_t unhex(char c) @@ -321,7 +359,7 @@ int32_t decode_hex(unsigned char *bytes,int32_t n,char *hex) { int32_t adjust,i = 0; //printf("decode.(%s)\n",hex); - if ( is_hexstr(hex,64) == 0 ) + if ( is_hexstr(hex,n) == 0 ) { memset(bytes,0,n); return(n); @@ -507,6 +545,19 @@ static int _decreasing_uint64(const void *a,const void *b) #undef uint64_b } +static int _decreasing_uint32(const void *a,const void *b) +{ +#define uint32_a (*(uint32_t *)a) +#define uint32_b (*(uint32_t *)b) + if ( uint32_b > uint32_a ) + return(1); + else if ( uint32_b < uint32_a ) + return(-1); + return(0); +#undef uint32_a +#undef uint32_b +} + int32_t sortds(double *buf,uint32_t num,int32_t size) { qsort(buf,num,size,_increasing_double); @@ -525,6 +576,12 @@ int32_t revsort64s(uint64_t *buf,uint32_t num,int32_t size) return(0); } +int32_t revsort32(uint32_t *buf,uint32_t num,int32_t size) +{ + qsort(buf,num,size,_decreasing_uint32); + return(0); +} + /*int32_t iguana_sortbignum(void *buf,int32_t size,uint32_t num,int32_t structsize,int32_t dir) { int32_t retval = 0; diff --git a/crypto777/inet.c b/crypto777/inet.c index 4ca687a67..6579bd6be 100755 --- a/crypto777/inet.c +++ b/crypto777/inet.c @@ -20,6 +20,7 @@ #define crypto777_inet_h #include "OS_portable.h" + #ifdef _WIN32 #define in6_addr sockaddr #define in_addr_t struct sockaddr_storage @@ -32,7 +33,12 @@ struct sockaddr_in6 { struct in6_addr sin6_addr; u_long sin6_scope_id; }; +#else +#ifndef __MINGW +#include #endif +#endif + #ifdef _WIN32 #ifdef AF_INET6 #undef AF_INET6 @@ -404,7 +410,8 @@ uint64_t calc_ipbits(char *ip_port) expand_ipbits(ipaddr2,ipbits); if ( ipbits != 0 && strcmp(ipaddr,ipaddr2) != 0 ) { - printf("calc_ipbits error: (%s) -> %llx -> (%s)\n",ip_port,(long long)ipbits,ipaddr);//, getchar(); + if ( ipaddr[0] != 0 ) + printf("calc_ipbits error: (%s) -> %llx -> (%s)\n",ip_port,(long long)ipbits,ipaddr);//, getchar(); ipbits = 0; } } diff --git a/crypto777/jpeg/jmemnobs.c b/crypto777/jpeg/jmemnobs.c deleted file mode 100755 index eb8c33772..000000000 --- a/crypto777/jpeg/jmemnobs.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * jmemnobs.c - * - * Copyright (C) 1992-1996, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file provides a really simple implementation of the system- - * dependent portion of the JPEG memory manager. This implementation - * assumes that no backing-store files are needed: all required space - * can be obtained from malloc(). - * This is very portable in the sense that it'll compile on almost anything, - * but you'd better have lots of main memory (or virtual memory) if you want - * to process big images. - * Note that the max_memory_to_use option is ignored by this implementation. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" -#include "jmemsys.h" /* import the system-dependent declarations */ - -#ifndef HAVE_STDLIB_H /* should declare malloc(),free() */ -extern void * malloc JPP((size_t size)); -extern void free JPP((void *ptr)); -#endif - - -/* - * Memory allocation and freeing are controlled by the regular library - * routines malloc() and free(). - */ - -GLOBAL(void *) -jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject) -{ - return (void *) malloc(sizeofobject); -} - -GLOBAL(void) -jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) -{ - free(object); -} - - -/* - * "Large" objects are treated the same as "small" ones. - * NB: although we include FAR keywords in the routine declarations, - * this file won't actually work in 80x86 small/medium model; at least, - * you probably won't be able to process useful-size images in only 64KB. - */ - -GLOBAL(void FAR *) -jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject) -{ - return (void FAR *) malloc(sizeofobject); -} - -GLOBAL(void) -jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) -{ - free(object); -} - - -/* - * This routine computes the total memory space available for allocation. - * Here we always say, "we got all you want bud!" - */ - -GLOBAL(long) -jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, - long max_bytes_needed, long already_allocated) -{ - return max_bytes_needed; -} - - -/* - * Backing store (temporary file) management. - * Since jpeg_mem_available always promised the moon, - * this should never be called and we can just error out. - */ - -GLOBAL(void) -jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, - long total_bytes_needed) -{ - ERREXIT(cinfo, JERR_NO_BACKING_STORE); -} - - -/* - * These routines take care of any system-dependent initialization and - * cleanup required. Here, there isn't any. - */ - -GLOBAL(long) -jpeg_mem_init (j_common_ptr cinfo) -{ - return 0; /* just set max_memory_to_use to 0 */ -} - -GLOBAL(void) -jpeg_mem_term (j_common_ptr cinfo) -{ - /* no work */ -} diff --git a/crypto777/jpeg/jmemansi.c b/crypto777/jpeg/misc/jmemansi.c similarity index 100% rename from crypto777/jpeg/jmemansi.c rename to crypto777/jpeg/misc/jmemansi.c diff --git a/crypto777/jpeg/misc/jmemnobs.c b/crypto777/jpeg/misc/jmemnobs.c new file mode 100755 index 000000000..3a39a4474 --- /dev/null +++ b/crypto777/jpeg/misc/jmemnobs.c @@ -0,0 +1,109 @@ +/* + * jmemnobs.c + * + * Copyright (C) 1992-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file provides a really simple implementation of the system- + * dependent portion of the JPEG memory manager. This implementation + * assumes that no backing-store files are needed: all required space + * can be obtained from malloc(). + * This is very portable in the sense that it'll compile on almost anything, + * but you'd better have lots of main memory (or virtual memory) if you want + * to process big images. + * Note that the max_memory_to_use option is ignored by this implementation. + */ + +#define JPEG_INTERNALS +#include "../jinclude.h" +#include "../jpeglib.h" +#include "../jmemsys.h" /* import the system-dependent declarations */ + +#ifndef HAVE_STDLIB_H /* should declare malloc(),free() */ +extern void * malloc JPP((size_t size)); +extern void free JPP((void *ptr)); +#endif + + +/* + * Memory allocation and freeing are controlled by the regular library + * routines malloc() and free(). + */ + +GLOBAL(void *) +jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject) +{ + return (void *) malloc(sizeofobject); +} + +GLOBAL(void) +jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) +{ + free(object); +} + + +/* + * "Large" objects are treated the same as "small" ones. + * NB: although we include FAR keywords in the routine declarations, + * this file won't actually work in 80x86 small/medium model; at least, + * you probably won't be able to process useful-size images in only 64KB. + */ + +GLOBAL(void FAR *) +jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject) +{ + return (void FAR *) malloc(sizeofobject); +} + +GLOBAL(void) +jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) +{ + free(object); +} + + +/* + * This routine computes the total memory space available for allocation. + * Here we always say, "we got all you want bud!" + */ + +GLOBAL(long) +jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, + long max_bytes_needed, long already_allocated) +{ + return max_bytes_needed; +} + + +/* + * Backing store (temporary file) management. + * Since jpeg_mem_available always promised the moon, + * this should never be called and we can just error out. + */ + +GLOBAL(void) +jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, + long total_bytes_needed) +{ + ERREXIT(cinfo, JERR_NO_BACKING_STORE); +} + + +/* + * These routines take care of any system-dependent initialization and + * cleanup required. Here, there isn't any. + */ + +GLOBAL(long) +jpeg_mem_init (j_common_ptr cinfo) +{ + return 0; /* just set max_memory_to_use to 0 */ +} + +GLOBAL(void) +jpeg_mem_term (j_common_ptr cinfo) +{ + /* no work */ +} diff --git a/crypto777/jpeg/jpegtran.c b/crypto777/jpeg/misc/jpegtran.c similarity index 100% rename from crypto777/jpeg/jpegtran.c rename to crypto777/jpeg/misc/jpegtran.c diff --git a/crypto777/m_LP b/crypto777/m_LP new file mode 100755 index 000000000..259846c31 --- /dev/null +++ b/crypto777/m_LP @@ -0,0 +1,4 @@ +git pull +rm *.o +gcc -c -DLIQUIDITY_PROVIDER=1 -O2 *.c jpeg/*.c jpeg/unix/*.c -I/usr/lib/x86_64-linux-gnu/curl +rm -f ../agents/libcrypto777.a; ar rcu ../agents/libcrypto777.a *.o diff --git a/crypto777/m_android b/crypto777/m_android index b84f37742..d58e90d65 100755 --- a/crypto777/m_android +++ b/crypto777/m_android @@ -1,2 +1,9 @@ -git pull -cd iguana; ./m_android; cd .. +#!/bin/bash + +if [[ $# -eq 0 ]]; then + git pull + #cd iguana; ./m_android; cd .. +fi +echo "Compiling crypto777..." +$CC2 -c -O2 *.c jpeg/*.c jpeg/unix/*.c +rm -f ../agents/libcrypto777.a; $AR rcu ../agents/libcrypto777.a *.o diff --git a/crypto777/m_ios b/crypto777/m_ios index 6afeef994..60b4e2a03 100755 --- a/crypto777/m_ios +++ b/crypto777/m_ios @@ -4,5 +4,5 @@ AR="$(xcrun --sdk iphoneos --find ar)" echo Compiling .. -$CC -I /usr/local/opt/curl/include/ -c -O2 *.c jpeg/*.c jpeg/unix/*.c -I/usr/local/opt/ +$CC -Wno-deprecated -I ../OSlibs/ios/include/ -c -O2 *.c jpeg/*.c jpeg/unix/*.c -I/usr/local/opt/ rm -f ../agents/libcrypto777.a; $AR -rcs ../agents/libcrypto777.a *.o diff --git a/crypto777/m_js b/crypto777/m_js index e0aa6c132..22e1743e9 100755 --- a/crypto777/m_js +++ b/crypto777/m_js @@ -1,4 +1,4 @@ git pull rm *.o -emcc -c -s USE_PTHREADS=1 -s ALLOW_MEMORY_GROWTH=1 -O2 *.c jpeg/*.c jpeg/unix/*.c +emcc -c -s USE_PTHREADS=1 -O3 *.c jpeg/*.c jpeg/unix/*.c rm -f ../agents/libcrypto777.a; emar rcu ../agents/libcrypto777.a *.o diff --git a/crypto777/m_unix b/crypto777/m_unix index 07dbecfd3..0e4e734a9 100755 --- a/crypto777/m_unix +++ b/crypto777/m_unix @@ -1,4 +1,8 @@ -git pull +#!/bin/bash + +if [[ $# -eq 0 ]]; then + git pull +fi rm *.o gcc -c -O2 *.c jpeg/*.c jpeg/unix/*.c # -I/usr/lib/x86_64-linux-gnu/curl rm -f ../agents/libcrypto777.a; ar rcu ../agents/libcrypto777.a *.o diff --git a/crypto777/make_win32 b/crypto777/make_win32 index d9e99b05a..0ff09b83e 100644 --- a/crypto777/make_win32 +++ b/crypto777/make_win32 @@ -1,14 +1,15 @@ include crypto777.sources include ../mingw.path -all: clean build +all: clean copy build +copy : + mkdir -p ../agents/win32 || true build : - mkdir -p ../agents/win32 || true @echo "\nBuilding crypto777....." - $(TOOL_DIR)/$(MINGW)-gcc -w -D __MINGW -c $(CRYPTO777_SRCS) -I/usr/mingw32/include -I/usr/mingw32/include/sys -I/home/user/SuperNET/includes/openssl -I/home/user/SuperNET/crypto777 || (echo -e "\033[4mERROR: Compilation failed for win32 \033[0m"; exit 1; ) + $(TOOL_DIR)/bin/$(MINGW) -w -D__CLEANUP_C -DPTW32_STATIC_LIB -D __MINGW -DHAVE_STRUCT_TIMESPEC -c $(CRYPTO777_SRCS) -I$(TOOL_DIR)/include -I../includes/openssl -I../crypto777 -I../OSlibs/win -L../OSlibs/win -lpthreadGC2 || (echo -e "\033[4mERROR: Compilation failed for win32 \033[0m"; exit 1; ) - $(TOOL_DIR)/$(MINGW)-ar rcu ../agents/win32/libcrypto777.a *.o || (echo -e "\033[4mERROR: Failed to create libcrypto777.a\033[0m"; exit 1; ) + $(TOOL_DIR)/bin/$(MINGW)-ar rcu ../agents/win32/libcrypto777.a *.o || (echo -e "\033[4mERROR: Failed to create libcrypto777.a\033[0m"; exit 1; ) @echo "\Build Successful......" diff --git a/crypto777/make_win64 b/crypto777/make_win64 index e9d12a629..73e83c31b 100644 --- a/crypto777/make_win64 +++ b/crypto777/make_win64 @@ -5,13 +5,14 @@ all: clean build build: mkdir -p ../agents/win64 || true - @echo "\nBuilding crypto......" - $(TOOL_DIR)/$(MINGW)-gcc -w -D __MINGW -c $(CRYPTO777_SRCS) -I/usr/share/mingw-w64/include -I /usr/share/mingw-w64/include/sys -I/home/user/SuperNET/includes/openssl || (echo "\033[4m ERROR: Compilation failed for win64\033[0m"; exit 1; ) + @echo "\nBuilding crypto777......" + $(TOOL_DIR)/bin/$(MINGW) -w -D__CLEANUP_C -DPTW32_STATIC_LIB -D __MINGW -DHAVE_STRUCT_TIMESPEC -c $(CRYPTO777_SRCS) -I$(TOOL_DIR)/include -I../includes/openssl -I../OSlibs/win -L../OSlibs/win/x64 -lpthreadGC2 || (echo "\033[4m ERROR: Compilation failed for win64\033[0m"; exit 1; ) - $(TOOL_DIR)/$(MINGW)-ar rcu ../agents/win64/libcrypto777.a *.o || (echo "\033[4mERROR: Failed to create libcrypto777.a\033[0m"; exit 1; ) - + $(TOOL_DIR)/bin/$(MINGW)-ar rcu ../agents/win64/libcrypto777.a *.o || (echo "\033[4mERROR: Failed to create libcrypto777.a\033[0m"; exit 1; ) + @echo "\Build Successful......" clean: @echo "\nCleaning files......" rm -f ../agents/win64/* || true rm -f *.o || true + @echo "\nCleaned all files......" \ No newline at end of file diff --git a/crypto777/mingw b/crypto777/mingw index e5a3bc40f..aff4a1774 100755 --- a/crypto777/mingw +++ b/crypto777/mingw @@ -1,6 +1,6 @@ include crypto777.sources all: - $(TOOL_DIR)/$(MINGW)-gcc -w -D __MINGW -c $(CRYPTO777_SRCS) -I/usr/mingw32/include -I/usr/mingw32/include/sys -I/home/user/SuperNET/includes/openssl -I/home/user/SuperNET/crypto777 - $(TOOL_DIR)/$(MINGW)-ar rcu ../agents/win32/libcrypto777.a *.o + $(TOOL_DIR)/bin/$(MINGW) -w -D __MINGW -c $(CRYPTO777_SRCS) -I$(TOOL_DIR)/include -I../includes/openssl -I../crypto777 + $(TOOL_DIR)/bin/$(MINGW)-ar rcu ../agents/win32/libcrypto777.a *.o rm *.o diff --git a/crypto777/nanosrc/core/global.c b/crypto777/nanosrc/core/global.c index 0d457b208..51ab91709 100755 --- a/crypto777/nanosrc/core/global.c +++ b/crypto777/nanosrc/core/global.c @@ -79,6 +79,7 @@ #include #if defined NN_HAVE_MINGW +#define HAVE_STRUCT_TIMESPEC #include #elif defined NN_HAVE_WINDOWS #define gmtime_r(ptr_numtime, ptr_strtime) gmtime_s(ptr_strtime, ptr_numtime) diff --git a/crypto777/nanosrc/utils/glock.c b/crypto777/nanosrc/utils/glock.c index 7fe0c6dc3..21de524a6 100755 --- a/crypto777/nanosrc/utils/glock.c +++ b/crypto777/nanosrc/utils/glock.c @@ -51,7 +51,7 @@ void nn_glock_unlock (void) #else #include "err.h" - +#define HAVE_STRUCT_TIMESPEC #include static pthread_mutex_t nn_glock_mutex = PTHREAD_MUTEX_INITIALIZER; diff --git a/crypto777/nanosrc/utils/mutex.h b/crypto777/nanosrc/utils/mutex.h index b65de4105..f6083ee8a 100755 --- a/crypto777/nanosrc/utils/mutex.h +++ b/crypto777/nanosrc/utils/mutex.h @@ -26,6 +26,7 @@ #ifdef NN_HAVE_WINDOWS #include "win.h" #else +#define HAVE_STRUCT_TIMESPEC #include #endif diff --git a/crypto777/nanosrc/utils/sem.h b/crypto777/nanosrc/utils/sem.h index 82b8454df..38932e110 100755 --- a/crypto777/nanosrc/utils/sem.h +++ b/crypto777/nanosrc/utils/sem.h @@ -40,7 +40,7 @@ void nn_sem_post (struct nn_sem *self); int nn_sem_wait (struct nn_sem *self); #if defined __APPLE__ || defined __PNACL - +#define HAVE_STRUCT_TIMESPEC #include struct nn_sem { diff --git a/crypto777/nanosrc/utils/thread_posix.h b/crypto777/nanosrc/utils/thread_posix.h index c007fa02c..b76a99c7b 100755 --- a/crypto777/nanosrc/utils/thread_posix.h +++ b/crypto777/nanosrc/utils/thread_posix.h @@ -19,7 +19,7 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - +#define HAVE_STRUCT_TIMESPEC #include struct nn_thread diff --git a/crypto777/scrypt.c b/crypto777/scrypt.c new file mode 100755 index 000000000..99ce4a04a --- /dev/null +++ b/crypto777/scrypt.c @@ -0,0 +1,368 @@ + +/* + * Copyright 2009 Colin Percival, 2011 ArtForz, 2011-2014 pooler + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file was originally written by Colin Percival as part of the Tarsnap + * online backup system. + */ + +#include +#include +#include + +static const uint32_t keypad[12] = { + 0x80000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00000280 +}; +static const uint32_t innerpad[11] = { + 0x80000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x000004a0 +}; +static const uint32_t outerpad[8] = { + 0x80000000, 0, 0, 0, 0, 0, 0, 0x00000300 +}; +static const uint32_t finalblk[16] = { + 0x00000001, 0x80000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00000620 +}; + +static const uint32_t sha256_h[8] = { + 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, + 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 +}; + +static const uint32_t sha256_k[64] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; + +static inline void sha256_init(uint32_t *state) +{ + memcpy(state, sha256_h, 32); +} + +/* Elementary functions used by SHA256 */ +#define Ch(x, y, z) ((x & (y ^ z)) ^ z) +#define Maj(x, y, z) ((x & (y | z)) | (y & z)) +#define ROTR(x, n) ((x >> n) | (x << (32 - n))) +#define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22)) +#define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25)) +#define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ (x >> 3)) +#define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ (x >> 10)) + +/* SHA256 round function */ +#define RND(a, b, c, d, e, f, g, h, k) \ +do { \ +t0 = h + S1(e) + Ch(e, f, g) + k; \ +t1 = S0(a) + Maj(a, b, c); \ +d += t0; \ +h = t0 + t1; \ +} while (0) + +/* Adjusted round function for rotating state */ +#define RNDr(S, W, i) \ +RND(S[(64 - i) % 8], S[(65 - i) % 8], \ +S[(66 - i) % 8], S[(67 - i) % 8], \ +S[(68 - i) % 8], S[(69 - i) % 8], \ +S[(70 - i) % 8], S[(71 - i) % 8], \ +W[i] + sha256_k[i]) + +#define swab32(x) ((((x) << 24) & 0xff000000u) | (((x) << 8) & 0x00ff0000u) | (((x) >> 8) & 0x0000ff00u) | (((x) >> 24) & 0x000000ffu)) + +static inline void sha256_transform(uint32_t *state, const uint32_t *block, int swap) +{ + uint32_t W[64]; + uint32_t S[8]; + uint32_t t0, t1; + int i; + + /* 1. Prepare message schedule W. */ + if (swap) { + for (i = 0; i < 16; i++) + W[i] = swab32(block[i]); + } else + memcpy(W, block, 64); + for (i = 16; i < 64; i += 2) { + W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16]; + W[i+1] = s1(W[i - 1]) + W[i - 6] + s0(W[i - 14]) + W[i - 15]; + } + + /* 2. Initialize working variables. */ + memcpy(S, state, 32); + + /* 3. Mix. */ + RNDr(S, W, 0); + RNDr(S, W, 1); + RNDr(S, W, 2); + RNDr(S, W, 3); + RNDr(S, W, 4); + RNDr(S, W, 5); + RNDr(S, W, 6); + RNDr(S, W, 7); + RNDr(S, W, 8); + RNDr(S, W, 9); + RNDr(S, W, 10); + RNDr(S, W, 11); + RNDr(S, W, 12); + RNDr(S, W, 13); + RNDr(S, W, 14); + RNDr(S, W, 15); + RNDr(S, W, 16); + RNDr(S, W, 17); + RNDr(S, W, 18); + RNDr(S, W, 19); + RNDr(S, W, 20); + RNDr(S, W, 21); + RNDr(S, W, 22); + RNDr(S, W, 23); + RNDr(S, W, 24); + RNDr(S, W, 25); + RNDr(S, W, 26); + RNDr(S, W, 27); + RNDr(S, W, 28); + RNDr(S, W, 29); + RNDr(S, W, 30); + RNDr(S, W, 31); + RNDr(S, W, 32); + RNDr(S, W, 33); + RNDr(S, W, 34); + RNDr(S, W, 35); + RNDr(S, W, 36); + RNDr(S, W, 37); + RNDr(S, W, 38); + RNDr(S, W, 39); + RNDr(S, W, 40); + RNDr(S, W, 41); + RNDr(S, W, 42); + RNDr(S, W, 43); + RNDr(S, W, 44); + RNDr(S, W, 45); + RNDr(S, W, 46); + RNDr(S, W, 47); + RNDr(S, W, 48); + RNDr(S, W, 49); + RNDr(S, W, 50); + RNDr(S, W, 51); + RNDr(S, W, 52); + RNDr(S, W, 53); + RNDr(S, W, 54); + RNDr(S, W, 55); + RNDr(S, W, 56); + RNDr(S, W, 57); + RNDr(S, W, 58); + RNDr(S, W, 59); + RNDr(S, W, 60); + RNDr(S, W, 61); + RNDr(S, W, 62); + RNDr(S, W, 63); + + /* 4. Mix local working variables into global state */ + for (i = 0; i < 8; i++) + state[i] += S[i]; +} + +static inline void HMAC_SHA256_80_init(const uint32_t *key,uint32_t *tstate, uint32_t *ostate) +{ + uint32_t ihash[8]; + uint32_t pad[16]; + int i; + + /* tstate is assumed to contain the midstate of key */ + memcpy(pad, key + 16, 16); + memcpy(pad + 4, keypad, 48); + sha256_transform(tstate, pad, 0); + memcpy(ihash, tstate, 32); + + sha256_init(ostate); + for (i = 0; i < 8; i++) + pad[i] = ihash[i] ^ 0x5c5c5c5c; + for (; i < 16; i++) + pad[i] = 0x5c5c5c5c; + sha256_transform(ostate, pad, 0); + + sha256_init(tstate); + for (i = 0; i < 8; i++) + pad[i] = ihash[i] ^ 0x36363636; + for (; i < 16; i++) + pad[i] = 0x36363636; + sha256_transform(tstate, pad, 0); +} + +static inline void PBKDF2_SHA256_80_128(const uint32_t *tstate,const uint32_t *ostate, const uint32_t *salt, uint32_t *output) +{ + uint32_t istate[8], ostate2[8],ibuf[16], obuf[16]; int i, j; + memcpy(istate, tstate, 32); + sha256_transform(istate, salt, 0); + memcpy(ibuf, salt + 16, 16); + memcpy(ibuf + 5, innerpad, 44); + memcpy(obuf + 8, outerpad, 32); + for (i = 0; i < 4; i++) + { + memcpy(obuf, istate, 32); + ibuf[4] = i + 1; + sha256_transform(obuf, ibuf, 0); + memcpy(ostate2, ostate, 32); + sha256_transform(ostate2, obuf, 0); + for (j = 0; j < 8; j++) + output[8 * i + j] = swab32(ostate2[j]); + } +} + +static inline void PBKDF2_SHA256_128_32(uint32_t *tstate, uint32_t *ostate,const uint32_t *salt, uint32_t *output) +{ + uint32_t buf[16]; int i; + sha256_transform(tstate, salt, 1); + sha256_transform(tstate, salt + 16, 1); + sha256_transform(tstate, finalblk, 0); + memcpy(buf, tstate, 32); + memcpy(buf + 8, outerpad, 32); + sha256_transform(ostate, buf, 0); + for (i = 0; i < 8; i++) + output[i] = swab32(ostate[i]); +} + +static inline void xor_salsa8(uint32_t B[16], const uint32_t Bx[16]) +{ + uint32_t x00,x01,x02,x03,x04,x05,x06,x07,x08,x09,x10,x11,x12,x13,x14,x15; + int i; + + x00 = (B[ 0] ^= Bx[ 0]); + x01 = (B[ 1] ^= Bx[ 1]); + x02 = (B[ 2] ^= Bx[ 2]); + x03 = (B[ 3] ^= Bx[ 3]); + x04 = (B[ 4] ^= Bx[ 4]); + x05 = (B[ 5] ^= Bx[ 5]); + x06 = (B[ 6] ^= Bx[ 6]); + x07 = (B[ 7] ^= Bx[ 7]); + x08 = (B[ 8] ^= Bx[ 8]); + x09 = (B[ 9] ^= Bx[ 9]); + x10 = (B[10] ^= Bx[10]); + x11 = (B[11] ^= Bx[11]); + x12 = (B[12] ^= Bx[12]); + x13 = (B[13] ^= Bx[13]); + x14 = (B[14] ^= Bx[14]); + x15 = (B[15] ^= Bx[15]); + for (i = 0; i < 8; i += 2) { +#define R(a, b) (((a) << (b)) | ((a) >> (32 - (b)))) + /* Operate on columns. */ + x04 ^= R(x00+x12, 7); x09 ^= R(x05+x01, 7); + x14 ^= R(x10+x06, 7); x03 ^= R(x15+x11, 7); + + x08 ^= R(x04+x00, 9); x13 ^= R(x09+x05, 9); + x02 ^= R(x14+x10, 9); x07 ^= R(x03+x15, 9); + + x12 ^= R(x08+x04,13); x01 ^= R(x13+x09,13); + x06 ^= R(x02+x14,13); x11 ^= R(x07+x03,13); + + x00 ^= R(x12+x08,18); x05 ^= R(x01+x13,18); + x10 ^= R(x06+x02,18); x15 ^= R(x11+x07,18); + + /* Operate on rows. */ + x01 ^= R(x00+x03, 7); x06 ^= R(x05+x04, 7); + x11 ^= R(x10+x09, 7); x12 ^= R(x15+x14, 7); + + x02 ^= R(x01+x00, 9); x07 ^= R(x06+x05, 9); + x08 ^= R(x11+x10, 9); x13 ^= R(x12+x15, 9); + + x03 ^= R(x02+x01,13); x04 ^= R(x07+x06,13); + x09 ^= R(x08+x11,13); x14 ^= R(x13+x12,13); + + x00 ^= R(x03+x02,18); x05 ^= R(x04+x07,18); + x10 ^= R(x09+x08,18); x15 ^= R(x14+x13,18); +#undef R + } + B[ 0] += x00; + B[ 1] += x01; + B[ 2] += x02; + B[ 3] += x03; + B[ 4] += x04; + B[ 5] += x05; + B[ 6] += x06; + B[ 7] += x07; + B[ 8] += x08; + B[ 9] += x09; + B[10] += x10; + B[11] += x11; + B[12] += x12; + B[13] += x13; + B[14] += x14; + B[15] += x15; +} + +static inline void scrypt_core(uint32_t *X, uint32_t *V, int N) +{ + uint32_t i, j, k; + for (i = 0; i < N; i++) + { + //printf("core.%d V.%p X.%p\n",i,V,X); + memcpy(&V[i * 32], X, 128); + xor_salsa8(&X[0], &X[16]); + xor_salsa8(&X[16], &X[0]); + } + for (i = 0; i < N; i++) + { + j = 32 * (X[16] & (N - 1)); + for (k = 0; k < 32; k++) + X[k] ^= V[j + k]; + xor_salsa8(&X[0], &X[16]); + xor_salsa8(&X[16], &X[0]); + } +} + +void scrypt_1024_1_1_256(const uint32_t *input,uint32_t *output,uint32_t *midstate,uint8_t *scratchpad, int N) +{ + uint32_t *V,tstate[8],ostate[8],X[32] __attribute__((aligned(128))); + V = (uint32_t *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63)); + memcpy(tstate, midstate, 32); + HMAC_SHA256_80_init(input, tstate, ostate); + PBKDF2_SHA256_80_128(tstate, ostate, input, X); + scrypt_core(X, V, N); + PBKDF2_SHA256_128_32(tstate, ostate, X, output); +} + +void calc_scrypthash(uint32_t *hash,void *data) +{ + uint8_t *scratchbuf; uint32_t midstate[8]; + memset(midstate,0,sizeof(midstate)); + memset(hash,0,32); + sha256_init(midstate); + sha256_transform(midstate,(void *)data,0); + scratchbuf = malloc(1024 * 128 + 64); + scrypt_1024_1_1_256((void *)data,hash,midstate,scratchbuf,1024); + free(scratchbuf); +} +//010000000000000000000000000000000000000000000000000000000000000000000000d9ced4ed1130f7b7faad9be25323ffafa33232a17c3edf6cfd97bee6bafbdd97b9aa8e4ef0ff0f1ecd513f7c +//010000000000000000000000000000000000000000000000000000000000000000000000d9ced4ed1130f7b7faad9be25323ffafa33232a17c3edf6cfd97bee6bafbdd97b9aa8e4ef0ff0f1ecd513f7c00 \ No newline at end of file diff --git a/datachain/datachain.c b/datachain/datachain.c new file mode 100755 index 000000000..95792c520 --- /dev/null +++ b/datachain/datachain.c @@ -0,0 +1,334 @@ +/****************************************************************************** + * Copyright © 2014-2016 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#include "../iguana/iguana777.h" +#include "datachain_events.c" + +uint32_t datachain_checkpoint(struct supernet_info *myinfo,struct iguana_info *coin,uint32_t lastcheckpoint,uint32_t timestamp,bits256 merkle,int32_t lastheight,bits256 lasthash2) +{ + char str[65],str2[65]; struct iguana_info *btc = iguana_coinfind("BTC"); + printf("datachain_checkpoint.%s for %s.%u to %u lastheight.%d %s\n",bits256_str(str,merkle),coin->symbol,lastcheckpoint,timestamp,lastheight,bits256_str(str2,lasthash2)); + if ( (lastheight % NUMRELAYS) == RELAYID ) + { + // if designated relay, submit checkpoint -> add ip/relayid to opreturn + // + if ( strcmp(coin->symbol,"BTCD") == 0 ) + { + if ( btc != 0 ) + { + + } + } + else + { + } + } + return(timestamp); +} + +int32_t datachain_events_rewind(struct supernet_info *myinfo,int32_t ordered,struct datachain_info *dPoW,int32_t height,uint32_t hdrsi,uint32_t unspentind) +{ + uint64_t hdrsi_unspentind; int32_t i; + printf("datachain_events_rewind\n"); + if ( dPoW->numevents > 0 ) + { + datachain_events_sort(dPoW); + hdrsi_unspentind = ((uint64_t)hdrsi << 32) | unspentind; + for (i=dPoW->numevents-1; i>=0; i--) + if ( hdrsi_unspentind > dPoW->events[i]->hdrsi_unspentind ) + break; + printf("dPoW rewind %d to %d\n",dPoW->numevents,i+1); + dPoW->numevents = i+1; + } + return(dPoW->numevents); +} + +int32_t datachain_checkpoint_update(struct supernet_info *myinfo,struct iguana_info *coin,uint32_t timestamp) +{ + int32_t i,num,n,lastheight; bits256 *tree,hash2,lasthash2,merkle; struct iguana_block *block; + //printf("datachain_checkpoint_update\n"); + if ( coin->lastcheckpoint <= coin->blocks.hwmchain.height ) + { + num = (coin->blocks.hwmchain.height - coin->lastcheckpoint) + 1; + tree = (bits256 *)coin->blockspace; + if ( num <= IGUANA_MAXPACKETSIZE/(sizeof(bits256) * 2) ) + { + lastheight = -1; + memset(lasthash2.bytes,0,sizeof(lasthash2)); + for (i=n=0; ilastcheckpoint + i); + if ( bits256_nonz(hash2) != 0 ) + { + if ( (block= iguana_blockfind("datachain",coin,hash2)) != 0 && block->height == coin->lastcheckpoint + i && block->mainchain != 0 && block->RO.timestamp < timestamp ) + { + tree[n++] = hash2; + lastheight = block->height; + lasthash2 = hash2; + } + else break; + } + else + { + printf("got zero blockhash for %s.[%d]\n",coin->symbol,coin->lastcheckpoint + i); + break; + } + } + if ( n > 0 && lastheight >= 0 && bits256_nonz(lasthash2) != 0 ) + { + merkle = iguana_merkle(tree,num); + coin->lastcheckpoint = datachain_checkpoint(myinfo,coin,coin->lastcheckpoint,timestamp,merkle,lastheight,lasthash2); + } + } + } + return(coin->lastcheckpoint); +} + +void datachain_BTC_clock(struct supernet_info *myinfo,int32_t ordered,struct iguana_info *btc,int32_t height,uint32_t hdrsi,uint32_t unspentind,uint32_t timestamp) +{ + int32_t retval; struct iguana_info *btcd = iguana_coinfind("BTCD"); + //printf("datachain_BTC_clock\n"); + if ( (retval= datachain_eventadd(myinfo,ordered,&myinfo->dPoW.BTC,DATACHAIN_ISBTC,0)) < 0 ) + { + myinfo->dPoW.BTC.numevents = datachain_events_rewind(myinfo,ordered,&myinfo->dPoW.BTC,height,hdrsi,unspentind); + } + else if ( retval > 0 ) + { + if ( ordered != 0 && btcd != 0 && btcd->started != 0 && btcd->active != 0 ) + { + // new BTC block actions, ie gather BTCD hashes for checkpoint + btcd->lastcheckpoint = datachain_checkpoint_update(myinfo,btcd,timestamp); + printf("NEWBLOCK.%s ht.%d\n",btc->symbol,height); + } + } +} + +void datachain_KOMODO_newblock(struct supernet_info *myinfo,int32_t ordered,struct iguana_info *btcd,int32_t height,uint32_t hdrsi,uint32_t unspentind,uint32_t timestamp) +{ + int32_t retval; struct iguana_info *virt,*tmp; + //printf("datachain_KOMODO_newblock\n"); + if ( (retval= datachain_eventadd(myinfo,ordered,&myinfo->dPoW.BTCD,DATACHAIN_ISKOMODO,0)) < 0 ) + { + myinfo->dPoW.BTCD.numevents = datachain_events_rewind(myinfo,ordered,&myinfo->dPoW.BTCD,height,hdrsi,unspentind); + } + else if ( retval > 0 ) + { + // new BTCD block actions, ie gather all virtual hashes for checkpoint + if ( ordered != 0 ) + { + HASH_ITER(hh,myinfo->allcoins,virt,tmp) + { + if ( virt->started != 0 && virt->active != 0 && virt->virtualchain != 0 ) + virt->lastcheckpoint = datachain_checkpoint_update(myinfo,virt,timestamp); + } + //printf("NEWBLOCK.%s ht.%d\n",btcd->symbol,height); + } + } +} + +void datachain_virt_newblock(struct supernet_info *myinfo,int32_t ordered,struct iguana_info *virt,int32_t height,uint32_t hdrsi,uint32_t unspentind,uint32_t timestamp) +{ + int32_t retval; + printf("datachain_virt_newblock\n"); + if ( (retval= datachain_eventadd(myinfo,ordered,&virt->dPoW,0,0)) < 0 ) + { + virt->dPoW.numevents = datachain_events_rewind(myinfo,ordered,&virt->dPoW,height,hdrsi,unspentind); + } + else if ( retval > 0 ) + { + // new virt block actions, maybe nothing to do? + if ( ordered != 0 ) + printf("NEWBLOCK.%s ht.%d\n",virt->symbol,height); + } +} + +int32_t datachain_datascript(struct iguana_info *coin,uint8_t *script,uint8_t *data,int32_t datalen) +{ + int32_t i,pkey0,plen,len = 0; uint8_t p2sh_rmd160[20]; struct vin_info V; + memset(&V,0,sizeof(V)); + if ( len < 32*3 ) + pkey0 = 2, plen = 32; + else pkey0 = 4, plen = 64; + V.M = V.N = (datalen / plen) + ((datalen % plen) != 0); + for (i=0; iN; i++) + { + if ( (plen= bitcoin_pubkeylen(vp->signers[i].pubkey)) > 32 ) + memcpy(&opreturn[oplen],vp->signers[i].pubkey+1,plen-1), oplen += (plen - 1); + } + return(oplen); +} + +int32_t datachain_opreturnscript(struct iguana_info *coin,uint8_t *script,char *datastr,int32_t datalen) +{ + int32_t offset = 0; + script[offset++] = 0x6a; + if ( datalen >= 0x4c ) + { + if ( datalen > 0xff ) + { + script[offset++] = 0x4d; + script[offset++] = datalen & 0xff; + script[offset++] = (datalen >> 8) & 0xff; + } + else + { + script[offset++] = 0x4c; + script[offset++] = datalen; + } + } else script[offset++] = datalen; + decode_hex(&script[offset],datalen,datastr); + return(datalen + offset); +} + +int32_t datachain_opreturn_decode(uint8_t *opreturn,uint8_t *script,int32_t scriptlen) +{ + int32_t datalen,len = 1; + if ( (datalen= script[len++]) >= 76 ) + { + if ( datalen == 0x4c ) + datalen = script[len++]; + else if ( datalen == 0x4d ) + { + datalen = script[len++]; + datalen = (datalen << 8) | script[len++]; + } + } + memcpy(opreturn,&script[len],datalen); + if ( len+datalen == scriptlen ) + return(datalen); + else return(-1); +} + +void datachain_opreturn(struct supernet_info *myinfo,int32_t ordered,struct iguana_info *coin,uint32_t timestamp,int32_t btc_or_btcd,int64_t crypto777_payment,int64_t burned,int32_t height,uint64_t hdrsi_unspentind,uint8_t *opreturn,int32_t oplen) +{ + uint32_t hdrsi,unspentind; struct datachain_event *event; + hdrsi = (uint32_t)(hdrsi_unspentind >> 32); + unspentind = (uint32_t)hdrsi_unspentind; + //printf("datachain_opreturn\n"); + if ( btc_or_btcd == DATACHAIN_ISBTC ) // BTC + { + if ( opreturn == 0 ) + datachain_BTC_clock(myinfo,ordered,coin,height,hdrsi,unspentind,timestamp); + else + { + if ( (event= datachain_event_create(coin,crypto777_payment,burned,height,hdrsi,unspentind,opreturn,oplen)) != 0 ) + datachain_eventadd(myinfo,ordered,&myinfo->dPoW.BTC,btc_or_btcd,event); + } + } + else if ( btc_or_btcd == DATACHAIN_ISKOMODO ) // BTCD + { + if ( opreturn == 0 ) + datachain_KOMODO_newblock(myinfo,ordered,coin,height,hdrsi,unspentind,timestamp); + else + { + if ( (event= datachain_event_create(coin,crypto777_payment,burned,height,hdrsi,unspentind,opreturn,oplen)) != 0 ) + datachain_eventadd(myinfo,ordered,&myinfo->dPoW.BTCD,btc_or_btcd,event); + } + } + else + { + if ( opreturn == 0 ) + datachain_virt_newblock(myinfo,ordered,coin,height,hdrsi,unspentind,timestamp); + else + { + if ( (event= datachain_event_create(coin,crypto777_payment,burned,height,hdrsi,unspentind,opreturn,oplen)) != 0 ) + datachain_eventadd(myinfo,ordered,&coin->dPoW,btc_or_btcd,event); + } + } + if ( opreturn != 0 ) + { + int32_t i; + for (i=0; isymbol,oplen,height,hdrsi,unspentind,dstr(crypto777_payment),dstr(burned)); + } +} + +int32_t iguana_opreturn(struct supernet_info *myinfo,int32_t ordered,struct iguana_info *coin,uint32_t timestamp,struct iguana_bundle *bp,int64_t crypto777_payment,int32_t height,uint64_t hdrsi_unspentind,int64_t burned,uint32_t fileid,uint64_t scriptpos,uint32_t scriptlen) +{ + uint8_t type,scriptspace[IGUANA_MAXSCRIPTSIZE],opreturn[8192]; char fname[1024]; uint32_t oplen=0; int32_t btc_or_btcd=0,len = -1; struct vin_info V; + //printf("iguana_opreturn\n"); + if ( strcmp("BTC",coin->symbol) == 0 ) + btc_or_btcd = DATACHAIN_ISBTC; + else if ( strcmp("BTCD",coin->symbol) == 0 ) + btc_or_btcd = DATACHAIN_ISKOMODO; + else if ( coin->virtualchain == 0 ) + return(-1); + if ( height < bp->bundleheight || height >= bp->bundleheight+coin->chain->bundlesize ) + { + printf("iguana_opreturn illegal height %d for [%d] %d\n",height,bp->hdrsi,bp->bundleheight); + return(-1); + } + if ( crypto777_payment == 0 && burned == 0 && scriptlen == 0 && fileid == 0 && scriptpos == 0 ) + { + datachain_opreturn(myinfo,ordered,coin,timestamp,btc_or_btcd,crypto777_payment,burned,height,hdrsi_unspentind,0,0); + return(0); + } + if ( scriptpos > 0 && scriptlen > 0 ) + { + iguana_voutsfname(coin,bp->ramchain.from_ro,fname,fileid); + if ( (len= iguana_scriptdata(coin,scriptspace,coin->voutptrs[fileid],fname,scriptpos,scriptlen)) == scriptlen ) + { + memset(&V,0,sizeof(V)); + V.spendlen = scriptlen; + memcpy(V.spendscript,scriptspace,scriptlen); + type = _iguana_calcrmd160(coin,&V); + if ( type == IGUANA_SCRIPT_OPRETURN ) + oplen = datachain_opreturn_decode(opreturn,scriptspace,scriptlen); + else oplen = datachain_datascript_decode(opreturn,scriptspace,scriptlen,&V,type); + datachain_opreturn(myinfo,ordered,coin,timestamp,btc_or_btcd,crypto777_payment,burned,height,hdrsi_unspentind,opreturn,oplen); + return(oplen); + } else printf("iguana_opreturn error: %d bytes from fileid.%d[%d] %s for scriptlen.%d\n",len,fileid,(uint32_t)scriptpos,fname,scriptlen); + } + return(-1); +} + +void datachain_update_spend(struct supernet_info *myinfo,int32_t ordered,struct iguana_info *coin,uint32_t timestamp,struct iguana_bundle *bp,int32_t height,bits256 txid,int32_t vout,uint8_t rmd160[20],int64_t value) +{ + if ( strcmp("BTC",coin->symbol) == 0 ) + datachain_update_txidvout(myinfo,ordered,coin,&myinfo->dPoW.BTC,DATACHAIN_ISBTC,height,txid,vout,rmd160,value); + else if ( strcmp("BTCD",coin->symbol) == 0 ) + datachain_update_txidvout(myinfo,ordered,coin,&myinfo->dPoW.BTCD,DATACHAIN_ISKOMODO,height,txid,vout,rmd160,value); + else datachain_update_txidvout(myinfo,ordered,coin,&coin->dPoW,0,height,txid,vout,rmd160,value); +} + +int64_t datachain_update(struct supernet_info *myinfo,int32_t ordered,struct iguana_info *coin,uint32_t timestamp,struct iguana_bundle *bp,uint8_t rmd160[20],int64_t crypto777_payment,uint8_t type,int32_t height,uint64_t hdrsi_unspentind,int64_t value,uint32_t fileid,uint64_t scriptpos,int32_t scriptlen,bits256 txid,int32_t vout) +{ + if ( memcmp(rmd160,CRYPTO777_RMD160,20) == 0 ) + { + crypto777_payment += value; + printf("datachain_update crypto777 %.8f += %.8f\n",dstr(crypto777_payment),dstr(value)); + } + else if ( crypto777_payment != 0 && (type == IGUANA_SCRIPT_OPRETURN || type == IGUANA_SCRIPT_3of3 || type == IGUANA_SCRIPT_2of2 || type == IGUANA_SCRIPT_1of1) ) + { + printf("datachain_update opreturn\n"); + iguana_opreturn(myinfo,ordered,coin,timestamp,bp,crypto777_payment,height,hdrsi_unspentind,value,fileid,scriptpos,scriptlen); + } else datachain_update_spend(myinfo,ordered,coin,timestamp,bp,height,txid,vout,rmd160,value); + return(crypto777_payment); +} diff --git a/datachain/datachain.h b/datachain/datachain.h new file mode 100755 index 000000000..d44732f98 --- /dev/null +++ b/datachain/datachain.h @@ -0,0 +1,119 @@ +/****************************************************************************** + * Copyright © 2014-2016 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#ifndef H_DATACHAIN_H +#define H_DATACHAIN_H + +// Mutually Exclusive - first one to get this value is the only one that can get it, subsequent requests get rejected, unless it is from the original creator of the specific data item + +// Majority (threshold) vote - anybody can submit, but until the required thresholds are met there is no valid value + +// Auction and reverse auction - anybody can submit, everybody sees the highest (lowest) value + +// Random - value is a random value, but all nodes get the same value, useful for lottery type of use cases + +// MofN - shamir's shared secret + +// Pegged - values can be derived from external data feeds and pegged to a moving average + +// Averaged - value is a determistically chosen value that is close to the majority of other values in the time period. it is not a true mathematical average, but over time will be very close to the average. The advantage is that submission of bogus values wont affect things much. + +// Orderbook - price and volume are combined for bids and asks, Orderbook is constructed from auction (bid) and reverse auction (ask) + +// Oneshot (limited triggers) - defined value can only happen the specified number of times, then the data field is expired + +// Derived - value is derived from a combination of other values using a standard set of operations. For binary evaluation, values above 0 are treated as true, below zero as false and 0 means undefined. If any value a derived field depends on is undefined, then it also is undefined. + +// Scripts - turing complete scripts can be specified in C, that will have access to all the data fields and be able to do standard transactions and invoke any of the other derived data types. + +#define DATACHAIN_TYPE_BALANCE 1 +#define DATACHAIN_TYPE_DEPOSIT 2 +#define DATACHAIN_TYPE_PAYMENT 3 +#define DATACHAIN_TYPE_GROUP 4 +#define DATACHAIN_TYPE_QUOTE 5 + +#define DATACHAIN_TYPE_EXCLUSIVE 10 +#define DATACHAIN_TYPE_MAJORITY 11 +#define DATACHAIN_TYPE_AUCTION 12 +#define DATACHAIN_TYPE_REVAUCTION 13 + +#define DATACHAIN_TYPE_RANDOM 20 +#define DATACHAIN_TYPE_MOFN 21 +#define DATACHAIN_TYPE_PEGGED 22 + +#define DATACHAIN_TYPE_AVERAGED 100 +#define DATACHAIN_TYPE_ORDERBOOK 101 +#define DATACHAIN_TYPE_DERIVED 102 + +#define DATACHAIN_TYPE_TRIGGER 200 + +#define DATACHAIN_TYPE_TURING 1000 +#define DATACHAIN_TYPE_GATEWAY 1001 + +#define DATACHAIN_ACTION_SWAP 10000 +#define DATACHAIN_ACTION_PAY 10001 +#define DATACHAIN_ACTION_BID 10002 +#define DATACHAIN_ACTION_ASK 10003 +#define DATACHAIN_ACTION_QUOTE 10004 +#define DATACHAIN_ACTION_SENDGROUP 10005 + +#define DATACHAIN_ISBTC 1 +#define DATACHAIN_ISKOMODO 2 + +struct datachain_itemexclusive { uint8_t ownerpub[33]; }; + +struct datachain_item +{ + struct iguana_info *coin; + uint64_t value; + int32_t firstheight; + uint32_t expiration; // expires first time BTCD block timestamp exceeds expiration + uint16_t type,scaling,minconfirms; + char label[32]; + uint8_t rmd160[20]; + uint8_t itemdata[]; +}; + +struct datachain_event +{ + uint64_t hdrsi_unspentind,crypto777_payment,burned; + int32_t height,btc_or_btcd,oplen; + char symbol[16]; + uint8_t opreturn[]; +}; + +struct datachain_state +{ + int32_t numprocessed,lasthdrsi,lastunspentind; +}; + +struct datachain_info +{ + struct datachain_state state; + uint32_t numevents,maxevents,ordered; + struct datachain_event **events; +}; + +struct delayedPoW_info +{ + //struct gecko_sequences SEQ; + struct datachain_info BTC,BTCD; +}; + +int32_t datachain_datascript(struct iguana_info *coin,uint8_t *script,uint8_t *data,int32_t datalen); +int32_t datachain_opreturnscript(struct iguana_info *coin,uint8_t *script,char *datastr,int32_t datalen); +int32_t datachain_opreturn_create(uint8_t *serialized,char *symbol,char *name,char *coinaddr,int64_t PoSvalue,uint32_t nBits,uint16_t blocktime,uint16_t port,uint8_t p2shval,uint8_t wifval); + +#endif diff --git a/datachain/datachain_BTC.c b/datachain/datachain_BTC.c new file mode 100755 index 000000000..0e05d796a --- /dev/null +++ b/datachain/datachain_BTC.c @@ -0,0 +1,22 @@ +/****************************************************************************** + * Copyright © 2014-2016 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +// included from datachain.c + +void datachain_events_processBTC(struct supernet_info *myinfo,struct datachain_info *dPoW,struct datachain_event *event) +{ + +} + diff --git a/datachain/datachain_KOMODO.c b/datachain/datachain_KOMODO.c new file mode 100755 index 000000000..d9beb46a5 --- /dev/null +++ b/datachain/datachain_KOMODO.c @@ -0,0 +1,195 @@ +/****************************************************************************** + * Copyright © 2014-2016 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +// included from datachain.c + +int32_t datachain_rwgenesis(int32_t rwflag,uint8_t *serialized,struct gecko_genesis_opreturn *opret) +{ + int32_t len = 0; + if ( rwflag == 0 ) + { + memcpy(opret->type,&serialized[len],sizeof(opret->type)), len += sizeof(opret->type); + memcpy(opret->symbol,&serialized[len],sizeof(opret->symbol)), len += sizeof(opret->symbol); + memcpy(opret->name,&serialized[len],sizeof(opret->name)), len += sizeof(opret->name); + } + else + { + memcpy(&serialized[len],opret->type,sizeof(opret->type)), len += sizeof(opret->type); + memcpy(&serialized[len],opret->symbol,sizeof(opret->symbol)), len += sizeof(opret->symbol); + memcpy(&serialized[len],opret->name,sizeof(opret->name)), len += sizeof(opret->name); + } + len += iguana_rwnum(rwflag,&serialized[len],sizeof(opret->PoSvalue),&opret->PoSvalue); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(opret->netmagic),&opret->netmagic); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(opret->timestamp),&opret->timestamp); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(opret->nBits),&opret->nBits); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(opret->nonce),&opret->nonce); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(opret->blocktime),&opret->blocktime); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(opret->port),&opret->port); + if ( rwflag == 0 ) + { + opret->version = serialized[len++]; + opret->pubval = serialized[len++]; + opret->p2shval = serialized[len++]; + opret->wifval = serialized[len++]; + memcpy(opret->rmd160,&serialized[len],20), len += 20; + } + else + { + serialized[len++] = opret->version; + serialized[len++] = opret->pubval; + serialized[len++] = opret->p2shval; + serialized[len++] = opret->wifval; + memcpy(&serialized[len],opret->rmd160,20), len += 20; + } + //printf("opreturn len.%d\n",len); + return(len); +} + +bits256 datachain_opreturn_convert(uint8_t *txidbytes,int32_t *txlenp,struct iguana_msgblock *msg,struct gecko_genesis_opreturn *opret) +{ + bits256 txid,zero; int32_t minerpaymentlen=0; uint8_t minerpayment[512]; char coinbasestr[128],name[64],symbol[64]; + if ( opret->PoSvalue > 0 ) + minerpaymentlen = bitcoin_standardspend(minerpayment,0,opret->rmd160); + memset(zero.bytes,0,sizeof(zero)); + memset(symbol,0,sizeof(symbol)), memcpy(symbol,opret->symbol,sizeof(opret->symbol)); + memset(name,0,sizeof(name)), memcpy(name,opret->name,sizeof(opret->name)); + sprintf(coinbasestr,"%s_%s",symbol,name); + *txlenp = iguana_coinbase(1,GECKO_DEFAULTVERSION,txidbytes,opret->timestamp,zero,(uint8_t *)coinbasestr,(int32_t)strlen(coinbasestr)+1,minerpayment,minerpaymentlen,opret->PoSvalue,&txid); + memset(msg,0,sizeof(*msg)); + msg->H.version = opret->version; + msg->H.merkle_root = txid; + msg->H.timestamp = opret->timestamp; + msg->H.bits = opret->nBits; + msg->H.nonce = opret->nonce; + return(txid); +} + +int32_t datachain_genesis_verify(struct gecko_genesis_opreturn *opret) +{ + int32_t txlen,datalen; bits256 txid,threshold,hash2; uint8_t serialized[1024],txidbytes[1024]; struct iguana_msgblock msg; char str[65],str2[65]; + txid = datachain_opreturn_convert(txidbytes,&txlen,&msg,opret); + if ( opret->nBits >= GECKO_EASIESTDIFF ) + threshold = bits256_from_compact(GECKO_EASIESTDIFF); + else threshold = bits256_from_compact(opret->nBits); + datalen = iguana_rwblockhdr(1,0,serialized,&msg); + hash2 = iguana_calcblockhash("virtual",blockhash_sha256,serialized,datalen); + //for (i=0; i 0 ) + { + //printf(" valid blockhash!\n"); + return(0); + } + else + { + printf(" ERROR invalid blockhash! txid.%s %s\n",bits256_str(str2,txid),bits256_str(str,hash2)); + return(-1); + } +} + +int32_t datachain_opreturn_create(uint8_t *serialized,char *symbol,char *name,char *coinaddr,int64_t PoSvalue,uint32_t nBits,uint16_t blocktime,uint16_t port,uint8_t p2shval,uint8_t wifval) +{ + int32_t i,len,datalen,txlen; struct gecko_genesis_opreturn opret; bits256 threshold,txid,hash2; struct iguana_info *btcd; struct iguana_msgblock msg; uint8_t txidbytes[1024]; + btcd = iguana_coinfind("BTCD"); + memset(&opret,0,sizeof(opret)); + opret.type[0] = 'N', opret.type[1] = 'E', opret.type[2] = 'W'; + memcpy(opret.symbol,symbol,sizeof(opret.symbol)); + memcpy(opret.name,name,sizeof(opret.name)); + opret.version = GECKO_DEFAULTVERSION; + opret.PoSvalue = PoSvalue; + opret.nBits = nBits; + opret.p2shval = p2shval; + opret.wifval = wifval; + opret.blocktime = blocktime; + opret.port = port; + opret.timestamp = (uint32_t)time(NULL); + OS_randombytes((void *)&opret.netmagic,sizeof(opret.netmagic)); + bitcoin_addr2rmd160(&opret.pubval,opret.rmd160,coinaddr); + txid = datachain_opreturn_convert(txidbytes,&txlen,&msg,&opret); + if ( nBits >= GECKO_EASIESTDIFF ) + threshold = bits256_from_compact(GECKO_EASIESTDIFF); + else threshold = bits256_from_compact(nBits); + for (i=0; i<100000000; i++) + { + opret.nonce = msg.H.nonce = i; + datalen = iguana_rwblockhdr(1,0,serialized,&msg); + hash2 = iguana_calcblockhash(symbol,btcd->chain->hashalgo,serialized,datalen); + if ( bits256_cmp(threshold,hash2) > 0 ) + break; + } + //char str[65],str2[65]; + //for (i=0; iopreturn,"NEW",3) == 0 ) + { + //int32_t i; for (i=0; i<76; i++) + // printf("%02x",event->opreturn[i]); + //printf(" <- event\n"); + if ( (len= datachain_rwgenesis(0,event->opreturn,&opret)) <= event->oplen ) + { + datachain_genesis_verify(&opret); + memset(symbol,0,sizeof(symbol)), memcpy(symbol,opret.symbol,sizeof(opret.symbol)); + memset(name,0,sizeof(name)), memcpy(name,opret.name,sizeof(opret.name)); + hash2 = datachain_opreturn_convert(txidbytes,&txlen,&msg,&opret); + if ( opret.nBits >= GECKO_EASIESTDIFF ) + threshold = bits256_from_compact(GECKO_EASIESTDIFF); + else threshold = bits256_from_compact(opret.nBits); + msg.txn_count = 1; + //n = iguana_serialize_block(virt->chain,&hash2,serialized,newblock); + datalen = iguana_rwblockhdr(1,0,serialized,&msg); + hash2 = iguana_calcblockhash(symbol,btcd->chain->hashalgo,serialized,datalen); + for (i=0; i 0 ) + { + bitcoin_address(issuer,60,opret.rmd160,20); + bits256_str(hashstr,hash2); + for (j=0,i=3; i>=0; i--,j++) + buf[i] = (opret.netmagic >> (j*8)); + init_hexbytes_noT(magicstr,buf,4); + for (j=0,i=3; i>=0; i--,j++) + buf[i] = (opret.nBits >> (j*8)); + init_hexbytes_noT(nbitstr,buf,4); + init_hexbytes_noT(blockstr,serialized,datalen); + strcat(blockstr,"01"), datalen++; + init_hexbytes_noT(&blockstr[datalen << 1],txidbytes,txlen); + sprintf(argbuf,"{\"name\":\"%s\",\"symbol\":\"%s\",\"netmagic\":\"%s\",\"port\":%u,\"blocktime\":%u,\"pubval\":\"%02x\",\"p2shval\":\"%02x\",\"wifval\":\"%02x\",\"unitval\":\"%02x\",\"genesishash\":\"%s\",\"genesis\":{\"version\":1,\"timestamp\":%u,\"nBits\":\"%s\",\"nonce\":%d,\"merkle_root\":\"%s\"},\"genesisblock\":\"%s\"}",name,symbol,magicstr,opret.port,opret.blocktime,opret.pubval,opret.p2shval,opret.wifval,(opret.nBits >> 24) & 0xff,hashstr,opret.timestamp,nbitstr,opret.nonce,bits256_str(str2,msg.H.merkle_root),blockstr); + if ( (valsobj= cJSON_Parse(argbuf)) != 0 ) + { + printf("datachain.NEW (%s/%s port.%u blocktime.%d) issuer.%s (%s)\n",opret.symbol,opret.name,opret.port,opret.blocktime,issuer,jprint(valsobj,0)); + if ( (chain= gecko_chain(myinfo,chainname,valsobj)) != 0 && (virt= chain->info) != 0 ) + printf("duplicate chain.%s rejected\n",opret.symbol); + else if ( (virt= basilisk_geckochain(myinfo,symbol,chainname,valsobj)) != 0 ) + chain->info = virt; + free_json(valsobj); + } + } else printf("failed PoW test for genesis.%s\n",opret.symbol); + } else printf("opret unexpected len.%d vs %d\n",len,event->oplen); + } +} diff --git a/datachain/datachain_events.c b/datachain/datachain_events.c new file mode 100755 index 000000000..b6e2105d2 --- /dev/null +++ b/datachain/datachain_events.c @@ -0,0 +1,174 @@ +/****************************************************************************** + * Copyright © 2014-2016 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +// included from datachain.c +#include "datachain_KOMODO.c" +#include "datachain_BTC.c" + +void datachain_events_process_virt(struct supernet_info *myinfo,struct datachain_info *dPoW,struct datachain_event *event) +{ + +} + +int _increasing_events(const void *a,const void *b) +{ +#define uint64_a (*(struct datachain_event **)a)->hdrsi_unspentind +#define uint64_b (*(struct datachain_event **)b)->hdrsi_unspentind + if ( uint64_b > uint64_a ) + return(-1); + else if ( uint64_b < uint64_a ) + return(1); + return(0); +#undef uint64_a +#undef uint64_b +} + +void datachain_events_sort(struct datachain_info *dPoW) +{ + if ( dPoW->numevents > 0 ) + { + qsort(dPoW->events,dPoW->numevents,sizeof(dPoW->events),_increasing_events); + printf("sorted %d events\n",dPoW->numevents); + } +} + +struct datachain_event *datachain_event_create(struct iguana_info *coin,int64_t crypto777_payment,int64_t burned,int32_t height,uint32_t hdrsi,uint32_t unspentind,uint8_t *opreturn,int32_t oplen) +{ + struct datachain_event *event; + event = calloc(1,sizeof(*event) + oplen); + event->hdrsi_unspentind = ((uint64_t)hdrsi << 32) | unspentind; + event->crypto777_payment = crypto777_payment; + event->burned = burned; + event->height = height; + safecopy(event->symbol,coin->symbol,sizeof(event->symbol)); + if ( strcmp(event->symbol,"BTC") == 0 ) + event->btc_or_btcd = DATACHAIN_ISBTC; + else if ( strcmp(event->symbol,"BTCD") == 0 ) + event->btc_or_btcd = DATACHAIN_ISKOMODO; + event->oplen = oplen; + memcpy(event->opreturn,opreturn,oplen); + return(event); +} + +void datachain_events_process(struct supernet_info *myinfo,int32_t btc_or_btcd,struct datachain_info *dPoW,int32_t firsti,int32_t lasti) +{ + int32_t i; struct datachain_event *event; + if ( firsti >= 0 && lasti <= dPoW->numevents ) + { + for (i=0; i<=lasti; i++) + if ( (event= dPoW->events[i]) != 0 ) + { + if ( btc_or_btcd == DATACHAIN_ISBTC ) + datachain_events_processBTC(myinfo,dPoW,event); + else if ( btc_or_btcd == DATACHAIN_ISKOMODO ) + datachain_events_processKOMODO(myinfo,dPoW,event); + else datachain_events_process_virt(myinfo,dPoW,event); + dPoW->state.numprocessed++; + } + } else printf("illegal datachain_events_process.[%d, %d] numevents.%d\n",firsti,lasti,dPoW->numevents); +} + +void datachain_state_reset(struct supernet_info *myinfo,int32_t btc_or_btcd,struct datachain_info *dPoW) +{ + struct datachain_state *state = &dPoW->state; + memset(state,0,sizeof(*state)); +} + +void datachain_reset(struct supernet_info *myinfo,int32_t btc_or_btcd,struct datachain_info *dPoW) +{ + struct iguana_info *virt,*tmp; + if ( btc_or_btcd == DATACHAIN_ISBTC ) // all needs to be reset on BTC reorg + datachain_reset(myinfo,DATACHAIN_ISKOMODO,&myinfo->dPoW.BTCD); + else if ( btc_or_btcd == DATACHAIN_ISKOMODO ) + { + HASH_ITER(hh,myinfo->allcoins,virt,tmp) + { + if ( virt->started != 0 && virt->active != 0 && virt->virtualchain != 0 ) + datachain_reset(myinfo,0,&virt->dPoW); + } + } + datachain_events_sort(dPoW); + datachain_state_reset(myinfo,btc_or_btcd,dPoW); +} + +int32_t datachain_eventadd(struct supernet_info *myinfo,int32_t ordered,struct datachain_info *dPoW,int32_t btc_or_btcd,struct datachain_event *event) +{ + uint64_t hdrsi_unspentind; int32_t retval = 0; + if ( ordered != 0 ) + { + if ( dPoW->ordered == 0 ) + datachain_events_sort(dPoW); + } else dPoW->ordered = 0; + hdrsi_unspentind = ((uint64_t)dPoW->state.lasthdrsi << 32) | dPoW->state.lastunspentind; + if ( ordered != 0 ) + { + if ( dPoW->ordered != dPoW->numevents ) + { + printf("trigger reset and process.%d ordered.%d numevents.%d\n",btc_or_btcd,dPoW->ordered,dPoW->numevents); + datachain_reset(myinfo,btc_or_btcd,dPoW); + if ( dPoW->numevents > 0 ) + datachain_events_process(myinfo,btc_or_btcd,dPoW,0,dPoW->numevents-1); + if ( btc_or_btcd == DATACHAIN_ISBTC ) // all needs to be reprocessed on BTC reorg + { + if ( myinfo->dPoW.BTCD.numevents > 0 ) + datachain_events_process(myinfo,DATACHAIN_ISKOMODO,&myinfo->dPoW.BTCD,0,myinfo->dPoW.BTCD.numevents - 1); + } + else if ( btc_or_btcd == DATACHAIN_ISKOMODO ) + { + struct iguana_info *virt,*tmp; + HASH_ITER(hh,myinfo->allcoins,virt,tmp) + { + if ( virt->started != 0 && virt->active != 0 && virt->virtualchain != 0 ) + if ( virt->dPoW.numevents > 0 ) + datachain_events_process(myinfo,0,&virt->dPoW,0,virt->dPoW.numevents-1); + } + } + dPoW->ordered = dPoW->numevents; + } + } + if ( event != 0 ) + { + if ( dPoW->numevents >= dPoW->maxevents ) + { + dPoW->maxevents += 1024; + dPoW->events = realloc(dPoW->events,sizeof(*dPoW->events) * dPoW->maxevents); + } + if ( event->hdrsi_unspentind > hdrsi_unspentind ) + { + dPoW->state.lasthdrsi = (uint32_t)(event->hdrsi_unspentind >> 32); + dPoW->state.lastunspentind = (uint32_t)event->hdrsi_unspentind; + retval = 1; + } + if ( ordered != 0 ) + { + if ( retval != 1 && dPoW->ordered != 0 ) + { + printf("datachain_eventadd unexpected ordered event that is not at the end\n"); + retval = -1; + } + dPoW->events[dPoW->numevents] = event; + if ( dPoW->ordered == dPoW->numevents ) + datachain_events_process(myinfo,btc_or_btcd,dPoW,dPoW->numevents,dPoW->numevents); + dPoW->numevents++; + dPoW->ordered = dPoW->numevents; + } else dPoW->events[dPoW->numevents++] = event; + } + return(dPoW->numevents); +} + +void datachain_update_txidvout(struct supernet_info *myinfo,int32_t ordered,struct iguana_info *coin,struct datachain_info *dPoW,int32_t btc_or_btcd,int32_t spentheight,bits256 txid,int32_t vout,uint8_t rmd160[20],int64_t value) +{ + // MGW via deposit events +} diff --git a/InstantDEX/InstantDEX.c b/deprecated/InstantDEX/InstantDEX.c similarity index 100% rename from InstantDEX/InstantDEX.c rename to deprecated/InstantDEX/InstantDEX.c diff --git a/InstantDEX/InstantDEX_quote.h b/deprecated/InstantDEX/InstantDEX_quote.h similarity index 100% rename from InstantDEX/InstantDEX_quote.h rename to deprecated/InstantDEX/InstantDEX_quote.h diff --git a/InstantDEX/exchange_trades.h b/deprecated/InstantDEX/exchange_trades.h similarity index 100% rename from InstantDEX/exchange_trades.h rename to deprecated/InstantDEX/exchange_trades.h diff --git a/InstantDEX/exchangeparse.h b/deprecated/InstantDEX/exchangeparse.h similarity index 100% rename from InstantDEX/exchangeparse.h rename to deprecated/InstantDEX/exchangeparse.h diff --git a/iguana/InstantDEX/prices777.c b/deprecated/InstantDEX/prices777.c similarity index 100% rename from iguana/InstantDEX/prices777.c rename to deprecated/InstantDEX/prices777.c diff --git a/InstantDEX/quotes.h b/deprecated/InstantDEX/quotes.h similarity index 100% rename from InstantDEX/quotes.h rename to deprecated/InstantDEX/quotes.h diff --git a/iguana/InstantDEX/quotes777.c b/deprecated/InstantDEX/quotes777.c similarity index 100% rename from iguana/InstantDEX/quotes777.c rename to deprecated/InstantDEX/quotes777.c diff --git a/InstantDEX/subatomic.h b/deprecated/InstantDEX/subatomic.h similarity index 100% rename from InstantDEX/subatomic.h rename to deprecated/InstantDEX/subatomic.h diff --git a/InstantDEX/tradebots.h b/deprecated/InstantDEX/tradebots.h similarity index 100% rename from InstantDEX/tradebots.h rename to deprecated/InstantDEX/tradebots.h diff --git a/InstantDEX/trades.h b/deprecated/InstantDEX/trades.h similarity index 100% rename from InstantDEX/trades.h rename to deprecated/InstantDEX/trades.h diff --git a/iguana/InstantDEX/InstantDEX.c b/deprecated/InstantDEX2/InstantDEX.c similarity index 100% rename from iguana/InstantDEX/InstantDEX.c rename to deprecated/InstantDEX2/InstantDEX.c diff --git a/iguana/InstantDEX/InstantDEX_quote.h b/deprecated/InstantDEX2/InstantDEX_quote.h similarity index 100% rename from iguana/InstantDEX/InstantDEX_quote.h rename to deprecated/InstantDEX2/InstantDEX_quote.h diff --git a/InstantDEX/Makefile b/deprecated/InstantDEX2/Makefile similarity index 100% rename from InstantDEX/Makefile rename to deprecated/InstantDEX2/Makefile diff --git a/iguana/InstantDEX/exchange_trades.h b/deprecated/InstantDEX2/exchange_trades.h similarity index 100% rename from iguana/InstantDEX/exchange_trades.h rename to deprecated/InstantDEX2/exchange_trades.h diff --git a/iguana/InstantDEX/exchangeparse.h b/deprecated/InstantDEX2/exchangeparse.h similarity index 100% rename from iguana/InstantDEX/exchangeparse.h rename to deprecated/InstantDEX2/exchangeparse.h diff --git a/InstantDEX/exchanges/bitfinex.c b/deprecated/InstantDEX2/exchanges/bitfinex.c similarity index 100% rename from InstantDEX/exchanges/bitfinex.c rename to deprecated/InstantDEX2/exchanges/bitfinex.c diff --git a/InstantDEX/exchanges/bitstamp.c b/deprecated/InstantDEX2/exchanges/bitstamp.c similarity index 100% rename from InstantDEX/exchanges/bitstamp.c rename to deprecated/InstantDEX2/exchanges/bitstamp.c diff --git a/InstantDEX/exchanges/bittrex.c b/deprecated/InstantDEX2/exchanges/bittrex.c similarity index 100% rename from InstantDEX/exchanges/bittrex.c rename to deprecated/InstantDEX2/exchanges/bittrex.c diff --git a/InstantDEX/exchanges/btc38.c b/deprecated/InstantDEX2/exchanges/btc38.c similarity index 100% rename from InstantDEX/exchanges/btc38.c rename to deprecated/InstantDEX2/exchanges/btc38.c diff --git a/InstantDEX/exchanges/btce.c b/deprecated/InstantDEX2/exchanges/btce.c similarity index 100% rename from InstantDEX/exchanges/btce.c rename to deprecated/InstantDEX2/exchanges/btce.c diff --git a/InstantDEX/exchanges/checkbalance.c b/deprecated/InstantDEX2/exchanges/checkbalance.c similarity index 100% rename from InstantDEX/exchanges/checkbalance.c rename to deprecated/InstantDEX2/exchanges/checkbalance.c diff --git a/InstantDEX/exchanges/coinbase.c b/deprecated/InstantDEX2/exchanges/coinbase.c similarity index 100% rename from InstantDEX/exchanges/coinbase.c rename to deprecated/InstantDEX2/exchanges/coinbase.c diff --git a/InstantDEX/exchanges/huobi.c b/deprecated/InstantDEX2/exchanges/huobi.c similarity index 100% rename from InstantDEX/exchanges/huobi.c rename to deprecated/InstantDEX2/exchanges/huobi.c diff --git a/InstantDEX/exchanges/lakebtc.c b/deprecated/InstantDEX2/exchanges/lakebtc.c similarity index 100% rename from InstantDEX/exchanges/lakebtc.c rename to deprecated/InstantDEX2/exchanges/lakebtc.c diff --git a/InstantDEX/exchanges/okcoin.c b/deprecated/InstantDEX2/exchanges/okcoin.c similarity index 100% rename from InstantDEX/exchanges/okcoin.c rename to deprecated/InstantDEX2/exchanges/okcoin.c diff --git a/InstantDEX/exchanges/poloniex.c b/deprecated/InstantDEX2/exchanges/poloniex.c similarity index 100% rename from InstantDEX/exchanges/poloniex.c rename to deprecated/InstantDEX2/exchanges/poloniex.c diff --git a/InstantDEX/exchanges/quadriga.c b/deprecated/InstantDEX2/exchanges/quadriga.c similarity index 100% rename from InstantDEX/exchanges/quadriga.c rename to deprecated/InstantDEX2/exchanges/quadriga.c diff --git a/InstantDEX/index.html b/deprecated/InstantDEX2/index.html similarity index 100% rename from InstantDEX/index.html rename to deprecated/InstantDEX2/index.html diff --git a/InstantDEX/m_clean b/deprecated/InstantDEX2/m_clean similarity index 100% rename from InstantDEX/m_clean rename to deprecated/InstantDEX2/m_clean diff --git a/InstantDEX/m_pnacl b/deprecated/InstantDEX2/m_pnacl similarity index 100% rename from InstantDEX/m_pnacl rename to deprecated/InstantDEX2/m_pnacl diff --git a/InstantDEX/main.c b/deprecated/InstantDEX2/main.c similarity index 100% rename from InstantDEX/main.c rename to deprecated/InstantDEX2/main.c diff --git a/InstantDEX/manifest.json b/deprecated/InstantDEX2/manifest.json similarity index 100% rename from InstantDEX/manifest.json rename to deprecated/InstantDEX2/manifest.json diff --git a/InstantDEX/orderbooks.h b/deprecated/InstantDEX2/orderbooks.h similarity index 100% rename from InstantDEX/orderbooks.h rename to deprecated/InstantDEX2/orderbooks.h diff --git a/iguana/InstantDEX/quotes.h b/deprecated/InstantDEX2/quotes.h similarity index 100% rename from iguana/InstantDEX/quotes.h rename to deprecated/InstantDEX2/quotes.h diff --git a/iguana/InstantDEX/subatomic.h b/deprecated/InstantDEX2/subatomic.h similarity index 100% rename from iguana/InstantDEX/subatomic.h rename to deprecated/InstantDEX2/subatomic.h diff --git a/iguana/InstantDEX/tradebots.h b/deprecated/InstantDEX2/tradebots.h similarity index 100% rename from iguana/InstantDEX/tradebots.h rename to deprecated/InstantDEX2/tradebots.h diff --git a/iguana/InstantDEX/trades.h b/deprecated/InstantDEX2/trades.h similarity index 100% rename from iguana/InstantDEX/trades.h rename to deprecated/InstantDEX2/trades.h diff --git a/deprecated/SuperNET.c b/deprecated/SuperNET.c index ded022edf..138c6679a 100755 --- a/deprecated/SuperNET.c +++ b/deprecated/SuperNET.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2015 The SuperNET Developers. * + * Copyright © 2014-2016 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -13,495 +13,1542 @@ * * ******************************************************************************/ +#include "iguana777.h" +#include "../includes/tweetnacl.h" #include "../crypto777/OS_portable.h" -#include "SuperNET.h" - -void SuperNET_rpcloop(void *args) -{ - struct supernet_info *myinfo = args; - int32_t recvlen,bindsock,postflag,sock,remains,jsonflag,numsent,len; socklen_t clilen; - char remoteaddr[64],jsonbuf[8192],*buf,*retstr,*space;//,*retbuf; ,n,i,m - struct sockaddr_in cli_addr; uint32_t ipbits,i; uint16_t port; - int32_t size = 1024 * 1024 * 2; - port = SUPERNET_PORT; - bindsock = iguana_socket(1,"127.0.0.1",port); - printf("SuperNET_rpcloop 127.0.0.1:%d bind sock.%d\n",port,bindsock); - space = calloc(1,size); - while ( bindsock >= 0 ) - { - clilen = sizeof(cli_addr); - //printf("ACCEPT (%s:%d) on sock.%d\n","127.0.0.1",port,bindsock); - sock = accept(bindsock,(struct sockaddr *)&cli_addr,&clilen); - if ( sock < 0 ) - { - //printf("iguana_rpcloop ERROR on accept usock.%d\n",sock); - continue; +#include "../includes/libgfshare.h" +#include "../includes/utlist.h" +#include "../includes/uthash.h" +#include "../includes/curve25519.h" +#include "../includes/cJSON.h" + +#ifdef oldway + +cJSON *SuperNET_argjson(cJSON *json) +{ + cJSON *argjson = jduplicate(json); + jdelete(argjson,"agent"); + jdelete(argjson,"method"); + jdelete(argjson,"categoryhash"); + jdelete(argjson,"subhash"); + jdelete(argjson,"mypub"); + jdelete(argjson,"hexmsg"); + jdelete(argjson,"plaintext"); + jdelete(argjson,"broadcast"); + jdelete(argjson,"ov"); + jdelete(argjson,"check"); + jdelete(argjson,"yourip"); + jdelete(argjson,"myip"); + jdelete(argjson,"myipaddr"); + return(argjson); +} + +bits256 SuperNET_sharedseed(bits256 privkey,bits256 otherpub) +{ + bits256 seed2,seed; + seed = curve25519_shared(privkey,otherpub); + vcalc_sha256(0,seed2.bytes,seed.bytes,sizeof(bits256)); + return(seed2); +} + +int32_t SuperNET_delaymillis(struct supernet_info *myinfo,int32_t maxdelay) +{ + maxdelay += myinfo->maxdelay; + if ( maxdelay > SUPERNET_MAXDELAY ) + maxdelay = SUPERNET_MAXDELAY; + if ( maxdelay == 0 ) + return(0); + return(rand() % maxdelay); +} + +void SuperNET_remotepeer(struct supernet_info *myinfo,struct iguana_info *coin,char *symbol,char *ipaddr,int32_t supernetflag) +{ + uint64_t ipbits; struct iguana_peer *addr; + ipbits = calc_ipbits(ipaddr); + printf("got %s remotepeer.(%s) supernet.%d\n",symbol,ipaddr,supernetflag); + if ( supernetflag != 0 && (uint32_t)myinfo->myaddr.selfipbits != (uint32_t)ipbits ) + { + if ( (addr= iguana_peerslot(coin,ipbits,0)) != 0 ) + { + printf("launch startconnection to supernet peer.(%s)\n",ipaddr); + iguana_launch(coin,"connection",iguana_startconnection,addr,IGUANA_CONNTHREAD); + return; } - memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); - expand_ipbits(remoteaddr,ipbits); - memset(jsonbuf,0,sizeof(jsonbuf)); - remains = (int32_t)(sizeof(jsonbuf) - 1); - buf = jsonbuf; - recvlen = 0; - retstr = 0; - while ( remains > 0 ) - { - if ( (len= (int32_t)recv(sock,buf,remains,0)) < 0 ) + } + iguana_possible_peer(coin,ipaddr); +} + +int32_t SuperNET_confirmip(struct supernet_info *myinfo,uint32_t ipbits) +{ + int32_t j,total = 0; uint32_t x; struct iguana_info *coin,*tmp; + //portable_mutex_lock(&Allcoins_mutex); + HASH_ITER(hh,myinfo->allcoins,coin,tmp) + { + for (j=0; jpeers->active[j].myipbits) != 0 ) { - if ( errno == EAGAIN ) - { - printf("EAGAIN for len %d, remains.%d\n",len,remains); - usleep(10000); - } - break; + if ( x == ipbits ) + total++; + else total--; + } + } + } + //portable_mutex_unlock(&Allcoins_mutex); + return(total); +} + +void SuperNET_checkipaddr(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,char *myipaddr,char *remoteaddr) +{ + uint32_t myipbits = (uint32_t)calc_ipbits(myipaddr); + if ( addr->myipbits == 0 ) + addr->myipbits = myipbits; + else if ( addr->myipbits != myipbits ) + { + printf("%s: myipaddr conflict %x != %x?\n",addr->ipaddr,addr->myipbits,myipbits); + addr->myipbits = 0; + } + if ( addr->myipbits != 0 && myinfo->myaddr.myipbits == 0 ) + myinfo->myaddr.myipbits = addr->myipbits; + if ( addr->myipbits == myinfo->myaddr.myipbits ) + myinfo->myaddr.confirmed++; + else myinfo->myaddr.confirmed--; + if ( (myinfo->myaddr.totalconfirmed= SuperNET_confirmip(myinfo,addr->myipbits)) >= coin->peers->numranked ) + myinfo->myaddr.selfipbits = addr->myipbits; + if ( myinfo->myaddr.selfipbits == myinfo->myaddr.myipbits ) + { + expand_ipbits(myinfo->ipaddr,myinfo->myaddr.selfipbits); + vcalc_sha256(0,myinfo->myaddr.iphash.bytes,(uint8_t *)&myinfo->myaddr.selfipbits,sizeof(myinfo->myaddr.selfipbits)); + } + if ( myinfo->ipaddr[0] == 0 || strcmp(myinfo->ipaddr,"127.0.0.1") == 0 ) + { + strcpy(myinfo->ipaddr,myipaddr); + } + //printf("myipaddr.%s self.%x your.%x\n",myinfo->ipaddr,myinfo->myaddr.selfipbits,myinfo->myaddr.myipbits); +} +#endif + +int32_t _SuperNET_cipher(uint8_t nonce[crypto_box_NONCEBYTES],uint8_t *cipher,uint8_t *message,int32_t len,bits256 destpub,bits256 srcpriv,uint8_t *buf) +{ + memset(cipher,0,len+crypto_box_ZEROBYTES); + memset(buf,0,crypto_box_ZEROBYTES); + memcpy(buf+crypto_box_ZEROBYTES,message,len); + crypto_box(cipher,buf,len+crypto_box_ZEROBYTES,nonce,destpub.bytes,srcpriv.bytes); + return(len + crypto_box_ZEROBYTES); +} + +uint8_t *_SuperNET_decipher(uint8_t nonce[crypto_box_NONCEBYTES],uint8_t *cipher,uint8_t *message,int32_t len,bits256 srcpub,bits256 mypriv) +{ + int32_t err; + if ( (err= crypto_box_open(message,cipher,len,nonce,srcpub.bytes,mypriv.bytes)) == 0 ) + { + message += crypto_box_ZEROBYTES; + len -= crypto_box_ZEROBYTES; + return(message); + } + return(0); +} + +void *SuperNET_deciphercalc(void **ptrp,int32_t *msglenp,bits256 privkey,bits256 srcpubkey,uint8_t *cipher,int32_t cipherlen,uint8_t *buf,int32_t bufsize) +{ + uint8_t *origptr,*nonce,*message; void *retptr; + if ( bits256_nonz(privkey) == 0 ) + privkey = GENESIS_PRIVKEY; + *ptrp = 0; + if ( cipherlen > bufsize ) + { + message = calloc(1,cipherlen); + *ptrp = (void *)message; + } + else message = buf; + origptr = cipher; + if ( bits256_nonz(srcpubkey) == 0 ) + { + memcpy(srcpubkey.bytes,cipher,sizeof(srcpubkey)); + char str[65]; printf("use attached pubkey.(%s)\n",bits256_str(str,srcpubkey)); + cipher += sizeof(srcpubkey); + cipherlen -= sizeof(srcpubkey); + } + nonce = cipher; + cipher += crypto_box_NONCEBYTES, cipherlen -= crypto_box_NONCEBYTES; + *msglenp = cipherlen - crypto_box_ZEROBYTES; + if ( (retptr= _SuperNET_decipher(nonce,cipher,message,cipherlen,srcpubkey,privkey)) == 0 ) + { + *msglenp = -1; + free(*ptrp); + } + return(retptr); +} + +uint8_t *SuperNET_ciphercalc(void **ptrp,int32_t *cipherlenp,bits256 *privkeyp,bits256 *destpubkeyp,uint8_t *data,int32_t datalen,uint8_t *space2,int32_t space2size) +{ + bits256 mypubkey; uint8_t *buf,*nonce,*cipher,*origptr,space[8192]; int32_t onetimeflag=0,allocsize; + *ptrp = 0; + allocsize = (datalen + crypto_box_NONCEBYTES + crypto_box_ZEROBYTES); + if ( bits256_nonz(*destpubkeyp) == 0 || memcmp(destpubkeyp->bytes,GENESIS_PUBKEY.bytes,sizeof(*destpubkeyp)) == 0 ) + { + *destpubkeyp = GENESIS_PUBKEY; + onetimeflag = 2; // prevent any possible leakage of privkey by encrypting to known destpub + } + if ( bits256_nonz(*privkeyp) == 0 ) + onetimeflag = 1; + if ( onetimeflag != 0 ) + { + crypto_box_keypair(mypubkey.bytes,privkeyp->bytes); + allocsize += sizeof(bits256); + } + if ( allocsize > sizeof(space) ) + buf = calloc(1,allocsize); + else buf = space; + if ( allocsize+sizeof(struct iguana_msghdr) > space2size ) + { + cipher = calloc(1,allocsize + sizeof(struct iguana_msghdr)); + *ptrp = (void *)cipher; + } else cipher = space2; + cipher = &cipher[sizeof(struct iguana_msghdr)]; + origptr = nonce = cipher; + if ( onetimeflag != 0 ) + { + memcpy(cipher,mypubkey.bytes,sizeof(mypubkey)); + nonce = &cipher[sizeof(mypubkey)]; + } + OS_randombytes(nonce,crypto_box_NONCEBYTES); + cipher = &nonce[crypto_box_NONCEBYTES]; + _SuperNET_cipher(nonce,cipher,(void *)data,datalen,*destpubkeyp,*privkeyp,buf); + if ( buf != space ) + free(buf); + *cipherlenp = allocsize; + return(origptr); +} + +#ifdef oldway +int32_t SuperNET_copybits(int32_t reverse,uint8_t *dest,uint8_t *src,int32_t len) +{ + int32_t i; uint8_t *tmp; + if ( reverse != 0 ) + { + tmp = dest; + dest = src; + src = tmp; + } + //printf("src.%p dest.%p len.%d\n",src,dest,len); + //for (i=0; i> 3); +} + +uint16_t SuperNET_checkc(bits256 privkey,bits256 otherpub,void *num,int32_t len) +{ + uint8_t buf[40]; bits256 check,seed,seed2; + seed = curve25519_shared(privkey,otherpub); + vcalc_sha256(0,seed2.bytes,seed.bytes,sizeof(seed)); + memcpy(buf,seed2.bytes,sizeof(seed)); + iguana_rwnum(1,&buf[sizeof(seed)],len,num); + vcalc_sha256(0,check.bytes,buf,(int32_t)sizeof(seed2)+len); + //printf("SuperNET_checkc otherpub.%llx + privkey.%llx -> %x\n",(long long)otherpub.txid,(long long)privkey.txid,check.ushorts[0]); + return(check.ushorts[0]); +} + +int32_t SuperNET_json2bits(uint8_t *serialized,int32_t maxsize,cJSON *json,bits256 mypub,uint16_t checkc,uint32_t myipbits,uint32_t destipbits,int32_t _othervalid) +{ + uint16_t apinum; bits256 categoryhash,subhash; uint32_t tmp,crc,timestamp; char *agent,*method; char *hexmsg; uint8_t broadcastflag; int8_t othervalid; int32_t n,len = sizeof(uint32_t); + if ( _othervalid > 100 ) + othervalid = 100; + else if ( _othervalid < -100 ) + othervalid = -100; + else othervalid = _othervalid; + tmp = juint(json,"broadcast"); + if ( tmp > SUPERNET_MAXHOPS ) + broadcastflag = SUPERNET_MAXHOPS; + else broadcastflag = tmp; + if ( juint(json,"request") != 0 ) + broadcastflag |= 0x10; + categoryhash = jbits256(json,"categoryhash"); + subhash = jbits256(json,"subhash"); + timestamp = juint(json,"timestamp"); + if ( bits256_nonz(categoryhash) > 0 && memcmp(categoryhash.bytes,GENESIS_PUBKEY.bytes,sizeof(categoryhash)) != 0 ) + { + broadcastflag |= 0x40; + if ( bits256_nonz(subhash) > 0 && memcmp(subhash.bytes,GENESIS_PUBKEY.bytes,sizeof(subhash)) != 0 ) + broadcastflag |= 0x20; + else subhash = GENESIS_PUBKEY; + if ( broadcastflag == 0 ) + broadcastflag = 1; + } + else + { + categoryhash = subhash = GENESIS_PUBKEY; + if ( broadcastflag == 0 ) + broadcastflag = 1; + } + if ( juint(json,"plaintext") != 0 ) + broadcastflag |= 0x80; + //if ( (tag= j64bits(json,"tag")) == 0 ) + // OS_randombytes((uint8_t *)&tag,sizeof(tag)); + agent = jstr(json,"agent"), method = jstr(json,"method"); + if ( agent != 0 && method != 0 && strcmp(agent,"SuperNET") == 0 && strcmp(method,"json2bits") == 0 ) + { + agent = jstr(json,"destagent"); + method = jstr(json,"destmethod"); + } + if ( (apinum= SuperNET_API2num(agent,method)) == 0xffff ) + { + printf("agent.(%s) method.(%s) is not found\n",agent,method); + return(-1); + } + len += iguana_rwnum(1,&serialized[len],sizeof(uint32_t),×tamp); + len += iguana_rwnum(1,&serialized[len],sizeof(uint32_t),&destipbits); + len += iguana_rwnum(1,&serialized[len],sizeof(uint32_t),&myipbits); + //printf("myipbits.%x destipbits.%x\n",myipbits,destipbits); + len += iguana_rwnum(1,&serialized[len],sizeof(checkc),&checkc); + len += iguana_rwnum(1,&serialized[len],sizeof(apinum),&apinum); + //len += iguana_rwnum(1,&serialized[len],sizeof(tag),&tag); + len += iguana_rwbignum(1,&serialized[len],sizeof(mypub),mypub.bytes); + len += iguana_rwnum(1,&serialized[len],sizeof(othervalid),&othervalid); + len += iguana_rwnum(1,&serialized[len],sizeof(broadcastflag),&broadcastflag); + if ( (broadcastflag & 0x40) != 0 ) + { + len += iguana_rwbignum(1,&serialized[len],sizeof(bits256),categoryhash.bytes); + if ( (broadcastflag & 0x20) != 0 ) + len += iguana_rwbignum(1,&serialized[len],sizeof(bits256),subhash.bytes); + } + //printf("broadcastflag.%x\n",broadcastflag); + if ( (hexmsg= jstr(json,"hexmsg")) != 0 ) + { + n = (int32_t)strlen(hexmsg); + if ( (n & 1) == 0 && is_hexstr(hexmsg,n) > 0 ) + { + n >>= 1; + decode_hex(&serialized[len],n,hexmsg); + len += n; + } else return(-1); + } + crc = calc_crc32(0,&serialized[sizeof(crc)],len - sizeof(crc)); + iguana_rwnum(1,serialized,sizeof(crc),&crc); + //int32_t i; for (i=0; i SUPERNET_MAXHOPS ) + broadcastflag = SUPERNET_MAXHOPS; + //printf("<<<<<<<<<<<<<<<< crc.%u ipbits.(%x %x) tag.%llx checkc.%x apinum.%d valid.%d other.%d broadcast.%d plaintext.%d\n",crc,destipbits,myipbits,(long long)tag,checkc,apinum,addr->validpub,othervalid,broadcastflag,plaintext); + if ( SuperNET_num2API(agent,method,apinum) >= 0 ) + { + jaddstr(json,"agent",agent); + jaddstr(json,"method",method); + if ( timestamp != 0 ) + jaddnum(json,"timestamp",timestamp); + if ( bits256_nonz(categoryhash) > 0 && memcmp(GENESIS_PUBKEY.bytes,categoryhash.bytes,sizeof(categoryhash)) != 0 ) + jaddbits256(json,"categoryhash",categoryhash); + if ( bits256_nonz(categoryhash) > 0 && memcmp(GENESIS_PUBKEY.bytes,subhash.bytes,sizeof(subhash)) != 0 ) + jaddbits256(json,"subhash",subhash); + expand_ipbits(destip,destipbits), jaddstr(json,"yourip",destip); + expand_ipbits(myipaddr,myipbits), jaddstr(json,"myip",myipaddr); + jaddstr(json,"mypub",bits256_str(str,senderpub)); + categoryhash = subhash = GENESIS_PUBKEY; + if ( (broadcastflag & 0x40) != 0 ) + { + jaddbits256(json,"categoryhash",categoryhash); + if ( (broadcastflag & 0x20) != 0 ) + jaddbits256(json,"subhash",subhash); + } + //jadd64bits(json,"tag",tag); + init_hexbytes_noT(checkstr,(void *)&checkc,sizeof(checkc)); + jaddstr(json,"check",checkstr); + jaddnum(json,"ov",othervalid); + if ( requestflag != 0 ) + jaddnum(json,"request",requestflag); + if ( plaintext != 0 ) + jaddnum(json,"plaintext",plaintext!=0); + if ( broadcastflag != 0 ) + jaddnum(json,"broadcast",broadcastflag%SUPERNET_MAXHOPS); + if ( len < datalen ) + { + //printf("len %d vs %d datalen\n",len,datalen); + hexmsg = malloc(((datalen - len)<<1) + 1); + init_hexbytes_noT(hexmsg,&serialized[len],datalen - len); + //printf("hex.(%s)\n",hexmsg); + jaddstr(json,"hexmsg",hexmsg); + free(hexmsg); + } + //printf("bits2json.(%s)\n",jprint(json,0)); + return(json); + } else printf("cant decode apinum.%d (%d.%d)\n",apinum,apinum>>5,apinum%0x1f); + return(0); +} + +char *SuperNET_hexconv(char *hexmsg) +{ + cJSON *json; char *myip,*yourip,*retstr = hexmsg; uint32_t myipbits=0,destipbits=0; + uint8_t *bits; int32_t n,len = (int32_t)strlen(hexmsg); + //if ( hexmsg == 0 || is_hexstr(hexmsg,len) == 0 ) + return(hexmsg); + len >>= 1; + if ( (bits= calloc(1,len)) != 0 ) + { + decode_hex(bits,len,hexmsg); + if ( (json= cJSON_Parse((char *)bits)) != 0 ) + { + printf("parsed hexmsg.(%s)\n",(char *)bits); + if ( (myip= jstr(json,"myip")) != 0 ) + myipbits = (uint32_t)calc_ipbits(myip); + if ( (yourip= jstr(json,"yourip")) != 0 ) + destipbits = (uint32_t)calc_ipbits(yourip); + n = SuperNET_json2bits(bits,len,json,jbits256(json,"mypub"),juint(json,"checkc"),myipbits,destipbits,(int32_t)jdouble(json,"ov")); + cJSON *json2 = SuperNET_bits2json(bits,n); printf("hexconv.(%s) -> (%s)\n",jprint(json,0),jprint(json2,1)); + if ( (retstr= calloc(1,n*2+1)) != 0 ) + init_hexbytes_noT(retstr,bits,n); + else retstr = hexmsg; + free_json(json); + } //else printf("SuperNET_hexconv cant parse.(%s)\n",hexmsg); + free(bits); + } + return(retstr); +} + +void iguana_setkeys(struct supernet_info *myinfo,struct iguana_peer *addr,bits256 *myprivp,bits256 *mypubp,bits256 *destpubp,bits256 *nextprivp,bits256 *nextpubp,bits256 *nextdestpubp) +{ + *nextprivp = myinfo->privkey; + *nextpubp = myinfo->myaddr.pubkey; + *nextdestpubp = addr->pubkey; + *myprivp = *nextprivp, *mypubp = *nextpubp, *destpubp = *nextdestpubp; + //if ( addr->validpub < 3 ) + *destpubp = GENESIS_PUBKEY; + //if ( addr->othervalid < 3 ) + *myprivp = GENESIS_PRIVKEY, *mypubp = GENESIS_PUBKEY; + //char str[65]; printf("(priv.%llx pub.%llx) -> destpub.%s\n",(long long)myprivp->txid,(long long)mypubp->txid,bits256_str(str,*destpubp)); +} + +bits256 iguana_actualpubkey(int32_t *offsetp,uint8_t *cipher,int32_t cipherlen,bits256 destpubkey) +{ + int32_t i; + *offsetp = 0; + if ( cipherlen < 56+16 ) + return(destpubkey); + for (i=56; i<56+16; i++) + if ( cipher[i] != 0 ) + break; + if ( i == 56+16 ) + { + *offsetp = sizeof(destpubkey); + memcpy(destpubkey.bytes,cipher,sizeof(destpubkey)); + //char str[65]; printf("extracted destpubkey.(%s)\n",bits256_str(str,destpubkey)); + } + return(destpubkey); +} + +int32_t iguana_send_supernet(struct iguana_peer *addr,char *jsonstr,int32_t delaymillis) +{ + int32_t datalen,cipherlen,qlen = -1; uint8_t *serialized,space2[32768],*cipher; cJSON *json; + struct supernet_info *myinfo; uint16_t checkc; + bits256 destpub,privkey,pubkey,nextprivkey,nextpubkey,nextdestpub; void *ptr = 0; + myinfo = SuperNET_MYINFO(0); + if ( (json= cJSON_Parse(jsonstr)) != 0 ) + { + iguana_setkeys(myinfo,addr,&privkey,&pubkey,&destpub,&nextprivkey,&nextpubkey,&nextdestpub); + if ( juint(json,"plaintext") == 0 && juint(json,"broadcast") == 0 && memcmp(destpub.bytes,GENESIS_PUBKEY.bytes,sizeof(pubkey)) == 0 ) + { + printf("warning broadcasting non-plaintext! (%s) (%d %d %d)\n",jsonstr,juint(json,"plaintext"),juint(json,"broadcast"),memcmp(destpub.bytes,GENESIS_PUBKEY.bytes,sizeof(pubkey))); //getchar(); + //free_json(json); + //return(-1); + } + serialized = malloc(sizeof(struct iguana_msghdr) + IGUANA_MAXPACKETSIZE); + checkc = SuperNET_checkc(nextprivkey,nextdestpub,&nextpubkey.txid,sizeof(nextpubkey.txid)); + if ( (datalen= SuperNET_json2bits(&serialized[sizeof(struct iguana_msghdr)],IGUANA_MAXPACKETSIZE,json,nextpubkey,checkc,(uint32_t)calc_ipbits(myinfo->ipaddr),(uint32_t)calc_ipbits(addr->ipaddr),addr->validpub)) > 0 ) + { + if ( 0 && jstr(json,"method") != 0 && strcmp("getpeers",jstr(json,"method")) != 0 ) + printf("SUPERSEND -> (%s) (%s) delaymillis.%d datalen.%d checkc.%x\n",jprint(SuperNET_bits2json(&serialized[sizeof(struct iguana_msghdr)],datalen),1),addr->ipaddr,delaymillis,datalen,checkc); + if ( memcmp(destpub.bytes,GENESIS_PUBKEY.bytes,sizeof(destpub)) == 0 ) + { + qlen = iguana_queue_send(addr,delaymillis,serialized,"SuperNET",datalen+1); + //printf("send broadcast\n"); } else { - if ( len > 0 ) + if ( (cipher= SuperNET_ciphercalc(&ptr,&cipherlen,&privkey,&destpub,&serialized[sizeof(struct iguana_msghdr)],datalen,space2,sizeof(space2))) != 0 ) { - remains -= len; - recvlen += len; - buf = &buf[len]; - retstr = SuperNET_rpcparse(myinfo,space,size,&jsonflag,&postflag,jsonbuf,remoteaddr); - break; - } else usleep(10000); + void *msgbits; int32_t msglen,offset; bits256 testpriv; uint8_t space[65536]; void *ptr2; + destpub = iguana_actualpubkey(&offset,cipher,cipherlen,destpub); + if ( 0 && (msgbits= SuperNET_deciphercalc(&ptr2,&msglen,testpriv,destpub,&cipher[offset],cipherlen-offset,space,sizeof(space))) == 0 ) + { + int32_t i; for (i=0; iipaddr); + qlen = iguana_queue_send(addr,delaymillis,&cipher[-sizeof(struct iguana_msghdr)],"SuperNETb",cipherlen); + if ( ptr != 0 ) + free(ptr); + } } - } - if ( retstr != 0 ) - { - i = 0; - if ( postflag == 0 && jsonflag == 0 ) - retstr = SuperNET_htmlresponse(space,size,&remains,1,retstr,1); - else remains = (int32_t)strlen(retstr); - printf("RETBUF.(%s)\n",retstr); - while ( remains > 0 ) + } else printf("error json2bits\n"); + free(serialized); + } else printf("cant parse.(%s)\n",jsonstr); + return(qlen); +} + +int32_t DHT_dist(bits256 desthash,bits256 hash) +{ + int32_t i,dist = 0; + for (i=0; i<4; i++) + dist += bitweight(desthash.ulongs[i] ^ hash.ulongs[i]); + printf("(dist.%d) ",dist); + return(dist*0); +} + +struct iguana_peer *iguana_peerfind(struct supernet_info *myinfo,struct iguana_info **coinp,uint64_t destipbits,bits256 category,bits256 subhash) +{ + int32_t i,j; struct iguana_peer *addr; uint16_t port; + *coinp = 0; + port = (uint16_t)(destipbits >> 32); + for (i=0; ipeers.active[j]; + if ( addr->usock >= 0 ) { - if ( errno != EAGAIN && errno != EWOULDBLOCK ) + if ( destipbits == addr->ipbits || category_peer(myinfo,addr,category,subhash) >= 0 ) { - //printf("%s: %s numsent.%d vs remains.%d len.%d errno.%d (%s) usock.%d\n",retstr,ipaddr,numsent,remains,recvlen,errno,strerror(errno),sock); - break; + if ( port == 0 || addr->A.port == port ) + { + *coinp = Coins[i]; + return(addr); + } } } - else if ( remains > 0 ) + } + } + } + return(0); +} + +char *SuperNET_DHTsend(struct supernet_info *myinfo,uint64_t destipbits,bits256 categoryhash,bits256 subhash,char *hexmsg,int32_t maxdelay,int32_t broadcastflag,int32_t plaintext) +{ + int32_t i,j; char *convstr,*jsonstr=0; struct iguana_peer *addr; cJSON *json; struct iguana_info *coin; + if ( myinfo == 0 ) + return(clonestr("{\"error\":\"no supernet_info\"}")); + json = cJSON_CreateObject(); + jaddstr(json,"agent","SuperNET"); + jaddstr(json,"method","DHT"); + convstr = SuperNET_hexconv(hexmsg); + jaddstr(json,"hexmsg",convstr); + if ( convstr != hexmsg ) + free(convstr); + if ( broadcastflag > 0 ) + jaddnum(json,"broadcast",broadcastflag-1); + if ( plaintext != 0 ) + jaddnum(json,"plaintext",plaintext!=0); + if ( bits256_nonz(categoryhash) > 0 && memcmp(categoryhash.bytes,GENESIS_PUBKEY.bytes,sizeof(bits256)) != 0 ) + jaddbits256(json,"categoryhash",categoryhash); + if ( bits256_nonz(subhash) > 0 && memcmp(subhash.bytes,GENESIS_PUBKEY.bytes,sizeof(bits256)) != 0 ) + jaddbits256(json,"subhash",subhash); + if ( SuperNET_hexmsgfind(myinfo,categoryhash,subhash,hexmsg,1) >= 0 ) + { + //char str[65]; printf("duplicate hex.(%s) for %s\n",hexmsg,bits256_str(str,categoryhash)); + return(clonestr("{\"error\":\"duplicate packet rejected\"}")); + } + else + { + //printf("DHT send\n"); + SuperNET_hexmsgadd(myinfo,categoryhash,subhash,hexmsg,tai_now(),0); + } + jsonstr = jprint(json,1); + if ( broadcastflag != 0 || destipbits == 0 ) + { + for (i=0; i 0 ) - printf("iguana sent.%d remains.%d of len.%d\n",numsent,remains,recvlen); + addr = &Coins[i]->peers.active[j]; + if ( addr->usock >= 0 && addr->supernet != 0 && (broadcastflag != 0 || category_peer(myinfo,addr,categoryhash,subhash) >= 0) ) + { + if ( strcmp("0.0.0.0",addr->ipaddr) != 0 && strcmp("127.0.0.1",addr->ipaddr) != 0 ) + { + //char str[65]; printf("BROADCAST[%d] crc.%x %s SEND.(%d) to %s\n",j,calc_crc32(0,jsonstr,(int32_t)strlen(jsonstr)),bits256_str(str,categoryhash),(int32_t)strlen(jsonstr),addr->ipaddr); + iguana_send_supernet(addr,jsonstr,maxdelay==0?0:(rand()%maxdelay)); + } + } } } - if ( retstr != space ) - free(retstr); } - //printf("done response sock.%d\n",sock); - closesocket(sock); + return(clonestr("{\"result\":\"packet sent to all peers\"}")); } + if ( (addr= iguana_peerfind(myinfo,&coin,destipbits,categoryhash,subhash)) == 0 ) + return(clonestr("{\"error\":\"no route found\"}")); + if ( SuperNET_hexmsgfind(myinfo,categoryhash,subhash,hexmsg,1) >= 0 ) + { + printf("SEND.(%s) to %s\n",jsonstr,addr->ipaddr); + iguana_send_supernet(addr,jsonstr,maxdelay==0?0:(rand()%maxdelay)); + return(clonestr("{\"result\":\"packet sent directly\"}")); + } + return(clonestr("{\"result\":\"no appropriate peers to send to\"}")); +} + +char *SuperNET_DHTencode(struct supernet_info *myinfo,char *destip,bits256 categoryhash,bits256 subhash,char *hexmsg,int32_t maxdelay,int32_t broadcastflag,int32_t plaintext) +{ + uint32_t destipbits; char *retstr; + destipbits = (uint32_t)calc_ipbits(destip); + if ( (retstr = SuperNET_DHTsend(myinfo,destipbits,categoryhash,subhash,hexmsg,maxdelay,broadcastflag,plaintext)) != 0 ) + free(retstr); + return(clonestr("{\"result\":\"DHT sent\"}")); } -/* -struct endpoint find_epbits(struct relay_info *list,uint32_t ipbits,uint16_t port,int32_t type) + +char *SuperNET_forward(struct supernet_info *myinfo,char *hexmsg,uint32_t destipbits,bits256 categoryhash,bits256 subhash,int32_t maxdelay,int32_t broadcastflag,int32_t plaintext) { - int32_t i; struct endpoint epbits; - memset(&epbits,0,sizeof(epbits)); - if ( list != 0 && list->num > 0 ) + return(SuperNET_DHTsend(myinfo,destipbits,categoryhash,subhash,hexmsg,maxdelay,broadcastflag,plaintext)); +} + +int32_t SuperNET_destination(struct supernet_info *myinfo,uint32_t *destipbitsp,bits256 *categoryp,bits256 *subhashp,int32_t *maxdelayp,cJSON *json,char *remoteaddr) +{ + char *destip; int32_t destflag = 0; + if ( (destip= jstr(json,"destip")) != 0 ) + *destipbitsp = (uint32_t)calc_ipbits(destip); + else *destipbitsp = 0; + *maxdelayp = juint(json,"delay"); + *categoryp = jbits256(json,"categoryhash"); + *subhashp = jbits256(json,"subhash"); + if ( *destipbitsp != 0 ) { - if ( type >= 0 ) - type = nn_portoffset(type); - for (i=0; inum&&i<(int32_t)(sizeof(list->connections)/sizeof(*list->connections)); i++) - if ( list->connections[i].ipbits == ipbits && (port == 0 || port == list->connections[i].port) && (type < 0 || type == list->connections[i].nn) ) - return(list->connections[i]); + if ( *destipbitsp == myinfo->myaddr.selfipbits ) + destflag |= SUPERNET_ISMINE; + else destflag |= SUPERNET_FORWARD; } - return(epbits); + else if ( bits256_nonz(*categoryp) > 0 ) + { + if ( category_peer(myinfo,0,*categoryp,*subhashp) > 0 ) + destflag |= SUPERNET_ISMINE; + if ( juint(json,"broadcast") > 0 ) + destflag |= SUPERNET_FORWARD; + } + if ( juint(json,"request") != 0 || remoteaddr == 0 || remoteaddr[0] == 0 || strcmp(remoteaddr,"127.0.0.1") == 0 ) + destflag |= SUPERNET_ISMINE; + return(destflag); } -int32_t add_relay(struct relay_info *list,struct endpoint epbits) +char *SuperNET_JSON(struct supernet_info *myinfo,cJSON *json,char *remoteaddr,uint16_t port) { - list->connections[list->num % (sizeof(list->connections)/sizeof(*list->connections))] = epbits, list->num++; - if ( list->num > (sizeof(list->connections)/sizeof(*list->connections)) ) - printf("add_relay warning num.%d > %ld\n",list->num,(long)(sizeof(list->connections)/sizeof(*list->connections))); - return(list->num); + char hexbuf[8192]; bits256 category,subhash; + int32_t autologin = 0,hexlen,destflag,maxdelay,flag=0,newflag=0; uint32_t destipbits,timestamp; //cJSON *retjson; + char *str,*forwardstr=0,*retstr=0,*agent=0,*method=0,*message,*hexmsg=0,*jsonstr=0; uint64_t tag; + //printf("SuperNET_JSON.(%s)\n",jprint(json,0)); + if ( remoteaddr != 0 && strcmp(remoteaddr,"127.0.0.1") == 0 ) + remoteaddr = 0; + if ( (agent = jstr(json,"agent")) == 0 ) + agent = "bitcoinrpc"; + method = jstr(json,"method"); + if ( agent != 0 ) + { + if ( strcmp(agent,"pangea") == 0 && jobj(json,"categoryhash") == 0 ) + { + jaddbits256(json,"categoryhash",calc_categoryhashes(0,"pangea",0)); + if ( jobj(json,"subhash") == 0 ) + jaddbits256(json,"subhash",GENESIS_PUBKEY); + } + else if ( strcmp(agent,"InstantDEX") == 0 ) + { + if ( jobj(json,"passphrase") != 0 ) + { + if ( (str= SuperNET_login(myinfo,0,json,remoteaddr,jstr(json,"handle"),0,0,jstr(json,"passphrase"))) != 0 ) + free(str); + autologin = 1; + } + else if ( jobj(json,"password") != 0 ) + { + if ( (str= SuperNET_login(myinfo,0,json,remoteaddr,jstr(json,"handle"),jstr(json,"password"),jstr(json,"permanentfile"),0)) != 0 ) + free(str); + autologin = 1; + } + } + } + if ( remoteaddr == 0 ) + { + if ( jobj(json,"timestamp") != 0 ) + jdelete(json,"timestamp"); + timestamp = (uint32_t)time(NULL); + jaddnum(json,"timestamp",timestamp); + } + if ( (tag= j64bits(json,"tag")) == 0 ) + { + OS_randombytes((uint8_t *)&tag,sizeof(tag)); + jadd64bits(json,"tag",tag); + } + //printf("SuperNET_JSON.(%s) remote.(%s)\n",jprint(json,0),remoteaddr!=0?remoteaddr:""); + destflag = SuperNET_destination(myinfo,&destipbits,&category,&subhash,&maxdelay,json,remoteaddr); + //printf("destflag.%d\n",destflag); + if ( method != 0 && (hexmsg= jstr(json,"hexmsg")) == 0 && strcmp(agent,"bitcoinrpc") != 0 && (message= jstr(json,"message")) == 0 ) + { + jsonstr = jprint(json,0); + hexlen = (int32_t)strlen(jsonstr); + if ( hexlen*2+1 > sizeof(hexbuf) ) + hexmsg = malloc(hexlen*2+1), flag = 1; + else hexmsg = hexbuf; + init_hexbytes_noT(hexmsg,(uint8_t *)jsonstr,(int32_t)strlen(jsonstr)+1); + } + if ( (destflag & SUPERNET_FORWARD) != 0 ) + { + if ( hexmsg != 0 ) + { + if ( SuperNET_hexmsgfind(myinfo,category,subhash,hexmsg,0) < 0 ) + { + //printf("FORWARD.(%s)\n",hexmsg); + newflag = 1; + SuperNET_hexmsgadd(myinfo,category,subhash,hexmsg,tai_now(),remoteaddr); + forwardstr = SuperNET_forward(myinfo,hexmsg,destipbits,category,subhash,maxdelay,juint(json,"broadcast"),juint(json,"plaintext")!=0); + } + } + } + if ( (destflag & SUPERNET_ISMINE) != 0 && agent != 0 && method != 0 ) + { + if ( strcmp(agent,"bitcoinrpc") != 0 && newflag == 0 && hexmsg != 0 && SuperNET_hexmsgfind(myinfo,category,subhash,hexmsg,0) < 0 ) + { + //printf("SuperNET_JSON hexmsgadd\n"); + SuperNET_hexmsgadd(myinfo,category,subhash,hexmsg,tai_now(),remoteaddr); + } + if ( (retstr= SuperNET_processJSON(myinfo,json,remoteaddr,port)) == 0 ) + printf("null retstr from SuperNET_JSON\n"); + } + if ( flag != 0 && hexmsg != 0 && hexmsg != hexbuf ) + free(hexmsg); + if ( retstr == 0 ) + retstr = forwardstr, forwardstr = 0; + if ( forwardstr != 0 ) + free(forwardstr); + if ( jsonstr != 0 ) + free(jsonstr); + if ( autologin != 0 ) + SuperNET_logout(myinfo,0,json,remoteaddr); + return(retstr); } -int32_t nn_add_lbservers(struct supernet_info *myinfo,uint16_t port,uint16_t globalport,uint16_t relaysport,int32_t priority,int32_t sock,char servers[][MAX_SERVERNAME],int32_t num) +char *SuperNET_p2p(struct iguana_info *coin,struct iguana_peer *addr,int32_t *delaymillisp,char *ipaddr,uint8_t *data,int32_t datalen,int32_t compressed) { - int32_t i; char endpoint[512],pubendpoint[512]; struct endpoint epbits; uint32_t ipbits; - if ( num > 0 && servers != 0 && nn_setsockopt(sock,NN_SOL_SOCKET,NN_SNDPRIO,&priority,sizeof(priority)) >= 0 ) + struct supernet_info *myinfo;char *myipaddr,*method,*retstr,*checkstr; void *ptr=0; + bits256 senderpub,privkey,pubkey,nextprivkey,nextpubkey,nextdestpub; + uint16_t checkc,othercheckc; cJSON *json,*retjson; int32_t offset,maxdelay,msglen = datalen; + uint8_t space[8192],*msgbits = 0; + myinfo = SuperNET_MYINFO(0); + retstr = 0; + *delaymillisp = 0; + if ( compressed != 0 ) + { + //int32_t i; for (i=0; iipaddr); + addr->validpub >>= 1; + return(0); + } else { char str[65]; printf("GENESIS recv %s\n",bits256_str(str,senderpub)); } + } else printf("GENESIS recv GENESIS\n"); + } //else printf("decrypted mypriv.%llx senderpub.%llx\n",(long long)privkey.txid,(long long)senderpub.txid); + //for (i=0; iprivkey,senderpub,&senderpub.txid,sizeof(senderpub.txid)); + if ( checkc == othercheckc ) + addr->validpub += 1*0; + else if ( addr->validpub > 0 ) + addr->validpub >>= 1; + else addr->validpub--; + //printf("validpub.%d: %x vs %x priv.%llx senderpub.%llx\n",addr->validpub,checkc,othercheckc,(long long)myinfo->privkey.txid,(long long)senderpub.txid); + } + maxdelay = juint(json,"maxdelay"); + if ( 1 && jstr(json,"method") != 0 && strcmp(jstr(json,"method"),"getpeers") != 0 ) + printf("GOT >>>>>>>> SUPERNET P2P.(%s) from.%s %s valid.%d:%d\n",jprint(json,0),coin->symbol,addr->ipaddr,addr->validpub,addr->othervalid); + if ( (myipaddr= jstr(json,"yourip")) != 0 ) + SuperNET_checkipaddr(SuperNET_MYINFO(0),coin,addr,myipaddr,ipaddr); + jaddstr(json,"fromp2p",coin->symbol); + method = jstr(json,"method"); + if ( method != 0 && strcmp(method,"stop") == 0 ) + { + addr->dead = (uint32_t)time(NULL); + addr->rank = 0; + free_json(json); + if ( ptr != 0 ) + free(ptr); + //return(clonestr("{\"result\":\"peer marked as dead\"}")); + return(0); + } + retstr = SuperNET_JSON(myinfo,json,ipaddr,addr->A.port); + //printf("(%s) -> p2pret.(%s)\n",jprint(json,0),retstr); + *delaymillisp = SuperNET_delaymillis(myinfo,maxdelay); + senderpub = jbits256(json,"mypub"); + addr->othervalid = (int32_t)jdouble(json,"ov"); + addr->pubkey = senderpub; + free_json(json); + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + { + if ( jstr(retjson,"error") != 0 || (jstr(retjson,"result") != 0 && jstr(retjson,"method") == 0) ) { - printf("null ipbits.(%s)\n",servers[i]); - continue; + //printf("filter.(%s) no need to send back\n",retstr); + free(retstr); + retstr = 0; } - //printf("epbits.%llx ipbits.%x %s\n",*(long long *)&epbits,(uint32_t)ipbits,endpoint); - if ( ismyaddress(servers[i],myinfo) == 0 ) + free_json(retjson); + } + } else printf("error decoding bits2json\n"); + if ( ptr != 0 ) + free(ptr); + return(retstr); +} +#else +char *SuperNET_JSON(struct supernet_info *myinfo,cJSON *json,char *remoteaddr,uint16_t port) +{ + int32_t autologin = 0; uint32_t timestamp; char *retstr=0,*agent=0,*method=0,*jsonstr=0; uint64_t tag; + //printf("SuperNET_JSON.(%s)\n",jprint(json,0)); + if ( remoteaddr != 0 && strcmp(remoteaddr,"127.0.0.1") == 0 ) + remoteaddr = 0; + if ( (agent = jstr(json,"agent")) == 0 ) + agent = "bitcoinrpc"; + method = jstr(json,"method"); + if ( remoteaddr == 0 ) + { + if ( jobj(json,"timestamp") != 0 ) + jdelete(json,"timestamp"); + timestamp = (uint32_t)time(NULL); + jaddnum(json,"timestamp",timestamp); + } + if ( (tag= j64bits(json,"tag")) == 0 ) + { + OS_randombytes((uint8_t *)&tag,sizeof(tag)); + jadd64bits(json,"tag",tag); + } + if ( (retstr= SuperNET_processJSON(myinfo,json,remoteaddr,port)) == 0 ) + printf("null retstr from SuperNET_JSON\n"); + if ( jsonstr != 0 ) + free(jsonstr); + if ( autologin != 0 ) + SuperNET_logout(myinfo,0,json,remoteaddr); + return(retstr); +} +#endif + +cJSON *SuperNET_peerarray(struct iguana_info *coin,int32_t max,int32_t supernetflag) +{ + int32_t i,r,j,n = 0; struct iguana_peer *addr; cJSON *array = cJSON_CreateArray(); + r = rand(); + for (j=0; jpeers->active[i]; + if ( addr->usock >= 0 && supernetflag == (addr->supernet != 0) ) + { + jaddistr(array,addr->ipaddr); + if ( ++n >= max ) + break; + } + } + if ( n == 0 ) + { + free_json(array); + return(0); + } + return(array); +} + +int32_t SuperNET_coinpeers(struct iguana_info *coin,cJSON *SNjson,cJSON *rawjson,int32_t max) +{ + cJSON *array,*item; + if ( (array= SuperNET_peerarray(coin,max,1)) != 0 ) + { + max -= cJSON_GetArraySize(array); + item = cJSON_CreateObject(); + jaddstr(item,"coin",coin->symbol); + jadd(item,"peers",array); + jaddi(SNjson,item); + } + if ( max > 0 && (array= SuperNET_peerarray(coin,max,0)) != 0 ) + { + max -= cJSON_GetArraySize(array); + item = cJSON_CreateObject(); + jaddstr(item,"coin",coin->symbol); + jadd(item,"peers",array); + jaddi(rawjson,item); + } + return(max); +} + +void SuperNET_parsepeers(struct supernet_info *myinfo,cJSON *array,int32_t n,int32_t supernetflag) +{ + int32_t i,j,m; cJSON *coinarray,*item; char *symbol,*ipaddr; struct iguana_info *ptr; + if ( array != 0 && n > 0 ) + { + for (i=0; i= 0 ) + ptr = iguana_coinfind(symbol); + if ( (coinarray= jarray(&m,item,"peers")) != 0 ) { - printf("+R%s ",endpoint); - add_relay(&myinfo->active,epbits); - } - if ( myinfo->subclient >= 0 ) - { - if ( myinfo->iamrelay != 0 ) + for (j=0; jsubclient,pubendpoint) >= 0 ) - printf("+P%s ",pubendpoint); + if ( (ipaddr= jstr(jitem(coinarray,j),0)) != 0 ) + SuperNET_remotepeer(myinfo,ptr,symbol,ipaddr,supernetflag); + else printf("no ipaddr[%d] of %d\n",j,m); } - epbits = calc_epbits("tcp",ipbits,globalport,NN_PUB); - expand_epbits(pubendpoint,epbits); - if ( nn_connect(myinfo->subclient,pubendpoint) >= 0 ) - printf("+P%s ",pubendpoint); } + printf("parsed.%d %s.peers supernet.%d\n",m,symbol,supernetflag); } } - printf("added priority.%d\n",priority); - priority++; - } else printf("error setting priority.%d (%s)\n",priority,nn_errstr()); - return(priority); -} - -int32_t _lb_socket(struct supernet_info *myinfo,uint16_t port,uint16_t globalport,uint16_t relaysport,int32_t maxmillis,char servers[][MAX_SERVERNAME],int32_t num,char backups[][MAX_SERVERNAME],int32_t numbacks,char failsafes[][MAX_SERVERNAME],int32_t numfailsafes) -{ - int32_t lbsock,timeout,retrymillis,priority = 1; - if ( (lbsock= nn_socket(AF_SP,NN_REQ)) >= 0 ) - { - retrymillis = (maxmillis / 30) + 1; - printf("!!!!!!!!!!!! lbsock.%d !!!!!!!!!!!\n",lbsock); - if ( nn_setsockopt(lbsock,NN_SOL_SOCKET,NN_RECONNECT_IVL,&retrymillis,sizeof(retrymillis)) < 0 ) - printf("error setting NN_REQ NN_RECONNECT_IVL_MAX socket %s\n",nn_errstr()); - else if ( nn_setsockopt(lbsock,NN_SOL_SOCKET,NN_RECONNECT_IVL_MAX,&maxmillis,sizeof(maxmillis)) < 0 ) - fprintf(stderr,"error setting NN_REQ NN_RECONNECT_IVL_MAX socket %s\n",nn_errstr()); - timeout = SUPERNET_NETWORKTIMEOUT; - if ( 1 && nn_setsockopt(lbsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)) < 0 ) - printf("error setting NN_SOL_SOCKET NN_RCVTIMEO socket %s\n",nn_errstr()); - timeout = 100; - if ( 1 && nn_setsockopt(lbsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)) < 0 ) - printf("error setting NN_SOL_SOCKET NN_SNDTIMEO socket %s\n",nn_errstr()); - if ( num > 0 ) - priority = nn_add_lbservers(myinfo,port,globalport,relaysport,priority,lbsock,servers,num); - if ( numbacks > 0 ) - priority = nn_add_lbservers(myinfo,port,globalport,relaysport,priority,lbsock,backups,numbacks); - if ( numfailsafes > 0 ) - priority = nn_add_lbservers(myinfo,port,globalport,relaysport,priority,lbsock,failsafes,numfailsafes); - } else printf("error getting req socket %s\n",nn_errstr()); - //printf("myinfo->lb.num %d\n",myinfo->lb.num); - return(lbsock); -} - -int32_t nn_lbsocket(struct supernet_info *myinfo,int32_t maxmillis,int32_t port,uint16_t globalport,uint16_t relaysport) -{ - char Cservers[32][MAX_SERVERNAME],Bservers[32][MAX_SERVERNAME],failsafes[4][MAX_SERVERNAME]; - int32_t n,m,lbsock,numfailsafes = 0; - printf("redo lbsocket()\n"), exit(-1); - //strcpy(failsafes[numfailsafes++],"5.9.56.103"); - //strcpy(failsafes[numfailsafes++],"5.9.102.210"); - // n = crackfoo_servers(Cservers,sizeof(Cservers)/sizeof(*Cservers),port); - // m = badass_servers(Bservers,sizeof(Bservers)/sizeof(*Bservers),port); - lbsock = _lb_socket(myinfo,port,globalport,relaysport,maxmillis,Bservers,m,Cservers,n*0,failsafes,numfailsafes); - return(lbsock); -} - -void add_standard_fields(char *request) -{ - cJSON *json; uint64_t tag; - if ( (json= cJSON_Parse(request)) != 0 ) - { - if ( get_API_nxt64bits(cJSON_GetObjectItem(json,"NXT")) == 0 ) - { - randombytes((void *)&tag,sizeof(tag)); - sprintf(request + strlen(request) - 1,",\"NXT\":\"%s\",\"tag\":\"%llu\"}",myinfo->NXTADDR,(long long)tag); - if ( myinfo->iamrelay != 0 && (myinfo->hostname[0] != 0 || myinfo->ipaddr[0] != 0) ) - sprintf(request + strlen(request) - 1,",\"iamrelay\":\"%s\"}",myinfo->hostname[0]!=0?myinfo->hostname:myinfo->myipaddr); - } - free_json(json); } } -char *nn_loadbalanced(struct supernet_info *myinfo,uint8_t *data,int32_t len) +cJSON *SuperNET_rosettajson(bits256 privkey,int32_t showprivs) { - char *msg,*jsonstr = 0; - int32_t sendlen,i,lbsock,recvlen = 0; - if ( (lbsock= myinfo->lbclient) < 0 ) - return(clonestr("{\"error\":\"invalid load balanced socket\"}")); - for (i=0; i<10; i++) - if ( (nn_socket_status(lbsock,1) & NN_POLLOUT) != 0 ) - break; - if ( myinfo->Debuglevel > 2 ) - printf("sock.%d NN_LBSEND.(%s)\n",lbsock,data); - //fprintf(stderr,"send to network\n"); - if ( (sendlen= nn_send(lbsock,data,len,0)) == len ) + uint8_t rmd160[20],pub[33]; uint64_t nxt64bits; bits256 pubkey; + char str2[41],wifbuf[64],addr[64],str[128]; cJSON *retjson; + pubkey = acct777_pubkey(privkey); + nxt64bits = acct777_nxt64bits(pubkey); + retjson = cJSON_CreateObject(); + jaddbits256(retjson,"pubkey",pubkey); + RS_encode(str,nxt64bits); + jaddstr(retjson,"RS",str); + jadd64bits(retjson,"NXT",nxt64bits); + bitcoin_pubkey33(0,pub,privkey); + init_hexbytes_noT(str,pub,33); + jaddstr(retjson,"btcpubkey",str); + calc_OP_HASH160(str2,rmd160,str); + jaddstr(retjson,"rmd160",str2); + if ( bitcoin_address(addr,0,pub,33) != 0 ) { - for (i=0; i<10; i++) - if ( (nn_socket_status(lbsock,1) & NN_POLLIN) != 0 ) - break; - if ( (recvlen= nn_recv(lbsock,&msg,NN_MSG,0)) > 0 ) + jaddstr(retjson,"BTC",addr); + if ( showprivs != 0 ) { - if ( myinfo->Debuglevel > 2 ) - printf("LBRECV.(%s)\n",msg); - jsonstr = clonestr((char *)msg); - nn_freemsg(msg); + bitcoin_priv2wif(wifbuf,privkey,128); + jaddstr(retjson,"BTCwif",wifbuf); } - else + } + if ( bitcoin_address(addr,60,pub,33) != 0 ) + { + jaddstr(retjson,"BTCD",addr); + if ( showprivs != 0 ) { - printf("nn_loadbalanced got recvlen.%d %s\n",recvlen,nn_errstr()); - jsonstr = clonestr("{\"error\":\"lb recv error, probably timeout\"}"); + bitcoin_priv2wif(wifbuf,privkey,188); + jaddstr(retjson,"BTCDwif",wifbuf); } - } else printf("got sendlen.%d instead of %d %s\n",sendlen,len,nn_errstr()), jsonstr = clonestr("{\"error\":\"lb send error\"}"); - return(jsonstr); + } + if ( showprivs != 0 ) + jaddbits256(retjson,"privkey",privkey); + return(retjson); +} + +#include "../includes/iguana_apidefs.h" + +STRING_ARG(SuperNET,addr2rmd160,address) +{ + uint8_t addrtype,rmd160[20]; char rmdstr[41]; cJSON *retjson; + bitcoin_addr2rmd160(&addrtype,rmd160,address); + init_hexbytes_noT(rmdstr,rmd160,sizeof(rmd160)); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result",rmdstr); + jaddnum(retjson,"addrtype",addrtype); + jaddstr(retjson,"address",address); + return(jprint(retjson,1)); } -cJSON *relay_json(struct relay_info *list) +STRING_ARG(SuperNET,rmd160conv,rmd160) { - cJSON *json,*array; char endpoint[512]; int32_t i; - if ( list == 0 || list->num == 0 ) - return(0); - array = cJSON_CreateArray(); - for (i=0; inum&&i<(int32_t)(sizeof(list->connections)/sizeof(*list->connections)); i++) + uint8_t rmdbuf[20]; char coinaddr[64],p2shaddr[64]; cJSON *retjson = cJSON_CreateObject(); + if ( rmd160 != 0 && strlen(rmd160) == 40 ) { - expand_epbits(endpoint,list->connections[i]); - jaddistr(array,endpoint); + decode_hex(rmdbuf,20,rmd160); + bitcoin_address(coinaddr,coin->chain->pubtype,rmdbuf,20); + bitcoin_address(p2shaddr,coin->chain->p2shtype,rmdbuf,20); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"address",coinaddr); + jaddstr(retjson,"p2sh",p2shaddr); } - json = cJSON_CreateObject(); - jadd(json,"endpoints",array); - //cJSON_AddItemToObject(json,"type",cJSON_CreateString(nn_typestr(list->mytype))); - //cJSON_AddItemToObject(json,"dest",cJSON_CreateString(nn_typestr(list->desttype))); - jaddnum(json,"total",list->num); - return(json); + return(jprint(retjson,1)); } -char *relays_jsonstr(struct supernet_info *myinfo,char *jsonstr,cJSON *argjson) +HASH_AND_INT(SuperNET,priv2pub,privkey,addrtype) { - cJSON *json; - if ( myinfo->iamrelay != 0 && myinfo->ipaddr[0] != 0 ) + cJSON *retjson; bits256 pub; uint8_t pubkey[33]; char coinaddr[64],pubkeystr[67]; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + retjson = cJSON_CreateObject(); + crypto_box_priv2pub(pub.bytes,privkey.bytes); + jaddbits256(retjson,"curve25519",pub); + pub = bitcoin_pubkey33(myinfo->ctx,pubkey,privkey); + init_hexbytes_noT(pubkeystr,pubkey,33); + jaddstr(retjson,"secp256k1",pubkeystr); + bitcoin_address(coinaddr,addrtype,pubkey,33); + jaddstr(retjson,"result",coinaddr); + return(jprint(retjson,1)); +} + +ZERO_ARGS(SuperNET,keypair) +{ + cJSON *retjson; bits256 pubkey,privkey; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + retjson = cJSON_CreateObject(); + crypto_box_keypair(pubkey.bytes,privkey.bytes); + jaddstr(retjson,"result","generated keypair"); + jaddbits256(retjson,"privkey",privkey); + jaddbits256(retjson,"pubkey",pubkey); + return(jprint(retjson,1)); +} + +TWOHASHES_AND_STRING(SuperNET,decipher,privkey,srcpubkey,cipherstr) +{ + int32_t cipherlen=0,msglen; char *retstr; cJSON *retjson; void *ptr = 0; uint8_t *cipher,*message,space[8192]; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( cipherstr != 0 ) + cipherlen = (int32_t)strlen(cipherstr) >> 1; + if ( cipherlen < crypto_box_NONCEBYTES ) + return(clonestr("{\"error\":\"cipher is too short\"}")); + cipher = calloc(1,cipherlen); + decode_hex(cipher,cipherlen,cipherstr); + if ( (message= SuperNET_deciphercalc(&ptr,&msglen,privkey,srcpubkey,cipher,cipherlen,space,sizeof(space))) != 0 ) { - json = cJSON_CreateObject(); - jaddstr(json,"relay",myinfo->ipaddr); - if ( myinfo->active.num > 0 ) - jadd(json,"relays",relay_json(&myinfo->active)); - return(jprint(json,1)); - } - else return(clonestr("{\"error\":\"get relay list from relay\"}")); + message[msglen] = 0; + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","deciphered message"); + jaddstr(retjson,"message",(char *)message); + retstr = jprint(retjson,1); + if ( ptr != 0 ) + free(ptr); + } else retstr = clonestr("{\"error\":\"couldnt decipher message\"}"); + return(retstr); } -int32_t init_SUPERNET_pullsock(struct supernet_info *myinfo,int32_t sendtimeout,int32_t recvtimeout) +TWOHASHES_AND_STRING(SuperNET,cipher,privkey,destpubkey,message) { - char bindaddr[64],*transportstr; int32_t iter; - myinfo->pullsock = -1; - if ( (myinfo->pullsock= nn_socket(AF_SP,NN_PULL)) < 0 ) + cJSON *retjson; char *retstr,*hexstr,space[8129]; uint8_t space2[8129]; + uint8_t *cipher; int32_t cipherlen,onetimeflag; bits256 origprivkey; void *ptr = 0; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( (cipher= SuperNET_ciphercalc(&ptr,&cipherlen,&privkey,&destpubkey,(uint8_t *)message,(int32_t)strlen(message)+1,space2,sizeof(space2))) != 0 ) { - printf("error creating pullsock %s\n",nn_strerror(nn_errno())); - return(-1); + if ( cipherlen > sizeof(space)/2 ) + hexstr = calloc(1,(cipherlen<<1)+1); + else hexstr = (void *)space; + init_hexbytes_noT(hexstr,cipher,cipherlen); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result",hexstr); + onetimeflag = memcmp(origprivkey.bytes,privkey.bytes,sizeof(privkey)); + if ( onetimeflag != 0 ) + { + //jaddbits256(retjson,"onetime_privkey",privkey); + jaddbits256(retjson,"onetime_pubkey",destpubkey); + if ( onetimeflag == 2 ) + jaddstr(retjson,"warning","onetime keypair was used to broadcast"); + } + retstr = jprint(retjson,1); + if ( hexstr != (void *)space ) + free(hexstr); + if ( ptr != 0 ) + free(ptr); + return(retstr); } - printf("got pullsock.%d\n",myinfo->pullsock); - if ( nn_settimeouts(myinfo->pullsock,sendtimeout,recvtimeout) < 0 ) + printf("error encrypting message.(%s)\n",message); + return(clonestr("{\"error\":\"cant encrypt message\"}")); +} + +bits256 SuperNET_pindecipher(IGUANA_ARGS,char *pin,char *privcipher) +{ + cJSON *testjson; char *mstr,*cstr; bits256 privkey,pinpriv,pinpub; + conv_NXTpassword(pinpriv.bytes,pinpub.bytes,(uint8_t *)pin,(int32_t)strlen(pin)); + privkey = GENESIS_PRIVKEY; + if ( (cstr= SuperNET_decipher(IGUANA_CALLARGS,pinpriv,pinpub,privcipher)) != 0 ) { - printf("error settime pullsock timeouts %s\n",nn_strerror(nn_errno())); - return(-1); - } - printf("PULLsock.%d\n",myinfo->pullsock); - for (iter=0; iter<2; iter++) + if ( (testjson= cJSON_Parse(cstr)) != 0 ) + { + if ( (mstr= jstr(testjson,"message")) != 0 && strlen(mstr) == sizeof(bits256)*2 ) + { + decode_hex(privkey.bytes,sizeof(privkey),mstr); + } else printf("error cant find message privcipher\n"); + free_json(testjson); + } else printf("Error decipher.(%s)\n",cstr); + free(cstr); + } else printf("null return from deciphering privcipher\n"); + return(privkey); +} + +THREE_STRINGS(SuperNET,rosetta,passphrase,pin,showprivkey) +{ + uint8_t flag = 0; uint64_t nxt64bits; bits256 check,privkey,pubkey,pinpriv,pinpub; + char str[128],privcipher[512],*privcipherstr,*cstr; cJSON *retjson; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + nxt64bits = conv_NXTpassword(privkey.bytes,pubkey.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); + if ( showprivkey != 0 && strcmp(showprivkey,"yes") == 0 ) + flag = 1; + privcipher[0] = 0; + conv_NXTpassword(pinpriv.bytes,pinpub.bytes,(uint8_t *)pin,(int32_t)strlen(pin)); + if ( (cstr= SuperNET_cipher(IGUANA_CALLARGS,pinpriv,pinpub,bits256_str(str,privkey))) != 0 ) { - transportstr = (iter == 0) ? "ipc" : "inproc"; - sprintf(bindaddr,"%s://SuperNET.agents",transportstr); - if ( nn_bind(myinfo->pullsock,bindaddr) < 0 ) + if ( (retjson= cJSON_Parse(cstr)) != 0 ) { - printf("error binding pullsock to (%s) %s\n",bindaddr,nn_strerror(nn_errno())); - return(-1); - } + if ( (privcipherstr= jstr(retjson,"result")) != 0 ) + strcpy(privcipher,privcipherstr); + free_json(retjson); + } else printf("error parsing cipher retstr.(%s)\n",cstr); + free(cstr); + } else printf("error SuperNET_cipher null return\n"); + retjson = SuperNET_rosettajson(privkey,flag); + jaddstr(retjson,"privcipher",privcipher); + check = SuperNET_pindecipher(IGUANA_CALLARGS,pin,privcipher); + if ( memcmp(check.bytes,privkey.bytes,sizeof(check)) != 0 ) + { + jaddbits256(retjson,"deciphered",check); + jaddstr(retjson,"error","cant recreate privkey from (pin + privcipher)"); } - return(0); + else if ( flag != 0 ) + jaddbits256(retjson,"deciphered",check); + if ( jobj(retjson,"error") == 0 ) + jaddstr(retjson,"result","use pin and privcipher to access wallet"); + return(jprint(retjson,1)); +} + +STRING_ARG(SuperNET,broadcastcipher,message) +{ + bits256 zero; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + memset(zero.bytes,0,sizeof(zero)); + return(SuperNET_cipher(IGUANA_CALLARGS,zero,zero,message)); +} + +STRING_ARG(SuperNET,broadcastdecipher,message) +{ + bits256 zero; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + memset(zero.bytes,0,sizeof(zero)); + return(SuperNET_decipher(IGUANA_CALLARGS,zero,zero,message)); +} + +HASH_AND_STRING(SuperNET,multicastcipher,pubkey,message) +{ + bits256 zero; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + memset(zero.bytes,0,sizeof(zero)); + return(SuperNET_cipher(IGUANA_CALLARGS,zero,pubkey,message)); +} + +HASH_AND_STRING(SuperNET,multicastdecipher,privkey,cipherstr) +{ + bits256 zero; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + memset(zero.bytes,0,sizeof(zero)); + return(SuperNET_decipher(IGUANA_CALLARGS,privkey,zero,cipherstr)); } -void busdata_init(struct supernet_info *myinfo,int32_t sendtimeout,int32_t recvtimeout,int32_t firstiter) +ZERO_ARGS(SuperNET,stop) { - char endpoint[512]; int32_t i; - myinfo->servicesock = myinfo->pubglobal = myinfo->pubrelays = myinfo->lbserver = -1; - endpoint[0] = 0; - if ( (myinfo->subclient= nn_createsocket(myinfo,endpoint,0,"NN_SUB",NN_SUB,0,sendtimeout,recvtimeout)) >= 0 ) + if ( remoteaddr == 0 || strncmp(remoteaddr,"127.0.0.1",strlen("127.0.0.1")) == 0 ) { - myinfo->pfd[myinfo->numservers++].fd = myinfo->subclient, printf("numservers.%d\n",myinfo->numservers); - nn_setsockopt(myinfo->subclient,NN_SUB,NN_SUB_SUBSCRIBE,"",0); - } else printf("error creating subclient\n"); - myinfo->lbclient = nn_lbsocket(myinfo,SUPERNET_NETWORKTIMEOUT,SUPERNET_PORT + LB_OFFSET,myinfo->port + PUBGLOBALS_OFFSET,myinfo->port + PUBRELAYS_OFFSET); - printf("LBclient.%d port.%d\n",myinfo->lbclient,SUPERNET_PORT + LB_OFFSET); - sprintf(endpoint,"%s://%s:%u",myinfo->transport,myinfo->ipaddr,myinfo->serviceport); - if ( (myinfo->servicesock= nn_createsocket(myinfo,endpoint,1,"NN_REP",NN_REP,myinfo->serviceport,sendtimeout,recvtimeout)) >= 0 ) - myinfo->pfd[myinfo->numservers++].fd = myinfo->servicesock, printf("numservers.%d\n",myinfo->numservers); - else printf("error creating servicesock\n"); - for (i=0; inumservers; i++) - myinfo->pfd[i].events = NN_POLLIN | NN_POLLOUT; - printf("myinfo->iamrelay %d, numservers.%d ipaddr.(%s://%s) port.%d serviceport.%d\n",myinfo->iamrelay,myinfo->numservers,myinfo->transport,myinfo->ipaddr,myinfo->port,myinfo->serviceport); + iguana_exit(); + return(clonestr("{\"result\":\"exit started\"}")); + } else return(clonestr("{\"error\":\"cant do a remote stop of this node\"}")); } -void SuperNET_init(struct supernet_info *myinfo,char *jsonstr) +TWO_ARRAYS(SuperNET,mypeers,supernet,rawpeers) { - char *str; - if ( jsonstr != 0 && (str= SuperNET_JSON(myinfo,jsonstr)) != 0 ) - free(str); - busdata_init(myinfo,10,1,0); - init_SUPERNET_pullsock(myinfo,10,10); -}*/ + SuperNET_parsepeers(myinfo,supernet,cJSON_GetArraySize(supernet),1); + SuperNET_parsepeers(myinfo,rawpeers,cJSON_GetArraySize(rawpeers),0); + return(clonestr("{\"result\":\"peers parsed\"}")); +} -int32_t Supernet_lineparse(char *key,int32_t keymax,char *value,int32_t valuemax,char *src) +STRING_ARG(SuperNET,getpeers,activecoin) { - int32_t a,b,c,n = 0; - key[0] = value[0] = 0; - while ( (c= src[n]) == ' ' || c == '\t' || c == '\n' || c == '\t' ) - n++; - while ( (c= src[n]) != ':' && c != 0 ) + int32_t max = 64; struct iguana_info *tmp; cJSON *SNjson,*rawjson,*retjson = cJSON_CreateObject(); + SNjson = cJSON_CreateArray(); + rawjson = cJSON_CreateArray(); + if ( coin != 0 ) + max = SuperNET_coinpeers(coin,SNjson,rawjson,max); + else { - *key++ = c; - if ( ++n >= keymax-1 ) + //portable_mutex_lock(&Allcoins_mutex); + HASH_ITER(hh,myinfo->allcoins,coin,tmp) { - *key = 0; - printf("lineparse overflow key.(%s)\n",src); - return(-1); + max = SuperNET_coinpeers(coin,SNjson,rawjson,max); } + //portable_mutex_unlock(&Allcoins_mutex); } - *key = 0; - if ( src[n] != ':' ) - return(n); - n++; - while ( (c= src[n]) == ' ' || c == '\t' ) - n++; - while ( (c= src[n]) != 0 && c != '\r' && c != '\n' ) - { - if ( c == '%' && (a= src[n+1]) != 0 && (b= src[n+2]) != 0 ) - c = ((unhex(a) << 4) | unhex(b)), n += 2; - *value++ = c; - n++; - if ( n >= valuemax-1 ) - { - *value = 0; - printf("lineparse overflow.(%s)\n",src); - return(-1); - } + if ( max != 64 ) + { + jaddstr(retjson,"agent","SuperNET"); + jaddstr(retjson,"method","mypeers"); + jadd(retjson,"supernet",SNjson); + jadd(retjson,"rawpeers",rawjson); } - *value = 0; - if ( src[n] != 0 ) + else { - n++; - while ( (c= src[n]) == '\r' || c == '\n' ) - n++; + jaddstr(retjson,"error","no peers"); + free_json(SNjson); + free_json(rawjson); } - return(n); + return(jprint(retjson,1)); } -cJSON *SuperNET_urlconv(char *value,int32_t bufsize,char *urlstr) +/*TWOSTRINGS_AND_TWOHASHES_AND_TWOINTS(SuperNET,DHT,hexmsg,destip,categoryhash,subhash,maxdelay,broadcast) { - int32_t i,n,totallen,datalen,len = 0; cJSON *json,*array; char key[8192],*data; - json = cJSON_CreateObject(); - array = cJSON_CreateArray(); - totallen = (int32_t)strlen(urlstr); - while ( 1 ) + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"cant remote DHT\"}")); + else if ( hexmsg == 0 || is_hexstr(hexmsg,(int32_t)strlen(hexmsg)) <= 0 ) + return(clonestr("{\"error\":\"hexmsg missing or not in hex\"}")); + return(SuperNET_DHTencode(myinfo,destip,categoryhash,subhash,hexmsg,maxdelay,broadcast,juint(json,"plaintext")!=0)); +}*/ + +HASH_AND_STRING(SuperNET,saveconf,wallethash,confjsonstr) +{ + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + return(clonestr("{\"result\":\"saveconf here\"}")); +} + +HASH_ARRAY_STRING(SuperNET,layer,mypriv,otherpubs,str) +{ + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + return(clonestr("{\"result\":\"layer encrypt here\"}")); +} + +TWO_STRINGS(SuperNET,categoryhashes,category,subcategory) +{ + bits256 categoryhash,subhash; cJSON *retjson = cJSON_CreateObject(); + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + categoryhash = calc_categoryhashes(&subhash,category,subcategory); + jaddstr(retjson,"result","category hashes calculated"); + jaddbits256(retjson,"categoryhash",categoryhash); + jaddbits256(retjson,"subhash",subhash); + return(jprint(retjson,1)); +} + +TWO_STRINGS(SuperNET,subscribe,category,subcategory) +{ + bits256 categoryhash,subhash; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + categoryhash = calc_categoryhashes(&subhash,category,subcategory); + if ( category_subscribe(myinfo,categoryhash,subhash) != 0 ) + return(clonestr("{\"result\":\"subscribed\"}")); + else return(clonestr("{\"error\":\"couldnt subscribe\"}")); +} + +TWO_STRINGS(SuperNET,gethexmsg,category,subcategory) +{ + bits256 categoryhash,subhash; struct category_msg *m; char *hexstr; cJSON *retjson; struct private_chain *cat; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + categoryhash = calc_categoryhashes(&subhash,category,subcategory); + if ( (m= category_gethexmsg(myinfo,&cat,categoryhash,subhash)) != 0 ) { - for (i=len; urlstr[i]!=0; i++) - if ( urlstr[i] == '\r' || urlstr[i] == '\n' ) - break; - if ( i == len && (urlstr[len] == '\r' || urlstr[len] == '\n') ) + hexstr = calloc(1,m->len*2+1); + init_hexbytes_noT(hexstr,m->msg,m->len); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result",hexstr); + free(hexstr); + return(jprint(retjson,1)); + } else return(clonestr("{\"result\":\"no message\"}")); +} + +THREE_STRINGS(SuperNET,posthexmsg,category,subcategory,hexmsg) +{ + bits256 categoryhash,subhash; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + categoryhash = calc_categoryhashes(&subhash,category,subcategory); + category_posthexmsg(myinfo,categoryhash,subhash,hexmsg,tai_now(),remoteaddr); + return(clonestr("{\"result\":\"posted message\"}")); +} + +THREE_STRINGS(SuperNET,announce,category,subcategory,message) +{ + bits256 categoryhash,subhash; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + categoryhash = calc_categoryhashes(&subhash,category,subcategory); + return(SuperNET_categorymulticast(myinfo,0,categoryhash,subhash,message,juint(json,"maxdelay"),juint(json,"broadcast"),juint(json,"plaintext"),json,remoteaddr)); +} + +THREE_STRINGS(SuperNET,survey,category,subcategory,message) +{ + bits256 categoryhash,subhash; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + categoryhash = calc_categoryhashes(&subhash,category,subcategory); + return(SuperNET_categorymulticast(myinfo,1,categoryhash,subhash,message,juint(json,"maxdelay"),juint(json,"broadcast"),juint(json,"plaintext"),json,remoteaddr)); +} + +STRING_ARG(SuperNET,wif2priv,wif) +{ + bits256 privkey; char str[65]; uint8_t privkeytype; cJSON *retjson = cJSON_CreateObject(); + if ( bitcoin_wif2priv(&privkeytype,&privkey,wif) == sizeof(privkey) ) + { + jaddstr(retjson,"result","success"); + jaddstr(retjson,"privkey",bits256_str(str,privkey)); + jaddnum(retjson,"type",privkeytype); + } else jaddstr(retjson,"error","couldnt convert wif"); + return(jprint(retjson,1)); +} + +STRING_ARG(SuperNET,priv2wif,priv) +{ + bits256 privkey; char wifstr[65]; uint8_t wiftype; cJSON *retjson = cJSON_CreateObject(); + if ( is_hexstr(priv,0) == sizeof(bits256)*2 ) + { + wiftype = coin != 0 ? coin->chain->wiftype : 0x80; + decode_hex(privkey.bytes,sizeof(privkey),priv); + if ( bitcoin_priv2wif(wifstr,privkey,wiftype) > 0 ) { - len++; - continue; - } - urlstr[i] = 0; - if ( (n= Supernet_lineparse(key,sizeof(key),value,bufsize,&urlstr[len])) > 0 ) - { - if ( value[0] != 0 ) - jaddstr(json,key,value); - else jaddistr(array,key); - len += (n + 1); - if ( strcmp(key,"Content-Length") == 0 && (datalen= atoi(value)) > 0 ) + jaddstr(retjson,"result","success"); + jaddstr(retjson,"privkey",priv); + jaddnum(retjson,"type",wiftype); + jaddstr(retjson,"wif",wifstr); + } else jaddstr(retjson,"error","couldnt convert privkey"); + } else jaddstr(retjson,"error","non 32 byte hex privkey"); + return(jprint(retjson,1)); +} + +STRING_ARG(SuperNET,myipaddr,ipaddr) +{ + cJSON *retjson = cJSON_CreateObject(); + if ( myinfo->ipaddr[0] == 0 ) + { + if ( is_ipaddr(ipaddr) != 0 ) + strcpy(myinfo->ipaddr,ipaddr); + } + jaddstr(retjson,"result",myinfo->ipaddr); + return(jprint(retjson,1)); +} + +STRING_ARG(SuperNET,setmyipaddr,ipaddr) +{ + cJSON *retjson = cJSON_CreateObject(); + if ( is_ipaddr(ipaddr) != 0 ) + { + strcpy(myinfo->ipaddr,ipaddr); + jaddstr(retjson,"result",myinfo->ipaddr); + } else jaddstr(retjson,"error","illegal ipaddr"); + return(jprint(retjson,1)); +} + +STRING_ARG(SuperNET,utime2utc,utime) +{ + uint32_t utc = 0; cJSON *retjson = cJSON_CreateObject(); + utc = OS_conv_utime(utime); + char str[65]; printf("utime.%s -> %u -> %s\n",utime,utc,utc_str(str,utc)); + jaddnum(retjson,"result",utc); + return(jprint(retjson,1)); +} + +INT_ARG(SuperNET,utc2utime,utc) +{ + char str[65]; cJSON *retjson = cJSON_CreateObject(); + jaddstr(retjson,"result",utc_str(str,utc)); + return(jprint(retjson,1)); +} + +ZERO_ARGS(SuperNET,logout) +{ + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + iguana_walletlock(myinfo,coin); + return(clonestr("{\"result\":\"logged out\"}")); +} + +ZERO_ARGS(SuperNET,activehandle) +{ + cJSON *retjson; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + retjson = SuperNET_rosettajson(myinfo->persistent_priv,0); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"handle",myinfo->handle); + jaddbits256(retjson,"persistent",myinfo->myaddr.persistent); + if ( myinfo->expiration != 0 ) + { + jaddstr(retjson,"status","unlocked"); + jaddnum(retjson,"duration",myinfo->expiration - time(NULL)); + } else jaddstr(retjson,"status","locked"); + SuperNET_MYINFOadd(myinfo); + return(jprint(retjson,1)); +} + +struct supernet_info *SuperNET_accountfind(cJSON *json) +{ + int32_t num; char *decryptstr; struct supernet_info M,*myinfo; struct iguana_info *coin = 0; + char *password,*permanentfile,*passphrase,*remoteaddr,*perspriv; + myinfo = 0; + if ( (password= jstr(json,"password")) == 0 ) + password = ""; + if ( (permanentfile= jstr(json,"permanentfile")) == 0 ) + permanentfile = ""; + if ( (passphrase= jstr(json,"passphrase")) == 0 ) + passphrase = ""; + remoteaddr = jstr(json,"remoteaddr"); + if ( (passphrase == 0 || passphrase[0] == 0) && (decryptstr= SuperNET_decryptjson(IGUANA_CALLARGS,password,permanentfile)) != 0 ) + { + if ( (json= cJSON_Parse(decryptstr)) != 0 ) + { + memset(&M,0,sizeof(M)); + if ( (perspriv= jstr(json,"persistent_priv")) != 0 && strlen(perspriv) == sizeof(bits256)*2 ) { - data = &urlstr[totallen - datalen]; - data[-1] = 0; - //printf("post.(%s) (%c)\n",data,data[0]); - jaddstr(json,"POST",data); + M.persistent_priv = bits256_conv(perspriv); + SuperNET_setkeys(&M,0,0,0); + if ( (myinfo = SuperNET_MYINFOfind(&num,M.myaddr.persistent)) != 0 ) + { + //printf("found account.(%s) %s %llu\n",myinfo!=0?myinfo->handle:"",M.myaddr.NXTADDR,(long long)M.myaddr.nxt64bits); + return(myinfo); + } } - } else break; - } - jadd(json,"lines",array); - return(json); -} - -char *SuperNET_rpcparse(struct supernet_info *myinfo,char *retbuf,int32_t bufsize,int32_t *jsonflagp,int32_t *postflagp,char *urlstr,char *remoteaddr) -{ - cJSON *tokens,*argjson,*json = 0; char urlmethod[16],*data,url[1024],*retstr,*token = 0; int32_t i,j,n; - //printf("rpcparse.(%s)\n",urlstr); - for (i=0; ihandle:"",M.myaddr.NXTADDR,(long long)M.myaddr.nxt64bits); + return(myinfo); + } + } else printf("no passphrase in (%s)\n",jprint(json,0)); + free_json(json); + } else printf("cant parse.(%s)\n",decryptstr); + free(decryptstr); } - if ( token != 0 ) - jaddistr(tokens,token); - if ( (json= SuperNET_urlconv(retbuf,bufsize,urlstr+n)) != 0 ) + return(SuperNET_MYINFO(0)); +} + +FOUR_STRINGS(SuperNET,login,handle,password,permanentfile,passphrase) +{ + char *str,*decryptstr = 0; cJSON *argjson,*item,*walletitem; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( handle != 0 && handle[0] != 0 ) + safecopy(myinfo->handle,handle,sizeof(myinfo->handle)); + else memset(myinfo->handle,0,sizeof(myinfo->handle)); + if ( password == 0 || password[0] == 0 ) + password = passphrase; + /*if ( password != 0 && password[0] != 0 ) + safecopy(myinfo->secret,password,sizeof(myinfo->secret)); + else if ( passphrase != 0 && passphrase[0] != 0 ) + safecopy(myinfo->secret,passphrase,sizeof(myinfo->secret));*/ + if ( permanentfile != 0 ) + safecopy(myinfo->permanentfile,permanentfile,sizeof(myinfo->permanentfile)); + if ( (decryptstr= SuperNET_decryptjson(IGUANA_CALLARGS,password,myinfo->permanentfile)) != 0 ) { - jadd(json,"tokens",tokens); - jaddstr(json,"urlmethod",urlmethod); - if ( (data= jstr(json,"POST")) == 0 || (argjson= cJSON_Parse(data)) == 0 ) + if ( (argjson= cJSON_Parse(decryptstr)) != 0 ) { - argjson = cJSON_CreateObject(); - if ( (n= cJSON_GetArraySize(tokens)) > 0 ) + if ( jobj(argjson,"error") == 0 ) { - jaddstr(argjson,"agent",jstri(tokens,0)); - if ( n > 1 ) - jaddstr(argjson,"method",jstri(tokens,1)); - for (i=2; iexpiration,password); + if ( myinfo->decryptstr != 0 ) + free(myinfo->decryptstr); + myinfo->decryptstr = decryptstr; + if ( (passphrase= jstr(argjson,"passphrase")) != 0 ) { - if ( i == n-1 ) - jaddstr(argjson,"data",jstri(tokens,i)); - else - { - jaddstr(argjson,jstri(tokens,i),jstri(tokens,i+1)); - i++; - } + SuperNET_setkeys(myinfo,passphrase,(int32_t)strlen(passphrase),1); + free_json(argjson); + myinfo->expiration = (uint32_t)(time(NULL) + 3600); + return(SuperNET_activehandle(IGUANA_CALLARGS)); } - } + else + { + free_json(argjson); + return(clonestr("{\"error\":\"cant find passphrase in decrypted json\"}")); + } + } else free_json(argjson); + } + else + { + free(decryptstr); + return(clonestr("{\"error\":\"cant parse decrypted json\"}")); } - retstr = SuperNET_JSON(myinfo,argjson,remoteaddr); - printf("(%s) -> (%s) postflag.%d (%s)\n",urlstr,cJSON_Print(json),*postflagp,jprint(argjson,0)); - return(retstr); } - return(clonestr("{\"error\":\"couldnt process packet\"}")); + if ( passphrase != 0 && passphrase[0] != 0 ) + { + SuperNET_setkeys(myinfo,passphrase,(int32_t)strlen(passphrase),1); + if ( myinfo->decryptstr != 0 && (argjson= cJSON_Parse(myinfo->decryptstr)) != 0 ) + { + if ( jobj(argjson,"passphrase") != 0 ) + jdelete(argjson,"passphrase"); + if ( jobj(argjson,"error") != 0 ) + jdelete(argjson,"error"); + } + else + { + char rmd160str[41],str[65]; uint8_t rmd160[20]; + item = cJSON_CreateObject(); + calc_rmd160_sha256(rmd160,myinfo->persistent_pubkey33,33); + init_hexbytes_noT(rmd160str,rmd160,20); + jaddstr(item,rmd160str,bits256_str(str,myinfo->persistent_priv)); + walletitem = cJSON_CreateObject(); + jadd(walletitem,"default",item); + argjson = cJSON_CreateObject(); + jadd(argjson,"wallet",walletitem); + myinfo->dirty = (uint32_t)time(NULL); + } + jaddstr(argjson,"passphrase",passphrase); + if ( (str= SuperNET_encryptjson(myinfo,coin,argjson,remoteaddr,password,myinfo->permanentfile,"")) != 0 ) + free(str); + myinfo->expiration = (uint32_t)(time(NULL) + 3600); + return(SuperNET_activehandle(IGUANA_CALLARGS)); + } else return(clonestr("{\"error\":\"need passphrase\"}")); + printf("logged into (%s) %s %s\n",myinfo->myaddr.NXTADDR,myinfo->myaddr.BTC,myinfo->myaddr.BTCD); + return(SuperNET_activehandle(IGUANA_CALLARGS)); } +#include "../includes/iguana_apiundefs.h" diff --git a/deprecated/SuperNET.h b/deprecated/SuperNET.h new file mode 100755 index 000000000..9ae8f48d1 --- /dev/null +++ b/deprecated/SuperNET.h @@ -0,0 +1,200 @@ +/****************************************************************************** + * Copyright © 2014-2016 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#ifndef INCLUDED_SUPERNET_H +#define INCLUDED_SUPERNET_H + +deprecated file +#define SUPERNET_MAXHOPS 7 +#include "../crypto777/OS_portable.h" +#include "../includes/cJSON.h" +//#include "../crypto777/nanosrc/nn.h" + +#define SUPERNET_GETPEERSTR "{\"agent\":\"SuperNET\",\"method\":\"getpeers\",\"plaintext\":1}" +#define SUPERNET_STOPSTR "{\"agent\":\"SuperNET\",\"method\":\"stop\",\"plaintext\":1}" + +#define SUPERNET_MAXEXCHANGES 64 +#define SUPERNET_LBPORT 7770 +#define SUPERNET_PUBPORT 7771 +#define SUPERNET_PORTP2P 7770 +#define SUPERNET_NETWORKTIMEOUT 10000 +#define SUPERNET_POLLTIMEOUT 1 +#define SUPERNET_APIUSLEEP (SUPERNET_POLLTIMEOUT * 10000) +#define SUPERNET_MAXAGENTS 64 +#define NXT_TOKEN_LEN 160 +#define nn_errstr() nn_strerror(nn_errno()) +#define MAX_SERVERNAME 128 +#define SUPERNET_MAXRECVBUF (1024 * 1024 * 16) +#define SUPERNET_PINGGAP 6 + +#define SUPERNET_FORWARD 2 +#define SUPERNET_ISMINE 1 +#define SUPERNET_MAXDELAY (1000 * 3600) +#define SUPERNET_APIVERSION 0 +#define SUPERNET_MAXTIMEDIFF 10 + +#define CONNECTION_NUMBITS 10 +struct endpoint { queue_t nnrecvQ; int32_t nnsock,nnind; uint32_t ipbits; uint16_t port,directind; uint8_t transport,nn; }; + +struct direct_connection { char handler[16]; struct endpoint epbits; int32_t sock; }; + +struct supernet_msghdr +{ + bits256 dest,sender,arg; + uint8_t type,serlen[3],ser_nonce[4],ser_timestamp[4],ser_duration[4]; + char agent[8],coin[5],func; + uint8_t data[]; +}; + +struct supernet_agent +{ + struct queueitem DL; queue_t recvQ; uint64_t totalrecv,totalsent; + int32_t (*recvfunc)(void *myinfo,struct supernet_agent *,struct supernet_msghdr *msg,uint8_t *data,int32_t datalen); + cJSON *networks; + char name[9],ipaddr[64],reppoint[64],pubpoint[64]; int32_t reqsock,repsock,pubsock,subsock; + uint32_t ipbits,dead; int32_t num,sock; uint16_t port,pubport,repport; +}; + +struct supernet_address +{ + bits256 pubkey,iphash,persistent; + uint32_t selfipbits,myipbits; int32_t confirmed,totalconfirmed; uint64_t nxt64bits; + char NXTADDR[32],BTC[64],BTCD[64]; +}; + +struct supernet_info; +#include "../basilisk/basilisk.h" +#include "../gecko/gecko.h" + +struct supernet_info +{ + char ipaddr[64],transport[8]; int32_t APISLEEP; int32_t iamrelay; uint32_t expiration,dirty; + int32_t Debuglevel,readyflag,dead,POLLTIMEOUT; char rpcsymbol[16],LBpoint[64],PUBpoint[64]; + bits256 privkey,persistent_priv,BTCmarkerhash,instantdex_category,pangea_category,basilisk_category; + char secret[2048],NXTAPIURL[512],permanentfile[1024]; uint8_t persistent_pubkey33[33]; + uint8_t *recvbuf[6]; + struct supernet_address myaddr; + int32_t LBsock,PUBsock,reqsock,subsock,networktimeout,maxdelay; + uint16_t LBport,PUBport,reqport,subport,rpcport,publicRPC,argport; + struct supernet_agent agents[SUPERNET_MAXAGENTS]; queue_t acceptQ; + struct basilisk_info basilisks; + int32_t numagents,numexchanges,IAMRELAY; + struct exchange_info *tradingexchanges[SUPERNET_MAXEXCHANGES]; + struct iguana_waccount *wallet; void *ctx; + char handle[1024],*decryptstr; + struct iguana_info *allcoins; int32_t allcoins_being_added,allcoins_numvirts; portable_mutex_t allcoins_mutex; + +}; + +/*struct supernet_endpoint +{ + char name[64]; struct endpoint ep; + int32_t (*nnrecvfunc)(struct supernet_info *,struct supernet_endpoint *,int32_t ind,uint8_t *msg,int32_t nnlen); + queue_t nnrecvQ; + int32_t nnsock,num; struct endpoint eps[]; +};*/ + +struct category_chain +{ + bits256 *weights,*blocks,category_hwm,genesishash,hwmhash; + int32_t hashlen,addrlen,maxblocknum; + struct supernet_info *myinfo; + void *categoryinfo,*subinfo; + int32_t (*blockhash_func)(struct category_chain *catchain,void *blockhashp,void *data,int32_t datalen); + int32_t (*payment_func)(struct category_chain *catchain,void *src,void *dest,uint64_t amount); + bits256 (*stake_func)(struct category_chain *catchain,void *addr,int32_t addrlen); + bits256 (*hit_func)(struct category_chain *catchain,int32_t height,void *prevgenerator,void *addr,void *blockhashp); + bits256 (*default_func)(struct category_chain *catchain,int32_t func,int32_t height,void *prevgenerator,void *addr,void *blockhashp,bits256 heaviest); + int32_t (*ishwm_func)(struct category_chain *catchain,int32_t prevheight,void *prevblockhashp,void *blockhashp,void *prevgenerator,void *addr); +}; + +struct crypto777_msghdr +{ + struct acct777_sig sig __attribute__((packed)); + bits256 prevhash,btchash; + uint8_t cmd[8]; + uint8_t serialized[]; +} __attribute__((packed)); + +extern struct private_chain *Categories; +struct category_msg { struct queueitem DL; struct tai t; uint64_t remoteipbits; int32_t len; uint8_t msg[]; }; + +struct exchange_quote { uint64_t satoshis,orderid,offerNXT,exchangebits; double price,volume; uint32_t timestamp,val; }; + +void expand_epbits(char *endpoint,struct endpoint epbits); +struct endpoint calc_epbits(char *transport,uint32_t ipbits,uint16_t port,int32_t type); + +struct supernet_info *SuperNET_MYINFO(char *passphrase); +void SuperNET_init(void *args); +char *SuperNET_JSON(struct supernet_info *myinfo,cJSON *json,char *remoteaddr,uint16_t port); + +char *SuperNET_jsonstr(struct supernet_info *myinfo,char *jsonstr,char *remoteaddr,uint16_t port); +char *SuperNET_DHTencode(struct supernet_info *myinfo,char *destip,bits256 category,bits256 subhash,char *hexmsg,int32_t maxdelay,int32_t broadcastflag,int32_t plaintext); +char *SuperNET_parser(struct supernet_info *myinfo,char *agent,char *method,cJSON *json,char *remoteaddr); +char *SuperNET_processJSON(struct supernet_info *myinfo,cJSON *json,char *remoteaddr,uint16_t port); +char *SuperNET_DHTsend(struct supernet_info *myinfo,uint64_t destipbits,bits256 category,bits256 subhash,char *hexmsg,int32_t maxdelay,int32_t broadcastflag,int32_t plaintext); +uint16_t SuperNET_API2num(char *agent,char *method); +int32_t SuperNET_num2API(char *agent,char *method,uint16_t num); +bits256 SuperNET_sharedseed(bits256 privkey,bits256 otherpub); +int32_t SuperNET_decrypt(bits256 *senderpubp,uint64_t *senderbitsp,uint32_t *timestampp,bits256 mypriv,bits256 mypub,uint8_t *dest,int32_t maxlen,uint8_t *src,int32_t len); +cJSON *SuperNET_argjson(cJSON *json); + +void *private_chain(bits256 categoryhash,bits256 subhash); +void *private_chainset(bits256 categoryhash,bits256 subhash,void *info); +struct private_chain *category_find(bits256 categoryhash,bits256 subhash); +void SuperNET_hexmsgprocess(struct supernet_info *myinfo,cJSON *retjson,cJSON *json,char *hexmsg,char *remoteaddr); +struct private_chain *category_processfunc(bits256 categoryhash,bits256 subhash,char *(*process_func)(struct supernet_info *myinfo,struct private_chain *cat,void *data,int32_t datalen,char *remoteaddr)); +char *pangea_hexmsg(struct supernet_info *myinfo,struct private_chain *cat,void *data,int32_t len,char *remoteaddr); +void pangea_queues(struct supernet_info *myinfo); + +int32_t SuperNET_str2hex(uint8_t *hex,char *str); +void SuperNET_hex2str(char *str,uint8_t *hex,int32_t len); +void SuperNET_hexmsgadd(struct supernet_info *myinfo,bits256 categoryhash,bits256 subhash,char *hexmsg,struct tai now,char *remoteaddr); +int32_t SuperNET_hexmsgfind(struct supernet_info *myinfo,bits256 category,bits256 subhash,char *hexmsg,int32_t addflag); +void category_posthexmsg(struct supernet_info *myinfo,bits256 categoryhash,bits256 subhash,char *hexmsg,struct tai now,char *remoteaddr); +void *category_subscribe(struct supernet_info *myinfo,bits256 category,bits256 keyhash); +struct category_msg *category_gethexmsg(struct supernet_info *myinfo,struct private_chain **catptrp,bits256 categoryhash,bits256 subhash); +char *SuperNET_htmlstr(char *fname,char *htmlstr,int32_t maxsize,char *agentstr); +queue_t *category_Q(struct private_chain **catptrp,bits256 categoryhash,bits256 subhash); + +char *SuperNET_categorymulticast(struct supernet_info *myinfo,int32_t surveyflag,bits256 categoryhash,bits256 subhash,char *message,int32_t maxdelay,int32_t broadcastflag,int32_t plaintext,cJSON *argjson,char *remoteaddr); +bits256 calc_categoryhashes(bits256 *subhashp,char *category,char *subcategory); +//struct category_chain *category_chain_functions(struct supernet_info *myinfo,bits256 categoryhash,bits256 subhash,int32_t hashlen,int32_t addrlen,void *hash_func,void *stake_func,void *hit_func,void *default_func,void *ishwm_func,void *payment_func); +#define category_default_latest() (*catchain->default_func)(catchain,'L',0,0,0,0,zero) +void category_init(struct supernet_info *myinfo); +char *SuperNET_keysinit(struct supernet_info *myinfo,char *jsonstr); +double instantdex_aveprice(struct supernet_info *myinfo,struct exchange_quote *sortbuf,int32_t max,double *totalvolp,char *base,char *rel,double volume,cJSON *argjson); +void SuperNET_setkeys(struct supernet_info *myinfo,void *pass,int32_t passlen,int32_t dosha256); +char *InstantDEX_hexmsg(struct supernet_info *myinfo,struct private_chain *cat,void *data,int32_t len,char *remoteaddr); +bits256 bitcoin_pubkey33(void *ctx,uint8_t data[33],bits256 privkey); +char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey,int32_t len); + +uint8_t *cards777_recover(uint8_t *shares[],uint8_t *sharenrs,int32_t M,int32_t numcards,int32_t N); +int32_t cards777_calcmofn(uint8_t *allshares,uint8_t *myshares[],uint8_t *sharenrs,int32_t M,bits256 *xoverz,int32_t numcards,int32_t N); +int32_t init_sharenrs(unsigned char sharenrs[255],unsigned char *orig,int32_t m,int32_t n); +struct supernet_info *SuperNET_MYINFOfind(int32_t *nump,bits256 pubkey); +void SuperNET_MYINFOadd(struct supernet_info *myinfo); +struct supernet_info *SuperNET_accountfind(cJSON *argjson); +int32_t SuperNET_MYINFOS(struct supernet_info **myinfos,int32_t max); +FILE *myfopen(char *fname,char *mode); +int32_t myfclose(FILE *fp); +cJSON *SuperNET_rosettajson(bits256 privkey,int32_t showprivs); +char *basilisk_hexmsg(struct supernet_info *myinfo,struct private_chain *cat,void *ptr,int32_t len,char *remoteaddr); + +int32_t basilisk_sendcmd(struct supernet_info *myinfo,char *destipaddr,char *type,uint32_t *basilisktagp,int32_t encryptflag,int32_t delaymillis,uint8_t *data,int32_t datalen,int32_t fanout,uint32_t nBits); // data must be offset by sizeof(iguana_msghdr) + + +#endif + diff --git a/SuperNET/Makefile b/deprecated/SuperNET/Makefile similarity index 100% rename from SuperNET/Makefile rename to deprecated/SuperNET/Makefile diff --git a/deprecated/SuperNET/SuperNET.c b/deprecated/SuperNET/SuperNET.c new file mode 100755 index 000000000..800b04fe5 --- /dev/null +++ b/deprecated/SuperNET/SuperNET.c @@ -0,0 +1,736 @@ +/****************************************************************************** + * Copyright © 2014-2015 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +//#include "SuperNET.h" +#define IGUANA_FORMS "[ \ +\ +{\"disp\":\"simple explorer\",\"agent\":\"ramchain\",\"method\":\"explore\",\"fields\":[{\"skip\":1,\"field\":\"search\",\"cols\":65,\"rows\":1}]}, \ +{\"disp\":\"block height\",\"agent\":\"ramchain\",\"method\":\"block\",\"fields\":[{\"field\":\"height\",\"cols\":10,\"rows\":1}]}, \ +{\"disp\":\"block hash\",\"agent\":\"ramchain\",\"method\":\"block\",\"fields\":[{\"field\":\"hash\",\"cols\":65,\"rows\":1}]}, \ +{\"disp\":\"txid\",\"agent\":\"ramchain\",\"method\":\"txid\",\"fields\":[{\"skip\":1,\"field\":\"hash\",\"cols\":65,\"rows\":1}]}, \ +{\"disp\":\"status\",\"agent\":\"ramchain\",\"method\":\"status\",\"fields\":[{\"skip\":1,\"field\":\"coin\",\"cols\":1,\"rows\":1}]}, \ +{\"disp\":\"bundleinfo\",\"agent\":\"ramchain\",\"method\":\"bundleinfo\",\"fields\":[{\"skip\":1,\"field\":\"height\",\"cols\":12,\"rows\":1}]}, \ +\ +{\"disp\":\"addcoin\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"fields\":[{\"skip\":1,\"field\":\"coin\",\"cols\":8,\"rows\":1}]}, \ +{\"disp\":\"pausecoin\",\"agent\":\"iguana\",\"method\":\"pausecoin\",\"fields\":[{\"skip\":1,\"field\":\"coin\",\"cols\":1,\"rows\":1}]}, \ +{\"disp\":\"startcoin\",\"agent\":\"iguana\",\"method\":\"startcoin\",\"fields\":[{\"skip\":1,\"field\":\"coin\",\"cols\":1,\"rows\":1}]}, \ +{\"disp\":\"addnode\",\"agent\":\"iguana\",\"method\":\"addnode\",\"fields\":[{\"skip\":1,\"field\":\"ipaddr\",\"cols\":32,\"rows\":1}]}, \ +{\"disp\":\"maxpeers\",\"agent\":\"iguana\",\"method\":\"maxpeers\",\"fields\":[{\"skip\":1,\"field\":\"max\",\"cols\":8,\"rows\":1}]}, \ +{\"disp\":\"peers\",\"agent\":\"iguana\",\"method\":\"peers\",\"fields\":[{\"field\":\"coin\",\"cols\":16,\"rows\":1}]}, \ +{\"disp\":\"nodestatus\",\"agent\":\"iguana\",\"method\":\"nodestatus\",\"fields\":[{\"skip\":1,\"field\":\"ipaddr\",\"cols\":32,\"rows\":1}]}, \ +\ +{\"disp\":\"rates\",\"agent\":\"PAX\",\"method\":\"rates\",\"fields\":[{\"skip\":1,\"field\":\"peg\",\"cols\":16,\"rows\":1}]},\ +{\"disp\":\"prices\",\"agent\":\"PAX\",\"method\":\"prices\",\"fields\":[{\"skip\":1,\"field\":\"peg\",\"cols\":16,\"rows\":1}]},\ +{\"agent\":\"PAX\",\"method\":\"lock\",\"fields\":[{\"skip\":1,\"field\":\"peg\",\"cols\":16,\"rows\":1},{\"skip\":1,\"field\":\"lockdays\",\"cols\":6,\"rows\":1},{\"skip\":1,\"field\":\"units\",\"cols\":12,\"rows\":1}]}, \ +{\"agent\":\"PAX\",\"method\":\"redeem\",\"fields\":[{\"skip\":1,\"field\":\"txid\",\"cols\":65,\"rows\":1},{\"skip\":1,\"field\":\"dest\",\"cols\":65,\"rows\":1}]},\ +{\"disp\":\"balance\",\"agent\":\"PAX\",\"method\":\"balance\",\"fields\":[{\"skip\":1,\"field\":\"address\",\"cols\":44,\"rows\":1}]},\ +{\"agent\":\"PAX\",\"method\":\"rollover\",\"fields\":[{\"skip\":1,\"field\":\"txid\",\"cols\":16,\"rows\":1},{\"skip\":1,\"field\":\"newpeg\",\"cols\":16,\"rows\":1},{\"skip\":1,\"field\":\"newlockdays\",\"cols\":6,\"rows\":1}]},\ +{\"agent\":\"PAX\",\"method\":\"swap\",\"fields\":[{\"skip\":1,\"field\":\"txid\",\"cols\":16,\"rows\":1},{\"skip\":1,\"field\":\"othertxid\",\"cols\":16,\"rows\":1}]},\ +{\"agent\":\"PAX\",\"method\":\"bet\",\"fields\":[{\"skip\":1,\"field\":\"peg\",\"cols\":16,\"rows\":1},{\"skip\":1,\"field\":\"price\",\"cols\":16,\"rows\":1},{\"skip\":1,\"field\":\"amount\",\"cols\":16,\"rows\":1}]},\ +\ +{\"agent\":\"InstantDEX\",\"method\":\"placebid\",\"fields\":[{\"skip\":1,\"field\":\"base\",\"cols\":8,\"rows\":1},{\"skip\":1,\"field\":\"rel\",\"cols\":8,\"rows\":1},{\"skip\":1,\"field\":\"exchange\",\"cols\":16,\"rows\":1},{\"field\":\"price\",\"cols\":16,\"rows\":1},{\"field\":\"volume\",\"cols\":16,\"rows\":1}]}, \ +{\"agent\":\"InstantDEX\",\"method\":\"placeask\",\"fields\":[{\"skip\":1,\"field\":\"base\",\"cols\":8,\"rows\":1},{\"skip\":1,\"field\":\"rel\",\"cols\":8,\"rows\":1},{\"skip\":1,\"field\":\"exchange\",\"cols\":16,\"rows\":1},{\"field\":\"price\",\"cols\":16,\"rows\":1},{\"field\":\"volume\",\"cols\":16,\"rows\":1}]}, \ +{\"agent\":\"InstantDEX\",\"method\":\"orderbook\",\"fields\":[{\"skip\":1,\"field\":\"base\",\"cols\":8,\"rows\":1},{\"skip\":1,\"field\":\"rel\",\"cols\":8,\"rows\":1},{\"skip\":1,\"field\":\"exchange\",\"cols\":16,\"rows\":1}]}, \ +{\"disp\":\"orderstatus\",\"agent\":\"InstantDEX\",\"method\":\"orderstatus\",\"fields\":[{\"skip\":1,\"field\":\"orderid\",\"cols\":32,\"rows\":1}]}, \ +{\"disp\":\"cancelorder\",\"agent\":\"InstantDEX\",\"method\":\"cancelorder\",\"fields\":[{\"skip\":1,\"field\":\"orderid\",\"cols\":32,\"rows\":1}]}, \ +{\"disp\":\"balance\",\"agent\":\"InstantDEX\",\"method\":\"balance\",\"fields\":[{\"skip\":1,\"field\":\"exchange\",\"cols\":16,\"rows\":1}]}, \ +{\"newline\":0,\"disp\":\"allorderbooks\",\"agent\":\"InstantDEX\",\"method\":\"allorderbooks\",\"fields\":[{\"skip\":1,\"field\":\"allorderbooks\",\"cols\":1,\"rows\":1}]}, \ +{\"newline\":0,\"disp\":\"openorders\",\"agent\":\"InstantDEX\",\"method\":\"openorders\",\"fields\":[{\"skip\":1,\"field\":\"openorders\",\"cols\":1,\"rows\":1}]}, \ +{\"newline\":0,\"disp\":\"tradehistory\",\"agent\":\"InstantDEX\",\"method\":\"tradehistory\",\"fields\":[{\"skip\":1,\"field\":\"tradehistory\",\"cols\":1,\"rows\":1}]}, \ +{\"disp\":\"allexchanges\",\"agent\":\"InstantDEX\",\"method\":\"allexchanges\",\"fields\":[{\"skip\":1,\"field\":\"allexchanges\",\"cols\":1,\"rows\":1}]}, \ +\ +{\"agent\":\"pangea\",\"method\":\"bet\",\"fields\":[{\"skip\":1,\"field\":\"tableid\",\"cols\":24,\"rows\":1},{\"skip\":1,\"field\":\"amount\",\"cols\":24,\"rows\":1}]}, \ +{\"disp\":\"call\",\"agent\":\"pangea\",\"method\":\"call\",\"fields\":[{\"skip\":1,\"field\":\"tableid\",\"cols\":1,\"rows\":1}]}, \ +{\"disp\":\"fold\",\"agent\":\"pangea\",\"method\":\"fold\",\"fields\":[{\"skip\":1,\"field\":\"tableid\",\"cols\":1,\"rows\":1}]}, \ +{\"disp\":\"status\",\"agent\":\"pangea\",\"method\":\"status\",\"fields\":[{\"skip\":1,\"field\":\"tableid\",\"cols\":1,\"rows\":1}]}, \ +{\"disp\":\"hand history\",\"agent\":\"pangea\",\"method\":\"handhistory\",\"fields\":[{\"skip\":1,\"field\":\"tableid\",\"cols\":1,\"rows\":1}]}, \ +{\"disp\":\"history\",\"agent\":\"pangea\",\"method\":\"history\",\"fields\":[{\"skip\":1,\"field\":\"coin\",\"cols\":1,\"rows\":1}]}, \ +{\"disp\":\"follow\",\"agent\":\"pangea\",\"method\":\"follow\",\"fields\":[{\"skip\":1,\"field\":\"tableid\",\"cols\":24,\"rows\":1}]}, \ +{\"disp\":\"lobby\",\"agent\":\"pangea\",\"method\":\"lobby\",\"fields\":[{\"skip\":1,\"field\":\"coin\",\"cols\":8,\"rows\":1}]}, \ +{\"disp\":\"join\",\"agent\":\"pangea\",\"method\":\"join\",\"fields\":[{\"skip\":1,\"field\":\"tableid\",\"cols\":24,\"rows\":1}]}, \ +{\"agent\":\"pangea\",\"method\":\"buyin\",\"fields\":[{\"skip\":1,\"field\":\"coin\",\"cols\":8,\"rows\":1},{\"skip\":1,\"field\":\"tableid\",\"cols\":24,\"rows\":1},{\"skip\":1,\"field\":\"amount\",\"cols\":12,\"rows\":1}]}, \ +{\"agent\":\"pangea\",\"method\":\"newtournament\",\"fields\":[{\"field\":\"mintables\",\"cols\":8,\"rows\":1},{\"field\":\"maxtables\",\"cols\":4,\"rows\":1},{\"field\":\"starttime\",\"cols\":16,\"rows\":1},{\"field\":\"prizefund\",\"cols\":12,\"rows\":1},{\"field\":\"coin\",\"cols\":12,\"rows\":1}]}, \ +{\"agent\":\"pangea\",\"method\":\"newtable\",\"fields\":[{\"field\":\"minplayers\",\"cols\":4,\"rows\":1},{\"field\":\"maxplayers\",\"cols\":4,\"rows\":1},{\"field\":\"rake\",\"cols\":4,\"rows\":1},{\"field\":\"bigblind\",\"cols\":12,\"rows\":1},{\"field\":\"ante\",\"cols\":12,\"rows\":1},{\"field\":\"minbuyin\",\"cols\":12,\"rows\":1},{\"field\":\"maxbuyin\",\"cols\":12,\"rows\":1}]}, \ +{\"disp\":\"leave\",\"agent\":\"pangea\",\"method\":\"leave\",\"fields\":[{\"skip\":1,\"field\":\"tableid\",\"cols\":8,\"rows\":1}]}, \ +\ +{\"agent\":\"jumblr\",\"method\":\"send\",\"fields\":[{\"skip\":1,\"field\":\"coin\",\"cols\":8,\"rows\":1},{\"skip\":1,\"field\":\"amount\",\"cols\":13,\"rows\":1},{\"skip\":1,\"field\":\"address\",\"cols\":8,\"rows\":1}]}, \ +{\"agent\":\"jumblr\",\"method\":\"invoice\",\"fields\":[{\"skip\":1,\"field\":\"coin\",\"cols\":8,\"rows\":1},{\"skip\":1,\"field\":\"amount\",\"cols\":13,\"rows\":1},{\"skip\":1,\"field\":\"address\",\"cols\":8,\"rows\":1}]}, \ +{\"agent\":\"jumblr\",\"method\":\"shuffle\",\"fields\":[{\"skip\":1,\"field\":\"coin\",\"cols\":8,\"rows\":1},{\"skip\":1,\"field\":\"amount\",\"cols\":13,\"rows\":1}]}, \ +{\"agent\":\"jumblr\",\"method\":\"balance\",\"fields\":[{\"skip\":1,\"field\":\"coin\",\"cols\":8,\"rows\":1},{\"skip\":1,\"field\":\"address\",\"cols\":13,\"rows\":1}]}, \ +\ +{\"newline\":0,\"disp\":\"InstantDEX\",\"agent\":\"iguana\",\"method\":\"setagent\",\"fields\":[{\"field\":\"InstantDEX\",\"cols\":1,\"rows\":1}]}, \ +{\"newline\":0,\"disp\":\"PAX\",\"agent\":\"iguana\",\"method\":\"setagent\",\"fields\":[{\"field\":\"PAX\",\"cols\":1,\"rows\":1}]}, \ +{\"newline\":0,\"disp\":\"pangea\",\"agent\":\"iguana\",\"method\":\"setagent\",\"fields\":[{\"field\":\"pangea\",\"cols\":1,\"rows\":1}]}, \ +{\"newline\":0,\"disp\":\"jumblr\",\"agent\":\"iguana\",\"method\":\"setagent\",\"fields\":[{\"field\":\"jumblr\",\"cols\":1,\"rows\":1}]}, \ +{\"disp\":\"ramchain\",\"agent\":\"iguana\",\"method\":\"setagent\",\"fields\":[{\"field\":\"ramchain\",\"cols\":1,\"rows\":1}]}, \ +{\"newline\":0,\"disp\":\"iguana\",\"agent\":\"iguana\",\"method\":\"setagent\",\"fields\":[{\"field\":\"iguana\",\"cols\":1,\"rows\":1}]}, \ +\ +{\"agent\":\"hash\",\"method\":\"NXT\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":100,\"rows\":1}]}, \ +{\"agent\":\"hash\",\"method\":\"curve25519\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"rmd160_sha256\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"sha256_sha256\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"base64_encode\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"base64_decode\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"crc32\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"sha512\",\"fields\":[{\"skip\":1,\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"sha384\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"sha256\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"sha224\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"rmd320\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"rmd256\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"rmd160\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"rmd128\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"sha1\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"md2\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"md4\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"md5\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"tiger\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"whirlpool\",\"fields\":[{\"skip\":1,\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"hmac_sha512\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"hmac_sha384\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"hmac_sha256\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"hmac_sha224\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"hmac_rmd320\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"hmac_rmd256\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"hmac_rmd160\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"hmac_rmd128\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"hmac_sha1\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"hmac_md2\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"hmac_md4\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"hmac_md5\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"hmac_tiger\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}, \ +{\"agent\":\"hash\",\"method\":\"hmac_whirlpool\",\"fields\":[{\"skip\":1,\"field\":\"password\",\"cols\":32,\"rows\":1},{\"field\":\"message\",\"cols\":64,\"rows\":3}]}\ +]" + +char *HTMLheader = +" \ + \ + \ + \ + \ +iguana \ + \ + \ +\ + \ +"; + +// Link + +char *HTMLfooter = +" \ +\ + \ + \ +\ + \ + \ + \ + \ + \ + \ + \ +\ + \ +"; + +#define HTML_EMIT(str) if ( (str) != 0 && (str)[0] != 0 ) strcpy(&retbuf[size],str), size += (int32_t)strlen(str) + +/* +struct endpoint find_epbits(struct relay_info *list,uint32_t ipbits,uint16_t port,int32_t type) +{ + int32_t i; struct endpoint epbits; + memset(&epbits,0,sizeof(epbits)); + if ( list != 0 && list->num > 0 ) + { + if ( type >= 0 ) + type = nn_portoffset(type); + for (i=0; inum&&i<(int32_t)(sizeof(list->connections)/sizeof(*list->connections)); i++) + if ( list->connections[i].ipbits == ipbits && (port == 0 || port == list->connections[i].port) && (type < 0 || type == list->connections[i].nn) ) + return(list->connections[i]); + } + return(epbits); +} + +int32_t add_relay(struct relay_info *list,struct endpoint epbits) +{ + list->connections[list->num % (sizeof(list->connections)/sizeof(*list->connections))] = epbits, list->num++; + if ( list->num > (sizeof(list->connections)/sizeof(*list->connections)) ) + printf("add_relay warning num.%d > %ld\n",list->num,(long)(sizeof(list->connections)/sizeof(*list->connections))); + return(list->num); +} + +int32_t nn_add_lbservers(struct supernet_info *myinfo,uint16_t port,uint16_t globalport,uint16_t relaysport,int32_t priority,int32_t sock,char servers[][MAX_SERVERNAME],int32_t num) +{ + int32_t i; char endpoint[512],pubendpoint[512]; struct endpoint epbits; uint32_t ipbits; + if ( num > 0 && servers != 0 && nn_setsockopt(sock,NN_SOL_SOCKET,NN_SNDPRIO,&priority,sizeof(priority)) >= 0 ) + { + for (i=0; i= 0 ) + { + printf("+R%s ",endpoint); + add_relay(&myinfo->active,epbits); + } + if ( myinfo->subclient >= 0 ) + { + if ( myinfo->iamrelay != 0 ) + { + epbits = calc_epbits("tcp",ipbits,relaysport,NN_PUB); + expand_epbits(pubendpoint,epbits); + if ( nn_connect(myinfo->subclient,pubendpoint) >= 0 ) + printf("+P%s ",pubendpoint); + } + epbits = calc_epbits("tcp",ipbits,globalport,NN_PUB); + expand_epbits(pubendpoint,epbits); + if ( nn_connect(myinfo->subclient,pubendpoint) >= 0 ) + printf("+P%s ",pubendpoint); + } + } + } + printf("added priority.%d\n",priority); + priority++; + } else printf("error setting priority.%d (%s)\n",priority,nn_errstr()); + return(priority); +} + +int32_t _lb_socket(struct supernet_info *myinfo,uint16_t port,uint16_t globalport,uint16_t relaysport,int32_t maxmillis,char servers[][MAX_SERVERNAME],int32_t num,char backups[][MAX_SERVERNAME],int32_t numbacks,char failsafes[][MAX_SERVERNAME],int32_t numfailsafes) +{ + int32_t lbsock,timeout,retrymillis,priority = 1; + if ( (lbsock= nn_socket(AF_SP,NN_REQ)) >= 0 ) + { + retrymillis = (maxmillis / 30) + 1; + printf("!!!!!!!!!!!! lbsock.%d !!!!!!!!!!!\n",lbsock); + if ( nn_setsockopt(lbsock,NN_SOL_SOCKET,NN_RECONNECT_IVL,&retrymillis,sizeof(retrymillis)) < 0 ) + printf("error setting NN_REQ NN_RECONNECT_IVL_MAX socket %s\n",nn_errstr()); + else if ( nn_setsockopt(lbsock,NN_SOL_SOCKET,NN_RECONNECT_IVL_MAX,&maxmillis,sizeof(maxmillis)) < 0 ) + fprintf(stderr,"error setting NN_REQ NN_RECONNECT_IVL_MAX socket %s\n",nn_errstr()); + timeout = SUPERNET_NETWORKTIMEOUT; + if ( 1 && nn_setsockopt(lbsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)) < 0 ) + printf("error setting NN_SOL_SOCKET NN_RCVTIMEO socket %s\n",nn_errstr()); + timeout = 100; + if ( 1 && nn_setsockopt(lbsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)) < 0 ) + printf("error setting NN_SOL_SOCKET NN_SNDTIMEO socket %s\n",nn_errstr()); + if ( num > 0 ) + priority = nn_add_lbservers(myinfo,port,globalport,relaysport,priority,lbsock,servers,num); + if ( numbacks > 0 ) + priority = nn_add_lbservers(myinfo,port,globalport,relaysport,priority,lbsock,backups,numbacks); + if ( numfailsafes > 0 ) + priority = nn_add_lbservers(myinfo,port,globalport,relaysport,priority,lbsock,failsafes,numfailsafes); + } else printf("error getting req socket %s\n",nn_errstr()); + //printf("myinfo->lb.num %d\n",myinfo->lb.num); + return(lbsock); +} + +int32_t nn_lbsocket(struct supernet_info *myinfo,int32_t maxmillis,int32_t port,uint16_t globalport,uint16_t relaysport) +{ + char Cservers[32][MAX_SERVERNAME],Bservers[32][MAX_SERVERNAME],failsafes[4][MAX_SERVERNAME]; + int32_t n,m,lbsock,numfailsafes = 0; + printf("redo lbsocket()\n"), exit(-1); + //strcpy(failsafes[numfailsafes++],"5.9.56.103"); + //strcpy(failsafes[numfailsafes++],"5.9.102.210"); + // n = crackfoo_servers(Cservers,sizeof(Cservers)/sizeof(*Cservers),port); + // m = badass_servers(Bservers,sizeof(Bservers)/sizeof(*Bservers),port); + lbsock = _lb_socket(myinfo,port,globalport,relaysport,maxmillis,Bservers,m,Cservers,n*0,failsafes,numfailsafes); + return(lbsock); +} + +void add_standard_fields(char *request) +{ + cJSON *json; uint64_t tag; + if ( (json= cJSON_Parse(request)) != 0 ) + { + if ( get_API_nxt64bits(cJSON_GetObjectItem(json,"NXT")) == 0 ) + { + randombytes((void *)&tag,sizeof(tag)); + sprintf(request + strlen(request) - 1,",\"NXT\":\"%s\",\"tag\":\"%llu\"}",myinfo->NXTADDR,(long long)tag); + if ( myinfo->iamrelay != 0 && (myinfo->hostname[0] != 0 || myinfo->ipaddr[0] != 0) ) + sprintf(request + strlen(request) - 1,",\"iamrelay\":\"%s\"}",myinfo->hostname[0]!=0?myinfo->hostname:myinfo->myipaddr); + } + free_json(json); + } +} + +char *nn_loadbalanced(struct supernet_info *myinfo,uint8_t *data,int32_t len) +{ + char *msg,*jsonstr = 0; + int32_t sendlen,i,lbsock,recvlen = 0; + if ( (lbsock= myinfo->lbclient) < 0 ) + return(clonestr("{\"error\":\"invalid load balanced socket\"}")); + for (i=0; i<10; i++) + if ( (nn_socket_status(lbsock,1) & NN_POLLOUT) != 0 ) + break; + if ( myinfo->Debuglevel > 2 ) + printf("sock.%d NN_LBSEND.(%s)\n",lbsock,data); + //fprintf(stderr,"send to network\n"); + if ( (sendlen= nn_send(lbsock,data,len,0)) == len ) + { + for (i=0; i<10; i++) + if ( (nn_socket_status(lbsock,1) & NN_POLLIN) != 0 ) + break; + if ( (recvlen= nn_recv(lbsock,&msg,NN_MSG,0)) > 0 ) + { + if ( myinfo->Debuglevel > 2 ) + printf("LBRECV.(%s)\n",msg); + jsonstr = clonestr((char *)msg); + nn_freemsg(msg); + } + else + { + printf("nn_loadbalanced got recvlen.%d %s\n",recvlen,nn_errstr()); + jsonstr = clonestr("{\"error\":\"lb recv error, probably timeout\"}"); + } + } else printf("got sendlen.%d instead of %d %s\n",sendlen,len,nn_errstr()), jsonstr = clonestr("{\"error\":\"lb send error\"}"); + return(jsonstr); +} + +cJSON *relay_json(struct relay_info *list) +{ + cJSON *json,*array; char endpoint[512]; int32_t i; + if ( list == 0 || list->num == 0 ) + return(0); + array = cJSON_CreateArray(); + for (i=0; inum&&i<(int32_t)(sizeof(list->connections)/sizeof(*list->connections)); i++) + { + expand_epbits(endpoint,list->connections[i]); + jaddistr(array,endpoint); + } + json = cJSON_CreateObject(); + jadd(json,"endpoints",array); + //cJSON_AddItemToObject(json,"type",cJSON_CreateString(nn_typestr(list->mytype))); + //cJSON_AddItemToObject(json,"dest",cJSON_CreateString(nn_typestr(list->desttype))); + jaddnum(json,"total",list->num); + return(json); +} + +char *relays_jsonstr(struct supernet_info *myinfo,char *jsonstr,cJSON *argjson) +{ + cJSON *json; + if ( myinfo->iamrelay != 0 && myinfo->ipaddr[0] != 0 ) + { + json = cJSON_CreateObject(); + jaddstr(json,"relay",myinfo->ipaddr); + if ( myinfo->active.num > 0 ) + jadd(json,"relays",relay_json(&myinfo->active)); + return(jprint(json,1)); + } + else return(clonestr("{\"error\":\"get relay list from relay\"}")); +} + +int32_t init_SUPERNET_pullsock(struct supernet_info *myinfo,int32_t sendtimeout,int32_t recvtimeout) +{ + char bindaddr[64],*transportstr; int32_t iter; + myinfo->pullsock = -1; + if ( (myinfo->pullsock= nn_socket(AF_SP,NN_PULL)) < 0 ) + { + printf("error creating pullsock %s\n",nn_strerror(nn_errno())); + return(-1); + } + printf("got pullsock.%d\n",myinfo->pullsock); + if ( nn_settimeouts(myinfo->pullsock,sendtimeout,recvtimeout) < 0 ) + { + printf("error settime pullsock timeouts %s\n",nn_strerror(nn_errno())); + return(-1); + } + printf("PULLsock.%d\n",myinfo->pullsock); + for (iter=0; iter<2; iter++) + { + transportstr = (iter == 0) ? "ipc" : "inproc"; + sprintf(bindaddr,"%s://SuperNET.agents",transportstr); + if ( nn_bind(myinfo->pullsock,bindaddr) < 0 ) + { + printf("error binding pullsock to (%s) %s\n",bindaddr,nn_strerror(nn_errno())); + return(-1); + } + } + return(0); +} + +void busdata_init(struct supernet_info *myinfo,int32_t sendtimeout,int32_t recvtimeout,int32_t firstiter) +{ + char endpoint[512]; int32_t i; + myinfo->servicesock = myinfo->pubglobal = myinfo->pubrelays = myinfo->lbserver = -1; + endpoint[0] = 0; + if ( (myinfo->subclient= nn_createsocket(myinfo,endpoint,0,"NN_SUB",NN_SUB,0,sendtimeout,recvtimeout)) >= 0 ) + { + myinfo->pfd[myinfo->numservers++].fd = myinfo->subclient, printf("numservers.%d\n",myinfo->numservers); + nn_setsockopt(myinfo->subclient,NN_SUB,NN_SUB_SUBSCRIBE,"",0); + } else printf("error creating subclient\n"); + myinfo->lbclient = nn_lbsocket(myinfo,SUPERNET_NETWORKTIMEOUT,SUPERNET_PORT + LB_OFFSET,myinfo->port + PUBGLOBALS_OFFSET,myinfo->port + PUBRELAYS_OFFSET); + printf("LBclient.%d port.%d\n",myinfo->lbclient,SUPERNET_PORT + LB_OFFSET); + sprintf(endpoint,"%s://%s:%u",myinfo->transport,myinfo->ipaddr,myinfo->serviceport); + if ( (myinfo->servicesock= nn_createsocket(myinfo,endpoint,1,"NN_REP",NN_REP,myinfo->serviceport,sendtimeout,recvtimeout)) >= 0 ) + myinfo->pfd[myinfo->numservers++].fd = myinfo->servicesock, printf("numservers.%d\n",myinfo->numservers); + else printf("error creating servicesock\n"); + for (i=0; inumservers; i++) + myinfo->pfd[i].events = NN_POLLIN | NN_POLLOUT; + printf("myinfo->iamrelay %d, numservers.%d ipaddr.(%s://%s) port.%d serviceport.%d\n",myinfo->iamrelay,myinfo->numservers,myinfo->transport,myinfo->ipaddr,myinfo->port,myinfo->serviceport); +} + +void SuperNET_init(struct supernet_info *myinfo,char *jsonstr) +{ + char *str; + if ( jsonstr != 0 && (str= SuperNET_JSON(myinfo,jsonstr)) != 0 ) + free(str); + busdata_init(myinfo,10,1,0); + init_SUPERNET_pullsock(myinfo,10,10); +}*/ + +int32_t Supernet_lineparse(char *key,int32_t keymax,char *value,int32_t valuemax,char *src) +{ + int32_t a,b,c,n = 0; + key[0] = value[0] = 0; + while ( (c= src[n]) == ' ' || c == '\t' || c == '\n' || c == '\t' ) + n++; + while ( (c= src[n]) != ':' && c != 0 ) + { + *key++ = c; + if ( ++n >= keymax-1 ) + { + *key = 0; + printf("lineparse overflow key.(%s)\n",src); + return(-1); + } + } + *key = 0; + if ( src[n] != ':' ) + return(n); + n++; + while ( (c= src[n]) == ' ' || c == '\t' ) + n++; + while ( (c= src[n]) != 0 && c != '\r' && c != '\n' ) + { + if ( c == '%' && (a= src[n+1]) != 0 && (b= src[n+2]) != 0 ) + c = ((unhex(a) << 4) | unhex(b)), n += 2; + *value++ = c; + n++; + if ( n >= valuemax-1 ) + { + *value = 0; + printf("lineparse overflow.(%s)\n",src); + return(-1); + } + } + *value = 0; + if ( src[n] != 0 ) + { + n++; + while ( (c= src[n]) == '\r' || c == '\n' ) + n++; + } + return(n); +} + +cJSON *SuperNET_urlconv(char *value,int32_t bufsize,char *urlstr) +{ + int32_t i,n,totallen,datalen,len = 0; cJSON *json,*array; char key[8192],*data; + json = cJSON_CreateObject(); + array = cJSON_CreateArray(); + totallen = (int32_t)strlen(urlstr); + while ( 1 ) + { + for (i=len; urlstr[i]!=0; i++) + if ( urlstr[i] == '\r' || urlstr[i] == '\n' ) + break; + if ( i == len && (urlstr[len] == '\r' || urlstr[len] == '\n') ) + { + len++; + continue; + } + urlstr[i] = 0; + if ( (n= Supernet_lineparse(key,sizeof(key),value,bufsize,&urlstr[len])) > 0 ) + { + if ( value[0] != 0 ) + jaddstr(json,key,value); + else jaddistr(array,key); + len += (n + 1); + if ( strcmp(key,"Content-Length") == 0 && (datalen= atoi(value)) > 0 ) + { + data = &urlstr[totallen - datalen]; + data[-1] = 0; + //printf("post.(%s) (%c)\n",data,data[0]); + jaddstr(json,"POST",data); + } + } else break; + } + jadd(json,"lines",array); + return(json); +} + +char *SuperNET_rpcparse(struct supernet_info *myinfo,char *retbuf,int32_t bufsize,int32_t *postflagp,char *urlstr,char *remoteaddr) +{ + cJSON *tokens,*argjson,*json = 0; char urlmethod[16],*data,url[1024],*retstr,*token = 0; int32_t i,j,n; + //printf("rpcparse.(%s)\n",urlstr); + for (i=0; i 0 ) + { + jaddstr(argjson,"agent",jstri(tokens,0)); + if ( n > 1 ) + jaddstr(argjson,"method",jstri(tokens,1)); + for (i=2; i (%s) postflag.%d (%s)\n",urlstr,cJSON_Print(json),*postflagp,jprint(argjson,0)); + return(retstr); + } + return(clonestr("{\"error\":\"couldnt process packet\"}")); +} + +#ifdef notyet +int32_t iguana_htmlgen(char *retbuf,int32_t bufsize,char *result,char *error,cJSON *json,char *tabname,char *origjsonstr) +{ + char *url = "http://127.0.0.1:7778"; + int i,j,m,size = 0,n,rows,cols; cJSON *array,*obj,*array2,*item,*tmp; + char formheader[512],formfooter[512],clickname[512],buf[512],fieldbuf[512],fieldindex[2],postjson[8192]; + char *disp,*fieldname,*button,*agent,*method,*str; + bufsize--; + HTML_EMIT("

"); + sprintf(buf,"
"); + //sprintf(buf,"
COIN: "); + //HTML_EMIT(buf); + //HTML_EMIT(" Agent: "); HTML_EMIT(Default_agent); + + HTML_EMIT("

"); + HTML_EMIT(origjsonstr); HTML_EMIT(" -> "); + HTML_EMIT(""); + formheader[0] = formfooter[0] = 0; + if ( (array= jarray(&n,json,"forms")) != 0 ) + { + for (i=0; i function click_%s()\n{\n",clickname); + HTML_EMIT(buf); + sprintf(postjson,"%s/%s",agent,method); + //printf("form.%s button.%s [%s]\n",formname,button,postjson); + if ( (array2= jarray(&m,item,"fields")) != 0 ) + { + //sprintf(buf,"COIN = document.COIN_NAME.value;\n"); + //sprintf(postjson+strlen(postjson),"/%s/' + %s + '","coin","COIN"); + for (j=0; j (%s)\n",j,jprint(obj,0)); + sprintf(fieldindex,"%c",'A'+j); + if ( (fieldname= jstr(obj,"field")) != 0 ) + { + sprintf(buf,"%s = document.%s.%s.value;\n",fieldindex,clickname,fieldname); + HTML_EMIT(buf); + //sprintf(postjson+strlen(postjson),",\"%s\":\"' + %s + '\"",fieldname,fieldindex); + if ( juint(obj,"skip") == 0 ) + sprintf(postjson+strlen(postjson),"/%s/' + %s + '",fieldname,fieldindex); + else sprintf(postjson+strlen(postjson),"/' + %s + '",fieldindex); + } + } + //strcat(postjson,"}"); + sprintf(&retbuf[size],"location.href = '%s/%s';\n}\r\n",url,postjson), size += strlen(&retbuf[size]); + sprintf(formheader,"
",clickname,url); + HTML_EMIT(formheader); + disp = jstr(item,"disp"); + for (j=0; j",fieldname); + else sprintf(buf,"",cols,rows,fieldname,cols == 1 ? "hidden" : ""); + str = disp==0?jstr(obj,"disp"):disp; + sprintf(&retbuf[size],"\r\n",str!=0?str:fieldname,buf), size += strlen(&retbuf[size]); + } + sprintf(formfooter,"\n
%s %s
",button,clickname); + HTML_EMIT(formfooter); + } + } + } + HTML_EMIT("

"); HTML_EMIT(""); HTML_EMIT("

"); + return((int32_t)strlen(retbuf)); +} +#undef HTML_EMIT + +char *SuperNET_htmlresponse(char *retbuf,int32_t bufsize,int32_t *remainsp,int32_t localaccess,char *retstr,int32_t freeflag) +{ + static char *html = " %s "; + char *result=0,*error=0; int32_t n; cJSON *json,*formsjson; + retbuf[0] = 0; + /*if ( localaccess == 0 ) + sprintf(retbuf+strlen(retbuf),"Access-Control-Allow-Origin: *\r\n"); + else sprintf(retbuf+strlen(retbuf),"Access-Control-Allow-Origin: null\r\n"); + sprintf(retbuf+strlen(retbuf),"Access-Control-Allow-Credentials: true\r\n"); + sprintf(retbuf+strlen(retbuf),"Access-Control-Allow-Headers: Authorization, Content-Type\r\n"); + sprintf(retbuf+strlen(retbuf),"Access-Control-Allow-Methods: GET, POST\r\n"); + sprintf(retbuf+strlen(retbuf),"Cache-Control: no-cache, no-store, must-revalidate\r\n"); + sprintf(retbuf+strlen(retbuf),"Content-type: text/html\r\n"); + sprintf(retbuf+strlen(retbuf),"Content-Length: %8d\r\n\r\n",n);*/ + sprintf(retbuf+strlen(retbuf),"\n\r"); + n = (int32_t)strlen(retbuf); + formsjson = cJSON_Parse(IGUANA_FORMS); + if ( (json= cJSON_Parse(retstr)) == 0 ) + json = cJSON_CreateObject(); + jadd(json,"forms",formsjson); + error = jstr(json,"error"); + result = jstr(json,"result"); + //printf("process.(%s)\n",jprint(formsjson,0)); + n = iguana_htmlgen(&retbuf[n],bufsize-n,result,error,json,"iguana",Currentjsonstr); + free_json(json); + if ( n == 0 ) + { + n = (int32_t)(strlen(html) + strlen(retstr) + 1); + sprintf(retbuf+strlen(retbuf),html,retstr); + } + if ( freeflag != 0 ) + free(retstr); + if ( n > bufsize ) + { + printf("htmlresponse overflowed buffer[%d] with %d\n",bufsize,n); + exit(-1); + } + *remainsp = n; + return(retbuf); +} +#endif diff --git a/SuperNET/SuperNET.h b/deprecated/SuperNET/SuperNET.h similarity index 100% rename from SuperNET/SuperNET.h rename to deprecated/SuperNET/SuperNET.h diff --git a/SuperNET/busdata777.c b/deprecated/SuperNET/busdata777.c similarity index 100% rename from SuperNET/busdata777.c rename to deprecated/SuperNET/busdata777.c diff --git a/SuperNET/console777.c b/deprecated/SuperNET/console777.c similarity index 100% rename from SuperNET/console777.c rename to deprecated/SuperNET/console777.c diff --git a/SuperNET/hostnet777.c b/deprecated/SuperNET/hostnet777.c similarity index 100% rename from SuperNET/hostnet777.c rename to deprecated/SuperNET/hostnet777.c diff --git a/SuperNET/index.html b/deprecated/SuperNET/index.html similarity index 100% rename from SuperNET/index.html rename to deprecated/SuperNET/index.html diff --git a/SuperNET/m_clean b/deprecated/SuperNET/m_clean similarity index 100% rename from SuperNET/m_clean rename to deprecated/SuperNET/m_clean diff --git a/SuperNET/m_osx b/deprecated/SuperNET/m_osx similarity index 100% rename from SuperNET/m_osx rename to deprecated/SuperNET/m_osx diff --git a/SuperNET/m_pnacl b/deprecated/SuperNET/m_pnacl similarity index 100% rename from SuperNET/m_pnacl rename to deprecated/SuperNET/m_pnacl diff --git a/SuperNET/m_unix b/deprecated/SuperNET/m_unix similarity index 100% rename from SuperNET/m_unix rename to deprecated/SuperNET/m_unix diff --git a/deprecated/SuperNET/main.c b/deprecated/SuperNET/main.c new file mode 100755 index 000000000..57669e1eb --- /dev/null +++ b/deprecated/SuperNET/main.c @@ -0,0 +1,751 @@ +/****************************************************************************** + * Copyright © 2014-2015 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#define CHROMEAPP_NAME SuperNET +#define CHROMEAPP_STR "SuperNET" +#define CHROMEAPP_CONF "SuperNET.conf" +#define CHROMEAPP_MAIN SuperNET_main +#define CHROMEAPP_JSON SuperNET_JSON +#define CHROMEAPP_HANDLER Handler_SuperNET + +#include "../pnacl_main.h" +//#include "SuperNET.h" + +#ifndef MSG_NOSIGNAL +#define MSG_NOSIGNAL 0x4000 // Do not generate SIGPIPE +#endif + +// ALL globals must be here! + +int32_t nn_typelist[] = { NN_REP, NN_REQ, NN_RESPONDENT, NN_SURVEYOR, NN_PUB, NN_SUB, NN_PULL, NN_PUSH, NN_BUS, NN_PAIR }; +char *nn_transports[] = { "tcp", "ws", "ipc", "inproc", "tcpmux", "", "", "" }; + +void expand_epbits(char *endpoint,struct endpoint epbits) +{ + char ipaddr[64]; + if ( epbits.ipbits != 0 ) + expand_ipbits(ipaddr,epbits.ipbits); + else strcpy(ipaddr,"*"); + sprintf(endpoint,"%s://%s:%d",nn_transports[epbits.transport],ipaddr,epbits.port); +} + +struct endpoint calc_epbits(char *transport,uint32_t ipbits,uint16_t port,int32_t type) +{ + int32_t i; struct endpoint epbits; + memset(&epbits,0,sizeof(epbits)); + for (i=0; i<(int32_t)(sizeof(nn_transports)/sizeof(*nn_transports)); i++) + if ( strcmp(transport,nn_transports[i]) == 0 ) + { + epbits.ipbits = ipbits; + epbits.port = port; + epbits.transport = i; + epbits.nn = type; + break; + } + return(epbits); +} + +int32_t ismyaddress(struct supernet_info *myinfo,char *server) +{ + uint32_t ipbits; int32_t i,tlen; char str[64]; + for (i=0; iipaddr) == 0 || myinfo->ipbits == ipbits ) + { + printf("(%s) MATCHES me (%s)\n",server,myinfo->ipaddr); + return(1); + } + } + else if ( myinfo->my64bits == ipbits ) + return(1); + //printf("(%s) is not me (%s)\n",server,myipaddr); + return(0); +} + +char *nn_typestr(int32_t type) +{ + switch ( type ) + { + // Messages that need a response from the set of peers: SURVEY + case NN_SURVEYOR: return("NN_SURVEYOR"); break; + case NN_RESPONDENT: return("NN_RESPONDENT"); break; + // Messages that need a response, but only from one peer: REQ/REP + case NN_REQ: return("NN_REQ"); break; + case NN_REP: return("NN_REP"); break; + // One-way messages to one peer: PUSH/PULL + case NN_PUSH: return("NN_PUSH"); break; + case NN_PULL: return("NN_PULL"); break; + // One-way messages to all: PUB/SUB + case NN_PUB: return("NN_PUB"); break; + case NN_SUB: return("NN_SUB"); break; + case NN_BUS: return("NN_BUS"); break; + case NN_PAIR: return("NN_PAIR"); break; + } + return("NN_ERROR"); +} + +int32_t nn_oppotype(int32_t type) +{ + switch ( type ) + { + // Messages that need a response from the set of peers: SURVEY + case NN_SURVEYOR: return(NN_RESPONDENT); break; + case NN_RESPONDENT: return(NN_SURVEYOR); break; + // Messages that need a response, but only from one peer: REQ/REP + case NN_REQ: return(NN_REP); break; + case NN_REP: return(NN_REQ); break; + // One-way messages to one peer: PUSH/PULL + case NN_PUSH: return(NN_PULL); break; + case NN_PULL: return(NN_PUSH); break; + // One-way messages to all: PUB/SUB + case NN_PUB: return(NN_SUB); break; + case NN_SUB: return(NN_PUB); break; + case NN_BUS: return(NN_BUS); break; + case NN_PAIR: return(NN_PAIR); break; + } + return(-1); +} + +int32_t nn_portoffset(int32_t type) +{ + int32_t i; + for (i=0; i<(int32_t)(sizeof(nn_typelist)/sizeof(*nn_typelist)); i++) + if ( nn_typelist[i] == type ) + return(i + 2); + return(-1); +} + +int32_t nn_socket_status(int32_t nnsock,int32_t timeoutmillis) +{ + struct nn_pollfd pfd; + int32_t rc; + pfd.fd = nnsock; + pfd.events = NN_POLLIN | NN_POLLOUT; + if ( (rc= nn_poll(&pfd,1,timeoutmillis)) == 0 ) + return(pfd.revents); + else return(-1); +} + +int32_t SuperNET_msglen(struct supernet_msghdr *msg) +{ + return(msg->serlen[0] + ((int32_t)msg->serlen[1] << 8) + ((int32_t)msg->serlen[2] << 16)); +} + +int32_t SuperNET_msgvalidate(struct supernet_msghdr *msg) +{ + int32_t msglen = 0; + msglen = SuperNET_msglen(msg); + return(msglen); +} + +int32_t nn_settimeouts(int32_t sock,int32_t sendtimeout,int32_t recvtimeout) +{ + int32_t retrymillis,maxmillis; + if ( (maxmillis= SUPERNET_NETWORKTIMEOUT) == 0 ) + maxmillis = 3000; + retrymillis = maxmillis/40; + if ( nn_setsockopt(sock,NN_SOL_SOCKET,NN_RECONNECT_IVL,&retrymillis,sizeof(retrymillis)) < 0 ) + fprintf(stderr,"error setting NN_REQ NN_RECONNECT_IVL_MAX socket %s\n",nn_errstr()); + else if ( nn_setsockopt(sock,NN_SOL_SOCKET,NN_RECONNECT_IVL_MAX,&maxmillis,sizeof(maxmillis)) < 0 ) + fprintf(stderr,"error setting NN_REQ NN_RECONNECT_IVL_MAX socket %s\n",nn_errstr()); + else if ( sendtimeout > 0 && nn_setsockopt(sock,NN_SOL_SOCKET,NN_SNDTIMEO,&sendtimeout,sizeof(sendtimeout)) < 0 ) + fprintf(stderr,"error setting sendtimeout %s\n",nn_errstr()); + else if ( recvtimeout > 0 && nn_setsockopt(sock,NN_SOL_SOCKET,NN_RCVTIMEO,&recvtimeout,sizeof(recvtimeout)) < 0 ) + fprintf(stderr,"error setting sendtimeout %s\n",nn_errstr()); + else return(0); + return(-1); +} + +int32_t nn_createsocket(struct supernet_info *myinfo,char *endpoint,int32_t bindflag,char *name,int32_t type,uint16_t port,int32_t sendtimeout,int32_t recvtimeout) +{ + int32_t sock; + if ( (sock= nn_socket(AF_SP,type)) < 0 ) + fprintf(stderr,"error getting socket %s\n",nn_errstr()); + if ( bindflag != 0 ) + { + if ( endpoint[0] == 0 ) + expand_epbits(endpoint,calc_epbits(myinfo->transport,0,port,type)); + if ( nn_bind(sock,endpoint) < 0 ) + fprintf(stderr,"error binding to relaypoint sock.%d type.%d to (%s) (%s) %s\n",sock,type,name,endpoint,nn_errstr()); + else fprintf(stderr,"BIND.(%s) <- %s\n",endpoint,name); + } + else if ( bindflag == 0 && endpoint != 0 && endpoint[0] != 0 ) + { + if ( nn_connect(sock,endpoint) < 0 ) + fprintf(stderr,"error connecting to relaypoint sock.%d type.%d to (%s) (%s) %s\n",sock,type,name,endpoint,nn_errstr()); + else fprintf(stderr,"%s -> CONNECT.(%s)\n",name,endpoint); + } + if ( nn_settimeouts(sock,sendtimeout,recvtimeout) < 0 ) + { + fprintf(stderr,"nn_createsocket.(%s) %d\n",name,sock); + return(-1); + } + return(sock); +} + +bits256 SuperNET_OPRETURN(struct supernet_info *myinfo,char *symbol,double fee,uint8_t *buf,int32_t len) +{ + bits256 txid; + printf("send OPRETURN\n"); + return(txid); +} + +bits256 SuperNET_agentannounce(struct supernet_info *myinfo,struct supernet_agent *agent,cJSON *network) +{ + static const bits256 zero; + uint8_t buf[80 + sizeof(struct iguana_msghdr)],*data; + bits256 pubkey,sig; int32_t i,len=0; uint8_t netmagic[4]; char *sigstr,*announce,*pubkeystr; + memset(buf,0,sizeof(buf)); + data = &buf[sizeof(struct iguana_msghdr)]; + if ( (announce= jstr(network,"announce")) != 0 ) + { + data[len++] = SCRIPT_OPRETURN; + data[len++] = 75; + iguana_rwnum(1,&data[len],sizeof(myinfo->ipbits),&myinfo->ipbits); + for (i=0; i<7; i++) + if ( (data[len+i]= announce[i]) == 0 ) + break; + len = 13; + if ( (pubkeystr= jstr(network,"pubkey")) == 0 || strlen(pubkeystr) != sizeof(bits256)*2 ) + pubkeystr = GENESIS_PUBKEYSTR; + decode_hex(pubkey.bytes,sizeof(pubkey),pubkeystr); + len += iguana_rwbignum(1,&data[len],sizeof(pubkey),pubkey.bytes); // 45 bytes + if ( (sigstr= jstr(network,"sig")) != 0 && strlen(sigstr) == sizeof(bits256)*2 ) + { + sigstr = GENESIS_PUBKEYSTR; + len += iguana_rwbignum(1,&data[len],sizeof(sig),sig.bytes); // 77 bytes + } + decode_hex(netmagic,4,"e4c2d8e6"); + iguana_sethdr((struct iguana_msghdr *)buf,netmagic,"SuperNET",data,len); + return(SuperNET_OPRETURN(myinfo,"BTCD",.001,buf,len)); + } + printf("invalid SuperNET OPRETURN protocol.(%s)\n",announce!=0?announce:""); + return(zero); +} + +void Supernet_networkadd(struct supernet_info *myinfo,struct supernet_agent *agent,cJSON *network) +{ + int32_t sendtimeout=0,recvtimeout=0; + agent->pubpoint[0] = agent->reppoint[0] = 0; + if ( (agent->pubport= juint(network,"pubport")) > 1000 ) + { + agent->pubsock = nn_createsocket(myinfo,agent->pubpoint,1,"NN_PUB",NN_PUB,agent->pubport,sendtimeout,recvtimeout); + SuperNET_agentannounce(myinfo,agent,network); + } + else agent->pubport = -1; + if ( (agent->repport= juint(network,"repport")) > 1000 ) + agent->repsock = nn_createsocket(myinfo,agent->reppoint,1,"NN_REP",NN_REP,agent->repport,sendtimeout,recvtimeout); + else agent->repport = -1; + agent->subsock = nn_createsocket(myinfo,0,0,"NN_SUB",NN_SUB,0,sendtimeout,recvtimeout); + nn_setsockopt(agent->subsock,NN_SUB,NN_SUB_SUBSCRIBE,"",0); + agent->reqsock = nn_createsocket(myinfo,0,0,"NN_REQ",NN_REQ,0,sendtimeout,recvtimeout); +} + +int32_t SuperNET_agentcommand(struct supernet_info *myinfo,struct supernet_agent *agent,struct supernet_msghdr *H,uint8_t *buf,int32_t buflen) +{ + char *name; cJSON *json; int32_t i; + if ( strcmp(H->command,"register") == 0 ) + { + if ( (json= cJSON_Parse((char *)buf)) != 0 ) + { + if ( (name= jstr(json,"name")) != 0 ) + { + memset(agent->name,0,sizeof(agent->name)); + strncpy(agent->name,name,sizeof(agent->name)-1); + if ( (agent->networks= jarray(&agent->num,json,"networks")) != 0 ) + { + for (i=0; inum; i++) + Supernet_networkadd(myinfo,agent,jitem(agent->networks,i)); + } + } else free_json(json); + } + } + return(0); +} + +int32_t SuperNET_socket(int32_t bindflag,char *hostname,uint16_t port) +{ + int32_t opt,sock,result; uint32_t ipbits; char ipaddr[64]; struct timeval timeout; + struct sockaddr_in saddr; socklen_t addrlen; + addrlen = sizeof(saddr); + struct hostent *hostent = gethostbyname(hostname); + if ( hostent == NULL ) + { + printf("gethostbyname() returned error: %d",errno); + return(-1); + } + saddr.sin_family = AF_INET; + saddr.sin_port = htons(port); + memcpy(&saddr.sin_addr.s_addr,hostent->h_addr_list[0],hostent->h_length); + ipbits = (uint32_t)calc_ipbits(hostname); + //printf("ipbits.%08x vs %08x\n",ipbits,saddr.sin_addr.s_addr); + expand_ipbits(ipaddr,saddr.sin_addr.s_addr); + //if ( bindflag != 0 ) + // printf("iguana_socket.(%s:%d) bind.%d\n",ipaddr,port,bindflag), getchar(); + if ( strcmp(ipaddr,hostname) != 0 ) + printf("iguana_socket mismatch (%s) -> (%s)?\n",hostname,ipaddr); + if ( (sock= socket(AF_INET,SOCK_STREAM,0)) < 0 ) + { + if ( errno != ETIMEDOUT ) + printf("socket() failed: %s errno.%d", strerror(errno),errno); + return(-1); + } + if ( 0 && bindflag != 0 ) + { + timeout.tv_sec = 0; + timeout.tv_usec = 100000; + setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout,sizeof(timeout)); + } + opt = 1; + setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(void*)&opt,sizeof(opt)); +#ifdef __APPLE__ + setsockopt(sock,SOL_SOCKET,SO_NOSIGPIPE,&opt,sizeof(opt)); +#endif + result = (bindflag != 0) ? bind(sock,(struct sockaddr*)&saddr,addrlen) : connect(sock,(struct sockaddr *)&saddr,addrlen); + if ( result != 0 ) + { + if ( errno != ECONNRESET && errno != ENOTCONN && errno != ECONNREFUSED && errno != ETIMEDOUT && errno != EHOSTUNREACH ) + printf("connect(%s) port.%d failed: %s sock.%d. errno.%d\n",hostname,port,strerror(errno),sock,errno); + if ( sock >= 0 ) + close(sock); + return(-1); + } + if ( bindflag != 0 && listen(sock,3) != 0 ) + { + printf("listen(%s) port.%d failed: %s sock.%d. errno.%d\n",hostname,port,strerror(errno),sock,errno); + if ( sock >= 0 ) + close(sock); + return(-1); + } + return(sock); +} + +int32_t SuperNET_recv(int32_t sock,uint8_t *recvbuf,int32_t len) +{ + int32_t recvlen,remains = len; + while ( remains > 0 ) + { + if ( (recvlen= (int32_t)recv(sock,recvbuf,remains,0)) < 0 ) + { + if ( errno == EAGAIN ) + { + //printf("EAGAIN for len %d, remains.%d\n",len,remains); + usleep(10000); + } + else return(-errno); + } + else + { + if ( recvlen > 0 ) + { + remains -= recvlen; + recvbuf = &recvbuf[recvlen]; + } else usleep(10000); + } + } + return(len); +} + +int32_t SuperNET_send(struct supernet_info *myinfo,struct supernet_agent *agent,uint8_t *serialized,int32_t len) +{ + int32_t numsent,remains,sock; + if ( agent == 0 ) + return(-1); + if ( (sock= agent->sock) < 0 || agent->dead != 0 ) + { + return(-1); + } + remains = len; + while ( remains > 0 ) + { + if ( (numsent= (int32_t)send(sock,serialized,remains,MSG_NOSIGNAL)) < 0 ) + { + printf("send errno.%d %s\n",errno,strerror(errno)); + if ( errno != EAGAIN && errno != EWOULDBLOCK ) + { + printf("bad errno.%d %s zombify.%p\n",errno,strerror(errno),agent->name); + agent->dead = (uint32_t)time(NULL); + return(-errno); + } //else usleep(*sleeptimep), *sleeptimep *= 1.1; + } + else if ( remains > 0 ) + { + remains -= numsent; + serialized += numsent; + if ( remains > 0 ) + printf("SuperNET sent.%d remains.%d of len.%d\n",numsent,remains,len); + } + } + agent->totalsent += len; + //printf(" sent.%d bytes to %s\n",len,addr->ipaddr);// getchar(); + return(len); +} + +char *SuperNET_JSON(struct supernet_info *myinfo,cJSON *argjson,char *remoteaddr) +{ + char *agent,*method; + if ( (agent= jstr(argjson,"agent")) == 0 || (method= jstr(argjson,"method")) == 0 ) + return(clonestr("{\"error\":\"need both agent and method\"}")); +} + +void SuperNET_rpcloop(void *args) +{ + struct supernet_info *myinfo = args; + int32_t recvlen,bindsock,postflag,sock,remains,numsent,len; socklen_t clilen; + char remoteaddr[64],jsonbuf[8192],*buf,*retstr,*space;//,*retbuf; ,n,i,m + struct sockaddr_in cli_addr; uint32_t ipbits,i; uint16_t port; + int32_t size = 1024 * 1024 * 2; + port = SUPERNET_PORT; + bindsock = SuperNET_socket(1,"127.0.0.1",port); + printf("SuperNET_rpcloop 127.0.0.1:%d bind sock.%d\n",port,bindsock); + space = calloc(1,size); + while ( bindsock >= 0 ) + { + clilen = sizeof(cli_addr); + //printf("ACCEPT (%s:%d) on sock.%d\n","127.0.0.1",port,bindsock); + sock = accept(bindsock,(struct sockaddr *)&cli_addr,&clilen); + if ( sock < 0 ) + { + //printf("iguana_rpcloop ERROR on accept usock.%d\n",sock); + continue; + } + memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); + expand_ipbits(remoteaddr,ipbits); + memset(jsonbuf,0,sizeof(jsonbuf)); + remains = (int32_t)(sizeof(jsonbuf) - 1); + buf = jsonbuf; + recvlen = 0; + retstr = 0; + while ( remains > 0 ) + { + if ( (len= (int32_t)recv(sock,buf,remains,0)) < 0 ) + { + if ( errno == EAGAIN ) + { + printf("EAGAIN for len %d, remains.%d\n",len,remains); + usleep(10000); + } + break; + } + else + { + if ( len > 0 ) + { + remains -= len; + recvlen += len; + buf = &buf[len]; + retstr = SuperNET_rpcparse(myinfo,space,size,&postflag,jsonbuf,remoteaddr); + break; + } else usleep(10000); + } + } + if ( retstr != 0 ) + { + i = 0; + if ( postflag == 0 ) + { + //retstr = SuperNET_htmlresponse(space,size,&remains,1,retstr,1); + } + else remains = (int32_t)strlen(retstr); + printf("RETBUF.(%s)\n",retstr); + while ( remains > 0 ) + { + if ( (numsent= (int32_t)send(sock,&retstr[i],remains,MSG_NOSIGNAL)) < 0 ) + { + if ( errno != EAGAIN && errno != EWOULDBLOCK ) + { + //printf("%s: %s numsent.%d vs remains.%d len.%d errno.%d (%s) usock.%d\n",retstr,ipaddr,numsent,remains,recvlen,errno,strerror(errno),sock); + break; + } + } + else if ( remains > 0 ) + { + remains -= numsent; + i += numsent; + if ( remains > 0 ) + printf("iguana sent.%d remains.%d of len.%d\n",numsent,remains,recvlen); + } + } + if ( retstr != space ) + free(retstr); + } + //printf("done response sock.%d\n",sock); + closesocket(sock); + } +} + +int32_t SuperNET_msgrecv(struct supernet_info *myinfo,struct supernet_agent *agent,uint8_t *_buf,int32_t maxlen) +{ + int32_t len,recvlen; void *buf = _buf; struct supernet_msghdr H; + printf("got.(%s) from %s | sock.%d\n",H.command,agent->ipaddr,agent->sock); + memset(&H,0,sizeof(H)); + if ( (recvlen= (int32_t)SuperNET_recv(agent->sock,(uint8_t *)&H,sizeof(H))) == sizeof(H) ) + { + agent->totalrecv += recvlen; + if ( (len= SuperNET_msgvalidate(&H)) >= 0 ) + { + recvlen = 0; + if ( len > 0 ) + { + if ( len > maxlen ) + buf = calloc(1,len); + if ( (recvlen= SuperNET_recv(agent->sock,buf,len)) < 0 ) + { + printf("recv error on (%s) len.%d errno.%d (%s)\n",H.command,len,-recvlen,strerror(-recvlen)); + if ( buf != _buf ) + free(buf); + agent->dead = (uint32_t)time(NULL); + return(recvlen); + } else agent->totalrecv += recvlen; + } + printf("PROCESS.%c NNRECV(%s) recvlen.%d\n",H.type,H.command,recvlen); + if ( H.type == 'C' ) + SuperNET_agentcommand(myinfo,agent,&H,buf,recvlen); + else if ( agent->recvfunc != 0 ) + (*agent->recvfunc)(myinfo,agent,&H,buf,recvlen); + if ( buf != _buf ) + free(buf); + return(recvlen); + } + printf("invalid header received from (%s)\n",agent->ipaddr); + } + printf("%s recv error on hdr errno.%d (%s)\n",agent->ipaddr,-recvlen,strerror(-recvlen)); + return(-1); +} + +int32_t SuperNET_msgsend(struct supernet_info *myinfo,struct supernet_agent *agent,struct supernet_msghdr *msg) +{ + return(SuperNET_send(myinfo,agent,(uint8_t *)msg,SuperNET_msglen(msg) + sizeof(*msg))); +} + +int32_t SuperNET_nnsend(struct supernet_info *myinfo,struct supernet_endpoint *ptr,int32_t ind,struct supernet_msghdr *msg) +{ + return(nn_send(ptr->eps[ind].nnsock,(uint8_t *)msg,SuperNET_msglen(msg) + sizeof(*msg),0)); +} + +struct supernet_msghdr *SuperNET_msgpending(struct supernet_info *myinfo,struct supernet_agent *agent) +{ + return(queue_dequeue(&agent->recvQ,0)); +} + +struct supernet_msghdr *SuperNET_nnpending(struct supernet_info *myinfo,struct supernet_endpoint *ptr,int32_t ind) +{ + return(queue_dequeue(&ptr->eps[ind].nnrecvQ,0)); +} + +int32_t SuperNET_nnrecv(struct supernet_info *myinfo,struct supernet_endpoint *ptr,int32_t ind) +{ + void *msg; int32_t nnlen; + if ( (nnlen= nn_recv(ptr->eps[ind].nnsock,&msg,NN_MSG,0)) > 0 ) + { + printf("PROCESS NNRECV(%s)\n",msg); + if ( ptr->nnrecvfunc != 0 ) + (*ptr->nnrecvfunc)(myinfo,ptr,ind,msg,nnlen); + nn_freemsg(msg); + } + return(nnlen); +} + +int32_t Supernet_poll(struct supernet_info *myinfo,uint8_t *buf,int32_t bufsize,struct supernet_agent *agents,int32_t num,int32_t timeout) +{ + struct pollfd fds[SUPERNET_MAXAGENTS]; int32_t i,nonz,flag; struct supernet_msghdr *msg; struct supernet_agent *agent; + if ( num == 0 ) + return(0);; + memset(fds,0,sizeof(fds)); + flag = 0; + for (i=nonz=0; isock >= 0 ) + { + fds[i].fd = agent->sock; + fds[i].events = (POLLIN | POLLOUT); + nonz++; + } + } + if ( nonz != 0 && poll(fds,num,timeout) > 0 ) + { + for (i=0; isock < 0 ) + continue; + if ( (fds[i].revents & POLLIN) != 0 && SuperNET_msgrecv(myinfo,agent,buf,bufsize) >= 0 ) + flag++; + if ( (fds[i].revents & POLLOUT) != 0 ) + { + if ( (msg= SuperNET_msgpending(myinfo,agent)) != 0 && SuperNET_msgsend(myinfo,agent,msg) > 0 ) + flag++; + } + } + } + return(flag); +} + +int32_t Supernet_nnpoll(struct supernet_info *myinfo,uint8_t *buf,int32_t bufsize,struct supernet_endpoint **eps,int32_t num,int32_t timeout) +{ + struct nn_pollfd fds[1024]; int32_t i,j,n,k,r,starti,nonz,flag; struct supernet_msghdr *msg; struct supernet_endpoint *ptr; + if ( num == 0 ) + return(0); + memset(fds,0,sizeof(fds)); + flag = 0; + r = rand(); + for (j=k=nonz=n=0; jnum; k++,n++) + { + fds[n].fd = -1; + if ( ptr->eps[k].nnsock >= 0 ) + { + fds[n].fd = ptr->eps[k].nnsock; + fds[n].events = (POLLIN | POLLOUT); + nonz++; + } + } + } + if ( nonz != 0 && nn_poll(fds,num,timeout) > 0 ) + { + for (j=k=0; jnum; k++,n++) + { + if ( (fds[i].revents & POLLIN) != 0 && SuperNET_nnrecv(myinfo,ptr,n - starti) >= 0 ) + flag++; + if ( (fds[i].revents & POLLOUT) != 0 ) + { + if ( (msg= SuperNET_nnpending(myinfo,ptr,n - starti)) != 0 && SuperNET_nnsend(myinfo,ptr,n - starti,msg) > 0 ) + flag++; + } + } + } + } + return(flag); +} + +void SuperNET_acceptloop(void *args) +{ + int32_t bindsock,sock; struct supernet_agent *agent; struct supernet_info *myinfo = args; + socklen_t clilen; uint16_t agentport; struct sockaddr_in cli_addr; char ipaddr[64]; uint32_t ipbits; + bindsock = SuperNET_socket(1,"127.0.0.1",myinfo->acceptport); + printf("SuperNET_acceptloop 127.0.0.1:%d bind sock.%d\n",myinfo->acceptport,bindsock); + while ( bindsock >= 0 ) + { + clilen = sizeof(cli_addr); + printf("ACCEPT (%s:%d) on sock.%d\n","127.0.0.1",myinfo->acceptport,bindsock); + sock = accept(bindsock,(struct sockaddr *)&cli_addr,&clilen); + if ( sock < 0 ) + { + printf("ERROR on accept bindsock.%d errno.%d (%s)\n",bindsock,errno,strerror(errno)); + continue; + } + memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); + agentport = cli_addr.sin_port; + expand_ipbits(ipaddr,ipbits); + printf("NEWSOCK.%d for %x (%s:%u)\n",sock,ipbits,ipaddr,agentport); + agent = calloc(1,sizeof(*agent)); + strcpy(agent->ipaddr,ipaddr); + sprintf(agent->name,"%s:%d",ipaddr,agentport); + agent->ipbits = ipbits; + agent->sock = sock; + agent->port = myinfo->acceptport; + queue_enqueue("acceptQ",&myinfo->acceptQ,&agent->DL,0); + } +} + +int32_t SuperNET_acceptport(struct supernet_info *myinfo,uint16_t port) +{ + struct supernet_info *ptr; + ptr = calloc(1,sizeof(*myinfo)); + *ptr = *myinfo; + ptr->acceptport = port; + if ( OS_thread_create(malloc(sizeof(pthread_t)),NULL,(void *)SuperNET_acceptloop,(void *)ptr) != 0 ) + { + printf("error launching accept thread for port.%u\n",port); + return(-1); + } + return(0); +} + +void SuperNET_loop(struct supernet_info *myinfo) +{ + struct supernet_agent *ptr; char *buf; int32_t bufsize = 65536 * 32; + buf = calloc(1,bufsize); + while ( myinfo->dead == 0 ) + { + if ( (ptr= queue_dequeue(&myinfo->acceptQ,0)) != 0 ) + { + if ( myinfo->numagents < sizeof(myinfo->agents)/sizeof(*myinfo->agents)-1 ) + { + myinfo->agents[myinfo->numagents++] = *ptr; + free(ptr); + } + printf("SuperNET.[%d] got new socket %d for %s:%d\n",myinfo->numagents,ptr->sock,ptr->ipaddr,ptr->port); + } + else if ( Supernet_poll(myinfo,(uint8_t *)buf,bufsize,myinfo->agents,myinfo->numagents,myinfo->POLLTIMEOUT) <= 0 ) + usleep(10000); + } + free(buf); +} + +void SuperNET_main(void *arg) +{ + struct supernet_info MYINFO; int32_t i;//cJSON *json,*array; uint16_t port;,n = 0; + memset(&MYINFO,0,sizeof(MYINFO)); + if ( 1 ) + { + strcpy(MYINFO.transport,"tcp"); + strcpy(MYINFO.ipaddr,"127.0.0.1"); + MYINFO.acceptport = SUPERNET_PORT; MYINFO.serviceport = SUPERNET_PORT - 2; + // SuperNET_init(&MYINFO,arg); parse supernet.conf + if ( MYINFO.POLLTIMEOUT == 0 ) + MYINFO.POLLTIMEOUT = SUPERNET_POLLTIMEOUT; + } + /*if ( arg == 0 || (json= cJSON_Parse(arg)) == 0 ) + SuperNET_acceptport(&MYINFO,MYINFO.acceptport); + else + { + if ( (array= jarray(&n,json,"accept")) != 0 ) + { + for (i=0; i= 0 ) + { + clilen = sizeof(cli_addr); + //printf("ACCEPT (%s:%d) on sock.%d\n","127.0.0.1",port,bindsock); + sock = accept(bindsock,(struct sockaddr *)&cli_addr,&clilen); + if ( sock < 0 ) + { + //printf("iguana_rpcloop ERROR on accept usock.%d\n",sock); + continue; + } + memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); + expand_ipbits(remoteaddr,ipbits); + memset(jsonbuf,0,sizeof(jsonbuf)); + remains = (int32_t)(sizeof(jsonbuf) - 1); + buf = jsonbuf; + recvlen = 0; + retstr = 0; + while ( remains > 0 ) + { + if ( (len= (int32_t)recv(sock,buf,remains,0)) < 0 ) + { + if ( errno == EAGAIN ) + { + printf("EAGAIN for len %d, remains.%d\n",len,remains); + usleep(10000); + } + break; + } + else + { + if ( len > 0 ) + { + remains -= len; + recvlen += len; + buf = &buf[len]; + retstr = SuperNET_rpcparse(myinfo,space,size,&jsonflag,&postflag,jsonbuf,remoteaddr); + break; + } else usleep(10000); + } + } + if ( retstr != 0 ) + { + i = 0; + if ( postflag == 0 && jsonflag == 0 ) + retstr = SuperNET_htmlresponse(space,size,&remains,1,retstr,1); + else remains = (int32_t)strlen(retstr); + printf("RETBUF.(%s)\n",retstr); + while ( remains > 0 ) + { + if ( (numsent= (int32_t)send(sock,&retstr[i],remains,MSG_NOSIGNAL)) < 0 ) + { + if ( errno != EAGAIN && errno != EWOULDBLOCK ) + { + //printf("%s: %s numsent.%d vs remains.%d len.%d errno.%d (%s) usock.%d\n",retstr,ipaddr,numsent,remains,recvlen,errno,strerror(errno),sock); + break; + } + } + else if ( remains > 0 ) + { + remains -= numsent; + i += numsent; + if ( remains > 0 ) + printf("iguana sent.%d remains.%d of len.%d\n",numsent,remains,recvlen); + } + } + if ( retstr != space ) + free(retstr); + } + //printf("done response sock.%d\n",sock); + closesocket(sock); + } +} +/* +struct endpoint find_epbits(struct relay_info *list,uint32_t ipbits,uint16_t port,int32_t type) +{ + int32_t i; struct endpoint epbits; + memset(&epbits,0,sizeof(epbits)); + if ( list != 0 && list->num > 0 ) + { + if ( type >= 0 ) + type = nn_portoffset(type); + for (i=0; inum&&i<(int32_t)(sizeof(list->connections)/sizeof(*list->connections)); i++) + if ( list->connections[i].ipbits == ipbits && (port == 0 || port == list->connections[i].port) && (type < 0 || type == list->connections[i].nn) ) + return(list->connections[i]); + } + return(epbits); +} + +int32_t add_relay(struct relay_info *list,struct endpoint epbits) +{ + list->connections[list->num % (sizeof(list->connections)/sizeof(*list->connections))] = epbits, list->num++; + if ( list->num > (sizeof(list->connections)/sizeof(*list->connections)) ) + printf("add_relay warning num.%d > %ld\n",list->num,(long)(sizeof(list->connections)/sizeof(*list->connections))); + return(list->num); +} + +int32_t nn_add_lbservers(struct supernet_info *myinfo,uint16_t port,uint16_t globalport,uint16_t relaysport,int32_t priority,int32_t sock,char servers[][MAX_SERVERNAME],int32_t num) +{ + int32_t i; char endpoint[512],pubendpoint[512]; struct endpoint epbits; uint32_t ipbits; + if ( num > 0 && servers != 0 && nn_setsockopt(sock,NN_SOL_SOCKET,NN_SNDPRIO,&priority,sizeof(priority)) >= 0 ) + { + for (i=0; i= 0 ) + { + printf("+R%s ",endpoint); + add_relay(&myinfo->active,epbits); + } + if ( myinfo->subclient >= 0 ) + { + if ( myinfo->iamrelay != 0 ) + { + epbits = calc_epbits("tcp",ipbits,relaysport,NN_PUB); + expand_epbits(pubendpoint,epbits); + if ( nn_connect(myinfo->subclient,pubendpoint) >= 0 ) + printf("+P%s ",pubendpoint); + } + epbits = calc_epbits("tcp",ipbits,globalport,NN_PUB); + expand_epbits(pubendpoint,epbits); + if ( nn_connect(myinfo->subclient,pubendpoint) >= 0 ) + printf("+P%s ",pubendpoint); + } + } + } + printf("added priority.%d\n",priority); + priority++; + } else printf("error setting priority.%d (%s)\n",priority,nn_errstr()); + return(priority); +} + +int32_t _lb_socket(struct supernet_info *myinfo,uint16_t port,uint16_t globalport,uint16_t relaysport,int32_t maxmillis,char servers[][MAX_SERVERNAME],int32_t num,char backups[][MAX_SERVERNAME],int32_t numbacks,char failsafes[][MAX_SERVERNAME],int32_t numfailsafes) +{ + int32_t lbsock,timeout,retrymillis,priority = 1; + if ( (lbsock= nn_socket(AF_SP,NN_REQ)) >= 0 ) + { + retrymillis = (maxmillis / 30) + 1; + printf("!!!!!!!!!!!! lbsock.%d !!!!!!!!!!!\n",lbsock); + if ( nn_setsockopt(lbsock,NN_SOL_SOCKET,NN_RECONNECT_IVL,&retrymillis,sizeof(retrymillis)) < 0 ) + printf("error setting NN_REQ NN_RECONNECT_IVL_MAX socket %s\n",nn_errstr()); + else if ( nn_setsockopt(lbsock,NN_SOL_SOCKET,NN_RECONNECT_IVL_MAX,&maxmillis,sizeof(maxmillis)) < 0 ) + fprintf(stderr,"error setting NN_REQ NN_RECONNECT_IVL_MAX socket %s\n",nn_errstr()); + timeout = SUPERNET_NETWORKTIMEOUT; + if ( 1 && nn_setsockopt(lbsock,NN_SOL_SOCKET,NN_RCVTIMEO,&timeout,sizeof(timeout)) < 0 ) + printf("error setting NN_SOL_SOCKET NN_RCVTIMEO socket %s\n",nn_errstr()); + timeout = 100; + if ( 1 && nn_setsockopt(lbsock,NN_SOL_SOCKET,NN_SNDTIMEO,&timeout,sizeof(timeout)) < 0 ) + printf("error setting NN_SOL_SOCKET NN_SNDTIMEO socket %s\n",nn_errstr()); + if ( num > 0 ) + priority = nn_add_lbservers(myinfo,port,globalport,relaysport,priority,lbsock,servers,num); + if ( numbacks > 0 ) + priority = nn_add_lbservers(myinfo,port,globalport,relaysport,priority,lbsock,backups,numbacks); + if ( numfailsafes > 0 ) + priority = nn_add_lbservers(myinfo,port,globalport,relaysport,priority,lbsock,failsafes,numfailsafes); + } else printf("error getting req socket %s\n",nn_errstr()); + //printf("myinfo->lb.num %d\n",myinfo->lb.num); + return(lbsock); +} + +int32_t nn_lbsocket(struct supernet_info *myinfo,int32_t maxmillis,int32_t port,uint16_t globalport,uint16_t relaysport) +{ + char Cservers[32][MAX_SERVERNAME],Bservers[32][MAX_SERVERNAME],failsafes[4][MAX_SERVERNAME]; + int32_t n,m,lbsock,numfailsafes = 0; + printf("redo lbsocket()\n"), exit(-1); + //strcpy(failsafes[numfailsafes++],"5.9.56.103"); + //strcpy(failsafes[numfailsafes++],"5.9.102.210"); + // n = crackfoo_servers(Cservers,sizeof(Cservers)/sizeof(*Cservers),port); + // m = badass_servers(Bservers,sizeof(Bservers)/sizeof(*Bservers),port); + lbsock = _lb_socket(myinfo,port,globalport,relaysport,maxmillis,Bservers,m,Cservers,n*0,failsafes,numfailsafes); + return(lbsock); +} + +void add_standard_fields(char *request) +{ + cJSON *json; uint64_t tag; + if ( (json= cJSON_Parse(request)) != 0 ) + { + if ( get_API_nxt64bits(cJSON_GetObjectItem(json,"NXT")) == 0 ) + { + randombytes((void *)&tag,sizeof(tag)); + sprintf(request + strlen(request) - 1,",\"NXT\":\"%s\",\"tag\":\"%llu\"}",myinfo->NXTADDR,(long long)tag); + if ( myinfo->iamrelay != 0 && (myinfo->hostname[0] != 0 || myinfo->ipaddr[0] != 0) ) + sprintf(request + strlen(request) - 1,",\"iamrelay\":\"%s\"}",myinfo->hostname[0]!=0?myinfo->hostname:myinfo->myipaddr); + } + free_json(json); + } +} + +char *nn_loadbalanced(struct supernet_info *myinfo,uint8_t *data,int32_t len) +{ + char *msg,*jsonstr = 0; + int32_t sendlen,i,lbsock,recvlen = 0; + if ( (lbsock= myinfo->lbclient) < 0 ) + return(clonestr("{\"error\":\"invalid load balanced socket\"}")); + for (i=0; i<10; i++) + if ( (nn_socket_status(lbsock,1) & NN_POLLOUT) != 0 ) + break; + if ( myinfo->Debuglevel > 2 ) + printf("sock.%d NN_LBSEND.(%s)\n",lbsock,data); + //fprintf(stderr,"send to network\n"); + if ( (sendlen= nn_send(lbsock,data,len,0)) == len ) + { + for (i=0; i<10; i++) + if ( (nn_socket_status(lbsock,1) & NN_POLLIN) != 0 ) + break; + if ( (recvlen= nn_recv(lbsock,&msg,NN_MSG,0)) > 0 ) + { + if ( myinfo->Debuglevel > 2 ) + printf("LBRECV.(%s)\n",msg); + jsonstr = clonestr((char *)msg); + nn_freemsg(msg); + } + else + { + printf("nn_loadbalanced got recvlen.%d %s\n",recvlen,nn_errstr()); + jsonstr = clonestr("{\"error\":\"lb recv error, probably timeout\"}"); + } + } else printf("got sendlen.%d instead of %d %s\n",sendlen,len,nn_errstr()), jsonstr = clonestr("{\"error\":\"lb send error\"}"); + return(jsonstr); +} + +cJSON *relay_json(struct relay_info *list) +{ + cJSON *json,*array; char endpoint[512]; int32_t i; + if ( list == 0 || list->num == 0 ) + return(0); + array = cJSON_CreateArray(); + for (i=0; inum&&i<(int32_t)(sizeof(list->connections)/sizeof(*list->connections)); i++) + { + expand_epbits(endpoint,list->connections[i]); + jaddistr(array,endpoint); + } + json = cJSON_CreateObject(); + jadd(json,"endpoints",array); + //cJSON_AddItemToObject(json,"type",cJSON_CreateString(nn_typestr(list->mytype))); + //cJSON_AddItemToObject(json,"dest",cJSON_CreateString(nn_typestr(list->desttype))); + jaddnum(json,"total",list->num); + return(json); +} + +char *relays_jsonstr(struct supernet_info *myinfo,char *jsonstr,cJSON *argjson) +{ + cJSON *json; + if ( myinfo->iamrelay != 0 && myinfo->ipaddr[0] != 0 ) + { + json = cJSON_CreateObject(); + jaddstr(json,"relay",myinfo->ipaddr); + if ( myinfo->active.num > 0 ) + jadd(json,"relays",relay_json(&myinfo->active)); + return(jprint(json,1)); + } + else return(clonestr("{\"error\":\"get relay list from relay\"}")); +} + +int32_t init_SUPERNET_pullsock(struct supernet_info *myinfo,int32_t sendtimeout,int32_t recvtimeout) +{ + char bindaddr[64],*transportstr; int32_t iter; + myinfo->pullsock = -1; + if ( (myinfo->pullsock= nn_socket(AF_SP,NN_PULL)) < 0 ) + { + printf("error creating pullsock %s\n",nn_strerror(nn_errno())); + return(-1); + } + printf("got pullsock.%d\n",myinfo->pullsock); + if ( nn_settimeouts(myinfo->pullsock,sendtimeout,recvtimeout) < 0 ) + { + printf("error settime pullsock timeouts %s\n",nn_strerror(nn_errno())); + return(-1); + } + printf("PULLsock.%d\n",myinfo->pullsock); + for (iter=0; iter<2; iter++) + { + transportstr = (iter == 0) ? "ipc" : "inproc"; + sprintf(bindaddr,"%s://SuperNET.agents",transportstr); + if ( nn_bind(myinfo->pullsock,bindaddr) < 0 ) + { + printf("error binding pullsock to (%s) %s\n",bindaddr,nn_strerror(nn_errno())); + return(-1); + } + } + return(0); +} + +void busdata_init(struct supernet_info *myinfo,int32_t sendtimeout,int32_t recvtimeout,int32_t firstiter) +{ + char endpoint[512]; int32_t i; + myinfo->servicesock = myinfo->pubglobal = myinfo->pubrelays = myinfo->lbserver = -1; + endpoint[0] = 0; + if ( (myinfo->subclient= nn_createsocket(myinfo,endpoint,0,"NN_SUB",NN_SUB,0,sendtimeout,recvtimeout)) >= 0 ) + { + myinfo->pfd[myinfo->numservers++].fd = myinfo->subclient, printf("numservers.%d\n",myinfo->numservers); + nn_setsockopt(myinfo->subclient,NN_SUB,NN_SUB_SUBSCRIBE,"",0); + } else printf("error creating subclient\n"); + myinfo->lbclient = nn_lbsocket(myinfo,SUPERNET_NETWORKTIMEOUT,SUPERNET_PORT + LB_OFFSET,myinfo->port + PUBGLOBALS_OFFSET,myinfo->port + PUBRELAYS_OFFSET); + printf("LBclient.%d port.%d\n",myinfo->lbclient,SUPERNET_PORT + LB_OFFSET); + sprintf(endpoint,"%s://%s:%u",myinfo->transport,myinfo->ipaddr,myinfo->serviceport); + if ( (myinfo->servicesock= nn_createsocket(myinfo,endpoint,1,"NN_REP",NN_REP,myinfo->serviceport,sendtimeout,recvtimeout)) >= 0 ) + myinfo->pfd[myinfo->numservers++].fd = myinfo->servicesock, printf("numservers.%d\n",myinfo->numservers); + else printf("error creating servicesock\n"); + for (i=0; inumservers; i++) + myinfo->pfd[i].events = NN_POLLIN | NN_POLLOUT; + printf("myinfo->iamrelay %d, numservers.%d ipaddr.(%s://%s) port.%d serviceport.%d\n",myinfo->iamrelay,myinfo->numservers,myinfo->transport,myinfo->ipaddr,myinfo->port,myinfo->serviceport); +} + +void SuperNET_init(struct supernet_info *myinfo,char *jsonstr) +{ + char *str; + if ( jsonstr != 0 && (str= SuperNET_JSON(myinfo,jsonstr)) != 0 ) + free(str); + busdata_init(myinfo,10,1,0); + init_SUPERNET_pullsock(myinfo,10,10); +}*/ + +int32_t Supernet_lineparse(char *key,int32_t keymax,char *value,int32_t valuemax,char *src) +{ + int32_t a,b,c,n = 0; + key[0] = value[0] = 0; + while ( (c= src[n]) == ' ' || c == '\t' || c == '\n' || c == '\t' ) + n++; + while ( (c= src[n]) != ':' && c != 0 ) + { + *key++ = c; + if ( ++n >= keymax-1 ) + { + *key = 0; + printf("lineparse overflow key.(%s)\n",src); + return(-1); + } + } + *key = 0; + if ( src[n] != ':' ) + return(n); + n++; + while ( (c= src[n]) == ' ' || c == '\t' ) + n++; + while ( (c= src[n]) != 0 && c != '\r' && c != '\n' ) + { + if ( c == '%' && (a= src[n+1]) != 0 && (b= src[n+2]) != 0 ) + c = ((unhex(a) << 4) | unhex(b)), n += 2; + *value++ = c; + n++; + if ( n >= valuemax-1 ) + { + *value = 0; + printf("lineparse overflow.(%s)\n",src); + return(-1); + } + } + *value = 0; + if ( src[n] != 0 ) + { + n++; + while ( (c= src[n]) == '\r' || c == '\n' ) + n++; + } + return(n); +} + +cJSON *SuperNET_urlconv(char *value,int32_t bufsize,char *urlstr) +{ + int32_t i,n,totallen,datalen,len = 0; cJSON *json,*array; char key[8192],*data; + json = cJSON_CreateObject(); + array = cJSON_CreateArray(); + totallen = (int32_t)strlen(urlstr); + while ( 1 ) + { + for (i=len; urlstr[i]!=0; i++) + if ( urlstr[i] == '\r' || urlstr[i] == '\n' ) + break; + if ( i == len && (urlstr[len] == '\r' || urlstr[len] == '\n') ) + { + len++; + continue; + } + urlstr[i] = 0; + if ( (n= Supernet_lineparse(key,sizeof(key),value,bufsize,&urlstr[len])) > 0 ) + { + if ( value[0] != 0 ) + jaddstr(json,key,value); + else jaddistr(array,key); + len += (n + 1); + if ( strcmp(key,"Content-Length") == 0 && (datalen= atoi(value)) > 0 ) + { + data = &urlstr[totallen - datalen]; + data[-1] = 0; + //printf("post.(%s) (%c)\n",data,data[0]); + jaddstr(json,"POST",data); + } + } else break; + } + jadd(json,"lines",array); + return(json); +} + +char *SuperNET_rpcparse(struct supernet_info *myinfo,char *retbuf,int32_t bufsize,int32_t *jsonflagp,int32_t *postflagp,char *urlstr,char *remoteaddr) +{ + cJSON *tokens,*argjson,*json = 0; char urlmethod[16],*data,url[1024],*retstr,*token = 0; int32_t i,j,n; + //printf("rpcparse.(%s)\n",urlstr); + for (i=0; i 0 ) + { + jaddstr(argjson,"agent",jstri(tokens,0)); + if ( n > 1 ) + jaddstr(argjson,"method",jstri(tokens,1)); + for (i=2; i (%s) postflag.%d (%s)\n",urlstr,cJSON_Print(json),*postflagp,jprint(argjson,0)); + return(retstr); + } + return(clonestr("{\"error\":\"couldnt process packet\"}")); +} + diff --git a/deprecated/SuperNET_category.c b/deprecated/SuperNET_category.c new file mode 100755 index 000000000..6ba767ef9 --- /dev/null +++ b/deprecated/SuperNET_category.c @@ -0,0 +1,226 @@ +/****************************************************************************** + * Copyright © 2014-2016 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#include "iguana777.h" + +#include "../includes/tweetnacl.h" +#include "../crypto777/OS_portable.h" +#include "../includes/libgfshare.h" +#include "../includes/utlist.h" +#include "../includes/uthash.h" +#include "../includes/curve25519.h" +#include "../includes/cJSON.h" + +bits256 calc_categoryhashes(bits256 *subhashp,char *category,char *subcategory) +{ + bits256 categoryhash; + if ( category == 0 || category[0] == 0 || strcmp(category,"broadcast") == 0 ) + categoryhash = GENESIS_PUBKEY; + else vcalc_sha256(0,categoryhash.bytes,(uint8_t *)category,(int32_t)strlen(category)); + if ( subhashp != 0 ) + { + if ( subcategory == 0 || subcategory[0] == 0 || strcmp(subcategory,"broadcast") == 0 ) + *subhashp = GENESIS_PUBKEY; + else vcalc_sha256(0,subhashp->bytes,(uint8_t *)subcategory,(int32_t)strlen(subcategory)); + } + return(categoryhash); +} + +struct gecko_chain *category_find(bits256 categoryhash,bits256 subhash) +{ + struct gecko_chain *cat=0,*sub = 0; bits256 hash; + HASH_FIND(hh,Categories,categoryhash.bytes,sizeof(categoryhash),cat); + if ( cat != 0 ) + { + if ( bits256_nonz(subhash) > 0 && memcmp(GENESIS_PUBKEY.bytes,subhash.bytes,sizeof(subhash)) != 0 ) + { + hash = subhash; + HASH_FIND(hh,cat->subchains,hash.bytes,sizeof(hash),sub); + if ( sub != 0 ) + return(sub); + } + return(cat); + } //else printf("category_find.(%s) not found\n",bits256_str(str,categoryhash));//, getchar(); + return(0); +} + +queue_t *category_Q(struct gecko_chain **catptrp,bits256 categoryhash,bits256 subhash) +{ + struct gecko_chain *cat; + *catptrp = 0; + if ( (cat= category_find(categoryhash,subhash)) != 0 ) + { + *catptrp = cat; + return(&cat->Q); + } + else return(0); +} + +/*void *gecko_chain(bits256 categoryhash,bits256 subhash) +{ + struct gecko_chain *cat; + if ( (cat= category_find(categoryhash,subhash)) != 0 ) + return(cat->info); + else return(0); +}*/ + +void *gecko_chainset(bits256 categoryhash,bits256 subhash,void *info) +{ + struct gecko_chain *cat; + if ( (cat= category_find(categoryhash,subhash)) != 0 ) + { + cat->info = info; + return(info); + } + return(0); +} + +#ifdef later +struct gecko_chain *category_processfunc(bits256 categoryhash,bits256 subhash,char *(*process_func)(struct supernet_info *myinfo,struct gecko_chain *cat,void *data,int32_t datalen,char *remoteaddr)) +{ + struct gecko_chain *cat; + if ( (cat= category_find(categoryhash,subhash)) != 0 ) + { + cat->processfunc = process_func; + return(cat); + } + return(0); +} + +struct category_msg *category_gethexmsg(struct supernet_info *myinfo,struct gecko_chain **catptrp,bits256 categoryhash,bits256 subhash) +{ + queue_t *Q; + //char str[65]; printf("getmsg.(%s) %llx\n",bits256_str(str,categoryhash),(long long)subhash.txid); + if ( (Q= category_Q(catptrp,categoryhash,subhash)) != 0 ) + return(queue_dequeue(Q,0)); + else return(0); +} + +void category_posthexmsg(struct supernet_info *myinfo,bits256 categoryhash,bits256 subhash,char *hexmsg,struct tai now,char *remoteaddr) +{ + int32_t len; struct category_msg *m; queue_t *Q = 0; struct gecko_chain *cat; + if ( (Q= category_Q(&cat,categoryhash,subhash)) != 0 ) + { + len = (int32_t)strlen(hexmsg) >> 1; + m = calloc(1,sizeof(*m) + len); + m->t = now, m->len = len; + if ( remoteaddr != 0 && remoteaddr[0] != 0 ) + m->remoteipbits = calc_ipbits(remoteaddr); + decode_hex(m->msg,m->len,hexmsg); + queue_enqueue("categoryQ",Q,&m->DL,0); + //char str[65]; printf("POST HEXMSG.(%s) -> %s.%llx len.%d\n",hexmsg,bits256_str(str,categoryhash),(long long)subhash.txid,m->len); + return; + } + // char str[65]; printf("no subscription for category.(%s) %llx\n",bits256_str(str,categoryhash),(long long)subhash.txid); +} + +void *category_subscribe(struct supernet_info *myinfo,bits256 chainhash,bits256 keyhash) +{ + struct gecko_chain *chain,*subchain; bits256 hash; + HASH_FIND(hh,Categories,chainhash.bytes,sizeof(chainhash),chain); + if ( chain == 0 ) + { + chain = mycalloc('c',1,sizeof(*chain)); + chain->hash = hash = chainhash; + char str[65]; printf("ADD cat.(%s)\n",bits256_str(str,chainhash)); + HASH_ADD(hh,Categories,hash,sizeof(hash),chain); + } + if ( bits256_nonz(keyhash) > 0 && memcmp(GENESIS_PUBKEY.bytes,keyhash.bytes,sizeof(keyhash)) != 0 && chain != 0 ) + { + HASH_FIND(hh,chain->subchains,keyhash.bytes,sizeof(keyhash),subchain); + if ( subchain == 0 ) + { + subchain = mycalloc('c',1,sizeof(*subchain)); + subchain->hash = hash = keyhash; + char str[65],str2[65]; printf("subadd.(%s) -> (%s)\n",bits256_str(str,keyhash),bits256_str(str2,chainhash)); + HASH_ADD(hh,chain->subchains,hash,sizeof(hash),subchain); + } + } + return(chain); +} + +int32_t category_peer(struct supernet_info *myinfo,struct iguana_peer *addr,bits256 category,bits256 subhash) +{ + return(1); +} + +int32_t category_plaintext(struct supernet_info *myinfo,bits256 category,bits256 subhash,int32_t plaintext) +{ + return(plaintext); +} + +int32_t category_maxdelay(struct supernet_info *myinfo,bits256 category,bits256 subhash,int32_t maxdelay) +{ + return(maxdelay); +} + +int32_t category_broadcastflag(struct supernet_info *myinfo,bits256 category,bits256 subhash,int32_t broadcastflag) +{ + if ( broadcastflag < 1 ) + broadcastflag = 1; + else if ( broadcastflag > SUPERNET_MAXHOPS ) + broadcastflag = SUPERNET_MAXHOPS; + return(broadcastflag); +} + +char *SuperNET_categorymulticast(struct supernet_info *myinfo,int32_t surveyflag,bits256 categoryhash,bits256 subhash,char *message,int32_t maxdelay,int32_t broadcastflag,int32_t plaintext,cJSON *argjson,char *remoteaddr) +{ + char *hexmsg,*retstr; int32_t len; cJSON *retjson = cJSON_CreateObject(); + len = (int32_t)strlen(message); + //char str[65]; printf("multicast.(%s)\n",bits256_str(str,categoryhash)); + if ( is_hexstr(message,len) == 0 ) + { + hexmsg = malloc(((len+1) << 1) + 1); + init_hexbytes_noT(hexmsg,(uint8_t *)message,len+1); + } else hexmsg = message; + plaintext = category_plaintext(myinfo,categoryhash,subhash,plaintext); + broadcastflag = category_broadcastflag(myinfo,categoryhash,subhash,broadcastflag); + maxdelay = category_maxdelay(myinfo,categoryhash,subhash,maxdelay); + retstr = 0;//SuperNET_DHTsend(myinfo,0,categoryhash,subhash,hexmsg,maxdelay,broadcastflag,plaintext); + //if ( 0 && argjson != 0 ) + // SuperNET_hexmsgprocess(myinfo,retjson,argjson,hexmsg,remoteaddr); + if ( hexmsg != message) + free(hexmsg); + if ( retjson != 0 ) + { + if ( retstr != 0 ) + jaddstr(retjson,"result",retstr); + retstr = jprint(retjson,1); + } + return(retstr); +} + +void category_init(struct supernet_info *myinfo) +{ + bits256 pangeahash,instantdexhash,baseliskhash; + category_subscribe(myinfo,GENESIS_PUBKEY,GENESIS_PUBKEY); + pangeahash = calc_categoryhashes(0,"pangea",0); + myinfo->pangea_category = pangeahash; + category_subscribe(myinfo,pangeahash,GENESIS_PUBKEY); + category_processfunc(pangeahash,GENESIS_PUBKEY,pangea_hexmsg); + //category_chain_functions(myinfo,pangeahash,GENESIS_PUBKEY,sizeof(bits256),sizeof(bits256),0,0,0,0,0,0); + instantdexhash = calc_categoryhashes(0,"InstantDEX",0); + myinfo->instantdex_category = instantdexhash; + category_subscribe(myinfo,instantdexhash,GENESIS_PUBKEY); + category_processfunc(instantdexhash,GENESIS_PUBKEY,InstantDEX_hexmsg); + category_processfunc(instantdexhash,myinfo->myaddr.persistent,InstantDEX_hexmsg); + + baseliskhash = calc_categoryhashes(0,"baselisk",0); + myinfo->basilisk_category = baseliskhash; + category_subscribe(myinfo,baseliskhash,GENESIS_PUBKEY); + +} + +#endif diff --git a/deprecated/SuperNET_hexmsg.c b/deprecated/SuperNET_hexmsg.c new file mode 100755 index 000000000..5d3dc7bd9 --- /dev/null +++ b/deprecated/SuperNET_hexmsg.c @@ -0,0 +1,393 @@ +/****************************************************************************** + * Copyright © 2014-2016 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#include "iguana777.h" + +#ifdef oldway +int32_t SuperNET_hexmsgfind(struct supernet_info *myinfo,bits256 category,bits256 subhash,char *hexmsg,int32_t addflag) +{ + static int lastpurge; static uint64_t Packetcache[1024]; + bits256 packethash; int32_t i,datalen; + datalen = (int32_t)strlen(hexmsg) + 1; + vcalc_sha256(0,packethash.bytes,(void *)hexmsg,datalen); + if ( bits256_nonz(category) == 0 ) + category = GENESIS_PUBKEY; + if ( bits256_nonz(subhash) == 0 ) + subhash = GENESIS_PUBKEY; + packethash = curve25519(category,packethash); + //printf("addflag.%d packethash.%llx dest.%llx\n",addflag,(long long)packethash.txid,(long long)category.txid); + for (i=0; i slot[%d]\n",(long long)packethash.txid,hexmsg,i); + } + break; + } + else if ( Packetcache[i] == packethash.txid ) + { + //printf("SuperNET_DHTsend reject duplicate packet.%llx\n",(long long)packethash.txid); + return(i); + } + } + if ( i == sizeof(Packetcache)/sizeof(*Packetcache) ) + { + if ( addflag != 0 ) + { + printf("purge slot[%d]\n",lastpurge); + Packetcache[lastpurge++] = packethash.txid; + if ( lastpurge >= sizeof(Packetcache)/sizeof(*Packetcache) ) + lastpurge = 0; + } + } + return(-1); +} + +void SuperNET_hexmsgadd(struct supernet_info *myinfo,bits256 categoryhash,bits256 subhash,char *hexmsg,struct tai now,char *remoteaddr) +{ + char str[512],str2[65]; + str[0] = 0; + if ( memcmp(categoryhash.bytes,GENESIS_PUBKEY.bytes,sizeof(categoryhash)) == 0 ) + strcpy(str,"BROADCAST."); + else bits256_str(str+strlen(str),categoryhash); + if ( memcmp(subhash.bytes,GENESIS_PUBKEY.bytes,sizeof(subhash)) != 0 ) + { + bits256_str(str2,subhash); + strcat(str,str2); + } + category_posthexmsg(myinfo,categoryhash,subhash,hexmsg,now,remoteaddr); + //printf("HEXMSG.(%s).%llx -> %s\n",hexmsg,(long long)subhash.txid,str); +} + +void SuperNET_hexmsgprocess(struct supernet_info *myinfo,cJSON *retjson,cJSON *json,char *hexmsg,char *remoteaddr) +{ + int32_t len,flag=0; char *str; uint8_t _buf[8192],*buf = _buf; bits256 categoryhash,subhash; struct private_chain *cat; + if ( hexmsg != 0 ) + { + len = (int32_t)strlen(hexmsg); + if ( is_hexstr(hexmsg,len) > 0 ) + { + len >>= 1; + if ( len > sizeof(_buf) ) + buf = malloc(len); + decode_hex(buf,len,hexmsg); + //printf("hex.(%s) -> (%s)\n",hexmsg,buf); + categoryhash = jbits256(json,"categoryhash"); + subhash = jbits256(json,"categoryhash"); + if ( bits256_nonz(subhash) == 0 ) + subhash = GENESIS_PUBKEY; + if ( (cat= category_find(categoryhash,subhash)) != 0 ) + { + if ( cat->processfunc != 0 ) + { + if ( (str= (*cat->processfunc)(myinfo,cat,buf,len,remoteaddr)) != 0 ) + { + if ( retjson != 0 ) + jaddstr(retjson,"processfunc",str); + else free(str); + } + flag = 1; + //printf("PROCESSFUNC\n"); + } + } + if ( flag == 0 ) + { + printf("no processfunc, posthexmsg\n"); + category_posthexmsg(myinfo,categoryhash,jbits256(json,"subhash"),hexmsg,tai_now(),remoteaddr); + } + //char str[65]; printf("HEXPROCESS.(%s) -> %s\n",hexmsg,bits256_str(str,categoryhash)); + if ( buf != _buf ) + free(buf); + } + } +} + +int32_t category_default_blockhash(struct category_chain *catchain,void *blockhashp,void *data,int32_t datalen) +{ + bits256 hash; + vcalc_sha256(0,hash.bytes,data,datalen); + vcalc_sha256(0,blockhashp,hash.bytes,sizeof(hash)); + return(sizeof(*blockhashp)); +} + +bits256 category_default_stake(struct category_chain *catchain,void *addr,int32_t addrlen) +{ + bits256 stake; + memset(stake.bytes,0,sizeof(stake)); + stake.txid = ((uint64_t)1 << 63); + return(stake); +} + +bits256 catgory_default_hit(struct category_chain *catchain,int32_t height,void *prevgenerator,void *addr,void *blockhashp) +{ + bits256 hash; bits256 rawhit,hit; + memset(rawhit.bytes,0,sizeof(rawhit)); + memset(hit.bytes,0,sizeof(hit)); + vcalc_sha256cat(hash.bytes,prevgenerator,catchain->addrlen,addr,catchain->addrlen); + hit = (*catchain->stake_func)(catchain,addr,catchain->addrlen); + rawhit.txid = hash.txid % ((uint64_t)1 << 42); + if ( rawhit.txid != 0 ) + hit.txid /= rawhit.txid; + return(hit); +} + +#define category_default_heaviest() (*catchain->default_func)(catchain,'H',0,0,0,0,zero) +#define category_default_latest() (*catchain->default_func)(catchain,'L',0,0,0,0,zero) +#define category_default_setheaviest(height,blockhashp,heaviest) (*catchain->default_func)(catchain,'S',height,0,0,blockhashp,zero) +#define category_default_weight(height) (*catchain->default_func)(catchain,'W',height,0,0,0,zero) +#define category_default_blockfind(height) (*catchain->default_func)(catchain,'B',height,0,0,0,zero) + +bits256 category_default_func(struct category_chain *catchain,int32_t func,int32_t height,void *prevgenerator,void *addr,void *blockhashp,bits256 heaviest) +{ + static const bits256 zero; + if ( catchain->hashlen != sizeof(bits256) || catchain->addrlen != sizeof(bits256) ) + { + printf("unsupported hashlen.%d or addrlen.%d\n",catchain->hashlen,catchain->addrlen); + return(zero); + } + if ( height > catchain->maxblocknum + (func == 'S') ) + { + printf("error func.%c setting heaviest. skipped %d -> %d?\n",func,catchain->maxblocknum,height); + return(catchain->category_hwm); + } + if ( func == 'H' ) + return(catchain->category_hwm); + else if ( func == 'L' ) + { + if ( catchain->maxblocknum < 0 ) + return(catchain->genesishash); + else return(catchain->blocks[catchain->maxblocknum]); + } + else if ( func == 'S' ) + { + catchain->category_hwm = heaviest; + if ( height > catchain->maxblocknum ) + { + catchain->weights = realloc(catchain->weights,(catchain->maxblocknum+1) * sizeof(*catchain->weights)); + catchain->blocks = realloc(catchain->blocks,(catchain->maxblocknum+1) * sizeof(*catchain->blocks)); + } + catchain->maxblocknum = height; + catchain->weights[height] = heaviest; + if ( blockhashp != 0 ) + memcpy(&catchain->blocks[height],blockhashp,sizeof(catchain->blocks[height])); + } + else if ( func == 'B' ) + { + if ( height <= catchain->maxblocknum ) + return(catchain->blocks[height]); + else + { + printf("error: illegal height.%d vs max.%d\n",height,catchain->maxblocknum); + return(zero); + } + } + else if ( func == 'W' ) + { + if ( height >= 0 && height < catchain->maxblocknum ) + return(catchain->weights[height]); + else printf("error getting weight for height.%d vs maxblocknum.%d\n",height,catchain->maxblocknum); + } + return(catchain->category_hwm); +} + +int32_t category_default_ishwm(struct category_chain *catchain,int32_t prevheight,void *prevblockhashp,void *blockhashp,void *prevgenerator,void *addr) +{ + bits256 checkhash,prevwt,oldhit,hit,heaviest; static const bits256 zero; + checkhash = category_default_blockfind(prevheight); + if ( memcmp(checkhash.bytes,prevblockhashp,catchain->hashlen) == 0 ) + { + heaviest = category_default_heaviest(); + prevwt = category_default_weight(prevheight); + oldhit = category_default_weight(prevheight+1); + hit = (*catchain->hit_func)(catchain,prevheight+1,prevgenerator,addr,blockhashp); + if ( hit.txid > oldhit.txid && prevwt.txid+hit.txid > heaviest.txid ) + { + heaviest.txid = (prevwt.txid + hit.txid); + category_default_setheaviest(prevheight+1,blockhashp,heaviest); + return(prevheight+1); + } + + } else return(-2); + return(-1); +} + +int32_t category_default_payment(struct category_chain *catchain,void *src,void *dest,uint64_t amount) +{ + //uint32_t srcind=0,destind=0; + // catchain->balances[destind] += amount; + // catchain->balances[srcind] -= amount; + return(0); +} + +struct category_chain *category_chain_functions(struct supernet_info *myinfo,bits256 categoryhash,bits256 subhash,int32_t hashlen,int32_t addrlen,void *hash_func,void *stake_func,void *hit_func,void *default_func,void *ishwm_func,void *payment_func) +{ + struct private_chain *cat; struct category_chain *catchain = calloc(1,sizeof(*catchain)); + if ( (cat= category_find(categoryhash,subhash)) != 0 ) + { + catchain->maxblocknum = -1; + catchain->myinfo = myinfo, catchain->subinfo = cat->info; + if ( bits256_cmp(subhash,GENESIS_PUBKEY) == 0 ) + catchain->categoryinfo = cat->info, catchain->genesishash = categoryhash; + else catchain->categoryinfo = category_find(categoryhash,GENESIS_PUBKEY), catchain->genesishash = subhash; + if ( catchain->myinfo == 0 || catchain->categoryinfo || catchain->subinfo ) + { + printf("error with catchain pointers\n"); + return(0); + } + if ( (catchain->addrlen= addrlen) <= 0 || (catchain->hashlen= hashlen) <= 0 ) + { + printf("error with catchain lens.%d %d\n",addrlen,hashlen); + return(0); + } + if ( (catchain->blockhash_func= hash_func) == 0 || (catchain->stake_func= stake_func) == 0 || (catchain->hit_func= hit_func) == 0 || (catchain->default_func= default_func) == 0 || (catchain->ishwm_func= ishwm_func) == 0 || (catchain->payment_func= payment_func) == 0 ) + { + if ( addrlen == sizeof(bits256) && hashlen == sizeof(bits256) ) + { + catchain->blockhash_func = category_default_blockhash; + catchain->stake_func = category_default_stake; + catchain->hit_func = catgory_default_hit; + catchain->default_func = category_default_func; + catchain->ishwm_func = category_default_ishwm; + catchain->payment_func = category_default_payment; + } + else + { + printf("no category chain functions and addrlen.%d hashlen.%d not 32\n",addrlen,hashlen); + return(0); + } + } + //cat->catchain = catchain; + return(catchain); + } + return(0); +} + +struct crypto777_msghdr *crypto777_msgcreate(struct supernet_info *myinfo,struct crypto777_msghdr *msg,int32_t datalen) +{ + bits256 otherpubkey; uint64_t signerbits; uint32_t timestamp; uint8_t buf[sizeof(msg->sig)],*data; + memset(&msg->sig,0,sizeof(msg->sig)); + datalen += (int32_t)(sizeof(*msg) - sizeof(msg->sig)); + data = (void *)((long)msg + sizeof(msg->sig)); + otherpubkey = acct777_msgpubkey(data,datalen); + timestamp = (uint32_t)time(NULL); + acct777_sign(&msg->sig,myinfo->privkey,otherpubkey,timestamp,data,datalen); + if ( (signerbits= acct777_validate(&msg->sig,acct777_msgprivkey(data,datalen),msg->sig.pubkey)) != 0 ) + { + //int32_t i; + //char str[65],str2[65]; + //for (i=0; i>>>>>>>>>>>>>>> validated [%ld] len.%d (%s + %s)\n",(long)data-(long)msg,datalen,bits256_str(str,acct777_msgprivkey(data,datalen)),bits256_str(str2,msg->sig.pubkey)); + memset(buf,0,sizeof(buf)); + acct777_rwsig(1,buf,&msg->sig); + memcpy(&msg->sig,buf,sizeof(buf)); + return(msg); + } else printf("error validating crypto777_msgcreate msg\n"); + return(0); +} + +void crypto777_catchain(struct supernet_info *myinfo,struct private_chain *cat,bits256 *prevhashp,bits256 *btchashp) +{ + *btchashp = myinfo->BTCmarkerhash; + //*prevhashp = cat->catchain->hwmhash; +} + +char *crypto777_sendmsg(struct supernet_info *myinfo,bits256 category,bits256 subhash,uint8_t *data,int32_t datalen,int32_t hops,char cmdstr[8]) +{ + char *hexstr,*retstr; int32_t i; struct crypto777_msghdr *msg; bits256 prevhash,btchash; struct private_chain *cat; + msg = calloc(1,datalen + sizeof(*msg)); + for (i=0; icmd); i++) + if ( (msg->cmd[i]= cmdstr[i]) == 0 ) + break; + cat = private_chain(category,subhash); + crypto777_catchain(myinfo,cat,&prevhash,&btchash); + iguana_rwbignum(1,msg->prevhash.bytes,sizeof(bits256),prevhash.bytes); + iguana_rwbignum(1,msg->btchash.bytes,sizeof(bits256),btchash.bytes); + memcpy(msg->serialized,data,datalen); + if ( crypto777_msgcreate(myinfo,msg,datalen) != 0 ) + { + printf(">>>>>>>>>>>> crypto777_send.(%s) datalen.%d allocsize.%d crc.%x\n",cmdstr,datalen,msg->sig.allocsize,calc_crc32(0,(void *)((long)msg + 8),datalen-8)); + hexstr = malloc(msg->sig.allocsize*2 + 1); + init_hexbytes_noT(hexstr,(uint8_t *)msg,msg->sig.allocsize); + retstr = SuperNET_categorymulticast(myinfo,0,category,subhash,hexstr,0,hops,1,0,0); + free(hexstr), free(msg); + return(retstr); + } + else + { + free(msg); + printf("cant crypto777 msgcreate datalen.%d\n",datalen); + return(clonestr("{\"error\":\"couldnt create crypto777 message\"}")); + } +} + +char *crypto777_hexmsg(struct supernet_info *myinfo,void *ptr,int32_t len,char *remoteaddr) +{ + struct crypto777_msghdr *msg = ptr; int32_t slen,datalen,newlen,flag = 0; bits256 prevhash,btchash; + uint8_t *serdata; uint64_t signerbits; uint8_t tmp[sizeof(msg->sig)]; cJSON *argjson = 0; + datalen = len - (int32_t)sizeof(msg->sig); + serdata = (void *)((long)msg + sizeof(msg->sig)); + acct777_rwsig(0,(void *)&msg->sig,(void *)tmp); + memcpy(&msg->sig,tmp,sizeof(msg->sig)); + /*if ( remoteaddr != 0 && remoteaddr[0] == 0 && strcmp("127.0.0.1",remoteaddr) == 0 && ((uint8_t *)msg)[len-1] == 0 && (argjson= cJSON_Parse((char *)msg)) != 0 ) + { + printf("string crypto777_hexmsg RESULT.(%s)\n",jprint(argjson,0)); + free_json(argjson); + return(clonestr("{\"error\":\"string base packets deprecated\"}")); + } + else*/ if ( (signerbits= acct777_validate(&msg->sig,acct777_msgprivkey(serdata,datalen),msg->sig.pubkey)) != 0 ) + { + flag++; + iguana_rwbignum(0,msg->prevhash.bytes,sizeof(bits256),prevhash.bytes); + iguana_rwbignum(0,msg->btchash.bytes,sizeof(bits256),btchash.bytes); + printf("crypto777_hexmsg <<<<<<<<<<<<< sigsize.%d VALIDATED [%ld] len.%d t%u allocsize.%d (%s) [%d]\n",(int32_t)sizeof(msg->sig),(long)serdata-(long)msg,datalen,msg->sig.timestamp,msg->sig.allocsize,(char *)msg->serialized,serdata[datalen-1]); + newlen = (int32_t)(msg->sig.allocsize - ((long)msg->serialized - (long)msg)); + serdata = msg->serialized; + if ( (argjson= cJSON_Parse((char *)serdata)) != 0 ) + { + slen = (int32_t)strlen((char *)serdata) + 1; + serdata = &serdata[slen]; + newlen -= slen; + free_json(argjson); + } + } + return(clonestr("{\"result\":\"test packet\"}")); +} +#endif + +/* + Consensus rules: + 0. Valid burn protocol or new issuance with small fee to crypto777 account -> OP_RETURN on BTCD with txid of payment/burn + Ti boundary - Balances reconciled and signed by issuer or super majority vote. Only amounts marked as frozen eligible for atomic swaps. + tx via p2p, signed payment to dest acct, based on balance. no outputs to double spend + payment valid during Ti and Ti+1 + atomic cross chain: both sides freeze trade amount, wait for this to be confirmed in BTC OP_RETURN, then a joint swap tx is signed by both and submitted to both chains + + valid tx must be accepted and sig added with Ti slippage. It is valid if signed, and balance is available. + + When Ti boundary changes, all online nodes reconcile the submitted tx to make sure all are confirmed and balances updated. Special tx like freezing, atomics, etc. + +Top PoS account publishes balance changes and majority stake approves. Next trade period starts at Ti+2 + + Split into odd/even offset periods to allow nonstop tx + + 1. all nodes must ntp and all tx must be timestamped within 50 seconds in the past and cant be more than 10 seconds from the future. + 2. tx spends cannot exceed available balance/2 as of prior Ti. + 2. all tx must refer to the latest BTC.Ti and BTCD.Ti and BTC.RTblock. any tx received that has older BTC.Ti is rejected. + 3. +*/ diff --git a/_API.md b/deprecated/_API.md similarity index 100% rename from _API.md rename to deprecated/_API.md diff --git a/field.html b/deprecated/field.html similarity index 100% rename from field.html rename to deprecated/field.html diff --git a/footer.html b/deprecated/footer.html similarity index 100% rename from footer.html rename to deprecated/footer.html diff --git a/formfooter.html b/deprecated/formfooter.html similarity index 100% rename from formfooter.html rename to deprecated/formfooter.html diff --git a/formheader.html b/deprecated/formheader.html similarity index 100% rename from formheader.html rename to deprecated/formheader.html diff --git a/header.html b/deprecated/header.html similarity index 100% rename from header.html rename to deprecated/header.html diff --git a/deprecated/iguana_instantdex.c b/deprecated/iguana_instantdex.c new file mode 100755 index 000000000..9f21a4309 --- /dev/null +++ b/deprecated/iguana_instantdex.c @@ -0,0 +1,1610 @@ +/****************************************************************************** + * Copyright © 2014-2016 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +// selftest supports against allpairs list + +#include "exchanges777.h" + +struct instantdex_stateinfo *BTC_states; int32_t BTC_numstates; + +int64_t instantdex_BTCsatoshis(uint64_t price,uint64_t volume) +{ + volume *= price; + volume /= SATOSHIDEN; + return(volume); +} + +void instantdex_swapfree(struct instantdex_accept *A,struct bitcoin_swapinfo *swap) +{ + if ( A != 0 ) + free(A); + if ( swap != 0 ) + { + if ( swap->deposit != 0 ) + free(swap->deposit); + if ( swap->payment != 0 ) + free(swap->payment); + if ( swap->altpayment != 0 ) + free(swap->altpayment); + if ( swap->myfee != 0 ) + free(swap->myfee); + if ( swap->otherfee != 0 ) + free(swap->otherfee); + } +} + +int32_t instantdex_unbasebits(char *base,uint64_t basebits) +{ + char tmp[9]; + unstringbits(tmp,basebits); + if ( iguana_coinfind(tmp) == 0 ) + { + sprintf(base,"%lld",(long long)basebits); + return(1); + } + else + { + strcmp(base,tmp); + return(0); + } +} + +uint64_t instantdex_basebits(char *base) +{ + if ( is_decimalstr(base) != 0 ) + return(calc_nxt64bits(base)); + else return(stringbits(base)); +} + +int32_t instantdex_orderidcmp(uint64_t orderidA,uint64_t orderidB,int32_t strictflag) +{ + if ( strictflag == 0 ) + { + orderidA &= INSTANTDEX_ORDERSTATE_ORDERIDMASK; + orderidB &= INSTANTDEX_ORDERSTATE_ORDERIDMASK; + } + //printf("orderidA %llx vs orderidB %llx -> %llx\n",(long long)orderidA,(long long)orderidB,(long long)(orderidA ^ orderidB)); + return((orderidA ^ orderidB) != 0); +} + +uint64_t instantdex_decodehash(char *base,char *rel,int64_t *pricep,uint64_t *accountp,bits256 encodedhash) +{ + int32_t i; uint64_t offerid; + base[4] = rel[4] = 0; + for (i=0; i<4; i++) + { + base[i] = encodedhash.bytes[8 + i]; + rel[i] = encodedhash.bytes[12 + i]; + } + iguana_rwnum(0,(void *)&encodedhash.ulongs[2],sizeof(uint64_t),pricep); + iguana_rwnum(0,(void *)&encodedhash.ulongs[3],sizeof(uint64_t),accountp); + iguana_rwnum(0,(void *)&encodedhash.ulongs[0],sizeof(uint64_t),&offerid); + return(encodedhash.ulongs[0]); +} + +bits256 instantdex_encodehash(char *base,char *rel,int64_t price,uint64_t orderid,uint64_t account) +{ + bits256 encodedhash; int32_t i; char _base[4],_rel[4]; + iguana_rwnum(1,(void *)&encodedhash.ulongs[0],sizeof(uint64_t),&orderid); + memset(_base,0,sizeof(_base)); + memset(_rel,0,sizeof(_rel)); + strncpy(_base,base,4); + strncpy(_rel,rel,4); + for (i=0; i<4; i++) + { + encodedhash.bytes[8 + i] = _base[i]; + encodedhash.bytes[12 + i] = _rel[i]; + } + iguana_rwnum(1,(void *)&encodedhash.ulongs[2],sizeof(uint64_t),&price); + iguana_rwnum(1,(void *)&encodedhash.ulongs[3],sizeof(uint64_t),&account); + return(encodedhash); +} + +cJSON *instantdex_defaultprocess(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) +{ + uint8_t *serdata = *serdatap; int32_t serdatalen = *serdatalenp; + *serdatap = 0, *serdatalenp = 0; + if ( serdata != 0 && serdatalen > 0 ) + { + serdata[serdatalen-1] = 0; + } + return(newjson); +} + +cJSON *instantdex_defaulttimeout(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) +{ + uint8_t *serdata = *serdatap; int32_t serdatalen = *serdatalenp; + *serdatap = 0, *serdatalenp = 0; + if ( serdata != 0 && serdatalen > 0 ) + { + serdata[serdatalen-1] = 0; + } + return(newjson); +} + +struct instantdex_stateinfo instantdex_errorstate = { "error", 0,0, instantdex_defaultprocess, instantdex_defaulttimeout }; +struct instantdex_stateinfo instantdex_timeoutstate = { "timeout", 1,0, instantdex_defaultprocess, instantdex_defaulttimeout }; + +struct instantdex_stateinfo *instantdex_statefind(struct instantdex_stateinfo *states,int32_t numstates,char *statename) +{ + int32_t i; struct instantdex_stateinfo *state = 0; + if ( states != 0 && statename != 0 && numstates > 0 ) + { + for (i=0; iname,statename) == 0 ) + return(state); + } + } + return(0); +} + +void instantdex_stateinit(struct instantdex_stateinfo *states,int32_t numstates,struct instantdex_stateinfo *state,char *name,char *errorstr,char *timeoutstr,void *process_func,void *timeout_func) +{ + struct instantdex_stateinfo *timeoutstate,*errorstate; + memset(state,0,sizeof(*state)); + strcpy(state->name,name); + if ( (errorstate= instantdex_statefind(states,numstates,errorstr)) == 0 ) + errorstate = &instantdex_errorstate; + state->errorind = errorstate->ind; + if ( (timeoutstate= instantdex_statefind(states,numstates,timeoutstr)) == 0 ) + timeoutstate = &instantdex_timeoutstate; + else printf("TS.%s ",timeoutstr); + state->timeoutind = timeoutstate->ind; + if ( (state->process= process_func) == 0 ) + state->process = instantdex_defaultprocess; + if ( (state->timeout= timeout_func) == 0 ) + state->timeout = instantdex_defaulttimeout; +} + +struct instantdex_stateinfo *instantdex_statecreate(struct instantdex_stateinfo *states,int32_t *numstatesp,char *name,cJSON *(*process_func)(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp),cJSON *(*timeout_func)(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp),char *timeoutstr,char *errorstr,int32_t initialstate) +{ + struct instantdex_stateinfo S,*state = 0; + if ( (state= instantdex_statefind(states,*numstatesp,name)) == 0 ) + { + states = realloc(states,sizeof(*states) * (*numstatesp + 1)); + state = &states[*numstatesp]; + instantdex_stateinit(states,*numstatesp,state,name,errorstr,timeoutstr,process_func,timeout_func); + state->initialstate = initialstate; + printf("STATES[%d] %s %p %p %d %d\n",*numstatesp,state->name,state->process,state->timeout,state->timeoutind,state->errorind); + state->ind = (*numstatesp)++; + } + else + { + instantdex_stateinit(states,*numstatesp,&S,name,errorstr,timeoutstr,process_func,timeout_func); + S.ind = state->ind; + S.initialstate = initialstate; + if ( memcmp(&S,state,sizeof(S) - sizeof(void *) - sizeof(int)) != 0 ) + { + int32_t i; + for (i=0; iname,state->process,state->timeout,state->timeoutind,state->errorind,S.name,S.process,S.timeout,S.timeoutind,S.errorind); + printf("statecreate error!!! (%s) already exists\n",name); + } + } + return(states); +} + +struct instantdex_event *instantdex_addevent(struct instantdex_stateinfo *states,int32_t numstates,char *statename,char *cmdstr,char *sendcmd,char *nextstatename) +{ + struct instantdex_stateinfo *nextstate,*state; + if ( (state= instantdex_statefind(states,numstates,statename)) != 0 && (nextstate= instantdex_statefind(states,numstates,nextstatename)) != 0 ) + { + if ( (state->events= realloc(state->events,(state->numevents + 1) * sizeof(*state->events))) != 0 ) + { + memset(&state->events[state->numevents],0,sizeof(state->events[state->numevents])); + strcpy(state->events[state->numevents].cmdstr,cmdstr); + if ( sendcmd != 0 ) + strcpy(state->events[state->numevents].sendcmd,sendcmd); + state->events[state->numevents].nextstateind = nextstate->ind; + printf("[%d] (%s).%d %s -> %s, send.%s %d\n",state->ind,state->name,state->numevents,cmdstr,states[nextstate->ind].name,sendcmd==0?"":sendcmd,nextstate->ind); + state->numevents++; + } + return(state->events); + } + else + { + int32_t i; + for (i=0; i %s) without existing state and nextstate\n",statename,nextstatename); + exit(-1); + return(0); + } +} + +double instantdex_FSMtest(struct instantdex_stateinfo *states,int32_t numstates,int32_t maxiters) +{ + int32_t i,most,r,r2,n,m=0,initials[100],nextstate=-1; + struct instantdex_stateinfo *state; struct instantdex_event *event; double sum = 0.; + if ( maxiters < 1 ) + maxiters = 1; + for (i=n=most=0; i 0 ) + { + printf("initialstate[%d] %d %s\n",i,states[i].initialstate,states[i].name); + initials[n++] = i; + } + if ( n > 0 && n < sizeof(initials)/sizeof(*initials) ) + { + for (i=0; iname[0] == 0 || state->ind >= numstates ) + { + printf("illegal state.(%s) %d? ind.%d >= numstates.%d\n",state->name,nextstate,state->ind,numstates); + break; + } + m = 0; + while ( m++ < 1000 && state->initialstate >= 0 && state->numevents != 0 ) + { + if ( (i % 1000000) == 0 ) + fprintf(stderr,"%s ",state->name); + r2 = rand() % state->numevents; + event = &state->events[r2]; + if ( (nextstate= event->nextstateind) < 0 ) + break; + if ( event->nextstateind >= numstates ) + { + printf("nextstateind overflow? %d vs %d\n",event->nextstateind,numstates); + break; + } + state = &states[event->nextstateind]; + } + if ( m > most ) + most = m; + sum += m; + if ( (i % 1000000) == 0 ) + fprintf(stderr,"reached %s m.%d events most.%d ave %.2f\n",state->name,m,most,sum/(i+1)); + } + } + fprintf(stderr," most.%d ave %.2f\n",most,sum/(i+1)); + return(sum / maxiters); +} + +void instantdex_FSMinit() +{ + if ( BTC_states == 0 ) + BTC_states = BTC_initFSM(&BTC_numstates); +} + +cJSON *InstantDEX_argjson(char *reference,char *message,char *othercoinaddr,char *otherNXTaddr,int32_t iter,int32_t val,int32_t val2) +{ + cJSON *argjson = cJSON_CreateObject(); + if ( reference != 0 ) + jaddstr(argjson,"refstr",reference); + if ( message != 0 && message[0] != 0 ) + jaddstr(argjson,"message",message); + if ( othercoinaddr != 0 && othercoinaddr[0] != 0 ) + jaddstr(argjson,"othercoinaddr",othercoinaddr); + if ( otherNXTaddr != 0 && otherNXTaddr[0] != 0 ) + jaddstr(argjson,"otherNXTaddr",otherNXTaddr); + //jaddbits256(argjson,"basetxid",basetxid); + //jaddbits256(argjson,"reltxid",reltxid); + if ( iter != 3 ) + { + if ( val == 0 ) + val = INSTANTDEX_DURATION; + jaddnum(argjson,"duration",val); + jaddnum(argjson,"flags",val2); + } + else + { + if ( val > 0 ) + jaddnum(argjson,"baseheight",val); + if ( val2 > 0 ) + jaddnum(argjson,"relheight",val2); + } + return(argjson); +} + +struct instantdex_msghdr *instantdex_msgcreate(struct supernet_info *myinfo,struct instantdex_msghdr *msg,int32_t datalen) +{ + bits256 otherpubkey; uint64_t signerbits; uint32_t timestamp; uint8_t buf[sizeof(msg->sig)],*data; + memset(&msg->sig,0,sizeof(msg->sig)); + datalen += (int32_t)(sizeof(*msg) - sizeof(msg->sig)); + data = (void *)((long)msg + sizeof(msg->sig)); + otherpubkey = acct777_msgpubkey(data,datalen); + timestamp = (uint32_t)time(NULL); + acct777_sign(&msg->sig,myinfo->privkey,otherpubkey,timestamp,data,datalen); + //printf("signed datalen.%d allocsize.%d crc.%x\n",datalen,msg->sig.allocsize,calc_crc32(0,data,datalen)); + if ( (signerbits= acct777_validate(&msg->sig,acct777_msgprivkey(data,datalen),msg->sig.pubkey)) != 0 ) + { + //int32_t i; + //char str[65],str2[65]; + //for (i=0; i>>>>>>>>>>>>>>> validated [%ld] len.%d (%s + %s)\n",(long)data-(long)msg,datalen,bits256_str(str,acct777_msgprivkey(data,datalen)),bits256_str(str2,msg->sig.pubkey)); + memset(buf,0,sizeof(buf)); + acct777_rwsig(1,buf,&msg->sig); + memcpy(&msg->sig,buf,sizeof(buf)); + return(msg); + } else printf("error validating instantdex msg\n"); + return(0); +} + +bits256 instantdex_rwoffer(int32_t rwflag,int32_t *lenp,uint8_t *serialized,struct instantdex_offer *offer) +{ + bits256 orderhash; int32_t len = 0; + if ( rwflag == 1 ) + { + vcalc_sha256(0,orderhash.bytes,(void *)offer,sizeof(*offer)); + /*int32_t i; + for (i=0; ibase),offer->base); + len += iguana_rwvarstr(rwflag,&serialized[len],sizeof(offer->rel),offer->rel); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(offer->price64),&offer->price64); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(offer->basevolume64),&offer->basevolume64); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(offer->account),&offer->account); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(offer->expiration),&offer->expiration); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(offer->nonce),&offer->nonce); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(offer->myside),&offer->myside); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(offer->acceptdir),&offer->acceptdir); + if ( rwflag == 0 ) + { + vcalc_sha256(0,orderhash.bytes,(void *)offer,sizeof(*offer)); + /*int32_t i; + for (i=0; imyaddr.persistent); + reqstr = jprint(argjson,0); + slen = (int32_t)(strlen(reqstr) + 1); + if ( swap->otherchoosei < 0 ) + { + extraser = (void *)swap->deck; + extralen = (int32_t)sizeof(swap->deck); + serflag = 1; + } + else if ( swap->otherverifiedcut == 0 && bits256_nonz(swap->privkeys[swap->otherchoosei]) == 0 ) + { + extraser = swap->privkeys[0].bytes; + extralen = (int32_t)sizeof(swap->privkeys); + serflag = 2; + } else serflag = 0; + datalen = (int32_t)slen + extralen + olen; + msg = calloc(1,datalen + sizeof(*msg)); + for (i=0; icmd); i++) + if ( (msg->cmd[i]= cmdstr[i]) == 0 ) + break; + memcpy(msg->serialized,reqstr,slen); + memcpy(&msg->serialized[slen],serialized,olen); + //printf("extralen.%d datalen.%d slen.%d olen.%d\n",extralen,datalen,slen,olen); + if ( extralen > 0 ) + { + memcpy(&msg->serialized[slen + olen],extraser,extralen); + len = 0; + if ( serflag == 1 ) + { + //printf("send deck (%llx %llx)\n",(long long)swap->deck[0][0],(long long)swap->deck[0][1]); + while ( len < extralen ) + { + memcpy(&x,&((uint8_t *)extraser)[len],sizeof(x)); + iguana_rwnum(1,&((uint8_t *)extraser)[len],sizeof(x),&x); + len += sizeof(x); + } + } + else if ( serflag == 2 ) + { + while ( len < extralen ) + { + memcpy(&tmphash,&((uint8_t *)extraser)[len],sizeof(tmphash)); + for (j=0; j<32; j++) + ((uint8_t *)extraser)[len++] = tmphash.bytes[j]; + len += sizeof(bits256); + } + } + } + free(reqstr); + int32_t delaymillis=0,encryptflag=0; uint8_t *data; uint32_t basilisktag=0; + buf = malloc(datalen*2 + 1); + init_hexbytes_noT((char *)buf,(uint8_t *)msg,datalen); + sendjson = cJSON_CreateObject(); + jaddstr(sendjson,"hexmsg",(char *)buf); + free(buf); + //jaddstr(sendjson,"agent","SuperNET"); + //jaddstr(sendjson,"method","DHT"); + //jaddnum(sendjson,"plaintext",1); + //jaddbits256(sendjson,"categoryhash",myinfo->instantdex_category); + jaddstr(sendjson,"cmd",cmdstr); + jaddstr(sendjson,"handle",myinfo->handle); + jaddbits256(sendjson,"traderpub",myinfo->myaddr.persistent); + data = basilisk_jsondata(sizeof(struct iguana_msghdr),&allocptr,space,sizeof(space),&datalen,swap->mine.offer.base,sendjson,basilisktag); + basilisk_sendcmd(myinfo,addr->ipaddr,"DEX",&basilisktag,encryptflag,delaymillis,data,datalen,1,BASILISK_DEFAULTDIFF); + free_json(sendjson); + if ( allocptr != 0 ) + free(allocptr); + return(clonestr("{\"result\":\"success\"}")); + + /* if ( instantdex_msgcreate(myinfo,msg,datalen) != 0 ) + { + //printf(">>>>>>>>>>>> instantdex send.(%s) datalen.%d allocsize.%d crc.%x\n",cmdstr,datalen,msg->sig.allocsize,calc_crc32(0,(void *)((long)msg + 8),datalen-8)); + if ( addr != 0 ) + { + memset(serialized,0,sizeof(struct iguana_msghdr)); + memcpy(&serialized[sizeof(struct iguana_msghdr)],(uint8_t *)msg,msg->sig.allocsize); + iguana_queue_send(addr,0,serialized,"InstantDEX",msg->sig.allocsize); + } + else + { + printf("instantdex_sendcmd: deprecated path\n"); + if ( (hexstr= malloc(msg->sig.allocsize*2 + 1)) != 0 ) + { + init_hexbytes_noT(hexstr,(uint8_t *)msg,msg->sig.allocsize); + if ( (retstr= SuperNET_categorymulticast(myinfo,0,myinfo->instantdex_category,desthash,hexstr,0,hops,1,argjson,0)) != 0 ) + free(retstr); + free(hexstr); + } + } + free(msg); + return(jprint(argjson,0)); + } + else + { + free(msg); + printf("cant msgcreate datalen.%d\n",datalen); + return(clonestr("{\"error\":\"couldnt create instantdex message\"}")); + }*/ +} + +int32_t instantdex_bidaskdir(struct instantdex_offer *offer) +{ + if ( offer->myside == 0 && offer->acceptdir > 0 ) // base + return(-1); + else if ( offer->myside == 1 && offer->acceptdir < 0 ) // rel + return(1); + else return(0); +} + +cJSON *instantdex_offerjson(struct instantdex_offer *offer,uint64_t orderid) +{ + int32_t dir; cJSON *item = cJSON_CreateObject(); + jadd64bits(item,"orderid",orderid); + jadd64bits(item,"account",offer->account); + if ( (dir= instantdex_bidaskdir(offer)) > 0 ) + jaddstr(item,"type","bid"); + else if ( dir < 0 ) + jaddstr(item,"type","ask"); + else + { + jaddstr(item,"type","strange"); + jaddnum(item,"acceptdir",offer->acceptdir); + jaddnum(item,"myside",offer->myside); + } + jaddstr(item,"base",offer->base); + jaddstr(item,"rel",offer->rel); + jaddnum(item,"timestamp",offer->expiration); + jaddnum(item,"price",dstr(offer->price64)); + jaddnum(item,"volume",dstr(offer->basevolume64)); + jaddnum(item,"minperc",offer->minperc); + jaddnum(item,"nonce",offer->nonce); + jaddnum(item,"expiresin",offer->expiration - time(NULL)); + return(item); +} + +cJSON *instantdex_acceptjson(struct instantdex_accept *ap) +{ + cJSON *item = cJSON_CreateObject(); + jadd64bits(item,"orderid",ap->orderid); + jaddnum(item,"pendingvolume",dstr(ap->pendingvolume64)); + if ( ap->dead != 0 ) + jadd64bits(item,"dead",ap->dead); + jadd(item,"offer",instantdex_offerjson(&ap->offer,ap->orderid)); + return(item); +} + +void instantdex_statetxjson(struct iguana_info *coin,cJSON *array,char *name,struct bitcoin_statetx *tx) +{ + cJSON *item; + if ( tx != 0 ) + { + item = cJSON_CreateObject(); + jaddbits256(item,"txid",tx->txid); + jaddnum(item,"inputsum",dstr(tx->inputsum)); + jaddnum(item,"amount",dstr(tx->amount)); + jaddnum(item,"change",dstr(tx->change)); + jaddnum(item,"txfee",dstr(tx->inputsum) - dstr(tx->amount) - dstr(tx->change)); + jaddnum(item,"confirms",iguana_txidstatus(coin,tx->txid)); + jaddstr(item,"destaddr",tx->destaddr); + jaddstr(item,"txbytes",tx->txbytes); + jadd(array,name,item); + } +} + +cJSON *instantdex_statemachinejson(struct bitcoin_swapinfo *swap) +{ + cJSON *retjson,*txs; int32_t isbob,mydir,otherdir; + retjson = cJSON_CreateObject(); + if ( swap != 0 ) + { + mydir = instantdex_bidaskdir(&swap->mine.offer); + otherdir = instantdex_bidaskdir(&swap->other.offer); + isbob = instantdex_isbob(swap); + jaddnum(retjson,"isbob",isbob); + jaddnum(retjson,"mydir",mydir); + jaddnum(retjson,"otherdir",otherdir); + jaddnum(retjson,"expiration",swap->expiration); + jaddnum(retjson,"insurance",dstr(swap->insurance)); + jaddnum(retjson,"baseamount",dstr(swap->altsatoshis)); + jaddnum(retjson,"BTCamount",dstr(swap->BTCsatoshis)); + jaddnum(retjson,"expiration",swap->expiration); + if ( swap->dead != 0 ) + jadd64bits(retjson,"dead",swap->dead); + jaddbits256(retjson,"privAm",swap->privAm); + jaddbits256(retjson,"pubAm",swap->pubAm); + jaddbits256(retjson,"privBn",swap->privBn); + jaddbits256(retjson,"pubBn",swap->pubBn); + jaddbits256(retjson,"myorderhash",swap->myorderhash); + jaddnum(retjson,"choosei",swap->choosei); + jaddnum(retjson,"cutverified",swap->cutverified); + jaddbits256(retjson,"othertrader",swap->othertrader); + jaddbits256(retjson,"otherorderhash",swap->otherorderhash); + jaddnum(retjson,"otherchoosei",swap->otherchoosei); + jaddnum(retjson,"otherverifiedcut",swap->otherverifiedcut); + if ( isbob == 0 ) + { + jaddbits256(retjson,"pubA0",swap->mypubs[0]); + jaddbits256(retjson,"pubA1",swap->mypubs[1]); + jaddbits256(retjson,"pubB0",swap->otherpubs[0]); + jaddbits256(retjson,"pubB1",swap->otherpubs[1]); + } + else + { + jaddbits256(retjson,"pubB0",swap->mypubs[0]); + jaddbits256(retjson,"pubB1",swap->mypubs[1]); + jaddbits256(retjson,"pubA0",swap->otherpubs[0]); + jaddbits256(retjson,"pubA1",swap->otherpubs[1]); + } + if ( mydir > 0 && otherdir < 0 ) + { + jadd64bits(retjson,"bidid",swap->mine.orderid); + jadd64bits(retjson,"askid",swap->other.orderid); + } + else if ( mydir < 0 && otherdir > 0 ) + { + jadd64bits(retjson,"askid",swap->mine.orderid); + jadd64bits(retjson,"bidid",swap->other.orderid); + } + jadd(retjson,"other",instantdex_acceptjson(&swap->other)); + jadd(retjson,"mine",instantdex_acceptjson(&swap->mine)); + if ( swap->state != 0 ) + jaddstr(retjson,"state",swap->state->name); + txs = cJSON_CreateObject(); + instantdex_statetxjson(swap->coinbtc,txs,"deposit",swap->deposit); + instantdex_statetxjson(swap->coinbtc,txs,"payment",swap->payment); + instantdex_statetxjson(swap->altcoin,txs,"altpayment",swap->altpayment); + instantdex_statetxjson(swap->coinbtc,txs,"myfee",swap->myfee); + instantdex_statetxjson(swap->coinbtc,txs,"otherfee",swap->otherfee); + jadd(retjson,"txs",txs); + jaddstr(retjson,"status",swap->status); + } + return(retjson); +} + +cJSON *instantdex_historyjson(struct bitcoin_swapinfo *swap) +{ + // need to make sure accepts are put onto history queue when they are completed or deaded + // also to make permanent copy (somewhere) + return(instantdex_statemachinejson(swap)); +} + +struct bitcoin_swapinfo *instantdex_historyfind(struct supernet_info *myinfo,struct exchange_info *exchange,uint64_t orderid) +{ + struct bitcoin_swapinfo *swap,*tmp,*retswap = 0; + portable_mutex_lock(&exchange->mutexH); + DL_FOREACH_SAFE(exchange->history,swap,tmp) + { + if ( instantdex_orderidcmp(swap->mine.orderid,orderid,0) == 0 ) + { + retswap = swap; + break; + } + } + portable_mutex_unlock(&exchange->mutexH); + return(retswap); +} + +void instantdex_historyadd(struct exchange_info *exchange,struct bitcoin_swapinfo *swap) +{ + portable_mutex_lock(&exchange->mutexH); + DL_APPEND(exchange->history,swap); + portable_mutex_unlock(&exchange->mutexH); +} + +struct bitcoin_swapinfo *instantdex_statemachinefind(struct supernet_info *myinfo,struct exchange_info *exchange,uint64_t orderid) +{ + struct bitcoin_swapinfo *tmp,*swap,*retswap = 0; uint32_t now; + now = (uint32_t)time(NULL); + portable_mutex_lock(&exchange->mutexS); + DL_FOREACH_SAFE(exchange->statemachines,swap,tmp) + { + //printf("%p search for orderid.%llx in (%llx/%llx) %u %u\n",exchange->statemachines,(long long)orderid,(long long)swap->mine.orderid,(long long)swap->other.orderid,swap->mine.dead,swap->other.dead); + if ( now < swap->expiration && swap->mine.dead == 0 && swap->other.dead == 0 ) + { + if ( instantdex_orderidcmp(swap->mine.orderid,orderid,0) == 0 || instantdex_orderidcmp(swap->other.orderid,orderid,0) == 0 ) + { + retswap = swap; + break; + } + } + else + { + strcpy(swap->status,"expired"); + printf("expired pending, need to take action, send timeout event\n"); + DL_DELETE(exchange->statemachines,swap); + instantdex_historyadd(exchange,swap); + } + } + //printf("found statemachine.%p\n",retswap); + portable_mutex_unlock(&exchange->mutexS); + return(retswap); +} + +struct instantdex_accept *instantdex_offerfind(struct supernet_info *ignore,struct exchange_info *exchange,cJSON *bids,cJSON *asks,uint64_t orderid,char *base,char *rel,int32_t report) +{ + struct instantdex_accept *tmp,*ap,*retap = 0; uint32_t now; cJSON *item,*offerobj; char *type; + if ( exchange == 0 ) + return(0); + now = (uint32_t)time(NULL); + portable_mutex_lock(&exchange->mutex); + DL_FOREACH_SAFE(exchange->offers,ap,tmp) + { + if ( now < ap->offer.expiration && ap->dead == 0 ) + { + //printf("%d %d find cmps %d %d %d %d %d %d me.%llu vs %llu o.%llx | vs %llu\n",instantdex_bidaskdir(&ap->offer),ap->offer.expiration-now,strcmp(base,"*") == 0,strcmp(base,ap->offer.base) == 0,strcmp(rel,"*") == 0,strcmp(rel,ap->offer.rel) == 0,orderid == 0,orderid == ap->orderid,(long long)myinfo->myaddr.nxt64bits,(long long)ap->offer.account,(long long)ap->orderid,(long long)orderid); + if ( (report == 0 || ap->reported == 0) && (strcmp(base,"*") == 0 || strcmp(base,ap->offer.base) == 0) && (strcmp(rel,"*") == 0 || strcmp(rel,ap->offer.rel) == 0) && (orderid == 0 || instantdex_orderidcmp(ap->orderid,orderid,0) == 0) ) + { + if ( report != 0 && ap->reported == 0 ) + { + ap->reported = 1; + printf("MARK as reported %llx\n",(long long)ap->orderid); + } + retap = ap; + if ( (bids != 0 || asks != 0) && (item= instantdex_acceptjson(ap)) != 0 ) + { + //printf("item.(%s)\n",jprint(item,0)); + if ( (offerobj= jobj(item,"offer")) != 0 && (type= jstr(offerobj,"type")) != 0 ) + { + if ( bids != 0 && strcmp(type,"bid") == 0 ) + jaddi(bids,jduplicate(offerobj)); + else if ( asks != 0 && strcmp(type,"ask") == 0 ) + jaddi(asks,jduplicate(offerobj)); + } + free_json(item); + } + } + } + else + { + DL_DELETE(exchange->offers,ap); + free(ap); + } + } + portable_mutex_unlock(&exchange->mutex); + //printf("offerfind -> retap.%p Qsize.%d\n",retap,queue_size(&exchange->acceptableQ)); + return(retap); +} + +void instantdex_statemachineadd(struct exchange_info *exchange,struct bitcoin_swapinfo *swap) +{ + portable_mutex_lock(&exchange->mutexS); + DL_APPEND(exchange->statemachines,swap); + portable_mutex_unlock(&exchange->mutexS); +} + +void instantdex_offeradd(struct exchange_info *exchange,struct instantdex_accept *ap) +{ + portable_mutex_lock(&exchange->mutex); + DL_APPEND(exchange->offers,ap); + portable_mutex_unlock(&exchange->mutex); +} + +int32_t instantdex_peerhas_clear(struct iguana_info *coin,struct iguana_peer *addr) +{ + struct instantdex_accept *tmp,*ap; struct exchange_info *exchange; int32_t ind,num = 0; + if ( addr != 0 && (exchange= exchanges777_find("bitcoin")) != 0 ) + { + //printf("clear all bits for addrind.%d\n",addr->addrind); + ind = addr->addrind; + portable_mutex_lock(&exchange->mutex); + DL_FOREACH_SAFE(exchange->offers,ap,tmp) + { + CLEARBIT(ap->peerhas,ind); + } + portable_mutex_unlock(&exchange->mutex); + } + return(num); +} + +struct instantdex_accept *instantdex_acceptable(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,double minperc) +{ + struct instantdex_accept *tmp,*ap,*retap = 0; double aveprice; uint64_t minvol,bestprice64 = 0; uint32_t now; int32_t offerdir; + if ( exchange == 0 ) + { + printf("instantdex_acceptable null exchange\n"); + return(0); + } + aveprice = 0;//instantdex_avehbla(myinfo,retvals,A->offer.base,A->offer.rel,dstr(A->offer.basevolume64)); + now = (uint32_t)time(NULL); + offerdir = instantdex_bidaskdir(&A->offer); + minvol = ((A->offer.basevolume64 * minperc) / 100); + //printf("instantdex_acceptable offerdir.%d (%s/%s) minperc %.3f minvol %.8f vs %.8f\n",offerdir,A->offer.base,A->offer.rel,minperc,dstr(minvol),dstr(A->offer.basevolume64)); + portable_mutex_lock(&exchange->mutex); + DL_FOREACH_SAFE(exchange->offers,ap,tmp) + { + //printf("ap.%p account.%llu dir.%d\n",ap,(long long)ap->offer.account,offerdir); + if ( now > ap->offer.expiration || ap->dead != 0 || A->offer.account == ap->offer.account ) + { + printf("now.%u skip expired %u/dead.%u or my order orderid.%llx from %llu\n",now,ap->offer.expiration,ap->dead,(long long)ap->orderid,(long long)ap->offer.account); + } + else if ( A->offer.account != myinfo->myaddr.nxt64bits && ap->offer.account != myinfo->myaddr.nxt64bits ) + { + printf("skip offer as neither side matches account\n"); + } + else if ( strcmp(ap->offer.base,A->offer.base) != 0 || strcmp(ap->offer.rel,A->offer.rel) != 0 ) + { + printf("skip mismatched.(%s/%s) orderid.%llx from %llu\n",ap->offer.base,ap->offer.rel,(long long)ap->orderid,(long long)ap->offer.account); + } + else if ( offerdir*instantdex_bidaskdir(&ap->offer) > 0 ) + { + printf("skip same direction %d orderid.%llx from %llu\n",instantdex_bidaskdir(&ap->offer),(long long)ap->orderid,(long long)ap->offer.account); + } + else if ( minvol > ap->offer.basevolume64 - ap->pendingvolume64 ) + { + printf("skip too small order %.8f vs %.8f orderid.%llx from %llu\n",dstr(minvol),dstr(ap->offer.basevolume64)-dstr(ap->pendingvolume64),(long long)ap->orderid,(long long)ap->offer.account); + } + else if ( (offerdir > 0 && ap->offer.price64 > A->offer.price64) || (offerdir < 0 && ap->offer.price64 < A->offer.price64) ) + { + printf("skip out of band dir.%d offer %.8f vs %.8f orderid.%llx from %llu\n",offerdir,dstr(ap->offer.price64),dstr(A->offer.price64),(long long)ap->orderid,(long long)ap->offer.account); + } + else + { + if ( bestprice64 == 0 || (offerdir > 0 && ap->offer.price64 < bestprice64) || (offerdir < 0 && ap->offer.price64 > bestprice64) ) + { + printf(">>>> %llx MATCHED better price dir.%d offer %.8f vs %.8f orderid.%llx from %llu\n",(long long)A->orderid,offerdir,dstr(ap->offer.price64),dstr(A->offer.price64),(long long)ap->orderid,(long long)ap->offer.account); + bestprice64 = ap->offer.price64; + retap = ap; + } + } + } + portable_mutex_unlock(&exchange->mutex); + //printf("after acceptable Qsize.%d retap.%p\n",queue_size(&exchange->acceptableQ),retap); + return(retap); +} + +/*int32_t instantdex_inv2data(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,struct exchange_info *exchange) +{ + struct instantdex_accept *tmp,*ap; uint32_t now,n=0,len; bits256 encodedhash,hashes[100]; uint8_t serialized[100*36 + 1024]; + //printf("instantdex_inv2data exchange.%p (%s)\n",exchange,addr->ipaddr); + if ( exchange == 0 ) + return(0); + now = (uint32_t)time(NULL); + portable_mutex_lock(&exchange->mutex); + DL_FOREACH_SAFE(exchange->offers,ap,tmp) + { + if ( now < ap->offer.expiration && ap->dead == 0 ) + { + if ( instantdex_statemachinefind(0,exchange,ap->orderid) == 0 && instantdex_historyfind(0,exchange,ap->orderid) == 0 ) + { + encodedhash = instantdex_encodehash(ap->offer.base,ap->offer.rel,ap->offer.price64*instantdex_bidaskdir(&ap->offer),(ap->orderid&INSTANTDEX_ORDERSTATE_ORDERIDMASK) | ap->state,ap->offer.account); + if ( n < sizeof(hashes)/sizeof(*hashes) && GETBIT(ap->peerhas,addr->addrind) == 0 ) + { + hashes[n++] = encodedhash; + printf("(%d %llx) ",n,(long long)(ap->orderid&INSTANTDEX_ORDERSTATE_ORDERIDMASK) | ap->state); + } + } + } + else + { + DL_DELETE(exchange->offers,ap); + free(ap); + } + } + portable_mutex_unlock(&exchange->mutex); + if ( n > 0 ) + { + printf(" nhashes for (%s)\n",addr->ipaddr); + len = iguana_inv2packet(serialized,sizeof(serialized),MSG_QUOTE,hashes,n); + //printf("Send inv2[%d] -> (%s)\n",n,addr->ipaddr); + return(iguana_queue_send(addr,0,serialized,"inv2",len)); + } + return(-1); +}*/ + +struct instantdex_accept *instantdex_quotefind(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,bits256 encodedhash) +{ + char base[9],rel[9]; int64_t pricetoshis; uint64_t orderid,account; + orderid = instantdex_decodehash(base,rel,&pricetoshis,&account,encodedhash); + //printf("search for orderid.%llx (%s/%s) %.8f from %llu\n",(long long)orderid,base,rel,dstr(pricetoshis),(long long)account); + return(instantdex_offerfind(myinfo,exchanges777_find("bitcoin"),0,0,orderid,base,rel,0)); +} + +struct iguana_bundlereq *instantdex_recvquotes(struct iguana_info *coin,struct iguana_bundlereq *req,bits256 *quotes,int32_t n) +{ + int32_t i,len,state,m = 0; uint8_t serialized[10000]; struct instantdex_accept *ap; struct exchange_info *exchange; + exchange = exchanges777_find("bitcoin"); + if ( req->addr == 0 ) + return(0); + //printf("received quotehashes.%d from (%s)\n",n,req->addr->ipaddr); + for (i=1; iaddr,quotes[i])) != 0 ) + { + SETBIT(ap->peerhas,req->addr->addrind); + state = (quotes[i].txid & (~INSTANTDEX_ORDERSTATE_ORDERIDMASK)); + if ( state > ap->state ) + ap->state = state; + if ( ap->state == 0 ) + continue; + } + if ( instantdex_statemachinefind(0,exchange,quotes[i].ulongs[0]) != 0 || instantdex_historyfind(0,exchange,quotes[i].ulongs[0]) != 0 ) + continue; + quotes[m++] = quotes[i]; + } + if ( m > 0 ) + { + len = iguana_getdata(coin,serialized,MSG_QUOTE,quotes,m); + printf("send getdata for %d of %d quotes to %s\n",m,n,req->addr->ipaddr); + iguana_send(coin,req->addr,serialized,len); + } + return(req); +} + +int32_t instantdex_quoterequest(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t *serialized,int32_t maxlen,struct iguana_peer *addr,bits256 encodedhash) +{ + struct instantdex_accept *ap; int32_t olen,checklen; struct instantdex_offer checkoffer; bits256 orderhash,checkhash; + if ( (ap= instantdex_quotefind(myinfo,coin,addr,encodedhash)) != 0 ) + { + orderhash = instantdex_rwoffer(1,&olen,serialized,&ap->offer); + if ( instantdex_orderidcmp(orderhash.ulongs[0],ap->orderid,0) == 0 ) + { + checkhash = instantdex_rwoffer(0,&checklen,serialized,&checkoffer); + if ( bits256_cmp(checkhash,orderhash) != 0 ) + printf("%llx vs %llx, %d vs %d\n",(long long)checkhash.txid,(long long)orderhash.txid,checklen,olen); + return(olen); + } + else return(-1); + } + return(0); +} + +int32_t instantdex_quotep2p(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,uint8_t *serialized,int32_t recvlen) +{ + bits256 orderhash,encodedhash; int32_t state=0,added,checklen; struct instantdex_accept A,*ap; struct exchange_info *exchange; char *retstr; cJSON *argjson; uint64_t txid; + exchange = exchanges777_find("bitcoin"); + memset(&A,0,sizeof(A)); + orderhash = instantdex_rwoffer(0,&checklen,serialized,&A.offer); + A.orderid = orderhash.txid & INSTANTDEX_ORDERSTATE_ORDERIDMASK; + if ( checklen == recvlen ) + { + encodedhash = instantdex_encodehash(A.offer.base,A.offer.rel,A.offer.price64 * instantdex_bidaskdir(&A.offer),A.orderid,A.offer.account); + //printf("before quotefind.%d\n",queue_size(&exchange->acceptableQ)); + if ( (ap= instantdex_quotefind(myinfo,coin,addr,encodedhash)) == 0 ) + { + //printf("add quote here! Qsize.%d\n",queue_size(&exchange->acceptableQ)); + if ( exchange != 0 ) + { + if ( instantdex_statemachinefind(myinfo,exchange,A.orderid) == 0 && instantdex_historyfind(myinfo,exchange,A.orderid) == 0 ) + { + ap = calloc(1,sizeof(*ap)); + *ap = A; + SETBIT(ap->peerhas,addr->addrind); + argjson = cJSON_Parse("{}"); + //printf("before checkoffer Qsize.%d\n",queue_size(&exchange->acceptableQ)); + if ( (retstr= instantdex_checkoffer(myinfo,&added,&txid,exchange,ap,argjson)) != 0 ) + free(retstr); + if ( added == 0 ) + free(ap); + free_json(argjson); + } + } + } + else + { + printf("instantdex_quote: got %llx which was already there (%p %p) state(%d vs %d)\n",(long long)encodedhash.txid,ap,addr,ap->state,state); + if ( state > ap->state ) + ap->state = state; + SETBIT(ap->peerhas,addr->addrind); + } + } else printf("instantdex_quote: checklen.%d != recvlen.%d\n",checklen,recvlen); + return(checklen); +} + +void instantdex_propagate(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap) +{ + bits256 orderhash; uint8_t serialized[8192]; int32_t i,len; struct iguana_peer *addr; struct iguana_info *coin; uint32_t basilisktag = 0; + orderhash = instantdex_rwoffer(1,&len,&serialized[64+sizeof(struct iguana_msghdr)],&ap->offer); + if ( (coin= iguana_coinfind("BTCD")) != 0 && coin->peers != 0 && coin->peers->numranked > 0 ) + { + for (i=0; ipeers->numranked; i++) + if ( (addr= coin->peers->ranked[i]) != 0 && addr->supernet != 0 && addr->usock >= 0 && GETBIT(ap->peerhas,addr->addrind) == 0 && strcmp("0.0.0.0",addr->ipaddr) != 0 && strcmp("127.0.0.1",addr->ipaddr) != 0 ) + { + char str[65]; printf("send quote.(%s) <- [%d] %s %llx\n",addr->ipaddr,len,bits256_str(str,orderhash),(long long)orderhash.txid); + basilisk_sendcmd(myinfo,addr->ipaddr,"DEX",&basilisktag,0,0,&serialized[64+sizeof(struct iguana_msghdr)],len,1,BASILISK_DEFAULTDIFF); + //iguana_queue_send(addr,0,serialized,"quote",len); + } + } +} + + +// NXTrequest: +// sends NXT assetid, volume and desired +// request: +// other node sends (othercoin, othercoinaddr, otherNXT and reftx that expires well before phasedtx) +// proposal: +// NXT node submits phasedtx that refers to it, but it wont confirm +// approve: +// other node verifies unconfirmed has phasedtx and broadcasts cltv, also to NXT node, releases trigger +// confirm: +// NXT node verifies bitcoin txbytes has proper payment and cashes in with onetimepubkey +// BTC* node approves phased tx with onetimepubkey + +bits256 instantdex_acceptset(struct instantdex_accept *ap,char *base,char *rel,int32_t duration,int32_t myside,int32_t acceptdir,double price,double volume,uint64_t account,uint32_t nonce,uint8_t minperc) +{ + bits256 hash; + memset(ap,0,sizeof(*ap)); + safecopy(ap->offer.base,base,sizeof(ap->offer.base)); + safecopy(ap->offer.rel,rel,sizeof(ap->offer.rel)); + if ( nonce == 0 ) + OS_randombytes((uint8_t *)&ap->offer.nonce,sizeof(ap->offer.nonce)); + else ap->offer.nonce = nonce; + if ( duration < 1000000000 ) + ap->offer.expiration = (uint32_t)time(NULL) + duration; + else ap->offer.expiration = duration; + ap->offer.account = account; + ap->offer.myside = myside; + ap->offer.acceptdir = acceptdir; + ap->offer.minperc = minperc; + ap->offer.price64 = price * SATOSHIDEN; + ap->offer.basevolume64 = volume * SATOSHIDEN; + vcalc_sha256(0,hash.bytes,(void *)&ap->offer,sizeof(ap->offer)); + ap->orderid = hash.txid; + //int32_t i; + //for (i=0; ioffer); i++) + // printf("%02x ",((uint8_t *)&ap->offer)[i]); + //printf("\n(%s/%s) %.8f %.8f acceptdir.%d myside.%d\n",base,rel,price,volume,acceptdir,myside); + return(hash); +} + +int32_t instantdex_acceptextract(struct instantdex_accept *ap,cJSON *argjson) +{ + char *base,*rel; bits256 hash,traderpub; double price,volume; int32_t baserel,acceptdir,minperc; + memset(ap,0,sizeof(*ap)); + if ( (base= jstr(argjson,"base")) != 0 ) + { + volume = jdouble(argjson,"volume"); + if ( (minperc= juint(argjson,"minperc")) < INSTANTDEX_MINPERC ) + minperc = INSTANTDEX_MINPERC; + else if ( minperc > 100 ) + minperc = 100; + if ( (rel= jstr(argjson,"rel")) != 0 ) + safecopy(ap->offer.rel,rel,sizeof(ap->offer.rel)); + if ( (price= jdouble(argjson,"maxprice")) > SMALLVAL ) + { + baserel = 1; + acceptdir = -1; + } + else if ( (price= jdouble(argjson,"minprice")) > SMALLVAL ) + { + baserel = 0; + acceptdir = 1; + } else return(-1); + //printf("price %f vol %f baserel.%d acceptdir.%d\n",price,volume,baserel,acceptdir); + traderpub = jbits256(argjson,"traderpub"); + hash = instantdex_acceptset(ap,base,rel,INSTANTDEX_LOCKTIME*2,baserel,acceptdir,price,volume,traderpub.txid,0,minperc); + } + else + { + if ( (base= jstr(argjson,"b")) != 0 ) + safecopy(ap->offer.base,base,sizeof(ap->offer.base)); + if ( (rel= jstr(argjson,"r")) != 0 ) + safecopy(ap->offer.rel,rel,sizeof(ap->offer.rel)); + ap->offer.nonce = juint(argjson,"n"); + ap->offer.expiration = juint(argjson,"e"); + ap->offer.myside = juint(argjson,"s"); + ap->offer.acceptdir = jint(argjson,"d"); + ap->offer.account = j64bits(argjson,"o"); + ap->offer.price64 = j64bits(argjson,"p"); + ap->offer.basevolume64 = j64bits(argjson,"v"); + if ( (ap->offer.minperc= juint(argjson,"m")) < INSTANTDEX_MINPERC ) + ap->offer.minperc = INSTANTDEX_MINPERC; + vcalc_sha256(0,hash.bytes,(void *)&ap->offer,sizeof(ap->offer)); + ap->orderid = j64bits(argjson,"id"); + } + if ( instantdex_orderidcmp(hash.txid,ap->orderid,0) != 0 ) + { + int32_t i; + for (i=0; iorderid); + return(-1); + } + return(0); +} + +#include "swaps/iguana_BTCswap.c" +#include "swaps/iguana_ALTswap.c" +#include "swaps/iguana_NXTswap.c" +#include "swaps/iguana_PAXswap.c" + +struct bitcoin_swapinfo *bitcoin_swapinit(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *myap,struct instantdex_accept *otherap,int32_t aminitiator,cJSON *argjson,char *statename) +{ + struct bitcoin_swapinfo *swap = 0; int32_t i,deckflag = 1; + swap = calloc(1,sizeof(struct bitcoin_swapinfo)); + swap->coinbtc = iguana_coinfind("BTC"); + swap->altcoin = iguana_coinfind(myap->offer.base); + if ( swap->coinbtc == 0 || swap->altcoin == 0 ) + { + printf("missing BTC.%p or missing altcoin.%p\n",swap->coinbtc,swap->altcoin); + free(swap); + return(0); + } + portable_mutex_init(&swap->mutex); + swap->state = instantdex_statefind(BTC_states,BTC_numstates,statename); + swap->mine = *myap, swap->other = *otherap; + swap->expiration = (otherap->offer.expiration < myap->offer.expiration) ? otherap->offer.expiration : myap->offer.expiration; + swap->locktime = swap->expiration + INSTANTDEX_LOCKTIME; + swap->choosei = swap->otherchoosei = -1; + strcpy(swap->status,"pending"); + vcalc_sha256(0,swap->myorderhash.bytes,(void *)&swap->mine.offer,sizeof(swap->mine.offer)); + vcalc_sha256(0,swap->otherorderhash.bytes,(void *)&swap->other.offer,sizeof(swap->other.offer)); + for (i=0; i<4; i++) + swap->bothorderhash.ulongs[i] = (swap->myorderhash.ulongs[i] ^ swap->otherorderhash.ulongs[i]); + swap->mypubkey = myinfo->myaddr.persistent; + swap->othertrader = jbits256(argjson,"traderpub"); + swap->altsatoshis = myap->offer.basevolume64; + swap->BTCsatoshis = instantdex_BTCsatoshis(myap->offer.price64,myap->offer.basevolume64); + swap->btcconfirms = 0 * (1 + sqrt(dstr(swap->BTCsatoshis) * .1)); + swap->altconfirms = swap->btcconfirms * 3; + swap->insurance = (swap->BTCsatoshis / INSTANTDEX_INSURANCEDIV); + swap->altinsurance = (swap->altsatoshis / INSTANTDEX_INSURANCEDIV); + if ( myap->offer.myside != instantdex_isbob(swap) || otherap->offer.myside == instantdex_isbob(swap) ) + { + printf("isbob error.(%d %d) %d\n",myap->offer.myside,otherap->offer.myside,instantdex_isbob(swap)); + return(0); + } + if ( instantdex_pubkeyargs(myinfo,swap,2 + deckflag*INSTANTDEX_DECKSIZE,myinfo->persistent_priv,swap->myorderhash,0x02+instantdex_isbob(swap)) != 2 + deckflag*INSTANTDEX_DECKSIZE ) + printf("couldnt generate privkeys\n"); + instantdex_statemachineadd(exchange,swap); + return(swap); +} + +char *instantdex_checkoffer(struct supernet_info *myinfo,int32_t *addedp,uint64_t *txidp,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *argjson) +{ + struct instantdex_accept *otherap,*tmp; struct bitcoin_swapinfo *swap; cJSON *newjson; int32_t isbob = 0; char *retstr = 0; + *addedp = 0; + if ( exchange == 0 ) + { + printf("instantdex_checkoffer null exchange\n"); + return(0); + } + if ( instantdex_statemachinefind(myinfo,exchange,ap->orderid) != 0 || instantdex_historyfind(myinfo,exchange,ap->orderid) != 0 ) + { + printf("instantdex_checkoffer already have statemachine or history\n"); + return(0); + } + *txidp = ap->orderid; + if ( (otherap= instantdex_acceptable(myinfo,exchange,ap,ap->offer.minperc)) == 0 ) + { + if ( instantdex_offerfind(myinfo,exchange,0,0,ap->orderid,ap->offer.base,ap->offer.rel,0) == 0 ) + { + printf("instantdex_checkoffer add.%llx from.%llx to acceptableQ\n",(long long)ap->orderid,(long long)ap->offer.account); + instantdex_offeradd(exchange,ap); + *addedp = 1; + if ( instantdex_offerfind(myinfo,exchange,0,0,ap->orderid,ap->offer.base,ap->offer.rel,0) == 0 ) + printf("cant find %llu just added to acceptableQ\n",(long long)ap->orderid); + } + return(jprint(instantdex_offerjson(&ap->offer,ap->orderid),1)); + } + else + { + if ( instantdex_statemachinefind(myinfo,exchange,otherap->orderid) != 0 || instantdex_historyfind(myinfo,exchange,otherap->orderid) != 0 ) + { + printf("instantdex_checkoffer no acceptable, but already have statemachine or history\n"); + return(0); + } + if ( otherap->offer.account == myinfo->myaddr.nxt64bits ) + { + tmp = otherap; + otherap = ap; + ap = tmp; + //printf("SWAP otherap\n"); + } + else if ( ap->offer.account != myinfo->myaddr.nxt64bits ) + { + printf("checkoffer unexpected account missing\n"); + return(0); + } + isbob = ap->offer.myside; + swap = bitcoin_swapinit(myinfo,exchange,ap,otherap,1,argjson,"BTC_waitdeck"); + portable_mutex_lock(&swap->mutex); + //printf("ISBOB.%d vs %d\n",isbob,instantdex_isbob(swap)); + if ( swap != 0 ) + { + printf("STATEMACHINEQ.(%llx / %llx)\n",(long long)swap->mine.orderid,(long long)swap->other.orderid); + *addedp = 1; + if ( (newjson= instantdex_parseargjson(myinfo,exchange,swap,argjson,1)) == 0 ) + return(clonestr("{\"error\":\"instantdex_checkoffer null newjson\"}")); + if ( swap->pollevent != 0 ) + instantdex_eventfree(swap->pollevent); + swap->pollevent = instantdex_event("poll",argjson,newjson,(void *)swap->deck,sizeof(swap->deck)); + retstr = instantdex_sendcmd(myinfo,&swap->mine.offer,newjson,"BTCoffer",GENESIS_PUBKEY,INSTANTDEX_HOPS,swap->deck,sizeof(swap->deck),0,swap); + free_json(newjson); + } else printf("error creating statemachine\n"); + portable_mutex_unlock(&swap->mutex); + } + return(retstr); +} + +char *instantdex_gotoffer(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *myap,struct instantdex_accept *otherap,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,uint8_t *serdata,int32_t serdatalen) // receiving side +{ + struct bitcoin_swapinfo *swap = 0; bits256 traderpub; struct iguana_info *coinbtc,*altcoin; cJSON *newjson=0; char *retstr=0; int32_t isbob; + coinbtc = iguana_coinfind("BTC"); + traderpub = jbits256(argjson,"traderpub"); + if ( bits256_cmp(traderpub,myinfo->myaddr.persistent) == 0 ) + { + printf("got my own gotoffer packet orderid.%llx/%llx\n",(long long)myap->orderid,(long long)otherap->orderid); + return(clonestr("{\"result\":\"got my own packet\"}")); + } + if ( 0 ) + { + int32_t i; + for (i=0; ioffer); i++) + printf("%02x ",((uint8_t *)&otherap->offer)[i]); + printf("gotoffer.%llx\n",(long long)otherap->orderid); + } + printf(">>>>>>>>> GOTOFFER T.%d got (%s/%s) %.8f vol %.8f %llx offerside.%d offerdir.%d decksize.%d/datalen.%d\n",bits256_cmp(traderpub,myinfo->myaddr.persistent),myap->offer.base,myap->offer.rel,dstr(myap->offer.price64),dstr(myap->offer.basevolume64),(long long)myap->orderid,myap->offer.myside,myap->offer.acceptdir,(int32_t)sizeof(swap->deck),serdatalen); + if ( exchange == 0 ) + return(clonestr("{\"error\":\"instantdex_BTCswap null exchange ptr\"}")); + if ( (altcoin= iguana_coinfind(myap->offer.base)) == 0 || coinbtc == 0 ) + return(clonestr("{\"error\":\"instantdex_BTCswap cant find btc or other coin info\"}")); + if ( strcmp(myap->offer.rel,"BTC") != 0 ) + return(clonestr("{\"error\":\"instantdex_BTCswap offer non BTC rel\"}")); + if ( 0 ) //myap->offer.expiration < (time(NULL) + INSTANTDEX_DURATION) || otherap->offer.expiration < (time(NULL) + INSTANTDEX_DURATION) ) + { + printf("too close to expiration: %u >= %lu\n",otherap->offer.expiration,(time(NULL) + INSTANTDEX_DURATION)); + return(clonestr("{\"error\":\"instantdex_BTCswap offer too close to expiration\"}")); + } + isbob = myap->offer.myside; + swap = bitcoin_swapinit(myinfo,exchange,myap,otherap,0,argjson,"BTC_waitdeck"); + if ( swap == 0 ) + { + return(clonestr("{\"error\":\"couldnt allocate statemachine\"}")); + } + portable_mutex_lock(&swap->mutex); + //printf("ISBOB.%d vs %d\n",isbob,instantdex_isbob(swap)); + if ( (newjson= instantdex_parseargjson(myinfo,exchange,swap,argjson,1)) == 0 ) + { + printf("error parsing argjson\n"); + portable_mutex_unlock(&swap->mutex); + return(clonestr("{\"error\":\"instantdex_BTCswap offer null newjson\"}")); + } + else + { + printf("create statemachine isbob.%d\n",isbob); + if ( (retstr= instantdex_choosei(swap,newjson,argjson,serdata,serdatalen)) != 0 ) + { + free_json(newjson); + portable_mutex_unlock(&swap->mutex); + return(retstr); + } + else + { + if ( swap->pollevent != 0 ) + instantdex_eventfree(swap->pollevent); + swap->pollevent = instantdex_event("poll",argjson,newjson,(void *)swap->deck,sizeof(swap->deck)); + retstr = instantdex_sendcmd(myinfo,&swap->mine.offer,newjson,"BTCoffer",traderpub,INSTANTDEX_HOPS,swap->deck,sizeof(swap->deck),0,swap); + free_json(newjson); + } + } + portable_mutex_unlock(&swap->mutex); + return(retstr); +} + +char *instantdex_parse(struct supernet_info *myinfo,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,struct instantdex_offer *offer,bits256 orderhash,uint8_t *serdata,int32_t serdatalen) +{ + char cmdstr[16],*retstr; struct exchange_info *exchange=0; struct instantdex_accept A,*ap = 0; bits256 traderpub; cJSON *newjson; struct bitcoin_swapinfo *swap; struct bitcoin_eventitem *ptr; + exchange = exchanges777_find("bitcoin"); + memset(cmdstr,0,sizeof(cmdstr)), memcpy(cmdstr,msg->cmd,sizeof(msg->cmd)); + if ( argjson != 0 ) + { + traderpub = jbits256(argjson,"traderpub"); + memset(&A,0,sizeof(A)); + if ( instantdex_orderidcmp(j64bits(argjson,"id"),orderhash.txid,0) != 0 ) + { + printf("orderhash %llx (%s)\n",(long long)orderhash.txid,jprint(argjson,0)); + return(clonestr("{\"error\":\"orderhash mismatch\"}")); + } + A.offer = *offer; + A.orderid = orderhash.txid; + if ( strcmp("poll",cmdstr) != 0 ) + printf("got.(%s) have.%x for %llx account.%llu serdatalen.%d\n",cmdstr,juint(argjson,"have"),(long long)A.orderid,(long long)A.offer.account,serdatalen); + if ( (A.offer.minperc= jdouble(argjson,"p")) < INSTANTDEX_MINPERC ) + A.offer.minperc = INSTANTDEX_MINPERC; + else if ( A.offer.minperc > 100 ) + A.offer.minperc = 100; + if ( (swap= instantdex_statemachinefind(myinfo,exchange,A.orderid)) != 0 ) + { + if ( signerbits == swap->othertrader.txid ) + { + swap->expiration += INSTANTDEX_OFFERDURATION; + printf("OTHER SIDE sent packet\n"); + } + instantdex_privkeyextract(myinfo,swap,serdata,serdatalen); + //printf("found existing state machine %llx choosei.%d other.%d\n",(long long)A.orderid,swap->choosei,swap->otherchoosei); + newjson = instantdex_parseargjson(myinfo,exchange,swap,argjson,0); + if ( serdatalen == sizeof(swap->otherdeck) && swap->choosei < 0 && (retstr= instantdex_choosei(swap,newjson,argjson,serdata,serdatalen)) != 0 ) + { + printf("error choosei\n"); + if ( newjson != 0 ) + free_json(newjson); + return(retstr); + } + if ( (ptr= instantdex_event(cmdstr,argjson,newjson,serdata,serdatalen)) != 0 ) + queue_enqueue("eventQ",&swap->eventsQ,&ptr->DL,0); + free_json(newjson); + return(clonestr("{\"result\":\"updated statemachine\"}")); + } + else if ( strcmp(cmdstr,"BTCoffer") == 0 ) // incoming + { + //printf("BTCoffer state exchange.%p serdatalen.%d\n",exchange,serdatalen); + if ( (ap= instantdex_acceptable(myinfo,exchange,&A,A.offer.minperc)) != 0 ) + { + if ( instantdex_statemachinefind(myinfo,exchange,ap->orderid) == 0 && instantdex_historyfind(myinfo,exchange,ap->orderid) == 0 && instantdex_statemachinefind(myinfo,exchange,A.orderid) == 0 && instantdex_historyfind(myinfo,exchange,A.orderid) == 0 ) + { + retstr = instantdex_gotoffer(myinfo,exchange,ap,&A,msg,argjson,remoteaddr,signerbits,serdata,serdatalen); + if ( retstr != 0 ) // adds to statemachine if no error + { + printf("from GOTOFFER.(%s)\n",retstr); + return(retstr); + } else return(clonestr("{\"error\":\"gotoffer error\"}")); + } else return(clonestr("{\"error\":\"reject preexisting orderid\"}")); + } + else + { + printf("no matching trade for %s %llx -> InstantDEX_minaccept isbob.%d\n",cmdstr,(long long)A.orderid,A.offer.myside); + if ( instantdex_offerfind(myinfo,exchange,0,0,A.orderid,"*","*",0) == 0 ) + { + ap = calloc(1,sizeof(*ap)); + *ap = A; + printf("acceptableQ <- %llx\n",(long long)ap->orderid); + instantdex_offeradd(exchange,ap); + return(clonestr("{\"result\":\"added new order to orderbook\"}")); + } else return(clonestr("{\"result\":\"order was already in orderbook\"}")); + } + } + else + { + //printf("cant find existing order.%llx that matches\n",(long long)A.orderid); + return(clonestr("{\"error\":\"cant find matching order\"}")); + } + } + return(clonestr("{\"error\":\"request needs argjson\"}")); +} + +char *InstantDEX_hexmsg(struct supernet_info *myinfo,struct gecko_chain *cat,void *ptr,int32_t len,char *remoteaddr) +{ + struct instantdex_msghdr *msg = ptr; int32_t olen,slen,datalen,newlen,flag = 0; + uint8_t *serdata; struct instantdex_offer rawoffer; // struct supernet_info *myinfos[64]; + uint64_t signerbits; uint8_t tmp[sizeof(msg->sig)]; char *retstr = 0; + bits256 orderhash,traderpub; cJSON *retjson,*item,*argjson = 0; + datalen = len - (int32_t)sizeof(msg->sig); + serdata = (void *)((long)msg + sizeof(msg->sig)); + //printf("a signed datalen.%d allocsize.%d crc.%x\n",datalen,msg->sig.allocsize,calc_crc32(0,serdata,datalen)); + acct777_rwsig(0,(void *)&msg->sig,(void *)tmp); + memcpy(&msg->sig,tmp,sizeof(msg->sig)); + // printf("b signed datalen.%d allocsize.%d crc.%x\n",datalen,msg->sig.allocsize,calc_crc32(0,serdata,datalen)); + if ( (remoteaddr == 0 || remoteaddr[0] == 0 || strcmp("127.0.0.1",remoteaddr) == 0) && ((uint8_t *)msg)[len-1] == 0 && (argjson= cJSON_Parse((char *)msg)) != 0 ) + { + printf("string instantdex_hexmsg RESULT.(%s)\n",jprint(argjson,0)); + free_json(argjson); + return(clonestr("{\"error\":\"string base packets deprecated\"}")); + } + else if ( (signerbits= acct777_validate(&msg->sig,acct777_msgprivkey(serdata,datalen),msg->sig.pubkey)) != 0 ) + { + flag++; + if ( signerbits == myinfo->myaddr.nxt64bits ) + { + printf("filter out self-messages\n"); + return(0); + } + //printf("InstantDEX_hexmsg <<<<<<<<<<<<< sigsize.%d VALIDATED [%ld] len.%d t%u allocsize.%d (%s) [%d]\n",(int32_t)sizeof(msg->sig),(long)serdata-(long)msg,datalen,msg->sig.timestamp,msg->sig.allocsize,(char *)msg->serialized,serdata[datalen-1]); + newlen = (int32_t)(msg->sig.allocsize - ((long)msg->serialized - (long)msg)); + serdata = msg->serialized; + //printf("newlen.%d diff.%ld alloc.%d datalen.%d\n",newlen,((long)msg->serialized - (long)msg),msg->sig.allocsize,datalen); + if ( (argjson= cJSON_Parse((char *)serdata)) != 0 ) + { + slen = (int32_t)strlen((char *)serdata) + 1; + serdata = &serdata[slen]; + newlen -= slen; + } + if ( newlen > 0 ) + { + orderhash = instantdex_rwoffer(0,&olen,serdata,&rawoffer); + newlen -= olen; + //newlen -= ((long)msg->serialized - (long)msg); + serdata = &serdata[olen]; + //printf("received orderhash.%llx olen.%d slen.%d newlen.%d\n",(long long)orderhash.txid,olen,slen,newlen); + } else olen = 0; + if ( newlen <= 0 ) + serdata = 0, newlen = 0; + if ( serdata != 0 || argjson != 0 ) + { + //printf("CALL instantdex_parse.(%s)\n",argjson!=0?jprint(argjson,0):""); + retjson = cJSON_CreateArray(); + /*if ( (num= SuperNET_MYINFOS(myinfos,sizeof(myinfos)/sizeof(*myinfos))) == 0 ) + { + myinfos[0] = myinfo; + num = 1; + } + for (i=0; imyaddr.persistent)); + traderpub = jbits256(argjson,"traderpub"); + if ( bits256_cmp(traderpub,myinfo->myaddr.persistent) != 0 ) + { + if ( (retstr= instantdex_parse(myinfo,msg,argjson,remoteaddr,signerbits,&rawoffer,orderhash,serdata,newlen)) != 0 ) + { + item = cJSON_CreateObject(); + jaddstr(item,"result",retstr); + if ( myinfo->handle[0] != 0 ) + jaddstr(item,"handle",myinfo->handle); + jaddbits256(item,"traderpub",myinfo->myaddr.persistent); + jaddi(retjson,item); + } + } + } + retstr = jprint(retjson,1); + } + } else printf("sig err datalen.%d\n",datalen); + if ( argjson != 0 ) + free_json(argjson); + return(retstr); +} + +char *instantdex_createaccept(struct supernet_info *myinfo,struct instantdex_accept **aptrp,struct exchange_info *exchange,char *base,char *rel,double price,double basevolume,int32_t acceptdir,char *mysidestr,int32_t duration,uint64_t account,uint8_t minperc) +{ + struct instantdex_accept *ap; int32_t myside; char *retstr; + *aptrp = 0; + if ( exchange != 0 ) + { + *aptrp = ap = calloc(1,sizeof(*ap)); + if ( strcmp(mysidestr,base) == 0 ) + myside = 0; + else if ( strcmp(mysidestr,rel) == 0 ) + myside = 1; + else + { + myside = -1; + printf("myside.(%s) != base.%s or rel.%s\n",mysidestr,base,rel); + } + instantdex_acceptset(ap,base,rel,duration,myside,acceptdir,price,basevolume,account,0,minperc); + if ( instantdex_offerfind(myinfo,exchange,0,0,ap->orderid,ap->offer.base,ap->offer.rel,0) == 0 ) + { + instantdex_propagate(myinfo,exchange,ap); + retstr = jprint(instantdex_acceptjson(ap),1); + return(retstr); + } else return(0); + } else return(clonestr("{\"error\":\"invalid exchange\"}")); +} + +void instantdex_update(struct supernet_info *myinfo) +{ + /*struct instantdex_msghdr *pm; struct category_msg *m; char *str,remote[64]; queue_t *Q; struct queueitem *item; struct gecko_chain *cat; + //char str2[65]; printf("myinfo->instantdex_category.(%s)\n",bits256_str(str2,myinfo->instantdex_category)); + if ( (Q= category_Q(&cat,myinfo->instantdex_category,myinfo->myaddr.persistent)) != 0 && queue_size(Q) > 0 && (item= Q->list) != 0 ) + { + m = queue_dequeue(Q,0); + pm = (struct instantdex_msghdr *)m->msg; + if ( m->remoteipbits != 0 ) + expand_ipbits(remote,m->remoteipbits); + else remote[0] = 0; + { + char hexstr[3000]; + init_hexbytes_noT(hexstr,(uint8_t *)pm,m->len); + printf("instantdex_update.(%s) len.%d remote.(%s) %p\n",hexstr,m->len,remote,remote); + } + if ( (str= InstantDEX_hexmsg(myinfo,cat,pm,m->len,remote)) != 0 ) + free(str); + free(m); + }*/ +} + +/* +#include "../includes/iguana_apidefs.h" + +TWO_STRINGS_AND_TWO_DOUBLES(InstantDEX,maxaccept,base,rel,maxprice,basevolume) +{ + struct instantdex_accept *ap; int32_t added; char *retstr; struct exchange_info *exchange; uint64_t txid; + myinfo = SuperNET_accountfind(json); + if ( remoteaddr == 0 && (exchange= exchanges777_find("bitcoin")) != 0 ) + { + if ( (retstr= instantdex_createaccept(myinfo,&ap,exchange,base,rel,maxprice,basevolume,-1,rel,INSTANTDEX_OFFERDURATION,myinfo->myaddr.nxt64bits,juint(json,"minperc"))) != 0 ) + free(retstr); + retstr = instantdex_checkoffer(myinfo,&added,&txid,exchange,ap,json); + if ( added == 0 ) + free(ap); + return(retstr); + + } else return(clonestr("{\"error\":\"InstantDEX API request only local usage!\"}")); +} + +TWO_STRINGS_AND_TWO_DOUBLES(InstantDEX,minaccept,base,rel,minprice,basevolume) +{ + struct instantdex_accept *ap; int32_t added; char *retstr; struct exchange_info *exchange; uint64_t txid; + myinfo = SuperNET_accountfind(json); + if ( remoteaddr == 0 && (exchange= exchanges777_find("bitcoin")) != 0 ) + { + if ( (retstr= instantdex_createaccept(myinfo,&ap,exchanges777_find("bitcoin"),base,rel,minprice,basevolume,1,base,INSTANTDEX_OFFERDURATION,myinfo->myaddr.nxt64bits,juint(json,"minperc"))) != 0 ) + free(retstr); + retstr = instantdex_checkoffer(myinfo,&added,&txid,exchange,ap,json); + if ( added == 0 ) + free(ap); + return(retstr); + } else return(clonestr("{\"error\":\"InstantDEX API request only local usage!\"}")); +} + +char *instantdex_statemachineget(struct supernet_info *myinfo,struct bitcoin_swapinfo **swapp,cJSON *argjson,char *remoteaddr) +{ + struct bitcoin_swapinfo *swap; uint64_t orderid,otherorderid; struct exchange_info *exchange; + *swapp = 0; + if ( remoteaddr == 0 && (exchange= exchanges777_find("bitcoin")) != 0 ) + { + orderid = j64bits(argjson,"myorderid"); + otherorderid = j64bits(argjson,"otherid"); + if ( (swap= instantdex_statemachinefind(myinfo,exchange,orderid)) != 0 ) + { + if ( instantdex_orderidcmp(swap->other.orderid,otherorderid,0) != 0 ) + return(clonestr("{\"error\":\"statemachine otherid mismatch\"}")); + else + { + *swapp = swap; + return(0); + } + } else return(clonestr("{\"error\":\"statemachine not found\"}")); + } else return(clonestr("{\"error\":\"atomic API request only local usage!\"}")); +} + +THREE_STRINGS(atomic,approve,myorderid,otherid,txname) +{ + char *retstr,virtualevent[16]; cJSON *newjson; struct bitcoin_statetx *tx; struct bitcoin_swapinfo *swap = 0; + if ( (retstr= instantdex_statemachineget(myinfo,&swap,json,remoteaddr)) != 0 ) + return(retstr); + else if ( (tx= instantdex_getstatetx(swap,txname)) == 0 ) + return(clonestr("{\"error\":\"cant find txname\"}")); + else + { + strcpy(virtualevent,txname); + strcat(virtualevent,"found"); + newjson = cJSON_CreateObject(); + if ( (retstr= instantdex_sendcmd(myinfo,&swap->mine.offer,newjson,virtualevent,myinfo->myaddr.persistent,0,0,0,0,swap)) != 0 ) + return(retstr); + else + { + free_json(newjson); + return(clonestr("{\"result\":\"statemachine sent found event\"}")); + } + } +} + +THREE_STRINGS(atomic,claim,myorderid,otherid,txname) +{ + char *retstr; struct bitcoin_statetx *tx; struct bitcoin_swapinfo *swap = 0; + if ( (retstr= instantdex_statemachineget(myinfo,&swap,json,remoteaddr)) != 0 ) + return(retstr); + else if ( (tx= instantdex_getstatetx(swap,txname)) == 0 ) + return(clonestr("{\"error\":\"cant find txname\"}")); + else + { + return(clonestr("{\"result\":\"statemachine should claim tx\"}")); + } +} + +cJSON *instantdex_reportjson(cJSON *item,char *name) +{ + cJSON *newjson = cJSON_CreateObject(); uint64_t dateval; + dateval = juint(item,"timestamp"), dateval *= 1000; + newjson = cJSON_CreateObject(); + jadd(newjson,name,jduplicate(jobj(item,"price"))); + jadd(newjson,"volume",jduplicate(jobj(item,"volume"))); + jadd(newjson,"orderid",jduplicate(jobj(item,"orderid"))); + jadd(newjson,"account",jduplicate(jobj(item,"account"))); + jaddnum(newjson,"date",dateval); + jaddnum(newjson,"s",dateval % 60); + jaddnum(newjson,"m",(dateval / 60) % 60); + jaddnum(newjson,"h",(dateval / 3600) % 24); + return(newjson); +} + +TWO_STRINGS(InstantDEX,events,base,rel) +{ + cJSON *bids,*asks,*array,*item; int32_t i,n; struct exchange_info *exchange; + array = cJSON_CreateArray(); + if ( (exchange= exchanges777_find("bitcoin")) != 0 ) + { + bids = cJSON_CreateArray(); + asks = cJSON_CreateArray(); + instantdex_offerfind(myinfo,exchange,bids,asks,0,base,rel,1); + if ( (n= cJSON_GetArraySize(bids)) > 0 ) + { + for (i=0; i 0 ) + { + for (i=0; i +#include +#include +#include +#include "../includes/curve25519.h" +#include "secp256k1/include/secp256k1.h" +#include "secp256k1/include/secp256k1_ecdh.h" +#include "secp256k1/include/secp256k1_schnorr.h" +#include "secp256k1/include/secp256k1_rangeproof.h" +#include "secp256k1/include/secp256k1_recovery.h" + +SECP256K1_API extern const secp256k1_nonce_function secp256k1_nonce_function_rfc6979; + +#define bits256_nonz(a) (((a).ulongs[0] | (a).ulongs[1] | (a).ulongs[2] | (a).ulongs[3]) != 0) + +#define SECP_ENSURE_CTX int32_t flag = 0; if ( ctx == 0 ) { ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); secp256k1_pedersen_context_initialize(ctx); secp256k1_rangeproof_context_initialize(ctx); flag++; } else flag = 0; if ( ctx != 0 ) +#define ENDSECP_ENSURE_CTX if ( flag != 0 ) secp256k1_context_destroy(ctx); + +bits256 bitcoin_randkey(secp256k1_context *ctx) +{ + int32_t i; bits256 privkey; + SECP_ENSURE_CTX + { + for (i=0; i<100; i++) + { + privkey = rand256(0); + if ( secp256k1_ec_seckey_verify(ctx,privkey.bytes) > 0 ) + { + ENDSECP_ENSURE_CTX + return(privkey); + } + } + ENDSECP_ENSURE_CTX + } + fprintf(stderr,"couldnt generate valid bitcoin privkey. something is REALLY wrong. exiting\n"); + exit(-1); +} + +bits256 bitcoin_pubkey33(secp256k1_context *ctx,uint8_t *data,bits256 privkey) +{ + size_t plen; bits256 pubkey; secp256k1_pubkey secppub; + memset(pubkey.bytes,0,sizeof(pubkey)); + SECP_ENSURE_CTX + { + if ( secp256k1_ec_seckey_verify(ctx,privkey.bytes) == 0 ) + { + printf("bitcoin_sign illegal privkey\n"); + return(pubkey); + } + if ( secp256k1_ec_pubkey_create(ctx,&secppub,privkey.bytes) > 0 ) + { + plen = 33; + secp256k1_ec_pubkey_serialize(ctx,data,&plen,&secppub,SECP256K1_EC_COMPRESSED); + if ( plen == 33 ) + memcpy(pubkey.bytes,data+1,sizeof(pubkey)); + } + ENDSECP_ENSURE_CTX + } + return(pubkey); +} + +int32_t bitcoin_sign(void *ctx,char *symbol,uint8_t *sig,bits256 txhash2,bits256 privkey,int32_t recoverflag) +{ + int32_t fCompressed = 1; + secp256k1_ecdsa_signature SIG; secp256k1_ecdsa_recoverable_signature rSIG; bits256 extra_entropy,seed; int32_t recid,retval = -1; size_t siglen = 72; secp256k1_pubkey SECPUB,CHECKPUB; + seed = rand256(0); + extra_entropy = rand256(0); + SECP_ENSURE_CTX + { + if ( secp256k1_ec_seckey_verify(ctx,privkey.bytes) == 0 ) + { + printf("bitcoin_sign illegal privkey\n"); + return(-1); + } + if ( secp256k1_context_randomize(ctx,seed.bytes) > 0 ) + { + if ( recoverflag != 0 ) + { + if ( secp256k1_ecdsa_sign_recoverable(ctx,&rSIG,txhash2.bytes,privkey.bytes,secp256k1_nonce_function_rfc6979,extra_entropy.bytes) > 0 ) + { + recid = -1; + secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx,sig+1,&recid,&rSIG); + if ( secp256k1_ecdsa_recover(ctx,&SECPUB,&rSIG,txhash2.bytes) > 0 ) + { + if ( secp256k1_ec_pubkey_create(ctx,&CHECKPUB,privkey.bytes) > 0 ) + { + if ( memcmp(&SECPUB,&CHECKPUB,sizeof(SECPUB)) == 0 ) + { + sig[0] = 27 + recid + (fCompressed != 0 ? 4 : 0); + retval = 64 + 1; + } + else printf("secpub mismatch\n"); + } else printf("pubkey create error\n"); + } else printf("recover error\n"); + } else printf("secp256k1_ecdsa_sign_recoverable error\n"); + } + else + { + if ( secp256k1_ecdsa_sign(ctx,&SIG,txhash2.bytes,privkey.bytes,secp256k1_nonce_function_rfc6979,extra_entropy.bytes) > 0 ) + { + if ( secp256k1_ecdsa_signature_serialize_der(ctx,sig,&siglen,&SIG) > 0 ) + retval = (int32_t)siglen; + } + } + } + ENDSECP_ENSURE_CTX + } + return(retval); +} + +int32_t bitcoin_recoververify(void *ctx,char *symbol,uint8_t *sig65,bits256 messagehash2,uint8_t *pubkey) +{ + int32_t retval = -1; size_t plen; secp256k1_pubkey PUB; secp256k1_ecdsa_signature SIG; secp256k1_ecdsa_recoverable_signature rSIG; + pubkey[0] = 0; + SECP_ENSURE_CTX + { + plen = (sig65[0] <= 31) ? 65 : 33; + secp256k1_ecdsa_recoverable_signature_parse_compact(ctx,&rSIG,sig65 + 1,0); + secp256k1_ecdsa_recoverable_signature_convert(ctx,&SIG,&rSIG); + if ( secp256k1_ecdsa_recover(ctx,&PUB,&rSIG,messagehash2.bytes) > 0 ) + { + secp256k1_ec_pubkey_serialize(ctx,pubkey,&plen,&PUB,plen == 65 ? SECP256K1_EC_UNCOMPRESSED : SECP256K1_EC_COMPRESSED); + if ( secp256k1_ecdsa_verify(ctx,&SIG,messagehash2.bytes,&PUB) > 0 ) + retval = 0; + else printf("secp256k1_ecdsa_verify error\n"); + } else printf("secp256k1_ecdsa_recover error\n"); + ENDSECP_ENSURE_CTX + } + return(retval); +} + +int32_t bitcoin_verify(void *ctx,uint8_t *sig,int32_t siglen,bits256 txhash2,uint8_t *pubkey,int32_t plen) +{ + int32_t retval = -1; secp256k1_pubkey PUB; secp256k1_ecdsa_signature SIG; + SECP_ENSURE_CTX + { + if ( secp256k1_ec_pubkey_parse(ctx,&PUB,pubkey,plen) > 0 ) + { + secp256k1_ecdsa_signature_parse_der(ctx,&SIG,sig,siglen); + if ( secp256k1_ecdsa_verify(ctx,&SIG,txhash2.bytes,&PUB) > 0 ) + retval = 0; + } + ENDSECP_ENSURE_CTX + } + return(retval); +} + +bits256 bitcoin_sharedsecret(void *ctx,bits256 privkey,uint8_t *pubkey,int32_t plen) +{ + int32_t retval = -1; bits256 shared; secp256k1_pubkey PUB; + memset(shared.bytes,0,sizeof(shared)); + SECP_ENSURE_CTX + { + if ( secp256k1_ec_pubkey_parse(ctx,&PUB,pubkey,plen) > 0 ) + { + if ( secp256k1_ecdh(ctx,shared.bytes,&PUB,privkey.bytes) > 0 ) + retval = 0; + else memset(shared.bytes,0,sizeof(shared)); + } + ENDSECP_ENSURE_CTX + } + return(shared); +} + +int32_t bitcoin_schnorr_sign(void *ctx,uint8_t *sig64,bits256 txhash2,bits256 privkey) +{ + int32_t retval = -1; bits256 seed; + SECP_ENSURE_CTX + { + seed = rand256(0); + if ( secp256k1_schnorr_sign(ctx,sig64,txhash2.bytes,privkey.bytes,secp256k1_nonce_function_rfc6979,seed.bytes) > 0 ) + retval = 0; + ENDSECP_ENSURE_CTX + } + return(retval); +} + +int32_t bitcoin_schnorr_verify(void *ctx,uint8_t *sig64,bits256 txhash2,uint8_t *pubkey,int32_t plen) +{ + int32_t retval = -1; secp256k1_pubkey PUB; + SECP_ENSURE_CTX + { + if ( secp256k1_ec_pubkey_parse(ctx,&PUB,pubkey,plen) > 0 ) + { + if ( secp256k1_schnorr_verify(ctx,sig64,txhash2.bytes,&PUB) > 0 ) + retval = 0; + } + ENDSECP_ENSURE_CTX + } + return(retval); +} + +int32_t bitcoin_schnorr_recover(void *ctx,uint8_t *pubkey,uint8_t *sig64,bits256 txhash2) +{ + int32_t retval = -1; secp256k1_pubkey PUB; size_t plen; + SECP_ENSURE_CTX + { + if ( secp256k1_schnorr_recover(ctx,&PUB,sig64,txhash2.bytes) > 0 ) + { + plen = 33; + secp256k1_ec_pubkey_serialize(ctx,pubkey,&plen,&PUB,SECP256K1_EC_COMPRESSED); + retval = 0; + } + ENDSECP_ENSURE_CTX + } + return(retval); +} + +bits256 bitcoin_schnorr_noncepair(void *ctx,uint8_t *pubnonce,bits256 txhash2,bits256 privkey) //exchange +{ + int32_t retval = -1; size_t plen; secp256k1_pubkey PUB; bits256 privnonce,seed; + memset(privnonce.bytes,0,sizeof(privnonce)); + pubnonce[0] = 0; + SECP_ENSURE_CTX + { + seed = rand256(0); + if ( secp256k1_schnorr_generate_nonce_pair(ctx,&PUB,privnonce.bytes,txhash2.bytes,privkey.bytes,secp256k1_nonce_function_rfc6979,seed.bytes) > 0 ) + { + plen = 33; + secp256k1_ec_pubkey_serialize(ctx,pubnonce,&plen,&PUB,SECP256K1_EC_COMPRESSED); + retval = 0; + } + ENDSECP_ENSURE_CTX + } + return(privnonce); +} + +int32_t bitcoin_schnorr_partialsign(void *ctx,uint8_t *sig64,uint8_t *combined_pub,bits256 txhash2,bits256 privkey,bits256 privnonce,uint8_t *pubptrs[],int32_t n) // generate and exchange +{ + int32_t bitcoin_pubkeylen(const uint8_t *pubkey); + int32_t i,retval = -1; secp256k1_pubkey PUBall,**PUBptrs; size_t plen; + SECP_ENSURE_CTX + { + PUBptrs = calloc(n,sizeof(*PUBptrs)); + for (i=0; i 0 && secp256k1_ec_pubkey_combine(ctx,&PUBall,(void *)PUBptrs,n) > 0 ) + { + plen = 33; + if ( secp256k1_schnorr_partial_sign(ctx,sig64,txhash2.bytes,privkey.bytes,&PUBall,privnonce.bytes) > 0 ) + { + secp256k1_ec_pubkey_serialize(ctx,combined_pub,&plen,&PUBall,SECP256K1_EC_COMPRESSED); + retval = 0; + } + } + free(PUBptrs); + ENDSECP_ENSURE_CTX + } + return(retval); +} + +int32_t bitcoin_schnorr_combine(void *ctx,uint8_t *sig64,uint8_t *allpub,uint8_t **sigs,int32_t n,bits256 txhash2) +{ + int32_t rc,retval = -1; + SECP_ENSURE_CTX + { + if ( (rc= secp256k1_schnorr_partial_combine(ctx,sig64,(void *)sigs,n)) > 0 ) + { + if ( bitcoin_schnorr_recover(ctx,allpub,sig64,txhash2) == 0 ) + { + if ( bitcoin_schnorr_verify(ctx,sig64,txhash2,allpub,33) == 0 ) + retval = 0; + } + } + ENDSECP_ENSURE_CTX + } + return(retval); +} + +int32_t bitcoin_pederson_commit(void *ctx,uint8_t *commit,bits256 blind,uint64_t value) +{ + int32_t retval = -1; + SECP_ENSURE_CTX + { + if ( secp256k1_pedersen_commit(ctx,commit,blind.bytes,value) > 0 ) + retval = 0; + ENDSECP_ENSURE_CTX + } + return(retval); +} + +bits256 bitcoin_pederson_blindsum(void *ctx,bits256 **blindptrs,int32_t n,int32_t numpos) +{ + bits256 blind_out; + memset(blind_out.bytes,0,sizeof(blind_out)); + SECP_ENSURE_CTX + { + if ( secp256k1_pedersen_blind_sum(ctx,blind_out.bytes,(void *)blindptrs,n,numpos) == 0 ) + memset(blind_out.bytes,0,sizeof(blind_out)); + ENDSECP_ENSURE_CTX + } + return(blind_out); +} + +int32_t bitcoin_pederson_tally(void *ctx,uint8_t **commits,int32_t n,int32_t numpos,int64_t excess) +{ + int32_t retval = -1; + SECP_ENSURE_CTX + { + if ( secp256k1_pedersen_verify_tally(ctx,(void *)commits,numpos,(void *)&commits[numpos],n - numpos,excess) > 0 ) + retval = 0; + ENDSECP_ENSURE_CTX + } + return(retval); +} + +int32_t bitcoin_rangeproof_message(void *ctx,uint8_t *blind_out,uint8_t *message,uint64_t *valuep,bits256 nonce,uint64_t *min_valuep,uint64_t *max_valuep,uint8_t *commit,uint8_t *proof,int32_t prooflen) +{ + int32_t outlen = 0,retval = -1; + SECP_ENSURE_CTX + { + if ( secp256k1_rangeproof_rewind(ctx,blind_out,valuep,message,&outlen,nonce.bytes,min_valuep,max_valuep,commit,proof,prooflen) > 0 ) + retval = outlen; + ENDSECP_ENSURE_CTX + } + return(retval); +} + +uint64_t bitcoin_rangeverify(void *ctx,int32_t *exponentp,int32_t *mantissap,uint64_t *min_valuep,uint8_t *commit,uint8_t *proof,int32_t prooflen) +{ + uint64_t max_value,retval = 0; + max_value = *min_valuep = *exponentp = *mantissap = 0; + if ( secp256k1_rangeproof_info(ctx,exponentp,mantissap,min_valuep,&max_value,proof,prooflen) > 0 ) + { + if ( commit != 0 ) + { + if ( secp256k1_rangeproof_verify(ctx,min_valuep,&max_value,commit,proof,prooflen) > 0 ) + retval = max_value; + } else retval = max_value; + } + return(retval); +} + +int32_t bitcoin_rangeproof(void *ctx,uint8_t *proof,uint8_t *commit,bits256 blind,bits256 nonce,uint64_t value,uint64_t min_value,int32_t exponent,int32_t min_bits) +{ + int32_t prooflen=0 ,retval = -1; + SECP_ENSURE_CTX + { + if ( secp256k1_rangeproof_sign(ctx,proof,&prooflen,min_value,commit,blind.bytes,nonce.bytes,exponent,min_bits,value) > 0 ) + retval = prooflen; + ENDSECP_ENSURE_CTX + } + return(retval); +} + + /* + * The intended procedure for creating a multiparty signature is: + * - Each signer S[i] with private key x[i] and public key Q[i] runs + * secp256k1_schnorr_generate_nonce_pair to produce a pair (k[i],R[i]) of private/public nonces. + * - All signers communicate their public nonces to each other (revealing your + * private nonce can lead to discovery of your private key, so it should be considered secret). + * - All signers combine all the public nonces they received (excluding their + * own) using secp256k1_ec_pubkey_combine to obtain an Rall[i] = sum(R[0..i-1,i+1..n]). + * - All signers produce a partial signature using + * secp256k1_schnorr_partial_sign, passing in their own private key x[i], + * their own private nonce k[i], and the sum of the others' public nonces Rall[i]. + * - All signers communicate their partial signatures to each other. + * - Someone combines all partial signatures using secp256k1_schnorr_partial_combine, to obtain a full signature. + * - The resulting signature is validatable using secp256k1_schnorr_verify, with + * public key equal to the result of secp256k1_ec_pubkey_combine of the signers' public keys (sum(Q[0..n])). + * + * Note that secp256k1_schnorr_partial_combine and secp256k1_ec_pubkey_combine + * function take their arguments in any order, and it is possible to + * pre-combine several inputs already with one call, and add more inputs later + * by calling the function again (they are commutative and associative). + */ + +#ifdef test_schnorr +#include "secp256k1/src/util.h" +#include "secp256k1/src/hash_impl.h" +#include "secp256k1/src/testrand_impl.h" + +void test_schnorr_threshold(void *ctx) { + unsigned char msg[32]; + unsigned char sec[5][32]; + secp256k1_pubkey pub[5]; + unsigned char nonce[5][32]; + secp256k1_pubkey pubnonce[5]; + unsigned char sig[5][64]; + const unsigned char* sigs[5]; + unsigned char allsig[64]; + const secp256k1_pubkey* pubs[5]; + secp256k1_pubkey allpub; + int n, i; + int damage; + int ret = 0; + + damage = secp256k1_rand_bits(1) ? (1 + secp256k1_rand_int(4)) : 0; + secp256k1_rand256_test(msg); + n = 2 + secp256k1_rand_int(4); + for (i = 0; i < n; i++) { + do { + secp256k1_rand256_test(sec[i]); + } while (!secp256k1_ec_seckey_verify(ctx, sec[i])); + CHECK(secp256k1_ec_pubkey_create(ctx, &pub[i], sec[i])); + CHECK(secp256k1_schnorr_generate_nonce_pair(ctx, &pubnonce[i], nonce[i], msg, sec[i], NULL, NULL)); + pubs[i] = &pub[i]; + } + if (damage == 1) { + nonce[secp256k1_rand_int(n)][secp256k1_rand_int(32)] ^= 1 + secp256k1_rand_int(255); + } else if (damage == 2) { + sec[secp256k1_rand_int(n)][secp256k1_rand_int(32)] ^= 1 + secp256k1_rand_int(255); + } + for (i = 0; i < n; i++) { + secp256k1_pubkey allpubnonce; + const secp256k1_pubkey *pubnonces[4]; + int j; + for (j = 0; j < i; j++) { + pubnonces[j] = &pubnonce[j]; + } + for (j = i + 1; j < n; j++) { + pubnonces[j - 1] = &pubnonce[j]; + } + CHECK(secp256k1_ec_pubkey_combine(ctx, &allpubnonce, pubnonces, n - 1)); + ret |= (secp256k1_schnorr_partial_sign(ctx, sig[i], msg, sec[i], &allpubnonce, nonce[i]) != 1) * 1; + sigs[i] = sig[i]; + } + if (damage == 3) { + sig[secp256k1_rand_int(n)][secp256k1_rand_bits(6)] ^= 1 + secp256k1_rand_int(255); + } + ret |= (secp256k1_ec_pubkey_combine(ctx, &allpub, pubs, n) != 1) * 2; + if ((ret & 1) == 0) { + ret |= (secp256k1_schnorr_partial_combine(ctx, allsig, sigs, n) != 1) * 4; + } + if (damage == 4) { + allsig[secp256k1_rand_int(32)] ^= 1 + secp256k1_rand_int(255); + } + if ((ret & 7) == 0) { + ret |= (secp256k1_schnorr_verify(ctx, allsig, msg, &allpub) != 1) * 8; + } + CHECK((ret == 0) == (damage == 0)); +} +#endif + +int32_t iguana_pederson_test(void *ctx) +{ + uint8_t commits[100][33],*commitptrs[100],proofs[100][5138]; uint16_t vouts[100]; int64_t min_value,values[100],totalpos,totalneg; bits256 txids[100],nonces[100],blinds[100],*blindptrs[100],blindsum; int32_t prooflens[100],i,r,pos,neg,numpos,exponent,min_bits,n,N = 100; + srand(100); + for (i=numpos=n=0; i 0 ) + { + commitptrs[pos] = commits[i]; + blindptrs[pos] = &blinds[i]; + totalpos += values[i]; + pos++; + } + } + if ( pos != numpos ) + { + printf("pos.%d != numpos.%d\n",pos,numpos); + return(-1); + } + for (totalneg=i=neg=0; i 1 ) + { + if ( bitcoin_schnorr_partialsign(ctx,sig64[i],combined_pub[i],txhash2,privkeys[i],privnonces[i],pubptrs,N-1) < 0 ) + errs++; + } + else + { + if ( bitcoin_schnorr_sign(ctx,sig64[0],txhash2,privkeys[0]) < 0 ) + errs++; + } + } + if ( errs != 0 ) + printf("partialsign errs.%d\n",errs); + for (i=0; i 0 ) + { + EC_KEY_set_private_key(KEY,bn); + EC_KEY_set_public_key(KEY,pub_key); + ptr = tmp; + i2o_ECPublicKey(KEY,&ptr); + *oddevenp = tmp[0]; + memcpy(pubkeyp->bytes,&tmp[1],sizeof(*pubkeyp)); + } + BN_clear_free(bn); + } + EC_POINT_free(pub_key); + } + BN_CTX_free(ctx); + } + } + return(KEY); +} + +int32_t oldbitcoin_verify(uint8_t *sig,int32_t siglen,uint8_t *data,int32_t datalen,uint8_t *pubkey,int32_t len) +{ + ECDSA_SIG *esig; int32_t retval = -1; uint8_t tmp[33],*ptr,*sigptr = sig; EC_KEY *KEY = 0; + if ( len < 0 ) + return(-1); + if ( (esig= ECDSA_SIG_new()) != 0 ) + { + if ( d2i_ECDSA_SIG(&esig,(const uint8_t **)&sigptr,siglen) != 0 ) + { + if ( (KEY= EC_KEY_new_by_curve_name(NID_secp256k1)) != 0 ) + { + EC_KEY_set_conv_form(KEY,POINT_CONVERSION_COMPRESSED); + if ( len == 32 ) + { + memcpy(tmp+1,pubkey,len); + for (tmp[0]=2; tmp[0]<=3; tmp[0]++) + { + ptr = tmp; + o2i_ECPublicKey(&KEY,(const uint8_t **)&ptr,33); + if ( ECDSA_do_verify(data,datalen,esig,KEY) > 0 ) + { + retval = 0; + break; + } + } + } + else + { + ptr = pubkey; + o2i_ECPublicKey(&KEY,(const uint8_t **)&ptr,len); + if ( ECDSA_do_verify(data,datalen,esig,KEY) > 0 ) + retval = 0; + } + EC_KEY_free(KEY); + } + } + ECDSA_SIG_free(esig); + } + return(retval); +} + +int32_t oldbitcoin_sign(uint8_t *sig,int32_t maxlen,uint8_t *data,int32_t datalen,bits256 privkey) +{ + EC_KEY *KEY; uint8_t oddeven; bits256 pubkey; uint8_t *ptr; int32_t siglen,retval = -1; + ECDSA_SIG *SIG; BN_CTX *ctx; const EC_GROUP *group; BIGNUM *order,*halforder; + if ( (KEY= oldbitcoin_privkeyset(&oddeven,&pubkey,privkey)) != 0 ) + { + if ( (SIG= ECDSA_do_sign(data,datalen,KEY)) != 0 ) + { + ctx = BN_CTX_new(); + BN_CTX_start(ctx); + group = EC_KEY_get0_group(KEY); + order = BN_CTX_get(ctx); + halforder = BN_CTX_get(ctx); + EC_GROUP_get_order(group,order,ctx); + BN_rshift1(halforder,order); + if ( BN_cmp(SIG->s,halforder) > 0 ) + { + // enforce low S values, by negating the value (modulo the order) if above order/2. + BN_sub(SIG->s,order,SIG->s); + } + ptr = 0; + siglen = i2d_ECDSA_SIG(SIG,&ptr); + if ( ptr != 0 ) + { + if ( siglen > 0 ) + { + memcpy(sig,ptr,siglen); + retval = siglen; + } + free(ptr); + } + BN_CTX_end(ctx); + BN_CTX_free(ctx); + ECDSA_SIG_free(SIG); + } + //if ( ECDSA_sign(0,data,datalen,sig,&siglen,KEY) > 0 && siglen <= maxlen ) + // retval = siglen; + EC_KEY_free(KEY); + } + return(retval); +} + +bits256 oldbitcoin_pubkey33(void *_ctx,uint8_t *data,bits256 privkey) +{ + uint8_t oddeven,data2[65]; size_t plen; bits256 pubkey; secp256k1_pubkey secppub; secp256k1_context *ctx; + EC_KEY *KEY; + if ( (KEY= oldbitcoin_privkeyset(&oddeven,&pubkey,privkey)) != 0 ) + { + data[0] = oddeven; + memcpy(data+1,pubkey.bytes,sizeof(pubkey)); + EC_KEY_free(KEY); + if ( (ctx= secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY)) != 0 ) + { + if ( secp256k1_ec_pubkey_create(ctx,&secppub,privkey.bytes) > 0 ) + { + plen = 33; + secp256k1_ec_pubkey_serialize(ctx,data2,&plen,&secppub,1); + if ( memcmp(data2,data,plen) != 0 ) + printf("pubkey compare error plen.%d\n",(int32_t)plen); + else printf("pubkey verified\n"); + } //else printf("error secp256k1_ec_pubkey_create\n"); + secp256k1_context_destroy(ctx); + } + } else memset(pubkey.bytes,0,sizeof(pubkey)); + return(pubkey); +} + +void bn_mpi2bn(BIGNUM *vo,uint8_t *data,int32_t datalen) +{ + uint8_t vch2[64 + 4]; uint32_t i,vch2_len = (int32_t)datalen + 4; + if ( datalen < sizeof(vch2) ) + { + vch2[0] = (datalen >> 24) & 0xff; + vch2[1] = (datalen >> 16) & 0xff; + vch2[2] = (datalen >> 8) & 0xff; + vch2[3] = (datalen >> 0) & 0xff; + for (i=0; i= 4 && sz < sizeof(s_be) ) // get MPI format size + { + BN_bn2mpi(v,s_be); + // copy-swap MPI to little endian, sans 32-bit size prefix + sz -= 4; + for (i=0; i= 2 && revdata[len - 1] == 0 && revdata[len - 2] >= 0x80 ) + len--; + zeroes = 0; + for (p=coinaddr; *p==base58_chars[0]; p++) + zeroes++; + be_sz = (uint32_t)len + (uint32_t)zeroes; + memset(data,0,be_sz); + for (i=0; i> 1) ) + { + ctx = BN_CTX_new(); + BN_init(&bn58), BN_init(&bn0), BN_init(&bn), BN_init(&dv), BN_init(&rem); + BN_set_word(&bn58,58); + BN_set_word(&bn0,0); + for (i=0; i 0 ) + { + if ( BN_div(&dv,&rem,&bn,&bn58,ctx) == 0 ) + { + flag = -1; + break; + } + BN_copy(&bn,&dv); + rs[n++] = base58_chars[BN_get_word(&rem)]; + } + if ( flag == 0 ) + { + for (i=0; iblockspace,sizeof(coin->blockspace),&checktxid,tx,height,0,0)) > 0 ) + if ( (len= iguana_txbytes(coin,coin->blockspace,coin->blockspacesize,&checktxid,tx,height,0,0)) > 0 ) { txbytes = mycalloc('x',1,len*2+1); init_hexbytes_noT(txbytes,coin->blockspace,len*2+1); @@ -16444,6 +16444,2215 @@ len = 0; return s_enc; } */ + /*if ( fieldstr != 0 && valuestr != 0 ) + { + flag = 0; + if ( (len= is_hexstr(fieldstr,0)) > 0 ) + { + if ( strlen(fieldstr) == 20*2 ) + decode_hex(rmd160,sizeof(rmd160),fieldstr); + else + { + len >>= 1; + decode_hex(script,len,valuestr); + calc_rmd160_sha256(rmd160,script,len); + bitcoin_address(p2shaddr,coin->chain->p2shtype,rmd160,20); + fprintf(fp,"%s %s %32s=%d # addr=%s # p2sh\n",valuestr,utc_str(str,(uint32_t)time(NULL)),account,i+1,p2shaddr); + flag = 1; + } + } else bitcoin_addr2rmd160(&addrtype,rmd160,fieldstr); + if ( flag == 0 ) + { + privkey = bits256_conv(valuestr); + bitcoin_priv2wif(wifstr,privkey,coin->chain->wiftype); + bitcoin_address(coinaddr,coin->chain->pubtype,rmd160,20); + fprintf(fp,"%s %s %32s=%d # addr=%s\n",wifstr,utc_str(str,(uint32_t)time(NULL)),account,i+1,coinaddr); + } + + wiftype = 188; + for (j=0; jchain != 0 ) + { + if ( addrtype == coin->chain->pubtype ) + { + wiftype = coin->chain->wiftype; + privkey = bits256_conv(privkeystr); + if ( bits256_nonz(privkey) != 0 && bitcoin_priv2wif(wifstr,privkey,wiftype) > 0 ) + { + fprintf(fp,"%s %s %32s=%d # addr=%s\n",wifstr,utc_str(str,(uint32_t)time(NULL)),account,i+1,coinaddr); + } + break; + } + else if ( addrtype == coin->chain->p2shtype ) + { + fprintf(fp,"%s %s %32s=%d # addr=%s # p2sh\n",privkeystr,utc_str(str,(uint32_t)time(NULL)),account,i+1,p2shaddr); + break; + } + } + } + }*/ + /*coinaddr = child->string; + privkeystr = child->valuestring; + if ( coinaddr != 0 && privkeystr != 0 ) + { + if ( (wacct= iguana_waccountcreate(myinfo,coin,account)) != 0 ) + { + if ( iguana_waddresssearch(myinfo,coin,&tmp,coinaddr) == 0 ) + { + memset(&waddr,0,sizeof(waddr)); + strcpy(waddr.coinaddr,coinaddr); + waddr.addrtype = coin->chain->p2shtype; + if ( bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr) == sizeof(rmd160) && addrtype == coin->chain->p2shtype ) + iguana_waddressadd(myinfo,coin,wacct,&waddr,privkeystr); + else + { + waddr.addrtype = coin->chain->pubtype; + privkey = bits256_conv(privkeystr); + if ( iguana_waddresscalc(myinfo,coin->chain->pubtype,coin->chain->wiftype,&waddr,privkey) != 0 ) + iguana_waddressadd(myinfo,coin,wacct,&waddr,0); + } + } else printf("dup.(%s) ",coinaddr); + len = (int32_t)strlen(privkeystr); + for (j=0; jwallet,wacct,tmp) + { + if ( account != 0 && strcmp(account,"*") != 0 && strcmp(account,wacct->account) != 0 ) + continue; + HASH_ITER(hh,wacct->waddr,waddr,tmp2) + { + if ( waddr->addrtype != coin->chain->pubtype || (bits256_nonz(waddr->privkey) == 0 && waddr->scriptlen == 0) ) + continue; + if ( waddr->balance > 0 ) + { + remains -= waddr->balance; + waddrs[num++] = waddr; + if ( num >= maxwaddrs || remains <= 0 ) + break; + } + } + if ( num >= maxwaddrs || remains <= 0 ) + break; + } + + /*int64_t iguana_unspentset(struct supernet_info *myinfo,struct iguana_info *coin) + { + int64_t sum = 0,total; struct iguana_waccount *wacct,*tmp; struct iguana_waddress *waddr,*tmp2; int32_t n,numunspents = 0; cJSON *addresses = cJSON_CreateArray(); + HASH_ITER(hh,myinfo->wallet,wacct,tmp) + { + HASH_ITER(hh,wacct->waddr,waddr,tmp2) + { + if ( waddr->addrtype != coin->chain->pubtype || (bits256_nonz(waddr->privkey) == 0 && waddr->scriptlen == 0) ) + continue; + jaddstr(array,waddr->coinaddr); + total = 0; + n = 0; + iguana_pkhasharray(myinfo,coin,0,coin->minconfirms,coin->longestchain,&total,0,coin->bundlescount,waddr->rmd160,waddr->coinaddr,waddr->pubkey,coin->blocks.hwmchain.height - coin->minconfirms,(uint64_t *)coin->blockspace,&n,(int32_t)(coin->blockspacesize/sizeof(*waddr->unspents))-1000); + if ( n > 0 ) + { + if ( waddr->unspents == 0 || waddr->maxunspents < n ) + { + waddr->unspents = realloc(waddr->unspents,sizeof(*waddr->unspents) * n); + waddr->maxunspents = n; + } + memcpy(waddr->unspents,coin->blockspace,sizeof(*waddr->unspents) * n); + waddr->numunspents = n; + waddr->balance = total; + sum += total; + numunspents += n; + } + } + } + //printf("available %.8f\n",dstr(sum)); + return(sum); + }*/ + + /*int32_t bitcoin_verifytx(struct iguana_info *coin,bits256 *signedtxidp,char **signedtx,char *rawtxstr,struct vin_info *V,int32_t numinputs) + { + int32_t len,maxsize,retval = -1; uint8_t *serialized,*serialized2; + struct iguana_msgtx msgtx; bits256 txid; char vpnstr[64]; + len = (int32_t)strlen(rawtxstr); + maxsize = len + 32768; + serialized = calloc(1,maxsize), serialized2 = calloc(1,maxsize); + len >>= 1; + vpnstr[0] = 0; + decode_hex(serialized,len,rawtxstr); + memset(&msgtx,0,sizeof(msgtx)); + if ( iguana_rwmsgtx(coin,0,0,serialized,maxsize,&msgtx,&txid,vpnstr) > 0 && numinputs == msgtx.tx_in ) + { + if ( bitcoin_verifyvins(coin,signedtxidp,signedtx,&msgtx,serialized2,maxsize,V,SIGHASH_ALL) == 0 ) + retval = 0; + else printf("bitcoin_verifytx: bitcoin_verifyvins error\n"); + } else printf("bitcoin_verifytx: error iguana_rwmsgtx\n"); + free(serialized), free(serialized2); + return(retval); + } + + cJSON *iguana_signtx(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,char **signedtxp,struct bitcoin_spend *spend,cJSON *txobj,cJSON *vins) + { + int32_t i,j,m,n,plen; char *rawtxstr,*pubkeystr,*spendstr; struct vin_info *V,*vp; bits256 txid; struct iguana_waccount *wacct; struct iguana_waddress *waddr; cJSON *vitem,*vinsobj,*pubkeys; + V = calloc(spend->numinputs,sizeof(*V)); + if ( *signedtxp != 0 ) + { + if ( txobj != 0 ) + free_json(txobj); + txobj = bitcoin_hex2json(coin,&txid,0,*signedtxp); + if ( vins != 0 ) + { + if ( jobj(txobj,"vin") != 0 ) + jdelete(txobj,"vin"); + jadd(txobj,"vin",iguana_createvins(myinfo,coin,txobj,vins)); + } + //printf("bitcoin_hex2json (%s)\n",jprint(txobj,0)); + free(*signedtxp); + } + vinsobj = jarray(&n,txobj,"vin"); + for (i=0; inuminputs; i++) // N times less efficient, but for small number of inputs ok + { + vp = &V[i]; + if ( i < n ) + { + if ( (vitem= jitem(vinsobj,i)) != 0 && ((spendstr= jstr(vitem,"scriptPub")) != 0 || (spendstr= jstr(vitem,"scriptPubKey")) != 0) ) + { + vp->spendlen = (int32_t)strlen(spendstr) >> 1; + decode_hex(vp->spendscript,vp->spendlen,spendstr); + } else spendstr = 0; + } + else vitem = 0; + vp->N = vp->M = 1; + if ( (rawtxstr= bitcoin_json2hex(myinfo,coin,&txid,txobj,0)) != 0 ) + { + for (j=0; jinputs[i].privkeys)/sizeof(*spend->inputs[i].privkeys); j++) + { + if ( bits256_nonz(spend->inputs[i].privkeys[j]) != 0 ) + { + vp->signers[j].privkey = spend->inputs[i].privkeys[j]; + bitcoin_pubkey33(coin->ctx,vp->signers[j].pubkey,vp->signers[j].privkey); + } + else + { + vp->signers[j].pubkey[0] = 0; + break; + } + } + if ( vitem != 0 && (pubkeys= jarray(&m,vitem,"pubkeys")) != 0 )//spend->inputs[i].numpubkeys > 0 ) + { + for (j=0; jinputs[i].privkeys)/sizeof(*spend->inputs[i].privkeys); j++) + { + if ( j < m && (pubkeystr= jstr(jitem(pubkeys,j),0)) != 0 && is_hexstr(pubkeystr,(int32_t)strlen(pubkeystr)) > 0 ) + decode_hex(vp->signers[j].pubkey,(int32_t)strlen(pubkeystr)>>1,pubkeystr); + else if ( (plen= bitcoin_pubkeylen(spend->inputs[i].pubkeys[j])) > 0 ) + memcpy(vp->signers[j].pubkey,spend->inputs[i].pubkeys[j],plen); + } + } + //if ( spend->inputs[i].spendlen > 0 ) + // { + // memcpy(vp->spendscript,spend->inputs[i].spendscript,spend->inputs[i].spendlen); + // vp->spendlen = spend->inputs[i].spendlen; + // } + if ( spend->inputs[i].p2shlen > 0 ) + { + memcpy(vp->p2shscript,spend->inputs[i].p2shscript,spend->inputs[i].p2shlen); + vp->p2shlen = spend->inputs[i].p2shlen; + } + for (j=0; jinputs[i].privkeys)/sizeof(*spend->inputs[i].privkeys); j++) + { + if ( vp->signers[j].coinaddr[0] == 0 && (plen= bitcoin_pubkeylen(spend->inputs[i].pubkeys[j])) > 0 ) + { + bitcoin_address(vp->signers[j].coinaddr,coin->chain->pubtype,spend->inputs[i].pubkeys[j],plen); + } + } + if ( myinfo->expiration != 0 ) + { + for (j=0; jinputs[i].privkeys)/sizeof(*spend->inputs[i].privkeys); j++) + { + if ( bits256_nonz(vp->signers[j].privkey) == 0 && vp->signers[j].coinaddr[0] != 0 ) + { + if ( (waddr= iguana_waddresssearch(myinfo,coin,&wacct,vp->signers[j].coinaddr)) != 0 ) + vp->signers[j].privkey = waddr->privkey; + } + } + } + vp->sequence = spend->inputs[i].sequence; + //printf("json2hex.(%s)\n",rawtxstr); + } + } + bitcoin_verifytx(coin,txidp,signedtxp,rawtxstr,V,spend->numinputs); + //printf("json2hex.(%s)\n",rawtxstr); + free(rawtxstr); + if ( *signedtxp != 0 && i != spend->numinputs ) + free(*signedtxp), *signedtxp = 0; + free(V); + return(txobj); + }*/ + /*int64_t iguana_availunspents(struct supernet_info *myinfo,uint64_t **unspentsp,int32_t *nump,struct iguana_info *coin,int32_t minconf,char *account,void *ptr,int32_t maxsize) + { + int32_t i,j,num,numwaddrs; struct iguana_waddress **waddrs,*waddr; uint64_t *unspents,value,avail=0; + *unspentsp = unspents = 0; + *nump = num = 0; + waddrs = (struct iguana_waddress **)ptr; + numwaddrs = iguana_unspentslists(myinfo,coin,waddrs,(int32_t)(maxsize/sizeof(*waddrs)),(uint64_t)1 << 62,minconf); + if ( numwaddrs > 0 ) + { + unspents = (uint64_t *)((long)ptr + sizeof(*waddrs)*numwaddrs); + for (i=num=0; inumunspents > 0 ) + { + for (j=0; jnumunspents; j++) + { + if ( (value= iguana_unspentavail(coin,waddr->unspents[j],minconf,coin->longestchain)) != 0 ) + { + unspents[num << 1] = waddr->unspents[j]; + unspents[(num << 1) + 1] = value; + num++; + avail += value; + printf("([%d].u%u) ",(uint32_t)(waddr->unspents[j]>>32),(uint32_t)waddr->unspents[j]); + } + } + printf("(%s %.8f)\n",waddr->coinaddr,dstr(waddr->balance)); + } + } + } + *unspentsp = unspents; + *nump = num; + return(avail); + }*/ + + instantdex_addevent(s,*n,"BOB_sentprivs","BTCprivs","BTCprivs","BOB_waitfee"); + instantdex_addevent(s,*n,"BOB_sentprivs","BTCdeckC","BTCprivs","BOB_waitfee"); + instantdex_addevent(s,*n,"BOB_sentprivs","BTCprivC","BTCprivs","BOB_waitfee"); + instantdex_addevent(s,*n,"BOB_sentprivs","poll","BTCprivs","BOB_waitfee"); + + s = instantdex_statecreate(s,n,"ALICE_sentprivs",BTC_waitprivsfunc,0,"BTC_cleanup",0,0); + instantdex_addevent(s,*n,"ALICE_sentprivs","BTCprivs","BTCprivs","Alice_waitfee"); + instantdex_addevent(s,*n,"ALICE_sentprivs","BTCdeckC","BTCprivs","Alice_waitfee"); + instantdex_addevent(s,*n,"ALICE_sentprivs","BTCprivC","BTCprivs","Alice_waitfee"); + instantdex_addevent(s,*n,"ALICE_sentprivs","poll","BTCprivs","Alice_waitfee"); + + s = instantdex_statecreate(s,n,"BOB_waitfee",BOB_waitfeefunc,0,"BTC_cleanup",0,0); + instantdex_addevent(s,*n,"BOB_waitfee","feefound","BTCdeptx","BOB_sentdeposit"); + instantdex_addevent(s,*n,"BOB_waitfee","BTCdeckC","BTCprivs","BOB_waitfee"); + instantdex_addevent(s,*n,"BOB_waitfee","BTCprivs","poll","BOB_waitfee"); + instantdex_addevent(s,*n,"BOB_waitfee","poll","BTCprivs","BOB_waitfee"); + + s = instantdex_statecreate(s,n,"Alice_waitfee",ALICE_waitfeefunc,0,"BTC_cleanup",0,0); + instantdex_addevent(s,*n,"Alice_waitfee","feefound","BTCprivs","ALICE_waitdeposit"); + instantdex_addevent(s,*n,"Alice_waitfee","BTCdeckC","BTCprivs","Alice_waitfee"); + instantdex_addevent(s,*n,"Alice_waitfee","BTCprivs","poll","Alice_waitfee"); + instantdex_addevent(s,*n,"Alice_waitfee","poll","BTCprivs","Alice_waitfee"); + + s = instantdex_statecreate(s,n,"ALICE_waitdeposit",ALICE_waitdepositfunc,0,"BTC_cleanup",0,0); + instantdex_addevent(s,*n,"ALICE_waitdeposit","depfound","BTCalttx","ALICE_sentalt"); + instantdex_addevent(s,*n,"ALICE_waitdeposit","feefound","poll","ALICE_waitdeposit"); + instantdex_addevent(s,*n,"ALICE_waitdeposit","poll","BTCprivs","ALICE_waitdeposit"); + + s = instantdex_statecreate(s,n,"BOB_sentdeposit",BOB_waitBTCalttxfunc,0,"BOB_reclaimed",0,0); + instantdex_addevent(s,*n,"BOB_sentdeposit","BTCalttx","poll","BOB_altconfirm"); + instantdex_addevent(s,*n,"BOB_sentdeposit","poll","poll","BOB_sentdeposit"); + + s = instantdex_statecreate(s,n,"BOB_altconfirm",BOB_waitaltconfirmfunc,0,"BOB_reclaimed",0,0); + instantdex_addevent(s,*n,"BOB_altconfirm","altfound","BTCpaytx","BOB_sentpayment"); + instantdex_addevent(s,*n,"BOB_altconfirm","poll","poll","BOB_altconfirm"); + + // [BLOCKING: BTCpaytx] now Alice's turn to make sure payment is confrmed and send in claim or see bob's reclaim and reclaim + s = instantdex_statecreate(s,n,"ALICE_sentalt",ALICE_waitBTCpaytxfunc,0,"ALICE_reclaimed",0,0); + instantdex_addevent(s,*n,"ALICE_sentalt","BTCpaytx","poll","ALICE_waitconfirms"); + instantdex_addevent(s,*n,"ALICE_sentalt","poll","poll","ALICE_sentalt"); + + s = instantdex_statecreate(s,n,"ALICE_waitconfirms",ALICE_waitconfirmsfunc,0,"ALICE_reclaimed",0,0); + instantdex_addevent(s,*n,"ALICE_waitconfirms","altfound","BTCprivM","ALICE_claimedbtc"); + instantdex_addevent(s,*n,"ALICE_waitconfirms","poll","poll","ALICE_checkbobreclaim"); + + /*cJSON *BTC_waitdeckCfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) + { + *serdatap = 0, *serdatalenp = 0; + strcmp(swap->expectedcmdstr,"BTCdeckC"); + return(newjson); + } + + cJSON *BTC_waitprivCfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) + { + strcmp(swap->expectedcmdstr,"BTCprivC"); + printf("call privkey extract from serdatalen.%d\n",*serdatalenp); + instantdex_privkeyextract(myinfo,swap,*serdatap,*serdatalenp); + *serdatap = 0, *serdatalenp = 0; + return(newjson); + } + + cJSON *ALICE_waitfeefunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) + { + struct iguana_info *coinbtc; + coinbtc = iguana_coinfind("BTC"); + *serdatap = 0, *serdatalenp = 0; + strcpy(swap->waitfortx,"fee"); + if ( coinbtc != 0 && swap->otherfee != 0 ) + jaddstr(newjson,"virtevent","feefound"); + return(newjson); + } + + cJSON *BTC_waitprivsfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) + { + *serdatap = 0, *serdatalenp = 0; struct iguana_info *coin = iguana_coinfind("BTC"); + if ( coin != 0 ) + { + strcmp(swap->expectedcmdstr,"BTCprivs"); + instantdex_privkeyextract(myinfo,swap,*serdatap,*serdatalenp); + } + return(newjson); + } + + cJSON *ALICE_waitBTCpaytxfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) + { + *serdatap = 0, *serdatalenp = 0; + strcmp(swap->expectedcmdstr,"BTCpaytx"); + return(newjson); + } + + cJSON *BOB_waitprivMfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) + { + char *retstr; + strcmp(swap->expectedcmdstr,"BTCprivM"); + if ( swap->payment != 0 && (retstr= BTC_txconfirmed(myinfo,iguana_coinfind(swap->mine.offer.base),swap,newjson,swap->payment->txid,&swap->payment->numconfirms,"altfound",0)) != 0 ) + { + free(retstr); + jaddstr(newjson,"virtevent","altfound"); + } + printf("search for payment spend in blockchain\n"); + *serdatap = 0, *serdatalenp = 0; + return(newjson); + } + + cJSON *BOB_waitaltconfirmfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) + { + char *retstr; struct iguana_info *altcoin; + altcoin = iguana_coinfind(swap->mine.offer.base); + *serdatap = 0, *serdatalenp = 0; + strcpy(swap->waitfortx,"alt"); + //reftime = (uint32_t)(ap->offer.expiration - INSTANTDEX_LOCKTIME*2); + if ( altcoin != 0 && swap->altpayment != 0 && swap->otherchoosei >= 0 && (retstr= BTC_txconfirmed(myinfo,altcoin,swap,newjson,swap->altpayment->txid,&swap->altpayment->numconfirms,"altfound",altcoin->chain->minconfirms)) != 0 ) + { + if ( swap->payment != 0 || (swap->payment= instantdex_bobtx(myinfo,swap,altcoin,swap->mypubs[1],swap->otherpubs[0],swap->privkeys[swap->otherchoosei],swap->reftime,swap->BTCsatoshis,0)) != 0 ) + { + free(retstr); + jaddstr(newjson,"virtevent","altfound"); + } + } + return(newjson); + } + + cJSON *ALICE_waitconfirmsfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) + { + char *retstr; double btcconfirms; struct iguana_info *coinbtc; + coinbtc = iguana_coinfind("BTC"); + *serdatap = 0, *serdatalenp = 0; + if ( swap->BTCsatoshis < SATOSHIDEN/10 ) + btcconfirms = 0; + else btcconfirms = 1. + sqrt((double)swap->BTCsatoshis / SATOSHIDEN); + if ( swap->payment != 0 && (retstr= BTC_txconfirmed(myinfo,coinbtc,swap,newjson,swap->payment->txid,&swap->payment->numconfirms,"payfound",btcconfirms)) != 0 ) + { + free(retstr); + jaddstr(newjson,"virtevent","payfound"); + // if bobreclaimed is there, then reclaim altpayment + printf("search for Bob's reclaim in blockchain\n"); + } + return(newjson); + } + + cJSON *ALICE_checkbobreclaimfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) + { + char *retstr; double btcconfirms; struct iguana_info *coinbtc; + coinbtc = iguana_coinfind("BTC"); + *serdatap = 0, *serdatalenp = 0; + if ( swap->BTCsatoshis < SATOSHIDEN/10 ) + btcconfirms = 0; + else btcconfirms = sqrt((double)swap->BTCsatoshis / SATOSHIDEN); + if ( swap->payment != 0 && (retstr= BTC_txconfirmed(myinfo,coinbtc,swap,newjson,swap->payment->txid,&swap->payment->numconfirms,"payfound",btcconfirms)) != 0 ) + { + free(retstr); + jaddstr(newjson,"virtevent","payfound"); + // if bobreclaimed is there, then reclaim altpayment + printf("search for Bob's reclaim in blockchain\n"); + } + return(newjson); + } + + cJSON *BTC_idlerecvfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) + { + *serdatap = 0, *serdatalenp = 0; + jaddstr(newjson,"error","need to cleanup"); + return(newjson); + } + */ + + cJSON *BOB_reclaimfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) + { + *serdatap = 0, *serdatalenp = 0; + if ( swap->deposit != 0 ) + printf("reclaim deposit.(%s) to %s\n",swap->deposit->txbytes,swap->deposit->destaddr); + strcpy(swap->waitfortx,"bre"); + // reclaim deposit + return(newjson); + } + + cJSON *BOB_feereclaimfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) + { + *serdatap = 0, *serdatalenp = 0; + if ( swap->myfee != 0 ) + printf("reclaim fee.(%s) -> %s\n",swap->myfee->txbytes,swap->myfee->destaddr); + strcpy(swap->waitfortx,"bfr"); + // reclaim deposit + return(newjson); + } + + cJSON *BOB_claimaltfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) + { + *serdatap = 0, *serdatalenp = 0; + if ( 0 && swap->altpayment != 0 ) + printf("spend altpayment.(%s) -> %s\n",swap->altpayment->txbytes,swap->altpayment->destaddr); + strcpy(swap->waitfortx,"bcl"); + // spend altpayment + return(newjson); + } + + cJSON *ALICE_reclaimfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) + { + *serdatap = 0, *serdatalenp = 0; + // reclaim altpayment + if ( swap->altpayment != 0 ) + printf("reclaim altpayment.(%s) -> %s\n",swap->altpayment->txbytes,swap->altpayment->destaddr); + strcpy(swap->waitfortx,"are"); + return(newjson); + } + + cJSON *ALICE_feereclaimfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) + { + *serdatap = 0, *serdatalenp = 0; + // reclaim fee + if ( swap->myfee != 0 ) + printf("reclaim fee.(%s) -> %s\n",swap->myfee->txbytes,swap->myfee->destaddr); + strcpy(swap->waitfortx,"afr"); + return(newjson); + } + + cJSON *ALICE_claimdepositfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) + { + *serdatap = 0, *serdatalenp = 0; + if ( swap->deposit != 0 ) + printf("reclaim deposit.(%s) -> %s\n",swap->deposit->txbytes,swap->deposit->destaddr); + strcpy(swap->waitfortx,"adp"); + // reclaim deposit + return(newjson); + } + + cJSON *ALICE_claimbtcfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) + { + *serdatap = 0, *serdatalenp = 0; + if ( swap->payment != 0 ) + printf("spend BTC payment.(%s) -> %s\n",swap->payment->txbytes,swap->payment->destaddr); + strcpy(swap->waitfortx,"acl"); + // spend BTC + return(newjson); + } + + /* + s = instantdex_statecreate(s,n,"ALICE_claimedbtc",ALICE_claimbtcfunc,0,0,0,0); + instantdex_addevent(s,*n,"ALICE_claimedbtc","aclfound","poll","BTC_cleanup"); + instantdex_addevent(s,*n,"ALICE_claimedbtc","poll","poll","ALICE_claimedbtc"); + + s = instantdex_statecreate(s,n,"BOB_depclaimed",BOB_reclaimfunc,0,0,0,0); // deposit back + instantdex_addevent(s,*n,"BOB_depclaimed","brefound","poll","BTC_cleanup"); + instantdex_addevent(s,*n,"BOB_depclaimed","poll","poll","BOB_depclaimed"); + + s = instantdex_statecreate(s,n,"BOB_claimedalt",BOB_claimaltfunc,0,0,0,0); + instantdex_addevent(s,*n,"BOB_claimedalt","bclfound","poll","BOB_depclaimed"); + instantdex_addevent(s,*n,"BOB_claimedalt","poll","poll","BOB_claimedalt"); + + // if things go wrong, bob gets his deposit and fee back + s = instantdex_statecreate(s,n,"BOB_feereclaimed",BOB_feereclaimfunc,0,0,0,0); + instantdex_addevent(s,*n,"BOB_feereclaimed","bfrfound","poll","BTC_cleanup"); + instantdex_addevent(s,*n,"BOB_feereclaimed","poll","poll","BOB_feereclaimed"); + + s = instantdex_statecreate(s,n,"BOB_reclaimed",BOB_reclaimfunc,0,0,0,0); // deposit back + instantdex_addevent(s,*n,"BOB_reclaimed","brefound","poll","BOB_feereclaimed"); + instantdex_addevent(s,*n,"BOB_reclaimed","poll","poll","BOB_reclaimed"); + + // if things go wrong, alice reclaims her altpayment or claims the deposit and then fee + s = instantdex_statecreate(s,n,"ALICE_feereclaimed",ALICE_feereclaimfunc,0,0,0,0); + instantdex_addevent(s,*n,"ALICE_feereclaimed","afrfound","poll","BTC_cleanup"); + instantdex_addevent(s,*n,"ALICE_feereclaimed","poll","poll","ALICE_feereclaimed"); + + s = instantdex_statecreate(s,n,"ALICE_reclaimed",ALICE_reclaimfunc,0,0,0,0); // altpayment + instantdex_addevent(s,*n,"ALICE_reclaimed","arefound","poll","ALICE_feereclaimed"); + instantdex_addevent(s,*n,"ALICE_reclaimed","poll","poll","ALICE_reclaimed"); + s = instantdex_statecreate(s,n,"ALICE_depositclaimed",ALICE_claimdepositfunc,0,0,0,0); // altpayment + instantdex_addevent(s,*n,"ALICE_depositclaimed","adpfound","poll","ALICE_feereclaimed"); + instantdex_addevent(s,*n,"ALICE_depositclaimed","poll","poll","ALICE_depositclaimed"); + s = instantdex_statecreate(s,n,"ALICE_checkbobreclaim",ALICE_checkbobreclaimfunc,0,"ALICE_reclaimed",0,0);*/ + // end terminal [BLOCKING] states + + // need to create states before they can be referred to, that way a one pass FSM compile is possible + //s = instantdex_statecreate(s,n,"BOB_gotoffer",BTC_waitprivCfunc,0,"BTC_cleanup",0,1); + //s = instantdex_statecreate(s,n,"ALICE_gotoffer",BTC_waitprivCfunc,0,"BTC_cleanup",0,1); + //s = instantdex_statecreate(s,n,"BOB_sentprivs",BTC_waitprivsfunc,0,"BTC_cleanup",0,0); + //s = instantdex_statecreate(s,n,"BOB_waitfee",BOB_waitfeefunc,0,"BTC_cleanup",0,0); + //s = instantdex_statecreate(s,n,"BOB_sentdeposit",BOB_waitBTCalttxfunc,0,"BOB_reclaimed",0,0); + //s = instantdex_statecreate(s,n,"BOB_altconfirm",BOB_waitaltconfirmfunc,0,"BOB_reclaimed",0,0); + //s = instantdex_statecreate(s,n,"BOB_sentpayment",BOB_waitprivMfunc,0,"BOB_reclaimed",0,0); + //s = instantdex_statecreate(s,n,"ALICE_sentprivs",BTC_waitprivsfunc,0,"BTC_cleanup",0,0); + //s = instantdex_statecreate(s,n,"Alice_waitfee",ALICE_waitfeefunc,0,"BTC_cleanup",0,0); + //s = instantdex_statecreate(s,n,"ALICE_waitdeposit",ALICE_waitdepositfunc,0,"BTC_cleanup",0,0); + //s = instantdex_statecreate(s,n,"ALICE_sentalt",ALICE_waitBTCpaytxfunc,0,"ALICE_reclaimed",0,0); + //s = instantdex_statecreate(s,n,"ALICE_waitconfirms",ALICE_waitconfirmsfunc,0,"ALICE_reclaimed",0,0); + + /*if ( 0 ) // following are implicit states and events handled externally to setup datastructures + { + instantdex_addevent(s,*n,"BOB_idle","usrorder","BTCoffer","BTC_waitdeck"); // send deck + instantdex_addevent(s,*n,"ALICE_idle","usrorder","BTCoffer","BTC_waitdeck"); + } + s = instantdex_statecreate(s,n,"BOB_idle",BTC_checkdeckfunc,0,"BTC_cleanup",0,1); + s = instantdex_statecreate(s,n,"ALICE_idle",BTC_checkdeckfunc,0,"BTC_cleanup",0,1); + instantdex_addevent(s,*n,"BOB_idle","BTCoffer","poll","BTC_waitdeck"); // send deck + Chose + instantdex_addevent(s,*n,"ALICE_idle","BTCoffer","poll","BTC_waitdeck");*/ + + char *basilisk_issuebalances(struct supernet_info *myinfo,char *remoteaddr,int32_t basilisktag,char *symbol,int32_t lastheight,int32_t minconf,cJSON *addresses,int32_t timeoutmillis) + { + struct iguana_info *coin; char *retstr = 0; cJSON *retjson,*args = 0; + if ( (coin= iguana_coinfind(symbol)) != 0 ) + { + if ( coin->basilisk_balances != 0 ) + { + if ( (retstr= (*coin->basilisk_balances)(myinfo,coin,remoteaddr,basilisktag,&args,lastheight,minconf,addresses,timeoutmillis)) != 0 ) + { + retjson = basilisk_resultsjson(myinfo,symbol,remoteaddr,basilisktag,timeoutmillis,retstr,args); + free(retstr); + retstr = jprint(retjson,1); + } + } + } + return(retstr); + } + + char *basilisk_issuevalue(struct supernet_info *myinfo,char *remoteaddr,uint32_t basilisktag,char *symbol,bits256 txid,int16_t vout,char *coinaddr,int32_t timeoutmillis) + { + struct iguana_info *coin; char *retstr = 0; cJSON *retjson,*args = 0; + if ( (coin= iguana_coinfind(symbol)) != 0 ) + { + if ( coin->basilisk_value != 0 ) + { + if ( (retstr= (*coin->basilisk_value)(myinfo,coin,remoteaddr,basilisktag,&args,txid,vout,coinaddr,timeoutmillis)) != 0 ) + { + retjson = basilisk_resultsjson(myinfo,symbol,remoteaddr,basilisktag,timeoutmillis,retstr,args); + free(retstr); + retstr = jprint(retjson,1); + } + } + } + return(retstr); + } + int32_t basilisk_submit(struct supernet_info *myinfo,cJSON *reqjson,int32_t timeout,int32_t fanout,struct basilisk_item *ptr) + { + int32_t i,j,k,l,r2,r,n; struct iguana_peer *addr; struct iguana_info *coin; char *reqstr; cJSON *tmpjson; + tmpjson = basilisk_json(myinfo,reqjson,ptr->basilisktag,timeout); + reqstr = jprint(tmpjson,1); + //printf("basilisk_submit.(%s)\n",reqstr); + if ( fanout <= 0 ) + fanout = BASILISK_MINFANOUT; + else if ( fanout > BASILISK_MAXFANOUT ) + fanout = BASILISK_MAXFANOUT; + r2 = rand(); + for (l=n=0; lpeers.active[j]) != 0 && addr->supernet != 0 && addr->usock >= 0 ) + { + ptr->submit = (uint32_t)time(NULL); + printf("submit to (%s)\n",addr->ipaddr); + iguana_send_supernet(addr,reqstr,0); + if ( n++ > fanout ) + break; + } + } + } + } + free(reqstr); + return(n); + } + + /*cJSON *basilisk_json(struct supernet_info *myinfo,cJSON *hexjson,uint32_t basilisktag,int32_t timeout) + { + char *str,*buf; cJSON *retjson; + if ( jobj(hexjson,"basilisktag") != 0 ) + jdelete(hexjson,"basilisktag"); + jaddnum(hexjson,"basilisktag",basilisktag); + str = jprint(hexjson,0); + buf = malloc(strlen(str)*2 + 1); + init_hexbytes_noT(buf,(uint8_t *)str,(int32_t)strlen(str)); + free(str); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"hexmsg",buf); + free(buf); + jaddstr(retjson,"agent","SuperNET"); + jaddstr(retjson,"method","DHT"); + jaddnum(retjson,"request",1); + jaddnum(retjson,"plaintext",1); + jaddbits256(retjson,"categoryhash",myinfo->basilisk_category); + jaddnum(retjson,"timeout",timeout); + return(retjson); + } + if ( strcmp(type,"BID") == 0 || strcmp(type,"ASK") == 0 ) + { + instantdex_quotep2p(myinfo,0,addr,data,datalen); + } + else if ( (argjson= cJSON_Parse((char *)data)) != 0 ) + { + jaddstr(argjson,"agent","basilisk"); + jaddnum(argjson,"basilisktag",basilisktag); + if ( strcmp(type,"RET") == 0 ) + { + jaddstr(argjson,"method","return"); + } + else if ( strcmp(type,"RAW") == 0 ) + { + jaddstr(argjson,"method","rawtx"); + } + else if ( strcmp(type,"VAL") == 0 ) + { + jaddstr(argjson,"method","value"); + } + jsonstr = jprint(argjson,1); + if ( (retstr= basilisk_hexmsg(myinfo,0,(void *)jsonstr,(int32_t)strlen(jsonstr)+1,remoteaddr)) != 0 ) + free(retstr); + free(jsonstr); + char *basilisk_results(uint32_t basilisktag,cJSON *valsobj) + { + cJSON *resultobj = cJSON_CreateObject(); + jadd(resultobj,"vals",valsobj); + jaddstr(resultobj,"agent","basilisk"); + jaddstr(resultobj,"method","result"); + jaddnum(resultobj,"plaintext",1); + if ( jobj(resultobj,"basilisktag") != 0 ) + jdelete(resultobj,"basilisktag"); + jaddnum(resultobj,"basilisktag",basilisktag); + return(jprint(resultobj,1)); + } + + cJSON *basilisk_resultsjson(struct supernet_info *myinfo,char *symbol,char *remoteaddr,uint32_t basilisktag,int32_t timeoutmillis,char *retstr) + { + cJSON *hexjson=0,*retjson=0; + if ( retstr != 0 ) + { + if ( remoteaddr != 0 && remoteaddr[0] != 0 ) + { + hexjson = cJSON_CreateObject(); + jaddstr(hexjson,"agent","basilisk"); + jaddstr(hexjson,"method","result"); + if ( (retjson= cJSON_Parse(retstr)) != 0 ) + jadd(hexjson,"vals",retjson); + retjson = basilisk_json(myinfo,hexjson,basilisktag,timeoutmillis); + free_json(hexjson); + printf("resultsjson.(%s)\n",jprint(retjson,0)); + } + else // local request + retjson = cJSON_Parse(retstr); + } + return(retjson); + }*/ + /* cJSON *array=0,*result,*item,*retjson,*hexjson; int32_t i,n,besti=-1; char *coinaddr,*balancestr=0,*retstr=0; int64_t total=0,amount,most=0; struct basilisk_item *ptr; + array = cJSON_CreateArray(); + if ( coin != 0 && basilisk_bitcoinavail(coin) != 0 ) + { + if ( (n= cJSON_GetArraySize(addresses)) > 0 ) + { + for (i=0; iVALIDATENODE != 0 || coin->FULLNODE != 0 ) + balancestr = iguana_balance(myinfo,coin,0,remoteaddr,coin->symbol,coinaddr,lastheight,minconf); + //else balancestr = bitcoin_balance(coin,coinaddr,lastheight,minconf); + if ( balancestr != 0 ) + { + if ( (result= cJSON_Parse(balancestr)) != 0 ) + { + if ( jobj(result,"balance") != 0 ) + { + item = cJSON_CreateObject(); + amount = SATOSHIDEN * jdouble(result,"balance"); + total += amount; + jaddnum(item,coinaddr,dstr(amount)); + jaddi(array,item); + } + free_json(result); + } + free(balancestr); + } + } + } + } + else + { + hexjson = cJSON_CreateObject(); + jaddnum(hexjson,"basilisktag",basilisktag); + jadd(hexjson,"addresses",jduplicate(addresses)); + jaddnum(hexjson,"minconf",minconf); + jaddnum(hexjson,"lastheight",lastheight); + jaddstr(hexjson,"agent","basilisk"); + jaddstr(hexjson,"method","balances"); + if ( (ptr= basilisk_issue(myinfo,hexjson,timeoutmillis,0,1,basilisktag)) != 0 ) + { + for (i=0; inumresults; i++) + { + if ( ptr->results[i] == 0 ) + continue; + if ( retstr != 0 && strcmp(ptr->results[i],retstr) == 0 ) + ptr->numexact++; + if ( (retjson= cJSON_Parse(ptr->results[i])) != 0 ) + { + if ( (total= j64bits(retjson,"balance")) > most ) + { + most = total; + besti = i; + } + free_json(retjson); + } + } + retstr = basilisk_finish(ptr,arrayp,besti); + } + free_json(hexjson); + } + *arrayp = array; + return(most);*/ + if ( agent != 0 && method != 0 && strcmp(agent,"SuperNET") == 0 && strcmp(method,"DHT") == 0 && (hexmsg= jstr(remotejson,"hexmsg")) != 0 ) + { + n = (int32_t)(strlen(hexmsg) >> 1); + tmpstr = calloc(1,n + 1); + decode_hex((void *)tmpstr,n,hexmsg); + free_json(remotejson); + printf("NESTED.(%s)\n",tmpstr); + if ( (remotejson= cJSON_Parse(tmpstr)) == 0 ) + { + printf("couldnt parse decoded hexmsg.(%s)\n",tmpstr); + free(tmpstr); + return(0); + } + free(tmpstr); + agent = jstr(remotejson,"agent"); + method = jstr(remotejson,"method"); + } + + char *basilisk_hexmsg(struct supernet_info *myinfo,struct category_info *dontuse,void *ptr,int32_t len,char *remoteaddr) // incoming + { + char *method,*retstr = 0; uint8_t *data=0; cJSON *array,*valsobj; struct iguana_info *coin=0; uint32_t basilisktag,datalen=0,jsonlen; + array = 0; + if ( (valsobj= cJSON_Parse((char *)ptr)) != 0 ) + { + jsonlen = (int32_t)strlen((char *)ptr) + 1; + if ( len > jsonlen ) + data = (uint8_t *)((long)ptr + jsonlen), datalen = len - jsonlen; + basilisktag = juint(valsobj,"basilisktag"); + printf("basilisk.(%s)\n",jprint(valsobj,0)); + if ( jobj(valsobj,"coin") != 0 ) + coin = iguana_coinfind(jstr(valsobj,"coin")); + if ( (method= jstr(valsobj,"method")) != 0 && coin != 0 ) + { + if ( coin->FULLNODE != 0 || coin->VALIDATENODE != 0 ) // iguana node + { + if ( strcmp(method,"rawtx") == 0 ) + retstr = basilisk_rawtx(myinfo,coin,0,remoteaddr,basilisktag,valsobj,coin->symbol); + else if ( strcmp(method,"balances") == 0 ) + retstr = basilisk_balances(myinfo,coin,0,remoteaddr,basilisktag,valsobj,coin->symbol); + else if ( strcmp(method,"value") == 0 ) + retstr = basilisk_value(myinfo,coin,0,remoteaddr,basilisktag,valsobj,coin->symbol); + if ( retstr != 0 ) + free(retstr); + retstr = 0; + // should automatically send to remote requester + } + else // basilisk node + { + if ( strcmp(method,"result") == 0 ) + retstr = basilisk_result(myinfo,coin,0,remoteaddr,basilisktag,valsobj); + } + } else printf("basilisk_hexmsg no coin\n"); + free_json(valsobj); + } + printf("unhandled bitcoin_hexmsg.(%d) from %s (%s)\n",len,remoteaddr,(char *)ptr); + return(retstr); + } + + int32_t basilisk_hashstamps(struct iguana_info *btcd,struct hashstamp *BTCDstamps,struct basilisk_sequence *seq,int32_t max,uint32_t reftimestamp) + { + uint32_t i,timestamp; struct iguana_block *block; + block = &btcd->blocks.hwmchain; + while ( block != 0 && (timestamp= block->RO.timestamp) > reftimestamp ) + block = iguana_blockfind("hashstamps",btcd,block->RO.prev_block); + if ( block == 0 ) + return(-1); + for (i=0; iRO.hash2; + BTCDstamps[i].timestamp = block->RO.timestamp; + BTCDstamps[i].height = block->height; + if ( (block= iguana_blockfind("hashstamps",btcd,block->RO.prev_block)) == 0 ) + return(i+1); + } + return(i); + } + //printf("mapped Soffset.%ld\n",(long)mapchain->data->Soffset); + /*iguana_ramchain_link(&R,block->RO.hash2,bp->hdrsi,bp->bundleheight+bundlei,bundlei,1,firsti,1); + if ( 1 ) // unix issues? + { + if ( (err= iguana_ramchain_cmp(ramchain,mapchain,0)) != 0 ) + fpos = -1, printf("error.%d comparing ramchains\n",err); + else + { + ptr = mapchain->fileptr; fsize = mapchain->filesize; + mapchain->fileptr = 0, mapchain->filesize = 0; + iguana_ramchain_free(coin,mapchain,1); + memset(&R,0,sizeof(R)); + R.H.data = (void *)(long)((long)ptr + fpos), R.filesize = fsize; + iguana_ramchain_link(&R,block->RO.hash2,bp->hdrsi,bp->bundleheight+bundlei,bundlei,1,firsti,1); + } + } + if ( (err= iguana_ramchain_cmp(ramchain,&R,0)) != 0 ) + { + fpos = -1; + block->issued = 0; + block->RO.recvlen = 0; + printf("error.%d comparing REMAP ramchains\n",err); + } + else + { + iguana_ramchain_extras(coin,&R,0,0); + if ( (err= iguana_ramchain_iterate(coin,0,&R,bp,bundlei)) != 0 ) + printf("err.%d iterate ",err); + //printf("SUCCESS REMAP\n"); + bp->numtxids += rdata->numtxids; + bp->numunspents += rdata->numunspents; + bp->numspends += rdata->numspends; + //bp->rawscriptspace += rdata->scriptspace; + } + iguana_ramchain_free(coin,&R,1); + if ( err != 0 ) + iguana_blockunmark(coin,block,bp,bundlei,1);*/ + + char *basilisk_respond_setfield(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 prevhash,int32_t from_basilisk) + { + struct iguana_info *virt; struct iguana_block *prevblock,*prev2,*newblock,block; char chainname[BASILISK_MAXNAMELEN],str[65],*blocktx; uint32_t nBits,timestamp,nonce; cJSON *retjson; bits256 btcdhash; + if ( datalen <= 0 ) + return(clonestr("{\"error\":\"no data specified\"}")); + if ( (virt= basilisk_chain(myinfo,chainname,valsobj)) == 0 ) + return(clonestr("{\"error\":\"couldnt get basilisk_chain\"}")); + printf("from.(%s) SET.(%s) datalen.%d prev.%s\n",remoteaddr,jprint(valsobj,0),datalen,bits256_str(str,prevhash)); + if ( bits256_nonz(prevhash) == 0 ) + prevhash = virt->blocks.hwmchain.RO.hash2; + if ( (prevblock= iguana_blockfind("setfield",virt,prevhash)) == 0 ) + return(clonestr("{\"error\":\"couldnt find prevhash\"}")); + if ( (prev2= iguana_blockfind("setfield",virt,prevblock->RO.prev_block)) == 0 ) + return(clonestr("{\"error\":\"couldnt find prevhash2\"}")); + timestamp = juint(valsobj,"timestamp"); + nonce = juint(valsobj,"nonce"); + nBits = iguana_targetbits(virt,(struct iguana_block *)&virt->blocks.hwmchain,prevblock,prev2,1,virt->chain->targetspacing,virt->chain->targettimespan); + blocktx = basilisk_block(myinfo,virt,&block,1,timestamp,&nonce,prevhash,nBits,prevblock->height+1,0,0,data,datalen,btcdhash,jobj(valsobj,"coinbase")); + retjson = cJSON_CreateObject(); + jaddbits256(retjson,"hash",block.RO.hash2); + jaddstr(retjson,"data",blocktx); + if ( (newblock= _iguana_chainlink(virt,&block)) != 0 ) + { + jaddstr(retjson,"result","chain extended"); + jaddnum(retjson,"ht",block.height); + } else jaddstr(retjson,"error","couldnt extend chain"); + free(blocktx); + return(jprint(retjson,1)); + } + + char *basilisk_respond_getfield(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 prevhash,int32_t from_basilisk) + { + struct iguana_info *coin; cJSON *retjson; char chainname[BASILISK_MAXNAMELEN]; + if ( (coin= basilisk_chain(myinfo,chainname,valsobj)) == 0 ) + return(clonestr("{\"error\":\"couldnt get basilisk_chain\"}")); + printf("getfield\n"); + retjson = cJSON_CreateObject(); + return(jprint(retjson,1)); + } + /*int32_t basilisk_sendPUB(struct supernet_info *myinfo,uint32_t basilisktag,uint8_t *data,int32_t datalen) // data must be offset by sizeof(iguana_msghdr)+sizeof(basilisktag) + { + int32_t i,j,r,r2,s,k,val,l,n=0; uint32_t *alreadysent; struct iguana_info *coin; struct iguana_peer *addr; + alreadysent = calloc(IGUANA_MAXPEERS * IGUANA_MAXCOINS,sizeof(*alreadysent)); + r = rand(), r2 = rand(); + for (k=0; kpeers.active[i]) != 0 && addr->ipbits != 0 && addr->usock >= 0 && addr->basilisk != 0 ) + { + for (s=0; sipbits ) + break; + if ( s == n ) + { + printf("pub (%s) addr->supernet.%u to (%s).%d\n",(char *)&data[4],addr->supernet,addr->ipaddr,addr->A.port); + if ( (val= iguana_queue_send(addr,0,&data[-sizeof(struct iguana_msghdr)],"SuperNETpub",datalen)) >= datalen ) + { + alreadysent[n++] = (uint32_t)addr->ipbits; + if ( n >= IGUANA_MAXPEERS*IGUANA_MAXCOINS ) + break; + } + } + } + } + if ( n >= IGUANA_MAXPEERS*IGUANA_MAXCOINS ) + break; + } + free(alreadysent); + return(n); + }*/ + + struct iguana_info *_iguana_coinadd(char *symbol,cJSON *argjson) + { + struct iguana_info *coin; char *privatechain; int32_t pval,i = 0; + if ( symbol == 0 ) + { + printf("_iguana_coinadd deprecated null symbol\n"); + exit(-1); + } + else + { + for (i=0; i= sizeof(Hardcoded_coins)/sizeof(*Hardcoded_coins) ) + break; + //printf("Hardcoded_coins[i][0] %s vs.(%s)\n",Hardcoded_coins[i][0],symbol); + //if ( symbol[0] == 0 ) + // getchar(); + if ( strcmp("endmarker",Hardcoded_coins[i][0]) == 0 || strcmp(symbol,Hardcoded_coins[i][0]) == 0 ) + { + if ( coin->chain == 0 ) + { + if ( i < sizeof(Hardcoded_coins)/sizeof(*Hardcoded_coins) ) + strcpy(coin->name,Hardcoded_coins[i][1]); + else if (argjson != 0 ) + { + if ( jstr(argjson,"name") != 0 ) + safecopy(coin->name,jstr(argjson,"name"),sizeof(coin->name)); + else strcpy(coin->name,symbol); + } + } + return(coin); + } + } + } + return(0); + } + + void basilisk_pending_result(struct supernet_info *myinfo,struct basilisk_item *ptr,struct basilisk_item *pending) + { + int32_t n; basilisk_metricfunc metricfunc; + if ( (n= pending->numresults) < sizeof(pending->results)/sizeof(*pending->results) ) + { + pending->numresults++; + if ( (metricfunc= pending->metricfunc) == 0 ) + pending->metrics[n] = n + 1; + else if ( (pending->metrics[n]= (*metricfunc)(myinfo,pending,ptr->retstr)) != 0. ) + pending->childrendone++; + printf("%s.%u Add results[%d] <- metric %f\n",pending->CMD,pending->basilisktag,n,pending->metrics[n]); + pending->results[n] = ptr->retstr, ptr->retstr = 0; + /*if ( strcmp(ptr->CMD,"SEQ") == 0 ) + { + if ( (retjson= cJSON_Parse(ptr->retstr)) != 0 ) + { + gecko_seqresult(myinfo,ptr->retstr); + free_json(retjson); + } + } + else*/ + if ( strcmp(ptr->CMD,"RET") == 0 || strcmp(ptr->CMD,"GET") == 0 ) + { + printf("got return for tag.%d parent.%p\n",pending->basilisktag,pending->parent); + /*if ( (parent= pending->parent) != 0 ) + { + pending->parent = 0; + parent->childrendone++; + }*/ + if ( strcmp(ptr->CMD,"GET") == 0 ) + basilisk_geckoresult(myinfo,ptr->retstr); + } + } + } + + int32_t basilisk_issued_iteration(struct supernet_info *myinfo,struct basilisk_item *pending) + { + basilisk_metricfunc metricfunc; int32_t i,flag = 0; + //printf("pending.%u numresults.%d m %f func.%p\n",pending->basilisktag,pending->numresults,pending->metrics[0],pending->metricfunc); + if ( (metricfunc= pending->metricfunc) != 0 ) + { + for (i=0; inumresults; i++) + if ( pending->metrics[i] == 0. && pending->results[i] != 0 ) + { + if ( (pending->metrics[i]= (*metricfunc)(myinfo,pending,pending->results[i])) != 0 ) + pending->childrendone++; + // printf("iter.%d %p.[%d] poll metrics.%u metric %f\n",iter,pending,i,pending->basilisktag,pending->metrics[i]); + flag++; + } + } + /*basilisk_iscomplete(myinfo,pending); + if ( OS_milliseconds() > pending->expiration ) + { + if ( pending->finished == 0 ) + { + if ( (parent= pending->parent) != 0 ) + { + pending->parent = 0; + parent->childrendone++; + } + pending->finished = (uint32_t)time(NULL); + if ( pending->retstr == 0 ) + pending->retstr = clonestr("{\"error\":\"basilisk timeout\"}"); + fprintf(stderr,"timeout.%s call metrics.%u lag %f - %f\n",pending->CMD,pending->basilisktag,OS_milliseconds(),pending->expiration); + for (i=0; inumresults; i++) + if ( (metricfunc= pending->metricfunc) != 0 && pending->metrics[i] == 0. ) + pending->metrics[i] = (*metricfunc)(myinfo,pending,pending->results[i]); + flag++; + } + }*/ + //fprintf(stderr,"c"); + if ( pending->finished != 0 && time(NULL) > pending->finished+60 ) + { + if ( pending->dependents == 0 || pending->childrendone >= pending->numchildren ) + { + HASH_DELETE(hh,myinfo->basilisks.issued,pending); + if ( pending->dependents != 0 ) + free(pending->dependents); + //fprintf(stderr,"HASH_DELETE free ptr.%u refcount.%d\n",pending->basilisktag,pending->refcount); + for (i=0; inumresults; i++) + if ( pending->results[i] != 0 ) + free(pending->results[i]), pending->results[i] = 0; + //if ( pending->vals != 0 ) + // free_json(pending->vals), pending->vals = 0; + free(pending); + flag++; + } + } + return(flag); + } + + + int32_t basilisk_besti(struct basilisk_item *ptr) + { + int32_t i,besti = -1; double metric,bestmetric=-1.; + for (i=0; inumresults; i++) + { + if ( (metric= ptr->metrics[i]) > 0. ) + { + if ( (ptr->metricdir < 0 && (bestmetric < 0. || metric < bestmetric)) || (ptr->metricdir > 0 && (bestmetric < 0. || metric > bestmetric)) || (ptr->metricdir == 0 && bestmetric < 0.) ) + { + bestmetric = metric; + besti = i; + } + } + } + if ( besti >= 0 ) + { + for (ptr->numexact=i=0; inumresults; i++) + if ( fabs(ptr->metrics[i] - bestmetric) < SMALLVAL ) + ptr->numexact++; + } + return(besti); + } + + char *basilisk_iscomplete(struct supernet_info *myinfo,struct basilisk_item *ptr) + { + int32_t i,numvalid,besti=-1; char *errstr = 0,*retstr = 0; + if ( ptr->childrendone < ptr->numchildren ) + return(0); + if ( ptr->retstr != 0 || ptr->finished != 0 ) + return(ptr->retstr); + if ( (numvalid= ptr->numresults) >= ptr->numrequired ) + { + for (i=numvalid=0; inumresults; i++) + { + if ( ptr->metrics[i] != 0. ) + numvalid++; + } + } + if ( numvalid < ptr->numrequired ) + { + //printf("%u: numvalid.%d < required.%d m %f\n",ptr->basilisktag,numvalid,ptr->numrequired,ptr->metrics[0]); + return(0); + } + if ( ptr->uniqueflag == 0 && ptr->numexact != ptr->numresults && ptr->numexact < (ptr->numresults >> 1) ) + besti = -1, errstr = "[{\"error\":\"basilisk non-consensus results\"}]"; + else besti = basilisk_besti(ptr), errstr = "[{\"error\":\"basilisk no valid results\"}]"; + //printf("%u complete besti.%d\n",ptr->basilisktag,besti); + retstr = basilisk_finish(myinfo,ptr,besti,errstr); + //printf("%u besti.%d numexact.%d numresults.%d -> (%s)\n",ptr->basilisktag,besti,ptr->numexact,ptr->numresults,retstr); + return(retstr); + } + + char *basilisk_finish(struct supernet_info *myinfo,struct basilisk_item *ptr,int32_t besti,char *errstr) + { + char *str,*retstr = 0; int32_t i; struct basilisk_item *parent; cJSON *retarray,*item; + if ( ptr->retstr != 0 ) + return(ptr->retstr); + /*if ( besti >= 0 && besti < ptr->numresults ) + { + retstr = ptr->results[besti]; + ptr->results[besti] = 0; + } else printf("besti.%d vs numresults.%d retstr.%p\n",besti,ptr->numresults,retstr); + */ + if ( ptr->numresults > 0 ) + { + retarray = cJSON_CreateArray(); + for (i=0; inumresults; i++) + if ( (str= ptr->results[i]) != 0 ) + { + ptr->results[i] = 0; + if ( (item= cJSON_Parse(str)) != 0 ) + { + if ( jobj(item,"myip") == 0 ) + jaddstr(item,"myip",myinfo->ipaddr); + jaddi(retarray,item); + } else printf("couldnt parse.(%s)\n",str); + free(str); + } + retstr = jprint(retarray,1); + } + if ( retstr == 0 ) + retstr = clonestr(errstr); + ptr->retstr = retstr; + ptr->finished = (uint32_t)time(NULL); + if ( (parent= ptr->parent) != 0 ) + { + ptr->parent = 0; + parent->childrendone++; + } + return(retstr); + } + + char *basilisk_check(int32_t *timeoutmillisp,uint32_t *basilisktagp,char *symbol,cJSON *vals) + { + if ( symbol != 0 && symbol[0] != 0 && vals != 0 ) + { + if ( *basilisktagp == 0 ) + *basilisktagp = rand(); + if ( (*timeoutmillisp= jint(vals,"timeout")) < 0 ) + *timeoutmillisp = BASILISK_TIMEOUT; + return(0); + } else return(clonestr("{\"error\":\"missing activecoin or vals\"}")); + } + + char *basilisk_standardcmd(struct supernet_info *myinfo,char *CMD,char *activecoin,char *remoteaddr,uint32_t basilisktag,cJSON *vals,basilisk_func func,basilisk_metricfunc metric) + { + char *retstr; struct basilisk_item *ptr,Lptr; int32_t timeoutmillis; struct iguana_info *coin; + if ( (retstr= basilisk_check(&timeoutmillis,&basilisktag,activecoin,vals)) == 0 ) + { + if ( (coin= iguana_coinfind(activecoin)) != 0 ) + { + if ( (ptr= basilisk_issuecmd(&Lptr,func,metric,myinfo,remoteaddr,basilisktag,activecoin,timeoutmillis,vals)) != 0 ) + { + return(basilisk_waitresponse(myinfo,CMD,coin->symbol,remoteaddr,&Lptr,vals,ptr)); + } + else return(clonestr("{\"error\":\"null return from basilisk_issuecmd\"}")); + } else return(clonestr("{\"error\":\"couldnt get coin\"}")); + } else return(retstr); + } + + char *_basilisk_value(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) + { + struct iguana_info *coin; char *symbol; + if ( (symbol= jstr(valsobj,"coin")) != 0 || (symbol= jstr(valsobj,"symbol")) != 0 ) + { + if ( (coin= iguana_coinfind(symbol)) != 0 ) + return(basilisk_standardcmd(myinfo,"VAL",symbol,remoteaddr,basilisktag,valsobj,coin->basilisk_value,coin->basilisk_valuemetric)); + } + return(clonestr("{\"error\":\"couldnt get coin\"}")); + } + + char *_basilisk_balances(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) + { + struct iguana_info *coin; char *symbol; + if ( (symbol= jstr(valsobj,"coin")) != 0 || (symbol= jstr(valsobj,"symbol")) != 0 ) + { + if ( (coin= iguana_coinfind(symbol)) != 0 ) + return(basilisk_standardcmd(myinfo,"BAL",symbol,remoteaddr,basilisktag,valsobj,coin->basilisk_balances,coin->basilisk_balancesmetric)); + } + return(clonestr("{\"error\":\"couldnt get coin\"}")); + } + + char *_basilisk_rawtx(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) + { + char *retstr,strbuf[4096],*symbol,*str = 0; struct iguana_info *coin; + if ( (symbol= jstr(valsobj,"coin")) != 0 || (symbol= jstr(valsobj,"symbol")) != 0 ) + { + if ( (coin= iguana_coinfind(symbol)) != 0 ) + { + printf("remote rawtx.(%s)\n",jprint(valsobj,0)); + basilisk_addhexstr(&str,valsobj,strbuf,sizeof(strbuf),data,datalen); + retstr = basilisk_rawtx(myinfo,coin,0,remoteaddr,basilisktag,valsobj,coin->symbol); + if ( str != 0 ) + free(str); + return(retstr); + } + } + return(clonestr("{\"error\":\"couldnt get coin\"}")); + } + + char *basilisk_waitresponse(struct supernet_info *myinfo,char *CMD,char *symbol,char *remoteaddr,struct basilisk_item *Lptr,cJSON *vals,struct basilisk_item *ptr) + { + char *retstr = 0; + if ( ptr == Lptr ) + { + //if ( (retstr= Lptr->retstr) == 0 ) + // retstr = clonestr("{\"result\":\"null return from local basilisk_issuecmd\"}"); + //ptr = basilisk_itemcreate(myinfo,CMD,symbol,Lptr->basilisktag,Lptr->numrequired,vals,OS_milliseconds() - Lptr->expiration,0);//Lptr->metricfunc); + //queue_enqueue("submitQ",&myinfo->basilisks.submitQ,&ptr->DL,0); + retstr = Lptr->retstr; + } + else + { + //queue_enqueue("submitQ",&myinfo->basilisks.submitQ,&ptr->DL,0); + while ( OS_milliseconds() < ptr->expiration ) + { + //if ( (retstr= basilisk_iscomplete(ptr)) != 0 ) + if ( ptr->numresults >= ptr->numrequired || (retstr= ptr->retstr) != 0 ) + break; + usleep(50000); + } + if ( retstr == 0 ) + { + //ptr->finished = (uint32_t)time(NULL); + //retstr = clonestr("[{\"error\":\"basilisk wait timeout\"}]"); + free(ptr); + return(0); + } + } + basilisk_sendback(myinfo,CMD,symbol,remoteaddr,ptr->basilisktag,retstr); + return(retstr); + } + struct basilisk_item *basilisk_issuecmd(struct basilisk_item *Lptr,basilisk_func func,basilisk_metricfunc metricfunc,struct supernet_info *myinfo,char *remoteaddr,uint32_t basilisktag,char *symbol,int32_t timeoutmillis,cJSON *vals) + { + struct iguana_info *coin; struct basilisk_item *ptr; + memset(Lptr,0,sizeof(*Lptr)); + if ( (coin= iguana_coinfind(symbol)) != 0 ) + { + if ( func != 0 ) + { + if ( (ptr= (*func)(Lptr,myinfo,coin,remoteaddr,basilisktag,timeoutmillis,vals)) != 0 ) + { + strcpy(ptr->symbol,symbol); + ptr->basilisktag = basilisktag; + ptr->expiration = OS_milliseconds() + timeoutmillis; + return(ptr); + } else Lptr->retstr = clonestr("{\"error\":\"error issuing basilisk command\"}"); + } else Lptr->retstr = clonestr("{\"error\":\"null basilisk function\"}"); + } else Lptr->retstr = clonestr("{\"error\":\"error missing coin\"}"); + return(Lptr); + } + /*int32_t gecko_chainvals(struct supernet_info *myinfo,char *CMD,cJSON *valsobj) + { + struct iguana_info *virt; struct gecko_chain *chain; bits256 hash,prevhash; struct iguana_block *block; char chainname[GECKO_MAXNAMELEN]; + if ( strcmp(CMD,"SET") == 0 || strcmp(CMD,"GET") == 0 ) + { + if ( (chain= gecko_chain(myinfo,chainname,valsobj)) == 0 || (virt= chain->info) == 0 ) + clonestr("{\"error\":\"cant find gecko chain\"}"); + if ( strcmp(CMD,"SET") == 0 ) + { + hash = GENESIS_PUBKEY; + if ( jobj(valsobj,"prev") != 0 ) + { + prevhash = jbits256(valsobj,"prev"); + if ( (block= iguana_blockfind("basilisk",virt,prevhash)) == 0 ) + { + char str[65]; printf("warning couldnt find %s in %s\n",bits256_str(str,prevhash),chainname); + prevhash = virt->blocks.hwmchain.RO.hash2; + } + } else prevhash = virt->blocks.hwmchain.RO.hash2; + hash = prevhash; + if ( jobj(valsobj,"prev") != 0 ) + jdelete(valsobj,"prev"); + } + return(0); + } + return(-1); + } + + cJSON *gecko_genesisargs(char *symbol,char *chainname,char *chain,char *keystr,char *genesishash,char *genesisblock,char *magicstr,uint16_t port,uint16_t blocktime,char *nbitstr,char *pubval,char *p2shval,char *wifval,uint32_t isPoS) + { + int32_t timespan,targetspacing; cJSON *argvals = cJSON_CreateObject(); + if ( genesishash != 0 && genesishash[0] != 0 ) + jaddstr(argvals,"genesishash",genesishash); + if ( genesisblock != 0 && genesisblock[0] != 0 ) + jaddstr(argvals,"genesisblock",genesisblock); + jaddstr(argvals,"netmagic",magicstr); + jaddstr(argvals,"symbol",symbol); + jaddstr(argvals,"name",chainname); + if ( pubval == 0 || is_hexstr(pubval,0) != 2 ) + pubval = "00"; + jaddstr(argvals,"pubval",pubval); + if ( p2shval == 0 || is_hexstr(p2shval,0) != 2 ) + p2shval = "05"; + jaddstr(argvals,"p2shval",p2shval); + if ( wifval == 0 || is_hexstr(wifval,0) != 2 ) + wifval = "80"; + jaddstr(argvals,"wifval",wifval); + if ( nbitstr == 0 || nbitstr[0] == 0 ) + nbitstr = GECKO_DEFAULTDIFFSTR; + jaddstr(argvals,"nBits",nbitstr); + jaddstr(argvals,"chain",chain); + if ( keystr != 0 ) + jaddstr(argvals,"key",keystr); + jaddnum(argvals,"isPoS",isPoS); + //printf("argvals isPoS.%d\n",isPoS); + if ( port == 0 ) + { + jaddstr(argvals,"geckochain",chainname); + jaddnum(argvals,"services",128); + } + else + { + jaddnum(argvals,"services",129); + jaddnum(argvals,"portp2p",port); + } + if ( blocktime == 0 ) + blocktime = 1; + jaddnum(argvals,"blocktime",blocktime); + if ( blocktime != 0 && 0 ) + { + if ( blocktime == 0xffff ) + targetspacing = 24 * 60 * 60; // one day + else targetspacing = blocktime; // one minute + jaddnum(argvals,"targetspacing",targetspacing); + if ( (timespan= sqrt(604800 / targetspacing)) < 7 ) + timespan = 7; + jaddnum(argvals,"targettimespan",targetspacing * timespan); + } + return(argvals); + } + + cJSON *gecko_genesisjson(struct supernet_info *myinfo,struct iguana_info *btcd,int32_t isPoS,char *symbol,char *chainname,cJSON *valsobj,char *magicstr,uint16_t blocktime) + { + char str2[64],hashstr[65],argbuf[1024],*pubstr,*p2shstr,*wifvalstr,*nbitstr,*blockstr; uint8_t buf[4]; int32_t i; uint32_t nBits; struct iguana_block genesis; + if ( (nbitstr= jstr(valsobj,"nBits")) == 0 ) + { + nBits = GECKO_DEFAULTDIFF; + nbitstr = GECKO_DEFAULTDIFFSTR; + } + else + { + for (i=0; i<4; i++) + decode_hex(&buf[3-i],1,&nbitstr[i*2]); + memcpy(&nBits,buf,sizeof(nBits)); + } + if ( (blocktime= juint(valsobj,"blocktime")) == 0 ) + blocktime = 1; + if ( (pubstr= jstr(valsobj,"pubval")) == 0 ) + pubstr = "00"; + if ( (p2shstr= jstr(valsobj,"p2shval")) == 0 ) + p2shstr = "05"; + if ( (wifvalstr= jstr(valsobj,"wifval")) == 0 ) + wifvalstr = "80"; + printf("json netmagic.%s\n",magicstr); + memset(&genesis,0,sizeof(genesis)); + genesis.RO.version = GECKO_DEFAULTVERSION; + genesis.RO.bits = nBits; + if ( (blockstr= gecko_createblock(myinfo,blocktime,0,btcd,isPoS,&genesis,symbol,0,0,10000,0,0)) != 0 ) + { + bits256_str(hashstr,genesis.RO.hash2); + sprintf(argbuf,"{\"isPoS\":%d,\"name\":\"%s\",\"symbol\":\"%s\",\"netmagic\":\"%s\",\"port\":%u,\"blocktime\":%u,\"pubval\":\"%s\",\"p2shval\":\"%s\",\"wifval\":\"%s\",\"isPoS\":%u,\"unitval\":\"%02x\",\"genesishash\":\"%s\",\"genesis\":{\"version\":1,\"timestamp\":%u,\"nBits\":\"%s\",\"nonce\":%d,\"merkle_root\":\"%s\"},\"genesisblock\":\"%s\"}",isPoS,chainname,symbol,magicstr,juint(valsobj,"port"),blocktime,pubstr,p2shstr,wifvalstr,juint(valsobj,"isPoS"),(nBits >> 24) & 0xff,hashstr,genesis.RO.timestamp,nbitstr,genesis.RO.nonce,bits256_str(str2,genesis.RO.merkle_root),blockstr); + free(blockstr); + printf("argbuf.(%s) hash.%s\n",argbuf,hashstr); + return(cJSON_Parse(argbuf)); + } else return(cJSON_Parse("{\"error\":\"couldnt create block\"}")); + } + + cJSON *gecko_genesisissue(char *symbol,char *chainname,char *chainstr,cJSON *valsobj) + { + printf("issue blocktime.%d\n",juint(valsobj,"blocktime")); + return(gecko_genesisargs(symbol,chainname,chainstr,jstr(valsobj,"key"),jstr(valsobj,"genesishash"),jstr(valsobj,"genesisblock"),jstr(valsobj,"netmagic"),juint(valsobj,"port"),juint(valsobj,"blocktime"),jstr(valsobj,"nBits"),jstr(valsobj,"pubval"),jstr(valsobj,"p2shval"),jstr(valsobj,"wifval"),juint(valsobj,"isPoS"))); + }*/ + /*char *basilisk_respond_newgeckochain(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 prevhash,int32_t from_basilisk) + { + struct iguana_info *virt,*btcd; struct gecko_chain *chain; char fname[512],*symbol,*retstr,*chainstr,chainname[GECKO_MAXNAMELEN],*genesises; cJSON *chainjson,*retjson,*genesisjson; long filesize; FILE *fp; + if ( (chain= gecko_chain(myinfo,chainname,valsobj)) != 0 && (virt= chain->info) != 0 ) + { + //printf("%s already exists\n",chainname); + return(clonestr("{\"error\":\"cant create duplicate geckochain\"}")); + } + if ( (btcd= iguana_coinfind("BTCD")) != 0 && (symbol= jstr(valsobj,"symbol")) != 0 && (chainstr= jstr(valsobj,"chain")) != 0 ) + { + if ( (virt= basilisk_geckochain(myinfo,symbol,chainname,valsobj)) != 0 ) + { + chain->info = virt; + if ( (retjson= gecko_genesisissue(symbol,chainname,chainstr,valsobj)) != 0 ) + { + jaddstr(retjson,"result","success"); + retstr = jprint(retjson,0); + sprintf(fname,"genesis/%s",symbol); + genesisjson = 0; + filesize = 0; + if ( (fp= fopen(fname,"wb")) != 0 ) + { + if ( fwrite(retstr,1,strlen(retstr),fp) == strlen(retstr) ) + { + if ( (genesises= OS_filestr(&filesize,"genesis/list")) != 0 ) + { + genesisjson = cJSON_Parse(genesises); + free(genesises); + } else genesisjson = cJSON_CreateArray(); + chainjson = cJSON_CreateObject(); + jaddstr(chainjson,"chain",chainname); + jaddstr(chainjson,"symbol",symbol); + jaddstr(chainjson,"agent","basilisk"); + jaddstr(chainjson,"method","newgeckochain"); + jadd(chainjson,"vals",retjson); + jaddi(genesisjson,chainjson); + } + fclose(fp); + } + if ( genesisjson != 0 ) + { + genesises = jprint(genesisjson,1); + if ( strlen(genesises) > filesize ) + { + if ( (fp= fopen("genesis/list","wb")) != 0 ) + { + fwrite(genesises,1,strlen(genesises),fp); + fclose(fp); + } + } + } else free_json(retjson); + return(retstr); + } else return(clonestr("{\"error\":\"couldnt create gecko genesis\"}")); + } + } + return(clonestr("{\"error\":-22}")); + } + + int32_t gecko_genesises(struct supernet_info *myinfo,cJSON *array) + { + char *chainstr,chainname[GECKO_MAXNAMELEN],*symbol; int32_t i,n,num=0; cJSON *item,*valsobj; struct iguana_info *btcd,*virt; struct gecko_chain *chain; + if ( (btcd= iguana_coinfind("BTCD")) == 0 ) + return(0); + if ( array != 0 && (n= cJSON_GetArraySize(array)) != 0 ) + { + for (i=0; iinfo) != 0 ) + { + //printf("%s %s already exists\n",chainname,symbol); + continue; + } + if ( (virt= basilisk_geckochain(myinfo,symbol,chainname,valsobj)) != 0 ) + { + myinfo->genesisresults++; + chain->info = virt; + num++; + } + } + } + } + return(num); + } + + char *basilisk_respond_geckogenesis(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 txid,int32_t from_basilisk) + { + long filesize; + return(OS_filestr(&filesize,"genesis/list")); + }*/ + /*HASH_ARRAY_STRING(basilisk,sequence,hash,vals,hexstr) + { + return(basilisk_standardservice("SEQ",myinfo,hash,vals,hexstr,1)); + } + + HASH_ARRAY_STRING(basilisk,newgeckochain,hash,vals,hexstr) + { + char chainname[GECKO_MAXNAMELEN],magicstr[9],*retstr=0,*symbol,*chainstr; struct iguana_info *btcd; cJSON *argjson,*argvals,*retjson=0; int32_t i,isPoS; uint32_t magic; struct gecko_chain *chain; + if ( (btcd= iguana_coinfind("BTCD")) != 0 && (symbol= jstr(vals,"symbol")) != 0 && (chainstr= jstr(vals,"chain")) != 0 ) + { + if ( iguana_coinfind(symbol) == 0 && (chain= gecko_chain(myinfo,chainname,vals)) != 0 && chain->info != 0 ) + { + printf("%s already exists\n",chainname); + return(clonestr("{\"error\":\"cant create duplicate geckochain\"}")); + } + if ( jobj(vals,"netmagic") == 0 ) + { + OS_randombytes((void *)&magic,sizeof(magic)); + for (i=0; iFULLNODE != 0 || btcd->VALIDATENODE != 0 ) + { + basilisk_wait(myinfo,0); + retstr = basilisk_respond_newgeckochain(myinfo,"NEW",0,0,0,argvals,0,0,GENESIS_PUBKEY,0); + } + if ( retstr == 0 ) + retstr = basilisk_standardservice("NEW",myinfo,GENESIS_PUBKEY,argvals,0,1); + free_json(argvals); + if ( (argvals= cJSON_Parse(retstr)) != 0 ) + { + if ( jobj(argvals,"result") != 0 && strcmp(jstr(argvals,"result"),"success") == 0 ) + { + if ( basilisk_geckochain(myinfo,symbol,chainname,argvals) != 0 ) + jaddstr(argvals,"status","active"); + } else jaddstr(argvals,"error","couldnt initialize geckochain"); + free(retstr); + return(jprint(argvals,1)); + } + if ( retjson != 0 ) + free_json(retjson); + free_json(argvals); + return(retstr); + } else return(clonestr("{\"error\":\"couldnt create genesis_block\"}")); + } + return(clonestr("{\"error\":\"need symbol and chain and BTCD to create new gecko chain\"}")); + }*/ + + /*HASH_ARRAY_STRING(basilisk,geckogenesis,hash,vals,hexstr) + { + long filesize; int32_t i,j,n,m; struct iguana_info *btcd; char *ref,*symbol,*retstr=0; cJSON *item,*array = 0,*arrayB = 0; FILE *fp; + if ( (btcd= iguana_coinfind("BTCD")) != 0 ) + { + if ( (retstr= basilisk_standardservice("GEN",myinfo,hash,vals,hexstr,1)) != 0 ) + { + arrayB = cJSON_Parse(retstr); + free(retstr); + } + if ( btcd->FULLNODE != 0 || btcd->VALIDATENODE != 0 ) + { + if ( (retstr= OS_filestr(&filesize,"genesis/list")) != 0 ) + { + array = cJSON_Parse(retstr); + free(retstr); + } + if ( array == 0 ) + array = arrayB; + else if ( arrayB != 0 ) + { + if ( (n= cJSON_GetArraySize(array)) > 0 ) + { + if ( (m= cJSON_GetArraySize(arrayB)) > 0 ) + { + for (j=0; j> 1; + if ( siglen < sizeof(sig) ) + { + decode_hex(sig,siglen,sigstr); + vcalc_sha256(0,txhash2.bytes,data,datalen); + memset(pubkey33,0,33); + if ( bitcoin_recoververify(myinfo->ctx,"BTCD",sig,txhash2,pubkey33) == 0 ) + { + // compare with existing + init_hexbytes_noT(pubstr,pubkey33,33); + printf(" verified relay data siglen.%d pub33.%s\n",siglen,pubstr); + if ( (retstr= basilisk_addrelay_info(myinfo,pubkey33,(uint32_t)calc_ipbits(remoteaddr),hash)) != 0 ) + free(retstr); + n = (int32_t)(datalen / sizeof(uint32_t)); + for (i=len=0; irelaybits)]; cJSON *vals; bits256 hash; char *retstr,hexstr[sizeof(myinfo->relaybits)*2 + 1]; + //printf("skip sending relays\n"); + if ( 0 && myinfo != 0 ) + { + vals = cJSON_CreateObject(); + hash = myinfo->myaddr.persistent; + for (i=0; inumrelays; i++) + len += iguana_rwnum(1,&serialized[len],sizeof(uint32_t),&myinfo->relaybits[i]); + init_hexbytes_noT(hexstr,serialized,len); + //printf("send relays.(%s)\n",hexstr); + vcalc_sha256(0,txhash2.bytes,serialized,len); + if ( 0 && bits256_nonz(myinfo->persistent_priv) != 0 && (siglen= bitcoin_sign(myinfo->ctx,"BTCD",sig,txhash2,myinfo->persistent_priv,1)) > 0 ) + { + init_hexbytes_noT(strbuf,sig,siglen); + jaddstr(vals,"sig",strbuf); + } + if ( (retstr= basilisk_standardservice("RLY",myinfo,hash,vals,hexstr,0)) != 0 ) + free(retstr); + free_json(vals); + return(0); + } else return(-1); + } + + char *basilisk_respond_relays(struct supernet_info *myinfo,char *CMD,void *_addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) + { + uint32_t *ipbits = (uint32_t *)data; int32_t num,i,j,n = datalen >> 2; + for (i=num=0; inumrelays; j++) + if ( ipbits[i] == myinfo->relays[j].ipbits ) + break; + if ( j == myinfo->numrelays ) + { + num++; + printf("i.%d j.%d ensure new relay.(%s)\n",i,j,remoteaddr); + basilisk_ensurerelay(iguana_coinfind("BTCD"),ipbits[i]); + } + } + if ( num == 0 ) + return(clonestr("{\"result\":\"no new relays found\"}")); + else return(clonestr("{\"result\":\"relay added\"}")); + }*/ + + /*char *basilisk_checkrawtx(int32_t *timeoutmillisp,uint32_t *basilisktagp,char *symbol,cJSON *vals) + { + cJSON *addresses=0; char *changeaddr,*spendscriptstr; int32_t i,n; + *timeoutmillisp = -1; + changeaddr = jstr(vals,"changeaddr"); + spendscriptstr = jstr(vals,"spendscript"); + addresses = jarray(&n,vals,"addresses"); + if ( addresses == 0 || changeaddr == 0 || changeaddr[0] == 0 ) + return(clonestr("{\"error\":\"invalid addresses[] or changeaddr\"}")); + else + { + for (i=0; ibasilisk_rawtx,coin->basilisk_rawtxmetric,myinfo,remoteaddr,basilisktag,activecoin,timeoutmillis,vals)) != 0 ) + { + if ( (ptr->numrequired= juint(vals,"numrequired")) == 0 ) + ptr->numrequired = 1; + //ptr->uniqueflag = 1; + //ptr->metricdir = -1; + return(basilisk_waitresponse(myinfo,"RAW",coin->symbol,remoteaddr,&Lptr,vals,ptr)); + } else return(clonestr("{\"error\":\"error issuing basilisk rawtx\"}")); + } //else return(retstr);*/ + /*int32_t basilisk_request_pending(struct supernet_info *myinfo,struct basilisk_request *rp,uint32_t requestid) + { + int32_t i,j,n,alreadystarted = 0; struct basilisk_relay *relay; uint32_t quoteid; + portable_mutex_lock(&myinfo->DEX_reqmutex); + for (j=0; jnumrelays; j++) + { + relay = &myinfo->relays[j]; + if ( (n= relay->numrequests) > 0 ) + { + for (i=0; irequests[i].requestid == requestid && relay->requests[i].quoteid == quoteid ) + { + alreadystarted = 1; + break; + } + } + } + } + portable_mutex_unlock(&myinfo->DEX_reqmutex); + return(alreadystarted); + } + + void basilisk_request_check(struct supernet_info *myinfo,struct basilisk_request *rp) + { + double retvals[4],aveprice; struct basilisk_request R; struct iguana_info *src,*dest; char message[128]; uint32_t quoteid; + if ( (src= iguana_coinfind(rp->src)) != 0 && (dest= iguana_coinfind(rp->dest)) != 0 ) + { + if ( basilisk_request_pending(myinfo,&R,rp->requestid) == 0 ) + { + aveprice = instantdex_avehbla(myinfo,retvals,rp->src,rp->dest,dstr(rp->srcamount)); + quoteid = rp->requestid ^ myinfo->myaddr.persistent.uints[0]; + sprintf(message,"{\"price\":%.8f,\"requestid\":%u,\"quoteid\":%u}",aveprice,rp->requestid,quoteid); + if ( basilisk_request_enqueue(myinfo,rp->hash,rp->src,rp->srcamount*aveprice,myinfo->myaddr.persistent,rp->dest,rp->srcamount*aveprice,message,quoteid) != rp->requestid ) + printf("error creating quoteid\n"); + } + } + }*/ + + /*double basilisk_bitcoin_rawtxmetric_dependents(struct supernet_info *myinfo,struct iguana_info *coin,struct basilisk_item *ptr,struct bitcoin_rawtxdependents *dependents) + { + int32_t i,j,numaddrs,notfinished = 0; cJSON *childjson,*addresses; struct basilisk_item *child; double metric = 0.; char *childstr,*coinaddr; int64_t inputsum,value,txfee; + for (i=0; inumptrs; i++) + { + if ( (child= dependents->ptrs[i]) != 0 ) + { + if ( ptr->finished != 0 ) + { + //printf("parent finished\n"); + if ( child->finished == 0 ) + { + ptr->childrendone++; + child->finished = (uint32_t)time(NULL); + } + } + else if ( child->finished == 0 ) + notfinished++; + } + } + if ( notfinished != 0 ) + { + if ( ptr->finished != 0 ) + return(-13.); + else return(0.); + } + else if ( ptr->vals != 0 ) + { + if ( (txfee= j64bits(ptr->vals,"txfee")) == 0 ) + txfee = coin->chain->txfee; + if ( txfee == 0 ) + txfee = 10000; + addresses = jarray(&numaddrs,ptr->vals,"addresses"); + printf("got all inputs:\n"); + for (inputsum=i=0; inumptrs; i++) + { + if ( (child= dependents->ptrs[i]) != 0 && (childstr= child->retstr) != 0 ) + { + printf("childi.%d (%s)\n",i,childstr); + coinaddr = &dependents->coinaddrs[64*i]; + if ( (childjson= cJSON_Parse(childstr)) != 0 ) + { + if ( (value= j64bits(childjson,"satoshis")) != 0 ) + { + inputsum += value; + for (j=0; jretstr = 0; + } + } + if ( (inputsum - dependents->outputsum) != txfee ) + { + printf("inputsum %.8f - outputsum %.8f = %.8f != txfee %.8f\n",dstr(inputsum),dstr(dependents->outputsum),dstr(inputsum)-dstr(dependents->outputsum),dstr(txfee)); + return(-1001.); // error + } + //printf("dependents cost %lld\n",(long long)dependents->cost); + return(dstr(dependents->cost)); + } else return(-666.); // no vals?? + } + + double basilisk_bitcoin_rawtxmetric(struct supernet_info *myinfo,struct basilisk_item *ptr,char *resultstr) + { + cJSON *txobj,*vouts,*vin,*sobj,*addrs,*vins,*argvals,*resultsobj,*addresses; int64_t outputsum=0,amount=0,cost = 0; int32_t i,m,numaddrs,spendlen,n; struct iguana_msgtx msgtx; uint8_t extraspace[8192],script[IGUANA_MAXSCRIPTSIZE],serialized[16384],asmtype; struct vin_info V; char *scriptstr,*changeaddr,*coinaddr,*rawtx,*spendscriptstr; bits256 txid; struct iguana_info *coin; struct basilisk_item Lsubptr,*child; struct bitcoin_rawtxdependents *dependents=0; double metric; uint32_t locktime; + if ( (coin= iguana_coinfind(ptr->symbol)) != 0 ) + { + if ( (dependents= ptr->dependents) != 0 ) + { + if ( (metric= basilisk_bitcoin_rawtxmetric_dependents(myinfo,coin,ptr,dependents)) != 0. ) + { + for (i=0; inumptrs; i++) + if ( (child= dependents->ptrs[i]) != 0 ) + child->parent = 0; + } + return(metric); + } + if ( (resultsobj= cJSON_Parse(resultstr)) == 0 || (vins= jobj(resultsobj,"vins")) == 0 || (rawtx= jstr(resultsobj,"rawtx")) == 0 ) + { + if ( resultsobj != 0 ) + free_json(resultsobj); + printf("resultstr error.(%s)\n",resultstr); + return(-1.); // error + } + if ( (spendscriptstr= jstr(ptr->vals,"spendscript")) != 0 ) + { + spendlen = (int32_t)strlen(spendscriptstr) >> 1; + decode_hex(script,spendlen,spendscriptstr); + } + changeaddr = jstr(ptr->vals,"changeaddr"); + locktime = juint(ptr->vals,"locktime"); + amount = j64bits(ptr->vals,"satoshis"); + addresses = jarray(&numaddrs,ptr->vals,"addresses"); + if ( (txobj= bitcoin_hex2json(coin,&txid,&msgtx,rawtx,extraspace,sizeof(extraspace),serialized)) != 0 ) + { + //printf("GOT VINS.(%s) rawtx.(%s) out0 %.8f\n",jprint(vins,0),rawtx,dstr(msgtx.vouts[0].value)); + if ( juint(txobj,"locktime") != locktime ) + { + printf("locktime mismatch %u != %u\n",juint(txobj,"locktime"),locktime); + return(-2.); // error + } + else if ( jobj(txobj,"error") == 0 && cJSON_GetArraySize(vins) == msgtx.tx_in ) + { + dependents = calloc(1,sizeof(*dependents) + msgtx.tx_in*(sizeof(*dependents->results) + sizeof(*dependents->ptrs) + 64)); + dependents->results = (void *)&dependents->ptrs[msgtx.tx_in]; + dependents->coinaddrs = (void *)&dependents->results[msgtx.tx_in]; + dependents->numptrs = msgtx.tx_in; + ptr->dependents = dependents; + ptr->numchildren = dependents->numptrs; + for (i=0; i> 1; + decode_hex(V.spendscript,V.spendlen,scriptstr); + asmtype = _iguana_calcrmd160(coin,&V); + coinaddr = &dependents->coinaddrs[64 * i]; + //if ( asmtype == IGUANA_SCRIPT_76A988AC || asmtype == IGUANA_SCRIPT_AC || asmtype == IGUANA_SCRIPT_76AC || asmtype == IGUANA_SCRIPT_P2SH ) + bitcoin_address(coinaddr,coin->chain->pubtype,V.rmd160,20); + if ( (argvals= cJSON_CreateObject()) != 0 ) + { + jaddbits256(argvals,"txid",jbits256(vin,"txid")); + jaddnum(argvals,"timeout",ptr->expiration - OS_milliseconds()); + jaddnum(argvals,"vout",jint(vin,"vout")); + jaddstr(argvals,"address",coinaddr); + if ( (dependents->ptrs[i]= basilisk_bitcoinvalue(&Lsubptr,myinfo,coin,0,rand(),(ptr->expiration - OS_milliseconds()) * .777,argvals)) != 0 ) + { + if ( dependents->ptrs[i] == &Lsubptr ) + { + dependents->results[i] = Lsubptr.retstr; + dependents->ptrs[i] = 0; + } + else dependents->ptrs[i]->parent = ptr; + } + free_json(argvals); + } + } else printf("cant find spend info.(%s)\n",jprint(vin,0)); + } + if ( (vouts= jarray(&n,txobj,"vout")) != 0 && n == msgtx.tx_out ) + { + for (i=0; ispentsatoshis = msgtx.vouts[i].value; + continue; + } + else + { + if ( (sobj= jobj(jitem(vouts,i),"scriptPubKey")) != 0 && (addrs= jarray(&m,sobj,"addresses")) != 0 ) + { + if ( m == 1 && strcmp(jstri(addrs,0),changeaddr) == 0 ) + { + dependents->change = msgtx.vouts[i].value; + printf("verify it is normal spend for %s %.8f\n",changeaddr,dstr(msgtx.vouts[i].value)); + continue; + } + } + } + cost += msgtx.vouts[i].value; + //printf("boost cost %.8f\n",dstr(msgtx.vouts[i].value)); + } + } + } + free_json(txobj); + } + } + if ( dependents->spentsatoshis != amount ) + { + printf("spentsatoshis %.8f != expected %.8f, change %.8f\n",dstr(dependents->spentsatoshis),dstr(amount),dstr(dependents->change)); + return(-1000.); // error + } + if ( (dependents->outputsum= outputsum) <= 0 ) + { + printf("illegal outputsum %.8f\n",dstr(outputsum)); + return(-1001.); // error + } + if ( cost == 0 ) + cost = 1; + dependents->cost = cost; + return(0.); + }*/ + /*n = queue_size(&validateQ) / IGUANA_NUMHELPERS + 1; + printf("vQ is n.%d\n",n); + for (iter=0; iterbp) != 0 && (coin= ptr->coin) != 0 && coin->active != 0 ) + { + printf("helper.%d validate.[%d] %d vs %d\n",helperid,bp->hdrsi,coin->blocks.hwmchain.height/coin->chain->bundlesize,(coin->longestchain-1)/coin->chain->bundlesize); + if ( coin->blocks.hwmchain.height/coin->chain->bundlesize >= (coin->longestchain-1)/coin->chain->bundlesize ) + flag += iguana_bundlevalidate(coin,bp,0); + else + { + usleep(10000); + printf("requeue vQ.[%d]\n",bp->hdrsi); + iguana_validateQ(coin,bp); + } + } + else if ( coin->active != 0 ) + printf("helper validate missing param? %p %p\n",ptr->coin,ptr->bp); + myfree(ptr,ptr->allocsize); + flag++; + }*/ + + /*int32_t iguana_inv2poll(struct supernet_info *myinfo,struct iguana_info *coin) + { + struct exchange_info *exchange; int32_t i,n=0; struct iguana_peer *addr; char myipaddr[64]; + expand_ipbits(myipaddr,myinfo->myaddr.myipbits); + //printf("iguana_inv2poll exchange.%p %s maxpeers.%d\n",exchanges777_find("bitcoin"),coin->symbol,coin->MAXPEERS); + if ( coin != 0 && coin->peers != 0 && (exchange= exchanges777_find("bitcoin")) != 0 && strcmp(coin->symbol,"BTCD") == 0 ) + { + if ( time(NULL) > coin->lastinv2+10 ) + { + coin->lastinv2 = (uint32_t)time(NULL); + for (i=n=0; iMAXPEERS; i++) + { + addr = &coin->peers->active[i]; + if ( addr->supernet != 0 ) + { + //printf("iguana_inv2poll (%s) usock.%d dead.%u ready.%u ipbits.%u supernet.%d\n",addr->ipaddr,addr->usock,addr->dead,addr->ready,(uint32_t)addr->ipbits,addr->supernet); + if ( addr->usock >= 0 && addr->dead == 0 && addr->ready != 0 && addr->ipbits != 0 && strcmp(addr->ipaddr,myipaddr) != 0 ) + { + instantdex_inv2data(myinfo,coin,addr,exchange); + n++; + } + } + } + } + } + return(n); + }*/ + + continue; + for (i=bp->hdrsi; i>=0; i--) + { + if ( (bp= coin->bundles[i]) != 0 ) + { + ramchain = 0; + if ( iguana_pkhashfind(coin,&ramchain,&deposits,&lastunspentind,&p,rmd160,i,i) != 0 && (rdata= ramchain->H.data) != 0 ) + { + spent = 0; + deposits = 0; + unspentind = lastunspentind; + U = RAMCHAIN_PTR(rdata,Uoffset); + T = RAMCHAIN_PTR(rdata,Toffset); + while ( unspentind > 0 ) + { + if ( iguana_spentflag(myinfo,coin,&RTspend,&spentheight,ramchain,i,unspentind,lastheight,0,1<<31,U[unspentind].value) == 0 ) + deposits += U[unspentind].value; + else spent += U[unspentind].value; + unspentind = U[unspentind].prevunspentind; + } + weights[pkind] += (deposits - spent); + /*if ( (A2= ramchain->A2) != 0 && p.pkind > 0 && p.pkind < rdata->numpkinds && (U2= ramchain->Uextras) != 0 ) + { + T = RAMCHAIN_PTR(rdata,Toffset); + U = RAMCHAIN_PTR(rdata,Uoffset); + unspentind = A2[p.pkind].lastunspentind; + while ( unspentind > 0 ) + { + uheight = iguana_uheight(coin,ramchain->height,T,rdata->numtxids,&U[unspentind]); + if ( uheight < lastheight ) + spent += U[unspentind].value; + unspentind = U2[unspentind].prevunspentind; + } + weights[pkind] -= spent; + } else printf("PoS.[%d] rdata.%p or A2.%p error [%d] pkind.%d\n",pkind,rdata,A2,i,p.pkind);*/ + if ( weights[pkind] != 0 ) + printf("wt %.8f P.%d -> [%d] pkind.%d deposits %.8f spent %.8f\n",dstr(weights[pkind]),pkind,i,p.pkind,dstr(deposits),dstr(spent)); + } + } + /*if ( (retstr= iguana_orderbook("bitfinex","BTC","USD",10)) != 0 ) + { + if ( (aveprice= tradebots_update(&Fbtc_usd,"bitfinex","BTC","USD",retstr,1)) != 0 ) + { + Fbtc = _pairaved(avebtc,aveprice); + avebtc = _pairaved(Ebtc,Fbtc); + } + free(retstr); + } + if ( (retstr= iguana_orderbook("btce","BTC","USD",10)) != 0 ) + { + if ( (aveprice= tradebots_update(&Ebtc_usd,"btce","BTC","USD",retstr,1)) != 0 ) + { + Ebtc = _pairaved(avebtc,aveprice); + avebtc = _pairaved(Ebtc,Fbtc); + } + free(retstr); + } + if ( (retstr= iguana_orderbook("bittrex","SBD","BTC",10)) != 0 ) + { + if ( (aveprice= tradebots_update(&Bsbd_btc,"bittrex","SBD","BTC",retstr,10)) != 0 ) + { + Bsbd = _pairaved(avesbd,aveprice); + avesbd = _pairaved(Bsbd,Psbd); + } + free(retstr); + } + if ( (retstr= iguana_orderbook("poloniex","SBD","BTC",10)) != 0 ) + { + if ( (aveprice= tradebots_update(&Psbd_btc,"poloniex","SBD","BTC",retstr,10)) != 0 ) + { + Psbd = _pairaved(avesbd,aveprice); + avesbd = _pairaved(Bsbd,Psbd); + } + free(retstr); + } + if ( (retstr= iguana_orderbook("bittrex","STEEM","BTC",10)) != 0 ) + { + if ( (aveprice= tradebots_update(&Bsteem_btc,"bittrex","STEEM","BTC",retstr,100)) != 0 ) + { + Bsteem = _pairaved(avesteem,aveprice); + avesteem = _pairaved(Bsteem,Psteem); + } + free(retstr); + } + if ( (retstr= iguana_orderbook("poloniex","STEEM","BTC",10)) != 0 ) + { + //printf("retstr.(%s)\n",retstr); + if ( (aveprice= tradebots_update(&Psteem_btc,"poloniex","STEEM","BTC",retstr,100)) != 0 ) + { + Psteem = _pairaved(avesteem,aveprice); + avesteem = _pairaved(Bsteem,Psteem); + } + free(retstr); + }*/ + + uint32_t basilisk_msgid(struct supernet_info *myinfo,uint32_t channel,bits256 hash,uint8_t *data,int32_t datalen) + { + struct message_info *mp; bits256 msghash; uint32_t now; int32_t i,j,firstj,firsti = -1; + vcalc_sha256(0,msghash.bytes,data,datalen); + //msghash.bytes[0] = channel & 0xff; + //msghash.bytes[1] = (channel >> 8) & 0xff; + //msghash.bytes[2] = (channel >> 16) & 0xff; + now = (uint32_t)time(NULL); + for (i=0; imsgids)/sizeof(*myinfo->msgids); i++) + { + mp = &myinfo->msgids[i]; + if ( mp->msgcount != 0 ) + { + if ( bits256_cmp(hash,mp->refhash) == 0 ) + { + firstj = -1; + for (j=0; jmsgcount; j++) + { + if ( mp->timestamps[j] != 0 ) + { + if ( now > mp->timestamps[j]+30 ) + memset(mp,0,sizeof(*mp)); + else if ( bits256_cmp(msghash,mp->msghashes[j]) == 0 ) + return(j + 1); + } + if ( firstj < 0 && mp->timestamps[j] == 0 ) + firstj = j; + } + if ( firstj >= 0 ) + { + mp->msghashes[firstj] = msghash; + mp->timestamps[firstj] = (uint32_t)time(NULL); + return(firstj + 1); + } + if ( mp->msgcount < sizeof(mp->msghashes)/sizeof(*mp->msghashes) ) + { + j = mp->msgcount++; + mp->msghashes[j] = msghash; + mp->timestamps[j] = (uint32_t)time(NULL); + return(j + 1); + } else return(0); + } + } else if ( firsti < 0 ) + firsti = i; + } + if ( firsti >= 0 ) + { + mp = &myinfo->msgids[firsti]; + mp->msghashes[0] = msghash; + mp->timestamps[0] = (uint32_t)time(NULL); + mp->msgcount = 1; + mp->refhash = hash; + return(1); + } else return(0); + } #endif #endif diff --git a/pangea/Makefile b/deprecated/pangea/Makefile similarity index 100% rename from pangea/Makefile rename to deprecated/pangea/Makefile diff --git a/pangea/cards777.c b/deprecated/pangea/cards777.c similarity index 100% rename from pangea/cards777.c rename to deprecated/pangea/cards777.c diff --git a/pangea/hostnet777.c b/deprecated/pangea/hostnet777.c similarity index 100% rename from pangea/hostnet777.c rename to deprecated/pangea/hostnet777.c diff --git a/pangea/index.html b/deprecated/pangea/index.html similarity index 100% rename from pangea/index.html rename to deprecated/pangea/index.html diff --git a/pangea/m_clean b/deprecated/pangea/m_clean similarity index 100% rename from pangea/m_clean rename to deprecated/pangea/m_clean diff --git a/pangea/m_pnacl b/deprecated/pangea/m_pnacl similarity index 100% rename from pangea/m_pnacl rename to deprecated/pangea/m_pnacl diff --git a/pangea/main.c b/deprecated/pangea/main.c similarity index 100% rename from pangea/main.c rename to deprecated/pangea/main.c diff --git a/pangea/manifest.json b/deprecated/pangea/manifest.json similarity index 100% rename from pangea/manifest.json rename to deprecated/pangea/manifest.json diff --git a/pangea/pangea777.c b/deprecated/pangea/pangea777.c similarity index 100% rename from pangea/pangea777.c rename to deprecated/pangea/pangea777.c diff --git a/pangea/pangeafunds.c b/deprecated/pangea/pangeafunds.c similarity index 100% rename from pangea/pangeafunds.c rename to deprecated/pangea/pangeafunds.c diff --git a/pangea/poker.c b/deprecated/pangea/poker.c similarity index 100% rename from pangea/poker.c rename to deprecated/pangea/poker.c diff --git a/pangea/tourney777.c b/deprecated/pangea/tourney777.c similarity index 100% rename from pangea/tourney777.c rename to deprecated/pangea/tourney777.c diff --git a/peggy/Makefile b/deprecated/peggy/Makefile similarity index 100% rename from peggy/Makefile rename to deprecated/peggy/Makefile diff --git a/peggy/accts777.h b/deprecated/peggy/accts777.h similarity index 100% rename from peggy/accts777.h rename to deprecated/peggy/accts777.h diff --git a/peggy/index.html b/deprecated/peggy/index.html similarity index 100% rename from peggy/index.html rename to deprecated/peggy/index.html diff --git a/peggy/m_clean b/deprecated/peggy/m_clean similarity index 100% rename from peggy/m_clean rename to deprecated/peggy/m_clean diff --git a/peggy/m_pnacl b/deprecated/peggy/m_pnacl similarity index 100% rename from peggy/m_pnacl rename to deprecated/peggy/m_pnacl diff --git a/peggy/main.c b/deprecated/peggy/main.c similarity index 100% rename from peggy/main.c rename to deprecated/peggy/main.c diff --git a/peggy/manifest.json b/deprecated/peggy/manifest.json similarity index 100% rename from peggy/manifest.json rename to deprecated/peggy/manifest.json diff --git a/peggy/opreturn777.h b/deprecated/peggy/opreturn777.h similarity index 100% rename from peggy/opreturn777.h rename to deprecated/peggy/opreturn777.h diff --git a/peggy/peggy777.c b/deprecated/peggy/peggy777.c similarity index 100% rename from peggy/peggy777.c rename to deprecated/peggy/peggy777.c diff --git a/peggy/peggytx.h b/deprecated/peggy/peggytx.h similarity index 100% rename from peggy/peggytx.h rename to deprecated/peggy/peggytx.h diff --git a/peggy/serdes777.h b/deprecated/peggy/serdes777.h similarity index 100% rename from peggy/serdes777.h rename to deprecated/peggy/serdes777.h diff --git a/peggy/txind777.h b/deprecated/peggy/txind777.h similarity index 100% rename from peggy/txind777.h rename to deprecated/peggy/txind777.h diff --git a/prices/Makefile b/deprecated/prices/Makefile similarity index 100% rename from prices/Makefile rename to deprecated/prices/Makefile diff --git a/prices/index.html b/deprecated/prices/index.html similarity index 100% rename from prices/index.html rename to deprecated/prices/index.html diff --git a/prices/m_clean b/deprecated/prices/m_clean similarity index 100% rename from prices/m_clean rename to deprecated/prices/m_clean diff --git a/prices/m_pnacl b/deprecated/prices/m_pnacl similarity index 100% rename from prices/m_pnacl rename to deprecated/prices/m_pnacl diff --git a/prices/main.c b/deprecated/prices/main.c similarity index 100% rename from prices/main.c rename to deprecated/prices/main.c diff --git a/prices/manifest.json b/deprecated/prices/manifest.json similarity index 100% rename from prices/manifest.json rename to deprecated/prices/manifest.json diff --git a/prices/prices777.c b/deprecated/prices/prices777.c similarity index 100% rename from prices/prices777.c rename to deprecated/prices/prices777.c diff --git a/prices/quotes777.c b/deprecated/prices/quotes777.c similarity index 100% rename from prices/quotes777.c rename to deprecated/prices/quotes777.c diff --git a/tradebots/Makefile b/deprecated/tradebots/Makefile similarity index 100% rename from tradebots/Makefile rename to deprecated/tradebots/Makefile diff --git a/tradebots/index.html b/deprecated/tradebots/index.html similarity index 100% rename from tradebots/index.html rename to deprecated/tradebots/index.html diff --git a/tradebots/m_clean b/deprecated/tradebots/m_clean similarity index 100% rename from tradebots/m_clean rename to deprecated/tradebots/m_clean diff --git a/tradebots/m_pnacl b/deprecated/tradebots/m_pnacl similarity index 100% rename from tradebots/m_pnacl rename to deprecated/tradebots/m_pnacl diff --git a/deprecated/tradebots/main.c b/deprecated/tradebots/main.c new file mode 100755 index 000000000..a45455fd7 --- /dev/null +++ b/deprecated/tradebots/main.c @@ -0,0 +1,36 @@ +/****************************************************************************** + * Copyright © 2014-2015 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#define CHROMEAPP_NAME tradebots +#define CHROMEAPP_STR "tradebots" +#define CHROMEAPP_CONF "tradebots.conf" +#define CHROMEAPP_MAIN tradebots_main +#define CHROMEAPP_JSON tradebots_JSON +#define CHROMEAPP_HANDLER Handler_tradebots + +#include "../pnacl_main.h" + +// ALL globals must be here! + +void tradebots_main(void *arg) +{ + while ( 1 ) + sleep(777); +} + +char *tradebots_JSON(char *jsonstr) +{ + return(clonestr("{\"error\":\"tradebots is just a stub for now\"}")); +} \ No newline at end of file diff --git a/tradebots/manifest.json b/deprecated/tradebots/manifest.json similarity index 100% rename from tradebots/manifest.json rename to deprecated/tradebots/manifest.json diff --git a/tradebots/tradebots.h b/deprecated/tradebots/tradebots.h similarity index 100% rename from tradebots/tradebots.h rename to deprecated/tradebots/tradebots.h diff --git a/widget/ReadMe.MD b/deprecated/widget/ReadMe.MD similarity index 100% rename from widget/ReadMe.MD rename to deprecated/widget/ReadMe.MD diff --git a/widget/index.html b/deprecated/widget/index.html similarity index 100% rename from widget/index.html rename to deprecated/widget/index.html diff --git a/widget/pasted-widget.html b/deprecated/widget/pasted-widget.html similarity index 100% rename from widget/pasted-widget.html rename to deprecated/widget/pasted-widget.html diff --git a/widget/widguana-snippet.html b/deprecated/widget/widguana-snippet.html similarity index 100% rename from widget/widguana-snippet.html rename to deprecated/widget/widguana-snippet.html diff --git a/widget/widguana.js b/deprecated/widget/widguana.js similarity index 100% rename from widget/widguana.js rename to deprecated/widget/widguana.js diff --git a/gecko/gecko.c b/gecko/gecko.c new file mode 100755 index 000000000..496279174 --- /dev/null +++ b/gecko/gecko.c @@ -0,0 +1,335 @@ + +/****************************************************************************** + * Copyright © 2014-2016 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +// + code mempool and tx (payment and opreturn protocol) +// + debug remote <-> server and p2p network +// port DEX to use geckochain +// debug DEXchain +// debug network port mode +// debug virtual + network port mode + +// debug genesis balances +// debug reorgs, detect when network is forked + + +// code subchains synchronized with parent chain +// port pangea to use gecko with subchains +// debug pangea + +// debug delayed PoW, code BTCD -> BTC, delegate selection using virtual coin stakes +// code datachain +// + +#include "../iguana/iguana777.h" +#include "gecko_delayedPoW.c" +#include "gecko_headers.c" +#include "gecko_mempool.c" +#include "gecko_miner.c" +#include "gecko_blocks.c" + +void gecko_iteration(struct supernet_info *myinfo,struct iguana_info *btcd,struct iguana_info *virt,int32_t maxmillis) +{ + char mineraddr[64]; int32_t hwmhdrsi,longesthdrsi; struct iguana_bundle *bp; + hwmhdrsi = virt->blocks.hwmchain.height / virt->chain->bundlesize; + longesthdrsi = virt->longestchain / virt->chain->bundlesize; + if ( (bp= virt->bundles[hwmhdrsi]) != 0 ) + { + //iguana_RTspendvectors(myinfo,virt,bp); + //iguana_RTramchainalloc("RTbundle",virt,bp); + //iguana_update_balances(virt); + //iguana_realtime_update(myinfo,virt); + } + if ( 0 && hwmhdrsi <= longesthdrsi )//&& virt->blocks.hwmchain.height < virt->longestchain-1 ) + { + if ( time(NULL) > virt->hdrstime+3 ) + { + fprintf(stderr,"request %s headers\n",virt->symbol); + gecko_requesthdrs(myinfo,virt,hwmhdrsi); + //fprintf(stderr,"R"); + virt->hdrstime = (uint32_t)time(NULL); + } + } + if ( 0 && btcd->FULLNODE != 0 )//&& virt->blocks.hwmchain.height >= virt->longestchain-virt->chain->bundlesize ) + { + bitcoin_address(mineraddr,virt->chain->pubtype,myinfo->persistent_pubkey33,33); + //fprintf(stderr,"mine.%s %s\n",virt->symbol,mineraddr); + gecko_miner(myinfo,btcd,virt,maxmillis,myinfo->persistent_pubkey33); + } +} + +int32_t iguana_ROallocsize(struct iguana_info *virt) +{ + return(virt->chain->zcash != 0 ? sizeof(struct iguana_zblock) : sizeof(struct iguana_block)); +} + +bits256 calc_categoryhashes(bits256 *subhashp,char *category,char *subcategory) +{ + bits256 categoryhash; + if ( category == 0 || category[0] == 0 || strcmp(category,"broadcast") == 0 ) + categoryhash = GENESIS_PUBKEY; + else vcalc_sha256(0,categoryhash.bytes,(uint8_t *)category,(int32_t)strlen(category)); + if ( subhashp != 0 ) + { + if ( subcategory == 0 || subcategory[0] == 0 || strcmp(subcategory,"broadcast") == 0 ) + *subhashp = GENESIS_PUBKEY; + else vcalc_sha256(0,subhashp->bytes,(uint8_t *)subcategory,(int32_t)strlen(subcategory)); + } + return(categoryhash); +} + +struct gecko_chain *category_find(bits256 categoryhash,bits256 subhash) +{ + struct gecko_chain *cat=0,*sub = 0; bits256 hash; + HASH_FIND(hh,Categories,categoryhash.bytes,sizeof(categoryhash),cat); + if ( cat != 0 ) + { + if ( bits256_nonz(subhash) > 0 && memcmp(GENESIS_PUBKEY.bytes,subhash.bytes,sizeof(subhash)) != 0 ) + { + hash = subhash; + HASH_FIND(hh,cat->subchains,hash.bytes,sizeof(hash),sub); + if ( sub != 0 ) + return(sub); + } + return(cat); + } //else printf("category_find.(%s) not found\n",bits256_str(str,categoryhash));//, getchar(); + return(0); +} + +queue_t *category_Q(struct gecko_chain **catptrp,bits256 categoryhash,bits256 subhash) +{ + struct gecko_chain *cat; + *catptrp = 0; + if ( (cat= category_find(categoryhash,subhash)) != 0 ) + { + *catptrp = cat; + return(&cat->Q); + } + else return(0); +} + +void *category_subscribe(struct supernet_info *myinfo,bits256 chainhash,bits256 keyhash) +{ + struct gecko_chain *chain,*subchain; bits256 hash; + portable_mutex_lock(&myinfo->gecko_mutex); + HASH_FIND(hh,Categories,chainhash.bytes,sizeof(chainhash),chain); + if ( chain == 0 ) + { + chain = mycalloc('c',1,sizeof(*chain)); + chain->hash = hash = chainhash; + //char str[65]; printf("ADD cat.(%s)\n",bits256_str(str,chainhash)); + HASH_ADD(hh,Categories,hash,sizeof(hash),chain); + } + if ( bits256_nonz(keyhash) > 0 && memcmp(GENESIS_PUBKEY.bytes,keyhash.bytes,sizeof(keyhash)) != 0 && chain != 0 ) + { + HASH_FIND(hh,chain->subchains,keyhash.bytes,sizeof(keyhash),subchain); + if ( subchain == 0 ) + { + subchain = mycalloc('c',1,sizeof(*subchain)); + subchain->hash = hash = keyhash; + //char str[65],str2[65]; printf("subadd.(%s) -> (%s)\n",bits256_str(str,keyhash),bits256_str(str2,chainhash)); + HASH_ADD(hh,chain->subchains,hash,sizeof(hash),subchain); + } + } + portable_mutex_unlock(&myinfo->gecko_mutex); + return(chain); +} + +struct gecko_chain *gecko_chain(struct supernet_info *myinfo,char chainname[GECKO_MAXNAMELEN],cJSON *valsobj) +{ + char *chainstr,*keystr; bits256 keyhash,chainhash; struct gecko_chain *chain; + chainname[0] = 0; + if ( (chainstr= jstr(valsobj,"symbol")) == 0 ) + return(0); + if ( (keystr= jstr(valsobj,"name")) != 0 ) + vcalc_sha256(0,keyhash.bytes,(uint8_t *)keystr,(int32_t)strlen(keystr)); + else keyhash = GENESIS_PUBKEY; + vcalc_sha256(0,chainhash.bytes,(uint8_t *)chainstr,(int32_t)strlen(chainstr)); + if ( (chain= category_subscribe(myinfo,chainhash,keyhash)) == 0 ) + return(0); + safecopy(chainname,chainstr,30), chainname[30] = 0; + if ( keystr != 0 ) + { + strcat(chainname,"."); + safecopy(chainname+strlen(chainname),keystr,GECKO_MAXNAMELEN-1-strlen(chainname)); + } + return(chain); +} + +struct iguana_info *basilisk_geckochain(struct supernet_info *myinfo,char *symbol,char *chainname,cJSON *valsobj) +{ + int32_t n,datalen,hdrsize,len=0; struct iguana_info *virt=0; char *hexstr; uint8_t hexbuf[8192],*ptr,*serialized; struct iguana_peer *addr; struct iguana_txblock txdata; + portable_mutex_lock(&myinfo->gecko_mutex); + printf("basilisk_geckochain symbol.%s chain.%s (%s)\n",symbol,chainname,jprint(valsobj,0)); + if ( iguana_coinfind(symbol) == 0 && (hexstr= jstr(valsobj,"genesisblock")) != 0 && (virt= iguana_coinadd(symbol,chainname,valsobj,1)) != 0 ) + { + safecopy(virt->name,chainname,sizeof(virt->name)); + virt->chain = calloc(1,sizeof(*virt->chain)); + virt->enableCACHE = 1; + serialized = get_dataptr(BASILISK_HDROFFSET,&ptr,&datalen,hexbuf,sizeof(hexbuf),hexstr); + iguana_chaininit(virt->chain,1,valsobj); + virt->chain->isPoS = 1; + hdrsize = (virt->chain->zcash != 0) ? sizeof(struct iguana_msgblockhdr_zcash) : sizeof(struct iguana_msgblockhdr); + if ( gecko_blocknonce_verify(virt,serialized,hdrsize,virt->chain->nBits,0,0) > 0 ) + { + virt->chain->genesishash2 = iguana_calcblockhash(symbol,virt->chain->hashalgo,serialized,hdrsize); + memcpy(virt->chain->genesis_hashdata,virt->chain->genesishash2.bytes,sizeof(virt->chain->genesishash2)); + if ( ptr != 0 ) + free(ptr); + if ( virt->TXMEM.ptr == 0 ) + iguana_meminit(&virt->TXMEM,virt->name,0,IGUANA_MAXPACKETSIZE * 2,0); + virt->chain->genesis_hex = clonestr(hexstr); + virt->MAXPEERS = 0; + virt->FULLNODE = 1; + virt->virtualchain = 1; + addr = &virt->internaladdr; + strcpy(virt->VALIDATEDIR,GLOBAL_VALIDATEDIR); + printf("GLOBAL_VALIDATEDIR.(%s) (%s)\n",GLOBAL_VALIDATEDIR,virt->VALIDATEDIR); + iguana_callcoinstart(myinfo,virt); + iguana_initpeer(virt,addr,calc_ipbits("127.0.0.1")); + iguana_peerslotinit(virt,addr,IGUANA_MAXPEERS,addr->ipbits); + if ( addr->blockspace == 0 ) + addr->blockspace = calloc(1,IGUANA_MAXPACKETSIZE + 8192); + if ( addr->RAWMEM.ptr == 0 ) + iguana_meminit(&addr->RAWMEM,virt->symbol,0,IGUANA_MAXPACKETSIZE * 2,0); + if ( addr->TXDATA.ptr == 0 ) + iguana_meminit(&addr->TXDATA,"txdata",0,IGUANA_MAXPACKETSIZE * 2,0); + if ( addr->HASHMEM.ptr == 0 ) + iguana_meminit(&addr->HASHMEM,"HASHPTRS",0,256,0);//IGUANA_MAXPACKETSIZE*16,0); + iguana_bundlesload(myinfo,virt); + if ( virt->blocks.hwmchain.height == 0 ) + { + memset(&txdata,0,sizeof(txdata)); + if ( (n= iguana_gentxarray(virt,&virt->TXMEM,&txdata,&len,serialized,datalen) == datalen) || n == datalen-1 ) + { + txdata.zblock.height = 0; + txdata.zblock.RO.allocsize = iguana_ROallocsize(virt); + gecko_hwmset(myinfo,virt,&txdata,virt->TXMEM.ptr,serialized,datalen,txdata.numtxids,0); + } + } + virt->started = virt; + virt->active = (uint32_t)time(NULL); + iguana_datachain_scan(myinfo,virt,CRYPTO777_RMD160); + } else printf("error validating nonce\n"); + } + portable_mutex_unlock(&myinfo->gecko_mutex); + return(virt); +} + +char *basilisk_standardreturn(char *CMD,char *type,struct iguana_info *virt,uint8_t *serialized,int32_t datalen,bits256 hash) +{ + char space[16384],*allocstr = 0; cJSON *retjson = cJSON_CreateObject(); + if ( datalen > 0 && basilisk_addhexstr(&allocstr,retjson,space,sizeof(space),serialized,datalen) != 0 ) + { + jaddstr(retjson,"CMD",CMD); + jaddstr(retjson,"type",type); + jaddstr(retjson,"symbol",virt->symbol); + jaddnum(retjson,"hwm",virt->blocks.hwmchain.height); + jaddnum(retjson,"datalen",datalen); + jaddbits256(retjson,"chaintip",virt->blocks.hwmchain.RO.hash2); + jaddbits256(retjson,"hash",hash); + } else jaddstr(retjson,"error","no data to send"); + if ( allocstr != 0 ) + free(allocstr); + return(jprint(retjson,1)); +} + +char *basilisk_respond_geckoget(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash2,int32_t from_basilisk) +{ + int32_t (*getfunc)(struct supernet_info *myinfo,struct iguana_info *virt,uint8_t *serialized,int32_t maxsize,cJSON *valsobj,bits256 hash2); + uint8_t *serialized; int32_t maxsize; char *symbol,*type; struct iguana_info *virt; + if ( (type= jstr(valsobj,"type")) != 0 ) + { + if ( strcmp(type,"HDR") == 0 ) + getfunc = basilisk_respond_geckogetheaders; + else if ( strcmp(type,"BLK") == 0 ) + getfunc = basilisk_respond_geckogetblock; + else if ( strcmp(type,"GTX") == 0 ) + getfunc = basilisk_respond_geckogettx; + else return(clonestr("{\"error\":\"invalid geckoget type, mustbe (HDR or BLK or GTX)\"}")); + if ( (serialized= ((struct iguana_peer *)addr)->blockspace) == 0 ) + return(clonestr("{\"error\":\"peer has no blockspace\"}")); + maxsize = IGUANA_MAXPACKETSIZE; + if ( (symbol= jstr(valsobj,"symbol")) != 0 && (virt= iguana_coinfind(symbol)) != 0 ) + { + datalen = (*getfunc)(myinfo,virt,serialized,maxsize,valsobj,hash2); + printf("return datalen.%d for %s\n",datalen,type); + return(basilisk_standardreturn(CMD,type,virt,serialized,datalen,hash2)); + } else return(clonestr("{\"error\":\"couldt find gecko chain\"}")); + } else return(clonestr("{\"error\":\"invalid geckoget type, mustbe (HDR or BLK or GTX)\"}")); +} + +#include "../includes/iguana_apidefs.h" +#include "../includes/iguana_apideclares.h" + +char *gecko_sendrawtransaction(struct supernet_info *myinfo,char *symbol,uint8_t *data,int32_t datalen,bits256 txid,cJSON *vals,char *signedtx) +{ + char *retstr = 0; struct iguana_info *virt,*btcd = iguana_coinfind("BTCD"); + virt = iguana_coinfind(symbol); + if ( btcd != 0 && (btcd->FULLNODE != 0 || btcd->VALIDATENODE != 0) ) + { + basilisk_wait(myinfo,virt); + retstr = basilisk_respond_geckotx(myinfo,"GTX",0,0,0,vals,data,datalen,txid,0); + } + if ( retstr == 0 ) + retstr = basilisk_standardservice("GTX",myinfo,0,txid,vals,signedtx,1); + return(retstr); +} + +HASH_ARRAY_STRING(basilisk,geckotx,hash,vals,hexstr) +{ + struct iguana_info *btcd; char *retstr=0,*symbol; uint8_t *data,*allocptr,space[4096]; int32_t datalen; bits256 txid; + if ( (btcd= iguana_coinfind("BTCD")) != 0 && (symbol= jstr(vals,"symbol")) != 0 ) + { + if ( (data= get_dataptr(BASILISK_HDROFFSET,&allocptr,&datalen,space,sizeof(space),hexstr)) != 0 ) + { + txid = bits256_doublesha256(0,data,datalen); + retstr = gecko_sendrawtransaction(myinfo,symbol,data,datalen,txid,vals,hexstr); + } else retstr = clonestr("{\"error\":\"no tx submitted\"}"); + if ( allocptr != 0 ) + free(allocptr); + if ( retstr == 0 ) + retstr = clonestr("{\"error\":\"couldnt create geckotx\"}"); + return(retstr); + } return(clonestr("{\"error\":\"need symbol and chain and BTCD to create new gecko tx\"}")); +} + +HASH_ARRAY_STRING(basilisk,geckoblock,hash,vals,hexstr) +{ + return(clonestr("{\"error\":\"geckoblock is an internal reporting function\"}")); +} + +HASH_ARRAY_STRING(basilisk,geckoheaders,hash,vals,hexstr) +{ + return(clonestr("{\"error\":\"geckoheaders is an internal reporting function\"}")); +} + +HASH_ARRAY_STRING(basilisk,geckoget,hash,vals,hexstr) +{ + struct iguana_info *btcd,*virt; char *symbol; + if ( (btcd= iguana_coinfind("BTCD")) != 0 && (symbol= jstr(vals,"symbol")) != 0 ) + { + if ( (virt= iguana_coinfind(symbol)) != 0 ) + { + basilisk_wait(myinfo,virt); + return(basilisk_respond_geckoget(myinfo,"GET",&coin->internaladdr,remoteaddr,0,vals,0,0,hash,0)); + } else return(clonestr("{\"error\":\"geckoget needs virtualchain\"}")); + } + return(clonestr("{\"error\":\"geckoget needs BTCD\"}")); +} + +#include "../includes/iguana_apiundefs.h" + + diff --git a/gecko/gecko.h b/gecko/gecko.h new file mode 100755 index 000000000..0bd668200 --- /dev/null +++ b/gecko/gecko.h @@ -0,0 +1,97 @@ +/****************************************************************************** + * Copyright © 2014-2016 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#ifndef H_GECKO_H +#define H_GECKO_H + +#define GECKO_MAXBTCGAP 9 +#define GECKO_MAXBTCDGAP 18 + +#define GECKO_DEFAULTVERSION 1 +#define GECKO_EASIESTDIFF 0x1f7fffff +#define GECKO_DEFAULTDIFF 0x1f0fffff +#define GECKO_DEFAULTDIFFSTR "1f0fffff" + +#define GECKO_FIRSTPOSSIBLEBTC 414000 +#define GECKO_FIRSTPOSSIBLEBTCD 1100000 +#define GECKO_MAXNAMELEN 64 +#define GECKO_MAXMINERITERS 10000000 +#define GECKO_DIFFITERS 13 +#define GECKO_MAXFUTUREBLOCK 60 + +struct iguana_peer; + +/*struct hashstamp { bits256 hash2; uint32_t timestamp; int32_t height; }; +struct gecko_sequence { struct hashstamp *stamps; int32_t lastupdate,maxstamps,numstamps,lasti,longestchain; }; +struct gecko_sequences { struct gecko_sequence BTC,BTCD; };*/ + + +struct gecko_genesis_opreturn +{ + char type[3],symbol[6],name[15]; + uint64_t PoSvalue; + uint32_t netmagic,timestamp,nBits,nonce; + uint16_t blocktime,port; + uint8_t version,pubval,p2shval,wifval,rmd160[20]; +}; + +struct gecko_memtx +{ + double feeperkb; + bits256 txid; + int64_t txfee,inputsum,outputsum; + int32_t pending,numinputs,numoutputs,datalen; + uint32_t ipbits; + bits256 data256[]; +}; + +struct gecko_mempool +{ + int32_t numtx; uint32_t ipbits; + bits256 txids[0xffff]; + struct gecko_memtx **txs; +}; + +struct gecko_chain +{ + UT_hash_handle hh; queue_t Q; + char *(*processfunc)(struct supernet_info *myinfo,struct gecko_chain *cat,void *data,int32_t datalen,char *remoteaddr); + bits256 hash; struct gecko_chain *subchains; struct iguana_info *info; +}; + +struct gecko_chain *gecko_chain(struct supernet_info *myinfo,char chainname[GECKO_MAXNAMELEN],cJSON *valsobj); + +char *basilisk_respond_geckogenesis(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 txid,int32_t from_basilisk); +char *basilisk_respond_hashstamps(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 prevhash,int32_t from_basilisk); +char *basilisk_respond_newgeckochain(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 prevhash,int32_t from_basilisk); +char *basilisk_respond_geckotx(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 prevhash,int32_t from_basilisk); +char *basilisk_respond_geckoblock(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 prevhash,int32_t from_basilisk); +char *basilisk_respond_geckoheaders(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash2,int32_t from_basilisk); +char *basilisk_respond_geckoget(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash2,int32_t from_basilisk); + +void gecko_miner(struct supernet_info *myinfo,struct iguana_info *btcd,struct iguana_info *virt,int32_t maxmillis,uint8_t *minerpubkey33); +void gecko_seqresult(struct supernet_info *myinfo,char *retstr); +int32_t gecko_sequpdate(struct supernet_info *myinfo,char *symbol,uint32_t reftimestamp); +char *gecko_blockarrived(struct supernet_info *myinfo,struct iguana_info *virt,char *remoteaddr,uint8_t *data,int32_t datalen,bits256 hash2,int32_t verifyonly); +char *gecko_txarrived(struct supernet_info *myinfo,struct iguana_info *virt,char *remoteaddr,uint8_t *data,int32_t datalen,bits256 hash2); +char *gecko_mempoolarrived(struct supernet_info *myinfo,struct iguana_info *virt,char *remoteaddr,uint8_t *data,int32_t datalen,bits256 hash2); +char *gecko_headersarrived(struct supernet_info *myinfo,struct iguana_info *virt,char *remoteaddr,uint8_t *data,int32_t datalen,bits256 hash2); +char *gecko_sendrawtransaction(struct supernet_info *myinfo,char *symbol,uint8_t *data,int32_t datalen,bits256 txid,cJSON *vals,char *signedtx); + +struct gecko_mempool *gecko_mempoolfind(struct supernet_info *myinfo,struct iguana_info *virt,int32_t *numotherp,uint32_t ipbits); +void gecko_iteration(struct supernet_info *myinfo,struct iguana_info *btcd,struct iguana_info *virt,int32_t maxmillis); +int32_t iguana_coinbase(int32_t isPoS,uint32_t txversion,uint8_t *serialized,uint32_t timestamp,bits256 prev_hash,uint8_t *coinbasescript,uint32_t coinbaselen,uint8_t *minerpayment,uint32_t minerpaymentlen,int64_t blockreward,bits256 *txidp); + +#endif diff --git a/gecko/gecko_blocks.c b/gecko/gecko_blocks.c new file mode 100755 index 000000000..0e0b61045 --- /dev/null +++ b/gecko/gecko_blocks.c @@ -0,0 +1,403 @@ +/****************************************************************************** + * Copyright © 2014-2016 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +// included from gecko.c + +void gecko_txidpurge(struct iguana_info *virt,bits256 txid) +{ + struct gecko_mempool *pool; int32_t i,n; struct gecko_memtx *memtx; + if ( (pool= virt->mempool) != 0 && pool->txs != 0 && (n= pool->numtx) ) + { + for (i=0; itxs[i]) != 0 && bits256_cmp(txid,memtx->txid) == 0 ) + { + free(pool->txs[i]); + pool->txs[i] = pool->txs[--pool->numtx]; + } + } + } + if ( virt->FULLNODE != 0 ) + { + for (i=0; imempools[i]) != 0 && (n= pool->numtx) != 0 ) + { + for (i=0; itxids[i]) == 0 ) + { + pool->txids[i] = pool->txids[--pool->numtx]; + memset(pool->txids[pool->numtx].bytes,0,sizeof(pool->txids[pool->numtx])); + } + } + } + } + } +} + +struct iguana_bundle *gecko_bundleset(struct iguana_info *virt,struct iguana_block *block) +{ + int32_t hdrsi,bundlei; struct iguana_bundle *bp; + hdrsi = (block->height / virt->chain->bundlesize); + bundlei = (block->height % virt->chain->bundlesize); + if ( (bp= virt->bundles[hdrsi]) == 0 ) + printf("error ensuring bundle ht.%d\n",block->height); + else + { + bp->blocks[bundlei] = block; + bp->hashes[bundlei] = block->RO.hash2; + //char str[65]; printf("[%d:%d] <- %s %p\n",hdrsi,bundlei,bits256_str(str,block->RO.hash2),block); + iguana_hash2set(virt,"ensure",bp,bundlei,block->RO.hash2); + } + return(bp); +} + +struct iguana_bundle *gecko_ensurebundle(struct iguana_info *virt,struct iguana_block *block,int32_t origheight,int32_t depth) +{ + int32_t hdrsi,bundlei,checkbundlei,height = origheight; bits256 zero; + memset(zero.bytes,0,sizeof(zero)); + bundlei = (height % virt->chain->bundlesize); + hdrsi = (height / virt->chain->bundlesize); + if ( bundlei == 0 ) + { + if ( hdrsi+1 > virt->bundlescount ) + virt->bundlescount = hdrsi + 1; + return(iguana_bundlecreate(virt,&checkbundlei,origheight,block->RO.hash2,zero,0)); + } + /*for (iter=0; iter<2; iter++) + { + prev = block; + height = block->height; + for (i=0; ichain->bundlesize); + hdrsi = (height / virt->chain->bundlesize); + if ( iter == 1 ) + { + if ( (bp= virt->bundles[hdrsi]) != 0 ) + { + iguana_hash2set(virt,"ensure",bp,bundlei,prev->RO.hash2); + bp->blocks[bundlei] = prev; + bp->hashes[bundlei] = prev->RO.hash2; + } + else + { + printf("cant find bundle for ht.%d\n",height); + return(0); + } + } + else if ( bundlei == 0 && virt->bundles[hdrsi] == 0 ) + iguana_bundlecreate(virt,&checkbundlei,height,prev->RO.hash2,zero,0); + prev = iguana_blockfind("geckoensure",virt,prev->RO.prev_block); + } + if ( iter == 0 ) + { + char str[65]; + bundlei = (origheight % virt->chain->bundlesize); + hdrsi = (origheight / virt->chain->bundlesize); + if ( (bp= virt->bundles[hdrsi]) != 0 ) + iguana_hash2set(virt,"ensure",bp,bundlei,block->RO.hash2); + if ( iguana_bundlefind(virt,&bp,&bundlei,block->RO.hash2) == 0 ) + printf("cant find ht.%d %s\n",block->height,bits256_str(str,block->RO.hash2)); + } + }*/ + return(gecko_bundleset(virt,block)); +} + +int32_t gecko_hwmset(struct supernet_info *myinfo,struct iguana_info *virt,struct iguana_txblock *txdata,struct iguana_msgtx *txarray,uint8_t *data,int32_t datalen,int32_t depth,int32_t verifyonly) +{ + struct iguana_peer *addr; int32_t i,hdrsi; struct iguana_bundle *bp,*prevbp; struct iguana_block *block; + if ( (block= iguana_blockhashset("gecko_hwmset",virt,txdata->zblock.height,txdata->zblock.RO.hash2,1)) != 0 ) + { + iguana_blockcopy(virt->chain->zcash,virt->chain->auxpow,virt,block,(struct iguana_block *)&txdata->zblock); + } else return(-1); + addr = &virt->internaladdr; + if ( gecko_ensurebundle(virt,block,block->height,depth) == 0 ) + { + printf("no bundle for %s.%d\n",virt->symbol,block->height); + return(-1); + } + if ( iguana_ramchain_data(virt,addr,txdata,txarray,block->RO.txn_count,data,datalen) >= 0 ) + { + block->fpipbits = (uint32_t)addr->ipbits; + block->RO.recvlen = datalen; + block->txvalid = 1; + if ( verifyonly == 0 ) + { + iguana_blockzcopy(virt->chain->zcash,(void *)&virt->blocks.hwmchain,block); + hdrsi = block->height / virt->chain->bundlesize; + block->hdrsi = hdrsi; + block->height = + block->bundlei = (block->height % virt->chain->bundlesize); + if ( block->queued == 0 ) + { + block->req = calloc(1,datalen + sizeof(datalen)); + memcpy(block->req,&datalen,sizeof(datalen)); + memcpy((void *)((long)block->req + sizeof(datalen)),data,datalen); + block->queued = 1; + } + if ( (bp= virt->bundles[hdrsi]) != 0 ) + { + bp->numsaved = 0; + for (i=0; ichain->bundlesize; i++) + if ( bp->blocks[i] != 0 && bp->blocks[i]->txvalid != 0 ) + bp->numsaved++; + virt->current = bp; + //iguana_RTspendvectors(myinfo,virt,bp); + //iguana_RTramchainalloc("RTbundle",virt,bp); + printf("update virtchain balances\n"); + //iguana_update_balances(virt); + //iguana_realtime_update(myinfo,virt); + if ( (block->height % virt->chain->bundlesize) == 13 && hdrsi > 0 && (prevbp= virt->bundles[hdrsi - 1]) != 0 && prevbp->emitfinish == 0 && prevbp->numsaved >= prevbp->n ) + { + iguana_bundlefinalize(myinfo,virt,prevbp,&virt->MEM,virt->MEMB); + prevbp->emitfinish = (uint32_t)(time(NULL) - 3600); + iguana_bundlepurgefiles(virt,prevbp); + iguana_savehdrs(virt); + iguana_bundlevalidate(virt,prevbp,1); + for (i=0; iRO.txn_count; i++) + gecko_txidpurge(virt,txarray[i].txid); + } + } + //printf("created block.%d [%d:%d] %d\n",block->height,bp!=0?bp->hdrsi:-1,block->height%virt->chain->bundlesize,bp->numsaved); + } + return(block->height); + } else printf("Error updating virt ramchain\n"); + return(-1); +} + +char *gecko_blockarrived(struct supernet_info *myinfo,struct iguana_info *virt,char *remoteaddr,uint8_t *data,int32_t datalen,bits256 hash2,int32_t verifyonly) +{ + struct iguana_txblock txdata; int32_t height,valid,adjacent,gap,n,i,j,len = -1; struct iguana_block *block,*prev; struct iguana_txid tx; char str[65],str2[65]; bits256 txid,threshold; struct iguana_msgtx *txs; + memset(&txdata,0,sizeof(txdata)); + iguana_memreset(&virt->TXMEM); + if ( (n= iguana_gentxarray(virt,&virt->TXMEM,&txdata,&len,data,datalen)) == datalen || n == datalen-1 ) + { + if ( bits256_cmp(hash2,txdata.zblock.RO.hash2) != 0 ) + { + printf("gecko_blockarrived: mismatched hash2.%s vs %s\n",bits256_str(str,hash2),bits256_str(str2,txdata.zblock.RO.hash2)); + return(clonestr("{\"error\":\"gecko block hash2 mismatch\"}")); + } + if ( txdata.zblock.RO.bits >= GECKO_EASIESTDIFF ) + threshold = bits256_from_compact(GECKO_EASIESTDIFF); + else threshold = bits256_from_compact(txdata.zblock.RO.bits); + if ( bits256_cmp(threshold,hash2) <= 0 ) + { + printf("gecko_blockarrived: failed nBits diff\n"); + return(clonestr("{\"error\":\"gecko block failed nBits diff\"}")); + } + txs = virt->TXMEM.ptr; + for (i=0; ibundlescount-1) != 0 && height >= 0 ) + { + printf("gecko_blockarrived: duplicate.[%d] txid.%s\n",i,bits256_str(str,txid)); + return(clonestr("{\"error\":\"gecko block duplicate txid\"}")); + } else printf("%s is new txid ht.%d i.%d\n",bits256_str(str,txid),virt->blocks.hwmchain.height,i); + } + txdata.zblock.RO.allocsize = iguana_ROallocsize(virt); + if ( iguana_blockvalidate(virt,&valid,(struct iguana_block *)&txdata.zblock,1) < 0 ) + { + char str[65]; printf("got block that doesnt validate? %s\n",bits256_str(str,txdata.zblock.RO.hash2)); + return(clonestr("{\"error\":\"gecko block didnt validate\"}")); + } + if ( (block= iguana_blockfind("geckoblock",virt,hash2)) == 0 ) + { + if ( (block= iguana_blockhashset("geckoblock",virt,-1,hash2,1)) == 0 ) + return(clonestr("{\"error\":\"gecko block couldnt be created\"}")); + } + iguana_blockcopy(virt->chain->zcash,virt->chain->auxpow,virt,block,(struct iguana_block *)&txdata.zblock); + prev = block; + adjacent = -1; + for (i=0; ichain->bundlesize; i++) + { + //char str2[65]; + //printf("scan back.%d: prev.%s hwm.%s ht.%d\n",i,bits256_str(str,prev->RO.prev_block),bits256_str(str2,virt->blocks.hwmchain.RO.hash2),virt->blocks.hwmchain.height); + if ( (prev= iguana_blockfind("geckoprev",virt,prev->RO.prev_block)) == 0 ) + return(clonestr("{\"error\":\"gecko block is orphan\"}")); + if ( i == 0 ) + { + adjacent = prev->height; + block->height = (prev->height + 1); + } + //printf("i.%d prevht.%d adjacent.%d hwm.%d\n",i,prev->height,adjacent,virt->blocks.hwmchain.height); + if ( prev->height >= 0 && prev->mainchain != 0 ) + { + if ( (adjacent + 1) > virt->blocks.hwmchain.height ) // longest chain wins + { + //printf("new HWM %d adjacent.%d prev.%d i.%d\n",block->height,adjacent,prev->height,i); + if ( (gap= (block->height - virt->blocks.hwmchain.height)) > 1 ) + { + prev = iguana_blockfind("geckoclear",virt,virt->blocks.hwmchain.RO.prev_block); + for (j=0; jprotected,bits256_str(str,prev->RO.hash2),prev->height,block->height); + if ( prev->protected != 0 ) + { + printf("REJECT block: cant overwrite protected block\n"); + return(clonestr("{\"error\":\"gecko block cant override protected block\"}")); + } + prev->mainchain = 0; + prev = iguana_blockfind("geckoclrprev",virt,prev->RO.prev_block); + } + } + prev = block; + for (j=0; j<=i+1; j++) + { + if ( prev->protected == 0 || prev->height == (adjacent + 1 - j) ) + { + if ( prev->mainchain != 1 ) + prev->mainchain = 1; + if ( prev->height != (adjacent + 1 - j) ) + prev->height = (adjacent + 1 - j); + gecko_ensurebundle(virt,prev,prev->height,0); + //gecko_bundleset(virt,prev); + if ( prev->height == 0 ) + break; + } + else + { + printf("REJECT block: cant change height of protected block: ht.%d vs %d\n",adjacent + 1 - j, prev->height); + return(clonestr("{\"error\":\"gecko block cant override protected block's height\"}")); + } + if ( (prev= iguana_blockfind("geckoprev",virt,prev->RO.prev_block)) == 0 ) + return(clonestr("{\"error\":\"gecko block mainchain link error\"}")); + } + txdata.zblock.height = block->height; + txdata.zblock.mainchain = block->mainchain = 1; + if ( gecko_hwmset(myinfo,virt,&txdata,virt->TXMEM.ptr,data,datalen,i+1,verifyonly) >= 0 ) + { + block->txvalid = block->valid = 1; + if ( block->height > virt->longestchain ) + virt->longestchain = block->height; + virt->backstoptime = (uint32_t)time(NULL); + return(clonestr("{\"result\":\"gecko block created\"}")); + } + else return(clonestr("{\"error\":\"gecko error creating hwmblock\"}")); + } else return(clonestr("{\"result\":\"gecko block wasnt hwmblock\"}")); + } + } + return(clonestr("{\"error\":\"gecko orphan block\"}")); + } else printf("blockarrived error generating txlist\n"); + return(clonestr("{\"error\":\"gecko block didnt decode\"}")); +} + +char *basilisk_respond_geckoblock(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash2,int32_t from_basilisk) +{ + char *symbol; struct iguana_info *virt; bits256 checkhash2; int32_t hdrsize; struct iguana_msgblock msg; struct iguana_block *block; + //printf("got geckoblock len.%d from (%s) %s\n",datalen,remoteaddr!=0?remoteaddr:"",jprint(valsobj,0)); + if ( (symbol= jstr(valsobj,"symbol")) != 0 && (virt= iguana_coinfind(symbol)) != 0 ) + { + if ( (block= iguana_blockfind("geckoblock",virt,hash2)) != 0 ) + { + char str[65]; + if ( block->height == juint(valsobj,"height") ) + return(0); + printf("REJECT: duplicate block %s\n",bits256_str(str,hash2)); + return(clonestr("{\"error\":\"duplicate block rejected\"}")); + } + hdrsize = (virt->chain->zcash != 0) ? sizeof(struct iguana_msgblockhdr_zcash) : sizeof(struct iguana_msgblockhdr); + //nBits = gecko_nBits(virt,&prevtimestamp,(struct iguana_block *)&virt->blocks.hwmchain,GECKO_DIFFITERS); + //if ( gecko_blocknonce_verify(virt,data,hdrsize,nBits,virt->blocks.hwmchain.RO.timestamp,prevtimestamp) > 0 ) + { + iguana_rwblock(symbol,virt->chain->zcash,virt->chain->auxpow,virt->chain->hashalgo,0,&checkhash2,data,&msg,datalen); + if ( bits256_cmp(hash2,checkhash2) == 0 ) + { + if ( gecko_blocknonce_verify(virt,data,hdrsize,msg.H.bits,0,0) > 0 ) + return(gecko_blockarrived(myinfo,virt,addr,data,datalen,hash2,0)); + else return(clonestr("{\"error\":\"block nonce didnt verify\"}")); + } else return(clonestr("{\"error\":\"block error with checkhash2\"}")); + } + } + return(0); +} + +int32_t basilisk_blocksubmit(struct supernet_info *myinfo,struct iguana_info *btcd,struct iguana_info *virt,struct iguana_peer *addr,char *blockstr,bits256 hash2,int32_t height) +{ + int32_t i,datalen,num,numerrs,numresults=0; uint8_t *data,space[16384],*allocptr; cJSON *valsobj=0,*retjson,*retarray,*item; char *str,*str2,*othercoin; bits256 othertip; + //printf("blocksubmit.(%s)\n",blockstr); + if ( (data= get_dataptr(sizeof(struct iguana_msghdr) + BASILISK_HDROFFSET,&allocptr,&datalen,space,sizeof(space),blockstr)) != 0 ) + { + if ( (str= gecko_blockarrived(myinfo,virt,"127.0.0.1",data,datalen,hash2,0)) != 0 ) + { + if ( (retjson= cJSON_Parse(str)) != 0 ) + { + if ( jobj(retjson,"error") == 0 ) + { + valsobj = cJSON_CreateObject(); + jaddnum(valsobj,"minresults",NUMRELAYS - 1); + jaddnum(valsobj,"timeout",3000); + jaddnum(valsobj,"fanout",-1); + jaddnum(valsobj,"height",height); + jaddstr(valsobj,"symbol",virt->symbol); + if ( (str2= basilisk_standardservice("BLK",myinfo,addr,hash2,valsobj,blockstr,0)) != 0 ) + { + if ( 0 && (retarray= cJSON_Parse(str2)) != 0 ) + { + numerrs = numresults = 0; + if ( (num= cJSON_GetArraySize(retarray)) > 0 ) + { + for (i=0; isymbol) == 0 && juint(item,"hwm") == height ) + { + othertip = jbits256(item,"chaintip"); + if ( bits256_cmp(hash2,othertip) == 0 ) + numresults++; + else numerrs++; + } else numerrs++; + } + } + } + printf("%s got responses.%d good.%d errs.%d (%s)\n","BLK",num,numresults,numerrs,str2); + free_json(retarray); + } + free(str2); + } + free_json(valsobj); + } + free_json(retjson); + } + free(str); +/*#ifndef __APPLE__ + if ( numresults >= (myinfo->numrelays >> 1) ) +#endif + { + if ( (str= gecko_blockarrived(myinfo,virt,"127.0.0.1",data,datalen,hash2,0)) != 0 ) + free(str); + }*/ + } + } else printf("basilisk_blocksumbit dataptr error\n"); + if ( allocptr != 0 ) + free(allocptr); + return(numresults); +} + +int32_t basilisk_respond_geckogetblock(struct supernet_info *myinfo,struct iguana_info *virt,uint8_t *serialized,int32_t maxsize,cJSON *valsobj,bits256 hash2) +{ + int32_t datalen = 0; char str[65]; + printf("GOT request for block.(%s)\n",bits256_str(str,hash2)); + // find block and set serialized + return(datalen); +} diff --git a/gecko/gecko_delayedPoW.c b/gecko/gecko_delayedPoW.c new file mode 100755 index 000000000..280f3065f --- /dev/null +++ b/gecko/gecko_delayedPoW.c @@ -0,0 +1,273 @@ +/****************************************************************************** + * Copyright © 2014-2016 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +// included from gecko.c + +/*int32_t gecko_hashstampsfind(struct hashstamp *stamps,int32_t max,struct gecko_sequence *seq,bits256 hash,uint32_t reftimestamp) +{ + int32_t j,i = 0,foundflag = -1,gap = -1; uint32_t timestamp; + if ( seq->stamps == 0 ) + return(-1); + if ( seq->stamps[seq->lasti].timestamp < reftimestamp && seq->lasti >= 3 ) + i = seq->lasti - 3; + for (; inumstamps; i++) + { + if ( (timestamp= seq->stamps[i].timestamp) == 0 || timestamp > reftimestamp ) + { + memset(stamps,0,sizeof(*stamps) * max); + for (j=0; j=0; j++) + stamps[j] = seq->stamps[i - j]; + return(gap); + } + if ( foundflag < 0 && bits256_cmp(hash,seq->stamps[i].hash2) == 0 ) + { + seq->lasti = i; + foundflag = i; + gap = 0; + } + else if ( foundflag >= 0 ) + gap++; + } + return(-1); +} + +bits256 gecko_hashstampscalc(struct supernet_info *myinfo,struct iguana_info *btcd,bits256 *btchashp,uint32_t reftimestamp) +{ + struct hashstamp BTCDstamps[GECKO_MAXBTCDGAP],BTCstamps[GECKO_MAXBTCGAP]; bits256 btcdhash; + btcdhash = *btchashp = GENESIS_PUBKEY; + if ( gecko_hashstampsfind(BTCDstamps,GECKO_MAXBTCDGAP,&myinfo->dPOW.SEQ.BTCD,btcdhash,reftimestamp) < 0 ) + { + btcdhash = BTCDstamps[GECKO_MAXBTCDGAP >> 1].hash2; + if ( gecko_hashstampsfind(BTCstamps,GECKO_MAXBTCGAP,&myinfo->dPOW.SEQ.BTC,*btchashp,reftimestamp) < 0 ) + *btchashp = BTCstamps[GECKO_MAXBTCGAP >> 1].hash2; + } + return(btcdhash); +} + +// have local coin +int32_t gecko_hashstampsreverse(struct iguana_info *coin,struct gecko_sequence *seq,int32_t firstpossible,int32_t max,struct iguana_block *block,uint32_t reftimestamp) +{ + uint32_t timestamp; int32_t j,offset; + while ( block != 0 && (timestamp= block->RO.timestamp) > reftimestamp ) + block = iguana_blockfind("hashstamps",coin,block->RO.prev_block); + if ( block == 0 ) + return(-1); + offset = (block->height - firstpossible); + for (j=0; jstamps[offset].hash2 = block->RO.hash2; + seq->stamps[offset].timestamp = block->RO.timestamp; + seq->stamps[offset].height = block->height; + if ( offset-- < 0 || (block= iguana_blockfind("revstamp",coin,block->RO.prev_block)) == 0 ) + return(block == 0 ? -1 : j); + } + return(j); +} + +int32_t gecko_hashstampset(struct iguana_info *coin,struct hashstamp *stamp,int32_t height) +{ + struct iguana_block *block; struct iguana_bundle *bp; + if ( height >= 0 && height < coin->bundlescount && (bp= coin->bundles[height / coin->chain->bundlesize]) != 0 ) + { + if ( (block= bp->blocks[height % coin->chain->bundlesize]) != 0 ) + { + stamp->hash2 = block->RO.hash2; + stamp->timestamp = block->RO.timestamp; + stamp->height = block->height; + return(0); + } + } + return(-1); +} + +void gecko_ensure(struct gecko_sequence *seq,int32_t num) +{ + int32_t oldmax,incr = 1000; + if ( num >= seq->maxstamps ) + { + oldmax = seq->maxstamps; + seq->maxstamps = ((num + 2*incr) / incr) * incr; + seq->stamps = realloc(seq->stamps,sizeof(*seq->stamps) * seq->maxstamps); + memset(&seq->stamps[oldmax],0,sizeof(*seq->stamps) * (seq->maxstamps - oldmax)); + } +} + +int32_t gecko_hashstampsupdate(struct iguana_info *coin,struct gecko_sequence *seq,int32_t firstpossible) +{ + while ( (firstpossible + seq->numstamps) < coin->blocks.hwmchain.height ) + { + gecko_ensure(seq,seq->numstamps); + if ( gecko_hashstampset(coin,&seq->stamps[seq->numstamps],firstpossible + seq->numstamps) < 0 ) + break; + else seq->numstamps++; + } + seq->longestchain = coin->longestchain; + return(seq->numstamps); +} + +int32_t gecko_sequpdate(struct supernet_info *myinfo,char *symbol,uint32_t reftimestamp) +{ + struct gecko_sequence *seq=0; int32_t max=0,firstpossible=0; struct iguana_info *coin; struct iguana_block *block; + if ( (coin= iguana_coinfind(symbol)) != 0 && (coin->FULLNODE != 0 || coin->VALIDATENODE != 0) ) + { + if ( strcmp(symbol,"BTCD") == 0 ) + { + seq = &myinfo->dPOW.SEQ.BTCD; + firstpossible = GECKO_FIRSTPOSSIBLEBTCD; + } + else if ( strcmp(symbol,"BTC") == 0 ) + { + seq = &myinfo->dPOW.SEQ.BTC; + firstpossible = GECKO_FIRSTPOSSIBLEBTC; + } else return(-1); + //printf("basilisk update.%s %u lag.%d\n",symbol,reftimestamp,(uint32_t)time(NULL)-seq->lastupdate); + if ( gecko_hashstampsupdate(coin,seq,firstpossible) > 0 ) + { + if ( (block= iguana_blockfind("SEQupdate",coin,coin->blocks.hwmchain.RO.hash2)) != 0 ) + gecko_hashstampsreverse(coin,seq,firstpossible,max,block,reftimestamp); + return(0); + } + } + return(-1); +} + +int32_t iguana_rwhashstamp(int32_t rwflag,uint8_t zcash,uint8_t *serialized,struct hashstamp *stamp) +{ + int32_t len = 0; + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(stamp->hash2),stamp->hash2.bytes); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(stamp->timestamp),&stamp->timestamp); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(stamp->height),&stamp->height); + //len += iguana_rwblockhdr(rwflag,zcash,&serialized[len],(void *)stamp->RO); + return(len); +} + +cJSON *gecko_sequencejson(uint8_t zcash,struct gecko_sequence *seq,int32_t startheight,int32_t firstpossible) +{ + int32_t i,n,len=0,datalen,num = 0; cJSON *item; uint8_t *data; char strbuf[8192],*hexstr=0; + if ( startheight < firstpossible ) + startheight = firstpossible; + if ( (i= (startheight - firstpossible) ) < 0 || i >= seq->numstamps ) + return(0); + item = cJSON_CreateObject(); + n = (seq->numstamps - i); + datalen = (int32_t)(n * sizeof(*seq->stamps)); + data = calloc(n,sizeof(*seq->stamps)); + for (; inumstamps && numstamps[i].timestamp == 0 ) + break; + len += iguana_rwhashstamp(1,zcash,&data[len],&seq->stamps[i]); + } + jaddnum(item,"start",startheight); + jaddnum(item,"num",num); + jaddnum(item,"lastupdate",seq->lastupdate); + jaddnum(item,"longest",seq->longestchain); + basilisk_addhexstr(&hexstr,item,strbuf,sizeof(strbuf),data,datalen); + if ( hexstr != 0 ) + free(hexstr); + return(item); +} + +void gecko_seqresult(struct supernet_info *myinfo,char *retstr) +{ + struct iguana_info *btcd; struct hashstamp stamp; struct gecko_sequence *seq = 0; cJSON *resultjson; uint8_t *allocptr = 0,space[8192],*data = 0; int32_t ind,startheight,datalen,lastupdate,longestchain,i,num,firstpossible,len = 0; char *hexstr; + if ( (btcd= iguana_coinfind("BTCD")) != 0 && (resultjson= cJSON_Parse(retstr)) != 0 ) + { + if ( jstr(resultjson,"BTCD") != 0 ) + seq = &myinfo->dPOW.SEQ.BTCD, firstpossible = GECKO_FIRSTPOSSIBLEBTCD; + else if ( jstr(resultjson,"BTC") != 0 ) + seq = &myinfo->dPOW.SEQ.BTC, firstpossible = GECKO_FIRSTPOSSIBLEBTC; + if ( seq != 0 ) + { + startheight = jint(resultjson,"start"); + if ( (ind= startheight-firstpossible) < 0 ) + { + free_json(resultjson); + return; + } + num = jint(resultjson,"num"); + lastupdate = jint(resultjson,"lastupdate"); + longestchain = jint(resultjson,"longest"); + hexstr = jstr(resultjson,"data"); + printf("got startheight.%d num.%d lastupdate.%d longest.%d (%s)\n",startheight,num,lastupdate,longestchain,hexstr!=0?hexstr:""); + if ( hexstr != 0 && (data= get_dataptr(BASILISK_HDROFFSET,&allocptr,&datalen,space,sizeof(space),hexstr)) != 0 ) + { + gecko_ensure(seq,ind + num); + for (i=0; ichain->zcash,&data[len],&stamp); + // verify blockheader + seq->stamps[ind] = stamp; + } + } + if ( allocptr != 0 ) + free(allocptr); + } + free_json(resultjson); + } +} + +char *basilisk_respond_hashstamps(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 prevhash,int32_t from_basilisk) +{ + int32_t startheight; struct iguana_info *btcd; cJSON *retjson = cJSON_CreateObject(); + if ( (btcd= iguana_coinfind("BTCD")) != 0 ) + { + if ( (startheight= juint(valsobj,"BTCD")) != 0 ) + jadd(retjson,"BTCD",gecko_sequencejson(btcd->chain->zcash,&myinfo->dPOW.SEQ.BTCD,startheight,GECKO_FIRSTPOSSIBLEBTCD)); + else if ( (startheight= juint(valsobj,"BTC")) != 0 ) + jadd(retjson,"BTC",gecko_sequencejson(btcd->chain->zcash,&myinfo->dPOW.SEQ.BTC,startheight,GECKO_FIRSTPOSSIBLEBTC)); + } + return(jprint(retjson,1)); +}*/ + +/* +done = 3; +if ( btcd->FULLNODE != 0 || btcd->VALIDATENODE != 0 ) +{ + if ( (now= (uint32_t)time(NULL)) > myinfo->dPOW.SEQ.BTCD.lastupdate+10 ) + { + if ( gecko_sequpdate(myinfo,"BTCD",now) >= 0 ) + done &= ~1; + myinfo->dPOW.SEQ.BTCD.lastupdate = (uint32_t)time(NULL); + } +} +if ( (now= (uint32_t)time(NULL)) > myinfo->dPOW.SEQ.BTC.lastupdate+30 ) +{ + if ( gecko_sequpdate(myinfo,"BTC",now) >= 0 ) + done &= ~2; + myinfo->dPOW.SEQ.BTC.lastupdate = (uint32_t)time(NULL); + } +if ( done != 3 ) +{ + valsobj = cJSON_CreateObject(); + if ( btcd->FULLNODE == 0 && btcd->VALIDATENODE == 0 ) + { + //fprintf(stderr,"e"); + jaddnum(valsobj,"BTCD",myinfo->dPOW.SEQ.BTCD.numstamps+GECKO_FIRSTPOSSIBLEBTCD); + basilisk_standardservice("SEQ",myinfo,GENESIS_PUBKEY,valsobj,0,0); + flag++; + } + if ( (done & 2) == 0 ) + { + //fprintf(stderr,"f"); + free_json(valsobj); + valsobj = cJSON_CreateObject(); + jaddnum(valsobj,"BTC",myinfo->dPOW.SEQ.BTC.numstamps+GECKO_FIRSTPOSSIBLEBTC); + basilisk_standardservice("SEQ",myinfo,GENESIS_PUBKEY,valsobj,0,0); + flag++; + } + free_json(valsobj); +} +*/ \ No newline at end of file diff --git a/gecko/gecko_headers.c b/gecko/gecko_headers.c new file mode 100755 index 000000000..520a3253b --- /dev/null +++ b/gecko/gecko_headers.c @@ -0,0 +1,104 @@ +/****************************************************************************** + * Copyright © 2014-2016 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +// included from gecko.c + +int32_t basilisk_respond_geckogetheaders(struct supernet_info *myinfo,struct iguana_info *virt,uint8_t *serialized,int32_t maxsize,cJSON *valsobj,bits256 hash2) +{ + int32_t i,n,num,height,len=0; struct iguana_block *block; + if ( (block= iguana_blockfind("geckohdr",virt,hash2)) != 0 ) + { + if ( (height= block->height) >= 0 ) + { + if ( (num= juint(valsobj,"num")) == 0 || num > virt->chain->bundlesize ) + num = virt->chain->bundlesize; + for (i=0; i 0 ) + len += n; + } + hash2 = iguana_blockhash(virt,height+i+1); + block = iguana_blockfind("geckohdri",virt,hash2); + } + return(len); + } + } + return(-1); +} + +void gecko_blockhashupdate(struct iguana_info *virt,bits256 hash2,int32_t height) +{ + int32_t bundlei; struct iguana_bundle *bp; bits256 zero; + char str[65]; printf("gecko_blockhashupdate height.%d %s\n",height,bits256_str(str,hash2)); + memset(zero.bytes,0,sizeof(zero)); + if ( (height % virt->chain->bundlesize) == 0 ) + bp = iguana_bundlecreate(virt,&bundlei,height,hash2,zero,0); + else if ( (bp= virt->bundles[height / virt->chain->bundlesize]) != 0 ) + iguana_bundlehash2add(virt,0,bp,height % virt->chain->bundlesize,hash2); +} + +char *gecko_headersarrived(struct supernet_info *myinfo,struct iguana_info *virt,char *remoteaddr,uint8_t *data,int32_t datalen,bits256 firsthash2) +{ + bits256 hash2,prevhash2; struct iguana_block *block; int32_t height,firstheight,i,len=0,n,num; struct iguana_msgblock msgB; char str[65],str2[65]; + num = (int32_t)(datalen / 84); + printf("headers.%s arrived.%d from %s\n",virt->symbol,num,bits256_str(str,firsthash2)); + if ( (block= iguana_blockfind("geckohdrs",virt,firsthash2)) != 0 && (firstheight= block->height) >= 0 ) + { + gecko_blockhashupdate(virt,firsthash2,firstheight); + prevhash2 = firsthash2; + for (i=0; isymbol,virt->chain->zcash,virt->chain->auxpow,virt->chain->hashalgo,0,&hash2,&data[len],&msgB,datalen-len)) > 0 ) + { + if ( bits256_cmp(msgB.H.prev_block,prevhash2) == 0 ) + { + height = (firstheight + i + 1); + gecko_blockhashupdate(virt,hash2,height); + printf("ht.%d %s %08x t.%u\n",height,bits256_str(str,hash2),msgB.H.bits,msgB.H.timestamp); + } else printf("ht.%d non prevhash i.%d %s %s\n",height,i,bits256_str(str,prevhash2),bits256_str(str2,msgB.H.prev_block)); + len += n; + prevhash2 = hash2; + } + } + return(clonestr("{\"result\":\"gecko headers processed\"}")); + } else return(clonestr("{\"error\":\"gecko headers couldnt find firsthash2\"}")); +} + +char *basilisk_respond_geckoheaders(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash2,int32_t from_basilisk) +{ + char *symbol; struct iguana_info *virt; + printf("respond to incoming headers datalen.%d\n",datalen); + if ( (symbol= jstr(valsobj,"symbol")) != 0 && (virt= iguana_coinfind(symbol)) != 0 ) + return(gecko_headersarrived(myinfo,virt,addr,data,datalen,hash2)); + else return(clonestr("{\"error\":\"couldt find gecko chain\"}")); +} + +void gecko_requesthdrs(struct supernet_info *myinfo,struct iguana_info *virt,int32_t hdrsi) +{ + bits256 zero; struct iguana_bundle *bp=0; cJSON *vals; char *retstr; + if ( (bp= virt->bundles[hdrsi]) != 0 ) + { + vals = cJSON_CreateObject(); + memset(zero.bytes,0,sizeof(zero)); + jaddstr(vals,"symbol",virt->symbol); + jaddstr(vals,"type","HDR"); + if ( (retstr= basilisk_standardservice("GET",myinfo,0,bp->hashes[0],vals,0,0)) != 0 ) + free(retstr); + free_json(vals); + } else printf("dont have bundle needed\n"); +} + diff --git a/gecko/gecko_mempool.c b/gecko/gecko_mempool.c new file mode 100755 index 000000000..ce953211d --- /dev/null +++ b/gecko/gecko_mempool.c @@ -0,0 +1,369 @@ +/****************************************************************************** + * Copyright © 2014-2016 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +// included from gecko.c +// struct gecko_memtx { bits256 txid; char *rawtx; int64_t txfee; int32_t pending; uint32_t ipbits; }; + +struct gecko_mempool *gecko_mempoolfind(struct supernet_info *myinfo,struct iguana_info *virt,int32_t *numotherp,uint32_t ipbits) +{ + int32_t j,firstz,numother; bits256 *othertxids; struct gecko_mempool *otherpool = 0; + othertxids = 0; + numother = firstz = 0; + for (j=0; jmempools[j]) != 0 ) + { + if ( otherpool->ipbits == ipbits ) + { + othertxids = otherpool->txids; + numother = otherpool->numtx; + break; + } + } else firstz = j; + } + if ( otherpool == 0 ) + { + virt->mempools[firstz] = otherpool = calloc(1,sizeof(struct gecko_mempool)); + otherpool->ipbits = (uint32_t)ipbits; + } + return(otherpool); +} + +void gecko_mempool_sync(struct supernet_info *myinfo,struct iguana_info *virt,bits256 *reftxids,int32_t numtx) +{ + int32_t i,j,k,n,num,numother; struct iguana_peer *addr; bits256 txid,*txids; struct gecko_mempool *pool,*otherpool; struct iguana_info *coin; + if ( (pool= virt->mempool) == 0 || NUMRELAYS <= 0 ) + return; + n = sqrt(NUMRELAYS) + 2; + if ( n > NUMRELAYS ) + NUMRELAYS = n; + i = (myinfo->myaddr.myipbits % n); + txids = calloc(pool->numtx,sizeof(bits256)); + if ( virt->peers == 0 ) + coin = iguana_coinfind("BTCD"); + else coin = virt; + for (; inumtx; j++) + { + txid = reftxids[j]; + if ( numother > 0 ) + { + for (k=0; ktxids[k]) == 0 ) + break; + if ( k != numother ) + continue; + } + txids[num++] = txid; + } + if ( num > 0 ) + basilisk_hashes_send(myinfo,virt,addr,"MEM",txids,num); + } + } + } + free(txids); +} + +uint8_t *gecko_txdata(struct gecko_memtx *memtx) +{ + return((void *)((long)memtx->data256 + memtx->numoutputs * sizeof(int64_t) + memtx->numinputs * sizeof(bits256))); +} + +int64_t *gecko_valueptr(struct gecko_memtx *memtx,int32_t vout) +{ + return((void *)((long)memtx->data256 + vout * sizeof(int64_t) + memtx->numinputs * sizeof(bits256))); +} + +int32_t gecko_memtxcmp(struct gecko_memtx *memtxA,struct gecko_memtx *memtxB) +{ + int32_t i,numdiff; int64_t valA,valB,diff; + if ( memtxA->numinputs == memtxB->numinputs && memtxA->numoutputs == memtxB->numoutputs ) + { + for (i=0; inuminputs; i++) + { + if ( bits256_cmp(memtxA->data256[i],memtxB->data256[i]) != 0 ) + return(-1 - 2*i); + } + for (i=numdiff=0; inumoutputs; i++) + { + memcpy(&valA,gecko_valueptr(memtxA,i),sizeof(valA)); + memcpy(&valB,gecko_valueptr(memtxB,i),sizeof(valB)); + if ( (diff= valA - valB) < 0 ) + diff = -diff; + if ( diff > 100000 ) + return(-1); + if ( valA != valB ) + numdiff++; + } + if ( numdiff > 1 ) + return(-memtxA->numinputs*2 - 2); + + return(0); + } + return(-1); +} + +struct gecko_memtx *gecko_unspentfind(struct gecko_memtx ***ptrpp,struct iguana_info *virt,bits256 txid) +{ + struct gecko_mempool *pool; int32_t i; struct gecko_memtx *memtx; + if ( (pool= virt->mempool) != 0 ) + { + for (i=0; inumtx; i++) + if ( (memtx= pool->txs[i]) != 0 && bits256_cmp(memtx->txid,txid) == 0 ) + { + if ( ptrpp != 0 ) + *ptrpp = &pool->txs[i]; + return(memtx); + } + } + return(0); +} + +struct gecko_memtx *gecko_mempool_txadd(struct supernet_info *myinfo,struct iguana_info *virt,int32_t height,char *rawtx,uint32_t senderbits,int32_t suppress_pubkeys) +{ + struct gecko_memtx *spentmemtx,**ptrp,*memtx = 0; uint8_t *extraspace; char *str; struct iguana_msgtx msgtx; int32_t i,len,extralen = 65536; cJSON *retjson; int64_t value; + extraspace = calloc(1,extralen); + if ( (str= iguana_validaterawtx(myinfo,virt,height,&msgtx,extraspace,extralen,rawtx,1,suppress_pubkeys)) != 0 ) + { + if ( (retjson= cJSON_Parse(str)) != 0 ) + { + if ( jobj(retjson,"error") == 0 ) + { + len = (int32_t)strlen(rawtx) >> 1; + memtx = calloc(1,sizeof(*memtx) + len + msgtx.numoutputs * sizeof(int64_t) + msgtx.numinputs * sizeof(bits256)); + memtx->numinputs = msgtx.numinputs; + memtx->numoutputs = msgtx.numoutputs; + memtx->inputsum = msgtx.inputsum; + memtx->outputsum = msgtx.outputsum; + memtx->txfee = msgtx.txfee; + memtx->txid = msgtx.txid; + memtx->ipbits = senderbits; + memtx->datalen = len; + memtx->feeperkb = dstr(memtx->txfee) / (memtx->datalen / 1024.); + for (i=0; idata256[i] = msgtx.vins[i].prev_hash; + for (i=0; imempool,msgtx.vins[i].prev_hash)) != 0 ) + { + memcpy(&value,gecko_valueptr(spentmemtx,msgtx.vins[i].prev_vout),sizeof(value)); + if ( value < 0 ) + { + if ( gecko_memtxcmp(spentmemtx,memtx) != 0 || memtx->txfee <= spentmemtx->txfee ) + { + printf("already spent mempool error\n"); // check for replacment! + free(memtx); + } + else + { + printf("replace identical vins/vouts with higher txfee\n"); + free(spentmemtx); + *ptrp = memtx; + } + memtx = 0; + free_json(retjson); + free(extraspace); + free(str); + return(0); + } + } + } + for (i=0; imempool,msgtx.vins[i].prev_hash)) != 0 ) + { + memcpy(&value,gecko_valueptr(spentmemtx,msgtx.vins[i].prev_vout),sizeof(value)); + value = -value; + memcpy(gecko_valueptr(spentmemtx,msgtx.vins[i].prev_vout),&value,sizeof(value)); + } + } + } else printf("gecko_mempool_txadd had error.(%s)\n",str); + free_json(retjson); + } else printf("gecko_mempool_txadd couldnt parse.(%s)\n",str); + free(str); + } + free(extraspace); + return(memtx); +} + +struct gecko_mempool *gecko_mempool_alloc(int32_t otherflag) +{ + struct gecko_mempool *pool; + pool = calloc(1,sizeof(*pool)); + if ( otherflag == 0 ) + pool->txs = calloc(0xffff,sizeof(*pool->txs)); + return(pool); +} + +int32_t basilisk_respond_geckogettx(struct supernet_info *myinfo,struct iguana_info *virt,uint8_t *serialized,int32_t maxsize,cJSON *valsobj,bits256 hash2) +{ + int32_t datalen = 0; + char str[65]; printf("got request for GTX.%s\n",bits256_str(str,hash2)); + // find txid and set serialized + return(datalen); +} + +char *gecko_txarrived(struct supernet_info *myinfo,struct iguana_info *virt,char *remoteaddr,uint8_t *serialized,int32_t datalen,bits256 txid) +{ + struct gecko_mempool *pool; int64_t txfee,vinstotal,voutstotal; uint64_t value; int32_t i,numvins,numvouts,txlen,spentheight,minconf,maxconf,unspentind; struct iguana_msgtx msg; char *rawtx; struct gecko_memtx *memtx; struct iguana_info *btcd; struct iguana_outpoint outpt; + memset(&msg,0,sizeof(msg)); + iguana_memreset(&virt->TXMEM); + txlen = iguana_rwtx(virt->chain->zcash,0,&virt->TXMEM,serialized,&msg,datalen,&txid,virt->chain->isPoS,strcmp("VPN",virt->symbol) == 0); + vinstotal = voutstotal = 0; + maxconf = virt->longestchain; + minconf = virt->chain->minconfirms; + if ( (numvins= msg.tx_in) > 0 ) + { + for (i=0; ibundlescount-1,1)) != 0 ) + { + memset(&outpt,0,sizeof(outpt)); + outpt.hdrsi = spentheight / virt->chain->bundlesize; + outpt.unspentind = unspentind; + if ( iguana_unspentavail(myinfo,virt,outpt,minconf,maxconf) != value ) + { + printf("vin.%d already spent\n",i); + return(clonestr("{\"error\":\"gecko tx has double spend\"}")); + } + vinstotal += value; + } + } + } + if ( (numvouts= msg.tx_out) > 0 ) + for (i=0; imempool) == 0 ) + pool = virt->mempool = gecko_mempool_alloc(0); + rawtx = calloc(1,datalen*2 + 1); + init_hexbytes_noT(rawtx,serialized,datalen); + if ( (memtx= gecko_mempool_txadd(myinfo,virt,virt->blocks.hwmchain.height,rawtx,(uint32_t)calc_ipbits(remoteaddr),0)) != 0 ) + { + for (i=0; inumtx; i++) + { + if ( memtx->feeperkb >= pool->txs[i]->feeperkb ) + break; + } + pool->txs[pool->numtx++] = pool->txs[i]; + pool->txs[i] = memtx; + char str[65]; printf("add tx.%s to mempool i.%d numtx.%d\n",bits256_str(str,memtx->txid),i,pool->numtx); + for (i=0; inumtx; i++) + pool->txids[i] = pool->txs[i]->txid; + if ( (btcd= iguana_coinfind("BTCD")) != 0 && btcd->FULLNODE != 0 && myinfo->IAMRELAY != 0 ) + gecko_mempool_sync(myinfo,virt,pool->txids,pool->numtx); + } + else + { + free(rawtx); + return(clonestr("{\"error\":\"geckotx invalid\"}")); + } + free(rawtx); + return(clonestr("{\"result\":\"gecko tx queued\"}")); +} + +char *basilisk_respond_geckotx(struct supernet_info *myinfo,char *CMD,void *addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 txid,int32_t from_basilisk) +{ + bits256 checktxid; char *symbol; struct iguana_info *virt; + if ( data != 0 && datalen != 0 && (symbol= jstr(valsobj,"symbol")) != 0 && (virt= iguana_coinfind(symbol)) != 0 ) + { + checktxid = bits256_doublesha256(0,data,datalen); + if ( bits256_cmp(txid,checktxid) == 0 ) + return(gecko_txarrived(myinfo,virt,addr,data,datalen,txid)); + else return(clonestr("{\"error\":\"geckotx mismatched txid\"}")); + } + return(clonestr("{\"error\":\"no geckotx chain or missing tx data\"}")); +} + +struct gecko_memtx **gecko_mempool_txptrs(struct supernet_info *myinfo,struct iguana_info *virt,int64_t *rewardp,int32_t *txn_countp,void **ptrp,void *space,int32_t max,int32_t height) +{ + int32_t i,n; struct gecko_memtx **txptrs; struct gecko_mempool *pool; int64_t txfees = 0,reward = virt->chain->initialreward; + if ( virt->chain->halvingduration != 0 && (n= (height / virt->chain->halvingduration)) != 0 ) + { + for (i=0; i>= 1; + } + *ptrp = 0; + *txn_countp = 0; + if ( (pool= virt->mempool) == 0 ) + pool = virt->mempool = gecko_mempool_alloc(0); + if ( pool->numtx*sizeof(char *) <= max ) + txptrs = space; + else + { + txptrs = calloc(pool->numtx,sizeof(char *)); + *ptrp = (void *)txptrs; + } + for (i=n=0; inumtx; i++) + { + if ( pool->txs[i]->pending == 0 ) + { + txfees += pool->txs[i]->txfee; + txptrs[n++] = pool->txs[i]; + pool->txs[i]->pending = height; + } + } + *rewardp = (reward + txfees); + if ( n > 0 ) + printf("reward %.8f n.%d numtx.%d\n",dstr(*rewardp),n,pool->numtx); + if ( (*txn_countp= n) != 0 ) + return(txptrs); + else return(0); +} + +char *gecko_mempoolarrived(struct supernet_info *myinfo,struct iguana_info *virt,char *remoteaddr,uint8_t *data,int32_t datalen,bits256 hash2) +{ + int32_t i,j,numother,len = 0; struct gecko_mempool *otherpool; bits256 txid; + if ( (otherpool= gecko_mempoolfind(myinfo,virt,&numother,(uint32_t)calc_ipbits(remoteaddr))) != 0 ) + { + if ( numother > 0 ) + { + for (i=0; inumtx; j++) + if ( bits256_cmp(txid,otherpool->txids[j]) == 0 ) + break; + if ( j == otherpool->numtx ) + { + otherpool->txids[otherpool->numtx++] = txid; + printf("if first time, submit request for txid\n"); + } + } + } + } + return(clonestr("{\"result\":\"gecko mempool queued\"}")); +} + +char *basilisk_respond_mempool(struct supernet_info *myinfo,char *CMD,void *_addr,char *remoteaddr,uint32_t basilisktag,cJSON *valsobj,uint8_t *data,int32_t datalen,bits256 hash,int32_t from_basilisk) +{ + char *symbol; struct iguana_info *virt; + printf("got getmempool request\n"); + if ( (symbol= jstr(valsobj,"symbol")) != 0 && (virt= iguana_coinfind(symbol)) != 0 ) + return(gecko_mempoolarrived(myinfo,virt,_addr,data,datalen,hash)); + else return(clonestr("{\"error\":\"couldt find gecko chain\"}")); +} diff --git a/gecko/gecko_miner.c b/gecko/gecko_miner.c new file mode 100755 index 000000000..f77193f93 --- /dev/null +++ b/gecko/gecko_miner.c @@ -0,0 +1,423 @@ +/****************************************************************************** + * Copyright © 2014-2016 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +// included from gecko.c + +uint32_t gecko_earliest_blocktime(int32_t estblocktime,uint32_t prevtimestamp) +{ + uint32_t timestamp,now = (uint32_t)time(NULL); + if ( prevtimestamp == 0 ) + prevtimestamp = now; + timestamp = (prevtimestamp + ((estblocktime << 1) / 3)); + if ( timestamp <= prevtimestamp ) + timestamp = prevtimestamp + 1; + return(timestamp); +} + +int32_t gecko_blocknonce_verify(struct iguana_info *virt,uint8_t *serialized,int32_t datalen,uint32_t nBits,uint32_t timestamp,uint32_t prevtimestamp) +{ + bits256 threshold,hash2; + //printf("time.%u prev.%u\n",timestamp,prevtimestamp); + if ( timestamp != 0 && prevtimestamp != 0 ) + { + if ( prevtimestamp != 0 && timestamp < gecko_earliest_blocktime(virt->chain->estblocktime,prevtimestamp) ) + { + printf("reject timestamp prev.%u %u earliest.%u\n",prevtimestamp,timestamp,gecko_earliest_blocktime(virt->chain->estblocktime,prevtimestamp)); + return(-1); + } + if ( timestamp > time(NULL) + GECKO_MAXFUTUREBLOCK ) + { + printf("reject future timestamp.%u vs %u\n",timestamp,(uint32_t)time(NULL)); + return(-1); + } + } + if ( nBits >= GECKO_EASIESTDIFF ) + nBits = GECKO_EASIESTDIFF; + threshold = bits256_from_compact(nBits); + hash2 = iguana_calcblockhash(virt->symbol,virt->chain->hashalgo,serialized,datalen); + if ( bits256_cmp(threshold,hash2) > 0 ) + { + //printf("nonce worked crc.%x\n",calc_crc32(0,serialized,datalen)); + return(1); + } + else + { + char str[65],str2[65]; + printf("nonce failed crc.%x nBits.%08x %s vs %s\n",calc_crc32(0,serialized,datalen),nBits,bits256_str(str,threshold),bits256_str(str2,hash2)); + } + return(-1); +} + +uint32_t gecko_nBits(struct iguana_info *virt,uint32_t *prevtimestampp,struct iguana_block *block,int32_t n) +{ + uint32_t nBits = GECKO_DEFAULTDIFF,starttime,endtime,est; struct iguana_block *prev=0; int32_t i,diff; bits256 targetval; + *prevtimestampp = 0; + if ( virt->chain->estblocktime == 0 ) + return(GECKO_EASIESTDIFF); + for (i=0; iRO.prev_block)) == 0 || prev->height == 0 ) + { + i++; + break; + } + if ( i == 0 ) + { + *prevtimestampp = endtime = prev->RO.timestamp; + nBits = prev->RO.bits; + } + starttime = prev->RO.timestamp; + block = prev; + } + if ( starttime != 0 && endtime > starttime && i > 1 ) + { + diff = (endtime - starttime); + est = virt->chain->estblocktime * i; + targetval = bits256_from_compact(nBits); + if ( diff > est ) + { + targetval = bits256_ave(targetval,bits256_ave(targetval,bits256_rshift(targetval))); + } + else if ( diff < est ) + { + if ( nBits == GECKO_EASIESTDIFF ) + return(GECKO_EASIESTDIFF); + targetval = bits256_ave(targetval,bits256_ave(targetval,bits256_lshift(targetval))); + } + //printf("diff.%d est.%d nBits.%08x <- %08x\n",diff,virt->chain->estblocktime * i,bits256_to_compact(targetval),nBits); + nBits = bits256_to_compact(targetval); + } + if ( nBits > GECKO_EASIESTDIFF ) + { + //printf("nBits.%08x vs easiest %08x\n",nBits,GECKO_EASIESTDIFF); + nBits = GECKO_EASIESTDIFF; + } + return(nBits); +} + +int32_t gecko_delayedPoW(struct supernet_info *myinfo,struct iguana_info *btcd,int32_t isPoS,uint8_t *coinbase,bits256 *btcdhashp,uint32_t timestamp,int32_t height) +{ + int32_t len = 0; //bits256 btchash; + memset(btcdhashp,0,sizeof(*btcdhashp)); + len += iguana_rwnum(1,&coinbase[len],sizeof(height),(void *)&height); + coinbase[len++] = 0; + if ( (isPoS & 7) != 0 ) + { + /**btcdhashp = gecko_hashstampscalc(myinfo,btcd,&btchash,timestamp); + if ( (isPoS & 2) != 0 && (bits256_cmp(*btcdhashp,GENESIS_PUBKEY) == 0 || bits256_nonz(*btcdhashp) == 0) ) + return(-1); + if ( (isPoS & 4) != 0 && (bits256_cmp(btchash,GENESIS_PUBKEY) == 0 || bits256_nonz(btchash) == 0) ) + return(-1);*/ + //len += iguana_rwbignum(1,&coinbase[len],sizeof(*btcdhashp),btcdhashp->bytes); + //len += iguana_rwbignum(1,&coinbase[len],sizeof(btchash),btchash.bytes); + } + return(len); +} + +int32_t iguana_coinbase(int32_t isPoS,uint32_t txversion,uint8_t *serialized,uint32_t timestamp,bits256 prev_hash,uint8_t *coinbasescript,uint32_t coinbaselen,uint8_t *minerpayment,uint32_t minerpaymentlen,int64_t blockreward,bits256 *txidp) +{ + int32_t len = 0,rwflag=1; uint32_t prev_vout,sequence,lock_time; char txidstr[65]; struct iguana_msgtx msg; + memset(&msg,0,sizeof(msg)); + msg.tx_out = (blockreward > 0) ? 1 : 0; + msg.tx_in = 1; + sequence = prev_vout = -1; + lock_time = 0; + msg.version = txversion; + msg.timestamp = timestamp; + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg.version),&msg.version); + if ( isPoS != 0 ) + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg.timestamp),&msg.timestamp); + { + len += iguana_rwvarint32(rwflag,&serialized[len],&msg.tx_in); + // tx_in times + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(prev_hash),prev_hash.bytes); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(prev_vout),&prev_vout); + len += iguana_rwvarint32(rwflag,&serialized[len],&coinbaselen); + len += iguana_rwmem(rwflag,&serialized[len],coinbaselen,coinbasescript); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(sequence),&sequence); + } + { + len += iguana_rwvarint32(rwflag,&serialized[len],&msg.tx_out); + // tx_out times + if ( msg.tx_out > 0 ) + { + len += iguana_rwnum(rwflag,&serialized[len],sizeof(blockreward),&blockreward); + len += iguana_rwvarint32(rwflag,&serialized[len],&minerpaymentlen); + len += iguana_rwmem(rwflag,&serialized[len],minerpaymentlen,minerpayment); + } + } + len += iguana_rwnum(rwflag,&serialized[len],sizeof(lock_time),&lock_time); + *txidp = bits256_doublesha256(txidstr,serialized,len); + return(len); +} + +char *gecko_coinbasestr(struct supernet_info *myinfo,struct iguana_info *virt,bits256 *txidp,uint32_t timestamp,uint8_t *minerpubkey,uint64_t blockreward,uint8_t *data,int32_t datalen,bits256 coinbasespend) +{ + char *rawtx=0; uint8_t minerpayment[512],serialized[8192]; int32_t minerpaymentlen=0,len=0; + if ( blockreward > 0 ) + minerpaymentlen = bitcoin_pubkeyspend(minerpayment,0,minerpubkey); + len = iguana_coinbase(virt->chain->isPoS,virt->chain->normal_txversion,serialized,timestamp,coinbasespend,data,datalen,minerpayment,minerpaymentlen,blockreward,txidp); + if ( len > 0 ) + { + rawtx = malloc(len*2 + 1); + init_hexbytes_noT(rawtx,serialized,len); + } + return(rawtx); +} + +char *gecko_blockconstruct(struct supernet_info *myinfo,struct iguana_info *virt,struct iguana_block *newblock,uint32_t *noncep,struct gecko_memtx **txptrs,int32_t txn_count,uint8_t *coinbase,int32_t coinbaselen,bits256 coinbasespend,double expiration,uint8_t *minerpubkey,int64_t blockreward) +{ + struct iguana_info *btcd; uint8_t serialized[sizeof(*newblock)],space[16384]; int32_t i,n,len,totaltxlen=0; char *coinbasestr,str[65],str2[65],*blockstr=0; bits256 *txids=0,txspace[256],threshold,hash2; struct gecko_memtx *memtx; + if ( (btcd= iguana_coinfind("BTCD")) == 0 ) + { + printf("basilisk needs BTCD\n"); + return(0); + } + if ( txn_count+2 < sizeof(space)/sizeof(*space) ) + { + txids = txspace; + memset(txids,0,sizeof(*txids) * (txn_count+2)); + } else txids = calloc(txn_count+2,sizeof(*txids)); + if ( txn_count > 0 ) + { + for (i=0; idatalen; + txids[i + 1] = memtx->txid; + printf("memtxid.%s\n",bits256_str(str,memtx->txid)); + } + } + } + if ( (coinbasestr= gecko_coinbasestr(myinfo,virt,&txids[0],newblock->RO.timestamp,minerpubkey,blockreward,coinbase,coinbaselen,coinbasespend)) != 0 ) + { + newblock->RO.merkle_root = iguana_merkle(txids,txn_count + 1); + newblock->RO.txn_count = (txn_count + 1); + if ( txn_count > 0 ) + { + printf("%s %s\n",bits256_str(str,txids[0]),bits256_str(str2,txids[1])); + } + if ( newblock->RO.bits >= GECKO_EASIESTDIFF ) + newblock->RO.bits = GECKO_EASIESTDIFF; + threshold = bits256_from_compact(newblock->RO.bits); + if ( (newblock->RO.nonce= *noncep) == 0 ) + { + struct iguana_msgblock msg; + memset(&msg,0,sizeof(msg)); + msg.H.version = newblock->RO.version; + msg.H.prev_block = newblock->RO.prev_block; + msg.H.merkle_root = newblock->RO.merkle_root; + msg.H.timestamp = newblock->RO.timestamp; + msg.H.bits = newblock->RO.bits; + for (i=0; ichain,&hash2,serialized,newblock); + //char str[65]; printf("nonce.%08x %s\n",newblock->RO.nonce,bits256_str(str,newblock->RO.hash2)); + len = iguana_rwblockhdr(1,virt->chain->zcash,serialized,&msg); + hash2 = iguana_calcblockhash(virt->symbol,virt->chain->hashalgo,serialized,len); + if ( bits256_cmp(threshold,hash2) > 0 ) + { + //printf("FOUND NONCE %d iterations\n",i+1); + newblock->RO.hash2 = hash2; + break; + } + if ( newblock->height != 0 && OS_milliseconds() > expiration ) + { + //printf("time limit exceeded %u %d iterations\n",virt->blocks.hwmchain.RO.timestamp,i+1); + free(coinbasestr); + if ( txids != txspace ) + free(txids); + return(0); + } + } + } + newblock->RO.nonce = *noncep; + n = iguana_serialize_block(virt->chain,&newblock->RO.hash2,serialized,newblock); + while ( 1 && time(NULL) <= newblock->RO.timestamp + GECKO_MAXFUTUREBLOCK ) + { + //printf("wait for block to be close enough to now: lag %ld\n",time(NULL) - newblock->RO.timestamp); + sleep(1); + } + //if ( gecko_blocknonce_verify(virt,serialized,n,newblock->RO.bits,newblock->RO.timestamp,virt->blocks.hwmchain.RO.timestamp) >= 0 ) + if ( bits256_cmp(threshold,newblock->RO.hash2) > 0 ) + { + blockstr = calloc(1,strlen(coinbasestr) + (totaltxlen+n)*2 + 1); + init_hexbytes_noT(blockstr,serialized,n); + printf("block.(%s) coinbase.(%s) lens.%ld\n",blockstr,coinbasestr,(strlen(blockstr)+strlen(coinbasestr))/2); + strcat(blockstr,coinbasestr); + len = (int32_t)strlen(blockstr); + for (i=0; idatalen); + len += memtx->datalen << 1; + printf(" txi.%d (%s)\n",i,&blockstr[len]); + } + } + } else printf("nonce failure\n"); + free(coinbasestr); + } + if ( txids != txspace ) + free(txids); + return(blockstr); +} + +char *gecko_createblock(struct supernet_info *myinfo,int32_t estblocktime,uint32_t prevtimestamp,struct iguana_info *btcd,int32_t isPoS,struct iguana_block *newblock,char *symbol,struct gecko_memtx **txptrs,int32_t txn_count,int32_t maxmillis,uint8_t *minerpubkey,int64_t blockreward) +{ + bits256 btcdhash; uint8_t coinbase[512]; int32_t coinbaselen; uint32_t nonce; double expiration = OS_milliseconds() + maxmillis; + //char str[65]; printf("create prev.(%s) %p\n",bits256_str(str,newblock->RO.prev_block),&newblock->RO.prev_block); + if ( btcd != 0 ) + { + newblock->RO.timestamp = gecko_earliest_blocktime(estblocktime,prevtimestamp); + if ( (coinbaselen= gecko_delayedPoW(myinfo,btcd,isPoS,coinbase,&btcdhash,newblock->RO.timestamp,newblock->height)) < 0 ) + { + printf("error generating coinbase for height.%d\n",newblock->height); + return(0); + } + nonce = 0; + return(gecko_blockconstruct(myinfo,btcd,newblock,&nonce,txptrs,txn_count,coinbase,coinbaselen,btcdhash,expiration,minerpubkey,blockreward)); + } else return(0); +} + +cJSON *gecko_paymentsobj(struct supernet_info *myinfo,cJSON *txjson,cJSON *valsobj,int32_t reusedaddrs) +{ + cJSON *item,*array; char *coinaddr; uint64_t satoshis; uint8_t addrtype,pubkey33[33],rmd160[20],outputscript[512]; int32_t i,n,scriptlen; uint32_t locktime,txversion; struct iguana_waddress *waddr; struct iguana_waccount *wacct; + locktime = jint(valsobj,"locktime"); + if ( (txversion= juint(valsobj,"txversion")) == 0 ) + txversion = (locktime == 0) ? IGUANA_NORMAL_TXVERSION : IGUANA_LOCKTIME_TXVERSION; + if ( txjson == 0 ) + txjson = bitcoin_txcreate(1,locktime,txversion); + if ( (array= jarray(&n,valsobj,"payments")) != 0 && n > 0 ) + { + for (i=0; i 0 ) + { + printf("payment.%s <- %.8f\n",coinaddr,dstr(satoshis)); + bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr); + scriptlen = 0; + if ( reusedaddrs == 0 ) + { + if ( (waddr= iguana_waddresssearch(myinfo,&wacct,coinaddr)) != 0 ) + { + if ( bitcoin_pubkeylen(waddr->pubkey) > 0 ) + scriptlen = bitcoin_pubkeyspend(outputscript,0,pubkey33); + } + } + if ( scriptlen == 0 ) + scriptlen = bitcoin_standardspend(outputscript,0,rmd160); + bitcoin_txoutput(txjson,outputscript,scriptlen,satoshis); + } + } + } + return(txjson); +} + +int32_t gecko_blocksubmit(struct supernet_info *myinfo,struct iguana_info *btcd,struct iguana_info *virt,char *blockstr,bits256 hash2,int32_t height) +{ + uint8_t *data,space[16384],*allocptr=0; int32_t i,len,numranked=0; struct iguana_peers *peers; struct iguana_peer *addr; + //printf("submit.(%s)\n",blockstr); + if ( (peers= virt->peers) == 0 || (numranked= peers->numranked) <= 0 ) + { + if ( basilisk_blocksubmit(myinfo,btcd,virt,0,blockstr,hash2,height) < 0 )//(NUMRELAYS >> 1) ) + return(-1); + } + else // physical node for geckochain + { + if ( (data= get_dataptr(sizeof(struct iguana_msghdr),&allocptr,&len,space,sizeof(space),blockstr)) != 0 ) + { + for (i=0; iranked[i]) != 0 && addr->usock >= 0 && addr->supernet != 0 ) + iguana_queue_send(addr,0,data,"block",len); + } + } + if ( allocptr != 0 ) + free(allocptr); + } + return(0); +} + +void gecko_miner(struct supernet_info *myinfo,struct iguana_info *btcd,struct iguana_info *virt,int32_t maxmillis,uint8_t *minerpubkey33) +{ + struct iguana_zblock newblock; uint32_t prevtimestamp,nBits; int64_t reward = 0; int32_t txn_count; char *blockstr,*space[256]; struct gecko_memtx **txptrs; void *ptr; //struct iguana_bundle *bp; +#ifndef __APPLE__ + int32_t i,gap; + if ( virt->virtualchain == 0 || RELAYID < 0 || NUMRELAYS < 1 ) + { + //printf("skip non-virtual chain.%s\n",virt->symbol); + return; + } + if ( virt->blocks.hwmchain.height < virt->longestchain-1 ) + return; + if ( (virt->blocks.hwmchain.height % NUMRELAYS) != RELAYID ) + { + //if ( NUMRELAYS < 3 ) + // return; + gap = (int32_t)(time(NULL) - virt->blocks.hwmchain.RO.timestamp) / 60;//virt->chain->estblocktime; + for (i=0; iblocks.hwmchain.height+i) % NUMRELAYS) == RELAYID ) + break; + } + if ( i == gap ) + return; + printf("backup block generator RELAYID.%d gap.%d ht.%d i.%d num.%d\n",RELAYID,gap,virt->blocks.hwmchain.height,i,NUMRELAYS); + } +#endif + /*if ( virt->newblockstr != 0 ) + { + gecko_blocksubmit(myinfo,btcd,virt,virt->newblockstr,virt->newblock.RO.hash2,virt->newblock.height); + memset(&virt->newblock,0,sizeof(virt->newblock)); + free(virt->newblockstr); + virt->newblockstr = 0; + return; + }*/ + memset(&newblock,0,sizeof(newblock)); + newblock.height = virt->blocks.hwmchain.height + 1; + newblock.RO.prev_block = virt->blocks.hwmchain.RO.hash2; + newblock.RO.version = GECKO_DEFAULTVERSION; + newblock.RO.allocsize = iguana_ROallocsize(virt); + if ( (nBits= gecko_nBits(virt,&prevtimestamp,(void *)&newblock,GECKO_DIFFITERS)) != 0 ) + { + if ( (newblock.RO.bits= nBits) > GECKO_EASIESTDIFF ) + newblock.RO.bits = GECKO_EASIESTDIFF; + char str[65]; printf("mine.%s %s nBits.%x ht.%d maxmillis.%d\n",virt->symbol,bits256_str(str,bits256_from_compact(newblock.RO.bits)),nBits,newblock.height,maxmillis); + txptrs = gecko_mempool_txptrs(myinfo,virt,&reward,&txn_count,&ptr,space,(int32_t)(sizeof(space)/sizeof(*space)),newblock.height); + //char str[65]; printf("HWM.%s %p\n",bits256_str(str,newblock.RO.prev_block),&newblock.RO.prev_block); + if ( (blockstr= gecko_createblock(myinfo,virt->chain->estblocktime,prevtimestamp,btcd,virt->chain->isPoS,(void *)&newblock,virt->symbol,txptrs,txn_count,maxmillis,minerpubkey33,reward)) != 0 ) + { + char str[65]; + printf("tx0.%s\n",bits256_str(str,newblock.RO.merkle_root)); + printf(">>>>>>>>>>>>>>>>> MINED %s.%x %s %u %d %.8f %d\n",virt->symbol,newblock.RO.bits,bits256_str(str,newblock.RO.hash2),newblock.RO.timestamp,newblock.height,dstr(reward),newblock.RO.txn_count); + if ( gecko_blocksubmit(myinfo,btcd,virt,blockstr,newblock.RO.hash2,newblock.height) == 0 ) + free(blockstr); + else + { + //virt->newblockstr = blockstr; + //virt->newblock = newblock; + free(blockstr); + } + } else printf("didnt find %s.block\n",virt->symbol); + if ( txptrs != (void *)space ) + free(txptrs); + } +} + diff --git a/help/.tmpmarker b/help/.tmpmarker deleted file mode 100755 index e69de29bb..000000000 diff --git a/iguana/Kashi/Getnewaddress_dumpprivkey b/iguana/Kashi/Getnewaddress_dumpprivkey new file mode 100755 index 000000000..6a8a215e7 --- /dev/null +++ b/iguana/Kashi/Getnewaddress_dumpprivkey @@ -0,0 +1,12 @@ +#!/bin/bash + +echo "unlocking the wallet" +echo "" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"walletpassphrase\",\"password\":\"kashifAli!123\",\"timeout\":300}" +echo "" + +echo "Generating new address" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"getnewaddress\",\"account\":\"kashif\"}" >/tmp/newAddresses +echo "" + ./json_extract /tmp/newAddresses address + diff --git a/iguana/Kashi/Reg_bitcoinRPCs b/iguana/Kashi/Reg_bitcoinRPCs new file mode 100755 index 000000000..5c8b0bdf5 --- /dev/null +++ b/iguana/Kashi/Reg_bitcoinRPCs @@ -0,0 +1,1034 @@ +#!/bin/bash +clear +printf "\n" +echo " ***************************************" +echo " * IGUANA *" +echo " * Automated RPC REGRESSION Testing *" +echo " * Script *" +echo " ***************************************" +printf "\n" +printf "\t\t\tTest started at %s\n\n\n" "$(date)" + + +# declaring global integer variables +declare -ix failed=0 +declare -ix passed=0 +declare -ix addr_match=0 +declare -ix addr_unmatch=0 +declare -ix addr_match_sa=0 +declare -ix addr_unmatch_sa=0 + +startCoin="BTCD" + + +# RPC START BTCD COIN +printf "Executing [RPC: startBTCD]\n" +printf "==============================\n" +~/tests/./startBTCD_p2p > /tmp/startBTCD_p2p.txt +printf "\n" + +# call json_extract script to get the RPC result value +result=$(~/tests/./json_extract /tmp/startBTCD_p2p.txt result) +error=$(~/tests/./json_extract /tmp/startBTCD_p2p.txt error) + + if [ "$result" != "coin added" ] + then + printf "RESULT_STARTBTCD_ERROR MISMATCH(result -> %s)\n" "$result" + printf "info: BTCD coin should have been added successfully!\n\n" + fi + + if [ "$result" == "coin added" ] + then + printf "RESULT_PASSED: RPC START BTCD\n\n" + let passed+=1 + rm -f /tmp/startBTCD_p2p.txt + + else + printf "RESULT_FAILED:RPC START BTCD (%s)\n\n" "$error" + let failed+=1 + fi + +# ACTIVE HANDLE RPC before WALLETPASSPHRASE +printf "\n" +sleep 3 + +printf "Executing [RPC: ACTIVEHANDLE]\n" +printf "==============================\n" + +~/tests/./activehandle > /tmp/activehandle.txt +printf "\n +" +# call json_extract script to get the RPC status value +Wstatus=$(~/tests/./json_extract /tmp/activehandle.txt status) +err_ah=$(~/tests/./json_extract /tmp/activehandle.txt error) + + if [ "$Wstatus" != "locked" ] + then + printf "RESULT_ACTIVEHANDLE_ERROR MISMATCH(STATUS -> %s)\n" "$Wstatus" + printf "info: wallet should be \n\n" + fi + + if [ "$Wstatus" == "locked" ] + then + printf "RESULT_PASSED: RPC ACTIVEHANDLE\n\n" + let passed+=1 + rm -f /tmp/activehandle.txt + + else + printf "RESULT_FAILED: RPC ACTIVEHANDLE (%s)\n\n" "$err_ah" + let failed+=1 + fi + +# GETINFO RPC +sleep 3 +printf "\n" + +printf "Executing [RPC: GETINFO]\n" +printf "==============================\n" + +~/tests/./getinfo > /tmp/getinfo.txt +printf "\n" + +# call json_extract script to get the RPC status value +r_getinfo=$(~/tests/./json_extract /tmp/getinfo.txt result) +err_getinfo=$(~/tests/./json_extract /tmp/getinfo.txt error) + + if [ "$r_getinfo" == "success" ] + then + printf "RESULT_PASSED: RPC GET INFO\n\n" + let passed+=1 + rm -f /tmp/getinfo.txt + + else + printf "RESULT_FAILED: RPC GET INFO(%s)\n\n" "$err_getinfo" + let failed+=1 + fi + +# ENCRYPTWALLET RPC +sleep 3 +printf "\n" + +printf "Executing [RPC: ENCRYPTWALLET]\n" +printf "==================================\n" + +~/tests/./encryptwallet_SP > /tmp/encryptwallet_SP +printf "\n" + +# call json_extract script to get the RPC status & result values +r_ew=$(~/tests/./json_extract /tmp/encryptwallet_SP result) +s_ew=$(~/tests/./json_extract /tmp/encryptwallet_SP status) +err_ew=$(~/tests/./json_extract /tmp/encryptwallet_SP error) + + if [ "$s_ew" != "unlocked" ] + then + printf "RESULT_ENCRYPTWALLET_ERROR MISMATCH(STATUS -> %s)\n" "$s_ew" + printf "info: wallet should have \n\n" + fi + + if [ "$r_ew" == "success" ] && [ "$s_ew" == "unlocked" ] + then + printf "RESULT_PASSED: RPC ENCRYPTWALLET\n\n" + let passed+=1 + rm -f /tmp/encryptwallet_SP + + else + printf "RESULT_FAILED: RPC ENCRYPTWALLET (%s)\n\n" "$err_ew" + let failed+=1 + + fi + +# WALLETPASSPHRASE RPC +sleep 3 +printf "\n" + +printf "Executing [RPC: WALLETPASSPHRASE]\n" +printf "==============================\n" + +~/tests/./walletpassphrase_WVP > /tmp/walletpassphrase_WVP +printf "\n" + +# call json_extract script to get the RPC status & result values +r_wpp=$(~/tests/./json_extract /tmp/walletpassphrase_WVP result) +s_wpp=$(~/tests/./json_extract /tmp/walletpassphrase_WVP status) +err_wpp=$(~/tests/./json_extract /tmp/walletpassphrase_WVP error) + + if [ "$s_wpp" != "unlocked" ] + then + printf "RESULT_WALLETPASSPHRASE_ERROR MISMATCH(STATUS -> %s)\n" "$s_wpp" + printf "info: wallet should be \n" + fi + + + if [ "$r_wpp" == "success" ] && [ "$s_wpp" == "unlocked" ] + then + printf "RESULT_PASSED: RPC WALLETPASSPHRASE\n\n" + let passed+=1 + rm -f /tmp/walletpassphrase_WVP + + else + printf "RESULT_FAILED: RPC WALLETPASSPHRASE (%s)\n\n" "$err_wpp" + let failed+=1 + fi + +# WALLETLOCK + +sleep 3 +printf "\n" + +printf "Executing [RPC: WALLETLOCK]\n" +printf "==============================\n" + +result=$(~/tests/./walletlock) +printf "\n" + + + if [ "$result" != "success" ] + then + printf "RESULT_WALLETLOCK_ERROR MISMATCH(STATUS -> %s)\n" "$result" + printf "info: wallet should be \n\n" + fi + + + if [ "$result" == "success" ] + then + printf "RESULT_PASSED: RPC WALLETLOCK\n\n" + let passed+=1 + + else + printf "RESULT_FAILED: RPC WALLETLOCK (%s)\n\n" "$result" + let failed+=1 + fi + + +# WALLETPASSPHRASE RPC +sleep 3 +printf "\n" + +printf "Executing [RPC: WALLETPASSPHRASE]\n" +printf "==============================\n" + +~/tests/./walletpassphrase_WVP > /tmp/walletpassphrase_WVP +printf "\n" + +# call json_extract script to get the RPC status & result values +r_wpp=$(~/tests/./json_extract /tmp/walletpassphrase_WVP result) +s_wpp=$(~/tests/./json_extract /tmp/walletpassphrase_WVP status) +err_wpp=$(~/tests/./json_extract /tmp/walletpassphrase_WVP error) + + if [ "$s_wpp" != "unlocked" ] + then + printf "RESULT_WALLETPASSPHRASE_ERROR: MISMATCH(STATUS -> %s)\n" "$s_wpp" + printf "info: wallet should be \n\n" + fi + + + if [ "$r_wpp" == "success" ] && [ "$s_wpp" == "unlocked" ] + then + printf "RESULT_PASSED: RPC WALLETPASSPHRASE\n\n" + rm -f /tmp/walletpassphrase_WVP + + else + printf "RESULT_FAILED: RPC WALLETPASSPHRASE (%s)\n\n" "$err_wpp" + fi + + + +# CHECKWALLET RPC +sleep 3 +printf "\n" + +printf "Executing [RPC: CEHCKWALLET]\n" +printf "==============================\n" + +~/tests/./checkwallet > /tmp/checkwallet +printf "\n" + +# call json_extract script to get the RPC status & result values +b_cw=$(~/tests/./json_extracti /tmp/checkwallet bad) +err_cw=$(~/tests/./json_extracti /tmp/checkwallet error) + +if [ "$b_cw" -ne 0 ] + then + printf "RESULT_CHECKWALLET_ERROR MISMATCH(BAD -> %d)\n" "$b_cw" + printf "info: bad should be <0>\n\n" +fi + + if [ "$b_cw" -eq 0 ] + then + printf "RESULT_PASSED: RPC CHECKWALLET\n\n" + let passed+=1 + rm -f /tmp/checkwallet + + else + printf "RESULT_FAILED: ERROR: %s\n\n" + let failed+=1 + fi + + +# ACTIVE HANDLE RPC after WALLETPASSPHRASE +printf "\n" +sleep 3 + +printf "Executing [RPC: ACTIVEHANDLE]\n" +printf "==============================\n" + +~/tests/./activehandle > /tmp/activehandle.txt +printf "\n +" +# call json_extract script to get the RPC status value +Wstatus=$(~/tests/./json_extract /tmp/activehandle.txt status) +err_ah=$(~/tests/./json_extract /tmp/activehandle.txt error) + + if [ "$Wstatus" != "unlocked" ] + then + printf "RESULT_ACTIVEHANDLE_ERROR MISMATCH(STATUS -> %s)\n" "$Wstatus" + printf "info: Wallet should have \n\n" + fi + + + if [ "$Wstatus" == "unlocked" ] + then + printf "RESULT_PASSED: RPC ACTIVEHANDLE\n\n" + let passed+=1 + rm -f /tmp/activehandle.txt + + else + printf "RESULT_FAILED: RPC ACTIVEHANDLE(%s)\n\n" "$err_ah" + let failed+=1 + fi + + + +# WALLETPASSPHRASE RPC +sleep 3 +printf "\n" + +printf "Executing [RPC: WALLETPASSPHRASE]\n" +printf "==============================\n" + +~/tests/./walletpassphrase_WVP > /tmp/walletpassphrase_WVP +printf "\n" + +# call json_extract script to get the RPC status & result values +r_wpp=$(~/tests/./json_extract /tmp/walletpassphrase_WVP result) +s_wpp=$(~/tests/./json_extract /tmp/walletpassphrase_WVP status) +err_wpp=$(~/tests/./json_extract /tmp/walletpassphrase_WVP error) + + if [ "$s_wpp" != "unlocked" ] + then + printf "RESULT_WALLETPASSPHRASE_ERROR (STATUS -> %s)\n" "$s_wpp" + printf "info: wallet should be \n\n" + fi + + + if [ "$r_wpp" == "success" ] && [ "$s_wpp" == "unlocked" ] + then + printf "RESULT_PASSED: RPC WALLETPASSPHRASE\n\n" + let passed+=1 + rm -f /tmp/walletpassphrase_WVP + + else + printf "RESULT_FAILED: RPC WALLETPASSPHRASE (%s)\n\n" "$err_wpp" + let failed+=1 + fi + + +# BACKUPWALLET RPC +sleep 3 +printf "\n" + +printf "Executing [RPC: BACKUPWALLET]\n" +printf "=================================\n" + +~/tests/./backupwallet > /tmp/backupwallet +printf "\n" + +# call json_extract script to get the RPC status value +r_bw=$(~/tests/./json_extract /tmp/backupwallet result) +err_bw=$(~/tests/./json_extract /tmp/backupwallet error) + + + if [ "$r_bw" != "wallet backup saved" ] + then + printf "RESULT_BACKUPWALLET_ERROR MISMATCH (RESULT -> %s)\n" "$r_bw" + printf "info: wallet backup should be \n\n" + fi + + if [ "$r_bw" == "wallet backup saved" ] + then + printf "RESULT_PASSED: RPC BACKUPWALLET\n\n" + let passed+=1 + rm -f /tmp/walletpassphrase_WVP + + else + printf "RESULT_FAILED: RPC BACKUPWALLET (%s)\n" "$err_bw" + let failed+=1 + fi + + +#GETACCOUNTADDRESS RPC +sleep 3 +printf "\n" + +printf "Executing [RPC: GETACCOUNTADDRESS]\n" +printf "=====================================\n" + +~/tests/./getaccountaddress_WVA > /tmp/getaccountaddress_WVA +printf "\n" + +# call json_extract script to get the RPC status value +addr_gaa=$(~/tests/./json_extract /tmp/getaccountaddress_WVA address) +acc_gaa=$(~/tests/./json_extract /tmp/getaccountaddress_WVA account) +pkey_gaa=$(~/tests/./json_extract /tmp/getaccountaddress_WVA pubkey) +r_gaa=$(~/tests/./json_extract /tmp/getaccountaddress_WVA result) +err_gaa=$(~/tests/./json_extract /tmp/getaccountaddress_WVA error) + + +if [ "$acc_gaa" != "IGUANA" ] +then + printf "RESULT_GETACCOUNTADDRESS_ERROR MISMATCH (ACCOUNT -> %s)\n" "$acc_gaa" + printf "info: Account should be created!\n\n" +fi + + + if [ "$acc_gaa" == "IGUANA" ] && [ "$r_gaa" == "success" ] + then + printf "RESULT_PASSED: RPC GETACCOUNTADDRESS\n\n" + let passed+=1 + rm -f /tmp/getaccountaddress_WVA + + else + printf "RESULT_FAILED: RPC GETACCOUNTADDRESS (ERROR:%s\n)" "$err_gaa" + let failed+=1 + fi + + +#GETACCOUNT RPC +sleep 3 +printf "\n" + +printf "Executing [RPC: GETACCOUNT]\n" +printf "==============================\n" + +curl -s --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"getaccount\",\"address\":\"$addr_gaa\"}" > /tmp/getaccount +printf "\n" + +# call json_extract script to get the RPC status value +acc_ga=$(~/tests/./json_extract /tmp/getaccount account) +r_ga=$(~/tests/./json_extract /tmp/getaccount result) +err_ga=$(~/tests/./json_extract /tmp/getaccount error) + + if [ "$acc_ga" != "$acc_gaa" ] + then + printf "RESULT_GETACCOUNT_ERROR MISMATCH(ACCOUNT -> %s)\n" "$acc_ga" + printf "info: account name should be \n\n" + fi + + if [ "$acc_ga" == "$acc_gaa" ] && [ "$r_ga" == "success" ] + then + printf "RESULT_PASSED: RPC GETACCOUNT\n\n" + let passed+=1 + rm -f /tmp/getaccount + + else + printf "RESULT_FAILED: RPC GETACCOUNT ERROR(%s)\n" "$err_ga" + let failed+=1 + fi + +#DUMPPRIVKEY RPC +sleep 3 +printf "\n" + +printf "Executing [RPC: DUMPPRIVKEY]\n" +printf "==============================\n" + +curl -s --url "http://127.0.0.1:7778" --data "{\"method\":\"dumpprivkey\",\"params\":[\"$addr_gaa\"]}"> /tmp/dumprivkeyI +prvkey=$(cat /tmp/dumprivkeyI) +printf "\n" + + if [ "$prvkey" != "" ] + then + printf "RESULT_PASSED: RPC DUMPRIVKEY\n\n" + let passed+=1 + rm -f /tmp/dumprivkeyI + + else + printf "RESULT_FAILED: RPC DUMPPRIVKEY\n\n" + let failed+=1 + fi + + +#WIF2PRV + +sleep 3 +printf "\n" + +printf "Executing [RPC: WIF2PRV]\n" +printf "==============================\n" + +curl -s --url "http://127.0.0.1:7778" --data "{\"agent\":\"SuperNET\",\"method\":\"wif2priv\",\"wif\":\"$prvkey\"}" > /tmp/wif2prv +privkey=$(~/tests/./json_extract /tmp/wif2prv privkey) +res=$(~/tests/./json_extract /tmp/wif2prv result) +err=$(~/tests/./json_extract /tmp/wif2prv error) + + +printf "\n" + + if [ "$privkey" != "" ] && [ "$res" == "success" ] + then + printf "RESULT_PASSED: RPC WIF2PRV\n\n" + let passed+=1 + rm -f /tmp/wif2prv + + else + printf "RESULT_FAILED: RPC WIF2PRV\n\n" + printf "ERROR: %s\n" "$err" + let failed+=1 + fi + +#PRV2PUB + +sleep 3 +printf "\n" + +printf "Executing [RPC: PRV2PUB]\n" +printf "==============================\n" + +curl -s --url "http://127.0.0.1:7778" --data "{\"agent\":\"SuperNET\",\"method\":\"priv2pub\",\"privkey\":\"$privkey\",\"addrtype\":\"\"}"> /tmp/prv2pub + +secp256k1=$(~/tests/./json_extract /tmp/prv2pub secp256k1) +addr=$(~/tests/./json_extract /tmp/prv2pub result) +err1=$(~/tests/./json_extract /tmp/prv2pub error) + +printf "\n" + + if [ "$secp256k1" == "$pkey_gaa" ] + then + printf "RESULT_PASSED: PUBKEY/PRVKEY PAIRS MATCHES\n" + let passed+=1 + rm -f /tmp/prv2pub + + else + printf "RESULT_FAILED: PUBKEY/PRIVKEY PAIRS MISMATCH\n" + printf "SECP256K1\n" "$secp256k1" + printf "PUBKEY:\n" "$pkey_gaa" + printf "ERROR: %s\n" "$err1" + let failed+=1 + fi + +#VALIDATEPUBKEY + +sleep 3 +printf "\n" + +printf "Executing [RPC: VALIDATEPUBKEY]\n" +printf "==============================\n" + +curl -s --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"validatepubkey\",\"pubkey\":\"$secp256k1\"}"> /tmp/validatepubkey + +pubkey=$(~/tests/./json_extract /tmp/validatepubkey pubkey) +result=$(~/tests/./json_extract /tmp/validatepubkey result) +coin=$(~/tests/./json_extract /tmp/validatepubkey coin) +address=$(~/tests/./json_extract /tmp/validatepubkey address) +err1=$(~/tests/./json_extract /tmp/validatepubkey error) + +if [ "$pubkey" != "$secp256k1" ] +then + printf "RESULT_VALIDATEPUBKEY_ERROR MISMATCH(pubkey-> <%s>)\n" "$pubkey" + printf "info: PUBKEY should be <%s>\n\n" "$secp256k1" +fi + +if [ "$result" != "success" ] +then + printf "RESULT_VALIDATEPUBKEY_ERROR MISMATCH(result-> %s)\n" "$result" + printf "info: Result should be \n\n" +fi + +if [ "$coin" != "$startCoin" ] +then + printf "RESULT_VALIDATEPUBKEY_ERROR MISMATCH(result-> %s)\n" "$coin" + printf "info: COIN should be <%s>\n" "$startCoin" +fi + +printf "\n" + + if [ "$secp256k1" == "$pkey_gaa" ] + then + printf "RESULT_PASSED: PUBKEY/PRVKEY PAIRS MATCHES\n\n" + let passed+=1 + rm -f /tmp/prv2pub + + else + printf "RESULT_FAILED: PUBKEY/PRIVKEY PAIRS MISMATCH\n\n" + printf "ERROR: %s\n" "$err1" + let failed+=1 + fi + + + + +#GETADDRESSBYACCOUNT RPC +sleep 3 +printf "\n" + +printf "Executing [RPC: GETADDRESSBYACCOUNT]\n" +printf "========================================\n" + +curl -s --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"getaddressesbyaccount\",\"account\":\"$acc_ga\"}" > /tmp/getaddressbyaccount + +# call json_extract script to get the RPC status value +addr_gaba=$(~/tests/./json_extracta /tmp/getaddressbyaccount result) +err_gaba=$(~/tests/./json_extracta /tmp/getaddressbyaccount error) + + +#split the string based on delims[,] and get the array of addresses returned in addr_gaba + +addrs=$(echo $addr_gaba | tr "[,]" "\n") + +if [ -z "$addrs" ] +then + printf "RESULT_GETADDRESSBYACCOUNT_ERROR\n" + printf "info: address list returned by GETADDRESSBYACCOUNT RPC!\n\n" + let addr_unmatch+=1 + +else + + +for iguana_addrs in $addrs +do + +# split the address string again based on delim "" from iguana_addrs +actual_addrs=($(echo $iguana_addrs | tr -d '""')) + +# call GETACCOUNT RPC to get the account name associated with that address and match it with account created with RPC GETACCOUNTADDRESS + +curl -s --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"getaccount\",\"address\":\"$actual_addrs\"}"> /tmp/getaccount + +# call json_extract script to get the RPC status value +acc_name=$(~/tests/./json_extract /tmp/getaccount account) + + if [ "$acc_name" != "$acc_gaa" ] + then + printf "RESULT_GETACCOUNTBYADDRESS_ERROR MISMATCH(ACCOUNT -> %s\n)" "$acc_name" + printf "info: ACCOUNT name should be iguana becuase all addresses associated with IGUANA account\n\n" + fi + + if [ "$acc_name" == "$acc_gaa" ] + then + let addr_match+=1 + IGUANA_ADDR=$actual_addrs + + else + let addr_unmatch+=1 + printf "RESULT_MISMATCH_addr:%s\n" "$actual_addrs" + fi + +done +fi + +if [ "$addr_unmatch" -eq 0 ] +then + printf "RESULT_PASSED: RPC GETADDRESSBYACCOUNT\n\n" + let passed+=1 + rm -f /tmp/getaddressbyaccount +else + printf "RESULT_FAILED: RPC GETADDRESSBYACCOUNT\n\n" + let failed+=1 +fi + +#SETTX RPC +sleep 3 +printf "\n" + +printf "Executing [RPC: SETTX]\n" +printf "=====================================\n" + +~/tests/./settx > /tmp/settx +printf "\n" + +# call json_extract script to get the RPC results value +r_st=$(~/tests/./json_extracti /tmp/settx result) +err_st=$(~/tests/./json_extracti /tmp/settx error) + +if [ "$r_st" != "true" ] +then + printf "RESULT_SETTX_ERROR MISMATCH(result -> %s)\n" "$r_st" + printf "info: settx should \n\n" +fi + + if [ "$r_st" == "true" ] + then + printf "RESULT_PASSED: RPC SETTX\n\n" + let passed+=1 + rm -f /tmp/settx + + else + printf "RESULT_FAILED: RPC SETTX\n" + printf "ERROR: %s \n\n" "$err_st" + let failed+=1 + fi + +#GETBESTBLOCKHASH RPC +sleep 3 +printf "\n" + +printf "Executing [RPC: GETBESTBLOCKHASH]\n" +printf "=====================================\n" + +~/tests/./getbestblockhash > /tmp/getbestblockhash +printf "\n" + +# call json_extract script to get the RPC results value +r_gbbh=$(~/tests/./json_extract /tmp/getbestblockhash result) +err_gbbh=$(~/tests/./json_extract /tmp/getbestblockhash error) + +if [ "$r_gbbh" == "" ] +then + printf "RESULT_GETBESTBLOCKHASH_ERROR\n\n" +fi + + if [ "$r_gbbh" != "0000000000000000000000000000000000000000000000000000000000000000" ] + then + printf "RESULT_PASSED: RPC GETBESTBLOCKHASH\n\n" + let passed+=1 + rm -f /tmp/getbestblockhash + + else + printf "RESULT_FAILED: RPC GETBESTBLOCKHASH\n\n" + printf "ERROR: %s \n\n" "$err_gbbh" + let failed+=1 + fi + + +#GETBLOCKHASH RPC +sleep 3 +printf "\n" + +printf "Executing [RPC: GETBLOCKHASH]\n" +printf "=====================================\n" + +~/tests/./getblockhash > /tmp/getblockhash +printf "\n" + +# call json_extract script to get the RPC results value +r_gbh=$(~/tests/./json_extract /tmp/getblockhash result) +err_gbh=$(~/tests/./json_extract /tmp/getblockhash error) + +if [ "$r_gbh" != "50a4f738d4319ad1f437df56ec90fdfb2592b95f5508db379c41227b2cc992c0" ] +then + printf "RESULT_GETBLOCKHASH_ERROR MISMATCH (hash -> %s)\n\n" "$r_gbh" + printf "info: Hash should be <50a4f738d4319ad1f437df56ec90fdfb2592b95f5508db379c41227b2cc992c0>\n\n" +fi + + if [ "$r_gbh" == "50a4f738d4319ad1f437df56ec90fdfb2592b95f5508db379c41227b2cc992c0" ] + then + printf "RESULT_PASSED: RPC GETBLOCKHASH\n\n" + let passed+=1 + rm -f /tmp/getblockhash + + else + printf "RESULT_FAILED: RPC GETBLOCKHASH\n\n" + printf "ERROR: %s\n\n" "$err_gaa" + let failed+=1 + fi + + +#GETBLOCK RPC +printf "\n" + +printf "Executing [RPC: GETBLOCK]\n" +printf "============================\n" + +~/tests/./getblock > /tmp/getblock +printf "\n" + +# call json_extract script to get the RPC results value +r_gb=$(~/tests/./json_extract /tmp/getblock result) +bh_gb=$(~/tests/./json_extract /tmp/getblock hash) +h_gb=$(~/tests/./json_extracti /tmp/getblock height) +ver_gb=$(~/tests/./json_extracti /tmp/getblock version) +prvblock_gb=$(~/tests/./json_extract /tmp/getblock previousblockhash) +nxtblock_gb=$(~/tests/./json_extract /tmp/getblock nextblockhash) +err_gb=$(~/tests/./json_extract /tmp/getblock error) + +# get previous block header hash + +curl -s --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"getblockhash\",\"height\":\"345323\"}" > /tmp/prvblockheader + +prvbh=$(./json_extract /tmp/prvblockheader result) + +# get nex block header hash + +curl -s --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"getblockhash\",\"height\":\"345325\"}" > /tmp/nxtblockheader + +nxtbh=$(./json_extract /tmp/nxtblockheader result) + + if [ "$r_gb" != "success" ] + then + printf "RESULT_GETBLOCK_ERROR MISMATCH ( RESULT -> %s)\n" "$r_gb" + printf "info: RESULT should be \n\n" + fi + + if [ "$bh_gb" != "$r_gbh" ] + then + printf "RESULT_GETBLOCK_ERROR MISMATCH ( HASH -> %s)\n" "$bh_gb" + printf "info: HASH should be <%s>\n\n" "$r_gbh" + fi + + if [ "$h_gb" -ne 345324 ] + then + printf "RESULT_GETBLOCK_ERROR MISMATCH ( HEIGHT -> %d)\n" "$h_gb" + printf "info: Height should be <345324>\n\n" + fi + + if [ "$ver_gb" -ne 1 ] + then + printf "RESULT_GETBLOCK_ERROR MISMATCH (VERSION -> %d)\n" "$ver_gb" + printf "info: Version should be <1>\n\n" + fi + + if [ "$prvblock_gb" != "$prvbh" ] + then + printf "RESULT_GETBLOCK_ERROR MISMATCH(PRVIOUS_BLOCK -> %s)\n" "$prvblock_gb" + printf "info: Previous block should be <%s>\n\n" "$prvbh" + fi + + if [ "$nxtblock_gb" != "$nxtbh" ] + then + printf "RESULT_GETBLOCK_ERROR MISMATCH (NEXT_BLOCK -> %s)\n" "$nxtblock_gb" + printf "info: Next Block should be <%s>\n\n" "$nxtbh" + fi + + if [ "$r_gb" == "success" ] && [ "$bh_gb" == "$r_gbh" ] && [ "$h_gb" -eq 345324 ] && [ "$ver_gb" -eq 1 ] && [ "$prvblock_gb" == "$prvbh" ] && [ "$nxtblock_gb" == "$nxtbh" ] + then + printf "RESULT_PASSED: RPC GETBLOCK\n\n" + let passed+=1 + rm -f /tmp/getblock + + else + printf "RESULT_FAILED: RPC GETBLOCK\n" + printf "ERROR: %s : %s\n\n" "$err_gb" + let failed+=1 + fi + +#GETNEWADDRESS RPC +sleep 3 +printf "\n" + +printf "Executing [RPC: GETNEWADDRESS]\n" +printf "=====================================\n" + +~/tests/./getnewaddress > /tmp/getnewaddress +printf "\n" + +# call json_extract script to get the RPC results value +r_gna=$(~/tests/./json_extract /tmp/getnewaddress result) +c_gna=$(~/tests/./json_extract /tmp/getnewaddress coin) +acc_gna=$(~/tests/./json_extract /tmp/getnewaddress account) +addr_gna=$(~/tests/./json_extract /tmp/getnewaddress address) +err_gna=$(~/tests/./json_extract /tmp/getnewaddress error) + + if [ "$addr_gna" == "" ] + then + printf "RESULT_GETNEWADDRESS_ERROR MISMATCH(ADDRESS -> %s)\n" "$addr_gna" + printf "info: ADDRESS was generated!\n\n" + fi + + if [ "$acc_gna" != "IGUANA" ] + then + printf "RESULT_GETNEWADDRESS_ERROR MISMATCH (ACCOUNT -> %s)\n" "$acc_gna" + printf "info: Account name should be \n\n" + fi + + if [ "$r_gna" != "success" ] + then + printf "RESULT_GETNEWADDRESS_ERROR MISMATCH (RESULT -> %s)\n" "$r_gna" + printf "info: Result should be \n\n" + fi + + if [ "$c_gna" != "$startCoin" ] + then + printf "RESULT_GETNEWADDRESS_ERROR MISMATCH (COIN -> %s)\n" "$c_gna" + printf "info: Coin should be <%s>!\n\n" "$startCoin" + fi + + + if [ "$r_gna" == "success" ] && [ "$c_gna" == "$startCoin" ] && [ "$acc_gna" == "IGUANA" ] && [ "$addr_gna" != "" ] + then + printf "RESULT_PASSED: RPC GETNEWADDRESS\n\n" + let passed+=1 + rm -f /tmp/getnewaddress + + else + printf "RESULT_FAILED: RPC GETNEWADDRESS\n" + printf "ERROR: %s:\n\n" "$err_gna" + let failed+=1 + fi + +#SIGNMESSAGE RPC +sleep 3 +printf "\n" + +printf "Executing [RPC: SIGNMESSAGE]\n" +printf "=====================================\n" + +curl -s --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"signmessage\",\"address\":\"$addr_gna\",\"message\":\"testMessage\"}" > /tmp/signmessage +printf "\n" + +# call json_extract script to get the RPC results value +r_sm=$(~/tests/./json_extract /tmp/signmessage result) +err_sm=$(~/tests/./json_extract /tmp/signmessage error) + + if [ "$r_sm" == "" ] + then + printf "RESULT_SIGNMESSAGE_ERROR MISMATCH(result -> %s)\n" "$r_sm" + printf "info: SIGNMESSAGE was generated!\n\n" + fi + + if [ "$r_sm" != "" ] + then + printf "RESULT_PASSED: RPC SIGNMESSAGE\n\n" + let passed+=1 + rm -f /tmp/signmessage + + else + printf "RESULT_FAILED: RPC SIGNMESSAGE\n" + let failed+=1 + fi + +#VERIFYMESSAGE RPC +sleep 3 +printf "\n" + +printf "Executing [RPC: VERIFYMESSAGE]\n" +printf "=====================================\n" + +curl -s --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"verifymessage\",\"address\":\"$addr_gna\",\"sig\":\"$r_sm\",\"message\":\"testMessage\"}" > /tmp/verifymessage +printf "\n" + +# call json_extract script to get the RPC results value +r_vm=$(~/tests/./json_extract /tmp/verifymessage result) +addr_vm=$(~/tests/./json_extract /tmp/verifymessage address) +m_vm=$(~/tests/./json_extract /tmp/verifymessage message) +err_vm=$(~/tests/./json_extract /tmp/verifymessage error) + + if [ "$r_vm" != "true" ] + then + printf "RESULT_VERIFYMESSAGE_ERROR MISMATCH(result -> %s)\n" "$r_vm" + printf "info: Result should have been \n\n" + fi + + if [ "$addr_vm" != "$addr_gna" ] + then + printf "RESULT_VERIFYMESSAGE_ERROR MISMATCH(addr -> %s)\n" "$addr_vm" + printf "info: Address should have been <%s>\n\n" "$addr_vm" + fi + + if [ "$m_vm" != "testMessage" ] + then + printf "RESULT_VERIFYMESSAGE_ERROR MISMATCH(Message -> %s)\n" "$m_vm" + printf "info: Message should have been \n\n" + fi + + + + if [ "$r_vm" == "true" ] && [ "$addr_vm" == "$addr_gna" ] && [ "$m_vm" == "testMessage" ] + then + printf "RESULT_PASSED: RPC VERIFYMESSAGE\n\n" + let passed+=1 + rm -f /tmp/verifymessage + + else + printf "RESULT_FAILED: RPC VERIFYMESSAGE\n" + let failed+=1 + fi + + +#SETACCOUNT RPC +sleep 3 +printf "\n" + +printf "Executing [RPC: SETACCOUNT]\n" +printf "=====================================\n" + +result=$(curl -s --url "http://127.0.0.1:7778" --data "{\"method\":\"setaccount\",\"params\":[\"$addr_gna\", \"iguana_change\"]}") +printf "\n" + +# Executing getaddressbyaccount rpc to verify that setaccout rpc has successfully associate the particular address to particular account + +curl -s --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"getaddressesbyaccount\",\"account\":\"iguana_change\"}" >/tmp/iguana_change + + + # call json_extract script to get the RPC status value +addr_sa=$(~/tests/./json_extracta /tmp/iguana_change result) +err_sa=$(~/tests/./json_extracta /tmp/iguana_change error) + + +#split the string based on delims[,] and get the array of addresses returned in addr_gaba + +addrs_sa=$(echo $addr_sa | tr "[,]" "\n") + +if [ -z "$addrs_sa" ] +then + printf "RESULT_SETACCOUNT_ERROR\n" + printf "info: address list returned by SETACCOUNT RPC!\n\n" + let addr_unmatch_sa+=1 + +else + + for iguana_addr in $addrs_sa + do + +# split the address string again based on delim "" from iguana_addrs +actual_addr_sa=($(echo $iguana_addr | tr -d '""')) + +# call GETACCOUNT RPC to get the account name associated with that address and match it with account created with RPC GETNEWADDRESS + +curl -s --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"getaccount\",\"address\":\"$actual_addr_sa\"}"> /tmp/getaccount + +# call json_extract script to get the RPC status value +acc_name_sa=$(~/tests/./json_extract /tmp/getaccount account) + + if [ "$acc_name_sa" != "iguana_change" ] + then + printf "RESULT_SETACCOUNT_ERROR MISMATCH(ACCOUNT -> %s\n)" "$acc_name_sa" + printf "info: ACCOUNT name should be iguana_change\n\n" + let addr_unmatch_sa+=1 + + fi + + if [ "$addr_gna" != "$actual_addr_sa" ] + then + printf "RESULT_SETACCOUNT_ERROR MISMATCH(ADDRESS -> %s\n)" "$actual_addr_sa" + printf "info: ADDRESS should be <%s>\n\n" "$addr_gna" + let addr_unmatch_sa+=1 + + + fi + + if [ "$addr_unmatch_sa" -eq 0 ] + then + let addr_match_sa+=1 + + else + let addr_unmatch_sa+=1 + fi + + done +fi + +if [ "$addr_unmatch_sa" -eq 0 ] +then + printf "RESULT_PASSED: RPC SETACCOUNT\n\n" + let passed+=1 + rm -f /tmp/getaddressbyaccount +else + printf "RESULT_FAILED: RPC SETACCOUNT\n\n" + let failed+=1 +fi + +printf "\n\n" +printf "Regression Test FINISHED: PASSED=%i FAILED=%i\n" "$passed" "$failed" +printf "\n" + + diff --git a/iguana/Kashi/activehandle b/iguana/Kashi/activehandle new file mode 100755 index 000000000..113cd1057 --- /dev/null +++ b/iguana/Kashi/activehandle @@ -0,0 +1 @@ +curl -s --url "http://127.0.0.1:7778" --data "{\"agent\":\"SuperNET\",\"method\":\"activehandle\"}" diff --git a/iguana/Kashi/addmultisig b/iguana/Kashi/addmultisig new file mode 100755 index 000000000..10891244b --- /dev/null +++ b/iguana/Kashi/addmultisig @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"addmultisig\",\"params\":[2, [\"1CHzgAakwGCvGX2BG1duWygDuVE6s7tzZ6\", \"d0296ed1364639c696c374730320480301f3194c86231f62f0409cd76467f87c\", \"d045925b3e6f648bca6ed0c65149ee445137f0ab14e88cf60013d88419bcdd60\"], \"msigs\"]}" + diff --git a/iguana/Kashi/backupwallet b/iguana/Kashi/backupwallet new file mode 100755 index 000000000..5c8af9a8c --- /dev/null +++ b/iguana/Kashi/backupwallet @@ -0,0 +1 @@ +curl -s --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"backupwallet\",\"filename\":\"wallet1.txt\"}" diff --git a/iguana/Kashi/bitcoinrpc b/iguana/Kashi/bitcoinrpc new file mode 100755 index 000000000..dba1bd3de --- /dev/null +++ b/iguana/Kashi/bitcoinrpc @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"SuperNET\",\"method\":\"bitcoinrpc\",\"setcoin\":\"$1\"}" diff --git a/iguana/Kashi/bjsoncmp.c b/iguana/Kashi/bjsoncmp.c new file mode 100755 index 000000000..04ab98dd5 --- /dev/null +++ b/iguana/Kashi/bjsoncmp.c @@ -0,0 +1,47 @@ +#include +#include +#include "../../includes/cJSON.h" +#include "../../crypto777/OS_portable.h" + +int32_t main(int32_t argc,char **argv) +{ + cJSON *argjson,*array,*filejson,*obj,*fobj; char *fname,*filestr,*fstr,*str,*field; int32_t i,n; long filesize; + printf("argv[2]: %s\n",argv[2]); + if ( argc > 2 && (argjson= cJSON_Parse(argv[2])) != 0 ) + { + fname = argv[1]; + printf("got file: %s\n",fname); + if ( (filestr= OS_filestr(&filesize,fname)) != 0 ) + { + if ( (filejson= cJSON_Parse(filestr)) != 0 ) + { + if ( (array= jarray(&n,argjson,"fields")) != 0 ) + { + for (i=0; ichild) != 0 ) + { + if ( (fobj= jobj(filejson,field)) != 0 ) + { + fstr = jprint(fobj,0); + str = jprint(obj,0); + if ( strcmp(fstr,str) != 0 ) + { + printf("{\"error\":\"field.(%s) in (%s) i.%d of n.%d mismatch (%s) != (%s)\"}\n",field,fname,i,n,fstr,str); + fprintf(stderr,"{\"error\":\"field.(%s) in (%s) i.%d of n.%d mismatch (%s) != (%s)\"}\n",field,fname,i,n,fstr,str); + } + else printf("{\"result\":\"MATCHED.[%s] (%s).(%s)\"}\n",fname,field,fstr); + free(str); + free(fstr); + } else fprintf(stderr,"cant find field.(%s) in (%s)\n",field,fname); + } else fprintf(stderr,"no fieldname array[%d]\n",i); + } + } else fprintf(stderr,"no fields array\n"); + free_json(filejson); + } else fprintf(stderr,"cant parse.(%s)\n",filestr); + free(filestr); + } else fprintf(stderr,"cant load (%s)\n",fname); + } else fprintf(stderr,"argc.%d fname.(%s) error\n",argc,argv[1]); +} + diff --git a/iguana/Kashi/checkwallet b/iguana/Kashi/checkwallet new file mode 100755 index 000000000..9a74a45e5 --- /dev/null +++ b/iguana/Kashi/checkwallet @@ -0,0 +1,5 @@ +#!/bin/bash + +curl -s --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"checkwallet\"}" + + diff --git a/iguana/Kashi/createmultisig b/iguana/Kashi/createmultisig new file mode 100755 index 000000000..3ebde792c --- /dev/null +++ b/iguana/Kashi/createmultisig @@ -0,0 +1,7 @@ +#!/bin/bash + + +#curl --url "http://127.0.0.1:7778" --data "{\"method\":\"createmultisig\",\"params\":[2, [\"026b49ef6a53346455a947c462bbb2a6af25d68ea08fcacb9c288dc7ca727937fe\"]}" + +curl -s --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"createmultisig\",\"Message\":\"1\",\"pubkeys\":\"026b49ef6a53346455a947c462bbb2a6af25d68ea08fcacb9c288dc7ca727937fe\",\"ignore\":\"\"}" + diff --git a/iguana/Kashi/createrawtransaction b/iguana/Kashi/createrawtransaction new file mode 100755 index 000000000..c34c63b49 --- /dev/null +++ b/iguana/Kashi/createrawtransaction @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"createrawtransaction\",\"params\":[[{\"txid\":\"d8e4c1e92fad9e58ecc3352f35b90298fc0b81241577897b11f414ee88ff11e3\",\"vout\":1}], {\"RAoMou7euzvDwa9dQwjrNB5A41hrAWgvBt\":0.01}]}" + diff --git a/iguana/Kashi/decoderawtransaction b/iguana/Kashi/decoderawtransaction new file mode 100755 index 000000000..3d30869e0 --- /dev/null +++ b/iguana/Kashi/decoderawtransaction @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"decoderawtransaction\",\"params\":[\"9869064cd9d571ebc6690cd42dcefeafa2245af625da0e9d34dd540cca3ca6c2","signedtx":"010000005280b357019a1cfa971b8f66f39494d8ec369cfcdbc5096461f52a6d71ec23d9b5867b67a9010000006b483045022100dcffe92e3d1d74a55341f4262141ee0ccff56778d5df58922e00451303f82384022039d5162c9369aaa42d5d20b685b8656fe52cf95313c41d235da71b3b29a353b001210300f1c5870675f3fb332213967ebf6a6af16a036cd324297afc6c32a2d27a0953ffffffff02409c0000000000001976a914b7592ae8a9edd516e6b64731bf575ed5c094fc6288acb0feea0b000000001976a914c7d64ee16ec73e65a7274271170081100f09f89388ac00000000\"]}" diff --git a/iguana/Kashi/decoderawtransactionB b/iguana/Kashi/decoderawtransactionB new file mode 100755 index 000000000..5338b3df9 --- /dev/null +++ b/iguana/Kashi/decoderawtransactionB @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"decoderawtransaction\",\"params\":[\"01000000dc4f24570156bb006164173811be6647f68f9a46eab4322e6fdef816aeb3e71e419ca49bfe180000006a473044022027e0e1983c88832e9adcad681692e905333f32905553bedc6df2fcacc250574d0220259aa91c7fb0378561c37477c2b5e7872b5c9a1daababe087945639fe79593e0012102d14a195654f536df6dfe5a38278d1b470d00f17de78eeb5ce9e9eea9edb2c212ffffffff01588c0200000000001976a914d8b8c039206af6cec82bca950f592801e62808cb88ac00000000\"]}" diff --git a/iguana/Kashi/decodescript b/iguana/Kashi/decodescript new file mode 100755 index 000000000..c3d245b46 --- /dev/null +++ b/iguana/Kashi/decodescript @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"decodescript\",\"scriptstr\":\"76a914dcc39f9cfc5558b09fc7862535cafc98e5a4d63088ac\"}" diff --git a/iguana/Kashi/dumpprivkey b/iguana/Kashi/dumpprivkey new file mode 100755 index 000000000..38d2ccb0e --- /dev/null +++ b/iguana/Kashi/dumpprivkey @@ -0,0 +1,9 @@ +<<<<<<< Updated upstream +<<<<<<< Updated upstream +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"dumpprivkey\",\"params\":[\"RLaBkgU3Y61VLXPNjBd2cW1RfkghXU8yHt\"]}" +======= +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"dumpprivkey\",\"params\":[\"RTzXyTyEYQAELSsSzdfG3orcNyES9jrXGX\"]}" +>>>>>>> Stashed changes +======= +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"dumpprivkey\",\"params\":[\"RTzXyTyEYQAELSsSzdfG3orcNyES9jrXGX\"]}" +>>>>>>> Stashed changes diff --git a/iguana/Kashi/dumpprivkeyB b/iguana/Kashi/dumpprivkeyB new file mode 100755 index 000000000..3c6151dc5 --- /dev/null +++ b/iguana/Kashi/dumpprivkeyB @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"dumpprivkey\",\"params\":[\"RLaBkgU3Y61VLXPNjBd2cW1RfkghXU8yHt\"]}" diff --git a/iguana/Kashi/dumpprivkeyC b/iguana/Kashi/dumpprivkeyC new file mode 100755 index 000000000..f5e88c91a --- /dev/null +++ b/iguana/Kashi/dumpprivkeyC @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"dumpprivkey\",\"params\":[\"RBNzdRUrY2iDsjucQVEtEF1jyohYLg1d7U\"]}" diff --git a/iguana/Kashi/dumpprivkeyI b/iguana/Kashi/dumpprivkeyI new file mode 100755 index 000000000..eea0e7b26 --- /dev/null +++ b/iguana/Kashi/dumpprivkeyI @@ -0,0 +1,3 @@ +#!/bin/bash + +curl -s --url "http://127.0.0.1:7778" --data "{\"method\":\"dumpprivkey\",\"params\":[\"RJy9q8GbvqKGZkHmHn6cav96fJqCREWr8d\"]}" diff --git a/iguana/Kashi/dumpprivkeyP b/iguana/Kashi/dumpprivkeyP new file mode 100755 index 000000000..3e3b60245 --- /dev/null +++ b/iguana/Kashi/dumpprivkeyP @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"dumpprivkey\",\"params\":[\"RPEz7SQ5qn3F5A1uXkab19kzwDf3ryvhvP\"]}" diff --git a/iguana/Kashi/dumpprivkeyR b/iguana/Kashi/dumpprivkeyR new file mode 100755 index 000000000..15572b565 --- /dev/null +++ b/iguana/Kashi/dumpprivkeyR @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"dumpprivkey\",\"params\":[\"522102c866c51b603e2d943774314b88aff1eb04aef3971fcf34503c8f07d27915bc1d2102e053cc9d98d9e157917ed74bcabeaf72006b1ecf019d148dd3eac06271b6bcf02102869ca05bf6b476bb8cb433e08846a67037b921062f49cd0f9f66087454e88abb53ae\"]}" diff --git a/iguana/Kashi/dumpwallet b/iguana/Kashi/dumpwallet new file mode 100755 index 000000000..5ec708ec9 --- /dev/null +++ b/iguana/Kashi/dumpwallet @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"dumpwallet\",\"params\":[]}" diff --git a/iguana/Kashi/dumpwallet_B b/iguana/Kashi/dumpwallet_B new file mode 100755 index 000000000..d5ac5bd52 --- /dev/null +++ b/iguana/Kashi/dumpwallet_B @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"dumpwallet\",\"filename\":\"dump.txt\"}" diff --git a/iguana/Kashi/encryptwallet b/iguana/Kashi/encryptwallet new file mode 100755 index 000000000..9e4bb9185 --- /dev/null +++ b/iguana/Kashi/encryptwallet @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"encryptwallet\",\"passphrase\":\"testingaccount\"}" diff --git a/iguana/Kashi/encryptwallet_LP b/iguana/Kashi/encryptwallet_LP new file mode 100755 index 000000000..8ee594037 --- /dev/null +++ b/iguana/Kashi/encryptwallet_LP @@ -0,0 +1,18 @@ +#!/bin/bash + +clear +echo "" +echo " +The encryptwallet RPC encrypts the wallet with a passphrase. +This is only to enable encryption for the first time. After encryption is enabled, +you will need to enter the passphrase to use private keys" +echo "" +echo "" + +echo "Scenario: Test encryptwallet RPC with long passphrase]" +echo "Result: Should Return status:locked" +echo "" + +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"encryptwallet\",\"passphrase\":\"This is a very long passphrase i set to test the encryptwallet rpc\"}" +echo "" +echo "" diff --git a/iguana/Kashi/encryptwallet_SP b/iguana/Kashi/encryptwallet_SP new file mode 100755 index 000000000..fd8fecdf7 --- /dev/null +++ b/iguana/Kashi/encryptwallet_SP @@ -0,0 +1,4 @@ +#!/bin/bash + +curl -s --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"encryptwallet\",\"passphrase\":\"Admin1234@\"}" + diff --git a/iguana/Kashi/encryptwallet_WOP b/iguana/Kashi/encryptwallet_WOP new file mode 100755 index 000000000..425fb3d3f --- /dev/null +++ b/iguana/Kashi/encryptwallet_WOP @@ -0,0 +1,18 @@ +#!/bin/bash + +clear +echo "" +echo " +The encryptwallet RPC encrypts the wallet with a passphrase. +This is only to enable encryption for the first time. After encryption is enabled, +you will need to enter the passphrase to use private keys" +echo "" +echo "" + +echo "Scenario: Test encryptwallet RPC without passphrase" +echo "Result: Should Return an error message indicating passphrase required" +echo "" + +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"encryptwallet\",\"passphrase\":\"\"}" +echo "" +echo "" diff --git a/iguana/Kashi/getaccount b/iguana/Kashi/getaccount new file mode 100755 index 000000000..f4ae76754 --- /dev/null +++ b/iguana/Kashi/getaccount @@ -0,0 +1,16 @@ +#!/bin/bash + +echo "" +echo " + +The getaccount RPC returns the name of the account associated with the given address. + +Parameter #1—a Bitcoin address +Result—an account name + +" +echo "" + +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"getaccount\",\"address\":\"RQbUDfuCitztPgJkG8edBU5dy59GD7WQqT\"}" +echo "" + diff --git a/iguana/Kashi/getaccount_WOA b/iguana/Kashi/getaccount_WOA new file mode 100755 index 000000000..ab99cc4f7 --- /dev/null +++ b/iguana/Kashi/getaccount_WOA @@ -0,0 +1,21 @@ +#!/bin/bash + +echo "" +echo " + +The getaccount RPC returns the name of the account associated with the given address. + +Parameter #1—a Bitcoin address +Result—an account name" +echo "" +echo "" + +echo "Scenario: Verify the error return incase address field is set empty" +echo "Expected: No account for that address" +echo "" + +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"getaccount\",\"address\":\"RSrtzi1tPkdxD9KfHkXmxDynvPqYc7scV6\"}" + +echo "" + + diff --git a/iguana/Kashi/getaccount_WVA b/iguana/Kashi/getaccount_WVA new file mode 100755 index 000000000..3ade6ad3a --- /dev/null +++ b/iguana/Kashi/getaccount_WVA @@ -0,0 +1,23 @@ +#!/bin/bash + +echo "" +echo " + +The getaccount RPC returns the name of the account associated with the given address. + +Parameter #1—a Bitcoin address +Result—an account name" +echo "" +echo "" +echo "Dependencies:" +echo "Getaccountaddress RPC, use the address return by getaccountaddress RPC" +echo "" + +echo "Scenario: Verify the valid account's name is returned" +echo "Expected: RPCtesting account name should be returned" +echo "" + +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"getaccount\",\"address\":\"RQ9mx8ZMc5TcrsjZ8HJmgGzGZcT1DEqM1K\"}" +echo "" + + diff --git a/iguana/Kashi/getaccountaddress b/iguana/Kashi/getaccountaddress new file mode 100755 index 000000000..0aaa95b10 --- /dev/null +++ b/iguana/Kashi/getaccountaddress @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"getaccountaddress\",\"account\":\"check\"}" diff --git a/iguana/Kashi/getaccountaddress_WVA b/iguana/Kashi/getaccountaddress_WVA new file mode 100755 index 000000000..4516b64f1 --- /dev/null +++ b/iguana/Kashi/getaccountaddress_WVA @@ -0,0 +1,5 @@ +#!/bin/bash + +curl -s --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"getaccountaddress\",\"account\":\"IGUANA\"}" + + diff --git a/iguana/Kashi/getaddressFromBundle b/iguana/Kashi/getaddressFromBundle new file mode 100755 index 000000000..6d71a4727 --- /dev/null +++ b/iguana/Kashi/getaddressFromBundle @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"bundleaddresses\",\"activecoin\":\"BTCD\",\"height\":\"500\"}" + diff --git a/iguana/Kashi/getaddressbyaccount_DA b/iguana/Kashi/getaddressbyaccount_DA new file mode 100755 index 000000000..5ab7b7e4a --- /dev/null +++ b/iguana/Kashi/getaddressbyaccount_DA @@ -0,0 +1,21 @@ +#!/bin/bash + +echo "" +echo " + +The getaddressesbyaccount RPC returns a list of every address assigned to a particular account. + +Parameter #1—the account name +Result—a list of addresses +" +echo "" +echo "Dependencies:" +echo "getaccountaddress_WVA RPC" +echo "" + +echo "Scenario: Verify the addresses associated with default account" +echo "Result: List of default account addresses" +echo "" + +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"getaddressesbyaccount\",\"account\":\"\"}" +echo "" diff --git a/iguana/Kashi/getaddressbyaccount_WVN b/iguana/Kashi/getaddressbyaccount_WVN new file mode 100755 index 000000000..8bf6f719d --- /dev/null +++ b/iguana/Kashi/getaddressbyaccount_WVN @@ -0,0 +1,4 @@ +#!/bin/bash + +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"getaddressesbyaccount\",\"account\":\"change\"}" +echo "" diff --git a/iguana/Kashi/getbalance_PA b/iguana/Kashi/getbalance_PA new file mode 100755 index 000000000..b03d1b69c --- /dev/null +++ b/iguana/Kashi/getbalance_PA @@ -0,0 +1,3 @@ +#!/bin/bash + +curl -s --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"method\":\"getbalance\",\"params\":[\"IGUANA\",1,0]}" diff --git a/iguana/Kashi/getbalance_casuingCrash b/iguana/Kashi/getbalance_casuingCrash new file mode 100755 index 000000000..02657290e --- /dev/null +++ b/iguana/Kashi/getbalance_casuingCrash @@ -0,0 +1,19 @@ +#!/bin/bash + +echo "" +echo " + +The getbalance RPC gets the balance in decimal bitcoins across all accounts or for a particular account. + +Parameter #1—an account name +Parameter #2—the minimum number of confirmations +Parameter #3—whether to include watch-only addresses +Result—the balance in bitcoins +" + +echo "" +echo "" + +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"getbalance\",\"confirmations\":\"\",\"includeempty\":\"0\",\"watchonly\":\"0\"}" + +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"method\":\"getbalance\",\"params\":[*,6,0]}" diff --git a/iguana/Kashi/getbestblockhash b/iguana/Kashi/getbestblockhash new file mode 100755 index 000000000..ea98f3865 --- /dev/null +++ b/iguana/Kashi/getbestblockhash @@ -0,0 +1,5 @@ +#!/bin/bash + +curl -s --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"getbestblockhash\"}" + + diff --git a/iguana/Kashi/getblock b/iguana/Kashi/getblock new file mode 100755 index 000000000..9f00dec3d --- /dev/null +++ b/iguana/Kashi/getblock @@ -0,0 +1,3 @@ +#!/bin/bash + +curl -s --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"getblock\",\"blockhash\":\"50a4f738d4319ad1f437df56ec90fdfb2592b95f5508db379c41227b2cc992c0\",\"verbose\":\"1\",\"remoteonly\":\"0\"}" diff --git a/iguana/Kashi/getblockcount b/iguana/Kashi/getblockcount new file mode 100755 index 000000000..2594b7a48 --- /dev/null +++ b/iguana/Kashi/getblockcount @@ -0,0 +1,5 @@ +#!/bin/bash + +curl -s --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"getblockcount\"}" + + diff --git a/iguana/Kashi/getblockhash b/iguana/Kashi/getblockhash new file mode 100755 index 000000000..03733b802 --- /dev/null +++ b/iguana/Kashi/getblockhash @@ -0,0 +1,4 @@ +#!/bin/bash + +curl -s --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"getblockhash\",\"height\":\"345324\"}" + diff --git a/iguana/Kashi/getblockhash.c b/iguana/Kashi/getblockhash.c new file mode 100755 index 000000000..af5c9da99 --- /dev/null +++ b/iguana/Kashi/getblockhash.c @@ -0,0 +1,340 @@ + + +/****************************************************************************** + * * + * * + * Using Brute force techinque program will randomly pick the block and * + * would compare is header hash. The expected header hashes for the blocks * + * are accurate and caculated using local bitcoind * + * * + * All api calls are made on Iguana Core * + * * + ******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#define MAX_HEADER 45 +#define STR_LEN 64 +struct MemoryStruct +{ + char *memory; + size_t size; +}; + +static size_t +WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp) +{ + size_t realsize = size * nmemb; + struct MemoryStruct *mem = (struct MemoryStruct *)userp; + + mem->memory = realloc(mem->memory, mem->size + realsize + 1); + if(mem->memory == NULL) { + /* out of memory! */ + printf("not enough memory (realloc returned NULL)\n"); + return 0; + } + + memcpy(&(mem->memory[mem->size]), contents, realsize); + mem->size += realsize; + mem->memory[mem->size] = 0; + + return realsize; +} + + + +void fetchBlockHeader(const char * jsonrpc); +void bruteforceHashComparer(); +int hash_index = 0; +int in=0; +int ind=0; +//char ActualHash[STR_LEN]; +//char ExpectedHash[STR_LEN]; +char *ActualHash; +char *ExpectedHash; + +const char *hashes[MAX_HEADER] = + {"00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048", + "0000000026f34d197f653c5e80cb805e40612eadb0f45d00d7ea4164a20faa33", + "000000007bc154e0fa7ea32218a72fe2c1bb9f86cf8c9ebf9a715ed27fdb229a", + "000000009ca75733b4cf527fe193b919201a2ed38c9e147a5665fdfade551f4d", + "000000008f1a7008320c16b8402b7f11e82951f44ca2663caf6860ab2eeef320", + "000000004e833644bc7fb021abd3da831c64ec82bae73042cfa63923d47d3303", + "0000000062b69e4a2c3312a5782d7798b0711e9ebac065cd5d19f946439f8609", + "00000000e286ad94972e44b0532f2823bcda3977661a5136ff4d9d7db107d944", + "000000002dd9919f0a67590bb7c945cb57270a060ce39e85d8d37536a71928c3", + "00000000e474895c09bcdaf9261845960b35ea54ed3ecaf60d8a392940f1f3f9", + "000000004ff664bfa7d217f6df64c1627089061429408e1da5ef903b8f3c77db", + "00000000314ff43c77573a3b8094951ce4b0f86aceee65e226914eb737ada575", + "00000000c7f956a913bbef9c94f517c318805821b59ea6227175f3841792ea88", + "00000000d3ebca0f1cf140987959ba9231e9da43f3f76aed02d0cfe9d88b71d7", + "0000000084d973c18381c87a63a2430ad2eff1d84934ec34e3bfd78ffd3cd9c1", + "00000000ad8174a71c1b2c01fd6076143c2cf57d768bf80d7c11b6721d3a2525", + "00000000def8545899ea7274e5c59bda5982f8f960052774df45b7d5c64f9c5d", + "00000000923a992877f070d2c8fa5ae67e66f6edcd828b321caa75885136386b", + "00000000e684309e67fabdf765bea193cdf8532111079b7f53a0839746d19240", + "00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09", + "000000009cd3f93cd2d843202155561eb773b2a7b7c97561ddef31e707f4eb4b", + "00000000f0b6da96d1e3272e87e181a7057c3d79bf984b420d4f6fd6d7a49fc7", + "0000000047a712b762d9c91aa1cc2e33fb48ea64276a7086c3c10aa252a934ab", + "00000000c9c28d2bb760225beaddbc212a01720869b624f088e9311df5b5d8f2", + "000000007d07681a955b7bb9d96c473e847395b592b6e9e5a73b15b594bd4013", + "00000000f6b38fee667afb9cb2eedc5a9988d345e7b61ce220d34005d2d5b8bf", + "000000009bf03aa138b1bb31491261221f8d4562941c1022a798acda7e3158d4", + "00000000046d4e2de13c9a31dec05fafcae393ae7de773242abd4db47e9e747f", + "00000000e67f39a80dbba80e5bf130294ef460b89022c7a56c3df76ab2df2e71", + "00000000dfd5d65c9d8561b4b8f60a63018fe3933ecb131fb37f905f87da951a", + "00000000d5092034c3a92473d42f28e3fd279f0652e2d5b0049c7d40fcbc990b", + "0000000070118b55e0436a721d4533fc3d09a0238f72a5380e8a694c9dbf948e", + "0000000091a5fdf4b5f5fe07ed869bf82049b3d61a403f2771b5cbd1937dad09", + "00000000081038eb250216ebb27f94d8896d2984dc962020c53e6a2852b92967", + "00000000d84724559f1691d916b2ed63a44884d495d155197647ce7667116b16", + "0000000091a7488531bb1050f24c0f8f90d4da873673eb4dec62bbce56a32910", + "000000001731f7bb532ebd8ff11c253f128a9e3108eaf038d8155fedeba5bc0c", + "00000000d10250150162aefbf7d64ab10f3b4706ffe4d04ae59ca410f672e97b", + "00000000a4342e04aa766386cdb4da70137efd47ac271f1a4e18429af3020a7c", + "000000004a81b9aa469b11649996ecb0a452c16d1181e72f9f980850a1c5ecce", + "00000000bccaab487030fe7c0d8d66a80fefc157bd75f0de40b6b8d61ea1d287", + "00000000b6641cc18693437c5208bf362730c533fd3ea4cca364793603bba957", + "00000000bfa35a68d94bf878a712c538484d8bc272c6ddd70de4e636d55f45de", + "00000000b590a5ff44afeb50e51444d8b6ccd08f6232951316f33e19b5ca5ff2", + "00000000922e2aa9e84a474350a3555f49f06061fd49df50a9352f156692a842" + }; + +const char *jsonRPC[MAX_HEADER] = + { "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [1] }", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [50] }", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [100]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [150]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [200]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [250]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [300]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [350]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [400]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [450]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [500]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [550]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [600]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [650]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [700]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [750]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [800]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [850]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [900]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [1000]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [1100]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [1200]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [1300]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [1400]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [1500]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [1600]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [1700]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [1800]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [1900]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [2000]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [2100]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [2200]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [2300]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [2400]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [2500]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [2600]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [2700]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [2800]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [2900]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [3000]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [3200]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [3400]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [3600]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [3800]}", + "{\"id\":\"jl777\", \"method\": \"getblockhash\", \"params\": [4000]}"}; + + + +int main() +{ + int api; + CURL *curl; + CURLcode res; + + // struct MemoryStruct chunk; + + // chunk.memory = malloc(1); /* will be grown as needed by the realloc above */ + // chunk.size = 0; /* no data at this point */ + + // curl_global_init(CURL_GLOBAL_ALL); + // initialize all sub modules and return an easy handle for upcoming easy transfer + // curl = curl_easy_init(); + + // raise an assertion if handle is NULL + + for(api=0; api<(MAX_HEADER-1); api++) + { + // printf("api == %d\n",api); + fetchBlockHeader(jsonRPC[api]); + } + + + + return 0; +} + +void fetchBlockHeader(const char* jsonrpc) +{ + + CURL *curl; + CURLcode res; + struct MemoryStruct chunk; + + chunk.memory = malloc(1); /* will be grown as needed by the realloc above */ + chunk.size = 0; /* no data at this point */ + + curl_global_init(CURL_GLOBAL_ALL); + // initialize all sub modules and return an easy handle for upcoming easy transfer + curl = curl_easy_init(); + + if(curl == NULL) + { + assert(curl); + } + + ActualHash = (char*)calloc(64,sizeof(char)); + ExpectedHash = (char*)calloc(64,sizeof(char)); + if(ActualHash == NULL) + { + printf("ERROR: memory allocation failed for ActualHash\n"); + exit(1); + } + + if(ExpectedHash == NULL) + { + printf("ERROR: memory allocation failed for ExpectedHash\n"); + exit(1); + } + + + + + printf("\n"); + printf("RPC:%s\n\n",jsonrpc); + // set the properties and options for curl + // printf("1\n"); + curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1:7778"); + + /* send all data to this function */ + // printf("2\n"); + + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); + + /* we pass our 'chunk' struct to the callback function */ + // printf("3\n"); + + curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk); + + // calculate the length of data that will be passed using POST method to server + // printf("4\n"); + + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long) strlen(jsonrpc)); + + // the data parameter should be a pointer to character + // printf("5\n"); + + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, jsonrpc); + + // request using SSL for the transfer, otherwise normal transfer + // printf("6\n"); + + curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_TRY); + // printf("7\n"); + + res =curl_easy_perform(curl); + // printf("8\n"); + + /* check for errors */ + if(res != CURLE_OK) { + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(res)); + } + else + { + // printf("9\n"); + + strcpy(ActualHash,chunk.memory); + //remove space from string +/* + while(ActualHash[in] !='\0') + { + if((ActualHash[in] != ' ') (ActualHash[in+1] != ' ')) + { + + iguanaResp[ind] = ActualHash[in]; + ind++; + } + else + { + printf("Got whitespace\n"); + } + in++; + } + iguanaResp[ind] = '\0'; +*/ + // printf("10\n"); + + bruteforceHashComparer(curl); + + + } + + sleep(2); + + free(ActualHash); + // printf("11\n"); + + free(ExpectedHash); + // printf("12\n"); + free(chunk.memory); + // printf("13\n"); + + in=0; + ind=0; + curl_easy_cleanup(curl); + //printf("14\n"); + + + + +} + +void bruteforceHashComparer() +{ + + int ret; + strcpy(ExpectedHash,hashes[hash_index]); + printf("Expect Hash: %s\n",ExpectedHash); + printf("Acutal Hash: %s\n",ActualHash); + + ret = strncmp(ExpectedHash,ActualHash,64); + if(ret == 0) + { + printf("\t****************** PASSED ****************\n"); + } + + else + { + printf("\t****************** FAILED ****************\n"); + + } + + hash_index++; + + if(hash_index == MAX_HEADER) + { + hash_index = 0; + // curl_easy_cleanup(curl); + } + + +} diff --git a/iguana/Kashi/getblockhash_cp b/iguana/Kashi/getblockhash_cp new file mode 100755 index 000000000..d7994ee81 --- /dev/null +++ b/iguana/Kashi/getblockhash_cp @@ -0,0 +1,4 @@ +#!/bin/bash + +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"getblockhash\",\"height\":\"50\"}" + diff --git a/iguana/Kashi/getinfo b/iguana/Kashi/getinfo new file mode 100755 index 000000000..da84a9b26 --- /dev/null +++ b/iguana/Kashi/getinfo @@ -0,0 +1,4 @@ +#!/bin/bash + +curl -s --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"getinfo\"}" + diff --git a/iguana/Kashi/getnewaddress b/iguana/Kashi/getnewaddress new file mode 100755 index 000000000..03b72abca --- /dev/null +++ b/iguana/Kashi/getnewaddress @@ -0,0 +1 @@ +curl -s --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"getnewaddress\",\"account\":\"IGUANA\"}" diff --git a/iguana/Kashi/getrawchangeaddress_notImplemented b/iguana/Kashi/getrawchangeaddress_notImplemented new file mode 100755 index 000000000..12934c191 --- /dev/null +++ b/iguana/Kashi/getrawchangeaddress_notImplemented @@ -0,0 +1,20 @@ +#!/bin/bash + +echo "" +echo " +The getrawchangeaddress RPC returns a new Bitcoin address for receiving change. +This is for use with raw transactions, not normal use." + +echo "" + +echo "Result: +A P2PKH address which has not previously been returned by this RPC. +The address will be removed from the keypool but not marked as a receiving address, +so RPCs such as the dumpwallet RPC will show it as a change address." + +echo "" + +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"getrawchangeaddress\"}" + +echo "" + diff --git a/iguana/Kashi/getrawtransaction b/iguana/Kashi/getrawtransaction new file mode 100755 index 000000000..5efc8136e --- /dev/null +++ b/iguana/Kashi/getrawtransaction @@ -0,0 +1,18 @@ +#!/bin/bash +echo "" +echo " + +The getrawtransaction RPC gets a hex-encoded serialized transaction or a JSON object describing the transaction. By default, Bitcoin Core only stores complete transaction data for UTXOs and your own transactions, so the RPC may fail on historic transactions unless you use the non-default txindex=1 in your Bitcoin Core startup settings. + +Parameter #1—the TXID of the transaction to get +Parameter #2—whether to get the serialized or decoded transaction +Result (if transaction not found)—null +" + +echo "" + + + + +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"getrawtransaction\",\"params\":[\"7173c6a02ed2882ffaf6365cad9ed256bd5a60515658a26ab7ba5fcf4793c3bc\"]}" +echo "" diff --git a/iguana/Kashi/getreceivedbyaccount_WIA b/iguana/Kashi/getreceivedbyaccount_WIA new file mode 100755 index 000000000..ac7cb744e --- /dev/null +++ b/iguana/Kashi/getreceivedbyaccount_WIA @@ -0,0 +1,13 @@ +#!/bin/bash + +echo "" + +echo "Dependencies:" +echo "getaccoutaddress, setaccount" +echo "" +echo "Scenario: Verify that correct total amount is retured for mentioned account" +echo "" + +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"getreceivedbyaccount\",\"account\":\"R\",\"includeempty\":\"2\"}" + +echo "" diff --git a/iguana/Kashi/getreceivedbyaccount_WVA b/iguana/Kashi/getreceivedbyaccount_WVA new file mode 100755 index 000000000..15b1e0c1e --- /dev/null +++ b/iguana/Kashi/getreceivedbyaccount_WVA @@ -0,0 +1,13 @@ +#!/bin/bash + +echo "" + +echo "Dependencies:" +echo "getaccoutaddress, setaccount" +echo "" +echo "Scenario: Verify that correct total amount is retured for mentioned account" +echo "" + +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"getreceivedbyaccount\",\"account\":\"IGUANA\",\"includeempty\":\"2\"}" + +echo "" diff --git a/iguana/Kashi/getreceivedbyaddress b/iguana/Kashi/getreceivedbyaddress new file mode 100755 index 000000000..675193ac3 --- /dev/null +++ b/iguana/Kashi/getreceivedbyaddress @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"getreceivedbyaddress\",\"params\":[\"17outUgtsnLkguDuXm14tcQ7dMbdD8KZGK\"]}" diff --git a/iguana/Kashi/getreceivedbyaddress_WVA b/iguana/Kashi/getreceivedbyaddress_WVA new file mode 100755 index 000000000..4a1071c7c --- /dev/null +++ b/iguana/Kashi/getreceivedbyaddress_WVA @@ -0,0 +1,25 @@ +#!/bin/bash + +echo "" +echo " The getreceivedbyaddress RPC returns the total amount received by the specified address in transactions with the specified number of confirmations. It does not count coinbase transactions. + +Parameter #1—the address +Parameter #2—the minimum number of confirmations +Result—the number of bitcoins receiv" + +echo "" +echo "Dependencies:" +echo "Wallpassphrase, incase wallet is locked" +echo "getaccountaddres, incase account and address don't exist already" +echo "sendtoaddress, if you want to send some coins to that address" +echo "" + +echo "Senario: Verify that correct amount is returned for mentioned address" +echo "Result: Correct amount for provided address should be returned" +echo "" + + + + +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"getreceivedbyaddress\",\"params\":[\"RMcHHn9RtkdtgVHiCxysrG8q2EQTYiJfRT\"]}" +echo "" diff --git a/iguana/Kashi/getrecev b/iguana/Kashi/getrecev new file mode 100755 index 000000000..5c4246049 --- /dev/null +++ b/iguana/Kashi/getrecev @@ -0,0 +1,30 @@ +#!/bin/bash + +#GETRECEIVEDBYACCOUNT RPC +sleep 3 +printf "\n" + +printf "Executing [RPC: GETRECEIVEDBYACCOUNT]\n" +printf "=====================================\n" + +curl -s --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"getreceivedbyaccount\",\"account\":\"RMcHHn9RtkdtgVHiCxysrG8q2EQTYiJfRT\",\"includeempty\":\"2\"}" > /tmp/getreceivedbyaccount + +printf "\n" + +# call json_extract script to get the RPC results value +r_grba=$(~/tests/./json_extract /tmp/getreceivedbyaccount result) +err_grba=$(~/tests/./json_extract /tmp/getreceivedbyaccount error) + + + if [ "$r_grba" -eq 0 ] + then + printf "PASSED: GETRECEIVEDBYACCOUNT\n\n" + let passed+=1 + rm -f /tmp/getreceivedbyaccount + + else + printf "FAILED: (Returning Integer WILL IMPLEMENT LATER)\n" + printf "ERROR: %s:\n\n" "$err_grba" + let failed+=1 + fi + diff --git a/iguana/Kashi/gettransaction b/iguana/Kashi/gettransaction new file mode 100755 index 000000000..81ee8faf8 --- /dev/null +++ b/iguana/Kashi/gettransaction @@ -0,0 +1,15 @@ +#!/bin/bash +echo "" + +echo " + +The gettransaction RPC gets detailed information about an in-wallet transaction. + +Parameter #1—a transaction identifier (TXID) +Parameter #2—whether to include watch-only addresses in details and calculations +Result—a description of the transaction +" +echo "" + +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"gettransaction\",\"params\":[\"e3c08af74ca337ec632294c78c1deb461944e824f9272a280e4e750e70782714\"]}" +echo "" diff --git a/iguana/Kashi/gettxout b/iguana/Kashi/gettxout new file mode 100755 index 000000000..6718f25b8 --- /dev/null +++ b/iguana/Kashi/gettxout @@ -0,0 +1,11 @@ +#!/bin/bash +echo "" +echo "The gettxout RPC returns details about a transaction output. Only unspent transaction outputs (UTXOs) are guaranteed to be available. + +Parameter #1—the TXID of the output to get +Parameter #2—the output index number (vout) of the output to get +Parameter #3—whether to display unconfirmed outputs from the memory " +echo "" + +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"method\":\"gettxout\",\"params\":[\"51ae6e4cef61c9f496ab9df81800afacd1397bebafafb426b3c5eee1d069e84d\", 1]}" +echo "" diff --git a/iguana/Kashi/gettxoutsetinfo b/iguana/Kashi/gettxoutsetinfo new file mode 100755 index 000000000..6cecc742a --- /dev/null +++ b/iguana/Kashi/gettxoutsetinfo @@ -0,0 +1,3 @@ +#!/bin/bash + +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"gettxoutsetinfo\"}" diff --git a/iguana/Kashi/getwalletinfo b/iguana/Kashi/getwalletinfo new file mode 100755 index 000000000..8f1ded377 --- /dev/null +++ b/iguana/Kashi/getwalletinfo @@ -0,0 +1,19 @@ +#!/bin/bash + +echo "" +echo " + +The getbalance RPC gets the balance in decimal bitcoins across all accounts or for a particular account. + +Parameter #1—an account name +Parameter #2—the minimum number of confirmations +Parameter #3—whether to include watch-only addresses +Result—the balance in bitcoins +" + +echo "" +echo "" + +#curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"getbalance\",\"confirmations\":\"\",\"includeempty\":\"0\",\"watchonly\":\"0\"}" + +curl --url "http://127.0.0.1:7778" --data "{\"agents\":\"bitcoinrpc\",\"coin\":\"BTCD\",\"method\":\"getwalletinfo\",\"params\":[]}" diff --git a/iguana/Kashi/importprivkey b/iguana/Kashi/importprivkey new file mode 100755 index 000000000..265df88e8 --- /dev/null +++ b/iguana/Kashi/importprivkey @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"importprivkey\",\"params\":[\"UwoZ8tmhWth5bNacdL2YHiYv3mUZpoXhTjjFXdsm2Fhzft3fUDUF\"]}" diff --git a/iguana/Kashi/importprivkeyB b/iguana/Kashi/importprivkeyB new file mode 100755 index 000000000..fea5c86cc --- /dev/null +++ b/iguana/Kashi/importprivkeyB @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"importprivkey\",\"params\":[\"b81e824a58cefff953eb53e9743059d001be0f5cfeb7599fbdd6bd18dba6616c\"]}" diff --git a/iguana/Kashi/importprivkeyR b/iguana/Kashi/importprivkeyR new file mode 100755 index 000000000..e8a2551a1 --- /dev/null +++ b/iguana/Kashi/importprivkeyR @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"importprivkey\",\"params\":[\"522102c866c51b603e2d943774314b88aff1eb04aef3971fcf34503c8f07d27915bc1d2102e053cc9d98d9e157917ed74bcabeaf72006b1ecf019d148dd3eac06271b6bcf02102869ca05bf6b476bb8cb433e08846a67037b921062f49cd0f9f66087454e88abb53ae\"]}" diff --git a/iguana/Kashi/json_extract b/iguana/Kashi/json_extract new file mode 100755 index 000000000..f2c833a9d Binary files /dev/null and b/iguana/Kashi/json_extract differ diff --git a/iguana/Kashi/json_extract.c b/iguana/Kashi/json_extract.c new file mode 100755 index 000000000..60143e3a3 --- /dev/null +++ b/iguana/Kashi/json_extract.c @@ -0,0 +1,25 @@ +#include +#include +#include "../../includes/cJSON.h" +#include "../../crypto777/OS_portable.h" + +int32_t main(int32_t argc,char **argv) +{ + cJSON *filejson; char *fname,*filestr,*field; long filesize; + if ( argc > 2 ) + { + fname = argv[1]; + field = argv[2]; + if ( (filestr= OS_filestr(&filesize,fname)) != 0 ) + { + if ( (filejson= cJSON_Parse(filestr)) != 0 ) + { + if ( jstr(filejson,field) != 0 ) + printf("%s\n",jstr(filejson,field)); + free_json(filejson); + } else fprintf(stderr,"cant parse.(%s)\n",filestr); + free(filestr); + } else fprintf(stderr,"cant load (%s)\n",fname); + } else fprintf(stderr,"argc.%d fname.(%s) error\n",argc,argv[1]); +} + diff --git a/iguana/Kashi/json_extracta b/iguana/Kashi/json_extracta new file mode 100755 index 000000000..a76453978 Binary files /dev/null and b/iguana/Kashi/json_extracta differ diff --git a/iguana/Kashi/json_extracta.c b/iguana/Kashi/json_extracta.c new file mode 100644 index 000000000..1283f061d --- /dev/null +++ b/iguana/Kashi/json_extracta.c @@ -0,0 +1,25 @@ +#include +#include +#include "../../includes/cJSON.h" +#include "../../crypto777/OS_portable.h" + +int32_t main(int32_t argc,char **argv) +{ + cJSON *filejson; char *fname,*filestr,*field; long filesize; int32_t n; + if ( argc > 2 ) + { + fname = argv[1]; + field = argv[2]; + if ( (filestr= OS_filestr(&filesize,fname)) != 0 ) + { + if ( (filejson= cJSON_Parse(filestr)) != 0 ) + { + if ( jarray(&n,filejson,field) != 0 ) + printf("%s\n",jprint(jobj(filejson,field),0)); + free_json(filejson); + } else fprintf(stderr,"cant parse.(%s)\n",filestr); + free(filestr); + } else fprintf(stderr,"cant load (%s)\n",fname); + } else fprintf(stderr,"argc.%d fname.(%s) error\n",argc,argv[1]); +} + diff --git a/iguana/Kashi/json_extractd b/iguana/Kashi/json_extractd new file mode 100755 index 000000000..904e6e4e2 Binary files /dev/null and b/iguana/Kashi/json_extractd differ diff --git a/iguana/Kashi/json_extractd.c b/iguana/Kashi/json_extractd.c new file mode 100644 index 000000000..8c0cca0e1 --- /dev/null +++ b/iguana/Kashi/json_extractd.c @@ -0,0 +1,25 @@ +#include +#include +#include "../../includes/cJSON.h" +#include "../../crypto777/OS_portable.h" + +int32_t main(int32_t argc,char **argv) +{ + cJSON *filejson; char *fname,*filestr,*field; long filesize; + if ( argc > 2 ) + { + fname = argv[1]; + field = argv[2]; + if ( (filestr= OS_filestr(&filesize,fname)) != 0 ) + { + if ( (filejson= cJSON_Parse(filestr)) != 0 ) + { + if ( jobj(filejson,field) != 0 ) + printf("%.8f\n",jdouble(filejson,field)); + free_json(filejson); + } else fprintf(stderr,"cant parse.(%s)\n",filestr); + free(filestr); + } else fprintf(stderr,"cant load (%s)\n",fname); + } else fprintf(stderr,"argc.%d fname.(%s) error\n",argc,argv[1]); +} + diff --git a/iguana/Kashi/json_extracti b/iguana/Kashi/json_extracti new file mode 100755 index 000000000..2dc31c7f1 Binary files /dev/null and b/iguana/Kashi/json_extracti differ diff --git a/iguana/Kashi/json_extracti.c b/iguana/Kashi/json_extracti.c new file mode 100644 index 000000000..6b300e150 --- /dev/null +++ b/iguana/Kashi/json_extracti.c @@ -0,0 +1,25 @@ +#include +#include +#include "../../includes/cJSON.h" +#include "../../crypto777/OS_portable.h" + +int32_t main(int32_t argc,char **argv) +{ + cJSON *filejson; char *fname,*filestr,*field; long filesize; + if ( argc > 2 ) + { + fname = argv[1]; + field = argv[2]; + if ( (filestr= OS_filestr(&filesize,fname)) != 0 ) + { + if ( (filejson= cJSON_Parse(filestr)) != 0 ) + { + if ( jobj(filejson,field) != 0 ) + printf("%d\n",jint(filejson,field)); + free_json(filejson); + } else fprintf(stderr,"cant parse.(%s)\n",filestr); + free(filestr); + } else fprintf(stderr,"cant load (%s)\n",fname); + } else fprintf(stderr,"argc.%d fname.(%s) error\n",argc,argv[1]); +} + diff --git a/iguana/Kashi/jsoncmp b/iguana/Kashi/jsoncmp new file mode 100755 index 000000000..2a7843737 Binary files /dev/null and b/iguana/Kashi/jsoncmp differ diff --git a/iguana/Kashi/jsoncmp.c b/iguana/Kashi/jsoncmp.c new file mode 100755 index 000000000..9cc20c778 --- /dev/null +++ b/iguana/Kashi/jsoncmp.c @@ -0,0 +1,45 @@ +#include +#include +#include "../../includes/cJSON.h" +#include "../../crypto777/OS_portable.h" + +int32_t main(int32_t argc,char **argv) +{ + cJSON *argjson,*array,*filejson,*obj,*fobj; char *fname,*filestr,*fstr,*str,*field; int32_t i,n; long filesize; + if ( argc > 2 && (argjson= cJSON_Parse(argv[2])) != 0 ) + { + fname = argv[1]; + if ( (filestr= OS_filestr(&filesize,fname)) != 0 ) + { + if ( (filejson= cJSON_Parse(filestr)) != 0 ) + { + if ( (array= jarray(&n,argjson,"fields")) != 0 ) + { + for (i=0; ichild) != 0 ) + { + if ( (fobj= jobj(filejson,field)) != 0 ) + { + fstr = jprint(fobj,0); + str = jprint(obj,0); + if ( strcmp(fstr,str) != 0 ) + { + printf("{\"error\":\"field.(%s) in (%s) i.%d of n.%d mismatch (%s) != (%s)\"}\n",field,fname,i,n,fstr,str); + fprintf(stderr,"{\"error\":\"field.(%s) in (%s) i.%d of n.%d mismatch (%s) != (%s)\"}\n",field,fname,i,n,fstr,str); + } + else printf("{\"result\":\"MATCHED.[%s] (%s).(%s)\"}\n",fname,field,fstr); + free(str); + free(fstr); + } else fprintf(stderr,"cant find field.(%s) in (%s)\n",field,fname); + } else fprintf(stderr,"no fieldname array[%d]\n",i); + } + } else fprintf(stderr,"no fields array\n"); + free_json(filejson); + } else fprintf(stderr,"cant parse.(%s)\n",filestr); + free(filestr); + } else fprintf(stderr,"cant load (%s)\n",fname); + } else fprintf(stderr,"argc.%d fname.(%s) error\n",argc,argv[1]); +} + diff --git a/iguana/Kashi/listaccount_ALL b/iguana/Kashi/listaccount_ALL new file mode 100755 index 000000000..dd8c480f1 --- /dev/null +++ b/iguana/Kashi/listaccount_ALL @@ -0,0 +1,4 @@ +#!/bin/bash + +curl -s --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"listaccounts\",\"minconf\":\"0\",\"includewatchonly\":\"0\"}" +echo "" diff --git a/iguana/Kashi/listaddressgrouping b/iguana/Kashi/listaddressgrouping new file mode 100755 index 000000000..1052d0f79 --- /dev/null +++ b/iguana/Kashi/listaddressgrouping @@ -0,0 +1,5 @@ +#!/bin/bash + +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"listaddressgroupings\"}" + + diff --git a/iguana/Kashi/listaddressgroupings b/iguana/Kashi/listaddressgroupings new file mode 100755 index 000000000..1052d0f79 --- /dev/null +++ b/iguana/Kashi/listaddressgroupings @@ -0,0 +1,5 @@ +#!/bin/bash + +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"listaddressgroupings\"}" + + diff --git a/iguana/Kashi/listlockunspent b/iguana/Kashi/listlockunspent new file mode 100755 index 000000000..dbb443ecf --- /dev/null +++ b/iguana/Kashi/listlockunspent @@ -0,0 +1,3 @@ +#!/bin/bash + +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"listlockunspent\"}" diff --git a/iguana/Kashi/listreceivedbyaccount b/iguana/Kashi/listreceivedbyaccount new file mode 100755 index 000000000..8392185cf --- /dev/null +++ b/iguana/Kashi/listreceivedbyaccount @@ -0,0 +1,3 @@ +#!/bin/bash + +curl -s --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"listreceivedbyaccount\",\"confirmations\":\"10\",\"includeempty\":\"1\",\"watchonly\":\"0\"}" diff --git a/iguana/Kashi/listreceivedbyaddress b/iguana/Kashi/listreceivedbyaddress new file mode 100755 index 000000000..1d4d9b3a5 --- /dev/null +++ b/iguana/Kashi/listreceivedbyaddress @@ -0,0 +1,17 @@ +#!/bin/bash + +echo "" +echo " + +The listreceivedbyaddress RPC lists the total number of bitcoins received by each address. + +Parameter #1—the minimum number of confirmations a transaction must have to be counted +Parameter #2—whether to include empty accounts +Parameter #3—whether to include watch-only addresses in results +Result—addresses, account names, balances, and minimum confirmations +" + +echo "" + +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"listreceivedbyaddress\",\"minconf\":\"1\",\"includeempty\":\"1\",\"flag\":\"0\"}" +echo "" diff --git a/iguana/Kashi/listtransactions b/iguana/Kashi/listtransactions new file mode 100755 index 000000000..66183cd8d --- /dev/null +++ b/iguana/Kashi/listtransactions @@ -0,0 +1,7 @@ +#!/bin/bash + +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"listtransactions\",\"account\":\"IGUANA\",\"count\":\"1\",\"skip\":\"0\",\"includewatchonly\":\"0\"}" + +echo "" + + diff --git a/iguana/Kashi/listunspent b/iguana/Kashi/listunspent new file mode 100755 index 000000000..b0203ae61 --- /dev/null +++ b/iguana/Kashi/listunspent @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"listunspent\",\"params\":[\"RQK4mc7ZySXtQ6EweC4r2fcCdBTvsZqDc6\"]}" diff --git a/iguana/Kashi/listunspent_WIA b/iguana/Kashi/listunspent_WIA new file mode 100755 index 000000000..0dbe0eb82 --- /dev/null +++ b/iguana/Kashi/listunspent_WIA @@ -0,0 +1,12 @@ +#!/bin/bash +echo "" +echo "The listunspent RPC returns an array of unspent transaction outputs belonging to this wallet" + +echo "" +echo "Dependencies:" +echo "Walletpassphrase" + + +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"listunspent\",\"params\":[\"185oP\"]}" + +echo "" diff --git a/iguana/Kashi/listunspent_WVA b/iguana/Kashi/listunspent_WVA new file mode 100755 index 000000000..791d39dc7 --- /dev/null +++ b/iguana/Kashi/listunspent_WVA @@ -0,0 +1,5 @@ +#!/bin/bash + +curl -s --url "http://127.0.0.1:7778" --data "{\"method\":\"listunspent\",\"params\":[\"RQCP1TcfevTQU35ZftPNx2TZpB9ZkSZQ3S\"]}" + +echo "" diff --git a/iguana/Kashi/lockunspent b/iguana/Kashi/lockunspent new file mode 100755 index 000000000..6f2072e25 --- /dev/null +++ b/iguana/Kashi/lockunspent @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"lockunspent\",\"flag\":\"1\",\"array\":\"e3c08af74ca337ec632294c78c1deb461944e824f9272a280e4e750e70782714\"}" diff --git a/iguana/Kashi/login b/iguana/Kashi/login new file mode 100755 index 000000000..bd706185e --- /dev/null +++ b/iguana/Kashi/login @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"SuperNET\",\"method\":\"login\",\"passphrase\":\"test\"}" diff --git a/iguana/Kashi/logout b/iguana/Kashi/logout new file mode 100755 index 000000000..a5836beba --- /dev/null +++ b/iguana/Kashi/logout @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"SuperNET\",\"method\":\"logout\"}" diff --git a/iguana/Kashi/make_jsoncmp b/iguana/Kashi/make_jsoncmp new file mode 100755 index 000000000..9e8b79ce8 --- /dev/null +++ b/iguana/Kashi/make_jsoncmp @@ -0,0 +1 @@ +gcc -o jsoncmp jsoncmp.c ../../agents/libcrypto777.a -pthread -lm diff --git a/iguana/Kashi/makekeypair b/iguana/Kashi/makekeypair new file mode 100755 index 000000000..acf03128c --- /dev/null +++ b/iguana/Kashi/makekeypair @@ -0,0 +1,3 @@ +#!/bin/bash + +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"makekeypair\"}" diff --git a/iguana/Kashi/move b/iguana/Kashi/move new file mode 100755 index 000000000..5d6452542 --- /dev/null +++ b/iguana/Kashi/move @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"move\",\"fromaccount\":\"iguana\",\"toaccount\":\"iguana\",\"amount\":\"0.004\",\"minconf\":\"0\",\"comment\":\"moving\"}" diff --git a/iguana/Kashi/prv2pub b/iguana/Kashi/prv2pub new file mode 100755 index 000000000..579d5fd53 --- /dev/null +++ b/iguana/Kashi/prv2pub @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"SuperNET\",\"method\":\"priv2pub\",\"privkey\":\"1deb4ff7875c83563e7e3c5b9a427e9a7798bae9b69a78caca960295b8d837\",\"addrtype\":\"\"}" diff --git a/iguana/Kashi/prv2pub1 b/iguana/Kashi/prv2pub1 new file mode 100755 index 000000000..287109492 --- /dev/null +++ b/iguana/Kashi/prv2pub1 @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"SuperNET\",\"method\":\"priv2pub\",\"privkey\":\"6590e46b4f16cdca3a0516d84fd5ca29b24fa6a04006a9243d080daa1fc5b285\",\"addrtype\":\"\"}" diff --git a/iguana/Kashi/rates b/iguana/Kashi/rates new file mode 100755 index 000000000..74c8501c7 --- /dev/null +++ b/iguana/Kashi/rates @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"rates\",\"quotes\":[\"BTC/USD\", \"EUR/USD\", \"BTC/EUR\"]}" diff --git a/iguana/Kashi/repairwallet b/iguana/Kashi/repairwallet new file mode 100755 index 000000000..c3790559d --- /dev/null +++ b/iguana/Kashi/repairwallet @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"repairwallet\"}" diff --git a/iguana/Kashi/sendfrom b/iguana/Kashi/sendfrom new file mode 100755 index 000000000..42d1fb29e --- /dev/null +++ b/iguana/Kashi/sendfrom @@ -0,0 +1,11 @@ +#!/bin/bash + +echo "" +echo "The sendfrom RPC spends an amount from a local address to bitcoin address" +echo "" + +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"sendfrom\",\"fromaccount\":\"change\",\"toaddress\":\"REX9Qs25nJjDkPSx65kt1FTpA9om14cnos\",\"amount\":\"0.00400000\",\"minconf\":\"1\",\"comment\":\"Test_transaction\",\"comment2\":\"sendingFrom change account\"}" +echo"" + + + diff --git a/iguana/Kashi/sendmany b/iguana/Kashi/sendmany new file mode 100755 index 000000000..2a57b1841 --- /dev/null +++ b/iguana/Kashi/sendmany @@ -0,0 +1,6 @@ +#!/bin/bash + +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"sendmany\", \"params\":[\"RVQV5spiARDTqfwBCxstWnMbrT6Q8mhRYz\", {\"RL1tyXPK5NzT1d4upgcHnujgG5v3xjLaYC\":0.04, \"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\":0.04}, 2]}" + + + diff --git a/iguana/Kashi/sendrawtransaction b/iguana/Kashi/sendrawtransaction new file mode 100755 index 000000000..c617b57a8 --- /dev/null +++ b/iguana/Kashi/sendrawtransaction @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:14632" --user "user:rzDbtP9UDZEbPcn" --data "{\"method\":\"sendrawtransaction\",\"params\":[\"0100000095f4265701f6d17d847b7096cdd9b79e4df4b74aabb9ac34b7abd4f9fce19d761e97cca0e8000000006a47304402207ddad8357583b7b3707b3de1a2625b6054367c42a893edb10cd8fce4ea766895022079043096f5e278d131fafcc12d360c65f8cd4eaa81bc09ec709b5e34da7c0bdc012102d14a195654f536df6dfe5a38278d1b470d00f17de78eeb5ce9e9eea9edb2c212ffffffff0240420f00000000001976a91410acba3a841fae68aba4b5ff162714c493bcc04e88acd0300e00000000001976a914d8b8c039206af6cec82bca950f592801e62808cb88ac00000000\"]}" + diff --git a/iguana/Kashi/sendtoaddress b/iguana/Kashi/sendtoaddress new file mode 100755 index 000000000..3113f0b64 --- /dev/null +++ b/iguana/Kashi/sendtoaddress @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"sendtoaddress\",\"params\":[\"17outUgtsnLkguDuXm14tcQ7dMbdD8KZGK\", 0.4]}" + diff --git a/iguana/Kashi/sendtoaddress_WVA b/iguana/Kashi/sendtoaddress_WVA new file mode 100755 index 000000000..f4906aa94 --- /dev/null +++ b/iguana/Kashi/sendtoaddress_WVA @@ -0,0 +1,18 @@ +#!/bin/bash + +echo "" +echo "The sendtoaddress RPC spends an amount to a given address. + +Parameter #1—to address +Parameter #2—amount to spend" +echo "" +echo "Dependencies:" +echo "Walletpassphrase, Incase valid is locked" +echo "getaccountaddress, incase account and address don't exist already" +echo "" +echo "Scenario: Verify that amount is sent to given account" +echo "Results: Amount should be sent to the given account" +echo "" + +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"sendtoaddress\",\"params\":[\"RQbUDfuCitztPgJkG8edBU5dy59GD7WQqT\", 0.0004]}" +echo "" diff --git a/iguana/Kashi/setaccount b/iguana/Kashi/setaccount new file mode 100755 index 000000000..41edb3368 --- /dev/null +++ b/iguana/Kashi/setaccount @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"setaccount\",\"params\":[\"RQK4mc7ZySXtQ6EweC4r2fcCdBTvsZqDc6\", \"change\"]}" diff --git a/iguana/Kashi/setaccount_WIA b/iguana/Kashi/setaccount_WIA new file mode 100755 index 000000000..71a132efb --- /dev/null +++ b/iguana/Kashi/setaccount_WIA @@ -0,0 +1,14 @@ +#!/bin/bash + +echo "" +echo "The setaccount RPC put the specified address in the given account" +echo "" +echo "Dependencies:" +echo "Getnewaddress RPC, if you don't have an address already" +echo "Getaccountaddress RPC, if account doesn't exist already" +echo "" +echo "Scenario: Verify that ERROR is returned incase of invalid or empty account name" +echo "Result: Need address and account " +echo "" + +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"setaccount\",\"params\":[\"RW8oinV4TjRobRWNcNx2cjoexnGS5g8yh5\", \"\"]}" diff --git a/iguana/Kashi/setaccount_WVA b/iguana/Kashi/setaccount_WVA new file mode 100755 index 000000000..801e61b63 --- /dev/null +++ b/iguana/Kashi/setaccount_WVA @@ -0,0 +1,14 @@ +#!/bin/bash + +echo "" +echo "The setaccount RPC put the specified address in the given account" +echo "" +echo "Dependencies:" +echo "Getnewaddress RPC, if you don't have an address already" +echo "Getaccountaddress RPC, if account doesn't exist already" +echo "" +echo "Scenario: Verify that user is able to linked address with specified account" +echo "Result: Address should be linked to mentioned account" +echo "" + +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"setaccount\",\"params\":[\"RQK4mc7ZySXtQ6EweC4r2fcCdBTvsZqDc6\", \"IGUANA_CHANGE\"]}" diff --git a/iguana/Kashi/settx b/iguana/Kashi/settx new file mode 100755 index 000000000..e05cd9582 --- /dev/null +++ b/iguana/Kashi/settx @@ -0,0 +1 @@ +curl -s --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"settxfee\",\"amount\":\"0.00002\"}" diff --git a/iguana/Kashi/signmessage b/iguana/Kashi/signmessage new file mode 100755 index 000000000..a14f984c2 --- /dev/null +++ b/iguana/Kashi/signmessage @@ -0,0 +1,12 @@ +#!/bin/bash + +echo 'Sign a Message with the Private Key of Given Address' +echo 'Parameter1: Address Corresponding to Private key to sign with' +echo 'Parameter2: Message To Sign' + +echo 'Return Signature for corresponding Message' + +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"signmessage\",\"address\":\"REurKb7jWHJgE2WKMqvqiDdbFf6Tmd2CEX\",\"message\":\"testMessage\"}" +echo "" + + diff --git a/iguana/Kashi/signmessagewithwrongaddress b/iguana/Kashi/signmessagewithwrongaddress new file mode 100755 index 000000000..8a790c29d --- /dev/null +++ b/iguana/Kashi/signmessagewithwrongaddress @@ -0,0 +1,9 @@ +o 'Sign a Message with the Private Key of Given Address' +echo 'Parameter1: Address Corresponding to Private key to sign with' +echo 'Parameter2: Message To Sign' + +echo 'Return Signature for corresponding Message' + +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"signmessage\",\"address\":\"REurKb7jWHJgE2WKMqvqiDdbFf6Tmd2C\",\"message\":\"testMessage\"}" + + diff --git a/iguana/Kashi/signrawtransaction b/iguana/Kashi/signrawtransaction new file mode 100755 index 000000000..02a68732d --- /dev/null +++ b/iguana/Kashi/signrawtransaction @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"signrawtransaction\",\"params\":[\"0100000095f4265701f6d17d847b7096cdd9b79e4df4b74aabb9ac34b7abd4f9fce19d761e97cca0e80000000000ffffffff0240420f00000000001976a91410acba3a841fae68aba4b5ff162714c493bcc04e88acd0300e00000000001976a914d8b8c039206af6cec82bca950f592801e62808cb88ac00000000\", [{\"txid\":\"e8a0cc971e769de1fcf9d4abb734acb9ab4ab7f44d9eb7d9cd96707b847dd1f6\",\"vout\":0,\"scriptPubKey\":\"2102d14a195654f536df6dfe5a38278d1b470d00f17de78eeb5ce9e9eea9edb2c212ac\"}], [\"UqvuZXEAVXDXJkL4j4Xq6qoMdeJfPF1aNsCzmzfZaQ1ZgBTwfmWn\"], \"ALL\"] }" + diff --git a/iguana/Kashi/signrawtransaction2 b/iguana/Kashi/signrawtransaction2 new file mode 100755 index 000000000..a25bf319e --- /dev/null +++ b/iguana/Kashi/signrawtransaction2 @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTC\",\"method\":\"signrawtransaction\",\"params\":[\"01000000dc4f24570156bb006164173811be6647f68f9a46eab4322e6fdef816aeb3e71e419ca49bfe1800000000ffffffff01588c0200000000001976a914d8b8c039206af6cec82bca950f592801e62808cb88ac00000000\", [{\"txid\":\"fe9ba49c411ee7b3ae16f8de6f2e32b4ea469a8ff64766be113817646100bb56\",\"vout\":24}], [\"UqvuZXEAVXDXJkL4j4Xq6qoMdeJfPF1aNsCzmzfZaQ1ZgBTwfmWn\"], \"ALL\"] }" + diff --git a/iguana/Kashi/startBTCD b/iguana/Kashi/startBTCD new file mode 100755 index 000000000..9e655a9d7 --- /dev/null +++ b/iguana/Kashi/startBTCD @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"BTCD\",\"services\":0}" diff --git a/iguana/Kashi/startBTCD_p2p b/iguana/Kashi/startBTCD_p2p new file mode 100755 index 000000000..7737074e2 --- /dev/null +++ b/iguana/Kashi/startBTCD_p2p @@ -0,0 +1 @@ +curl -s --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"BTCD\",\"services\":0,\"portp2p\":14631}" diff --git a/iguana/Kashi/start_btc_basliskMode b/iguana/Kashi/start_btc_basliskMode new file mode 100755 index 000000000..7bc26a7b1 --- /dev/null +++ b/iguana/Kashi/start_btc_basliskMode @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"prefetchlag\":5,\"poll\":1,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"BTC\",\"startpend\":8,\"endpend\":6,\"services\":129,\"maxpeers\":64,\"RELAY\":0,\"VALIDATE\":0,\"portp2p\":8333}" diff --git a/iguana/Kashi/start_btc_fullMode b/iguana/Kashi/start_btc_fullMode new file mode 100755 index 000000000..22b9218d4 --- /dev/null +++ b/iguana/Kashi/start_btc_fullMode @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"prefetchlag\":5,\"poll\":1,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"BTC\",\"startpend\":8,\"endpend\":6,\"services\":129,\"maxpeers\":64,\"RELAY\":1,\"VALIDATE\":1,\"portp2p\":8333}" diff --git a/iguana/Kashi/testing b/iguana/Kashi/testing new file mode 100755 index 000000000..d8726019c --- /dev/null +++ b/iguana/Kashi/testing @@ -0,0 +1,36 @@ +#!/bin/bash + +curl -s --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"getaddressesbyaccount\",\"account\":\"IGUANA\"}" > /tmp/getaddressbyaccount +printf "\n" + +# call json_extract script to get the RPC status value +addr_gaba=$(~/tests/./json_extracta /tmp/getaddressbyaccount result) +err_gaba=$(~/tests/./json_extracta /tmp/getaddressbyaccount error) + +addrs=$(echo $addr_gaba | tr "[,]" "\n") + + +for iguana_addrs in $addrs +do + +addrs1=($(echo $iguana_addrs | tr -d '""')) + +printf "new address:%s\n" "$addrs1" + +curl -s --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"getaccount\",\"address\":\"$addrs1\"}"> /tmp/getaccount +printf "\n" + +# call json_extract script to get the RPC status value +acc_ga=$(~/tests/./json_extract /tmp/getaccount account) +printf "ACCOUNT:%s\n" "$acc_ga" + + if [ "$acc_ga" == "IGUANA" ] + then + printf "PASSED:" + else + printf "FAILED:" + + fi +done + + diff --git a/iguana/Kashi/validateaddress b/iguana/Kashi/validateaddress new file mode 100755 index 000000000..dfadfd92b --- /dev/null +++ b/iguana/Kashi/validateaddress @@ -0,0 +1,7 @@ +#!/bin/bash +echo "" +echo "The validateaddress RPC accepts a block, verifies it is a valid addition to the block chain, and broadcasts it to the network. Extra parameters are ignored by Bitcoin Core but may be used by mining pools or other programs." + +echo"" + +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"validateaddress\",\"address\":\"RKfr35KdFCvM5DrmVFPouszesqUWvL6vxd\"}" diff --git a/iguana/Kashi/validatepubkey b/iguana/Kashi/validatepubkey new file mode 100755 index 000000000..ea9f0079f --- /dev/null +++ b/iguana/Kashi/validatepubkey @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"validatepubkey\",\"pubkey\":\"026b49ef6a53346455a947c462bbb2a6af25d68ea08fcacb9c288dc7ca727937fe\"}" diff --git a/iguana/Kashi/validaterawtransaction b/iguana/Kashi/validaterawtransaction new file mode 100755 index 000000000..349689e26 --- /dev/null +++ b/iguana/Kashi/validaterawtransaction @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"validaterawtransaction\",\"params\":[\"e69031847ad70f3bea75fbc4e4952caa64bd8866e65369399a93e2bcdeeb48d6","signedtx":"01000000a7133a5701922b48e7f96adaaef034dc67ea0d35b622ab6f16a41a69a5f3a6dc0fd3ac00fd010000006b483045022100c6286b399f2e98e5d8afe1ec139e38dc0efb14b563d220c4bcad99dc6360d9fe022051aeee65e8fdda7cb995f88ff4501578a0169e13693bd685d3820ab5b0c8436001210377a998571f6beb441a567165d65a7cebd449234607637a816ce810cbd9cca5caffffffff02a0860100000000001976a91433589918e1417aa730082041b94dd444f5bf6f9788ace00d901d000000001976a914dcc39f9cfc5558b09fc7862535cafc98e5a4d63088ac00000000\"]}" diff --git a/iguana/Kashi/verifymessage b/iguana/Kashi/verifymessage new file mode 100755 index 000000000..86a37fd9c --- /dev/null +++ b/iguana/Kashi/verifymessage @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"signmessage\",\"params\":[\"testmessage\"]}" + diff --git a/iguana/Kashi/verifymessagewithsignature b/iguana/Kashi/verifymessagewithsignature new file mode 100755 index 000000000..8024edbaf --- /dev/null +++ b/iguana/Kashi/verifymessagewithsignature @@ -0,0 +1,11 @@ +#!/bin/bash +# +# VerifyMesage + +echo 'Bitcoin RPC : verifymessage' +echo 'Param1 : Address' +echo 'Param2 : Signature' +echo 'Param3 : Message' + +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"verifymessage\",\"address\":\"REurKb7jWHJgE2WKMqvqiDdbFf6Tmd2CEX\",\"sig\":\"HzVTJEsYyldwfZ1YQxCntxfPn4QidpPKkkVs7dwwqspLBopw0aYSFmac1RpD9hQD5m/cy55FJBGxbKkd+tscjOY=\",\"message\":\"testMessage\"}" +echo "" diff --git a/iguana/Kashi/walletlock b/iguana/Kashi/walletlock new file mode 100755 index 000000000..d9bd9a47f --- /dev/null +++ b/iguana/Kashi/walletlock @@ -0,0 +1 @@ +curl -s --url "http://127.0.0.1:7778" --data "{\"method\":\"walletlock\",\"params\":[]}" diff --git a/iguana/Kashi/walletpassphrase b/iguana/Kashi/walletpassphrase new file mode 100755 index 000000000..a54094cea --- /dev/null +++ b/iguana/Kashi/walletpassphrase @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"walletpassphrase\",\"password\":\"kashifali\",\"timeout\":300}" + diff --git a/iguana/Kashi/walletpassphraseChange b/iguana/Kashi/walletpassphraseChange new file mode 100755 index 000000000..5917cfab1 --- /dev/null +++ b/iguana/Kashi/walletpassphraseChange @@ -0,0 +1,5 @@ +#!/bin/bash + +curl -s --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"walletpassphrasechange\",\"oldpassword\":\"Admin123@\",\"newpassword\":\"Admin123456@\",\"oldpermanentfile\":\"\",\"permanentfile\":\"\"}" + + diff --git a/iguana/Kashi/walletpassphrase_WIP b/iguana/Kashi/walletpassphrase_WIP new file mode 100755 index 000000000..de1021166 --- /dev/null +++ b/iguana/Kashi/walletpassphrase_WIP @@ -0,0 +1,21 @@ +#!/bin/bash +clear +echo "" + +echo " +The walletpassphrase RPC stores the wallet decryption key in memory for the indicated number of seconds. +Issuing the walletpassphrase command while the wallet is already unlocked will set a new unlock time +that overrides the old one. + +Parameter #1—the passphrase +Parameter #2—the number of seconds to leave the wallet unlocked + +" +echo "" +echo " +Scenario: To Test walletpassphrase with invalid password +Result: ERORR: Passphrase not found in decrypted json" +echo "" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"walletpassphrase\",\"password\":\"kashifali\",\"timeout\":300}" +echo "" + diff --git a/iguana/Kashi/walletpassphrase_WVP b/iguana/Kashi/walletpassphrase_WVP new file mode 100755 index 000000000..f0be9493d --- /dev/null +++ b/iguana/Kashi/walletpassphrase_WVP @@ -0,0 +1,4 @@ +#!/bin/bash + +curl -s --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"walletpassphrase\",\"password\":\"Admin1234@\",\"timeout\":300}" + diff --git a/iguana/Kashi/wallett b/iguana/Kashi/wallett new file mode 100755 index 000000000..0691917e7 --- /dev/null +++ b/iguana/Kashi/wallett @@ -0,0 +1,2 @@ +curl -s --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"walletpassphrase\",\"password\":\"kashif!Ali123\",\"timeout\":300}" + diff --git a/iguana/Kashi/wif2prv b/iguana/Kashi/wif2prv new file mode 100755 index 000000000..07c60821d --- /dev/null +++ b/iguana/Kashi/wif2prv @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"SuperNET\",\"method\":\"wif2priv\",\"wif\":\"UvVucHx4ob6ttrG4PRcUxryHFbm7KXj3TzyTci8XHfcnSdQpbcCc\"}" diff --git a/iguana/Kashi/wif2prv1 b/iguana/Kashi/wif2prv1 new file mode 100755 index 000000000..5b333688f --- /dev/null +++ b/iguana/Kashi/wif2prv1 @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"SuperNET\",\"method\":\"wif2priv\",\"wif\":\"UsQyVEi7TZ8JJmzcmJijU98HUc55b2wdPcfmuWfZgE5e8tG5xeXz\"}" diff --git a/iguana/Makefile b/iguana/Makefile index c6c016bad..2fd6616bb 100755 --- a/iguana/Makefile +++ b/iguana/Makefile @@ -26,9 +26,9 @@ DEPS = nacl_io #LIBS = crypto777 curl ssl crypto z pthread ppapi nacl_io #DEPS = nacl_io #LIBS = crypto777 curl ssl crypto z glibc-compat nacl_spawn ppapi nacl_io ppapi_simple # cli_main ppapi_cpp ppapi_simple -LIBS = crypto777 z glibc-compat nacl_spawn ppapi nacl_io ppapi_simple +LIBS = crypto777 curl ssl crypto z glibc-compat nacl_spawn ppapi nacl_io ppapi_simple -CFLAGS = -Wall -O2 -fno-strict-aliasing $(EXTRA) +CFLAGS = -Wall -O2 -DLIQUIDITY_PROVIDER=1 -fno-strict-aliasing $(EXTRA) LFLAGS = libs # Build rules generated by macros from common.mk: diff --git a/iguana/SuperNET.c b/iguana/SuperNET.c deleted file mode 100755 index 15d6e50c0..000000000 --- a/iguana/SuperNET.c +++ /dev/null @@ -1,1474 +0,0 @@ -/****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - -#include "iguana777.h" -#include "../includes/tweetnacl.h" -#include "../crypto777/OS_portable.h" -#include "../includes/libgfshare.h" -#include "../includes/utlist.h" -#include "../includes/uthash.h" -#include "../includes/curve25519.h" -#include "../includes/cJSON.h" - - -cJSON *SuperNET_argjson(cJSON *json) -{ - cJSON *argjson = jduplicate(json); - jdelete(argjson,"agent"); - jdelete(argjson,"method"); - jdelete(argjson,"categoryhash"); - jdelete(argjson,"subhash"); - jdelete(argjson,"mypub"); - jdelete(argjson,"hexmsg"); - jdelete(argjson,"plaintext"); - jdelete(argjson,"broadcast"); - jdelete(argjson,"ov"); - jdelete(argjson,"check"); - jdelete(argjson,"yourip"); - jdelete(argjson,"myip"); - jdelete(argjson,"myipaddr"); - return(argjson); -} - -bits256 SuperNET_sharedseed(bits256 privkey,bits256 otherpub) -{ - bits256 seed2,seed; - seed = curve25519_shared(privkey,otherpub); - vcalc_sha256(0,seed2.bytes,seed.bytes,sizeof(bits256)); - return(seed2); -} - -int32_t SuperNET_delaymillis(struct supernet_info *myinfo,int32_t maxdelay) -{ - maxdelay += myinfo->maxdelay; - if ( maxdelay > SUPERNET_MAXDELAY ) - maxdelay = SUPERNET_MAXDELAY; - if ( maxdelay == 0 ) - return(0); - return(rand() % maxdelay); -} - -void SuperNET_remotepeer(struct supernet_info *myinfo,struct iguana_info *coin,char *symbol,char *ipaddr,int32_t supernetflag) -{ - uint64_t ipbits; struct iguana_peer *addr; - ipbits = calc_ipbits(ipaddr); - printf("got %s remotepeer.(%s) supernet.%d\n",symbol,ipaddr,supernetflag); - if ( supernetflag != 0 && (uint32_t)myinfo->myaddr.selfipbits != (uint32_t)ipbits ) - { - if ( (addr= iguana_peerslot(coin,ipbits,0)) != 0 ) - { - printf("launch startconnection to supernet peer.(%s)\n",ipaddr); - iguana_launch(coin,"connection",iguana_startconnection,addr,IGUANA_CONNTHREAD); - return; - } - } - iguana_possible_peer(coin,ipaddr); -} - -int32_t SuperNET_confirmip(struct supernet_info *myinfo,uint32_t ipbits) -{ - int32_t i,j,total = 0; uint32_t x; - for (i=0; ipeers.active[j].myipbits) != 0 ) - { - if ( x == ipbits ) - total++; - else total--; - } - } - } - } - return(total); -} - -void SuperNET_checkipaddr(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,char *myipaddr,char *remoteaddr) -{ - uint32_t myipbits = (uint32_t)calc_ipbits(myipaddr); - if ( addr->myipbits == 0 ) - addr->myipbits = myipbits; - else if ( addr->myipbits != myipbits ) - { - printf("%s: myipaddr conflict %x != %x?\n",addr->ipaddr,addr->myipbits,myipbits); - addr->myipbits = 0; - } - if ( addr->myipbits != 0 && myinfo->myaddr.myipbits == 0 ) - myinfo->myaddr.myipbits = addr->myipbits; - if ( addr->myipbits == myinfo->myaddr.myipbits ) - myinfo->myaddr.confirmed++; - else myinfo->myaddr.confirmed--; - if ( (myinfo->myaddr.totalconfirmed= SuperNET_confirmip(myinfo,addr->myipbits)) >= coin->peers.numranked ) - myinfo->myaddr.selfipbits = addr->myipbits; - if ( myinfo->myaddr.selfipbits == myinfo->myaddr.myipbits ) - { - expand_ipbits(myinfo->ipaddr,myinfo->myaddr.selfipbits); - vcalc_sha256(0,myinfo->myaddr.iphash.bytes,(uint8_t *)&myinfo->myaddr.selfipbits,sizeof(myinfo->myaddr.selfipbits)); - } - if ( myinfo->ipaddr[0] == 0 || strcmp(myinfo->ipaddr,"127.0.0.1") == 0 ) - { - strcpy(myinfo->ipaddr,myipaddr); - } - //printf("myipaddr.%s self.%x your.%x\n",myinfo->ipaddr,myinfo->myaddr.selfipbits,myinfo->myaddr.myipbits); -} - -int32_t _SuperNET_cipher(uint8_t nonce[crypto_box_NONCEBYTES],uint8_t *cipher,uint8_t *message,int32_t len,bits256 destpub,bits256 srcpriv,uint8_t *buf) -{ - memset(cipher,0,len+crypto_box_ZEROBYTES); - memset(buf,0,crypto_box_ZEROBYTES); - memcpy(buf+crypto_box_ZEROBYTES,message,len); - crypto_box(cipher,buf,len+crypto_box_ZEROBYTES,nonce,destpub.bytes,srcpriv.bytes); - return(len + crypto_box_ZEROBYTES); -} - -uint8_t *_SuperNET_decipher(uint8_t nonce[crypto_box_NONCEBYTES],uint8_t *cipher,uint8_t *message,int32_t len,bits256 srcpub,bits256 mypriv) -{ - int32_t err; - if ( (err= crypto_box_open(message,cipher,len,nonce,srcpub.bytes,mypriv.bytes)) == 0 ) - { - message += crypto_box_ZEROBYTES; - len -= crypto_box_ZEROBYTES; - return(message); - } - return(0); -} - -void *SuperNET_deciphercalc(void **ptrp,int32_t *msglenp,bits256 privkey,bits256 srcpubkey,uint8_t *cipher,int32_t cipherlen,uint8_t *buf,int32_t bufsize) -{ - uint8_t *origptr,*nonce,*message; void *retptr; - if ( bits256_nonz(privkey) == 0 ) - privkey = GENESIS_PRIVKEY; - *ptrp = 0; - if ( cipherlen > bufsize ) - { - message = calloc(1,cipherlen); - *ptrp = (void *)message; - } - else message = buf; - origptr = cipher; - if ( bits256_nonz(srcpubkey) == 0 ) - { - memcpy(srcpubkey.bytes,cipher,sizeof(srcpubkey)); - //char str[65]; printf("use attached pubkey.(%s)\n",bits256_str(str,srcpubkey)); - cipher += sizeof(srcpubkey); - cipherlen -= sizeof(srcpubkey); - } - nonce = cipher; - cipher += crypto_box_NONCEBYTES, cipherlen -= crypto_box_NONCEBYTES; - *msglenp = cipherlen - crypto_box_ZEROBYTES; - if ( (retptr= _SuperNET_decipher(nonce,cipher,message,cipherlen,srcpubkey,privkey)) == 0 ) - { - *msglenp = -1; - free(*ptrp); - } - return(retptr); -} - -uint8_t *SuperNET_ciphercalc(void **ptrp,int32_t *cipherlenp,bits256 *privkeyp,bits256 *destpubkeyp,uint8_t *data,int32_t datalen,uint8_t *space2,int32_t space2size) -{ - bits256 mypubkey; uint8_t *buf,*nonce,*cipher,*origptr,space[8192]; int32_t onetimeflag=0,allocsize; - *ptrp = 0; - allocsize = (datalen + crypto_box_NONCEBYTES + crypto_box_ZEROBYTES); - if ( bits256_nonz(*destpubkeyp) == 0 || memcmp(destpubkeyp->bytes,GENESIS_PUBKEY.bytes,sizeof(*destpubkeyp)) == 0 ) - { - *destpubkeyp = GENESIS_PUBKEY; - onetimeflag = 2; // prevent any possible leakage of privkey by encrypting to known destpub - } - if ( bits256_nonz(*privkeyp) == 0 ) - onetimeflag = 1; - if ( onetimeflag != 0 ) - { - crypto_box_keypair(mypubkey.bytes,privkeyp->bytes); - allocsize += sizeof(bits256); - } - if ( allocsize > sizeof(space) ) - buf = calloc(1,allocsize); - else buf = space; - if ( allocsize+sizeof(struct iguana_msghdr) > space2size ) - { - cipher = calloc(1,allocsize + sizeof(struct iguana_msghdr)); - *ptrp = (void *)cipher; - } else cipher = space2; - cipher = &cipher[sizeof(struct iguana_msghdr)]; - origptr = nonce = cipher; - if ( onetimeflag != 0 ) - { - memcpy(cipher,mypubkey.bytes,sizeof(mypubkey)); - nonce = &cipher[sizeof(mypubkey)]; - } - OS_randombytes(nonce,crypto_box_NONCEBYTES); - cipher = &nonce[crypto_box_NONCEBYTES]; - _SuperNET_cipher(nonce,cipher,(void *)data,datalen,*destpubkeyp,*privkeyp,buf); - if ( buf != space ) - free(buf); - *cipherlenp = allocsize; - return(origptr); -} - -int32_t SuperNET_copybits(int32_t reverse,uint8_t *dest,uint8_t *src,int32_t len) -{ - int32_t i; uint8_t *tmp; - if ( reverse != 0 ) - { - tmp = dest; - dest = src; - src = tmp; - } - //printf("src.%p dest.%p len.%d\n",src,dest,len); - //for (i=0; i> 3); -} - -uint16_t SuperNET_checkc(bits256 privkey,bits256 otherpub,void *num,int32_t len) -{ - uint8_t buf[40]; bits256 check,seed,seed2; - seed = curve25519_shared(privkey,otherpub); - vcalc_sha256(0,seed2.bytes,seed.bytes,sizeof(seed)); - memcpy(buf,seed2.bytes,sizeof(seed)); - iguana_rwnum(1,&buf[sizeof(seed)],len,num); - vcalc_sha256(0,check.bytes,buf,sizeof(buf)); - return(check.ushorts[0]); -} - -int32_t SuperNET_json2bits(uint8_t *serialized,int32_t maxsize,cJSON *json,bits256 mypub,uint16_t checkc,uint32_t myipbits,uint32_t destipbits,int32_t _othervalid) -{ - uint16_t apinum; bits256 categoryhash,subhash; uint32_t tmp,crc,timestamp; - char *agent,*method; //uint64_t tag; - char *hexmsg; uint8_t broadcastflag; int8_t othervalid; int32_t n,len = sizeof(uint32_t); - if ( _othervalid > 100 ) - othervalid = 100; - else if ( _othervalid < -100 ) - othervalid = -100; - else othervalid = _othervalid; - tmp = juint(json,"broadcast"); - if ( tmp > SUPERNET_MAXHOPS ) - broadcastflag = SUPERNET_MAXHOPS; - else broadcastflag = tmp; - categoryhash = jbits256(json,"categoryhash"); - subhash = jbits256(json,"subhash"); - timestamp = juint(json,"timestamp"); - if ( bits256_nonz(categoryhash) > 0 && memcmp(categoryhash.bytes,GENESIS_PUBKEY.bytes,sizeof(categoryhash)) != 0 ) - { - broadcastflag |= 0x40; - if ( bits256_nonz(subhash) > 0 && memcmp(subhash.bytes,GENESIS_PUBKEY.bytes,sizeof(subhash)) != 0 ) - broadcastflag |= 0x20; - else subhash = GENESIS_PUBKEY; - if ( broadcastflag == 0 ) - broadcastflag = 1; - } - else - { - categoryhash = subhash = GENESIS_PUBKEY; - if ( broadcastflag == 0 ) - broadcastflag = 1; - } - if ( juint(json,"plaintext") != 0 ) - broadcastflag |= 0x80; - //if ( (tag= j64bits(json,"tag")) == 0 ) - // OS_randombytes((uint8_t *)&tag,sizeof(tag)); - agent = jstr(json,"agent"), method = jstr(json,"method"); - if ( agent != 0 && method != 0 && strcmp(agent,"SuperNET") == 0 && strcmp(method,"json2bits") == 0 ) - { - agent = jstr(json,"destagent"); - method = jstr(json,"destmethod"); - } - if ( (apinum= SuperNET_API2num(agent,method)) == 0xffff ) - { - printf("agent.(%s) method.(%s) is not found\n",agent,method); - return(-1); - } - len += iguana_rwnum(1,&serialized[len],sizeof(uint32_t),×tamp); - len += iguana_rwnum(1,&serialized[len],sizeof(uint32_t),&destipbits); - len += iguana_rwnum(1,&serialized[len],sizeof(uint32_t),&myipbits); - //printf("myipbits.%x destipbits.%x\n",myipbits,destipbits); - len += iguana_rwnum(1,&serialized[len],sizeof(checkc),&checkc); - len += iguana_rwnum(1,&serialized[len],sizeof(apinum),&apinum); - //len += iguana_rwnum(1,&serialized[len],sizeof(tag),&tag); - len += iguana_rwbignum(1,&serialized[len],sizeof(mypub),mypub.bytes); - len += iguana_rwnum(1,&serialized[len],sizeof(othervalid),&othervalid); - len += iguana_rwnum(1,&serialized[len],sizeof(broadcastflag),&broadcastflag); - if ( (broadcastflag & 0x40) != 0 ) - { - len += iguana_rwbignum(1,&serialized[len],sizeof(bits256),categoryhash.bytes); - if ( (broadcastflag & 0x20) != 0 ) - len += iguana_rwbignum(1,&serialized[len],sizeof(bits256),subhash.bytes); - } - //printf("broadcastflag.%x\n",broadcastflag); - if ( (hexmsg= jstr(json,"hexmsg")) != 0 ) - { - n = (int32_t)strlen(hexmsg); - if ( (n & 1) == 0 && is_hexstr(hexmsg,n) > 0 ) - { - n >>= 1; - decode_hex(&serialized[len],n,hexmsg); - len += n; - } else return(-1); - } - crc = calc_crc32(0,&serialized[sizeof(crc)],len - sizeof(crc)); - // char str[65]; printf("crc.%u ip.(%s %s) tag.%llx checkc.%x apinum.%d >>>>>>>>>>>>>>>> mypub.%s\n",crc,destip,myipaddr,(long long)tag,checkc,apinum,bits256_str(str,mypubkey)); - iguana_rwnum(1,serialized,sizeof(crc),&crc); - //int32_t i; for (i=0; i SUPERNET_MAXHOPS ) - broadcastflag = SUPERNET_MAXHOPS; - //printf("<<<<<<<<<<<<<<<< crc.%u ipbits.(%x %x) tag.%llx checkc.%x apinum.%d valid.%d other.%d broadcast.%d plaintext.%d\n",crc,destipbits,myipbits,(long long)tag,checkc,apinum,addr->validpub,othervalid,broadcastflag,plaintext); - if ( SuperNET_num2API(agent,method,apinum) >= 0 ) - { - jaddstr(json,"agent",agent); - jaddstr(json,"method",method); - if ( timestamp != 0 ) - jaddnum(json,"timestamp",timestamp); - if ( bits256_nonz(categoryhash) > 0 && memcmp(GENESIS_PUBKEY.bytes,categoryhash.bytes,sizeof(categoryhash)) != 0 ) - jaddbits256(json,"categoryhash",categoryhash); - if ( bits256_nonz(categoryhash) > 0 && memcmp(GENESIS_PUBKEY.bytes,subhash.bytes,sizeof(subhash)) != 0 ) - jaddbits256(json,"subhash",subhash); - expand_ipbits(destip,destipbits), jaddstr(json,"yourip",destip); - expand_ipbits(myipaddr,myipbits), jaddstr(json,"myip",myipaddr); - jaddstr(json,"mypub",bits256_str(str,senderpub)); - categoryhash = subhash = GENESIS_PUBKEY; - if ( (broadcastflag & 0x40) != 0 ) - { - jaddbits256(json,"categoryhash",categoryhash); - if ( (broadcastflag & 0x20) != 0 ) - jaddbits256(json,"subhash",subhash); - } - //jadd64bits(json,"tag",tag); - init_hexbytes_noT(checkstr,(void *)&checkc,sizeof(checkc)); - jaddstr(json,"check",checkstr); - jaddnum(json,"ov",othervalid); - if ( plaintext != 0 ) - jaddnum(json,"plaintext",plaintext!=0); - if ( broadcastflag != 0 ) - jaddnum(json,"broadcast",broadcastflag%SUPERNET_MAXHOPS); - if ( len < datalen ) - { - //printf("len %d vs %d datalen\n",len,datalen); - hexmsg = malloc(((datalen - len)<<1) + 1); - init_hexbytes_noT(hexmsg,&serialized[len],datalen - len); - //printf("hex.(%s)\n",hexmsg); - jaddstr(json,"hexmsg",hexmsg); - free(hexmsg); - } - //printf("bits2json.(%s)\n",jprint(json,0)); - return(json); - } else printf("cant decode apinum.%d (%d.%d)\n",apinum,apinum>>5,apinum%0x1f); - return(0); -} - -char *SuperNET_hexconv(char *hexmsg) -{ - cJSON *json; char *myip,*yourip,*retstr = hexmsg; uint32_t myipbits=0,destipbits=0; - uint8_t *bits; int32_t n,len = (int32_t)strlen(hexmsg); - //if ( hexmsg == 0 || is_hexstr(hexmsg,len) == 0 ) - return(hexmsg); - len >>= 1; - if ( (bits= calloc(1,len)) != 0 ) - { - decode_hex(bits,len,hexmsg); - if ( (json= cJSON_Parse((char *)bits)) != 0 ) - { - printf("parsed hexmsg.(%s)\n",(char *)bits); - if ( (myip= jstr(json,"myip")) != 0 ) - myipbits = (uint32_t)calc_ipbits(myip); - if ( (yourip= jstr(json,"yourip")) != 0 ) - destipbits = (uint32_t)calc_ipbits(yourip); - n = SuperNET_json2bits(bits,len,json,jbits256(json,"mypub"),juint(json,"checkc"),myipbits,destipbits,(int32_t)jdouble(json,"ov")); - cJSON *json2 = SuperNET_bits2json(bits,n); printf("hexconv.(%s) -> (%s)\n",jprint(json,0),jprint(json2,1)); - if ( (retstr= calloc(1,n*2+1)) != 0 ) - init_hexbytes_noT(retstr,bits,n); - else retstr = hexmsg; - free_json(json); - } //else printf("SuperNET_hexconv cant parse.(%s)\n",hexmsg); - free(bits); - } - return(retstr); -} - -void iguana_setkeys(struct supernet_info *myinfo,struct iguana_peer *addr,bits256 *myprivp,bits256 *mypubp,bits256 *destpubp,bits256 *nextprivp,bits256 *nextpubp,bits256 *nextdestpubp) -{ - *nextprivp = myinfo->privkey; - *nextpubp = myinfo->myaddr.pubkey; - *nextdestpubp = addr->pubkey; - if ( 1 || addr->validpub < 3 || addr->othervalid < 3 ) - *myprivp = GENESIS_PRIVKEY, *destpubp = *mypubp = GENESIS_PUBKEY; - else *myprivp = *nextprivp, *mypubp = *nextpubp, *destpubp = *nextdestpubp; - //char str[65]; printf("(priv.%llx pub.%llx) -> destpub.%s\n",(long long)myprivp->txid,(long long)mypubp->txid,bits256_str(str,*destpubp)); -} - -bits256 iguana_actualpubkey(int32_t *offsetp,uint8_t *cipher,int32_t cipherlen,bits256 destpubkey) -{ - int32_t i; - *offsetp = 0; - if ( cipherlen < 56+16 ) - return(destpubkey); - for (i=56; i<56+16; i++) - if ( cipher[i] != 0 ) - break; - if ( i == 56+16 ) - { - *offsetp = sizeof(destpubkey); - memcpy(destpubkey.bytes,cipher,sizeof(destpubkey)); - //char str[65]; printf("extracted destpubkey.(%s)\n",bits256_str(str,destpubkey)); - } - return(destpubkey); -} - -int32_t iguana_send_supernet(struct iguana_info *coin,struct iguana_peer *addr,char *jsonstr,int32_t delaymillis) -{ - int32_t datalen,cipherlen,qlen = -1; uint8_t *serialized,space2[32768],*cipher; cJSON *json; - struct supernet_info *myinfo; uint16_t checkc; - bits256 destpub,privkey,pubkey,nextprivkey,nextpubkey,nextdestpub; void *ptr = 0; - myinfo = SuperNET_MYINFO(0); - if ( (json= cJSON_Parse(jsonstr)) != 0 ) - { - iguana_setkeys(myinfo,addr,&privkey,&pubkey,&destpub,&nextprivkey,&nextpubkey,&nextdestpub); - if ( juint(json,"plaintext") == 0 && juint(json,"broadcast") == 0 && memcmp(destpub.bytes,GENESIS_PUBKEY.bytes,sizeof(pubkey)) == 0 ) - { - printf("reject broadcasting non-plaintext! (%s)\n",jsonstr); getchar(); - free_json(json); - return(-1); - } - serialized = malloc(sizeof(struct iguana_msghdr) + IGUANA_MAXPACKETSIZE); - checkc = SuperNET_checkc(nextprivkey,nextdestpub,&nextpubkey.txid,sizeof(nextpubkey.txid)); - if ( (datalen= SuperNET_json2bits(&serialized[sizeof(struct iguana_msghdr)],IGUANA_MAXPACKETSIZE,json,nextpubkey,checkc,(uint32_t)calc_ipbits(myinfo->ipaddr),(uint32_t)calc_ipbits(addr->ipaddr),addr->othervalid)) > 0 ) - { - if ( 0 && jstr(json,"method") != 0 && strcmp("getpeers",jstr(json,"method")) != 0 ) - printf("SUPERSEND -> (%s) (%s) delaymillis.%d datalen.%d\n",jprint(SuperNET_bits2json(&serialized[sizeof(struct iguana_msghdr)],datalen),1),addr->ipaddr,delaymillis,datalen); - if ( 0 && memcmp(destpub.bytes,GENESIS_PUBKEY.bytes,sizeof(destpub)) == 0 ) - qlen = iguana_queue_send(coin,addr,delaymillis,serialized,"SuperNET",datalen,0,0); - else - { - if ( (cipher= SuperNET_ciphercalc(&ptr,&cipherlen,&privkey,&destpub,&serialized[sizeof(struct iguana_msghdr)],datalen,space2,sizeof(space2))) != 0 ) - { - void *msgbits; int32_t msglen,offset; bits256 testpriv; uint8_t space[65536]; void *ptr2; - destpub = iguana_actualpubkey(&offset,cipher,cipherlen,destpub); - if ( 0 && (msgbits= SuperNET_deciphercalc(&ptr2,&msglen,testpriv,destpub,&cipher[offset],cipherlen-offset,space,sizeof(space))) == 0 ) - { - int32_t i; for (i=0; i> 32); - for (i=0; ipeers.active[j]; - if ( addr->usock >= 0 ) - { - if ( destipbits == addr->ipbits || category_peer(myinfo,addr,category,subhash) >= 0 ) - { - if ( port == 0 || addr->A.port == port ) - { - *coinp = Coins[i]; - return(addr); - } - } - } - } - } - } - return(0); -} - -char *SuperNET_DHTsend(struct supernet_info *myinfo,uint64_t destipbits,bits256 categoryhash,bits256 subhash,char *hexmsg,int32_t maxdelay,int32_t broadcastflag,int32_t plaintext) -{ - int32_t i,j; char *convstr,*jsonstr=0; struct iguana_peer *addr; cJSON *json; struct iguana_info *coin; - if ( myinfo == 0 ) - return(clonestr("{\"error\":\"no supernet_info\"}")); - json = cJSON_CreateObject(); - jaddstr(json,"agent","SuperNET"); - jaddstr(json,"method","DHT"); - convstr = SuperNET_hexconv(hexmsg); - jaddstr(json,"hexmsg",convstr); - if ( convstr != hexmsg ) - free(convstr); - if ( broadcastflag > 0 ) - jaddnum(json,"broadcast",broadcastflag-1); - if ( plaintext != 0 ) - jaddnum(json,"plaintext",plaintext!=0); - if ( bits256_nonz(categoryhash) > 0 && memcmp(categoryhash.bytes,GENESIS_PUBKEY.bytes,sizeof(bits256)) != 0 ) - jaddbits256(json,"categoryhash",categoryhash); - if ( bits256_nonz(subhash) > 0 && memcmp(subhash.bytes,GENESIS_PUBKEY.bytes,sizeof(bits256)) != 0 ) - jaddbits256(json,"subhash",subhash); - if ( SuperNET_hexmsgfind(myinfo,categoryhash,subhash,hexmsg,1) >= 0 ) - { - char str[65]; printf("duplicate hex.(%s) for %s\n",hexmsg,bits256_str(str,categoryhash)); - return(clonestr("{\"error\":\"duplicate packet rejected\"}")); - } else SuperNET_hexmsgadd(myinfo,categoryhash,subhash,hexmsg,tai_now(),0); - jsonstr = jprint(json,1); - if ( broadcastflag != 0 || destipbits == 0 ) - { - for (i=0; ipeers.active[j]; - if ( addr->usock >= 0 && addr->supernet != 0 && (broadcastflag != 0 || category_peer(myinfo,addr,categoryhash,subhash) >= 0) ) - { - char str[65]; printf("BROADCAST[%d] crc.%x %s SEND.(%d) to %s\n",j,calc_crc32(0,jsonstr,(int32_t)strlen(jsonstr)),bits256_str(str,categoryhash),(int32_t)strlen(jsonstr),addr->ipaddr); - iguana_send_supernet(Coins[i],addr,jsonstr,maxdelay==0?0:(rand()%maxdelay)); - } - } - } - } - return(clonestr("{\"result\":\"packet sent to all peers\"}")); - } - if ( (addr= iguana_peerfind(myinfo,&coin,destipbits,categoryhash,subhash)) == 0 ) - return(clonestr("{\"error\":\"no route found\"}")); - if ( SuperNET_hexmsgfind(myinfo,categoryhash,subhash,hexmsg,1) >= 0 ) - { - printf("SEND.(%s) to %s\n",jsonstr,addr->ipaddr); - iguana_send_supernet(coin,addr,jsonstr,maxdelay==0?0:(rand()%maxdelay)); - return(clonestr("{\"result\":\"packet sent directly\"}")); - } - return(clonestr("{\"result\":\"no appropriate peers to send to\"}")); -} - -char *SuperNET_DHTencode(struct supernet_info *myinfo,char *destip,bits256 categoryhash,bits256 subhash,char *hexmsg,int32_t maxdelay,int32_t broadcastflag,int32_t plaintext) -{ - uint32_t destipbits; char *retstr; - destipbits = (uint32_t)calc_ipbits(destip); - if ( (retstr = SuperNET_DHTsend(myinfo,destipbits,categoryhash,subhash,hexmsg,maxdelay,broadcastflag,plaintext)) != 0 ) - free(retstr); - return(clonestr("{\"result\":\"DHT sent\"}")); -} - -char *SuperNET_forward(struct supernet_info *myinfo,char *hexmsg,uint32_t destipbits,bits256 categoryhash,bits256 subhash,int32_t maxdelay,int32_t broadcastflag,int32_t plaintext) -{ - return(SuperNET_DHTsend(myinfo,destipbits,categoryhash,subhash,hexmsg,maxdelay,broadcastflag,plaintext)); -} - -int32_t SuperNET_destination(struct supernet_info *myinfo,uint32_t *destipbitsp,bits256 *categoryp,bits256 *subhashp,int32_t *maxdelayp,cJSON *json,char *remoteaddr) -{ - char *destip; int32_t destflag = 0; - if ( (destip= jstr(json,"destip")) != 0 ) - *destipbitsp = (uint32_t)calc_ipbits(destip); - else *destipbitsp = 0; - *maxdelayp = juint(json,"delay"); - *categoryp = jbits256(json,"categoryhash"); - *subhashp = jbits256(json,"subhash"); - if ( *destipbitsp != 0 ) - { - if ( *destipbitsp == myinfo->myaddr.selfipbits ) - destflag |= SUPERNET_ISMINE; - else destflag |= SUPERNET_FORWARD; - } - else if ( bits256_nonz(*categoryp) > 0 ) - { - if ( category_peer(myinfo,0,*categoryp,*subhashp) > 0 ) - destflag |= SUPERNET_ISMINE; - if ( juint(json,"broadcast") > 0 ) - destflag |= SUPERNET_FORWARD; - } - if ( remoteaddr == 0 || remoteaddr[0] == 0 || strcmp(remoteaddr,"127.0.0.1") == 0 ) - destflag |= SUPERNET_ISMINE; - return(destflag); -} - -char *SuperNET_JSON(struct supernet_info *myinfo,cJSON *json,char *remoteaddr,uint16_t port) -{ - char hexbuf[8192]; bits256 category,subhash; - int32_t hexlen,destflag,maxdelay,flag=0,newflag=0; uint32_t destipbits,timestamp; //cJSON *retjson; - char *forwardstr=0,*retstr=0,*agent=0,*method=0,*message,*hexmsg=0,*jsonstr=0; uint64_t tag; - //printf("SuperNET_JSON.(%s)\n",jprint(json,0)); - if ( remoteaddr != 0 && strcmp(remoteaddr,"127.0.0.1") == 0 ) - remoteaddr = 0; - if ( (agent = jstr(json,"agent")) == 0 ) - agent = "bitcoinrpc"; - method = jstr(json,"method"); - if ( agent != 0 && strcmp(agent,"pangea") == 0 && jobj(json,"categoryhash") == 0 ) - { - jaddbits256(json,"categoryhash",calc_categoryhashes(0,"pangea",0)); - if ( jobj(json,"subhash") == 0 ) - jaddbits256(json,"subhash",GENESIS_PUBKEY); - } - if ( remoteaddr == 0 ) - { - if ( jobj(json,"timestamp") != 0 ) - jdelete(json,"timestamp"); - timestamp = (uint32_t)time(NULL); - jaddnum(json,"timestamp",timestamp); - } - if ( (tag= j64bits(json,"tag")) == 0 ) - { - OS_randombytes((uint8_t *)&tag,sizeof(tag)); - jadd64bits(json,"tag",tag); - } - //printf("SuperNET_JSON.(%s) remote.(%s)\n",jprint(json,0),remoteaddr!=0?remoteaddr:""); - destflag = SuperNET_destination(myinfo,&destipbits,&category,&subhash,&maxdelay,json,remoteaddr); - //printf("destflag.%d\n",destflag); - if ( method != 0 && (hexmsg= jstr(json,"hexmsg")) == 0 && strcmp(agent,"bitcoinrpc") != 0 && (message= jstr(json,"message")) == 0 ) - { - jsonstr = jprint(json,0); - hexlen = (int32_t)strlen(jsonstr); - if ( hexlen*2+1 > sizeof(hexbuf) ) - hexmsg = malloc(hexlen*2+1), flag = 1; - else hexmsg = hexbuf; - init_hexbytes_noT(hexmsg,(uint8_t *)jsonstr,(int32_t)strlen(jsonstr)+1); - } - if ( (destflag & SUPERNET_FORWARD) != 0 ) - { - if ( hexmsg != 0 ) - { - if ( SuperNET_hexmsgfind(myinfo,category,subhash,hexmsg,0) < 0 ) - { - //printf("add.(%s)\n",hexmsg); - newflag = 1; - SuperNET_hexmsgadd(myinfo,category,subhash,hexmsg,tai_now(),remoteaddr); - forwardstr = SuperNET_forward(myinfo,hexmsg,destipbits,category,subhash,maxdelay,juint(json,"broadcast"),juint(json,"plaintext")!=0); - } - } - } - if ( (destflag & SUPERNET_ISMINE) != 0 && agent != 0 && method != 0 ) - { - if ( strcmp(agent,"bitcoinrpc") != 0 && newflag == 0 && hexmsg != 0 && SuperNET_hexmsgfind(myinfo,category,subhash,hexmsg,0) < 0 ) - SuperNET_hexmsgadd(myinfo,category,subhash,hexmsg,tai_now(),remoteaddr); - if ( (retstr= SuperNET_processJSON(myinfo,json,remoteaddr,port)) != 0 ) - { - //printf("retstr.(%s)\n",retstr); - /*if ( retstr[strlen(retstr)-1] != '\n' && (retjson= cJSON_Parse(retstr)) != 0 && is_cJSON_Array(retjson) == 0 ) - { - if ( jobj(retjson,"result") == 0 || jobj(retjson,"error") != 0 || jobj(retjson,"method") != 0 ) - { - free(retstr); - retstr = 0; - } - free_json(retjson); - }*/ - } else printf("null retstr from SuperNET_JSON\n"); - } - if ( flag != 0 && hexmsg != 0 && hexmsg != hexbuf ) - free(hexmsg); - if ( retstr == 0 ) - retstr = forwardstr, forwardstr = 0; - if ( forwardstr != 0 ) - free(forwardstr); - if ( jsonstr != 0 ) - free(jsonstr); - return(retstr); -} - -char *SuperNET_p2p(struct iguana_info *coin,struct iguana_peer *addr,int32_t *delaymillisp,char *ipaddr,uint8_t *data,int32_t datalen,int32_t compressed) -{ - struct supernet_info *myinfo;char *myipaddr,*method,*retstr,*checkstr; void *ptr=0; - bits256 senderpub,privkey,pubkey,nextprivkey,nextpubkey,nextdestpub; - uint16_t checkc,othercheckc; cJSON *json,*retjson; int32_t offset,maxdelay,msglen = datalen; - uint8_t space[8192],*msgbits = 0; - myinfo = SuperNET_MYINFO(0); - retstr = 0; - *delaymillisp = 0; - if ( compressed != 0 ) - { - //int32_t i; for (i=0; iipaddr); - addr->validpub = 0; - return(0); - } else { char str[65]; printf("GENESIS recv %s\n",bits256_str(str,senderpub)); } - } else printf("GENESIS recv GENESIS\n"); - } //else printf("decrypted mypriv.%llx senderpub.%llx\n",(long long)privkey.txid,(long long)senderpub.txid); - //for (i=0; iprivkey,senderpub,&senderpub.txid,sizeof(senderpub.txid)); - if ( checkc == othercheckc ) - addr->validpub++; - else if ( addr->validpub > 0 ) - addr->validpub >>= 1; - else addr->validpub--; - //printf("validpub.%d: %x vs %x shared.%llx\n",addr->validpub,checkc,othercheckc,(long long)addr->sharedseed.txid); - } - maxdelay = juint(json,"maxdelay"); - if ( 0 && jstr(json,"method") != 0 && strcmp(jstr(json,"method"),"getpeers") != 0 ) - printf("GOT >>>>>>>> SUPERNET P2P.(%s) from.%s %s valid.%d:%d\n",jprint(json,0),coin->symbol,addr->ipaddr,addr->validpub,addr->othervalid); - if ( (myipaddr= jstr(json,"yourip")) != 0 ) - SuperNET_checkipaddr(SuperNET_MYINFO(0),coin,addr,myipaddr,ipaddr); - jaddstr(json,"fromp2p",coin->symbol); - method = jstr(json,"method"); - if ( method != 0 && strcmp(method,"stop") == 0 ) - { - addr->dead = (uint32_t)time(NULL); - addr->rank = 0; - free_json(json); - if ( ptr != 0 ) - free(ptr); - //return(clonestr("{\"result\":\"peer marked as dead\"}")); - return(0); - } - retstr = SuperNET_JSON(myinfo,json,ipaddr,addr->A.port); - //printf("p2pret.(%s)\n",retstr); - *delaymillisp = SuperNET_delaymillis(myinfo,maxdelay); - senderpub = jbits256(json,"mypub"); - addr->othervalid = (int32_t)jdouble(json,"ov"); - addr->pubkey = senderpub; - free_json(json); - if ( (retjson= cJSON_Parse(retstr)) != 0 ) - { - if ( jstr(retjson,"error") != 0 || (jstr(retjson,"result") != 0 && jstr(retjson,"method") == 0) ) - { - //printf("filter.(%s) no need to send back\n",retstr); - free(retstr); - retstr = 0; - } - free_json(retjson); - } - } - if ( ptr != 0 ) - free(ptr); - return(retstr); -} - -cJSON *SuperNET_peerarray(struct iguana_info *coin,int32_t max,int32_t supernetflag) -{ - int32_t i,r,j,n = 0; struct iguana_peer *addr; cJSON *array = cJSON_CreateArray(); - r = rand(); - for (j=0; jpeers.active[i]; - if ( addr->usock >= 0 && supernetflag == (addr->supernet != 0) ) - { - jaddistr(array,addr->ipaddr); - if ( ++n >= max ) - break; - } - } - if ( n == 0 ) - { - free_json(array); - return(0); - } - return(array); -} - -int32_t SuperNET_coinpeers(struct iguana_info *coin,cJSON *SNjson,cJSON *rawjson,int32_t max) -{ - cJSON *array,*item; - if ( (array= SuperNET_peerarray(coin,max,1)) != 0 ) - { - max -= cJSON_GetArraySize(array); - item = cJSON_CreateObject(); - jaddstr(item,"coin",coin->symbol); - jadd(item,"peers",array); - jaddi(SNjson,item); - } - if ( max > 0 && (array= SuperNET_peerarray(coin,max,0)) != 0 ) - { - max -= cJSON_GetArraySize(array); - item = cJSON_CreateObject(); - jaddstr(item,"coin",coin->symbol); - jadd(item,"peers",array); - jaddi(rawjson,item); - } - return(max); -} - -void SuperNET_parsepeers(struct supernet_info *myinfo,cJSON *array,int32_t n,int32_t supernetflag) -{ - int32_t i,j,m; cJSON *coinarray,*item; char *symbol,*ipaddr; struct iguana_info *ptr; - if ( array != 0 && n > 0 ) - { - for (i=0; ictx,pubkey,privkey); - jaddbits256(retjson,"secp256k1",pub); - bitcoin_address(coinaddr,addrtype,pubkey,33); - jaddstr(retjson,"result",coinaddr); - return(jprint(retjson,1)); -} - -ZERO_ARGS(SuperNET,keypair) -{ - cJSON *retjson; bits256 pubkey,privkey; - if ( remoteaddr != 0 ) - return(clonestr("{\"error\":\"no remote\"}")); - retjson = cJSON_CreateObject(); - crypto_box_keypair(pubkey.bytes,privkey.bytes); - jaddstr(retjson,"result","generated keypair"); - jaddbits256(retjson,"privkey",privkey); - jaddbits256(retjson,"pubkey",pubkey); - return(jprint(retjson,1)); -} - -TWOHASHES_AND_STRING(SuperNET,decipher,privkey,srcpubkey,cipherstr) -{ - int32_t cipherlen=0,msglen; char *retstr; cJSON *retjson; void *ptr = 0; uint8_t *cipher,*message,space[8192]; - if ( remoteaddr != 0 ) - return(clonestr("{\"error\":\"no remote\"}")); - if ( cipherstr != 0 ) - cipherlen = (int32_t)strlen(cipherstr) >> 1; - if ( cipherlen < crypto_box_NONCEBYTES ) - return(clonestr("{\"error\":\"cipher is too short\"}")); - cipher = calloc(1,cipherlen); - decode_hex(cipher,cipherlen,cipherstr); - if ( (message= SuperNET_deciphercalc(&ptr,&msglen,privkey,srcpubkey,cipher,cipherlen,space,sizeof(space))) != 0 ) - { - message[msglen] = 0; - retjson = cJSON_CreateObject(); - jaddstr(retjson,"result","deciphered message"); - jaddstr(retjson,"message",(char *)message); - retstr = jprint(retjson,1); - if ( ptr != 0 ) - free(ptr); - } else retstr = clonestr("{\"error\":\"couldnt decipher message\"}"); - return(retstr); -} - -TWOHASHES_AND_STRING(SuperNET,cipher,privkey,destpubkey,message) -{ - cJSON *retjson; char *retstr,*hexstr,space[8129]; uint8_t space2[8129]; - uint8_t *cipher; int32_t cipherlen,onetimeflag; bits256 origprivkey; void *ptr = 0; - if ( remoteaddr != 0 ) - return(clonestr("{\"error\":\"no remote\"}")); - if ( (cipher= SuperNET_ciphercalc(&ptr,&cipherlen,&privkey,&destpubkey,(uint8_t *)message,(int32_t)strlen(message)+1,space2,sizeof(space2))) != 0 ) - { - if ( cipherlen > sizeof(space)/2 ) - hexstr = calloc(1,(cipherlen<<1)+1); - else hexstr = (void *)space; - init_hexbytes_noT(hexstr,cipher,cipherlen); - retjson = cJSON_CreateObject(); - jaddstr(retjson,"result",hexstr); - onetimeflag = memcmp(origprivkey.bytes,privkey.bytes,sizeof(privkey)); - if ( onetimeflag != 0 ) - { - //jaddbits256(retjson,"onetime_privkey",privkey); - jaddbits256(retjson,"onetime_pubkey",destpubkey); - if ( onetimeflag == 2 ) - jaddstr(retjson,"warning","onetime keypair was used to broadcast"); - } - retstr = jprint(retjson,1); - if ( hexstr != (void *)space ) - free(hexstr); - if ( ptr != 0 ) - free(ptr); - return(retstr); - } - printf("error encrypting message.(%s)\n",message); - return(clonestr("{\"error\":\"cant encrypt message\"}")); -} - -bits256 SuperNET_pindecipher(IGUANA_ARGS,char *pin,char *privcipher) -{ - cJSON *testjson; char *mstr,*cstr; bits256 privkey,pinpriv,pinpub; - conv_NXTpassword(pinpriv.bytes,pinpub.bytes,(uint8_t *)pin,(int32_t)strlen(pin)); - privkey = GENESIS_PRIVKEY; - if ( (cstr= SuperNET_decipher(IGUANA_CALLARGS,pinpriv,pinpub,privcipher)) != 0 ) - { - if ( (testjson= cJSON_Parse(cstr)) != 0 ) - { - if ( (mstr= jstr(testjson,"message")) != 0 && strlen(mstr) == sizeof(bits256)*2 ) - { - decode_hex(privkey.bytes,sizeof(privkey),mstr); - } else printf("error cant find message privcipher\n"); - free_json(testjson); - } else printf("Error decipher.(%s)\n",cstr); - free(cstr); - } else printf("null return from deciphering privcipher\n"); - return(privkey); -} - -THREE_STRINGS(SuperNET,rosetta,passphrase,pin,showprivkey) -{ - uint8_t flag = 0; uint64_t nxt64bits; bits256 check,privkey,pubkey,pinpriv,pinpub; - char str[128],privcipher[512],*privcipherstr,*cstr; cJSON *retjson; - if ( remoteaddr != 0 ) - return(clonestr("{\"error\":\"no remote\"}")); - nxt64bits = conv_NXTpassword(privkey.bytes,pubkey.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); - if ( showprivkey != 0 && strcmp(showprivkey,"yes") == 0 ) - flag = 1; - privcipher[0] = 0; - conv_NXTpassword(pinpriv.bytes,pinpub.bytes,(uint8_t *)pin,(int32_t)strlen(pin)); - if ( (cstr= SuperNET_cipher(IGUANA_CALLARGS,pinpriv,pinpub,bits256_str(str,privkey))) != 0 ) - { - if ( (retjson= cJSON_Parse(cstr)) != 0 ) - { - if ( (privcipherstr= jstr(retjson,"result")) != 0 ) - strcpy(privcipher,privcipherstr); - free_json(retjson); - } else printf("error parsing cipher retstr.(%s)\n",cstr); - free(cstr); - } else printf("error SuperNET_cipher null return\n"); - retjson = SuperNET_rosettajson(privkey,flag); - jaddstr(retjson,"privcipher",privcipher); - check = SuperNET_pindecipher(IGUANA_CALLARGS,pin,privcipher); - if ( memcmp(check.bytes,privkey.bytes,sizeof(check)) != 0 ) - { - jaddbits256(retjson,"deciphered",check); - jaddstr(retjson,"error","cant recreate privkey from (pin + privcipher)"); - } - else if ( flag != 0 ) - jaddbits256(retjson,"deciphered",check); - if ( jobj(retjson,"error") == 0 ) - jaddstr(retjson,"result","use pin and privcipher to access wallet"); - return(jprint(retjson,1)); -} - -STRING_ARG(SuperNET,broadcastcipher,message) -{ - bits256 zero; - if ( remoteaddr != 0 ) - return(clonestr("{\"error\":\"no remote\"}")); - memset(zero.bytes,0,sizeof(zero)); - return(SuperNET_cipher(IGUANA_CALLARGS,zero,zero,message)); -} - -STRING_ARG(SuperNET,broadcastdecipher,message) -{ - bits256 zero; - if ( remoteaddr != 0 ) - return(clonestr("{\"error\":\"no remote\"}")); - memset(zero.bytes,0,sizeof(zero)); - return(SuperNET_decipher(IGUANA_CALLARGS,zero,zero,message)); -} - -HASH_AND_STRING(SuperNET,multicastcipher,pubkey,message) -{ - bits256 zero; - if ( remoteaddr != 0 ) - return(clonestr("{\"error\":\"no remote\"}")); - memset(zero.bytes,0,sizeof(zero)); - return(SuperNET_cipher(IGUANA_CALLARGS,zero,pubkey,message)); -} - -HASH_AND_STRING(SuperNET,multicastdecipher,privkey,cipherstr) -{ - bits256 zero; - if ( remoteaddr != 0 ) - return(clonestr("{\"error\":\"no remote\"}")); - memset(zero.bytes,0,sizeof(zero)); - return(SuperNET_decipher(IGUANA_CALLARGS,privkey,zero,cipherstr)); -} - -ZERO_ARGS(SuperNET,stop) -{ - if ( remoteaddr == 0 || strncmp(remoteaddr,"127.0.0.1",strlen("127.0.0.1")) == 0 ) - { - iguana_exit(); - return(clonestr("{\"result\":\"exit started\"}")); - } else return(clonestr("{\"error\":\"cant do a remote stop of this node\"}")); -} - -TWO_ARRAYS(SuperNET,mypeers,supernet,rawpeers) -{ - SuperNET_parsepeers(myinfo,supernet,cJSON_GetArraySize(supernet),1); - SuperNET_parsepeers(myinfo,rawpeers,cJSON_GetArraySize(rawpeers),0); - return(clonestr("{\"result\":\"peers parsed\"}")); -} - -STRING_ARG(SuperNET,getpeers,activecoin) -{ - int32_t i,max = 64; - cJSON *SNjson,*rawjson,*retjson = cJSON_CreateObject(); - SNjson = cJSON_CreateArray(); - rawjson = cJSON_CreateArray(); - if ( coin != 0 ) - max = SuperNET_coinpeers(coin,SNjson,rawjson,max); - else - { - for (i=0; i0; i++) - if ( Coins[i] != 0 ) - max = SuperNET_coinpeers(Coins[i],SNjson,rawjson,max); - } - if ( max != 64 ) - { - jaddstr(retjson,"agent","SuperNET"); - jaddstr(retjson,"method","mypeers"); - jadd(retjson,"supernet",SNjson); - jadd(retjson,"rawpeers",rawjson); - } - else - { - jaddstr(retjson,"error","no peers"); - free_json(SNjson); - free_json(rawjson); - } - return(jprint(retjson,1)); -} - -TWOSTRINGS_AND_TWOHASHES_AND_TWOINTS(SuperNET,DHT,hexmsg,destip,categoryhash,subhash,maxdelay,broadcast) -{ - if ( remoteaddr != 0 ) - return(clonestr("{\"error\":\"cant remote DHT\"}")); - else if ( hexmsg == 0 || is_hexstr(hexmsg,(int32_t)strlen(hexmsg)) <= 0 ) - return(clonestr("{\"error\":\"hexmsg missing or not in hex\"}")); - return(SuperNET_DHTencode(myinfo,destip,categoryhash,subhash,hexmsg,maxdelay,broadcast,juint(json,"plaintext")!=0)); -} - -HASH_AND_STRING(SuperNET,saveconf,wallethash,confjsonstr) -{ - if ( remoteaddr != 0 ) - return(clonestr("{\"error\":\"no remote\"}")); - return(clonestr("{\"result\":\"saveconf here\"}")); -} - -HASH_ARRAY_STRING(SuperNET,layer,mypriv,otherpubs,str) -{ - if ( remoteaddr != 0 ) - return(clonestr("{\"error\":\"no remote\"}")); - return(clonestr("{\"result\":\"layer encrypt here\"}")); -} - -TWO_STRINGS(SuperNET,categoryhashes,category,subcategory) -{ - bits256 categoryhash,subhash; cJSON *retjson = cJSON_CreateObject(); - if ( remoteaddr != 0 ) - return(clonestr("{\"error\":\"no remote\"}")); - categoryhash = calc_categoryhashes(&subhash,category,subcategory); - jaddstr(retjson,"result","category hashes calculated"); - jaddbits256(retjson,"categoryhash",categoryhash); - jaddbits256(retjson,"subhash",subhash); - return(jprint(retjson,1)); -} - -TWO_STRINGS(SuperNET,subscribe,category,subcategory) -{ - bits256 categoryhash,subhash; - if ( remoteaddr != 0 ) - return(clonestr("{\"error\":\"no remote\"}")); - categoryhash = calc_categoryhashes(&subhash,category,subcategory); - if ( category_subscribe(myinfo,categoryhash,subhash) != 0 ) - return(clonestr("{\"result\":\"subscribed\"}")); - else return(clonestr("{\"error\":\"couldnt subscribe\"}")); -} - -TWO_STRINGS(SuperNET,gethexmsg,category,subcategory) -{ - bits256 categoryhash,subhash; struct category_msg *m; char *hexstr; cJSON *retjson; struct category_info *cat; - if ( remoteaddr != 0 ) - return(clonestr("{\"error\":\"no remote\"}")); - categoryhash = calc_categoryhashes(&subhash,category,subcategory); - if ( (m= category_gethexmsg(myinfo,&cat,categoryhash,subhash)) != 0 ) - { - hexstr = calloc(1,m->len*2+1); - init_hexbytes_noT(hexstr,m->msg,m->len); - retjson = cJSON_CreateObject(); - jaddstr(retjson,"result",hexstr); - free(hexstr); - return(jprint(retjson,1)); - } else return(clonestr("{\"result\":\"no message\"}")); -} - -THREE_STRINGS(SuperNET,posthexmsg,category,subcategory,hexmsg) -{ - bits256 categoryhash,subhash; - if ( remoteaddr != 0 ) - return(clonestr("{\"error\":\"no remote\"}")); - categoryhash = calc_categoryhashes(&subhash,category,subcategory); - category_posthexmsg(myinfo,categoryhash,subhash,hexmsg,tai_now(),remoteaddr); - return(clonestr("{\"result\":\"posted message\"}")); -} - -THREE_STRINGS(SuperNET,announce,category,subcategory,message) -{ - bits256 categoryhash,subhash; - if ( remoteaddr != 0 ) - return(clonestr("{\"error\":\"no remote\"}")); - categoryhash = calc_categoryhashes(&subhash,category,subcategory); - return(SuperNET_categorymulticast(myinfo,0,categoryhash,subhash,message,juint(json,"maxdelay"),juint(json,"broadcast"),juint(json,"plaintext"),json,remoteaddr)); -} - -THREE_STRINGS(SuperNET,survey,category,subcategory,message) -{ - bits256 categoryhash,subhash; - if ( remoteaddr != 0 ) - return(clonestr("{\"error\":\"no remote\"}")); - categoryhash = calc_categoryhashes(&subhash,category,subcategory); - return(SuperNET_categorymulticast(myinfo,1,categoryhash,subhash,message,juint(json,"maxdelay"),juint(json,"broadcast"),juint(json,"plaintext"),json,remoteaddr)); -} - -STRING_ARG(SuperNET,wif2priv,wif) -{ - bits256 privkey; char str[65]; uint8_t privkeytype; cJSON *retjson = cJSON_CreateObject(); - if ( bitcoin_wif2priv(&privkeytype,&privkey,wif) == sizeof(privkey) ) - { - jaddstr(retjson,"result","success"); - jaddstr(retjson,"privkey",bits256_str(str,privkey)); - jaddnum(retjson,"type",privkeytype); - } else jaddstr(retjson,"error","couldnt convert wif"); - return(jprint(retjson,1)); -} - -STRING_ARG(SuperNET,priv2wif,priv) -{ - bits256 privkey; char wifstr[65]; uint8_t wiftype; cJSON *retjson = cJSON_CreateObject(); - if ( strlen(priv) == sizeof(bits256)*2 && is_hexstr(priv,(int32_t)sizeof(bits256)*2) == sizeof(bits256)*2 ) - { - wiftype = coin != 0 ? coin->chain->wiftype : 0x80; - decode_hex(privkey.bytes,sizeof(privkey),priv); - if ( bitcoin_priv2wif(wifstr,privkey,wiftype) > 0 ) - { - jaddstr(retjson,"result","success"); - jaddstr(retjson,"privkey",priv); - jaddnum(retjson,"type",wiftype); - jaddstr(retjson,"wif",wifstr); - } else jaddstr(retjson,"error","couldnt convert privkey"); - } else jaddstr(retjson,"error","non 32 byte hex privkey"); - return(jprint(retjson,1)); -} - -STRING_ARG(SuperNET,myipaddr,ipaddr) -{ - cJSON *retjson = cJSON_CreateObject(); - if ( myinfo->ipaddr[0] == 0 ) - { - if ( is_ipaddr(ipaddr) != 0 ) - strcpy(myinfo->ipaddr,ipaddr); - } - jaddstr(retjson,"result",myinfo->ipaddr); - return(jprint(retjson,1)); -} - -STRING_ARG(SuperNET,setmyipaddr,ipaddr) -{ - cJSON *retjson = cJSON_CreateObject(); - if ( is_ipaddr(ipaddr) != 0 ) - { - strcpy(myinfo->ipaddr,ipaddr); - jaddstr(retjson,"result",myinfo->ipaddr); - } else jaddstr(retjson,"error","illegal ipaddr"); - return(jprint(retjson,1)); -} - -STRING_ARG(SuperNET,utime2utc,utime) -{ - uint32_t utc = 0; cJSON *retjson = cJSON_CreateObject(); - utc = OS_conv_utime(utime); - char str[65]; printf("utime.%s -> %u -> %s\n",utime,utc,utc_str(str,utc)); - jaddnum(retjson,"result",utc); - return(jprint(retjson,1)); -} - -INT_ARG(SuperNET,utc2utime,utc) -{ - char str[65]; cJSON *retjson = cJSON_CreateObject(); - jaddstr(retjson,"result",utc_str(str,utc)); - return(jprint(retjson,1)); -} - -ZERO_ARGS(SuperNET,logout) -{ - if ( remoteaddr != 0 ) - return(clonestr("{\"error\":\"no remote\"}")); - memset(myinfo->persistent_priv.bytes,0,sizeof(myinfo->persistent_priv)); - memset(myinfo->myaddr.persistent.bytes,0,sizeof(myinfo->myaddr.persistent)); - memset(myinfo->handle,0,sizeof(myinfo->handle)); - memset(myinfo->myaddr.NXTADDR,0,sizeof(myinfo->myaddr.NXTADDR)); - myinfo->myaddr.nxt64bits = 0; - myinfo->expiration = 0; - return(clonestr("{\"result\":\"logged out\"}")); -} - -ZERO_ARGS(SuperNET,activehandle) -{ - cJSON *retjson; - if ( remoteaddr != 0 ) - return(clonestr("{\"error\":\"no remote\"}")); - retjson = SuperNET_rosettajson(myinfo->persistent_priv,0); - jaddstr(retjson,"result","success"); - jaddstr(retjson,"handle",myinfo->handle); - jaddbits256(retjson,"persistent",myinfo->myaddr.persistent); - if ( myinfo->expiration != 0 ) - { - jaddstr(retjson,"status","unlocked"); - jaddnum(retjson,"duration",myinfo->expiration - time(NULL)); - } else jaddstr(retjson,"status","locked"); - SuperNET_MYINFOadd(myinfo); - return(jprint(retjson,1)); -} - -struct supernet_info *SuperNET_accountfind(cJSON *json) -{ - int32_t num; char *decryptstr; struct supernet_info M,*myinfo; struct iguana_info *coin = 0; - char *password,*permanentfile,*passphrase,*remoteaddr,*perspriv; - myinfo = 0; - if ( (password= jstr(json,"password")) == 0 ) - password = ""; - if ( (permanentfile= jstr(json,"permanentfile")) == 0 ) - permanentfile = ""; - if ( (passphrase= jstr(json,"passphrase")) == 0 ) - passphrase = ""; - remoteaddr = jstr(json,"remoteaddr"); - if ( (passphrase == 0 || passphrase[0] == 0) && (decryptstr= SuperNET_decryptjson(IGUANA_CALLARGS,password,permanentfile)) != 0 ) - { - if ( (json= cJSON_Parse(decryptstr)) != 0 ) - { - memset(&M,0,sizeof(M)); - if ( (perspriv= jstr(json,"persistent_priv")) != 0 && strlen(perspriv) == sizeof(bits256)*2 ) - { - M.persistent_priv = bits256_conv(perspriv); - SuperNET_setkeys(&M,0,0,0); - if ( (myinfo = SuperNET_MYINFOfind(&num,M.myaddr.persistent)) != 0 ) - { - printf("found account.(%s) %s %llu\n",myinfo!=0?myinfo->handle:"",M.myaddr.NXTADDR,(long long)M.myaddr.nxt64bits); - return(myinfo); - } - } - else if ( (passphrase= jstr(json,"result")) != 0 || (passphrase= jstr(json,"passphrase")) != 0 ) - { - SuperNET_setkeys(&M,passphrase,(int32_t)strlen(passphrase),1); - if ( (myinfo= SuperNET_MYINFOfind(&num,M.myaddr.persistent)) != 0 ) - { - printf("found account.(%s) %s %llu\n",myinfo!=0?myinfo->handle:"",M.myaddr.NXTADDR,(long long)M.myaddr.nxt64bits); - return(myinfo); - } - } else printf("no passphrase in (%s)\n",jprint(json,0)); - free_json(json); - } else printf("cant parse.(%s)\n",decryptstr); - free(decryptstr); - } - return(SuperNET_MYINFO(0)); -} - -FOUR_STRINGS(SuperNET,login,handle,password,permanentfile,passphrase) -{ - char *argstr,*str,*decryptstr = 0; cJSON *argjson; //uint32_t expire = myinfo->expiration; //savehandle[1024],savepassword[1024],savepermanentfile[1024] - if ( remoteaddr != 0 ) - return(clonestr("{\"error\":\"no remote\"}")); - //safecopy(savehandle,myinfo->handle,sizeof(myinfo->handle)); - //safecopy(savepassword,myinfo->secret,sizeof(myinfo->secret)); - //safecopy(savepermanentfile,myinfo->permanentfile,sizeof(myinfo->permanentfile)); - //if ( bits256_nonz(myinfo->persistent_priv) != 0 && (str= SuperNET_logout(IGUANA_CALLARGS)) != 0 ) - // free(str); - //myinfo->expiration = expire; - if ( handle != 0 && handle[0] != 0 ) - safecopy(myinfo->handle,handle,sizeof(myinfo->handle)); - else memset(myinfo->handle,0,sizeof(myinfo->handle)); - if ( password != 0 && password[0] != 0 ) - safecopy(myinfo->secret,password,sizeof(myinfo->secret)); - else if ( passphrase != 0 && passphrase[0] != 0 ) - safecopy(myinfo->secret,passphrase,sizeof(myinfo->secret)); - //else memset(myinfo->secret,0,sizeof(myinfo->secret)); - if ( permanentfile != 0 ) - safecopy(myinfo->permanentfile,permanentfile,sizeof(myinfo->permanentfile)); - //else memset(myinfo->permanentfile,0,sizeof(myinfo->permanentfile)); - if ( (decryptstr= SuperNET_decryptjson(IGUANA_CALLARGS,myinfo->secret,myinfo->permanentfile)) != 0 ) - { - if ( (argjson= cJSON_Parse(decryptstr)) != 0 ) - { - if ( jobj(argjson,"error") == 0 ) - { - //printf("decrypted.(%s) exp.%u pass.(%s)\n",decryptstr,myinfo->expiration,password); - if ( myinfo->decryptstr != 0 ) - free(myinfo->decryptstr); - myinfo->decryptstr = decryptstr; - if ( (passphrase= jstr(argjson,"passphrase")) != 0 ) - { - SuperNET_setkeys(myinfo,passphrase,(int32_t)strlen(passphrase),1); - free_json(argjson); - myinfo->expiration = (uint32_t)(time(NULL) + 3600); - return(SuperNET_activehandle(IGUANA_CALLARGS)); - } - else - { - free_json(argjson); - return(clonestr("{\"error\":\"cant find passphrase in decrypted json\"}")); - } - } else free_json(argjson); - } - else - { - free(decryptstr); - return(clonestr("{\"error\":\"cant parse decrypted json\"}")); - } - } - if ( passphrase != 0 && passphrase[0] != 0 ) - { - SuperNET_setkeys(myinfo,passphrase,(int32_t)strlen(passphrase),1); - if ( myinfo->decryptstr != 0 && (argjson= cJSON_Parse(myinfo->decryptstr)) != 0 ) - { - if ( jobj(argjson,"passphrase") != 0 ) - jdelete(argjson,"passphrase"); - if ( jobj(argjson,"error") != 0 ) - jdelete(argjson,"error"); - } else argjson = cJSON_CreateObject(); - jaddstr(argjson,"passphrase",passphrase); - argstr = jprint(argjson,1); - if ( (str= SuperNET_encryptjson(IGUANA_CALLARGS,myinfo->secret,myinfo->permanentfile,argstr)) != 0 ) - free(str); - free(argstr); - return(SuperNET_activehandle(IGUANA_CALLARGS)); - } - else return(clonestr("{\"error\":\"need passphrase\"}")); - printf("logged into (%s) %s %s\n",myinfo->myaddr.NXTADDR,myinfo->myaddr.BTC,myinfo->myaddr.BTCD); - return(SuperNET_activehandle(IGUANA_CALLARGS)); -} - -#include "../includes/iguana_apiundefs.h" diff --git a/iguana/SuperNET.h b/iguana/SuperNET.h deleted file mode 100755 index 4a963b279..000000000 --- a/iguana/SuperNET.h +++ /dev/null @@ -1,196 +0,0 @@ -/****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - -#ifndef INCLUDED_SUPERNET_H -#define INCLUDED_SUPERNET_H - -#define SUPERNET_MAXHOPS 7 -#include "../crypto777/OS_portable.h" -#include "../includes/cJSON.h" -//#include "../crypto777/nanosrc/nn.h" - -#define SUPERNET_GETPEERSTR "{\"agent\":\"SuperNET\",\"method\":\"getpeers\",\"plaintext\":1}" -#define SUPERNET_STOPSTR "{\"agent\":\"SuperNET\",\"method\":\"stop\",\"plaintext\":1}" - -#define SUPERNET_MAXEXCHANGES 64 -#define SUPERNET_LBPORT 7770 -#define SUPERNET_PUBPORT 7771 -#define SUPERNET_PORTP2P 7770 -#define SUPERNET_NETWORKTIMEOUT 10000 -#define SUPERNET_POLLTIMEOUT 1 -#define SUPERNET_APIUSLEEP (SUPERNET_POLLTIMEOUT * 10000) -#define SUPERNET_MAXAGENTS 64 -#define NXT_TOKEN_LEN 160 -#define nn_errstr() nn_strerror(nn_errno()) -#define MAX_SERVERNAME 128 -#define SUPERNET_MAXRECVBUF (1024 * 1024 * 16) -#define SUPERNET_PINGGAP 6 - -#define SUPERNET_FORWARD 2 -#define SUPERNET_ISMINE 1 -#define SUPERNET_MAXDELAY (1000 * 3600) -#define SUPERNET_APIVERSION 0 -#define SUPERNET_MAXTIMEDIFF 10 - -#define CONNECTION_NUMBITS 10 -struct endpoint { queue_t nnrecvQ; int32_t nnsock,nnind; uint32_t ipbits; uint16_t port,directind; uint8_t transport,nn; }; - -struct direct_connection { char handler[16]; struct endpoint epbits; int32_t sock; }; - -struct supernet_msghdr -{ - bits256 dest,sender,arg; - uint8_t type,serlen[3],ser_nonce[4],ser_timestamp[4],ser_duration[4]; - char agent[8],coin[5],func; - uint8_t data[]; -}; - -struct supernet_agent -{ - struct queueitem DL; queue_t recvQ; uint64_t totalrecv,totalsent; - int32_t (*recvfunc)(void *myinfo,struct supernet_agent *,struct supernet_msghdr *msg,uint8_t *data,int32_t datalen); - cJSON *networks; - char name[9],ipaddr[64],reppoint[64],pubpoint[64]; int32_t reqsock,repsock,pubsock,subsock; - uint32_t ipbits,dead; int32_t num,sock; uint16_t port,pubport,repport; -}; - -struct supernet_address -{ - bits256 pubkey,iphash,persistent; - uint32_t selfipbits,myipbits; int32_t confirmed,totalconfirmed; uint64_t nxt64bits; - char NXTADDR[32],BTC[64],BTCD[64]; -}; - -struct supernet_info -{ - char ipaddr[64],transport[8]; int32_t APISLEEP; int32_t iamrelay; uint32_t expiration,dirty; - int32_t Debuglevel,readyflag,dead,POLLTIMEOUT; char rpcsymbol[16],LBpoint[64],PUBpoint[64]; - //int32_t pullsock,subclient,lbclient,lbserver,servicesock,pubglobal,pubrelays,numservers; - bits256 privkey,persistent_priv,BTCmarkerhash; char secret[2048],NXTAPIURL[512],permanentfile[1024]; - uint8_t *recvbuf[6]; - struct supernet_address myaddr; - int32_t LBsock,PUBsock,reqsock,subsock,networktimeout,maxdelay; - uint16_t LBport,PUBport,reqport,subport,rpcport,publicRPC,argport; - //struct nn_pollfd pfd[SUPERNET_MAXAGENTS]; //struct relay_info active; - struct supernet_agent agents[SUPERNET_MAXAGENTS]; queue_t acceptQ; - int32_t numagents,numexchanges; - struct exchange_info *tradingexchanges[SUPERNET_MAXEXCHANGES]; - struct iguana_waccount *wallet; void *ctx; - char handle[1024],*decryptstr; -}; - -/*struct supernet_endpoint -{ - char name[64]; struct endpoint ep; - int32_t (*nnrecvfunc)(struct supernet_info *,struct supernet_endpoint *,int32_t ind,uint8_t *msg,int32_t nnlen); - queue_t nnrecvQ; - int32_t nnsock,num; struct endpoint eps[]; -};*/ - -struct category_chain -{ - bits256 *weights,*blocks,category_hwm,genesishash,hwmhash; - int32_t hashlen,addrlen,maxblocknum; - struct supernet_info *myinfo; - void *categoryinfo,*subinfo; - int32_t (*blockhash_func)(struct category_chain *catchain,void *blockhashp,void *data,int32_t datalen); - int32_t (*payment_func)(struct category_chain *catchain,void *src,void *dest,uint64_t amount); - bits256 (*stake_func)(struct category_chain *catchain,void *addr,int32_t addrlen); - bits256 (*hit_func)(struct category_chain *catchain,int32_t height,void *prevgenerator,void *addr,void *blockhashp); - bits256 (*default_func)(struct category_chain *catchain,int32_t func,int32_t height,void *prevgenerator,void *addr,void *blockhashp,bits256 heaviest); - int32_t (*ishwm_func)(struct category_chain *catchain,int32_t prevheight,void *prevblockhashp,void *blockhashp,void *prevgenerator,void *addr); -}; - -struct crypto777_msghdr -{ - struct acct777_sig sig __attribute__((packed)); - bits256 prevhash,btchash; - uint8_t cmd[8]; - uint8_t serialized[]; -} __attribute__((packed)); - -struct category_info -{ - UT_hash_handle hh; queue_t Q; - char *(*processfunc)(struct supernet_info *myinfo,struct category_info *cat,void *data,int32_t datalen,char *remoteaddr); - struct category_chain *catchain; - bits256 hash; void *info; struct category_info *sub; -}; -extern struct category_info *Categories; -struct category_msg { struct queueitem DL; struct tai t; uint64_t remoteipbits; int32_t len; uint8_t msg[]; }; - -struct exchange_quote { uint64_t satoshis,orderid,offerNXT,exchangebits; double price,volume; uint32_t timestamp,val; }; - -void expand_epbits(char *endpoint,struct endpoint epbits); -struct endpoint calc_epbits(char *transport,uint32_t ipbits,uint16_t port,int32_t type); - -struct supernet_info *SuperNET_MYINFO(char *passphrase); -void SuperNET_init(void *args); -char *SuperNET_JSON(struct supernet_info *myinfo,cJSON *json,char *remoteaddr,uint16_t port); - -char *SuperNET_jsonstr(struct supernet_info *myinfo,char *jsonstr,char *remoteaddr,uint16_t port); -char *SuperNET_DHTencode(struct supernet_info *myinfo,char *destip,bits256 category,bits256 subhash,char *hexmsg,int32_t maxdelay,int32_t broadcastflag,int32_t plaintext); -char *SuperNET_parser(struct supernet_info *myinfo,char *agent,char *method,cJSON *json,char *remoteaddr); -char *SuperNET_processJSON(struct supernet_info *myinfo,cJSON *json,char *remoteaddr,uint16_t port); -char *SuperNET_DHTsend(struct supernet_info *myinfo,uint64_t destipbits,bits256 category,bits256 subhash,char *hexmsg,int32_t maxdelay,int32_t broadcastflag,int32_t plaintext); -uint16_t SuperNET_API2num(char *agent,char *method); -int32_t SuperNET_num2API(char *agent,char *method,uint16_t num); -bits256 SuperNET_sharedseed(bits256 privkey,bits256 otherpub); -int32_t SuperNET_decrypt(bits256 *senderpubp,uint64_t *senderbitsp,uint32_t *timestampp,bits256 mypriv,bits256 mypub,uint8_t *dest,int32_t maxlen,uint8_t *src,int32_t len); -cJSON *SuperNET_argjson(cJSON *json); - -void *category_info(bits256 categoryhash,bits256 subhash); -void *category_infoset(bits256 categoryhash,bits256 subhash,void *info); -struct category_info *category_find(bits256 categoryhash,bits256 subhash); -void SuperNET_hexmsgprocess(struct supernet_info *myinfo,cJSON *retjson,cJSON *json,char *hexmsg,char *remoteaddr); -struct category_info *category_processfunc(bits256 categoryhash,bits256 subhash,char *(*process_func)(struct supernet_info *myinfo,struct category_info *cat,void *data,int32_t datalen,char *remoteaddr)); -char *pangea_hexmsg(struct supernet_info *myinfo,struct category_info *cat,void *data,int32_t len,char *remoteaddr); -void pangea_queues(struct supernet_info *myinfo); - -int32_t SuperNET_str2hex(uint8_t *hex,char *str); -void SuperNET_hex2str(char *str,uint8_t *hex,int32_t len); -void SuperNET_hexmsgadd(struct supernet_info *myinfo,bits256 categoryhash,bits256 subhash,char *hexmsg,struct tai now,char *remoteaddr); -int32_t SuperNET_hexmsgfind(struct supernet_info *myinfo,bits256 category,bits256 subhash,char *hexmsg,int32_t addflag); -void category_posthexmsg(struct supernet_info *myinfo,bits256 categoryhash,bits256 subhash,char *hexmsg,struct tai now,char *remoteaddr); -void *category_subscribe(struct supernet_info *myinfo,bits256 category,bits256 subhash); -struct category_msg *category_gethexmsg(struct supernet_info *myinfo,struct category_info **catptrp,bits256 categoryhash,bits256 subhash); -char *SuperNET_htmlstr(char *fname,char *htmlstr,int32_t maxsize,char *agentstr); -queue_t *category_Q(struct category_info **catptrp,bits256 categoryhash,bits256 subhash); - -char *SuperNET_categorymulticast(struct supernet_info *myinfo,int32_t surveyflag,bits256 categoryhash,bits256 subhash,char *message,int32_t maxdelay,int32_t broadcastflag,int32_t plaintext,cJSON *argjson,char *remoteaddr); -bits256 calc_categoryhashes(bits256 *subhashp,char *category,char *subcategory); -struct category_chain *category_chain_functions(struct supernet_info *myinfo,bits256 categoryhash,bits256 subhash,int32_t hashlen,int32_t addrlen,void *hash_func,void *stake_func,void *hit_func,void *default_func,void *ishwm_func,void *payment_func); -#define category_default_latest() (*catchain->default_func)(catchain,'L',0,0,0,0,zero) -void category_init(struct supernet_info *myinfo); -char *SuperNET_keysinit(struct supernet_info *myinfo,char *jsonstr); -double instantdex_aveprice(struct supernet_info *myinfo,struct exchange_quote *sortbuf,int32_t max,double *totalvolp,char *base,char *rel,double volume,cJSON *argjson); -void SuperNET_setkeys(struct supernet_info *myinfo,void *pass,int32_t passlen,int32_t dosha256); -char *InstantDEX_hexmsg(struct supernet_info *myinfo,struct category_info *cat,void *data,int32_t len,char *remoteaddr); -bits256 bitcoin_pubkey33(void *ctx,uint8_t data[33],bits256 privkey); -char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey,int32_t len); - -uint8_t *cards777_recover(uint8_t *shares[],uint8_t *sharenrs,int32_t M,int32_t numcards,int32_t N); -int32_t cards777_calcmofn(uint8_t *allshares,uint8_t *myshares[],uint8_t *sharenrs,int32_t M,bits256 *xoverz,int32_t numcards,int32_t N); -int32_t init_sharenrs(unsigned char sharenrs[255],unsigned char *orig,int32_t m,int32_t n); -struct supernet_info *SuperNET_MYINFOfind(int32_t *nump,bits256 pubkey); -void SuperNET_MYINFOadd(struct supernet_info *myinfo); -struct supernet_info *SuperNET_accountfind(cJSON *argjson); -int32_t SuperNET_MYINFOS(struct supernet_info **myinfos,int32_t max); -FILE *myfopen(char *fname,char *mode); -int32_t myfclose(FILE *fp); -cJSON *SuperNET_rosettajson(bits256 privkey,int32_t showprivs); - -#endif - diff --git a/iguana/SuperNET_category.c b/iguana/SuperNET_category.c deleted file mode 100755 index c56bce779..000000000 --- a/iguana/SuperNET_category.c +++ /dev/null @@ -1,214 +0,0 @@ -/****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - -#include "iguana777.h" - -#include "../includes/tweetnacl.h" -#include "../crypto777/OS_portable.h" -#include "../includes/libgfshare.h" -#include "../includes/utlist.h" -#include "../includes/uthash.h" -#include "../includes/curve25519.h" -#include "../includes/cJSON.h" - - - -bits256 calc_categoryhashes(bits256 *subhashp,char *category,char *subcategory) -{ - bits256 categoryhash; - if ( category == 0 || category[0] == 0 || strcmp(category,"broadcast") == 0 ) - categoryhash = GENESIS_PUBKEY; - else vcalc_sha256(0,categoryhash.bytes,(uint8_t *)category,(int32_t)strlen(category)); - if ( subhashp != 0 ) - { - if ( subcategory == 0 || subcategory[0] == 0 || strcmp(subcategory,"broadcast") == 0 ) - *subhashp = GENESIS_PUBKEY; - else vcalc_sha256(0,subhashp->bytes,(uint8_t *)subcategory,(int32_t)strlen(subcategory)); - } - return(categoryhash); -} - -struct category_info *category_find(bits256 categoryhash,bits256 subhash) -{ - struct category_info *cat=0,*sub = 0; - HASH_FIND(hh,Categories,categoryhash.bytes,sizeof(categoryhash),cat); - if ( cat != 0 ) - { - if ( bits256_nonz(subhash) > 0 && memcmp(GENESIS_PUBKEY.bytes,subhash.bytes,sizeof(subhash)) != 0 ) - { - HASH_FIND(hh,cat->sub,subhash.bytes,sizeof(subhash),sub); - if ( sub != 0 ) - return(sub); - } - return(cat); - } //else printf("category_find.(%s) not found\n",bits256_str(str,categoryhash));//, getchar(); - return(0); -} - -queue_t *category_Q(struct category_info **catptrp,bits256 categoryhash,bits256 subhash) -{ - struct category_info *cat; - *catptrp = 0; - if ( (cat= category_find(categoryhash,subhash)) != 0 ) - { - *catptrp = cat; - return(&cat->Q); - } - else return(0); -} - -void *category_info(bits256 categoryhash,bits256 subhash) -{ - struct category_info *cat; - if ( (cat= category_find(categoryhash,subhash)) != 0 ) - return(cat->info); - else return(0); -} - -void *category_infoset(bits256 categoryhash,bits256 subhash,void *info) -{ - struct category_info *cat; - if ( (cat= category_find(categoryhash,subhash)) != 0 ) - { - cat->info = info; - return(info); - } - return(0); -} - -struct category_info *category_processfunc(bits256 categoryhash,bits256 subhash,char *(*process_func)(struct supernet_info *myinfo,struct category_info *cat,void *data,int32_t datalen,char *remoteaddr)) -{ - struct category_info *cat; - if ( (cat= category_find(categoryhash,subhash)) != 0 ) - { - cat->processfunc = process_func; - return(cat); - } - return(0); -} - -struct category_msg *category_gethexmsg(struct supernet_info *myinfo,struct category_info **catptrp,bits256 categoryhash,bits256 subhash) -{ - queue_t *Q; - //char str[65]; printf("getmsg.(%s) %llx\n",bits256_str(str,categoryhash),(long long)subhash.txid); - if ( (Q= category_Q(catptrp,categoryhash,subhash)) != 0 ) - return(queue_dequeue(Q,0)); - else return(0); -} - -void category_posthexmsg(struct supernet_info *myinfo,bits256 categoryhash,bits256 subhash,char *hexmsg,struct tai now,char *remoteaddr) -{ - int32_t len; struct category_msg *m; queue_t *Q = 0; struct category_info *cat; - if ( (Q= category_Q(&cat,categoryhash,subhash)) != 0 ) - { - len = (int32_t)strlen(hexmsg) >> 1; - m = calloc(1,sizeof(*m) + len); - m->t = now, m->len = len; - if ( remoteaddr != 0 && remoteaddr[0] != 0 ) - m->remoteipbits = calc_ipbits(remoteaddr); - decode_hex(m->msg,m->len,hexmsg); - queue_enqueue("categoryQ",Q,&m->DL,0); - //char str[65]; printf("POST HEXMSG.(%s) -> %s.%llx len.%d\n",hexmsg,bits256_str(str,categoryhash),(long long)subhash.txid,m->len); - return; - } - // char str[65]; printf("no subscription for category.(%s) %llx\n",bits256_str(str,categoryhash),(long long)subhash.txid); -} - -void *category_subscribe(struct supernet_info *myinfo,bits256 categoryhash,bits256 subhash) -{ - struct category_info *cat,*sub; bits256 hash; - HASH_FIND(hh,Categories,categoryhash.bytes,sizeof(categoryhash),cat); - if ( cat == 0 ) - { - cat = mycalloc('c',1,sizeof(*cat)); - cat->hash = hash = categoryhash; - char str[65]; printf("ADD cat.(%s)\n",bits256_str(str,categoryhash)); - HASH_ADD(hh,Categories,hash,sizeof(hash),cat); - } - if ( bits256_nonz(subhash) > 0 && memcmp(GENESIS_PUBKEY.bytes,subhash.bytes,sizeof(subhash)) != 0 && cat != 0 ) - { - HASH_FIND(hh,cat->sub,subhash.bytes,sizeof(subhash),sub); - if ( sub == 0 ) - { - sub = mycalloc('c',1,sizeof(*sub)); - sub->hash = hash = subhash; - char str[65],str2[65]; printf("subadd.(%s) -> (%s)\n",bits256_str(str,hash),bits256_str(str2,categoryhash)); - HASH_ADD(hh,cat->sub,hash,sizeof(hash),sub); - } - } - return(cat); -} - -int32_t category_peer(struct supernet_info *myinfo,struct iguana_peer *addr,bits256 category,bits256 subhash) -{ - return(1); -} - -int32_t category_plaintext(struct supernet_info *myinfo,bits256 category,bits256 subhash,int32_t plaintext) -{ - return(plaintext); -} - -int32_t category_maxdelay(struct supernet_info *myinfo,bits256 category,bits256 subhash,int32_t maxdelay) -{ - return(maxdelay); -} - -int32_t category_broadcastflag(struct supernet_info *myinfo,bits256 category,bits256 subhash,int32_t broadcastflag) -{ - if ( broadcastflag < 1 ) - broadcastflag = 1; - else if ( broadcastflag > SUPERNET_MAXHOPS ) - broadcastflag = SUPERNET_MAXHOPS; - return(broadcastflag); -} - -char *SuperNET_categorymulticast(struct supernet_info *myinfo,int32_t surveyflag,bits256 categoryhash,bits256 subhash,char *message,int32_t maxdelay,int32_t broadcastflag,int32_t plaintext,cJSON *argjson,char *remoteaddr) -{ - char *hexmsg,*retstr; int32_t len; cJSON *retjson = cJSON_CreateObject(); - len = (int32_t)strlen(message); - //char str[65]; printf("multicast.(%s)\n",bits256_str(str,categoryhash)); - if ( is_hexstr(message,len) == 0 ) - { - hexmsg = malloc(((len+1) << 1) + 1); - init_hexbytes_noT(hexmsg,(uint8_t *)message,len+1); - } else hexmsg = message; - plaintext = category_plaintext(myinfo,categoryhash,subhash,plaintext); - broadcastflag = category_broadcastflag(myinfo,categoryhash,subhash,broadcastflag); - maxdelay = category_maxdelay(myinfo,categoryhash,subhash,maxdelay); - retstr = SuperNET_DHTsend(myinfo,0,categoryhash,subhash,hexmsg,maxdelay,broadcastflag,plaintext); - //if ( 0 && argjson != 0 ) - // SuperNET_hexmsgprocess(myinfo,retjson,argjson,hexmsg,remoteaddr); - if ( hexmsg != message) - free(hexmsg); - if ( retjson != 0 ) - { - if ( retstr != 0 ) - jaddstr(retjson,"result",retstr); - retstr = jprint(retjson,1); - } - return(retstr); -} - -void category_init(struct supernet_info *myinfo) -{ - bits256 pangeahash; - category_subscribe(myinfo,GENESIS_PUBKEY,GENESIS_PUBKEY); - pangeahash = calc_categoryhashes(0,"pangea",0); - category_subscribe(myinfo,pangeahash,GENESIS_PUBKEY); - category_processfunc(pangeahash,GENESIS_PUBKEY,pangea_hexmsg); - category_chain_functions(myinfo,pangeahash,GENESIS_PUBKEY,sizeof(bits256),sizeof(bits256),0,0,0,0,0,0); - exchanges777_init(myinfo,0,0); -} diff --git a/iguana/SuperNET_hexmsg.c b/iguana/SuperNET_hexmsg.c deleted file mode 100755 index b03701a9c..000000000 --- a/iguana/SuperNET_hexmsg.c +++ /dev/null @@ -1,390 +0,0 @@ -/****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - -#include "iguana777.h" - -int32_t SuperNET_hexmsgfind(struct supernet_info *myinfo,bits256 category,bits256 subhash,char *hexmsg,int32_t addflag) -{ - static int lastpurge; static uint64_t Packetcache[1024]; - bits256 packethash; int32_t i,datalen; - datalen = (int32_t)strlen(hexmsg) + 1; - vcalc_sha256(0,packethash.bytes,(void *)hexmsg,datalen); - if ( bits256_nonz(category) == 0 ) - category = GENESIS_PUBKEY; - if ( bits256_nonz(subhash) == 0 ) - subhash = GENESIS_PUBKEY; - packethash = curve25519(category,packethash); - //printf("addflag.%d packethash.%llx dest.%llx\n",addflag,(long long)packethash.txid,(long long)category.txid); - for (i=0; i slot[%d]\n",(long long)packethash.txid,hexmsg,i); - } - break; - } - else if ( Packetcache[i] == packethash.txid ) - { - //printf("SuperNET_DHTsend reject duplicate packet.%llx\n",(long long)packethash.txid); - return(i); - } - } - if ( i == sizeof(Packetcache)/sizeof(*Packetcache) ) - { - if ( addflag != 0 ) - { - printf("purge slot[%d]\n",lastpurge); - Packetcache[lastpurge++] = packethash.txid; - if ( lastpurge >= sizeof(Packetcache)/sizeof(*Packetcache) ) - lastpurge = 0; - } - } - return(-1); -} - -void SuperNET_hexmsgadd(struct supernet_info *myinfo,bits256 categoryhash,bits256 subhash,char *hexmsg,struct tai now,char *remoteaddr) -{ - char str[512],str2[65]; - str[0] = 0; - if ( memcmp(categoryhash.bytes,GENESIS_PUBKEY.bytes,sizeof(categoryhash)) == 0 ) - strcpy(str,"BROADCAST."); - else bits256_str(str+strlen(str),categoryhash); - if ( memcmp(subhash.bytes,GENESIS_PUBKEY.bytes,sizeof(subhash)) != 0 ) - { - bits256_str(str2,subhash); - strcat(str,str2); - } - category_posthexmsg(myinfo,categoryhash,subhash,hexmsg,now,remoteaddr); - //printf("HEXMSG.(%s).%llx -> %s\n",hexmsg,(long long)subhash.txid,str); -} - -void SuperNET_hexmsgprocess(struct supernet_info *myinfo,cJSON *retjson,cJSON *json,char *hexmsg,char *remoteaddr) -{ - int32_t len,flag=0; char *str; uint8_t _buf[8192],*buf = _buf; bits256 categoryhash,subhash; struct category_info *cat; - if ( hexmsg != 0 ) - { - len = (int32_t)strlen(hexmsg); - if ( is_hexstr(hexmsg,len) > 0 ) - { - len >>= 1; - if ( len > sizeof(_buf) ) - buf = malloc(len); - decode_hex(buf,len,hexmsg); - categoryhash = jbits256(json,"categoryhash"); - subhash = jbits256(json,"categoryhash"); - if ( bits256_nonz(subhash) == 0 ) - subhash = GENESIS_PUBKEY; - if ( (cat= category_find(categoryhash,subhash)) != 0 ) - { - if ( cat->processfunc != 0 ) - { - if ( (str= (*cat->processfunc)(myinfo,cat,buf,len,remoteaddr)) != 0 ) - { - if ( retjson != 0 ) - jaddstr(retjson,"processfunc",str); - else free(str); - } - flag = 1; - //printf("PROCESSFUNC\n"); - } - } - if ( flag == 0 ) - { - printf("no processfunc, posthexmsg\n"); - category_posthexmsg(myinfo,categoryhash,jbits256(json,"subhash"),hexmsg,tai_now(),remoteaddr); - } - //char str[65]; printf("HEXPROCESS.(%s) -> %s\n",hexmsg,bits256_str(str,categoryhash)); - if ( buf != _buf ) - free(buf); - } - } -} - -int32_t category_default_blockhash(struct category_chain *catchain,void *blockhashp,void *data,int32_t datalen) -{ - bits256 hash; - vcalc_sha256(0,hash.bytes,data,datalen); - vcalc_sha256(0,blockhashp,hash.bytes,sizeof(hash)); - return(sizeof(*blockhashp)); -} - -bits256 category_default_stake(struct category_chain *catchain,void *addr,int32_t addrlen) -{ - bits256 stake; - memset(stake.bytes,0,sizeof(stake)); - stake.txid = ((uint64_t)1 << 63); - return(stake); -} - -bits256 catgory_default_hit(struct category_chain *catchain,int32_t height,void *prevgenerator,void *addr,void *blockhashp) -{ - bits256 hash; bits256 rawhit,hit; - memset(rawhit.bytes,0,sizeof(rawhit)); - memset(hit.bytes,0,sizeof(hit)); - vcalc_sha256cat(hash.bytes,prevgenerator,catchain->addrlen,addr,catchain->addrlen); - hit = (*catchain->stake_func)(catchain,addr,catchain->addrlen); - rawhit.txid = hash.txid % ((uint64_t)1 << 42); - if ( rawhit.txid != 0 ) - hit.txid /= rawhit.txid; - return(hit); -} - -#define category_default_heaviest() (*catchain->default_func)(catchain,'H',0,0,0,0,zero) -#define category_default_latest() (*catchain->default_func)(catchain,'L',0,0,0,0,zero) -#define category_default_setheaviest(height,blockhashp,heaviest) (*catchain->default_func)(catchain,'S',height,0,0,blockhashp,zero) -#define category_default_weight(height) (*catchain->default_func)(catchain,'W',height,0,0,0,zero) -#define category_default_blockfind(height) (*catchain->default_func)(catchain,'B',height,0,0,0,zero) - -bits256 category_default_func(struct category_chain *catchain,int32_t func,int32_t height,void *prevgenerator,void *addr,void *blockhashp,bits256 heaviest) -{ - static const bits256 zero; - if ( catchain->hashlen != sizeof(bits256) || catchain->addrlen != sizeof(bits256) ) - { - printf("unsupported hashlen.%d or addrlen.%d\n",catchain->hashlen,catchain->addrlen); - return(zero); - } - if ( height > catchain->maxblocknum + (func == 'S') ) - { - printf("error func.%c setting heaviest. skipped %d -> %d?\n",func,catchain->maxblocknum,height); - return(catchain->category_hwm); - } - if ( func == 'H' ) - return(catchain->category_hwm); - else if ( func == 'L' ) - { - if ( catchain->maxblocknum < 0 ) - return(catchain->genesishash); - else return(catchain->blocks[catchain->maxblocknum]); - } - else if ( func == 'S' ) - { - catchain->category_hwm = heaviest; - if ( height > catchain->maxblocknum ) - { - catchain->weights = realloc(catchain->weights,(catchain->maxblocknum+1) * sizeof(*catchain->weights)); - catchain->blocks = realloc(catchain->blocks,(catchain->maxblocknum+1) * sizeof(*catchain->blocks)); - } - catchain->maxblocknum = height; - catchain->weights[height] = heaviest; - if ( blockhashp != 0 ) - memcpy(&catchain->blocks[height],blockhashp,sizeof(catchain->blocks[height])); - } - else if ( func == 'B' ) - { - if ( height <= catchain->maxblocknum ) - return(catchain->blocks[height]); - else - { - printf("error: illegal height.%d vs max.%d\n",height,catchain->maxblocknum); - return(zero); - } - } - else if ( func == 'W' ) - { - if ( height >= 0 && height < catchain->maxblocknum ) - return(catchain->weights[height]); - else printf("error getting weight for height.%d vs maxblocknum.%d\n",height,catchain->maxblocknum); - } - return(catchain->category_hwm); -} - -int32_t category_default_ishwm(struct category_chain *catchain,int32_t prevheight,void *prevblockhashp,void *blockhashp,void *prevgenerator,void *addr) -{ - bits256 checkhash,prevwt,oldhit,hit,heaviest; static const bits256 zero; - checkhash = category_default_blockfind(prevheight); - if ( memcmp(checkhash.bytes,prevblockhashp,catchain->hashlen) == 0 ) - { - heaviest = category_default_heaviest(); - prevwt = category_default_weight(prevheight); - oldhit = category_default_weight(prevheight+1); - hit = (*catchain->hit_func)(catchain,prevheight+1,prevgenerator,addr,blockhashp); - if ( hit.txid > oldhit.txid && prevwt.txid+hit.txid > heaviest.txid ) - { - heaviest.txid = (prevwt.txid + hit.txid); - category_default_setheaviest(prevheight+1,blockhashp,heaviest); - return(prevheight+1); - } - - } else return(-2); - return(-1); -} - -int32_t category_default_payment(struct category_chain *catchain,void *src,void *dest,uint64_t amount) -{ - //uint32_t srcind=0,destind=0; - // catchain->balances[destind] += amount; - // catchain->balances[srcind] -= amount; - return(0); -} - -struct category_chain *category_chain_functions(struct supernet_info *myinfo,bits256 categoryhash,bits256 subhash,int32_t hashlen,int32_t addrlen,void *hash_func,void *stake_func,void *hit_func,void *default_func,void *ishwm_func,void *payment_func) -{ - struct category_info *cat; struct category_chain *catchain = calloc(1,sizeof(*catchain)); - if ( (cat= category_find(categoryhash,subhash)) != 0 ) - { - catchain->maxblocknum = -1; - catchain->myinfo = myinfo, catchain->subinfo = cat->info; - if ( bits256_cmp(subhash,GENESIS_PUBKEY) == 0 ) - catchain->categoryinfo = cat->info, catchain->genesishash = categoryhash; - else catchain->categoryinfo = category_find(categoryhash,GENESIS_PUBKEY), catchain->genesishash = subhash; - if ( catchain->myinfo == 0 || catchain->categoryinfo || catchain->subinfo ) - { - printf("error with catchain pointers\n"); - return(0); - } - if ( (catchain->addrlen= addrlen) <= 0 || (catchain->hashlen= hashlen) <= 0 ) - { - printf("error with catchain lens.%d %d\n",addrlen,hashlen); - return(0); - } - if ( (catchain->blockhash_func= hash_func) == 0 || (catchain->stake_func= stake_func) == 0 || (catchain->hit_func= hit_func) == 0 || (catchain->default_func= default_func) == 0 || (catchain->ishwm_func= ishwm_func) == 0 || (catchain->payment_func= payment_func) == 0 ) - { - if ( addrlen == sizeof(bits256) && hashlen == sizeof(bits256) ) - { - catchain->blockhash_func = category_default_blockhash; - catchain->stake_func = category_default_stake; - catchain->hit_func = catgory_default_hit; - catchain->default_func = category_default_func; - catchain->ishwm_func = category_default_ishwm; - catchain->payment_func = category_default_payment; - } - else - { - printf("no category chain functions and addrlen.%d hashlen.%d not 32\n",addrlen,hashlen); - return(0); - } - } - cat->catchain = catchain; - return(catchain); - } - return(0); -} - -struct crypto777_msghdr *crypto777_msgcreate(struct supernet_info *myinfo,struct crypto777_msghdr *msg,int32_t datalen) -{ - bits256 otherpubkey; uint64_t signerbits; uint32_t timestamp; uint8_t buf[sizeof(msg->sig)],*data; - memset(&msg->sig,0,sizeof(msg->sig)); - datalen += (int32_t)(sizeof(*msg) - sizeof(msg->sig)); - data = (void *)((long)msg + sizeof(msg->sig)); - otherpubkey = acct777_msgpubkey(data,datalen); - timestamp = (uint32_t)time(NULL); - acct777_sign(&msg->sig,myinfo->privkey,otherpubkey,timestamp,data,datalen); - if ( (signerbits= acct777_validate(&msg->sig,acct777_msgprivkey(data,datalen),msg->sig.pubkey)) != 0 ) - { - //int32_t i; - //char str[65],str2[65]; - //for (i=0; i>>>>>>>>>>>>>>> validated [%ld] len.%d (%s + %s)\n",(long)data-(long)msg,datalen,bits256_str(str,acct777_msgprivkey(data,datalen)),bits256_str(str2,msg->sig.pubkey)); - memset(buf,0,sizeof(buf)); - acct777_rwsig(1,buf,&msg->sig); - memcpy(&msg->sig,buf,sizeof(buf)); - return(msg); - } else printf("error validating crypto777_msgcreate msg\n"); - return(0); -} - -void crypto777_catchain(struct supernet_info *myinfo,struct category_info *cat,bits256 *prevhashp,bits256 *btchashp) -{ - *btchashp = myinfo->BTCmarkerhash; - *prevhashp = cat->catchain->hwmhash; -} - -char *crypto777_sendmsg(struct supernet_info *myinfo,bits256 category,bits256 subhash,uint8_t *data,int32_t datalen,int32_t hops,char cmdstr[8]) -{ - char *hexstr,*retstr; int32_t i; struct crypto777_msghdr *msg; bits256 prevhash,btchash; struct category_info *cat; - msg = calloc(1,datalen + sizeof(*msg)); - for (i=0; icmd); i++) - if ( (msg->cmd[i]= cmdstr[i]) == 0 ) - break; - cat = category_info(category,subhash); - crypto777_catchain(myinfo,cat,&prevhash,&btchash); - iguana_rwbignum(1,msg->prevhash.bytes,sizeof(bits256),prevhash.bytes); - iguana_rwbignum(1,msg->btchash.bytes,sizeof(bits256),btchash.bytes); - memcpy(msg->serialized,data,datalen); - if ( crypto777_msgcreate(myinfo,msg,datalen) != 0 ) - { - printf(">>>>>>>>>>>> crypto777_send.(%s) datalen.%d allocsize.%d crc.%x\n",cmdstr,datalen,msg->sig.allocsize,calc_crc32(0,(void *)((long)msg + 8),datalen-8)); - hexstr = malloc(msg->sig.allocsize*2 + 1); - init_hexbytes_noT(hexstr,(uint8_t *)msg,msg->sig.allocsize); - retstr = SuperNET_categorymulticast(myinfo,0,category,subhash,hexstr,0,hops,1,0,0); - free(hexstr), free(msg); - return(retstr); - } - else - { - free(msg); - printf("cant crypto777 msgcreate datalen.%d\n",datalen); - return(clonestr("{\"error\":\"couldnt create crypto777 message\"}")); - } -} - -char *crypto777_hexmsg(struct supernet_info *myinfo,void *ptr,int32_t len,char *remoteaddr) -{ - struct crypto777_msghdr *msg = ptr; int32_t slen,datalen,newlen,flag = 0; bits256 prevhash,btchash; - uint8_t *serdata; uint64_t signerbits; uint8_t tmp[sizeof(msg->sig)]; cJSON *argjson = 0; - datalen = len - (int32_t)sizeof(msg->sig); - serdata = (void *)((long)msg + sizeof(msg->sig)); - acct777_rwsig(0,(void *)&msg->sig,(void *)tmp); - memcpy(&msg->sig,tmp,sizeof(msg->sig)); - /*if ( remoteaddr != 0 && remoteaddr[0] == 0 && strcmp("127.0.0.1",remoteaddr) == 0 && ((uint8_t *)msg)[len-1] == 0 && (argjson= cJSON_Parse((char *)msg)) != 0 ) - { - printf("string crypto777_hexmsg RESULT.(%s)\n",jprint(argjson,0)); - free_json(argjson); - return(clonestr("{\"error\":\"string base packets deprecated\"}")); - } - else*/ if ( (signerbits= acct777_validate(&msg->sig,acct777_msgprivkey(serdata,datalen),msg->sig.pubkey)) != 0 ) - { - flag++; - iguana_rwbignum(0,msg->prevhash.bytes,sizeof(bits256),prevhash.bytes); - iguana_rwbignum(0,msg->btchash.bytes,sizeof(bits256),btchash.bytes); - printf("crypto777_hexmsg <<<<<<<<<<<<< sigsize.%d VALIDATED [%ld] len.%d t%u allocsize.%d (%s) [%d]\n",(int32_t)sizeof(msg->sig),(long)serdata-(long)msg,datalen,msg->sig.timestamp,msg->sig.allocsize,(char *)msg->serialized,serdata[datalen-1]); - newlen = (int32_t)(msg->sig.allocsize - ((long)msg->serialized - (long)msg)); - serdata = msg->serialized; - if ( (argjson= cJSON_Parse((char *)serdata)) != 0 ) - { - slen = (int32_t)strlen((char *)serdata) + 1; - serdata = &serdata[slen]; - newlen -= slen; - free_json(argjson); - } - } - return(clonestr("{\"result\":\"test packet\"}")); -} - -/* - Consensus rules: - 0. Valid burn protocol or new issuance with small fee to crypto777 account -> OP_RETURN on BTCD with txid of payment/burn - Ti boundary - Balances reconciled and signed by issuer or super majority vote. Only amounts marked as frozen eligible for atomic swaps. - tx via p2p, signed payment to dest acct, based on balance. no outputs to double spend - payment valid during Ti and Ti+1 - atomic cross chain: both sides freeze trade amount, wait for this to be confirmed in BTC OP_RETURN, then a joint swap tx is signed by both and submitted to both chains - - valid tx must be accepted and sig added with Ti slippage. It is valid if signed, and balance is available. - - When Ti boundary changes, all online nodes reconcile the submitted tx to make sure all are confirmed and balances updated. Special tx like freezing, atomics, etc. - -Top PoS account publishes balance changes and majority stake approves. Next trade period starts at Ti+2 - - Split into odd/even offset periods to allow nonstop tx - - 1. all nodes must ntp and all tx must be timestamped within 50 seconds in the past and cant be more than 10 seconds from the future. - 2. tx spends cannot exceed available balance/2 as of prior Ti. - 2. all tx must refer to the latest BTC.Ti and BTCD.Ti and BTC.RTblock. any tx received that has older BTC.Ti is rejected. - 3. -*/ diff --git a/iguana/SuperNET_keys.c b/iguana/SuperNET_keys.c index a9a95a422..0e7b8d077 100755 --- a/iguana/SuperNET_keys.c +++ b/iguana/SuperNET_keys.c @@ -23,6 +23,46 @@ #include "../includes/cJSON.h" +/* +if ( 0 ) +{ + int32_t i,max=10000000; FILE *fp; bits256 check,val,hash = rand256(0); + if ( (fp= fopen("/tmp/seeds2","rb")) != 0 ) + { + if ( fread(&check,1,sizeof(check),fp) != sizeof(check) ) + printf("check read error\n"); + for (i=1; i (dsize= OS_filesize(destfname)) ) + printf("skip replacing (%s) since new one is smaller %lld vs %lld\n",finalfname,(long long)fsize,(long long)dsize); + else + { + strcpy(oldfname,finalfname), strcat(oldfname,".old"); + OS_renamefile(finalfname,oldfname); + OS_renamefile(destfname,finalfname); + } } + myinfo->dirty = 0; return(retval); } @@ -203,7 +249,7 @@ cJSON *SuperNET_decryptedjson(char *destfname,char *passphrase,int32_t passsize, SuperNET_linehash(fname2fa); // maps special chars wallet2priv = SuperNET_wallet2priv(fname2fa,wallethash); //char str[65],str2[65]; printf("(%s + %s) -> wallethash.%s 2.(%s)\n",passphrase,fname2fa,bits256_str(str,wallethash),bits256_str(str2,wallet2priv)); - } + } first = (bits256_nonz(wallethash) != 0 && bits256_cmp(wallethash,GENESIS_PRIVKEY) != 0); second = (bits256_nonz(wallet2priv) != 0 && bits256_cmp(wallet2priv,GENESIS_PRIVKEY) != 0); if ( first != 0 || second != 0 ) @@ -212,7 +258,7 @@ cJSON *SuperNET_decryptedjson(char *destfname,char *passphrase,int32_t passsize, wallethash = GENESIS_PRIVKEY; wallet2shared = SuperNET_wallet2shared(wallethash,wallet2priv); wallet2pub = curve25519(wallet2shared,curve25519_basepoint9()); - sprintf(destfname,"confs/%s",bits256_str(str,wallet2pub)); + sprintf(destfname,"%s/%s",GLOBAL_CONFSDIR,bits256_str(str,wallet2pub)); //printf("fname.(%s) wallet2pub.%s < [%s, %s]\n",destfname,bits256_str(str,wallet2pub),passphrase,fname2fa); if ( (confstr= OS_filestr(&allocsize,destfname)) != 0 ) { @@ -250,7 +296,7 @@ cJSON *SuperNET_decryptedjson(char *destfname,char *passphrase,int32_t passsize, return(msgjson); } -int32_t _SuperNET_encryptjson(char *destfname,char *passphrase,int32_t passsize,char *fname2fa,int32_t fnamesize,cJSON *argjson) +int32_t _SuperNET_encryptjson(struct supernet_info *myinfo,char *destfname,char *passphrase,int32_t passsize,char *fname2fa,int32_t fnamesize,cJSON *argjson) { bits256 wallethash,wallet2priv,wallet2shared,wallet2pub; char str[65]; wallethash = wallet2priv = GENESIS_PRIVKEY; @@ -262,16 +308,16 @@ int32_t _SuperNET_encryptjson(char *destfname,char *passphrase,int32_t passsize, //char str2[65]; printf("ENCRYPT.[%s %s] (%s) 2.%s\n",passphrase,fname2fa,bits256_str(str,wallethash),bits256_str(str2,wallet2priv)); wallet2shared = SuperNET_wallet2shared(wallethash,wallet2priv); wallet2pub = curve25519(wallet2shared,curve25519_basepoint9()); - sprintf(destfname,"confs/%s",bits256_str(str,wallet2pub)); - //printf("SAVE ARGJSON.(%s) [%s, %s] -> destfname.(%s)\n",jprint(argjson,0),passphrase,fname2fa,destfname); + sprintf(destfname,"%s/%s",GLOBAL_CONFSDIR,bits256_str(str,wallet2pub)); + printf("SAVE ARGJSON.(%s) [%s, %s] -> destfname.(%s)\n",jprint(argjson,0),passphrase,fname2fa,destfname); //printf("shared.%llx -> pub.%s\n",(long long)wallet2shared.txid,bits256_str(str,wallet2pub)); - SuperNET_savejsonfile(destfname,wallethash,wallet2pub,argjson); + SuperNET_savejsonfile(myinfo,destfname,wallethash,wallet2pub,argjson); return(0); } void SuperNET_setkeys(struct supernet_info *myinfo,void *pass,int32_t passlen,int32_t dosha256) { - uint8_t pubkey33[33]; bits256 hash; + bits256 hash; if ( dosha256 != 0 ) { memcpy(myinfo->secret,pass,passlen+1); @@ -285,11 +331,9 @@ void SuperNET_setkeys(struct supernet_info *myinfo,void *pass,int32_t passlen,in myinfo->myaddr.nxt64bits = hash.txid; } RS_encode(myinfo->myaddr.NXTADDR,myinfo->myaddr.nxt64bits); - bitcoin_pubkey33(myinfo->ctx,pubkey33,myinfo->persistent_priv); - //btc_priv2pub(pubkey33,myinfo->persistent_priv.bytes); - //init_hexbytes_noT(pubkeystr,pubkey33,33); - bitcoin_address(myinfo->myaddr.BTC,0,pubkey33,33); - bitcoin_address(myinfo->myaddr.BTCD,60,pubkey33,33); + bitcoin_pubkey33(myinfo->ctx,myinfo->persistent_pubkey33,myinfo->persistent_priv); + bitcoin_address(myinfo->myaddr.BTC,0,myinfo->persistent_pubkey33,33); + bitcoin_address(myinfo->myaddr.BTCD,60,myinfo->persistent_pubkey33,33); } void SuperNET_parsemyinfo(struct supernet_info *myinfo,cJSON *msgjson) @@ -308,7 +352,7 @@ void SuperNET_parsemyinfo(struct supernet_info *myinfo,cJSON *msgjson) if ( bits256_nonz(myinfo->persistent_priv) == 0 ) { printf("null persistent_priv? generate new one\n"); - OS_randombytes(myinfo->persistent_priv.bytes,sizeof(myinfo->privkey)); + OS_randombytes(myinfo->persistent_priv.bytes,sizeof(myinfo->persistent_priv)); } myinfo->myaddr.persistent = jbits256(msgjson,"persistent_pub"); checkhash = curve25519(myinfo->persistent_priv,curve25519_basepoint9()); @@ -343,6 +387,7 @@ char *SuperNET_keysinit(struct supernet_info *myinfo,char *argjsonstr) { OS_randombytes(myinfo->persistent_priv.bytes,sizeof(myinfo->persistent_priv)); myinfo->myaddr.persistent = curve25519(myinfo->persistent_priv,curve25519_basepoint9()); + bitcoin_pubkey33(myinfo->ctx,myinfo->persistent_pubkey33,myinfo->persistent_priv); } json = cJSON_CreateObject(); jaddstr(json,"ipaddr",myinfo->ipaddr); @@ -351,7 +396,7 @@ char *SuperNET_keysinit(struct supernet_info *myinfo,char *argjsonstr) OS_randombytes((void *)&r,sizeof(r)); jadd64bits(json,"rand",r); //printf("call SuperNET_encryptjson\n"); - _SuperNET_encryptjson(destfname,passphrase,sizeof(passphrase),fname2fa,sizeof(fname2fa),json); + _SuperNET_encryptjson(myinfo,destfname,passphrase,sizeof(passphrase),fname2fa,sizeof(fname2fa),json); //printf("save.(%s)\n",jprint(json,0)); free_json(json); } @@ -377,8 +422,8 @@ char *SuperNET_keysinit(struct supernet_info *myinfo,char *argjsonstr) strcpy(myinfo->ipaddr,"127.0.0.1"); myinfo->myaddr.selfipbits = (uint32_t)calc_ipbits(myinfo->ipaddr); } - OS_randombytes(myinfo->privkey.bytes,sizeof(myinfo->privkey)); - myinfo->myaddr.pubkey = curve25519(myinfo->privkey,curve25519_basepoint9()); + //OS_randombytes(myinfo->privkey.bytes,sizeof(myinfo->privkey)); + //myinfo->myaddr.pubkey = curve25519(myinfo->privkey,curve25519_basepoint9()); printf("(%s) %s %llu session(%s %s) persistent.%llx %llx\n",myinfo->ipaddr,myinfo->myaddr.NXTADDR,(long long)myinfo->myaddr.nxt64bits,bits256_str(str,myinfo->privkey),bits256_str(str2,myinfo->myaddr.pubkey),(long long)myinfo->persistent_priv.txid,(long long)myinfo->myaddr.persistent.txid); return(coinargs); } @@ -398,7 +443,7 @@ TWO_STRINGS(SuperNET,decryptjson,password,permanentfile) wallet2priv = bits256_conv(fname2); if ( (retjson= SuperNET_decryptedjson(destfname,pass,sizeof(pass),wallethash,fname2,sizeof(fname2),wallet2priv)) != 0 ) { - printf("decrypt pass.(%s) fname2.(%s) -> destfname.(%s)\n",pass,fname2,destfname); + //printf("decrypt pass.(%s) fname2.(%s) -> destfname.(%s)\n",pass,fname2,destfname); //obj = jduplicate(jobj(retjson,"payload")); //jdelete(retjson,"payload"); //jadd(retjson,"result",obj); @@ -419,7 +464,7 @@ THREE_STRINGS(SuperNET,encryptjson,password,permanentfile,payload) jdelete(argjson,"permanentfile"); jdelete(argjson,"timestamp"); jdelete(argjson,"tag"); - if ( _SuperNET_encryptjson(destfname,pass,sizeof(pass),fname2,sizeof(fname2),argjson) == 0 ) + if ( _SuperNET_encryptjson(myinfo,destfname,pass,sizeof(pass),fname2,sizeof(fname2),argjson) == 0 ) { jaddstr(retjson,"result","success"); jaddstr(retjson,"filename",destfname); diff --git a/iguana/btcd b/iguana/btcd deleted file mode 100755 index a2ad9d596..000000000 --- a/iguana/btcd +++ /dev/null @@ -1 +0,0 @@ -curl --url "http://127.0.0.1:7778" --data "{\"prefetchlag\":-1,\"poll\":1,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"BTCD\",\"startpend\":100,\"endpend\":100,\"services\":128,\"maxpeers\":64}" diff --git a/iguana/cards777.c b/iguana/cards777.c index 762a1df6d..023234d97 100755 --- a/iguana/cards777.c +++ b/iguana/cards777.c @@ -130,11 +130,11 @@ void cards777_layer(bits256 *layered,bits256 *xoverz,bits256 *incards,int32_t nu } } -int32_t cards777_calcmofn(uint8_t *allshares,uint8_t *myshares[],uint8_t *sharenrs,int32_t M,bits256 *xoverz,int32_t numcards,int32_t N) +int32_t cards777_calcmofn(struct supernet_info *myinfo,uint8_t *allshares,uint8_t *myshares[],uint8_t *sharenrs,int32_t M,bits256 *xoverz,int32_t numcards,int32_t N) { - int32_t size,j; + int32_t size,j; uint8_t space[8192]; size = N * sizeof(bits256) * numcards; - calc_shares(allshares,(void *)xoverz,size,size,M,N,sharenrs); // PM &allshares[playerj * size] to playerJ + calc_shares(myinfo,allshares,(void *)xoverz,size,size,M,N,sharenrs,space,sizeof(space)); // PM &allshares[playerj * size] to playerJ for (j=0; j + + + + + + iguana + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + +
+
+
+
+
+
+
+ + + +
+
+
+

Json posting form

+
+ +
+
+
+
+
+
+ +
+
+ + +
+
+
+
+
+
+ +
JSON response
+ +
+
+
+
+

+ List of games + +

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

Coin Management

+
+
+ +
+ + + +
+ + + + + + + + + + + + +
SymbolDescriptionStatusAction
+ + + + +
+
+
+
+
+ +
+
+ + +
+
+
+
+
+
+ +
JSON response
+ +
+
+
+
+
+
+ + + + +
+
+
+
+

+ Peer Management +

+
+
+ + + + +
+ +
+ + + + + + + + + + + + + + +
IP AddressCoin TypeHeightRankBlockFavourite Actions
+
+
+
+
+ +
+
+
+
+

+ Tradebot +

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

Settings

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

+ Encrypt/decrypt JSON +

+
+
+
+
+
+
+ +
+ + +
+
+
+ +
+
+ + +
+
+
+
+ +
+ + +
+
+
+ + +
+ +
+
+
+ +
JSON response
+ + +
encrypted file content
+ + +
+
+ +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + +
+
+
+
+ +
+ +
+ +
+
+ +
+
+ + +
+
+ +
+

Block Explorer tab

+
+
+
+ +
+

Set Active coin

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

InstantDEX

+
+ + + + + + + + + + + + + + +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+
+ + +
+
+ +
+ +
+ + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iguana/coins/allofus b/iguana/coins/allofus new file mode 100755 index 000000000..3671efb31 --- /dev/null +++ b/iguana/coins/allofus @@ -0,0 +1,19 @@ +../agents/iguana coins/genbtcd.json & +sleep 5 +../agents/iguana coins/genbtc.json & +sleep 5 +../agents/iguana coins/gendoge.json & +sleep 5 +../agents/iguana coins/gendgb.json & +sleep 5 +../agents/iguana coins/gengmc.json & +sleep 5 +../agents/iguana coins/genltc.json & +sleep 5 +../agents/iguana coins/genmzc.json & +sleep 5 +../agents/iguana coins/gensys.json & +sleep 5 +../agents/iguana coins/genuno.json & +sleep 5 +../agents/iguana coins/genzet.json & diff --git a/iguana/coins/basilisk b/iguana/coins/basilisk new file mode 100755 index 000000000..eedabcbdc --- /dev/null +++ b/iguana/coins/basilisk @@ -0,0 +1,4 @@ +curl --url "http://127.0.0.1:7778" --data "{\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"BTCD\",\"startpend\":1,\"endpend\":1,\"services\":128,\"maxpeers\":16,\"RELAY\":0,\"VALIDATE\":0,\"portp2p\":14631}" +curl --url "http://127.0.0.1:7778" --data "{\"prefetchlag\":5,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"BTC\",\"startpend\":1,\"endpend\":1,\"services\":128,\"maxpeers\":16,\"RELAY\":0,\"VALIDATE\":0,\"portp2p\":8333}" +curl --url "http://127.0.0.1:7778" --data "{\"RELAY\":0,\"VALIDATE\":0,\"prefetchlag\":11,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":1,\"endpend\":1,\"services\":128,\"maxpeers\":16,\"newcoin\":\"LTC\",\"name\":\"Litecoin\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"fbc0b6db\",\"p2p\":9333,\"rpc\":9334,\"pubval\":48,\"p2shval\":5,\"wifval\":176,\"txfee_satoshis\":\"100000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2\",\"genesis\":{\"version\":1,\"timestamp\":1317972665,\"nBits\":\"1e0ffff0\",\"nonce\":2084524493,\"merkle_root\":\"97ddfbbae6be97fd6cdf3e7ca13232a3afff2353e29badfab7f73011edd4ced9\"},\"alertpubkey\":\"040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9\",\"protover\":70002}" + diff --git a/iguana/coins/extract_genesis.c b/iguana/coins/extract_genesis.c new file mode 100755 index 000000000..906a21574 --- /dev/null +++ b/iguana/coins/extract_genesis.c @@ -0,0 +1,17 @@ +#include +int main() +{ +FILE *fp; +if ( (fp= fopen("blk00000.dat","rb")) != 0 ) +{ +int i,c; +for (i=0; i<88; i++) +{ +c = fgetc(fp); +if ( i >= 8 ) +printf("%02x",c); +} +printf("\n"); +fclose(fp); +} +} diff --git a/iguana/coins/fastbtcd b/iguana/coins/fastbtcd new file mode 100755 index 000000000..659d8a3f4 --- /dev/null +++ b/iguana/coins/fastbtcd @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"prefetchlag\":-1,\"poll\":1,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"BTCD\",\"startpend\":4096,\"endpend\":4096,\"services\":129,\"maxpeers\":256,\"RELAY\":1,\"VALIDATE\":1,\"portp2p\":14631,\"rpc\":14632}" diff --git a/iguana/coins/genbtc b/iguana/coins/genbtc new file mode 100755 index 000000000..7dbd49524 --- /dev/null +++ b/iguana/coins/genbtc @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"prefetchlag\":5,\"poll\":1,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"BTC\",\"startpend\":12,\"endpend\":1,\"services\":128,\"maxpeers\":512,\"RELAY\":1,\"VALIDATE\":1,\"portp2p\":8333}" diff --git a/iguana/coins/genbtc.json b/iguana/coins/genbtc.json new file mode 100755 index 000000000..ca5852db4 --- /dev/null +++ b/iguana/coins/genbtc.json @@ -0,0 +1 @@ +{"numhelpers":8,"prefetchlag":-1,"poll":1,"active":1,"agent":"iguana","method":"addcoin","newcoin":"BTC","startpend":1,"endpend":1,"services":129,"maxpeers":512,"RELAY":1,"VALIDATE":1,"portp2p":8333} diff --git a/iguana/coins/genbtcd b/iguana/coins/genbtcd new file mode 100755 index 000000000..46dab365f --- /dev/null +++ b/iguana/coins/genbtcd @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"prefetchlag\":-1,\"poll\":50,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"BTCD\",\"startpend\":8,\"endpend\":4,\"services\":129,\"maxpeers\":64,\"RELAY\":1,\"VALIDATE\":1,\"portp2p\":14631,\"rpc\":14632}" diff --git a/iguana/coins/genbtcd.json b/iguana/coins/genbtcd.json new file mode 100755 index 000000000..89a62eeec --- /dev/null +++ b/iguana/coins/genbtcd.json @@ -0,0 +1 @@ +{"prefetchlag":-1,"poll":50,"active":1,"agent":"iguana","method":"addcoin","newcoin":"BTCD","startpend":1,"endpend":1,"services":129,"maxpeers":64,"RELAY":1,"VALIDATE":1,"portp2p":14631,"rpc":14632} diff --git a/iguana/coins/genbtcfast.json b/iguana/coins/genbtcfast.json new file mode 100755 index 000000000..20a80c342 --- /dev/null +++ b/iguana/coins/genbtcfast.json @@ -0,0 +1 @@ +{"numhelpers":16,"prefetchlag":5,"poll":1,"active":1,"agent":"iguana","method":"addcoin","newcoin":"BTC","startpend":512,"endpend":64,"services":129,"maxpeers":512,"RELAY":1,"VALIDATE":1,"portp2p":8333} diff --git a/iguana/coins/gendgb b/iguana/coins/gendgb new file mode 100755 index 000000000..b056034b6 --- /dev/null +++ b/iguana/coins/gendgb @@ -0,0 +1,3 @@ +curl --url "http://127.0.0.1:7778" --data "{\"startpend\":16,\"endpend\":8,\"services\":129,\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"maxpeers\":256,\"newcoin\":\"DGB\",\"name\":\"Digibyte\",\"netmagic\":\"FAC3B6DA\",\"p2p\":12024,\"rpc\":14022,\"pubval\":30,\"p2shval\":5,\"wifval\":128,\"txfee_satoshis\":\"10000\",\"minconfirms\":2,\"genesishash\":\"7497ea1b465eb39f1c8f507bc877078fe016d6fcb6dfad3a64c98dcc6e1e8496\",\"genesis\":{\"version\":1,\"timestamp\":1389388394,\"nBits\":\"1e0ffff0\",\"nonce\":2447652,\"merkle_root\":\"72ddd9496b004221ed0557358846d9248ecd4c440ebd28ed901efc18757d0fad\"},\"alertpubkey\":\"04F04441C4757F356290A37C313C3772C5BC5003E898EB2E0CF365795543A7BF690C8BBBFA32EE3A3325477CE2000B7D0453EFBB203329D0F9DF34D5927D022BC9\"}" + + diff --git a/iguana/coins/gendgb.json b/iguana/coins/gendgb.json new file mode 100755 index 000000000..a4d3a1ff8 --- /dev/null +++ b/iguana/coins/gendgb.json @@ -0,0 +1,3 @@ +{"startpend":1,"endpend":1,"services":129,"RELAY":1,"VALIDATE":1,"prefetchlag":-1,"poll":10,"active":1,"agent":"iguana","method":"addcoin","maxpeers":256,"newcoin":"DGB","name":"Digibyte","netmagic":"FAC3B6DA","p2p":12024,"rpc":14022,"pubval":30,"p2shval":5,"wifval":128,"txfee_satoshis":"10000","minconfirms":2,"genesishash":"7497ea1b465eb39f1c8f507bc877078fe016d6fcb6dfad3a64c98dcc6e1e8496","genesis":{"version":1,"timestamp":1389388394,"nBits":"1e0ffff0","nonce":2447652,"merkle_root":"72ddd9496b004221ed0557358846d9248ecd4c440ebd28ed901efc18757d0fad"},"alertpubkey":"04F04441C4757F356290A37C313C3772C5BC5003E898EB2E0CF365795543A7BF690C8BBBFA32EE3A3325477CE2000B7D0453EFBB203329D0F9DF34D5927D022BC9"} + + diff --git a/iguana/coins/gendoge b/iguana/coins/gendoge new file mode 100755 index 000000000..34f665878 --- /dev/null +++ b/iguana/coins/gendoge @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"startpend\":8,\"endpend\":4,\"services\":129,\"auxpow\":1,\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"maxpeers\":256,\"newcoin\":\"DOGE\",\"name\":\"Dogecoin\",\"netmagic\":\"C0C0C0C0\",\"p2p\":22556,\"rpc\":22555,\"pubval\":30,\"p2shval\":5,\"wifval\":128,\"txfee_satoshis\":\"100000000\",\"minconfirms\":2,\"genesishash\":\"1a91e3dace36e2be3bf030a65679fe821aa1d6ef92e7c9902eb318182c355691\",\"genesis\":{\"hashalgo\": \"scrypt\",\"version\":1,\"timestamp\":1386325540,\"nBits\":\"1e0ffff0\",\"nonce\":99943,\"merkle_root\":\"5b2a3f53f605d62c53e62932dac6925e3d74afa5a4b459745c36d42d0ed26a69\"},\"alertpubkey\":\"04d4da7a5dae4db797d9b0644d57a5cd50e05a70f36091cd62e2fc41c98ded06340be5a43a35e185690cd9cde5d72da8f6d065b499b06f51dcfba14aad859f443a\"}" + diff --git a/iguana/coins/gendoge.json b/iguana/coins/gendoge.json new file mode 100755 index 000000000..148037ea5 --- /dev/null +++ b/iguana/coins/gendoge.json @@ -0,0 +1,2 @@ +{"startpend":1,"endpend":1,"services":129,"auxpow":1,"RELAY":1,"VALIDATE":1,"prefetchlag":-1,"poll":10,"active":1,"agent":"iguana","method":"addcoin","maxpeers":256,"newcoin":"DOGE","name":"Dogecoin","netmagic":"C0C0C0C0","p2p":22556,"rpc":22555,"pubval":30,"p2shval":5,"wifval":128,"txfee_satoshis":"100000000","minconfirms":2,"genesishash":"1a91e3dace36e2be3bf030a65679fe821aa1d6ef92e7c9902eb318182c355691","genesis":{"hashalgo": "scrypt","version":1,"timestamp":1386325540,"nBits":"1e0ffff0","nonce":99943,"merkle_root":"5b2a3f53f605d62c53e62932dac6925e3d74afa5a4b459745c36d42d0ed26a69"},"alertpubkey":"04d4da7a5dae4db797d9b0644d57a5cd50e05a70f36091cd62e2fc41c98ded06340be5a43a35e185690cd9cde5d72da8f6d065b499b06f51dcfba14aad859f443a"} + diff --git a/iguana/coins/geneac b/iguana/coins/geneac new file mode 100755 index 000000000..e7906a2a1 --- /dev/null +++ b/iguana/coins/geneac @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"services\":129,\"auxpow\":0,\"txhastimestamp\":1,\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"maxpeers\":256,\"newcoin\":\"EAC\",\"name\":\"EarthCoin\",\"netmagic\":\"C0DBF1FD\",\"p2p\":15677,\"rpc\":15678,\"pubval\":30,\"p2shval\":5,\"wifval\":221,\"txfee_satoshis\":\"1000000\",\"minconfirms\":2,\"genesishash\":\"21717d4df403301c0538f1cb9af718e483ad06728bbcd8cc6c9511e2f9146ced\",\"genesis\":{\"version\":1,\"timestamp\":1386746168,\"nBits\":\"1e0ffff0\",\"nonce\":12468024,\"merkle_root\":\"13757c3610411891452ac1f04d7f81946339b0e5b5aba216e6646e81805c4bb1\"},\"alertpubkey\":\"04dcba12349012341234900abcd12223abcd455abcd77788abcd000000aaaaabbbbbcccccdddddeeeeeff00ff00ff00ff001234567890abcdef0022446688abc11\"}" + diff --git a/iguana/coins/gengmc b/iguana/coins/gengmc new file mode 100755 index 000000000..688b18f50 --- /dev/null +++ b/iguana/coins/gengmc @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"startpend\":8,\"endpend\":2,\"services\":129,\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"maxpeers\":256,\"newcoin\":\"GMC\",\"name\":\"GameCredits\",\"netmagic\":\"fbc0b6db\",\"p2p\":40002,\"rpc\":40001,\"pubval\":38,\"p2shval\":5,\"wifval\":166,\"txfee_satoshis\":\"100000\",\"minconfirms\":2,\"genesishash\":\"91ec5f25ee9a0ffa1af7d4da4db9a552228dd2dc77cdb15b738be4e1f55f30ee\",\"genesis\":{\"hashalgo\":\"scrypt\",\"version\":1,\"timestamp\":1392757140,\"nBits\":\"1e0ffff0\",\"nonce\":2084565393,\"merkle_root\":\"d849db99a14164f4b4c8ad6d2d8d7e2b1ba7f89963e9f4bf9fad5ff1a4754429\"},\"alertpubkey\":\"04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284\",\"auxpow\":1,\"protover\":80006,\"isPoS\":0}" diff --git a/iguana/coins/gengmc.json b/iguana/coins/gengmc.json new file mode 100755 index 000000000..9e1894548 --- /dev/null +++ b/iguana/coins/gengmc.json @@ -0,0 +1 @@ +{"startpend":8,"endpend":2,"services":129,"RELAY":1,"VALIDATE":1,"prefetchlag":-1,"poll":10,"active":1,"agent":"iguana","method":"addcoin","maxpeers":256,"newcoin":"GMC","name":"GameCredits","netmagic":"fbc0b6db","p2p":40002,"rpc":40001,"pubval":38,"p2shval":5,"wifval":166,"txfee_satoshis":"100000","minconfirms":2,"genesishash":"91ec5f25ee9a0ffa1af7d4da4db9a552228dd2dc77cdb15b738be4e1f55f30ee","genesis":{"hashalgo":"scrypt","version":1,"timestamp":1392757140,"nBits":"1e0ffff0","nonce":2084565393,"merkle_root":"d849db99a14164f4b4c8ad6d2d8d7e2b1ba7f89963e9f4bf9fad5ff1a4754429"},"alertpubkey":"04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284","auxpow":1,"protover":80006,"isPoS":0}" diff --git a/iguana/coins/genltc b/iguana/coins/genltc new file mode 100755 index 000000000..f5faec175 --- /dev/null +++ b/iguana/coins/genltc @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":8,\"endpend\":8,\"services\":129,\"maxpeers\":256,\"newcoin\":\"LTC\",\"name\":\"Litecoin\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"fbc0b6db\",\"p2p\":9333,\"rpc\":9332,\"pubval\":48,\"p2shval\":5,\"wifval\":176,\"txfee_satoshis\":\"100000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2\",\"genesis\":{\"hashalgo\":\"scrypt\",\"version\":1,\"timestamp\":1317972665,\"nBits\":\"1e0ffff0\",\"nonce\":2084524493,\"merkle_root\":\"97ddfbbae6be97fd6cdf3e7ca13232a3afff2353e29badfab7f73011edd4ced9\"},\"alertpubkey\":\"040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9\",\"protover\":70002}" + diff --git a/iguana/coins/genltc.json b/iguana/coins/genltc.json new file mode 100755 index 000000000..cd0665d3c --- /dev/null +++ b/iguana/coins/genltc.json @@ -0,0 +1,2 @@ +{"RELAY":1,"VALIDATE":1,"prefetchlag":-1,"poll":10,"active":1,"agent":"iguana","method":"addcoin","startpend":1,"endpend":1,"services":129,"maxpeers":256,"newcoin":"LTC","name":"Litecoin","hasheaders":1,"useaddmultisig":0,"netmagic":"fbc0b6db","p2p":9333,"rpc":9332,"pubval":48,"p2shval":5,"wifval":176,"txfee_satoshis":"100000","isPoS":0,"minoutput":10000,"minconfirms":2,"genesishash":"12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2","genesis":{"version":1,"timestamp":1317972665,"nBits":"1e0ffff0","nonce":2084524493,"merkle_root":"97ddfbbae6be97fd6cdf3e7ca13232a3afff2353e29badfab7f73011edd4ced9"},"alertpubkey":"040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9","protover":70002} + diff --git a/iguana/coins/genmzc b/iguana/coins/genmzc new file mode 100755 index 000000000..0f3c41e6f --- /dev/null +++ b/iguana/coins/genmzc @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"services\":129,\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"maxpeers\":256,\"newcoin\":\"MZC\",\"name\":\"MazaCoin\",\"netmagic\":\"f8b503df\",\"p2p\":12835,\"rpc\":12832,\"pubval\":50,\"p2shval\":9,\"wifval\":224,\"txfee_satoshis\":\"0\",\"minconfirms\":2,\"genesishash\":\"00000c7c73d8ce604178dae13f0fc6ec0be3275614366d44b1b4b5c6e238c60c\",\"genesis\":{\"version\":1,\"timestamp\":1390747675,\"nBits\":\"1e0ffff0\",\"nonce\":2091390249,\"merkle_root\":\"62d496378e5834989dd9594cfc168dbb76f84a39bbda18286cddc7d1d1589f4f\"},\"alertpubkey\":\"04f09702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284\"}" diff --git a/iguana/coins/genmzc.json b/iguana/coins/genmzc.json new file mode 100755 index 000000000..5fcba58dd --- /dev/null +++ b/iguana/coins/genmzc.json @@ -0,0 +1 @@ +{"services":129,"startpend":1,"endpend":1,"RELAY":1,"VALIDATE":1,"prefetchlag":-1,"poll":10,"active":1,"agent":"iguana","method":"addcoin","maxpeers":256,"newcoin":"MZC","name":"MazaCoin","netmagic":"f8b503df","p2p":12835,"rpc":12832,"pubval":50,"p2shval":9,"wifval":224,"txfee_satoshis":"0","minconfirms":2,"genesishash":"00000c7c73d8ce604178dae13f0fc6ec0be3275614366d44b1b4b5c6e238c60c","genesis":{"version":1,"timestamp":1390747675,"nBits":"1e0ffff0","nonce":2091390249,"merkle_root":"62d496378e5834989dd9594cfc168dbb76f84a39bbda18286cddc7d1d1589f4f"},"alertpubkey":"04f09702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284"} diff --git a/iguana/coins/gennmc b/iguana/coins/gennmc new file mode 100755 index 000000000..6165ad19e --- /dev/null +++ b/iguana/coins/gennmc @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"NMC\",\"active\":1,\"maxpeers\":128,\"services\":129,\"poll\":1,\"minconfirms\":3,\"estblocktime\":600,\"txfee_satoshis\":500000,\"useaddmultisig\":1,\"hastimestamp\":0,\"pubval\":\"00\",\"scriptval\":\"05\",\"wiftype\":\"80\",\"netmagic\":\"fba4c795\",\"genesishash\":\"000000000062b72c5e2ceb45fbc8587e807c155b0da735e6483dfba2f0a9c770\",\"genesis\":{\"hashalgo\":\"sha256\",\"version\":1,\"timestamp\":1303000001,\"nbits\":\"1c007fff\",\"nonce\":2719916434,\"merkle_root\":\"41c62dbd9068c89a449525e3cd5ac61b20ece28c3c38b3f35b2161f0e6d3cb0d\"},\"p2p\":8334,\"rpc\":8836}" diff --git a/iguana/coins/gensys b/iguana/coins/gensys new file mode 100755 index 000000000..209e33213 --- /dev/null +++ b/iguana/coins/gensys @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":18,\"endpend\":18,\"services\":129,\"maxpeers\":256,\"newcoin\":\"SYS\",\"name\":\"SYScoin\",\"hasheaders\":0,\"useaddmultisig\":0,\"netmagic\":\"f9beb4d9\",\"p2p\":8369,\"rpc\":8370,\"pubval\":0,\"p2shval\":5,\"wifval\":128,\"txfee_satoshis\":\"100000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"0000072d66e51ab87de265765cc8bdd2d229a4307c672a1b3d5af692519cf765\",\"genesis\":{\"version\":1,\"timestamp\":1450473723,\"nBits\":\"1e0ffff0\",\"nonce\":5258726,\"merkle_root\":\"5215c5a2af9b63f2550b635eb2b354bb13645fd8fa31275394eb161944303065\"},\"protover\":70012,\"auxpow\":1}" + diff --git a/iguana/coins/gensys.json b/iguana/coins/gensys.json new file mode 100755 index 000000000..9e8983347 --- /dev/null +++ b/iguana/coins/gensys.json @@ -0,0 +1,2 @@ +{"RELAY":1,"VALIDATE":1,"prefetchlag":-1,"poll":10,"active":1,"agent":"iguana","method":"addcoin","startpend":1,"endpend":1,"services":129,"maxpeers":256,"newcoin":"SYS","name":"SYScoin","hasheaders":0,"useaddmultisig":0,"netmagic":"f9beb4d9","p2p":8369,"rpc":8370,"pubval":0,"p2shval":5,"wifval":128,"txfee_satoshis":"100000","isPoS":0,"minoutput":10000,"minconfirms":2,"genesishash":"0000072d66e51ab87de265765cc8bdd2d229a4307c672a1b3d5af692519cf765","genesis":{"version":1,"timestamp":1450473723,"nBits":"1e0ffff0","nonce":5258726,"merkle_root":"5215c5a2af9b63f2550b635eb2b354bb13645fd8fa31275394eb161944303065"},"protover":70012,"auxpow":1} + diff --git a/iguana/coins/genuno b/iguana/coins/genuno new file mode 100755 index 000000000..a8733b364 --- /dev/null +++ b/iguana/coins/genuno @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"services\":129,\"auxpow\":1,\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"maxpeers\":256,\"newcoin\":\"UNO\",\"name\":\"Unobtanium\",\"netmagic\":\"03d5b503\",\"p2p\":65534,\"rpc\":65535,\"pubval\":130,\"p2shval\":30,\"wifval\":224,\"txfee_satoshis\":\"1000000\",\"minconfirms\":2,\"genesishash\":\"000004c2fc5fffb810dccc197d603690099a68305232e552d96ccbe8e2c52b75\",\"genesis\":{\"version\":1,\"timestamp\":1375548986,\"nBits\":\"1e0fffff\",\"nonce\":1211565,\"merkle_root\":\"36a192e90f70131a884fe541a1e8a5643a28ba4cb24cbb2924bd0ee483f7f484\"},\"alertpubkey\":\"04fd68acb6a895f3462d91b43eef0da845f0d531958a858554feab3ac330562bf76910700b3f7c29ee273ddc4da2bb5b953858f6958a50e8831eb43ee30c32f21d\"}" diff --git a/iguana/coins/genuno.json b/iguana/coins/genuno.json new file mode 100755 index 000000000..64b226fa0 --- /dev/null +++ b/iguana/coins/genuno.json @@ -0,0 +1 @@ +{"services":129,"startpend":1,"endpend":1,"auxpow":1,"RELAY":1,"VALIDATE":1,"prefetchlag":-1,"poll":10,"active":1,"agent":"iguana","method":"addcoin","maxpeers":256,"newcoin":"UNO","name":"Unobtanium","netmagic":"03d5b503","p2p":65534,"rpc":65535,"pubval":130,"p2shval":30,"wifval":224,"txfee_satoshis":"1000000","minconfirms":2,"genesishash":"000004c2fc5fffb810dccc197d603690099a68305232e552d96ccbe8e2c52b75","genesis":{"version":1,"timestamp":1375548986,"nBits":"1e0fffff","nonce":1211565,"merkle_root":"36a192e90f70131a884fe541a1e8a5643a28ba4cb24cbb2924bd0ee483f7f484"},"alertpubkey":"04fd68acb6a895f3462d91b43eef0da845f0d531958a858554feab3ac330562bf76910700b3f7c29ee273ddc4da2bb5b953858f6958a50e8831eb43ee30c32f21d"} diff --git a/iguana/coins/genvia b/iguana/coins/genvia new file mode 100644 index 000000000..2b7bad89a --- /dev/null +++ b/iguana/coins/genvia @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"services\":129,\"startpend\":4,\"endpend\":4,\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"maxpeers\":256,\"newcoin\":\"VIA\",\"name\":\"Viacoin\",\"netmagic\":\"0f68c6cb\",\"p2p\":5223,\"rpc\":38332,\"pubval\":71,\"p2shval\":33,\"wifval\":199,\"txfee_satoshis\":\"100000\",\"minconfirms\":2,\"genesishash\":\"4e9b54001f9976049830128ec0331515eaabe35a70970d79971da1539a400ba1\",\"genesis\":{\"version\":1,\"timestamp\":1405164774,\"nBits\":\"1e01ffff\",\"nonce\":4016033,\"merkle_root\":\"0317d32e01a2adf6f2ac6f58c7cdaab6c656edc6fdb45986c739290053275200\"},\"alertpubkey\":\"047885d9f6c0cf9e918d04634d4dd696cf172763f1975aad099daddca3f3c712c98754eae293b36484055e0d414800e519f5a342e56e09217faf07abff5bd96507\"}" + diff --git a/iguana/coins/genvia.json b/iguana/coins/genvia.json new file mode 100755 index 000000000..28a100101 --- /dev/null +++ b/iguana/coins/genvia.json @@ -0,0 +1,2 @@ +{"services":129,"startpend":1,"endpend":1,"RELAY":1,"VALIDATE":1,"prefetchlag":-1,"poll":10,"active":1,"agent":"iguana","method":"addcoin","maxpeers":256,"newcoin":"VIA","name":"Viacoin","netmagic":"0f68c6cb","p2p":5223,"rpc":38332,"pubval":71,"p2shval":33,"wifval":199,"txfee_satoshis":"100000","minconfirms":2,"genesishash":"4e9b54001f9976049830128ec0331515eaabe35a70970d79971da1539a400ba1","genesis":{"version":1,"timestamp":1405164774,"nBits":"1e01ffff","nonce":4016033,"merkle_root":"0317d32e01a2adf6f2ac6f58c7cdaab6c656edc6fdb45986c739290053275200"},"alertpubkey":"047885d9f6c0cf9e918d04634d4dd696cf172763f1975aad099daddca3f3c712c98754eae293b36484055e0d414800e519f5a342e56e09217faf07abff5bd96507"} + diff --git a/iguana/coins/genvpn b/iguana/coins/genvpn new file mode 100755 index 000000000..d87aa3ab8 --- /dev/null +++ b/iguana/coins/genvpn @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":8,\"endpend\":8,\"services\":129,\"maxpeers\":256,\"newcoin\":\"VPN\",\"name\":\"VPNcoin\",\"hasheaders\":1,\"useaddmultisig\":0,\"isPoS\":1,\"minoutput\":10000,\"minconfirms\":2,\"txfee_satoshis\":\"10000\",\"genesishash\":\"00000ac7d764e7119da60d3c832b1d4458da9bc9ef9d5dd0d91a15f690a46d99\",\"genesis\":{\"version\":1,\"timestamp\":1409839200,\"nBits\":\"1e0fffff\",\"nonce\":64881664,\"merkle_root\":\"698a93a1cacd495a7a4fb3864ad8d06ed4421dedbc57f9aaad733ea53b1b5828\"},\"protover\":70002,\"netmagic\":\"fbc0b6db\",\"p2p\":1920,\"rpc\":1921,\"pubval\":71,\"p2shval\":5,\"wifval\":199}" diff --git a/iguana/coins/genzcash b/iguana/coins/genzcash new file mode 100755 index 000000000..fbdf0ccda --- /dev/null +++ b/iguana/coins/genzcash @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"unitval\":\"20\",\"zcash\":1,\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":8,\"endpend\":8,\"services\":129,\"maxpeers\":32,\"newcoin\":\"ZEC\",\"name\":\"Zcash\",\"hasheaders\":0,\"useaddmultisig\":0,\"netmagic\":\"6df6e755\",\"p2p\":18333,\"rpc\":18332,\"pubval\":111,\"p2shval\":196,\"wifval\":239,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"27d1f4ce03fc473c9dd6e1e307c682c8f802eae1f5a2f61402aa1ae8702ed3b6\",\"protover\":70002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5494dffff7f200000000000000000000000000000000000000000000000000000000000000000209d0900001dc600004fba000024e20100e5660000778100007e190100222f0100720e000056e50100eb12010089920100583d00002e660000844e01001bfe0100cf0c0000892a0000f5230000f9680000976e00009b7b000046770000afd80100bd0d000057650000048f000082b100006a2500004e0601006fef000048410100\"}" + diff --git a/iguana/coins/genzet b/iguana/coins/genzet new file mode 100755 index 000000000..b2a82272b --- /dev/null +++ b/iguana/coins/genzet @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"services\":129,\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"maxpeers\":256,\"newcoin\":\"ZET\",\"name\":\"Zetacoin\",\"netmagic\":\"fab503df\",\"p2p\":17333,\"rpc\":17335,\"pubval\":80,\"p2shval\":9,\"wifval\":224,\"txfee_satoshis\":\"10000\",\"minconfirms\":2,\"genesishash\":\"000006cab7aa2be2da91015902aa4458dd5fbb8778d175c36d429dc986f2bff4\",\"genesis\":{\"version\":1,\"timestamp\":1375548986,\"nBits\":\"1e0fffff\",\"nonce\":2089928209,\"merkle_root\":\"d0227b8c3e3d07bce9656b3d9e474f050d23458aaead93357dcfdac9ab9b79f9\"},\"alertpubkey\":\"045337216002ca6a71d63edf062895417610a723d453e722bf4728996c58661cdac3d4dec5cecd449b9086e9602b35cc726a9e0163e1a4d40f521fbdaebb674658\"}" diff --git a/iguana/coins/genzet.json b/iguana/coins/genzet.json new file mode 100755 index 000000000..8d3a29203 --- /dev/null +++ b/iguana/coins/genzet.json @@ -0,0 +1 @@ +{"services":129,"startpend":1,"endpend":1,"RELAY":1,"VALIDATE":1,"prefetchlag":-1,"poll":10,"active":1,"agent":"iguana","method":"addcoin","maxpeers":256,"newcoin":"ZET","name":"Zetacoin","netmagic":"fab503df","p2p":17333,"rpc":17335,"pubval":80,"p2shval":9,"wifval":224,"txfee_satoshis":"10000","minconfirms":2,"genesishash":"000006cab7aa2be2da91015902aa4458dd5fbb8778d175c36d429dc986f2bff4","genesis":{"version":1,"timestamp":1375548986,"nBits":"1e0fffff","nonce":2089928209,"merkle_root":"d0227b8c3e3d07bce9656b3d9e474f050d23458aaead93357dcfdac9ab9b79f9"},"alertpubkey":"045337216002ca6a71d63edf062895417610a723d453e722bf4728996c58661cdac3d4dec5cecd449b9086e9602b35cc726a9e0163e1a4d40f521fbdaebb674658"} diff --git a/iguana/coins/m_extract_genesis b/iguana/coins/m_extract_genesis new file mode 100755 index 000000000..eaa0bcae4 --- /dev/null +++ b/iguana/coins/m_extract_genesis @@ -0,0 +1 @@ +gcc -o extract_genesis extract_genesis.c diff --git a/iguana/confs/BTCD_hdrs.h b/iguana/confs/BTCD_hdrs.h deleted file mode 100644 index 591a99b77..000000000 --- a/iguana/confs/BTCD_hdrs.h +++ /dev/null @@ -1,2118 +0,0 @@ -char *BTCD_hdrs[][4] = { -{ "0", "0000044966f40703b516c5af180582d53f783bfd319bb045e2dc3e05ea695d46", "a5d211145f8e6ba0920b2893d307c5d7c207ae0800a80955299678d1706ea8ac", "000000000c4682089c916de89eb080a877566494d4009c0089baf35fe94de22f"}, -{ "500", "000000000680a9a697eb71155b18a5827e0889fca28afb81fcbb46469ed7877e", "79f80a8f54c6762d6408347c6dd7dfd2f8b8c191077c1d7881dfc5b7ec6a408e", "0000000002b868fe717dc60b8d146de4d9aecf779b7314224908566e01847769"}, -{ "1000", "0000000000000cf908c887020f8970b7fe952f8b81164d83a87621dfdb581d08", "3356ec4296ff2f04281492b0dedbaed80edeb6dd9170b87230ff79f6b0daade7", "0000000000001e7c6d28962a03b3d75ffa1355ecc6d3021893b2727a1ccfc669"}, -{ "1500", "00000000000010e39eaa987e695caed67aa0f3c33576fd2621422c7c09152ca2", "e9d31ec9f5dd4dc2688791edd4cd1abc964a7f843c59b948903c3492940e459a", "00000000000008c67c2e1a3dd564c1effa5ac4edb11b8326e790b01d215b10a9"}, -{ "2000", "000000000000029e318c44be8a5e1d5bc8f7823907bad160aa63fd6121dd0ba0", "15e2439021c4563c7eab5b91c916a0c9c24c3fb374b49ea24a4e2aec241ab099", "0000000000000477e2b3fe268246df89cc66d4df5ded6eb1339f46fc3d41e637"}, -{ "2500", "0000000000000b813b136f623f85155cad3069031cde918b4079e907e1a9fd58", "76ef339392ae45dbfeb2c6263e4e88b4cf888264d7ce8d0361258a81061fadb6", "000000000000219c3f912aedf5899b545ad237a1bdc16fc4111e092dba394e00"}, -{ "3000", "00000000000000e5ac27d3bb729f5c8a4312f69b28c9cefbb18b8fb55ee42c87", "dee1d4ef373897e52847416837485706f5c0fe29245eccb0819ea5d32f594051", "0000000000000858c1d9330cbe0318d79ec09d00d8b020245f4ebf7e304cc2d4"}, -{ "3500", "000000000000123b4e50db3f3706974f7e3593c2897bb545177d5c8a5a11fd35", "75c65538d4fd33e5a77d5b9e5d756587f45a7cdf55646f1cd72f2da2b7ae5772", "e0fc6aa659df9d7d095a90cdb67637df1d2802227242b139e988d5202669030d"}, -{ "4000", "000000000000013e3c1513a7ffd71ba89d7440fcacef6bb39a76527815a71043", "6ca70d4bd86a4dabdf5312a88a99aeb874d851df717879049d8d91b464109adc", "00000000000007a831e09844b26f357a1476bf9e99959ac3dbb92447e938835f"}, -{ "4500", "00000000000006e6d70e292394dd1f4aaf1ba3ea7313ae981a0b2f38ec4b0503", "e97f1c03d9e0445a00c160c648d2f4920845502e788f5c3f2a5a392544e18d0f", "00000000000008c83a46958c24fca62b35237889269858a639c7a659ad8dc031"}, -{ "5000", "0000000000000278ac01346559ded91fc585defc88bbaa9d7f111b199e516779", "45f12a1790418c3e9000bca11394719138f398232fd62ed3c801b5eb1e9199c5", "1a022cc6d920c078509ee34069e3671e195d7a906d0a2c7cf78dd2849d53a85e"}, -{ "5500", "0000000000000284e3d2455f09d9613ff71c49144823f882b003ed3177c1abab", "149ab9c582053c69b64d9b3c3041f04527bcd47c572d600947d0f737d675f953", "00000000000012ec069ab657694add0d888db799ec7c108c6de58b71da884f10"}, -{ "6000", "0000000000000bd43190ec79e54ba203c9387abcc8c1c03c52452a44466f24b9", "ab0f1f81aaf4000295bec7b21ad5c272aecf7dee60c451bcbfafb0beddabd2be", "0000000000000ecd84126d8a476fe76920ccd8ed29f4a2273a345eaa489f7722"}, -{ "6500", "000000000000029e27c331ad9865fee87dd19e5ed0e526f9974510649616cc1b", "9ee7b5e21984f8e3ceaa88aba5ab2d88dda10cf28c57b826e3bc8401d0bac0cd", "00000000000009a940eb271c38622190df017bb472da54a9a1aa218c5bf6cbd3"}, -{ "7000", "000000000000034bfd6bd049678a41563af84a9581d1ccaeb4952c954e327918", "e09213923b66de743cf8edc0389ab1b6c07c0c79a175b3e93364ed73c2efeb69", "0000000000000b7d67e13d24448ae494f169723a215e0d5c2f712af1e8e8b7fe"}, -{ "7500", "00000000000003c5a246cab977e3f339041bc95aec5cddcc3d459d3d2cd546a7", "4f26360f00347667d1c2f108ad3e2b2f599a599cb77b1ba9936988664ac53d4d", "00000000000005ffe9c2f6517f0e04151c40e9d8cddefccd34b71e0d4d35fb34"}, -{ "8000", "34d2ddf9aa94d6e02224588d3d6585028a22f05f53529a19a202f41ceb36cefc", "8bc3244b74f884ae355598fe0200a7f09bfab53de1b3e122020c4e2daf08fb63", "920cc777b15af320bdd69029399e2632bdfd8b741de509f2517ffb8feadf9493"}, -{ "8500", "87ddea52f5073e5283ecaf0efc637da3a47986396ad30b3adec8ea2ba5f6a09b", "65ae81f7094626494fe8b984141c265f689f4d6abd33a3a74eb491c31c5d02eb", "4349cc0c4c3040b098d7f6bcf5f98b47ce1057505800e7126f080024dad8d377"}, -{ "9000", "000000000000016845387841c3d5a584d82763471d4b84af3921ee2832715e4e", "11b2851886bc2208cd41c8381ff7bd6350379f6c0224f9608450fb0da56a59d0", "00000000000002e96fe9805c42c0bc4b6a8811ba63fa835f2cc2883635d8c98e"}, -{ "9500", "e64e3a10f2daca17836d2bb5868e76290da1fd3e0574da496b06182033fc70ac", "5d6ac130a3a5cbbf28cf389cda08aabe9cd5bd9a4da2d0ecd19c27d9ab2320fa", "0000000000000040b3de6fb9627d96a86bac4cd28e20cd2356724a9604fd5e55"}, -{ "10000", "00000000000001634bb95749a866092348aef266f9169c3ddbcf226d4807ba09", "986b59e97d259c74881bec99d68adad8e219a0fcaaff6af3fa31b0b5a89e1b33", "0000000000000069574ac2e1558be068e9f0306b79d0812476002ce7f17febf2"}, -{ "10500", "9a98c541a5e55bcfc8eb6d887d83dc6049a33381fe0aa3f4766006c1fb066905", "3dc29b2469167c07aab94fcd87c03e0bad1a99d47c3594d80b700b05190eb526", "00000000000002d53a0ae3c22c4424fd877c898dc08cc90860b382c68e4c8e45"}, -{ "11000", "54bafbe72c3547248f553615eacb2254fefe5a4d4cdcc66a2efde3e1ad9f3354", "7113b80a2fd13692c85f39cf494ba0d30285981b4829caaa92b4b748df134346", "000000000000025e9a743a9023c5edb762b776d61569e374b82accf5a78a95ff"}, -{ "11500", "9d6f0308699be5bed63c54a2518b7a69aa2e7f5076202ec077d3d53159b291e2", "32f1b2236a56fbbfac8b1a72e3e3cfe24531bdb2c38c2619828d11c1474df677", "c3c477b83ffe98338aeea638c538d0ce0f12486695dfed554ba6b7b9c1c68db9"}, -{ "12000", "00000000000000734778db2ce455744e1a50745ff4d10ad3d787e49c9c2913ba", "712f312d18d3c817c33e522dc5b7b50b9a16c0dbac13e56ce817e8b6d7f75ccd", "0000000000000136e3a5599beaaab0b3a4d61e88c79b859be81dcf94ef9c9e7d"}, -{ "12500", "00000000000001209c8fe742d1a45c5fa9689f8622217ace049fa3864ae24321", "0c4bf64e0024dde945ddad558a13bb180d931ed8d6ca79c13112a154db415794", "805c869dc4a5e69debd0ac3b9ed943839f89b4e75ad9e0129e29919656344ff1"}, -{ "13000", "0000000000000064fade9e75fa24d1d1974f5ca69e84e8688ef0a58b9dd2dad2", "b3411ebcf6385fb575beaac292c70d4e79686d832d6138ff3b68cac8fb8e96c4", "00000000000000ff65f8b119f936e985947155cc1dce87a01ca201f5808bbccf"}, -{ "13500", "000000000000012cdd1996be2f29e14c0654b11476e254e4ba4c6829c6887ac6", "054f36fdd7e83ed836fa5c6ca63ee54929fe3549b45da07a1efd1cbfca73188f", "87ac07eb5721f5c903e1f30e1082ece5aa619e403f3267f3a4ce0d061fb258c1"}, -{ "14000", "00000000000000b930521b5956b17943d5dcf001b4d319ba7157bd7fee6a6fa1", "80ed5287e00bf627a20e525cacd1b6ebc2077a3e2c71a400bec64eb7b80046f5", "b11909221a9f3cb0cd4e5edfb6024d1ac49ada7c08a77c0ebdc129b05747fb0b"}, -{ "14500", "225abc3eacd079cc0949cd8d0eb8978b5bb00720da7178ef5652e70754914d88", "c87e7237cadf805554ab3f259bc89eecda51149fdff0ffb29925712a218f76f8", "4daa8b7d1d927bfb346a7314e891a986bd793b17985722bac72223a15869eafb"}, -{ "15000", "000000000000001f08d59b246a225efd70b813c3df8e468bc9d99d7d686fedc6", "2ec038bb14816230448f041cae3a9ab64f4e237a53cdb0416dff8a2e062586b5", "e874af931cde446e73ca568e2d367e777e799a4bba62573373d36ca7c7f00bf0"}, -{ "15500", "1181e59d86d7026c523659c152db3732c69e56a04ead32a0617be36ad3f2f0ad", "a2511b8ee2e0158dc668e0de527e71455b7245c01f41ad66e296118715aa33a5", "000000000000009e8b780ae68208f996543f46c2580ea3bd12fb75d01093498c"}, -{ "16000", "0000000000000015155b08a0f074b1ae3c960bb90e96549a16d0b3eb20a4353a", "05409419f76edb4ecdaba62aa65195063865344c93cfa1e35bd41931201830dd", "b3f2857fbea121637598c8f7460fa13da33cd224af1373cabb2e6b2581ea0983"}, -{ "16500", "91d0e76a759d19aed57d2657cea4dbe861e849b57602a4c5c69028d24f795fb5", "767a41f042292ccf2acdb0b91163b18dd6b59aae25ba60a8557a01f02a5db8d9", "0000000000000078da7ba00aa57c04dd563cb07989d2c329a6913b7736ff9044"}, -{ "17000", "000000000000009f949c3d1a6eb1d50cbe5a3638acc49987902526df0d4c3eee", "dc090785300641d04d64f572fa7d645faa11c4677d74ff356bd8d51f50c0517a", "3074c34dbe4aa0c81eee8b20f475f4adf1f31e0711057caa2394e46f3b0490c5"}, -{ "17500", "00000000000000376f6a1ca86680e16d0127507a1182507e502c6cb85cb6719d", "89dd74d7a8b4f5ee127e7b4aebe54f4cb2c91c79fbc3045a59e5f94227ac6b12", "b128c00df0413a021711fb36ca2fdc1f27a5357ca63ce93ff5d1b40e2683cdf8"}, -{ "18000", "a02b59af01d4fc762d8a5708b22be769b7ef651afa88ecada21eec58dfd53cdd", "42abadc5ef27ee4c954518ed1a1e865a3b2bff3683baad8fb35589f8953ac5e4", "00000000000000a77265a8b139651c098948666521ff2f23b494e78e1dfd384d"}, -{ "18500", "00000000000000dc2e6182da1a35d916b98a4778fc35c50de27a770b9f63daeb", "7a44c2603b3d31b23a607a40cd63f9ce9486a7a3de507bb26f6ad7c1e0e75466", "0000000000000031466bf69a5d20f11e97c1a2f96bd3e77bc632924c589d32cc"}, -{ "19000", "00000000000000017207a368616b26632bf68e16984c098be64d2fb064d3a2dc", "190ef6e670cda631380598333765702648c55bbc0c92d68d3c2bb5f76bc546d6", "6f2c3f758ce2e2ef7fca1fbc0d043164db325f4a886001d369af7feee1acba53"}, -{ "19500", "00000000000000ab3d7e8810b7ca9f8b61f630ec6e596ee105cbeffe80c41d4e", "5bb4af1b5c912873e90a93c0d2c998b367768f05fa8650246bce8dd4e8b5f0a8", "000000000000006f4d9713879fd57d7237f1050507bc3dae8aeaed8debd3bda5"}, -{ "20000", "000000000000003adb97f0d6976b906982f3272ae0d656e1c593406b05bae17c", "fdf85ac01a396b796ee5dfdf3c7869dd3f7eac36a61bc7a30a5c7e8a9c5dea1e", "11afb3010b72d18ea6b84d2a33ef5801110ca44a0f504ce7aedd5f67443b261d"}, -{ "20500", "dabee81d7aeb87b59d94c497ebe1552b3f5a5ee1e366ce64143e9fa426a6462b", "017e99080b6064d5f8852f6cda7563f8bf299dd15370a64ac74f89f22bb42220", "78c46faa3aae5ce7ca25ef0ca634750514f4a06d6c956d39b8cd3be8e68a8ac0"}, -{ "21000", "7b549feae0c08f58c44ece421b89b0626d15547fd1199ff172704a51476e17a3", "50e176972bbd1528d333c01501e05baf97876b8a51030cc3dced40c1bfd852fe", "1892435e8046922f475512ec827d870ee9f4429a0ba4a10a920e44eb7a960443"}, -{ "21500", "4d7df2acdfee2592ee66f6498c2b0de972ca6e0c8e2ab38eb641dfbbce8aca04", "e10aafa5c02a56181cc6ed4b48ddf1a52370d95c99678bcf5fc6a106df343bd2", "3a708e4a34101e701039b240614fcbea2f334a54e0bd1921257ce7a202635349"}, -{ "22000", "1f2cd2094e85ba89286a183da2b9135d94b2be2c5b3f31bafe89ab3f631c5791", "b97f1ff53a6a11d6ad3b0ff270ed2bcf70500069ab5651b8466110d472a1651b", "e29e5a1ddf2f66ddcb413df0582977b27d7f4bb4e66b3a2b0ecb1348c0f54bc3"}, -{ "22500", "e797c4b4ed2720b494a3501a32a247f7acc38f526245ff89c8f148babbbf0cdf", "a5b1353f344534e8a9ef6365be58040355391297cde74c723c6a5465e39f727d", "2602265eb704fb881dc85d8ce28752b8c46e2ce6ddfe6fa9c6303189ee6be09f"}, -{ "23000", "50b9f76effc822c9f1051b1c0ce25bba6112a31d32a055520d84ca0f1fc39b8c", "e12e33c6b273416adbf598ccec93ce0dd6a3fc817c6f8e4753064e9ef78e89a2", "b1790f4379c3fc9ed1b2a9429ee58a7f186ea7fd2b0fad8a784f4f7d2f771e38"}, -{ "23500", "fcf644a9930ec30bb933cc37061a17d0edc29bb16a04ea4bbf8b27444d442415", "d5a23580de1505a7df77130fda147aa774abfa1f16468a55b542f69bb6199019", "f670d4586d3b84f836bb9d6a81dfcae930072b3b4f665a2ce6ec769b2ab4b8a6"}, -{ "24000", "144f4d11b3a867d17560ef3ef04362efc715c89c30082882df0692a214cdbd75", "add23a1feaf6ae651d6d322142bed5998f2d3345fc767082817ca86139d2de71", "231d9a803ad8076ff5c2039720e154723bf6673a00fc6a44841b8ef89e3d4afb"}, -{ "24500", "8d8fa5a290cae00be37053ee99cf2ae70b37b4806b41575a09b7a948545215eb", "ce758bf937c83d93671078985a70493b6bc1ab33e680143c6e93c2c5aa3674b6", "3257b67e00dff0255bd4a03e9d09ea6400096e44320ce0a7f28a4cbfedf47d0f"}, -{ "25000", "b5c67f326ffd5481bdd18f140c03ac34a9d467bee8116c7a559a8777c688ee18", "2e618ba056f201573ae6222928d56fc3321a3b16c32681dcba8c07587ce581b5", "c7cfa101584cfd837d9c3d6d0067f9ebf9ce8857abd0c508e3f1cf7a25c1970e"}, -{ "25500", "80d41cb90ce050cb9db84205aad00db5761a465b000b8b3a74bdf57e7bc272c4", "fa5e727492c4a83fe816724e80c54ef2add090d60c3fdd788c44721b67331726", "5e151a04afa93b9e1c38040bbcde89080e66dbe99409eee73ed21ededd300d54"}, -{ "26000", "de58126ac82bebb58f841f75602b4307ceafa0d9aad7271567ec69d734b3422e", "3931c58b417157cbfa4e990ceb75e8f2aaef945922962b671c17fc9076be9c7c", "31e3b4e3c88d910ea31f6ee7c23d5fa185b43aea4ec9e18fb210882a3804df6f"}, -{ "26500", "857f050c1a4a323b2f9d808bf2da8e11a9d691517cb0189ed2f7f103794bcad1", "a7ea3d0c368fe526c8a1a79c9ce3b5cba52634c324271b3982c70e2ec1698800", "540c63627ad9dc26a6cf2b26a739404e4d07e76fe8e9a2cbcdc8bc18a60f3d23"}, -{ "27000", "43b14fcd1424ed78b3cf03615ba16c8fdb53c414e894a6fe555b5a0221053ca9", "6719c5530a1c6579dc00a6d6bc26c59900d5437d4bef8d03fc47cc018937a52e", "ec17180090117c4560874b64677be3f2dbdaf6840d050887f719a16338d1f755"}, -{ "27500", "503b22cd2997d3ff79a7857530f975798fe48a3b46bad0a38a3f83653beb8d1a", "e013d7f398f337d83d758e6af4eec6ecce14d080ab95f037e8c4354b1e4265b3", "e2bf10a3bf1aa3cd6ab411d8eb2af0d50bbf21c7ca24a4e6c873f4d14ebba287"}, -{ "28000", "85e03383bd64b7cde88467bfd7973ad219d635708a69f925316e958d524c1b2a", "112902560ea7fe15351297834affe49c0a8e768b587d1a8e6574ae89903d8143", "e04c436fc9403ffb3716e49fbfd18cac060350742ad2031e07af778b5dd9f847"}, -{ "28500", "57c1ce655a20e5d4639e934776edbbc5ad099c383b62c7bfc623368a2c3368a0", "c3e03e5754ed76153656787b565a0143d538298277c55ac0ca79e99b0ea134ff", "1742f2919898d186151f39cbe3adc53c7d3bf3377674af4bb27eb3aad00c54f5"}, -{ "29000", "d9963c1d22e68c2492bef7a33f34bb7bda7b326b4256104ac1ef7d6421862c5b", "91dce271c5fcec2b60e9e9a7d1670f191be7f8e76d3d13e75eecbad77dce8173", "ba82a0879da29a77ac7e402693bc183897acde32a327066933e15b108ad28ac9"}, -{ "29500", "43f543efd477664f84ee78bac095d5413449e552ef90204f79bb8463ecbd5e89", "4e93e04161f98d745707c6c7a85bd4b223f124c6dad64aa7080dc612526329f3", "2ff134e1f184f488057bd12cc4482364d1e15da2caf46c65bb924a05b18f1fff"}, -{ "30000", "23da6267be7a1511a4f9892875bd61bc1ae5d1b35063d78a7a448379db07c40d", "760c525285ec0731ff71deed949476248fde392c8bb15f100af786b7d7e60642", "949a3e5c3fa9e4347e193891a994db3d631577fa519243b5c6085ce21a246795"}, -{ "30500", "199d170a784a96d70fd6421057653141b423cb730e577bbe490c4d9d5b31621c", "f836756815de2b187d68e2729bc667522ac6f00379759c5a7815c728d52fdd6b", "ea22c401b1a3717ccf1ccdacf25b41b305d19e1d109a9dcc0e459f7472268464"}, -{ "31000", "a2f6774be3decd68c4fc0d55249a61d73333358b03a5d7f48f19ff53c6eca193", "a72c7c5328570231dfa7e3b7fb68ed42e4b4f9f4e05505ea4526779d279b6045", "a51ea6dddb667211fbf69dc697d9061d05448d3c9be461d18362ae977c8db721"}, -{ "31500", "ead2b784815b474f24a12e57068086c7cd2b59051e4570eb4eff43c00079120a", "cdfb920e73fa2ab6278a84292a23123bc921782c7b9648c137ea3b5d936838a8", "e8b8f3d2f6c037a46a617533bdca57edb609ac7526b7f025caa96b180025f4f7"}, -{ "32000", "51690f90531b33b61489e34c805c7d1235708691163d0b25a9afe161b5bde918", "44ba77a723c883778528e872d4cc6779c6485e4274ceb2ee7c1f219274c74297", "9a85fd835a31d057ade3ba18680d0e79a328b3632fc16a302cd782889f52d193"}, -{ "32500", "b8f881e8f20864ef1db26eccd81bc46ce2b5dff8359ab86cc0b915bd6d1437e9", "f390ac467135ddb1d88617c29db574c34ee51a4a79cf041bf7444c522229f8f5", "c4c06a639a920b8f6b788d9481f45d8dcb2e5284127837cf52edbc5447a22903"}, -{ "33000", "8c8c61289e79ec3e22d294ab824743c29194740fca09ab44d460291599a33186", "24bf35eb0ef662470b75fe38c332729ec8cdfa122a52be3d81a97bb9cad009d5", "01cfa5ba001b9497b25ba9226f0ccb17f24d7e948d384ba9bc993c4362827dc8"}, -{ "33500", "958755e9cf4e957d0471cfbeec0913140759fb3219aa74096c26cba2536579ae", "e88ae01956031b06310eb260b95a76e2e4e9b66d40df56300ecf108cb4579c4f", "095cd89a4e4c95283fa2438c6d031ca1b0422816f67168a499f5bb3320c65ede"}, -{ "34000", "d4effcfa7746bab24f9c3d12bf94680770ecc8405b5b0a17bfd0b33c2f4f475c", "9e5f3f87097c229ec5011c8ce05cc12a81dfd166741ad2762a0f156a8d3b3928", "9398fcc470c7c81ac2160660b5dbbc134e4ac35b60255bfae5e07a4635224000"}, -{ "34500", "7f971e1a0d2e94dd8cd0ccabc451fef38429ddbf2400bd45278fe000210d5f87", "8b08d83e6bebcb12ae7b2b9fc1de91a0566ed33f2c40125d7810e2a97566a28a", "70b251ad75de6ab61987951c3d5cad249ea12e6e820f8d935793739cad30d4bf"}, -{ "35000", "90e4d16dd67369b4b5795571fe0cfe63be8c1796ecf5870cad20798a752d92f2", "619428a018aadf7a144b3981ecf018bfffa7975819a58cfc0e16f9ef0ba274e9", "724316079c231a8a8ac11edaa2652aa127160a355df35b6e8ca40054b29ffc75"}, -{ "35500", "03aad5e354d5019e2cecb5a44c4ab79c7120543370cce9830b1d41590a59706b", "d94a9fa2f0ef62b409348c56bc376733e50fcab89ecd7fe711845f66c03a8409", "a153f111a3d9d4d98d06f1eaa3660efc2ab84bf4d8525e7c41cfd1f1cabbfa22"}, -{ "36000", "5659c47e9c1b006ddb991b7b0163777977d04d70b4b52f4e3b87bc3aae6fba2c", "b1cb79822ef346bdfbcaacb59b7a289bd07b5cc02c8c6f9c9b1c5d27111c892b", "7daa94c5b2e044db9e991868d953c7df2cf48fbe15bb04af59916a6f4a444733"}, -{ "36500", "166c22d2278b5d4960af665a6dcb8c4718ca3c489fb12f6744a60337a6ea4a97", "b55d2820c96584bb049d4f57766a2fb7b21ac2998038d1dad3c39dd553309a5d", "cce95178fe08033f16dd7e6bb1f1a57ff8aaca69441747ac339cbf5c6ada01f4"}, -{ "37000", "0c73b35172fd5a08dad4570ade1ae552008a801be8f2df85e52ae71957cc8bf1", "66fceda7365584ca4e28a192d4716cd0bc61da166e5c6036bd2dad1ba0f034f2", "75bf71b04fee9102f680ac069773adca193420ddf477af36e71dcafd129c46be"}, -{ "37500", "e25729880903dd4f6562deb2c3e076c00d29e08e9c531518b2920b3e747ba6ce", "886750b60b53c72b8d9bd1cf744d74fd3947ea62b878fd186618a46f1ae114af", "21c5623b70151d13d93303599698d825c9fb8080af8c74bb812b086074287297"}, -{ "38000", "fd1aa8f0791fca7ab540a37b8fe5a6a23a84d0bf372ee35d6b12fe540b53f746", "3bb81e40ce808ad93fd0057fe4c8c111478857f8ee143a27383a4d64f7c9cce7", "37daa6c75e80010969a1c65d80c8eced5080cfc70b3bc023e90ae0789f458cad"}, -{ "38500", "73dc7035d76f11e288a04b87036996efbce8dc6233d00a1238f40ccd95a4ddc2", "b8f0d99842fa481e5b0e6011ddd8abed25c9073b259e37ee7bf2f451d4ad2c92", "34ccab36126ddd68197efc40b27eef83462084a914f61953f297b14db3460f8d"}, -{ "39000", "f0e3715e1a7b82521f8d39fb490f261c5b8684008f5b52fbca7e5f7b204ddecb", "2851428725cdcc924d42f907200a50ec708342cc1025ad035dbd7f84c0818340", "290a3f59a71d2af6b93a0c00d93fb1852b1d564d59a4766be690c0c85769ebfd"}, -{ "39500", "16693e3a20a6c2d2d823b7c3020af1a20d555401ab098f94ea8a83b7a2a9af4c", "400ac0ebe9428f526123f90c8bccf69a6835ad322affdfcfda314ea795e1a1b1", "24ceaf357c22d83a9a66ce1da14ae06e18bd1271b5478f3402b64d60d848a613"}, -{ "40000", "fbe5242823fe378d36335366cf45b3309e8fad0df3f9dd542e10eab3b7a296fb", "f73a533f1c917595a88ca8058bcf54b2d8e3c8cf8c46a165c84ef124fb07d15f", "2c4922f36ba63458af37d6ad62138ef67479aec2036f7224b131899b72536045"}, -{ "40500", "448e82eebd5d00a7ed11123f43f8ee955790cab17cfad0fb4f1ba154b20cd1d4", "f6c092a7945bdf4ce8bbb08645a349b208b054925376821f469309fcf46cb4de", "9b365c24bf635d86b8e0506e21683ebb1c6f588c6f3dcbd22b4358dfd2bb9581"}, -{ "41000", "42e29e0fc3e8fb2c517bf4b7d24175f7467980d793bb18d4b1903fec0292d0a0", "b8d88a3f3968b88b98e51232a0304506821c7c83f405515d2acf89a6a39a7048", "1d10fd930aacab4a063e39d302c2f8cc041cc1bd1591dcee998181970c05bf5e"}, -{ "41500", "fce90b09826a8120907462a95aef4b8dd9487efa4b0b2cb7e90a4d6d3d40e4a8", "2a4319200375bf38a272bba432cb62054c4863db024e4a30c5bd20bdd569b939", "fd08240c46d9c5424c44850720b857ac2f3ce88e509476d40eab2291f72cb232"}, -{ "42000", "f0815d389fe88bfbf5c361762efc5bd1264dd9256bf895b8dc6f39128e130154", "b26d951f8be8ab9091f1e6c56a539d1d7a01b50c265ae1c025b698f3edde5b6c", "fc414c310ea4cbcdbe701ee801c384dbf953c002341efb9295760899ec66ef24"}, -{ "42500", "97171a32bd838c19f12586fb03992387b4b4c8d1342a0ddf3397e44b7c9b432a", "04737e3fefb938c73100a32ccea93455aa0a564e41e608a1772ffdd2e0d10033", "514d6f0e769246a01deb8043720d9ebc343a30061dff74b8c2931309ea70a177"}, -{ "43000", "a1ae4df09a7e3f060a6693d9bd75af599a658f501b0a5583442aed2bd0393dff", "b6290ff23b70623802b15c12dfe3e19111ce081bedd2f24a0c6b4ead9d8989ba", "49730c987540a895c5cbdc00a5964f893213269f8086e01764bf83d73674a4d2"}, -{ "43500", "85e2d7b7fda1433ec964d4ea6cb4fa7af661d38f761877bb9b0aa0acead5e437", "8dcd8aa4dd692a271a4e6efe7b8314f2fc5adc4b96bdd932e2ffe76b496f1347", "7bde02816df1ae3710696092c464b82d2d6948ce7268f85b500f2fad7b59bf49"}, -{ "44000", "7526450969b0254a66686dd28d61c10d0bffafd0bbb623d0ac71f6c45048b195", "7c626106e228c853ba6d6c9d63f934e51661ebd7ecaa02d66608bc2f1da0877e", "6ece98559c2f3e6e595e5650230092cf482f3362ce00a0b5a8a598a3df11bb2f"}, -{ "44500", "313c4a7250c92bf888dbbbe977f119854876d877cd7ebad97da3e793e4167084", "e1da8d161f08c6e7cbff74ccfcb80644b571747988ada991c4982625e59d1a0b", "c6511fbcd73f38d607677d10f5ebb270b78bd392b83907c58b4a44e84477b859"}, -{ "45000", "9fde3334234a707dee9c6a2e3ef6069a30c0bb4293555f59ac70ec398c818e94", "987db78e383fd57efd0a1b0b0b8fe38c50dbcd648da9a1eaf5d5f59d0c15235d", "5664ee540251229a71cd2ad5913a8a4e8165fee2ba960a4bf092fb3dd6623856"}, -{ "45500", "30f5524584e0e3016ea738b1984cc7fdbac63956d6a154ac474ff28c873eaf02", "2a6909db1ed2d684bae8cacedac0453a13e37ef1485760b0ef6329228a71bccd", "dfdc3b0ccadc42a812d9777a6023ef1dc9143c81a2b1ffa11e57743b96597da4"}, -{ "46000", "b79943e9ccbd2513710f58b3a5ac822bdcd6f390afc8258ce7fa1ea6822daf2c", "1db10c590ef1fb219c3b98c707fa294e263bf95a4ad26c2c214ebb19d4236297", "7a680be9d04c8bbba564af82f08007abb0e3528c35e5fc3cfab68a69ec47df76"}, -{ "46500", "9680afcbae2cdf4712605c9d592ddaeb87f9e8c522c6b5f0beb219e71de389b8", "75ab5e40232ac575b25c0b892af025d5405aafe1f808551e7bd33abdca9a86cc", "a625bfad95b8b109ac2717201cb5e5988418cd26471771706a797b59fd0be320"}, -{ "47000", "1deba95895fa7fa09760b2b6f12395e6a40dc7ed3b14e629b7d85875e6913eda", "e735fd2aefe57540d02327e774c7069d08a3ec5b35e6ba939b1609d98a29a245", "e955c958f1444bd9c6f6ec1f3c081bc37e2e4f8bc554ae806df4570adddd04b8"}, -{ "47500", "400b71a80cf5c7a408363c4a88a6f17b9fee56830f9639bf682cca7f6a1b9ef4", "179f44d13af45605ea60c9fa6e0030b5de6c274104649283e5929abda3cabd0b", "7e15cf3d27b7fb311eaa8e5be6a16f66df730fcd917206b04944bb7efbc0662b"}, -{ "48000", "b62fdb21ede8c1760346b4325be6d08852ea3944fb0adea0b408742977fe122a", "8ff82f9540381a20ba68681f6e5442df8852cf38b2476d0a6bc61162d6eeabf3", "f9590291e90b1145409aafc4b35b003c3226a54b865299168fdc55ad056e6cae"}, -{ "48500", "baf6f61655d7a53726d313806841300c1d729f7206f62a267c1b4c351b365763", "fde6fd7055e1f6e03b9d327b3c502fc02bac00738ae0fb079f128e2774d0078a", "7bf98929914e719c43f044b8bf5bd0cb23c1dc197682fd0e62e517d426cdc1ac"}, -{ "49000", "854ab5b99aa89fc7d03f0b2d7f8a54aa7c98b23957520ebc8f4e6305902cf2cd", "f39213ce4a4fb7c2de3088ffcef3712113958562638395dcfda8ff6da621a09d", "82dae721c7e522a846a3964961366f428d60788ebe25f8f649ecd605fefcf2c1"}, -{ "49500", "c964b7057db84d6b9282baff7f2f09dd72fff06dec110201904bfc3846923bdc", "51261dc44b1299e50eb364ca4d236b9b5074606928ecc6acae0eec2b6352376d", "39f54442526f11b0c232276a00372762bd2481def4502b9db2413e0ecbe42ed6"}, -{ "50000", "fab7500f5f0b1694a9c65a4b02e84dff228af92fa447d810200a3b14c35242cb", "194fd02a69a66e9293a06d354206757e2bc23484e3e8cd80522ff71feffbdff2", "4da797c00b7fff361aeda31e847b2e8675c4061d1cc87e02a040c7ac34bd198d"}, -{ "50500", "ed4e556f251680672e442c00cf6a48f3a787acc589ef3e83019851808ffd05a5", "b51a4252fdbf12378dae10ac1c94690365e096f786feadb8e75cbad87c8f8a99", "5a366c4316e15730fdc118fa8c910850d3f43ab2534023892dee2c1834c4595c"}, -{ "51000", "2410005ccfce88835da97372f39ba6708e7eb10f97a4428ba2cd51e8ee87f7dc", "64e4a8d5a545ffb1af7a5dc66be6ff2aa517a99c7bc5d7b2d1d1afafc1b93a84", "574faa5def6045f6a923539b36bd27d5f92fc7043c3d6fd783cd3721ac604c4b"}, -{ "51500", "ae13af1cc26f53deaa57482111239bd24f99814dae1e01580a1957f11aa49a63", "4a0c54d391ad8bdc303e226fa1aca24cce0ba24370424396bec9917804f0bce7", "0849cb255103b5a13e30455f5666a79873a4ea09dd8dc06d628f2812d8460133"}, -{ "52000", "163e369cecd2362ecebef4717e206124e3bd47dd40104efcbbc8610fb48dbe46", "3b68edeaf66e8bf1e1b187fc0a5e0424b6cc896661e2a4f44882cb060f9815f9", "8ef8dcd02588600e7235ec512d10ac2753b1d0d9bca850de6479f20f678757a3"}, -{ "52500", "c3e5334bfa7c8d5d577b1a74df2deb553a006f68b384ebd44eb7bdd7aca3a297", "fa5cd9249e7b39e2aef8bb19e83e214d77a45b4c67c4504522f94baeec2241f1", "c3208eed6877bb901a5c104dc7f6829e8f21d26381f04dc9913cae3354b52cca"}, -{ "53000", "3a790689d0f51fe7dd6115b7f0e5f5265a3aeb912692596d2611050a17795705", "23b602a52f2e393f2cedd9c8ea0597931f6abd7b4f4f1d85f1de8d6382c03ec4", "22e3b57a04499e2821002a0e4bc9e81bd4f49b0455ff1a369a84317b53de5e8e"}, -{ "53500", "70a1da282b26b9dffe0b36a6dcdfc0c4bf218a86164adfbe7df4cc9c0b978969", "f6ffbf0fc14817b41ce42831d14add2f8ec22307e5b6baaa9f07dad06c387e8c", "61244a97e0cea7e9f539d0b93a6f2b17be206a6191da6b96c6c8bab82bfc48f7"}, -{ "54000", "630d02d2f2a8889fe47a4c2235a60b2dfd31ca78e487860f59d24637a2032af3", "901287c9cb47c082b5329f422d94e71def436bd0979e939e7def8c60f99272bd", "c17de5403465843f5fc7e06ea68b3d45632391503ba6c3e08fef7e307efee627"}, -{ "54500", "4943f865d3e75ddd060f8145558ec7f57c10d186b3bbd3d90377be4713e1fd22", "26a8c618d328579faee0816d1d723736a249dda1e95647ce7775b0aae5b72854", "c55e2330f03cc18e461c27c80393abb8cb22e02809d2381e58ad9f72e44a576c"}, -{ "55000", "6e96c77b0964fc2077455aaa2067110351212e2ca707fda778c963fbbddc844c", "350612a0426a630a0b001ec51d875e2d1c87d20353a480539e5fddf91cb3097c", "818a9301476f02887da2af0daf9e7d06ad8b2129957706547ec766937cfa844e"}, -{ "55500", "cd718716c94cebd61eafac70f8562db8b48735765a8613aec79d901e0c5a05e6", "234209073d425564622dfa5268e7f2af5aac71a18e2b15d23ceff1da4d876563", "aba44d2b14d211b90829dffcdcbcbbd7705056e49f671290cd160a0b778787b3"}, -{ "56000", "04002106ca4da32c5c7889c8f17369d23a35bce62a8196477c8f8e0e0dbe4efc", "ac25f2042536f1a588ac6747b2ff3b45de9aed063b096ea59632b3aa45441ddd", "5ff02cd837efbf14a19c5a187db83c5406947178bbcaedcc4d1ca99aaf9e3796"}, -{ "56500", "6460fc580380db980f3b76e9480b2dd98f4fec5c9642b211f7258f50575522c3", "12c289cc82037f732305d895742cb703eaa35a4656faf84c6f7dd9a2783cd2a9", "ddfb3a3ff60a67bc60f19d00f0c63f1e97ef355c74ed1d85fbe4d5b1b214ed1f"}, -{ "57000", "7f1a59ac62a06df2d3d82226e03a1081fa9a8c72c5333ba485565f9215423362", "5363e6896a5eac3c62543b82b6260a18b07597b5963d038e728a9508ab55b181", "f0e932ed8ab5fc1e33872aba4976166e13b6d879d15dc3c87be2080ac8914b32"}, -{ "57500", "88bf14d568f5b9d8e88d27a92f2aa97a569f371850be3d6d1ec175fd9e1dee54", "56aa31dfeccbed31839cc2399397a826f2e64a16c4fd309ba87ebb2ae7e7f695", "015c08dd60a5eabf977e86e7e037c946299fb6cfea812374dad62fc8f8dc198a"}, -{ "58000", "0ab0e582e675d0ead1173cd65e71157f13841b22560251a2aace14ca86fd66f2", "bb20d53b616962e78610b02a60785252e90c54d78f33a3578172cde77075a776", "9baf4ea45dbf06d4508012d7b02fbfc4b56beadac64d579d65e86b2fdbfd9093"}, -{ "58500", "637d24d3f5e56f5481735d0853d74cc85c170dc95dba4eb733af11ec3ff048d4", "aa8d5505be6a30af2a0292fcd19800b0744acd87634bc49ce43b0d767117a5cb", "1f591f7deba103f980059330ab5579257932772930da3bd5cb92c4ed3a2e3d32"}, -{ "59000", "2d88b4676741afa7b183502fffd15bb1580f81b4b8631844be86bacaeec0524b", "fe841a70acbed4f52a83b35cf30c0cd5ad38b36b21b24da1a0ead110f5e7b2fa", "40171cabf3a46be3a3987f71fa7a969987191d9f53316919c098a4718923c4e6"}, -{ "59500", "e5b98e82ea2968293969b1da31bbb8e30dec3ab5cf10308d4a979e3264513bff", "17429be3ddc868c9e3662b5aa6223340d57b7284138db428c725c8fe69e1f89d", "4a351a969f3b5658c5ed9d91bd474827765b53b8346b4832d1dcbfb2f5a1be4c"}, -{ "60000", "98764fcdc2a2f8a740a4a1c891ad966b44062f64195effad2ba0aa4bb9c4370b", "55053a4d083f019f602ca159faef86ddf421c4c4c3bcef9f0849f45e1f8c1c44", "cbe42ad4b0adeab094db6fd8374b6e3d6696664f583a8720ce1bb15650cb9647"}, -{ "60500", "24bdb847b0ae121363eb0d2a7ab69d672627b4d68195fee18df5ab5c076ba3ed", "be197241a0c377fa6982b5c24af043034024f889cd3ebe42d4a9b3fa5dd18953", "a2955e0abc57b88a148cb41f22fded072fd04da5197fd62677951cf86b73d9cd"}, -{ "61000", "54222686316d912f144e6d0bbaee1b3fa50549e9da65ffc21b04c5beb3ec6daf", "6c5a388a8dd7f9d104377e1f5b2817b50f9269145da48dd0d71f48e2af8b8731", "b8a43a400ee3bab44c6d5340395f0e1f92d394d577fbfb58ed7bbccd2cffc10f"}, -{ "61500", "f14bee1d7d3830f8c316f448ca36fd0591371a63fb9d04596c657051ab4c2ff8", "86c9232b738073c671adec011771072c92ed0616c361bcb6e9af6074d09bd6ff", "54fe8b0e5998f386356388ef8bb5454e1c2526ebcfae9b677e08f208f678be56"}, -{ "62000", "5903eccbe3d0442fabf30748705e88e9cd83128a0bbfbef66841f590b5011bdc", "4de78ca5e16fc438337a8d5f7aefd2cbbc66790d019a1bbc5de082a79e39c303", "8a85e0a258f4cb99dc4f83cc28a30721618cd33fab70ebae4695c5c097debcfd"}, -{ "62500", "35db59c0b059705518e07b3beab25716c9fa347a1fdf7bfa0089d011e2586419", "961e208bd356ecb07f838ec1d1cba0eddd79d5e026ae350f0945cc321dec970c", "4a38f7b73e53602754a6dfa97d9ae5d289f190c3cad7748f7879821d204177e3"}, -{ "63000", "5fb6db58962ea9eabcc50dde4f473a0adf58eb9a409665d57cea3b2d3d2f44ea", "b673d848fb79ad142be92514c27dad64fbf98d26e1e4f5957376bcb2f8542288", "9056ec83e8dcee1f4fba1482124215868e1fe542699560acb750083a63f77259"}, -{ "63500", "92e31a33e15bb677aed01f2ed669a2700223a34fa7342270275561ed5b88eac7", "7932d5bdbb9c2fd7f172a79a9e93f73aa3703c284afa98e7530ea4ebbb4ce7fa", "471d2a03dbf58e74f50681d6dfcaa42b2fe579c9669b40fc7f0c608d99744e5f"}, -{ "64000", "065c7297e545fd1739d04c6ed41da4a82a24404c7b3573bbacca0c266c4cb716", "912632c93e91f5f539b2f9d6ff8b16a1817c8eca88b6d579dab56bf4d48eb31f", "45cf6e550b32597e97193b7904c3c8c4fd709fb9fbbf00bcb178393d4b0071bc"}, -{ "64500", "a011434ee029b50acdd49262a91b0767a897a5dfa7f5c22dda0a32aca9ff334a", "37993dc2223b292109f02e9eda7db4178f6602aae957b80eee7cf94dfdcbf020", "30367b1daa375bc234f8ac0495facba100246d643e308ce11351a9d090e23791"}, -{ "65000", "5144e900145e481fb1e569b1b522143348a38052d35452dc7d97e2140b812e26", "217530b550c589b0de7d145fc8b1059215bf5c124be7e79b5854acc200b511a0", "26ba9b125f161c2d53ab6665f343e060134303e77dba1cbf22a9822a59cc4b87"}, -{ "65500", "6db49e04b2c1ed108caba28d4de98628fc786f5224b098de1636a697ddbd6e6c", "5cc92190d39119982836cd5b0759902c4c61517aebaba16e6515cfca53bbcba2", "0278b2431cb9eb97bc1b003994e371f9bde5a602452443a91791f1ebca9406b4"}, -{ "66000", "559d2603be7835ec386467221e23836803606f7fcd7068f6a42ac5054e48fe88", "68c9698e2684c3375d6b4d83b33155e15ff1d50aaa0fe61276a854f7c022e3c5", "13bb29b335c2c7d96c2c1ed7a7c797065c1d9ddbbddf5ca63836c903b799f23b"}, -{ "66500", "d724f78b706b6a58400a729586b050fcbe843a3e632376f24db6fd4cb9a44177", "968a75dc8e7e9128b5e7e00b22a78fb53553102b54247bf644247546a9db85e3", "10ccec92a6edea5d410279734abd7910dc5ac0c1e15ddf157d814cfc6d6777bc"}, -{ "67000", "8ddfa37cf395f7b4b8d6d09e29cb7f11e7d06f929d7ce7a77ced27c79011235b", "9cba1d323704f1b566fe4b639737ca2f6f96ab6f9f1373d95e1d8cfef0a0a1fd", "58670ec690d41bc890ae2b8238cd529068dd4a26d72cd3c953fe6c503b7b601a"}, -{ "67500", "2c5e2421936073eb47199fb03dc0023bf42572f507f484fd9181eb1a862e8972", "4928ddef10d983dccfdbcce08743afe2a0d1238fd84bb4b6e1781ca7847d6ff7", "80c4fa7ce15230b8e68ba5d72eaa7960d34f8045407ece0d3b1c4b31eed2c00d"}, -{ "68000", "cf49fb97e127593bcf3591390401803095f71ea86922369e573b1c6bf59ca692", "accdaba238ebdebdf85fcb74a46d17e5c29a996e3f1be6147a3f6027a13c8412", "0e50686f415f26137166d657c217b547dd943539dad26b19bbf746af7df6d8c3"}, -{ "68500", "eb68bd36c8212efaa20bcc2d1c17f17af6ce65b060ca7ef80dec2f44052defcf", "e04d8a45c474fb6ab8071cadd8fb14f5d208472089f6a22ff5c04904f7a01d55", "14da49cacd179812640740b70aabbf5b3518447f669024e44e0d3c49fff50e1a"}, -{ "69000", "03609399659eacd9b55c608e6f35195530a35358812bed13782f9d5df5da1ebe", "cf4d7449a4a7aebba820fc84f3dca2a48ada14feda094a425833d4a5aec834aa", "41ec9e81ab7bc3532110cdbdc77b8b8e7827f0302b2e53439d1e079fb6a6e63d"}, -{ "69500", "1d23b15a2484a71d270170f32918f36fb87e80cf4020f6a3e6d61907276fb3a5", "2a218f285edae9995b3334352864684c66f4a919c92031ee3b24510b568f6246", "16ebeab13ce1ce77819913c4c6866628c4541e3548f242a90f2d034fa0cba0b6"}, -{ "70000", "5667dd2604c90cb15f49a75456b0bcc2a0098bc025592d48379f4360844b79c5", "1b6966e82886048d64879d2b76663fd70689c7dee808cb42352f57af598f9bca", "40226bcffdf6f4ca816a09f4f8b19ab1fb245b506648ef481dbaa9f0f3c78a92"}, -{ "70500", "745715d010b5ab51456342b8772a53b95ef0cd409980df39c443531f2f6c2346", "a1ca05cd11e6f3d9eb2f0498b8a4743defe546c7602c3fe06642f0226cd22719", "2d34067c353b61a32c8c6231f77f6d50c4d95598cd3101532a3a02e80cda7113"}, -{ "71000", "c622f3d2de9a6aa2d649f10532164082ff6ac21da796b037f2b2a210fd2910ad", "3c24535ccd8328940b86980f1797d0c4e0dd0fed2ada72a0d9ce7927f4e3b040", "0fcc88b5927ded864afc1ce561cb814d9e26a21b053ff81e7201cb06432b6472"}, -{ "71500", "c4350561b063c19326afb0b38b7aa70a65a928ecbe3a545f26f1dfba40d16599", "7167266f09bc1b259fc6dc6ddd1c4e03514e4b4e5a985ce79cc320d80f376e9b", "f6e1408b9924b633079efcbf87a6d58ada9b92de902e1cf06dfde2aedebcdf8d"}, -{ "72000", "df857691f4e2d2ad6a7de6a3fd77cd3e1ee19be220f7f92006e30c4cab62eb8a", "1e962f15a4472d511bc049be123041f357376d95df56677c32ebf69640fa5459", "6238d0f58374c120051c6df5ad197884fe673daa41fb9744ad261e3b102be59c"}, -{ "72500", "affa0299a9d64d61176179cb14978c6dfd116b0350638b5e2633c5a73bb9e5ba", "b04e559b1ff6d04f2fdd2693c384bc89f05ee28f5ba8cee49cd057c575b0acf4", "a19593b0eb1c2af96cc2b8d2a51d1dfc01e8f3199fd034a3166d5f2b3744b06e"}, -{ "73000", "a50964b3523aaffcbcfd0be0a6fda32ceb87018450ad2ff81f1ba61de5fa20b7", "e3301d1249deb8b1065c59ddf02c4480af9208ca0fe70f0b94f7135e3baed857", "925258df26bd35c53566a703ddcebcd0736a83c02febadce41775c6a749e1ccc"}, -{ "73500", "629acc1dd038725bbad7598fc49a7178771332ca4f12372248da579ee5dbbe54", "8d2425646be01e20cf3554feec43cb91bdd92f0a6e8791c7f8fac4d21767b45e", "0cdd774880e4510e46ac772c74a1d7e9489ec661e385ab2a30c54d302073b69d"}, -{ "74000", "068954a253aa54239a0a4169f50ee7d37b0b5bdfcdfe9719ce9921a5917715eb", "722bb617216427a0cbbaa037d1234bb7d6765707108aaf171cbe14e24392a8d0", "a1d78d4187cf5554867bbcc68949c2998037c4be0a7cb3f3b0e3c4115089cf51"}, -{ "74500", "e688640c22b3c55fdd29e86a159e1cb665cb0937cd6a5591730a1b5de7c04b76", "4ed22bf35c9c19ccb01db47714af7f2ed0a7d2506f40a5e43b92b971edf62250", "9cf4fe5d63466b2a310c28107621a4e2ab34eddbd8593bb426f334b2bf9942be"}, -{ "75000", "31c015b503c6830b93948a51598beefedc78d8957af82aca6ccedb2aa592de8c", "b75f99a073680d704089e1a77cca65d027722aee3a4fd7c1f9578b535150d5e6", "b3081220431a4246895b22aad5fb257d09fd2ae1cdbd57aff483adf909a5495b"}, -{ "75500", "3eb906d2939c3f6ad815a51421f488025326b8cbdbe28c15ef32ba410b7b8ab4", "39ed4ea10fdb97d192dc03a86a397b24f6883439e7ff6e82d9e6738cb90ed5d0", "112ca7210993aa0fc5581f7819420bfd74dfa5b7b9e2a1bf3e0d2fb5708e28c7"}, -{ "76000", "d21f08b186c4d763e03ff71b1ae4e7c07a9dbd30c518242740c2c93119d8d96d", "3898b748f911a413cf66daf2e319b3e72ad25ceddb77f56a7de9165484405cd1", "c3a319de284ca1cf8fe3b8ef075d1ec77f9305f52c9651610d383993213a5dc2"}, -{ "76500", "5c8f54cbdc2f5f83621da3e57c28d8e19faca81a438cb5f4aa144a4c037a0055", "979a3726654c4e3bc195da85f13e24639650c2d65c460c91ff1b377e27a3b73e", "520b9b2d18e11c3aae19fdedfd75036c9035e115b287396dcd53f45fe063f812"}, -{ "77000", "e5e2e50e27fe46845384682b593999c03b4848a5912bb45d22974cccb551d125", "75be98b3706894389661b6e9c20057b55cdabfa26ffd74bcaac8fc01ba273340", "560695b5286f2a9b5f3a61891adbd806476ba326c9901d89a4144d25730382e3"}, -{ "77500", "be8371eaee6d9fbf2c550f71e9b41d135201b8b4657b94e6660c908f239f986c", "32b8f8fdb525510204119ba84666c0713d8f486328a98a130c166f36a2582523", "20cece5da3a52ed79ca9da8dfc49906e29abb2fd13277d8131ff41ed5116409f"}, -{ "78000", "2eff5feda9ab021f5afc380a7f931e7d52e7fe2ff3e2cf1ee7fdbde0eef82b64", "65fbc737d459fa4f14f34704e11ecd9adfd51078f45626671bc698ae18d849d6", "2864e1e45f74b90f0c7d05c88b86c31c0f6534a8a349f626fec3a58508814b1a"}, -{ "78500", "3018bc8d8b545e9ec88e936af13fee6bdf3ede83f61d2bab5f723803e53e0062", "7b2380f5e4d64db1aefd218b868cc51902a54d0a0db42cefed99c7e8de87a218", "92a0304a2442f4c9695f01d26aa2e8b5d34146c9b8a858c53de43d87e466b863"}, -{ "79000", "b0c165f1302d8f19256dc2e278a7a5ecb99eac7c998306a50c8b4686a077356d", "491242e8fb5fc40eb435f931bd11bc42428634a5b83abd1fb9f19059712b1ec5", "53e79c824e8c366f63f1d49a454053093c4572423c9c81f23b369cc9381feca4"}, -{ "79500", "68a1ec922af3091b3f2d59824979ab0f53a92198465ba557236cd41723deffb8", "fb4a299d949b55ea78834906a69ab9022a49d8de653310369fd8ba9af477b7ce", "b2e281683255d479875753fa7e28a8d4d18ff9e2a88efa3096ab74ef053c0a7f"}, -{ "80000", "3b7489d3c34d0848f031a2325269daeacd8d00cca588b2b0155a81bf5bead1a2", "9ec13567c8ceb32e9315afa4321f0a088d662f7853d492e8fea9aa0825f0c8ba", "2df863950a969a02053217306182378d8cf92e7d0d20261970edf99ef4f81e3e"}, -{ "80500", "a4bdbb1067263df39ae9c3fe98b7e436bfc29fb020ca4e0caedc4b92409cbabf", "5d94d51295cffe3419841c9aa1afe3a281863f571789ded22dbee32e03726946", "b28f04015449472163c3a2de60bc86a748344fc019737e96005a72b9cab30e54"}, -{ "81000", "ff01efad3f1d35001246db4167727135f57b0e2603185bd8f43310d2725b4da5", "41766254f9700bf8590b6bfa6993eb56e866af75377438b7b7ec4aecff1062e0", "4ca72d6d1f8416c9c1d62c0adacc2fa865386e2403c611151aa04a860aaed815"}, -{ "81500", "1e6d76e93daa7db4bef0b866414eb884b80193359343f7984cc4ad813f10a555", "87b53a2233125cc8b28fa7fce0ed9d4030665fe83b9e63a76e545f7eaf332fd9", "7020d3fb137061b452f9946ff2dc143ba7388863becce1b384a50481c63d75e7"}, -{ "82000", "f77522692699eaa7adfa876193ff59d445443d55389e9110c211d4892d0e4501", "a283d883a0705d2dba7c61cb45d6019a7e464aaaf297d8cb28103358c12e33db", "384ed0155684b2265e88923aa42ea92fef934e279d5c620be94078868d6bf789"}, -{ "82500", "ce6f78297eeeaaae876c2528e2620ee91005af068e45c079f16523772b1ad1ab", "f52cb36181b62da6142382debe8325153fa672ea2a82ae0f4f1f05d3945ab944", "57560eca2d832e2ab12c003beeefcc53a73d9af27c28c8af087ccc786ad1bbe3"}, -{ "83000", "fb926dce75fe0237ca38f35e58a77ce4ee8be04da61b16f360b029ccb889ff75", "28adc102bd9b8be9013e2400e65d2d57750e995bce1b03ecdf1cee59712f359a", "65ea426980d984b17394705620f3b309b68fc832a60b8ab81263ac84269fd795"}, -{ "83500", "f41912c2e881115560d9b957f91a8463c082efd4b887d3a9762fa7aa70d7dac0", "aca22527fa30f5d0e0a8f2505a12fad648526bf7c7a0012b2ea02ecdf55b6fa2", "28c9c97c6416a1a1566abf837b74612f3345849f6e0d20af3658eedb30c246c6"}, -{ "84000", "04c39ca3103cde71f02315b339936f58cb04aafe9990c46326733493897f848e", "cacfdbf9b2ae2aeee8bfc355d807badb9cc02835889a999e93c14ea7800d54c5", "a8a1f5a1cc75741b3597b9371c208013cd2e8d98b11a2895ef40954a8ff9495e"}, -{ "84500", "5f40a8c35de9dd97ecd7244e84a895deb4fffaeadc22ed8d206d303578471ad8", "e1c2dc0617f6e76b2ab84179c8bbc55c46d9732c6952beabec2d14babd7fd9c0", "f6a927e6e9c0f51c6819da1dbf55beab055f96c3732b6afcf60d603e7a96f232"}, -{ "85000", "b181b9521ee2b12c19c5db467c39855af3e1f636a4086e1c6a728e2b45165402", "8243d308e207fc44be4180ad0a63916aef3877e6278d30cb6f795d463541d26a", "c0abd81ab72aa7762ddfb2d2476324f5237705d8dd97542242dcb8c3e4752bcc"}, -{ "85500", "b010687cf83e100f2d398b3927659ca342b25e443147badc9be5f13331fde93c", "c635b1e609f40f3bbd4aaee0df1ea6b27f18094f1d00377f69430b6507012e88", "c47c926b3d18f1f2853fd5fd99e80c0cb9075b6fb333cefa64a0b8e6fee346d3"}, -{ "86000", "291fee34f060bf3d1c39be96f5ee8cf18c625515947c5495775924f5702abfad", "47e1684b5b4942e0719228e060af33e8f13389619e91925d58f86408ea149035", "b050f83dff11fb334541f21aa3f8248e3e88b055d4017babd998ad01ddb57415"}, -{ "86500", "bdaeabf298427c06e09a2e646e10ca3d17056bf1ba9619371327ccdb3f72c09a", "4eda2aae345266db3c1d7f8e49699c30e70c8675735a83972d0dbf0db2372c24", "2bc18aaed2b179c27204b8846637ff5917663850fd453ff16ff09f891d0f59b5"}, -{ "87000", "8f8fbadad337ea15f63bc845e472d58d4c6467a516d77d08fd603ddb3b98d823", "2d021df329f3c3bd4a39a5ecbae773b063f4baaf776f8ffb519b0fd4d803373b", "d6c50b050c32e92b6a9b462aec1fbc4ec26ac4d9ec9d1b26e84b495d66bf060b"}, -{ "87500", "109c6f62e3aa5e0ade745ab3544f8d055d4ee1bf27d217bcaa0815f8b31118f1", "1cf68acbbe94735132fe7929ae72e1fced6fc8cf569bfbc088a16c93c3e9e403", "b3b55622d8f81f35eaefd008e01a33e2a78697ee655c93d24866f618836ac65c"}, -{ "88000", "f46e00026587a254cd7a382218d9f2d61d37139d7c3c4f0ad76d35c76a2e8fd3", "fc2e809bba17e3198bb92edc5999820f19a4d7135330b2f7b055252ab91f4896", "6e1a58ff143797a81cadf49051e123bb3851028bf1a5ad1e8a41e5abdec89540"}, -{ "88500", "a048c5a363aaf55cee60a2a4286afc8199b7bd0d57d5e039027d3db2a6cfada8", "fcddf7448b220764d0452dacea67e5a91d537830349e307fdd20763143f92bc5", "0f39a201acad8ddb4f46cc03f59ec624d6d427e7c5f1180f09bab87e16cfe8c0"}, -{ "89000", "95e0fcbc78961eb79d44bd8e8055a26e77056036cb235779fe1ce22086a8705e", "3454b0857e99663789646a938c33241ff00e4f7f853870665767bfe04ffce0bd", "fbc9e1b12395084723c96867f18d41ef6e09a29378ae5005f69d47595077252f"}, -{ "89500", "8ed9d4f7f4c3ec8eaaa57d893a9464cafa4e2ea705756bc00c9b9719d51ee56c", "e836a5257dd6be6b167b7cf6c39b17a2433b07e86b2ceecc6886e57cddfa2a94", "39daa73bdfac0f7653179049450cf01387713ae121500d04fbdb0bdab729ac32"}, -{ "90000", "bd2cdc7f05511794992b0ce31ee8d58e428ddf12874905f102d2ca0a37adf8c8", "e182353321678e537290c24a2a9c09d226ecd91044cc139038dd134ec1ef1a73", "68188008335cc99621108f18feb5b958e7a78f40234e29b59af0892011a8c2af"}, -{ "90500", "a996f4865ec304be3972056e4fa5890baaa296db692f4442c5b0b7337e75054d", "98a91f31ee5cfdf960e1fcda3ff3d8d058471e2df6db7bea0e3937dd09baf06d", "89ecbedf84c494096914b7126d5837b8f98ff5594d0670dad7d0df04aaa235de"}, -{ "91000", "f6cb4c4b3fe3b7365cd9e05f757498cef6da8eb0e6730f4c569bcd3700ba1d2a", "91a792fa965f57abd8c8c95a37069682f68a3ad2112883779fd33fddf3cf7368", "94b75f07a61e22e43490bc799ed000ae3b9fffb955f63f2bf456954cd395d051"}, -{ "91500", "4421ef207f0a56fe208ecf3cc145cefe926784dc163500dd5018585c6bc4c0b0", "2870e9bbe0c6ae16f66d6255485d6c6c5c198e16b7a721c0a027df05bcbb46d0", "2c313cd244af86b7c34cf6a6a96a330589509974a5c1066241653a241bdd2c83"}, -{ "92000", "eb18cde79b36e5cfb7047d7ffd72374892d294d97b19965f67c264a42be981c2", "77ce5943ff19145cab30c4b25f762f1e93afbb25e284388f88b4078fb934db67", "d488ce3cee93a883d773acdd624b1686b74074035544625f494a7790f7f62a86"}, -{ "92500", "2a1e0986047c363c557e0719dc464f44cb2a5530f36ead6455caf22579fa728c", "3fc8941af430a2cbbe3a9e51ece9042410bce0c9eec2905109433485e8dc6eb6", "059825226e127fb3df58e84f2b060d82472347a37c67c6aef9a75b5daa5a2e8a"}, -{ "93000", "759bd6b0b243739d3d6c28227f3a9eeca8afc6d341d17da49751065ff6d9027c", "ff40f2c094d151ad356ff66fd39eaed507a78f9d3c4ed2ccde744d600d3ee843", "0ec4bc2e42e2782257d1f79a48365d5af74e82bf3b4829442bee0d3210cd8b2b"}, -{ "93500", "0c1648e1e670c38758befb41e8fc48f337f3b9c2aa8cf162c2856bfd44dfb4e6", "e417032b5b7a38c5a9812822810148a15818047c2e8364ec0766a33cba25ef34", "487bef320afe68cb94ca64269911d08cab750286cb79b06782a0dc27332bf62b"}, -{ "94000", "66cfc1f322a9971bc39ee18125a9464b9f82eef9c314670e51261402e50086d7", "34ddac2e7b943cd760ed4863497ce0ba2a723bad5afb6f391082f1f1603c5a51", "790de15153bcfc0e6ca17c286ac161e548c2361c689cc1e9a725e1140b97877c"}, -{ "94500", "0bf23f1c069fc47b2289bf52f8462229a39ace7afa517a43a52276f5cb8a0f00", "6d333049619b2fa4f612c1a6bc8bf82ab8a7db7cbedb51a258ea1bcc33b03f90", "dc932b2e5268500fe351bfd2759302bd1987faa6c486fd740e2424c8c911a021"}, -{ "95000", "1781fded2a4d5a2ab054b04de3935c97fd5f535f0bd109496aab9abbc6564dba", "18990d4e8be1e75e4e97a92e16bb4fbd805afa2d419629a5eec4d46a269438a1", "3ac8fee137a3e10fe18575baec6a598e3fb2cc7b1771c4044e8e079a3be7a1ba"}, -{ "95500", "ac453fe6cbfc81ed0c9b32241f121410d4caae7ab57c62ef99e08750f2d5f153", "e3c4ea5da181b0fbd82e45e106a9c3dde36c28382093708d8cebbb72d001960c", "3416c602f3620d5c1d3b1dde6b61b75e90bbe01f46ed14e0a73f737a8c20b10c"}, -{ "96000", "e464e4c5f135dcbdbe41de354730b1f633f00f458994d6ab3e7b272a5335e3b0", "093f11b3784b1ef794fb06db18424f84c6a1bea0b9038666ac5eb0d36b18258d", "4cc144ce8742ee482ad9e5e68aa7f51ef8de2bba485c4e7234cee76a87962477"}, -{ "96500", "82345f602aad0d7ff796eaddddda22958f4d3c9c41fb987378947be6ee12f808", "f6bb034032bc77c931558568182e10066932b5326940dfe562048d83dba4c126", "86c5337f6554d22573de1cb49573549633775ad3c236db26fdc53d91575c090b"}, -{ "97000", "eae3af1d8bfe6d1c40c118e0c78bae2bfb1800401d532b63a3c875fd3fc8a24f", "ea34ca2227308ab8818f085e7fefb2f140dfe9479558e6dae8c0dc049e09765d", "145e4ae1acc6cf254a5e21b6b002bc6f1eb0b5f870b80d3fd5215ccc3fcfe059"}, -{ "97500", "60dc3e9f055602d3673ddb11ab25d7c094057a0c71db2a327a491b3be93eb9a4", "186a25fa3609da954813d575a4128ff890d571f0c003f0e6d62a6322279125a1", "097db3da36ec7ac168d59915fd8dac8ad15e6d7e27273536d9d9c5f44255a44f"}, -{ "98000", "5124c9f250499786c2948dcf5e2be2c7c61b446be3972adbc0d65edc8ff87b0b", "7f5892932cd29e78d17fda5c3d15bba0a600f1e9ec2281dbaf0fb1dc67d5e8dc", "102458513889b0fe4946100a0d8d3091f46e7627c09a5b5c08a78f2cef987f25"}, -{ "98500", "6f507567f549b3b1e387f1bf80ec0fef03a9a1af73147dbbbae2134d6d1633c1", "60d73750b6ce4d508dc18cc64adc9e68b6bb7ea4828f09e8fb7419b56eb652dc", "93645d925bd3d878b65cdee59ac3349db5af2325abfd0fc696fa8a2831d33d77"}, -{ "99000", "64999aa405a2a2e5de34a4c3547ee525b503566532d82c35839a9e74a1389ffc", "20052d2448a28485dee72fe536fa8b6ffda1e8465af82491e87980c8f806c8ac", "783113c40eca4f0a067fca5ebfb7bf091561cf6751c3e4ebc3473c8c4c5c6400"}, -{ "99500", "3cd60a841f4913bfaf6183237ebd325b7baee3a5992f092118fa49817240a385", "e21adf8931f3ee5103fc1a3f8a92282e8bafa9fccd203acc2cb24dd0d28b6ca6", "c43bb024c7dd0865bb95082f5864746f7bb41f9c7feca9adfd50856834b50d11"}, -{ "100000", "f0394d3c54a8687b6090333aa03f93f9369846e7c142653524adaa9192b37b7b", "a739c2cc2c59123a161c9b9864a4c834dfd5021066198f51fde3ba9348d195d5", "2045168ef0fde83f218d83274f9bb7204356cee8ee0554bd6824cd9b720d5429"}, -{ "100500", "c5ad61c2da15ed8083a3d3dfd80d226b9977dc831c11e83b75b3ed68d2af0e25", "e3121bb1573ace63889a3fb9305fb95857bda6e889e9a88aa2ad4c76cc407386", "ccd1cfeb131dd0e478ba664886c27238e71ecfac2f3effe52e192ba370e5bb2b"}, -{ "101000", "27c2691b9e3e9cc2008da070c0af12d0997c895fea5c405347496c6a37570f95", "d465e2fcce8e1b4bf7355b4d87445d2557336354b86db40bc924752796aca840", "982d0e97bbd8caa7a1f02b9b2093354bcacbac1d02836a26f15af92f5dd9c7dd"}, -{ "101500", "80c3bf7835d6a11fcaa22931aae51bbc602af4412ee8ec0e8b96c3a9c7128f16", "1d7c3e519be3686c4b9f09708e225c8259c5ba6647fd78653b387539f58bdbdf", "9d7dfc1f142ad98c262face14a901620f92eaefadadaad38516bb5c7adc9eceb"}, -{ "102000", "52bf59cb7e10047df152f35bfb683611f084d444aac4301bd0284d3e458b6022", "7c8226cd17af258fd69631ce4cfdf204dab70dcf93bfed953d6cf488d576f56e", "3c7c8a26ce9a97f67d1428e098c42ed2afa0256e0d5eb226f359e7fd562f2d44"}, -{ "102500", "5dc7c42f2501c79ca5d610b8b69d408033bf0f7d16d036bea01e90e6c1ac9342", "403edaea352b4da33ec3269ccbae23c226a39961f457e5d3f84b806e517074fe", "3b9710ebfe1aae2e249cd9e7ecdbd09fed6b067b5271e391da4ca5092ed8d556"}, -{ "103000", "719c3b85ab62248c015de680a8fba158d0a336492668bc0b202ff9fae1b1b5e4", "d90dede7a044e1b11ae429bd313e841c12e8d0303aa6626db4c953d198b0f531", "acc9eeb7091adb2d2abdd03b650c540ec439b8d74b605dbe0f6d56acc0fdad6d"}, -{ "103500", "fa0bc10bbd112c733022783fa67cc4ba045bf93115654e1f25e680595024ef04", "e55422d2e8d2b8b6429ed85747a8ee57c549651eda0fcb2871ae5762862a86c9", "8010ad6ca7b744c25584f31bd0b389ed6ed204024d2a3d43085480025ca2c8e3"}, -{ "104000", "e63af7f5547bf8bc2f36058a43569a30f7edd8286ce44ea561e63a3bc11ea7d4", "939e2e2c30e66ae3b9077e947acda9b7dc0b9f326c55cef4e4d2e5025a0df9a0", "6a5a080ec382c2a1f1a7f7456bb1847239723fe6a836117b9aaae24d3a979050"}, -{ "104500", "d73f74f43bc0653041db94c60b0e68c194199041c830e4f90345c1dee78b9c23", "d1b14fe1a0631af85d0da1b0376a93ed925248fb2c5bc47d4284832d40fa318b", "f3b6dd22bce5f76f69b412b787be853833ec93c80be63d256745196c8175b628"}, -{ "105000", "460580489a262514f5414c1fdc95ef0d8290a23bdca4af93fd226d72ca79bb11", "11fedbb936fb27e227c2602d32f688f1d024a5fbc8d31823d273818ed142ae62", "79fe072ab0376188eb2502e46fe32dbd4a36151959975c65f907b3c7021e90cf"}, -{ "105500", "a461d00c1217d40b1774f631ce44e78c974be18cdefc160ec33e865b1c7805d5", "24f67d2f822429d89701691d7834c58593be43e7249530a9c1dae9aa12cde4d2", "4c7f21e6d5b6f0b86b0df017852e08e8317a7909f4ef8e9530c064f623e82cc6"}, -{ "106000", "70b95f002b31d55c7b523451d746df1ea1ab182f4e3d26a6a8146daa6b175f70", "f59d284adbc90a549c211187c55814e85b8343c7797ade9c5f761e5b4c5855c8", "15038f05ae2ec71ec3f88554f81aeab060849b24474194e70ebccdb89c802c10"}, -{ "106500", "5bcd8c94849d744d137dac85d734d893dea9963746e1d5adefc0852cc99c3c66", "67b4fb04c0780ac951d84e6779fafa76dae5d46e84ef41cf690cd33392c6f926", "5341b18362d34aa0f314dfb91efcc583fa160723051942c653b9c6621f8dab43"}, -{ "107000", "aa50a7001438cb8eab4442c4635453881df972b8707150275fac0867d7254341", "9e2451f91358f222b3934b24013be83c1fcc78415c12b4fab2cc5dd8a3d3c36a", "79250dadccf089c315b6a9929b1d1d0828fabc87be5424b7bf327faf08eb1b9e"}, -{ "107500", "f83ed835545b9320da20a1b2961c285adf11dcde168619a3e7e746f93cb93cb3", "e27c84ca437850f8aeb0cf3bd1a727caf91808663679f2dfca99f4c676a4cef6", "2c9755d38f916650e6a237d3c0e67534b0ee27dfe7da05c503cc01027e79d72d"}, -{ "108000", "d9cabd49da35be240bfaf8dc107e13fa3ead3029573f7711c51c874f09e2af83", "85f41c365756daf80d25256a132c25ced262eefd77547a42a51603fb98f0fac2", "b793aaab687ad533b67e99d954742be66a9d624e8f030cfdf4e1d7f03310f81f"}, -{ "108500", "e6f6bf4d75295e5dfff4f979fb12292736dfa7d4d8a7dc683f6238a4e00caf0d", "f294a30724f9d9ffcc244995acf528e501f6ffd0840f5ba8ecddbba1d1bbe250", "3e05c579dfaaa081ce6c61c4236685854acfec868568142ce188db8c0fc85407"}, -{ "109000", "154e12021e0e5198def8989a1d68326833d020409a76f980e4e41cb1662e0d47", "2e486aa0080740653141a5219ef25dc79777d3976bd9fad1a7c7bddc2fae858c", "410f3e29b17c1ba1714595fcd8697e13be3216b2747ec16b84523d612aeaae30"}, -{ "109500", "02a8b8fcee9f8a420ad024de30fb8f4b2db683b4f93e37d5a7936728ad1bc1a9", "f9c26724d2d6e8398a66e8ac080c8aadfc5155ce4be3521b3ae5aff95fca7541", "1354ab334c8590c339ff2f674497925320c95dab6d70fd0bd28bce9417e1228a"}, -{ "110000", "587654021f4afef0e863df85d5c48c1da57af439c890cd7c82f57112b523e567", "41299bbc731c54c00252ac8506c5671a019c2f24117534a52a6dc243de19e60c", "f68cdac1bcaf2c5b1d309a18816faf79533d8200b369505e74e88d996b520824"}, -{ "110500", "1b144103a2729d255d2c79223dc4804e9ec38bbd07105eda2eda5d350933c8e0", "47988c8a2b50a19d5c4cfd5c657b3bdb19848828866e762f5fe40f8ed3b0fc5d", "a8de7b91c00f0dccc29a832d4e278a2a788065a3d491e566be37563e0ad932c3"}, -{ "111000", "d2dfeee7017ce245109d6fd20d439a58fba318eb0853369ad740a4c7d8cb3679", "89d0671f5c51cc5e682fde76759bf130bde74a8c3d0334013165cdc74df67a35", "a81b3e0f2b3ccf04a60d59e048fbc01f591da5425bfd9643220ce97b03bca914"}, -{ "111500", "7bad9ae95d958cfdfe5f6f1ab0692c74023e9676aebf77696f0dd92f272484ee", "8711ac67cfc650bcc9a9a3b170896959954dce728667035278b865e843c5f5d2", "a59bc8880cda0f7f950577ffd851a18acb7c750440510209f6f56ab31dfbe591"}, -{ "112000", "aaa6a01ee0e8be04b54950e9fc47308bea161476fd9e5f7d931a9ac7a177c6b1", "cfbf8e1b380186cdd7dff5b1775e68857e0144a6cff5c699cda0df8a9b755879", "f43fe907a5c313040e43adf015a98d0b9c936971c9d85e639e92c180b1196a38"}, -{ "112500", "856c253a4ff511cde2cd1138cc415c15fc4601a9cf20f97a40a3ed5a8e4bd28a", "2418313d86bc12dd0b7ae5246d70c5c95ddc342c5f522d33a4faa38677b1cf74", "3802e55d5625b66deb5cf658a3a498de6dcb6a286ed67ca855799e25e52a8255"}, -{ "113000", "d39c76ff2213efb6aaf21e1831e8dfd86e82851311214222cacd1065e5f442f5", "7027dd65582113bd83834da3b8feb6f5e724156d8653689be02acecf664ed8b5", "60ad7e5a8a6aa36da5c85fdbd95a1fad66955a25ad7bf051c740dca3ecc0d80f"}, -{ "113500", "072de8c792fb777438dae0fe6605d05f84c05c478cf045595236439ed614c869", "66e29b9bcaa1beaa8d901e8227510190b64b665c427147e79fbb03f4c7560df3", "9f43ac28a04dee975b9b3dcbff3ede4eb7040d5dbc8d9fc79bcaa432464017d3"}, -{ "114000", "2727f22d9d9b83d232fb91cf7fef9923d998166a632e104da344aa5b2c33f963", "afb687e99a9ef1e794a049e78417ff2b0a15bf3c0f0a01b5c04e381dfd3eced0", "93fc7bc539d464859ce7d3ea47c7789a64ddee4155ddaf0d7be6891c7aa6939d"}, -{ "114500", "fda2f80a90dd787eb236d38096e1f73b7ee1b54d067c53ee62d4201004df7f96", "434c6e214b4120e3df23c820dfbf7ecf3facaf2f30b55fcce4dc094d0d052ff3", "9aa0f3861ad62b5e80fa6c255adad3b7366b90b2535baac36aa890fede0cd494"}, -{ "115000", "f8642fb7ecc176c23e6919e2a5f9a3f69d60c1bf10329e853b94141d7eecec79", "02a4953482c2887d0dc4d2980de20cf75b73ec8d81d5b3d6ca6df741a3f3fc7c", "41838982adc609b176d3dca2460d01603b07fc794d907a314b7844692e3d2a7c"}, -{ "115500", "96be8c04c6533cf914499dfa780622f64e3362ee67b888c3d187c7cd167c124f", "d160418c73e78f1f75972ff6fce579d50f936678a03b8e3e2e8eec885c8e7f97", "2ac87fa3abaca2b37705ce9fab3334309ab49d40892f1c2e5389164f5f9c7cbc"}, -{ "116000", "6efc2af9311adf3ae7cefcd558b25335048a0344d0fcca48f4a8302e0c2f4e4c", "5bd32d67887dbdc6482620b347a1ad8eb9c8d124ecf4e6966269a1ee537f7562", "b6f3154843cc3d1fa7a91b65008d690c66e21e9d1fa97eddb66442b77a1f06b5"}, -{ "116500", "d2fca2b2bf347959eda9a08e76c269d1e00d475d90ed02ec7d5d537e542c648b", "9476a9957e44fe4de208e4c707f0b6d1a2c0c0b3a32dabd912707ea86823f62f", "2dbdd08eb831f98085b217f3523857d434ae7eb9fc883c163f59ee6e1aa27cc9"}, -{ "117000", "5ac65e76af1b75c9aee7eb49b22ff2fee88a1bda49287fc5dc7762b2c5b8768f", "d357d64072327f9db3d73ea738abdf89f5bd20ed4b56733bc9df37d200b6db39", "a40c37148ebeab7a231c90ad9d5f832f2a50a7fa60c0633098ac7fc58aa74ccb"}, -{ "117500", "3d7e8e1235d8f137cd5661125cc0627dcb3c18945254e9676e21f2a445ab8b9f", "0f9c97626569303b76ebbd2cb960341f2297f69ae140cc84a40a83695993605f", "8755a33fd86f9497f14cf0f47e4729d735bbdbc609068c09712f1fd7146bb2d3"}, -{ "118000", "be2144efc3b4ccf0d4d3d7b66c5f6ba253d1fff069b89a69f8eb2cc4ff44fe34", "9bffc6fa6a4cf35486018721652d5358be0bbeeef8b98398c9373c352cacd4be", "c3efd174ed8698f182b4e7839ee78549e91b42fd05537150c2b9f49e3b75d1cd"}, -{ "118500", "58ca03280dfb1e73dfe8ae35f67b60087586b36823e7fcdfb0509bed23c0f9d3", "58ce09f4189a7f9263ee9292d7cafb880bb3676175c7553a04e25bc261ca21f8", "f1551f00755727e4c81091c294c0fbb99c7f45cfe091334cbb3708b8c3997ff3"}, -{ "119000", "907a0fea05eed4572602c76515bfa03d5cc79da72496d41d84afb4ce4098be07", "32779d699cd1abba0d653a332f07727b9a2094a4149fb66cb11f16df7c68d34f", "4eca044e4c6e854a875f634e37677102a876195019a9ab868506f33850a4bd54"}, -{ "119500", "ee7317e1516104041197ebb0bba085bb14932972d5bf4ce305a3bacb9ce17dbf", "6c779c5b384b94c7649ed90936688e83762407a89643aa89f730c6c399abcade", "b4cb0f26597d60b510022272b256861dc541c5df07d45ba11f81548b6665c98a"}, -{ "120000", "7105703f4cfd592d639e0b5bf6f2d25380a1787346f24331401eeed04f146130", "2a44b6fc864aac66301c1b20def1cafb0704830fb07e2684651513a6f8a89843", "8b843486a87af20a9cc7c7950b9b0406ef462f24d25becbd36433f7c005647b7"}, -{ "120500", "1dc347ca251ff3eda0a459a85d9df212ed27b9e7521bcb8445d5a377e23da48a", "3da9eaf002870bd0bc46688093150e254cbc0171abafafacb2c03f6381a532b1", "58991cbe89cb2e1bcd00dad869d9d93cda1269e4ca917b44d9b92e21ce40a4a2"}, -{ "121000", "7b8f755c93b69f842a1f9ab68f67e597f0fce31b94e0cfed7f3847662dd1a401", "f175a7b245645b0f769638a6ceeec460e87782994586ff8be749cee06da716a4", "96fdb34452cda7bb2904119d24c006fb9b4c44563a0e3be36acdc7c034dcf88b"}, -{ "121500", "2e5aa2e8bd0b018cc58a7d1cfc18d19903cd57882ed5ae8f2d6eedf72efab59c", "daa4a0635304dda991bc047ed1e075a9bfce603bd3bc1dcf93da809f82b0c5de", "cc2f0ced896193b19fe01f8aeb16ddb1256cf7ebf311f30d8dd5ca680313d98b"}, -{ "122000", "9c662917653809b60484673f8f223f3ccc52f9288b8598b6414bef79181de9aa", "c8c62e402da8ff36b5833ba9327dd92a501367be811157fca1f0b80ee49a4ef2", "5df9ed5e6769b16609fae4dcd7b7d3357dc5f496cdb9c02a9a1fab3bc8e4727d"}, -{ "122500", "74a15173b1a78cb7e95f220178205db14c5bb67dcc64f8a1e4feb2cb5b2a6e28", "f480c746a1436fb843e7f5935f2a8eb79007857b4c110a9348d4391302537110", "0ae1ab7f7adbb725c581632172d514e33a82dbc410c709d0d654f1a0d4d7de55"}, -{ "123000", "38b438bda7e108f97112d984725fab27d277a08b1a72affda99b79654c21e0f7", "b1bfac6a48327a4005f79408df343adb7c9cb22d2b70ebf2ad79121cbbfddfde", "605d68df65abb13b0b19301fb134674efae08e35be4b80d00e4124118e2f7a6d"}, -{ "123500", "ec7a4edbed36c3d7a0eb4098e6c6bca397bf08cbc0e0b190a4cfd506df0ac656", "7700c27d9c2e7a0360bfa2426fb3688bc8b3ca935de69d15b6dce9ca6b31a4fd", "df19951e635cc5ed4fc8c1b89b25e72949eec677b0a08b9f4bb1a2d04a00c99a"}, -{ "124000", "c3d8229a44faa337d05e0b5311a5dda37b91babcf95e5a8ccefbe872af0bd2fa", "793481678c778e8653890f1145e178e42effa2ea7f8e50522187ab298ec6b512", "76327e3f2c09f87ca41a12c67941a5caea3779a1c84f0d37a8c6d530d21f626a"}, -{ "124500", "1510db798814caabdc90f2b18282456d1b1be40948ba43fdc68e2da017c2dedd", "df6d64ca6cc492e32e22a218af5a3b802ae452d66ebb018c5d87ccd35489322f", "3f12f0e3189266aba9532c078df96b9f6db6c9f4105057feee13485af445451a"}, -{ "125000", "82460aef9d1133d30707bd416b3afc2929a388ec8d1431e92699aa625a4cc3e9", "8ac7f7dd700d26de62506f88cf117282a7840236bd66aeb148cde751ee3f7dbe", "fdc651d228df5a66e58c4e8566034b13fc7c5b9d6e8ba6e7ad0ed1047e0c3533"}, -{ "125500", "cf883230f6afd44caf802508a9bce39adeae83cfdaea0ca10c5eeb7e6e0f7abd", "269f3d0cfa2df454579a4b7bc758970ffb853aaa7600808071ff130b994adfc8", "cc6f34524eeb81b4d04f506e63828603973ec28f2f6eec8fbcc89178f3bf5f29"}, -{ "126000", "e36d486bbf7eed518a2a1b1668b516daf85bcfb0359337042bb8c278a5826863", "8ebd6563987e0969505718a915e7945f0d26213475be39a4b36ce9928d313935", "c139ca3a3866adb6d80c89c4ffb871c9cedbdbbd8e2cc4e273a3ca2d5897268e"}, -{ "126500", "41b57270dc8a7fdaef0345502f3ad6ecf8012b680714cf7723aea4c7cb03a864", "e422bcde2c4b3e00c42dde121d189205de9acc58be35d92bc590a67fc11b336e", "23277af9201d11f0c7bff9713f093d7d13827e9bf5ce45c95cf8116a02997c7d"}, -{ "127000", "34d5852f2c7ab91f6b7ba43851efe2838a874f1d47e6c41dcf413f263617c4e0", "296613313aa18e97281d6dc14419528e0914d61bf8eb26f4ee08105aa358c0d2", "6bd6797c2eb799e28a79010c8f79ff632d6559417cc253beca15ea6805b98165"}, -{ "127500", "07f471a70c1d559e6fd70d2adf4720987ac72e71d29c4bafd5f78e428aa6dc00", "c32efb7a2072cf74b7124a008939f8093f7028259a69d8c9d175e0bb4910f03a", "4e5c23dbf9a28332f3c9ca25568e9a27e49588ab6d8fe605aad8c40b98f34139"}, -{ "128000", "063c53a0e11590d0f370d0a3c2fdb3722c1c91e0203558436fb43b16b06f572b", "2cf68c71009f221feec16d73d8ec1b729b0624f854851153bf78146935b69148", "4a107a87caf55b16d2951f807ebe93768d406ca00450cfb669b5ed6c2f6ecd68"}, -{ "128500", "32a9b0507313417fdb97dce6e15852a8a55c80690028759b577723b629ec0234", "b2e0756fd80ff838386d84e8d82e2704a52c07e56c10a88fdea969948893b808", "a353283c0cedf81c24102cae0c01d2297e7d965b5c4c4f6a6c1afb2b9dcdfd2e"}, -{ "129000", "b3dc6186f79ecf8e7d4b2937ddc1ff5372684cf818665a730771a932461fa8b6", "6da8856b4177dafa784a25b68c4df9c250a664cc6831c9804403cb021239d03f", "ed6fa11d6ab43cbd6b53ea78bf00a2c664e6d768f376a8b33477df69c50027a5"}, -{ "129500", "1f5e8b0c9c4229ece2580e76e5164e1beb86e165d959cff8d7a0a9f74660505a", "fc76b8f58cf2fcbf3f2821d871788cf4cfac6e52b0fb0476e96769311865d90c", "169723a26b91806d2e4426a01f96d4c506a9004f8c858b5e4c7b1fac5b317ea0"}, -{ "130000", "3052fa9be8c4f5f24f40c5cdf0a8eef8087e08f1d168dde5d1e502960183f137", "8d108e91ab41a1057413efa8794611be06459dc53a8d2099457073ba932acb4c", "59e9715c601fbfda3ce117226d4e2d76e1d1c239e05aa23c2fdefc4761ebe4dd"}, -{ "130500", "73ed2cd1c1fa06e01c3c6fa4848d31b24564e667e3871ee032a1ae04812c4383", "df3d5e20f9ebc94bc84af002cdc9211efbbcabee00cd755653a0cadfe4cf77c3", "fc6c50d51abdb07de66327eadb4b803320de4f58e4254ba732f5eaa17dea8fa3"}, -{ "131000", "f78703a391119a15b5ce6a2a2bebf2988fb164656c968f72359af65852080c1c", "8fca74427f6789147cd1e233e020050d9babd0bd6f078ed53f704c6922b5ce3a", "fbc836afa97af45234ed223da7462c2a74383fd23277fb277731a3e1716ca620"}, -{ "131500", "e8873601a44048b85d11b25b05c225fa970d4ae14a3a30c0072bcf6459f2d828", "140c8f3bdc90be5ca51e7c3179c7b8839afed4458278759a35c4a078ae8cf4e7", "a3dfe4abdf91c14b0273001bbf71ec44f4698f8c6f1f6f30eb522c5c73170086"}, -{ "132000", "98752c54d7a5238387599ac3a0fe44b3ec462f88eb0c3c6414160ce79c128a14", "f82ed570eb9d3c9078ccf41e675c13fcf6e73e6e5bfbc4b6b2c1e4649dbf8a0d", "810b74f9c767aa7c62d699ec3889a615e85243f8cd7710845424677b0a43c5f2"}, -{ "132500", "7377043aca01beda7f7d70c6c2a9f59ecec4769cb330c231abf8439f231a6355", "3a35dacdff298a95ee0fc61728b4711d99c4d1bd4806dc738c684d2632fd48fd", "6bbab9b2642936d0e25f2f0b0e987c3eaa15515a7a70f6a14f00dce3eb63b36c"}, -{ "133000", "0d70e8ae76041c02ab65bdd3b0f6a456288532d5447dab7f7e30123b28e16543", "d6b3a5ad40a90d26a4b218b8b90852d49f508cde1bb2a23031f64e765d519dbe", "2aed7749ae9e8c34545f6aa4b13c2caf55ef2a9c6669c18b2d6a2fc79d89f13f"}, -{ "133500", "37aa235fefa6f62af6e393639361a4109369d0393d66597a3c63736fa5113a02", "9c59c20c57628b250fa5757d8d2d55feec38752453f21232141f82c1be4dea63", "cf42ac7466e89a3c791602ae3f785d709196d4bb20d1f8e19f5e69f30c57f398"}, -{ "134000", "2605e14bfe5b9a39a4d01da070c05d9bce4b6453b599a1f6f95d8a6344138edf", "1b02cbaad0ab46a737dd848c3db0f111c3fdc248d472636765ede6a6c2389b74", "3d4224d4eeafafda11e3261a668a714b7eaf019e8881dd30688dac28a087da93"}, -{ "134500", "12cb93a2b1e5ce4d9c6d2266bc6984839271c92f8ac34205dc621da8033af81b", "6346ab5cc2bca05485ed517f9e494e1e35e33ab9ce011923c6713dd0bc28fe1c", "6e270e7979e87e8a8dd0ede4b24ab6c2188d4f33d9f0f08f6fae0ca6d739824d"}, -{ "135000", "5d475b01fc5b6a22c775b89914c3b148431956df26fff2631111e9ee7d1ea55e", "182dc60ad5a4689e655a00728594807ca659ea3e870a4c71152b220279fda836", "f0ba10f249ef958564d7cd9d31e2b1578e432e7d8c2285931e4d7ca1e740ecd5"}, -{ "135500", "d4b244f6df6c05a1c918ec0c80b4a230c2e40de23847a3c6a48b8706b55191a0", "c0ea29271b681e460441fc515fe8af217459716e9116ebfaf9899531e55b9181", "48b5ebd4690edb79ca74a4560c09d79d8da8647e57690ad8954052b95448904f"}, -{ "136000", "123eb5d144a44b6940cc6194be4ba041c5fd8a5ffb342b5d62d8779605d1fff9", "9836476b408a143b336dab7cfcee4c07ddcbf6939fd40267f8315a7d4d576fd4", "f21dd2c8a381b01a01f3a4b73a70b4712f276e21639d5a63dc5ed5f69a34ceac"}, -{ "136500", "c169555d2b59eaf45046d5c3832203dd5109c6e3018504de66fd99242b41d5ad", "0884992c307a5b98b026f9885b6c81082aaa18a12ddd0b302fc5e358e313c810", "24a2322238cb677fc929fa52ff40fed8ab3712ec28ecc3569b8c8fd588ca3612"}, -{ "137000", "123d022b5482871c55b3638324b5713e225c6e36ab4f83120d883ddf3c0fbbf0", "024aa453462e49f50c55c36736542e4129f56cc81956b74f7c77e90b0e6796cb", "051560bd18e48d8b27f648aa13437285f887559b306b979075173ffe19e34949"}, -{ "137500", "3dbdb568d735e6c47c5fb8f459bc448693566ee30140da275f786fffb244901b", "c0e599ed4901402951a3663d225047e94861817b0a412b01e4c770c9719cfe53", "f998f1da46fec63c0c363b47020fe3f3422b4ebdc9eb514c9a1308982e6d9c5e"}, -{ "138000", "9dcdb63588c3f9d43ce67bb6da88a144e98b3340eed60478d67941bc1f3e48b0", "0c04f84ec720ccb4908774fb474149dc069c8420a53e89e9007dea32d90e380e", "e3e932a8d0a9424dc1ae73f0b7856d83cefd4549a0fa9f0519d11fd9b3c94a4d"}, -{ "138500", "918f3566304f92ee937b50939e5224bcefce1b61503b8cf5c75cddd293115037", "345d16e0d5aa525aeef890c1cd118edb3d1e6bf784e9445aad720dadc3408667", "57234942c9ecd8d449dcf6237a637bdd009829bd7227f0d0aa4fa1bad549103c"}, -{ "139000", "5a5cd26abe8d7b66b82dc847fe582d00c1aedf51bb747cda126f35d177df3780", "b11a4c12939538a057f35a15f561da8ad09ce4ec33a1b6b965e6c35d7f6da935", "d94865465650a0f5f1ded1d43c0fd0afea436f29e999560aa1ee0b07a5355f73"}, -{ "139500", "883ccc866e98513c10d46ce62ffc4b2f52914f9d3c77835ea88b2d772647098b", "ae7d18414cffeb5073a788005a70e1e80b3c04abc1726101177509d0872ef2a7", "e0d75910529fdb92ebe2279551b7f6614ce56217e14ebcdedf57451f35025b2c"}, -{ "140000", "0d53fc7a730aab5b7751832647af30f6ae6de5f66a26aec228c9642132460c09", "d157b0bf7301f4c28143ea0266a95c92a05a3499dac2ab929d57ab75b2be499f", "a6b6f4f34cb06f19a0cefcba963982cfc4d0200074371e0cad65e14a3655b809"}, -{ "140500", "b67b7cad6c800acd1fa41cad0e075a544368d679d03d620f5cee45cd966b61ee", "eec57bbe03beb832a99ab0bc6b77817e6bc459e365367b09fbcb905f3edfa85e", "2bd388afddafe559e744b0b3b07e6586edb24a1909e71bfd6153340b1d7dfb73"}, -{ "141000", "68756fe78e60cc7191d62c387eeccd0030ea6a67d4b1fb6667c068c5dbe20d53", "113007738fdc702b03dc17993f916d40e24e88d12a95726aef18156355990d7a", "695cca03b85013042bcce092fdeb39222498a6743031a96b0fc8af3dabbbce61"}, -{ "141500", "12aa3f916704a9120c99c22977c22b16bfb670c9e9d2807e0cadc444c9e8d02b", "e7dc3dcc436c770ba20dcbc3f4f762b7ab343fdb180e867b3f3db34f8b279871", "4baa32ead38ae032e115655d55a31d08647c588a3362e4f6b85f8d6b8ac99b7c"}, -{ "142000", "629495f161c45d033130f52a4df5e06cf5f705842039b89c3d499aa658ce5a6d", "865d4be2b339178a44d8d9ac4a53abc6b4f710b723583053f23b73c0dabd77b0", "25265bb92b7c7e669482e1ed6e8c41c2d60b169c5707d5bb15a33f959ee769bd"}, -{ "142500", "941a5dbf034317971407a4743fe1c5cf11ae87be184fe4e7749e2d32632deed5", "d8d4c2edb8362a39b9ef8b2693e1b4ed597a9b315e60e424e26797ac5266f353", "57a4154baa1de288b989de2dcf06d8a1f3b50af5bbf5a9a085f72921841ec59d"}, -{ "143000", "b8ac8abfe7b81372299d2a8be307e13786a5aeb4c3a671c8ae45d32f4bba9281", "8d7e1ac28129b56b0ee93dc931e54293f181d3aa253e844d1807d47b31193f56", "fc792c95df1f7a222dde5d47286fdefc2d7060f02db26b03708cf7642e445dd9"}, -{ "143500", "610bc499b94eb7e00d1aae8388937087aa421bfa9cfa70baf798b8f97e1b23d6", "e990d00ff71509c232b43bde64c749bb1fe597e52e40116893e02937c7943b1d", "09acf59e7f882faa32db3b0025aaa3c1a632ca14618e84530c665f82542d2657"}, -{ "144000", "58ab7580eef5d40c0ec3d7ac52425ad5afcbccac834192fe71ec5a1d15cd4ed7", "d9194f449db3d58a1784cdda50ca32d4212d43a12e85c6ad9f8b77687ca04a6f", "7ea883e770b9067c08ed807f0004fd96d3d35584781cf20d74a8269c34c03b70"}, -{ "144500", "9a49c8d5f6b072b617ff80d4b70116bf3db461f9fdf283009cd9e9b2c2df0925", "a2921c9b5ac78ceb49666c487d217ec303b1f5347d6902baca9b8e3779774c5f", "a48ddf29d2ff688201025318bc0362f95f7f4e7fbd7265a8eb95acce19088759"}, -{ "145000", "29f1fe68b8289b62a4eaabaec5abe811c61b6f2220dd15f04bf3d2ed3f98ba02", "8d3672fa9d6c4767e8d3819f09a9bfdeb98a6f35b83f01faf1f7b85c6871118a", "4b5eb44ce00f52df4406aebcac1f42a9b2e79685ae8ddb3c0125dc14a73cea0a"}, -{ "145500", "677d2c090d3beb31d1e611e42801e75fd3e2004e10ba8ef1cbbad5e2b17eb02d", "93a4cedb34458ef8b90ee740a6b19364f5ba6c0096a16142929987d2386358f6", "8b422f5ba0f1b2e149e032ca4f566fe353bc1330f5b40b5cab9bd65ebedb2529"}, -{ "146000", "b85efd80a2171505e8e2a83feb7f7d12e3793fa4ed2999d7b6148a1673e574e7", "c76311a2cba2713e1e7706f71e22abd117ec5c45d7463bd7cf9baa7734468c79", "782f73b81c2d2333ace904959e2e795099582fac13c71a11e051889864abd89b"}, -{ "146500", "f1dec5d905557b23d644829ceb4f9de311a05ea717740e9103d155157e4d1354", "3764ee8b0d6ae8dc762a3b43d012eea45e1e5c1008e90403ba84549502c3b62d", "41a73a0299e49dfb3da0d483734e359aa70c9fa846e624314a87ab2e5291f82b"}, -{ "147000", "1e59d25367fe453ea1e39d7f0c870f14bc37e99ae2899a6f0e67dc8ca110804e", "238df05f6e2a851137fb165117f2feb458487307ae95d0683bc85fa748cea31c", "84fdecfbad7b1f0c5f7c2fb6513fb0a9871fe8af6879a7e04a40faadc409aa6b"}, -{ "147500", "4547d35c4821dd671dd3d4d99fce894d455c083985eeaff26531187f54349bd4", "13f4a0105947e707604293a632917b8b93caeb00c02a28668a9559de36e5822e", "6d41213b961e96e1cede02df017f362181f6c10b3faf55a066fee7e817980f22"}, -{ "148000", "f50a828d973baaefd78a069efcbc42389c7a9d0e17cf4476d6bff763d3b219a7", "7d057f6f26c87ead3d5a3bd63b23ad81ba5a9a84258b46921f27f07919be82cc", "88dcf2f5fff804ef8b64dc24ea8747bda74ec2f0f0b1c15e5144ebef5543d29d"}, -{ "148500", "219d8ce760106e41d5b6cb72360801884950e795cb80c5cb75a4cbee7c9884cc", "66abe4202adfd1c91b092dc15dcd702b0e383c2a9a87dad84efc20f2391d6024", "2e1b9af96ce01ed55a76a373db6f175aa7939267222b8ae2b81d904ab115c6e9"}, -{ "149000", "e13e98351891f9940b40210188016098d67d555ee60922bd710d234393583886", "2751b92f77148b0b55b15c1e1939f566749d8bd28b70f9fa9445d5c66b116a4c", "679915acf67eff37a889fdec00abfe90edd8d9a6b5195eb403b4a33b2b02f6ad"}, -{ "149500", "bd0986d58541fe55bc5615de06174615007bb0a4e9b7d52a6e1de27660ff5e1c", "8cbd4ddd59183bf20e4bd2ce22136e8b1109ea2e81fae850281e600a04816105", "03d93cf4d27bf5519c826bc4fcf8bdc5ebe413953587f82355c4df6b77346882"}, -{ "150000", "b0a52b599b482e9e081373c2d0c12adae59742c92c3feb16f2b56a536389c566", "2b66e1c89afb06043357c8a702e15f37c6cebfe2c3ac2e2994b387b111852c2c", "d4e5a3daa131a0afa29967f8ad8f402f8baee17056f075d0c811687b53617103"}, -{ "150500", "348a90e69dee425ca95455f04bb8e0a9a5e8e4c9efc06e8358e90069f33cbd87", "6296399a3fc3e48c09ff1bfda646b6f19277f2c2562c8cac5c850d691b2c2110", "f2e3eb906a46f4e787a786c9372b847e3d667e8b7afd9dec5ec2ad405c5995d5"}, -{ "151000", "c2fc138fb4f13487c8f0ba65b1843cbcbfef598d66205495ce12eded834ed5d6", "6b3d49e0f596367b951b6939dae4629d81758a560d8bbee402b4258fe3896e18", "8db9363659e76cca5e94af0b7bc72a2da150e5e34a80aa86fb42d56df45e2494"}, -{ "151500", "f22af8f0a616af674ee4e07e5821c6ae1ba54d431200daaf39362d203283af2e", "8c445485555c915933539ad6c8ec776b65480a6b6100cc2f2355af041d37ae9c", "2057ceef9679c1a12ef58985712ee4ba239592d95eaaf5d67ea9023355d1af89"}, -{ "152000", "ffb05330a4e59f90c081b821c1cc26def98eaade28aa6fa36688c9c9ec2a0ea4", "7c94c4bbaec72efc42d8c00f50f777d09fd0bf0c71475a31183bc391038e4fa1", "13864d254b6e9099c6dbbee5f505134c40793b9c353cb738b1d97b80e6c44926"}, -{ "152500", "b7c7e8aa6953c0ad15cc9b003dea50f9f8bc08d8c8ffcbb287918a9e570affbd", "16591b434c6436280873b7b1d81157359b67969455cab02fcbf7ed9dec87e64b", "998ea569a30d37978769b49eaa6a5792e64a7309313f4e982b5763c2a1f69712"}, -{ "153000", "fef11d21d57c34ca41af06608c09e6d0a1623e6970123e654a81959089913630", "0683353ede70fecca1f5f072916105b0fe941d24b2744dced890e2d4cc114356", "20a6cc7045658dd34f400e80232324750eadbdd1375fd0ae3f72fcebb8e5d6eb"}, -{ "153500", "0decdb908b6c897fd269156ef088ea6c5c76ad98cae97cdab6b9958fa458c4f1", "458fa9b12274e81b31d551966d7992d6304bd3486a76d9e484af250b4d725e83", "c8782ffde622ed54700cd51b78fef2fc8f1d0276e1398945678088c449428592"}, -{ "154000", "8e921a4716e55e2c03536ace904f1b76f2e1c1f44eb1efc293e819619fc64a6f", "9f3faf97a3d07baee0cab898c7e2c16e1e75cb08b8593b30897f9290e7564464", "58e96c936858c0d209e875234d5ab2b9e46ba4f0766cf53399e53a19804ffe61"}, -{ "154500", "b2ab747c57f1e073712e5c7c63d14e427e4c5aecb70c749d686ae6740eaccdd0", "5b6d69da753ccb8fc0e7cc323bc544e272b607f0fcd7ecd3afc27fa454bb13c1", "f720914ac67c99900d3582520b06c775eddb424243b2f00c74fa5b78534291e3"}, -{ "155000", "4a27f6a366c137b5b0d9a7864ad6ae3aa2aa4f92fd96afad203f9750743d1b25", "5618bbb8a52a4a6523d7b79f9da38af51c38ec0b250918f9fe13df1f5ca4cded", "5457390cf1c31b2e16cd5c42c20b3907b5f68e2031af2ed0e18f4e42f33ae788"}, -{ "155500", "44de83681d8bcc4a775141039552a3bc94ae7150ba6cccb0eb51d12f67cfd3db", "526775b79eb1e6f88bf7b11c21c21cd3de6b70c591b146f75dd6f7dfb25d8258", "fbaad0826ed4fb17fc50559bbed4e4465f62d7bcda7c2841868128f2b682e541"}, -{ "156000", "fd67b25d5f2f9e33e0717ef2eb6f7a8b61c0e369d1bb27d363c2fffec6934c6f", "069fcfe28f96738efe2241bd5c46e5f9dc2568399dedf97a3b222e7db1f8d479", "828d25c4b68222571874c8f59096afb593a9a8f3b21d0da13e80db52e1a7b1b0"}, -{ "156500", "e4ccbec221374ecbbed5f7515a62ab145566ca98f91fca6e9e9e5faa5a302e1f", "0138154cbb27aeafb8785898175459b8fad1a50e5526745da4f3e3fce73906ea", "6a9d291450c9e77ef6037e3ba4e4dfee19d922ef52b20d48cb51216247ba8868"}, -{ "157000", "7931d577b76d43c21d638b392ce9e89deb30440d5965bdeeff5ddca528b23f8e", "2b3023999ab4fa8af216fc6fcd1b74a6d9b91805c25286b3a9b5c21d111bd929", "5483ff5e1b7a0d69cf11b8445a1e9a1260641f7e303d234e880d098b76756971"}, -{ "157500", "5a785cae6668099aa3bba0aced796a2efd3f32357d5cda07964c38bbb8547f11", "92fa0afcea0018aa72753e44978b29517c44b86583a7e7293bf41d0fc52adc33", "f7b8d7db38fd620cdfc62860ce93c698ee8fc716776edc93f6fc03e2639d6b32"}, -{ "158000", "215585110369813d5c23324bba75c2fba77a3cbbb8074822747d1d5f7a54459e", "c2bcfd99aadb46819152e678172eca6ea41d068cb9c3644effd3da1d90fdb6d9", "4555c9718c5e20d36a96dea771a7b3d3753c871454c10285057b792f62bece49"}, -{ "158500", "33ea7e9a89e3e620f7622a67f945e6a84caab88f8df84416920e34611183a012", "fe4a8ca54ee30957c1c4ff378addca94aa3c2faa44d6dff2c90aa740c94f322f", "676d511f80604351ac7666c70d8775c2f86aec0f43d339e705d16172517aa82f"}, -{ "159000", "5dac31f23e99492315f0ec0395c5913a197ecc6bfa5a1f1c38fcbbce10f5b2b1", "3f33701f476adc2de539a516353507c2319ee322415cbe2d2a81d25579320df7", "1798754aebb4e7543f64a7935dead4fb7c197cb27b68e660cc7420eabe87c1c9"}, -{ "159500", "e49f3c6d819ba98b65a07f3e2b4cbd4ed74f8f352ddcc5b29cf715870ffc96b6", "8d4baf5eb4e709a1749ffab123eae1c16c84c08c2b10c1bf35b904214b55622d", "35e32ff53ab80061b60218b9e199045e59d7274c18d18b3ecb65ae67df00a73e"}, -{ "160000", "4ffcbf8641b4b794fe4e304f3e33f8b252b45c99d647e26c174830811d5214f4", "d9feccb9318af01dda19ac1b834e8aba8f1a31b7e3c0c874c2340e5f963099f5", "e539bd7ccfca8e6a80a5826779678e65131dec0c3260a430dcbdabce60c018c4"}, -{ "160500", "940e235e254ce7e8c7884b846860faa5a7f8fe08fd7d05bedf60a178b294bbc2", "4c96d0c1b2293677ff55acaca052f84941b801d35426f5f6fdd0985a772e140b", "369a4692e6c3548bed6868c8f5540ff7773fd465795cb6f4f167a38a9ae134e8"}, -{ "161000", "49a2fe7b8f78e83709f195d11f092cd5bf6756dfbea8b61f6ad4acca38e0f433", "c61985a4419ef741b3255effd2490b3959d9a37b9fa458a01e314acf2cd110c5", "51745f2fb8b5b26377d02698cad29b811725181176b024b8cb6270a826aa2d1a"}, -{ "161500", "adf7a049b0055137358e82ff4cd0b223d4f1e65a99cd9427eb8892e9b3956546", "f2ea625ab6cfbd295435c3e70fc60ca04f444e88a9951351519c27066044094c", "822600252a5f7b5579773d156f38accebba75f2da548111012f2413eadfbc939"}, -{ "162000", "78eb9152a6249d26cfb9acccd3be7692835f61a70f9c4dbca7dbce97e8eaef29", "92bb404d3deec9249fdb8e8b0c11e1e6ffccdce4f6b76e49185e0e0aa6480b30", "083108fe3985638966053b609666fd101cebb4826499205dca009f72106fe219"}, -{ "162500", "f0016f65cfe29b53a443c3117392b631edda432fb508e67f537158d939bd24f9", "7da855957173b1caef3a5be9882b88d6be2feb3860bc528822ac203df9480ef7", "97173e216716af1354c97761a088c7e53f624cf44e0566d20b1e6a4638351487"}, -{ "163000", "16310f334b323b1c422388a77287e590286b436eb1d54c99a7dce533febad9d1", "50b8d182a094d5709040d1f8be2ed7aff41c50d3dfb49b6474ed04c7563a2afc", "b4843076181bc70a13ff31ac41a165cd89223f409c9e0d13f235bea9e51182bb"}, -{ "163500", "54529c58d723c981aa51c3bf7202246d09e30d6bcc22b28929b2bc80b970a46f", "81722de9f999145ae10c5a72cb03be616a2c631f6239f01243836ceaadb219d8", "7f60e919dfc92720ef62c9e3bff5878b9a4406e01cae08ca99cf4b3f86b2809e"}, -{ "164000", "135d6c860f9cd670d82153e8e37e5202b6b1632cc35280c0210587f4cb4d8f49", "c5bf964eb82fb51d1f5a4507bc2c9d658ae2f868cd517674ee1d81266971aef7", "fc75259e7d42db12a26a3e42931fb01e8dfcaf7f0ccbad81db12a4130cb978ca"}, -{ "164500", "08495f35f925470863e7dfb79ec17bd61029899bad972ca0e5bdb0512a0ad908", "8901ac98fdcdd833938280eb495214ec81269d8ee99e0c10886b9184b0aa9d26", "ec01d72736d931f0852ed396196ae71dc6a82c0b42d661a43c424f43211b0ab1"}, -{ "165000", "5178c8e3106c700a225efb2d7453be3a94616e980fae5a532c0a9fd103aeaaab", "a71b7ee462788bdcf6b6945da2a2b426770bb4e31c7063db4b9c80f82ca88af7", "33dd08e6f7e8858c84e0b9c438ad4e6c59eb9c4c30aed571f57a7c213cd78795"}, -{ "165500", "3d1e48c8657aa62207f24888630361eb85ea3f8225e65deab240e5a242fcc463", "b16e47a7ad5a208fe467efb2f7a2aba78cccc41dbcdfde571ded9b033b2c660b", "6aebbedc83a2cb1fda9df193023a8738e6e4ec691b5485a8229bb0eda0f5ddb9"}, -{ "166000", "2a5df181ba84755d4893b8af164abc28ba9d67f0fbf70a9fe44f78202c19e78d", "6382ac5c3033076f67f758d9d4a66006b6c67983e46eb4488b8482e5d020cc7f", "c190f4febd681311354ce703dbc7504012e9e2c7f176f87d87d97ad0213ce2a4"}, -{ "166500", "f33bbe1188c265e4f52649d90a9c853742c89348276119166d9dfb5b0a1c1d1c", "bc724795f0704caf13beea8188647ee2d0d8c05593cff788541d1f694f02e7df", "04e29612e5d6d95e89b80a3ca7fc24ca2f8472b2cc4f7b87f852a58a3e3bab0a"}, -{ "167000", "278a49c7367096b101da81aeed3a9b3763b9087446e3f3eb7d279bbb180ccd1a", "c90bba777861cff1db1ef3cd40e240a74bdbeaa23e2d4716dff0700608431547", "b1dc55904cc908d2c676275faee49c1a788c14c4ee6c7db7fbf85cfabee49924"}, -{ "167500", "de103832de75b420ee01b8eb238c7e5ab2fc2895848f1fb934bc0979af54ee3d", "5263039373a72cea915df57bc9369aa15e7dd2ca6c3b6df27938d5240ef4cd8f", "0f8d4bbae624d8c65e75cecebd8c8924c544404fb51a5122d6d79f6ad81148af"}, -{ "168000", "c347ff8a9e0c4297f74db5943de2edcda14652f1e707b0d789878424b0f50555", "fd732e674ea0cc59454e599365d9526a135a67ee82a1e54460f90b934957f9cf", "7c421c0a72e79c75e76037f83184ff85f13a833acc677d120ca890d2ee62576a"}, -{ "168500", "7c4bd55cdd16268ac7da91c44a5c204519aad6dc79a173d65227995d8f480ca4", "66e715d9afc7e37855c6f1436bb3344b440a7db44fe5163f2674b542a3a8affe", "756e2c879bd29673c2622c3ddf7ab61784b968784d4b38e8bcb5064a4056080c"}, -{ "169000", "8d8295fb630e487b21d46f82e5e0bb95d667635b1c0cde080e9965ea021f0d3d", "32309e6dc4e7812fe36a3e9f14079eb2f9a04dd910965a631f76fb23f29f2c5c", "cb1db6a081bc3bfcbbe3936ecbf34475345855d6a80e004f44d6f3a2aa883bee"}, -{ "169500", "3ff4f89571d4b7f8e2b25a761e2b03dbe82d9d2acc565c8f06f8e61b7b84a48a", "d71ea82c1b352917a9a60feeb3ea40f35447c58909a0832d17451458c4a0a079", "9791e55a423775872967f93b1c93656d60c275daec74680174f9f3462ada4fe5"}, -{ "170000", "e4612c319a4c8cda00c8853428e0c57c4c688d9c7ed0ebe3adb4ea410066230a", "2428df1325dedaad3c6c2e18ba57184348603cb4e5d4fad961d9f66a33e8d4c5", "298faf147be61758d1bf330195d35ac46b2a674af72b7cad4098a790f60b9a13"}, -{ "170500", "38f6d4c55c456c85b59d965db3386f3bebc9f3ffc101703667c9ada2c6f110fd", "7fec7fc3f24c1f7e635e06427d949e9244c3383ae8a1cbe5ff92c20318d1b303", "784adfc421d9d79b16745145916d119a7b8d21fcdc1b2b2a5de378b5caffc8a4"}, -{ "171000", "fa2d2abf42e47345b9b06ab4f0dbcb6d818815b383959b5b0f69a207e755ae18", "6943c6e99feadbcc5f22d2000b715e609874953a2f6b06ab18c6f6fe0d9ead08", "a5617beb4eb621345e1af0f9a671e21a92b223feb5ea9011fe196f8d673b5bdb"}, -{ "171500", "b269e08b7b8fcfaacc4cb1cdc39bea13237265f03eeea6df488039715959d60d", "f978606a7a355e240373d149a0bf3b2a80d735371506f6d83a7eaf2a05f6a300", "5c977031ed8854024e6d2484de8c4ebfad7c69f130b063240b6ceef706ff7dcc"}, -{ "172000", "c1ff70cb404b9a3f97513e00fe8d713ffc5a1ea49b29be1480dfd3b0e4410d1b", "f2d46aa05b23a697e347a4260c9d14b51e08af5108bf22123b820a54c73c3fe0", "878d911ccff1d8bc13825fae7d2a40dcfdf3c2c6c817f9d4f4f2ba0c77d7dc97"}, -{ "172500", "6af8406f49ba05570e46ebbea295e07ff856de60f7f7a85f29ccdf0483deb414", "2bfa8eaf8be3fde78ec35b8bc4ec1274cd089732617255d9b1450f676d359631", "1c5f68b20516cf13759bfc90f300a01c970c2ed22aec2f5440d524f4fb8ed2f8"}, -{ "173000", "4187e88e79ee333c661955addb9fd1ff4853bccda1c1f73585fbc4b866d46ffc", "2c561a6112ac2531467818ef79bda7fd294cc2d1aca8d700ffaa8ca3c7e2cabb", "b4b9badb564279262308912a9588870961cbdb6fb9ca5488f37928ed9eb3802d"}, -{ "173500", "979cd0755a559b4298c4e1af1ca1ed389c152f6800718aee777431e3b84b2975", "817578adb3539145804a17166425c07a798bedb2637e8e6567e77406da8cbab2", "e0337c7b2e52ff99af8dabedd1f1912d1a2201e8153b3b984036c26a7fc46ea1"}, -{ "174000", "84e476b10a846c1f76cd25ee8721aa8098a3a794f56a5a6e2fa8ea08dd7de954", "7e3015ed948fc061ef3955ff4d18f5c9f2ccd86794be959d5e51e604c4ba315f", "4282860b30cc16a2db68903e8bb0f3c1dbaa5949174240e3222d70a994cec1f0"}, -{ "174500", "daef6a8cec458daee2a97f145d74867790d12697f424e390fa5ea96c0edc5889", "e70b3b4de2ebddde769763e56a861ea73e3a9ab8360f0626ef5075560899c18f", "e69b1eef08603fd07359c1216cb118cca49ee176a5448a49e9a3fbaddf9936cb"}, -{ "175000", "3f6c5c68d024c26235bb054fe0e892b4172a50c900ff7e36a061b17bb4adb44c", "f36837bd4b44bb99bc4a99acdc71611e6bbfef26095aad173d5b6c2847cf5cfe", "31f4639cb01d8370582158623353a2f1843dc7d0d5240035572fe76aff38480c"}, -{ "175500", "2a25fd32974c49ec621f4256e89f3c1569734a675bfde35fe0ec4572459a99ce", "0de2de8ab8f49f684a4ed93762fad169165b9f29306fddcce37a10b3e0f324b6", "4aa307435bb260b7936bda377dc6b2ee78dea1859c5a50504adc278372449044"}, -{ "176000", "ca43896b57242e50c5e1b0904b12b7008d63f30810c9d1728929a45a051b1c28", "0c0a240dbb5b8d9c5303c2e401b1a9be3eb940a2ccdbd40482b18ebd9d16fdc2", "735a67586d8c32fb70e490082bff35c245683e46815882484721852e5cd958d4"}, -{ "176500", "01bd824255da4562af0cfe656645a2e644bedd67f5c4c2266e9d706d724f77c3", "c1c8c3eefcd2a0dd893ec58a59d9b4b9fca2456b4ebfa118caf122316ec1758d", "be47ea88b1c0c059de0a8ec08c34a38b3595772d37516a3f23c86c12936aa27a"}, -{ "177000", "1931b94a1d1731ee2fb2b959098279a73f2938815dabb1689c98ca64ca265eb3", "9ecec3dcc0f626eff5310a338ac6ec36e52cde0e31dd2668510985504dec6b76", "4ed89396d2f57a853ab5c7cd9df8b3a83a00c56806c8e31e8c229d835f56a056"}, -{ "177500", "d5e641f50d45b9d3c2f81c255fab7812b79d778bfbf3acc3a905255009efabb7", "780102c55e6488511505df92213d370484505fcc63e36844adb4e55e28b11891", "14dc898b282b20f15851d882a8a54723f6daa46598ba197a435faf51ca0cf3fd"}, -{ "178000", "41dc7c791cea13b0c22c556ecf0b9c43bcabfe110cda05fdffc9a213d07878bd", "f502dfc4f8e1e754fb19789de0195d3f76515af97df6f6a4dff9af35e9e64cc2", "501bdb86464c2e4c544c8c7fd634dd884c38c237a80897da49f526e44b452dce"}, -{ "178500", "86fd0e05f7c975edd10fa04040fcfc06aa5988f25a24dc475468023fb5ba60d5", "9a9d5b0da31bb391cfadb78b79de03e6d2f9356b6e8f2a6b6f3561718607666b", "d6a0a18399d9c382a9d7333af7208f4084dbc08054cbe0d8f0c0403e63489470"}, -{ "179000", "9f87f2c50cac2bf6596533b242692ac06dd59688c85711dd3075556a42b5a51f", "62c5b9a2f74642239aa89a9468c1959af35f4218d16ae1c0e22879ce5aea14fb", "1e72866f3fbcc54b6d32cce2b1405ea585e5d98f36eaa840882db29d1cb40384"}, -{ "179500", "2802d26be7d5a8dfa0e84d507569ab54eb2815addf1363e844143d4d1949aae3", "04a66a42a874e8a94de4b35e0fe5b2415e2806089e62b0ce867206a3bbeec923", "6c97ac192eebe679bc5905a7e5684ee9f1dd3f0988b85e8c1e104cbd40c8cac1"}, -{ "180000", "fc0f88ce08e8dfefa8774c7b9e101f82f4c7928aac246233b5d97b178ea1e8c8", "d2cb3429b3bb7ca9c4bdbffed735f779979900ec989687ff9563819b3f340a40", "ebc045856c0f24839f6a45dd27eae4ae20f4661434a02544469b92d44d80133e"}, -{ "180500", "55068efb221561b62da4c6cd3933963165b99679274f0a18b57e12a0f59c02bc", "f4a3a53f8756a0f1ab9f0dde456df65f68b487f452e35119a395990224589672", "bd9796c38a7e9d8812e8aa74fe7400283cc92e520eee8b25cec8fb8b49e678b8"}, -{ "181000", "87c0badaa9ad1ee338a1e0bee51f0e5d95eeb69b608604b687e1b75cfe28b1fc", "55c6a1f3d35e1ba2c56261370b991094f37b2e0c94c585c83c91ceb0e66b4205", "c27ff860820231b97dd7e5966560e39679ecd722ecc3b5d350db9d614072d9e6"}, -{ "181500", "0223e4ac4db7cb7aca8c5dbcccf4dd6d67c261e158579465c830d00f0b2065a4", "1523b5a7b17c5f0a487b27b05911b0b023b7b70c1e93a676178193e10dee764d", "d1b905426b42ce35f13137ee204becc90c653d824d70a7ad3dab923aa6e49106"}, -{ "182000", "3bd580fcde83b72980a98de1bd2bc33f5d2e5260a45b2025f8993ff148006fc8", "b5867c690edbe8ebe6938bc93774d516dc0de5a71a28b48539e4029162825354", "44c3ef084983f11e3a1f40f9d87e3c0af847b4341e1fc53d576a93fc9910251b"}, -{ "182500", "d5ed6e8efecd96800b30644154dbaef8704783309362f9cdba26c757fcad2d70", "f64f64d8652b12527197f54411334ba0ba66f2515e4c99281a075d1df597c8b3", "0c1f07a69cf1735407b92ec781050dc703cd29874cb873c09126cb3afa36d701"}, -{ "183000", "e926c6476da9f0d3fd84aec136e029881901667ff07d80ecd1e6e6e4a1e78979", "e74160bd9ff069b6511c0602a1c72fc61dddb22899f805cd9c2c0be184848033", "96eab6f32832d3e27bbffae0e7db6c7ef6fb2aac226893ca446387a1b76230c5"}, -{ "183500", "5bde7c982564b58b9d46d8208922b3ae8cd1d50f2f68c7a4a8d71e636b66181f", "00d016a3247ef22887c0909dc0a7370c62bb2601b09425bfbcd93f782e1466a1", "12c823ca9c001b3f59b04b61af005cf13d260633d4bcdabd77594c9e6b08c14b"}, -{ "184000", "f1cecf410b8d9f5cecd6bf19ddb1c7157cdc5c42e110a42596620d9b54216dbb", "ca3d938eed902785feee39efcc9a60f26ba5a53ef969f174ffc7f44dbe544bfc", "fb6bae9cbddcdad7e3115e225bac8ccfd62e4c0d450f84a1b0bb1d40e716d095"}, -{ "184500", "89d6e5e381ea4c429428a773caa457945d6e5986e77830699d64ca84b6b7cfde", "30e5fef97c937baabf267183b5f8bc9de88eb72b00c204abf6db1962ad1e1f0b", "3b3ca3348b62cb425ac208e34729700e2c0f40c8ff769c3a2f078479768bf6a0"}, -{ "185000", "d55dfc02a7dc5e64f615b9821e7738cc3f4b1cea50e291834b3d950457c0befa", "3976b8fa6d5486bb07e4f6a5a63f200089781bc8c347f858bcd2d4a8eb4ebc7b", "896b5c4d3a04983ae70e3fd2a3a47966c20203204f3f55ddde32541d3688aebc"}, -{ "185500", "b74792db4244be3b16341cd6bb1af5c7a9b71df58b812691901a59e2e6889f8b", "4523193666a8f6eab2f73949efa94fd98d9ac8821ffec1c8069abfb1dca83b0f", "41b6264e2cd8870abddbfe47bc199ad0ea07fcbcdc541b7b1891c9dc1657515b"}, -{ "186000", "673e42a71dc7428d516a2bd892f5bba9740deb4a8e7100afbb0db70de4432d4b", "54bb7fcf882d25f7e4cc19b41bd13e44d70c04d31a6b4e2ddc388b6ebc0b1818", "46d0b88252df9f4992a57d8accf413548bb64cfc04dddc3cb04ffd994dedc695"}, -{ "186500", "ac9d112147478ad6096daea4f3b9b76912367605cfb6ac68a5951478787d84a5", "7e112c5297f3521039d52a994be89b1dc3b6387b4be5398d7673542df3db0945", "f9147a1faa3d7041dd4c83681f8fce6bbc11b307815b2697f02d133d6fe7d5de"}, -{ "187000", "b06838fe81d8bc39304fd98dc9f24ebdc0e6a05a363713e028382d77334c2afe", "53c32d4af24bd19d1dda8c23186b6cbad5cfbaa6ee169666de3b028473f3d388", "7da79dc097ecfc37210e4c4bdd457cd81c4d3e150a775b2665c44b65e09de915"}, -{ "187500", "c3f730a1d3977c557401a7ba920f22b768e9e89924a07598af8f6dc0930a4585", "a83e748dec264dcc6494d6ef7c63025e554aea410915c25db93249088c287442", "c3933db2926c4b67ca839e3be9171e1e075e9dc1d001d4da8b7199477c673ee4"}, -{ "188000", "4a74ac7ebe38798b80ff54f21a428c40915895bc44a528bd8e4ac3b9f378def9", "847a11b8eb71e0b5dd698b277fbcbbfae9c54e55477320396a602a26b1f73d8d", "caa476f95144ecad27f8d99b6b8f0a6e5d1c247cc48fa9535f4cfc986e0a91f7"}, -{ "188500", "59891ac998632472cdca935fa4a3819fc676d23702621f0c41d6d38fb9e354a0", "4393d0b0d5af19f6c123777762a186fd30666e8498fd76468c3cf928b4e6fe1a", "38f92f653e9cd1415db7b4f10650f767133e43f413173f20db9689680e33be76"}, -{ "189000", "7c43d2b882946af37b0d1b1e0b3c08a8c55e83b9d93e0d3c10ecd3ac7a49c1c9", "0a5758bf838434644aedcccdb7905d4bcbd576745f82e53ef74c9539b9c95cd0", "a78379476f62d06d8e3817387860f6ca0e409869efc3e674332c2bcd5a543ac4"}, -{ "189500", "4913cd6821bb3900bb012df98da308582c7f99c8907d1dcbde5caeeb04ba1abe", "83dd01f4f3544a1254fb7b6c1fd8654a10b4ed99581b1058c79ff2a3a08b3ab7", "d38a7cd403d69c3d04f3ea66cd135fbcb77393e3d8747c81a43ae30acc6fb763"}, -{ "190000", "825d6842d16dafb7b6d3fff172fd176916478e6a14c50efca5e2b6990f7c2299", "0d7f3744d4e18d9132d3bf7e94b9325900ad8a574c6a48b04e6594f2ed07083c", "a485cc141b0697e8239feb81967a584aacc332c4f0c9dc689fa9cef5a7d52a32"}, -{ "190500", "b7dbfde08c23efe184956485d0c19d62325d121b493560ebb0d45321b1832b38", "227eab03ea5949234a281ae85657bb5fa39b271fa2218e294c4dade8273639eb", "189b8d34a7c89ad218babeadbb95200ea07e4aae2a840f432ce29180cfee95c3"}, -{ "191000", "e61629b5f59b130b4e6fbe4d3aa8027d13aafd890ac3a16b1ffeb1d3f590bc5e", "7736329d7fc7d226fbce139fd58d1b21a41381b442fd62f1d03bc53b5580f906", "60f22a08d5f6f33ecba45cd1d80f82b42029db3809d1101c43ae3e9bd9efc2f6"}, -{ "191500", "06e8304e59c8f386db5f89bbbf524959e5674c1f560121ee65e04b5902833f98", "5e099e60aa5f56a39831962822390e897947b435b4b84cc2f45a1e98319aeac3", "93ee0024748a9eeb8124bf9b5c298f7402d928459d5e2b8c5e3e241812da7fde"}, -{ "192000", "7a94bca1896611bedd44c28323897ac0b065d2832d36000b51da6d8da42ba38e", "640f07390bf420c0f65d0b59112d66b148df416f2a139f961bee379df0928bd7", "6196ad843e24ef1aca394913cb15a1a659e12aaa7b7cda6d0b87764480164193"}, -{ "192500", "23a1270346e2cd8b1439b2357aa6d9967285d727963656385edad740cd66922c", "fe551350fefafd463b3d5f47a53ab239b346bebeaca875c6c7a87d42ba976bf2", "f354c08b5a5faada798b058f860e779260600c5a36827b2e00280fc368ddc671"}, -{ "193000", "5c7ee526691d558d00b30f649c4f77ca4c595742f23e389ead78633f8ce2dd35", "68a041f99854b2ea4ae5bec9b030b48ef9edb3aa89a144bad9c7e744b234d409", "f54a673573587b3d9d1274e6e0b65b29cfc204724c6a7bb9cabfe362e28d04d7"}, -{ "193500", "d03957be53c5a92ade2f6caa1e1999c3dfb567084580cfc618fc7bbc6758fc1a", "e218bdc4ec703cc01b2ec52b860b2bc0ad51b90087088c9cc0e58736d625de91", "b68bf79767cfeef3edaec65988b827e286bacca28042ce3114d56658177c0cfb"}, -{ "194000", "d50b3435b1f5fe763970370fe9fba1f0a5af9e9a9abe295e1e61d8832b43ffe0", "6f3878f181e0dadfd1dafc8b2e75c73c6ae0fbf97a6bd1894b20aa93139cfd80", "4ce93b30284eaa26b7ea61bdd747fdacf2c4537c609924824997f748184fc30f"}, -{ "194500", "43f28b5c1af708ef1725ae8b0e4542dc6c6f33585455e6763038d93b37992cf5", "6792e3e7d2ee64a48ec47e9fb86823aa726ac49948e3843d43ef80995a4ba7e3", "59421cc124edaf1dc5e7d717176118325f8f75ca3e9f7c4c506134fe9bb90cd2"}, -{ "195000", "27deca29e0f720fa505c64794b7904c2f15e2b2bdd539f6066bdbfa8b9cb16ae", "53d423505456177cb9e6e39879e51b1a473abc363a6df7025d6c523f71fe10aa", "d8f3589f66e7c921cca22ebd1c9145ba10dc97f8d9aa1d738877d55309bcfab9"}, -{ "195500", "4996255d3fc243ca9b29ed6f5e7cb2799330bcf2c11e42ce9a82c017fa4dc47d", "1ee2de24a628d83a4a9b796d5f3c6c65d0327202191554d0362ceb1418904a26", "dfa80cb7bfc802b65a7f4a655d21701371798227507205908dab6ca115e53e2f"}, -{ "196000", "c3861c14add9fd9665a1751e1bee488a13e0156bbd37013e3e6a8da54da26550", "4da431d08df43f875267b70903b275831281c28902749fefd4bbe544989a910a", "45a345fa82f8f2447a738b7a6489b6f5e64157753f7f661e391e4b6fa4b4cff5"}, -{ "196500", "9e85e9ce7c9f969af748556cb124ec97c581e6ed8367c4c44e8b9b12d5495ea9", "14f7254f9bf3d122eadff425ddb06f86c16c4a4954bcadb5e99ba6ea78f8f0f1", "f141304882870f7a1a54ca77797b0d713ad31e7f287765be87d5133e9abcdbac"}, -{ "197000", "387b990115d39fb36240de77081a933eb7d4f8ae20cd72f0dcc162c496717a4e", "69c3b4cee6ad5d2d315e2b133a716b8640b170a0f5ea53269343bf4455a886f9", "a0ce44475b164c0f91bba84d738187d02ca78cdd865fbb28a5d8f22c33c1e237"}, -{ "197500", "0db48271823bfbbb62c8d9bb68a0ff7f46724dd251ceb8244253418b3089060e", "0c2cf4682db25fe743e7e2781ecedaa243dda4d9944edd9d1aec7a9e93b831df", "1f3027ed373f00ea7980e7e14bc8a1bd9fe3952af41e078f2b1df32f55c77d38"}, -{ "198000", "c65104e71ac22bf228691460ed6036046fb091eed1059ce756e1056bf149148b", "3c3f1f86ad2cd5cea8a979c55d01fe3dfcd5d6ec6fe485c3461d65604ad4adc0", "02fc4a02986275f8692e7ecccc1264bc784dcc1ccd811bdb1db098cd1e3eef1b"}, -{ "198500", "30e8c038e2a43c5ddc9e0f3a030070380cbb09e577ed7d783b83651df9ad5015", "dd0bd23d500ed9eb599249629cf07236244c001e0517c93dbe6debe262e7f4ee", "e6739a8f4f4e629a08189b31048e82982103b7d33ab0b4b56c5cdcb1ea2ed1b9"}, -{ "199000", "4b4e61aa4eec7a39dd94aae2c114994fe32185c72050d3908b7fc0860d41458e", "0443985e3352c7ec9e83fc34187460671679f71a3eff263956dfdb306f4e518b", "f6611077832a1c9dd956b563c1b09457d98a2b6b832d3788e30d8319a1026fdf"}, -{ "199500", "09e62ab674ae8526370e0059097c80cbf382fa098e67d4a1175bada96d5d87a1", "83de440f57fa996de35e346f73bc616137946dff6edd47273615c0a7d4d3d7e7", "681274c8b4d83a3eb9b76bf5e984c2dfe0892282f89c2be9fcde7921ebb62dc0"}, -{ "200000", "cd9a04e20b651dcc4518ae71ff5b0c8bc2ed5c6eb3d5fd2196b1e636987c3a95", "6160d970d27a8f799d74d3e01630761bd655268486a9107be28b128fbbc9dbe6", "e00de657836ceaf31f5bde6a5751a6c4c475cc23f9e78a01b405c06e106b5414"}, -{ "200500", "03609721a5de60ab9175d5cf5b9dc444f8c9d420b94814be90e39e4d5411f33a", "f1625e3d9d93f152c9e351928677f1e8cbca9c6812473c759de6216321fbfe53", "d3beb126fd503a82fc169a7b4b2c56840e2313847bfeeb520a91bfc0bfc721b6"}, -{ "201000", "f1be5c8c40f967dc2f1448f38a7e7e6a47c6d7e6ae9eae150762642394644f19", "562f88889f723e4c4d2a7b0f8b0eed383db6aa34c8e094f88238526206af125a", "1e62d55da61d7571fe187cac6157379772d99a15a967492074786b5aecbe6250"}, -{ "201500", "668f7b1463226ffe529002e0dd28b813c68396ed381a5725d166691660a0383c", "0077ebac17ba34e5d77c492ce62473602d1010d21a99380380dcf52f1a6a3318", "fa3afe138a87f31ecbebc18904846de2b7897b9759f7b6c60b230a8101a30e60"}, -{ "202000", "60ea6173bbe62b24b704cfe2b6e1d1995dc8854d618fb0e42e0c712110b70e50", "aa3b08fccaff9887aed03778827f73871a658dfae6ad99b7521142cdf8e86dd0", "4e95ee5671de054d13d166e8318a170bf440ad2ebe6182b2e55dbf12025c171b"}, -{ "202500", "6de298a7a2fa7ce5bba344237129f982b1071969df56c15d0ca2c0fa39f9c1c7", "dedfea5340d820409423688ebf7c236cbead8e502dcb39af7686681b1f4cdea2", "cbb2326e4c743de2d0834b486e4f8b1029e96db14dde184423a72cbb284b4341"}, -{ "203000", "0e117900e8f0bc91b0279b83445b8d9cebb374dd81c84a52f0b3e6b94c880e1c", "74c1495fb1f720209dadc85404e75bde143a59c7d21ecac61204734dacf63545", "b42a2959dfb5317c241e686bcb83ac1bfda5b7b87fa8a0004cf069be1193ab9a"}, -{ "203500", "ee347878394b9da8a6c11dcad54882196eb1a6acd7e323154167e764d57f00b5", "6ef1bef22de744dcac118ba398ca60424a713140fbb76fe0555f1e89369458b1", "33ab652565274a6f0ca4e32152c5ad71cca5e7f2a0a198ef2e7af6d11e7663a0"}, -{ "204000", "a687e4d0cdb3eb142d1acaed94b80625e8d9a9d472545ed1dec3c5e966db98b7", "728306e941f0ebde00511bfc3a30e50cbf283e1850ad4145f2697671f14c5775", "80256fc3b1e5468981bcc71318d368520445ea6a76654b2c4ce3c8238bf405dc"}, -{ "204500", "c813ad2efcaa352e786ef9dc912e133bb1f32fe408a54c114152223fa3c4e96a", "fefab4b9604535559292b1b31c4996dd815f25a8ac474cf8bc31d0c176aba97b", "904cf3d024345bc0cb59b2394adea94e9f9e0b24c0b298369fa8f13a4a788443"}, -{ "205000", "b67beac20c8c3dc2e07c7d88d8bd4922b8803da3a5cbaec8c8b0a6601314df69", "88197fef17e17da657552b7cc5ea2e09377fc466d37dbc22ff8a948509057d63", "b9ceb088a6bec5d9ef64b9f3fbea11d3c74a023589afc1d03d9ebeb8dd171f76"}, -{ "205500", "0937f7527f96ec479765e3be263f25130d7898056813dfdc67f3f95f4923f2c8", "716b95c3c62dce9b236cba23dfd9dd3fcc68cd41cbe9d13d6f8349503fdc3827", "33ad2f9960e74628b62f3c9ee3ae6158c811656b69b093eb7224d9e7de52a58e"}, -{ "206000", "aaa70022052f41b2195c68a4c77c11b78e1a8136f03477d310a57ffdcdf835d2", "dd9991c1a086391127322eec9667bc193908aa869a012b36f0968270c8c679a0", "5dd178775801ce351cd81f8a943ea7226c58711a5c51e1e1a23f5697728b9d3b"}, -{ "206500", "7724e797f7f8e157fe2292c5a76a018278bd7bb95924932df289d975c4191c6d", "dbe2029b6398ed4f32b906956006915345255bfac82ddcd79e44848574c50d36", "d1b982b2945accffddfa88f88a6ecca1857e5004ba7cef7c764c3c348989bfed"}, -{ "207000", "3d779550ba9dcc4e29106cfbd2efd9b22340432345c0df139ab31eac25a45226", "cbe3c2dd884e9ed7a1dae427c3d475a8c9f3c8803d0f3507398b92a6cf5ddb96", "e4f050dbe983ce3a4c222639bac89a731956ba1b8d78d9ecb04c724527207e5b"}, -{ "207500", "5484677fb6f857f8009fe0e371280b61ba15d0a5fac08bad41392dec1f38c85a", "649c2c9faebadeb93551828d590b757b444b6a54b40298519e5aa8505fd81009", "7b3fee88b64fa8f3b491877f080c4cdb756e70d4a3cb4731c384f4be754650df"}, -{ "208000", "cf31a458b286a4f77890e65d02cc506bb0454be9f373a1685f2f6b2b91a76207", "22e9abf8f61d55f7fd7b85e0efa3d8a0f6579f43020b19cbe921a79d0122000d", "a28f21af0dfda5b9461198a4d1bb6a1668ad397de817cc1cba0c9ca092831401"}, -{ "208500", "4fd3fc158e9219659c7ceea1c4f02bb89563c7524e9b8e9f158b61bc82c52881", "4a0ec89610a1cbe8193dc195991742ac08583b9c86f9d24a5b63241f8da4b476", "7ec70ca3a2fc695421810e24d119812218bb549b078d36d04c272ddf11255643"}, -{ "209000", "d54f4d0b5a8ce4ee97d0ef4cb455ac54b93b0092e177f1532e6513052439e9fd", "59a0a1d9ca71393c4e4271d8d1ea63d8f0fa6e8388c610fe4bfe8362dc0fb231", "af3eb79681d6c9ab82b6d4110b48ab5bfef942b0fed6354464db6cabe8526e2a"}, -{ "209500", "14e2bf16398fc52492652cc0ef3fd516eaffaf2cc3b7f89e37f3bce63d1117de", "d9a9a12a655ef80cc830f766200a05617bb235555e7cea98818bf103a3a6c1ab", "c5206760e03824d9bc3897c88f85dbbc62e0c26bf0b399cf3b0b0cc2556608b6"}, -{ "210000", "4e035fb68e9d78b953e76e14a90355fa127db686af2bed4bdb301fc3223c322a", "f6916044d1b6a16eb726cbd05a2e900f5b9f828625c850cccb699327c22037ba", "f1e000d5a2879e26b15937259b57891c59f50720888d76ee66ce7dabc3678231"}, -{ "210500", "e9ad24df7fe871c7a87de17e0c091b99a332b47903d8d39da2a18ccafe02dc1f", "f2cb48175161b22cf3369f59e67941f77675c6109590ad622a4bc476364043a4", "2733184c95cd78942b971fc16340175508f01259703aaeb2c8ab74624c1e7f50"}, -{ "211000", "21fc2c297b7bb7c088668fa502215ac26b2ded973796765acc4feaf2bff112a9", "e21b83547b49382c15c8fdb2929711d49eb8693d08c0738813df68c359fa2442", "204c7d0fe115c292647e70fa3f45212bb876f173885b51c402a6f47c9f6c7f3f"}, -{ "211500", "a83b2da994898b752271b844f26d88d300646e04c4e89786f24fb4c7397ce6fd", "4d8d8b7364ca603e61da4d09bc9c0b1dbc2373e65f5db2297828aec6395b5991", "2e8e7abf5d80dfb979a72d14b5636b2f43a03b732e81453167bdae994b5e0730"}, -{ "212000", "ab0f9dd7169c2b902f4762fce10983fe94e3c349353e189a510781244d66b77a", "3ba1a0d61a8b8a750cebf79f5c00362bf3c909f11725bc9e9762f21de08a7945", "8b45c656f9e0a66ef94b346f2692ad3cded09857bf55991d280dd9e27e614a38"}, -{ "212500", "b1fb4ee2f329a5664e6be5c85834dd79452b1f89551d599a70852bf49daec183", "d9143da167a6553a85f452745577ee6ef19fd21565b09ed5fa6cdc00a0f01a49", "dd2aa2786a23ab647fe5806dd1f2feb46461090b4149ede9295ff2dd62ab5120"}, -{ "213000", "dc4c87ea7c60026a65104a0d8a04e5540e3952df79a62e59deebfef6ae235e81", "8da8a14d3971436306dba00351d265f0bd06b1f59005f94336aea44880498b5d", "1373235a2734e53819e68a14b579b27f63ab5858c92e6b405cd990f30daad0ed"}, -{ "213500", "2466c2e233db8e30bce3d5ba87f694c3095fd391b6c38c2edf907a4f97d498eb", "c3f5734faaf87bcaa9be69122a144ad1f26009d8fce1f859a17c2fd4bc0c2c0c", "c6eacb28a16d84395e1f13d6ca6de8e3e7eded624e85739f23bc05cc917041a1"}, -{ "214000", "fa84d9bd1c6575cabfcec73e1834d129821b6a94d7814d15d038239cbc4a568e", "bd1413d32f7719df41ee9caf406a30c8b97e2f875efe7c9ab2fc56555136b5d5", "41e83363b59ad285cba7f5b42e9c845195bbf14e4cb3afee000fd51e3b03f790"}, -{ "214500", "556dbda0caa051476bf896fab40e8854a166c7bc416d5f3121fe1d312369dd0c", "4e5d7dafa56fbb04283e8c41e18697dac7beddc742d098bfb87d4df1fe90679a", "d3c7e3f958b443a227af7473a4776564e6f2820fc88db797469ce6824038ebe2"}, -{ "215000", "b7ccb76ed29ea49301f630ca5e9cf200ba7a9388156304636814ba6a6b417265", "8392386752e5ac61b9856b95e9c833b57fbbc5717e93f63e3944676202df04e0", "fe5fd65400df2fc764107ce9f33000c37d5e27cec021c2db43364c76d2d2d4d0"}, -{ "215500", "a56a071a789afd22ee4a9e4abcebd695a26ff824a895f5291ab639336d609bcf", "6dcf6a9b561236f8f627cd567d937ca4d7e6e9df72d466fcbcb505af9bf1ab11", "5db7fc42ca74a15514001d9781c8eb72833094b6967223e45135169f12928feb"}, -{ "216000", "0e1a9b2d055f2e7b637d9fdeb778c040967a8a2fbe0a38ee57bce4e8f4bb0a51", "c5532c221b5cba08f4ca281a247e98d28654b934c8595e57873232111c347ecd", "d7e521b1376e2ecfc6582d4164d57d89e61196fed40bafd33052cff69f65e101"}, -{ "216500", "9890c0ab7b427bfa46ae90fda04503f1b17a2493c7b36f12fccf0dc010d3f9da", "24ba34ff5619c38e4dc516e815af584f4c5ae6518a57918aedb59403a3b356de", "2b43b5a22e6fdaef8644a6113189ae7327dbf69e2b53c702bca1993bae8ba0c7"}, -{ "217000", "b282a7dbf2dfcfa4a46938422e557404ddcdf11509053fae49f5add5dd101d8c", "645bf6456c36a43bef5c217fd00b1e457ae136d52396e504db5ed9a97e406594", "80a8a9c2f44c33be9e641e56b5d9a5a154a2800a73bbab2a0580e214f37c7303"}, -{ "217500", "9539ac7cca0ca0524060e3fb6ee956d28ba115c7ae3f54d5927492d0a43eb49d", "21f680a60447675216989ea718c68c63361fab5615c683a7f047960d50ff8873", "05692be96ac1ea5432427408a51b86eac351cca847b10c46a7181fb2c46723d8"}, -{ "218000", "dd15ae9a3a001651303c757cdfa162b252b9aea2d1c4fcac645cfbc1d7dcbd7f", "78cd6e280ca819c264e6447e6cb93c616f0bd03547259a0f23ae38234e907dbd", "2516f646e05b15c638a1ff0ba0fbd35701cf22f4c2518d18f8791ecc77375632"}, -{ "218500", "6455bdb4441ac37e8f0d04b645fc033010698430944a873c2c097f7c0d3a02bf", "466f4eda729538e0604472f6c00c4f7398a28c9e59c89602716f611ed8731edc", "6e8ab1cd2afe546d81758f4dfd19312cf676fe1e7efe7423c127068f4f91a808"}, -{ "219000", "a8944486d2a12285430d1764ccfa03bfed013dbff38ff5fada97148b883db9f3", "5e8d4e1d9d6b8bcfdb3ca94ef5d0f8c75b9620b7bb5f360d8172e1becad9353e", "a1fca9e49edb1754773ebfdf2dec492f9d49d619d4d39f7591f7b8c0aeeefd48"}, -{ "219500", "adad89636c4dbae0dc680326d95d5a2bec6ffe7baf704f26889730681328b3e8", "d17aeaafa2e7a17d6aaabe48e88ffc53a8e61bca58de2e844fade3461f4931e1", "8fd8c2a561a09d2a686ec49ed898b43d4bae8383d938b2f7191d102f3c4109f3"}, -{ "220000", "69fc4cb8e3103151a20add15fcd55a9ee3c1f2cf78ed3bf9ddcd0692b78c2a71", "25cbfeac28f67981d5d011357c01ad82e097c0d09e77f0746fb11a93329c6958", "fe050048a14dd17565ae650de9a772e04dca5e2c7d53f16369633356b18a886b"}, -{ "220500", "fb7731f8712f081c1e9f446217bc1882d62d3db40bbe2711a25654e2e74c6cb0", "796240f85e38b57a751b19d648938d9f8f66cc8cd2e8611635832cec8d25179c", "b360d59819b84f71e3867a35356907474f67539eb4d1ec02911ef16bef70ec91"}, -{ "221000", "488df413aeead90e34c182fe75cd71227be759865df577cc6a4508cda9f13213", "bce1bde7cca72a43d9d80b03ea33c845799313914905c7800f7672654821a7a5", "3ce3b65c898cdac02127d69d28d38164fb235730ae6373487a6dfd3fd3b1a3c8"}, -{ "221500", "84d958c341c484ca8e85984cbdf5ea436fc1564c95baac52ec00e9f03d5dda3c", "c493d1eeb83f8dad5c17eec83e69277fc98e519c639d3c892faee2d6f80a5fe7", "e88c0947ba38c03fcd4661c33c9e2ffa10ada3a77746c6d28d99adcdf093ec46"}, -{ "222000", "24f8be00386b9a38f5507e77e72cea34598910fb8aeb57c5d7fd5b8b082b1d16", "77d77f3bc606ba0a8ac17dacf2d6d794bf655c58709a5e6affb1c2238149fe94", "9190732d87bb2140d12e5ccc17025a725480f5192563b58bb78993a5dc071631"}, -{ "222500", "c9db027d5a71c17a32dfd7694775edd913f829900532a36cc673168de4b41cd1", "c98ee6b634235506cd78e47c3c51ff7f20e2da5be5bc51c9269e0585a77f344a", "bc2e01c66f5e16c5166f33d813153626b5e29d2f72fd135ee38002638585302b"}, -{ "223000", "2491331dde706d72557719b2d51300a41185e0a231600a748cadf6d76cb97be2", "f464bf83372078d78b37b0aab9e98a697eb07bca9eb62d65919635d9a62c29f6", "16b0949606f4d837cf58811261026d3e7a014f716ce4b8775e94808c33fcb1a5"}, -{ "223500", "757897eb0ef5db6fac3a16b4167e73ac300fdf2126d175ddbfab527fe72e5cc6", "8033074e1db6b73e123b62aebd8983887d50385f70770bec207b628e9c945425", "ff9e7cd3fdafc513b0522c21678c4b6334872dd9c0487fdbbac6d8bd11b3e516"}, -{ "224000", "b07c519e796e7ca9ecf620e6437128ea8762b00f16ffb3f2ee2abd5973fc3b21", "eb8135fbce4a5f3d73713eb67416be84d02239e85bf87dccd22763075438c693", "ed89408882869163baecf310923d4ab5bb880d85741bfb2b4ce322c6b049bae8"}, -{ "224500", "4a873566e5cb9ef793cee37c09f7bc11668091934776eaf0cc5254cf8f565ebc", "9484bb580ed6e25fec7482b2f708ee463088b54ee3bf3a06ffe06a1892e70360", "ba459cb6f5e554cbff0c1fb05d217e2b67c53583b6ceb3f91f0885ed76af94d1"}, -{ "225000", "b4b671d3954ba70856a978c8c173096a9db7ba168c8815730cb445ed0b921f7c", "b16288a5f727839ad38a64139741eba8f93f33035d294365e841e714927ce5d6", "0a54bbd14b732d0e359a9d335dab210d8fe841f5f60246a688ea574a19b171cb"}, -{ "225500", "17279999d391f86406797119b105c9f5f6a02678f7c3d34d9f272c73dd77faf8", "d555247b00f10b1b9825a09d2692d22129b967e1ff244d1a60a756e7b2d9cefe", "d5fa227b78fcc9305f36c7e8ea6cf1c3f8af9cb61a697b5ec0658d2fea876edf"}, -{ "226000", "94d997cdf120719be0ea6a4eb198704a18baebdf13f65e28e51b49df7de1d861", "d3d5f6655db1fa41b2f916399ed5f36246ad98025f6943480fe15e43b0a8a034", "c5144eb0548d037485fff77b1bf83cb11fcae1177d23d5883c4b711ba0a6419f"}, -{ "226500", "dd41f722e300bee85cd30450c9fd08c3d4102b1095f88617c10b100556c5da49", "f43f89d4fabd9330fee3336ad9bf701601c33aad3abdd56eb6c164c21da1ff10", "28f53fc862f547a8ac2ba68d6dcd67af9c55ee7f78cff9da296f327da4ac711c"}, -{ "227000", "a0e48510962ea5a5f18c8d413b48688843e5cb36b8b74b5e61bf357b43334ec3", "0fcdb763c6a77599a872c5baa6fd1ddd761889eca1c53e882b616dbe40de391b", "ee39eb0234440a966c8d7908596539d233186b96d16cbfe4ba353d3c488fb68b"}, -{ "227500", "7f5337c81192ee64e2e1fd4da832f60ba2d89b0336e8e169423dd403d6f76a7d", "fdebb66099af9283e9c026e1e9a112a66af6e3bb0f657ef78392a9dad4768963", "1b8d657321389d19914e8807820f47f412ff10598ae38cc6968db8f07e897cfd"}, -{ "228000", "a8779b9ce01000a531f400c46d8930c487ad00315f0ec4ee8acfcbbd02ec9e7a", "e9b6fdc4d73e7910e18d95bf096bd5becac7b96a9989d60e564f1ac2480b1fcd", "ed4a46642d2b08d633609ef1e2b606235fabc7b6edde6ddd1b7efba80e24ba7f"}, -{ "228500", "074c0079bec868361a58eae22d107577538fcfcd531bd3b0516becef48d25083", "b0bb15325aa285bc0890e24b0892efb113246e6d785554e59022c0917ee4c35f", "6b0fd05325b08bc3e76624c3965df9639e65cd6a09836311d36ac958421a4b29"}, -{ "229000", "27c38d7adc92ec6c3b2e5c16ddea6cc06d25cf138ebd45a935953a357143cc68", "f916d1f8fef52c7532988bb984eea0f136d7c777fdbab72ca0011b4535c91e46", "f91af3f0774116fcdf41eb53e3daf292b151d5ca659b06138bce03949d7d0882"}, -{ "229500", "1010ad9db0dbaf647e510b73feb8352b927c1170dd09dfa15fa0f5b9735852fb", "7a7b2eb60a9dab15faf8e37370dfcbb6684a67faaf7ec1f50980694c26dc558f", "f2b26bdca9c6481cc63717041a580e912d81a566798355274a8c0fd318174bf1"}, -{ "230000", "e84c9aa480b0a7900f557d49afdc6273171bfea6e6adee45c3c2c7408c7a172b", "1f03b2bfbe709d7b411679979aaaf2eccfbf14b2a08aecb7139b191691acf77b", "d8a6802d515be3e56d7a00368b1b2621235aa970d5bd42bbe3bbc52610a88dfa"}, -{ "230500", "1cab5352d167b21bf28c9b3b0f8cc821eda60b32ce9f2f77de5737edbf28bcda", "8867625cb142e048d056cfcfe5627fb7ac7a20a83de0a9fc008bd4951ed7def7", "88e69682650794237dadf48c525a4ae488acd73f9f312672149a989a5e86d7bb"}, -{ "231000", "a7e7ae0369d5839690ba5cd0f83167cf68e6dc9c5604feddeb986b17cd35ae76", "4f7deab8e1ace7033b726836f01863f33677e4ecf1f8a488fb19b99630fd2176", "7b068f0bf62f019f82ecf753f56febf8161a14d3fd602ba2c1f3b652831a5d00"}, -{ "231500", "3bf6451daa832303c2242f195ad2ee1a205ca168fe132087ff899461f29dadfd", "6b87a643ce4a5cdee1f45ea3ee7fcb9b5df8452209970de76513c846c73ae7aa", "9fd201df310afe19da892c9a5ec244ad5670fef388f54872c972099a71d32de6"}, -{ "232000", "6e1ae43ba56524a6e2bda4d769f8ec8e99620690baed8d8d1764c3a42509af81", "eff179dfdb3a490f2038514a8ca3c65a1ce73c266f808378d767c60d1a8f9b16", "514c7d3a6f929542b5c61c3c2ae5f65273c5fa335c145688344bf30daa47ad12"}, -{ "232500", "95589eb200430bba2e6660842109cfceef9a90889ab8eef7091685dd052037d7", "2b8b93e3ab1fd3b12368ba3dcb7b087d84528932cd4fef51ae863dc40718df55", "3ce34edc74e8c7e402234d169c5ec387e02cd9fe9ca3701b06c1ad2a1c5dc65c"}, -{ "233000", "edef1536377488c20d7836daea81dc7b542347febfdb3b7f0e89ace9a9a2f980", "ef9ee2dc8e6eece115a4fa188288ac21117d58bf45921924db619655394ef4d5", "791945e15a74ac1375df1076c41b37634e1e812d6cefed1e9bf18299b177e1d9"}, -{ "233500", "7cef0816722fc26a5a131003a9df2d08cfb005d752a7211cf52c6c27acb735ae", "dc9115037b26543076cef7cfaa03c2839378b0cfcb8b164f883f2f73cfa95b11", "fc90108555e02fa1ab8434db732d30539708376211e5f2d4c7a751cce2302395"}, -{ "234000", "da363a034d807c2ec1aab013d8695631a0d24c50c34dc0db04286a1a53fd58ad", "ef5a49fea7936d6c151fb533277c19b7e2bb3e88e9351cec946bdce22c5ae5b6", "f2dcc08b2d9b7b39269b00c9a1ea2af3293a51a7b516308c7e8d28b88692b0b9"}, -{ "234500", "e35fd8c71da099b9f3f1d6017c9b799b6f150e553ef827f83f84b4d62ef723cc", "b469f833b3d307d9f12fdfcb7a9777aff2c37a2ccf713d2239275f39ccdac37a", "8b2a09ac35e35fc13ee005a727ef7284948370812e3a2fb1878a7b12e3139b69"}, -{ "235000", "903c98a140b5e8ce72a2571fc17c585544c4076e6d2b2efa8c58b635adcef6db", "5d048227793f68e79facf5538ee5980089562490688dd1f929fbfd459edc3263", "53708603f5ccc4ad229bcd619940e473bfcbe112d8663ee4de727ffc5b812f99"}, -{ "235500", "1e0c48356729ddb9196f9bc8cfff295e2205283e468534eb127eac2a8503612f", "152dff3242d0914c503c8ecdb376d1cec2426abc09cc99907b1f43b31dc197b3", "ba7df23159f8f78ce63125050842c5497c20bf9d746e5985ff964dd329ba29b2"}, -{ "236000", "48c76115fb5c845fb7e9b8d9bcbe2270755b054db11cd6ad6c2ad89152607576", "1420e404d7b541a053200034e94f9bdadd705dbfb57532c2a454b9b17c36cee9", "f38a89aee24a3a08e18b6f5dedb4cd567f646d7ed3aa06fddcfa4129e4983c58"}, -{ "236500", "76dbcbc51593c2ced3dad33d42a9f8c522f01a21383b227b0e6511c76363d782", "f432ef854ed6a03b4809d3ecd8a46def940a0d251d09484ef1b6bcc3271b0f17", "dcf2169bf1b7d2d68d675d63808d7fc41a7b3b8396365a32928a367def6f23c4"}, -{ "237000", "8c821cb30e183a3f5a3b28bff8b16d1606566e3836a2eb0d47f6c02af8d3f324", "b4bd12526051dd6ba2a2d616a95212c8ab4d6adc18ac21822a57738eb8284e2f", "feafff7676658b8dbd88abfc9f266df07564bd279c37ed6d9317c9264224feb5"}, -{ "237500", "ed4f21e0bf654339e17083701448309eff81e272b89e00fdabff166cdf812bbd", "9d03191f41bf9d7bfe65b5cea79e55f32c57765ed5909e11ef961fa56f3f69fa", "d5c2791447c14649d99a71a5f6213bd71efe8ac7d56cdaa7ebab49cac398868a"}, -{ "238000", "5af7f4d9b69ce00a56f5c7d89de2ffb0df0ae23520ff218ab2330ce4817ee326", "509f60bae30c0cb7666f7baf33fedb510f3364abccfd0881671650caceca4cf6", "765f7f7eec11f7f3be4461fa8c07e260ca15d5231f0df4106750101ffe2a4cf8"}, -{ "238500", "e95df9d3b7bae4323a4562627b9926d2a3f4c152e93513f0b57d83ec88ad8868", "9d0e160a8f87e36e9fc815538b27d8636daf94ae5c8701d323995054446ade18", "4bcfd021d9f54456bb843225a6d760252dc8a914aa0b71e7db8bbe57579168f2"}, -{ "239000", "17dd8f7338c85dbdbaf0d87bfa224d5fc13e58aa465cda17eed21ec1e5a13051", "61604321167ce51b0c2043524749d385b40cf729814d88e0394149298e1d612b", "31e49ef282416590d0ccd69ea1dc54cd191a8ad5aeb3d65be56c96262089be3f"}, -{ "239500", "d10a85ecd99d5fa8df9df4aaae9ff7b6360bf0f6c541fa6e1c8d743ba350d1b9", "085caebd6ae46fd58b66481d21579720316fca78552121f9252ff8fd5019257a", "a818e7b156f2b8a6b2b80481fb48ed123e8e037b15dff6d3f8756e4b8ab26866"}, -{ "240000", "dd21b880d234b770079e0478bddfc53646feba611a1858a82be2d68a5f70b5cd", "d0bdb4e68e287851256fe8cd8518ab06b2f8bdc30984ef27feb96cbf2625bd81", "eee895ab9a76886db1159344b4f0274145dfa8d3a875d42aee1df6c4d8c13d4e"}, -{ "240500", "4bb3da166c854ac97920a04fff729b2da619b130b3b257fba10f5be47354faed", "b7081936dea5f45ae555b58ad83d42234183f80123236a1474f1df92b289dbb3", "588912e750fca882ac5651cb56fe42bf2d3b39aa255e291940f2fb7b3477cb73"}, -{ "241000", "cad2acf8c8a9802e5c162170b2cb7112447b1b5bdf3184dfb6ffca5d5ca066f4", "50a13b720476b0d72efe8fedb30d6c24265a0cef374e1de14df89e3488fd3930", "db397f10c56a1c85f49cf2a3ad21119add4671fca5262d41168399675aaceff7"}, -{ "241500", "f89869f168fee009c6b743da990e96a296823c795da2fbece16346aff95cc0d1", "f1e24d47abbd5056f7d3fd322a882ef885585d877ebe23b86787fd8bfda5c03b", "158908caa9be532ba7cee05944c191206d13ae103310523dba267dae8f10759f"}, -{ "242000", "8cd2957d89f5937f87ecdc188f5ad6b275768752b873f36348fffde02bfcc4bc", "9e37495c487f19227aa0b4312458907ff749f668a3cd386d46318281e03497f2", "be9e5bbf9fec786bbe5de797be25ff3350587f8b9f6e2558a7a7ee39444fe74f"}, -{ "242500", "4d84991c165bcd35c6f24e4124e5b93678214af88c683ba82419330162070a43", "dbc9324659ca8a138b7f72edddffa009859cbdfe03dd397da0d897b40eb97efc", "b3769991128809cb16c4692fb4ddbe36638cffbf285b0d2576cfeb5a4f1e40fb"}, -{ "243000", "99f2ae7beed98478d52ce8a3e8106262d777e9220d54159cd29173f823002468", "f1af12a5aa6ba842b39e357a45bcdcf93c9f718992cc160e1849c693211642cd", "19f07cdc4b0a888a48f45c2eb9e9c0b9d7f41b2b20f76184199bb1d5509f298c"}, -{ "243500", "84b668ed1334a0f60f2b7cccd9a1bd05b758fcc1d3b6de13314b60b1ce8dd69c", "a02d27be36d8ff1a07ad35d80e1b2340c042bbfeb7ba7c0f4289eeb8b66ae117", "941e486598b5e0e2ccbc01ccbc2b353c73d9f62b9b65a7a6c19d0e0cd0661a1c"}, -{ "244000", "58ccb25106990e5eef0f7118707b96402f853599ec51917347012350230701ce", "989a5646dc6e9f91b27d9d3f3eee07de2267b5b62ca8c2e0faed6883f1d04e18", "9a1abf9c623f17a54724cd6dcccef464a48945860546783a0249155776ab6b15"}, -{ "244500", "60b50cdbc1be5d94c144f682c62cada4668154d94b909100baa392bd914fabfd", "15fe02c7705d1c3860305d80ae479410c94dbe8ed03f942dde09d3a3094163c5", "feded4a0f87382ea84f1f789e638864fecaeda1c5c16d83352595f9d2bcb68ef"}, -{ "245000", "538eb0feb39a02cb69f673a6707d23f80be40a922ef8fb43ddb1782d8bca83e3", "ca4b24d390ad10642d096a14bcf8fd51d7135681c9a750a80144b107ea02ce1a", "30b1817c8d6bb5d0217d147708649bd75ff6af32a8e17d81c562e17a4c8d0c53"}, -{ "245500", "8e7a40c1deab5dedd03f960399dd0a59ae92ed849f0288ed447307112a4679c4", "fe223451b524113b6d13c696681af1a1004e5be0fcd14dba4edf5d43f1b52894", "e0beb5d5705be0bc851ecffc517fffcccbeb2972a1784750e736219dbb346da4"}, -{ "246000", "e5410e4186cb320449ee28882d9f32cd3eeb79104f807651b8dfa0164ebbef82", "0a4203ec776383111ff8f9ff697c72bd8fe1203d55242790a9cd42086b2f6013", "38987dcd959005aa0638e7caf50d4ebe553edbd892c4854e8ff4a99d0ac90d60"}, -{ "246500", "0c2a1c0920dffa7e8a582bb47b121ac02167b2015deacd3cc2a4151419dd8dde", "1df603f77f223501d3036d16d2201004c712f86aed58cd0b3d89b32fdd1b2032", "4d5324138f4576ee887daa3f45e7b41eeee59b71fef399c69eecfe6170f8cf64"}, -{ "247000", "def0d291743461c8680127c4393f912663ea3e8105026bc76c315de3f7471a17", "830d9dfbf53d41d49c1a28631361db55fee2284001c16395ed3046f9a9278212", "5944d9c5fac27c3034bc271b35c16247ff7dd0a7b5fcb49a6079b4feff366942"}, -{ "247500", "41c85aad59b4ed9baa25743ed3b2205550292eb7e5e4dac974f0839053d0df75", "dbeb22eb94053b3bda3520ea239bf64c51d046da08951074dabeb73b06cce009", "2da981e79aa5ee1fbc27622b35ef4bb96249ba35ee4d219e7222a7bf489127c0"}, -{ "248000", "e34f803c19b9214d128703d584947a348459dcb0191cfd0a3928447747b7e3cf", "e58a6b50690ab0de2e1d7e5eaac39e60495e7f15c0e494797c49ff0a83e80d6f", "f139662f345cef60380f9b3e62c4923ebd53a286497e8f90ced8a3a03e948f8a"}, -{ "248500", "779f30864bc7a0eff2ff65a65af9ef49ed7125f708e923cff6a7a88d661c1688", "34ac76a53fca6d0daada5f7f12e339fddf5d654bc1ebe03267716822cbbd0514", "a0c941f4b2e5089e371c04426d84a1081972e00f6556b40ec401c4b02a66030e"}, -{ "249000", "46d582e130542ed696e49a52224757fbadbf61037d15182cbaee9d6895261d72", "7487aaf55ca988670dec71cb5386b80d8975446ba57feecaf64b3cc9c52a18e2", "178e37d57ce7da4f4b1925117cc97773475e24282737d91eacd043cf274266cc"}, -{ "249500", "87fdc18e9972ab01bd0f1c0314fe017d5b825b2a802da4da2be0c495e8a6c2fe", "364509f6a5c984e616212b9a328735397515d8392c612f774a55e8013b80f868", "faec158f0c1bc224e1b7f40a5e0d3c1302574d271e766b45b205c7f2d7da3f6d"}, -{ "250000", "f345e75ffd358b61924b0bf3fcf99156f97c1479a0b31c53713c219a38846b5f", "156b414c9c8d5782e5ff3c541bae9a14641338757b351f8cd7340d91ffe7c8ba", "f9fb2f646c22ff1d61f307af33c1e989499d9007340b70f191485b1a66aba30c"}, -{ "250500", "111446c3129d174c80978898f17b8c14c485a4c92396a8c2b15c76d7da4e4ee3", "67bc454190eebae6062bcfbd41b10f18161d777d0c7f1547d9c922fbe59301e3", "849f8ac1d68557adc798d5a31397749d9eb37ccc33b91d14d91fb0e6af078c02"}, -{ "251000", "a1d9e94171306fd7e28559cfdfc8be43a89ce142208f0b4a4319177bd6e1821c", "bb9e6ac2b06ece214228cab806b96fafd12d7fab5899ad4b8f6c57764c04b65a", "77d968ec31ab7d473525224abf9ff0361b4022ba8a4780cbd9695ca3954af307"}, -{ "251500", "011ed051ea80d7aa8c5631cc3f6c808582b7bae9533a47a1e9336280e244a66d", "5ab6d307a8215f078406e4ef5256e86f30683732743e4e102fca988e3e9bf157", "18c51804cd1c8ba5cb28eb6e3123525123e5eb7ce154a1e3ef1abecff63ab06d"}, -{ "252000", "0f60353af5fa6f614467ac0b793c0cbfb723b48353e45a163384288db9039860", "977d7256cf493f632575935a40240e3cbc08e8b82b9cb78666fdf4e17a80748f", "9b64c6052aea790947c3560f6a8bbf66c9f1e4838ba06cd9a9e65a8e5f7fa997"}, -{ "252500", "856aa75176f71b2613ce0655d8bbefc03739a2ea066d1a396f608d596de9214e", "6edcec572883a3e3e60b10a312a59c1e4486a0c4a73f5726b7b3cd1fa5ad8a8c", "08733b998bfba6bda0e903937f56042b4e19ef839cdcc67b6b052f863d8a422e"}, -{ "253000", "135cd797ea002f028f372b545ba294120d92fc0368996f3f0a4a2c3aff5e2178", "f6f35b4573ebff09a1d86085a7c5ad8f5154bc67cf6f1b821780ce3f39d845c7", "5ffd6a38fb26450294129d892604accf80e1a66cf02c5966a967d846dac8a11c"}, -{ "253500", "7e62b3ed039f164bd4b37eeacc05736f7160fbd8ab2a0ed7c8789817ba43f47d", "92fe7b5cfff4d6c5fa17c317ba47417e2841e65a9a985499f3ed0ebccb05993a", "6d4c21387cf0c1bd29f3c94c024f4f03dcfedb144593562fa918ff26a5d511eb"}, -{ "254000", "413a5fd20a447bae48dd74c04912c73ced49cb866c96a65aa447164084dc3723", "dbdf24cc5fe71f376465115ace1ebbfdb9382c6a47ffeca175f7b1d71d077109", "ae6fc5a32ea4fc5bff43651d04a34112f3cde947601cb41bf297bd907ffbdbaf"}, -{ "254500", "dae6ea70719a1798ef4cd7eea67fb84482f58695bbf68106fb1ffca714532549", "aa0bf86ce61e6a6801a133340c93e099d26f06c45ea6a7d0303866d59720cd45", "846cd8c100d89c35d8e0f031c7c78403170734a71f89b41b599e3204b5bff115"}, -{ "255000", "48686fa37b3f22077cadd219544c1d55015b613ec8c5a4c367b0e32a1d93f114", "8419590a10c931fc7b06e4f0c9cd66add2783839c03872569a4d84100fd3ec7f", "cbdd4929ef4806d80da65fad8800927305d763531614ef9b44009c1c9207fafe"}, -{ "255500", "3480ad9060e55cf444b9f63adf976cc48c8e68e9c5d9f2e173d30ee5e21f8e55", "22d1784cfffac5b2f3587152e60a93c18c3ba34d5872ac90a1bc249b98aa17ab", "fa4403617cb029fad549d6cf18eb128fde5f574647cb7fc0a105d1f6f868938e"}, -{ "256000", "773459b90dc0d860e1caf2eeb99f85410a17adcd86b9c7a91e282d7375f69b87", "dfe7baf5a19c7d41d0be344f1c0648ae6a720b5c9b50d1a1755908da38ca28bb", "ea9dcf13fcc782c2091ec7e84982fd2774e1e436cb2c4d33a3c12ba41fd3160a"}, -{ "256500", "5c5a4002c3f5675ed11fbe0d1640a0cf72150462b9f38f2b6fefa04e2d47e57f", "504eb85fa2d5bd399b16262f3ed52330fd25eff4396ce7ce96604c58c835314d", "e2cfce4f77ced79d5e0a61c0786b810f219329b32f52928bd4bb5192657c0116"}, -{ "257000", "f957080ceb81d1ff1a57fac8d99d89f92332198d332b82ed19f116bb2e4bb232", "2aa6db9a7e207b621656e249da6a29182bb6e77489137f185c4adc4b43c2063b", "95ccc92fe8b6bc201819f99cab1347b864098aa83aa68be978a6e31d19191da3"}, -{ "257500", "124667d3ac4e97b204a238e688229f21aac351bceaee670bc86b048aa25a326f", "0806775e04bc4c3536af5ee7c404d2d53e780775da20c269b0c52258be37dad0", "781b0b767484115002c26e4be6d2e903d49c472e9343e422ddfb3c11698619dd"}, -{ "258000", "281275e81b624913ab150bb6061bfc3d065c3b8e876c1c84c933d1340342804c", "f2a8c5a57fa4b177d510bd095fcdf765e7b4c08d8ded22f12c07e3fe85011df8", "8cb11b3cfeb5f2714c096137da42e4fad410aad3f856f28025b9ed2b261d9a3f"}, -{ "258500", "99b3f45ea656e722d919f59a89e1ef97e171f1422ef68fe6ea17e84496369d31", "4b30ebda14fbb69dc80d6219066b66d8716e2235595125113444f28e2e0e3ee0", "4c7cde3753cfa77c0d82c7d2d292a2f17a82256aadc556c814a029e707274c04"}, -{ "259000", "a3c8b1010cff2df85b748d06b4070653855a780fa89c1fea1df8af1b99e1f71f", "611c731a6c76c22ace3e93b064a4f73f2debf5f63d270a9a3a59a7a46544d6ba", "1cb253f4e69ad610219c674194d9471a78c4128ce6ce918d7830b68081906b87"}, -{ "259500", "6f80b9fc49fe6de69d6ca2ec1a783fb006b73c7e2fc0caac427088dc31d0b527", "d9ddfb40c125b781b7780845a78f6c90c2b887b8c28a0a930ccd6ce7020bfd3a", "ee8cc1c3f98c7f8f083ed4f4de0d6bfab57f3a3bb2b9f688289c66a24827b9db"}, -{ "260000", "d3f3a0df265b13c30fd6d529da8a8628c98144abee10ac66feb2d98972e52f54", "31ada4b62db504d84fed898117105427ae16309d45de494c4a266316f8225d25", "fd7360e574377c4adcb394b707e421e770688a6fe8bc08c3f3bbfe82e78d6182"}, -{ "260500", "10c9f1214c1a77cf5d4097d05a4ecc043d8db4dc9ed855892763104094e4a1f7", "273762c7e60334efe73f1325072dd8829130ace31287493f4028fa9c22c98619", "b82c870a9178e80f581b4f92c6cfa3a78d0729db64312afe731aeb3150504ae7"}, -{ "261000", "bed3ea15e53cd2a4b2f8d515efa665b1552ac7bcdd575048efb6bafa8b3d0f0d", "3fe66c2acc1cef4355c4ae83ecb34597060c44da2aa73f0a51618f4f6956a8e1", "f5b264177952358c8af607060f3f962564d985d79b111f967db973a5f71a933d"}, -{ "261500", "0e9b83d06669715a10a70adbd0a89d58a56a853be8c6b4e6fbd3894fb865c224", "992896ed5c5c7c262850a9d3f7b10ab729de8fc572190e0c08745ca9aa2a5433", "cbd1670a1e8fbc5c785ac30f2586d926bdd2f7991015c2d34257ab8abb55c299"}, -{ "262000", "61022120589859e23c0c4fa1f2650329f44feda0823bd30d597be34ed030c86a", "eec28d8aa336511816f17eb3cbff661e6fb35bdd9cc7a63e9ce830e7dc1261bf", "6cba28cd036be7ffece24c46d9a749b6623cbd7ab6f09e0ec4146e8ecb8d606f"}, -{ "262500", "957872933b3a7c22e527930d65220a77ebf04077130f18703f4d9eb8384edac4", "e267fc444b94c0c3e8312c063746af1e93887e4f9affb11d03d5728885b63cc6", "00b7841dd209bbebc1b00f9f36fcc7306cd43639a782bbc2cee0976a899eb42f"}, -{ "263000", "e06e647a254beaeea41f7d2cf9d88531c5193df8a75d4f1d8df403e1c2a24309", "5aa9aa86564cd18ec3e2dca55315b46958ed92e4ed8710e33ecf3da9b051107f", "1cdf59e22388e040a20293b6b4c72b2589bb5efcc3a0dcc4913bea664a475551"}, -{ "263500", "152388327d812eedfbbaf6f841061eb28be5ed87dc9453402355d8d06c64011a", "23552aaa4ce81d4ada113f198ba4c848defa3870f8093576be677c2e3c92c149", "80bcdeeba034170cfc2c2aa7d93fc60adf78cb65098e7dabc3496f1dce11b4cd"}, -{ "264000", "ce414cd76a86b1af60c778ff9e5b04c31464198d303c9f1d53126cfa930e706a", "2a3acad69f31b7b30208aab2b1bd15695cfaca2d8aa20bb2751afcb5755ac0c6", "49fda7e1acf5e17b38a618fcdd22e97de446ba8d276f3950bc9984b4951c44a4"}, -{ "264500", "d259e8637b4b48b373b6a1a7afcd89b1056e2adda59b819654f393e63ad2653b", "31bbff6e4910bae42fb446c184efe8191dac8d6a86156568daa369230b5198d3", "de1cbb25b85663124fcf585ba74b00c41ea23a87bb6384a515e0a08816ab6b42"}, -{ "265000", "ead49b3a388fe07616d1a8e8c391d50dffa01899a7444df60d4d2c40fd8afaca", "9fa60617a2f080f521628ef3d754f1706c464fb43a8282bd07ce2ed26994be5d", "421c20f2a014b14fe6c5ad01fb72e7469100e4d264bf9fe77258920c9fc35df5"}, -{ "265500", "6bacbbb516631a7922e9a988fcc5e102d6f58601085f09511601f4672a3fe316", "4a5b61cce54e08360b9b2e338f39f45ae427b2cc49034fb0f1e71948a7eb92be", "015b0e44b26ae7e3aaeac859facff0ba812e7ede3df26ff257b3ba515bd04da4"}, -{ "266000", "b6993a4fddf6404fe544fddf2df238c999366b43e7a335b81b4524f9aed32999", "91407232bbaf55fa658262dd6269b1ec6c620eefab326e556434fa1d0d64cd95", "bda05714512e418de85a00f6a90dd00e63f5d0f88fd95f96c02d692a9439c4fd"}, -{ "266500", "a22adcd41d7ee4df6deb8633f53d381e9826dfbc7709e68b7b1ad5d71e8898f6", "314feaaf908e8a8046ab6eba7cbe3c97aa478b2ad93c39aee7df9f5a72955db4", "3cb8a12a98cda65e6dea78e1e5be078c3634bf5b8ab03b3b6ab7b66b30b9fe59"}, -{ "267000", "d270af2ee0a98e7e407e39d50cf4cd22005faa34480d638e7a6b7c10b8d59e4f", "024ad7c62e3a9ab757d4905bba29fccf5ef435e4471fbed49ef50f6f9bd1075b", "8f092d967cb25c5b745c65302fdf334662797e5ae57f62f19c527f5cf05ae1e4"}, -{ "267500", "1fa94c5777a0fb5f2c0b89389d3b537d5d6465bfd432810fc173dfed7a666c36", "b4e5805d093717d9c5d8766b1ccbf2791eb10118c9fb51898f0c49273c3ace31", "7620763c114241b5f75c35dc6675896a50037818e08d594bfe490d6f2656eb09"}, -{ "268000", "ef3af0dbba05b3633b87348bfa9492b90d0c500f8427c2f83e485ddb4e326b7f", "ea130ea23e47338355b0336648892d7c09251bcc9df307a7f587d7a425d2a741", "339197172403a19a3eb4efd95b1e39d141177fa0df817add3b9310dcdce7d715"}, -{ "268500", "f7d6e8a528849da7d14e07869feea84c406697ae7a16ccac0ef890aac5fcf4eb", "489c417d04b8a41f630bca15696e7a05ce36d4d216c04b1a6560db25e03e3cdd", "22291189be339d88d7200e09e4348ee5157cc2637368de6c14d0c902d80cc94c"}, -{ "269000", "0237cc909ecc6a560183034f478c44d9f9fc96d5a0369b89d5f9510676274123", "e84c666b3a8122ccb250bef7b603c2afde722fd985aa36be484e76368f13f10c", "0b2fc53dcc0fb9840bea67516680b5eae925125aa21fa4ffbf5d9c7d9e955e93"}, -{ "269500", "d342e101fa8308700ee1a663fd05b05da014141725d0b3655a3f0fb15da83771", "93daf70fc7af5e7fb37d973246c434cc834a37a1fc69fb522f9ea5b82ed2bb2d", "b144b04a09760b2cb65ac9142ca3ee6a1ba87d505dbfaa34f258f8dea0ad26bf"}, -{ "270000", "83e4f6c8831be3fa7b6b6a0aa13805ae107ebe64f496be123a4ed9711cd69065", "ef10852638bcb24c4341161935a116bf5b764ed34380ee55243a35c938fef7fe", "836224c011a17009dea9d2ce9842cb7d19c1b837eb26f57aabb14a786f198ff2"}, -{ "270500", "557c88f51ceba0d2dcf7bffe8ee8cb308f8fb2f14998db8b6c23764d00d756eb", "ed1e1382a827b3dbee6c583053acc263ef365697a9325d3ab3bb60f80621b66f", "c2da9b6c6ffde7b4040c2d4ef1a06465e07e6220b140b6c04d4e85259af35b16"}, -{ "271000", "8cf965660be26838d4edfc4ee6c9e3f700c5074a0537edf09d19fa8b25f9297f", "f717dc6ecf1404858433dea8353cae36a181baec3c8ab3fb0c8eaf17e76f2f46", "3c1e09a5c48938b029d8232814e48f169f693f208d8d251c3b7d6d78f531a09a"}, -{ "271500", "940439c29f8259ebd1f7a7a76f9cb7c34981795365d06cef15b272ceafddb513", "e013f425e7b9e0c919d3a8a6e584fda18d798f64cd32003c79d1b9acffe92f8b", "8f104372f8900d6abdbea8e173ebe003f60baef8214a067c4c037f0e599612bc"}, -{ "272000", "6aa33a0d087f0a56f911acfa99469611ce6a9fc336e2ef2ede07c854c0ac34aa", "34612581d8665965d653cd9736459b2708141168a297c9eda4c73e64ee4b3511", "d065b6b1de7d2ed8f8190bb76d73f699f56b67f7bac3ba3fffa313b0368eb791"}, -{ "272500", "e165b1f323ea11ebff46a9365e5c15c736a639c87e0e7866a790c212398fab51", "6e2b03ecf9ce016d375afd28e4895a3905c5e79e64a451f4b5863d6f8ad37c15", "54bc63721296bf1f6f2990f9364f8991089b183b646e0ddbca6c1b31451b11fd"}, -{ "273000", "7e8e42c625a39262e7cd8ba81d6042788c5685fb7e1925556bb81d87f23fc9fc", "60337941f27f0191f55253642397b4141c09a3796a2e8c972154c90847a04adc", "f65c9be70852523b31c7a92f95821f306e9017297e04d39cbfc4c8dc3ac0678e"}, -{ "273500", "50d2fab64d92e6bd34396a65ea083c254392b73b806c9c23d10a64fa2046ef63", "def5f3f2d73ebc5c90d4a3e5e8100e51e3144b63d3de0fed9a6393ba3138f62b", "62b9175a2c605119fc599836a2a00fde40a976be16043bf98c0773318e8ad14c"}, -{ "274000", "86afbaf7b386a0a5ca9199f42849ba58e03c52c3e14e4796be5a47bca65c3e56", "9fa018f6e78596557adb6a6294c3ed8c02e5b07835258d38d00714b662cb88ad", "dffa1e76e920169f88dd0892436e3dfb2a3a6daa1ec42287913d5b758ce918e8"}, -{ "274500", "f4a2f13cdd599a02991bab088d21e7d28d907caab124755cda5b5da1a0ac3514", "3e9121bbd05409156a601f33892ebc88a1d832d59180e591e571cb8bb16d0233", "77b22ea80e05caf4ff54cc45a88682693fb8d94f28c18084ec8f8d5774ea4a79"}, -{ "275000", "a655f397a1362429e51239e663aca0a3582f4a984001c6093e48c4e0a2e05941", "c3a045ee8c5239615793c006587052cce7d63cc81c2ecb2af75e67f3c53a8ab2", "380849376c9a323fb3a9bc59969eac627adda0498cc3f60c6c8979be719e29e1"}, -{ "275500", "b3b6e311d0f5bd738f2502c2684af690e0f71c2a4c55afd5661d069e604ef3fa", "0690d029ffaee874f0407d12906116c79bba67f9b8378a31334b25483daadf3f", "a930052ad595d7b8a70e71c48aaffda01d38e459df8e0c1887b07799cca6bc5e"}, -{ "276000", "f24a85fcd91ad6a82056c8a76c2d3d5d04070ffd7d9b84a94ad0d6b8acc0c187", "5c21716aa2a15d63d306717b47e86748fb203faeb1c6b19d63a5349176e9fa06", "50e49772aa15a6a72eb61487d735b18f15f493cb29145911cadc97c1b684bef5"}, -{ "276500", "787f090210f18af487a5a4f9f284f1d3314fafddfdee64723d3237f55d7597b7", "3fafdf028ccf9b4ccc043ab7159a37ec9740b5cb34847a6ef427e117ed86f206", "b1b6faf4dc475c27eca39833e9e90e8608609b31ab38600710c7e3ff30242b19"}, -{ "277000", "b431470e16022c9e3e58e772bc8db6482f309cfb72a197a773b67ee7ffcdb756", "894962f8fdc8091b4f15d60a3ea4de232e7921227ec9092e4674338c6d0907d0", "e5e101d2a2f32a1dc051af8913cb1d611024910988c45848f9b079d9621f45d1"}, -{ "277500", "d4f3d44e493b537d6f5a6e63e315dcf5031240fbe6b6ac65a76eb8c35f5db13d", "fed8c64ebc096321c5b99ff1d5d424c213c3e75d13375645f37dc5aa807eb57d", "bc8767da1df224712512ff57acc5f836153fcf3d33af4a488783c172c9a3a4d5"}, -{ "278000", "4f76c78fc8d544c1e8a0d0429f7dac32c9f0857f906944503c80f58d809d25a4", "eeb4b5d853e4a976e994c9e129bad662bd03d8f2c7e78fe68bdbd47c28480ba2", "caf3543690b2c0033cadcdd0e989231ec6ab6008140bab3d401030009eec98b8"}, -{ "278500", "494b9880d486e1151d466eb73004b3f226ea90b6127a4aef1b3a90edffd4d0ca", "d9b63101013dfd8dac4895a0d5ece4c62702aad7cdb81a6b186e530df840996f", "18fc3d39d5ca9b8910aa153e2e32be9cbe36ba2d0cd789fd94e9676ade8d8be9"}, -{ "279000", "8722865896dd4d2351ef4e4def382a2e622b1e46ad54b3940a16f5073bb1d844", "2ee3816538cef7b1d029887af7e39d60cc1e336036fdbf089439f38cf13ebcef", "0a761847f3ea4261128d81a5b9f6d84c6f443b36e93d8830d6fea779264945eb"}, -{ "279500", "3423afaedb970d2a590a0f3e023906bef4110f1389bdf54e2c4620c36b72a3ef", "3e7446b32ace025408872375b1f3111075f305cc83f615ff2c6133e49ac96d88", "70e66af4ab3048775db66647a98a51d42511441e864a3072111bb46e10c305bd"}, -{ "280000", "9cb8d7f3caee172f2a7b8b8c2bab3fd01326468f8b5932bb88921e06167a0e31", "468c01acf084fd4986b21d1c0e1defef6a874a01b0ec21be66098d53fc4244c7", "6d0f0593c36f3b294d32c15b7e79002e2f15d8781ddf9781e59bf6f868da084c"}, -{ "280500", "6cdf47d170a6a5e57f6a9cfef7f2239d4f15a61d5c37f5b44a72188aeabd541a", "dc58435982155aaba2de5c124a9f441a90a575c9cda3f071fc9c4a3c9db61c8c", "2d49762f68d9f46ae49e6589818814e5fdc346b8e23ee41bae3595ab2a88f7ee"}, -{ "281000", "3228123dd268365939c7fd5d9ea6a151b6a95825ee1a49b9fbf3ab9f3ea45508", "9320e6e8aef527e622e610ab13eddcf82598b3f2b744f6e90727ebbad920c080", "e9a2293b4c692741422e626e36d5a0608e04ae7a39a0d69aac2d95e95c783460"}, -{ "281500", "a35ba852d6be87b2a614ceece176b04152feb39a95e52e641e7da7c1fcfd220a", "547cc277e5a3fe410e5265d8622bf0ce0f722c39c23b3274458f7f99e68f0ef0", "ed34358e2dcd89d40b2b86b619603a413876b29ed1cf8c9407c5817ef8add859"}, -{ "282000", "2533068b9c436719d1eadc4bd7e3e805ebd949d57e75cf5e0b17321d109a9a10", "1ee93f862e7504974feb14b488a590aa9221ebf331beae0786bebbc013278457", "2cbcfcf0cb47425beadf191db745e5664af5d6e8a59a6da8087c260c28a03df3"}, -{ "282500", "47262c1b2c424270254ebc4ad32694e51ff4c09d8c8da9e944b17ca3bc734e1b", "f940a70f96d1369af5b0318ee86f9902bd122036ace273643a8aa0ae7878764a", "b7c219d4d68bd82bc079b6eadb8205c9f3a4f9878dd3fb4e593d6e1ab39b91df"}, -{ "283000", "bbaa0da5024d6e74becb1d0d62b2aa4a8ce1c3bcfe27c587d3c89b581f22b893", "b8f67f07d3e46ae0436cdbe91a4eac1ffd8a8de111cab322c4895423393be210", "d3774c417554f65595146416dc39836999e63d5d4a7b617554d651ad839a6810"}, -{ "283500", "008c22a6e8d0b46e6c785736f6098de9ac43d5d1964b2103ab383498623a53d1", "77b3fa5d6f930d2da8b1171725e9f6e7ac340b88637955083de8a55a0d129b70", "5a762918736f2d6090e47bfc68f71005c8da87518f1a60cd7163c01a7e70d05c"}, -{ "284000", "6273a37ce3e5fe2c58d6b1bbc1f31822f9e1f78e434d62c9aedf2c6c18faddb7", "0e5422505c2be9b93d74f39ddb43b8f2a6cebccdad41d3e631e56a5c075622ea", "f8daf28977a24e392a7550087803586900d30f35b34bca786992c85c89b6c2be"}, -{ "284500", "6dd5efb7d0636ca3212a14ec60bdb9940d355e75c4c3890958c2120c4e0e92e0", "8adad9dc3bad71a55635afc41505883ae38fe99f3c96f021137e049a1b829a55", "bfa9f23723426ae1b670779900fd77b957248dd1005f0677a51329ffd15b6a3c"}, -{ "285000", "7d49941cc51ef16e04919b3dc5c5ec87b62e98267f173202167ee9a359d8a5b8", "d947bdd3999caf548887208f2049fe528335634f5762d6882d4075dbbc6c6b1a", "12d4187421eb70562d96f5a73261abb5c5d75bc8c3fd7baf5e4707ffc76eb470"}, -{ "285500", "c06cb12bcc248f8a0c2e764e2c160d85ca356ba7235faa143eecf42f7ac2f7b8", "7ef16bd0db693d3ebd90f3e9152a8cc1c420a3c57dbb6bf02a86cfb3b1d19dd9", "b30a3f94cff5b1bb3f8a6c7fdb4aecc6a36260b71670214078600b6356aa1127"}, -{ "286000", "45583c3f15ca70ada0a0c38923bf9a7c63a82d7be1a05dd2d3d098fa6040b522", "d497cde577489bcf9ea8e08eec093ae16e80f5c58ea09344c27bf55b98fe3fd9", "7ceb57dc1b782604406fc32b6219e84e88bd52e12e404b2cf064eae6226826e6"}, -{ "286500", "94f13e245e46c93614627914bf086bde72751bbc3f88b35877d73bc28bd4a7b7", "83245d666cc2a32058839f630baf72c0d96977e7aa4fc400f58e75f2f9ecf78f", "6b4d11e78c15ccf29d5162656a219cfc84bba07dddb0af95e7e14051700022d4"}, -{ "287000", "eda15ec5157413f65856008baef31e5d124c511a95716b1f6b7364f5e3b5e75a", "5ac1908f2739c718feb04686b434dfa4e7ddfd5213d9977137354ecfdf5eca28", "ff3f1fb5580aa6c748374c95e371375edd5402d81f092c2f3f7f99ed01050594"}, -{ "287500", "9f7a944ae0a5d2caa33f72042e674d47334445b2f47ac89da38e29357301a060", "b7fca600d7445e8470e57c18e2eadaf73aae7abe888acdfba5d458197ecc1e6e", "929c0c6c37a26aa97b8256619da4a06437cd8d9bbee1fffb21b2f821ba40f626"}, -{ "288000", "0853047a1ac1adb0d95427898e88464c078405fa22ec5def178eb5de7ad31e02", "a3369699142afb6a7da295ca36953c883d67a31d3096d158486b578a6a585fae", "4edf3fac88f835729201fde959ef538f8b9f6201cf20427862755677dda1bd30"}, -{ "288500", "eab408ff9eb88ad56e302df11a2513c1dd7873311632911cfdfce5ad4f814066", "4f39359784cfd3619082b590cfdef0d6978434ad01885e66ea50f2d96abb2674", "4d88e8cfd4f195cdac4908f10c06ec9c7409ace62bb2b765beb593f6db52c99d"}, -{ "289000", "1eacafb1bff01bc0489b29ebc39bf137d040e6641170ce3dd89ff6ba59abf97e", "c8d5fe21e49f66adbcfa0c7d71ddbd5bfd2210554315f1142656f3802fb9de86", "95d1e5142422e26d394a2aaae4e79d7a5e6075b1207540599527e424d3fd9025"}, -{ "289500", "887dd7480f6c7ac0983d66c8af20fde72fd415dc9341eb28e1c017cc0ca046fc", "64cc676cdff6225d910a798088789b311dd78932e090292f289b965e35812bfa", "6a410a3735e9b9d42e2ad8024477d603f11e3bd9a1422ca3392bc99aaee715e2"}, -{ "290000", "d537cc92d4d860c7d1e74c77d63543d1ee28bfccfb33a3798b8fe4ee6aad5fae", "b1422ca72d6adfc0c8ac92b75dd68b19615bf27ce351c07dc461e4a483a01d36", "6e13f50e1bda168ba72506ec99a6481aeeb6c6a4e934b24c57ed41f95c4ce8bd"}, -{ "290500", "1f72a0f641f0e7c0a14ae8aa3a90a93130a302bc82616e7df2eac6cc893f8826", "7cfd6bdf925165f98609e9ac990d9c91cb484a1b0c4f26181f519180b2cd0ad1", "aedfc88bc4fea62174ad9c47b4da51e0bb89cd0d2977932943422d5a4cb51827"}, -{ "291000", "045c570b2414764749905e61329694b5feda76d2656dc07c208e0f163e8d8be6", "ff11ec49560b7c1264cc610daaf95d5bb7f581edf89568fefcc83bbef13b5835", "ee75c4c5048c7b58b1f03fe95b73e6c4deb422b079c13ee331c62054d729c3ce"}, -{ "291500", "fd55aa9e9dcba1752e4c20055a1c9b6ac46a21a3a932f059ee574f49b721f507", "3575b8d9556832ef3d4d929787f0ffcb147cb349499026edc50e4be282b15863", "329c508a52886135ea917a7ac4175d57ba7fc8fa928b6d9d453f10b1d1213637"}, -{ "292000", "37273300cca125ee3ecca17ef0b26cc7880ad9b6caf876a4eb5f248743433519", "9e2e93489d99a34477c9e7e60d7a971b7e7a14f2b1d1af1d797d95c945c26d08", "3aff06b73f04c09346166ee039067088d9f424f3b1ce7c34296e7e5424ea201e"}, -{ "292500", "c6d6356e96458404221b2fde26482fa42559dfd1caab1b600f045d8f6a2302cc", "5fd0c22eecda0a4ec51190a6356fcedb96e3d4662a03d1c231575dca131b801c", "5b5478d4a6d58150d08ba008d03b0eec8e78fc46cc198d43a2d962b0ac19d5dc"}, -{ "293000", "d3cadc149d4b135ec11e9b97cd25d6e1caac6560b16c0d53a798fdc191519682", "e8fb2e323adbb30a6ac4a40239c68d2377e9c8fc2094901d694e0957b9815cb0", "54527162bbf644ad5504de900d11b3393cfb533aac73038b6652a5152ff977de"}, -{ "293500", "a0ebf3b0b17cd3dfce121b5a4466c2a60a9ce0169c79aa070efbab912bc0bdd0", "c9da3ed914a818f8973e44fc8a4d450e68d775dac064b9baed30d71db09323e2", "3115f86a9da7e78d766c7945f8482567b9f9e23e7825e1f3a07c5a39dbb94c40"}, -{ "294000", "492dad282770f45e70bc4cccb1ff2d69568a4d761395515f41d53d0d703db481", "7c090581b9e3e74b2ae80d821555b83a563442f01ec32994b87b8794c8a94dfe", "5e369901a873b8417c9a5f998f055a33bf962f6fe0dc054c4f3e421e23c75d08"}, -{ "294500", "8923473c7806f6175ad2be0cc98c4066e69dd2acf8e7f965fdcefadbcdcbc930", "689e66a64c3f66de762b38b5cb0593b6c0f076c84a04823cb1f927f5d6601c12", "b64cdfd0ce81f7511e0efd94ee32e02252280ffb38612fc41fbb09cfbe65b4bf"}, -{ "295000", "3d5870c04b03d0cfb60c9d47169b81aa5c669fcbfffc602ae51b930391d06f7a", "34ef893941a5215eccb47786b0d108e5150cee56d691cd6d54280afa5ce5e85a", "9a909a02091159a4c6977ee981a8386a935a1b5d6f2bbba1192f675a3a6ec7f2"}, -{ "295500", "96c1ad430e0ca606b9da9929ea3e6644ba7d42c02371abd5d1a1ae099654192b", "8e03c6f39a7dc904f768bb459ba01c623791992208f124c37bc679e61a49fbe5", "65530d71db0ac3f29161ca58977a9a9cf8ee3383924203208a0f85ff60567956"}, -{ "296000", "6407e9c420afe4be97d10102c8cfc0d7f5ebaac40f6d5e678cac8144f007fff0", "d19593e2ea6bc1c13a6a3269bc9d7c6ff918f0a01dcc61daac670b37d2d80347", "f6e6fdccfbd9394a5b8261e3a23f91e9f68a08a442e39ac4d0c7d971dbee8e04"}, -{ "296500", "1f8d31ccc299f2c5b05e93383d8926862fbc09ca5b01085b3a1dd82d5d495d8b", "31fe78d77df28d71d73858589dd74fd5362642fafc9c8d29ba137126bfc0fbc3", "3fea4ab883e22a92a3040592c7202c45fdcf6abb271e0ef2f5bca2c337b6dafe"}, -{ "297000", "9cfe512e43f2cd52ff58f90464a04f076dfd0d12d59cdeb100818f109a9003e4", "5e47ee43df09cc31576cd9b0440c619a16298d39ab9264f639b5b9c86f8af572", "8c0565ebc2d8ba4bea6fb9ff082542adf2656fba21fb1fb9a237ba73c92bd8fc"}, -{ "297500", "95a02da1b06b1593ea08b020b4bafdc67f5e176dde40de7a1feda249571e53ac", "43777410c9686e5c56891eb7eb0c37f2110b339e5eefb75da0bb28b78f3072c9", "90995b05bea1c26dfe6edebf055eac9d8d67d5bb99a25b45a7c70c86ec6b578a"}, -{ "298000", "0d802cbe03a4b85c23624a03bb35290b461d8d9dcffa128de936649b7007f622", "b5b3a839917d03e52ba179edc51c12fe47a6dd9a5c57d678299387299219d164", "dbdf55e36a6b24cc6ee06dc1de48c38df924a62fd30b08e60f01d04e41f625b0"}, -{ "298500", "7e4e639258fe47ffca25a4b7bc7b908cdff41c7e1a737abfd45fdea1ba62ec12", "a8c88f6180fdb40fc4524197c5eb32ab9bfda23b88c4eda4a422994710030d1c", "754859875fbead5f6bc020587b66511c9e853cd9ff27a8940b600584870a4617"}, -{ "299000", "d2980e238042ab1ee113dedd25dd97fde37f474e6ea666efc83ad169c7ac4cb6", "5f89ed52f8866c340657985291ef23e18eb47e0631407dadde650801b632c010", "78ecdb589efc3612834eaf00b8407fe1e5aa47f4b361a358b11fc686246b8266"}, -{ "299500", "a3f56b859e1362c88c4ff21ad8cf5c799c2ae565f46f15bcbd275e7cb0fbef1d", "2a189688c70b29e449f6b3bc93fe61d4b2eef5af756039f90fd745b47bd74403", "977e42fb9f0b3caf99b4caab3ebf3b593771f749c528a8da32d80ba48171d917"}, -{ "300000", "5a2452a4745eaa9cd3c1c42b7e4482193c4f7c3324ef185a4d0a403d2002c0a2", "0276aa15dc1d6f0d96dde0520e357fb5ca4d8469115a894dd76e4a34d79b792d", "f945fad38baa507bf58a84d4fd333200b32de4b3ef2d6f6e872eee58f4e2ebfa"}, -{ "300500", "d02571cc76f7cdccf536b836770aa02a0d238cde89f23f767fde8e62e2648735", "25fc046b62a57b71347be8c33dbe9d201af1efecf98e973b35294f32b745fe25", "b3eb3b176561653fcd519c66bf5cbb766e46270b125d23a8629850293ad8ae46"}, -{ "301000", "b8ef5fe2861b8750589ed344c9d8edc7ebb9630dac0ec507ce09bdd532af32b3", "bdd32f8faa1bebe0c4d250a309d8e983c5444f63b8748eef76470b980c2542c1", "eeca0264e569685a79cdc0cecf89d2cf3dad1571d8be44e511e6ef8c70698744"}, -{ "301500", "573f412e4b6a3a7cd2506df938810bee7029b9af102e096e83861eb3b29647a4", "e8fb5de4c13ef24efd099f7808c0952e287aa23d51a96d37ca919c3fe08b9685", "5b71da4b99e34534688a2189be42fa184431d1c7a65728b60736be85807fb972"}, -{ "302000", "18b4cdc5a75c82496545009007b5f488aaef67892f6886bb36ec2526f02a5501", "c8898b9f003e3a651e963ce212412e35d3d825ad2170cbd1cc56bcb1f7a0c4e4", "c2d335c48e85d4b2b4ce1d1e01016e53cc515e252dbd262a78a970248cb021b3"}, -{ "302500", "ca57a75391cd670c7e1ed0fde565c1c15d67ac4fadddf92549874fefc3a51c74", "08a7221ce567158af54cd9ebb89e6cde68430c185f6ae18f1c4d7001970f0dad", "9052843ea255f0c302eecff974f8d6abc74280a6f283d93b2253fde0a56460e3"}, -{ "303000", "e6dcb8971d8b0e379173bec442b5e465d02e700b30a79598de9be17a5497cb89", "41c38012157119f65a5404f0e62a7656673f033eb64e8cf4275bc81aa4d88805", "96e6876e63aacea65a02d3ff472db7a6cb2a36595f0a964b0e44de222e03768a"}, -{ "303500", "e737b5b4805e4740cc8c50d60ce3769621294b1d20ea8b1bd3f3757c2a37e1b9", "b5aba92d8014d56fa32993c21c908b42330c6ca382631f57162cc63aa1b842a9", "7eb1f7d3e3a4a67f7d206ac431fadbf392a28d05179d9c89bf8670568b265a7a"}, -{ "304000", "9e5aa8da5821d8594bd9ed376f69dc851e5a7e0b4cdd755c6394f0eaf76d0e9d", "225f9b063c89eac0ee1e3136e644cba4f65fbb475fc5a0e2c1fb66270f6f13fe", "57088e40e0af0d94498c02f9a08890126063e2a75340a6c47efb79fcff0a092e"}, -{ "304500", "45a43ebbca6f1cd31a03e301398c2e9e9d15f1bf91db745a7417b4d8f25ac394", "4246e0afd88d5225b8ed8642d8337681f42952d0df01a71aa94d268790755cf5", "10ec6bcf6be4136829f4f735ffa2b6ecf32cf58b509032f99a84f45917a4e002"}, -{ "305000", "153be3e755e4953c3810e08165407725c11fbf92665616c708bd3b824e973cfd", "aa39085be20fd4450a1a03bab45c09f669a0a50d84219505b7077c0bccdde28d", "2c2a42b022dc3f6814ce6df5667be0c2b2b2319c726008f1913f5ead0ce913c4"}, -{ "305500", "c488fbfd55f3fc873ca49d57111f71aaf5a42c4bbdd720c0d96a5dc66eeb6736", "546e53c9ec8cab56e41df87aa26122e2cab4077646b800b63134a712a1e3d543", "18a0bed423ccc6bdd266dc57f917e1e8ce9476f7a4edd39832451d6b5621ef98"}, -{ "306000", "83982570d251358e02e1b359a0d95b96b9f64f3736dd823654d47da633d48708", "6a861e2b1c87c8002bf0794ea718b6be98b4d77ffa95a22a3decf18aa985bb25", "1e58e6045bf77bc6a9d9b0151d0528c50ebdff775080472e225ecb3429351454"}, -{ "306500", "96485ddc1d2d81f38a752fcf1ed3d7b734197c472e8ccfb0eb4ce3101a473394", "068dc5f5f5064a475c7c84960a192433e9bf18098d581f0877066c60ff0a8861", "9f58c14bb3a4c813730ef2a4eaf4606c6d6688519dc2831e17dd9bd30999e353"}, -{ "307000", "0d209df0e3d2879d8a0f356f7d4041d6e0825ed0b33011d5c8db9bb1ec0c7d42", "1f41650a79db8f7bfe188f47b7f1bb293ad4f178ad4cbea99d8f87876b68ce91", "f81ad79a2c76005588bdce6f0067b4c4b646a4ab66ddbbc1b9c9d0c9f0a55483"}, -{ "307500", "aad6c7f578667b9527223b8e4785e9a6739169528d9b0bb741119f224e0125a3", "d56e00856dd907339c3959733761bf3d2ed206bdad2bbf9d49e8ce6cec4be663", "a376a5fce9cea256226a714a82cb0d71e7e1773cace180dee21e8cc96a4cd9e6"}, -{ "308000", "1a02c273d30fd2bdfd3c0391715a78f6223c944db913c846927b8a20289ea527", "232e616645960a14c845a721665ccbffe5a70408ac38dc2f9d53e306c40287e6", "3b07c2f02ba7fc2380635d9940e457db2f4f3cfd0c023e997110c74366698a98"}, -{ "308500", "b5f04f2fd81500e1f7d817b94c566b97c38cddb21041bc5ad38757a1d11c3a74", "5596842f2ec00ea253eb5a0a5565d21e871a511caf4a40f7e559d089ac67ae08", "546d23c82d0cc5671004032e63646240364929fff8f455146650de9ed4bf4283"}, -{ "309000", "ec31bf5b86d611359ba7818f0926b3314c13e7fc6be4771e78aa66c65f308e1b", "19be4c08d59662682dcf27d7cea164915e94d1ff761f8321d6302d7de2bafdc4", "f4f65a7dc7e658ae2336e13df29e9f5897544a9e4524c675df9d990460996c20"}, -{ "309500", "a40c3dc8a06147b339366c16bc1a21d4841ffffb9721f952276c35f6ebb0fc67", "161fbd3c4ba1d443606832471979959ac0281462f897801dfc9e4a48d03df741", "7694e0b93a2b2c3edd6406b8b6ad715c99d62a1c595f925596dfd343ca3c8bad"}, -{ "310000", "10eeededb4d54ad661d257fe3ee8b383d88ea175da4eca06cb0d2afd91d705aa", "82535ab42a3a4494e51e508dcf04f233df0ee6869b14f12c2eeb3de7d0d9bfb0", "4573a6b08dde9b2e032125118082676e73366419cb39e394c47bed550ebea7d8"}, -{ "310500", "5937e9322a0b8b1886bdd639f3fdea48392c3a1f3ce5c729f4300307b30a9858", "463320d4b753e3deae3eaba1c7c0c81de49d883a7205d34efc6f933287bec340", "7c78e6d8f3831d83191c0f757628cc26c5348533681592c0ea35664c8e28512b"}, -{ "311000", "106bcfeebd4f8d313bc06f691e30560fc6d5fd4e8eb2d3aa6e5e553d5d7d6769", "efd1663f7e472207765e064537779ac8b52090326f6afcfbaccbcf0dd5c7cb49", "393147e3a4392a43bae029a6c4ca33678aa619236fc2231d228a60e7ec7bdbfb"}, -{ "311500", "81c0cd746d76874a8add01868bcc5465d7ff0a28ef2ba742b75c6c89986ca3cd", "1e89778081b0b13e825bf16daf61ee16669826b50efc794cf871ea170399ca1f", "52aec7d09759e499a9ac7e6121448a74cd8c268f2f6e541fca8fc6b685bf0755"}, -{ "312000", "bdcec2a9a093b8c5e6a3f712c866bf78e720862b26918e7387d511de18af59e0", "96fb2b8bdf01cf8b391a87158b880f38acdf15a6f761abe2cfbcbee83478566c", "ea915f8312f50abb1f93d4d0548b30b4c4bf908c0716b636f11afda31c278ea2"}, -{ "312500", "a9716ae91f6c1577726c38cc4fddf8a39f1bac41cd1d9b5605e52184e573d6c5", "4fae3413451a71a5f1e4ad71341035c582aa1aa721ded95eaabd734137ddfce8", "64e176102a790cc4816fe4510450bdefb75cfe83407b62fab817b0dde33e73f5"}, -{ "313000", "cfa985aff09b9e7f22b17a600cbc428dc8e2dbb9c2b22420050ed8dd4597963a", "fc3335bb9389d77b4323758d39d7391d4896b94ad440a66b178b9366492fc79c", "617fbebd70243a76bf7ac49007d32f683cde4914c5f322c9ce384201a1e50af5"}, -{ "313500", "959ad500e00153dcd9d8b6a8cf1190c799f69d3c5f6dfdff026a5d78ca5d0c5b", "711b49060d7eee4f08a198fd3fbb3c611915c64cb12c8152210e9c4ffbbe9c0f", "8c77050cdc2e2babcadb760c0c3ae04fdb8c15cf8bd273575a4e6a678d2d1362"}, -{ "314000", "ab6a7acb2629ccba949934209d7dc9cd895eacddcd7143dcd7eda19604ebe05c", "3faeb9f09e3a75ed2247e4e6352c5744e091f5f44792ad20000721198a075c79", "5820cea058fb71cfeaa1e0b97ecec144f54f7645c12a7e3a3601598dbd49af82"}, -{ "314500", "d9527af7b2e46e049c738a9d40f7720d8ac2e8e94b847cb8884d922ed004f543", "03476229cf97cd0f2813169fab1ac07b9648a4dd86ea864feead69fa34dc498d", "1367767bf0f13399e7fcf36703fda084a2e84a058bc7c792ed0e939863c67a27"}, -{ "315000", "626c5f923088c9093b00b846a1ee92657bae30a36370f679804743d1decf948b", "d51b5ca87ce3888f7299e3f2c0ab7f3e28afeef234f63337553c972f6e688be2", "c2b5bd34a86888ab91365677eddeb350efdc08ea8e7a0412d1625a1e2a2c68b0"}, -{ "315500", "2446c74456b4b4b216b760d567abed176c12c2f474459d6be711490190904e07", "23a8dd7d4d710ef6a23aada5e4fb960bcaff7873416c6b9904e1cf61c2abb0d9", "682141b8f01b129962a351be4f513c57b5b9e6cc731af7d5e8a4c2ecefde252f"}, -{ "316000", "32e55b2ff3cae917e3248bfdf7ebf79cdeb323cacb54348bfdd0b1f411c92186", "ed4b4d67a3f55e5e3247f48d32ff231d24ef6970f8223e255c2870aa2ddfc92e", "99c2dbb31a927d7fc58e2469d9d6696275008c8fd7ce8c4b7a763d451b262e5b"}, -{ "316500", "634fd61f515e6ab677e142e73668fe41e462f25351383262b369e1a622bb9784", "0f6cfcbdc1408b6bc3cf64c897fb67126affe7e82ac682707d90894d0c6768ed", "907b1ad13b42c90eafc0f367ee58f72687e8e9206dacf4b7363cf224be8f0b2e"}, -{ "317000", "1a8b1bfb7cf59f0ea1d7141f2859a289b1cc0cc312836f5754121000a5a08dae", "189e9b6ec139450bdf78eb6e37a63c60a13551e1b9d0ab737051cd5dc29dc445", "d6c457a968c9fdf545c1e3bedb35878c5625e78020149a213ee94cbe27906664"}, -{ "317500", "d2d2e1c03ca763382245658d9e13d60db1c11199930c6edffa504cea704e9cb4", "5ecf2ae923e1b0ad4bb52dda4d3c5b6ab31dae5a1152f40688992ac56cf7c1e7", "25ece3bcea84121fff756ce85ee8587c1afe2677fc24b9fb351594beb49e890f"}, -{ "318000", "14c481ed71e0265d9971041215ffa9d80bd9ae3d8a20bdd514b3cb15e6d820bb", "b83d25bc14861317c60d2a38c2cebc995004a3164e49dc4109d195ce719165a3", "b90c053847352df09121fdbea59b636a257c21b6230089ebaf9cbb7df6f4b0c3"}, -{ "318500", "fb1bdbe68f6fa03555a52cc7c70086b585d1585bad7e7f36bd7849b20bd62d7f", "56c93b2ec1e226511dc23b53e7c6992905a4c4875ee9146558712faf39024595", "f69310ba42600ab030dd00a61fc4614bc7ee33c8b0b4a7b3c739c81cab9ee01c"}, -{ "319000", "3d520676419671efd72eb59b19a912dd30419f5d50f9dcdc3faa15797e8b78ee", "f0cb1c494644102763b745ed186810fd2fd2443abbf4c8ef02dd42e20e344e35", "e38b3874c6a10de03ff946f37ea26ca61047c7b3eb133af49941a968e8f84535"}, -{ "319500", "e6f93385e77b36b8bd02e95a7be1daf93e43c2c15df61ad7a53cdf76581c93e7", "8679904d6abde60c2f8b0628024a00f1357357852ea5e0085a8557cd55a3d5b5", "fb8bc1b7eeeb5277f551dcddf5937bec026ff0d1e4007aaf3aa31f2c531166fc"}, -{ "320000", "edbd0041bf7c7fe4378c089724a0dc3d91bcff7efae1aa5a5e9b1d914d9f4255", "83d2528f44d5537305cd76560b0fe1da24549b295e84a37ebc9f7e442f59a2d6", "f73ddd2faab0d9f48a5847489d5ee6be324d47c39797d98b05acad0368063fd2"}, -{ "320500", "fe6af92a7429dc15ded665d91c0280feddee060e7a12cea78ab54f591a2a97c8", "3840d83015f1c9053f2a74305ec9aaa4ab9c8fca66c62b71c898c0d8e40f94a4", "a5b40bbe9947a9a6dde0556b09fe2861d8cb80ca2389995690c1a4a3f9ca121e"}, -{ "321000", "09fbf5bf7f04579822b0643da9de72f9ffb4e3b086334876dd7ebd4a0b1e5456", "3d01cbb877ed01843faf98fb687aedfdd63b6eef204d7a08e5177e93b6315237", "29a612c741f988fc0a2eee429ced3d48018b415ad9be263b05f46846833a89aa"}, -{ "321500", "79143aebef47a364850164688450127d503fb0b5fbbf6b3ff422a655973699da", "b65e2511ade0cf401a38d1089a5ee4a0747e003fdc2c29cd48e47b288d776801", "56d1c182d92b89acbd68757169ff8935bbf5544a916634b280965929168b37b6"}, -{ "322000", "03aa6946623b9252193d58e6dd00bf586ad4f57dc8fa04dee924b5c15d08d8ba", "378b057486d0bcb43313d5206b5e08eeb06be740ceb84456f5cf8549e46157c6", "bd11e7da95ef2ae8209685205c82a739873bf894bee4e50d6dae7c6b81772cf2"}, -{ "322500", "cf8971a02d54a830b3729fb8f1d1c283135b1a7e30d5cfffb4462a2472467d66", "233e6d4bb154d5d3fb1739a4e90a258f0910ceab33eaad183fd2108d8ed464d5", "7fbe3ed0761dc6172430d30f139157c8b898502f1634307e4f3f08d49f9be590"}, -{ "323000", "8d6c05ddfebc0476b7ea506c6edd8b1e7a1f04f46d3d44c404936fd8c8c97089", "c8e2bb9126149c636285107b6b51a2ea4dfae6a9362ea82e9a01fc5b62317e13", "5ad60ef0abc2a5ecac539d9f11d0c77c0cdefabdab5a9b5a4f839ff5d4986002"}, -{ "323500", "f92d520784eb12d8ae3c11ad1803d5dd95a497c0084c88784702a5acce66ae41", "81e2f522cc756b27794e1472df684a598aa925938ee87027d455dada0d2835e4", "c0a590351ad91977c743641c25a96711de72eb7afcae92068bec7d39044db470"}, -{ "324000", "4d33cb6af695638f89500645f741981a2b96eb2b6f1361cf4915e9df14639412", "0d5d58a71b6fb721127f551a4744091aaafc4740ce74e1e094783488946bf46b", "95d0d5cff5e6ec05e646c3afb0267b14cf1455be7cc94c7b2b99caefb333a913"}, -{ "324500", "9cd5a93ac51080a0a3dfa6e7612adebfd307a7c2ea510d033368490c6d25b7be", "046e088e42fe85a8f29cf0c61d1d7c57619c29f3a5574cb7284374151fc02f75", "ba026961f26ad93bf8a1bd29ed0fd9c00d3b8d20bffedde3c7656344ea5e7686"}, -{ "325000", "ea1bd97d2e59f6bddba189466ffe1e7be63f5574f110d5b87ec3e0294b2bfe5e", "c4d8725f512f352599b2a7506b3c52e78012eded7fa5f6bfd99058046342b2a6", "2806e0b32c301fc7e7b517ae6f3499179296a2a56e71256b70a68f44a6c18b41"}, -{ "325500", "df8156f044118b84c3e2482e346c5639a19b2f1583944286cb9550931c3ca0f2", "4310bc5bfec110e5da8fe1dc798b18d1b1453895c70554fb4d52dd7d6d7d813e", "0121cceb434fb22a7fe131aa8e3cccddaed1db6365159c2a4540a3e82bf89af8"}, -{ "326000", "d46ca9a4ec0e9126c9b570d00f7b47a005d51f25d9fcbf0c4ca71a29a5f255e6", "426c81fa951ff0ceab76207fe576bad3be2279d802d5b95b45881c73827a1241", "aa8d073b426c4a1f76a7fe65b5f70ef93a2257a4d8736432f524e67f5845848d"}, -{ "326500", "603728e060b7c7cfa603aebb548a3362364f3ebd83b07742458a412777ba9259", "16fea467df6f746c0a430e00b12d568c7103829328a2bc9b57fcb55c74a66bb5", "d919599180ec29d9c60387ae68bcba2f0c88c9ebe8876d351ece0fe6189f0753"}, -{ "327000", "6913cd3da36dbaf5c6d407da68f46bcdabeb504269ea70c0cdc219590355796e", "745d85006082600149a72c38c32e2d378917153b7c8dbade476f6ba32726c893", "f30e90e6104c58c79bc5edea2d7739d2a788669f2c969f8cdb1fdd6116137d07"}, -{ "327500", "b6538b2705612808867fe5d1da0fb00b6257c3a4314d327b0c6403facc8c06fe", "bf9d4d5ad9f15c14615c36f8cc7ae29defe64971c5824f95aa535c1bba7083e9", "839b723581c717d4cb889d7e14505634ab4480dea58abb53b34bc47c6975c5b0"}, -{ "328000", "ff013ae3b0bf04df355f954637c6ca2510479c51180977a99af805bcc8c2d63a", "fad93d54a8cd267fd2e63abf1da6b26f2f9bc1febac401d4731af0103b31fc6e", "88fc2b74015e76da36ff1ce8cbfe4c3b23d7c0243c9295cdbb451364fdef1254"}, -{ "328500", "ab64d04f26e2164824afa50c1b5592c172469531a20f35a38181993a087a5cfb", "24d35a5eb7accd3545888e4c525742d90b01981447d1c2969ca744181e4d6b70", "a030745dfc07980d9daf81655a705a35c78ddb6594937b505784fa1528a79a6c"}, -{ "329000", "79384d9bb22811755a4bad2ca7d238243ad975b956019cca645144215ead0547", "295fe151911572801c0d4e1ee4e753852edbf6078d7bd798dc5e2da10692e7a8", "51f963e7c2e27a31dccdfa70eb948778488463162943bd74217df26ed9ede3d3"}, -{ "329500", "1839ba9cdb5db971f72defa707c006ef6ebeb93dfff2bf36ce873acd327531f9", "a930915c8a7d58ab4774dffb87fa36a6f9b513b466bd73e5c96965f85ec3300c", "7f1a0fd540c40140bd7f5d626f51ce2998064e9809c43719d309e35e1ff0dd4b"}, -{ "330000", "829b9c203a0c146c2794aa0ac22bc71033ddd15a68959064526afc2722febf94", "e09093eed9d282fce0825778bd7d2c9415fa5b9adcfd2263e7137537d861d29b", "ac77c200bec1912410ba921f77e306f6a09e4652d31514625ac78dc00bc71c33"}, -{ "330500", "740e9f27889b06a301e355ef7dee62cf10dcda17d4023c157c55327420b308f3", "a298a8255a0b30782c5d968988514e0437f4cb34a0a2f7df8475a18809007d1e", "9722342e209584cb9eef0f5f5c57ff8545dad281d39e9bef7b4c0eebbd3cd3df"}, -{ "331000", "e2a4cc3a53ac8a24ac52f6fc574d0e9fed0d240710de0694ed5656abfbcbec46", "74e67ad885d1f874c4ae7453085f29d254c684ebc71eca3af50f3278c9e1c266", "43828e2a6cfa59da76a3aead5ae91068ec8031c348826bf11846316f3c475fa2"}, -{ "331500", "afdc42adb73a6717f48e35b3b51bb13dc6233645b8a4805723dd771062dfcbdd", "a3988534eac8b2c3f5d557d1277440783c624597b8b922df33b6fa38b824fc33", "f6269385ecd144edc5dd3527e373daf61488aef4dfde18101b014e58ea3aa39d"}, -{ "332000", "4812ec71190df534e5d8d4965492cabc3606e51c11e4f9181c470a779926dd7b", "3d1fb3699e9f859472fd032915cab01de53232e123b1e4c93db2871f7c2aff6b", "adfbf39fde89189f36229f39dd7cd13fad00b9486a0d706ab9c19d4534e2c17f"}, -{ "332500", "50ae97dd398c25069522d5eb3b45a2332fd045f6be4d615c7d36c7ccf54c6c18", "0bb46697d721417a2217fb4e632513d2ff82f34287bbdd732b9e2f893ac10df3", "298e9c841af61baf161808fe5ff29c268490906feb3a7897d3d433d1d369e558"}, -{ "333000", "fdd8f58aece53dd4f24881f1007cbd0ed25d9f3c62f356a00dc92aa68a13539a", "e0ed76c2c22a2e784c8a689e1032cf00b65a2702f2b3f025c78e2d1e5190070c", "842641e07f071ed697b5689501d8455969c977fb6327ec31523e8c600db51fb9"}, -{ "333500", "5ea2791919a4000f9e363e277b7522fd9ebc9c06ee5fd9dc15e4ca8984a2d8d2", "69d3bcbe827a926dca144c589eaa175f16b6e523b487773b93fee7b45a5a60c1", "7fc573e06ccca42108fc016d4c9ee7d0bcd607245fa871470f4b034330b5b71e"}, -{ "334000", "cac1a3b80353133e863014d138b408202c77a5759cfc5642546416d73f66ed84", "9005b02c03c93c41c6c78357f4323a3234bf12db1eaf36e81c1077a324f7a07e", "2ff0b8561b95225125133dc2aa1dfa52c4e816a4fe8347b84e63ef6d3167f25b"}, -{ "334500", "50861ba6d952e1f0fe4dac891ff4339ac5fb7094205767f2d6233941d2821c10", "f77408c3140c620c63f8bedefb370397dab67077b4168c628d787d5b22419aa4", "d55baf24587b88808b8e35834c74869f9d3ad0ffdfb0d1da607a0f8fd8214c84"}, -{ "335000", "594b37798c188fab76d6d65c058115b58757893ec32173b45bfc618e8c857fa8", "fe50dd76cb7dbe52cc6a9f6c25a3497dc5e4d141e59ce1bafed04367fb155b3f", "61b2a970de4379841279c59bcbc2ce67ae76fae42d5e5ef2dae197bdd48f07ff"}, -{ "335500", "69b0bd40b74e7fd15be354b734717bf197f1800bec85120b26ca21ea5ac0255c", "58cf057f1edd07227964239e7d220b4a6bae95793694841f7a06479c5e5f7420", "413fc049ef2299a39d19574d01cc36c85a63d99bff587482e26374b461080fdb"}, -{ "336000", "71631092dff7d8d09d44bbf35c187c7cb5521c7a5eddb1422f790e52107b6797", "e3bbb2e549a6c857855772ad5317902ce52231c464fa78a107811c8381629a49", "5ca7df0ba49c0bb880a55258a53d084950bf0cbb4259987f0920e1dec015f247"}, -{ "336500", "ec3497d60fb7d85cfb349bd96712903aaf8a86e6d746f8187a54a1aa5b7b3d51", "dc276fdf1858b7a7600213f9b06d4377dc53ef54e112efc864006d28c6cba3ff", "5c9a0b41ab2b10fc7c757be7c2977e61bd48f4dbe79619d6f1656ff0a81278a6"}, -{ "337000", "70b67fe1ffc39b65d7c3834439efd501fcb9e5d31202322a878be2cb78f741ff", "b91daa38e81b0b79bbd48c50f9d5ef92cd965e729b075e10b270e29effadcc3f", "6c505bfd33c714e5bc7702ae3ad169ea244b89bd0e5becd96f0d0284c28cc07e"}, -{ "337500", "c5df2f17757c5cf77fc421904662468bf003326049de85bec43003d97a5fc47d", "29d4cbe540e3ac54271d12308edae379b59365521ee2f09a6585a82a046d7550", "fb7918c3fc90af8f8c951c5c1c4bb29ae06a1b57a35e7a597a31e8636b59d5c8"}, -{ "338000", "60ba652d7ad31c96015323efbe454694c5ec72dd732c8f4578ec2f5d072afbf2", "2e3a1bbd3ea4e0f318830e43b20d53162ab6b6fbd2191524725965c549360550", "f9495fdaa8cabfd460b7f8ab9ba36870eee6d2a0f3bad67fdb52e79a7dd9532e"}, -{ "338500", "c898aa2617812d17eaa3f8ee142c3018fe2807862ba6d06f309b3344e7d799ad", "6bdee06900bdd6c83f8fd8538d75af113af8893ff99cf9a25de6842d3f0d9889", "25a5a722cf5bf7d4ee4aff66a6294274f598602717a0ecefc0be192633c053b1"}, -{ "339000", "e0d97756042e78b1c14495a68291e5033c39c56f37a48adaccaf350b12f59202", "913f62e783258b88638a7c42b2f403328b683f8c657520ab723ce2196af69666", "bd0caf46efb2dcb6e26d920ff6794cf3a77b592a7a33903efa6e2108cc6b8a86"}, -{ "339500", "1dbe406aeef28cf78b7d43eed5fcdd8c9d7d6d11363cb7e595d7bc1d1899140c", "8cee4f37f98fc3da1826dbb96aa525a49fb1fa6db5b2bd64dd3bbd4fb7d6c238", "450abb3653fc86852646e95572ca4653c1050de7eedfdf3fbc219fa400c52342"}, -{ "340000", "99ed171ddc0aafa8a5b6f9e5890822c34f6ddf4bf63f1488afde10526c74c8b2", "ffe05de29a9901370e815a782c7478c3075f8444ff473b20ff5a2ab311a63022", "abca9c6b29a08f99c78109f92296e105ea18e208af03ffbb7ed827393f634603"}, -{ "340500", "92da105d515c1952ffbdcb5f5b99acaa565500d8f4b6e45aa093b61ae53fb7e0", "852c42d37d42f8d2c740e57b8e9e769e72445f57c8fc9d1f91e62f029d7d985d", "04114d48ae342df3b1994cfa44fe6341345eb49b8d228fa0b77514f00c719fa1"}, -{ "341000", "da401dfe258750911b7264ccee0de1b53bd7b90f63d73f46ad5d5914203b59f6", "84e7b57cabd661c1cfb68407595a6a9607e0dcaf68f74dce2f8487b1f43a6ac4", "e454513ea741faeaab0bbeaaded3ff3244e8e2c8bc53942ef26efa9012ca49b0"}, -{ "341500", "ada69a2ac0977672d08682d195934176caaa7de0baae2f3a32b1391ebf550eb0", "cc1d077aae6a1c18f60c874525182f8cc211cfd0a851381773cd0166c108a43c", "09ef805774a86fd01d17e379b36357093acca1ea6c8ff5c8856e12dbc82b1ad2"}, -{ "342000", "ff83fa02f1e15e52a1e6ab3f8690bd9c4bcc7f3adf77dda003c6871283b695ac", "5983b9dee33342727befc15d5982f9ce987ccee38fef71c34c482c92e062308b", "53699f929f82af192f093ff8b7cabe83778ec64db78584a73f892235a9eb3db6"}, -{ "342500", "cfcf80f28aefa27c6f09f71080e4af7bfb33f94d1c47e80633187f80a806c6cc", "08f62f928db36fa7757f30edd40f93c20dc43c65c693ca5de4c87467d40377a1", "a1b4bd9ea2f7d8b01d7e1a761f09abd0c1c89ac28552fc0f2cb5e4e6666790c1"}, -{ "343000", "55e1b51f72f048231b675c90224571930a59146003b4ddd3e883bcbe4c8c2685", "1f6c53f636480ebaac6569f100e804de9a604dc1bca0a626004ba9852f2fb546", "2caa3fdaae8801ef2aa217390696053529040ce256b839f3f3d26557cb24db62"}, -{ "343500", "3d1f67b0a5d905f15f3fe5a7a07aba456ce3ce41422a3bd94f92fd19ce7960e4", "4201088ace85294f87bf646209d2e9cea09ac2587654d57c8105b016ed3adac4", "06928ab5b470f9bccccb6292549f48341536a3e0a28db92e2d8f17198ccc0557"}, -{ "344000", "1e718e4e82839b50bb5409297dc94bd783264f1bd3da639f2e4b5444c6765025", "c2e0bdb2e293d2940f99295b59d2fd9b57a02632605bc66e4ed69de4e26c4afa", "93c559c784cbe4d7df210f059dda5a5b7ea35df91b63704ad483680bf53eb9dd"}, -{ "344500", "aee9558284286ee6de93a1456fd3cf6c81ff542b4c1eac2c7694b869742572e4", "56b70751d01bc1925f288a0af1223f309b7bac54e1cde463ccc9667ea50c9ddf", "879ad91894bdcaa2250107f95879d7cb97ce26cfa1a0d6c71b91689e41879795"}, -{ "345000", "852cae52d99ea4f4f299f1b5f4a7629ab0d32f8693f503cf74a1f0a31a9a80e2", "a627a26363ae216baf1774585d1159977d378f34b54119670620bb82cc9784d1", "9b6d95864a083bed38bcb6eede6fc4a8e0b6af52db78b9ad59121047a6f95858"}, -{ "345500", "09a3e1f7d56b1662f10470c2497e662495b62065364f40dfefdf8d34f5939fce", "e4d96a1576f516b5303b60dcdded21cb4e3f382f4e7c4b10399ea4b6fc37670d", "d46d62b87b4809283a35462c2841b606094612d2df79b3edbe90042a3d43cd3d"}, -{ "346000", "3dc0fc157c00c40ca92c8125e818f8b5c6163761b0c6955a88eb48498b1d6a45", "6f60e0950cb6f6ad48e5b56e9e94a680ac85109ea90ff94df6ccb58adc44d3a2", "354c3b2393598bc3961d45c2cd2d8600076ee0ad3efaf582fcfd065bc75a6889"}, -{ "346500", "bd5552ed2748d686ed3540c52ec7a0f97b839254c953074357fc019667d69188", "d1707671c71c75edd986ed69fa0d8462f1d7aaea3e0b5cf519972cd3ce7d73a2", "ec6489225bb34ff2c7560d204f2772ec37b862d9b93642faa6089b8e73aad020"}, -{ "347000", "68b383fb101b4ad08a4ab58777b9f3e34c69143bc3872785c281b155de8769f1", "0105724a536021bd7c8fbf2ca7e433c247009c97aa48a8688dc7c9af88018688", "4a329bace708ed6a32c94890216feac9141147f47d53cf0439a22899e97d673e"}, -{ "347500", "af3af4870dfdc980d2bc5c946e773806957c2f5d98200d5e9ace72e4301d0ef9", "20b564b903b75c62b5c7bdb911c753fa67a547a47d47e5a60a0a4790362adb49", "2e447615292fc2aacc273c021ec96b58a9d1856b557f684e531457ff4101cdb9"}, -{ "348000", "e72024ff3d0ee72f4f78b7e63ade7a7ea037da43bfa9deab400f6739fde391c5", "c0ed8b08b6b7d50bf86069b1e8f6c7c36435817114e27745be63db96b5f716bb", "e8f81bcd2b69a03b9eb423336a20bdcf659ae0711c3d765e7ac89931fb25d2b1"}, -{ "348500", "1d9d9ad6a6b1a8d5392aa6d35a7472fbf80535ee334a043025cc3637d9894db9", "101e9ff2c05137c25a2a270055264bfdcc81b290826d968ca94de4038f791790", "a3afe000faf5b427c10820657138d0fe4713b009daad3c797c00c35aa35d2d38"}, -{ "349000", "bf0cadc56a8359bb703738a06f7a31b305fe7433989e7e4094f379511e27a19e", "2a2cfebba2b09215327049cba461b4c56cf54cf31a0d3c6f8b21a637e6a4db5a", "7630b9c11e847b125d2d7879d4e6305401fe6656c5c997c7a521cafaf170a131"}, -{ "349500", "78065cd5e2af5a3a4e838289be5d1460605048c1cf2fd1ef9ba8c88619631e91", "c00a12d97c8a1cdf4cfd4e5185ef06ebf6b6c58aec4cbba2851e47c51ab03089", "2d1790871fad7a3ac8348c2c1272d78f99e71e73ff4d51e4e0f1421815b4cf7b"}, -{ "350000", "937db7a154c0d4c5043fe8bdaa0969670f132252a6c6bf8f7ed5858ee11c97de", "8c276300614c430a75552e0cca7d83834ce7bccd7ea1d592012300ac2bc5bc66", "1fbcff068ae14baf34f3bbce37b16a8cb04bb7d3cb561eff4207b4430d23b8cb"}, -{ "350500", "6ebacc5b6fe9ff0e34d64a047981fd170f1b13d40139073e6e65da9a617fbd18", "f181abacd6038099f96854c2c0ac8f7d19504609f36dd0aa085af150f21ef930", "08c66db3dc00525562741c47770de3332ebe18568d59fd418949a93788b0e785"}, -{ "351000", "156a0053ebf2ee2e68a7ef337edc14044503653188c60669ec924fde43c21ea5", "dd728a51d7f9e8f04e74e2116698305470591a6e7937b2c4b714193843eeb584", "6e541a9fa878ece79546e3659f1a8dee6e9b7a49fbb66073f69e3c7eee9a8339"}, -{ "351500", "5cea6cb5b1b96a2641bcd705ae86c40ce7a8572ff4d6815d7531ebdbca13b958", "fd4148c5b36775f35873746e962941ed43d95db28ef21734f4351f1d8a69d012", "86fe88a8015b6b1c64b729af16e6997820f9d95de1d7eb12e70bbb1d5899109a"}, -{ "352000", "43dc3dcb74fcab2f5e90992eedd8a7719f7b7c7658b2086583ef881092f88aa1", "eac1623de8acd8fd497f9da85f85614f5cd02c69aac6044f24a3685957009f58", "47ad336943ccdc25684fea6e107940073027bbf850fafae7139b612fc94dd123"}, -{ "352500", "6b895134f53c26c0b24e9909472962abb3dba5f8b8ab65693ff8e45b3b77e566", "aa1abff115fc49dbd6847ba4779ee7c514dfdbe3895e7bc3105b74d0fcf1f4e4", "884c7d07fbfb39307f6edd46fa87e83d1afaefbbe3237ec1e89065b70579a0b2"}, -{ "353000", "7785e099822d5b6bac5c707ea57d5d2cabeb52e1e2d82619c8bc2051b486767c", "afcd99c877d144c3253dacf018ca36e61e95761e44f993e0a4cee0854a7030c4", "adcf80e9e4bb78e530cdc25d81ab9c78482397643a136c585a8d10738a62a700"}, -{ "353500", "c0790882442b7ad61aec5a64faa355a8486f8112f9a691208f38e9bc96230492", "f7888632b88cc7800d381774153c34626ff63d859ce489286d9fe904403e9ec0", "e43f0519f71417cb8a09cce20d8559384e86e64ca7a6b8f392b5f545e94afb88"}, -{ "354000", "de0551272a32e89def017385ba1833443c4e2ec02196c33739deb8bac6cdaf25", "78038315c2d8c142ae67a01dfb98009847380ad96cbf6cf700af8693f6260caa", "eddd66351b2cddf490d23278f6afc79315da83bae7dc10084310bb791e7705ec"}, -{ "354500", "c2e4b7243560cd6e4511d175e2c3fe98df223524124f44faabfc252f57d503d7", "1d0fc9a93c812ad30f81462a5ce1fb62d74f14a1672e69dee3a3b797fde53270", "6fd7ff9a6576088f6e6498606fdfed2a629bb8e481fa60ddab26827644df175e"}, -{ "355000", "1a11051121727fbe8bf80391ee403566e3b0dce4ac611b37a516c7e3432aa231", "f363b96bad7663c981865cd98aa36aa2cadf8b4a623a030e3c7e8a58dea81992", "c8168a25c3140673c0275e75090ed811c6e5656bd49e151560df2fc1ae640334"}, -{ "355500", "c877ee5b39b2a7ea9723e1c90b2e307f861e42275c826ecf5b6c84f97c120385", "d7cc21f18f45fcba316afb516f70ae028723a709a1a0ad2994579078aec10ddd", "529fe08e2adc1316c2a0ca6128039d21ceaa68995c754340a769044bf6980a16"}, -{ "356000", "4226d4f7d74316c4f9baf33868b492a72f2a2deabe02b5568ef40606641862be", "a364b4408c45633b64ca685f42f4be377a4b730fd762f28e0015e2ae6e23b0e8", "afe55e92e2c9bb42e4c02a6d0b5a54d98b52b8053e4bdb4bffb954f4f8942dd7"}, -{ "356500", "f0014d06574914b9215379d2b187dcca46081a5fa27d6a32a38efd382a9e945f", "853c10ad51f992a4bf0c46c8471046641edaa972c537c8a92b32cc79ff80b445", "56ddb16e6fbfa6aad2c73a8d5829b67a450b7ab1ae5fed5d75bb860ed939762a"}, -{ "357000", "1c78c05a5a6c50b6d0372745b8a3f0ccbd6c4878e5fe2227c81bf36cbe31fede", "118150dac00bdc45c95b36d35a57c63379205cabc42f8da5d8cac3f8198df0aa", "db8240e2b8713497a22a8f2ac518ab5b029c5747f314e86cd1ad8ff3f1503217"}, -{ "357500", "44900087fce8f2c01a87a2ab15befccc1d9b9e702b17c0184cda90876a07fc86", "621888deca43a1398ce69ef2cb1ea7523e563dd552e173c3af45eb3f00667df0", "82fefcfa3f4acf31f877878c219f83cfc671fe1f80dcf7f763636a73101fa324"}, -{ "358000", "40d642581118288429f0b72a73930470989ff443944b7215edbddf7ad8596d31", "819138d682f96c5be33a73fb51c7b698f347c76086d468a3cec421b5ded9bdef", "07bf777103a5eb60fac5053417011d7d6a9a5a89c8c34bfd0b202ba48dff697e"}, -{ "358500", "39f707f88dda6ce8bc39c64bdad9d1fe29f98b517080ed55466a8a221ee19bcc", "30d012c4929eb3131b7f50c34986d7e1337b46ce6ae7065a0613ba6ad336d2dc", "3fb61fad96e3da7e8b6eb33c884df7ce843d64babebcb7b7926b613a30ecede2"}, -{ "359000", "8a04b19b8f068b14a987511d635cdc70ea66e37b63a5c3750bbf9bb2881439ce", "7d053e5b5d919b21a1ca21dcb5d31126f519c76f8c0d2816555816496229c970", "632f9c544be4365c0cddf8bf92bcb63ce286e7233344413fb313ba2ff586ac0b"}, -{ "359500", "15293eeb7f425f8f041248d3cb15cbedf19eb921389a4425b8a14a30d9f6f08a", "5b47bc2a1eaaf8b83461d28c535cb1b6b376826c9b554df7498216cbfbd5e76b", "8dc135f880bb9401007f1dd5f874c1e3b005bc84fa1454288a7863ee1afdad54"}, -{ "360000", "37577d18f84202e74e17eb9fd38e760dd94096b4623917c8fbe4eb8c1fe727b8", "985b64f248199de5acb5f6dd54aadfe6b2eec0580ac17701e1a6590b46830cab", "70f9a5163ae901c5e23401b39f96a068c1c048b8bdad27586435cf669b63abcb"}, -{ "360500", "2db2b88ab382de78f62fb710454fbe0a9e07dc7c09ba76ef26bf72e4768b8cfd", "a1f4e7d6f52f1fcc610793c0822a6c9a40e0224deb7e56495d34ead537fe2fb5", "47aafb43595d1b250de55f611a94570ba7292572dfc257b0cd5b716faddda2ed"}, -{ "361000", "3891670905fc1e7ca588a4b72a30c57749cb7c9c2ed47907ed3a69c7339caef6", "164eecf5a84889a1ce42accb7ffcae55c4bf598b13720c34eb403fc849dc5801", "087c29e43d9cceae103703acfe3b296cb4c50b1e22aa18c3473b52ff3f8885bd"}, -{ "361500", "ebe6b83861d092f8eff3579515524a45568c743e7df656feb775c45981251891", "ba453dda58aa37da9c4babea1597815a99cc4bfc9aec16fc3f8ba1d85a031574", "cbcc76e776b4170358edba336f2d98c9195adc0d1ba82bd4c7840aa9ff46b5b0"}, -{ "362000", "8524397d4612f5acd6fe921ca9de4e9338e2f74221d4d1755c3682fdbb2bdada", "d9de4ba457b0d1ae37a2dcb9c8d921acf206e96673d45346ff85de620fc08334", "04ec872f96170049e211be83f0f09942fb27a2056b14a9d5bebecd30af615a84"}, -{ "362500", "244d8c96246dd1772efa9b6dedf90ed9933f9a1fef43a5a61fb9d59e9e19645d", "fbd24f0a05dad2f8048794e8f0c48aef1d9419e28e125ead88eb1127bef72ed8", "60c9c9ec0cc6804311d0324aaeab9c743338ad5295fdd80caea2216bd3a81cd9"}, -{ "363000", "2d0854b709d2c4fd84c1d66a736c4148a3b1001fb083f1acb38aa34416063487", "eaaf97d25a09d024b71fb1dbe1935a8cf34bf0d30736df8e9a7b6fcd4fcd63c7", "814a2b982f34b758a145f8d21f44d4518bbfabca32e0bbbce8117530a880622a"}, -{ "363500", "eb76872dee58ba1a3285a93cf5b257a12a903f9f628828bde4dd320ce44ea11e", "2145d5e2136393a6d205af57d6544782db4c701b6a5b3f14a90528f30cded69b", "36fc0b74a6927578a7daa39ab73ee6d90199df057a75599c6bac59cd4ab63f63"}, -{ "364000", "043d7b87efe77f8f2d34833a08544e15838bd8b8e1bcd902d8b1ba9dc30285f9", "71ad76919b65882a929954ac642c401dd8f298faebf7208aa01301815df4f32a", "795babd03501ed1d5f9e5fcfddc1202feff8319e219d468a008d7a16d77dacdb"}, -{ "364500", "10b77b07108cd3c1b5166e51eae74df84f39313508e8093af4fb5a5c8db99c8f", "9738d20593ba72b8e0f80a8c960f343846b639d3b5f3ac623ab7d7d0258e8c61", "a99e4094e7751fc605904406931c76491f4300d52ef5584e3d00eeefa01dc440"}, -{ "365000", "a88f0052b9b490639e238ed8d2bdae3ac573c598eebc036fecfbe8d0d651cb62", "806193a3ff83178e6847129340bc66f087903dc85e8d45d50a3843511625fe4d", "f800f9b0da3e850407de0198d39482c22418ed5e085af6c6bc0492bda6491492"}, -{ "365500", "07674af4f751c8a09011204107b77df887eb0989580ab710bc28f86e1724b972", "a59376d69d1fd2b3601728c2eb2f3f935177f5abec94f9b441a6734b8c9dd57a", "f050c7b58f25bdc732add78f058b17b437f684cda3cdb9697ef1ccc26593b3d2"}, -{ "366000", "e7f0e9b3671c1fd8ac289879d42ff60cb2decb8c9fb8095152e444d183d33d55", "f04e0f59196d771ea62c59ac3882474ecd053519d37899e2ce9bb2d1a779b3d1", "b0c17ab8421de54b13fa25a7be2b623f92fdfc99bf9cff188da8d00ee05776a6"}, -{ "366500", "28fe13630301f2809e429288503e7a341a536de22c078ba11f5056400837d18d", "a3a2aa196a595a7effa0e8a3ddf8197fa3837c1a55a392f456bbe2745442d844", "6e3e34faf2a38205cee3dcc12ed0519960dc05b4378a5d7b264e977a34145362"}, -{ "367000", "066c5da3bfb95638c9b0c37cf99fe28f31cc4852082933305b1561f8b289ebe2", "4d69dc379574aebfb8c507bc6791adee838a066e7de10e2e5d633faa6aaf7927", "c10e1ebf67ad69e6cafa722890d7e63bd8fa7af02b3504d04721d7dca1cadff3"}, -{ "367500", "ee383e75691d5d76bd0d84fb2edb77a9f3e453fe14e3a0840524d4966eb3bfc7", "addae0433c1a0e30adaa6bc21dc08c4c37c7ad6d12109458cc8b9c3deb4fa80c", "bd8e9a602a825d25fc27b6d83ad29e34ff074ea2a8ea694c919e88d639a3729b"}, -{ "368000", "7718d30ae93a53584971a1aae7c71b99f17332702adfa3ba93ac53faa3131bb3", "00d48572249cc7eb9929065f4d8e5a4268b69c425ab521e974066c7a15ba96eb", "74789961c36e16dd0c2817513103375041368b49ff8ecbbabe300c64f66afa71"}, -{ "368500", "49160ed17423768caebf15a07b978b51b9a50f88cb934cfcb2ca335db599b313", "252c55080a47e986faa7b8e8321239a25b25d5109f3b60cdd66c2d7086c32bed", "9d2db8c4d6d232322264bd21f19fdd4abd273c77e440f79392e96302846aceb7"}, -{ "369000", "2a35afabeb4c08f7e0fc8564b016b65792e64b6beba78e5d7c0641af63530170", "08264c57b5533fcc49b365920cb2d8b698be6d412ee0693e4d78d847530eecc2", "4106088b6f4e3c1905df95439b4986171c20dc64b019149fe72d03ba0d79576c"}, -{ "369500", "003a85d64df7bbbe1692464040b072934789d092d6f866338b0e9427e823a83e", "7084540c646571d0af1e383b6753e92aec196cf20c88bd913e074ff05dd63502", "b30146442cc357beec3cf48ccf52376250011fbb712a4efd5446004d201745c6"}, -{ "370000", "434d40143a0e8d8fe2e00984effc5579bd3661fdf33dbd93cca7fd72351dfafc", "bef78b640aacd4fd8598056dd42dfd6557355ba44f18fa9aba104eba4bad9738", "9d4f569ef3874b03e72f2ed5029f9ebd8844fd88051cebb97c1c3daa087f7372"}, -{ "370500", "02cf8d2c1db6faf3e7755a2b3d144a4936dcd9f34214f1c8aa826465cc3918e5", "24b38a6971f48836c71e37abbeeff129d21fe5975302103ec2af62a337c33afd", "6061f78f93a983e545f9b0e06d2098b8ce8a67f9a98d9e922a58e7e7de1b754f"}, -{ "371000", "2534f9c4ca46fe2df863db301dea97a3bfc6e5a3645f4080d221e9fc214efc8b", "24faf019a5e3c38e1e9c941869b93a6c5bb2b2e3e3c754c37d83bfe009f78c20", "d8f2e545e9f60114a37b677d35d5b1140c933a491728de7a7154e6f9eeb99416"}, -{ "371500", "1c3ab21bf75be98963553462f21fc369e7503fb8699d9f6e1f635a952c55db42", "8dba0c68d6c580055ce406b81e3262b9c7057ba8cbb8b221130766e667c878a9", "70c1bb70564110d67adf9d12494e89753fd4a4f05e0f4f0902c058e626cc7c70"}, -{ "372000", "b7d862d978a007b9e4afa1f2f0650bb20c0298b8bbce1666d58b009c07014bed", "f070560c4db4d96f47694e25dc96746634b3b1f172ae1efc8435b29ab083697f", "4aae622c2506753047894ce5cf9d7eb707435a9e994896a6f4d7eb0fd02e0e99"}, -{ "372500", "aa2c34e6c03803e0edee9675926dba87db1bed0c89e605dc40c2213a330e53cf", "dbad4244855f790740309f5f7e49755213bec4d672cef6491758cba12b5571e6", "adfe6f7b32d60df2f459b9a6cefeaee4c6d8699f7d021742a5d593bd3c4bde72"}, -{ "373000", "c03556ea141010a523c44868eca127684b01e83f0a76090906728aa34e599931", "b2d61cc71ab0b18171db2117a6d535128c25e68031c3c44c059c7c7965d05c53", "4762b483ebc34a038245662d1ff2938c9b345ea9f0c43d2b06efaecac6184115"}, -{ "373500", "b61ce82c38d812c1e72a830b062bd3854701409fed42cb8cf89d9c83a68aa4a2", "3cb1ca2e543310ff8d22cba4bfa2973e264837d2a4a5052cfccde4de4a4a477b", "85177a9b8ee909e6b462a0edbb6bf8fa04fb45c20a41242c60cf9e25ca661a36"}, -{ "374000", "0a2b671cf0c4e82c857482fd9eae13f8212fabc508c3f6137fd3004038d2fb7f", "fe35de23fa234b6dae59ea82cfeac3259eef5f8d8878aece906a9e71121ed71a", "2d73b8297e43e4800b22a92a402fc7fd9298cf4ae76b7d48a97e286d6833eb75"}, -{ "374500", "31b2c402de5e4f0911f5d14b927f38483fec9234b0ef67efa026a3648ffd12a0", "80a419a3787c4ab2a27cdeebbb020eca8f63743beceb73559c09297682c46475", "b96f53cb6f434570c6f019f74824dab40cf8df0874c43fa257442b69f43915a5"}, -{ "375000", "1673933d5b2d1584e3c923b45bacbae604b308007ff19e25999f5a1d89afb040", "cdf2c192e290686651e7f63bbadc54d0d8f7b1d2f7208a097807de32159451c2", "c5b8ecdcb1e90452677fbcfcdb638f552e39c9f1b842b5e7bce3ffc104aeb718"}, -{ "375500", "6b35b7e04b2d788de6e2cc8909ab7fc5470b385905dc0e7b7b8524ff57d7d7d3", "ce795b401b8cc3db0def999633c2835436348b032919c9123e1481800aaac88e", "16d2091d9d7e6571a6a837e81f4000bbbb3057e229a8999b69ca532e068d84d2"}, -{ "376000", "9a2ec84dae6c1b6dd358c57205e0858d987b68bc1e029cae1b8239ee5ac181c0", "d576e0d718d3f594ef61eb7be25e4083d1ead1201fe8eaabad00c63938144f85", "87b22143efdfaee0e8bcb0ae2c50b0c5b70154d0160e2718f9f6deeb867f86e7"}, -{ "376500", "bca044a02b4bd78ddd32eb668c603f16f14daaf04cf3541d019d3421868a14d6", "9abdb75f5d7bccf402e2e02a07b5e6d5205822c4ff20ff5531d29d4a8cae5d4b", "d006de8ead0065377831d34c519404f011d6543b4c0c07ffca21673dbbe73554"}, -{ "377000", "1b4b732e1f4b18b744aa40196b7bc5d3e1074fee1beb4efc674e38f16deea7e9", "04755ac05c88590c66be5b72ea85735df901ee644ea1f35772b82bf18c2eed13", "ace5a8992ce6a0e9649e7af13c92c8c8bf94fec2c9b7c919e885db7bc4e84544"}, -{ "377500", "a51b1aadb6f280e7c23ad430b8c59c8067f0b8dc10a0be61666d1da71bcfadda", "d8eb0789d6088438ddd828d02844a644a2102dcda7614b262daf994437be74e1", "504975ecd3f6a7a4d6f76dd29393a289784ef8031505cde3739f9eeb6439502b"}, -{ "378000", "82f6ad88db9e44f44c837c7a117802a6bc4379ba9141c4faeb9e7731bec60f35", "8c48f7630228d3c0322986552aa96929eba1314f8c62baeb801b95cd3cf400f1", "9a8f21d53b2e81d3d6a7d8cd55679ac21a6301d399bbda5a3edb394b915d5c3b"}, -{ "378500", "c2fbdc981504762cd306473faab285e108b27bff83a84a1460bf513839d9ee93", "37a18476810b603df1cb7efbad84e3b49a24676073397977eda35fb559e7dca7", "2a31aed6c09e9adb08dd67540fb0f501ba40d18e7cc3de9e22a0ff619637cd1a"}, -{ "379000", "5866ea5d40e02e5c73a1828d3c3bc5ffe23f9702292ba595560908f66b23366b", "ffd0dffc4b8703364b9885055b427f2bea2336714ad4c5fe567e1efbc8fb7b62", "153d00afc4ba8d2b059e818023870686c13b43cb1bfcdf00175a8684f178b673"}, -{ "379500", "2519dfa5eccc5f59b59c89bf35ecf2aa0f5f8b43ccb098622def88dda5177b36", "56df546c0e7bc87f0ca01ee62f0d0939810749cd5fe68fa4848f6f302052ccc0", "e1a9efad3f09dfd23d883b2eaa6da604044947d3d7edf52384d0338288ca5156"}, -{ "380000", "7bfff4292f5f17bc71f6763e2257fa585c6d56470390648079609d8116988255", "e5c4c441e3a8f0b5f55bb8f5ad18a9bf4bf04719a558e2b954109e5c47cb9896", "334f5b20d53e889991f7770f0ab58c442dd11a7bb1f40a7c02e95265f290bf60"}, -{ "380500", "386869e1fc8e3f7d6aa8bf28caac3d5a344330e974a42704885aea3cb459e179", "279bf20f5fc0c66f97256a42cecb4597dfbee3eda52cc03c01239d2be7ce0e0f", "9a691875fc9f4d84829b0569c3ff9654b4a79121bb3cf31fb9238edd27d3a2b2"}, -{ "381000", "86cf8da3f13d65311d707cbdc932a563a44fc12e1c43de337583bc0d113a5a03", "733b60f69120d3ba845a388871c75cec4b4e2479ffe31d83c0bfe980133460a0", "8f7bdeffa5b735d5114b7632878fe921080e42b1064794843fd311e95ed31a6e"}, -{ "381500", "3ddcf06f6b302ddea992508dc99ce57c1a7922d05a89decd38668c974c0d3d41", "145aa998b1e691947f9e9c1f9d7bce235dd64fb3101664f2c310b59479a49954", "eab537a2ce29dd0d3c7c7154f83e505684f4cf429235453f8f69e362f6ae8cad"}, -{ "382000", "5cbf96c1818addd8739c3b0a928605824a71eeae2cff1f520e644096662c6d95", "0282ec673961b684b9c2c43f17dc47d7a1c4128a19b4dde559103986abf4ca50", "ff00f371acd91a3ce59d3749087a3879ea474f2faa3562a22c4dc51080bff089"}, -{ "382500", "01447f3299aee987ac9c9294682b89f9643f28bf18123ce8114b3ffdb6a03c5e", "8a0e1f6c67098b89b81bb0769c520cb50a87299fff5497a87486417b43efb9f7", "dada8ebdae71dc3c94c923dae9dd4c90a65e2bf99ee6c56cc19a7d8e0daf0c88"}, -{ "383000", "d5efe4b385b101b754b2b30f6f99c2bf3736e9fd0e5a06d0b5ed3064e7641852", "245a1712512d17bf19156fd5288ebf706e85ba49278ed03c2d506364e7002e08", "e0aea51d3797945a25c74a6ff6a3ce3c78eb7ce94174af5f0cce318551baaed1"}, -{ "383500", "5b88888d1abb320e7d295c00a15bd74041ab35850fa768a8786d2e0cfff0948e", "adbbab8c600e751c331a054924b778213bef9b5a5e23f3d9ca8c9e3b877d8b30", "405c01bd1f9ebc8c3d667d84b3eba5d07cd070d0215e53b92592f38ae7284be8"}, -{ "384000", "def1f25883b2060a7b02f078b184a1fb50ebc9b9ee8190971a6315386382328a", "31cf28e8a9ff6242a0e4c9b2ba30c018acdf9279b8326185516851a41a15535f", "f9a34cd72e59a3f70cd776298fe2d3526f5a8119f67ea3b09d88d27b52a0bfbb"}, -{ "384500", "a08467964a472ee61fb3ed6b622acbcec35b4903251cb99324f14f2b9bba7545", "720e5881cab3613d6baeb94449d6695102a1e508f1b456ab03d2fdcc32486ebc", "3606653b8ce7719fe8ef866128c203d2c90d4b7be4a2f52e50c2f7d1b55714b4"}, -{ "385000", "d460b85b1ac270fad347a02c19917b9f38ce22c01d8b88e90d0baf63f011b117", "b207a874a45789d7b09e0948eafcef8b76c9184aa370a508a4bafdf9d26ebe29", "6bff034cc5d7f348e854dfd1e6abd3ca4c093d2eb766e821dbd03196bddf76b2"}, -{ "385500", "abe63c027a3d085071de60832600c63e46d78d244315facbee6f0f3fdbb02912", "7d911e4630c29d4daf24ef749a17d8b7276c4c9c3f6194c6b0176b4b5f9271c9", "51f3e82af0c3aa29b7af55ae6c7d6a15ce2a4ef6f84897bf464844342fb33162"}, -{ "386000", "656989d4c67537591081d194c31766bbd9fe449159aa2d3037afa3fab0f74a82", "bb24425f9ada80398f6b1e4505b1f6eb372966389f0805b22f2e2d8607aaa38e", "0bce2fb4e1c88f8403597fd89d31cd90fa38d25dc5f424bdbe13fdab85840189"}, -{ "386500", "2c055ea6793d46b622e43db2f1d25e05558f77edab26f4b1b200bd5aba514747", "17499e0c656152df6a2d6096c5dbc50eadc4f19ed4919a04aa3a5c06668f3acf", "736428b80f27438e4ea2b83c014253bc113cd7b342cb6b95aa60f2bac6fb835f"}, -{ "387000", "b25736d7898a4555b0e257ee1e4cc0a96c1275378dcdc0056234846010c29101", "15a65bf7b60e7729a9c9a12883b882eeae58af6b07aa9e1e4b7eab5775de2154", "2b9ec63bfdb56932f3216fc47aaa17292283cedd49a7a04cc2cc41a93a67b7d4"}, -{ "387500", "623ea15901831a8ece8d44b5da072e281b237a693fc3524b523f658fc4ab621c", "adcaaf4a4184c1719060e828a12933ceaf54184d50afa75118d16df5a67aa578", "c749b80575fc01e7835631b523a4b934f5935963d5afd277c86ff797d3b3ef53"}, -{ "388000", "91bbcc4c97dbbca8f88c68abad1a68e91c79f337a0bb7e14180bc2ce92eac137", "21bc2be4b2c59b991ac29c2266fc1cafdfe59da48e957f3105f8d45fe2284c41", "ec34df2e57a330cca8d7620b1d9353aa79ee0f98ca70e3a92dca3df2fb9a3906"}, -{ "388500", "8b9552c05fef1a291df8a1b47d92229429ba2aa1c3453c274bdbf8d3c7c4fc92", "f146203b047b7ecb750434bc317aaa95adc82c1fad15f35b22b879325ba38958", "ae8444d003815306abd9bda668bae4e19f52160eaf4b4f3061351a154f6abfa6"}, -{ "389000", "8e938a51863daea6ed977f9068092e5764c7dc9bb2491ac10291921725be7ef6", "ccf2ce60dd83f9dfae647c30e824864a5c208ed5c8837420f30cbbc7caa3638d", "b2c27b0f52a80b2dfde788ad620baec4ddd7f933ee69addefe33acb1dbb93483"}, -{ "389500", "7505772f28c062e4751b5653080ccdf943181e5f0419069bc20ee6255c2cdd2d", "a4080018717b150e0384c0cae9a6500dac7779a57565cad365483cf79ea99a4a", "5ab9117677d99645546e9dac7ff3fbe6f7d5da87bc9fb20b5af6e7b958a35409"}, -{ "390000", "6f4b50c04bbd5aed6b57f287a0e6d90a11ea1571dd3635ca9b6ca6ef541cbdd8", "b408a6d6415251b4b6ab6db5ae815ee07d0dfc8a8e9ac22c44470916d7d57ef9", "0361c1a625b6ebcb9300f0b7885bdb81147b83ee27595380405330eb84ce3043"}, -{ "390500", "b8caebe933d7dc40b9648b530bc042f1f93f4a1bf6e1530164682a1397dc1aef", "192645f2fce9e3b4a7398c935db6ecbe5b79d25d8557fc5ee13d1a5c95fe790f", "63bf3991947441745874d378da8cb9bdb65dbcca2fb0b4f67d1459e23f803333"}, -{ "391000", "0e6e6686e469e5fe43fe99fdfb377dc48f85d7892b9aa70e1ca46fcba1fbc940", "face758288797482e69de640daa24de10d7a35e17e3b575fe147d73666fd0b75", "42f1717e6dd23f095bac64c9be18b2530e7d0e00fe093e6fa129a63a7b853216"}, -{ "391500", "fd1e752770b8e555108d7e32c8f6c7e1f9b8dfcb20502babe4cd541910a03b68", "89601e3e196aa20964f326b166a74f7a601174815ac89bd1c385a464cee7a54d", "8b2f34e08e98c276848f6796daf338c2c08647b7048154327b0e58d4a230b52a"}, -{ "392000", "529453ab5db3938d1195a3ef84c286e8103c42b7b1b25362898674a66a48ed5e", "892462e851252b9a2ee03c507d1acae80ea67d360514a4c5770d7ce0dd3e1f54", "8270cbb4a1814555b8002dcdc92547a98b5913175a4e255c0266cd5f03616a0e"}, -{ "392500", "e3a3fd9781e171e256dbee0afe8373a2be01930182de5bcdf501db3a73a70952", "945a626198abde6c92ee9304cec95937cb148057692f8a6c5080e0ae930be61d", "11cc890a72c56df46f5237f6fd4c2a537949fa53ea0a065dd6a16996c7b22af6"}, -{ "393000", "01db0c4add701bc81282082aacd1fa1ed032967c1ce44c88a46f22f09a00af6f", "7b2b867b0ac1dc90aa91e0b88722f474b7d78a3322ba125ce36d0ac755b2c3f9", "7f916ca6a85ed98b74f5be9ee8c0451e63ef3e9c91573eb295335c2c27a2ff47"}, -{ "393500", "c045647644b0d7daac826a34e5f7cdb1f55a4cb4cb5500c16ba4791a8f46433b", "8985e0f86f19a7a72fbe581cab68588d1882b9a4b1c236836aa1e559612692ca", "7361778fb183e94949e43aa335bd2a472885ae10818d96530c5fa6b4fbb859d5"}, -{ "394000", "7336f022ef425203978336336066daf7f85850fd1ca5ce2be57119543211b7d6", "6f1a7d270bd2cd756c02d24aed1e33fb78042efa052bc7e710cf37a60110bffb", "ad66c0970633f1c1b542a1151287d4551e83392510c0a30f6d79b090287134b7"}, -{ "394500", "2791b8c33b59179365cb1f1e97a71a0ed8c4f9dcf98105ca35275dbfde1b8213", "8b5c24c27b2fe79353caa4f2d7548591db269b31c1c53b5e7664a47ff1646a33", "53d2c4e4243d4e00d6b332c4ff257d13c51190052f4c0c72f82ddb0b06143ed2"}, -{ "395000", "b68a97351f28549882241171a79cb58a1ae92d93a30e7524f3580dfa69bd70b1", "a2d0161bea0620be17038a96a9c21a7c5ef08df89362f1e82ce8de29187735bd", "4e5f889f7efe01700e2103a125cedff7286bbe6b270fc8abbc17ed614ed644dd"}, -{ "395500", "f674116f1af73caf4c6d464f99d55c1152f7529c15b0d28a12f35abc1553f91e", "32fd584340a63818498504c5fabc21fdf3feb2a4529a6b5af5d9ad67f3679b20", "d40aad5a5333194b1adde906913a50c32448090efbe02eab7e37df4b68a4f960"}, -{ "396000", "ded515c3d960dfe073403b321aae9d66a1dbe4a9565caed08c9314e8f1b1d2df", "134fcfe75781458a3899ad3330c143de491b74c09c98b8e95c16f79cac282828", "bd15a67e4b54b428e0c74c14e1fea888ffa584e9a323ec86e85672bb3061f7ed"}, -{ "396500", "b6745b3e2a46f458eca58083625f3eeab22ca3256087a45aa6457cdbe9999aa6", "4124109f22fdfc42c1343feb20ed8a93ba55cd7f65ac34146c3f5caeee272d94", "0bfea25929cab536e6128420fff5a11f559648af36cf6566d44bf1e87f116e2a"}, -{ "397000", "c79ef7c45f179c76254995bf3c810a62636c40d7283658c3d35f167f9b4289f7", "a6fe1a5721abe2a12fce95bc5f5e12a4185596ce991d6af28ad2cb2972305637", "487e1173dac8b4afb016d702dd349ea3e9f67d579e36ced25103d8242d2b8020"}, -{ "397500", "d36dcc0090a5585951004c7f9dd645a5a2daff1d97b796f2dba60c78a89d5a14", "a89cd3b2d93dcf17cdcb0f7badfe7af1077f916d6ad5329adfc38a6e1d25cb5c", "94c443495e8142bbea3d6a22e34cc6f8e9ec838e3cd9c4f61ae6ff170b7b90f5"}, -{ "398000", "2b97743e109f78d910532ee0f342b1c491ae74badc58085ba2a7b9029f9fab5f", "7ab0985407419f861b725834b5643d2666cbf5aaef6aa6eb94dc9e35c0f630cc", "ab4a3aa2dc717532967156a2f29cadcdaced3564a28b3f2a2bf5387b9f961c2b"}, -{ "398500", "4df2d83b00fd22751d5fc8b22743c9831701408cb9b788d86bf081c666e389fc", "9c545b4c3cac0e1d1f9fecd92ba0f7c61ac3e8a28a8c973ff6026fdcd90c4a43", "a5ff589844dbde9cd52951da27d06731785b5bec0908d7dfcf1703a40a81855e"}, -{ "399000", "6a00c77818429d3ed4b9bd5211a3cca69cf68c9a99a89f9e1f9e5301c08afb03", "44e27a5f4e4c32f6698257f5cd63ecf165cf4941a94f7473f3995b1a3a6bfd82", "3a870921ca65e9a9bae895a4a29520a70a4f3ca8178117491427be7642070aab"}, -{ "399500", "a6e49cf1def602b4915fbc2b208490f5a84c8a93366582f77ecf5575119e6cab", "83be829fea8e1ec65f493f3910ae0f3798b9fbe006e41df4bd927a9bd98f3cc9", "c001f8b45cf32c6503760c6905278ee2d55f3035b79c05307b9e446d1f2a5bb1"}, -{ "400000", "641c6a53eaa3c9b94e924327e70830770397343d7927eb713609f14448ea6228", "4252f178c0c42e28cce9ef5c0c40f08bc03e3b631a393de6eeff90e7b4d26d38", "b1ed7a8cc5c9177b8fb8754170251bca86c728a244cfb54b7c79fd84f025021d"}, -{ "400500", "73e034517c9649420d36a641130bf16b8634fd3b2568e58198508e65def1fa37", "a13f2b06f4b1b3daff6c10571f25318c3ec8e9f2d42c59f4f19369bcbff62da4", "f3788132cb664a0e812910995c536e03da19b95e03d40771fe6a7094afc1ba77"}, -{ "401000", "b249ae5082bc1eb852ce420a2361be80dd17228fd17c709761d0f52e81e8478f", "679e41c907f1e82c438671466ce285437ba23fa2c845d8c07b43af0829692b69", "b5c351cc2ce12bd45cfdfb989b02ab756db45764b8cbfc5c2214ddc999d606b3"}, -{ "401500", "ae40fda2bd776861208459ccc6f1d205b769de518dd00aec84f87811e006098c", "2cb9da6c40cfc83129da322498da46fbb48f7509d66d7e5ad53b6ccf2723ab83", "0e79cc1abab489be666493ce7dfad2892c158847d6abfd927febeb09c872671e"}, -{ "402000", "53a37e92887f0f1305b937538e060a4626675b361a28d8ac3cd88ce7c16adede", "d8bd6aadcc2b327c5d2ebe73f48ff2df81310be0b9c194cde8fa5aca004874d9", "4d93737748203b5132bb1b9a6bcf4d31d2515b7ada13ac68cdf08615d4ff9fff"}, -{ "402500", "54008c3fb34d324191f2e8790f68e097dab91c9933bb83566e2039abd876818a", "cd1605e18479c4a48bc76ea463608f2c2475d5b3d603bf9ba7555194f6a77d73", "f19c359ce0f426e59bf440bcc5b38ed78f44d1f000ac11122d76b49453eb4800"}, -{ "403000", "7ccb2c59698108c6ada2be19fe72a1be124c9650abbad735cdcd1b07fb5888c8", "208d179f6a09f352c3ce8c445468340beac166c28398132d642afa58cbb06fbd", "54497aba52a3092e6e944fba240418ad695f9f9501e26f147348354ca9b6c765"}, -{ "403500", "4307fac30841a99cdb606d9828cd6a920da0155afbea4e5ec770d2e82da4a850", "b6304f7d096028bb882b39de8ab14f625d2ae63e4c597d34fddbaed7c2b9f526", "21fdf4bf6cb0121101ae86c775a903512837e720dd1f2ccc1565343ee99642c6"}, -{ "404000", "b7845240f6d8ee0cc32e37d8682c587dbc52d07eef8c1b1fa38f73428b73afa4", "326e6eaf313513e4a52cfbdbb0106538065a4ed8fdf3d0e7eb6e00ba46037af1", "4174eede9b7fc4e01f1c012643298afca39ae871fa781430fe98890c0e78796d"}, -{ "404500", "73ba4ce92e212342e14471f4d85581e85c402a55671db59282110671ede03341", "b2af723149653ceffb01cae05de8860e28208128f215e3bd8bc65c7f2d03de41", "606f423f018c4abecfd83a7075225f01fca721dc89525e76d36650169fbe8248"}, -{ "405000", "3b3d4f18a6a63daf34505404d27dd936531654047b1dc9d1b1f864c33f7ed996", "b6287250e883b8c416c65541fbd8cdb01e7d76f989f3fe3e2c31b762d9c3269a", "f4241f2c2781ca2575187428bfe71098afb3db7e4a8380b5e3d4a92edbd0bdfa"}, -{ "405500", "74fe48ee491e1f7e881a9a5918f1848dbd129b08720f0c9f2dac17dd413454f4", "d57fd78c8080fb6739f260c4117e08c2214bd1afa6c4244bc16fdfd04804fa76", "5c80a17d894fb620e225de86352aae89d34d93533e9d44283dff3e70788f9180"}, -{ "406000", "81c002e0fe1d6089bc83dc43cd9d616138fb16db20f8ff9dcb039a2bf54bdbd8", "7e37f0088205c718348f6f13211a98b16ad8808ed51c824050c1c3793562197c", "b04710e9e4246dee4dc6be1151401dafba18618997d1b8ae0bf4de1e5b80d3f2"}, -{ "406500", "20aa6245826270b507ea3aa44b5360d608e2d52b20109dc81a63181f9727dcfc", "2d722a96f3605f68e844eaa0d3629408e9e20e8d5d095d33c435ea2427420a9a", "6fc4b43b79a0b8b6c35ee23683a9e4b8f38d1d766a5ef21d007e8783fded3409"}, -{ "407000", "51c75ef8115644c138fc20ce9af7b771731a1efd11231c881096fdaf59591660", "11b150fec2d433d57eee04489446c967a692ccdd64fb6c90f95b150f6d5ccaa9", "1874e943352cd0c34a96faf793f3eb4ca1c7be75e2c7c807159f0950fb2cdc7f"}, -{ "407500", "6f24e1c00195775eda44acca48e654190b2a9cb22f2dfca41410ce90a067af16", "8b49f54e99a2096f0ab8dcf8f22fe21db789b9bad29e43edd3566f5eb7045b5b", "6c1f21da50c16552a04055b16753fbe51ea9d024a98fac7d886991f880aa2450"}, -{ "408000", "ce3c90abbc8da7ea5c5df3c25ad6fd3a7fda496b1e0f696195bda3e6dbe7919f", "a5a21a4cbf89271969f43d9c808706c6cdb624daf4e5250d6690d40bfef2e78f", "8759d76d04358bd628a1b6d3ccef5583ac09ea3de67caaa33dbb46c96d276925"}, -{ "408500", "ff9b888f601e151a141d92abe7007d40203e6cdbf107740c78a4c1c715608626", "3a6e13fefffab34b8bc11418f83163112c871b7483b6cebaac9f9397b5894976", "a0908b7c3a62eef624fb191bffb175c01498f593b7d85f0aed815c016eff40a1"}, -{ "409000", "7f3914a988816ad71eeabeaa91e918ab92df56753de139ce9170256ea433c610", "39c9ca62d51e871cec9c9724f12841ded9e81d1b684ba9bbbd118c4d79675e3d", "942ebd81ade6be2c6bb33732810c9e2b351d2bea484338bc237156270ce38dbb"}, -{ "409500", "e3fa8435841942ec88357b1e3e0c33702412a83b07c68589319064dfdffaaf81", "beda309cb0d0295f165e7ff4168eeb205c921f202c3c9524960152b7ddfa00d4", "4058bcfec1a3664865d77e828c6b832891b2d1ec0b57f210d53d59bd31b256f1"}, -{ "410000", "3ae6fd96e35b4a84bd063aaf72cb8ce5eda797e213dfa856008516a88039a94d", "58e69a89912f506e6f4ed9e89229f9d81113cdaeb5bbd120ca273136117dc82c", "7d997c8d8ecb9a4d6585ff3c93438fea372a8896f67b45ebdf524128ae1382e8"}, -{ "410500", "eb2bc9bd04d8c2c4ccfc4096116e390bd407e98f0d81b2a7a1f096ce0e86336b", "3a87b4d2e3e1c6c5171edf685bfbd0694f293987197b33680dfd338e3ecb4b98", "ba448dee877fa01c76a73f0777778d806ca738030a64d46bef3b9a4eb97d39b3"}, -{ "411000", "a57f32043fdbc1b8eabab9e66fdbb7f40066ea9e92d3b1055e7867faa4b73187", "afaf24d67374beb37bf9b1c1f0e231ba901b91abae33f81367d55bdf78e1cf2f", "8db864625b2c002339a7c5a7e1a50f596c2c22f6304b0329432fc787f19df836"}, -{ "411500", "ea48060ae79a850a73fb9da920ff9d38245420ff20fd71ee09f5e1411c53f60d", "248238d9ddd8abfa0b502311f3e2b21f3e5c5b75719915069a209beb7a1be710", "da02af0658237703797b8a73fec8e7ab7f471ff0b312e152c1584720112ba9ce"}, -{ "412000", "aa2691852758d5a285217fe3a9bd1c2d29a6d337a0e350abd60809cecfe3207a", "5a3ac34a9dfcdc2b17eb45244fccf0fb4e9a843dec6c6f76355c1a81b16f90f0", "84e9cd8662d95fe81e421ba6d02268febeea187d3b710fc16490c90eaf4bccb9"}, -{ "412500", "5a0807ca910611b9dc9992060c41491071f17f9b4f71b8934e8fba9cbdf95a69", "a904ce16e3399f6e8eca3201ccc7fe5b15344c4bf306f1e63da4ab019e0d9582", "3ec35eba33a7ba4d1fdeed451986728b0ff9f9fea4b407362a9016d5f6ef2e46"}, -{ "413000", "6b93d17d702eef90b2795ba888ba49dd4d0d1545784e5d508bab8f3f3700be79", "20028cf3dfdf9af6de78fd6ec4f174f46a617f2d3204ba22c3b487d3cc135be5", "fc86207d5b5cd24f4948eb88cb46b669fa563894cae0997ad41194a7d747ba24"}, -{ "413500", "1bf2cd60f8c697785716c23db0c3588c42528d3acd6a8427311ad176e9bd3d71", "b6e7e1e76a68c20f6909cdcab53f6e820bfbe896cf25a7e435a52ec6c2c3bb85", "c48beabe0f4091cb2123d6eedbafdc409d3a6902fd3a7fa47aebf356d27da31c"}, -{ "414000", "ca3778a71094657cab8c697bb6d36930a875d3c76fba72194abcd69fa5c17703", "02c6d73c2091a860215de5aa0741c1396c9fb5334dad2786f1f483add87f1ce0", "2262ec877765e09b6232f90ca1cefb23eba57935ef49a9219b8faacd014f4abc"}, -{ "414500", "97f6a6e7e49a245ff3e2acf4c2882ec0173994a21c619f7a384adb93804bfea7", "79845ca1a36820aada03e8c46de2dd19dacd64131d91ea5c102bb90df653cf6e", "4de40e1303bd9d37f007dde622c1cc446dc537fc6836cd009b94ddc437100077"}, -{ "415000", "e68357575afa23d47a2a7fd4077e14d22e51b786c8866042263c42ce2f6fdda4", "4cf1d285f03ccf0ef31333c8b6ba0142b54791b826f29ed619266270c725b070", "1e194249fe3404efdf742b982dd74c828448f9429be057e0eda060065cd1d3e0"}, -{ "415500", "f975006a0b269a3c5e89fea165ec1821ab21dadd0e95d2f372428339a09b9476", "a2e3b1b7b2cedaaf531168cf85aea230e8a27131f3643f15269cd8b7fb55387d", "21938ac9bc8bc929926c4b7773a9a002213bf132592e682772e67b3d1baf5d70"}, -{ "416000", "27ac3cca7b525e4bced3bf89072f6df21ab97f85317dd242d9698a9f695b3d29", "65b7175c50d753059f0955541a646bb523b47f1fa35f5d3d86ffec0077e5e6ec", "318af64c025936fa7c6d9eac3c43ae98b361eac10481b35cf03c96c832eefc8e"}, -{ "416500", "c3947b6b74b100c5bfd70c7cf1baf822871046f3ebddf211f20ac0ad00660851", "ee1d3925d350a9da5ee86bd63c792406dc6a1c70fc0d286dda655687a0b83b57", "af9acad2158b709dad09721ff0df14576b6d9fa44f6c8b7534a53bce657f925c"}, -{ "417000", "cdd42386e134f3cbe56a5b6ff14b08dc50a1a02b70278f20a6982517868c7613", "2f7eb3c08a36c3d1ffd90dafc4ce917e3b44fe62e8f545e581af01a2fec59891", "a77c8210926d9f7ff84820ef7760888206d1fa7e6fe91891f280232d515ef087"}, -{ "417500", "758c5ed9fa53f6a940eb15078bfc3300f68a45174ad55b6d754de04344db5dc6", "9d180ee51efbd082e027e34d85c9002b72233e99014924f3b56955f3dc2ba17e", "bd9bbb6cb9e629aac281de80994cfdd3397acca99651fdde653c906300d4ea38"}, -{ "418000", "de38ce06e6f7c0509fb958124422fc1e0711c318d7fd1a0fbadae47352ec0eeb", "128c492324c57e30449629f7a9d475ccff48d077ccb61dcc5b7f91d013d89337", "5081c305aa4c0327fa8cbfb020382fdc0d31b1925a187b06b73059cbade1f026"}, -{ "418500", "52335906771b9b38787ad4381361b609d5eda9864ca2a7d2d22125faecbbf76e", "192a8939e510e4b270a3cdcaf4d5ae7379dd0a20e4addae21c2115d0bcad0d18", "4002323d26b41013d1ea056ce4e1e2f407ca07bf38061d02c0041e8196963d0d"}, -{ "419000", "d7718cb6a671d3e323e7f8c85b013f8f46dd89353a6f77672806cbddd9887379", "ccdffea8a7310aadb5f103ae277ad075b9daa876c08f3bc4e13ca1fe85a400c2", "38eb759cf7d0b9fef659e9c2640d71387e762d0d0c35dd2d9d02b92a490ac4fc"}, -{ "419500", "311eb00a753d20b8c4c073eca48fbf44066e4c97dead7b0224ea65d24dae43e2", "5d4d46ec84c96ba390f8d1ab5cd82fad5d412133341c4ec204f36a47462a1633", "c08cf696bad8203144615527689a09db37e35b54183571f36a15cc47f422f2ef"}, -{ "420000", "02abe9181281799d247884c1887745c6aa80f60a1ceb12693d328015d28b5a84", "c5713fdc696198d00a681a1602a8703b724c13362bf059dee081747db8c31908", "a2c34ff963efd864a186e1dd9c96bdc75abc145341e129cae1b1a4227d506b07"}, -{ "420500", "f24e5019cfcf1f0612785511437fb2eb94b0a44ae6207ff537b07113a6deaa5a", "4c49208f8e5513b0dd1940c861175e2bf7bba04d6373e734cdac63237fc24f1a", "2a06b91a345e95c498468479da44100d4eb31198aeb0473d902dd935f2c89f0d"}, -{ "421000", "0ebae57f2319ea062c101095eb8c2cde71bb38b0df36fccd23fe6d5e40f968bc", "7c50e4dcbe642218c07f3bc8df56974ea197f1107b9b523cc8d984f1903c944c", "80200e27ad1a99c9b556577e4a7183dbe9a9d87a89ad2076006ec94d9864cca9"}, -{ "421500", "3a65fa88661cc79145ba391c18d2eb928842a9ee2642c757b3731ef399323e13", "2dee8bda6a09ea7ab0349f743da33dee3614c069af8977377a94bd87d072f131", "219a15a9adc94181afe5c2b29532613b8f06757e90b3e83ab418365a7a993730"}, -{ "422000", "030b699998f98d4b331ef746f96eda057e7a454f98765a0b695d16fd3e7aa44f", "9b2c25f8a003bba7778aa66ea405ca0a7d1b4d1a44ab35c28124d0d147a731cd", "0cf658dea39d09846e7ef4eb06df6cc066e8160373025491262efd613e188942"}, -{ "422500", "44dd126ceb8b88b2d3d942246ec2ff298ff07890fc75156510de8dfa22c121a6", "fa987f8cf06191b45925bee07fa035ab558e651c1b94d1d518524db426449e5d", "8a32b94cb5f773f48202b8b15150b2a317badedd78d46118281352d3ca19737e"}, -{ "423000", "93bc08b4a0ce5ef57f63ee483936125540dffca3d9d6aa1a24ca2f69df2e2100", "a02f084ecd89f843bf976fcc5f5c3d7b9a5c2b5f549c12b896f4985f3fb18f82", "28fe299babd0481c8eeb2ea1cec2f68f82ab85f571d104be8d33943008ee5f31"}, -{ "423500", "4a09df19634b6b11e40263176de979e2aa0b3aca1a95825c3ad7eac2a84bad86", "1a2acd078f11b82d5bfc43a088c8ad652ac993c2478fc2469859ee4885da2ef9", "dbfc352c35d85d0d29acc20be05bdf46ab6e6772d8373a7f43c73912d1b803e5"}, -{ "424000", "bad4fea158757021f14bfa735be04d0514bc3632f96600b1e4d632efc33c6238", "ea4dcf8ad8122d652811cb25f7277c96380f8f3b1c839f63d8085d1aa69f5f89", "e33554c749df7d7bd996e3edd93461887d2f891cbc8ad2d8a4eb39604bb40c32"}, -{ "424500", "bc5a6d616947f853ed4f4d9737fa063959d32b8acdd92b11e27dd47b435b38b7", "335830fefaaddfa0a3daee3b4ce06b16ac1930cc7b2411dbe831d3c518a520a1", "bf4174f8c15c19be02ce4152174b1fea5ac4d471e854c80dd226a6dc098c0969"}, -{ "425000", "5b30049913f1ad030235ecd4deb6fc86120b8206e5269d39e56e6c5f1bdef8e8", "40b7b38eead88896d0993db8806af19167c6c2dcaf989e571a90cc689568e9a4", "81374c7f070937999acbb9c2f4c59cb64f5d477fd823bc45bf158bc54bdcc9f1"}, -{ "425500", "1c8c6b6e080abbbd1aae24639ad147ce9dcfb2836be1a4d5520ebfb3a9af61f1", "c6e3bb5149886a4050a284990303b89355967d534894ec988b9b9be1f451edcb", "15249bdd6d51cfcc7470babf6556d8bfd2494c18e57723a4974660afd4af2554"}, -{ "426000", "9a644de2cda849b362daeec3da5cc28e71652c6a2bbf37151d8ec938e728f2b3", "a38d8a78768bea93a802d40ee5d92753afeae17ec5c625515512f4284d56eb1d", "d1c2c919b2a3e3615ff340778ba6d3bdd2d0a177dcc679ed3f27cc28a8896731"}, -{ "426500", "4b3cba7009b8a7e4fca74996822c10f661db865afde3ccf0335607d549db29ea", "91b61ada9596f861c6ae77dcb3f1da3ea0f39dd623b58910ffbacb800448a8ca", "6538ac7b92c96a890c9024ef1072219dea4481c7d48bcc7728f83a54df8d47b4"}, -{ "427000", "6c5ce8cfc2031e16ddbc1da1b7854aa2b45d1e3a69f2fb73bb14d74a34c702ca", "ab6ed27075246d24cad1577e05b7c23f081c1be76318508cc5f08aa692ebad22", "753b425d2acbf22bf4dfd17eb1a76c9b55e0ca8f9fe4b43b89a2094e91525eec"}, -{ "427500", "8156e4220e867b6f1f988b354b5a96ad98b7f7e83774dc658aef3cb7113d274b", "f8874e6dca4d1a2e74d442999c6f47bb74a49892a0d9a1894c81fb7d1c350f40", "93438b999660e155678f757ae0b6940dcef316dc19f7e9d028cd900a79cee091"}, -{ "428000", "8dbc7ef6a382825ff9af8347d23569898d687ffd3743285297278cd90e3cdb13", "21978c24fad677e5014f13ed54d547eb96722526cb52969673292324cb188b79", "bbe888f9da80c32c1e4c1634d5261cdb85b79ea5626355d5fd8d3ae8bd541d87"}, -{ "428500", "cd56d45be8fc1eef02a601ff132566ef3537c7a69f67f2d8ca6de2fbcff16bf7", "f0b9826043f778014106dd4bc0e5429d0f217fce16e401a42ed252b1d2ea6551", "b61a9c7bfe67bf1866ff00fdbc11c428663137f8df30a61a4ef4d347a75fbd83"}, -{ "429000", "4aec842c5e392ec18423fe3735e8f9c84203ef54f2b3dc837100e42fba29dd61", "5e2a8cf8c42f6cbdcd136ecb5386e02eb993ab5314fd3410354159cb6497943c", "3b1e20816a54f52aeaf9990cb09b894bcc8c0092304f892cb59e0586951e0031"}, -{ "429500", "24d33bfe6e7a8694630a848958175d99c8c5a5fc092437ca95edb5e8f1aaee5c", "dc92e71cbf3286ffc80dd237cc7cf5ed769de81324291bb80548a79b6a12e354", "2255d534152b8491818735d41a74246953cba35c63e31e1219e964ec80d99f4e"}, -{ "430000", "64e5cb5e05477470b8068e35326c7e6779e4cbb740cdab675f60a3048e15fc25", "c622476e2285d634a82c4720d0a864b11332b9e00c3379f7001f28608c1c4817", "25f4ad4b2d4d171bcbe707177e7e5d460acc32dc1b9c95374f75bcaa8422730e"}, -{ "430500", "c7938907c4845919f2ec22dd7ff432e7e3e2429e65118a11ae5f2fdc1f5d9ba4", "5b34e827fefc85f603439e3367c5bcbb63d94aef7f5389c54e10bf41c1149d09", "c952e2ef3d66b2e4d422deccb4b16864a66b281227b6d895ee0688a244ff160b"}, -{ "431000", "a1f4642fec301e246762ea675616ba729278569d221b83e0fee38459ebb157a0", "449b183170ba71bd90a2cf58cf0fa0a61ae8d86fe32075dd4b9e80c0a3d8f365", "d7ee3255ecc8c054b8815feb6f0a70c5a5f6ac4a518998bbe54cad80f250acf2"}, -{ "431500", "012e1de4c57ac640cce243e1577db4193427c285579d43614463815932e6f227", "c5e13378fdc635b4f2d4dc61ee5d1c0ed7f60850a9de87de8307c9e7e494cbdf", "ef50f48542781827d015d7b8052f505946f3412b66836e954ee3e0bb9e09d18c"}, -{ "432000", "e530822bbe70b043e108e5101b6a684e9b1d5c47a8d0b2e5ace12e44810097f4", "211321ba33cbfd213efb8e3df7e7ea774ea25fb24c82cb757e568b756472ee12", "9daf8cba2e949ccc6c601548dea3db3b2190503041253d14c27c80cfbb90db2a"}, -{ "432500", "c40c2a8915c595ad827fc5097518aaeedb71832cfdc7f3336789fd6ec0fe4231", "37b6a9e80f2b789d61060f97f6f7b8ce019ff788339de54fccb2101c184b810c", "0de5670c0bdc09dea96ae3fcf25e696695ad584481004b0ed0d0866643d676cb"}, -{ "433000", "c471b86324fb2df461084f3b3f91364c8e4e54b9c592457044805c9c0b1b1ff0", "c3cac09940b2a846d2798df91b2e697dff55fcac233473d159da02f5d2a8865d", "4c5b4f409b7791478132fb3163f1b8de1d962d776681f9d6792a2f64fbde1f52"}, -{ "433500", "7c83482c8fd9e4c57aa0dd75563c991933b314f3f18c7cc821204bc41d4c76d3", "4d6ebbf09ef39066a45d9157273466fc6e1b08f246396ad00ca6a533a4d08da5", "d71a19094986f21cba0d87a134122b9b739dced2d253bdb86ce0654d5515474f"}, -{ "434000", "7d3607cb242e5daa146bb817da979a8874bbbb9abdffa2cfecc546bef9a2cd26", "7bbd1335b9852ee4cb13b1d7285dc11f9c2867fbe267cc4b6c1b1a3dd6a15803", "5794e0fa1101da3c9a01f3d7887783501007ed3ad3b8e100f1392f8e4ba8625e"}, -{ "434500", "0534c7881cc8c3745dcac6942291cfab024520de1159d3cd1cd6fd853a52e1c2", "b08a60d232a23a137cb4808f3636128335ccd3dd10fdcf766ae5c20b64d8a926", "31ade4612e2b6643beca1290e1b393b6cacb155eb807ded71060f50bee82902c"}, -{ "435000", "264a1cbeeed20cb538b71b99c8da4874af707bdf7591cc37e8f2780ed8fda372", "f226d8a6d56c761d1f9ebb8f5b06414d1339c17889767ce48317564edbfb337b", "398bdd3b22c722cc65c029a5324d04124d341e4b094069cffffeef232092214b"}, -{ "435500", "410932e8557a564a226ac672c5578f75653ed84c4669f64b6bc29fabcdd90586", "a5c68267fd466a48ec4473ff1c904efa8eeed2124b7e4bab8bbf83ee876dc375", "d22821fd1f65ec706e2f4ea674026ae1f266c12b8493bb4ce16d8f1d0e446d4b"}, -{ "436000", "c153195fdfcf3938a5dd5ebb0d5dd0ec59692a8decf1184083679c46569b537a", "5d8daaa7bff2de12b5d9b428e84e5ba25ef9001e45ab728ec74d6a22c61b269b", "11f2341d723906e44683e681f911663b4273f0e446422cfb0512f56d93bda046"}, -{ "436500", "5e3b108e26916d2507a40bc30211948a0bcff8ce4b40117ade096cb5f94d22c4", "16754de8c6290ed9a3e8769b8a03375448921fdf847c7f1ed6d627e614b8f6ea", "56996116a345cac41199d917efed3ffa92cb624114ece62a086043a42248f5ed"}, -{ "437000", "06ad60451a13eb38ac6f9abd2375d50afa00d4d8c5dc1c2806bb5a05727ba523", "4960cb8d1571d7c0aaf33b659c0721fb84bdda17daad04f0cc169dfe1a22ee28", "dca2b15c5324a29d81dfe54dd537d6a84cf1bc0f5f97265766e64a467da8f1a4"}, -{ "437500", "2f14aaa3e58a32d5a3f17562b3ccbf8edc8bd17193a9a09af65052be99225a2b", "8709492c2ef726d995e4a2092a2d062a849450a00582ccf51fd7ce3905ffd2c6", "e0853cf80fea64c09107b6e12394b88dc4111c7fa806b65827b5421e75fd46a4"}, -{ "438000", "87d16a339b0ffda31c75b16f3fc8f7c45d0c67ed9de0bb27027524661b1f91a7", "c21254cce7d2b9df55ce98218ab9d20d9d2afc3a450ad1f3931e9c7802de8f35", "1eb9cf7aca7e18f6a95f0d1fcd876545f9ea02c9b5fcb7dcc311c9a9272ec279"}, -{ "438500", "b84fb753cd672d1622e7384382069066410f1c27763902b5ee2c919ba3f20bce", "075834fbe8e33fb3add9426e52ca900f7db370b85651ae10ac5079aae540153a", "2fc29d34f8d996a5f9cff1dffb49255462fc1edf5af8f42fa552a5abad79d40a"}, -{ "439000", "cebe0aac7f629f59ee1b2928d8ce4340b247c0c619e3ff53b369375bfa71abaa", "7e5fe6db2171c4040cf71a4bbc598983a4892689b7b8da5e3cd161ed7696a410", "3880d26f0e572013c1f076793fa1ee719f81db61a9b5b2b901479106f0a87e79"}, -{ "439500", "7a70cbc08418eb8b711aa13b0a49ca6cdf063a443a0aace6b8f78aa0c9bdc3d5", "c7107988cc60c6c66c2c9fce42c97303bfbe3d3db9ebb17da8416d0b1a918e44", "647b6cd53b1ba42af61bf2f6e2c6d72e0d728774129422ed96e16610644d05a9"}, -{ "440000", "7649654fe753d823dc09f3ccd2157d9e9849e534962d5ec32f5a71775ba31fff", "3670ea77b7e5a8750d63d8d846cc2e676e69539125ca1a3f66c1d1573e47ede3", "e96b220b011bf5948e3398b3831dee3c7e7df23a46b3f68450be2c1bc9eba100"}, -{ "440500", "9ad49b33c96384a916c19e0b7fceecc324d33aaa8fc45b5e48c661aec09c880e", "e594489948d159bafb11b9a4151a89280c37b8f5665d6d209766ccda296346a1", "9876c19a50263b8ae919b6b7c9a0aaedebf2b982c674319b9baca1c3e89e91bd"}, -{ "441000", "2a3a6ecf5d7defaaee82b14d7073402109769a5a8c940d6ee1fd35f23303bf95", "e8520de1202a192e8f8bc825b528d2fd8805efb774b18c4ab2f3dd153063a0dc", "7448a30847d0c10547e0d79519e363cfa2281b18003306968133c9ad2c25e229"}, -{ "441500", "72fbb24c48304e9daaec1801004fcd4bb4b6c0c511932821a6d875bf4c9e6bc9", "13850c1041b5b257adf6f51551051abcdcf13bf6d674e075c0ea32028011acc5", "f193ce67a931e61bcaa796a46c0018229600837508a693a7f447ade876ad5470"}, -{ "442000", "d8d9a1091bf2e48609bde3ea3140ec19cfb7a2a14735474c6f9ef6105c46c8f6", "8879f9476a6a342e58cb8ba5e4e40a9ff6ed0b605f3cd9b4bd9e6cf5dd2dfff1", "21e3613ee1ff3bfd0f1461baa7f7a2a5c1d68e6a21106155607eefea238cfad8"}, -{ "442500", "78782ee99be29090c13682ee644a47f85f410c5a24c1976dc047f3249dc1e0e4", "b4fd6ca7a0b0a77143c457285ecc982da5b9639a5659c03ba88315432e4881dc", "978f2508e977ccec4c29433bab1606f12e4e0b324053e9f85abc6829df5f7706"}, -{ "443000", "a5d7115bce13dbdf436226400b23c30de09f68f6a5137cba50de278effa35891", "cfcc7a433eb789185f88cd600fb249d26b8c945d5e5a5d7e978ae3c1c1118a10", "dee8a4dbaebf41b33c79b1f32f679a36bc24c5c127a305ca2b1923ba121447bf"}, -{ "443500", "f73cd58af88e5cc893f5a5981888e792f6a15cc06093c14e0ed91110778f0312", "22b5b27df320f33c1856dd087c8537e5837c0686ccb436961189989d593b318b", "fb92695de156c669016fa9f27dd174406470b91f73cf3daf7be351314936c575"}, -{ "444000", "7c497c96ad4740eb68993e26ae3127c6c9e10b8625f9e759131574b87cd722a3", "e5405706b778afbf261e0b4ec0a7fdca861baa26ec3a65f5e970769a8497ac1d", "64c785620f16baaf73a811e570ccecf1c10aca3d189a2606d013947e7f5d9441"}, -{ "444500", "cd52d7101a166f4dea73875c0fa5c494db3419bc3f63d539e57c8e853e96cc6f", "c874b6d14b66ae740907a7ef12eb55dc0983a4a9ad00b27885902a11c72d8009", "1fed952263d7cb5b5ce2525b5e9f9a2adeae5beb94bbcf18fc07ac91079e2bad"}, -{ "445000", "30283438585b2c4d3409d61110cc5d400b0abc0cb8e8b65b9fd8619e54dc387a", "3664d9de72ce8aebeaf5f1e844e44f5b3362d0faa80415de24c2cf5fdce153a0", "7b642814a213d9494bf730f43b90aecc16904f97448bf5e2f6eabc288d748ea9"}, -{ "445500", "a4496d3bd4aea3dbe7cf7d2d5a3f0850f5c01b04662dfd38d3dbe6736251e91f", "8cfad175dbdfb208dc40cdc2f03d0ebcbd9f3b12847f6d069fac33a5c1ba5173", "25adb001aeda4bd4909bacb421b7d82de30a9200b70f520e4ad23759f7a2e3a8"}, -{ "446000", "7cff0564cc670e8a69315b18b0ee229269682bb0286b5e4b3db25f02ce0c4d2c", "b5c22f647055dc1204b243da18d999adebc56060e52f1f0c4d35450a9e941c68", "307379f276df96f5cc93828b4ba92cccd6d9a2fb5a54d2cfdde7ed6e2197ccc6"}, -{ "446500", "201cc692970eec864c92e5e7af036192a9562a62d2723204366bdbfdb0741fa4", "f3abf2331a35c83fb86e4484026fbc40266f5551bc90551b90be2d26b3771e3d", "1e0f73f08434857355a8e7f1d4950a3d0ccbb5ddd80f5473f99ec0698d63a4db"}, -{ "447000", "c06f8dfebb81f0cb3f19109f662a7dcaa4a023f1fbf735ed81fdd6bf9fa95023", "0799398c8a29c71de6027c446de153b17b1bb364570328bf5aea872fa246ca98", "a0f76a7d67f1f9336b2665b032cecae3e9cb80463c5679ebc28b7fe29c185d22"}, -{ "447500", "05185f624dab270906ae111fb2c43e838b70a78e0420e84fcc94bfe4fc911dbe", "f73e1007bb6e28fa8a5add7dc21539c7545ca68c600ebc62b10ae00382c9a538", "8fcb834dcb86b9c51bf43cbffb9de5b1d7c2e30b22f783c99394787524f06ba1"}, -{ "448000", "4fc96bd14509bf55922cb5d8ed4cbf372f7ce991646e5be3a086204fea0c368d", "0fff78f76cbc925b62ffe927d50cbc02dc83fd9e5405a3a77e232b55a494812d", "67e09df16c3fb0a8fac40ee153922aac6983631f99a341cde08c05252fc4e11d"}, -{ "448500", "742e9431b2ac6f0ac24e58cb8e6088ac1de875cda8f16739a78e0f1f7c05ce33", "d892c34609acf3eeaeb32a384985fd2da70c4f53f59f8c459eaa5e74b3d61c40", "2997569447cfd809ddb51792a754d7b497adb3c23ad38b2fb15082e4f09c53c6"}, -{ "449000", "335341c810fdea9e158ba78a542922754fac2e0fece92c27559d14c5c3ca0267", "8d6340cdabfbfcddacf2991913176b17513be28b9472b744e7a64b2f2ca13896", "b0cde57f64c7794da94547a5341aea6fc5680f24bb3188a01171ebc61415471b"}, -{ "449500", "2b97e9d073d0b8922e73a1b1d6fcb7f8dbcb0e22fea6a707d9faa2afa1cddf8f", "4fb82487fd05bafd111f032ee92e9864534dc93a7d0cf994928703612d816f4d", "1c5d2bcb3165e293bc70060db78a5cf299d42c4815896b65b5f54d742923f434"}, -{ "450000", "a6448ff3de412e8784a4d0590120e0727c3ef1c6e98af7adec4b687e10c22b40", "b12232c014cf52f4f8d0fdb4037642bc1ce2a4d709ae37b91d908c9d36830fd2", "d0a08ef423f57c6c0488096bc46df33cbf920226423f7930c27c813c9d34c71d"}, -{ "450500", "32343305ccca111d5b0396816091f1f169314acfb4974629e7beb8680523cd47", "36cc9b37d7962e434782de92543635fb826a4d84fb5260ca0161680523f54272", "a2ada16c0fce347e1158c64a85eafc07d49f6fdf5c91d0b1c1d973c3655d4f75"}, -{ "451000", "adcb05f8f053823db604b6278de320da2097890b386fe67c0104721e6cd76954", "c63c045a3117df4fef3287be2f66c5691b700b18b42d3ba60509faf162dc9720", "642495d66438cd4d827f29aab00729237d60adfa77f4fb3e74640b459b79868f"}, -{ "451500", "c3f6f574abc62ac6ee2b65eee953b3386808361f721ec77e4df9bad7811b0c13", "8ed2df18709fd8580694387f903d9c31fa4a7c5e3bf3845b4fa4e9a701441112", "8b317080fb74b592ebb41cc1902a0a466d4cdeec51bd10f4da17a2b263ef534d"}, -{ "452000", "b47901f63e411758d074dd4181d87fe30acb1b1623d0e69701093d93bc505b4b", "227dde0bdd2ce1659265ced176e8c5514aa1d7c9c58c5f92d18534141e157539", "f919704e59bb5bfe322594e6146c55724c38e493565745772c735583e826ccad"}, -{ "452500", "723793ff45924363551d433d63f58d9951d58791f6954a6aa906d8c61f80d535", "1a931421c2325c0c2cdea860d128402f6ba18decc20e05279f62f0d0f5940f58", "46a8f9f7cc7ad3ada81614675edceb12361c35acbe7922c7a7223d2f7dc89010"}, -{ "453000", "14a86fdf9716b2225cf80394126c1bcebeba3be4a4f103a3497c8eb079ab11bf", "c0261d2846f68bee936c5ebfb638d9d4e6bffc53519b76ce72dcefa8f66e948b", "bfd4b0429989a852b9d98718fa499d4fc75245139046162a4cb45726589ffbd3"}, -{ "453500", "4204f92e27edb642343263ee5c8265639a4e4bcfe6743c323e5915af2db0f68f", "681663c10b07fae27a187f5512c63f266d4460abd46ec1f464e8744b5ddaef67", "5a478160537a5353e374707d131b56e1fe7efc9d5baf224aee671d7ae9449d38"}, -{ "454000", "d7173ff752ac555014e60e3928c1a8ba368d9ecfacec9b302cda79a6c6162eb4", "c34bd72a990e253a26ffe68a91553b0b771083a569e512c6a46a52e5c7b6a724", "ab445849e1252ba4bef39031ee3ba2f5d874002c669a39629f7501290dd5f656"}, -{ "454500", "df134eb761013d3ba1bd9ccb38d735427a299f2e275a3a1764ae436ba07f09c2", "4d9b5dfb6baf847acb9499ef9cedfabe98dd58150569156e5bd692d1f7434f3f", "75bce4c6a1817c3fb96328aab91271ebe51ee816a0cb874a4158d72e615f530d"}, -{ "455000", "edf2fdc49b76a90ecdfcf0e238e66d574794b7ebab6a4e7d212e1884a21588d0", "c40b528799070a1964e73025da6badbda9f994fe3d83cb4ac5fae95aa2e42963", "9d6656615f986f128404fd2a501d9361bd002b72928d22f63d9956c264d9fecd"}, -{ "455500", "0728ecc53f1b1b7be2478f687881eff7e6ba31e9d565619ed628ea9263b67a97", "700384e16447d9873213d70063f468f9e4e9b1f780104d9a118d86b09aab9594", "859ce00ed105ec338d519f2743a7b3a46dc19c8e7d86a31d1e4d4b9556a42f2c"}, -{ "456000", "fee4d1a2fb2a99260e941a74ab4dc87e0520c28a115ba86c6382791b2f06f1f6", "e0487333ab303a6d155cbc61b33eb1b23a3a9bfc3d466c32d8e6793328b3bd8d", "f9e43e85269d5bb16a54bb0eab65e7236b1c1bc1fd4fd2937776d0d37af7a9bc"}, -{ "456500", "b5f05116bdbe8b51f4c1ffaff1a0e0a445e3a0f0c6c718a72d346162820509bc", "c7a2de5b71c4c7b338b04adfa8fe16857ba3c926fffbfc97dac86b0b75033978", "6c99c37c34fd8f4f06be74b129a37bf12b4ee423434b3103205b7daa4a7f6ee5"}, -{ "457000", "b414f29bc13f7cac4f028641c788a54786bc9412ed582f4aedd5df86039a8e00", "ce69e9060126b330e010d201b073dfc0e16924a8c11acdaa61c7776f0f2d8021", "63d198d0d2d1fe07d46a18efb3ad448ab9ec6aa919b6309a4009242734c67ec2"}, -{ "457500", "c2f18fb64768083a462a48b87b993870ab96a70e325cc1b7ce676a504dbbf4a2", "bcf97c78db8bc3b69a377a185a429277aa530aa853c7ea12c2ab06566e837c9d", "34cb2719f39251f056d511bc2990386829224280c0253ef19a45182af0efb716"}, -{ "458000", "379e0643c8dab2bdefcc1cedf8118337bc0133f0c938a1553088230052f5cfcb", "22e7617308101b51b4ddaebed23dc67e0d1e0b3f84c5074039ed77c466cc83a5", "09ac8a585922541577aa4698c7590b0343345a40448b854e441bc724984e108d"}, -{ "458500", "5b8d6a2de4952aa7aa38b9a1d403fd80e65f6cefb5e824c062d060894d490946", "56ff3b66fcc71ae8550fd0630fc358edf11f7afdd551d69a2ec9d4b9fe154bae", "eb82ab3d805a77df91f9aded634cc7e9b1d0e197f274587f144f6192534d4c2f"}, -{ "459000", "426443a695e4615554b95c1070f14391c199178d8be6860807b69cf2d686501f", "40015ea68bd905903100db2ed67d0a0e25510796dbcd1bfaa0b8dffec058ec4c", "01cf6151b050ac3c65f8d273b0aa9991afc6d2c99a19b73eb58c4458ea448582"}, -{ "459500", "561074bb87ee4d3132bd22b91af78df7d2cdec1c6914b43b12a4004204094a4c", "86a908568cbb19be09a1c70b4a92a0b3022e5d0008ad78d6ed536a9bdb08deec", "3d22d3d556bb349cec89c50054d81ad210e9c4d93585b8907192bacf920221cb"}, -{ "460000", "7adb9b6d14e8124ab25bb4696bc8afe6a96cdae5396ac2a5d6d859c47236990b", "6ea2894408475e17a8c4476b5084cd76742a3cdb97292eba2e2ba0ad4bb17d87", "e22e9309202f9a77ce29b5772f411c7ec5e47689496e4cb566b05a01fe71da97"}, -{ "460500", "5cc330e1e985af39a1a24602603f26535df43ea7e5e164c6b654f292bb359633", "69c11c20de0f89ada1a65781a2b7e7a1e235f964341eb70434135888794032c8", "ce3fb2a64db272c7138e730e433a3adf8dbf7b4bd754a2c1dda585d4475e3f0f"}, -{ "461000", "c1c45b5a71cf6ed3c5d9a739c227b68fdd3cb41e8102b7e99c28084776c3d8c9", "122728c928e7025fba2e58a3b70cf5dbf448e26389be3606b43f3b014d5f2001", "39ce156b16a89759e1827b550c1d56bc9f9b9b45e0c8f0c1c70922220c3ec34a"}, -{ "461500", "096479184f5b32532940e42b35c51e50008b8224b2c6d6317dc69478d3d316ac", "aa693ef567b3b7c4a7091b5bb3d34161b4235e7bb3b573a22e66bab0e622f16e", "9e242e78240d389ae4e2b845e3fd1f4aff02b280e743e5a0232c2be5a7d3ddd9"}, -{ "462000", "c78d5a646f9130aacd23a52cc3dfc5a084add7fde9dddbefdd13d5c438e024a2", "3242055c63d5e14c1efdba0effc3580106e14c443a3c39c699931a6c4a36c94b", "b586f9c9cd03b22f452fb7da6fc1f5026a53cb86120ed1af6dc81d77c841bbfd"}, -{ "462500", "b464f9105311560ac63c29a94f8a0a5f378bcf5c22cbd23d5818ebe2e62550d3", "4b91a857ed6803609c0f1d514e5793f3f63ea3dd37f84b345c3c64c7248f8358", "6e0a56c8afc1967c6e3e9eae4ac2cf0c8dc6437035a07dc4a9fa0b282e539900"}, -{ "463000", "ad7d579916aabacd745a9d48122a64e420ba111b8633119f6110a93125eb6072", "ab7a1e347245f8d9ca551cc5e89247e18d130aa0180d375673de0578dffdec36", "39d7e8e516f09f532c1eb829fc0ed11e3489ef4d42e34a14676e84805d831ee8"}, -{ "463500", "9f647ead66c59424ffdba0067d38a93c33cbc5cce95c1fb19483d3138d9a2924", "f9be09f0a7ec9832b7d2e238f0f3841a10e99967b378bb93e1e8ed95025791e4", "a0625aa3447319a563d31e3a63f67fe9a3c372809e5e2d2b6eb7ee328191a2ef"}, -{ "464000", "8239a8c5704697db70720d8227fef8093751df0e79bc792a4583106c5229d97c", "56a2bdda4613688231ea85b9d659f05000786ebd53300466da5dcc474f8386f1", "7f2658ce497a6ba01c6b9a8e02261fc39102420f84793b7e16784b2b5a962d11"}, -{ "464500", "b8500802e87f0a3d08b275296b32aa66211d93ba13dffce95a77f4d2ab6ff8a1", "87c4e1ae3a488895890a0dda084969a43703e9abb82fa8a6b0fffda090b1fcb0", "60056e3e3de9d7893dc58b07cea9258dacfe904a71949f764579ef6f9aa1ee28"}, -{ "465000", "9c5f241c6d7947c078423264cd080eebeb852aca6898b71dec1f2fe0f97f40a4", "eef3196b8ab3c6d1e3df1eeed6f857644e50f6a751843e308a86d72e945cc6b6", "ecb9587021098efd5e2df880998cc544af71206a067d1f5f5a57bb6b4964e95c"}, -{ "465500", "714cef624738d796efc3fb3fdae8f42478924d28a0644c225374b1e5f8707262", "8d68d66be9f3952f46bcbe5df4829d93eff2f4501bf422582e8594bf3f03730e", "2cf7854558253ffb17282849c66c8db530c422810e2b9a35c1df67c2a403af0f"}, -{ "466000", "760869daabeae89da11828967600ecfc92ff38d5eb79326da9fc526ff88e3dc5", "ff631213c2cd21307d635337ecefd200cc2b7767c171ba5913ecb785d6876aca", "78b71f347088929e48f5bc408ec2a2934f541481e3f26bde43305644ea391548"}, -{ "466500", "9699ebe38cd6fed8bad4e96c18eeb8bbfce93fa6be86c0c364ac187c246d47e9", "f18cb4eae80510bbccc360228942bbde0144f6c66f378e0b4bd0005ce35debe9", "15e67ba70c538b0d6a1ccb9f692d496d163390975c9c6acc4f245818dec88a32"}, -{ "467000", "6de68cf541236c2b20da6bb789be6df085207919a94074f31975a54250c4d918", "0c998a0b617d6dbe4454ad981478bc5903ace25595e5f868c6bbab61f80cab09", "2e0152c2e09f602ccc26407b314d0df711ce94d81981b4c6ee0f6dc475232665"}, -{ "467500", "34aae978a356d729783acb130e2238fefadba1789ddf82d73b87c79d862d297f", "a90873e05bcc6a81932e4562242f7ca201a07707b505f5dddb46418cfc26c5dd", "ceb302532871d7a8254e16b214ff73614ccc4274b16e9d28943598178483f575"}, -{ "468000", "96a959479e0159621c8660165d2053878cad8adccc1ea5a4020c4a1f63941b09", "ad947d10fe2c2fb1f61572586b941c872bd958499342e2e44b545d4c0faaafc3", "3eb3bd86f7ad52574f6ed3dda2581091096b326d49d53384fb62e36450299dae"}, -{ "468500", "ef36c23495b3e062fd2a92e24164f80a01d74452d2d439a23a38e403e531ffb4", "5790fe543b78423f088a1d53daf1692a7051169bbf1e469caaa7d3862d709b2d", "c7eef6ed2d806de2c40c6015e7ca28d1489a699c56def39a220660511b8c460c"}, -{ "469000", "e32fb17dab672f159e97ac45ddb12dfe0dc0bf2a2abdc455beccdfaca5e2c69b", "56f4d6e427a46b3467c26174b6a4b66e30f5d962450273ebaa598c06aa31975b", "9c227b4d82d86a5603e5b07eb357bcdbd4e6732396b6e446532954b4ac31f263"}, -{ "469500", "3870050849e79e3243d3460ea594ef741a1d6327f5d336f8036fa5e97e0cfbb2", "2e0823dd7f7a137a063f473cb6991510a112460ecacfe18aba39094d410c8930", "94dd6c074f375f6a33464439c1e6f1a2f7a5d8933c0ad2c3e971e9faabdc8502"}, -{ "470000", "2aeac4abdc914d4ac3fde31a5882b242aa26f1049c86f703fa5da279edad5a7f", "db8d47e66737aa4776e8cb857386d346d356ba91d0f6212d8aac34c9ac2e5906", "c3599f29edfae99bd37c27e39acdc17960c2b50c18c6dae37b1499e2e87e0616"}, -{ "470500", "fdab2f454e5102f44be86a36b7c2a54aea2f5681bcbe811942451827e8106734", "cb60e3d4e6620535cbf57bf0f94c5055eabf0ca48052e9728fb28f5ec913e5c9", "1af5a3097081200030a5ee02d1bfa703abe356f23003c9985464c9fa1e69ea1c"}, -{ "471000", "afd4b785fe4656f48ec1120a14136d133df7059eedf76f407dc2bddb91ab0ce4", "0eca3c26dcc9bd50d78a8322c07b18d59c7609bc6ac97258b56b20ac73187f06", "0201199c7a9201bc722195289d50bb927fbf05adae168d1e0355a1a519d939a5"}, -{ "471500", "e633efdf19faa95b16be4cb94f7072dc1238342d624bb4d69609555a927f2522", "570bc44f8e51f6dceddce363db3b87fc17d9c8ae51ab9266a3d9248b546df4cc", "bc1d5b7d7b85c5419fbda0ae3517865bf429ef7ec3877654639e6d1120a6a04c"}, -{ "472000", "d4aeba089eca88aca7c2b7cc89e10146158dac72fd7643e4c7dada43c8645757", "e49b1d22916fa97893a9f31f31bce50f96d49f6a388ee1c8ec2216aa619d9101", "7fef7bb7753e24b89110558c1711b0f93b6c666cfbc6e21b2be9e2d7de78964f"}, -{ "472500", "a1c6bef24a340e81f3212db55e9db0bbe8135334e14f66839123c21fa393ea57", "1b5318294e73812e157fd78c84b79a31d076bafd91aeda00fa49055003be7e91", "6bb3a2ec06a00afff5bdfbfb4b4ac00397836a5d1e144ccb39b9c81f65145db4"}, -{ "473000", "c2f76403fbff7b3601c0b2bc71cc00963cf0b012e09d6be5d8fcc12a8f78c8e6", "be2ae59d51ecc553798bcd9c82f4e747dfd1782ad18021dadc24e4838c2b0666", "0422e26c8a7eb63d5b18dda0c3efe7bc646e75332413430c532788704507625e"}, -{ "473500", "5f6ff7d98fff43942ec210bff0555d74768aff3e5fd5ab6e0b546d0bfea79921", "b828dfae2a89c1199e2cad79165f815f8d858620d87aefe17630048ec05f0bbe", "5c85d46886845128e04460eaf50ade9e4c8f1c3ca6456e74f76061492407c9e1"}, -{ "474000", "2c191256f2a1ea617517c81c3133a47d2fa264586885b2ca6a7b782f9c78a8bf", "7d0b4169707e36667345fa68284bb9eb0dbbb726b9391ec0b3018c71a343ce0b", "e3f7ea82b53a82fe22c0b553fe30c4c5514f5a4df2bda23b6c315d894612822c"}, -{ "474500", "50b6c4f4c1da30ee2043c4a18b0dfa1da9aa33000be4525bb07b2462d8cabd2f", "9939b0eb461196a4ea22dc6c0e2d3c776cdf08673694e3d5a520bb644df71e9c", "5a123ab254ec518a34af619ae78a6caf68f12ab08ea1cf8bca8f9ddcbd5bb862"}, -{ "475000", "2c38054fd7a02ffcac28fb8c53ad84b68d50ef30af030e597414e15b59bef269", "6faee9c17b651d220534dc8c66c0345d162426661af23bd6be235d1c0eef73ab", "68fd23bcab5583cc821cc1e2fdfbd4630eeb912e69d8d3ce68fe22c0d8d55881"}, -{ "475500", "8d981411752ee6b44f12860a9975ef23df0c7dcb5b5c621368be19033de81de2", "23fd87f81163c7f0580a7eaf5f74b7501a868508ba60f47836488f5b72716608", "2efe456c536da42607c5d527fa75633d20e07ed10e8d747064e21e866f115e06"}, -{ "476000", "27aaae6fc04f000f25a467ff5c2fcf62a6872b3ea96a3ca445e0947bc912d050", "061c4b35170cf452518590f1e96624dbc031e5eec8b9de1acc81a477bbaa18a0", "026f245193b14cd91226fb93bb05307b3f84c121c3b4cf979eb48a4899e2329b"}, -{ "476500", "84e8616d4259371a11abc9625c4f7d55ccaf949881e017b663f249d29aaabf70", "6e6418118d4d34c06bf73284c95f2e3622c87c42ebd4a8e1380939e6abeca428", "de01d9328991d787e797992316e87257c9925542e3b8d15a992f185f5f4556e7"}, -{ "477000", "d459f75729583c8259ea66e8dcc7b8e1486b0a30e14864332dd014757bac1f5f", "9316f02e5bffa72a4ea6c7809be57001db28415e75048320d33dbf23c3a39e86", "6af818c2d7626e65486a4f77f8962944a3fb51adff66b53fb70630225b0ca9e1"}, -{ "477500", "329e7c98cde787901a05bbae8aea2a10fa244630640182eb9fcb80e83ff47cc8", "04fabe2b506d1c811471d88cb7986d2a67a988e0e094936d398af0b20dafed91", "2ca5bd042acdd1149737878821deb3ac9ec658d4543b234dbd4ba50499567e8c"}, -{ "478000", "8515a758d83284a93a354e91ca1389d0dae0914aabde4c7069180dac0f88ece2", "0f9d14354952b22318f9909502aaf188e43c511ea6c627724bcb7f0d14550233", "9f16c907bc9e804b8d89875191fbee34dd334d0398c5d10f02ee4669d85d6fa5"}, -{ "478500", "e0b6428a55906d115c2365630e7a748422b1309a75df0712730a018e138f8ae7", "75327db1cbc6d65c203eea4cf697e0e8674ff0cf180ad7730c0f42fac2cb2259", "7bb6036c936214f8cd8d4fce9355d6892e7ea2f768580f890a4e09d0e9c3b5a1"}, -{ "479000", "acdd6bdcb3e05e00631aeac70db0beacb5ff7339f9efffe5d125a748e050cf0a", "2f4a8780e4913da0886b73e399430b0a65b84e906eb7b47bb14ef6139699e222", "6d47a71a51d8b75b6949e5b95088de3af2446e78cee21a33e1ef090f9429c04c"}, -{ "479500", "173ac0f8bef2de4b544b42c3506aa887ddb348e6f719f2b4fe16beb569b6b9a9", "550714098a237e5f2a2313711787f7037937081893315ca43450ca64c071c798", "9b628260e5d8678c6d02155837bd823d326a33c57c01b120f2b3a31d198760be"}, -{ "480000", "39a37003b75d37e0588e177d5d5566dbd2cf4f1ade343067de439e4e60d401e7", "e90cf6f99b06ab2f396192723accafe62f0a7705a8795b39371238dc660881ff", "2f6ac37efcc941311dd89b57197c45e684d33750139e46891fd25f6d0c7126db"}, -{ "480500", "675b1ab9b45350f0db5814692844dedce30a416b0c5a6b04e3ec778de1c54476", "0cb43e9d578692ced5b3c43a067a09dc8e582a12e46208e1a26841645ebbccf4", "dbcc352ee3e2b565c678cc858df6b3ca0898a6ee07073ae621b1605803aee606"}, -{ "481000", "c49b18c02ab6cdbcbd1380535c394567b0fef261db605ae42584fcfc5657292a", "e45920a96e78f6ef20be3f24d9a8b1accb6ed9b0a9ace38694eba826aafe2bd5", "4e13fb32c6795e96ce1576e5b38f2874d22609f4fec41fec3a63a8f1ac98351b"}, -{ "481500", "e70588e89d0a3a15d7de9bc26e47768a94964a14edaa0355853f5629a500dffa", "f623feb088592f1cc01e94f8984e5bd7f5469ce71ff7645ed81648dcb25ecebe", "8004dba192b725abd95366b8f0dfe62ab4a75cc3fee5c1c523ba12f765c33f5b"}, -{ "482000", "bdfa119169d8507d41720ba8fa40f5ecb75267570ad0ba58e342f4351fb74575", "f28b44f2e70183e19deb6562a107d204531edc8b46d4f5aac76884d7d3a9e750", "881e217cb102b28ad20cb8bfba39b8779f7e857a9bb94ccfd0ed5ddb61a1bdaf"}, -{ "482500", "14e2be2612c4290229084f2c1edfefd0e432a91254abb83ef8ddbe8d7bf2e661", "aa012dfb4ea0b0d0a565fd8f2f55692135969aeb6a9d3f34cb17b31e32ab22c6", "6eec8e5808b4e00484134d46ed734f238f979fcbf3754d9017f79d718d1c4b6c"}, -{ "483000", "8cc62d490274477579f93e8af507c07b3816d393200aafdbb6b68755b763c2f8", "3bce0766356c52720491791bd9cc5a6584c48a39d620bb185f368eb7dd7db697", "aa99ea2b1829fce8adf1831a2416e7bc33a6859ad82269d58a3d3a5f023df47f"}, -{ "483500", "72c78ca3f93bde96a8afdc199714ae18e9c15b92526ff48845c050047343f548", "f4c218fc750e8b31e2b4f56ea5bdd7f027227b58920c7d08946d193bd090a366", "c7564a5ba5a84fb5d02ccaab954ca67b1a37d88c7b78cb89176fa968c40fceb1"}, -{ "484000", "ad5719becb74523e16221adb2353a4786de357612d9e2ae86753be7035d1074c", "f040df388303fff9b7c97bfd38d55a94c1701b82ff4f2d594b1f4637fd8ba964", "9afcd022cc235297c99a8b00e63d94cf20f89fdc1532c41d6012e1fd42672caf"}, -{ "484500", "a143595d89e542b00901e959c20b1bee243c6b7f2a8bd930401a0a922586308e", "1c50e70afe27a5026a6ae968118f5141448e69955b431f74c2b94af7bee31ffe", "76628ba63114b144c59fca247c50c53f4bdb06cd34b9b311473d078aae6e7159"}, -{ "485000", "ca0faa2c4b601116d3e03c898bb6fd6de955e9e083910fcbe93303702522fecb", "98250685f5d2fc349e6088d617a7986ea28204843abf4e887ee121b3f89a2b36", "9db6d0fcaf950249c2dcfafb15777159cb589101637f7c76752c04596588ec2b"}, -{ "485500", "1d2f98bacec2bc91b7ffcd9e760c49bc18183ddf1bfb4aac8145abcfe2f91adf", "c03ae99bd105f3c8154bed1630bbfc10d56a2aa4e36a85d4a9fb2e629920e285", "422ad706d5de44123c1e68becdf8757022af0aa1d64678c7787eec828ad5d214"}, -{ "486000", "3f9896825fb06766d9216cf1004aa6d2541642253b2980c59775fa720e1af9d4", "e8ff26003f9db4ca25d4a5e8f22c615b6b376f2aba0b6e3d3ec1fc54bfd3e8c9", "1e16510e1f176a888727956adc3c041bb83fcc512425f57a6c3f558ae2f46dd2"}, -{ "486500", "8387046d6d520535e933c40c8e7a9b253dea20d1d4fea49c53cca41d13f87b5e", "29e01fc49acda9fd49203e03a86fd7fafff8dba947e907ca41db1b6e2802081c", "b68d45a08f6fb2acc92fd619b0dc8498ea81fd57d3c5b971d5b31803afa79a6e"}, -{ "487000", "3ee4cfc2068bfe1472bb2345900fda4ce7d99aef724ce5c35e8dafc97472a163", "84ee857e054c6f118f897926d53b546c4fbaa38576d66eee4560d88f90f2ac91", "1fd96fa809024f42da38f6f5a75fe6292b9dce007ce635ed1aa865a5fc20a330"}, -{ "487500", "7802c03efcb4298fbff0c05c7c2a2670e2b5c5c0a912260fca95f5ee401f9fac", "9c507f7adb01fdb9fe8edd09d969ea7b12474cd9f317e6e0c8d1047f720cfa01", "f271dcb04df54f998866b55a7d0727e691c2e51b6c1147f668cb2542339b99de"}, -{ "488000", "6c0026aa2c04a1ab5ab59df72d9ac017f559889453749c95937e01230628ff22", "89cd039f94be43a6d229425daa26daef3bee7688fd591dc954ee503ebe2f3573", "3ea3b7011c70b0d49b9f36bd7b83265128b7a1c5ca9f69ceeb5ceb933cb959a8"}, -{ "488500", "ad7a33c68b62d181fe269bb58ad9f00b48b4b19f77cae3c68407ba81af9e29f5", "e26367c609049d5cd867041787aac089a459ae2a39e420b791b778f49c4222e6", "1978075a6d69518c80dd58998a9f9636df40421eb6af7670dbf683db894118b6"}, -{ "489000", "dce5e567c4502e3b3344804468bd48900df890568521360b198e5b7e48c4a7cf", "497cd478db672eb3f6e975b722a162b26d5f0fffdfeabba6dc28664d4dc76bb2", "d1d75bf13e39e9c5d4dff8446d5092619012d2dd19ec4f53a886946b47772c1a"}, -{ "489500", "326013c6ec37ad623eb9c5a35a51c154447c8e180d4efc381f02a791c8dff517", "81c2d130a11e3caf98c5d4af0ae7c05bd5d79099d5c959efabe7766a211c87f6", "27814c5edf60b9e069fba619805454722fb7357b50bba2dcfddae253611c4a99"}, -{ "490000", "b0ddbded4a9bad235b75d2dad597b8fd87b80cb721d2c322bde82e9bb3763d72", "5abf2e1aa1273cc9de5eab070f0dcd5b082cf7459de699a96e7b12dae3311265", "8a5c2459345000c6403134ff5743329cae055dbef1466abc5cc078187e8fb304"}, -{ "490500", "40f093e9a8e074fded5c67276c85a0261d15f3e418e492ab1452e340da3c0469", "0d79b5359c16640713fd6b885d6327bf67971e99395eb633ec71edf9f67a0649", "37231655e968680404305a8056c5abb98d300996f657362803b1be28e6187664"}, -{ "491000", "42ff56a78710f1d58f555a7f55001a1760c7090441dd2657f959a67b2d8a8289", "7a167a1f0656c972aaaf079ba002f35ecb7d47aed4c72a7da645276ee21f9ae5", "68151c99713577c18520079cb48c0d1ca1b2df2de1237fd16a153cacebf98b2b"}, -{ "491500", "38a42670dbea9a526f90e8a824bb52398335afd259b0d89f287687810cb3a268", "c4f01d0a2b59e7cedc7957ca4dd510eb692cb5ef4c257a76fce04c3e51487e20", "831668b7ce58262b8741ac9bc0a07cd87ef253aa348af5f4c5ef54ae26428ee7"}, -{ "492000", "1aedf52ef4f42d0e049cd6f2b564a1416ff737cf792eef860c4678cf4b1929f6", "a6c9e1dee9d08b510553bee2acf0d1b8b2f0bcd202ae4d28110fff8dcedd85c8", "c83967d6ff555c205f808f7d9f632bd3460e7e5b88fad92e61770c772eb7171d"}, -{ "492500", "d7c8c52fb1f9138293bdf0c28ac68aa8447efcb1246b8896a1777e5b20800ee5", "0d6687cf95402d4df5a9115b6786b1fdd27493c88b0e1fba921bb7b722084a88", "462256ef01f138f31dea3dc2e783f733c65cc02d6cfdae0e71491e903bc0fda1"}, -{ "493000", "e4265d17c243d4e4dcbe12d216d7dfe7e4e3b7da161226203881b0c007f2936e", "a6f9daa6f9635dcf4a2cc894a4b459a8aa5dc2ed487d95d733bbfe827aebb0f2", "7a1c0950c21786b59d9de46274908bff4705bd18cc0b5aeef2b41fdd27ec3c9d"}, -{ "493500", "9c3b415ad45f42001d88e2dd38748048ef9f40223e5c1c62caf5eb7912d78b42", "e68eb0e1b1b95dea2fff359dc5444930588ef743a58da356b8d33d8e6a0ee1b7", "332360bfafa171fb3f3f7333d63b494e7a7e7d6642a5d1932f9ced9df92dfa13"}, -{ "494000", "e78ce6a76a928e878b6cb5a0ca25c6b9a8cd69d4e2db9a066e702635c11ebe17", "ea5640b26510140f3abd04e611f124851c15338caa163bea3a5032fd0d16b160", "517147f19ca77c35290433c196ad20dec0bcb92db6751efe04549dd1f9207971"}, -{ "494500", "cb62ce4407ef63b81d3afec33e7b57b31a6e7c8b3e0888b8db96f17e4d39756a", "6600b14d7f4f7bbc0f680587684f9fa7d5a7acd26cf9d103ac31bbedf9d6afed", "9a6c67d7bd9fe4f9fa89540b33d9db8c61db8154018f6ed22b0c4f6abb1f885b"}, -{ "495000", "0e8a7e8cc89426af75740fb8469fc9616a8e75401fc785a8e686d5ec0f4e5732", "0a1ce34d16dece7d7bda04e5b9bcce126b08d7e514e0fb37c5c1b0871cff4cda", "94539c965b7c4e0272e499bc3eb27ca73c2a77321813c6c9a3805d5b99dd51ac"}, -{ "495500", "ba423afca93230eb911c2f4dfbba40b893b938a7365cfc2068e1ecd3bc770b5f", "5720feefb7971397896c9a270a6318f2adc667cb20f2cd218b2791778cd50680", "a3e540aa54bc1cf7419598be27ba01dc1b7b295fbd939b9ba74dba091169ea34"}, -{ "496000", "352a1fd91dc52fe0cd78e2de4240e75a785420049e7b95e01adfa3d1ac4ad512", "781da1ffa0ccbadf08f451c290221fbef9b440c52b5f7ef5bfa3dfe51562de47", "63cc34ac782e8fe5e1e18aebac8cac230295662f93cff675909b338c9899fd7e"}, -{ "496500", "d0743556e112656c069f2749baef59ef56225b6bbee44b2336ff106773fbe965", "ebc3df7a34a4a4e9d8a60151f4a5bdce4f40cc8864851520f5161abf9b9e6d51", "dfe11ad63217c9f1b6fb08b45a4084081340fb5bb9d284439d2e3276214e0e74"}, -{ "497000", "1887117917c8adb81cfbf85bd4950684145a964a12c81ca89a44fa107247c275", "e48c07018555f1a8be3ad71f6ec7c31932eab7aedfb414c99bb793715ec36e4a", "e29b08fff1fa075aea805b5799be10d3dbbbb23afd76b9cedd88f5fa2555ffe5"}, -{ "497500", "2ffe736439e02d764f544aa4f86a125b1567ab7d24a9d944313877d2d7c39d14", "a2b4732449a3ad1488478233895bd8ba26b72f14bf839a33d5fc0f2934bcdf2a", "524c1cd19b37aa1c9d5cb5da2733d04ecaab6230db6555143fc8ff1d02657fb9"}, -{ "498000", "0bc8b494b42efd68080fb3d3d83cc8156b56439c10fa789814d751d5c4f7d9dc", "ea1ad23e7f85ec30d138ecdf527a5ec5ac6d925eb888ab061b9ae24e48e60b2b", "a9ff67fe494fd28395d671744bb1d60b38ac89b53e4f66eadbc03c5d5dd31bef"}, -{ "498500", "5440fcfb2e8888508c4fd6920d0e6c7c1f3f1095813d45b691edc3a2a475722a", "4c2c9c60a2a43f9786004a9b43275656b60a70c9643d6c676ede104b9f0cec12", "de98b78d64b182ef34488808079e358e30189df43bff459894d14b47382d85c3"}, -{ "499000", "d84c475656720900a0b3765c4ed57ae1f0ba17238d34ac17b1635c6c95064750", "236f102f6f2350128916d138401344233a7483a0dcb1eb39730c6a5fa22fed3a", "88c61322be07f9b75d7a58001e4e7460dd34bb2a72214e949d28f184007d0c97"}, -{ "499500", "8b9aabf8cb60c29c4b60a942812968ab80ec48cad4053de2624d42372a547756", "540651876cd6a44a6de24fe75706bb959b3a701ef281c7b8a3ba083d6e329dfc", "4d743db021924f24501d20e27564a7dc2276c5978e0000af4a97eeea092703b8"}, -{ "500000", "bb94f21cd879e992217888fa56f0cb57bf585f8a41f845fbb46872fd7ddd4a40", "541ce9a7c0f8771a84281db66fba7cc2dc43fa636a39a840fee5bdf987a3348f", "254e33a659e25fb647aca414051e33f03899a896d032fcb7d307b90c9080d023"}, -{ "500500", "d74c1f7510c4307c942906d4c66ce5fc542f2a1944659c1ad37a0eb82be11751", "976e8ed703619833f8d78889bb8a3a71a06392e257b093a01f7a1b7036d22fb0", "fb7d68808d45544296419dfd89b69540cdb6df0917827d982ebd72adb3042843"}, -{ "501000", "3383f0c0456774cc529b5b0633a947e0708156bc873180f56fe3c32008c8bdac", "69c86425b5c47c2bc3a9fe3669b0a80aeeb72bad8179676a55dae6445b7bdd36", "22618e433ce9b9fa9bafacecf096c50bb49978a2fa883ea1dbcd2211075afee4"}, -{ "501500", "d076738e554cadcd99a14287f0d0af18fca6f893e6ab519fff1a9c987e3aa7c9", "9ceace4059979133e529e2e33930ee2ceeb2058633e06c31efecc7d2112a2437", "78706172ed2a93a0610e3f40648b1817d60fce479eb8d39b12cd99527a069090"}, -{ "502000", "03b70f8f87fc995b1f25c5979cab284b112e66ebeec690dd93e6c1f238ab616a", "5c4442bcce1ace2848f3bbff98abe5776b58af7da464ea4d8ce5c681ecb99261", "83307faabe36b7556ad019e41b11f1078ed9f42050728c949934b0cf3356910c"}, -{ "502500", "99130d7f62752e1e0a7318ae3a933b638ae37528134af7b76590d477bee107b5", "206bd50bea02399a5ad897c4e1190e96ba7c092f83cbad5e0bd65955cc253219", "a858f0c5073b29aa642dfe18243bfd3c1a488c2e18379e8029ca8f6c723ae8f2"}, -{ "503000", "3eeca5fb5aa1f44a7a86e9c2756add708089ba817e4ebe983da92bd815fd51da", "fc3643c494c343939f26a8237b3df02c2b96235e034e92e199980834ed4a59b1", "2fb413410aa7b7bdb682e803b2c3d4f17c7588a3c2ec33b17853ed85c2dcc299"}, -{ "503500", "8034c879f7596a3d9846ce1ae028fa596b84c62313f9b43564ada16c3e2f547a", "fd766d22b34e5e391c7a3e8c1318ae469a763ba6c49b75d55b0f928c83e5f992", "1776e527de48623b8a469082e8bf087f40bfacfd4ccd1711f14f7d39f121e8a7"}, -{ "504000", "bbc5fdb678ff466da54e09ab29562e16a798ae2a05eaf776d97edfa35c839a85", "b6dce69571860fa8d6db1cae19087b3232b06b8282f5b905a6ff462528a1fcc7", "94f9788f4ac548a410b0a32abf35971813f7a3cf18dbf06e3eb70ed23df7a0a9"}, -{ "504500", "956aea829d066998cf96a8b8edb9a0323dfd018642692dd7daf59d0be1b31ef5", "f90a6f0b96ed84327fe33e6edf930a439d1843046154fe1fdcd65c011aafde2b", "565c856c4321080b6b270e3d385f85ae3cdc3b0a2134f4a0a6b32a8be8370259"}, -{ "505000", "0a3445456f4807eb2f234e51acf42870aa7b6a2eb96749ac3cf764979d3aeb14", "f6977bf4113ff5e28895c0f148fa0ae812a4dfed4ac0483419d08e3493c90e4d", "32c3920d7fb47fcbe62ea2491212b56b8073d3c570380bc5baa3d6237794169a"}, -{ "505500", "fdf15fb92600803d9d99b54b13c028ebe2a39d0681e7cb751496a155b11a9656", "6fdd6b0729448d9a5dbd5b5ec1198c5f89d0a437c9019c94e0cc4b0cff9344f5", "631072ba472ad83e323cbcd05121a6459818c95c77d08d40bc06f19333399386"}, -{ "506000", "94533d7531d5ab46aa3ad4c03ad71b8a6f78574805a683be4021d3648a56b0b0", "7c1f8200acab1aa87ce1ce548b727d3c47239045d9dcb6d80ba58d908af43c99", "5dcfc85d934f268608d9a3ff0efd0a6b0ea46c24c31da5b41fc9db5bd9f417e2"}, -{ "506500", "0f86a6ffdc4880c047c73dc16aa8d0bf27d1dde7700c2fd77e4cdd7e7d926cd8", "e9c9a93746ec3a17feb362c2dce6e9a9c51a0d9f0d9700d21bd8aba906602e95", "397c09bb2457cdeae289fe4bd827fac0056e60cea33a2a2616007bd0a7175811"}, -{ "507000", "431e08381fac05624f905ca38d18e788204823803e0607106e147bbbe8bf688a", "4ac228d8c9c41f4e3d3a3c4e320ed04c13be367680f9fdbe8f6e5a7ab2a23f36", "93d88fc835441329dbfdfd0eb847f44a30391a86945ac792211e0271ea4653c0"}, -{ "507500", "a227a08c0b6d0818ac30280e4cc9f422bbb17cde711c371acb7fc19c8a642276", "6dd10139c09a88ed1692aa137b788336a80ccd60753eb237e90687a15ec987cb", "ba460e1c6e185f402765688792e23bcc17f2411db8e25eebaa4d43fd239fc9c7"}, -{ "508000", "ac9eed373dc35d2906cefc9e3ad2c8044253e75789f4d028b84a5acab33f8187", "d4fcd4e62b88c4ef4e9609e8e5c85ba44b15b999dafa68a7cd45eea0b9fee193", "bd867a112c5c29790dccb96c03a55ccdd2da7feddc5d9a3fe946bb8af6fe44c5"}, -{ "508500", "82837e772818deb177c58056f9b8eb8c42b42c75053c206ce64d4cb0caa569a0", "088031bb4d6c8d50690782746dae3a2894e04749cb8073703758bf84403f65e9", "7104cdf4ab6dc7991d885ecf65601fd63540005c3b90fc40d356ee5179559484"}, -{ "509000", "46d4c946d3305147e565ccd6bcf5049931048ab9fa78fe64a45fcd29df7edeee", "0d2fb9af0d18a37f8bd0d90677391033552038c5d24a58db89420c355342bc33", "db50d238011cd3ae24649f78ed23cd5e597dec6c269d02103488fe12d55c0d05"}, -{ "509500", "dd8574ebf8743606a8b2692ca8fe7c406487b6ba9a0eb1194eba2631c7ce67c1", "2ff727ddf8cb09ef0622821c1886cb8270d4401658d2249c402f48a6ffbbbcbe", "3a14a7e0da7f1e829a3a42aedbaa7d19d7913bfcd235a8c62851942dfdd651dd"}, -{ "510000", "8b496633b233a6ff9deba1fc40f3e1ecff693d91d8abda762bb165b4f10933e9", "3a409f0d90719857a525deb2038518acc44e2e710e3f51830c11f3a83c89ec22", "29ecf4fea155a00149f0394f8a972cdc29bb090b20511e214e1db1ea2e3185ae"}, -{ "510500", "1052dbabe3ecd64ab6a4b0b05f41c6c4131f5beee2028096f688af8da17151c9", "0cdd930cbfb6e609de9a22d029c15c5106fbb5603222b8e470a43594d1ee1dd5", "df8274c837ef863b3be71eeaa914d08a305b8080445467986fb0d082e9efc681"}, -{ "511000", "e1718d99ca8b8c0e1f84663aaa6ac9cd8c369e9118bd6ea5919856382019f5b7", "8320100810a7678c08ef0003dd4f057369386278d95ac3d9b316a062b1cd119a", "2bfa8f88541e9201f152753e37a77308212371e9ee9637f6ca5494835375718c"}, -{ "511500", "df937a1ddd9ab676d6b958c03e97b7789fc0b486d52e1a518f4d4e46d22db830", "e5b333e553b5a4bca5ee6f4a3ed9d83ba46d981a3ce30fe8fe0578788a400f42", "a28191834653d7ee866bc1f494d2563a209e6ff3ab47481b98fd97200dd52be9"}, -{ "512000", "38982a86cf02da0b76412cd5bc52aac39854cb1d000c7f24e6b66061c9552820", "7b4b3c77c94a5b9de5a7ce479a1c15ae56663e655104b0f0efb5f3adb971cd4a", "842759a6fe200e67aae64ce6726e5ff2ce631bff7094456b4b584dfc985a363e"}, -{ "512500", "c668fd92e5ab8abe4fa8c66022eaf0b8387408849349453ba8751194bc9ea391", "aebb86a20afe467e4959eb4704849a076a8e02cbc51c2dfe07648562e42f9f5b", "23e62a8921ca4fc780d6323c4a18d14eb845f3a1007392e7b7bb76b18e503c87"}, -{ "513000", "fa2042f44dad2c0e4b243fc07a60172d057c7715b7d7f73e9cdab068df241dca", "9bf87e1bf1a619c55107e28f3abdabc3bb3267a0b0225855695ccae2be2c8492", "242cc6413f3e77fc4612f2dbbabd708b8053589e852776a2bf64b49e3e2865af"}, -{ "513500", "3ada907b4eb50e027c4dce815bc8464aab74eebaa02c3fff63e829fcbcc06790", "1504730fea3476e4a5a65059e9e45acf9fde314062f93761273d0d47ef900b5d", "55f328b9a86f6704d88149b0a26c708e495ea614fc7c5874d8f45cf4e1d26350"}, -{ "514000", "b690974d95cf519aa561d59afc9812bf23f8596633d4e43638aefd0a645cfd9a", "53527239f3915f67eca6a1f57a5b82564ca7c4c5344668140b960adb23246528", "557fae97a12d934a1802a877e722fbe2e61b98c388bcf5785238414582179dde"}, -{ "514500", "4efdb833ed17ee35a5c830945a287adb464a23d60f16c1f1d6d3488d628df9cf", "f6990f581fe79ffb9d1bed01f84a338213c70bc996261e07507624df42c528a7", "d3f812637fb609e9c825929ca166e72fe21804ffb2d76b081ca43e9c6fe388ba"}, -{ "515000", "f902ef1df4acafde6dfad28852fa03b1961241be620aa057860c9a70a0fffafc", "f8f7c7f68536f87056eb0a199f0112974f80f4ca443721ec8c1d67c3cbb7fbfb", "ec115e6892b1887bf0c592c1e8f756c40dcf0a6f7e11898940d20377ed9b56c6"}, -{ "515500", "df363417aed948a08fe0c6aa48dbc5764fd5cfffadbc7945f1a6ae310a9a1d50", "d55f6e43fa28f97008367107abdef40ea271780e5d19a561db5f3af215e60ae3", "e3875a934a00bf7597f8a4d53a768e9174e1ca7d15c460c18d76bb761f99dc77"}, -{ "516000", "6af0f998e7b95f5928801133f52c03133ca1d706f044f545812d0e64afa7eb56", "79daefaf210fa29d3c633094944a6ea814f73589d3d477a38fb6d68f0380795c", "8652c12820f235e18f982ece7b8dea102025e48240aa6ad15f33e3c83928ada6"}, -{ "516500", "c7174fb637f35bc6822a651eddde06e842534badc1d7a4c2d61090e79510b970", "ed427f81415ab5bfc57f4cfaf8461c18a23a2ca0a7ec9b48002d694c70137716", "c89de38183c186ea1a1c82c9fb12b55a96d1fd66d71b0220704278a240c1bf14"}, -{ "517000", "f4055907d0bc72d6e28eaa1b566ab77904495bcf286d0dd6d7bc297b8fef7a63", "74104317e7c69033b643afb089ea06cafe18e13f125bb7a2f381ac88d362eb63", "66a856aa315f78489bd05b7785d0df90369e3425f1fc15faf09db747b2b4eb42"}, -{ "517500", "dfc6759e8ed2c1078dbf08a64b71ddc9ab2a04fff41fbe9a5c82a250cb3ef4a9", "5a544c7180a99ca77684597ca3cfb1257ee0e3fccd468e3771c55e4fd9a1152f", "1c5d3934a121c421245ba556b78779072c690c8acb7ca76c5487a04b4f5b8aed"}, -{ "518000", "3f867c72bf194f1c257f1476aa4cfd18cbe3a5df52e374b1f705e496e06840c5", "36fc1c6723e3e48773e1bd8ae04210fdf0a9d22cce523387250deb28c3793a8c", "7426d712b994a6cefb5f5103cb758d3df26f63462a6b40eee0f909068cbea6de"}, -{ "518500", "941b4dd50e5124b756a381e83ef95106d15522461c348d5e032c1b61d838e50f", "ab5d00a5d8df0c54e297611a063ba4357b4686259473accba2b139ee69dc4d8e", "4be2dfc858d43707f1aac833d26a1b451367b8f3d81915dc68db87366f90df82"}, -{ "519000", "2136325d5351d77945e009193f054b04492a8d8f210eef016a51630313a17c3a", "ceaa807d0b581d95060026f8ff02c392db4fd0ab5007a86053f9e0b93049aae3", "6074d6a72d358b551341996d6647c7ce0f89acd0c3fd38d9b850e6f0c19288e9"}, -{ "519500", "8740a71b16e0335054adba609b5df4dc066d157dcb0511442d8d413c2333d883", "216da33354860bd3b2b44d9f217b89d2a203836e5f0c04de39381776c78d43f1", "c8d27f5a757e018ed9f5e4ebdbb9b97c92f45e15ef33cc8335c9160bcdd7264f"}, -{ "520000", "21557c530c9135898351f2625779248d5c5ad1fa473d8989e8795cd650f3b036", "02327cfdef960f127b2a99811b52f651fd5f84d3064dc10b2b8c4c528a362c2b", "e44f6a53c416a47a1f4f3ff8fccfe6816a9042e7ba588c98f223c2da74b0c906"}, -{ "520500", "fdd0b3a9a08562ab9256162fdf1e8aebba6589b585f34ce26ff0ac20f3b35715", "cb7b802cfb533b7191e892348f4076176e842e2a598e373e6653c92b62b4d5f9", "8312f8654d973eb58dc5e3a9565bbadb47312966a776f619c9f8fb4dc238dfbd"}, -{ "521000", "4d45b8b34e350a098a5ec1575639465783982db7710d4ad07f7a299a19b860b1", "587836bb3390bf2dc472a0b9e20a5e643cb270d85ed4286180f358cc8d0dfe88", "b3099b886e7d7ee570dd7ef18190f281d69cf8af4b9222ab41dfa51fadb786ec"}, -{ "521500", "8357476f03fda1bb1f346946484bfa6cc9d80a89b508255c3c4b583c71ead128", "2c2d08c950c6437e2f9ff89d0c3b0d0467a7761a0f19d421e0c0846c2792bb62", "ea7c47406b51fa4fff9d4dde4cf1a312cb7f9bdd136b3dd1a0ee772ee56a7743"}, -{ "522000", "a12936a6677badc6d2c8e83d2058abcbd2deb580e5147f1e742e379f0ffbee7d", "322277c4d49c9c37e94b84c184e09dccd63cbf0154e61e36b497369c4c7f3fc4", "2e88c7b5e944e7fbd2d0a39f57e39fd1f467a7e85013fe3e3f0970dcdcc648a1"}, -{ "522500", "f0770540ebe64a0de99c169cd1a7d9c8459eae0e67873510f1a8dcf4841131a3", "25ae4d82a8a9089095bc4583c9842984d53bb4b0e6a162d369a70802b7f9476f", "2086480119c6dd31340a4ad53b39d23e2f357551ecf188fe077a4cdac405caf0"}, -{ "523000", "72d57e281db8b4a79f566fb587e448883bc1d1325c9ffc2931f1100b63e5836c", "00fcd8bff8a5e19824f0e98fca489d02ca2d27fa2b4fd9a73e410d935a1b93d1", "cde20a46475c12e517a4326e85632a956c9f5a2a3af22c84ac9ffbb0b088366b"}, -{ "523500", "97b2d54ba68ed4a14ca1fb4e4b697b2bf8f7d0332272af4531a72c94c35dc932", "04d4f8ef5ff03931eb5c0eac18894a9a7ac8ac7f6bc0b34b43420ae9d7802a1b", "21b276e5d11eb1a8331df44a4cd05c46d1868c573f3f82c8f047f67d3858a7bc"}, -{ "524000", "f5c96b25808ab9cbbcedecfe467e163e3bd9d771a8efbd3cc414c7adf1b7d380", "c11e17455d687b0dbee864879ffb41fa6dfefffd54d339fff58dfa99790a78f9", "b2bafd7f61e6485200c761f5ed481e768563fef25f82469c0c67ff1d1cb988d5"}, -{ "524500", "cc5a17d877467df92ed0b3462d0031003c642f64896f4019da641d1572d693e9", "7b878f323c00d5b6d0f73d89cff64319ff2299d310a67a2d046084a77b411101", "8f9c19111567dae6467b3d76132c1f786e278a040099af2ff5354f81f7c1cb6e"}, -{ "525000", "1b009804fbb8489d23d5512262d7536375873ef933c154a7058ec1c934f61892", "d583cc3f0f7f01c67294d2e98d28e83c81824cee30d1252816a7828c0461f350", "f1cced480702a35ee83501eac3168b6331c2a82ecf69f2387597d21eafb011d5"}, -{ "525500", "63de360342a1abd256b2f4a3f1a74da8e5bfff409282c8d06cadfea596220f9e", "124aca94373c78ba91a8f1c01d89d5bbeded60581199d3b12ac66b76c37c112f", "35bb495f4aba29424e088ef8b4ebb7b4b10e69902ca07c65f83057078bfa8561"}, -{ "526000", "25464aef8a123b8bc5dc4b9f6b83149c84511a88da41f7b5f6ddf4cbd340dd30", "ca911108aa51b78a806e58f876767baaf341c9844f31da71959ed4ea2f87d62e", "53ad3900a8a89b100539e325e86c7a7a515d77ed8d7bd0bea832a1196d8a2c0a"}, -{ "526500", "54cfed1a647b8513e845b57381456d983320e1f6dfc26bdcd4e97da73f31bd60", "a5639a2ead728587161e02add9b047738a8534d0725a84c5532bdd054e715ee7", "c5756392113ad44704a3691cff97601b8d7d4300ac2f0600cc17fd83fe74d0cf"}, -{ "527000", "d601736c31be7964de7a76ee1fa2c4771d804dca1c1a268b608f3c77971893b2", "1831200e768d735e9bf8b5ddddb9119ec19c43e22b966bd969346814cf454d55", "29c80fda0b25d26f7a5c2aca063a6702151d2f6af47a8af74ca4b38dd4b935fd"}, -{ "527500", "dbfd9c8fe9edc773e210401cb7341166fda6e1153a1fb47f866b919dbef91d31", "5f15be969fa28b64f5250f0787876b05adfcd2c64ee1c2c72eb9724403ed6dee", "2259567111129402e6f857b636fc0b58b1f732b522738ca1fc458ba6208b6e7c"}, -{ "528000", "92d74a8d4df0a8f7510fab8b5d02692442d1fb8bb9046cff981cecbef3353585", "b67baa2dd73a4061188c5cbaf13ed1c063e29193fedcac0b5440e042d39a45e2", "959f3a09311e382c55480bc857cf511a99fe3e6285b66bbffff01e97cd5fe527"}, -{ "528500", "b4a034b57dac02980cec5830c0718b0ce4a89bd3ef3f5f36e8b4181c1f42ace7", "de92eb4a468c264b4a9ad63eb75ca3702af7c023481c829041f328797d2e3636", "2acecdcd0c7fbd48c8bba8229d6f1c0a03568ae5fbb77f66716a1c3b574c9ce1"}, -{ "529000", "a05c9409ae06d5bc48284e5c624f8d6f6b001cc6f887d459043f442367e5e1e3", "dcb56fadb166de779d9d0e4e5e4d30dd558b0ef3fba4f9afc8023ae5715d30df", "b8c359b671bdd5ba67e8db94b747bf8bdc065f4dfd40ceebaccc0de8d7513f31"}, -{ "529500", "f62867ba72013c202a9a61da49b6e4eabc05e6d247f2ffd98235b8e4d862e795", "915588450e5ec1300605afdbd6dc47954df1fcb45a6a10953db21bb54bba5797", "0a21fe5e0943df74d2453e053ef4f5005db902996d852681c5a2f9bbb5dc85d9"}, -{ "530000", "35c57a8e961f11ffe1cf6712861b43b4e7d3cc3107c28d6d8722de90506a5b54", "1c060c7a921b2d8567acb70356957e7aa044d8e37abe1923ec1ccd3f0f7191b2", "b4229e26f05148844cf0d38199e94f5dab81704af3efd1de77c757b5b0a74d66"}, -{ "530500", "0aa4f3b5419e0844a7316ac4b76e00f3230781c8d320cdd62dc1dbe21875dbbd", "a3bf6f2508bcf7bf8a6fc19b2a75859a8c2d3a68858d6dedca2de5a5c687b94d", "dca35a1c94d6ac0857f3cad6f04b3ded87442aea24717a1b41d075c559030a8d"}, -{ "531000", "b65e6fc5a87f8d30ac2203e13e9e9fa450ada17650d6c639fde4f71d2832062f", "6c4e276f9cc20e4111c9c45b760cb529b12e6f6f9d984c6338e47ecf0d1fd5d5", "481ba258b254237c2af95e840b28ec971aa79f07255c696aca3d9212de6fc74a"}, -{ "531500", "4fc020cbe21507bbfef6eb1cb30c11359f8ba8ed0fabfd67181b596859a11fee", "736ebd1d9d616f4132934784dc13c0ddd6382616a501f11f84071f39bb794a0c", "396f8f1b3f89cf10e886890c8b5b3eadb5343e7df8df1ee9a5030fea95ef1dc1"}, -{ "532000", "936bf25a71f4f427a32035e860b049c5e0ecf36b0dc007608b31fb9a496b058b", "9c412485687232293357f94ea0cf8a76c84e8757046eae59406f5ee225651a55", "c4c17ffcb5bab52d1d4c4de9b23499080682f8a0846dfbd3939a6ee9c1c27e8f"}, -{ "532500", "51b5d1a338bf32a3273b45d2dcabcc8fde6bfb68f80624624b8a0ccecfacf751", "81559753a06dfa90b7ed984962a88154310cefa89233d47edce8438601051981", "c6cf7a820a418397881aff15b8da6023e70c44347cd440ce3c470ff56dc10ec5"}, -{ "533000", "d80bd2b8d148cc346bcc49974171c998a30bad85878c6e508d16c728098d5418", "cd8c0e674768e8afa69fc6366c3e2aa66ee31b8a10cceba75d3148857442c30d", "e496a4c724bf9f997429bf080e3fd5f7f5580b524d1e6c30639f8cd1cf7096bb"}, -{ "533500", "06cddea66b25e0387bb678836918cca4be53f245e84c01fdd8194ff147377a1a", "cc77c89ce8bc38a702e21b00df5e4e65f2217fd7e3d330aeaea89e67b2906d7a", "21f4e346e1ca43a731c5a0b8436f2330a3208906ec3466f50549e8aea4a14c96"}, -{ "534000", "0427f67b170428d1d33242707a2a8273c6447a2762ed42e49580526cee35bb3c", "66b923b19b1dae626b62a5c76dc9710d396b9436cb8cc549b87a4878f457e561", "f15ffb3d566f30e326febac3bc791706ad96b2a04a35a2792eca301bcb0e5c83"}, -{ "534500", "de3c914cd38e7fee1888806ccd3d4cd5d39b81cdd22f869cc5c2d5335fa29533", "77b2265b37eef1e316d0d480f28bbaeb8faaefee270991fba6bb5680a65f5298", "43b3d5d782029b1db91507a16cd1b8fa86d02d86761ba0d9e3a310e80d88a0e5"}, -{ "535000", "b4c2ed2b12c9b6ee617058231e9099ceacfbb10e344c8060df631fc42cc276f8", "1cef714d86e11d17fccfa377f5550acbdf781a19f272cc8917c3c9886b99414e", "779c713030d24a5f0b3477edce23e0ad33d798be1c5f70bd65cc5c982ad1f480"}, -{ "535500", "9515324744b14c233fe0463842b81e99c1c7bb28d99234d0c2126ecea9a3250c", "c96091825c57b11639c7eb8ac6f6c76d48c4507af32c1fc95a93fad60e5b1a78", "e7d3dbd4004dfd8cf66cef4a21ff7acbb71c07cf50f87ba69de6a2834231cf2d"}, -{ "536000", "ba4a67d76d58f76b3cb47b9f89792153db68285c94062df446d924e59ccf7b87", "6208b177efeaa145f365051fd3d5f9e82dba8c42f1d0d2b67635c4a908b7dd17", "ede7352ee474c6077c2812e5a598051740e885e16288a5426ef9d4a25f80fb87"}, -{ "536500", "865528966307aa0504e45931d75610ae56b4c4490c763198c1570a66f75b1f1a", "09c2e4d9405d693c07371d2eae527aa1c2311db979f6d2d0abfdc5467b81cb65", "d2d0a63b54ff19d1117c4fdb9d2f11368c1fc79f251ac539c05adc085b65e04c"}, -{ "537000", "c3355c3c49454bb38156c96fb23c13fe9e5fb73129bfae6c61ba4e6d1e46ef00", "29ce20cbec7687f75730f0e4be6c672d1fcf96baa9168eefe3030116e7f06b63", "818cdf33ac00f5a623486e47a6d74b145e5c61595b57055c3cf73041a111eb84"}, -{ "537500", "895be1cd157309627c65fc37e677a72fd82f27d0418e6b43998aba564d205369", "d5e4a2bc8d014079e205050f18f390c776f5b45940c5835ed995817dbcfb9da3", "4156fa1dff52b59ecc3a803a3949a5d2a100791e8390e10c10199d93e278f15f"}, -{ "538000", "99248aee8ec1681099e7018b3f27ff7d48023639c7a16f846ceba99bfb8b6794", "51589b8c95d4c555e3e85904368362e86c1ca65ee73cf4b3a56348352d48187c", "405b2b52ade6f4c8b82ef01114817f7d7ed72fc57cfb977ffe2316c62364cab9"}, -{ "538500", "8ed90c82d16b675f2e1616b4e6877fea7d223f4c6049c8abe24071ed0cf55cff", "0952515dbe216e7f8705998796c926f16186b5d911466f31d36255852c2a1740", "6b7c8f5da9b0681690e1f9e2be83d1b7ce20a9cd4a2c060ec17c7dde95464d26"}, -{ "539000", "5eee066175978a2e04f8070ec0a1c5e215afe79e6342f882f272e3ab3e5088d3", "a8fcd0b0db8bf7fa522a86757bc674077b64491860fe1e1c346d48b5056c3625", "50e3d3f8ccd7d7bdba7aea9f18af6b137ad7fd5e4291563a292a43a650601f1f"}, -{ "539500", "1fc7f87c388bd6e524b114ae6bd9654031d2cede075e50c5070d5f7492238b49", "86203c750603c2b64073e488e635049afd299e58642bc90cfc7bd562fa1372db", "3487bb31bc0ae1e79c810aa261000875d1364fb97719df7e5ee43b72c28520f1"}, -{ "540000", "c7c3d0e72955da1daf3ed29a7f50e39bbc72a97a7a3b9657151e2180b297bfdf", "d8789c0edcb9150d9cf88b973a2fba35c0e8a13a79e9f5e6fe67eb527f100dda", "65b14ecc122d122661553dd1d71b49450f843080dba874f5baa6fdfd20467c4e"}, -{ "540500", "078244b881a7ea8079cee149a21afb1f3e12513eac743435b26fca944d1f8c0a", "b0d2681f5339e6747da87fbdc8eea0947f09458e9e121fe715050d97d5380b1c", "117d776ab41d5019ec163153f0abef5c27f093f6b88a8a278c690f856f334cdc"}, -{ "541000", "c1fc5936f601dbe88f86537a73e3082d817270cfc534f985e6aadf1e69017c62", "c5025d93f22d3c16cf3f1be03756c8a04da4c330a8779bb156b6d6812b65db25", "03884521ced22f201c1a1e326eda5f100a82101bfc943109cc364b7ea7ea0ea9"}, -{ "541500", "f06fc398ee363680986ea85bba8897ca25e7d7398defc7ae5dea8950e5e10b9a", "6eb30b839ec9f6b85ba6a68be9a25f4ad0d72cddfcbcf5bd4346e61905e1ce37", "275cfe4e765b4c188cdf7170de44f22c15b868f25d0d6b12767b748a1b6513d1"}, -{ "542000", "f1133f6d4e5f03eee2ab13868e8a296ecb14fa9a0fb0074e5fc3cc46a1f7f2f9", "b1827592124a51a20ae293f4e824c8030eee78ee82ea039c27e427fe4d2da5c6", "c656ea7ef821db02521815d458246f5f692cab0056c7b754fcf9bf610916f4b5"}, -{ "542500", "7892e32548d849918dd9946be8adab0f8d0842afa1e9f62c066d27924a96153b", "421009927f9b4183293a0e7a57882322f87b30137239b6db48168b25d1fc5ede", "93910eb3544aca246ca379af94f4d0b102ce68aa282f899386d656059ac38370"}, -{ "543000", "656da82150e03b0f6920c13ae9f012c768ad1db9da51f3cb36cb08f597c944ef", "3fdc935dccb715960e745f505147ea8508aa5ba7c7f2a657a14ee46eec52732e", "0ccabbaaec21367052451bbce72072144a79388d4ea4af9af60e0bdf370632fc"}, -{ "543500", "9c3e877261982dd30c2c1c7bf6604e64b22fcb0ac6f1f31d133ad853e8b2475c", "058abb454a8f38b333a57e220049716ddcf596ca81ed33fa28772cbd87968bf2", "8edb00afd9e9f985db0b5e3a2fa076945cec714937afea659a981a36990c6662"}, -{ "544000", "1ecd239bf3296b13b04cd7aa240769324beb8a9de6e35f10c193ce60adfcd2b0", "7321ab6022acecdd7ec7526d7fd560c768da79151c01e409de85f70e8d9d9bf3", "1f35ff2be617b3d5298aaadb9cf600876c300bcda68dcef1c271c2a2e1fcef1a"}, -{ "544500", "ab6981fdb795d866908290b102477a670822935da8f8af9c6a32ee740d69bbe7", "c1eb309bc65e67917e1c46e7d0f232900974267e048abd48a1b04e1d4a3172f8", "960d00f60661be6b528eebefb975b8901243626368ea7f2507748e9c091a389d"}, -{ "545000", "00257b2829d7c11f95de86dee675a7edb80dff9715bd2ab64d7454182f213a0d", "bf13fcbf0b1247b11accd940ac8772789e081f0bf1cb70b1425d6288c69b1e76", "8079693ec5c445cf8ae5b353b0cda42cbdc95a417fd85f7217f98d2b42570e76"}, -{ "545500", "ea64a39237ad3d242cb2db3a1faebecd3b20c682383b014227a3f230a3345dd2", "09c175ccbaa02745d5f72bb6f68a9b32cac259ecc88aa1f49bb30d336d79bf59", "f2cb03e606e67f0f17b73375d215ac36ff167765383812b927792c3789d92c13"}, -{ "546000", "efaebeda777c28c7e35347e84da7681aaa14c502d53698838eea8aba6e55c1a4", "79194dc97f5c84f2a55ca245e93b69b5caa44c6bd5e581044e2e26580bcf561e", "d937a59618f4f848d0b4e37e1bb1239e1a036858240f70dd164615ed43af6f4b"}, -{ "546500", "bffd9b66e5207f5cb60bcdce5dda495ab78fa6206aed6981bfeb3ab4961ed56c", "2e133bc3bb1e140288f0abd4ac9fa18fc4e30ba6fa672f75cdea8fedbcf093cf", "157052919d1a72c7c79ae5494d54655b76a4af0aa63cd2205a819cdf1302958c"}, -{ "547000", "b7c08bd8cd06070b6b52aafb511d26a3e4dde18e15ef004576de6c06024f2a30", "6aa7c21876ee2145c6b97d41d858abf162abee2f179e94e354799664f38be6b9", "6d4eaa24d3d7467bf302941fe3210cb2702ddb5a57f6e1a79aab790c72bd3d44"}, -{ "547500", "77b94303d50c7c640f68812f0dd13cde9cdc2b43c5f6e3fa4c99621be61279a9", "31c6dfbadc919ec783b0bdada382c4c3e1204008b245b6455679b08aa7f2a6bc", "17987eb01c4bd98d605cb76a32be640687e8ec900b36680bf6dacae55bd32f3b"}, -{ "548000", "bf973366b8395a897b56bb1f9160f8144c40ba17934fb14b46d2bdbb32715fe5", "a732ddef1fa97dee750cea03675a6eb9557af9ed6314a162f5ebd8ded9407698", "d78fa85231b0fb69790e643c079cb7c34d1c114fbfa8c1d7712b01ff71805749"}, -{ "548500", "c2f20ed6a252cc714238efd5531084bd5555ab8ec65169a86c9a0ba97b2a7eb5", "d029d1bf6706c1b298d9f7ffdd53a26b17704433c42683bc02718ef33d2d70b7", "a2464ef54773a2cd6dfdbf05187ea2b0e1723b3dc22e31e1480d414a4bd13943"}, -{ "549000", "7e07ebf8ad3697390d81f7381637048377f461e46030c8eb1feb17eea4c9d3dd", "1f2183d7618eabf7356a08a0486675b0163aafe13e6b27bb6179fdaa59685fce", "ecb2f323e8f843183dac9fda0ddb68aed54277bbc0e5de60b2ebd0ab37a0cc95"}, -{ "549500", "7ce04ee7a21eaffbe862646c3a301460da80cecad0e9a66a157bc1d0c335a18c", "989d7ef547727ed49f342ae3681e86247ee5b6ad009a863ba0dc517e7977790d", "7745d4f12b75c63a7213bfed8d46bdb2d0ea5f75d9765aa47ce7a689a456be59"}, -{ "550000", "0b717011e4c14ba25388b6be779ec7a7fa2939c68a49ad5fc8cccb32a3fc96e6", "d95f6b2500300308ce3f44e53c38e6f0eda793b3e1d96f698cdfd8d70888e277", "1446f3a94e8fcecd1819e47eda64932ab5f7cd161f4801b96d751bd11bd8edf9"}, -{ "550500", "b1388fa70e3a79143b985bbe2587a8a36a3ce7f90dbdf93c312bf375b04204d4", "2f81d9add40226b4b3d3f2466a2330e412de80bc31cf3242e0f8e8c1f45f1a88", "2e0c55c354dbfa29d8ecc9611013fd969f5a843b8413aa79d4b5676d9a79b7a1"}, -{ "551000", "b0f768d89c0f0e5929e41afa3e9711a2f6dd04c71519c718ec5a4851f13ae4e4", "2b1fb05c01f17b3eb7268d552a99acd306e4dc0107985d6020dfaf4443dadd73", "4ef4d4f9a0fe87fa3b1bc65c582fea5eb43b00e4253b97bd536eb342a3dd3457"}, -{ "551500", "891da4a1108be080247fbc0089c4cbc2922d25cf2285538261195b41bfb48747", "e5f1700d6fa46e80db5586d1f3261b758d374d43adcfbfad70ed5112bb1bf603", "a7d24449924bfee8b65e9f093a2bb9f91f104687d03bf464ac13500b995ede8d"}, -{ "552000", "8a4da9058e5aa3a483af0775ddb984048bec5a52dfefe711d620a0d179856ee3", "333c9af8ca1f58b6185db26d60b4fbb955176320995ce208f18aaacd277b4f1e", "bdb844ca20bec8acc9248d5af27b3dcf24dcc409eb510831d512be7ac8edecc1"}, -{ "552500", "f290fd729e75722394720a4b82e34da44d640af62c995fe6867fdd9167ba8335", "e85093bef089d344639461c61bd1ec7819d5105b4f984d423041d035335e24fc", "690cc872111b3dec9cc8a048824d722043ac13ef208e12d83b596977cb444569"}, -{ "553000", "2558178ee645f229d1b39f11e8bc8e423e6665ce3e7491ca195fb72d8a13034f", "0a823b23f9e2761e8f32e42f7bd569ebb56869af3a1093d7a170f792605be7dc", "16413e820e03f1fde3817eb61868061671bd12df892e47edd173c9c9184e7455"}, -{ "553500", "001c1d53874f0032ac25fabae2f92deca9235bd409eaac1aebec39bd798830d2", "d36b5ccec99827a8a5d775d707a82836c0a10d13bf9199e25a3c31bd17f66370", "29bde729227b92003a7c09dc8f78dbc155f72129129c2adc973277ce578323ae"}, -{ "554000", "e2710db357675cd18df933733e23992517017ab0507fa218fb45bc9f5d812224", "786326555bcb406ffe22d8dd499684db1b8b70df508572f1ada7dcd6eeae85d1", "418767697d50c0e474795dd78c354da21c5f71eaead7bfd37d8f74f282b581a9"}, -{ "554500", "cd244e1a5feb9d4f3a6c51f92f1c9396b8871ac5a20cf587092abb68b4fe2eec", "e7a78e8e16dc73cdf9064f039df1a67996bb3eaa744f2fc0598bd07519078b24", "9782647f3aa642046e2439c624bf99de6355dbdf5bab50f74ca65512369b6b05"}, -{ "555000", "1a6ebd86249e3a3837d8a1eff644e240333704c7f9c48515e849578016d8fc8f", "b5da194a23915c042e044b0d3e5e1856f7640ac8344a013d7a1c459d967d6eb0", "8a70c7be79d5edecf987e4cdcabae2f6dde5118fd8b3fb967ff40fc054197ba0"}, -{ "555500", "978b357011addba581355b92d3faf71397a7c55689ac4fb0d4a6eebd8409f714", "519677a9eca60cabdfcd5e888ecb570d09275bb7e2585e9226a9b664ad0d7fe4", "675bfea85793acff321a1585195718624421451f27c0642d964ab066a1db35e2"}, -{ "556000", "edc28b6ce373cf5a5d13e86ffea09ac385d8d2bd251ea07617b10abade558e12", "7b3f6c61707185443f2565ad2f228bcb006302a1bec5a203f143e730c681a9c2", "4e04bdcc89e6827779bfee9bf287c347c564e6bd2eacd870b59e22fb6fa0dfd7"}, -{ "556500", "95ae0bac1e11d4df7fcb554f665966b3bb2195010c0cddf48d07803743149578", "1c9c7ca6f9c8b40134151daca7a7cd1b7cc24deac24aaf2f3a450b34b74730ba", "a8e00ff92f14de5e42fdf72a2f432c30cbbc9c0b4ae93b6c44ab753e272b3c99"}, -{ "557000", "a1cbf8cd746fe3b27616f6515149cfb57408d82b8147c19510ad13806b7845b6", "2287f21d56991d98d17edc545f93a85d01b7919fde25d726cc9cff6f62d97461", "dc13f0a7ee84fdc2a585797efee7a60066331d73320701861c538e9233ca36f4"}, -{ "557500", "1cd1617ae1474529b7b4f322db9442763fcd418410a3c3e918e17f13966491d4", "e71635aa05a9aee0ca857b41574d348954419959f8782b6aa3b7a3e0d3b6fb43", "1a0b713c663485f64881db18ddbdeca1fb0ad1804e79ccf3508b95cd57a2e2bf"}, -{ "558000", "ecca0843b0d748735413e34ca513454ce2497271cf04a9d12455f0bf07c09f22", "c3a7537c5ee0d6615a53e3e30cdcc6433a554a120756be6247f3c3b703f023c9", "4d1e23b9f0015f6f61e2dac4b1cb9eb95b57e341b648a17148fa52009f76879d"}, -{ "558500", "0bc0b2dc367328ad409219afddf852412ecedb43e048ee73449cdfa5e152159a", "64f4cd8ebaf6f492c200b11b080c521f4efe87e777818f9012e969eb2dc0fb57", "e431dfc02248b71de80ac7384a53e01a05ec14e4b4fb45bde40887fcf2704978"}, -{ "559000", "ac95a1595559d38fc68c9dc48d9af40b3e31d71c292a83998398af38f09b3fb8", "a65b3a0e37cadbb31f367a83edbc4c70d0537633af498c9ece211c681fb9f671", "2b96cefcfe13308712200f32876b7a6256bffa98286c8764450ea1a83a442067"}, -{ "559500", "06afcb286229def7721d7a5bfb22cb59f1b25c6aea819bd26456d5fe0baedf74", "b871a3c694108b366de593c52d6a1b3c38af1849b0092e5474275258239e6088", "24417d305aa20fcf134683ad23b967f19e186a64252f3bae6eca3e4e4a3ef57c"}, -{ "560000", "538bfca7649306c7ad77eefd31a7cce9b81ee7ee9d20d97322e9f785cb555afc", "e08954b12673a8e87fc4db6f848c2129d39286fe856ab80f3a11480a82772963", "7b06510d88d1fa90997ef87420a1d1a1bdc5928428203a648429b628d781d717"}, -{ "560500", "05fe497d72e403e9753264fa5d4a7348843e07afbd260e21fdcb9898d9de63ca", "b538d81ebe3d0367d4820f155315debd0b078100fe17f3ec6a0c1b1d989fdf8d", "0b1da1f2ffd782650bce992b478854978c6664b6c481bf27598afe744302ca7b"}, -{ "561000", "b80da09d4fc326223399fac5659ad647dcf37232eb63546212c7b951d429effa", "014c43fc1995d966785af2772de5f8d4738b44785a2bd81145d32236931bc978", "d14ee2fd9bf678f965b7ef6d3f22b032a66ca72f433ce8334d2845190aced1ca"}, -{ "561500", "998927d54433d0ea4fe19a4ab0eb8e08ae656e8cac608e3a824bb084967a37e4", "a7709319ad385d1345ee6171bb57bef2d0a648278e6cf763068496eca01d5315", "8e3a7ebd7addc79667a9a8373b6c599ea24a4ed13ce6a936535a81eb275691dc"}, -{ "562000", "a005e7c48077a108e353402f478f0f3cdbadeb95f360f6d4d056ec8aab302f7a", "ad678ad8a4b421f5211b5953c3080ffde18f2a395f5f77a467a6a3991e155b97", "15d1e5baf244b9c32913691d2c2c300104b18857f5cc173b53a4d9306c0b8c55"}, -{ "562500", "cf4a618bbd1d4eec4f6ca3993fb2b3ce901592c365c2b7526c9de2d0c98cb74f", "05921bea10fcdc426b73459e8ea0ab421c1635c93b60ee8d950cfa0efa91a126", "e99c2a2cab3e0d393929fda25bb77a7d21b9660e78b02f36bbe6d9a35ab67f9a"}, -{ "563000", "ffcd676fa825e67eb4832cc72b5767f50fa306f1dd251055ee3f623d9fbf4d6b", "f3fcba9c0dafd172664da1d0e692cb1f4e898f23eccce5a265104164a5ece2d4", "26ec1364d9b1312f0adb2908c1447cc89c4afc51db4b238217b763878b353532"}, -{ "563500", "5f96af414cb11afbbcf48a7fd1738fc1c8ae91dfe58ccfaaa7149264ce34c5d4", "54756714dd75d4cbcf87b452238296c5acbece0f991ff2cf3b239d6af4b7f4ee", "5d10e1111c38741986dd46de80f42c6c2410281c518c46ec13810ee566f6082d"}, -{ "564000", "0345b35925619ae8f774196dbc6ae52b2d065ee4ca6f9ab87aac366307e1512c", "7ccabfabcd36f82cc3195d587e6b530f2e303525e253d84376f02b907e1bf611", "1fc483c4037a1e0bc2d4b5f638e53c9ab8cd1c1e0743ad3613797c307a0cdbd7"}, -{ "564500", "478fd153799b8afd93360f4288321ae7e82aa7bb5474f13913274834bd4b1ba9", "b73b7af475c03ffe2bd0e9b09f32a966126d650007f991cde96bc8ae208d2844", "2672f60ea8969e06815e56c9241a79ef6249cbf7be3bea3752394f008799b8c1"}, -{ "565000", "4bf82342209df889c321571400c9170621b17c9b88b60b609a7a9a31a4e6879d", "d33e0ac1f8f8614cfec0768dca67ba99561976ef142a62171bd596ca26265462", "d638ba536ad22a53e0a2768f80102d958b1ad4d24205a4d617d9cb7d082e5537"}, -{ "565500", "18ef43d2230a09c588644154757d4c3136a0dcebbd1e7169349f280be113ec99", "d3cff22fd147792fef86c9d94f7b8553c555a925e7038e738bde608c83ceda53", "0b5c5018ae69065cd19e245914afce8cea9cdb05f2c26b1cbe6c5ba0764dca45"}, -{ "566000", "178cd3b2773545e457ec933671f4b7e0cfa269454371789d79c4c73d879fa497", "776636ace5ca4a51abb4f04c22d5a2a0c51d42368f43b8b776299b087d1bafff", "9bdc510f5ca8f1205df553f32a927022ee88c90f7d2c69b4379b06c4b62f40a4"}, -{ "566500", "6e70ed03c1ade6968a6f18aed75a42130abe4674a9cb3d6715d5320474a310f0", "9e51b370f5e5b6dd65ffe6fc854265dc071b7dddad6a68e25a6082d60a4573e8", "c7f964bba1c9b43b1ae9018d55f6b9da0d900c503d266916ba781616e67069d1"}, -{ "567000", "6a0b1d677c5cc0ce3f890ae8495c70403ffae874414fec9e3ec8b3aa73bfbf12", "44a2fd59a3f18b4d59d7bcabc842bc21681b3c82613c95038aec10315bfdc050", "382a6656d846da8d438bc7223b7461859732ab1b06a80b454d78fade676c7c64"}, -{ "567500", "aaa507e4d8344e885c748389b8812c28ab49533b13fa635bb345a4495be34850", "f0b2d2e0f7477c8703fb6c7ddaf4d22c17da14d6bb1be606d96b4fe23932ff61", "e52ba28cd8136cad574b671e145507841135a991c1888fec787df0d544932e1a"}, -{ "568000", "058e126ea94bbb99030e2be4364db58bbe0703c0fb4c3155ee7c386e19efe976", "e68dcd0c11aa8d9b09161d9fdb25196b0b02017743235c5e77c83314139abc6a", "49d5e2d66a782195a1e12691f6ce53d9a07e338eebfce99008c280917ddda751"}, -{ "568500", "369e444ff13a9ce379c2c98e70e2e50e18c823b4b43d51e57224f9d7bf7c2a82", "e5755456750a9a92ffefb86ebd18fcb6d4f790bd51e47f1dd92d5d0db8c60b7c", "400e3e42c56872793b2fa5cc0edda233f746bd4c13f7a5f89a02d07985170c8a"}, -{ "569000", "50685dcbbd12f30781fbb546d1a4cbc349244a2d6e14ccb1530059e4073fc0d4", "5841f99c2648c1075709873b22b8bc25695c01fb146b0e82291b6a0f5cf16fbf", "273062f388221c9d500cb7532dedfce411ea6129fae1ee2ed43d54de4aa6751b"}, -{ "569500", "452253574aa43c9f3ecd39f7122789bcb9c83e343843540860b950ff27d673cc", "2ab70f1d2aa896e8a8495df628e675c983e45047d719a9e8fa0804f34a8f82e9", "73e5be387bfda500adb062cb6229402555b29d5b9a83a928aade50443e17c68f"}, -{ "570000", "c1b6627d3100900dcf795d2b684e83d11a797d2302a3bc058dab61ba109e5d08", "997761e1d03f77cee9256dcf268f308a14899d00386cf1cdcd9df39a57ade810", "781e60d9004ff259f5c679728c36e1824abef28335ff874b89d5de2a02f40eb8"}, -{ "570500", "7cd59e7583d4c4878b1dc3171dcbab4832d2c4d61512d7f313ab88782a9d9336", "0a439cac39577c5f0188a201ff1ed831ed2fbd5d819c6682d7aecb2e4b77b7d8", "51dbef7173c663e33c223a0e5cf70cb857efc63c4cc9175f9ba9b817552c94e8"}, -{ "571000", "6aa099647512a9654c54e730e3f1d4a1fda25ac58387503932ded2817e5b446f", "a629a59a6420e7edf13f0a7dc05a918f86f9fb337459a1f85b65cdc71b301d92", "1413e4b5c9ac9c379a8c558e0e20eb284818837e07799e4ca0d01fe5d53429a6"}, -{ "571500", "a3d2f0b075cf3e735e586c69c3eeaf7a07cf0f391e1a6ecada1327abe8ab8c8e", "c97c75ac8bd884337edb7011ce4a68f31d1a06f477d821b9e473614f871e059c", "bc488c752c8548cb78aa967bf11e8d2f8c23c6f011a4d609746ff18f27f0f3d5"}, -{ "572000", "154d5a1e996a34d40d3aaaf2244d5df055de5902201bbefdff166b63d440090e", "38fafdb36a68381be6d3a3f358ee61f1998c8647949eb6659f8794c5d84646f9", "34bb1f2f2e84acad99d095f9d37904ed8aa9a72cad03f6b6a20051184a53639c"}, -{ "572500", "05d47c51813cee5f42bf7803a627ade017772b7f4e734fdce5a824edbf480359", "ce6eeaba07d4a7d43ae137f3f66d7bd2c3ff0b55b973c0e87283011f58f94fc8", "d5e8c7f3eaa1dd7e2e9e86c3f904fa18066afc90f19f5b09b5119ceac51383e3"}, -{ "573000", "2cc24da51032f6db15842996a46a0f01e17e7c1fa178d34f4d520e57a1dec5f5", "814f5511a95d2112e9d6f5ff9147e4af6d2d14c674008901888a59d77adc0127", "97cf19530e18aed12569602045be833d526fe06530a6358c515603de77834b91"}, -{ "573500", "5a412746451823e5fe7cf63b331c59b6b1808d176c1f3562631755a1aec62267", "a8a55f440729934a987fa7bcc21e4bed9ae4cb4fdda5bba05f328d33c1c93dca", "5c9ee5926501ab49698c54a8eb543b5f212b2a65dbd6b3d71bcbd04e9798c411"}, -{ "574000", "4e71a21262bee73564eed3938de4c2a673ae763450fcb183bab52fc3739e9307", "f5fd0fbd347c9146a3356914145926887833b394f0664b2e5d098660848e8b5c", "cc86ade9b13e059ed4015a5481ef18d63069f67a52d67749e4abe1ea165d62c0"}, -{ "574500", "bee3161612969794e4cc7811c35fb9fd844623da6a5b5f2dc38f32d50728ab90", "ec00c96d649a6290cd6b929e1a71251e4519498493fa0ee2020ed494012693b3", "baac4866328b40b281dba068cb2d3682cde33b52ef2101df94ce1883d61bdd9a"}, -{ "575000", "0560ddebf2a1fefe36dfcbf14c0b9e2101445b34e79b4d2d2f7c329c1dc5c97a", "58a5850806bdc8a70223873c23aa3a5975634c989d8ef4f4f78fc0b71c025a59", "2cf5c97d7e1dac4ea45e91316928d92e4b74440d2c059bdade7bb7c1cf1d45bf"}, -{ "575500", "077c9db46dee33b8fed0edbe55dd09ced1c04eb22096d9a7f0a8238b764a9005", "a527ce25eff18c724535306c76670e1a44b010183ad970d41e4168c7e47e8ef7", "db44f4bd7201dd8e1b9deb53e77c7a93787e9a992ad6b9446a3eb12f28bebeb1"}, -{ "576000", "f9762a0e8b01efc84c09bf94e0eec3168852cac22bf5e0e657957ffbeb857c08", "41b866640d3804e09ffd386d7f6b0cfcc5e95c65991fa0b753c875676eec7c37", "363b120084d9530ed7d17cce535866b196dc4d39aba6ba1cc875778afedad3ee"}, -{ "576500", "fff9ba66ac3dd62ff0931e644ac522896b5e86c2a23e04bb4f2501145dd96b75", "def321280e76f1a8aefd6607ded8cb73769de57f19c641b7c6356e60105d89a6", "c8f349560443ad0a472731d00b20f77881ff0000d4e429d8272b13628d9879fa"}, -{ "577000", "69c48c7908b7b71bde3ba3aaacc99951cccbbf4ca98fe699367cda9c2101efe1", "da1cfb6020117eb45c262bdafdc11ef962f6156c0c95e68cee1bf1a2b7b9a1e5", "b6f18f6a70537b73dc145452ef80a31555c131c5edca2b7815a5b9f7985a07bf"}, -{ "577500", "9c563371fc767b2343d7f1cf6f23e4cc7b42aabb564e94a5cfa940cd84330cb2", "33aaa085f7076d2841dbce57b42bb7c61739c76f041c130becc350efcbcb5138", "045c19b336f55e018042905e862fe43b2b2dc16a1b8e4adc317184e91768251f"}, -{ "578000", "e5b36705e126028107e070cd6b748d0ba1820ef3f0b7cdbd8c60a822011afbe3", "b2797c8eec34eb94ad7b5de3c93144e6511d79ec389cd2b3037abf705da704c0", "6f8eec5d3f44c63f9f3a3756b7458e19608fa7b2684463a59daf70abe2e08a13"}, -{ "578500", "0bb4c3b62c096285827dd7079f91bb367f08fbf323f01cc27257c6ad1b6b09f2", "2709c029d1cd3164ac618ca33d9453913f52247ca266755995eba29516fd6693", "00483a8ba5971f1cec76a0d4981b68ebbab3cb8d85081f517afd5fb6459b9357"}, -{ "579000", "62ca69f749191230d6588250d41ff452312e141c30bdc253a4ba473d3736c8fd", "9690b50bbb4fae4acf7114beebb9c8f012328638fbafd2f54c18db4983c019fd", "2d1d6f2e164c7f52e9d62d9822d503c15fc45afc1b5cacd362adcce8c11f989e"}, -{ "579500", "ef36ef78010479cc9664a2e7cbbeed19da7b60b990ae1d6ca1c62815b74e4ac7", "dedc37c50f5ee81e9697c49243e55aa6ed5c5ba8d1d56305c5120b308600fb6c", "46275bf5cd6ca0c8c1d87fabf04278cb022408a213e75a118a33761af59106b5"}, -{ "580000", "439f43597ce36aa161cc2c4cd7c25607edada72003a7fb681be2f6d8b714d14d", "be5636a23710b20c61b3aa181bd75a4e0992dbfc1d267be7c66a3bb459ad10cd", "055fd581f041fb63c623e7a7405d178da44d129f6d854ac6e3627230e177d688"}, -{ "580500", "c6b2c13db62622a7c3ac9e8072840de5d24c34f6337fc3d8f826933501245deb", "25eba3116b640e04a77b843ad79a25847d31c2c5eef7da98952ebbb526440eba", "6da7cf2ecb2cd071163c66ffa5e8eb3b392b48992ae3b8a66070394cf5d0e167"}, -{ "581000", "4dcd0d20d94245063d630bcf6d8079cbc52dfc522c0e320e39c16ca18853cd6c", "ee3c988f0ea99a39c2cf69e88ba22aedaa2710f49bbaccd1ea0b2c1ee65648d9", "58291224ca13b2ff40bd30df8edca325b0e3ebc5564b218d472efb7c50837a6f"}, -{ "581500", "44b084102871018a5db5f990085f3177856a38a8b727a36b29837c34e4a8ce59", "6d6899031aab90e68c34f4bc3c1458960c7debc0e5e88de13bc0d29d9a4f1406", "7f6af65874fabff02aa73e1351f90945b167255db2ada7ddcca6192a39fce9f0"}, -{ "582000", "4fc26f1bccf775fbc7314ca86532fffb93b9be94bc6f1bd75fbcbe688eb9dc1f", "07296b68ecad02d38df4dfc0c927b430ce4c978fd42772740cfb185d1f73cf08", "2149719640ce63893636f94b837b785d177c0823c548b7fdbca39467cfcf43ec"}, -{ "582500", "fcdd7ac7dbd7a3ec5bffcf498ca341ea6f45eec4f07fcf5d838805979c154e75", "1fdcf21608195ac2f0076e8203f72e8468099613e8edd350440efb4fa495de35", "8f746c3c260e6c70bede298a49413b678bf3c5adad82adebf03c73efdbca9dd8"}, -{ "583000", "d32c77f1ee2542c91734ccfbbba36b35dc4b76db17374b52d514ab45e03031bd", "d7414a5f1b9e801ffdd889f95d91b381486c2b7bfd718907df3e4f3c16f831aa", "a786bd1059f0d53827f3fc5b95f44a302e30da16bde84a9b9f6b635b0b57f1b7"}, -{ "583500", "bf8b25a2a0b19d293bc739d63786a6e5be7cf111d60d6cfea462dc2cc7cab22d", "c03d273bfa3ebeff31d43a7a1fe34b51a5c968676dab85910f61691ea66cd879", "9880b1b9a9f0fc497d0116b07708f56601a9f0d617632b4300327e8e3e3c220a"}, -{ "584000", "b3ec434425ed197a317fe360d7f2bdd065a7f167e5c57bc9623cd150df2aa5bf", "42bd629da8bdfeaa2aff0cbd4092f1db54db6da4e4487a7460ca7081849b1d01", "985da906d7a0a79f9960993d47e5627543a6d53921c96f687d065030e3fbdbea"}, -{ "584500", "f09dc804f47fc9fbd5a391883d0be1d3ccf5b71a69e9c2571ce1ff55b83422df", "28cec5b73ebea11f29daf62db2ac9a594a7497ede4087e0932881d39343d15d1", "fa2d4b9a933dcb66f6e57dbd7a13f7c2ddb67e9701aa39a77a520f14586159c0"}, -{ "585000", "5874d180e9c48959e292587310dd81134eb03197f0257be1516c7c50248fc3b5", "c5e42637b4e90535090b09f2d90d7ab90ce46eb3255ce6abad941ff07ab5e0cf", "403a7015bedc6c32d9390a083ac82f7b7afb46aea0a4a83d5167ec7a67c2a447"}, -{ "585500", "a6dd4e58143b11d190e168b1dd20fd7da47ba2af0d089f70bdb5ab423c8f47fd", "134ef498a9bf87099abd879d68ad7d67ef4dc45b63bc16438aa0f95092e34c8d", "d2ee92dad9d11746f6f8dffbfd0809108733f964b345bbdbf7694a0f6e88a17d"}, -{ "586000", "5fc5f5de827b01b620304dc74ea53a0fea4f814bb51ec5fe3b6c74ef560a5917", "e1d0845de83160f08be85d114882976278106adf7a3c16ce16ff6f08caeeba7b", "9d3de6f846271f15a037a646c6332b33fb288dc3fac8dac4e694f5c903543b35"}, -{ "586500", "2d1270ba120a5cf1427736d7f89cb05c42af508e0a0038833c9445dfa9c66fd7", "be7998a06e1fa3910cf77a7cb385cbc6933abee919664bc52a52afa5388c5b0f", "8264179f305f8c60ad40a69140749aa1353fec67ee02e3fe09b0b9f51d5c1d23"}, -{ "587000", "47ae47f30d7d51e5b874e5ae103aa38208203f2a380b624cbe1ba122d222f9e5", "81558ea382a62cc93ccc002e8ba9d88058ebfe683b05be16fac0d84612ad2152", "8acf0fe6fd5d74dfcc4c012fcbf80cb0b93b7d212c1113b6a3f5796f9f54a319"}, -{ "587500", "a558bd54422bc5d0a90c20310f81d9901a9d3956f5d5505a5dc50b6459ecaffe", "a8994820ef7c6f2fd8d9b6d710a0f83b537ff6fa1368060418cb00ddf642f357", "746fd31278c09ebf66550d76a61464e1dc2dcec233acd70ced2932210d715156"}, -{ "588000", "fe5749f9e8ce47f885f4335cf2b24a6659913ed62e7d5af026ef0470004d4983", "87e2b4277260305d5bfbd921b2d4592e180837e092f2acd3896621cffa5228d4", "46bebbbb161226814d223a33cd8e0a172a30febd134800c2fc583eb62989464c"}, -{ "588500", "4c798283eb8cbfca17647b16a919d49b77a999d0bd319fa624ed665b30172e21", "a4c43d466e6429ac399cba93e1a594703176f7d1d7f86990936973120554c72e", "6b6f4b3290e47a69dbdbf251a00df4a2b7afeb7adbca47a41dc590d3a425429f"}, -{ "589000", "f8c9ccb89cd751d66c9e2b053cdfa670556f6dafac1e67a12f8bf06790c9fb93", "ef76c7bdbce08ea6dc8dfbefec9d64b2bbf3180dc4304ee7e39d8c098ce3602d", "b69b5f0e54c78368bf62eafc60ff13cb2ff8489f8421583f75097968784f1aee"}, -{ "589500", "0971e83e6a813fcc290f352ada5422a0f48b12e15628f9522d1ce40b2fd01e85", "cd5ac7829f9c4de5b606b3a5406383ab2634f09661977f867c47d58f89f16081", "31182ab94364878b63c1a91f2e0f939202bf757bd02ebd22d88ea7b555d077c1"}, -{ "590000", "cc8a0c71618970a1cd40ecd78572568e8522faf1c6cdf597def52feaabd15eed", "ede2c72e45aef2c244f56183b127ef08f9137effd46386eb8013f1435de42f08", "3e67a14b9f791f361630904de1369a3caaf2472a593ca037dfea9e0a5985eae8"}, -{ "590500", "6c876707aa719eef0d5a9534f9961ffceadfdfa16e75a4a8c7f5c7822f8d9945", "44d6b98fec0842acf25460f93ac90ce132d3600c752bcfb18d3e4bea90b9e052", "c5a46e6e838d286e58975e95cf4a8e300db9f1485a2c8e1b1ec5fcb853ae9f6e"}, -{ "591000", "5c5a7be46768f7b29d8912feb8eacabb2c592fac374fd8b1c9d74124a5bde94a", "b725f0ce70d650d386e7fae730da1d44a308d2517c91e0f6d6fc659316647202", "0877e7e5eb963694dcb43790291d82c01af543e18e14f4692a01f4509f7e3f54"}, -{ "591500", "4df0cd912fb5772a508f9ab6fc5dc26ebcfc8e5fda9026d682cdeee3350f7f99", "1a9e6cf241740c2f4f615bf2017473e6eccf52ce14ca3c244609c83411749374", "90e218efcba04b935ae73a7e1311b084051c3c2bf61f811a248430377237deed"}, -{ "592000", "5a9465ba2bf3034272ebb1a8b742abe5b66607193dd04f838bd9a2e9525081c3", "c36756b7c0b4f7577f33bb7a6a2cb06d444e5bfac823242a2208a74dfa4a5264", "0d5e09dda5e7e93d41364001d41b24b7ac3eea27c446208854aa5636a0a65a32"}, -{ "592500", "8e712cb434a6086e1068c5a36a70ac8382f8bd2df8f3328e869b5f74c4d3e268", "1f6f8f8c7b6abb35e1bcc30443a2112a1cf6711f020c6474ea2b987e122e2710", "3294921e4f70a5a69efbf0c3133ca8da617007c78f066f630af08aa65bf2a38e"}, -{ "593000", "5d4b59deb55edff702d98ceafe7e74fb2c27a9e82b3b8f38a747c0013210125a", "397321c39e0255bbf2f345d8c410a3a75f0cddf11f90b04e1fed22d57313f436", "b040ad6fb241b404d089784c592f8459a34cab1d98b45604e259f97cd2455979"}, -{ "593500", "efab77d82b76d1ba1f130c61a5146828ef22808cabae00e8aaca746c9701756d", "5ae3383c918a2d0de41ef7e68ecc81a14448ae6265fec8146377b88c14678583", "5edcc7b13d4dc057c9ec45bb9092d9edc9059ca7c66cec27f98291a40e514839"}, -{ "594000", "2eddcbffecddf8dd19c6183606ed678b8d3c80b3d18a03d1f6c98de436465bbc", "313ed4476687d320b09ed8f775c84f848b315ec7051a819b7b5db928b06b10bc", "85ebdce92d77627fb4f70f770b45eafb2ec031a0a7d5462d09ee5935aaeda4ee"}, -{ "594500", "17c2823062fbd036efda8d7a6cf9f02177470df9ab03a1ca6a49a4feceaa813e", "967817ffd15c1eb09ae18be9c89af301d4faca27bd1435a4c1b016328efd7452", "1629667a82436cdebe1c637f4b12892d0ccd4bc70506da6c4d8112d75508a8cc"}, -{ "595000", "0b2d83d89d4bfcf2ba0bb0d6f4f002f83b33532a9c72d204b84c3624b82d1d12", "ac1ae8086c27ae5dcb5491883fd2c00dd1936ce5ebb753bb9721795b51ac427e", "bb234d094a4a1a1fe506aee4b5db427ca92a0b608841d82d79e3bf83e2b9780b"}, -{ "595500", "94e93ae2421b77bdb8eebc5a889e0dbf64bf0af3a9d7d718b92c626186186adc", "58b3debd63420f3503c3f813e1fec6e2dc9de31eabbfe6a5517eda797c5a1381", "a58374ca77ddaa4242e2bf68a540339e00323538759b0bd33ca68f127fb8d638"}, -{ "596000", "e556867900ceab6ad0fb7923aaad1331b8a44fb432ed5479bc8255a9f9889db7", "5608f70ec745d7dd10b0d6650661ee7db9d15ead665ce8062892cdb60c51b81e", "5bf82ecb4e612f1a1290f08f79b9a17c4f6e705c54382d79ef4828d8a5174e2e"}, -{ "596500", "e07b8c8db8312393c02cfe1bc00a1a5ee6166083702d2db0fd24297095202f77", "3df091b27bde63d70fc8d0feb4da1e97ee21915b24f6be2a60bf702051c243d7", "4c713e21bcd71574e8ff3d13968e2c1ff86cf69348872a9319d0d879d0462236"}, -{ "597000", "8e07ad6645a83dc63b311fb7d39bb583980164e40032a0821d0acb50953b8ef5", "96c796666a2f4c215410baa022874914fd9c04a430313d38e98f6c5b743b969d", "08f78b239d3bd3b934efa4ab3eb676dca0e24e4c945416e22967d6bad3c01a74"}, -{ "597500", "6681cd271934d16f89af3d71bdd886f5d3d50f6ef9fbe17c4d95eefb6c770974", "e7909149c034c8ea84b92f77b39a9331560661cb4c158edda770306a4ed7cc9b", "dc6087c2c41ff738c099a11f2dd7e2c641f97f6bfcd2c343ecc372a0b78e09ee"}, -{ "598000", "92b359d658152c31b8c2f32c4509f3ccb1cc18b4544745608da9a230327c109e", "3f75a2b9ea70de0fdc330ebbc5f83301dd507c4e0fe536200402cdf30fd28a12", "5788ceff503809b984ceaf32a496e51bba2374ba415e3f459590a1655cefffc1"}, -{ "598500", "be474d552a4f17ec673478af48534ad3c65eef1752223ed3012534dcc4274db4", "9c304d0d24348fa013c7223f1e05fc9092a773e6da14920e628baf05669a0f08", "67e9375d6815cb71ebddc38da5965a779ecc8729333b33bef2c4646bc611a7d4"}, -{ "599000", "275ca25666031af015670734cd4fa02ea0e0b099921240991498e684bc234940", "83b44eaabc822a3d26f168dabcbb175357e1a37a025813fe30d5e6560418dc4a", "3d2abb751cfd15a5cad35fcde5b52b4e82b32c11a567fa0860a25f83b69b5cdd"}, -{ "599500", "f20a2a85028e0a3c65f118e50296794ae25821fb5dc0a59f415305d826a827cb", "937a759ca109521f0ad2dd2bcabfbdcd08508b97d2928a81bfe79962c59f6e27", "504abaa85e6013ad139e47771e947acf3c858fc49e0b99c5236d7f84723f3c6c"}, -{ "600000", "fde9cb0677887e2f966c3be87d1780db88353977fa2e426249d9b26b01be1db1", "74fc8f58d336eaafad2f515f0b5a5eaa679c82160f2dc54f35fed44bb845c395", "3972038fd2bc0007c3ca205a21ae11ecb66096006ab3cc9ac2350e2da7f1c506"}, -{ "600500", "ed2fdfc9d3b07cd7e4d4fb46b5cde484b7ea5cbd436608698ba0be6407928d45", "78eebaf2d54a3f5ef9c98b58e75325a263d7040a85d2757eaa6fcd9edefa8bfa", "ab51bcdc56ef14d0313de8553fb8ddb2b9f8d08f8e9fb42ee67b2365e2855cfc"}, -{ "601000", "3a7b3e53a5c38bb7d0600352a71701c8c7b961a9936d319ec1f39eacbfa317ea", "ae8e3de2cdfe471244ac6698534f60a82a93e59b36ff22135ad57f5ffa9eddde", "131208c6ee4f9db5dbcb53f6b21d9de4b1bd8a4ac785684e91ec23446ae01489"}, -{ "601500", "9ac84b004712eedc9cb82e4eb4f459e92634ae20ded19ce2a01b5039bc9be041", "b1800a6430feb20276c6d1f65b1042d5da3d547a575d7aa8f8515985e793cc8c", "0534f69dece37746712175d940492ea534954520282a439fbb88f81e1460d4f1"}, -{ "602000", "e584426ba4821ce97899bedc37ebdc5667d94f796853b5dbfc8597123f61cd93", "670512bb3eb55350a01e55a614addd9a1936e220c349b5fdf83ff85d36ee4762", "b9e225817855b7fe034416f3c8f60d6e918699f9fb0268d5bab870ae293f3fb9"}, -{ "602500", "98c1693b6c94cebd5e17bed36779a7c1498f43d83c3fb9f833ac42eb3b1f148a", "4335ab6f363d6556b820a8527702f5b224789aae810a9799c40289f088d876cb", "ede7bc44211f6e62eed8f645fb0f102572e32287eb96203537ea916a60d28838"}, -{ "603000", "cc90f10fadd0c325018a7f5b2819ef126eeeceb29cfb1abac3aa4d918dec8ce6", "c323abc97d8ddde6d935f4c4a3748fd5df141948b855062c0d557814b6c57582", "22b9244f3382b385b197696db2b875e2fc0c12b0964100a33cb60edfc87e1840"}, -{ "603500", "88a282051002196bd7e47c2d4d05acccc49be9e0a1958c608bc8857b0752d805", "4a129ae3447c19b8a4ca1812fe819cc571bae08dcee26b2f312bdb2292e7567c", "0f0928f3ee33d03f8656fb4f47003e700e63cd4a1f38f0b395c04ccd0bf32589"}, -{ "604000", "8423befd6cbd718339237b9fd01a9bbc7de101525a01e45777cecc593795e76d", "10125b30e2a5762ca8991b3ee699bc69e552b65457759c8b0a85468f52575c2f", "af73d30590eac4ce33bedf0d830a2b525e1831475360baa1cd1b1e15313e6b45"}, -{ "604500", "5f07bfc38f07c663a551462ef3fffbbe9a1f01d54e4987727649b2cea7ea3716", "f17db8519ba7ab7e3cd0442a008bd05dd5354ddbfc696dc9e2aeb07385929acc", "b0ac0adc0867e94b14759e51d7e7a5e217acdb0fa27b5637e74befbb77abe463"}, -{ "605000", "691b12ae780daabc6228123ba85e5d4ce2c48d1f6084a428ed5d310d644ae101", "15ecf51f40220aff461a2662902a91b0ff974c6b5dfc6853a37d492ad0e7c507", "b15f1ef422d7205ea9a75e2a755bdc9dd9894167da2b3714596e6f72b961dca7"}, -{ "605500", "52537e09d147a2eaf5a3e843ce45824f3a0db686f36cbbe72f69fca61a2b1c01", "ab643490828905c7be3f1c8afe6f7755a27c4cdfaa5c8488fe2441aa6afaa70b", "fe93785d20e88a156d61e58fe667cd7d88b799235170892fb73a25021f9d6900"}, -{ "606000", "945062759b3b417205cfff5d9b2e1c29d29fdc235efc71971a5c930ef5fac2a6", "5cf40892ca34be01dfa549d94b8784051375b2949ba916931a8addf7eb3a9216", "7632b191ab5c86f8921e87dbd6e044b353ac8448f26ad1d0e341b6cfcab681a0"}, -{ "606500", "284cfde9bc92fc8a9a75636ed0bb98a68a7d26fa82acfdba09391939c2e9acdf", "e0d8d1c85bb390ccf48b59af60483c919c08df0f8830de5befe65a43a53a99fb", "d354e0802e7ac9ac517c773c45514b91c3e8fbcbc4f159ccdd842e52236ab02d"}, -{ "607000", "fabf1c22a50594542dd8cc8e0aeb6ce78992e1fb97dd46f25b1f766392b8c466", "c42f95954963685fb338b1ebf0f0de3c8fcbada7fa53dbd4c0472b7cabb75eee", "8fae72ad94a28231f967f2a8856aac31fc33f5bf9a062bdd59faf431ee62745b"}, -{ "607500", "a2af7276cb9398592a0f0d137875baf3d9291a606f583b269540f9ac44a17ce4", "b5170fbaafdd9059ecc043f1c4ca714de50133bee7054f8c119e0eed79e20ef1", "da9ff721da89780eb2f19bfa0540368764e1867c09d9bf979229ffd3b9dc00e9"}, -{ "608000", "6a78949783e00a8ac3d832c24e69a2c6fe028f110e8f1a7d87d652acfd5b6b63", "01ef19adaaf1a1d75900879f2c7bd5366ec4a6811ee539db16e81a2b981c192b", "bf5cb7827f5372036159b01293e6b4f8a7e6a95136b3a809007f99330ccff831"}, -{ "608500", "1941dfc27e96aee1848d5fc8ba94bad2507ee14f8a24235e4b35af5dc0559f05", "559954098665a3b7a698445445daeee8967c092ce38be59cf1fe78ce354d221c", "f137e99fa941b0e0170565f9e9d853c421908dadb65ac79d59401791ee909cb6"}, -{ "609000", "ddb824a17fcc47e7312cbc0b80838b8f4fdc077d1f8cad5b08008aad8a25afdf", "528daaece3c6a912cf0859f93018845f781575fa67f27479ccd56480f40b8c10", "8b95320442ebdee812dbbae0b254fbcdc0923130e39406b06dae60016d37053f"}, -{ "609500", "3f80a004163aa45d2c9d2a1c8bb238a15b9db4214c8b0ca08effb0f37697c40c", "e6a2eb1304a43261fa54127676cdee58792115ca1b400c4a08261f1e170f19fc", "530edb76f0368d187c0312843669fcef70f6f53547d58af9d47eb3d99e363db3"}, -{ "610000", "0362121a825d39875de7eb528be247603e5d93922f21f738f255ad44171f5edf", "3b57b352f45dde9c233dae766260ea380cf6114c7682dca95566e656e9be1511", "ee0cd70b32d25b140cd41391341494bb74ee64d0aaba36c8dd66bf47daf6efb5"}, -{ "610500", "d39319109dfd619800add37b85ab545fe8832c50036eaf1aea5489348e749f18", "14c16bbd895be10be482c66ae8444f39cfd67f9c3c244f86bb3f309f3f38ea3d", "23a66b83736092b91886d548614c6ccb4df931deb591ef60b795f3b9ffd59353"}, -{ "611000", "274d0b2789a39a2808a69e9c7d4fa6b2b34b7be5ad55d541785f6230103a6110", "610d4811e3da6b704ea224ce3cef798b3fb9495609971c09971691d88b714885", "5ffdffaaaa4c37919493ac9e80821fa240fcbc2d006b16544b0bcaa2e932695c"}, -{ "611500", "c25930007a1325f971285a32257362f90f6b5da474225d3cdd19b9053a55e6b2", "c052c3e6c7b866d2212ecc66d4956d8b3c0a9b97381a822ed203ea796ba58581", "db4f70e0b89e3b0552027680b9fa09bbb3b65a6fddd5fb35fccacee1b069658e"}, -{ "612000", "8dc46e21fcf1b95e59d6be6454adf1db9d141d9e78d583c0f4efa47e0b2e38a8", "538c9ffcee5485b309bce281d6913a254331647ab43d492250c66318503ada14", "66bb108ff47b96dbcb4ab0e0d49a2136a263c1539f67cba6cc5dd699b2da393d"}, -{ "612500", "48c70c688ae362b4ce2e19325b0bf5335301f45cd6f0f562ff263d5d57324a2c", "06f90f226b98bf0fff455478d39513800ed400dc9dbf41c3a6e498730c883e42", "c43d539f28c942ebeb575494bceb18356d322d6465b541fb1ef6bcb14d1d1cd6"}, -{ "613000", "a05ec2324bead1349845a8000c76ff7705e0ed1f958dfb46c92eaf3180f301f7", "4d6d1eefb176cf04b6cc0e9554cd81bcfb00e1f737ffe5e25e752f9eacfb20bd", "b4c6888c5232096a5f117b09b1b577301a45b99636d8556dbc03a833805ec50c"}, -{ "613500", "6d0183915fa23fbe61d2cfa7dc9ba9c54c164b246d9f3ea2bf28c675203896b5", "e233a4490b16a593a62853877efc01bff2e03b4e5017027fda754056171236ee", "f90d236bd564360e3964d4c1658aade4df26dc6b185285edfff8b7fa85ba7faf"}, -{ "614000", "dc4d72e154553d04502271aeea36609af31e967faec981fdb7aa7686b194ef72", "a20198e44d09d5a45d18b1b2e20911f6d8840ae7618e39f1805dead4136ff220", "8e805b125d35cbeb91989a832fe0573c60602778acce51c2e48647e3a9f44807"}, -{ "614500", "401187c2be8053257741c3c78fd751d5aa80b74239ac1a5fd7c2008623b8056e", "b3d69a8f679aa779dcfd6b03d44da4318c10241e1a87c8de46dc2067879e7561", "a7e8e2c3fb0ac16f1d4dfeafb173fc49e6d1dfac2e7a6dbaa750e27954bce7d3"}, -{ "615000", "a7edfae28117b555c502b1b0866e70c2e45b2b53095b0b3ec0518f76a3250e96", "180c90afe2385b2149b5622d702e1ae33e1908e03fc9ac457f18cc86e3453813", "f2883eb378e2317f4c587e7f6094d2c87d758d88f9e55bd202027cec5b0ddc13"}, -{ "615500", "247cbe6b3a28a410c816bbf3e344fd707f5b98c9fc7ea74a653e55daae43aa7a", "675ffec485147855367994e9f3ab4ac5ad7bedfb39a35959ced78034e9a04318", "dba0d9a788c2a5097c8bef58f8dcd1086721dee07ef94caa587e988d0b4493a9"}, -{ "616000", "091e39d1de4719fafc22075635a0ed10d1d8b5636a21927557b2baee8bc453a3", "5cd5dc9688dfccc2024c771720a75202758606c6c2b62b3317eaca215338eb9e", "8538647a15cdeeb27b070f34e3cbba6bd910dd6ca30acf41f4e8fcc69dfc2a92"}, -{ "616500", "245d68d439cb7cc9d17d41d8748be112448c1c3d757746c28c32e3531a23a66c", "dddbe95e870b48d8e1d3be72da7976def8a5f96e20846bee2ec8d3644de876bf", "67b7c47a006895547c671ee3e3078f5c4de5d8b54184348240c7ba7ebee7a49d"}, -{ "617000", "9a08546acd2859279fbf0a140d792be72040b3b5deccfdfcc3a40d640c60f35c", "3fa1b0094367169cfe3c3047b01a8bbe5bd1179ea5252153da7113477dda7bb6", "5f9e7e0db3ab571d518ba8918c74b343400962664b97339322d394cc431a6f0a"}, -{ "617500", "ec4c7a99f349f9b610a1c2c94f01fd8e37bf98d8feb6a68874517a47b27a199f", "ada5742a01ae9d78a4aaa0fefcc2542633e90bdd178f540e802a4e5bf96368e8", "d0b9c218ad2796ce4d4ec1716498d747ce2dd9fadd75ece154de1c50932140b8"}, -{ "618000", "30bf0bf59fc693f06b630ff38f55f5788f24b27fec1c171fd5f63b6a75729f83", "a4d0bec878322f07128ea1f7318a28c492a27649b4e216332589628ddd9053ae", "d66ecca88efc3eb08f52e332fd0fd5fb8ba7115b815bf253f0e39eeb514494f0"}, -{ "618500", "095af87395d73d93df9f2531ad54c6a486b0c98fff5e59a75d9f468e2317b989", "c98bdb9ed3f618281b60f496fad0753ed0610f95899058a5662a45bdc30f2c2c", "75076658902306923b786eb552a2faa289486c9ee08172538b170aa59ba109ef"}, -{ "619000", "53c7aaacaaf469764119760051cbb7be6806f80d51f75099d8096831443712aa", "8e52bf819476612fc0943a9b56d5027935ca897f9a5dfb686cbedb8dcdd83bc5", "8d76699c08cfc5eaf88aa13bc8af9a9b16e92d6e612ba3580066f24b15385f46"}, -{ "619500", "7e55322d59a65d0ff1be11ba083fccc9800550a273a52a77926d5a67c383f429", "1cde548b5fd12717415c6f8ab191b0a73aa77acfb6c8db2ab9ef1f374bb8fccb", "8173cc803d6469a845493f73a951754b2cfa9b5df473772a4a77e56a104697fc"}, -{ "620000", "ce46ee172a243c059752e237dab267c4c95b111745b808bb9ad1f8e99dbe84cd", "e14873bf1154683503d0b3a1d0180742f3eb790efe5a968845a337a4877f9cc8", "447b50d4296c156c2a3cfd7b4c8694a143361f7d9ed56b1b2497e81b01462e5f"}, -{ "620500", "31fca5e075086e3ce312c78e4e67a24a245c48db04b7d07688a46be3efd12560", "d5c066fadd66b4053f35e728308e8e1e9594693f9afe8f930e342f89014e1435", "9e53b050cb6df8118681c205ce2a3beac7952b65442e2ab7247a79c3c3c75702"}, -{ "621000", "c27deb337c86fa6c1a9c967c1c0e967d66ca91c3a605ee42ca9ecaa3c7801715", "4bf8d5ac8c9c275f434ce687e9aa2e5bb0e1c1a8634ad7dc0380ad74e9f2a471", "47e53749b73ad12c2671c9c1d544bd4758d8c0f7b0b30c00f2c4610aa21fbccd"}, -{ "621500", "6d6de5c0c183af66e09203c1f851e005b11ffc3e65821a0b0c53ddcf0577a86b", "f8e09ce62f6793636184630998b1cdd6e513174a268fedfa3c23d1beedd6f127", "933961fc62855e5241d0586e32be4460534b723fda2d7d0865e089a1c4324bc4"}, -{ "622000", "3bb4c331c1c410066bfc9c84fa96f35f008d7ebbb8630f35616b07d3a8f6bf09", "2625b34fe7f2c205449f2ff67a4bfe036ef5f479b520c16f0fc16ffc43e5e713", "328d4df64c5d59c971737f12d125a3d32d4794b506132e08a09a9043b0907e50"}, -{ "622500", "b69c590df86c64c53eec4355ff7e4525ab0ede7c40da8cb6304556c465708619", "ea025a51dbfa831f98ebb1597cb43dc29f34d18f5522b57ac06d7e19bca1ed39", "e7339a6249253a6fb0337bcf5fd188fd50bcfcc91fbd7c80cb1c830d711516d6"}, -{ "623000", "248e12a541844945c6b91e45f24d7f63db3dfb41016952e628c647bb82562c91", "d2dcaa98eed5db5e34581c8bc52808819c5cf98bd564661252e24fb7f98218d4", "2394ef40993563da36d854a0f5f06c0af1dce3ae7274d3a3d6655264d8e1da54"}, -{ "623500", "0f6332963afce6ea94d654d103c3604c724a5a6bcdf6e32bdf9a708d10de519f", "80f5b0685f010693bff7453273d0cbef3d878e9753b19e05a5d2fdb4984f8a0a", "e7705c345164e7069e9529e3e5d47c12222a3df70d0f1300e39f12cf6d361337"}, -{ "624000", "3a250bcfa462ff8b750d0a725962879d47832f0c77b46dfcd27e3eb4bf352257", "f75082779f75cba11e26f60eb9556caf48daa15221abc2b4a83a1cdfff9368f0", "7cc8074a65f117e7942ce910dfd07339069627e317e1d4a31106ed5847b218b3"}, -{ "624500", "6a0ceb40f1277b4289334b6cbd593aa5bf593160ea960b4887e40afd2b06d767", "cb0565ee88160d6c0a26057155cdb2f9e2b94217d229cdb627fbe0aae9aed145", "9802ef2c8e15d18bccf977c41463ad4cc0ff9af9dff0a1104194dd4ff18ab9c0"}, -{ "625000", "c28164fd18e1087787d2e3c7d67b8349aafcadfbf815fd7547fd7ae8da9e7937", "319cabe08b33898fc3421e1cfe329711de03a92bdf21828a59594e813e71393f", "894a1464c80bf83652ceab26af7dd40661b1f157f1a1f77be34cc57fe01f0505"}, -{ "625500", "00c9e51e1237a00f30562f40f8d7696876a62523a7888f3019103f97d27c2afb", "cc7d1fd4e2d9a95e3a9a7e23f44a96f6840036265a29cac5b4a364ae1ee1b806", "de6b94caf4e70ed1bbcd7722a4fa7e0cae7b2490f07a815eb2b4c9278e0b3600"}, -{ "626000", "452cd22905dce67c27114fdc0b6ca64f4127abcbaff999b7aed68be214fc9313", "c969541e23ade41ed8ab864eb6fba11ab9ba5c6f29374e666af4912c2c076de9", "1c307caaa8f2730c6bd3c202a15e94a9004ab2b6f0ae24d58ed678afcdbaaf00"}, -{ "626500", "7a3f9fe36cb72b3529747754309d2fec46a8155a6f297bf5d9998336ca26ed2f", "9184cefba7d61de4482fb57cafe1420eaaf58e3f2fe370e9c22f2dc235c26763", "44910dd207c9b780f4295ae81102f25cd2271f810d19de06cc914409a6fb3756"}, -{ "627000", "d8f9b2f906265aa50c5eefed906e89c06856dd2c25bfa2df52f402fa029b6c6a", "1c5dfbc7bb572903d6eb6a400fa50df3c18c87cedade5b4ac63be7037f050a7a", "3fe4aa644342a4d6f4cf92c6e15eb94151d403a521b58fbaf90dc0ab2228d530"}, -{ "627500", "711651d2f7440f20927ed66e680d833755ffecaa905c0712ed31e1e06a81a4f1", "6de06425cf412c7d272841f1b3de2652b15d3300902c0da6b7c1b08bf4e14112", "c2feec57979a5febd4e028b999c765b3b127a5c9a31154c2884633149a276485"}, -{ "628000", "1f04acc62ae096325174e8ae11579d88e65ab4f435e3bb8c41896a1cdee6e231", "c87dd969f7dc7a3a356d7935a69e4c8a4487c72e7c623f49cf0f60cbc438aded", "7a91eef62edf2d9c9752b0c433fce328a8fc4d23595a151c6ebecde64a55435e"}, -{ "628500", "f55649153110900f0fa6b7d2f9dd6c293bc44ed7911a6e4d52ebe5563eb3a4e5", "de1bf3695afd590e9ede9881a431abee861f4cac9ab8b42cfdb8c37f0e02e19c", "a02b318a4219df923d40ffc494d44c4fe0bde49a03743c588f816e99ce01b0a9"}, -{ "629000", "8e7208c5c406f95dae4ffd540aeb30a111696ed10374f03cdc186db66295f054", "5a8b55bcbfe3fed8453499ed4c4a51233f65626132aa23ff6acae30dd5cb3800", "1ec2dca991d021138b1b9d70a4d1f4f39d0dd4af1e6741c74fbc84ec2fe02552"}, -{ "629500", "30b5177f1554053efca360e8acc003ef0cc4ae26820331715fdfeeb2003daea6", "f7e5d1c5ed411c3afd3a51d63abc4f29fed49ee8bc2f810481491c138cf09183", "aa3a31f783a70cfe04040c1c0147b6e4f31820bfefc6d261378f62ededabf4ed"}, -{ "630000", "9bbdcad95ee5cacc45ff51ca8d627ec7a971b1040368ac62a4616f873623cc79", "306b7845856f157aa25e14e34165e75ee5abdef7337cfbfb9611f628287b83b2", "783038b2a1ddee91c807f00c7cd9206c7bc0209f70cf8fd93f9e87df6adb4ef7"}, -{ "630500", "cf2b412c6c992847944b1fb396cacf61bcd03aaa460cd810e3f42a2866e8d729", "8d2c8d7be61fe16d9f5c0f5ea155eaae7f926fd8011209de27e41cc67055f5a9", "a6c409f611781e61ef4b35ebe5fd1e3548bb181779a5738d423ebb2f9bc75156"}, -{ "631000", "ea5e4b4acfeba1f4a69c63647cbb45147ba1dd101b9fe58843dbc6fb09f7c12a", "2ef37567bfb65be1417d9b5914570c55bd88da0bc07f7ef7389e6324cb0b528d", "5549746df3b12cd08b070e6aac9a3001fa63b7a4c5c407fd68c66aa6fc12ab94"}, -{ "631500", "539334450cd6eca49473d63e4917725250afbb6a546a025b57b40e4ced8ce63d", "865fdec23689d881dac49ab8fe9a20c5984f42b4be7cdf3e94118a4baf4fdec1", "9bbccfea4bf635276eb9d1aac8ac9e0f4de8e9be30d31425db85db1f0a8104c9"}, -{ "632000", "dfdc58aa41d2ebe7751fe2b3ff90f0496e602cfaef1fa0f1c25181a3be4cebf5", "8e3f86b2b753e8f342046b61d84ed4d2e9ce107d7f30a47361e983aac874f448", "376df1c3dc60d76149265cf188e76ab5bb9f90f2d87e6e42927586c7a5e3d277"}, -{ "632500", "54f71b9330b758d881d325e8f3ac9e0f042d8ea1222e52b580a0337a3b4f3fde", "cc0ff7cff02212ef316bb6fc2a131b018fef8b6dbfac01b9e2eb275c9008c613", "18ed8351a297be31c3a6b1892bd51312d42fe81ae28e819a978c5a97f337489a"}, -{ "633000", "67de40386baf1179b74ea2a750bd20d6de8f6ec3cffe5100aa3307ec81bf3a4c", "7d69bc05bf967c291b2156c18c0851caa853110a8ee527bb9872001cd8179b34", "ad0f698fe88881abd872a3c74332a091fc1435d4b2b986a8feff93ec2510ddd1"}, -{ "633500", "4414265aed7c038b6f7ce24cc86619b0596162ced270a87c70a59ee3089165a5", "09970b09ad4958924d24703ec56fcf49a7526a0916cc7f0f841ed9796bff86f0", "bab8a103a1151cce8a253688cdc8c93a700afeeda79861febbc767bf4a95a2c7"}, -{ "634000", "a55d577e338fdde481a3cadfea26ee6c1777ddd6e35e66040a4d99455626d9c7", "5da3e590cd7190a473f7d61027754e5bc50545fceb8867db96006d3773a2b746", "3e66c1867ef38484dd98188fef38caf9097e6f29ba8719e902bad5187d1d483b"}, -{ "634500", "571d3172a3095d0a34747c18c2e2cbaa4173a09ae3a351736b2b4802752cd9b7", "6799dc3c2b9fe39f72a22e6fe27ebf46308c887e31245a5cbcc2a55f1060ab44", "8509597ffc90e9faa61e2f11dfccc9b81388a9663d4197d9154293219653af26"}, -{ "635000", "6786a43fee0f379b103bd594943f26eee0f0ab3af9dadd36d6afee547d7ff8b1", "60794659a5de639280735ce3ece1864a66e5754bb1608b2aaedb9874a6c34d51", "e71885bf66653e463925be8e6a1677b27c0daa1ed1f4c23f12a18af7ba58f8e0"}, -{ "635500", "bc5896373cd6ab14f28a690a7d59366ee57a625cd6291c502d64a3a9a5969a96", "cf6d7eb9c0306f24bd7a47fa0660804b633f29fbfb647e79d03a545518d5ba17", "e0ba3988d8f5ef59399453d1c2db9690ed32f25b8d06b718d2645dd770b0e277"}, -{ "636000", "1aec8a1d1f6f5abb68d49597795c24102bfb767822705205486829ba50940cb7", "348625a773758822cae41638d27628bed89a118fdff13dbb773ba28471ec914e", "d1b089ccca6da98d2f12777e9c39bc730aa0fba9eac004d9a09627dd60dbd566"}, -{ "636500", "cd844ea294ba265e14ea515b603d35c2dd13c9c402a4a1a13628925634e81f23", "2c881b78d84e98a3a6dffa6d4e55c347947053f184c22f2a75bf62cd779febe6", "56c67d302587bd787e1737e66c7fdc166f4b83d2ed88586c08b62c04d003b3b7"}, -{ "637000", "7f0393f05b3ebfd7838740f3030dd915d2125e9546e39f503e288a20b14d29d0", "ffcda35e368f4784c75aa0e6a98485a2b84fa1ccba37f7fb5a6b4d4e187a5033", "5cf175683ac51572c2fbd9d3ea1135b35288245bfce82ab8b20d93bd0d56a7d5"}, -{ "637500", "7453182caa6345472aebc820d839d70e916b8e01527e69d2451e68df9f5fff94", "df9418647903ff269234df3583ba76f054c7fefb3237b47206f7e25d9ac118ac", "aecfa9844364a499e2c72ac729128b46b93ebda616fe09898ac8283a62e4f800"}, -{ "638000", "2917816bff7d73f4b4f03a31fdbef162ab7b2bc38e2539952648f7e9b66dfdff", "c7367a49d181f9e332613c76cba3371c16cff94c10a6bacf504c8ac404358b74", "c06bc407d795e6252326bd4d1b06ebe165cb853f0038ab172a59f9d7846add38"}, -{ "638500", "e10674d6c53842c520040ea608584860418908244a9203ea9e726544ef6dcc6e", "b67a32293808e06725a391d616889dc4a438c8681893c17646896d19411e1cba", "b04d875cf1633f696fd0167d6567f117f0135a6f60ec9f3682503843b5931925"}, -{ "639000", "a4629de92adb7ee055af0b7a55a0690efde637a84e9c19fd423aa74389c7ca4c", "95ccb5ef5e2720ec5ce9635d8eaec7d000b16b3abe24936fb8daea2def31b681", "6cd590a9251fcaa1b3f807a7bc4e408ae0e826cfc9ace4d08f0c9e08e3b1412c"}, -{ "639500", "dffba976bf5db95ba5845ee2863a8f60f855391a80d3a59cff38762f0992b38a", "589744adb3b63b274b63d7c83913c65d121c13dbd8399aa7e0f317d4b37b5155", "051f5245a3d1b1f09f0411957ae16eb2eee1116d8e67cc0a5d8c25e3c2b60583"}, -{ "640000", "d5c3942c19dfae03595dbc0683dc712467c00e5307bfd96609c4a728eff4f586", "33aee46df3a2c807e3fb8961929402532d1f1061a5e1df2f28335ab40002096c", "344191b74b6c5c4374ea484a87b81f881b4aa24e72f8e3d55e7effcfc672a724"}, -{ "640500", "2efd0a03b8098ebfb96870e4235206b8bb428b5aa568aab56db36e3124c98c04", "e67d6fe1642bd591df2f838f07190f8477622358706dce1a631819c828dc4980", "fdfec92daa00d4402a8a3368a31a17784aa85b10da7222e283df9c7a0641512e"}, -{ "641000", "91beaca7dba7afc17cc193cabc2fa7c34be665d2d367c9f0d17a8385903c5299", "b90b505393575a5869ad32b498b2fe7ae026db5e3be2ae066ee4c8a4e50ccd0d", "2cbdde622da75fc20c993e7cd8000470b627ae3dbe0531ffb156f1260496ae0f"}, -{ "641500", "52a2ed25b8afbf07e9bcbee8bab225af6bb0834b500ec30114697924951b9db4", "0d30d77943438dfd2b1d85adbfe26de36a3f821303c50717d3a7e55abc59cfd5", "fa45abae09484832e3b6ab1510a79f1435e3f30da6fb2dfd5dd3e2e611f028f3"}, -{ "642000", "24cc44ed0510958b23b614206b702fab53cb7681905d1aeb12fb532fa850a415", "05e56dc42c34c44ae0c67c45985004c753588fe4588a4060444532194840e5a7", "1c5f05780ac875c2e6d90507d6f1ac2c62bd0a96ca5cc24b41ad28282e205ad7"}, -{ "642500", "2cacb3c0be5a18667d5972d99182b87eaf485c724ce81cb59f3417691a920977", "1d5689874267933eb1b72a5696935202699416f5f064b689e7221d6dd4a2c3c5", "49a3abe7968ac7db221603d4bad3d8f6f47e8b3dbf034429c335711d3a729a18"}, -{ "643000", "94ce4d9dcf18b532dd9f8a490fe270dab5697c14f49b7326efb3e3f82ddbe7b9", "f8466520f91a0a9b5136c8ba589bf7fa7a5ddb292516ea1dcf7820d3ee7c0cbd", "83d0fe5e99e509d48e6f8c9c0736d98435fd1cabc81f7e5a4c70c31ac4af433c"}, -{ "643500", "e3c751b8fb071c5ef4fd1e7ebc9e902d365b88c3dd5a90ca5386d7cc42813b39", "fb799e659716a37ba6e9982fd09e8848d637ef1d85555c61af74dc996e1c6908", "d312f2af49d0d8b7cf4959454a72c004f42dc06d5347fd311da1d484441b726f"}, -{ "644000", "2873489104d5b817e24659b1c91e0b4ed350c388563670846658b452e279a44b", "bc4bee8a1c8a2b98d32ec490a31632852f7935737bcad951d741e789ef99d15b", "8cbbd8beae20c883085e1adb6f33ca13eb867a2166acbb1f948c82fb3540b1e2"}, -{ "644500", "2996cff77ae12636ed2da94137e2dbda45f5db09c968e13d9002d9d5e8d1bc8f", "1482ea5ca89d761a9b99c8e0a5791d430478b289ecd506b3b1ee803d90be7f94", "b87e9b5e245a76d85dd89bd64fa4cef1ecf892b39828c415c76de1cb04385788"}, -{ "645000", "db1d293ab843d88849874e33883a8236a8bc4bff1d93b7d9922cf1f7dd3d0803", "b13760cc8ccad388e7a35b3fa743b2c07b1e40cd5604c3d4162695d02bf601dc", "a3aa481cd7c2879b8dc135f770e3f611288e8f0a1b9188ddae6f2476a7570d6f"}, -{ "645500", "0c98834ca2fbd0b1f4b7e708c5f9bc9e820370fdc2b1126aa50eca16a46813cf", "95b1ca36aee7f85aa247e91eed0bfd17f8ea675c5d9db342d9087017117d73c3", "f12775baadc6645e0f97bf551074b02b56fbb7dd4d33c9601f254931872c2f0c"}, -{ "646000", "dea1a9883f1c3af496fd37570580c5c9a1e1ff7e8822d70188737f7aa45df488", "ebab9f3327181450b58a388214d86b56c395f2e90be9f7d595ad7ec863e6c1c0", "f1dd6f32b53db9b62e895bae55320726b8879bd31da4df74fd26cbf77bdc083f"}, -{ "646500", "5cf92252a010e2d62030e5d74d6371e873f7fe6353a010791c21307d8236a3a3", "392318738e04bc641e4375f47820bb59664b62c88a0f62a3f1bcc75be023b3d9", "b5ee3b8caaf574e852f227a55e690159cf5c89d2cc5575d58105abda3e86ff0c"}, -{ "647000", "b0a00219234dbf1942eeceb7a31565ed117dd8a8152f1d343277433fb3a19233", "8cd4d156025aee385a9cfd46d38594d1c4825f52555a703031c99c005adb1513", "3be48c0c754c349317f07393558b718ba29f5fdf3709334ec95060fa3a912aa1"}, -{ "647500", "8cff85fb1e3b4a7218a58b6fb2e7d0168fb5a4ce4171bf3f0b7f1e7a5f214d0d", "50dd61b46e224a437159c8faa7d18cd9c100d1e3ff75eccd770d8debd7723410", "91207635925dac923650f6a18ab01456ce08a74ed238608894f2f0179b95f51b"}, -{ "648000", "133d2255f56a3c2737eb94f337c9fac97214a7e1f54e8ca9b4bbfc6e056443cf", "d10ca77595aabc294483ef2fd07975ec43cd2e0764d0df38786d3ecb5cdb810d", "4fc0a58c1832f9d5ca4992f030e43cddca4d33b9ee9028903e347cd2a5b672f3"}, -{ "648500", "37691423db6098cce3ac61dd2e0ad5202cd08d37e2a810a4b7e259742b50f561", "4fc55c6790346c316db4b0f1a35d067052bbaed3932cb8a369f8263791b9e749", "69958cdf79d3bc23a0f7eccc268248d1aac3948ab5afda1d409ad672f15e4484"}, -{ "649000", "e8f43ecdb6979574c66b478a2d3ad028145349c43ac18f67e089f6948a48812d", "7609d55e10c1b40d62adbb39792b58b5c075f1c34c6f8676cbbe39e91a7e504e", "a388b583005de4a80b25dab466f64d532aff83273c495e02fd89e94a956f0fa5"}, -{ "649500", "18f631309a2acc38dbd4d08322998f0d4fac526eadbb1aa2ef1ccf75173adbdd", "83794a76b25f0ee49153d50f9bf6d196d1b78bac25dca55b9d3eece5c8c1c3dd", "e68250eb6a12a699b48123095035f869ce12acb5df58bc82ba22d7bd79d1b261"}, -{ "650000", "fffaaa151d0634fdd830e104f884bc05d30160640eefd126e0e01b43bd5db5ef", "7ef1c36f637320886b505c0ad5847bf0a345c6abbf4e92432d863b0ff517bb91", "f8aa7d420f5288f135088e929258b2af97e9a9a569beb546f1aad5da449d3dc5"}, -{ "650500", "bae09e49248acd64fdbc94cefd831ecb2a957c0d5aed72644a3607a198c77740", "f1ca4b8b2e74774fc3d86ff3f2b5e6ea8d59e40a683b993fa638c6770aad547a", "f2e5d622db2bcc3a30dc98b50087fa2d1b1d08f4f056a0cf95c64089873188ed"}, -{ "651000", "5d9f45be4e7d558b3133ab3a7d01a96db73f6a16604f4e348fe04aedab48fc1d", "38c0484fb001d8039ac07895bf04765ad79babecb93040f8b45e18629c1fe566", "6302f913b0ef7b4ea4363f185260008e6a8bba77326b53e6ec21279b8d1d1632"}, -{ "651500", "7e12af704c44d001d842767b49709eba23ffc53c8a20bf96b0cbda7955168521", "3e563eb1f016f0b9a83caf023067785be15032588fb1ed9d6dc2e7d47d7df8d9", "1b2277d903daa8ab2a72e3039c5c782d3936b27776dbfe11894288c5aa34d3d8"}, -{ "652000", "6577afda5b1a2535cf30f91faff821b56dc9f969e590d406f644518ae4dff6ab", "a6aa3534f3f962041d6c88a5c413edb0860aad04ae8068ee31070716e552c03d", "5ff9539f10d6522936100b9b48090d278bdaa9cf418d511fa85020b2c7aa3868"}, -{ "652500", "f60863237c82f26f35682a510882c8c8b3ddf302e479fd201a5532fe02993d3a", "623ee7add095d1a51ccbeacebe34fde662c727a14ec2ce8c856d2da57ebd1537", "7532f207a5838a5053a0f396c10b086764cfe595456a80571f043c723752599a"}, -{ "653000", "6d2f869d3cc7314a06868edf43473c3eb2a4ffc902b6866b2b6d9ed8254aca15", "ddd54a91243a02e778e23135881e1a17a5829d6a698410cbc91c9c70047f5463", "c74489f4dfb0ab0b6edce234f2613ac2d05840b066af94bddb47907d3aa85673"}, -{ "653500", "32d04fcd783380025ac2f7776d0868e44808c446df33e7790b9eb06edf1a13c2", "9dce2c2f0200948be45127d74dfcce50bfe2787f01a1f62cb304cc7644754999", "3f8e85317fc99b79ba87df971a91bbdd0af877a37228e8e78bc094fd441ae077"}, -{ "654000", "ad3da7c147ea7020a8854d4768937b46b2e9ddca13d786a2dbcda5fd691aa264", "15baaddcb66534aaa738d7370796b82234bd7d1a183081ebd7f452a33254bb3c", "b0827747fa4b8eb0fed8ab0dfca523be4cf55bb6d96557e2cd9c5c844d4b2992"}, -{ "654500", "b38fc7f77f763e12c55c816230cb83453e513d7ffbc2f71cb18a4b970a30b6dc", "8b8acdaea52986089352c0b17b8479def4e4e01d8f797609fce1c737e36f4314", "bc8c0e523f860ac258ea93eb5e10ec62f9f2ca18eaa053cb02446fed76634eb1"}, -{ "655000", "58642d4240fc44829a1c5fb427e034890ca40c5097aaff77eadcce464be04701", "11f24474492b2851fa79a42ff8d8685162e2b4dd1099722f3ce9ec4d5686cbfe", "85d330044b1e65610ebba62ee60be75dbbe7dbdda61ede949847d790c44763cb"}, -{ "655500", "d71e2ed94bdc78741559fb4c58bb944dde0adedc05e7558d7de6ab254c332fbe", "7bbb488685c2ca7c84d98149d2383b157d88304c5b34aa7679ac24ad5c85b006", "c504fc50c50248a50d4a94516c198cb7f74d6a1b4ff7f6f5fade4ac30e4807c4"}, -{ "656000", "c1d7426dcfe8733c72b8fae49fbbd127a6e257ccbe4120600f8454287ad26105", "2f8f7af5f2ec8a3e0333cfafc069bdfca90b0ad6b99ca970b0f458bafb0dbc3b", "67342b5de61484aeed62fdaa4377eb6df94b8fdc49756aad0a3ed6989475b5e0"}, -{ "656500", "c4f911e6a72381235e92a8c58ebf6fc654e35c3f5f4b2851f7f8a9ed3949e047", "3d157f3d2c8158bf886bf994e549a6da2db2c092266c7050b831c8888d62b205", "d20439a0b162598ebbf5671096b2532ec909b9a1644cb13a3c2f727087cfb59a"}, -{ "657000", "da224ea959041cf5d98fa040a10ddd7a1904725a649ec84f2ca403a8117c7f5b", "9b9b9bbc0221a24b8642fadd26c1157ce903d7be532aff91519f431e886f9ebf", "d4fd3b6288248e117b86a9f9274dede17ab390e22d2163870067b3e4d8d92d42"}, -{ "657500", "61cdb241ff295b25fa6a478eaa78f111e8d7ada328853b0af54bb1b20a2a427a", "482b2e9a549491f90026f8e50ca10016dcc78e4c3d2064e9f730b23ca9520a2f", "0a5db2f0e89291389e3f88013e6081cf19dbfee7217626326ee90f708d135b47"}, -{ "658000", "1c4498c323201e26bfb8a8955f29cdeb66cd43d6a2b2befb1da4a6c0647d1c53", "931ef1f4868a3c5b54ef4354bfa791c3ffe15c02b3c704a6a281154e2f5be98f", "62cf96eed491499f2f2a8e734efb3ebee4cca4491fa6ca8e57ca32db6ef2546e"}, -{ "658500", "33dce694605303583aeadcaa80db0d8569ff712b588875d48edb395520a43981", "6247bcba2c8883551a85e364e30b4104edb0318eee718e0317dc42f2a26c7451", "c3c8ab5c1d3efb616f9e90d79cdb90009c8306c18a01bec6c83de9e0539eda38"}, -{ "659000", "339aa922137edb48aa37b841e956adee6c9222ae9bec106ed49ce5843b179681", "ded7991d424229bf67cbf220dc2a5a5b223b571374f52d14bc9e83df72ea4753", "dfb79abf0b25756f3b77e701a1612b433f44f18ad96e3aabe52dc4de4cb73206"}, -{ "659500", "38dddb9b6e5dad4ec1f95be3a83a156be12c5dd9d5e74a20bedee990b3f511fa", "7815a077c5c8a265fd122b282139e3a13ef5951482f6d550a566ad74ec2db369", "ccab21843b81bbbe14e77170588ea2b2f0d74b7c312ae5ef155fcaf844d07e34"}, -{ "660000", "5562a936684fa4976fade44cd5eaf6531bcc844027c9ca01e33516c0c87be6e6", "0af9d5b94d513c095d2883a381746ff79e47d5179cc95165708ad37dd0615764", "9b596d92042930a6c45911e3d8c837026a2d342c5d326c4fe3084f4e58511088"}, -{ "660500", "de362a2665571bb51834a5e8cf65cc0b436097d1a640ccb9666fb41ee1694713", "b7b39581644d06d7672965e189c645b4396f4d50b223eed99080a122b22c2f1b", "9dbee44c5fa617a8a911d2271446d5bbb614d5820c260b7605038f37ca0d7b82"}, -{ "661000", "7df5c95f34efbe842ac26e4252440f4f315b342bd66e74a3d1bc3c48ca0f3844", "0a4f81f5017d079725470dd800ffe7e955bd82df18b6e8abc325165537ead1f7", "4a11f1341ee66c1588979ed0721d87ea8729579c5a8752a6d756932bb38180cc"}, -{ "661500", "dfa40eda9296e76deebe46ab09b9d581445d20814c44c42090766c0015162e53", "88b577c05b1a5f27b2aec225732da967a44e30dbb463455bc7ed223bfdc76025", "7b8df039fe4a7d90c694b545146afef89db880d378d0e20c45711a514008d959"}, -{ "662000", "7cd8f5daa828803f06d2ad8e7899d4993999d0ec37e8a37ec52555d1c64acd8b", "d0a6e4b8cc44620fbb80e061a949a8fcc371fd1f2a0b05138978d234a99fbc26", "96040f6351e9a1dcd55787e4e2b20b912037f2024e86f5e708583c14b0d63940"}, -{ "662500", "057c9dcdeb7375f51cdedc28740c881bf6ae644ff17c0aeb77ed796e89db8672", "c749272ba9509a09bdb7697c6197f132c1de0c58de5130e8c3257288be94da8e", "f8c160085e3a1d45ee033f8bcb723f059352995cfd90f96c619eb7fc3bd353c8"}, -{ "663000", "d9ceb13692d03610ff6e97eeb643407840e27d32c389404cd3cdd14733756dcd", "05b1659e97dd91ccffdf180d8da3a35f6b2fceb9676091bd997ad363210e2f5b", "f5fc3da1820b598d7287f36a0f0e5e9d34e61d42bb8dda0cea45b86217ade9c1"}, -{ "663500", "cfe8d9435ad14423479546bd4d6d1e8dbdcd62a8214ab922402a86838a8fb3f0", "cf68cef0e01bc5856468753c4df42bd16f3d33dd68783e012c1b012a3cfddc48", "2e3b740dbf19349cd135c765330aab0d6060250d2b884bcc7fc7d28f9049b672"}, -{ "664000", "e18e31c640bf36f6cce981521fd55f42761fda24538dac34285fb02e69c427f2", "f237c6c072f16f524d90aae138ec3a9176c2fa8f3049ac9ec009ecbb678e4f77", "5984215039409092af394adfcf7eb210753971e61de048b0e626a2ee64415b53"}, -{ "664500", "2cc31198ec6c3fe6e286f01d98f097e19a5c23d3f478916414e83f201e724e19", "1805da29e7f7e8dbb2b5aff1e712b3a447106db48671120732111884e0783b5c", "66387d00229b4429c099eca4dcd9ceee1a889b38365d5b7454c9219e30bcb40a"}, -{ "665000", "4b332fdeb19f5d2fc8108c233679e861bd40df746262d5412b8a6800f50ec073", "b2119ba9b25aa2a5921c7aeba1759395795989824a5d6d204592d0ab6ee8ca12", "76b874e1bedcd17be5ce3e206c8acb04123e83f94910717def66723ae8126633"}, -{ "665500", "3f0705d552dc4294997339d7015a4897e55790353236540c775e330c78cbb34a", "9595abcff6a155b8b995057dc725cffc3b283086ca65a6213368073f7f5d2b34", "c8118d69d2598bd2c6fb0ad7b57b1f859d441a090e152a4875691e0486dd506a"}, -{ "666000", "df535e0c312494f9f1a288cc54b72779ec7ba745bac09f7b952191c5a904c56a", "a545eb072527dc053c0630dbd820c51a2c3a22510f31a389abf75294dfb34911", "7dd43421d30bb27da111d5034dd3a6e104533fa5c0dc158ddbe17e79ea46d747"}, -{ "666500", "ce6966c65ae25a88bac2a35c95d1943c482febdf7f9c28efb57eacf2dfb9544e", "4d6fbf4b0b9c493ac96d63f97dee48afd60c2c847f9aba07110791514b0f4e21", "2f925e0f1db7403d712a85ec861255352dcebb1e770acb878eea6552358c778a"}, -{ "667000", "e7a271b35d3fb008b6938cb618fc6f57032c92aa1e09fc50363cb181ca53e2cd", "0f496a3a120f9644e6e3c5d371e6e01de4afc4a85f010306919bbef0aa323942", "3a8150ef67e892d5ea237fcd135b0c903e03e1e0f087732dd7d8ae6ce25aa9cf"}, -{ "667500", "783bafc58044919edecb6e3938f0ac69dcc75bfc220bfd8717d419091bd680d2", "b22cef79cae030286f2fd4b62c409c6d9a801f65e377d66d455fd814628d5ac0", "f438fe81453f186f7c1b1f43b7d906e489cea3f970352fa1da36236ddfb0b5bd"}, -{ "668000", "beaea7bcbb6c4c3a18e0c9bcf6cee525f9036796157c8b4ce5748819c13c2967", "a81cfb88c97c1489d9193801faacea720e98d21981856d121ffd5e75f7ab393b", "55cbe60a2b86bd7c1b4e2e714b07f83e2438cd7ad63a8a27d26b2a01bb221056"}, -{ "668500", "393c647b49312eece8839452c0874a2e82aff7169a3a7e1e5326b1993a5d1af8", "212bf73b67feff4a971dde4a00c12b32fe82859167687a3cfeeb03a93ccdc14e", "9089b9443bdd360e32feda94a28ddc9e33cd427381a62602207f0fc97e5511b1"}, -{ "669000", "f24c2d105f11f385c356455d460f8b74d466885118dc0e1ece8bddf624cd5246", "d91bbe1649788ea71e0574f15865868289b28651ab7e28455d823a515492ce0a", "adece8b6adf69980fb7c00f59598c1a43be400612cab0d9a67700342f9a9056d"}, -{ "669500", "3dcf0b942af949fb37bdc61645d89efd6f72b13c02fac02a96ccf1375cf3cc21", "81fdc3a3d66e72026b4bc01320881275584a05be5b0a5f8edbb2a6f334126024", "5cdd39a3dd6d4911e9e6058ba1d0357937124cbd0f8ad2d60c1069b730d4660b"}, -{ "670000", "e6d5cc2dd441d4b9f08b05a582c291a01927bd1a945f1a43557e3bc70cac59be", "c82d3be4f90e23836110348e66a9224cfe135ca4408363489f3296dcb8c33f2b", "1e45718efa408302e479fbf9478f8158fb82b7445ae2a40b7c3de67e0cafc261"}, -{ "670500", "c420986426267474054b56073135491ad4381376c64dbba0c57deab84ef61846", "b0c138c7e5b8bf286b3f5b6ad0a83fafa7ba68d499fea78553241e741a05d183", "8a71746fd8b18bf6e792a4509813c920a3cf481d503cb8ae4cf1c6d3e637b586"}, -{ "671000", "d21e66d96e08adbb61bbdb75a7e8971ca9bd45a4906f3ce23dbd84c2e5e8d161", "ba60c1936b7c35369e31e9fb6be2739cf60fc4685d210a209c4fbcf341d5c9f8", "833810b0f9d5c89970991f55a0f07946d068ca8faafe5afd64d48d4a67f01d1a"}, -{ "671500", "f7bb538d49e99ee06136105edfbd282e2f370d3f4f4c6d2f20b75938aca43040", "9c1b787f1413f483e72003c0ca97831ef1e616b86fc3165423cc84e878d487b0", "da656f45090a6bfb6bc6959639b25a1a26e0595ed00d554eabe1c5da8e727f20"}, -{ "672000", "8c85db8531cb0e6bde769d488b6c6a639f4839a819abe23ccf88f3756caa6089", "598752609771c022cecd036a0b8aab8caf8fa3e64724dc20815a827b750daaa1", "7c8d703d1655a7ee2462c82f78a4e0f2f8bdb370a6dff19f28d98f8b1cc839b5"}, -{ "672500", "efd3aacdf98aa1fc4fea20a2f4cdd9ea3eba6dbe03a63a149610d842793bc85e", "93df0fed7bd2dfd8ca6293601d799ea9a54af7b0d45997c821e4a8a7ab7d1f9d", "8337579b8d6bba63893d3aaafd5661b224a808aed129aaa36216f583e29832b5"}, -{ "673000", "3109a32670b3c1a796f9c6cdf5f3744848e8ac3ef0ee2ea891fac0eb69223ae2", "baa8971d22821acd1fee4649f702edc70cf1b072517f4b69d6bf4060cefa34cc", "fe51c93dc781185d8a9fc3efe07271096264f598616d69407d0d85ba17ec633d"}, -{ "673500", "8064bdf0c36a535d5d7788f901ac0713b627e2f8b80c4b20d26cee0daf02ee6c", "5548c9d616e98ed4fcccb300d3e35a78d66e61aa95c6465fc66a98c1e40405c2", "b5aa467ee5592fa80eef3af90b239407d7e31fa4c6cef603ef50598548666cd1"}, -{ "674000", "b409ec86b27b1a828acc7f056dcece326a7892314cc5b0d6682d21c06d4e4cc5", "a25e0ee6404f9db371913c15348e3aa8a9ad4b3cd99cca3fbf1e8f95b6e152dd", "5d62ac697208e75078a5f465f2feda182ad6a988ce953ff4909ecad0feb96e0d"}, -{ "674500", "0c8142e02a8e0cc1667a81f4c4d08ab7577102481f73d31b9d8c67589874e970", "0e31001e8d410c86f7a525b201f135bf6902048a0a4a25d3f283b2b1ca9e0b63", "ae1ef0b9fa438940e44e4804ba785686e04250c675fd4bdb76b927156bfeb9ff"}, -{ "675000", "f200a64f03ed78fdfb3a35be9133cc144cb7621be76f0a470a6cc451d31de7d6", "2dec2d8e6cbe5d122786b9c571751d54ba1d597e23dd4aa03ebc50212c68cf8b", "f841d17cfcbc629ee12bda00e988164571dd7a3b8f9c68951620a62f378050ab"}, -{ "675500", "44927533602536ec6857a62ddd2e7ca31a05c733cd0699a078c5106620da51f3", "989564e602ccbd682fcf993e4ca7691f049bb6adcb099860f9577a83cbe436bf", "997061d34d9e259b99c7911924177d59e78f2c86d0a57743e5ca07c1f1495ad2"}, -{ "676000", "1349301af96fd291f3f6cac4d6a6a94779a2015ee9d63989d79c813e7bf3ec81", "c196991fb4a511513fcdd4300dad73d556daf8eaaea1411a5c4b0d0382e96d45", "e332be471e67a22109327b11ee3002dd4d151fcc0ea5355d6189e3529bedba04"}, -{ "676500", "7a7071dae50a8ee6f25b289f3e9d15d53661469e5379b56278f391381f2b5ce3", "918295a1444f694e137f7f9653f87f1863884241462386fffd0037927c3779c1", "748aef72e32a43e6a0c050dbb046d7cf06a095fda95ef0da741e704337667525"}, -{ "677000", "a816938aabe21e8efc9c41ccbe0e7de2188e0bdb3635541e05b9cc8e61ed3dec", "d59c6134dc9539b3cc6aaff9870b30ba12676fadafe95167bf90bda3f074bdde", "30ddfafa528aa4ed1e213e7ee40c5a1d10dbb5c2b8aa5d4a980c02c6b16f717d"}, -{ "677500", "d06ed31f2f1a7dee027e76fd419c93a2c80824f31e5b0bf09e85e10362cdfa8e", "30baa2fa7e5834e442e8445c81d124018eec1ecaaeea695d4278263ae60ef134", "821a14af37286851070ca1113303366d270a1f2a492fab4e70da8a65092ad2be"}, -{ "678000", "356bc1b553016f0a17399fc531e9d5a86bb273ef944843e8aca16d16480f1e1c", "74c26fdb3397f25f794bb15595b8807b7d4a4500ddc941e7461bb106a69daa62", "274c911f767c18dd29f34d01a8ef4d35d2fd39b5935f054f287f98674741d69f"}, -{ "678500", "e7f83fbb9fef902caa5ad499746100c3422842f793424bb2b17f9431b0a3b6ce", "5177927957f3b258bec01be88d817c262ee5a64cee44e04b6d78b5f227e44442", "4332c38deeb9febf6fdd3a3b9641b7dd8da1e7f7b870604cec9ffc4470549394"}, -{ "679000", "1ced7af5a996a7028c63fe45238dda8c540295b48d082cc278614f68dae0e249", "cbc8a6d5c9ec62bd0d50ddb90e7e1efc4b62dfef8d7aede6279ad95186497f7c", "2e75ec964a78a7800b7eab5ff9cffc0937e157ed47e3ca60f24d6e200e085201"}, -{ "679500", "a00fef7924aae620536c387899d8628d4eac6fb45bb1954447e2de6a4fdb2ab9", "69b47a27d041a54b0be2406df7be07f3fbecfafc0d58407a7946bbfb0f65cec9", "54a2dd370abf726f06c0fb38f50a2ced851955467d7e935101bd3f8b092799ed"}, -{ "680000", "76831117aae716df313e1e7af8c4c8076e2b7d37bd7239c827962cf903afdb55", "0ba660526d75f5b1765967a87119f6bb67d33a496e23b13e58335e960610b38e", "95cd680073e4611d1f8eeb66fa540ad018f933cb2a943e533d4f352520ea7d25"}, -{ "680500", "17835aef913aa41dfe7a49e91fa7bdd85411356233f5cdda375771706b5a4e5a", "b88eeb3ef96d4ce4adf49b87f88a5c835bdf4ff88aa3a45bc46d2970a14533fd", "d145a5ef679bf4a4142614e122e5128852b20271e4cc77dfa4db939f4e2c7791"}, -{ "681000", "86ca3bca8de152e4ddd4ac3171ed463466dc040afc5e2f38eafb7fd0ce49dbdf", "55a9a5b5ed90ef00ce658b5fe52373ec23b37e7ae1c477decf0e8a41326cad7f", "780df69883c475d6c0eef972e319d1fa9e4b6c9e29b6f11008857f0be445f7ed"}, -{ "681500", "5b31112aa2d9b190844d109c44f8a4845bcb0f75e567055bc1368bfbae9bd427", "9b695ac5b41310d05f09d0e5265f53b4ff475b10d2b0e27928d81543857a1f0b", "3aa9c40fcd4aa12184b3d201806a0437f23c0976423e576223f6c891144916ec"}, -{ "682000", "0f036f94ee9dccdbb0ccfd4dc10663890af3c2b7da67321baf4919f8da0ef388", "a9d70e8df288e875c0361d7273ff846b54dbdae0d6d6459831e71ea4a41397fa", "b38c91a8d98c4586676c2aec47cdaf95e9bd7b8d752bd41f289df6b89b44f5fc"}, -{ "682500", "18658069c688414684b22ffe62a7e4d9b84b3f27c28351b57c8c5763aee40ac8", "c4ec9845b905ddf71c374d400faeaa649ba8b08751f0a5c6b9780d4c7d497fee", "87b2f2714cc9131438ef6de56a30fee9f1639269aad00ede70c922c67ed519ab"}, -{ "683000", "ab2a4002ccfc546d80417f9c1c66dca34d8de7df714fbcd4eee134659c6b4261", "5bccf1dbe0d677d06768a02a5bb6fadf5deb0075582a97e4524e2128a4fa4363", "675687d470bf255c4244f6e78d4d70e7fbbf5c58a0caa7f998f2e186179bedc9"}, -{ "683500", "5b302ac27ba940456860fa752bdeb27a3c8494c1fec08578c6d204588ae18420", "ae3de94a6481c28aca678f115b73c830ecbd163fd2e11a9d85b2c3132911c3cd", "77d7f359371b5ae66ecea9019507163255c1744f3aaaab043096e5856fd1dc27"}, -{ "684000", "15fc8d38546017ea2ae0e0b4387d74bf702a396b52cccfa879bec7c415a164b0", "9a6e35b63f814b6837bf67d897103f320a25e5cb15dee8e5524d9961f53368d8", "463822c866010eebfc3f7fb3d71bda605c22e62a78d00aebe68c1980454ac87d"}, -{ "684500", "e40472171e3915e9518f1646a3ca09a46154b226443848605a4d8c78803c90d3", "2c7e33f27973f6345dac95862d63006b4b1506d5979f60d8c52fec12b74a1b78", "506e99d0e80bb6429b76bb4cf9f33e7d97d6b40ce4459480b1797952c1347a89"}, -{ "685000", "742e161c4d772ed9ab9b2aa95ab7dd4646e7fa71a7b71d0062120791fff3d538", "7854ab499956e6893c2679a3393fb30e450f2cda76cfbf08bb3e77b586b10599", "95c2ebb16170b750592bdd409dda3ca05fbd9afc895d6bb9dc4ceb249a146864"}, -{ "685500", "697224d799e123de9da2b93aaf6a3f00ddd507080eca2357c7cde1ed1ae8f189", "1b02e1bbb85f1e71e1a1bd1e58e4eca588997cddc1f545ee293b17267fe5fa50", "fd0d4596fdcfcce21bf7a49e3207a478679656f202d54f3244d8803a70e2e110"}, -{ "686000", "7a7fffd9aa90d0d9e7309ccc0e450c7544dde058085bf4bfc9efde0cf8fc7b3c", "fd10b3c2c0539bc586cda1dbdc454a1597f4acbfc1d9e7e7b472e2d3547c76a3", "eae66bdb96a86e3fcc78a9cf04d23120bf80908c41a188a26dfb0b9b26a6a6f6"}, -{ "686500", "3dc10029047449d4411fbefe15a7f25864007511102972f14697dadfb914d5d0", "8064a285a9ebb460f864525434c5bfd94ea7c437f67c9eb6268c3f3e4737b798", "b81d605dd67e0b7694f979043719ee9b5411be3bc6fa73ab1ed224cefdf4ac90"}, -{ "687000", "2e2c774dfd40cd18616a82d3e5769d4f447a2eb5214bd8783a5084cb8ab38e20", "52379664d91e53a60d1b1a4d64ae2005e6549972c45af11ef2ecf2f2faf82ba3", "2ec94fed8848b9b2e94ad24271c6e87c223f85d092755cb9b3dd2eb75cf58186"}, -{ "687500", "295e12eaca70c7eaafb7cd25efb6b461f5aca68665832ab9eb652e6fe476d809", "43763991b8beebed72f3b7215ee72a2f074daa83a27c8db1decca52bbfca7b15", "30007826e0b6d9e775b8c9743c2d8fa70ec45190ec1269b0f6c10b3bdeee32e5"}, -{ "688000", "88efc791202d8e4a0266dc8114487847252ff2497c022ff4ac237aabc6602406", "560346aa44e4afaf2fa9a4e1506534bce8c0e113efe4b19c6aa26804b405bb11", "ed8e66e7265bf0879d5e0a656eaf6151281760412b6263bf0c5802973b535dd4"}, -{ "688500", "8bde3d0d7f23d76ffb10e59c43a9a2cd4121c3f5033204c4689fe77b860d616e", "fbc4d97609351dc9fcc8f4e08b5a0c79624c9e81989b684e219245878ec2fed1", "eba83125c427d7e7953d6e91b82344841b5c59a441310b893011741f00165790"}, -{ "689000", "01a706323f362664abca40cfecb4c6efa65aece3270fb1240e238f1e93ea3ca1", "e4672adb018af124ae848405442ca5e255ff9af3909d258bba12d29f3aecfae8", "2b3e46e498f4c7befa001bb3d16d177feaed83f08a83302e1b46f0761a45e297"}, -{ "689500", "3d25b5834362be1296b92448e3d2ece79f8017708479f56d7e28d602817c82f8", "643b9f9b0a754b768ff504c9941c627627b49aecbe170a72590179536840b843", "d9fc0a70fae6a96ff522389fa7855c171f3daa166e60dc39ac2eaf861b9ce170"}, -{ "690000", "0e622f16da74d548cc9e49c20d072a9a8a6bf45dfd793830fd25369adca29bc9", "fcc1d77406d58f3e1e5630871011b389449597e41f1df035518c1e25affcdc9c", "ea81179b8d0250b07cc04be0c567b863d5f693f5068562428d93b09d87662c45"}, -{ "690500", "d96ee19654c250c20011f56dff3850e61b9b01a8c3be009b93c0f53c79d6ad5e", "d3b6058792062983ed59720fa58ca7cafc890e475e2411a01331a4e3e8ddc580", "bf7073645256ba35b58c48af2a0a1da2fdee8539ec0670c64573c791a6a29d9d"}, -{ "691000", "0e02a80970060ff139ed4ce0a83bf5221895d80de69da89bccfd720da52793a0", "20279d4dcc8aaf7a83a59d70cbfdc4c51e8d034467a956cf012349dc01d875ea", "92bc507ac9395231f1c4387f393428b47f03d79f1cdfa44c0d04543dab744ec9"}, -{ "691500", "6bbc975ee40102521ac8b041e481797c83174c5f2b5fceaf3090895a6301f42a", "4ba322db9723202338d5c0e46427fdcf24c8631f53f3db590489cf5cd74311bf", "65216ec91cf0206711d495b52d5bdfe54516c33d5c5a3768b67b5246f52da328"}, -{ "692000", "a36c0ce45bdbfbcd02fe25ec7c199be6e01f6edd8e5095dd745b136e1a1956ed", "65fb3e0023b45c838637825b0e95f461b02f90134e875d85ca8f084bd30d3eda", "f71487796ea260abc5d1356e178faf08b6f91a8f537fe2d0ade5537b43dc162d"}, -{ "692500", "2f8577c57b15cf8c176873a546e1451b379f4e09967643452a37b037b538a0e6", "b15ca73e362e6394166b6e104ac474d1f73d4fe671117a77ad3f9786ee35488d", "bebeefd2b5f2fc70448c02171877b83acc0882d38a5714c4fac4ca3e0728cbf5"}, -{ "693000", "634e96cae2b7253783b3ba6dc65bbf79ad87782a46f07a11ca8c3b2325e2d2aa", "08db37defef7bf06dd75f2d8e4f8d1be0f2004d24e816a71ffa4fee43fb5153d", "e14c7fb41dc5c08b49848f994278fd52b1a64eaacc6095e16b089862e0c0cfac"}, -{ "693500", "c472b7da4a1d6e9a9728e58dbabfdea31af58c18a17e79e3dcade6d96efdb689", "021ef6717375d52d4e02c36bd8757c6c73b77c97bf3bb4d6292cec23afc3c8ec", "cfe39e0052abc482f2bef739131cdacd79582c952cf1a18f18b822bd2a3412a9"}, -{ "694000", "8d5000ca461da1bf1687fc3ee92e3a1b414a92737d82e301895d6cf41e0e4cf9", "e2e6ad6d2a58ee8538e7dd8136587a612c39ac281fc3e6bf609b1c497d9e331e", "a341bcb67f9c01c7cfc99d09e5e8e0ce74d44603c48af064d508726c0083e901"}, -{ "694500", "daf014e18bd15e7a19ac859acd668aa28bae8fac71079e0b8285c25fd28a46d4", "9a671a25ba774c600b2f967a1632561ab4ebbfc4b4016979aa9288af8be93065", "61c76269727aa28aa7e21471a6894b778e28807559713ad41f6b832aed7d9a78"}, -{ "695000", "f0d64ffc15600b2a53e5b9f09f1a0f981273e1cff39f01bb69a3c27fbe679c71", "d5adc8baacd5fc0635fe0ac739a16893fe0c4215655ba111f49e3c709f0d1faa", "46f19a5bf4e7a9a77cc966982ea6f0d54e06670471faf8bb9a3b0e272d1498d6"}, -{ "695500", "d784ac30db59c0e5e8906f2211b6405356158cf57af758b047445926e8dc140d", "7d0c9248ce3387940358e82c01b7accebe7d3445fe97f6569b0a99a1a4822b61", "fab42a73d154f8f6dd6662f9c8b72919fcca0951d582a296eb48f6b6273037f3"}, -{ "696000", "16e6034f4089c38e9eb2a11669e4d5b896b4e36e767626bb4c2cb852031099ae", "5f54a918561ebc4c21c27b793cee698c347e8dbfa49ce72f4580ad7d3e464a91", "0f024cdcaf10c1503193c4a4e6976507f46eeb34974358191087c8690574bf55"}, -{ "696500", "bde4528da57c22025db1123e7fdf3e58f020015b1b500be5d2ea13be8f4f50fd", "954600e88d55d507e82333a0b9b36f5bfd5da128e5dfe721ea486a117f196e51", "6d65c68aeb31a3b4f823b9ceb46fcd48f93e0e279cd91158124dd4e4b6fa697b"}, -{ "697000", "eea7b9418887e6bfe3a460b03f30f800672d8df94217fab7d1e7a74f437ebd50", "a210a2e4efac6617e3df43fd4219eee8e4a9dbf05e4cf103cdc9f39e162d61dd", "dc2d1c8baa899d025878d103d902be6f2ce14b2a1f46bb3bfad94f13fb2cf3e4"}, -{ "697500", "af96502823fad0e9693d94bc707b04d59d3f42fb27a12134f1aa0a863ca616cd", "8cc57e73164f446606d37223429ba5a37d92d1ab52265fef43c81d8f5d9756ff", "7c22bda98d112e24cbcc50d7e6c71892d47ec18dd658f28686f58d7765ca7bc4"}, -{ "698000", "8a0878bcd828268633df687a5405b2b86051640a122f616231d8d6146d4c2ab2", "27a9f143cdcb85bc01f31868f92a964337c451cd1a546f93c29361f245aff07c", "dacf575151c578d5b0f283296f31337bd7a1b976607fd492dfb0a88e0411b9ce"}, -{ "698500", "afbb603de0da6476915e14cf182c6c785ec6514b17d9ba7bfa74e5a228f6d8e6", "f730e6ed2ef1334071ce63f9ac851de557383c98b40a72f8bdfb29c49bb7d571", "70863c81dcc8cc482907c82781ebee38697b9c01791ee71132212a49ee4cc875"}, -{ "699000", "4e3bcab244d1ec2528890ed24340027a9add680ccac038c42e9a5b4880368a57", "1b7062e806e70df560b7dd19713440125dbf814412ff713c5bafc8776c443a60", "7caf82dc9c49db7c7baf08b8863b2577aeb18da4679d6a26ebfb620b94b32fe1"}, -{ "699500", "69c03ffa655f439caaa38a36031f45c27f6afa345fd8d380064ac4106a47b9d6", "0522b34e7ce87f078124a74b1f26e25c44cda27ab10ca9884d777a91cff19df9", "770d8310ba9272994252c5df67d39d32018ed69a29cd7cf734a9e8458412f476"}, -{ "700000", "19c87f86c5d859f1d4ba642097f626a5c6cc8420f1b438ef0ddfc52d77b5a7ce", "e7cef1ed642d40f49563c66d9428c699a66241a86d05aba5cb6fc6d6218317a6", "0c8c3f94794122eb5e615582ac97d2bec3b09ea1c5262861c7d7c4db6734d2a6"}, -{ "700500", "c22be0aa764d1e0d90432e726ecb95a769d691a7de81ea480c1bb9e74f43bd8b", "b0c38cfcda8312393e4906e1068c7a323defc33624e99c8c8f918771010a417f", "422cc5c68ef275f1f6d93266cce5c9fde6c342e1ca44a94f39c3555ed4059759"}, -{ "701000", "b2505b0ce33e22fc06044bc95bcf1bcea363d91c541451ba7ebbb07079c9b8e6", "36066185fdc8a919096d36245786b921b24ea4b9ad0949d3685c7d54fd3faeed", "b8821bed4a54d18bfa8803cbc988a6328ffe601f98282b71ae2ae265c57de22d"}, -{ "701500", "11c69ac149f239f122c309f5c7c8c08ae9ed95e563e6e5ebc0db4d49628972d2", "52282de896ddb2f1cc56c22ec74637395d1c2ff49508e903cf4ef1f5c01a1da1", "be400f9771c269879c127f664b0942276cf7768a1da841f8100d9f9c008f29e4"}, -{ "702000", "73e7769b7982c2e9be15c6d3b0156680f7705c802452205d64a5d66187de5008", "623290f47a7ec8b202b95f45d5c6408072766e49439c1aed29f023bd79a8e1d0", "658bd4418ebc07af0c511bc5f99c029d23d6786cda4c1d6f16e3f23c61fbbeb0"}, -{ "702500", "cd7f69f08cba82026873f72e8709cffc89a4bfe3c5300231a180fe4e7335e87a", "4f1bd226f6b1bc4313e7618f03e4522da41509937f596a3728da2310deecf49c", "364f12a79c19d5d7f2ce28ca42e34ad435f0f73a5c0f20eca5567f56ef0454c5"}, -{ "703000", "6253ae1e6bcfdba8257a18760dbd8f42bdfedce3257b9cff76660667e29e5e20", "05134bea7f58be79fbc3942bff929fef977a42b5bce28e787bdf2bbc1bc70764", "f51a6b93287a28af8cab3eabe6168ce93f9c2237ad556d3460874bd6a0c99dba"}, -{ "703500", "affc08445fc42e60d11152790408c66118b2a815647640a3eabc3006e0f58f8f", "34c74888ee86d1759127612373b099f56c53bdba1b0fbabb0a7ec61eb0f24ef7", "e691493935a99f1250c1d6c63be39aa71b0f92be49c7281ef5d9f95ace106ba9"}, -{ "704000", "5298b2ba05735ba586e9f6aeaad350fe88b762d00c4551d6b02f6c0b706b0f34", "9a36354d1266eb50f84338359401e91aad336d97cbfc39d574a83fbb4aa11d67", "d6ac796bb0fd95a710f0895b3373d11e0c20dbfc4c30182821df72841345b73b"}, -{ "704500", "f674bfadd8d412cffe1c8d6fedeb91e9c8914c3280414896f97e1c08e05b53b5", "6e593d4f49588dc6a68b5adbf870674cd17037cf7431f34253eb6cde06364421", "2aac262167b4696b70805dace94450148de9d8b38c1fb335a8f24074f6b24899"}, -{ "705000", "d288536328fe3b3301de1ba97c0237dcd740f225f4df07e923bb570f68716604", "b918a47fe346fbb9958ebff0e557b9febde26c435ff6320858bdeaa09ed0eb60", "0748bc47d6824e6078bca751e7e1ab4f8ee1ea090fa714dc177060f217ba1066"}, -{ "705500", "bffd8b226418632ef3a9f71f473093e5592f446776db14fec222f85de068c840", "e889bcd01a761d5208221642a51bb1d0afb1f324f74914590242204164287740", "b5d68b7d55cd34164b0a82778936cec4c44ba1734d282515b93eabd0d1870085"}, -{ "706000", "2547d907a333fdebec0140593814d90a1d806ee539598cf0672cc30a1d5c31d6", "77323ead475140b2224eb35de6da439d3832a091f1ca17e53a885d0b4d469105", "7bb1897ef463a29cd8fa71160e3548715453b2e75262cae48634a5d8ae5e7a23"}, -{ "706500", "5625e44c5204f1d9d3cb4b5b55aaa18f13be66ec9f76988159a172713f141fa2", "31a50d4821509dd711e9a541a3c54e28aad4bd6c6314526ba82e64857f52f4aa", "391dc850fbc3760fd29cfb5182c2fd2da847b2ab00fc95b890b659386878e632"}, -{ "707000", "e15531acfd422b5932479ecfe5dbec51af4e824298c73658bd43c143958a70b6", "e9af02a4dbfa950c0a45fe96162bf991f65df101072db521b4631ba7e64ad248", "122d80446848d02cb0c41f3c774e9476694ed3d6aee605a5d155957191f309b2"}, -{ "707500", "904129b3e99e06b3a75bb2b903b65b1176d82601355b13c92dfd2551edeea6e3", "4e5bdefe9ac9916fa5ba321a6056ec1bc8fa32ce3370587f13bed12c32976b71", "a89c430927f04d1935f0c5babe97cc0c5708b205a843803bc1a3fa9472d5cf5e"}, -{ "708000", "23cd48d83d0bc7e5b80c8a337389801ef9bd5584097667310342d92beafbabe7", "e916d2f42c77692bf97058ded798c541ce883f69786596ad94a22108adc17694", "e76a76c39fa7423dc5d93fbf49593bb5205d8b4d6c1e26d42d596f2ee90a451d"}, -{ "708500", "2f58264be757741e695394b348381a9ae8fd583341791a84d68d338cd811ae39", "dafed9faf74c750eedfc2e65491b75d4bae7d13b9e082e6fa91376c2d6034da9", "a01f735cccfc8003ae24b4dbfa89385a73bd68348410927d2ff7871863523868"}, -{ "709000", "e55588bd39fc8e754f2b272f80ac86b5515bad37eeeac6fc3dc0d1179fd53423", "69815269b65b334aa89cfca70ebf71dce7de046cc84b68f0f9c462da718cc469", "fb38f0c1e62aad790786497bd1cc083a3214baa52977ede6ceadab3b15e44249"}, -{ "709500", "e30d4db49a196e4ae4502c992118f37ddd6da696f296413500ce20b4b9838497", "4cdf69b6c9515176894db3bb5ead92d5ea1772d53717224656242e8007552228", "6d30ed16ebfd3de5f0e740adf51b7abc43bdf106916001bfb7e62ee5225a21d8"}, -{ "710000", "6f141473cc79d5def23f888471ff143ab546b5b1d1d5fd1fe51c996674e3018d", "5af180a3caf0ca42e0ba20e959495120693f273201de65aec15993cca37cbd2b", "b4103cd60381eaa47b921e47afa9080e02306159cf1766107b5c73e64e0c5715"}, -{ "710500", "10d11c0d1dc7316a7bc8a99b685c0b12c9e2bbec941d3c33781059c7048ab022", "541f760b8b3ed77398d5b5193220799c84f36e5cf342256921661f6d6fee0316", "2ca42896757f6e84ed6f2db42582eb9bfce4e21f5d2148b7d18a12a1f8a3265d"}, -{ "711000", "dd068ba9611f623d9e761f5e6a10b0298130c8b25317f047b6a4e79a3360909e", "920987e93062ef5eebcfeb0a98ff5b108649f1a092f76cad1c7d09b276469f80", "3be52dfa74fa750a4e97632d4a6862d859d6f72a2185626748c81290784bc4ca"}, -{ "711500", "96778f4ce3094a1c3323e3afd658b20cff90b2aa7f23d886a5f5629704f5726d", "9f4d8c3657fbcdf2375c92f6f7e700f8f108a1a5df22468685782c897b15865a", "b4be160bd18cc35c6b4a9d14008bfdca143ab1f9ef58f8a744ee7f5551687864"}, -{ "712000", "f4414c743e2b4f89177f92e0e11d61e9f3b1669d3ddd6148b3915862dd2b87b0", "df705fe65a056478cc8c914ead67c0a9b6023fcecb68dc7d9ec56a8c6ea1b865", "1d77d1875c2fff9bf63f833455e2db0a63337357ddeef49f50d9dfa9534831a6"}, -{ "712500", "fba950fc02bb67da1c4de9b6805b7bcfc0cf7e2bfff478568be99a70596267ac", "dc357d74f8f524808f3f41d6604d74a8a96c6bb87f695a15ad835abcc6669be0", "259ac2dbd6e8e2972ec7393e876b26818d1b0d8aeb44e6672c3e49cce19d1052"}, -{ "713000", "ff4dd851417240d00e594ee5fb5408372e4fd5585bb5ebf3d73a97dce1f4c41f", "b54673e8a2bd6d75e2218fecd8d20c0bff1b231b80fedc53b3f1deefc7fe4747", "f63d43982f24de8b83ab1d3837c6b7774137ce48f15915f0a7aaf6543847b258"}, -{ "713500", "92e49d6caa2cdfde8ec7d8c37ae12d995b9552c76f7c7ba0abacb77b02bdb5c8", "4c7b0f7d4f28c7c4d35a29c0a74310b38789decd628308c72a5a270a66ae55ba", "695ab5232e19bb40c61da6ac310de6020d1118c197032762b466f132e15bd1af"}, -{ "714000", "dc8dfa5b910afe73d3558be9d077fa57f1b6ac42e058227cd73b1b1cc0c70231", "9ccbffeff96630cd9248b3001d7ec7ccc83c9daa5351bafbdefd8a88c03f3224", "0031da42727b6f35ee4655ca10e454b4cbae45c43809098d870d14b6d9a8739c"}, -{ "714500", "e172274b228f5e4f49167f7d36076f71db89acf666b9e519da3a33c548515826", "14e35bb2ffc296d0d1f30be89e8a66f0bc7ade63250bd68043acf98dc625c91e", "b33ea3c9fcb3941d3783924ac3430b384a13e725e698be744396fb3e30632a7a"}, -{ "715000", "a9b83db90d65b2e1db885b5b708f1d7203019a7073ca3e5310ed4dfe19bb9d61", "1e2fea7d862a4b98f558f07e35d23b1d229dcbe2047a58f7bcec840147dae863", "44cc59497c3c6af33eedf74daba3925d8ffb15d32ab42fb97bba51511b227fd6"}, -{ "715500", "969fa24302ef22b2bea25b3f981fbb756f3de84f841d6f73ad9d6a6bbf463fc0", "31872cd93e38c92acd7b1af2ca83b7ddbc9319dd8606725fe0aa2b50026d98aa", "f6f41e6dabf4a38f8ab1df628df7d3cbbf10a40f7408bb54a74729e1c21f390f"}, -{ "716000", "e33babb3b3269852ab03a5044a595312e1828dc11169020fa2a05f4ab329ac15", "129a208db82ccf3418d94c00f39f3eb81bb7ebbe901f2a698362be4fa1f6e7cc", "4af118880519c0d6d340c1f491c3f83c8e5e35ff9dc64b6608c4e090d0aae0ac"}, -{ "716500", "9c0cd626f57ca90c771b00015658c387466c2f3d462d36d9fd3622abec903b1b", "044c3a4459440fa9078eb26f15d114c6ef9d63bc5b8640f84289a1f376b4b85c", "e8739d4d29d69754256bf748347fbd85f66714d772fbfdad9539fc14a761f11e"}, -{ "717000", "77a31d517bfcc769f64d0de88617d62d4d433c1d1a3136962eb07baa5f227a86", "e1f060643884a9ede876b52b38690ccca9c9d94140470024d2f825f4307dc918", "cb8be832b1d59378ba62a3ee348b044b60a74c8cf4a7edebff236530a589d5f0"}, -{ "717500", "546d0c517b9b0c5910d4d7337c366d76c7d99be4b875f673cf3876ca5458cddb", "814a3c25d78419214f5645a68ca361b0199b58ba3fd3109817b585cde74503d1", "1a3552275af0b42cfcf5250b893bd46b266ebf45a74aa5397f99f92c9f99b7cb"}, -{ "718000", "7e44714aea5af5ac9195904d29c9d53d03fca15e00e0f2c1a071611b6fd03011", "38d5d155e5a9992a6e9c1423f0ee621f19173c533e6954a46258e02982b89a02", "135d0b0ab3e42a885cc0ff7e579455fb52054127b4b6b46ed4fe32b871e2b4e2"}, -{ "718500", "dabb2702316c8e8043539190a1581ecb881dfdb7502a517fa183815a012eb344", "268c57e30e191d41a2793ad6b70796829bfe2726aacb3864283e82e384eea0df", "22dd681a53aa2818e3956d37d5be7589582b5d850211ea6ae5e539b003e24b22"}, -{ "719000", "9db785b29f04f274688856f0858c7c63961a6aec5788a94bc1aeaf483dcbbfa7", "8addd23f1cf6b051fc6bcd5558893366fa7a54ed89deba74d79f7a307c5224bc", "7cb536f13dc79ae18c11e9240142e7577142a4b1f474fdb45941d91a7be4a4d5"}, -{ "719500", "4615a7726a6b3b00fe5a9cc53fc916af6402871508fdc9b9f6e5799083edf0db", "3d3702be96cdabe826e24dd724ecfc426024a693c161889d0b41275cd6130d19", "087027216c909231bc86b0b4db03ceb66674212d63be60175b834599dc49a834"}, -{ "720000", "6b70419e1023a8dd272910d32c30aa0617bef67234063aa6e7447aae5356fe34", "55f7d559d3733e4d3d6b5c3c68265e088eeb6d2892671e88e9567f238268925c", "92e88488be2bc52dc5a5f775bfb82c388630a19e7a5238d47c119a8fdbe2cae4"}, -{ "720500", "473da49304fdf70d4b5adadf6fcab3f0c332ab5ffe82972dffac6b14aa20f23c", "3de3c3ceb92f8a7f45fc19ccf72f79f2fb8d3bc61654c534f81df978e905a3a5", "3610f4b330e9ba1898d98a64dbaca5d63071e971623431b2a1e873c31c733474"}, -{ "721000", "c293a009462b561ea37ba8614559acaa63cb6291673c68082a6e4691ab0eea86", "ea34bdfab3e2a7087605df85d858866b54b4ab1acd86619e99f6283a99f7ad67", "4d87009034cbef9f17d7ba20023efa90676fa62f3bd397ddc9e2a00e3b66a498"}, -{ "721500", "a15ef2603cf7a7b0ebec81fe4abbc6035183755a08fa11604e40c95477d61812", "6aeba98a3c5083b997eca56cd003e7f0285963bcb8502f73f2994dc04492c35d", "e89cf0c9fea734cb385b7dbc8af311bf26ca4564c58f338c52f8f0b5afcf130c"}, -{ "722000", "39271600011dc5e938c1308fc8f467fa44145f8bbc5335f24719d125dc92f664", "bb0387e362d72388584708287f86c92ae50f7ba4330c9857b308837d150906fa", "dfe30371d170807cd3e31ac464d3e284026235f2043a8a9d5bed5545e9595fb8"}, -{ "722500", "d7f846f9e439702e48044fe02c689990aa0a56613fced844d989816e0317be80", "f9308f9c0bb63c44b443473a8a25777e34d9a0e903edcd33598b270f0d7e9036", "2333a3407fb1d80d66bb3655b2ae3e64e04e8099ab1a0c37235b106e74792f12"}, -{ "723000", "6fafd8c865b3d0bb05f18cac70fb93007cff223789fb46958b55a205ffbbc959", "cdc9d13b0b9a5fa827d2572e9c3232f498e8b06ed8627199c61db9525469fcdf", "2bf56e3e72f5c449653b64c5568cf6dec1602888a9e77631b68b814e5268d29d"}, -{ "723500", "6ed55084a271a39809b6f3455a08d082fb7c56ad97427307ec207135c7c16ef3", "cd4a3d7e1dc9e293cecbcf14b969480c0c2f277819e9eb2286d1761df7320694", "a0ce856d8b19fa250998213ddce8e945e25238617d9632b1345fc257bbbfcf4b"}, -{ "724000", "c1b649d3101d61bfe8b949f443e1035a3d5944310f83e94785592c4cc91552c7", "452655726058f019fcf400a89e464688ba4bd0fcf267493e54748b146c7dbe1a", "c21245ea304822f3c688f672f6068b2c67de6c3f2658a9e9cf7a509cc190c489"}, -{ "724500", "21f5f4bc2fbfbfff183a3eaa110c1e3f826eae2f58d32242919026a8d1ea6206", "27b9e765e888343c7180fa9b5066ea254d8b5765b2d7e4a51ec62a8ecf02c6ea", "c681b8a5fc3f74d6349426ef2f01340c85c28bb4fc8857fb74d284e6b3bcdd75"}, -{ "725000", "5db006a94bfe731764372f332c2b23f9863f7741c0aacc4d92769f353cb4a4d3", "db57165deffffe98c3cfe7b95e119d0253a6e984d11fc2b1894ba4bb3010301b", "93b86dfe0990138a22c323a851c26bdbc1ae9d2c71b7db6468afbe0052c96799"}, -{ "725500", "f313538888a7b2cbf72adfff7c6aac1583c44b477c27810920835e1f36104ec8", "c811a4d09b2afb0e9e70bc9416e58aa2c3dfa4955ec4ecf03b3db9b65450e858", "2a5cb9561d2f20edc69cc6010ad5ca11a07d77403c5f090e404bb65a879d3e29"}, -{ "726000", "f9f289b08641492431e4ff87acb944092bb1fd4ae405569e0f3f14e433aecc79", "5c10e47957ac47afc2bd4fc6daa0c7e30f127f0ebdeb1b52149756d9f996eb76", "770901cce9162461c95f8f5506586075d2e0b19b82f94eb83bebeb8733146728"}, -{ "726500", "769de3f5c47b72bb76aabcd88f8c84595015f6f3f8d78b4d4a0df2be171faf31", "12f1f3f363f1cfe762d972b988ba7e0943520065bcafadfeda1cd73aad8c2aec", "b38726eb05623a3e08a3015a53ceb5de482da78b04c14de040f543cef35c2650"}, -{ "727000", "2d757e0b21cd7f64dc962c5ef6a7268d0e0223814f74e6fff9c81f849e496ded", "3ef2c4f48504f065f4efc06814674b635ff6d31e9b667f9b1ad864819804f446", "7f02f5fe584df7843a2d2590e3a1539fcd8c8cabfcf9b196fa686e2263e50e12"}, -{ "727500", "5b2875cc1b107110464a44d7d9a1835e8c19246cc4d646402fd3bfacd53b7201", "48695a64b57a8523e285989dc5bca5360df44847a66d926c154c6929e92608a3", "5205580f5bfcee12d6d83696744f906c044a5ef6f2e15e45840eae9bac331622"}, -{ "728000", "35fb3c9e4fb0a40ebced7b7d2e9bae928790bac78a8460c311b99e70cb109c9b", "758fc72831974d7f37e9307b34f80de04f3ceebebfc97c79eae5e1dabcf2374d", "32a4d80985277ea290d1299ccd4b5701d8b809e6b3dcb2c401cd66f75079fded"}, -{ "728500", "156a06f3bbea42cebe61c148aa7ac4cdfebf95edde5d021c03a90ddaabffd20d", "6b170063e91dfa3d05c9d6edf71577d85a9e3f0ef734b7376f757d1bd5a42705", "2d46a53620e7d1d09d96f753cda4aa6de2300f05c4d6b2f5fadc3220fefc9bec"}, -{ "729000", "e8771ec45982e5e9928539d0f4f398b3a35f02b92f44ff6937e6a6a50fdf4100", "bba9a535cc36db2ca8af73b8707635e3c12b3125b320df91257a944ea3a6af8d", "c0d1699b8d4e8fe005dcf224e460dab44bb1f6393036f0a9e7bdaf3c740d655f"}, -{ "729500", "e17e17e50ead400f5dcb3f3ffec5a1ff95da211a7f6d30f87399cb034b2fed00", "0263cf2e76899d4424125c726396ca7c8c3f1830eef290b084bc67aa3dff7ea3", "17725208b4e351c91f043dc00ce64fc4882b12bc2f84c793cddbaba08d27e845"}, -{ "730000", "06ee01124cc2d7e6ef4f764638700ae11ca26a457317564df6e5e7f0d881ba4c", "f20e5e74a5a07e05fbea7bdbc73ad393bc83a144a7e15d03a096f052d7065eff", "0ea35c2865b1b0dffc4062e9cffebf710ee85294257e6b5de53c0439e0624cb2"}, -{ "730500", "2692d795f114318940b89b8aba8a910b6360170048ac824590c5d814f8b01973", "9aad48ed4e603ebd7c79c8535c24ec7d2ddf7db6eed92b9d1e83846e9e139a1e", "9958167159bba887a61cbe4100f975ff830eb291aa1ecf35d601e81c825c54ca"}, -{ "731000", "e167080479d38ecc4cbcd16e4fae05c1f87e09d33e4947b6a9813ca63e147d5d", "ae82cde68df2aab3ef79112d4080a285b806bed3e457aa4215c6ee35a6d73e33", "701917f137a9974dcebc359e7f39ce47c4c20127e5d90b0cc6f715290d4052f0"}, -{ "731500", "d8c7e6903152f5f559f108449eead76f647a5c9991f2815eef0d0058c25b6bb0", "f786151a72adafd6930fe59a04cad481a49770c191a3f5444eb9b4d49b000779", "1fa2adda7b69711f052d101fdc698be6cf424b7c9aa12ad51151d4fb61455c8b"}, -{ "732000", "7371a17e1393bde477a0beb136f98e89dd30f49ebb28cf59a265dea0f82deb70", "67d98bd80facaa69bcac4ddff46661d1dced445c622bc90bbdbe1e7de9a8f768", "12daac68a822872d95dcc053f2986f4d792377ceb347b5803739832b840425d7"}, -{ "732500", "921701199569749e2d13f7940e6347ded7a3f1dfee26b7f7bb744d5d3db586dc", "41fd3e2f31c4d732326d13c5f31cd850e864c43f1f179d8631ec1aa69c506d88", "018fc6f520e5ffcfc1f7cc8cbee755ff914818f3813b1c4fdf66ea67a42adb82"}, -{ "733000", "d452ca29f9949b714f175c7ca45841a6519857541c44df4e52caa73b4c9b347a", "616e3b11378287c338d03dc5e2395c5500915fff6340d6fb48c0123e33f92d51", "c33b9f88d8fe1a9f7392d5244a3c81f4b5e6ac8ce5c6bf01116acd3e582fd438"}, -{ "733500", "4ecb0e1b2273ed4df5bb7db47988c3271e81cb9933d7cf50120e9730db47c82a", "6dbe9a6615825d26d58bc5a2c068e9068dc5b4a1402dda75c43ad3810cc55a80", "85633a636edc1e9e147caa51f1dd0c9f347f224ae059f80a36e905562e035a1b"}, -{ "734000", "6ef7723b332f6d1a4791f14a1cf2811870cbb08c2484ece5cededa3f69fb920e", "de8e532d9596a92249adbea9833ff2022f96bdd3f82b7c734fc3580b4b3cc946", "1a3f96832ed8a83d09635e696af0c7e9c613d1223ad319a2a3b67ad0258f05b7"}, -{ "734500", "01d19d29a83d79e38c274b76943e9d5769932a6a7812e3f297620a40a0bc922c", "ff43eec3f821cef199133f7c5282c9892c1b1546a77f6fac3e9021037481fdb0", "9483a0bb66b7919d3e4577e0d388eb55554a2a9ef1e151625739a14fb9b15499"}, -{ "735000", "544a5f6ce7a71e13db7335cd2a4e02fb7b5ff98253016f9d7f26956dec908470", "662695548e437e31e7687cd4aa3a463d2dbd1b0579df23c6f5daa7e9b3788e66", "c746d32bd2dbed6a9eda016c6bad0036ada8232ea88b85dc939b7d12e0983b2d"}, -{ "735500", "997d9b45e87e6f1f1b76c7c212527bef213f348c51d806200bf6541da07b76d1", "68e5ed2790eb489379491eeb583227ffaa09afd5b62b9073117e540505058b8d", "b39478fd31667381d09d847574aee5cf03b9477bce4f683cb3600c6aa3f1950d"}, -{ "736000", "b371ea1a60567133d86757ae1b12faa8832166726b9c2eb67a643e6878b0f64c", "f5308b0f2fe00d7b1e1bde602e6028ba5f2ce8849da22ecf2cc07edb069a540a", "0cfe3bd3e577dbfb6dc463cbd437b5658392d640cff71ed697581ec6b7f7df85"}, -{ "736500", "ce6bfc2ae42b6e0893e4abf6edeab04ee36cae259415004f71811cac250e2abf", "cf5273f67e35b1bea345758b059f5b4b05ad705469c64e85cd90f392f03db171", "ba542ef5c7f0000a6e504124dc41cb5c833a9e8b132bfc51970f3971285a8de3"}, -{ "737000", "79e359fb34759ed805e4ba17b22b3f64f4e05bff59b0929d5a996038e3e2684a", "06fd8eed2bedf16f590dbe5210c4657f8f14142fbd12b823b4972a4062c46476", "6ea03bba2478d703a2733547490033224633d92a6d9cf23255673b97115cddf2"}, -{ "737500", "3d69d33e4b40ef18a677394e025c74f1ff03807f1cc1a9924301da4af97d40b9", "8d5cdd08a8a4db368da7ab6be4a68085fc9b2a156fc5e89b69ed661267bd9d05", "e2627eda436a29aad70b7ce047f4dbe731a21fcf889c41db65fe75ee8146106a"}, -{ "738000", "de67c044daf5e82856c70c57c05e0963d2767f721c9a2a3095052d271ff77a21", "3f6cace03de90c0a7093e549aaa5862b4d0d4304d20e548c1b77a7022a39722d", "7107bf0fd8cf132d24c92e2b15640e5bd98e857a64118b0a6292a1d36b1c0782"}, -{ "738500", "9857746dacb79d61819a9a7bed47d4f3f8a8ef2f0a4241e4a26e84eecc388178", "b324b1e1ec98f23aad98bd643e12396cb0e6db5b6679f5f197b8c82a74912869", "e3cc1d3066314c3a969cd1d4758b7d20919507e4a881f8c9162390cd6fb503f5"}, -{ "739000", "e760e2ba3fbf67764d9ebb7a9b5684b71d079174bbabdf7de315b7814e6a6d74", "74cb6e148688d11254c235898692018c699071730431d7e9f7438c6859e1b140", "f5a11830bacedd7dc2938de16c36e1e64b8a15418e99c443f3297a9b702be043"}, -{ "739500", "f066444b8192b7bb857f79443308595802f67e277d85efca22432c5dd095ca02", "91fdef383bf939a8e230f32a00ad0c58452c3bb0847a257a136297dcfd476a6e", "3ac87fa0067e5fa90dde3e5fbe065ebd5b81f5cf757416b6e218e9cb4006bad3"}, -{ "740000", "8d11e7b07aad1f84d0976806645f5d508acb6aa563e1905bdbfd49f88a83f561", "d1fa7be0afdec09bdc631fb8d5a35bdf26f47b479aeee287cee3557ddcc412e2", "327633198b1b9a062e0954dab483215898c26aebdb2a37ba043f5de5bf950dd7"}, -{ "740500", "54b44786a4b53f25a1ff7dcbe85ba288f6108cafb0abaf193c6fa9fd1bbec690", "511fae7de79f3e6aed0645375673168bba00a2d39563ea2596e09e3a0e609840", "53da3ae936a368c0341d066925cd431802924042b0aa65f68d03c3a78b256def"}, -{ "741000", "6e98421219a255828fe8067f68097ce9d08c9f33886b8a29a22d2ebe6ba1f3e0", "ad33286ebbf08385412b7a732c551354dead015e466163e74e7fb5f94f6b1cda", "bed250411cd373b3b2be382d14df5c00745a98ee5b2a0fa07a6dfffbeeb3f247"}, -{ "741500", "81eb9f3b0f352e0ed1c5935647d526ac71e0b775d8715732e262f50ab6a55963", "fa8c84206d369ea634fb6668aff771d4c9d3ca7e687a6f2aabf1b2c80563b955", "d00302262d909b8aeec2869fbe84179c8363d6a099e593b536a188c66bfe80ae"}, -{ "742000", "540e29303471cd64e05ae80fbd19847c61476ca202848595583e1432e45b6a12", "01c47d0edde8e38dbef982a21b7b95e6049dfd3ecdb75763b3ade1cb8b804ac5", "6de5d07a99e47f413357b1234c46f8ec1750153692c54150808309b6f841f10a"}, -{ "742500", "6bdd578f687b5b04d2492b7bebe989d618b7d55802b977c9f1362c022d37b5e0", "abaccce8aa24b8424fe18df7490c67e36999e1f44dbcc68ad557c59717da560f", "46ce514134acc7a1f0c69feda82c4442225be9cb87077b320970e56dc8f49f77"}, -{ "743000", "1a56cced54e09d3e03f267054909c5800b30e571a81e21cb8e1960c32fb615ce", "fceaa34349bdb34a4bd0125a9d5a0d73ac8eabd0da333a665f71613075268854", "5b81d35da286085c8c5f08bee82e38a8c0f90d544947c92f8d5afe8da7617b00"}, -{ "743500", "2b102f1ce482314a2ffc09c26320f241ed197ef0ad1b0b1b05884d95e98b4832", "0d514c31a22d865f9480fb408373139aeb312d750df0441dbba91f6dd74b7c34", "39bfc62af5e07b039baccebca8f47e56677f491d1105f662e9b40543a7325391"}, -{ "744000", "9eb6d3d3bb45887dccff04f8555b7b6ee5c16af80cfc8fd132f2f5d64ef32d85", "18c336ab05bde704336b82417e0f8a33d6d70df4bcf3fd3277dbdbac7d285313", "3eff0762442919b5bcd423ac1a3c0b1405182a40670c3b72e50d7c93d7e5a085"}, -{ "744500", "2c894cc985ba39b9d41d6cdffd9225d1137285bb2a9faa355fc04e1c3a503783", "fafb7464d1745969dd5edbe08aa6400acd05dcfaaf6d09a135b206eadb2d7a5b", "93107399425dd94d165437b4c24878aa326f48d67164b4bdadc01b801790b737"}, -{ "745000", "0d3d86df05886717a850b573d540f01159dc4aeb9715260e19da107d8a5768d3", "273a426515f6fbbc4d1f505ac48c2be61e47dfddeef2e0725d1d287da3706876", "17f3b83f2ba432653925cd636891dd78d469356d1c8a18f40cd2860b9bd66a81"}, -{ "745500", "b614d96445616a551d2ef219bec80a8b104035ae75230819c08c1bb5d40d3eb3", "e8a90e0d452a4db19b7703651fd04988b45763240ec6e769e681cff12a9713c4", "94918b14a3ecdcc5c1bc43e98b4d437ca0483f34a6e375ebc6e217f004b0e731"}, -{ "746000", "32fd2569cffbaa373077a1d958628f5bb59edb4f1123ea22d827e59b58e6128d", "f0023c390d625e1286ba9aecfc80f28d96109289f7c438379a75c7b08c915f24", "381767ea931c005ac7304adcc66633a229ee3b7a73f67a385da507be65fd5a1b"}, -{ "746500", "51f9b04af9044618552cc030e88269c4c8b6f6285653003ea31fa0596b3be8ca", "21e1a38a259322e17a4fcfc9d45cbfb75c345d2475f7081373a9e8b791e3d906", "de4d31abc59236bcc16c6bd7b36a5a383000bb1e9b57d55ba02eccb49e56dd62"}, -{ "747000", "ea7dec43ccd90255b703203200c0b71d3aa7332a2bb43549c5b713bb03b77f9c", "9cf126abdc8e883dd428ae846e7fa5d694e87f40d1de07f772f916de45db3de2", "f28ddc3a0c8dd9831dc98edf8e7c80395bbc2a6f482ec626d2a43d3f6c0dfd24"}, -{ "747500", "1b651b29875be11fbb4fa8ed4c857b030122b7facdc75ec31ddaed88e3623566", "66c676aae65eae30d876db4035a19e8e00bdf9a9331361e72f57af17a3da4dcc", "52c8869f00a2fb858219119c25d1e9d135bcad2fabc2e4a12dc96063b840c04c"}, -{ "748000", "55f61b3e6a5434428b1a062ee86523b68f5459e7615c29d83f01eee310ec66bb", "4927588d5f0600d0a418298312581aab6d41144ee3bb87a6875d7b11c676704d", "92182c1111a64f08ba98870b439de9f81627d117715b3ea650bfb5fea98feaa4"}, -{ "748500", "cc910d9ef1a087c0c9aadfb77da9051aed5124b7d072b976f4d34dc74f842f14", "f1b10cb29bf15f5280b2506a480c07a610de4dd63212ac5fb1a33894c2fc0353", "d5d083bee08926e2bc17c9aeec940906bdf6b0f37ea7d6c2c23b2d4d881185be"}, -{ "749000", "70c48f09a23f35a244e22e7d43f245a20d1d171bd3958ffe261363536f92a087", "5cf7c04ef74572576b5debed4c20f3446db017a0360142b325a330909c904b09", "e24e68210d96e24cc04563ac6fee29b4991f3b13fa04d3b31f83506a03fb2a68"}, -{ "749500", "33d54681aff8149655455f3331792f7a4582c0f0a436b9d3ec0fced7a525ecb6", "95e2c8c804a409d62130abace845c696125f8a938bcebe60a45d9c76442fa6c3", "9c16bb3f870ee8e50900d7310541f629e4e087ee581467f3dac27c7601a9a881"}, -{ "750000", "8e0b562cbf9f5d9e0539f9964745265261cce019e73e22cd0db86f0dc7049110", "03a1b08260d16527973210066d867267be1f3d4692f3bc680afadd2b1653f995", "4c77b7a73824f489244a9a1ba383b413f23b932a2b7cbdfabe707ab95c66f5fa"}, -{ "750500", "a85d11029aa82c4dfcad63d3e6e32c4525f9d192fe8ed223ab9f05a3fc4a5d11", "1e1aaa3b0c05e04b991026c5a9b6a56228b007a6f936902f7a80f1b8f48eacf7", "79078573a0874c4d42ed9497435e6a5e9fb2a6ceafce103a28a3f4b0f9753dd9"}, -{ "751000", "bc48dc5090db1a9a8016b89fcef45999f9d6c87c8982dc4ed52e4b583ac2f7bf", "94ffd27371d8ad63511d87f728731b0513ca8d8b948d8b777d852ea9aab4804e", "f0b84e3b614d9701a514808bb116eee3547821b42e0d2f6d6a3d2ed2863d951a"}, -{ "751500", "c45fd98831ad0acd126e9fc658da6851a2a14a1cb037ffa596da1f2da2fc47cb", "82be3962eb66aa5c0fbbababddc65c99ac5c70b372b32aff94aa47392ce6b802", "11d04f7ee3e0ced8bd872e7bd5243f39704b3650db2372a57a37b1caf00105b8"}, -{ "752000", "373e8654d6a04c16dc7ef938fa6db6abc8672283a0f027cc34eecb1ec872ab7d", "bc163b7e20ee438640c02e74d48ecd1f65a4bd4b16d21248663a48e63eb02616", "dfa51a2b8c35ea201b2fa58dc759969dc8f41036f3ff67e5710f2a6b2a8bfbec"}, -{ "752500", "5f217d14da39d80fabcaa06ee56ddb41ee0dfef892576c2e100793f03818145d", "91a33cc31ca938ce0b222ee141bb4edc500263a0689d0aed50660f8e4581a960", "be525451b8e4d3066207a25961ed80d3fd944ab128b1250c657bbea2be7c8ca5"}, -{ "753000", "3e4aa8b1ce5cd84238df7ad4558f411a41a674ebee9fbe087bb41e880936a7c5", "7b8530bc78bb832d51460962af3cca2f534cfdc28760d7f5363534e68a72ec9b", "4775a888543db3451784cd50e2459d686dd66b08684e9f82b2aed331beed3c38"}, -{ "753500", "23a5236d81db31cd3e174f58fc2f9c1263365c35dcde4a20f315cdb01fc29d65", "042dfcbd5f30011ff7476e398e4c4b90f890a9fa4eac0da6b809410c3a9cbba2", "e7b4c5c5d5757a05bd4aeb7a84b112c965b857dd65465c2def12144d828e6319"}, -{ "754000", "5b4879ebfac928244d38117df31bb10c9d7c9e8e8d2a35c5c2f8a230b4593434", "c57c3095308f688759285e35312da7e6da208cba0f9db64180d551affaf107ab", "baaeaca199cc01903acfc8d30213c08fdbfee34e81f63bc7bbf5f0f9a97bddc9"}, -{ "754500", "96cc5bb1028f5ad1cd8a33800d9832d85700d037d5746d6cb4e58c1eadc8b119", "df2a0abff85d391ea42eda8fb0a1d7a750eefe9d5fe25efa10a9f46fb6110f8b", "f0c2a4150df181efea04ac95cdc535f8683ab435c9915de021957be8c4865bb8"}, -{ "755000", "e7129e48fecdac55aa3944a4bbd19eb16f0d8a73cfadd44a79d641aaa46dfbde", "385cb4dea3040a9b4d475877dd9d3cb61e23091f492fc5ad741a5cad2268c6a8", "9ccebf717328abbdcfc4292031c481d94e058144645784c9ea37b5a21962e264"}, -{ "755500", "93174ce679911cf73dee7fb12bc26b02889deb145dbc92d69637a85407812272", "5f000b1a76187f1c309f9495dbdabd5001f69bee3f9498316d0277383d861388", "6e5c681a580f3a0c20aa42c5cd521b5259b1220c25e47844929ef21d14de7811"}, -{ "756000", "d2cad51c4c7f604a86bd42e5fa0855488394561fd8b8e403c968676dcecf2f9a", "d24b9c50230b5c1aac5e5937e488ef65f19cc11fd4cb6b97497cea46061d7e44", "74a6420ddc2aacd8cf0c4802e46cc50edb4504924c64bdb287884b4358a45b48"}, -{ "756500", "2e24a5dff5e90a2bddd7343297d9e1cc5f1e8555a19606314e46c09962ead770", "dcd2285a17c2b37a17fa6cd27899af70be173d7a3d5c28c7f3ba6cf4d835c716", "29e38f84c118831844b79aab7038ebdf2b9a4107b7c2217512976b2536597d78"}, -{ "757000", "d11e6ed1c335b9cbb3db5e79e9ac728fe2377ec42de299a318dcf31ffc545ae5", "748036b1271dd158b39d7de65e91a95fc4e51fc0e9eb3445cf7306f15c0974e7", "14150ef035ca4576a22d8f67724062f82c3d51ce0899bebc32a1af8d0d06114b"}, -{ "757500", "0b5f20e382095632dec99c72f66fa419e1ce638a80671b8ba91b9a6d24f51e29", "d6181cc28a4fd461f6de97bb298ef188941d1765a5bf650e95d418fa8b7fbd4c", "1d5d6329ebfe3b3e4677ec3da843318ce79e3831a1c0805b10e30d718ebe1d3d"}, -{ "758000", "5a2a205c4c51fd035a4f57e79f2d92ca5e3c9af3c8c2beba21a442fb02b2c705", "e019ca24e6b67025cf564537c25fc2e6e241b44730988c316eb32aa8afbb6804", "a3e465d0821f9f2f099aa45c16db42cd1f93bd213f010ceb1b467889f30d61b3"}, -{ "758500", "e33c965b4ebb8b924a1fb73c65017199c806b762d4441854b79661f4de03b427", "313706df2d3cde7074b2f6849c1f134ede50bb46a297da3884d21a1828ce8072", "3a750153373092dcfe4dd326860d933a459acc0a9a686516a59bb70b070f0ec9"}, -{ "759000", "31928e69c1bdd6c727eda5662bce3f72e36496d538d9fc1cff1424bfcc24d0b8", "98b76d0e9682ac933b75419da77ebdf7ba10f016d35d26638915a5ba5be4db94", "77111411b7f07c74f18996a48bbb02906214463af40540656f4b263f40fbb8d5"}, -{ "759500", "2d322b637e8d92f51372101bf714ba726396d413b0a8e9ba573018ee1023b0c1", "caea6763d02b49152bce73655908d1bf489b2918b8514982a2fbfcb1099011e9", "e56b99479d6001ec1424744a425809882d6309a53452d7d9772aa4eb3c5f0fff"}, -{ "760000", "1cd9bc900f95c2e15a802f7eceb33ff51dd12a71718cb4220e466bfaa0f5ffaa", "0243b603adce50f296920262a13469d2ac1d0c42c2ecd633feaabea80a4c6100", "3783656e78d3879fedbfceee5589968967364f6af046d0f281bc8b99c6d1b321"}, -{ "760500", "4de4cae653ec7611cf7079c4deecd470afc39ac6a083a7b5ebfacd9d789c4394", "d3a390c8ac0a632c7565327db3e9a4fcc30aacc43e2ba57377a1477235124baf", "2e276fb93c0e9608afcbdcddc74fb5c5a9fe3addcdbac27871aa547ef7819b05"}, -{ "761000", "6aee8513d50a19fdaf21e0ad49ffd92cea289ed0fae844cb3afa16ad3e60b934", "045c6ba4c62d4ae995dced0633d85b8e120542be2533abd9fd1fc8c651f47563", "9107af72a3f9b005b7ba8b6c379bd51ebbdf55d3bfd7d3f9b39c6ebbf3d62546"}, -{ "761500", "b1917f5b3a3f1acd43c09e2d975abdf63f4a2c6d0b8ab429b47f467020e5b31f", "c7f69fc7d9f169a97f9ce25956c25668cb780205eb59dbee76f592718d74503c", "21a08cc13cf867235f5cc7471480d289f3e7e203116d607853a359ec4e15bd7a"}, -{ "762000", "5f11eb707b887cdd88dfd5f98203a949824d1fe960c4c85525995a377a39a79d", "6a3963332b853b978afeaf71fdf868b0d36ab203773c958a5fe5a427013ad02d", "f9b97eae9b714d0256802379dfe0c9efe2812b64cdfd04425c13f14c4df8c893"}, -{ "762500", "8c3d3c496b6ab6a1e56cd5fceb131d8a9dd8c4fdc938d15e6ed090dab25889c2", "e6eb9f858bb451d57926036c80c3c7ac4617b7897b19f67e2cb1952ecab6a24b", "4062917f26bb776572408ae3fb0789ad6376c988ed58e99558b5a5f2ad19a55a"}, -{ "763000", "6fcef4afba243507e7d54aeeeba6cc7de011b43df9d90f364794e3c59621b980", "47461602514b2ae53177fa064e5abfc46da728227988a9388120901fb2dc9a94", "b58aa437641b3c7073ad03061ac0e9f7e84a8c40cbf5c6f2e237584c94235c4f"}, -{ "763500", "41ed18026f39928e570601d40419b18758312017a7c9568d73d12d4b828a121f", "c04c199a5b9d12441ed489dcdff90453791925fa29ab6eb6c62b0c4d648e28b8", "ca6b362ff73a0d0f8f2a7a7088004a73ae76da9b9d2a22333686a0e40e881d07"}, -{ "764000", "67e928458125fe2e3c6970092328b48497a4d26c6b04b01e53cac4de70fea64b", "9270bc1fbd0aeda1572f2c2ef56dc700086652533d70be2fc6d13e5bde70f8e3", "775bedfd115319f5255de4354039a7159685f98370819905b6ac06e5202e6f22"}, -{ "764500", "015f8999e9b59d173970ac6f7b5b6b460879a56fb254c55fc64c79c2f1ceb2af", "0fb0da763fc466bcda98bdb2d28195935e5ed9c8d35fdc877160aacf553a4a3e", "7d7cb857eca8938dffa7db3374ff242e637fc934814ca2fc627b3c03f90b6d10"}, -{ "765000", "9e706cdbb0b6dd01e5fed36ab646fc0a80a850e08f2088de2136388d4db8a219", "f307dd0ce42f0f743054ed8236b6e8c44e4370634d9382ba439ef593210f14ca", "cf725e3349b816344204d20b498755e08ae270bd798b55a3081642af7c9cc320"}, -{ "765500", "76b996f89bf12e2d725e1df6b6e1f9fb71a0e4741add4657f8233fa6b1a9cc0d", "1c1d390e6e339f40129dd63bf89b9dd34574b6c0e16739449ed1936b023f73a3", "8987ba1a7fa864569fd085de2d8fb6455ecb5f19c20cc57485ff1ce2c12550a7"}, -{ "766000", "46b8674f0faf71bdc7bf0a656e0e02660d90388ec7c3df894b0b3562d8541ba3", "ed993dfee8eda538ad156e46f49e73c96e6abeb40c4e2ce1b34751bcdf4e7bbd", "90b578e9e673e5a0bd8d28b9a19d65faed380af38b35dbb755f85eb0515e345b"}, -{ "766500", "719246e48b8d681ea5869953004219e8e9ad1ae095d9f7005b39316010542a79", "7d760e07389497315c4c3b10c43d939fa4e1d43dc29fd4e898911ab78a6943c4", "303206c118e59260c94e39b6cfce312c44f1450ee1e223c4f0ea0880f8e61470"}, -{ "767000", "281b1c63ced6e6a9e548f01039e79b341b4c75980548acc70b0c52d71feb8e6d", "fc8bd623900af0aecc3fdec5de0a55fc7889c6b3005c4aa8fc3973a221702eaa", "9b9834b90ef9349513a363f3fc57dcc98976193b706a9916c18b689b4c1f01c1"}, -{ "767500", "d9a20cb9dfca54abe3534dbcf69a04b8f6b43afbe3703e7aebb2bee8cb81f73d", "899b241bdd3264be250d3f665e9930a6b2f302e1eb87ef65845be021d856c35f", "1b6a40b17f0dda2c341f653cea81e3d6e6a8ddbfc9aaaa063a145b3d735fa0e6"}, -{ "768000", "8360e09883922bda97c55167146f583896798f25e12baf10cbdb39254ab11ba8", "fa86336cef4c01ff1afee67169e0f4a3810546750ff4c38cec86e37c27444bb8", "1854519636f63903204c5e6d7375411fe7d4ca51126a9b89bd903da11ea8088f"}, -{ "768500", "ffb03996ae3de8c5bf73eeb51ca0527f6ebee4b20dd059828efad08e7e6601c2", "df22eef90381eb583a9e93e90e0722e0a6210c72da28deed40c27499c7a5ef21", "b8eae47b85e4f4a219be1ebe5901f57de53415bd7410ca1b2577aa908cbd1fa4"}, -{ "769000", "2103acd9679638073a79876db195d494213d9d6e749faaeaddd6c672cc7e177a", "cc3a63870c9ff71fe67008397b61d975a8147d03a0d8d35a3565538ed514b4c9", "0180d7731d63e1b4a4ba0bcf7d40fa9997c0520eed0f1c89959c4f705ddfcc11"}, -{ "769500", "9336bf1ee4de809e164e98a29bddd7a448333f2e25de891b4ac528d1bd7af785", "605f77b3340dd29717f7ba780e9f4ce15fd0fa43f2ed916b9e54cf23aab2863f", "77371c10af50eb346f69bbb2a16a91044a48dbe7bec4982ddd1f3e80b1da8157"}, -{ "770000", "6182eaec959caf801de20f3000efc3b9431aa1af594a05d704bf2c53d810fd83", "1ff43d1f6b27ee4063f01fd16f49110f0db50d58ee4937c28fef346f0777335b", "469227309694c2f4b2bd3e0d691164a2b5e6bf747177ffa5315b26f98ac69a7f"}, -{ "770500", "5405e7303c38724438e124b5e518c9af26a0076596be02cc57348e91a89abb6e", "a64f6256dfe425b8fb3b98b45dae59bac34213b85fd777b91d08d15a62a25623", "f5cb13454e327025100ace0344bd4af58e088555d3d7dd78e5c0ccadbb3a15c6"}, -{ "771000", "07874de328fb41f73e1aadae9e57705d7679e8e186b8b6a2ac50ed5d1455d1a0", "38084368706c2b4c84de621b821faec1466db4cd8334bbb13e4eb6960dda4b5b", "8451f8da96a32b867f9fc444493bbb25d26d18a7eace68196afa1acd048f0a5b"}, -{ "771500", "caf1cde2dfee0a11872272140e8043b92a33ab604f0b8a8c34d7a7006a11381f", "eb96afea84eba379a82e30b8366611d133f219dbbc728f99d55419e5494c5b6c", "d7cde2e02cb4e0adad717bb9540c408d7de57c290db5f9fc0327e27f1edc9249"}, -{ "772000", "3f8fb7f8de518b519eb102a29f372ffb4627dca2bbe06dc035bf7ebd4e6b733a", "b6de44e3b4a2a16494b4d6d7e5423e1ca66faf4ec0916a8ac97e4a3a656fde81", "df44c8261bc11e19e81c4d8978013bd39cd33852c3b1315967ff0f4786949dad"}, -{ "772500", "2fe560018de02c9be5e9cb02c0d2abcf8d6efd94390f10d8eb84d9dd3964d53c", "631496990ae92715067442cef87711925361593696c1ac62ed053618951f9d76", "cf131dfff5f531c19ea26b7760c86cb3ac1b8ac3f8920f9c4f15d336bcb68973"}, -{ "773000", "53c1e8e472ee4d6bad6411fdc74d9fe4fe2564d0baf1bc5107b9dc4ec6262afe", "8d48f77bfb9b49f20dfdb2168f0abb988b8ddcd8e9e62ac35ab0a2968b912986", "e2aec43709ca010a47522638f0624907813138e1e1b380f7bbe6f180e628fd60"}, -{ "773500", "2836b1c2239c528ef1ca59823417c6ae51c93040e1a5e3ca11742dd10350d3e6", "16f14274772f96d6d2072a33cafd5c8f9cf4bbe37111b3f620e04bfc42392829", "0a71b92e9860fad2bd7f294d271466c0e66a73c057d4b8ad4fb7e0da53894584"}, -{ "774000", "69a397d817d7155b644d650da51d5413ed2c133a3cbe2b54bbab7ae7e5a82914", "c50ff677b8441b9a940984cf5ddb46f4b690ffbc9703ced2b163d89b929830b4", "f8a641d436f1f789a2f605267b1acccb8e851946b22731e19a4aea620672b3c9"}, -{ "774500", "e7569a38cfb85227d2d2189a89c59518b64da01e2fdc89bca8e4759269fad47d", "b72f3010914018a60019f151631c660311b949fb400e20696b900603404cb82a", "131c227374a68de26401bd9fb82fdcd47bb947602a40990c87ad1830d5c95b10"}, -{ "775000", "d62bff072790320b532267e13d16eaa2b6124b12e9dc9704ea8b3472c33a7584", "2ccb3c701d5d6730cb7fea0a703c1228f75c58b95dd167e135689d020e686cdc", "4434ccfb2b3ee14daec33d99f0e1a4f1e48f35ac1bc270a796db881fe872258c"}, -{ "775500", "69206115fd6be6c73b95c85875329472d8550ea98bbcdad27b1fff5f13f1a383", "1044c0b51ee23082e8268ea9f57e614ead985939009b2d6595f866bfd407c543", "36c58dd2f153bb315fb5ac171b2d7ea231c405a995705a9aa5448887e72c46d7"}, -{ "776000", "acae9ada07a40fbcd1abe244a88eea4497d892f56bc6c47c9a3256960c48a674", "fa6f6390e5912cac9e116a1dc8ce23ea3acd3a45ab8c372f265c2a813a1d43c6", "766450d063de6aab1e43fa81768c6d063e83fa9f1e3109eda9cf6dba976cf44f"}, -{ "776500", "c7800bf474c58aeae4052c7de8a9a5be9ec371403659d6ce87f478083814cc61", "5801468504c422c927e64b555cbde135e90690036800af540e0a515cde84a6ec", "3e003d9d796290a1e73dae287b93363e01403205bbaf21244b6abe9d079d0614"}, -{ "777000", "60999146dcce1a4d7c57777fd14c438aa74620575ee304da40f3139145be094e", "761c802120daf7dc3d71945a83698a8ec2813efe961ad3ddd5f0e8b05d88824e", "34924d2e59d9aed7ff6e66e5e35e97aca41d40399f5aff99be4319267e8d8000"}, -{ "777500", "55464b5c24a72ca78e577947e5e31095625d4a5453d4ae8e1a628586173696cb", "7198361fa24cc1510d0eed076fab9402f8d312924dad53b2cffe4a2634450753", "2c96807bf221759fe40c6573bf7ea44299c5c292d72534b698f20df0cea9fcfa"}, -{ "778000", "a96e3ae7c78171f4839888370b8ab6a75527c35181a76170fb0c0048a340efa9", "40f745faad08e9ec7fb07610cee6fb0bfdc4b221bfe568e692928cbd556fd0d1", "31a1cf9cb956557bf6c4c96b3b6bc5d4f9fbf8c53a37649b6691ecff7d076793"}, -{ "778500", "dd54a9dab8dfd4362d396a50863007b96b150c454397a2b4cc486f8b4436acc4", "45f3cb013e25a9a12e1998baf79504649e32d0405bda1b8d6cecb7f51597dac4", "88b4035bbf033b809c2c3ad7e410a48bf17a5704e49fbc92f7792d3932a96bd1"}, -{ "779000", "04bc1cac32dcf0121905e3b0f8bf15938de5a5470e130dad3d5e9478e5c04ded", "dfbf8b41e5cb2498ab9f6c772c18ae3af36f693115fd0b7ca12fc18fe8dc9d6e", "be291b18bee752f9cef517ca4263ab5ffe3d18de70f60ba98a0e3301ed8d5851"}, -{ "779500", "acdc4b3a573253149261bf7b8483f07e26febfa36a79b0f85663d0418bf89a87", "c4e9858c10b84a43f0d48b59f2aabbb978411667e1e740d26cd90e824e60bbcc", "8fd3e1dcdf0fa802af029b750601b028e971f623f731e35a2baa82b04868c384"}, -{ "780000", "70e69b1c46b39329196e880591e35915ed2ff68cb83f2899e1c8a09885462ddd", "eddb55e0d58a9e963cc6bd8e74cdea45af4a42783f9b070eac50fd00b10933e8", "25c18241d995a1759dec8fba925b3da79c38c3ec81f19989cd0526929a3f270d"}, -{ "780500", "44f6b73dd235490b827c83c949f8116d3e794d139ff88688db18a6b45e1473b1", "011d86e2b32e548d2143b273ff895d85f132b7ad91a6ada40d29517155de88e7", "d0e6dcd1658763ad2e899fe15a7091f139bc5540ed174d9a5b774e61fe6df67f"}, -{ "781000", "afa04315bad0a73e082c417351c846b882f070fb89fbb62f94bf6627355eaba9", "83f5ee23a34675c501aaeafbd8589c2173bed116beef5a6c05da3652da34eb4a", "96aad7c45f8253066e4efad6a5fe94c21dcd772afdc291cd30ba0acb0e9b6b93"}, -{ "781500", "daab9fd8e2a04d026d3dc748d775734b92ba9d42af448b88c4e54313458f8e55", "edfa9dc118b24ca0b01976fa94551d0e78fb276ab38af92581b336d08ad979eb", "04faece12c26b07545b058a21ae9a71b478a34ba3d7a362e394bf94d9d26d83d"}, -{ "782000", "71ac38f6202666bef6bd02261cdf9590ddc79b15b1f0fd74a0991f32d7076cd6", "d02102ec38f004cd966d4e8d53db021475903f0630404bac02af92fc1ba0f055", "7abe17429f2a42b3e4a1a9b48c21cf087f9de1afde339f2e71bab9060551aad3"}, -{ "782500", "7065d66fe20e800ec4e007a0cd3301a98985fa7f755f0fd904b2a999c45f16fd", "c68d77bdcd1b1080ab776a210493e4371a1d30e3c73d7fe871e04b9345a0661a", "f483702e71f5a84316d18605c3cc41b2cd010aa444b88992a7d5d48569d18c36"}, -{ "783000", "d494fe23c434284aa32d3043e1cc6443fd7bf9b36fe12410f7d2e35f5360b5e5", "4ef3f9328e1d2d96c19ca549d1147c2063430601ec62870fc66c5b6e68aab6bc", "45489e8456e3cb771b5aa7897c56a1602f3b861d3656bd9bc504e1e80bd050f7"}, -{ "783500", "568a8df7d5669899b02e916c28755a8d1fc4a111f3af3dfd4195298ab257a847", "7f752afdb474b41347fb14da6be44561bbd5dc034ad25035718d57ba0e326165", "f21daa8b18e339ec5aa19a6ec0d285de0c17589b5e0b0ddf74dc4bba29ecae0b"}, -{ "784000", "98aa97184148b247fa71460e2ac43389d0d04b6265546ce0eba7c2be328b6bbe", "cbb9d6529647174626503265092201bc8ed564798e1244839a9a2f022c5774ad", "3ffd983e39a9c3619919a3cf95f271a5c6e909457d005756e301c54cace97df1"}, -{ "784500", "db38f59e0843aca6f105b25581ed990384b8b6fa6c340cd21be37799ac892e8c", "bdf27aceb99b7e0386f937d7c1b8a5a8cc92ceb95cb3191e5502b41245ba3465", "8901786cc7cd832d1ee4b48e75d8b747bf9c729a742e7f6e7270c3112fb7df5e"}, -{ "785000", "ddb1f819bd3e7a89588081208e3dc87ebca46dd381593d402bc80aeede0cd724", "814c34edf844fbebab1739243a0a664de608eab49ef2d91c57ef7195bbee80f6", "3d7b3b15cb2fadfa928ab49ee537cc627e7bdb8a0fba2d2f0042945b7d87289a"}, -{ "785500", "92f3c145e77f1f518c1decb6e99b826ce6d778c24634b3d6d3340897cb670c63", "6d607478b75d072ff0a14c4c23454a04b9a08d3f9c196ebc0b817fc7b9efbd30", "e59d891441d06cd8f973f6ad5c05adb3e5666bbafd72408eace7c7f4aaa517c4"}, -{ "786000", "07a5df141fe4feb999505fef56d930e19c684e5e452ca352f0fc49c2d9eea76f", "192297c49f950aee2578f0ee3249bdebdbf6955714b4a4e05edb3e8f24aae8c6", "1140d8f9f47651b9fe9974a905afbef7da25fa1f28e9815a83ecfae2d14323de"}, -{ "786500", "d9b454e9c5a5a6f9d16d22acadb61cf1ce231ca4dae12878d868598425eae775", "d47d551d3fde80fb8fc6886f235fb6164cd99133fe9dedc2bdfeaeb10bd45308", "0d7646032a898170d3491176f37f62d78aee810e11a73df03a36b2f9cb443f99"}, -{ "787000", "1d5ad94333c42f9cd396bd5a2772973ec2440f1d9f3cedade83af2e4951cbb32", "0cddc7f86a6714a3e3d2d2b004d1d3869d5226992f0bdf0f0d3bba94177b6a49", "7fee71383d6838eddad2f3ae1de0fd6cb0f2586e6265be99e5d78eb59c8e7e0f"}, -{ "787500", "b454323565de62c5e27b717877037c918e5c046dea15404d0817ed066267fa1a", "e428f7829407e31e1079ddcac80dab9b56743be59912ddbc0e0691178991b568", "fce258bddd4cb4c1e979f1db0904ac6822c520b292f36622b61dbd922f997569"}, -{ "788000", "28c337da150a017aca9d5619b15d605cfe5c41838893650f9a8108c4844dc5b8", "0d7ed84426c912c0a3d3320009e66302ea92039ebfa4eeed9bce380b2b2df8fd", "6472ea9ff1201bbdffd7b8344fa8c32f9afa5f23fa534b071b0fe78eb8072fa4"}, -{ "788500", "5f6ec263add108aa8bae692f8381bf9e71a615ff5d4dbbe3785167a10465dfdd", "3171b907ce8071d79c40b61ab802f51d8f1ecff22c4cfcf618065e8bdefa3910", "6d0bc878ac444cb0d59c77ddec27baebc74be98a0739f14037d03f7b30303382"}, -{ "789000", "1a1a8318353d2997eb996843165ce0a2879e058d6cc2498ac43fc495f3010874", "0832a6b246a8221f36b8cfc3c15c743878842545a3ef3b5ffc0f1cde8246b72b", "f309df4a8e1bb1278d50f91826b348e0f0b041db376d3a18c864d43889d05ae2"}, -{ "789500", "88387f881fec667c0a2943deb34f9e508a994383c3ac8884d24b1dfc400344e2", "866305720d60de682a074333f7b1512e45c63ab0f9090d8791f315e199222519", "a94028bb8240ee43d6c5e07090cf2b198ffea495e7051580c34760811f2d4c11"}, -{ "790000", "1659d12734baca5dc87174dd4ea3020c907031df843af6bdf22cc2ec8dea611e", "63e7e3f379c2e361085770ef24c82f250cb47056045bae37c92cd369aff4984c", "550bae5652731d97b02f51443fac5bd465c5f19ccda22e8e0e685104c5beed42"}, -{ "790500", "a01132497c3c4a8622f3c0039f319e7bee99942268a0ef323cda3fddfa11f1f8", "aebda06ea6afc6b95cd31185250686bdd815e89025a1b067f47db36dec1fb8c2", "a299c70cfca4a801fb39ace7e623d8346dbcb7ecaa9e8f58c5a556274cbbd4c0"}, -{ "791000", "9209e4bff9f2c45a6bf3d2dd4f8960b050fef2a600c1dbafd65dda57bcd909b8", "e005838fe0d4d7128702bd61e7be6be96340f3d4538aac8ec8adf6955bfefa94", "9ab13acad78de5329ba9ad59dae73b681e37893b6ee45146fbd04457df3f2de5"}, -{ "791500", "facd9b684bce4af3ed32b93fde842ee8d30775ca97b1b3a691ac0f267301b280", "df48a7e529861e94604eaff33a4ecdd7e35be502a78ce16aaebc413f4f4ba59e", "2be1c96a19a5f3631aac8cb883f8e94d85ec5099ff406ad5ea962a13d0dffdb9"}, -{ "792000", "8439d367ef216677cf50d64e35abd6a55d555260d8a4f53af86560221aa48b07", "6b7959d457444a0e8c085d2f366d54460a8e8ea5691d8d0f198275ef79b72ed4", "056d4125acd9efd6ed734709aa7b23dcacbc1404cd764ce5f2a7abfa0bfc86aa"}, -{ "792500", "2200f9ce62b2fbb1b25ba5e05a09301f576ca7606c2eebeab05a7188ff5d714c", "2b7504213f6fa99dda613f8e7bca2fc6310930eb40c405a06df793406d146b8d", "301ad8619f7c451bac9fd29d4d41c83867692cb87fa20e11ed94855c9251ee7f"}, -{ "793000", "3c520432d9a47e6e272dcdd99e656b04a1bcabdaafeca135cdb61b105b31d413", "6f6b8a462b2d883580b1e2acacb9ce051016c06a12a87219097e5327c39d84b4", "96a981e03d7f6b44821c7ef67805d6ac18bed8983ef15881e7b4ad026508eb8e"}, -{ "793500", "a9ede0aed7bc7639d97fbf8c81203349b1aed926ab534ffd055199c047c427aa", "6b6e849eb0227f85c0faf658c06e5b4b75e15431263bc587a0417b801910ed72", "9083b804013b0971b268c4ba338c8df637bc8a9bb36343d5b15a2ed43b450f41"}, -{ "794000", "8173afb6ef69b30acaed892e2cb93eb9186a55ec63a8730cf5f23909c13cfa9a", "4f340c5f5665cf08ec366e0ffe561908c19c646b9567ab3078ddc99ce216fd32", "53b24a984c2ebb796223af7d02150cd5cb56082a0ac5b6c1f047ea533c4d080b"}, -{ "794500", "debb2e81b7e22fe9f49c42c5d747837344567a5d301f900731c7ec427bc671b7", "79a735251474e25bff8fd23b469f0d79eae7b941b45b181f475d7bf8ac2fb842", "bccf02675e786af7dceb9fc7a1345362f41520089cc1e6fa0f0c3ce462db9407"}, -{ "795000", "a83507c3c3bd71dec9a8b3f471cddb67361e6401767c8c8ad348926ce4830d89", "e626138e04de566aa065b5a7106daa670c614de2ab4d326523bfe5d1a4ad4899", "6aecc8858c719d0a8cc549660b54f5c9e8a34cd9cac07c1289151a482fcd37ba"}, -{ "795500", "0558ab8c1e1ddaa709688f0fbdbc1413bd8f80362f6e053f20479e9aeeedb4a3", "13a40efafdbd6358d9ef9f1b9307a88b458e999100a93b8f4611542996eaebf4", "9d679d11a6e91fad3b2f536fe18e47c9d6590a93967be96a98866779722f199d"}, -{ "796000", "a141fbfbd754e10fd7e956c10d459834261d3571affa49b8fd90c0c804d0fed0", "00fc2ab3f76f3b577f97c348313e9256331ea81a5cfb7d8466fdf144c8e9fbcc", "252b656f49a41308c16f727b69a001dfc325826b60683aae6bec855aa0517ae5"}, -{ "796500", "7351e53a275444b95005213efb4a5a1397a7a01d58b750323bd37ac47326c704", "57ea2db92ddb3e36ad171b3bacb48f883fb7e8ef74466fb769f7d5553be66c0a", "95b1da9a766ee86ab81026c998b07fd025d6eb4133c3279994aa4a725adde067"}, -{ "797000", "80fcb6e51160ba191312939b815fab48de5a56f4121a3d2cd7b6925918a07af9", "96242babb7769751d636828f5fdc2d1a44ca57e399fbe5b0683d09fd66b83da2", "3787de63477594b2a378e31210707d4b61f18d39bd84c748f70e260380236c51"}, -{ "797500", "57bf7c33a40e1813c1947efd7412a3977b0d74ebfb6e846097aa45d03eb1fe47", "e1250b6f44746881c59360dd6144bf4d2e86f8e31e68b0b820732b2a8bd69d5b", "316dbbba75ad23f9bd8cf6cfe3f6a277b1ef742596a3025165de2bd86c4da49d"}, -{ "798000", "f3370335ede3598caea04a87041fa7c1b51e5c9e1c5e0d50bf2bb136a64cd167", "e6e1d946fc72e48f0399f980e5a4f7e544b4eb2997739223c355e3b15af48fed", "647618c6d3effcc52dafc6a6705ad58695436d48ef25aaf8d684220757bca52a"}, -{ "798500", "8f2f93e0248a8d8ded2c5106fe5034916127161f1a554e2ce307c5b6afc3e00c", "2db41c24fb6ddfebf0b3bb5d74fbc1cbff4185082e7c22ef66c336467c652180", "ecfa971d637bc6ee3e0f461ddcc77ac59a408c30dfd2ef3dae3d43e16c15e5bf"}, -{ "799000", "5c376ff3e907391741b0ce9601a65e616d6183cff6bf744bdd6597c455b306eb", "9b86110172b3879f17995b766972b505bf547f40e1113cdb52533357eecc4ef7", "52173724bc690d27ecf672136ad648668707cbe81735bd2a77202a7c765ef32b"}, -{ "799500", "bd143703c66bf324a5cbf67f9da778755b4f7a598450c328fbb011d1eba4d96c", "83480b97e6c3221fe90a83591ec104492b37896fa34943c4f71265cdeb5659ba", "07f30ede5076d4d94c9e1e8e46bc5402d1fae50effbdd0a50fe82d31e2e5bf5f"}, -{ "800000", "e951054363c21bdb8e2c65154dc8453a7ed6908ecb10ed72fab814899d3cd345", "9a0b2888559918507acbb704a78888f3293e34ec18cbc9961ac7842ca297984c", "8252634f061e18d4e82e3f91d044ded94e90d223a7de0a13b6e772c5c75eb612"}, -{ "800500", "956b9c5b3c055d3ff4ca81de618186166629076e317b2bc429faab8ed5a9bea2", "9a80628c0558276ab328fbbff05e76501ccc20593000dc13d57eb3ac4b618838", "f65f6f7cfec65d2c895982d1ecbe70336c1f8405783317db7207dccb3a5b0c66"}, -{ "801000", "3abcc1a5f4b6411fad8b518e4e0266bebf4d74ec36400e0b242e299aab5d8d43", "6e72ab4aef323f82c48dcd697cff16bb1f0ecb039a1a892a74c57abaed498d92", "21dc9821cf54c46293bd6e575907a6e5ec525713f4328952b95cb5d9792d7131"}, -{ "801500", "c49350d66b895f226052f92ec5d5f35b70596d37a64fc2f36e386c21cdc224a2", "1e1eab3a1d14c473a254babba1a8c9f342cf97b0ef0f60c2946149c72cae6423", "4385f5a51158e98057db889478b6ad2eedfbe9463b47f2998bfc8001e1ff5c89"}, -{ "802000", "f739f9b985ba0ee82823c7c03d7ef8788d23c01ffa5ab040ab23682d5e1f27f7", "45786b2936278a79a8d856f96f53f0d4b09a04056b96a10d5bf71f5ff849cb58", "25e4902b2c0f1ff83a7b4e0b7796d4981b31c1a50256b9b64b4f2a66fdfb36e6"}, -{ "802500", "1bc5ec3d7f952e5f27e9de2f21a30fe9333fb4a53b9627d78567d789cd578098", "11b12b1784bf7f779aa53e67753bb6eb9d1fadae56dffeb1b9efb5f1b1ddbebf", "db3095dee6d0a50357a953c8dadc06f2498c054a4ab1155c0ba5163d6cf928ea"}, -{ "803000", "06fe520cf2eb81478bc9548d5802a7ca815743a5e541ad64b995af5b177ed245", "f2401149fd3855cb680fdbacdb22b368edb2a34f73c59af55099c2d44e79adf4", "2d31efaf10a7dc9b590db9fec6421b19cb6dd9d9284d4e731f1e34e940f510a1"}, -{ "803500", "2bc1768fa981d73fe4eef0174018988fcc0aaf5316c8597cc1c1eae8618eb055", "b1a09ed639e05848794994217faf96d9b66a9e5ea926a08efa7bdfcef312b107", "70849af07f962ffc21625509928d9977d6650bde0edf450ba910b14928022e92"}, -{ "804000", "9d0ce3d35c935bd67f2970d8d3d5b098f99f936e880f9ec87cc5e0b1f837a0d1", "4eb8648f841497a4bf8388158844361e138eebcde30aca295e530b9d97bbed6b", "84d64f6c3969c5a92a36911c98b66cac9942cf4e8a0cc8def314b28998593cfd"}, -{ "804500", "87f582951ccb498931e71f194f2bacc2aa593bfd236519e4abd2336136333283", "9ba93a57335f44c4bfb962c33fc0698f6846755d94ab393b23a81fa9acf72603", "e65a4a25e45bafca371b86fbbf7780de48b39fbf4a5dd9d5397673c953f25ed1"}, -{ "805000", "efa84f401e0f8a68ac402f09bc3988192fd6c85f22fdf239e5b76ce100e3a2df", "a4a5b65c94cf7ce1d1cfe3c087f63037ba522ee4916dc20051d5953f6d42e067", "a788f574e086bf728658f5e9a973441e92aa1bf0bcabcb1b077d3951df73a243"}, -{ "805500", "c0aa476e7e6452f41dbf4cb5bca05893a93782716c3299f44cf31670079f3190", "349733cacd77e399f52831dd1f33884319cabf7934c3705e798fd8add0d90247", "60fca81f8f2814562456842b24e875af9df1a5bab37f44e67f3c7c74c70fbf99"}, -{ "806000", "8459d195b63e53f3495da811539f2c883361bbcdd4b0097d0ba214fdc55a8219", "9fd38c1f19472a144ec9b8cf57d8d9a85966dbc99cfb05628f5683dbe75501eb", "345d444fc91ed2f7aefa42cbfbac89707532f876a91b91c84462d8defc5ed659"}, -{ "806500", "8ca60c34843a452a19d05b38dd13aaaddf0cf602601ab66769801c5443380904", "f1a31e6d1b4cf5387c7def82294d179a656a10f438585a643e49dd6372982193", "4a88dcd7895c712cb2b4e1fd05517f68655072c04713adbfaa9c88715c4ed4ae"}, -{ "807000", "ca98242c7ff34cee593fe6dad4393698bf5875e9a980928363fb0f2bfc01e0cf", "040fc4bf74790e2218abe48b6e53fbc6103ccaded8f389a0957e9008f96c9e2d", "021b8cf0157c9b7b74d65d4a19a8409fe69f571ded09a89cf2b26df608eda94f"}, -{ "807500", "39be5b7e38795922ba3653d1310f1579b152e493ea3c8bd6630e0a561465fd7e", "a88ca5c9790cb9542ef0a64dee1b5c001d56bee7636c09105a95abc859ca5335", "63e034d22973193d76f09a5a933a188954bcf1f2d28a8a86d1a04a06a3c4c0a4"}, -{ "808000", "8e9c44d713b7bb2ad9d8cbb9ba3d9aed199b4a70ea1f7288795ca86c966e323d", "2c9dbc0b472b7ae26418b1def60df7a4869a35cf9bbf74b9a323d08035aa13aa", "95d2fac440da1af130ff838fae84ea9f9a91a2f707a91b0312f05d3ab917b744"}, -{ "808500", "dfd89eee02bd3dd16482828c743927801121f67cab61a4335d4eead749876a21", "549d7b6c5b66bd74331c6cb6f937c8cbc605dee884796067f42fa1bd04bc6a86", "21e6841e9e4a40775fa7f01cae49b438560c94b49ca8187bbdf7bbe578883269"}, -{ "809000", "676d2d9df28b1d4bcc68bbb1606033349d3e3a4c11790eef43f689d5e8d3ba7a", "18d4addc8cc3174723f9ce263cf632f3817d015245ef3fb6ecae87aed807b0bd", "a358260fefbe6b4e1438bcb06a671260cc74b269f25fe018ea858331c5b658a6"}, -{ "809500", "001261eaa38a49c58facc31b6c7245af90f5ccae8d120be1aa3b23f80e68513e", "1489cbc34c82aa22a7de85e615f2039703a23da1494aaf7b9d1c425e4839849a", "0954013be6e64e28d40eba427c1c046d767e295102bef3ceaedaf706e0e6cd52"}, -{ "810000", "051b563ee0050d2539bb0f57e3a5b5edc759af06e4dca9ecc9b651122354d828", "84359c9f7e1bd44948c4df3a1affb6a4ee05c2761f3b22a192faf696c1c8cfe2", "8afa7f4a4d945eaad25ed01a71a065c33ab3788519b108ad54074681ca8601ac"}, -{ "810500", "9ca81889bc6223d0195bb98eaae9b2b81771b202153dbcd4aedeba781063e4e0", "9ee6f32bb1bcd2ac2787662019ca595b8a2569bb90a38be9dbdc77fd30e0f541", "8d69e782ade3fece55262c1dbafc192ac62eef03e87f547dfff6a6682994b20a"}, -{ "811000", "e24027de80e7e3cc2e2fb95439a4bc88541b10316eb1b111d107119a154ce444", "373b8d3021db012bcd4b8558235d625a2d8eebec48f5c9c8784ce80be7ea459d", "3b7baa5ff205a15500e756427cfc82481b5a4cd066a8588e3316091e2c9ad1db"}, -{ "811500", "2188003a3ac1f51c3147082a9737895235c62f579500ab7207e04c3db272300e", "5d5c778748335e1c6a4d7b72e799a84b1128150bc5b782238c222d234b6e916f", "c3d6ae0a5807575eee61c9e07cef23fa13e0ebbe17686880a722c04180097efb"}, -{ "812000", "8edc7d32936aead671b293ca3c35a4f2cd8da3da8d0a911eab810aae919c671a", "67921067e57ccb2692bfb932c9fadfd695208ae63e41c58cbaa2d1ead989b572", "3e70e461d77ffad5b2360e03d535f314e7d007a5124cedc04d2a9e5142b55df6"}, -{ "812500", "f93429e089b8304c72beec28ab2589d33557ec36f12f1e5c21acf96a1eccbbca", "bceb1b621ade4000a2e9855c387f4575dc2599df96fff5fbb43a4e934612010d", "2d33f5ae00324de69262e4187ca0930a32a9168b8901d3bf33429776d2445db4"}, -{ "813000", "c50b28d6a65438104f28a3518afc71932e5acfc9cbd3dbb0870dbdf8e175e159", "b43d73d2203a216818e42d28b5108016335c606dceac6f6706641e240b065929", "cd035b84d4a9e11704600b28b2f363dba81d32c87e2c402d5ebe6f4d0eac3b62"}, -{ "813500", "9ea262207c1743a9666200b8f174328d53875437ef4238ac0f7f9f1e841d52cd", "e915810eb721a46d939812114e3017db4a2fcee9c0d3b6701f070d61260706a7", "4a7f61aab0c3b237dca327b640b730ff5587be83bc94f49eb5036d512cd033b0"}, -{ "814000", "7fc202882e511a8dc8b76ba9fd0e5d24578c5c45f51998f83d22e5c54eb72c5b", "69feb5f7c9e1eae4dcb884df1bed34f628846110480539f3ad02db9e49c87f59", "d387dd72b95bc8e7522e3525f2a1d1093358be2b3852c8298f4caabbe56cd679"}, -{ "814500", "946dd535ac1806a838ff7af300006a3b019926e3caef42f04e77cc50453fb597", "91645835f2dfa4f7bcd0818c145f349fc912335d0c28bb21f5a6c88833531ef2", "6852325a0f560b5ba965fc180e05bcce4fda06e5e3a1dc75e6ee57d127f94a1c"}, -{ "815000", "32f06e0d2112aa022953d25a663a77c34fb1f0089091be64755920e082588a50", "09503cf3aa4c5c2dcdfed49412a77bea1120ed6741f024f25384f9a2f6865f4d", "0a90b89381fbcf7f61b4340ee9a1bff11a365472d68750575b08560ae4f538c4"}, -{ "815500", "ac758032ea15073a6e7063dc49bac109b04e84245383dfe4a57d8a2d68e74c5c", "e8796fee578d7b8c3a1282cdd6106eb5be84df03f16f290b1042788e3cad77a0", "87f052cf5fdb1900a280431413ce9ec399d7709407e5e928ea757959afeeba70"}, -{ "816000", "4b0a8e17626d583d00af2d1e0d3d5aaa733b2637c0e7daecdc9ca7d32ef78b16", "5513bb0e272bc3c35af92c733ac8e3f54a4f9280dd6305eb3f521c0a798864d8", "f49d5ce010baa5a402628547ba02fc10645b15b1304cb1a975e850c18fdd5b34"}, -{ "816500", "7883f443a30cbe6777c45da4c70e650bdbdf7f2296d0eef9580b412d304dd1d0", "83b8b3ed3caa544c6827b267919896ad0df9b50b416b4092a81c4a16cac4a2e1", "ff6182b74bc884b1eaf924d2fbc00984d7a078108b8244b8bd65b2e2fbf61be1"}, -{ "817000", "d13df124f351e01764c49f28bd7bd9d94ec697abb36970435ede31462e245b78", "3668760c6bac61282ad6173be88f0ac74108aab7e6b2d5b89bb05be5f7450139", "9bac941af8695cff28fd06e3908c6cce4b0a8b83302dc1cf4a6c346523c7851d"}, -{ "817500", "cd9bec7288443f2289c3e350aa1e2f133d13377ef45051c8ef68f588f0ebfb9b", "a6dcda37fb4542b47d6358e6f4990494b3889031b7d57270d4581c3c5f5c834a", "884493c8c41b3841ea683fd22d126ea1bb45ed0d2e6fdf227938eb91d4a1885f"}, -{ "818000", "db2426a8e3f0260a1385c6514a424c1db30e077cd18f25affc301b857899672c", "1e887aa787c16fd0a14425d7699a20ce4a184468a4e8ddda982637cd60dd684e", "b02eea2ba1695f8d2d9846d2da47b93bc05df3551d9d209a2705d09bab4a26fc"}, -{ "818500", "475ceb331fef75bf43194e6ad78493ee5a3132b1366764166bea3f98214c5e02", "67e95130d865ef6b96c3c3594993525b0ed740d94de1322bdbdee1ca44c52be8", "0f8cd1408b9de9af632f1e58985e0326c300e0eed6df70ff99bb77bdb38b00e5"}, -{ "819000", "8bb061140f8217d2d20fc59542169fd7afa823a911f74040d58b3c86dd366481", "226b79c0b56a187130199fa71bb43f0c0c17986b38be4bc953aae9035b3b137f", "a2db1e16f286b3eeb7efc9e17fc7da990cd35d6d0db72b74794c89658346346f"}, -{ "819500", "9fa10df35922528bf712983310840e630f4293f91e9e81ea9a6f416107b4b385", "23400d8d0d4f2eca02b0a320b012d9c3874250e3703defd32a742ff3a14161f2", "32dd6310b486174a8f3985f5a58cff61919ceb6dc90dde2ee18a01d9435bcf2b"}, -{ "820000", "0b83d657248250c7e9d96015875066e2e5d59b7a0696af84d83b246abf9355ae", "c7575028b8e2df600f1ba0acc5a101952b47e9660a8a912940a2b548172a05f4", "d74ebff85dcacf707b41d180abce396954d0bcac13d87bdddff2611fda3c68a0"}, -{ "820500", "e0176c1631f2909dcccd2e56971085cc4a435398a3a967945666e2d7b3232d1b", "86cbb6afeb7fa1e6ac902b3d28f2aff25971d24b6cff228da7e4c8046b397ad6", "8363434e90dc1c20ee0f5f4b47fd7c0dea0400b93943a51aff7986e173ad861f"}, -{ "821000", "be0584aaa7571f33c631f75d7881d80e2a19f6eaddb91f311547687ab8b6127f", "f8edec8d65127f3eaefc274cfce29f29c4cd339739f2903ec60759367f283f67", "c755a875eb8b6449f2a210cefc2d896fd89a457894a070554e0067c239f0bacc"}, -{ "821500", "fd2e812d81cc2da106beaca8ac8e7ec4ef854416f30d7428c83dc72944e01ed4", "9bccbcaf94c587dafd152fa579fe7bc4e87734d1840e0f939f494d1d60dcd499", "f032fa6b906ab9fa959545de75e6838ab6a908e5913c8bcb5deaaedf7037e5bc"}, -{ "822000", "9054e0ed1b7621397499863a4dfee073b379cbab6d211118e0daba86ec09b239", "0f78238858465e4308062dd44ccca1a81e3b1aa830378d63ba37cf340272f04c", "e315de9a64da20253bed5b374086a7707d049f1e99fbab8e68f1b9d0cf55a648"}, -{ "822500", "c50dafdd9aa14cb0fb01b2d54da426cb862dffeb6369c1ff1f27b86bec6ea28e", "d7d020758a8d3fd93ce7a603dc710b085d16c3c232f389f2518b96b88d903a68", "c5caf8bed22e2c5211f32b833db8b51dbe0e54018c177c883d5cbb25e3ffba53"}, -{ "823000", "6631367fed6a7ca98d2ca58e0ccb8060e9e0309df1bbb5d76ea337c386f3066d", "4ef109d1b5fc3ec978f34d66b8d93cd3ba0b278d7ba9c6ddf4fc3d56039e0fec", "88fe2323f91fc57da58b494933952f12aa11b292953077ee9664b6aa32d7c3f0"}, -{ "823500", "b924862a40ef19454769b776643bafafdf407500c16dd73a70a61ff7d033519c", "dc8d2c04b3dc1785a7a76698674830e8aa8371dcb815083d849851ecb47f1805", "7232bae203573f6c6689058ddb2b4d2b06ac19ddba5caed5a07b08c3912d6ad8"}, -{ "824000", "d9ff8b7426f57da2db3d9f855572b493eba90e61b0ff3b40beec0b46578679cb", "95e502ccf5b34258f239d7a5aa86f16c643e189873979210e0cee9c5acda128d", "cd794aad8626da79dea81ee006ca4c52b94aee1f55ef2912cb2f4807c75a091d"}, -{ "824500", "b668014cbc4e38dbe8870d15c7ece604e8a698dead63136af5954cc403a13921", "d79c1357567cc361a4629f57d3bb01e99929680f5597fb20e976ed9da246d732", "b3a4d6a91d00cd7ecb1890525ca19214242805f0ddd04555b4899008c735337d"}, -{ "825000", "ab26157df7834e458aacbb394f8f6f34fd489cce3c7a1e6251289401acc59062", "73352b8b59b8fdbe1d83e82c2da9ed6282c5788802e2eaf3db7e7647e04d83c6", "219be8d78268674671c9953aff79dc2f3bfac601cd535dc6839ea7dd550b194a"}, -{ "825500", "4447fc4bfa77499510c1f033998de510174732f103eccea27ffe544577472f5b", "f15ba38703c021fa9419af02b8210ad9a9658b8866f70cfd734e282daf996169", "9d3ea35ecad6a8d38b11e387681a7b6f3ec972492c9914e5a75093bc32288bcf"}, -{ "826000", "8b30104ee7551d9d564a9142e2334aade0c93f1fe7846f2d2d21380096a5a1c0", "dafdfa617b0bb3f7980b4df7dd4d0159144b7973976db5e60a28308c0e9a2216", "ada7a2c9ec028cbe84830bbbd0e4b0d4b503bd78b0567dc69a6e74e91ce59ac4"}, -{ "826500", "0e2e09768e2c0cf1f39eaab0b5182b1616b40b9a6d931946bfae09c246bff35e", "417a26d05c6fe49e0800213efe648fc7fa29040f0f16b4e0f3814ac4087fba79", "e6ca3b27dcc0a8d4129a7d458543297a7d3ea8ac12594de75b945fa58210ab60"}, -{ "827000", "9539816f7acbfb9151d30dbd91509b104a83bc0564050ab5f3c3a180d1659bbd", "b8d3ddccffd24ee4f56c161acf6a739668f48a10fc703233bae30108e8b23f04", "46961bf809626452945dc9b458e398e7df465214a7638f9b4fcb5acd54371a3b"}, -{ "827500", "735c35ab86f85b3d7c430b126cda4a4c8e55479a414be9b344ef0749bb2381dd", "526c10694250f563eb1f7e7be275d89c14893a95118bb5caa0fa3757d2f1b08c", "63113fad7d2e86757c9a30c110290e27b0eb3a34ae94c3c19bc98c65dbc9fbf6"}, -{ "828000", "846213c0f91cc5f47286bda5e74a48dc86d91bed3d5549f2130211dff2210540", "195e0a72d1b5934d7b37d8678c6ee6da4713fcfad761e397921573f0c727dcae", "31feb7525f87c51d0efa33adc2c7846e4086f9a5fb0d8a49e90356e9b7104493"}, -{ "828500", "033da5a6c02d67fd91df3e6d357de891ba0a8352546be1e4c3c47d6d7a0b8916", "3d55e3405532f51149ebf67cc1367c225ffcbe2832a37814c37dbbb324fe8c6d", "de49ee4299d76badb800b1df4df0506a30022a79d5090130584c9d2e1d842537"}, -{ "829000", "b64d6b04a7eeb8513608c60f52b3a54a2758808beecc359cf23e5a1c9991e1eb", "ccd618e28a3217ca7d14e462c4d2df34473438c0e89e68a498b9d236507003bd", "2f667922d18d9fab532b941589fb89f5ecbe9d182edb79e09fade2d3eb4dcf9f"}, -{ "829500", "31cc80619db75aad85974e5c52755375dba0dc8ce67a17e6e6e4cb29f60dad24", "41145f9a5566c0d919937386229a00f302067d3d0dfdc369d866f164c4edce40", "4a6178bcfc9fb6e5c545de1980f1ef89dcd83c4676a4201fe92e5f797c35894b"}, -{ "830000", "ba6ae9853c6f5efc64e12f9982df9f199587f43ac41c49c56c52a217c42d31fa", "db3584bd7127b287f20a097fefea21aafe602b6d36287248e5b878d8f59a55c0", "77361e13d129c986a762f3d37e7d02b47c84fb06774199ea9bb2f2d059e537ff"}, -{ "830500", "881ba4b6afba166f55baadba4ff7b98076398db48b53f05058e4fcef5931803b", "f2d61ffdc8eb96d572eeb829ebe227489c2748aabb4e7ae8dd2d4ff04db6135a", "a727d25ce975a1c188e4e15c2a460023893f985bbd65b4a1b65e0da3840dced0"}, -{ "831000", "a49b5343b0e4fa384c6cdd8a9b79713ddefccf1cf1b9a9b8340a55ec56330684", "d5d6f8ddaa5631cc30932ced1cd5151825bedbff4f7c454fcbccc0dedd8822c4", "b401a21a7c7d52316b22552a82facaf78ad6204f97b6f53b0595ec94394b48a9"}, -{ "831500", "2325e3f54a404e7bc60ccd0acd9ea77d90a31b18f8368ba2797d9a2f7388b482", "09565fb72aad572d7b2fbbf1b0662da7687c7d98db22f55063d753d0e59a9663", "4d8438c7be30e5e62e2283d0594256eef9bc8d91fb71d44ff3f8a9e8249f4253"}, -{ "832000", "79353ddf61d1fd1c8930b19c8e2abf92382f86b7ec5d3de61a766952b465144d", "2cfcfc5a17e8042417128b3e60f6c2f4acb4f980508c3d172e0530ef1322f55e", "c10e27c97f5093fe783e94e9bcb09110d32e61701c35c010799876e5e612a79f"}, -{ "832500", "15c4c20b6d16377134e683d2eb7d561d4276a32d61f2179b1ec4f6461ec4954b", "8d2364c10cb39a2c74360fda5585ead678c0325656ee7e2803383cf5c9e94862", "6ddc31d223921892ca90b4a5eebacfd6ba6fb38d67e71fd4383846b7240fbd9a"}, -{ "833000", "771fb7f8e60a4065f3977ce3397d58a58102e11111312bb8d61399be0774809a", "bb06d1ca6e8e92d34fa9f31c9e3332ee8b3b31e0a4bc3a1deacc6a9e0a24079b", "94888abe56fe36b87c7952bd271966e42012a8cfd289bf8aee2c9ac3c7f58d60"}, -{ "833500", "b9d939f1ccd4ee8a2b769a4b014dd932f2d51d765eb4a4cb45844e726ba26f7e", "77a9c4bdc03d8413b3600eece8b0593804b58afc41204063c3ab92b4c70d2478", "623f0e27437ad34d1003504cfaa0aca7236fd53edcbd8edd8e2b9fe13d695858"}, -{ "834000", "c7bf6a274ef1f46d5faec1bb73cea0d5873fd15340b0ed103b0551213bd0b168", "89deddbe651ce60767e84fcaf8419a7146cd8128f439436cd9c5edeea0c0262b", "d183306424b5963fedd2f7ede8e4e39d68b1a092957e84f8b32341afa963f611"}, -{ "834500", "614d3beaadffc9dd3765a68108e9f2e01c33a9c440438163970be6883f71b68f", "b8cc0eca95d7f827ab45bcba1eb5640f883f803c6635d09eefae1ab30558872a", "79dcd4eecd52ba310114e3df54e355e44b7a8142d9c5e7c32322605094d98374"}, -{ "835000", "9a9f3c4367e50c24b3210a0650dbcab4ca0762018f41110fd7d45e70a0270e7e", "d827e1af0280be63e64f467a81e39404d3798234593ed89f03619354cd4dd7a5", "7f307a633d01ead46c855a3ff23037de616aec636a15a68b005db4017c33d3cf"}, -{ "835500", "cbbc70202da7cdb4cde6059eda7529609c9781e534661c44a1f61e5fab4de31f", "9640b254c6bf22f95f94b10ee1263d475d76ec7ffc8d8813c2a7f73a7ca77a28", "dc221fc429853e9b64beac869a705396dbd079a96505aaed00e8fb9737c861d3"}, -{ "836000", "63d55fcaa4b84b7278dc98564a5955756f3ecf915b231cd6f2399ec836537a34", "be4ab8603457a5c080f6d4f451702426b19f87ade3869565c41aa9aa1cdb6b16", "81751c92dfb6cdc8fcb076788e7e070e8fe3e8b1253c9adffc10591220caa988"}, -{ "836500", "a0a1ad507cecde4069df4dcd3ff6b0e44b917e732cded5fb86d50acbae0009eb", "09c9ddd16cdd8ee68faa85a59b8547b9d07b19ef08ad42fc9d98f9d85ae7f54a", "45869cc5a27d1e5a0a20e4bccfafdd547509b7006a3179083e6f4d9d4fb72137"}, -{ "837000", "4236b2466078279f38a8df0df56bbdf71da7a184f750d439aae1b7b9b6a0e217", "1b7b95d0f01cc0dda255ea389572d8d66be622054e9913e6471347d83070da7f", "393991d1568d9894d8fc66b4d9be11f0b213fd3ad618bf1b9e2ee7045aee3f0b"}, -{ "837500", "975034c8d678099a6afeff9e8e37d1ee524f64a851ce07def65676c0ee189b4b", "2dbd86bbab192ae7e44609388bd9036e20d6496962b2ced1b23eb764d4eeb3b4", "c9a9e2e0176e36cfe676ba951e29afe717f905cf2e1932f16044fcace1c580a6"}, -{ "838000", "05228288f4e87f9283efa2e6547316fb61f8a6c9a1c4b3dd1b919d02c4beff88", "8bb8421d901f05fcb5b476b8d5aa66f4c380fb7b00f65833f6b0bdd6ca93f62e", "155861e19f5454556292463548962fd95d701ff0dea9aa2506afd3658815bc16"}, -{ "838500", "f165d6b92e8b15b8a276e7aa3682e61c44e6729a39111e1883cc8bcc78cf9b30", "55e669d31736fed4be07280a142594c8f283e7a427f0630f9ee7f0b06411b948", "7508837234344d9bd77efb2a47a09a2d4bb841a2abad90d37bfef179e8ae5605"}, -{ "839000", "e7b73701d281fab70e7279cc3406b961db9c7d89643139882ccc269515bfb8ce", "44e7b9087a0f031995a963ba2c3d4d59a2856ddf3e822d0944fa472768990ddf", "991dc1f6c6e7905e56fe721e467392c0a227f108b003ade2e13875145cc5c99a"}, -{ "839500", "a0e9976acd9fc6b93cedeaac38938156409b74d9192f1eb4d614d4af4072d67d", "774aeb086be488987a9ff3d9d80fe11d7815c1061754431fe3ec2ff387a4e2bd", "a66402d20b190cf54e62c6bf3917bf66bffca9d599911d6ff6ea4ae619ddfb87"}, -{ "840000", "85f4bef924671af404c377269d655812da734608007a1e43c7e2c974ff1a7f26", "a7c27c2f0b37677d61314ca1a510aef72e2a7149c0dfb3e314c47ff151a7589f", "298d9f5856f8db53b74c14c701b7a0947ba6f92a6e3c809a9d722cc84d778c38"}, -{ "840500", "9a3f8a90c257352934919ba5678d710e02abeb3f8c9b609f00827147d2f7cf81", "c9234118875f5ff26dd4c37d0f498911d1caba96dee4d33a50c7ce378a9a0749", "4a21e3ff00fabeb73bb38c41c1e1b97d25d59aa61a1a3dc248538016a482052c"}, -{ "841000", "51b45385204a2bec9cfb32ccd8677bb9fce49c7c5fcb6a53c452e9b36cdb0bde", "07ed169f164ef448a9a828d17a6c3455f3a11dd6c2bda1eb38a5100b8817e04c", "c512255a21d35ac5102e25983c4756960a5f6afd0eb8d7672eb8ec8321f61d4f"}, -{ "841500", "92f53759b018613ada40999270e66657ae1026e4997862ed0d5e5560b917d6d2", "37b8239afbb1d59bb35fd5696404860f47dd31163981e62738867af4d1d13c85", "96805068c6193df48a0eee37b2e41bdd0a3c73c7002a2369636c46adf59acb8e"}, -{ "842000", "a1202ffaaa1bef1c9c95e11f9b2f1e1b03e69f535628130df12635ed9a3fc297", "ff3835e7e4cb8e4514adddc8fdcce0466170f3062e57d9abd9599da0fd0ae1dc", "c076ccb715442fe2b85dc94cb8ddb79fdacf597b37ddc0974fef209a475b9dca"}, -{ "842500", "fcaf836bba0923b8d887f619a0ecd298a94f04a1127f82773a531d8951326582", "7fd60c91ddf7611c5d0200f3f5adffda13a651c5bc71929b0724a3ef0c178463", "1be228c7e806ebb9f4357ee1690da16982a8853629d04962a97ffa08bbddd6fd"}, -{ "843000", "37827f08056c92edc0a941127d96f9f4f481d70cf2cb6c8c0212bbca042ea04d", "863b61ceff5d6d3314fb420c17bb16c00b220833a634f53d24f7fb6c9ec7f7eb", "3eb3471a68af99385a084fb558401e63c7a952432a6f61d2cbeba43a26c9ea2d"}, -{ "843500", "5dae3f790ecdfda5bd46aa1005cdf1170b25daa976dfe3f83f07cddd47747f86", "3d352565915c9634066580e57621f6682cc147cc92fa1e7f0112af699a2a09fe", "9d565afa1bf4f9747dffe38abc72517e189be7af526058405d9e9d6178a1143f"}, -{ "844000", "b3b067a2be410c5b04cbc3088bcff2678204f31c734440fa5ce28a43e61f6e20", "dd379efdd80ed38f855dc2fed11db6947ffecca2c6d78c3b13d9e42de618eb95", "7d01e39a64e1171e37a6affb926a6b6ba95e7f804955d81093191f7657e7e40b"}, -{ "844500", "d8ec90a7f602aa58fe31112ed0917f4597352ffbfb186524253bd4a88a283efe", "b8684b9b13ead86b6620d8c6cb1b4e3ae9891ad53c74a5ed93bb547b05d1a8df", "1deee7cde09be77c018bcd36d69dee4048b1cf551c42c7168a39e9abe55e1111"}, -{ "845000", "66ca29da4d604a893f7a56ebd96f365b3853ac2de6b38b71db898ed7226fb49c", "2a671d1a790cf390618793e3a9e2995de070c431014e9b1c88c9c587cc12708a", "134177e23c5e52aea8025b0ceefbff4b19361eb4849473c43fb843f1990814ca"}, -{ "845500", "b735fe850f31101901fe04a4207e15ccae72039895ae0f149593dee3e6cf8a47", "fde7269beb8e5c3ea60f2b30d1d43ed52319787b1d9363aa67c53e6beb187d6d", "fea541f995264a4123a2c94178a42c2804ce048e48364373b14872eb4ab89a74"}, -{ "846000", "b526a9a73f37f20c6ae046ec9b131f6354e90a4596cec60cce1414285c838df4", "fd42d265ac2d194a94732500fcdaa7f4f2e629793fb220a871459880c0cd000f", "bca8382ad9026274cc09e2f3d0e8c6fc2ee05aec78774aaed3ead6d88715a072"}, -{ "846500", "761bbfd7f554b81cd153149a73641b567685b60914402dba0ee171d8dd0237e1", "2d9ea683992b346008f860b330b15ba6ea707338daba431103b2a444542f9870", "6cf67a4ff5492aa8c4700e89f9df215d90cf9898565a5ef0de702c35bfb96595"}, -{ "847000", "375dd44f3bb80150df686ae8f3813999d60507c6e9ac4750686b5d182adcec3d", "e4ad131095150cdc0a23d0d7948bf3c870e01ed0b4a6f9950457ecfbb254b342", "bd3c6fdc759d432bad20314c703d555d9e56388c7c77277de4a8b2c40cf2f4f8"}, -{ "847500", "0539f76c06c311da93887c10f65904de31c72a00a2c0ee1bc66a46c50433c0b7", "2ce4000e6e36145f7c0711f53a8b20144a69599490a7da79726938926685c5dd", "1fa52cb8ef3c0fb707e5f3ebeeb99d8e25adedc2eeef565b82b109fa6cfe198f"}, -{ "848000", "c6e8ae1f92209bde14bb652bc8478d5592d0f6741c3d2f2f232c037494d81f70", "b7c0aedb71b645f0501319a9842e1fac4873184f50a0c5b758fd9f2cc2547a1e", "69295041487a60c8f00f631c3e56114c9b348f5dc7ee790fc819631e55fffa0d"}, -{ "848500", "d302c73e4d2ce3e318afb5cc773b089956501f00f64de08073bde92b2f3a99f3", "0a8901df9a3d00b66ed1bd0b117645237b61fd34c63fc45a0604daf2ac932bea", "4b93992d98ad1fd9b9557cdc1568803133e96fb9dd51878d5e6958a170a02867"}, -{ "849000", "0ad8844c1a45d6846464c00e9c6853719f80056b6f0fb70821536a133432ba1b", "6478dd9c136dd28bbc4a49eacb7909c179abfef94618dc6da67adb4ffe69c6dd", "bc7dcc71f8572ab902c0c42773f396d327657951178a1e3376556a12c8be2391"}, -{ "849500", "8ddd724ab7ab24e5ce2f5355c2c4bea780fe7a2b4a01fd04d6a0be5bbcf6059f", "54da6435a5de096881e00dc1907cb0b66274ab5b976fe6b67ccdb70761fdfd44", "f71d51e6094c79459ca8b568389c91d23560f0daf00a023a460315511c97b09a"}, -{ "850000", "b5e0c35c2d33ac37932b6d187a8839f1bf846817dbf5f4c58b73418e9a93941e", "e9f2c9230ca20ec14c17a35fa24d9eecf9119c5a38809c420ef099d9cd4ac61c", "58c376de138829f5c2cdc42a78ed1936686cbb0cebcaa4f0c2ae8bf8d9e6f4fc"}, -{ "850500", "7c1ea7bb106ee4a55d64930589f44b2e9fe63ab9846eb3caa545fd3b5597ac0b", "9b2b304003bc1746f27de0d9a7cadc9dca7d6c87b6cd5c88da09f45282298480", "4adb35a77d7e23f431c34032f15421dc3a75e86bb025ff7a470eeacc0feeaaa3"}, -{ "851000", "78c3131d573b6a70a648b111fa904b99707c622bc56f842297953968e50bb804", "9dcd68f3d2c985c324ae53f03582ffce484a70724e2c13602f84099737641cd8", "b7e3f52bca1ede78075f9934b0bc416ab5b99ebc2dc32ce3007f9857131a1bdc"}, -{ "851500", "e470491ea5d0631653c6200effed322f6696614bd98109f9f1c90c2cfc72f211", "5dfdf81aae36a8b8aada229a8ddfba138552fb9e101f4faa56bc76d3860e7738", "10d9d0567062f9ffa7f8d8293d719b47be1f49a174847de61f3796bd16b0fb58"}, -{ "852000", "528590bfc01e4b7f567aa786f0de29c2b7aeb8dc3042114b087f761a5e6b161c", "a96175b5107c4129f6512d54adc38ebe2f236ed6c3f362f885cd4a96c6651e0d", "83cdc7cb8e37b75127d148dc8092f8b6152102360a23721c3fe45315865e0227"}, -{ "852500", "a286a106373a8e32cbc0b3df7ac65b0720c04cae34a07cf070bbf652474d8c56", "205a7977e413da822705095027abd2edbe7c5e34c9afb7225721dd18b700454c", "822fde522643b4f3382d6fb35048125d73a72555d4275f9df3feaa09a17844a4"}, -{ "853000", "a2d7a0b916cf5aff1d6cd5150b034448c58dbd104c5f88e9b18a692d4a8e98e3", "d91fce318de2b273cbff6891c8ab29c769d7dd2f09b302937493a38488ce1446", "3ac1da42ee057e0a2d6712c7fb4aab7f35a64381133426ce3e0b7c72694171a0"}, -{ "853500", "794d93de5f3d5c39ad05ee77658de33f094880b037da8d2c124f4257f7360164", "3f94598f08e53b436df3517458172624b710f4f9c108c463a39b2b816e511a0b", "be9a507170b144c094e21997367d47daf719134fd5b6234c26dc978ce6332fcf"}, -{ "854000", "886b8b0cae2d1c914ab6748d636d5553dde505c655102ccb384a5c9a2b864516", "308dae1dc6e58335096c15c90fc276e9cfc6639289c25a9a748ebe226f37604d", "3e10bac885ae26b5dce2fd259a9fe6e9ac91cfa46c247c53274050428b72d668"}, -{ "854500", "78d0ac66bbe4ed7830eb9025fb934514035d9440e2dfa75d4046410185235755", "e2976153d1e9c4253528b84741fbf9d8bc73e85089d63a59b29d5c847e336c02", "18ef920835702377682de6772a5b57be2c8ed8ace449d334d05a30b6c1b34113"}, -{ "855000", "be6a06e20a33be8f7e0c96318ffc3ad202215dcc9124c06ec678a6a775c8f67c", "4ce675eafc85e0f8d54f8281fecef780e98677534b3dbc3b1e9e7f7a529aa3dc", "67b323bdea8d1b397006d4caab0c950deb258ba35738eea3a737eb114acebc63"}, -{ "855500", "ac409e08616a1e06ddc3e14a2b1f6bd947840932fc6e8b007246de280a6b66bc", "ebb67251598e38254f9327ff1dc2336da5269cfc209a5476260da523cdfee0ab", "712ae779bde3503952ef75ef1d4a580acc03e12af09a5250ca52322c94da1aff"}, -{ "856000", "62a624ad49bb1908d25d7190f363019b1cb5f1a1dfb849bb50226561b3c60218", "ba4fef7924ee2e26f271a49319726894894497685b1c81ea84e0bb62246c24c5", "42670350f297560ecef23e4c5bf42c3bb72378c57f46ce6a8817c065b2ebb7b7"}, -{ "856500", "f02dd187e61db50768a596177bf62878130d15910ced1f4bed2d5aaebcf4960e", "8e9e38e2a88d1a24151ea08cd82c2debc7034d5fa21e75f926d9a6c0df18d6ab", "1895c5403923890bed2d912fcf2b6b7cebf2e23ecb8cbee27a27fd918633138e"}, -{ "857000", "b2ea7f0e6a51ea74155d6964d732dcc4fc8a0b71c4e6837d1f17030d026da89c", "8ceccd983eb05888198163e6a0ea44261e44876289a9effdcf3d377ccf62ef67", "4d2efb8494121ef8f03f7fb1d43c56d67205715eb81f5424a52d07e0d6810b12"}, -{ "857500", "f99e644cfa949f806ea938b97d5232d9430ca11a51ecb0ed30ded90e6d4f120d", "fd26d9ef2f463304bb2839e8bdb3b5b0f48592e2cdfd043ad809292e22391623", "793a973ea0030005c216afb7c2b40fd42f6fc269de9ccde2f7cd578f4dd1c4df"}, -{ "858000", "9dfed199b5f19ad984111f21fdaad2d5d1779a317ba5982a93e14e37e21a2eb0", "3da6db23d0fbcdc02c440eb755828b4a5c02fe77c75b153055eb25362399216d", "8d6e1cef06e63fabe0db295579b2312868d74053e4197860ca17a57a28711de3"}, -{ "858500", "daf47ce2ce33b9db10011f6bd963bca3abe9b8b27e6101394d5516555e8e7bc2", "4fecbb4ea28d764bd3dfdcb6571a7c6400c76c1e7f21a1c1407d057fbc6feb62", "b8ef93c05f197b5e555999918188a148b5d2234b4560663895070dfddd73866a"}, -{ "859000", "f6cbc9c86ebcd2832f2d0db57e47b611d187189a37f33f7588c7c24e2f2174fe", "e85af2f0bf8bae60e417cc65de17bcdac486348b40eb55da41a51e98b5c148e9", "d8c4da4448c5bc5dee35365b15d3352e4a66820c2e676ebbaeefbb5aeb621603"}, -{ "859500", "11102fd852576a361c4c9a3050eb8d605f317f82ee78200d2a2820d8a3ff76ae", "e70ce2ca1c2e9b818d276254f46f0d6156003a8421ffa99fa8499a09a982e1dc", "a30631a2a3c6f5532794a4ef7104b9d087131eb039c83ae4eb24ffb2550f17a3"}, -{ "860000", "b0689ff799ad43c8123c38f815e8a5dfcb4fa2b2cc1d59dd08f6d6e6f260ccbe", "60815a438a372d41ec3439f8b21cd8cbea71b090758260b1920dfdba4558f235", "21801f9d92c87f0cdec4e499059b503970e4c47669d8c398ac549c4f8889ed3e"}, -{ "860500", "6298a42b99734a2702bcc358dcf100321fca31a1cc547ef0c168fa83a50eb132", "2881b992eca478a15c1d505d3b021e2f589d536832e98cbb90831b4d0daff767", "65794277c6392e331fa20b893332ac9d755d33ababcef60bf3e1b4d97654294d"}, -{ "861000", "9f8f6446a6df4ac6674a0639bc616fbf8955fbd7c5a6ae8743ae009340acc6cd", "b9c2b8a675ec2a9f1323f5391a81d5a2bcb83ff02fbfb94e1960eebb50033bfc", "fb2d4ff73be7986b8df82094c1e8ab7b52e1697d4e259bc2fac8b91c790b3272"}, -{ "861500", "c53640e61534d7de4001cc4f6547133d225ebaf607937c6ea99b3a92e0f1b445", "7befef633b3eb72ac1897e3628b20540cb0cb51bc447fd69877d178705b165b7", "44cc2aae200ec72ac2b1741928330621ece7a7a0c3b5aaf58da2830f552225ed"}, -{ "862000", "1bb40c878bbe264e2fad6a6e523345390091bef9bf689f6860bd30fbd27ccece", "66bf4703cd800c13edc3e67d0889df0c4694e2f6545c5f71bb0d43d80adaaaf3", "14612a0dd18d1a9ddb64a1d068fd9c8027fdc9f86b6870cf7c0972ebb8048e72"}, -{ "862500", "464bf61e9afcf7f9418661d069ebb015bed143a3c53449e9ca98013c624c0d01", "b858f8d0afefa1f199f3434b656587228c659429a9b29876139cbcde4a66d36a", "42e9d60328738e7dc1a7ec7eb51fcfdd37ac65c504319aef0011ed50cd8dafcf"}, -{ "863000", "0dee780a99a58bfd60c05f95db7ecf49c8ca8380b7a5b8ccb4c7c26229966441", "4555335383dd8dc416b36cfdd110d6da87faee63fd0461dbacdb6cf9dc61fd1e", "58a77e6126ee627594569bc946a69928b328440f27c717558c89f0b14d97c9d2"}, -{ "863500", "98a57cc44810adfffccb2f42f93455e1124e3297a8dd4e176b6367bcf864fa6c", "b16bc478ec16263bc8995541eeb0cfc6640074c65853989f7619f1094b48f17e", "2bb84dd8577f675c40d2f79fc20f4c854b67a3e5d7f4226dc80e5923e48ba22a"}, -{ "864000", "516c8212c055b610d7295dd1dd14e797a2b4ac025f1fd2aa7b3d26488f260a60", "e221eacebb459d180c743666d691c11997995f6f4d75dd21613b75eed2be2425", "28fca9cdbee34e8df75cbdc4f32f1a64a83042e01dcc24f547ec69fe18157184"}, -{ "864500", "2e8ffca67b4cf71272e42d524e1427b794a8e663b437c156cce8f9ad39d28b58", "7237d3868b25d2fb9801de887b7c2071cf24952719c6170a6e550773a61a2170", "fb67497e89323233970c4a98b94be927dde692d743cd0faa9d3134e551cb9047"}, -{ "865000", "995bc313381ad5d7799cccbcfbc18876582f5a82e25dc4a6bfd299facb83adba", "3ea758c944b2f0be32fa7fb541e18f683734df6197ba711285bedad4f17d1c8f", "9f8e354ed83d6c246d802b0ce027d31fa350fe285e736924058b5009f1259d53"}, -{ "865500", "dc2fb63083a52596b814426dc2577b6eca27f5e80b08b83776c93adb0b913324", "007ae746a4a5b901f91e51014eefab59c84dbec3a3e784711d1a16df0aa04ac5", "404254a5047229551d03464a1d5b86887e1c0a72de0e981d02865b83c5e9646b"}, -{ "866000", "a1a4a61f9e30b4ac585c2777dcb066e543a3ff03ddc20b67aadb9fe8842080b8", "953ff29441259817927e36e3a89db69fafe11d253509c36a2bd00805563ec4a5", "94aa4289d06e9f12e46423e7286d041a63cda7fbea30695a6d8d8624e277794c"}, -{ "866500", "44fff17033fa5e2f48afd1313484e62ecb1bfaeaa0b19b1973514abe18381d2a", "1bee0d01001a576776d0e6113954449de228bd3f69feea67a11769f2626176cb", "a53e44164326bad1e2bab2c9187473d43d8fc1fe9e44263fc19e2ec3a0066d2b"}, -{ "867000", "77d6f737b4c7b493657ef08c7f28b5dc43e3a7194b2e3193a37d1a931daca9a9", "a9f847fa150f5881ffade66584ad6b5a741f8dcf9310eb808181c9c3e4724a8b", "21232a978d4964960887fa86460c27ee153c25601fb63ee11502dd105da94c88"}, -{ "867500", "98da2413dbd1bf3e2d3d6254f849e3a971ff9579e78a4bb1ba192f61a1ca1bf7", "55a4bc913aa643d798a0d9d29b5c31bd38db0051ccedef30bf4bfb2ae6210159", "174d2ff6dbfc46694e7fc438a37fcfe18f98a2f946b9d2eaf337c77f1dd6a058"}, -{ "868000", "1e33271126faa909e8b77bfe4431587ac68d50716e3ddee70f18f4ba56509c98", "6b3ceb03adfc3ed05acb7ca6a2c9822e0b183c1359826f2714d26fedcc8b779a", "a79c5253e761b325c53e7383becf3000e36b15268ea637514b84037da39ac78f"}, -{ "868500", "b4bc5ab2d0f52588e8e154a831e92f9bb249bb30c4b6a4e379d529d9c916508f", "e1810b871f581727fa81164f7ba37242a0376aa7870f897547fa032efef248a1", "61da85844a76502eb61d1b647470c06e0a7d1a9005b95eadec03bd2d16aa4e1c"}, -{ "869000", "9db0fa91a26eb2c05272e50cfff46c7c9faa4d72938f14f03736c7084c4b2d20", "e80a050a8dfd6c5d2ecf765f43222b8aec1a85232641c32583487753ab3107ae", "d2dd26abe610889bd4d2ac990a3f97030fc4acb66f63ccb3f4733d545820f510"}, -{ "869500", "ca4ed5b1069fe42bcf42af8fb065aaa98db119b2e98c23c8ee9dc823c46a0bc1", "1f45046c69978e3a13a013d995a469a2a6583b18cabe3e48c5735a1bbe88f1f0", "6adcfb05cd935fef4d4a76a7e0b6a0eff99ae5071f610ef7ade477cefd2a48d9"}, -{ "870000", "02da00fc2fa6bfb0027e8c85a1b92e919495b84e763dd57afe758df11635956c", "8ff1ef73ea14756b421192b3f936ed06cc5a8f016c33a4bb8c3eb94a0a4afb6b", "b8a590ef2388d946e9d71c758838b56227a4abc719cedfa19edc8eed9f6571e6"}, -{ "870500", "04cc97d0004ba00a8211986f0fa13bad1cb0e7cd17e302242128ba5bc923bbeb", "d4dce041cd8b2c51cfb7a50864de5d72a627a93ea5f5cc4d837004e9fac80691", "35cc8956a844e114e3f3d133a48e322bf2f8eb5b5d7b1d2a0e0a430f46546e90"}, -{ "871000", "8c46f91d61fa06dc47ef2715dd66a510f1eb909b275c85c0f8f914e8ef0e2ce8", "a04657d974398377996f4584c23bf29a55085fd914b88fcc85bcfdee46c1f4cf", "91bc499bb802787f73201fd4b19428be38b9ee7cda22e9c3a1f2c637cc8784e0"}, -{ "871500", "285a13a25bf27fd974c9bd32ffda2796ba46e57044b4c282331cdf94ad55ce0a", "c701e8a240d4dce38b98c91b01c0b306ea6c8e72c345a2fcec704f4af6f880a9", "a58593d021c87cb3647bf70d501386a4af2b66812b8dd83c6c21cfedb42002e9"}, -{ "872000", "0f474790eec84e0216b27a41df528a1037767792657a3aa79122dc31caf1e1bb", "0774199988a33ae42d91de34cf2c1450aabd65b62e4792acdd67ee92c9d617fe", "25203763e4455c575a0871bf241d8b8d40fcb5ee4299262c68bc7bcaa36d3165"}, -{ "872500", "4192751ee0a2c7b7bebe5e6a7c60dfb98f1527eb6dab97071b5ea89fb851215c", "9e36875819fc969d8b5f971bce6d1610be7a012a520b317ce574c1e24f26c0dc", "f39c114d1ca78036f445336b7b671ec4c6dc52d4460b339bba60711c75bc3f25"}, -{ "873000", "34692e36b62fdc785dd9468d43a0a637aae66ea75c592d5c92e3b79245efe449", "e97152bec752a6cda91c4153cf191e6a04135a2d824a6ef8ce6d64f640a97fab", "0ca6b7dff238551d4fb8495eb9cc85c22be5098f65245cf2da2ddfd4d4731eff"}, -{ "873500", "af2ef369df933f912140c7a4ba01d3e33ae803b7b2f4939f8a98405fa4127b90", "3e30270cf39cf279ffcf99ad4b0cd55c85872bbf82654d03f6a9a40867ceaead", "ac2375ca321b3bf357d1bfcdb51faf0664c89660abb3bdfe5e63eef55c14202a"}, -{ "874000", "7f1cd90d997b5a1da4daac3691082770bc7bad48acca998746980f0b57ccf21c", "d7cba24bf85848378fbc0f655a1795b9baea22b97a29b3bb1b74fcbdc25baec1", "2e4b750cd6433607f340cb88227e3d9dea81ad791931f096c1f57a9ba4199adc"}, -{ "874500", "c15fe484c8c031d1327d24f1b563bae0c6ceb1f81b8c0b37c1a3a6d3ea9c12a4", "77f11329dff67de4d40f655a73c71a76e4637b274af5ecadd6f8f2ce7e265d7d", "246acefff1f0368ed146b59c7ae6e3c74ff4e2c0e99c996942fa9b109f5ca498"}, -{ "875000", "6d606825c8c4902999704cd9839f60f072743c33ef3cc8fe5b075e15ad6f521d", "0f98e7eb858a741ea9b7f9260142cd07d98f3ef2fd0f5897f0dd1196506f28af", "b1c7dd3bc7112815fd1d6f4c8762dbcab3e87cab642dda4c9447a037d7fadc53"}, -{ "875500", "8102b25248d5cc9fc5e8780fa7782a5f37113d5797ec544bcb6164d922d91ddc", "5331a1c3f2f1e95e9acc0acb83ef4cbe04785dc7a319ce069d252cccaaa748b8", "55555d9c896142ea08db6eb683d05328b1d060bbcb4dc5aec81965a740737360"}, -{ "876000", "2a6d640eb47cbc93033640e4eece162640b36cf256a1cafb406e2c22f0c10fb0", "34f34e19ede327aa5be14240436f18ead4abe6f226c1571429937380247402d4", "ff5805c276bef1199b7adfdc679d716f30cc2aa8dd02c51a9c914f28424d4e1f"}, -{ "876500", "61e5fae25c4f18e92e7adf64242dcbf6507a7ce4f1b0de6f2e614b8f1f5b33c9", "3f421f95de7e2129353ef06a9f9a206639e0f5be018937dd02e4c39907b75702", "0bfe75b21927d526919bbc82a7beb4f77b9d2fadbcb6c5cc4c7aaff6a8d185b8"}, -{ "877000", "46d077012ece5a31c29ba761425e6ef9d42501740db45016c8c5b7da1d216c7d", "d06c5c6aa3c05475f8a8649b9b6134e0c92301d47186f2c379e7b159bab2388b", "4e8df3fbe81f73207daa1c4676347683302341edce0f2f8a1b581b548b0a8183"}, -{ "877500", "610a50c20c1661286355fad8c8d067e794b5ed61c14087d04976cf0f378e37fe", "18141f4f7bed0308bddc68a7b897a035293fa9fdb074b6af3b271c2365a3d1a1", "937748d05622215c2ff5b9c77fea03222d4f84e20d3da7b207d9d592db6c76df"}, -{ "878000", "1742b73fe7c2d014484b21a1604b0a70dc7f12540d52b21ccfdc9f9ea72dc53a", "90831e43dd3912ceefc00d3d544c3f26dbf358ff3b5d24041ba1f322be13d9f2", "5e5d115c0010292669d3bf10702e7fa5942a6031319b29c886819d6edf89d56a"}, -{ "878500", "749fec5fbed9d5446533f22f0aa36c20b63b35116e6005ca519f7fe1ddc76b93", "a13ee98f76ebaece600b0723a6ae7f7ebcabbb86e6beb5c4b9e5cf3e8170dd76", "53c82882fac1f55d23a1cb58b7b975e28038ccc395fbef1c5bb2d540ab011157"}, -{ "879000", "8c578dac00d2b6db2e1972886194a4be70dddbceeb457150cf1b74ff19022532", "627f0854e663c40920d22d252b41ecb60a4bff1de055d1789727ff33eee14455", "798f54759dca2eacf858dc30221ee3dd23cd3afa0e10ddfbc85f808a50690f32"}, -{ "879500", "b31016513fc56e8df0eaa71197462492482734a9dacbb0d85838bf4253b70b30", "854e8e0aca0625eda1261e56697d87244c1e386be8d6aa78f15de8de50a76169", "9e39462f5b988c5cd96dec54db1283f98a0d46cf6c6ac25632309fc9bf32747a"}, -{ "880000", "e0764e8169753f7f532973ad4706e5f6a07e64b7ec10f64240c91f0d319f485c", "4e1ebede695c7ee95e4442814a5d98539df2ba46757b95d8ba4f0e0e437bb535", "65de64495fae8054b2af0ac5c24045fd567d2089526c93176bf4fe641884d9fb"}, -{ "880500", "b72623a454e91149046f522d60935871a1e5f098389d9cad4086119732b5e3f6", "580082c91f04822d21265dcbbf8c3d3a0866171acf5564e982c8386ae5a3a40d", "53038b71554abb4f5d16a454e1c6694f14de3166eca6ba6f61e5603c663760a8"}, -{ "881000", "b94687f79df272c2c5e85e21bff01136c5e99576571bbb8a635353aa9b331c81", "8f383eea1f9a3014c27cc3c0a6196b0764c269a1f2f3effd31f4f6b76d2a33a7", "c0efdd9fe63174d834d1c2a5a40967b61a2e38dee84ea431cf1a0fcfae782ba4"}, -{ "881500", "5ed1eceeaeebe16a0c746f796507f6b0dde6da8c53f4e3502cf5a49f4ecdff18", "901bbb467df17a499475e767cf7886763681deebd4bbb537a4bfc7f3dfb89774", "2b42e9be5adfc9057532a7ec0cadd242e49c8b225d85f41b62e0dae491d43960"}, -{ "882000", "bf12ffa015864c59f04c80d0141643c9de99f79b79c2b26ddf9bc398b9d8bf32", "2b7b77da53ad2a19f61e3aa54ab5833bef79cb88700e51189ce7b1ecf001a2bc", "4286a5d81097b7e676a6884e65333957554da50fb15d8e400aeb5c938af843af"}, -{ "882500", "c8e8deff1d81c65f2b607cde0312982b03523aa76c6562c666c1dddf223e7432", "ee0cfaf5a0a284a4e324c4725bc6ed5499cec94d170baff0b955ad6b2a2eb487", "6fd53db43f079bd26b9bfeedbb5687bad13ff05c05a38dbc1d1f8cea0d7bd37c"}, -{ "883000", "b12011d25c4c08da00b5acef266ab9e451d06c2fe9c65e4f149f7f0bc32b9c44", "9b06de94a84c8e550c49947303d058d4a93d898970d50b8be9cea965ca656575", "030c738f6a0dc2eae18976ff9c86d99d1e3ef4cdb492ad0b2183ffd8473dbece"}, -{ "883500", "77b6c306c2410ce6e03c825d016aafeeaea3daa7172111085ebcc5806dcd3bd9", "01d7719a498afa8051f872a3e8fc32cda3eba0e4151fc16722c0944d8715a6ee", "4a16d0e045c3df58b454e37a884ef89ce882c51c0ef3d3418ec42ed5350353b8"}, -{ "884000", "1fe3f4911ede2f37d7587640a80408092c044904f44900ce1bc41df2e0f887fa", "8e9b706cdcdc53e77915c281b532f0589c649a80fb563bcedfa8fea8493d4a67", "f2552453cdbd0281c8cfe49ce64155a6995f5d3421635e73f8cb82631e92af12"}, -{ "884500", "22d008aa6022144cf5b7070e91a056b437f105ee9ee3d343c2e1eb485afc55e5", "90404898817c93e64a98b4919df62ae8a21e4dcc9bff13fb563a33d544b9a09b", "fe71a783991a7aeaecfaf21841596e948752f868c6c9b8957e9bdded0229b95a"}, -{ "885000", "0d39372bb9bdadcd80ce022e52792bd5097a8235cc9a571cffa92805b0d875b5", "bdf6ea092c4bf488f836f3db4b29361eab0dd0323add526c9448b115f5e269ad", "d1adfdde0b4fa3c041dbbc9a11ffe1f2d6c3b130c6b956395b0c422de8d00bda"}, -{ "885500", "b6c7b44b85b84f3366c87bfa92a3a5d047fdf0fd265d5923726d1edbcd823a0c", "f6d9bbdc568fa107333196bed759d22eb22a2e101d3fe25cdbf88b74272b7d5c", "46e3ab90c37dcebcb162ae85a4d8333fa68f12ed87e6432a66017e149da25bb7"}, -{ "886000", "00109348c7d7187a543a4f45d72c842076614af9f5ee0fe37ffcba6510d429a9", "893946048c4c8954313bab4b7f2ebbbad527fe54993f9055243b83460cfd2fb0", "b2a6503a4c9ae11366d03878d5e8b95894c33ff03a8adf130b31030c188d9ec5"}, -{ "886500", "c50a72846bd8f0fa69fcae71eca2dae0aec9b2582896ff54dd2cc32f1c91519b", "61192422f9fe7ff5aa553363267310c447ead236e9c8798057c3b22f4e32ed8a", "847329db8444ea7159e364ca10364bb63ccf41ce6bf4362f4b7a05b51ecd5fbd"}, -{ "887000", "51902324fddad3458c70670d38df58410ce98950a70fcc4aba475fb2a4c10554", "b4c451e8d6f329db4a0d191970be6d74479b4df4615f1d576589a826cf025fda", "e83d6a0542db0eaf77408e75b749df59425e58f3a8604cf5c617e463319f247a"}, -{ "887500", "576f26ef969d63688e1ea000213b96aedbe715cf97031c64ad19c0e5a0f9332c", "c1ae2f4a3337bb92b30c745971a612af9e911d78bf9503f2d4173d32ea3e2a6f", "2952fe72cd55224af4aa3fec9384721c1014d006f324c559b12a81b51bd785fb"}, -{ "888000", "a67f9a20265eba880a4615aa5ed2e62c51dda0d707b65f45eee03b4fc44f0e1f", "87877dd3894621175bd850a8656bbb101ca98ddac12d54a86af38a08684fb31d", "f3a75bdef56bf863e6d727a4211dc6d5b58c9e4591ef246f29578cf56a236fe5"}, -{ "888500", "ffe36e4c302b226917ba2587b586115115ccb319b79626fb739ab1f4e511f048", "0a3fe9d179cd2bebaf9f4fe064c9c6addb877f12a05090709f2abdd570b36ddc", "0219907577c432170e08eeb909bdf1d39d0deed3f411840f007408549fdc09ed"}, -{ "889000", "3fae8f764be49d5fef337a07943d3419f749eab745c5349faa81aee4aea0a638", "14c98ca1a85488d6878125fa5085d35c8373a461ba7458e3b689a54a13153f84", "340fa29de6407586a958d38626af76b1cd4f00f2bf41099837fd1e8d3bd25809"}, -{ "889500", "49a7936fd2f10c0c1fe2dcd9b65a0938fd4ae50f7c4ac195c6084fa067f76919", "b971aed9ab7b39f4a9d42d50c714443e9be5172b9cdbb055245695c28266ad53", "c99cbf94433fd898d33815bd970d3b96ce1665eb4eacc9dcfd6050ce1d8bc8ec"}, -{ "890000", "761f8aad21a4501b257bc29b52ebff2e27f55b0a465fb5497587ad11212b98b6", "81e6670cbf8594d99c9d24120c2ca70574834637314f6ca75996fa13a2694810", "e0b7cd5afbc69a293c1c554f5f39c2a89f8302169553477476e6d46c2055c5fe"}, -{ "890500", "6f040c12fce7f3e45c6cf2305533ebc2e740c7ed5aa812201372447494772b19", "b79f97bf1e7764c569e5cdd10751ae56de90d41ee4324f9c4b51ee3603852364", "5a3507ecef5219bb37e23c36b581af016bdfae7d3392565f48747aca46deee37"}, -{ "891000", "945ad3b937d8e0e0c8ca33a5da647d1019b9c8e37e0ac4337b66fd3e3a3cd09e", "d02331f0631f106e84bdc9a77e5e4d4ff4f3456286b1eef2962dfcade867522c", "4f06e91bf73d2c1909e6204d14a96761e1f56b728824c7b1ef2cff95a95fdd1e"}, -{ "891500", "118403722d3ba35113e3d5406abc1daa269440550145bcbd0272a84e528da03b", "90f9f71ce4b26c8cce5558f04e9b842f539ef65f16bf55de4d7003d28b5f9c8d", "fda330db9176d659ff4e31d71a14d6feb0267dc30553e8d91b2b48d9dadcc45d"}, -{ "892000", "80769648898afb23defea7a20cf1241f584c76ee5637cfc7a49223cd53d5ad76", "ebdc74487afd6fd4c963f8120e760ee8b8f0f8534cbf85cc28ec67058c642fed", "4ee3c316f5c26a26a9ade27054c6fda8ebd758ea0909d18fee3f5073b20befbf"}, -{ "892500", "887d6de372d68314ba865a6a1bc5a431e2f8df673742bd2fb7e11b439117b0c4", "46a0ffffbd5887f14c94ac1c232f46304cdfd029f1871b1a30b704fd1378b949", "a7d421ab4cf79ddc2b33ebb0a569bca25d8cf0eaa7b390e6946ceb3a945facfa"}, -{ "893000", "8b0bacc43bfc87581959a67dabb72df9fe52ff891daeffbac58b0581403a46e5", "5c472f2d80c437716aee3cbc3439ce0b4e256363248a93b5d1adbee71d77690e", "6792f9bcae3ec53b7fed0d070ec6fadeddfb929eb4746f0b56c6eb5df9509d83"}, -{ "893500", "961d3fa31e522bbdf6cea3742ce5b8646b3fca603fd44daa57f5c10f830e4071", "49e19baf811717ab81e294b95c8eeeb5d96fdd1a4cb26fda305046aeb5041207", "0b7645e62baaf6467b665125ed34bf47a6877b6a1ea16dae2fdfe1f1e10e7003"}, -{ "894000", "cd17ae71de5a09dfa983f6dfcb13fcfa6d6f242080ecf3be722c72f6bd7d402b", "9a26285e49feb36f6ae744bf0e89cc91a3b871339cfe538b8beeaf5ebbf54fd6", "76f30d6a2811ceb8c7788e7bd3b375e86688d749c1229dd7e85e233e73534302"}, -{ "894500", "25fa66f74866b3b730f3fbb2a9f92d3c705354e71f2efb2747f8ffe1427f494e", "a37b7358d87c473235c3731bb985bc698bf95f6cff9a5d3e225e4d1ba1c668e5", "875d3c2e15ee2757c420b7d38e239c0c0a1113a7c94299cb08f4b44ce0e27ba5"}, -{ "895000", "50b47a9ba28ab1c5131ec35372be0690b9ff7c5967a81f7d6d7d5d7bab8c34e8", "c6d808c63cdcdc412b9318270655cb0d37c315957dff5039d0b018ede34113fb", "d789857674b0158469cce78c39349de4dc4ff43914a8833b690a1c326f44f72b"}, -{ "895500", "944784b12fdca39238803ecceb354bc4e8e5d91d4279ec25792820866d5c3e5d", "21129c892476213ae6df19646a942694518db3758cd2916e38b4afe436d0be2c", "9798a519310c9f896214a005d9a400e58a2c47b099428177d986440c7368b223"}, -{ "896000", "8b45a6293b573820f4b798c57a2144f7d94bd2edd02118d44cc0c59d4c92a5ab", "de0a319d296d3e88d7bcc46a4cfcf93ec469305122840f5512114776011cc03f", "92dcff354a50898f923f899fc1fd3f44ea41957679fadd7456075e25193ae39b"}, -{ "896500", "c3303636f08723508f17d63f0d376e9819e7c537d96e7ddf5bacc5cf02455287", "36654846452e690e6b833d5fc2d4b6d402c5fe81754332d35162ea65b1ead7c2", "e0798392bf6afce7c1ef3ec91cf696b570d12651d25c7c8185c5104760ae09a0"}, -{ "897000", "6cf1a830afc57e6d8549c8197e90839f477113278db181bba75a3ccb3cd0718c", "387883d5fdf2362515430c50fb20dbbb0ef24c387c3b6fd4f21be58102f4f20f", "c14e890bf64e617106ca77768787a7d29ef1d18e254b29217982d432452d569b"}, -{ "897500", "323544c069e43993ba59d272db7d92d8857855f67cecfb03afb9fc6495aaeb98", "b006d9690b7a362398d09b5d5066bd8086f36863295b5da7c2a113035852ab00", "cf5e1d997aa0c51ac80169bae457d5f49810f5d7b601599e2d1d682cc93823e9"}, -{ "898000", "e303ff088305156ddd6d2b5d0c239e459d5175585902840d3f6713a40b2490f0", "4504065e186d009dd784aee6d957fbe295c8eb1c3bca23d860a92c6be32a9e16", "0d624b8f5443456d6afa38e9d8f65b44e63bdde4857b2dd7d86a79657350ce62"}, -{ "898500", "4400aba3a75afc73ab3f6f8328a179905fbae533dc9a75a67e8533dc34da8281", "f78290551a6f5db3989f2c6f6087b5746c0419604cca77a8bcd63268455aff2a", "493c6c9538fdd84f4a7ccdec7da1656bf3397863b566af0d053cdea28ddf4429"}, -{ "899000", "30d2245ee16163dcab5b9b71fd37c6e0a1a5a3924f621dc4bf2213702878da82", "83f95bf132b64bfdc4bd75ca04fd972d5caff941d36a7792f55f478fe140972a", "828367c69dcbc2bc8db30bd6a79fed31d5b0f465c1597faa85b9fd0299a7253b"}, -{ "899500", "f35505a5677e09578cbfc9c7900bc40b1add13a8df9f70781a95b00ff972add6", "a71b0bb9f424c20a026bd94aad9922dbde345382c0751bb892ac7cc9cf0b9722", "d6831c7b98fe9fe24be7e4e5e01e511c9eaea623a3c9378acc6f424f4675ed31"}, -{ "900000", "e37b70b214a685698666a18c3de3362baf0bd158b6f972e77bd306e62e7e4bea", "7a6f099828ed54a20b3b9565c1548ce0fcfa4de8c6131ed4caaa629d96e17864", "5a5155ad28208bc00f7e8cc3e48057f389d7e52db71d4e98ed747b4a58838f81"}, -{ "900500", "a2473a95b679ead1011918bbc526ef833ee8b03a5aa3f3e11198e30d11d2efae", "9736c820b1d63362019d39a77218d604205e38ec79a117c117ad12d1dd1f0075", "eeffa6fee4c89d0b7bf4aa5816c8f2d5c4bae46c937fa58f1815c732aac2de4e"}, -{ "901000", "dda19f6a2f7a7da12753b2d7c334e3df7cfaf74a44ba8304b3c5f5e05882afc7", "bc0f02a893b0609aa80e08392cffd1ad14ee3b625837d16be6869b5e405139c2", "4c98b101813e05bc7c83bed737947884c949e7b299a03b9416e93491b2b988ca"}, -{ "901500", "5d1585d8239afd15b1028bf7deac725db26ee14e9f611aaa8f972b27c8f8dc6f", "6f02fa43604aed757759d0116918538b094641c0cb9f66d75ccf62458139c5d8", "5017c361f626993f0914476c5a4f192e258979cf96ece6e0386868c3bbc2b49d"}, -{ "902000", "433e97c928b52d4964e08193549e6ebe938a665a0fb4bbea22307bc94c5ebc73", "6cc41a90d5140aece6e637d823cca6e4bb96fc7317a4d603c72fabc7f6239cb6", "db578775bc1f54616499ac4e819baa4b40b4e657b5dc18a5b1e7ea6e1b1cf918"}, -{ "902500", "4650e5d627e8526ec617f4f8c5a31bfb8ce3c6bdb2d10cea58873bf361cad4ef", "06acce13e151648075467370e9bec6864b80189ae6efe4e0e94a395b4852fcc9", "09b574f8cf4cacd2f1fcf2ceed04417defac847baf5f2d899cc0af70cf99e44e"}, -{ "903000", "3f9bdecef49c48d9d259d75cc8d8de5a09baa6b51aed59ac4cb9661afd4ee856", "ecb871b85f6e41259176b80cdfdbbca72a0e5831c0ec4d42dd90cfa361f2ea32", "938cbf36ae75d4ec793c8de82183e3e2c531f28ccae06603932618fd3460cd01"}, -{ "903500", "38512db7f3d831faafa2e27c548d9f10e08176c8745fceeb56a59b4f1ec16179", "cfe52056c802d202a734e35fa3693c77a8ba3a8f0774b76b9b2e9d962687003e", "fef1cb9e1986f58d64b1ac150366784a970b91c84182a5a2c8abc26f11a240fb"}, -{ "904000", "56e1e664a1de1e2f3fa285ed05c87b89a1db02aad29d4aa425d4491d6b502bff", "ffce9af2a239a9b97ab7f571269255fbe6bed14ec448078aa1315b1d7d823467", "c7cc12aff57434310d7d9d93a4114775b738f01c97c2918ec204ad5283ede6ac"}, -{ "904500", "62ed0214dee8bd914f40e07f60d0b42c2838e060aaa771b39e3fad5db4aba3e6", "004bdff9bea3fb7de4ed18cb1a546bae626f03adeda035d47fc8c6c7d04fce21", "d94ddcb97d5652096975c7456f98a99f81c2d4a7924d5ddb2728576fe5317f0d"}, -{ "905000", "02c1fb3064dd2e906dea5b09a9e9515ffeaf4a8e6290d213adf0328aa310e023", "0e8364f05dc947ea27a36adb21a97604d9e2fac67508a098f1c147968b7f9341", "c6031e17677cb3cd881166acd24b301964ad7ac0c6744650e8abd7c11fdd2454"}, -{ "905500", "013be02154184cdeeaa19e1e3419d4dd5f63991ad93362a2b4fa2e49039e9beb", "a12d791cfad9e6e291441245832cc82f7887902d4112108b57ddf584ba71d122", "a88ee394bce510665579b886509ba86417e3d937285c2e4991e17f23a814194d"}, -{ "906000", "3b1787f731829c85e9888fb9bc683df92ca34b636a1aa2878106d04e4d1ff448", "bc52cd21978e040a67220c44f03933086337dfe37f69cc3ace07f5d8ab1b3474", "7026fa68a8cd65d8f0a228b08dc1f2b8305b6c45626452142ce724ac0b80603f"}, -{ "906500", "0be9d3396dc9be557baf880730a8c8c98f0d008ccad020b54ab2f4d3ac5b2bf2", "79047ea467c9ea723cf97796ad295841d72b866b1e9b925fe363f99071eb9ec7", "0c791ca86defbe69ba22fe652e8d99edc976fa89e9d816c33a2d5e6b68acce15"}, -{ "907000", "6e80e964c740b9b31d2ffb3939b60f86d019bee6af9c3714f3afb313f659e9da", "9fced4419a17762d628a0fb6efce506270556b2b041eac626ed03b923e68730f", "9620881fe0c84df16713e0e1605a1e25236c9fdbdef5789f17b67f69165e4a18"}, -{ "907500", "7f70ecb783d1d233ea3f331fc823479f0478d4ba40e0b3e25bb5149307e688e2", "06a68c9ca8e4e9803d7d91072c7b8008dd77da2df6f1a329f071ab497b16dcf7", "214ed849404ce6d70a5f2ec0160f64e2461235ae3839eec2d51e9175e09ba4f1"}, -{ "908000", "1bb873cd795e98cb9b30c692846a31531cc7f4ce5a474a50bed96e2061e65e17", "0b269ad251a90950543ba4657bd0044258f3bdcf6c50d4aac1c89d87499d1aca", "e1d891bb3a149411fa39a8075fd428e2e6dfd32ab888a949b0ab3e9405d881c1"}, -{ "908500", "c57c7855c97f82ce4645a2addcea5145c98d1cb9553d56ad8909d43a29bdf320", "b97be283db5a293ad45e219ce5d9c8287118d7daa887e25eca7914ecce5b5db4", "c38048c0bdff948f1b636c072fa4af4b83fecc54ea561ebc74d728b402f173f2"}, -{ "909000", "340e921bae13e9a770996bfdc6b30d21502a9dbd0016d2cf0a60d299e01b55c4", "50d0d76f836bf9a1f6c807cfc9512ce2621a7f8e8d3215310d78222eff1dcdcc", "af825593546ad267439a73e196ea826c12d3629235be6b1e3e0bf01a550e1a3b"}, -{ "909500", "bb00fca39de21c9b3eeaef52a0f3ed353e63f041c817977b6339f6fa1c127827", "69b6dbb417be0072ca4ceb44d11e61569bff4161834baaf439361c0b17eef028", "c7cfbe1ec7c40047bd9a460e7eef271a77c32860b97baec14cdf274d7f46682f"}, -{ "910000", "355ed393bdcd6c79964e984b96df10eac86ebbdd70652985e5652175230e3f24", "6be87fd1fb578588c43235926805d8740eaf1fa271ed3ef54e1b830a976b85ab", "52e0ad64384b4dd7be7dc9fcbf4c4c6999935f4fd6ce4f2bbe018567e5324c8a"}, -{ "910500", "cebecf803381bd5bcfe62dd27d0fc46b34ca7f14ebbc463ec770e6998a1b629e", "6dca0680947bdb1ba9f6f2ebffd1475d18874ccc79ec26b75134ece99dee8c04", "a441f43ce75437af4af9d797d3ea8f3262ee86c42eb2f9b6d35b8512aa6ac652"}, -{ "911000", "0fce8ead8161e060242c6f7a6003c4de749dbc1194d8efa84dd22daea8cceab6", "649a3e01e83b89631a710906ed025cc0f67e8ea52f11e0b51ab3f8422a14de46", "9edca6d164ac003f15ad325e06f42763d213bd339161d67cc7fa053d0eaf3903"}, -{ "911500", "6e60193890cf91c0dafce4c0756a47c2d57b70b84723bed083cd3af287d82435", "b12f27c0626739460618af055b57710d241bf473d10c209edf8b10300d64a119", "49014d1f75815a2ead4ad7dcf46f86fa7b9434c22425b7d7ca99aa970f273328"}, -{ "912000", "c612c0ef542a4a95bc1f45d8b5992c5bbd499a0204d057fc5c3b8c6052b0bb48", "ef4f90f0e2c4a627416f8c7b590c79a4d030ce3b6ef7040fa8dfe20d9b1341cc", "5d9b94ec08ef46ab128a48ed2e40030a7fdf49722226c0274def2c0bc1f63334"}, -{ "912500", "4e8c07cc191bdca3f15f8e5e8fa2a0ccba376f23dc9618991f9fccaad35b1694", "6d2cf50ef5fb9c21ed59b5669566dc625e1a023ad3aefb75351c4e96a2df4222", "6af009dd536d8612079da2da7b7971c1faf48f858b860d1a90f3925b8daf033c"}, -{ "913000", "fc9fafc9d5208d6507d92462be6ffc8b3acebc7d3acba2bdb5f5b1afae779ab8", "bc2b997013ceeba576521c5a2dbaaf429b9d6eea2501947de4c696c2fc8083fb", "72a6ca802a448ab77bad7c28b3cea2ce9b8363fc7c978e2fad61345a686ad16e"}, -{ "913500", "928d12b4332252e7216fbb36d4384eba4ffd8bb79a50667b3fc15878c7deec76", "49d8085c3c7a8477fcdb80af39c1abdb69f5a0366e0dac79bfd30439b2f293e7", "805ee656d505d42bce2998fa67246169c9ec1f16e745490f1db09c54b1c281e3"}, -{ "914000", "7bf600d26589f7dc4cf0c68a9fd820b4709e95c864c379b4e5175b23d518091e", "6e60fe7892f34d0eb38229ada52332a8d1f0d120de231e404ef18f319adf5715", "ff1d407a33016b5ab38fabbb6ba22879805377114ec6adb19613274459e156b4"}, -{ "914500", "8e5cf10113f76678cb5265e293bd0365012f0ae661e58e6998005c96f1ac9869", "5df5fd9760d67bdf9708867bd15b11fe60230e125abf2db4500fd7db945fa6bd", "a933bfe1c6fdbc8d339369b5277743e85487d751d3dcea4c2add3e7cd1c78d08"}, -{ "915000", "33ddfa347fc55f5b299363d8b6bff03dc1d98ec1041236e66babf4023d3d52e7", "8a85853ae490805462a8aa3700c84a276cac17603b3dd0002c54490842cebee3", "cc0b6ba00675ca7088c7c4299286af7e1cb4ef0a98622e8109fc55cfc7bd2dc7"}, -{ "915500", "afba8520a990af275a8d1f82de844c793547432b5c6941e1b30859513098758f", "06ceaf9f70d81c901054cd961ddb15b5399fc0f19235c048649ff24bf916f552", "2f7ef80ddb64ee43f85492f1760fe53fa72ae703a1561e4d06aa1fbb3e36953f"}, -{ "916000", "fa8e0f7e4c73fa9914b795af620ee52434bf37fdaffba88d318af058830dd361", "41ec81c005795442c4705e943715065eb89cb4b32a2f38a311cf643b06880d79", "6d4b4d0f5a8c1a70bdac3261724846e02fb94bc538276f7f17bbd9bbd0914ee4"}, -{ "916500", "2b20f9d73d4c0af59212b3bf8383f845c95baabc51df6db044ba80fd5051eda1", "324489489a55e3767836aac9d5b620f5be775806ada19f27a61671a94098f269", "b87648e56fe39ca53538ec9c51d0ae98bdd38dea3049b54f0919568ebc5426e9"}, -{ "917000", "b7b20466d119311d1c85ebe1ef60dca612ee14b87e88d633fecc679d00b959a2", "96843566d7519919c12ee3cde2b4793e7043a066f63f3dfd690638d3b3d2bf5f", "128994409844e5ed3e8d4c53cf3f2a0f7ba386a88cbd21bcd2798642da105d2f"}, -{ "917500", "624ee2db152989d3e86cd4bdd32e84cde6f8d0fbc556561bc690c8d64d95319a", "d043c5740ca03cf42a53e4f8abcc96dea665a16acb738dacf29cccd3721a9081", "b53cf73a34e412370b6c793e3acdbb2ad92cd6ce6d6cf91d66a5e569b095b677"}, -{ "918000", "eab30c35d483b6b8d4ac7db12c139b294c9b9aec8d4c0db627f57586b3d1f6a8", "121c7b5a220fbcba9735c6ce0425ec14d9d80f75bb498a986684c446ce8ea2c6", "ec65f599ff6d9665845871374ec58197d0e6c0d7fb2afea19d7eb81c4bcb2651"}, -{ "918500", "e9bfefe8932f66486d1d3a740d14b1fbab1fbf80b5abc9abb4af1333efada148", "3909b21ceddd287e2b1d8cf16accff743dbfe6c2c0a0080a33592036cae626ca", "17df39dc7da315f869c7c7a1a6cf1a4abc14dc56b4200c3029e977ec7f1759df"}, -{ "919000", "4111e02c00666bb2701731d59808917da660228f50fad0d338d31324219fcd2c", "faa3d00c409b5cd2cac4bff556bc5d07fe901df0b3e6f1e1059e661f59dca640", "f098984bbe4e46aaa2fb1830f5d28fb920997095d0de60b0c44f839f60d035c4"}, -{ "919500", "fe8ceefd0657909d523c68ab34109db47c31a56d96190f25eec23ccac28356ac", "dff9eadfdd7da200e3f9ee425b46e6f1869c2947d77eb068d3de8e281ccc9f33", "90889e7baa5d936dff61a5953c5576e2877455f1f0d92bdf5d17084260d122a5"}, -{ "920000", "94c0c84e0720cf98585709161f8e0d52106a76810c36e8eceaa50c5937423e31", "985aeea9e4d2fa5b24727c5bab4979f7c181d52e1939f5c1e9b9fd9d8d21ffa5", "619a77f293cf5bcfe5b8e55422c347b1fe595d6a8b9380ecf51ffbcbc776f899"}, -{ "920500", "7942c1928c1c7fdce2a7f9948db255a58ac28c650d44f2cbb568b14b7e77a869", "3fac2092a646a391bcf3f5a3703341b9667c9dd1800148346bf3d0ac8eb0b8f8", "4274a21857221b986a03ab73c4106111e6c28de8d871ef01d78de3b3f2c8bd4d"}, -{ "921000", "3ad13dc5aa84d6f0c89d4c1d4424928e1c3f17def687432e3dc5bc0d1f748e4d", "fc66d327154d4f892c6fc8a1a766917e137dd5ac1de66a8e93a1e3206318133f", "4568c9acce0621cf48b4c9257deba3b99e91d3a271645605c2a35e654b73d3ee"}, -{ "921500", "fe4b447119ad825c1f495dbb58a1aa394eeb40e6fa1de1ddf72886ea69042eee", "aae2951a99bc6f730c70d78dbb6486d95d432b7fb154696f0e866b5e661baca6", "d546355aab871ec43391d1028847b386e92e2f80de62cd9140b01643738c74bc"}, -{ "922000", "7d1d205b9c72f860b446b8b254d1c22a8e5a5049227ceff04424ff01761cc29a", "9fca8ce08cf17dda9b4a2695096a50f5cbd54c8c11f7c048bad4e27c01a7dc9a", "511a897002b03614f4138dd5c05605da5e8d82a1da39d01b1d58433eb69421d0"}, -{ "922500", "c16ad392838d47ba7fcef91e9a0be7cfa1dd11d22c9ccc0b6f631aa48abc73f8", "01ccf18791d85e7a78fdc9e751948c42a6d58d9c4fefc118cf882c0a5bef2ac5", "a28930ef1b65db143de30c76efb40ac8dba61cbe0030eab5370d3e417263f61a"}, -{ "923000", "438bd2d6867e38f68f61f9dc64952993f7492e39771516520eedd7d5d9d4054f", "40b95ef95e78ae4c9e99865bd4e7a4f7d106c8d2aba90f54aed550f14aa9ce17", "ca62e3ac3b194977d03c66b015c7975457db5f6c849f7b999dca95161d06064e"}, -{ "923500", "6c205a2902c4c350df7de4e96c6815eda103645b9181fd9e8bbd6e53b5ed843f", "9d8c87504c9db8490188c7d8fb0e6aa1950a03a80cd2bd0f8baf0297a73ceb27", "c3cdf41378c92bd85ca01c42ff115906b51ace69f122d3b1b6b4a5f922d92098"}, -{ "924000", "821de00a7dd17becc9dc0ff750b9e74237ec391e9e2effbabb71d33fe96e574b", "c87cec5b256635170e6428e3040000d705decb654b84a7ac9d1566211e18dd36", "81890bcab453994fcd82bbe934219d642b127460aff6fd52a37c957bae1f0ca4"}, -{ "924500", "fc66fbb75f4f01611cc4bc86249e329e5f217ec40e0f64f332ef508f4d524fa4", "13e45c01e9098567eead7d1e2840a44cde36926ba83c270e6bb854ff079fe864", "af0db78afb9fd983d191c7482aef99fd8fc3f83ddc7bf969250a88db0cfe3e8b"}, -{ "925000", "b290fffcf3f8eb763704f79a4a6e5fd76a853a3cd013efe2e41fafb9177d223a", "3d9b89cc34b988fb0d1df0135f59df3495da0221277ed3abefed3558408ee132", "ba6e53516126dd7d723c11edf28c7f60eea4c250f4d9183b09cdcb74df0496d5"}, -{ "925500", "3a1fb804b8f62e4c394b4fb34b250986d195b4a066238eec560443219bb06a25", "3024ae8c2825c85dfe675f2b66b4576a6ebb934166dda6a12016fa8f79f12a63", "4d687963ecedcad164e63649974289bbf8f463acd84b790b1aa611ce7fbfe681"}, -{ "926000", "819094082ab3ba4c3a715880ca1de8c9b7036d68224202838a077d1c48a0fa33", "afb6ae704efec0cb30127cdc4c608245d88b3bd39e3f09b30273420046051679", "471b7d7e14436515e046998af8ac65f3e9ed8339f31e292c2c1f793eee400ae3"}, -{ "926500", "eb74c0dd62c2e8fc7e9c45545e190d959a6ca29515bc7775cf20f2bce27349f1", "13849b250174a3db106e2184f7621ea88b2e6b6fa4d36ebb2353cd7fcd0d4a12", "1303beca265306318f19a0a0aecbfd784a5304ff9a7537051d14f78c1be44815"}, -{ "927000", "6397314f6bdd9ef003cc2ba39a4539c1e2267b13272c78b886127419a1edcd28", "3455accc7f9a3e2324080e7691ba7134f8a6a3d6b0f59ac8ab1f8de3b1db976c", "4875a59e95790da4881487d2e8f881cfb6370ea23609e157a3d3b67ec84ae8da"}, -{ "927500", "5f1f6df5959482ae36d755bb88a5b2788a0f6e8ce6e2d62811da77c02324703f", "044a874fd1df9bc0e384a192c669fcacc6946d2ed148bd5b3cae0eea0ecaf625", "2fa5e7eb72e545b0de5970ea40f9a13a9df27a3442d71da9a75aec0d47c10160"}, -{ "928000", "3ee8e52f1ecd00dfa60cf89435c08ffbbfbd1e0f9596541cbcbef38c520cd71e", "af25521212acea8f5c894fb0e2c0f38a4abee868b66ed124a77980e5ae7fd840", "a839361ff828bc1035236d946e156b9f683598a5d432024ffcc81b4e53939df9"}, -{ "928500", "c3f4c0ddbf8dc7a91e5e27e3bd4d8f817d18ce724d9756354449d7894f96cb7f", "d7cd61faaf6d8e0b362aaef72304bf0d1d8d751b1fdb6e8c11482fa5b14c2045", "5e37546783cc6392c5658a293acb1e30132ab4c77ea58d328c00a9cd663381b1"}, -{ "929000", "73c7f82ac5c353490479945a8e5a3528e85ba4276e3c7b5b359ed66f34006d68", "9def4754e80ad70729276465a92e65e9d70a3fec02ce46d76a6b748bbf19180f", "5aac3534692f0996f5383d9cb8de32dcf0226b872a9b1005b855f7eb86693b81"}, -{ "929500", "90838c6bda7f6f4a9964c3b99caff44d656fde4928d526d7b761aade9f6c5a4d", "43be3d47189799a47edbe664a2e9452e57e7ecf8f5df272a5090552cce912ac5", "51a31579edf889149fd632d32a9e8f155fc2a73aed2d375f0069e9f131f42afa"}, -{ "930000", "993167ee131ed2e0875b7a764cb7e8651a01b44b85b4b40c16cf8b69f0754029", "5183e99bf7bc05a09fd514bcd646aa16fd040d8313d5c2083291d350988e99e7", "c53da68fc001a0f18d5850b88a9884e899cc09745a8fd5001610458b553ff45c"}, -{ "930500", "53525fdf3fee3ea4bd860ca7185365312b74dd8cc1e3f6397f3a467f2fd659f5", "b08fdc19e65d7ba7a01ae37de9db8065c344f602cd6811a6b0fa7efc22cc9ef5", "8478d3baf29d721b940b68501c85e0d81d566f89e56dc19188e44be9d3765f04"}, -{ "931000", "310257cecaa31778dc0ad056b4d0ba181b0339630bd9a54f1d2c01241546b648", "e84fb5af344ef95707e5060d1675d11e8b7373524227fbcdfd3a7790530b9eba", "adb90dc53ff35e4efcc94cf3e4872059e549ee9e0062ab9d12a7fb3fd3b04b4c"}, -{ "931500", "8f92f22fd3d4d35cd69456574605c6463abf15a58bafd4fb2144e58b2ae60bbc", "a05d6abd0dde92b9e65dfc93c149ca2f6ace7416efb996cbe4a1eb31d4add968", "b04d9131cc6c34eb0c55d962434e2a32c9352d4767f4305f5a4ee212b7682a3b"}, -{ "932000", "975a067e94d2f89f81945c70161dad251c93387934c9869007bf17f9f8175f66", "38b53fea2e9bf87fa3f0478da19edae0de9444e35605e064e864f441c6531ec1", "d4906ec70a0e2883a1c10ba3dd6d14b9b01bc52df11620685df1c7e2f7b1f515"}, -{ "932500", "438ce459632f23fc45667091be8a8a4247f6f83500e46805a7a63c72fd674b22", "aa7fc841988e91577fef8ed0b8b134e9261d1f8afadd12aac3fe7a39129cc393", "1cb0e73b74af2b1db898afe065e49022ccaaa178609aeec1251189133fd48ab1"}, -{ "933000", "07ece8e5df3457f385595c03d9abbf7b42654e15548ee72fa01b7c98d87fd654", "de3e7b6128fe92260b645119d9aef6a57361cc46ae6328c4752cf0feffa7e93a", "d6d5794e9583f01149951f860cf2fcdb80a563e78162acac5282a17b1af23095"}, -{ "933500", "bdbeb91240264a917bf44b878b92c09c6a15005a39d51bd7cc4d6d401e1e4319", "ae3181503323e70a8fd2a11ebc82decaaebe409793fdf43f8fce394b17dad188", "f8c6efd1358c3135e3d409b5801c521bb0d198ad7b2b3845bf703668fa08c2e9"}, -{ "934000", "f3bd01e5acae46dbfb3365f3432ec1c81a2cfdff7cc6affae91c109ef698615e", "74af995d48d047894f0d544423ba75d2018f04d928c6e7e468115bc9d447317b", "0a25e2580c6d19575df1b34a8a9d053a69cbd3ca7e47ee9dd5344cfafba900a7"}, -{ "934500", "d1518129840b5977d13fd42440c257445bb31944c177691c8204c6babbd58f46", "c270324df573701c0b3e41267557932eb7fd68e46d96f84e1e302b6e336207f2", "be679e077ec214a331e206447b59d5401fdc422e20362aaa83cd23ef1cdadb6c"}, -{ "935000", "00f16b56da0b5e21f74c506d5d2a1d7a10f4403e6feda3b75b269b93a7b8751a", "85b16fbf368e56074baa64cfe454fcd4d387dd2a3e4e8dfee7de5d65ea7a423c", "5b3050f09ad3ca761f65bd80fabee09db49f2f20a99c8f22d3b5c95dd7462296"}, -{ "935500", "bca2a40ec3e783714d2dea107f8a35cd01ac37f845d78181e79e88d3770b9192", "99a2c6c0e33f5dc75a98b39100a26426408944d396bdfa5302fa0aa8df340f2f", "ea65eaa05964c10969456e95d66d54e70f51904671eef31309dcf1659173a7b7"}, -{ "936000", "03e8bf996ca3565405d01cfacc215f59481b90ed44d2b8329379fce0967290c5", "7c6c2acfeb309f1fc6132fe8a812310aef3840b6af2cc1928394be16105e253a", "0e80f01c0ef1549e7ea13ad275af2cb0353e5415e44a5085d72c9a3e171b3319"}, -{ "936500", "36b9b71a5a9d854eb5456a8df936d8995f40520173c81befa852db9773a1d26b", "53733cbe7fd5a371c8508291f8d2ed3720b87838f3f15d3db8c16656f722b5d1", "8465a44a4efe2c42bb8efbae4cbe46d5819094f9096cc3bef9727e9a9056438f"}, -{ "937000", "665e5bb5ece8d808b906d0476716f2fffff168696bfeca1b5483c7345f029a7c", "801b0c3ff2814d875ba2f1be4f26abb060fea42ca9190a45275d13523103d015", "4eec03fc9f6315c94faf8e81ccbe7e9b840e42d991cd9ce72d1f880c5216a095"}, -{ "937500", "89c15cc1d22a312379aad5255d2c965ce9d466a9a308052fdace9d955878b03f", "e1b6c64abf2b80105d8c292532489650af97b6de6b6362ca8d5a090e3fb6e930", "b729dcdaa9799ad26958f0407c569a6ce6b6272b1c14bbc808b4a90e2250aa70"}, -{ "938000", "69263892b7a2117af68e35c3e6f5ac6de567bb84d10d86ef9492eb31cdb78e36", "1db7af4a0cf53f0686e7ad7dcc15076154d06e9fd8ca256fef101fd82a76adda", "1b744b3a013f3f3af72b65eddb918a11cc791b26fd4304e2c35b1696c7d70660"}, -{ "938500", "031638da90c052d869dc3da33fc044507e0831219ae121e416c10cd8ff5c25fe", "2e94ef6c5ac4720c93b9389a66cf999f22145751f58cf13bdaace6d5b1735344", "62380acade3dcb89b6cc458982cb9c760fc3be1455f7f8f1c5b8281067488968"}, -{ "939000", "342f820c0656c6e11de2032ca29247575c0121d8414c63e703c486a5662fcc00", "e23bfa4425b2d940da54a62f26883b429558dbae605a1a762be33a5aa18b63fd", "17f7d790a20ae0a292ed62f76f2ac831088effc15ee2047156658e51b779bf58"}, -{ "939500", "250cd72bd19b23ca51479cea2a7a9f4bfec67e343e250cd67b6727baee2d8520", "b2514af432838f255641352ff93268b990c0346997e2c11e93987dbffbf50344", "d59f0df3ee98c60d54360adf42c98dff754cfafd18d21b93ab45b120edd8a914"}, -{ "940000", "1fe1cf60f5e02ab75067eae08e3f8c71e4cff03d232bf2f2c6f789ef49dd134c", "c4b2e8af2ad3c324a01c586f22be66a30dce34d76e05c9c8296b6391cc143e44", "5c5379961483368837d22746583f5dcf50022019c71fa3f948429da2a4892f7f"}, -{ "940500", "37fd0de5d9900234dafcd91f2800fedc4bdd5f5f77c6091c5007ea3f5091e834", "257db0f9e944de6816c015102334c79e531decc0e89396c49ab043143d557ae7", "b752eabdea95cc3534b2f6140ede29ae47192a7003c09537329346847ca434ac"}, -{ "941000", "6751331b479dab2a45ccab32a8df6c5667df8717d99bce3eda9099d5a93976c3", "8d3c34ea9311963d4aa20cf0c35c17d5556c926589354d474ae4f89fc7610ce3", "9e17d95145857f43e5cbaa9dba6394406a1315a9823688bc1a3f75398962b600"}, -{ "941500", "e20ebc38059a946e50e5779e069d3598de8677e2974efac3aae5189904ec9b2c", "7d08a1657f10154b398f06cfba601c5b8cf68d0a70afb8b1905ea8b9e449ae43", "f808b65efeb9d8b9cf630fedebb42bab2965bd29f45772423d1dfc405e29f7ec"}, -{ "942000", "08b423776e24127b4db2d00a86ef3d23defa5a94ee9e8a8d04723a0061c80d09", "94e541a46a6d4c989c209f262c0c563bec8a6cafa3bf7a61e1bf73008a3ccf90", "49d866b9bf0ea648408347f88a07486802c1dfdbcb7c4b35165fb57de6f422c8"}, -{ "942500", "e99b00e621c453bc93e1238a8de8af078b2cb639f185a7061fe7b1d97c66b6b4", "0fcee30b06113c4d3b1f019e57cc19c5f448efa689f5a95f041a715c115deea1", "53a1e6bbf4b763b3730c7fc78a48efe5c79f6756157b2bedd17ab55324c1284f"}, -{ "943000", "dabc19a6f8952c1f8c2b4a6ee8540d91c59b54a953ab93071f026150cca356fb", "66da69070bf359d355715c3f66470c0711470eadaf3ceb1ac80648beb4265b5e", "f0d29101757acc0dd73a2270f7ef6068f011d25407d85da1d25034aed0fdd069"}, -{ "943500", "efa86ec88589aa9853bbf58b7a66708f52d72b32a43901253b48ef89fdc68195", "da99ff838ba09c7843aa05dd869311fc058e9a266ab3cb560e4c4ebad30bd6b7", "df2324edb9840ff91b45d2cd4769a4b57f5e4a9a1fcdda6f5a603d94f325bafc"}, -{ "944000", "2f594ae136ca24d6d073e29d4a7278134ae0fdb782e823c2fe6efa9ba8c053dc", "d285a29599828a65ddaad8acd888a3030133f8583f5618af616c3637c3778861", "3080c758a77224e44ba67c0667b77fa366310542f5b851c04b994c391634ab68"}, -{ "944500", "c3ba87169f55a8669f3f2c7e94df26be0afb0e810104dfb2fcabfe40847eb644", "e028eac5db8fb1a565277f5587d8ff105a3f4523946a20a3cbdb16e7eebaf586", "87c283fdcb34a2cbee915f730f72e3368b4cb47f6abe44ebc6fec8caaab96d74"}, -{ "945000", "5aabdf7dbbf96f3b9136f7891335b4b4d2ded4a4ef4b15aae24400ce7eede6d5", "a791d33db0c6c72fe407c3141d954c7b6166964cadecc7fc7d9d70a05c64f5d1", "b532999fd01a92636e0004fb99621a13161d561a7a3525c6b24919008b50d00d"}, -{ "945500", "160513624bd360141f9f2aa0b77e15f2f78adffde5408688a3f5cf2748f5a33e", "1978fbf063588d8d5c669261b70e569bb5242c67ea4b896e4fd273cd5fc919e9", "e1b29ffb015db13c6f12925809d5c607b39249f5f5051b90d78f925e43a890ed"}, -{ "946000", "baef0350d326a00c5724bbb63a3a7d12a8463d59407afe8cb775f3282dabe66f", "3a08925e17e7c91fa44526b13304a55ac9344cf0139d6b2573fb362efbf6e2e1", "12953db0d841e911244a3e10f9f971c035e714d9a7535d1057ce96b2b25a0200"}, -{ "946500", "3ba6204f144b41e18b5f571aaddd7591cc8a2461790e23117eb263def13a409b", "c72dd099c929527f4916ed7dc0cf34d3c4b98a4ea8f488be7b92980af42ba4d3", "9a967079f01e44081c5349fa42ccbe3436afab5acd9474ffe97a0e9b62c29c75"}, -{ "947000", "1bdd194c738e7fdf54249f73177a6c78104e06133d0fd97d2e732e86752d53ce", "45f323adec9c4eee2e3ca82bbb2a165a0a94db22d3d700dd34688fb2575343bb", "71ab8b24e330266c7745fffd95eaa3842ccbcfc89ee71d944cb4f394ddfd7f00"}, -{ "947500", "b99a2375ff79648c98fa232d1b0fe37759deb5826866853913e7ef1fe2eb65c2", "17dd7cc2b9689b1b4ac97ec835fdcf9ce80cd5728d2d5d2a14883e382e182f51", "b6e255002349e934651aa29ba88b523359aefe2c587b12b9ae5f315654e2ad06"}, -{ "948000", "de7bbfc82a59fa0c6691020204c4916b9b102f66536e061a3585824472bbf2ac", "2de0049ec5f874e752ed146e2c7edf63f6095e53a8a349ed06c052a341d87e1c", "e9f976098892480b5662a211469875d3957bc09297ca5445ec32118373d80d62"}, -{ "948500", "ac2e0e3c131538ed118a3123795a2fe51803a11c3b4b08a7e47981884b2f62cf", "f870ed2d50bf25f95cee956ed54551f4b3e92d54abeecc3f0aa5cc15c5b10a80", "9dc10ba06c9e3657acda84f512e71e2623e92153f355fc85f292efbd7fd27293"}, -{ "949000", "e1e69e1b1b21e4f0a18b04ac9cfd9f8285db96ff6f4e9ba2ea5a454d7b4a51cf", "f08f455608a96421e2c42c6fb44348331ded8f44536def80ddc2aaea53f811be", "e9fc9f8f87793b08608e8537c9e2ff487a6a0371c40f601076866cafe3819747"}, -{ "949500", "5be555320df6b2e99d8f77952bb45df07ca3f9f1bffe4a4800a156af93d0c629", "5801c09b3c3ddd4fecdc69bafd4b6ed5599f5b4c3d480b6cf9e319be1aebcad1", "77b78279551add5e0960ac20f6beca37c1a18a3f4d8bb4afa3ee783d5e05d95a"}, -{ "950000", "e227fbd4fabcb18eb1e600e30654fe09de863f77f81c7634c2815bdf909992a2", "5c5fdf4e2450ff02361822c4702cbecdd0cef3c818ec819a8ada6c7791516396", "2900534be4fa7b504bf8f6a1047adeced6250f63dd441cef1e1d684511f104ac"}, -{ "950500", "9c0dd1fb0034c4a92f5b77bcc7e5818dcccee55af147ec6edccd499465ed8502", "94d3663c2526c1645a1e7430614a665a7f35183275b7167c5893d6b1fac7b530", "8ffc20f33c23109237f1f1fbafaa719c87402f09f90ad22c73cdf18ce0fa5cd1"}, -{ "951000", "2e932c87fedb78048a70c47b4f33425ac91e5edf91ee12421a4dc6675c50b084", "2b9e81d117f74eb48f91f5ef0c75c345f0d1f8685b2caccdd0e739f8a4d54d04", "aaec22e07e78f82d3fd5336adfb33c5cf83ddc95df01a0ffe6624bc222724d80"}, -{ "951500", "3d14b8f5c18082a279d433595fed521d134c844ada0f144595bd1c6c271b02bb", "9b6803d021c36acac84246ff8e5ecf486a40de03cf3f256b91dbc1020c62f772", "09f5043a2a9f466d8ee91d7cb61acf9ad6d16758a27f72adea3eb453a968dac5"}, -{ "952000", "f1d7b3035d1b4a3ca9bb76325f8e09ff28baf0c0bc02d6d02f2f12e09cb25bf5", "336abcd43c7b1c697e751756f24bc499eb5450d9d6adbe83b01233a73587b72e", "c7aa3eb4463829a604d2d46823be735ff9f47ea78be069a25ea75dacf86c2a28"}, -{ "952500", "09ddfeb92d32ba800b9f715b8c2148d283e4fd0bfbd1d0fb1a32c2249dd919c9", "a22209348a5e34a49ff2a9dad503299d59877783d47d5ca6e770a29a07396adf", "69ec74309f004f52806a5b3158f98aed9b4b5b5dea08339023515c54d50e991d"}, -{ "953000", "613e697f705fac48776f20e3f1ead078e683ba3b5ad72ad9867e14be2d28cecd", "5d74a3b0feadd5f3edbafc529ee8a086eb81cfd9f8588e12ec8631eacb955600", "fece4fea60c77b3c982fbddca9895e9e3c24e6bbd5290287ea15cd2c3cb9cf20"}, -{ "953500", "f9ab20889ab4c8d6f7dd46411b80f89f3551920684d8e4b1d3de88a5dfcfdd6f", "3b4c8c9739de63889bdbae40394a5e0bb12b982a5159e01c32d005e31ba7b4cd", "9f322ff3e4fcb73f3849b552fcb961aac906ad7e7c368917935b302f75f0e99d"}, -{ "954000", "01471d646b617bc8199e95555f46f2893e97502bf541dc6dde371e0ceca8ddf1", "b805b91fa492fea176eb197c88526fe225f18a52196cfc3da37b8850eb36e4be", "a011d1c7c4af6cf1c6ef8eff91a62a1cd8e7908d4e880fa1c69509626e42f0d5"}, -{ "954500", "c26bbf96a0ff7d8d6ef2d2ca911b2c8f649be385be4f526753cd5776686f9683", "e22b003c8414dd5d24dcbd5882705846e7391883fee7252d2f0019d0f066193f", "bb2c86475f9f60c4d5904eac230f89dc03ce58eddb0c7f82a79b28d455ba4a92"}, -{ "955000", "2812f54afa9234f02d0f89ce067730047af24ee14b3c380024da7a6567787b3c", "3a796a63e0dfc3baaa249d05553a993a4bae85c3ed54b183adfbaaed1a1398a2", "4ece14cb9ad276c6eb4bbf4566657fc4eeaba0b5519b6111db5553520c024d36"}, -{ "955500", "9c05768aa95ace543246ebb963ce1548cd9e5ddee7a6f5e45cce1db5c47bb2a7", "c824fcfa5ae174f199cd91ecf2ed8049716e6d7dcedc0cb4be2a3bae035aa6ec", "e13affedf873d26bfc24d47b9d4d4fe5a3da26c28f84b4115c97a40287c89920"}, -{ "956000", "769586a0e2d78803ddc48d46a6477505359896a7b8070cb55076d142d9360ec3", "69a7018a58df10204ad1f874a7d652185e74bbd75d6e6b29dfe6bce759dfe945", "4f7f343a437f4a9af6f8cc6e5c2e355d62a66df820489155e67877303cfd688f"}, -{ "956500", "ee555f15c4a433b4ad77468b6dad7560838ceabb56fe1e67076ee0e23a2e5aee", "727ffc7586197dd0e3929e7641f10fe84c5b7c1255a4075496afa76cf8a4a473", "1bad79baeca77e98f4a0a127d38228b7760aad45e61d26ee8782c3d58a6e7a9e"}, -{ "957000", "1df30e4f986c04325e299cfb1350dffc76591f9ad53b40ab249769b38a1488cd", "3e689b1cb999a8528c0fb90fbe51adbd0b90f6237a80169b49991a25caa86fea", "6d7cd9894e43299c76779bab920d5956d7cb69037bcd2daaec94f40cf6413a4f"}, -{ "957500", "0be5166150c2dadabff827efe2a7e1760807aea08f7c0c5855a47e9cea4149c8", "b8c9f5d0a6b7baa4947e6bb898ef1ca502c6c77fb6e1abcb58bad5451bfaa94d", "1c35f4e7046e10f2c100559833e6f7daca3a51e8c81a1766445607d0a58f5652"}, -{ "958000", "05d2d2d75328dad0ecf43961e0b52b227ef311a18576b2a2c58f9a1fd4844aec", "ab2e7a9c7bac8c39a3bc96f989afe46468975542d8186cef457c9ad8adbb876b", "a70069a6c9f4f0ede4c3342ef63b636fab7adb0bc56a3be09c75d1e37d329e28"}, -{ "958500", "a06d333eb4fda03d0e2cbd27d8d415e84d5da63d7e5db371e0d5b2744c32e625", "7b093292ab44a6f779b5ed00cca79a1bae4eb79de2cb150b9ed38a43e7deb57a", "aab451b16be52aa2546d2bc54e78980c3aa64532fad80db5a13b4c8114faedf5"}, -{ "959000", "ce381f9253633f9d2b48b71987f9827e5b8d68d09bc55248badbbeb85ccd33dc", "ef5fa33efab771f5175bdeb4ad9f5a0e6b122f02d47fc5dfcf950d467778a23e", "ce46c78c4e93e8213f768527501def929bcb568fb266d4c331d09d7e1f264ed2"}, -{ "959500", "c6e95e1ea44b4e47cece003fb1e8da01479c0b41de18ed008e1f6746f208b75b", "9b6c1ecd301c7dce7d5c3f0da8c4e1e7523570aa387c8f3c5006a55117fc5420", "9b915bd62d44bb84dd76c96adc9468024b757018674fae0cb26a576b357c4637"}, -{ "960000", "bdb90de7a26c79d8559d48f9cf9acfd272a2ebefe86c78e11759a9614e5f2400", "5defaf36aad68670ae534577435596269927ebb28ff6daf25e7992863e048ac4", "1fc928c303d4f7a40e4b9ff2698575fd8978fdff1003850762a91f103a8ea0f6"}, -{ "960500", "c8394c48d68806fade6e2d1b27fb16f1db969be718c19151625ed723c4d782c4", "9074493aa1e6b8327a8c725279fc67b90dee31ebe94e9e2431ac9388f8d6b7c3", "2895f1f0145a7df71c22849ff4266ded050bf8fe5adabde369b398212acb577f"}, -{ "961000", "9177a28ac1eaf2190c6d3e96bbcfe1ace9cec8687d91c5d1ef6a51d3133a6251", "13d00e3d155f0535894a8a170925f592f63112f285d5859b05119a90d6ef06b9", "95ca6d7417b662f691b371faf949de77867de09164d2989e32e82b64f557b399"}, -{ "961500", "7fc9e7b2460070aa7de93a059e74f220dfed6ca9d60784f305737f4924067658", "d688c89a2e08e78cf11cf0b62ef92e4969f934a53ab7650a09b3178693f9f4f1", "841b8871077a869cf1eff185f6290f379832001cd6f36fb545ab9faf6fcb1517"}, -{ "962000", "92b750fd920737b637e87ec6ba242570e05c24805a4c06ca6adfe72de1cf3cca", "79ceeaf812c0d470eede3c04b06ae94cd14e3569958bd0e7ae4ab4583f1652a9", "717002615460b13db543f643e27ec120808571bfdcc82199e0e33599cfbddd97"}, -{ "962500", "4723dabab6846111db863946410887489b0917f28b6941661d38150e80045834", "2b5b5f09f42e8441a73d1d69ec1248b881401b23610153724bf4721158a8cdf9", "647da4cd89fd11d38c19847d198e921f3e538f5adb7d283ddb9338dc1ad0f5b8"}, -{ "963000", "e7718854b1a117c939c705a60d706adbab7bc1eb29e18b3fa86f6f7052a4ff5e", "aeff06b67b31c015553db2a96db0360e61d61e3ba03b81622a2f6535540bd431", "66781cf92c355b1c2b0a8d17868c0c880ae5dbff1d6b29142cafbfd689f6f50f"}, -{ "963500", "64755a7e2fe737d5c50c0294b03ce6f11cb5ec07f55e42955c5e0363f371c5ae", "3d5d8c6aac6ecff5aa8be9a984838046bd6a8c591e0e179ef9e171b1cb04869d", "ddb7bdff3758560760df753779577f8aca0f4fd391687cbcfc4d35661f4da2ee"}, -{ "964000", "59bd046c3893cc35c97f871dfcb03988af640790f5b81bcd37720fd13a4eafff", "c0dcc142ef875e0a37f250ebc98a96a50671a4f3e36868d2b6e3782be04c275f", "0e2accd5b8254d57a052f5b8de81d05393e019939bb667317ecdd42f47d185d3"}, -{ "964500", "6f0dce76e2a057372de537c19e9cf8e89261cc24a56b30bd3cef7d9458efae79", "186d6eb95874086c7dbede1decbe52e2ef4f9bd7389ff5897d40e5d63e4fbb97", "5bea9aa83277393356b825cab01690cde995625091b2af3d6634777fdf6896b2"}, -{ "965000", "6e7d4ade21bc5b59d50ba629a0bac97eba1ea1c22b909d55c62115d83c48b0a6", "9ceae7a7c366ce13b5903ef59ee5a940c2f50eeb7ed88e1b5d3fe41f3d5cc8e1", "b00ba8d4828b108349a7326d13a4699d02013b8c683f4de0e1d5ccd9e4e78cdd"}, -{ "965500", "07073df1aab61b4e7d6ac4e3a47cb41266476326136ae32a17e63da2df0eea3b", "8bba0ae4edf8a31f1d3f2eb3e2bc8cf89913e3588470c4c26002cab2533120de", "05d2bfdcb4dd59c20b9c54a59af159a75bf0a3ce3d3b8fc18690e5d4053a0493"}, -{ "966000", "46de91c0817c0802081c0382a111d4eb0383e64cc412e20e14925ca8256da92f", "4da17f7bced7a0672c7932fffcc076da613c82178e51618ba0d051897294a49c", "aa5c04b7225ed68ebebe52fcf6120524166bebe68416e7265f3e0a56e4321111"}, -{ "966500", "5d31a7188d2e344852c1cda1fca474397652e623eb5160cac91f0765317e1157", "4dd7385532824e90376cd8b918f5877e7d65e7826a55cc5eaec718f9959ced59", "19e82f194381e36df76799e88d4e71f32094dd8f109cb4157d3209bb821924e3"}, -{ "967000", "ab1b701b49ea5a3d698a37dd97453251fd53b70ff008b8fb6b34d90c30298e07", "f4d5279f7270a1277967be4076aee31ea3553c8baa7229456ec833a974713408", "c600620b995fe71b11254415ab8d8496e7b09f0abea4f05c6df7cc3b74ad29c1"}, -{ "967500", "fcec3fe1ca40415a65df82b0587f4ccee3f121fe82592d724de22700399e38a7", "c7fdcac6633aeb83f348ab7e86341906e3f30c84422c33b1352e96b858dcd2bb", "4b3ca0d6ccdcc52d365dd33834e115ba8ad32a53d5f184db6880d00d433f0830"}, -{ "968000", "9b8ded270161eeb47e94caf849655c0930476f6b73ca1afc050f35af10103e47", "3fd0c2e552084120e2fcc8b943e734d4bc1a60ff598ce4365fa8a1beec829381", "3908294f574a60fb2de3e642dce1e1a8bd5854dfa7f71ab1c2f32cc261eae392"}, -{ "968500", "0845de27097e020706a6f139763ff199f0d665d00567812507bbdb4c4739a7c4", "75003bbc6f63a32615d906f51b0e325f78a3281c706162f24d3468ef42d0b2f6", "8658ed5f9bf63a9429749978488323a72c94e6d703b44777bffc09bf1d588bba"}, -{ "969000", "f92cd5a018e68cbe9a7f4da90a101409966d441e596d102bcac073828c13cc11", "caffbbd1f4a08e8b23273a4ab7bcb53ad5c1b80f73925a18268d2f17f930d1f2", "4289e02fccd85fb8a0d9e981f24667346bf77eb7d49ce56b0580e4d363d27f98"}, -{ "969500", "b08c175b0d02a58d410f0d9bb296059e5478c58ceb35259b225ce26c58ec2ab6", "003d4e578d4e99ecd8d1b569535e33d57e5287248eeeefaa97ad0487f8836f15", "5906b9e9c0b48fb8b5349474d72c9726cda06d062f19e1cea40d2008c25824c3"}, -{ "970000", "391747367a3e4346b56c97953d6fb4fa89473d95429e93a75cd5844ffe846812", "9af7f2fb1b4e414d796c5cf0d2324150025e5366e8db18cfa5ad7804956e4e27", "029d6e6ae51f7d222928fc51ee95d099da8309ab66ec0abe1158c7c046c473f2"}, -{ "970500", "caa262b1741e47d85bf772b131badec7e12319a3ab8a617d9f57d6584360c2ad", "293f56976cad2572a3c4b77266dc83d0810a915c1b9f4c4dad5e1cccdd715101", "91ed5f7c7abf693f2d85551e5936354bd9c726c4698bf369036f122adb03f957"}, -{ "971000", "ac906e072ba4a6d698d5581a7ec46bf277c76691314d3390188e86b68089190c", "718aa15407bea582e47710421ec160dd724f9905a088d83c7d240097501ca2b5", "edf900aa75dc112b7f2cdd5d3f272303a1c6fd0b7e2d89a2cfce1d01cf410206"}, -{ "971500", "dd461c00d3aa9922d31abdaa8679ae8bbd75b8aade9a7f9e0bdd0174bb81318e", "6d4cf414e86245695ca9ecb3a4bc3fb9b5896f3348f4e9ba916daac9133d7916", "8297847fc9f28f3b713a386ee24bf660095dc195e891cc29ed91f68adc89b081"}, -{ "972000", "099e80a3f22cb61144d56175c2e423681e9d5fbcf8c82743af51019d0123b21a", "2ec23f05afd3c6f60376c4544414f84617c48f368b3c1a1b7b90b060fbd27018", "cb3805ca2213c239b20d2672cddcaa7c436c2b0926928a2ea3cdd482387168df"}, -{ "972500", "eb380990470813b19e97939e36bc7ec145ed5bb84a5c15a18f53d8c6c399f626", "b7f9eafe3239574d3c22e39a2d2a62b471b8a7ea59c8570b206fd2d67b23207d", "cb9fb936cf97d42acb845a2358b526a9692279b55591f876c22393094f1cf143"}, -{ "973000", "55ddd462f4830ae58cef001b80805828381fa6f01763551fe3bf41c47bd06e33", "48e54fb3fa548f31b6b8012129886ad14d438d0e6af6a05a82230ef00d80905d", "5f353708dea02d4fe10525399c823d4a027a07834457e02f86b31404ce12bc09"}, -{ "973500", "0a3ae4c2d5937527041e62d202f1f3eeb575062e464a3566f6e3d4e9811236ba", "5fdd512a86c7668309807bdb7146dcaefa13813bfe05f812935dbba0c7c04d62", "1c086557709d579b3773cfa821406e79327a0140967713b73241bff2a2a28d08"}, -{ "974000", "55e80cbd096b8eb1df3fc9fdc1a4db0685f135deef48c22236a3be1df8d075af", "69b5c8b41f2e5b28a329e3cb10293ba29312c252fd97e2a6e9257b2cc225354d", "dda002ddf0995fd3a122f864c5c55971d5590d465f019685337502e34540dabb"}, -{ "974500", "57983b1af96d8dca16423e30c6feb4451abb992c59eb7daac3aec47f0c10404d", "fab5f619f442fac58344026a8e3bffca1b547084e5aea670cd678ccf1e4f7be8", "a3859c46496083689d30027b40cac019d0daaf008145d6f168139dc7fc696bdd"}, -{ "975000", "789decbf3352b728ca2513866842487ccc080040c301c20e219a6169af17f8ad", "8cd8670e216d098ef817bc6f4ac83b0de623fabe5b0bdba2bd588c28b40b7b04", "bbb05c69cd49f0bcf5a87329c75f69efb90a91b5dc0ed931fa22d9b41992d3c0"}, -{ "975500", "e4955374301cd615e606fa045946f8e1b09dd05be8d4cb90ea334e1f0bb9b0bc", "73bfca0d4522e57aad1864c6659e0906da259865cac1fadc2d4c8aed47f23a12", "ae8b93c18324c8f49fa73de8bb19e75ea2c04eab0e8cbd71d591ededc819b2da"}, -{ "976000", "911ee9db7be3ef0f0932647a9ce131e21d7eef9ac7c3a40fb9da8f3d328a3313", "a2d82537257e03c3256edd144045b2767b844046c07dcb75122d4100830f7800", "b118c6acb7d2f8a04d82083a9f25d3f87e468a7d1d363a374bf652a3db866520"}, -{ "976500", "82038a79a9cb494206fba58cc2903270b915d0396a2b3d2dcfc00c5bffcdccec", "147ca1336392af0bc36504c629248081cc5abad35dda21a7c10be10d2850df55", "d68b8150120a191dd977d13674e572c072bcbb5f3d5a97b637247f3ab72dfcb0"}, -{ "977000", "92456a662c9047c73f7083d2cb6a9bbd7f484ec5eca845c3a23362dfc9387796", "9700bed9001c1f54a9193337b07715abc03c91d0da1da02bfba14cd22cf7bd6d", "9b33fc4f478d2671e7ce83519eb04b8d808abcd4121b0d58e9a4f06dbbff03ad"}, -{ "977500", "bf8914d9c6c6b33e67c47ff6100b7f026dc80f11cc6bbcdd91489f68887a68c1", "8093398e5a2f391a3ef245664e6222069167cdf90491f84e9899eec391e01f8e", "ecb680d03236b5ea5bcc4c8d5903285869d1d8ea7785169cf27af41e05c5b50e"}, -{ "978000", "b1d888e91bc2d0788175d1167c270dab6bb1257ba68bd0f8d1d57e19788a71ae", "cfb5b13f8abc2bfd9cbea92a9feccda90f4bdb96861e29d6824d6abf40088dee", "03321ac394dea33fc18f97735ab2498c0ec6cdbafbb174701a9a07f7dd48cfe5"}, -{ "978500", "6e5e3a0db764ba19342ffacc3343df6000afc4fd7ee8aef59ff7b6e933017eca", "6d5b50718e56fe6f6cfd3bc8a1c058b7c9cfbc7b6cb4701f1d2049e9401f5c7f", "d00f4ec5daaa22e9b41fb58b56c3fba59090027a0ebd111381266420fa4c3944"}, -{ "979000", "8ab1104fca85862d1df0ab6edb7d4a001962e612b427f7814b83a3e63a56ab39", "e8b74e9b60ace577954c8eb0504dbf1b8e5c0dc057d438554c156878d6924a11", "fc03ba57eba33fe7d66029fe72b9a52498a693ff39505a6eef822184e3b0bf55"}, -{ "979500", "4b5c03ed2fa33e96b1dd3be6646c65adb5bd35a3e70dcef17dc6eaef44f7512e", "1c899654861cf5a3f58d764f8cea03248806c5de89594eafd2a42d084c546be6", "cbb6af9ec044fdca6ecc012ae75ff33362a36cf379cf1de9faaf1c2843492fe5"}, -{ "980000", "d6dced594593bd65bdafe4f455f97c83aaaf195a195c327275d358517276cdc0", "cb73280ea478de4ba35c27fc544edca9f7ff6bb3a0c1a0b44c17452fc61f8a11", "c84997ccf6e5747a0bb3790f7cb8511294ac9d0194ef7e92882e604c5be0a4d1"}, -{ "980500", "a9b5fee48434bf6d6062d4c3f62403fe8882716af75891ee9de40c010ff4984a", "50c67a1f249e74da33887c715d827f8dadcae23627c3c01cc3c86e2cc332d3d9", "3f1cb64e6dc021b39e7faf2cd5cbcdffb17ca62fb55f27f513f09f80ae10cd4a"}, -{ "981000", "e49a842bf035c8ba0d6eeff766f7674df57bafba5bc8574c7ffd55a1918f4e07", "3352d7d0d6554aefd57951186ffd4a20906c4c9a562c1d85a911f8541e1f5833", "c33807c5bab23c467dafc31f61378ce37b29bd31ca9ca3f75eaf884de1be4bdb"}, -{ "981500", "f7563d6939461d13b3d2886ea0eeae55bfd5b70a2124fb1f99e3128b1aa57c41", "ede14ce9d15b6d7dd03bf87dd1d6f4358eef1de87edde1b4189b5a7006242895", "e2fe553357ac092e527000a26b54bcdbb8b9f5d97fa9760ca53a97d6a84fc35e"}, -{ "982000", "4bce72fa79b9a6cc3a049ee07f2b153aa5de690bdd9177c60b9129d0a3ec65ea", "790c73a90c7513fb9c6a2b0293739d8305807d61d8dd5d4ff607f8bfd385e96a", "39396dc395f66ca2ff0628a1898b7cde9f618ed8a62f78a853240563ebdc2ab7"}, -{ "982500", "77132e20fdc5fab30cf9b662a7f7f0e7cf54d1cb4d81367de088f28a594e8670", "2ee079db6a79f9348a2f6484b787092b71ed1bb4c1267d5a18eff8d4c321c14e", "b971f6a69e0bf347ee37171a52c622aea4594b876f55e0a5feef1d7339efddf5"}, -{ "983000", "fa83e50346e0ddfb583789e0e053b74ca5765a4240f99f02c80753b0664a2851", "9987f99ab0e62c8c49f5b8465f24689b780cc9c016f0c7094a489dd6724ba646", "158238bf3536cbb4d80dfccb792e65753254c2a912d4369e7c3c561a2508d447"}, -{ "983500", "4c65a2ebacb363949d2a461a6a7c0a2ef50e4318675f4f5c9e417fdccba4c8c6", "62e4e5b983d0546fed593a3012c6b7cfa0ff96ef28ccc455142618ac4c7fb0d0", "83bddf9dee3f3a2fad3355a2e96fa29cf44b3923633796e7679bf9fc0fea712c"}, -{ "984000", "15b16b66f736e2f12a9324bb45854c9f6b49dfc6b367f346e772eaf8ea49f14f", "46695fd3d752266cd9f1e6d529472996f8ba494f161a7194bbf05b1130e3a4ce", "ff43f975ce071a1ed4f4ddd5f0cd6903fd7ef1bc52910d12346d92aed2df010c"}, -{ "984500", "bd9c47bb23b50fd7e77822c377f78d7aea793eeb694484291b8901322642c7dc", "b8d50e9fb564090ff86cfb90867834e86bb23d4a1b9f03ba65b3729e78a85aa2", "8f48c1bb77cddba1c79fbffeae6b285cb02beec4a83dc652dd96e899f6f53aeb"}, -{ "985000", "215551bd7b382b243fba86059c241a3315ced3cb6eebcec5d64c731a9aa07d95", "f7bf9600e24bcacd6716ac7e79942f9f62f16b644aaa5bbfc2cf87b84a418494", "11a27d57a9f743be233736970ec505fe97d6b54689b9e7ec9d67f83494bf2e11"}, -{ "985500", "aed846fcf07535b706e65ae53577ac77f106d4d196aa5adcd04d81ee2159f6c2", "0c10ecc979a353ee4b5d050ec570f95c8199401598d09ff9009d0d7e03a7326a", "c44f23336baf563cc5d6fe96982e9b1ff10ea88cc5553682873b45a403d8db92"}, -{ "986000", "f273f50890e0f8125bd23c8ccbe22be64a280b6f293cbab62dd9e9482096a58f", "289913c0b5c8c8c34c66bbbc27b602060a274ce12463a0d94928b37cded39687", "4eea986addde925faac38e16e38b753ed03072b51649744f1e231faee489ba4e"}, -{ "986500", "bb2726763523d72fa76ae25415b8e5251d234caf180c1cbc46684d30ec96c1fe", "a6322ac39bd1cbb2d2a6cff84e25e3e310e4e51c7f78aca2c1828c443cfa42f7", "aaa5b0b41e877095f8ed5520b48b18ec2eabb6ddcaccac765e93d1cd19a409b8"}, -{ "987000", "eb16d2f4fd89294f684687a1fda4cef1d5d494324818c0c16b9e2b9669211c60", "a922d18fd438b0b631a45cc52f1b35192e101b890e35787f60676d5ee100a0f7", "62223de4e95a2037cc7789c5a78244a5e19f808b4e51c606ed93c2ca13416d25"}, -{ "987500", "d50c6155658a1707ecad02738b6557432513bf5ea78bf3a2e1cde78a3b672f91", "95b19f76982eda85133625b6b2d8ed6ec049533d9a8f015a7d8eeea85ebda3ce", "311c8d2774d702663337aef37b93c1d0872a6b97f0396d617dbdcde3fc31676a"}, -{ "988000", "8fae67f15c83e3f5ce559fa3be81c49b47ea2923be52f8fca6ea76432973a87f", "db354947189daf8324430538ebacff70a48b80bb9fbc80e640efe5a0032aed71", "d98ee08d71f3619599de36326036ef6871b0a8682a16cb8e3442d5672c371ff5"}, -{ "988500", "7c7b9d686c788f19718bc1bb0aa3add6d5071118fbf2a914d4447ec2867de02a", "f8360801e9268cc2ed86aa0ec2facf7d228bd891e0cb54a5ad7d4761797409a5", "ad90ede93f5f3b0d1dbfa2999e5fc38387a13fbec9639924488e06e28588cf0a"}, -{ "989000", "464836cbe95821ce2f4bf0ae1eb094b086d894130057e25703f109fd1f6932ab", "3e3682d443a12d532d27364e2f7b6a5edd53eb7236159d859c5fb4b60315af05", "6657ba0258dccdf0a18e0f1a9c00d8ee9ab04a245f489245739f953bff55ece1"}, -{ "989500", "29766a224c17b8de90c83325930b52e2b52ea23242192f7a3795120d43c6ceae", "6d1e2b7a6c886b98a131cecee608276d80903d9f230f2486a7eeb4b094bf13fe", "914a22d9a9c75e3a58d84e647b92254ea0e20316ecfae9a9fc008f4b9acc0a56"}, -{ "990000", "7a0d6f86cc9693e0a0ee0febca3b3f8116a2c1ca3e3f5478dc713b9c03f1286f", "77ac7bb4b87ce136b1e951aefa132fa8e70566b1aa83e2b41c7e51b50f7ce994", "d6092b1688cc0eae8bc30321e515588909de8bdbbf660ad9d88640936ef48419"}, -{ "990500", "2c605fb768a51433d5ff066d9e6736e991a806d3b387c873efe12b5edb30a967", "19bbe2a5c3b3d2416b9219cf5570841f143d71a0fc20e29382eb6cb07901707b", "4eed06211d950ffb7ee961e659fcdfa432c27255a08b03f0318b482205800285"}, -{ "991000", "13a48c504165faf127f177f7d4fe19e150c94f27e55747dffdeb035a9cd26c1e", "eb2aaa0eca1b723d685a29f82d8a802e81e53009b8f53d57f0c2d80aa5dd2c71", "4a2be43058338bab0472df815550ddcc91fe47215fd487d8eed8c0fa54da1c4d"}, -{ "991500", "d28753c20fc3c35531286a7c815604103662a182986e5f1e5f84e2437b49abcf", "7f0ad9f3223bd8989cac9836665da3878a14b6ab705495b626bab79a73ae3e92", "50b869e5f6dff40cd01214a3007802346924ca2d77871b76785f1c5687d7f5b9"}, -{ "992000", "86d7ea18c4c4d8ad086d71a384f12bf1cfac15ab847838aa2dd3dc2bec258f16", "b94aef8147f94f009f2ceefb00902ef16cb7bcd31acd16633162dbad61bdb282", "c9a821a330342d8ff2be0e177b2c903131359d0af900a81982674daf2f545869"}, -{ "992500", "e1b3cb464a21d2243d3577a87ffa8a5cf4f886ceda5c3b70e5142097b425fd46", "4c934f704aab283fa3ae0b18dff434bedcd7c549816fa1e1a4639b6252ffdf4d", "c7fb0a4e7acbfa3f98f20a143cd49469577cda8968a06d094fa41010faf5e1b3"}, -{ "993000", "88a8e95ccbef1cf83a82690b89c170722120394b01ea641001a35379ca8bbae6", "fca6247b8ee3dcb01af1aa29846486eca0092ca90bc14274d16d29c823abc081", "155947c3a9d25af71c26e52dc2b3a599d12f029aaa990335a5a5dd6e5788dc1d"}, -{ "993500", "c34e2bcb4c7ead30c306385655a8202de556ef19ced40c59aa14c0efac91e2ba", "796047ec552f3417fbda0bb7e8b47476652a831590572051ef810adce0b28f9e", "98cf236f8d3a23d8c6c1111eb2eb20ff080452bf3b9fe9689b3b9363ec39a770"}, -{ "994000", "d5298162e2923b179e6cbdd230cdcc57dbd74ee47f24b94467f61039eb9ea1f5", "4b23ad485cf4edb61c5db401a01488b7546d5c9ee52f2bd3d9152ecc35212b8e", "1d3efbcff1e39633e6b214f9c98c02185e3104bfcc32bd8a21e318994498a375"}, -{ "994500", "b0664adfbec0e115415ded1b9645a536b50ca6abbf6d4064fa0004b70fde8e6a", "e7c1d777900ebe2a77996f06d21877252817e02a565346e4d014b06c1a29767a", "f4a31f3384a9b9c47bab2e43b667e104c6b00ac9c108e7c523bdd75ae51958f7"}, -{ "995000", "e508ee8874d2bbe69aefc606873f503678aedf80f7d94f41d2f2c5dd03875cf4", "86d2b0cd16d25e2bffc226f79d7212271480febb960efbd50258fcc13096e179", "22e8674a9e44bd8e8903e6b3ce8aaf7e047d02b1a30bb87383d6833b2bb32d1a"}, -{ "995500", "a707c4371079cf705cd28106444573df7512088f6ddf94529d3ad23a7300293c", "d45f3c7e465894cbf6ade11bec71ce70dbaa476e9883264398651c58aadad749", "0cc797a364857eefb9d8c277b2d8797be8db1c7fa62a5cd53245b611f6d048ed"}, -{ "996000", "f7b87eb786f79e735e906e314053d44ca9e390f3e95ace03d9210540bf481ee9", "b97629b917bf0cf5d8fea9f1fc2e70c68b7dd5e26e7d9d46e39ab007e0d1da1b", "ac28bfa8f6b7579a819de912938d16a18c6a14559efaeb7dc1ef83d52e620444"}, -{ "996500", "b558b1cf6b6c8433c5800f23ae615142084f8f3d928a40e409f874aabbaca98e", "cced61b2eef93c36342b81a9d83762f622a6bd502c0cc7dd1c0682a4724742eb", "bce90a34adae9a39878fd3cfc9e5435730384e0b2fa9819bc9a2633fcb647eac"}, -{ "997000", "caaeb7a33c8889c80539ae6c7630467e1f9a63c7ad7e785b981a407da287a641", "670fffa544fc0473595daef1fabde40074c4f7044d4dc30693940beaeccfc389", "e6074a488e39ea5fe55b094d2d81d69df4f8345ab659c773b0e0ed6b2f2da9b1"}, -{ "997500", "8e34f4d6d0a279a37c8ba482b77251ad9f7fc96501553dab0680fcb22e6ede26", "302b33d0ad1a64fef2ef8930018ada4c3c5a78c1c73cb8000c0d7761e47ee10c", "335d19d5356567c6c95843110f969194ef4232b690d543e802a8f25d3e03e729"}, -{ "998000", "4d92ce92ad50fc20856ea205479db25276de24f146f131b15a84554d0aa6f9af", "3a0b07fc0edc28355ff8d43ea3394e609fef61e0452c1a6dea2ddf15c0ded10d", "8bca7a9c18f2762ceb021f3f53f6490e33468e27a31cf4533e5b5f3cea802bb3"}, -{ "998500", "9fa48484cb1aac18acaf940acefb7e016a01f2758bea1ebce66a20ce4f035bf9", "d46c0a9835b479ae3f11573929492f282a89d3cd81de832bfbf621c1f447f4df", "221d1d90f07fda3aa7c8e95da56284796600476a866316905991083187df30cf"}, -{ "999000", "ffc5bce237b717abe7ce11f385387313ecc2aa4696c69619a5b4086a53ee3271", "ff9b6e5ab60a595494e3acef825047568620b1c43e8e6113142603e7b0350082", "116c978b4824176655fc3128846b3b28df9290434a2920370a4fde4ea5166813"}, -{ "999500", "6fcd2218fbb6bb99a7ab3ee9907cb2d91332f8050a43f540dd1b927ea7406d06", "125f37d51d86d8fd684971d3ddf14658459571bd6d21d87a2b8a29aa79946ae9", "87e1efa60065b9e9656bc24787b28043c1070748c997f283a9f04f9209047f33"}, -{ "1000000", "0eab5112b99ed6e8cf660a001c42d98c8080cb6366c7097eea2ff77dc1609f37", "acb74f062691fcec64ec6ed73d0a383fa41a034d58367c8622fec495427df074", "bbd3c4e736e39dcec4064fc9f486826379d79ed954c19359e18add4351492c91"}, -{ "1000500", "d1def6c86921155cf5563b6f8c4ce542cdd4fdf9754d4000dbacadf94048ae82", "6f7bd3d0026433254bb0ec777cc7ada57e9f10918a0a422dacb183d2c35ef820", "ed39141222abf2e2c4760fa9aa1918da3433f32f5a234d7d5bb2e8f7c2f39cc7"}, -{ "1001000", "895076795aca0adde7b87924fa062ba68e78c47288b2bb85f00e7e4d49db4b26", "688a346250fe2ba536b9825274d23fe3ab45f80bdd79adb081f2e94982a5e4ab", "0ec7a8295aa452c6ad63eb016f1a1574e29f733a03cc0150bff3f7d7508f3ade"}, -{ "1001500", "5c22477fdd5bd95bd2d21c677164d7f5f0af91b4e57c40d3a4455a84bec21e57", "5ad71bdbeee74ce1a181a3ae5e6369ee464104bc12fd976ceb5f17c118829070", "aefd21dba77767131d6f6915420636d796b0ac24f6fdb8762c2cf24572d25924"}, -{ "1002000", "19c686c9af79a78c7cc99f40e01c1b6ef8e1a2fb2fa71be9534627a4d4f9a025", "658279857f203a5c1e707bf87d65c3395b687f8dd865831d892ecb7cdc8779b1", "5c2450dcb64d2b8a125db556cceb9b5ed77a1ca3a30b2c20664f09406cd8b4fe"}, -{ "1002500", "6d44ea79ca8224f60c6e406dfe9c7b459b253173288fb27fd53f2459be869fe1", "4d4cf2b50e60efd3830b0e19de7109bfcca8ef40807d483e32260b1a85a2ef9d", "5b13f594e0b2a6ca92994eed708582f53d9ada9f61e9198bed811e435e68fc2c"}, -{ "1003000", "e5b417ad3beff6e4f8864ea986901adc70cb998335784643accb38300ba26f33", "f947088aa2b8ce56cc93358c4049c034128ca2f3e67330d0881ebf49e0748f11", "5802e8c75cdd661f92146dbd83df5409cc9d537f584c8c75d2f5bd1d14e49435"}, -{ "1003500", "da0ed4a993783299c429b78e8702b1dc731cb587a331106925a410112ee6a241", "0f0c1c4ceffb15f8a875034287aabb36c185962d010699ad1161ec4a82f98367", "0595982bf5c066b4b3702ef403a8528a86b0b4780f4b9e8384eeffcf84cfd5c7"}, -{ "1004000", "764ac91a87f912be6230e1b59065b818bed0579c6ecb1f96a17e7303de702b39", "2ab1ef7f085464ccc0245b130d84641be08b8fc885c1f15960ab72e486834cb5", "ec4e13722178845b613ff902bab5806d92ec355f5c05e195716b87d5970e5fa1"}, -{ "1004500", "bdb68fc38ebf22d68dc2a984407588ed9c452a7aee062317ed760140148b0db1", "49563018d17110ead9266c3efd001ac2c0965f31cb08ea8c69b9309a00e08822", "cad664604a8bdb4e86beddc02608ffe42a254744b1d4b5dabca93fabded857c3"}, -{ "1005000", "98dd7428557fcb55e93aacc5ce52d4685a9ff114e27777124371bfbb82856a18", "a429996bc47364fab997ca87316cc079a62290f061b8495b93a14fe24087c49d", "7f17f657146ce62fad541c45f668f193b94276025e6a04e6be7d866870ce14b0"}, -{ "1005500", "0a94bafc026c86b317b33f8cd2661d6494b8f9b01a6931d771505ebd80ef3314", "37566fb68bc84fa11fa17c73f90cbafa0ab29336a0ff0f98eefa590c7426869c", "1b237de8296a75ece190c887768b4f54a926792e26a7c89fce387804a3827f18"}, -{ "1006000", "db286315d07b3d4cc4de96bf6b344be65c9406c6186318e32d10fd8d66d5e3ee", "2f1984d31cf7ab600246083e52855afac8a6ff5bdf62badd04f6ec8c532dc5c8", "546af916a106c2231a05259f3327e1ab74dea2878c19292b1f9d3b26218a063f"}, -{ "1006500", "7ed79e53672acebe07b0a25853c34af6822ef69078c94de86137f16ef35a39e2", "1d503606be0bf1c476e7154c2d632489d9b0ee7f13138a1face4d411a0e6f9a9", "e65fc30f976eb4cb8025dccfea9aabc31294856e2c4d9abf26cee7dafb49d413"}, -{ "1007000", "98056fa1e52b11ee70eb294a962ef9288df96ea4ad8fc4a5166a58ffa67cf650", "a802403c8ffeedfb9de8a5fc863730e39a06c142b04b3b88b791f12b3340741c", "c3e8ab95102df395fc770a236e77676c0f6fc6fe34ea93c55cefb561a13d21cc"}, -{ "1007500", "037eea45d7e266fe26cf97846726facb73968441f3c3b0b8f384371335ca8b54", "f919c88493be76b460431acafe67adf6c2cf18ad72549b93f51934791b628c22", "de3565e0b9070742b491b3d3a67ebdc0952f730b6489fc63063e462b43032d97"}, -{ "1008000", "0ac8cae34eadd6a2b2b4f8c19dbe7b81b3bd432c7fa84a4635ed19c8109df8d1", "7859a5b85c491881a7bf6f3d0d5dd0c0dfe381e2d76295608ae4a2e12ad52f40", "85299c1a9cef6426c6d1644bedaba75c49db2fd764620ad1aae8c10f173ac37d"}, -{ "1008500", "903511e59fc4c13cef0ba01903a85ad56a60406abcc5804fe0021d1f364f35f4", "be8421e49bd2f3e64db5309ba30e8954d1cf68eb8ead03f5f820fa88bce8cb51", "06f71da713bb2705ce46479537db6a8761be15f49425a5013f475ce941ed8440"}, -{ "1009000", "0c4432de0745d517d1bd48fb5bccd988985d77628c45f9bff545834b63986ac8", "577c73b6278b78665f4315543688743a5c49ebe86f63f985e9e7989829030386", "c12a778e6262fbfd3a4fc18821371bede78924cc02bf047ac561c3e26ed6f3b2"}, -{ "1009500", "e8ad9cb3b8e542229367fc34627ec8e1f6e4847a37552ebe2bcbc36eb0c0d955", "5bab28311ec5b559f423c3e7980a1d55e5c0971682ea84ff9d6740ff9ad43195", "28339cac8ce5f3c0a9d7942aec12339e6d2b0859b8ab75da7c61be7b5281955c"}, -{ "1010000", "8c8b963aa26439dcf83d0a67799551fc5fa3b1fce2261db4374a913e50745184", "d3c41f512eb318d2fb9c76dd883dde048ea1bae997bafb4013950b582d79f780", "20267ef9a3ef52b03185ead600467e4da83c9f38e12b1a4506c171b00f02e0da"}, -{ "1010500", "f3bb272a4c6145fd3a142e85744d9838c7e1ea33388c5501b76f2bf3fb6f2021", "015a4e570fa61d5b9cb0d8404f237d56571600de80f4e9291fd69b5f981a52d5", "877442676c9f93153345c6e7f48af95effe054947b0ab611d053e252f7d4a046"}, -{ "1011000", "e99b3e7d03403da96fa17a760491b2e627324e6e40c99c6291ee2477325506d2", "59894713ba320d48c79325fedf70951bb8112781aa32679b55c49f6739d4549f", "b967907ae6fca462af16a9cbd31411e867699dba311409bb93dbb6aadc4d7df1"}, -{ "1011500", "624b57fa2f3c1be8a6df1d8d07162b6dcbfe4d5b5bab6ae76dab199518c997b5", "b9b72cce7e651a9beeb7a0af57e82dd1a11ff0fe4df6c7935bd67d10978b7b91", "bd0ff6fbdb52c282d8b3c3e0737fc6c51883d3ea77d630648b8d7b90ed54e995"}, -{ "1012000", "1b26bceffc486dad37b7b8ec5822a388cc5b24d884fc6463963f1bb432440981", "308612e9d27755371409af57a2e7bbb53d9432ff575aa742854b074c8ee6f237", "afb1196dcf4ca82ae70800e68f6f822c73be51068e7a650b23efc56273ab48a5"}, -{ "1012500", "1fe71ca40d446eef37d4c00d208ecf6f503e180e6f55c68dbb5fcb9e3d2eb746", "bb77811625dd920f9ca60331a354187ec62026d596a06f49bf6aae63ed72da2e", "e6ab2be9399acffd7fa0c63699ac1625d5a8c2be7a08cc67af77ee51ee54c642"}, -{ "1013000", "332859dc2b9962c6f20ba5af9d3093ee01d1e034e8c1b2defbd65e81154a7f6e", "de3d066931f8e54297a44e6e2d44fed5829456960c2f5aab427c460522dba461", "b166f455541bb19e0fb02c42c1d4932da389b8ca6177f690fe63e14329e61c4d"}, -{ "1013500", "0e4af0f0df0ec61fa3a5af0aec7c4b4987d876be19be280f8a3046c36bb39a5b", "c198a22e2903158000099fdac41933c8ab9e0690a84988691aeeb0e1d1b53904", "1db107ead91e75c67e0db283c3e88144d100ff191a64f6fc06b4e2338eb09c59"}, -{ "1014000", "1355b040605fa16e26640135a12f9ca9643a6ae6020b951f0150898d16b9afb2", "c3c21ef46afe97464537f553d7dbff58e4da1057936c6f19709e0aeccae2867c", "e015f4147b8eee74bbd26cdb18d17cf99fd65a6b2ff74d9fcdd29f28b73b4fd8"}, -{ "1014500", "d4600ab85513dc5bedd837d88720fc5b336b72f89fd571eda9004ad474d50630", "86f43b00faca5b4a65a815f9ac690263cc81af330cb0905aa9f50f4730c1bd64", "4e2f0a33340982fa9a725ec71a9b0ab676b0f765b22f80f0538c4d9c1e7737e9"}, -{ "1015000", "0a4789562092c0fe5fc900254fa79fcae07c862aaafae8b1f0506d3b7f7b5b7e", "976a0948697a861f02ff643aa4fd2ac3852b0f694ce3ea18e764e18abd8ceac6", "11fadd2f1d937abc4ea283d854c7a42e1ff717efe9b93f11c7d3a86bb92c79b3"}, -{ "1015500", "9288fd9c568b760f0038e65bd5d5bbf43bd1a5cef8b4e60dffb190c60a9bcdb8", "4c5e0a487721cd7bb588bb15ca20f610071dd4a96c0f9445fe37deb3af4b50f5", "31969127d7349880ed8012923c8511be4881e5843882fd49095364d577b13151"}, -{ "1016000", "a2c07ee8e03f8f4915f90146a752a637be7a64afdc7dca46a2213a0aad16efcb", "90df13acf7e85c2a43369b020626cc6a16d3909bce6c42116a584dd65d119c78", "1afb05112bc4e0006fc82dc1b04393b27f52dc57e85ce15d277b0abbc31561c1"}, -{ "1016500", "c6d0413da86d3ca6e27ec349e8ae3cc63b38c2dbd1b1efb4621852fc55264fb5", "7621412436df2d39de48cb0de98fde07ea39e7a191055f90f18cdb05c73db51f", "e4ffb5c5bc611832cae9ff659b49223f591c0431e73a0d9775b0bc3b740fc399"}, -{ "1017000", "dedb9981b4c85b114905c98692a951e73a0620094fc1ec65b584c8cedd18f0eb", "7fad3d8a58d19856c7a8928a8a7408a4174022b3fd6627be6c784c822c72e790", "cc519b1480c913cfc3c2e7708bdecc134af59db0a4e20fd2a431bb86df483f47"}, -{ "1017500", "34c9ed49379330dc3d1ca58f018ccafe3c706093b428a115a18661040767e145", "03e7ea37256d09c6b89b4790257a156030032361d9f850eb6c0976623330e5ea", "615c957d7d2ac1c25ba6735aa7856774b36e206f867f9fc81c09594e00103f4a"}, -{ "1018000", "994e4293d08d8da39b62facd7f3fb82ef95605a27acd3ea15e0da47a0bab0f60", "3648a62fbb596b4ad5a0c655baf9d30e5580e9fc76d5dcc9475e18bb374df4e9", "6ec66f7d4020d0ce5f17f6a65d9b450654300f17b9a8eb86cba9729c0251f348"}, -{ "1018500", "1dd630cd6391c44c85c78a99e80cbdd55e6f493d2d82181e103d839bac021a70", "a39f7fa1791b102d8927b847d9bbd2d04e10b6eee5881f55760fe2730a8c4807", "ed7a0150a145a9608fb11c3deb7ee88fa8a30a1423139e6f3e280cb1ef6a5089"}, -{ "1019000", "f7d9073afa8d925eb6f8123fb74a00f380f937b0bcf0ff7d95f1f5a42d12b7e5", "98467a98281be59593e2f92370868d35b36f2d59e46e8c82935c0f2f3b7a41cf", "07f67fe39f4150037f98e6c4bd29afed07313df161d151dd4a6a3bc90de4cab6"}, -{ "1019500", "67c86a37a72ecc42e218914342df752279a75c6116c931d6c6d36e458b423596", "cac3f08697af498999fca9c3669c5133f5f152fc71f76ff2f0849bd260772dc9", "f9ed9419820af0ec217a418b3ee8892e9841c41c20b074630407375f3d2f4286"}, -{ "1020000", "78531e7178c89f87b6b37624e82a60a0e6d6a81c7829de6bf0d96ced1d506487", "f32a845743c254db6b95911b171cc56e7a1e569a5b859c605083d8f3c5725779", "1b6b483b54f05f78269615e62bf42a833b2b746424a42e7a0ec7168ed6e10a31"}, -{ "1020500", "e97e743b51d2ca155fb58e64a9e5a9fd8b306d844275e6915e2a961bec41edf6", "96fba4d16e4722a99b3958d864b032fc55972bc5d2f781ccab23eb17be8bd9b2", "9ea7b6a72f8360983662e1cd6385b9e04666613e00f02e582755453375fb0709"}, -{ "1021000", "1c8dc672143d2b0665aaac012d8473eeffbc03593f2bff19e5cd300dc1e3c0d0", "ebde0b66d6d8203bff12f9c3d523b58be1375a8779a37f0026ed109770264e16", "08e426d787e7e8e00b3d401c3d2cdddcfaac80a24912d51c952113e8d34c37db"}, -{ "1021500", "19f4073201921beed8c8dcfea23064a5279d458be19dadc71f95d1e6860d2cf2", "11f8a235b0a37a24a410be6649c1d99593a14835c1e769fedd6d93fba376e0af", "b30df098ecd266f92db73267ef08eb8adca49eaad8902fb15b3004e91f6e9413"}, -{ "1022000", "55346f3b9ad9b8c5b6eaf87ad3e665911ef7e6e2087bc2cac9cf18bb5b47ecc7", "148ce0270dccc99dec7fbcd56e740dac0d2fdd9ecb28336d8f10f3f93e72e621", "d56058a67216694f08e09837bf205abdfb714a90a1b33f84c891d556b69eae71"}, -{ "1022500", "13b87f0b3bccd3df87720f8d1305fea62c7f99eac08518d6ca4ec73f884b48ed", "6a6820ecb56e7f823c3ad44889eef94e701c6ef730ef5bb1972630b1e0ff21c1", "926d457cb5f5038e3dcda645a4da52d2869ef4c89c010cb4ea923893869fa540"}, -{ "1023000", "424224c1ededff18483f53c1801022f74fac2fed58474f8199a1dbcdfcf0b826", "d359f2cbfd8363a46d3d603d1785b33e417d2077e48a3f36d7f6804b2c7f88f1", "2097837835e58ca3295ba57d8ae5363a123a56fda2647fc0c638fc509c28dfb1"}, -{ "1023500", "6125ef9aa4514113036ab2f8ff15916d14e2207d47d5e2370cb5b7cc474156b5", "548476c915898d2e9830d05f0ec53b514f7227f2e3028d6cc538d5c33e80dd98", "a85852b5acdc540209b4b7170ff509413e353a482e7284a2d63abf307a7f5bfc"}, -{ "1024000", "fd357daf81ed6c277315e15d1874b547cd65cc13bf826993edd19a54fb7aeeb1", "301c910cb3993c6803243b6222d23775662bdda07502844133e1723994324594", "16a4d5e08f85e9bba2f4e98a2437a9ba49f9bb5dfb5f63c0282f1b5f9bb815f3"}, -{ "1024500", "ae271907a6c47c94f7f7f2588e04428829cb37ad332d3239c71af1457f261628", "d970f8e09a2c7fd2ba1cad97bf3fb51faebb596245c5f55e1b851849e66e5bb9", "7abb1dec17399ebe7152d385679394bfaf8b98dd693196f1a0bd2ca19fb83eff"}, -{ "1025000", "bf22939da65542b923c5291432d07ea2bd2a00ff167cb9d41f85ac51fff85587", "5c8eb42b81967d7277a29176911d8199152c695f87711ce6400f2b8318b69c57", "649849663e1fa75f7106948758af23244bac416d35b4ced3fd2e7dd5690140bf"}, -{ "1025500", "21b3d481f19ec99cf0c341cd66b5cccbc1a7ed425ee7280ba90af9386d4e91f0", "41362f4ee0b965287c917e198e7e95c69f07270f1340fe18d01b6154623d97d8", "e178502e8afc4f21ee51c0da6f21827802c461eea56448d25f1404cbf42b82bd"}, -{ "1026000", "f23c5c093cc19bc5dea0ceddff5107c7ff15713677374411429abb78cac42a91", "0dac57c3e96e57a826ea4aacd642fec6948a6723ba07a58e276fb651bdcf352b", "bbb40616f0391f15647483fde7e59ee29e8626662f0aa9dc379506cec12703fa"}, -{ "1026500", "345cf11b4d563109b2015319b036395b2b12801125cf254e6f5b68c0a6cd70c2", "f0bc274a028bb81ebe15a9b71e864b875feba257ce6853841819303ced071e0a", "bccecec79419ab1fd7390b404836198ccb48a39dc207a77fd900617a757d7ec3"}, -{ "1027000", "acd07fc45909b03b24cd255627da907c89a851e3e381b717739d1263982401b7", "17dad78ba692050cb485aec760af2b2d9daad8d9f1486e32a382fb03c7fe855a", "c4b57139cc21eaa56ef7fb2f6f3642ee7890b34918661a28b617b2096fe9d6d6"}, -{ "1027500", "207bd5e690189f2bbf82846ba98c1a0b00e495245823c6159c102019c004a82c", "66af363746bdfa0318d1e2c47dbda7cd9d054924011a4fbdf9412fb010e1d4d6", "c16264a03c120a8b681a8f06f933d5f6aaf7c33895e83d0bdc082d1ef7e3a39c"}, -{ "1028000", "ed8104c58a22e33933a48881f4691046e2f27fa2968cae6b158fdc60f766c2cb", "b19ed2ab60fc83e97a2f41974620e63f86a702fec2bfa3ae616a07f3c8a66cd4", "0a7c3cd130fdf9c86b42778d121586c1692d31ba6f20b0b04dbb95801797d862"}, -{ "1028500", "a8ec00772093f07ccaced49ee9c6d884d6a9a99494f134e504124c013bfb1667", "4c460320c0683413394f0048a404ac14c85b08522c9f7e7c95ddc36be0737e93", "f506033026705682c94d8e44aebed0d207e050944d83f658fefa1df41bf14714"}, -{ "1029000", "072dc699a6b2732f3b5eede2e4609bf33421b562e69a06a68dec7410f8dc17dc", "e140cf4044f9775fb650fb52609438faff24023310a3c0ffc8b3a7e1aa5ef07a", "0549a9ab65210cffbc191bfa966b68410862049fa8414b5e87b00f85a6cc97b2"}, -{ "1029500", "1b91daa7a0be56efcd6ef7fc9abeeb20ec7e9e91b292e3841f8fd5904d9bb55a", "816a5d038097153d2c0b78130d93e905f9fa1aab0431ba050b3c2d0983c278d7", "7a3a0ed54f0f8df4ad2f4864b08ce812001bd9fbff6fd7bded5b1d582d13f2bc"}, -{ "1030000", "60c0681496f782c6d175671a609d285350517adcf1351b13c5993690101b211c", "98d79fedf73559704a2bc76c089dac5604ca5de734220992148b7419f8cf48b6", "d97446ac79f5b498bc81d03d6563b6696b0f5a4db11b3f8bf4d53e625ef228b5"}, -{ "1030500", "c7290f8c90153a075f2957e7479522dc8b16b70427da55f51e6aeba41c86dbc6", "82ac3d69040e6be1098fb05b4a50f88979b2518135024c0a129eeaa33e2a3024", "8c8ecf230f23fe7364f9dbfea6dceb042a65d4d2b000e1f5ab6f84fdc01a2553"}, -{ "1031000", "10d5f1e3d7ebe4c1e0ac25c126939110ac48a9b03d8d48a299fa356f802cf5c2", "2e2aebc460ba1bd99198559c4e3ad33b126b0e19a4dfb42c5eb35b6ecaa63737", "6245b05af1438876861c8e1775f8e135a021ae14adc7ee5d3c4ec8b30cebfd29"}, -{ "1031500", "36faab3bdc61f3100234c00b4b537295768c2d23815813d169ae2df6b4c0c769", "2f70b464e2c6a88cc966d392c0324e4dbfc50ed6a85f02f09cf14c2485f2f84e", "b189fb3e4cb7e86cd172866294cfbc4cb759bb8f350b8835a53ed7ebd419e6f6"}, -{ "1032000", "017ec62875e8d55eef392f0ef3b1807a184c872643ac98bd38ee650618b77b25", "0a3b5e3fccb43dba43fb467f8d0d07f8921629fb0976b929ca4da686983a2deb", "ab1e4677a28c6dd28026ec874949eb480dac7ae6bd6d9174974cb125d430a669"}, -{ "1032500", "99ff5e99a1b61800e956c385dc96e653e42d4a04a4793ad7ac502b518d5213ef", "e3eebf3aeb13c3f16888f9203037f931efcc0441dbc8ad833d275461417e0b5f", "e8356d391e5214499afeee845cc93f2b797280a8c0f398fea831edf5c4055149"}, -{ "1033000", "a92f1f7987e1e91d78a8c107fdf9ee32a1e5d6c05c95ec946c3e80c645e9c3ee", "528ca55f0fed1a23181382a79cd0018929612f84cbe0aa4954d28466c548f655", "7b58191d1e838bb06560bbf57f883a5dbbb0a82da83c2d80a2f77cfd30cea5a0"}, -{ "1033500", "030e3cd7b93b70312a5ec6cbaac9f567358078422f5b53c197cc86d2519ab70b", "cdcbf7bd8b051a4eab6b41f351cd6f9573b8a9ae7408b1ab633457ad9491826a", "b752605382827e7074e446aa45510fb7432771a1caf9b6122717fa7fe004d9d7"}, -{ "1034000", "d15e32207ebde3b7911ebb3db34ca537b2f1e15cb1657544b30d13829390a3ba", "efc04e7c16e0ed1fd15e5d8c9068b77361e03feab82ebe7d73e0240877bfae72", "8e618f8996635c8a7f62e323a584b9e33761d1025c887ff02e72119dedc270e8"}, -{ "1034500", "b9d7ff12e0b634c98dd84165b76639fc92b5c86cbf793d313f0fde5d203eb8a3", "57c20ce8035f48f0e305fc7e239f86f33d6382b558d68a65e1a72eaaee1e3087", "9c0eb7689751f5d0419e6735d941ea1c63d785c1fdc07e9b343df87344d86c95"}, -{ "1035000", "124827740a242e34f993652a37a666b497e2bef00ad5aa5f639458b50fd1c381", "65da591da847364ffed7cb9b7953149fbde437a06d60d5e694adbbfd146b5e23", "cc64df2f0d0cf33f8d087caf4b1ea8d0ee543e73acc36207b7dd62463d2f0f83"}, -{ "1035500", "a90b40499493a906b68e4741c5a551d45a74b6b88d77b74825dd7e86197eec87", "a6684dffc164991b841c09901bd468b1b6cb38796c71cc32358c2d7ed0c06609", "94966b59a95417fe1202430140605edf7647e6e35a911f5c821b1a420b897c04"}, -{ "1036000", "961b6558ea0c6f4a96f5020bd937b024e2315937044e94d7e99a833f15a9c0fb", "2d5a5c1effbd7f67d84478e7be64718beee3ef6a95f4e34b0c239cffcaebd36d", "b3b00b3c22c35d8edb15d7f19d9e6df6bbae05706d923ade6bb4b9f8d85f86e4"}, -{ "1036500", "ac05f9f0469f980206088273193f50cf74792c57a4a9bc3ce526b840080fcda7", "e93603305a5386d63734dc73f8df0c3a1e56da9d1fcdfca2960760f3d553d38a", "3b5965457c65f4fa96b141b2383c3e8ea95650ce5d20bb0ed60db681c909d9c6"}, -{ "1037000", "e8d461c77555c99a60f1a92922f6b3b702ead412bf65baea1085339d9286b53d", "1aaece9384d54cbc7640948f3fac7f5377cef6d87be8f523f5e45c8f9f10a5fb", "cefd2bc447ce665a2e2df4d5343ceb2ca3e95e2206efae2e871f8145c4cd76ef"}, -{ "1037500", "394e689b23cdeab65a232d4789befc80e13b946f2cb7513b6f4401c21f2cf34f", "b869eb6a9da7a0d2ea4f039a8cac963aac4157ac76c0bd1b6db0a2db19dc3a4c", "3f8ec545a75b6850d99530cf6fdefcb8bf6ab95d1eaa183b10ad58ce14293bae"}, -{ "1038000", "d4914856b50ec1c683af57b7ad17dedb0d6d496b1c3fd9e8ac44254f5097da80", "da3578419c83ca27aea9e5aded3f037ea1796130d12a7031b589ca9ffe5a5fb0", "982d02d1adfbafaaeef3ead73a8b760ef8cc4c18913aa2990df5578627e0c63f"}, -{ "1038500", "4ef9de168a9cdf6e4074492cd69b15621990a9b1a731154a27c1df6c6eaa2f93", "da919b8ccf4214f215cbfdf08bb7e568cc9329097d2275628cf7e870d8c1e9d3", "93617d68bab22ad289cde335ed90604618792bd53cb844254c861f8a0f1e38e2"}, -{ "1039000", "aabc1d300ccb7c5e20f99c58679d5801a86dfc53f489649a78d61d2780c1ed52", "740ebeb1c46972cff11c9c488dcedb4b03b1b26af5bf11fd2f455cd50be8453f", "886512ffb3b7ce603349d7ddca6f133e9de3b328f097b2a9b54933be8547e4b5"}, -{ "1039500", "1983a2e59f7e6248803264d5a3d5d5d215ae8532edfd5d532c3a87d5dff90aa6", "28ee7a4caf5585b7ecba4bce8b0a067927189f91264b6f61d40ed0ac070c4fea", "d36c42008a876af88c8756e4e1b81bbbd2967f15cfc97a9caf7e70f7b1c480b7"}, -{ "1040000", "f3e2a0b028e42ae82e49bb92ea4695af9e8086a42b0fdf4703674709442af77c", "766f9a2ab585a28d9fcc8a5b1a5ac73cce4a34a8c35ee49017ee1d005a2d5506", "415a4eef34189b66dd62945c61ecdddbc6617979b767027be748f1045c45929b"}, -{ "1040500", "5232a4ede825823ba1165ab340ef035a7283332854465224f7f46aec64bd1ead", "dd2390fd9549367fcef416b69e21b513cf2ea238588cd4e493b698ac0b588306", "c419f9db6f156969425a0e1a9a4412f7d3a1763f9e045a9e0a628ddf9cbb6852"}, -{ "1041000", "c35789e22c2cfa11323d5db2a608eae5f48439961d510bc279d1e6c2222e015a", "1a30dda49c5a3b1e8fc9c1b7e8c40e75ef527f13e83a398a41cbd3bed39c3a21", "652e2ffc28f71b7bf7d1fdeaa36a973cb7afa0e8ee3964a68df5bdca88444394"}, -{ "1041500", "fba66082cac0bd85aa39fe56c7e3f25b58098dcdf71ad064bc1293c6a5be326f", "9365e5fd1c055bf56fc73a599ccb8ad2d71c6c889da5d53a15ce287c9907efff", "130f197d253f4486061c8b344933d4e6b9888af946ebfe5bdfa0d66be7afaa75"}, -{ "1042000", "f960f144c580e372fbb20aebc7c7693e1647dde35631165f03ceca0402fd5394", "f309ff65eddf5e85b4ea098a6d47a0cbcfcd553aca7e5092af04df2660216ecb", "d7fcea9da8cc94742d3a5e0b39100433fe0ace25f448153aa6fbe9af7aab2f21"}, -{ "1042500", "bc1c318eb954e6ffd656b40aa2034aaa57510a47c70a26d4a64798b4242a96c3", "f49366d3c65adf67d855e79a8b5f321bd43e969beaf8da624aaa444153e34804", "1e1cab22f6b5519ae4265e0283f1079b2f209ce8c5288e9d2a247084e46a41ae"}, -{ "1043000", "8e675a672f934f13443b463b09308f9857256bc5535c144411f5af2df9cc7ed1", "320a8ccb3a1d44f07f16bf989a3348b980b2502e9dadbc1f7467779384e49ddc", "e2fb1c4a95ba177748c3732b0420eab1881b51fe2874b73e589cc7a08d565065"}, -{ "1043500", "cc6046ba969972c5af0389612e75d8b289c113b4900681a7b26a19ec120f95e8", "635b5848a1345f1cfe64bdd7d463d9cd09f9d075bfb2d04cfa805ece973dcdd3", "172d5cfd06424e6ecc06b0eaa4b441d4257c20ac8826f65b6cf20a2c57377b11"}, -{ "1044000", "df415157f07298c695d76b1ef2bd2ba6c6459dda30b6aac026a8492240163319", "1430ac6d0d2753b35eed3cbc8885cebe65214a9179480748ae5c3857bcaa72fe", "2d4b8f1a666c3f94f22ba93d18eca27b596ca5e66cdc3e7385c68fa151feffd5"}, -{ "1044500", "dcd1e4bf92385427fb83f6430ada423739f5e79b50d9d54d2da7682349099d4d", "a565daeed39c5a0623391382793c6436a274f39b859797088521d7ae5df1b7ce", "513aae8157476d212e99a19ca1c8e88008358b43434156e37053e69100e127bb"}, -{ "1045000", "579743f2d5aa7780e4db1b3015190a235ba6d5f4e5ebae8d00142032a3db5ce3", "310cd0259443ed2aad00773a3fe718fe05e30fa6a79be5d48600bd0dff0ea09f", "b7ecada86be2ad137b8e1f896dc2673f40b1e834e09351d6d40de96f32494ebb"}, -{ "1045500", "8a9aa0f90288d2ef021cd7bc0ff79e851b3027305f2ef6c90bcb67be1d2ca664", "01bc88af745ea0e33c5cf5d22cf1d6ca2cfba216e43b16fe090d7806b67da16d", "340015f88c93cf427fe0ecac9385c31f6be182d4f06007091144e44ac05624ae"}, -{ "1046000", "c72ccab7669a1c77adb96eac880c3b8b5505f76f54875c9ce63e5ec0a4466e52", "c5f2bf64430c0a2cf5b0ebee135d44a84b63dc5161e5b6e3bf22994c6a2448bd", "1f87c9f3afa87d527a897813ed828532601560b0b67e75e1fd040af0df8c7b18"}, -{ "1046500", "3573934e82012b7ba458286dc61fc094ebaea2e6a44b6f75c628c223610200e3", "0d902f09a9ca3b972e3820f74d83df311ba5b35e8c6fa1229ff8da974aec6e63", "f360249b4cdd69f59573d023c5faf8b0fc1e6a0f5f9967b96ac34659ee72ffef"}, -{ "1047000", "9380a4a18403d26d8ed097c1ee3c8d9deb40423a40c75ab5990088c7e5c6be5c", "175b7c5aa160a7cc32bb88a1623cf5c740cd1963c2d52c2e108005e2c895a4b8", "dfe7420133a6092210dfecaa74b30f29f0c980f74fd6205c0ad325b69d5cfe94"}, -{ "1047500", "b3eb44a8d8c32ff51230776ef692ae2df253ea590e3ce094021965a48b923a9c", "770af1fc30b4a95ac9afc82aef5959f9425d91fc27dea24aedc5f1d1bbbaae6d", "6f6dac8855fac467d526bf3b7fae68e33a594acffb42301e8cfbc7fe6838163d"}, -{ "1048000", "47a84fcee4a633f734f7197155fab73b0d6066752fee07ba18a3f1b2d2aff2bf", "ad93d2d3692df1b72ab9a4a0a306962127780d114e8ba39a8e102568906b61df", "adaf5605fc79d9153a915d37541d51b61fb849c9f0bbcba5164bcc1e930c9aa6"}, -{ "1048500", "d80b9eef45c8bcdcfe112f4f398aa4141888fb4bf69794b419757256f7b9bfb0", "c252f3198f625fe91d91dc5e3032446956d8de987b00d5d3ba008c3e092f6763", "8518048f6083c29fb1e001fbe778ed185b87a988dcbe0c61cfa868365939b562"}, -{ "1049000", "be562935777742d22230f2b13f1d885fcd3f3966af8baaf182673075aede0a9a", "7a8940e33f897394ee39c5f9edf0b04d71f28a3e07a65011496024b64a91a70b", "a90c364c7302fafc86ce15d51b08167f9232c44e2a7744a7a674508a146bf7e2"}, -{ "1049500", "450bc6a5f1b7d502c9a86ecb08ed3bf26c87149f6b6242deebf998ec1190dacb", "e496811cc6cab5c2b821d21ba29b71ca4256b228889e352e779a82aeea96df63", "64fd7f1d78833ec1260e9b39249e9957207845d99bab950ef921a3a5fafdda46"}, -{ "1050000", "a835e80973ca0240c06703a30433a139d200453a7296c24a22b62792d17ff2a1", "44c9a74b2ad97727ae4f419a77804a88f9a3cb31bb3ae65e2b372040c1eb273e", "95c578d836ef48bd93f58757d6c3b093acaa373f9654410f85dae1aefdd5d3fc"}, -{ "1050500", "631b74a56a6719158926aca09aa8ab8cd89b61e563a5b6386ec6de5e782e926a", "1e1c4fc04badc617cc382d6aadde8ae735277694e233a225634e2be077c97a2a", "fd4f6efdea193b035f4b5947404483b6930997bf8089d1661d9b9ef48c9887aa"}, -{ "1051000", "1ec8fcfb9b6d6c602e2775686f04f1d39a768064ee6aeb65930bfee5b1a94e19", "4f2f38f9f74bfd1ea8daf0ac5ffa8afb485436d5e4b35fd0742c454439b21488", "f6311a3834e71c30635c01e0c45aacfcb2241780e3aa13f2c834a84f5afda969"}, -{ "1051500", "73133e5c1408263f8053ed9a93ae7164dffc2381d3a7fa24cc78c29665b3bf39", "a47a6e2a98fef063017953ee09b4471622b986b7fe8dc6d52adda451db9c852e", "fb14519af510b672ace64d3d250549fad14d1ed623dd0544bc541b7e3710e38b"}, -{ "1052000", "20e08cce79f51cc9e5b0dd212f6cc3a0ad742244e58ce252600d286fe2415cc3", "edcb3b3a1aff133bac74770612727bf2f15cfafab7c63dfbfe6f2378debda004", "d47a434a2ba0524ee99b5664f66792b81fc9134f5ceb00e69efdf9a46f8142f4"}, -{ "1052500", "37e19650eba3eb3e2967c2585147cc37714d24ac681a8b78d11f946ceca3c083", "069c1246cc4290b4748b26b30446f3a7aae4ca9bd847d0f1be6a8dd07e89d52e", "dd01920c16ffd5ab35e7d670ff88cfc9bf348f0c85238643b8f04a2919978c7a"}, -{ "1053000", "8a22777c8f3ee2b71fc33926cde2363be651b56f4886962d9aebf6e111ef4af5", "2789aab47bf324a74e8ba9fe94951e5b3e8caa995f93f1c01a9e6f4e95783bc8", "0b4d50b5fc9dd327976276cce10c407e52b7fb70cf03d233ed3e88dcd1d8d4c1"}, -{ "1053500", "693b78182f2e9dfbf138a54fe519285ca8b5665dd630b9651d63010208cf1250", "efd0a291bdd8f0928a31f4083021b5daf1fc5de4f7b1ccdf70b2c7f62c80c5c9", "9800ab253ae43ff7d243ba35495517747e70d7da20a4a0d4691808ed669a95ca"}, -{ "1054000", "7d052ca1210218d7316d2d9b82c15e8e57d59ac3d444fdd45dbf5e577f9b4c69", "bee8ff913f9b231c0b34a55bf2381184d18389d43b1f6719227fd4d5c80d8b60", "fcd0429b0f95329e6c482907dad4a9e4733c8860c129ba977299d6dfbbe45cbe"}, -{ "1054500", "1b00ae5589d8eae631a21b715150b89a3786a33166cf0fb11e79f1c12b493e5b", "f8d95559f470788377237801e29369ebdd9b682ac289e43fc18ccb751ecbe29a", "1d1b84b14c6aead094be828f14e8d90bb451216f84ce7c325641b3277276ba7d"}, -{ "1055000", "6c92f01ed8c5f4247722230e045ae10ba6973c3f8d8ad66684852efdfd801234", "59fb8eb1e18d1ed445f7378eacd8b02e92698d99c1ac4d1544e35d127134424e", "527e64783b51c20f17908f8d4a5222f837061f839e5a35effaee8625110d96b7"}, -{ "1055500", "655d624dd686c5c3f95a7e48687d3cc7f7e3623b02c1f8db8727e54186e16cef", "508f0be15eadc58ee080897002ad681fc2fd2f4bd4e175a319807626603ed601", "2a01b2336eb82c2d66c72dfa96f1bb4778d0a28b7c169c431a8030ffcb18056b"}, -{ "1056000", "af11656c7cb4f7ff056efc8255205feb3ea12f96da9ac416e33b034e93241e42", "a9d081e5eb78f1018e0a86b8c2c333989d375adb3f217df5ce8fe0dbcf84c5d4", "6e3b76382e6e42804f19c5552c36c46ea24829dc035c16b0a138254a2c192aab"}, -{ "1056500", "4f7ce26131a4923137977f716334a07a99d1fede466564c89aac75415eea0eb3", "6723f6345fe576dcac1c5ccb5390321e317408c7dc34c4ddca7a6ac83c577ca1", "1649fcd866bf63938016938d91a53248bf9a50db3fe7af3711beec8fc3ac573f"}, -{ "1057000", "1fbe16214e11324f46064f3754e3189dc4e57e9aafe221ea7fa45627f0db2f2d", "123d5e7d330c6dc7cf7a4b9efc6375736de9b6acd14e75205e72513a19e938de", "c7dc8a859791fb06bc5de694f4586affa038b1b065ceb3abec61ef4e27dd3c3f"}, -{ "1057500", "2c742e483d8a978656e28a4b574fcac3264f040a569e8e141fb3b5f0de9585c7", "301d401df39b752d5e5a7c3d11b8dc6f985b7f836a4f8e4a318631c45d6d4f6f", "eb5eea8f78367516258e9e79be1c491b84899dbd73b9469c862b115088f44e89"}, -}; diff --git a/iguana/confs/BTCD_hdrs.txt b/iguana/confs/BTCD_hdrs.txt index 973411d29..f73225519 100644 --- a/iguana/confs/BTCD_hdrs.txt +++ b/iguana/confs/BTCD_hdrs.txt @@ -1,4 +1,4 @@ -1039011 +1251510 0 0000044966f40703b516c5af180582d53f783bfd319bb045e2dc3e05ea695d46 a5d211145f8e6ba0920b2893d307c5d7c207ae0800a80955299678d1706ea8ac 000000000c4682089c916de89eb080a877566494d4009c0089baf35fe94de22f 500 000000000680a9a697eb71155b18a5827e0889fca28afb81fcbb46469ed7877e 79f80a8f54c6762d6408347c6dd7dfd2f8b8c191077c1d7881dfc5b7ec6a408e 0000000002b868fe717dc60b8d146de4d9aecf779b7314224908566e01847769 1000 0000000000000cf908c887020f8970b7fe952f8b81164d83a87621dfdb581d08 3356ec4296ff2f04281492b0dedbaed80edeb6dd9170b87230ff79f6b0daade7 0000000000001e7c6d28962a03b3d75ffa1355ecc6d3021893b2727a1ccfc669 @@ -98,7 +98,7 @@ 48000 b62fdb21ede8c1760346b4325be6d08852ea3944fb0adea0b408742977fe122a 8ff82f9540381a20ba68681f6e5442df8852cf38b2476d0a6bc61162d6eeabf3 f9590291e90b1145409aafc4b35b003c3226a54b865299168fdc55ad056e6cae 48500 baf6f61655d7a53726d313806841300c1d729f7206f62a267c1b4c351b365763 fde6fd7055e1f6e03b9d327b3c502fc02bac00738ae0fb079f128e2774d0078a 7bf98929914e719c43f044b8bf5bd0cb23c1dc197682fd0e62e517d426cdc1ac 49000 854ab5b99aa89fc7d03f0b2d7f8a54aa7c98b23957520ebc8f4e6305902cf2cd f39213ce4a4fb7c2de3088ffcef3712113958562638395dcfda8ff6da621a09d 82dae721c7e522a846a3964961366f428d60788ebe25f8f649ecd605fefcf2c1 -49500 c964b7057db84d6b9282baff7f2f09dd72fff06dec110201904bfc3846923bdc 51261dc44b1299e50eb364ca4d236b9b5074606928ecc6acae0eec2b6352376d 39f54442526f11b0c232276a00372762bd2481def4502b9db2413e0ecbe42ed6 +49500 c964b7057db84d6b9282baff7f2f09dd72fff06dec110201904bfc3846923bdc e2c15ad8f20ec681283af4d88c56e1433c9c20ccbd11e269ea267bbc2f9ebf1d 39f54442526f11b0c232276a00372762bd2481def4502b9db2413e0ecbe42ed6 50000 fab7500f5f0b1694a9c65a4b02e84dff228af92fa447d810200a3b14c35242cb 194fd02a69a66e9293a06d354206757e2bc23484e3e8cd80522ff71feffbdff2 4da797c00b7fff361aeda31e847b2e8675c4061d1cc87e02a040c7ac34bd198d 50500 ed4e556f251680672e442c00cf6a48f3a787acc589ef3e83019851808ffd05a5 b51a4252fdbf12378dae10ac1c94690365e096f786feadb8e75cbad87c8f8a99 5a366c4316e15730fdc118fa8c910850d3f43ab2534023892dee2c1834c4595c 51000 2410005ccfce88835da97372f39ba6708e7eb10f97a4428ba2cd51e8ee87f7dc 64e4a8d5a545ffb1af7a5dc66be6ff2aa517a99c7bc5d7b2d1d1afafc1b93a84 574faa5def6045f6a923539b36bd27d5f92fc7043c3d6fd783cd3721ac604c4b @@ -198,7 +198,7 @@ 98000 5124c9f250499786c2948dcf5e2be2c7c61b446be3972adbc0d65edc8ff87b0b 7f5892932cd29e78d17fda5c3d15bba0a600f1e9ec2281dbaf0fb1dc67d5e8dc 102458513889b0fe4946100a0d8d3091f46e7627c09a5b5c08a78f2cef987f25 98500 6f507567f549b3b1e387f1bf80ec0fef03a9a1af73147dbbbae2134d6d1633c1 60d73750b6ce4d508dc18cc64adc9e68b6bb7ea4828f09e8fb7419b56eb652dc 93645d925bd3d878b65cdee59ac3349db5af2325abfd0fc696fa8a2831d33d77 99000 64999aa405a2a2e5de34a4c3547ee525b503566532d82c35839a9e74a1389ffc 20052d2448a28485dee72fe536fa8b6ffda1e8465af82491e87980c8f806c8ac 783113c40eca4f0a067fca5ebfb7bf091561cf6751c3e4ebc3473c8c4c5c6400 -99500 3cd60a841f4913bfaf6183237ebd325b7baee3a5992f092118fa49817240a385 e21adf8931f3ee5103fc1a3f8a92282e8bafa9fccd203acc2cb24dd0d28b6ca6 c43bb024c7dd0865bb95082f5864746f7bb41f9c7feca9adfd50856834b50d11 +99500 3cd60a841f4913bfaf6183237ebd325b7baee3a5992f092118fa49817240a385 08f5df63fb4186638211b70120a165898891fdb195aa8a5b4e41bb0f9f0f16cc c43bb024c7dd0865bb95082f5864746f7bb41f9c7feca9adfd50856834b50d11 100000 f0394d3c54a8687b6090333aa03f93f9369846e7c142653524adaa9192b37b7b a739c2cc2c59123a161c9b9864a4c834dfd5021066198f51fde3ba9348d195d5 2045168ef0fde83f218d83274f9bb7204356cee8ee0554bd6824cd9b720d5429 100500 c5ad61c2da15ed8083a3d3dfd80d226b9977dc831c11e83b75b3ed68d2af0e25 e3121bb1573ace63889a3fb9305fb95857bda6e889e9a88aa2ad4c76cc407386 ccd1cfeb131dd0e478ba664886c27238e71ecfac2f3effe52e192ba370e5bb2b 101000 27c2691b9e3e9cc2008da070c0af12d0997c895fea5c405347496c6a37570f95 d465e2fcce8e1b4bf7355b4d87445d2557336354b86db40bc924752796aca840 982d0e97bbd8caa7a1f02b9b2093354bcacbac1d02836a26f15af92f5dd9c7dd @@ -248,7 +248,7 @@ 123000 38b438bda7e108f97112d984725fab27d277a08b1a72affda99b79654c21e0f7 b1bfac6a48327a4005f79408df343adb7c9cb22d2b70ebf2ad79121cbbfddfde 605d68df65abb13b0b19301fb134674efae08e35be4b80d00e4124118e2f7a6d 123500 ec7a4edbed36c3d7a0eb4098e6c6bca397bf08cbc0e0b190a4cfd506df0ac656 7700c27d9c2e7a0360bfa2426fb3688bc8b3ca935de69d15b6dce9ca6b31a4fd df19951e635cc5ed4fc8c1b89b25e72949eec677b0a08b9f4bb1a2d04a00c99a 124000 c3d8229a44faa337d05e0b5311a5dda37b91babcf95e5a8ccefbe872af0bd2fa 793481678c778e8653890f1145e178e42effa2ea7f8e50522187ab298ec6b512 76327e3f2c09f87ca41a12c67941a5caea3779a1c84f0d37a8c6d530d21f626a -124500 1510db798814caabdc90f2b18282456d1b1be40948ba43fdc68e2da017c2dedd df6d64ca6cc492e32e22a218af5a3b802ae452d66ebb018c5d87ccd35489322f 3f12f0e3189266aba9532c078df96b9f6db6c9f4105057feee13485af445451a +124500 1510db798814caabdc90f2b18282456d1b1be40948ba43fdc68e2da017c2dedd ecd23539bb6699ca362d898cfd6181c49ac97b0d9031538fdc0303cc8441fe9d 3f12f0e3189266aba9532c078df96b9f6db6c9f4105057feee13485af445451a 125000 82460aef9d1133d30707bd416b3afc2929a388ec8d1431e92699aa625a4cc3e9 8ac7f7dd700d26de62506f88cf117282a7840236bd66aeb148cde751ee3f7dbe fdc651d228df5a66e58c4e8566034b13fc7c5b9d6e8ba6e7ad0ed1047e0c3533 125500 cf883230f6afd44caf802508a9bce39adeae83cfdaea0ca10c5eeb7e6e0f7abd 269f3d0cfa2df454579a4b7bc758970ffb853aaa7600808071ff130b994adfc8 cc6f34524eeb81b4d04f506e63828603973ec28f2f6eec8fbcc89178f3bf5f29 126000 e36d486bbf7eed518a2a1b1668b516daf85bcfb0359337042bb8c278a5826863 8ebd6563987e0969505718a915e7945f0d26213475be39a4b36ce9928d313935 c139ca3a3866adb6d80c89c4ffb871c9cedbdbbd8e2cc4e273a3ca2d5897268e @@ -298,7 +298,7 @@ 148000 f50a828d973baaefd78a069efcbc42389c7a9d0e17cf4476d6bff763d3b219a7 7d057f6f26c87ead3d5a3bd63b23ad81ba5a9a84258b46921f27f07919be82cc 88dcf2f5fff804ef8b64dc24ea8747bda74ec2f0f0b1c15e5144ebef5543d29d 148500 219d8ce760106e41d5b6cb72360801884950e795cb80c5cb75a4cbee7c9884cc 66abe4202adfd1c91b092dc15dcd702b0e383c2a9a87dad84efc20f2391d6024 2e1b9af96ce01ed55a76a373db6f175aa7939267222b8ae2b81d904ab115c6e9 149000 e13e98351891f9940b40210188016098d67d555ee60922bd710d234393583886 2751b92f77148b0b55b15c1e1939f566749d8bd28b70f9fa9445d5c66b116a4c 679915acf67eff37a889fdec00abfe90edd8d9a6b5195eb403b4a33b2b02f6ad -149500 bd0986d58541fe55bc5615de06174615007bb0a4e9b7d52a6e1de27660ff5e1c 8cbd4ddd59183bf20e4bd2ce22136e8b1109ea2e81fae850281e600a04816105 03d93cf4d27bf5519c826bc4fcf8bdc5ebe413953587f82355c4df6b77346882 +149500 bd0986d58541fe55bc5615de06174615007bb0a4e9b7d52a6e1de27660ff5e1c 075df9893a744f62bc60e850104f6ad60764b8098a18f89eba4418789bbb7c6b 03d93cf4d27bf5519c826bc4fcf8bdc5ebe413953587f82355c4df6b77346882 150000 b0a52b599b482e9e081373c2d0c12adae59742c92c3feb16f2b56a536389c566 2b66e1c89afb06043357c8a702e15f37c6cebfe2c3ac2e2994b387b111852c2c d4e5a3daa131a0afa29967f8ad8f402f8baee17056f075d0c811687b53617103 150500 348a90e69dee425ca95455f04bb8e0a9a5e8e4c9efc06e8358e90069f33cbd87 6296399a3fc3e48c09ff1bfda646b6f19277f2c2562c8cac5c850d691b2c2110 f2e3eb906a46f4e787a786c9372b847e3d667e8b7afd9dec5ec2ad405c5995d5 151000 c2fc138fb4f13487c8f0ba65b1843cbcbfef598d66205495ce12eded834ed5d6 6b3d49e0f596367b951b6939dae4629d81758a560d8bbee402b4258fe3896e18 8db9363659e76cca5e94af0b7bc72a2da150e5e34a80aa86fb42d56df45e2494 @@ -348,7 +348,7 @@ 173000 4187e88e79ee333c661955addb9fd1ff4853bccda1c1f73585fbc4b866d46ffc 2c561a6112ac2531467818ef79bda7fd294cc2d1aca8d700ffaa8ca3c7e2cabb b4b9badb564279262308912a9588870961cbdb6fb9ca5488f37928ed9eb3802d 173500 979cd0755a559b4298c4e1af1ca1ed389c152f6800718aee777431e3b84b2975 817578adb3539145804a17166425c07a798bedb2637e8e6567e77406da8cbab2 e0337c7b2e52ff99af8dabedd1f1912d1a2201e8153b3b984036c26a7fc46ea1 174000 84e476b10a846c1f76cd25ee8721aa8098a3a794f56a5a6e2fa8ea08dd7de954 7e3015ed948fc061ef3955ff4d18f5c9f2ccd86794be959d5e51e604c4ba315f 4282860b30cc16a2db68903e8bb0f3c1dbaa5949174240e3222d70a994cec1f0 -174500 daef6a8cec458daee2a97f145d74867790d12697f424e390fa5ea96c0edc5889 e70b3b4de2ebddde769763e56a861ea73e3a9ab8360f0626ef5075560899c18f e69b1eef08603fd07359c1216cb118cca49ee176a5448a49e9a3fbaddf9936cb +174500 daef6a8cec458daee2a97f145d74867790d12697f424e390fa5ea96c0edc5889 8edfed33a6db9e18b19b49a451c2278d0df8c17b86a5be2703336ad41ddecdb7 e69b1eef08603fd07359c1216cb118cca49ee176a5448a49e9a3fbaddf9936cb 175000 3f6c5c68d024c26235bb054fe0e892b4172a50c900ff7e36a061b17bb4adb44c f36837bd4b44bb99bc4a99acdc71611e6bbfef26095aad173d5b6c2847cf5cfe 31f4639cb01d8370582158623353a2f1843dc7d0d5240035572fe76aff38480c 175500 2a25fd32974c49ec621f4256e89f3c1569734a675bfde35fe0ec4572459a99ce 0de2de8ab8f49f684a4ed93762fad169165b9f29306fddcce37a10b3e0f324b6 4aa307435bb260b7936bda377dc6b2ee78dea1859c5a50504adc278372449044 176000 ca43896b57242e50c5e1b0904b12b7008d63f30810c9d1728929a45a051b1c28 0c0a240dbb5b8d9c5303c2e401b1a9be3eb940a2ccdbd40482b18ebd9d16fdc2 735a67586d8c32fb70e490082bff35c245683e46815882484721852e5cd958d4 @@ -398,7 +398,7 @@ 198000 c65104e71ac22bf228691460ed6036046fb091eed1059ce756e1056bf149148b 3c3f1f86ad2cd5cea8a979c55d01fe3dfcd5d6ec6fe485c3461d65604ad4adc0 02fc4a02986275f8692e7ecccc1264bc784dcc1ccd811bdb1db098cd1e3eef1b 198500 30e8c038e2a43c5ddc9e0f3a030070380cbb09e577ed7d783b83651df9ad5015 dd0bd23d500ed9eb599249629cf07236244c001e0517c93dbe6debe262e7f4ee e6739a8f4f4e629a08189b31048e82982103b7d33ab0b4b56c5cdcb1ea2ed1b9 199000 4b4e61aa4eec7a39dd94aae2c114994fe32185c72050d3908b7fc0860d41458e 0443985e3352c7ec9e83fc34187460671679f71a3eff263956dfdb306f4e518b f6611077832a1c9dd956b563c1b09457d98a2b6b832d3788e30d8319a1026fdf -199500 09e62ab674ae8526370e0059097c80cbf382fa098e67d4a1175bada96d5d87a1 83de440f57fa996de35e346f73bc616137946dff6edd47273615c0a7d4d3d7e7 681274c8b4d83a3eb9b76bf5e984c2dfe0892282f89c2be9fcde7921ebb62dc0 +199500 09e62ab674ae8526370e0059097c80cbf382fa098e67d4a1175bada96d5d87a1 b78d27bf65267b4e1e7298efed4270582f8c9e26d53af59d73250d4862ca4968 681274c8b4d83a3eb9b76bf5e984c2dfe0892282f89c2be9fcde7921ebb62dc0 200000 cd9a04e20b651dcc4518ae71ff5b0c8bc2ed5c6eb3d5fd2196b1e636987c3a95 6160d970d27a8f799d74d3e01630761bd655268486a9107be28b128fbbc9dbe6 e00de657836ceaf31f5bde6a5751a6c4c475cc23f9e78a01b405c06e106b5414 200500 03609721a5de60ab9175d5cf5b9dc444f8c9d420b94814be90e39e4d5411f33a f1625e3d9d93f152c9e351928677f1e8cbca9c6812473c759de6216321fbfe53 d3beb126fd503a82fc169a7b4b2c56840e2313847bfeeb520a91bfc0bfc721b6 201000 f1be5c8c40f967dc2f1448f38a7e7e6a47c6d7e6ae9eae150762642394644f19 562f88889f723e4c4d2a7b0f8b0eed383db6aa34c8e094f88238526206af125a 1e62d55da61d7571fe187cac6157379772d99a15a967492074786b5aecbe6250 @@ -448,7 +448,7 @@ 223000 2491331dde706d72557719b2d51300a41185e0a231600a748cadf6d76cb97be2 f464bf83372078d78b37b0aab9e98a697eb07bca9eb62d65919635d9a62c29f6 16b0949606f4d837cf58811261026d3e7a014f716ce4b8775e94808c33fcb1a5 223500 757897eb0ef5db6fac3a16b4167e73ac300fdf2126d175ddbfab527fe72e5cc6 8033074e1db6b73e123b62aebd8983887d50385f70770bec207b628e9c945425 ff9e7cd3fdafc513b0522c21678c4b6334872dd9c0487fdbbac6d8bd11b3e516 224000 b07c519e796e7ca9ecf620e6437128ea8762b00f16ffb3f2ee2abd5973fc3b21 eb8135fbce4a5f3d73713eb67416be84d02239e85bf87dccd22763075438c693 ed89408882869163baecf310923d4ab5bb880d85741bfb2b4ce322c6b049bae8 -224500 4a873566e5cb9ef793cee37c09f7bc11668091934776eaf0cc5254cf8f565ebc 9484bb580ed6e25fec7482b2f708ee463088b54ee3bf3a06ffe06a1892e70360 ba459cb6f5e554cbff0c1fb05d217e2b67c53583b6ceb3f91f0885ed76af94d1 +224500 4a873566e5cb9ef793cee37c09f7bc11668091934776eaf0cc5254cf8f565ebc e0b9c689e95ff5d675aaafc9916f010b7e5b9a13b201686d4a600c5516a8e263 ba459cb6f5e554cbff0c1fb05d217e2b67c53583b6ceb3f91f0885ed76af94d1 225000 b4b671d3954ba70856a978c8c173096a9db7ba168c8815730cb445ed0b921f7c b16288a5f727839ad38a64139741eba8f93f33035d294365e841e714927ce5d6 0a54bbd14b732d0e359a9d335dab210d8fe841f5f60246a688ea574a19b171cb 225500 17279999d391f86406797119b105c9f5f6a02678f7c3d34d9f272c73dd77faf8 d555247b00f10b1b9825a09d2692d22129b967e1ff244d1a60a756e7b2d9cefe d5fa227b78fcc9305f36c7e8ea6cf1c3f8af9cb61a697b5ec0658d2fea876edf 226000 94d997cdf120719be0ea6a4eb198704a18baebdf13f65e28e51b49df7de1d861 d3d5f6655db1fa41b2f916399ed5f36246ad98025f6943480fe15e43b0a8a034 c5144eb0548d037485fff77b1bf83cb11fcae1177d23d5883c4b711ba0a6419f @@ -548,7 +548,7 @@ 273000 7e8e42c625a39262e7cd8ba81d6042788c5685fb7e1925556bb81d87f23fc9fc 60337941f27f0191f55253642397b4141c09a3796a2e8c972154c90847a04adc f65c9be70852523b31c7a92f95821f306e9017297e04d39cbfc4c8dc3ac0678e 273500 50d2fab64d92e6bd34396a65ea083c254392b73b806c9c23d10a64fa2046ef63 def5f3f2d73ebc5c90d4a3e5e8100e51e3144b63d3de0fed9a6393ba3138f62b 62b9175a2c605119fc599836a2a00fde40a976be16043bf98c0773318e8ad14c 274000 86afbaf7b386a0a5ca9199f42849ba58e03c52c3e14e4796be5a47bca65c3e56 9fa018f6e78596557adb6a6294c3ed8c02e5b07835258d38d00714b662cb88ad dffa1e76e920169f88dd0892436e3dfb2a3a6daa1ec42287913d5b758ce918e8 -274500 f4a2f13cdd599a02991bab088d21e7d28d907caab124755cda5b5da1a0ac3514 3e9121bbd05409156a601f33892ebc88a1d832d59180e591e571cb8bb16d0233 77b22ea80e05caf4ff54cc45a88682693fb8d94f28c18084ec8f8d5774ea4a79 +274500 f4a2f13cdd599a02991bab088d21e7d28d907caab124755cda5b5da1a0ac3514 27a84bde9f23b95957a07f3950a238602bd158eb9fc3d8b7ba88884425fa2eca 77b22ea80e05caf4ff54cc45a88682693fb8d94f28c18084ec8f8d5774ea4a79 275000 a655f397a1362429e51239e663aca0a3582f4a984001c6093e48c4e0a2e05941 c3a045ee8c5239615793c006587052cce7d63cc81c2ecb2af75e67f3c53a8ab2 380849376c9a323fb3a9bc59969eac627adda0498cc3f60c6c8979be719e29e1 275500 b3b6e311d0f5bd738f2502c2684af690e0f71c2a4c55afd5661d069e604ef3fa 0690d029ffaee874f0407d12906116c79bba67f9b8378a31334b25483daadf3f a930052ad595d7b8a70e71c48aaffda01d38e459df8e0c1887b07799cca6bc5e 276000 f24a85fcd91ad6a82056c8a76c2d3d5d04070ffd7d9b84a94ad0d6b8acc0c187 5c21716aa2a15d63d306717b47e86748fb203faeb1c6b19d63a5349176e9fa06 50e49772aa15a6a72eb61487d735b18f15f493cb29145911cadc97c1b684bef5 @@ -648,7 +648,7 @@ 323000 8d6c05ddfebc0476b7ea506c6edd8b1e7a1f04f46d3d44c404936fd8c8c97089 c8e2bb9126149c636285107b6b51a2ea4dfae6a9362ea82e9a01fc5b62317e13 5ad60ef0abc2a5ecac539d9f11d0c77c0cdefabdab5a9b5a4f839ff5d4986002 323500 f92d520784eb12d8ae3c11ad1803d5dd95a497c0084c88784702a5acce66ae41 81e2f522cc756b27794e1472df684a598aa925938ee87027d455dada0d2835e4 c0a590351ad91977c743641c25a96711de72eb7afcae92068bec7d39044db470 324000 4d33cb6af695638f89500645f741981a2b96eb2b6f1361cf4915e9df14639412 0d5d58a71b6fb721127f551a4744091aaafc4740ce74e1e094783488946bf46b 95d0d5cff5e6ec05e646c3afb0267b14cf1455be7cc94c7b2b99caefb333a913 -324500 9cd5a93ac51080a0a3dfa6e7612adebfd307a7c2ea510d033368490c6d25b7be 046e088e42fe85a8f29cf0c61d1d7c57619c29f3a5574cb7284374151fc02f75 ba026961f26ad93bf8a1bd29ed0fd9c00d3b8d20bffedde3c7656344ea5e7686 +324500 9cd5a93ac51080a0a3dfa6e7612adebfd307a7c2ea510d033368490c6d25b7be daf9a838f7b869ca77d3d1fbfa8631bd99aaf46967802148dc7e44fd261a530e ba026961f26ad93bf8a1bd29ed0fd9c00d3b8d20bffedde3c7656344ea5e7686 325000 ea1bd97d2e59f6bddba189466ffe1e7be63f5574f110d5b87ec3e0294b2bfe5e c4d8725f512f352599b2a7506b3c52e78012eded7fa5f6bfd99058046342b2a6 2806e0b32c301fc7e7b517ae6f3499179296a2a56e71256b70a68f44a6c18b41 325500 df8156f044118b84c3e2482e346c5639a19b2f1583944286cb9550931c3ca0f2 4310bc5bfec110e5da8fe1dc798b18d1b1453895c70554fb4d52dd7d6d7d813e 0121cceb434fb22a7fe131aa8e3cccddaed1db6365159c2a4540a3e82bf89af8 326000 d46ca9a4ec0e9126c9b570d00f7b47a005d51f25d9fcbf0c4ca71a29a5f255e6 426c81fa951ff0ceab76207fe576bad3be2279d802d5b95b45881c73827a1241 aa8d073b426c4a1f76a7fe65b5f70ef93a2257a4d8736432f524e67f5845848d @@ -698,7 +698,7 @@ 348000 e72024ff3d0ee72f4f78b7e63ade7a7ea037da43bfa9deab400f6739fde391c5 c0ed8b08b6b7d50bf86069b1e8f6c7c36435817114e27745be63db96b5f716bb e8f81bcd2b69a03b9eb423336a20bdcf659ae0711c3d765e7ac89931fb25d2b1 348500 1d9d9ad6a6b1a8d5392aa6d35a7472fbf80535ee334a043025cc3637d9894db9 101e9ff2c05137c25a2a270055264bfdcc81b290826d968ca94de4038f791790 a3afe000faf5b427c10820657138d0fe4713b009daad3c797c00c35aa35d2d38 349000 bf0cadc56a8359bb703738a06f7a31b305fe7433989e7e4094f379511e27a19e 2a2cfebba2b09215327049cba461b4c56cf54cf31a0d3c6f8b21a637e6a4db5a 7630b9c11e847b125d2d7879d4e6305401fe6656c5c997c7a521cafaf170a131 -349500 78065cd5e2af5a3a4e838289be5d1460605048c1cf2fd1ef9ba8c88619631e91 c00a12d97c8a1cdf4cfd4e5185ef06ebf6b6c58aec4cbba2851e47c51ab03089 2d1790871fad7a3ac8348c2c1272d78f99e71e73ff4d51e4e0f1421815b4cf7b +349500 78065cd5e2af5a3a4e838289be5d1460605048c1cf2fd1ef9ba8c88619631e91 aac94ac665bc7ba954323a07216ac1669f19bcae1541459f41534d8058dfd3b5 2d1790871fad7a3ac8348c2c1272d78f99e71e73ff4d51e4e0f1421815b4cf7b 350000 937db7a154c0d4c5043fe8bdaa0969670f132252a6c6bf8f7ed5858ee11c97de 8c276300614c430a75552e0cca7d83834ce7bccd7ea1d592012300ac2bc5bc66 1fbcff068ae14baf34f3bbce37b16a8cb04bb7d3cb561eff4207b4430d23b8cb 350500 6ebacc5b6fe9ff0e34d64a047981fd170f1b13d40139073e6e65da9a617fbd18 f181abacd6038099f96854c2c0ac8f7d19504609f36dd0aa085af150f21ef930 08c66db3dc00525562741c47770de3332ebe18568d59fd418949a93788b0e785 351000 156a0053ebf2ee2e68a7ef337edc14044503653188c60669ec924fde43c21ea5 dd728a51d7f9e8f04e74e2116698305470591a6e7937b2c4b714193843eeb584 6e541a9fa878ece79546e3659f1a8dee6e9b7a49fbb66073f69e3c7eee9a8339 @@ -748,7 +748,7 @@ 373000 c03556ea141010a523c44868eca127684b01e83f0a76090906728aa34e599931 b2d61cc71ab0b18171db2117a6d535128c25e68031c3c44c059c7c7965d05c53 4762b483ebc34a038245662d1ff2938c9b345ea9f0c43d2b06efaecac6184115 373500 b61ce82c38d812c1e72a830b062bd3854701409fed42cb8cf89d9c83a68aa4a2 3cb1ca2e543310ff8d22cba4bfa2973e264837d2a4a5052cfccde4de4a4a477b 85177a9b8ee909e6b462a0edbb6bf8fa04fb45c20a41242c60cf9e25ca661a36 374000 0a2b671cf0c4e82c857482fd9eae13f8212fabc508c3f6137fd3004038d2fb7f fe35de23fa234b6dae59ea82cfeac3259eef5f8d8878aece906a9e71121ed71a 2d73b8297e43e4800b22a92a402fc7fd9298cf4ae76b7d48a97e286d6833eb75 -374500 31b2c402de5e4f0911f5d14b927f38483fec9234b0ef67efa026a3648ffd12a0 80a419a3787c4ab2a27cdeebbb020eca8f63743beceb73559c09297682c46475 b96f53cb6f434570c6f019f74824dab40cf8df0874c43fa257442b69f43915a5 +374500 31b2c402de5e4f0911f5d14b927f38483fec9234b0ef67efa026a3648ffd12a0 63c1e30437b3fd68e0529230da7123339e9b8d2079576d68221897e443be0e3e b96f53cb6f434570c6f019f74824dab40cf8df0874c43fa257442b69f43915a5 375000 1673933d5b2d1584e3c923b45bacbae604b308007ff19e25999f5a1d89afb040 cdf2c192e290686651e7f63bbadc54d0d8f7b1d2f7208a097807de32159451c2 c5b8ecdcb1e90452677fbcfcdb638f552e39c9f1b842b5e7bce3ffc104aeb718 375500 6b35b7e04b2d788de6e2cc8909ab7fc5470b385905dc0e7b7b8524ff57d7d7d3 ce795b401b8cc3db0def999633c2835436348b032919c9123e1481800aaac88e 16d2091d9d7e6571a6a837e81f4000bbbb3057e229a8999b69ca532e068d84d2 376000 9a2ec84dae6c1b6dd358c57205e0858d987b68bc1e029cae1b8239ee5ac181c0 d576e0d718d3f594ef61eb7be25e4083d1ead1201fe8eaabad00c63938144f85 87b22143efdfaee0e8bcb0ae2c50b0c5b70154d0160e2718f9f6deeb867f86e7 @@ -798,7 +798,7 @@ 398000 2b97743e109f78d910532ee0f342b1c491ae74badc58085ba2a7b9029f9fab5f 7ab0985407419f861b725834b5643d2666cbf5aaef6aa6eb94dc9e35c0f630cc ab4a3aa2dc717532967156a2f29cadcdaced3564a28b3f2a2bf5387b9f961c2b 398500 4df2d83b00fd22751d5fc8b22743c9831701408cb9b788d86bf081c666e389fc 9c545b4c3cac0e1d1f9fecd92ba0f7c61ac3e8a28a8c973ff6026fdcd90c4a43 a5ff589844dbde9cd52951da27d06731785b5bec0908d7dfcf1703a40a81855e 399000 6a00c77818429d3ed4b9bd5211a3cca69cf68c9a99a89f9e1f9e5301c08afb03 44e27a5f4e4c32f6698257f5cd63ecf165cf4941a94f7473f3995b1a3a6bfd82 3a870921ca65e9a9bae895a4a29520a70a4f3ca8178117491427be7642070aab -399500 a6e49cf1def602b4915fbc2b208490f5a84c8a93366582f77ecf5575119e6cab 83be829fea8e1ec65f493f3910ae0f3798b9fbe006e41df4bd927a9bd98f3cc9 c001f8b45cf32c6503760c6905278ee2d55f3035b79c05307b9e446d1f2a5bb1 +399500 a6e49cf1def602b4915fbc2b208490f5a84c8a93366582f77ecf5575119e6cab 5100ff78853bcfc8606b12c5c335c772964323d7486d55af0fe315c05715875f c001f8b45cf32c6503760c6905278ee2d55f3035b79c05307b9e446d1f2a5bb1 400000 641c6a53eaa3c9b94e924327e70830770397343d7927eb713609f14448ea6228 4252f178c0c42e28cce9ef5c0c40f08bc03e3b631a393de6eeff90e7b4d26d38 b1ed7a8cc5c9177b8fb8754170251bca86c728a244cfb54b7c79fd84f025021d 400500 73e034517c9649420d36a641130bf16b8634fd3b2568e58198508e65def1fa37 a13f2b06f4b1b3daff6c10571f25318c3ec8e9f2d42c59f4f19369bcbff62da4 f3788132cb664a0e812910995c536e03da19b95e03d40771fe6a7094afc1ba77 401000 b249ae5082bc1eb852ce420a2361be80dd17228fd17c709761d0f52e81e8478f 679e41c907f1e82c438671466ce285437ba23fa2c845d8c07b43af0829692b69 b5c351cc2ce12bd45cfdfb989b02ab756db45764b8cbfc5c2214ddc999d606b3 @@ -848,7 +848,7 @@ 423000 93bc08b4a0ce5ef57f63ee483936125540dffca3d9d6aa1a24ca2f69df2e2100 a02f084ecd89f843bf976fcc5f5c3d7b9a5c2b5f549c12b896f4985f3fb18f82 28fe299babd0481c8eeb2ea1cec2f68f82ab85f571d104be8d33943008ee5f31 423500 4a09df19634b6b11e40263176de979e2aa0b3aca1a95825c3ad7eac2a84bad86 1a2acd078f11b82d5bfc43a088c8ad652ac993c2478fc2469859ee4885da2ef9 dbfc352c35d85d0d29acc20be05bdf46ab6e6772d8373a7f43c73912d1b803e5 424000 bad4fea158757021f14bfa735be04d0514bc3632f96600b1e4d632efc33c6238 ea4dcf8ad8122d652811cb25f7277c96380f8f3b1c839f63d8085d1aa69f5f89 e33554c749df7d7bd996e3edd93461887d2f891cbc8ad2d8a4eb39604bb40c32 -424500 bc5a6d616947f853ed4f4d9737fa063959d32b8acdd92b11e27dd47b435b38b7 335830fefaaddfa0a3daee3b4ce06b16ac1930cc7b2411dbe831d3c518a520a1 bf4174f8c15c19be02ce4152174b1fea5ac4d471e854c80dd226a6dc098c0969 +424500 bc5a6d616947f853ed4f4d9737fa063959d32b8acdd92b11e27dd47b435b38b7 80e414f560811279931e8906a37b79d64836df3f560e19ad9a9940a2e282ce47 bf4174f8c15c19be02ce4152174b1fea5ac4d471e854c80dd226a6dc098c0969 425000 5b30049913f1ad030235ecd4deb6fc86120b8206e5269d39e56e6c5f1bdef8e8 40b7b38eead88896d0993db8806af19167c6c2dcaf989e571a90cc689568e9a4 81374c7f070937999acbb9c2f4c59cb64f5d477fd823bc45bf158bc54bdcc9f1 425500 1c8c6b6e080abbbd1aae24639ad147ce9dcfb2836be1a4d5520ebfb3a9af61f1 c6e3bb5149886a4050a284990303b89355967d534894ec988b9b9be1f451edcb 15249bdd6d51cfcc7470babf6556d8bfd2494c18e57723a4974660afd4af2554 426000 9a644de2cda849b362daeec3da5cc28e71652c6a2bbf37151d8ec938e728f2b3 a38d8a78768bea93a802d40ee5d92753afeae17ec5c625515512f4284d56eb1d d1c2c919b2a3e3615ff340778ba6d3bdd2d0a177dcc679ed3f27cc28a8896731 @@ -898,7 +898,7 @@ 448000 4fc96bd14509bf55922cb5d8ed4cbf372f7ce991646e5be3a086204fea0c368d 0fff78f76cbc925b62ffe927d50cbc02dc83fd9e5405a3a77e232b55a494812d 67e09df16c3fb0a8fac40ee153922aac6983631f99a341cde08c05252fc4e11d 448500 742e9431b2ac6f0ac24e58cb8e6088ac1de875cda8f16739a78e0f1f7c05ce33 d892c34609acf3eeaeb32a384985fd2da70c4f53f59f8c459eaa5e74b3d61c40 2997569447cfd809ddb51792a754d7b497adb3c23ad38b2fb15082e4f09c53c6 449000 335341c810fdea9e158ba78a542922754fac2e0fece92c27559d14c5c3ca0267 8d6340cdabfbfcddacf2991913176b17513be28b9472b744e7a64b2f2ca13896 b0cde57f64c7794da94547a5341aea6fc5680f24bb3188a01171ebc61415471b -449500 2b97e9d073d0b8922e73a1b1d6fcb7f8dbcb0e22fea6a707d9faa2afa1cddf8f 4fb82487fd05bafd111f032ee92e9864534dc93a7d0cf994928703612d816f4d 1c5d2bcb3165e293bc70060db78a5cf299d42c4815896b65b5f54d742923f434 +449500 2b97e9d073d0b8922e73a1b1d6fcb7f8dbcb0e22fea6a707d9faa2afa1cddf8f 52066346f6120422b739d9d1cfd8452a00c55505e0b2b9805351f7721cf253db 1c5d2bcb3165e293bc70060db78a5cf299d42c4815896b65b5f54d742923f434 450000 a6448ff3de412e8784a4d0590120e0727c3ef1c6e98af7adec4b687e10c22b40 b12232c014cf52f4f8d0fdb4037642bc1ce2a4d709ae37b91d908c9d36830fd2 d0a08ef423f57c6c0488096bc46df33cbf920226423f7930c27c813c9d34c71d 450500 32343305ccca111d5b0396816091f1f169314acfb4974629e7beb8680523cd47 36cc9b37d7962e434782de92543635fb826a4d84fb5260ca0161680523f54272 a2ada16c0fce347e1158c64a85eafc07d49f6fdf5c91d0b1c1d973c3655d4f75 451000 adcb05f8f053823db604b6278de320da2097890b386fe67c0104721e6cd76954 c63c045a3117df4fef3287be2f66c5691b700b18b42d3ba60509faf162dc9720 642495d66438cd4d827f29aab00729237d60adfa77f4fb3e74640b459b79868f @@ -948,7 +948,7 @@ 473000 c2f76403fbff7b3601c0b2bc71cc00963cf0b012e09d6be5d8fcc12a8f78c8e6 be2ae59d51ecc553798bcd9c82f4e747dfd1782ad18021dadc24e4838c2b0666 0422e26c8a7eb63d5b18dda0c3efe7bc646e75332413430c532788704507625e 473500 5f6ff7d98fff43942ec210bff0555d74768aff3e5fd5ab6e0b546d0bfea79921 b828dfae2a89c1199e2cad79165f815f8d858620d87aefe17630048ec05f0bbe 5c85d46886845128e04460eaf50ade9e4c8f1c3ca6456e74f76061492407c9e1 474000 2c191256f2a1ea617517c81c3133a47d2fa264586885b2ca6a7b782f9c78a8bf 7d0b4169707e36667345fa68284bb9eb0dbbb726b9391ec0b3018c71a343ce0b e3f7ea82b53a82fe22c0b553fe30c4c5514f5a4df2bda23b6c315d894612822c -474500 50b6c4f4c1da30ee2043c4a18b0dfa1da9aa33000be4525bb07b2462d8cabd2f 9939b0eb461196a4ea22dc6c0e2d3c776cdf08673694e3d5a520bb644df71e9c 5a123ab254ec518a34af619ae78a6caf68f12ab08ea1cf8bca8f9ddcbd5bb862 +474500 50b6c4f4c1da30ee2043c4a18b0dfa1da9aa33000be4525bb07b2462d8cabd2f 097a81a5771e9db71271cc6c0ce12a4053e89f2975e8523b6dde6556c170e5e8 5a123ab254ec518a34af619ae78a6caf68f12ab08ea1cf8bca8f9ddcbd5bb862 475000 2c38054fd7a02ffcac28fb8c53ad84b68d50ef30af030e597414e15b59bef269 6faee9c17b651d220534dc8c66c0345d162426661af23bd6be235d1c0eef73ab 68fd23bcab5583cc821cc1e2fdfbd4630eeb912e69d8d3ce68fe22c0d8d55881 475500 8d981411752ee6b44f12860a9975ef23df0c7dcb5b5c621368be19033de81de2 23fd87f81163c7f0580a7eaf5f74b7501a868508ba60f47836488f5b72716608 2efe456c536da42607c5d527fa75633d20e07ed10e8d747064e21e866f115e06 476000 27aaae6fc04f000f25a467ff5c2fcf62a6872b3ea96a3ca445e0947bc912d050 061c4b35170cf452518590f1e96624dbc031e5eec8b9de1acc81a477bbaa18a0 026f245193b14cd91226fb93bb05307b3f84c121c3b4cf979eb48a4899e2329b @@ -998,7 +998,7 @@ 498000 0bc8b494b42efd68080fb3d3d83cc8156b56439c10fa789814d751d5c4f7d9dc ea1ad23e7f85ec30d138ecdf527a5ec5ac6d925eb888ab061b9ae24e48e60b2b a9ff67fe494fd28395d671744bb1d60b38ac89b53e4f66eadbc03c5d5dd31bef 498500 5440fcfb2e8888508c4fd6920d0e6c7c1f3f1095813d45b691edc3a2a475722a 4c2c9c60a2a43f9786004a9b43275656b60a70c9643d6c676ede104b9f0cec12 de98b78d64b182ef34488808079e358e30189df43bff459894d14b47382d85c3 499000 d84c475656720900a0b3765c4ed57ae1f0ba17238d34ac17b1635c6c95064750 236f102f6f2350128916d138401344233a7483a0dcb1eb39730c6a5fa22fed3a 88c61322be07f9b75d7a58001e4e7460dd34bb2a72214e949d28f184007d0c97 -499500 8b9aabf8cb60c29c4b60a942812968ab80ec48cad4053de2624d42372a547756 540651876cd6a44a6de24fe75706bb959b3a701ef281c7b8a3ba083d6e329dfc 4d743db021924f24501d20e27564a7dc2276c5978e0000af4a97eeea092703b8 +499500 8b9aabf8cb60c29c4b60a942812968ab80ec48cad4053de2624d42372a547756 4fdf0de2a22bbd66bcebdd844beeaa7d5caa353352275953936b6f7839497577 4d743db021924f24501d20e27564a7dc2276c5978e0000af4a97eeea092703b8 500000 bb94f21cd879e992217888fa56f0cb57bf585f8a41f845fbb46872fd7ddd4a40 541ce9a7c0f8771a84281db66fba7cc2dc43fa636a39a840fee5bdf987a3348f 254e33a659e25fb647aca414051e33f03899a896d032fcb7d307b90c9080d023 500500 d74c1f7510c4307c942906d4c66ce5fc542f2a1944659c1ad37a0eb82be11751 976e8ed703619833f8d78889bb8a3a71a06392e257b093a01f7a1b7036d22fb0 fb7d68808d45544296419dfd89b69540cdb6df0917827d982ebd72adb3042843 501000 3383f0c0456774cc529b5b0633a947e0708156bc873180f56fe3c32008c8bdac 69c86425b5c47c2bc3a9fe3669b0a80aeeb72bad8179676a55dae6445b7bdd36 22618e433ce9b9fa9bafacecf096c50bb49978a2fa883ea1dbcd2211075afee4 @@ -1048,7 +1048,7 @@ 523000 72d57e281db8b4a79f566fb587e448883bc1d1325c9ffc2931f1100b63e5836c 00fcd8bff8a5e19824f0e98fca489d02ca2d27fa2b4fd9a73e410d935a1b93d1 cde20a46475c12e517a4326e85632a956c9f5a2a3af22c84ac9ffbb0b088366b 523500 97b2d54ba68ed4a14ca1fb4e4b697b2bf8f7d0332272af4531a72c94c35dc932 04d4f8ef5ff03931eb5c0eac18894a9a7ac8ac7f6bc0b34b43420ae9d7802a1b 21b276e5d11eb1a8331df44a4cd05c46d1868c573f3f82c8f047f67d3858a7bc 524000 f5c96b25808ab9cbbcedecfe467e163e3bd9d771a8efbd3cc414c7adf1b7d380 c11e17455d687b0dbee864879ffb41fa6dfefffd54d339fff58dfa99790a78f9 b2bafd7f61e6485200c761f5ed481e768563fef25f82469c0c67ff1d1cb988d5 -524500 cc5a17d877467df92ed0b3462d0031003c642f64896f4019da641d1572d693e9 7b878f323c00d5b6d0f73d89cff64319ff2299d310a67a2d046084a77b411101 8f9c19111567dae6467b3d76132c1f786e278a040099af2ff5354f81f7c1cb6e +524500 cc5a17d877467df92ed0b3462d0031003c642f64896f4019da641d1572d693e9 471a8ebde906603f5c054eed0da8b69aee53c35133712be35b22e5b4a8a3435c 8f9c19111567dae6467b3d76132c1f786e278a040099af2ff5354f81f7c1cb6e 525000 1b009804fbb8489d23d5512262d7536375873ef933c154a7058ec1c934f61892 d583cc3f0f7f01c67294d2e98d28e83c81824cee30d1252816a7828c0461f350 f1cced480702a35ee83501eac3168b6331c2a82ecf69f2387597d21eafb011d5 525500 63de360342a1abd256b2f4a3f1a74da8e5bfff409282c8d06cadfea596220f9e 124aca94373c78ba91a8f1c01d89d5bbeded60581199d3b12ac66b76c37c112f 35bb495f4aba29424e088ef8b4ebb7b4b10e69902ca07c65f83057078bfa8561 526000 25464aef8a123b8bc5dc4b9f6b83149c84511a88da41f7b5f6ddf4cbd340dd30 ca911108aa51b78a806e58f876767baaf341c9844f31da71959ed4ea2f87d62e 53ad3900a8a89b100539e325e86c7a7a515d77ed8d7bd0bea832a1196d8a2c0a @@ -1098,7 +1098,7 @@ 548000 bf973366b8395a897b56bb1f9160f8144c40ba17934fb14b46d2bdbb32715fe5 a732ddef1fa97dee750cea03675a6eb9557af9ed6314a162f5ebd8ded9407698 d78fa85231b0fb69790e643c079cb7c34d1c114fbfa8c1d7712b01ff71805749 548500 c2f20ed6a252cc714238efd5531084bd5555ab8ec65169a86c9a0ba97b2a7eb5 d029d1bf6706c1b298d9f7ffdd53a26b17704433c42683bc02718ef33d2d70b7 a2464ef54773a2cd6dfdbf05187ea2b0e1723b3dc22e31e1480d414a4bd13943 549000 7e07ebf8ad3697390d81f7381637048377f461e46030c8eb1feb17eea4c9d3dd 1f2183d7618eabf7356a08a0486675b0163aafe13e6b27bb6179fdaa59685fce ecb2f323e8f843183dac9fda0ddb68aed54277bbc0e5de60b2ebd0ab37a0cc95 -549500 7ce04ee7a21eaffbe862646c3a301460da80cecad0e9a66a157bc1d0c335a18c 989d7ef547727ed49f342ae3681e86247ee5b6ad009a863ba0dc517e7977790d 7745d4f12b75c63a7213bfed8d46bdb2d0ea5f75d9765aa47ce7a689a456be59 +549500 7ce04ee7a21eaffbe862646c3a301460da80cecad0e9a66a157bc1d0c335a18c cc27c95b13f1ece38002d33c7f55f371076fc10dfe1b48754e3418a0222248c4 7745d4f12b75c63a7213bfed8d46bdb2d0ea5f75d9765aa47ce7a689a456be59 550000 0b717011e4c14ba25388b6be779ec7a7fa2939c68a49ad5fc8cccb32a3fc96e6 d95f6b2500300308ce3f44e53c38e6f0eda793b3e1d96f698cdfd8d70888e277 1446f3a94e8fcecd1819e47eda64932ab5f7cd161f4801b96d751bd11bd8edf9 550500 b1388fa70e3a79143b985bbe2587a8a36a3ce7f90dbdf93c312bf375b04204d4 2f81d9add40226b4b3d3f2466a2330e412de80bc31cf3242e0f8e8c1f45f1a88 2e0c55c354dbfa29d8ecc9611013fd969f5a843b8413aa79d4b5676d9a79b7a1 551000 b0f768d89c0f0e5929e41afa3e9711a2f6dd04c71519c718ec5a4851f13ae4e4 2b1fb05c01f17b3eb7268d552a99acd306e4dc0107985d6020dfaf4443dadd73 4ef4d4f9a0fe87fa3b1bc65c582fea5eb43b00e4253b97bd536eb342a3dd3457 @@ -1148,7 +1148,7 @@ 573000 2cc24da51032f6db15842996a46a0f01e17e7c1fa178d34f4d520e57a1dec5f5 814f5511a95d2112e9d6f5ff9147e4af6d2d14c674008901888a59d77adc0127 97cf19530e18aed12569602045be833d526fe06530a6358c515603de77834b91 573500 5a412746451823e5fe7cf63b331c59b6b1808d176c1f3562631755a1aec62267 a8a55f440729934a987fa7bcc21e4bed9ae4cb4fdda5bba05f328d33c1c93dca 5c9ee5926501ab49698c54a8eb543b5f212b2a65dbd6b3d71bcbd04e9798c411 574000 4e71a21262bee73564eed3938de4c2a673ae763450fcb183bab52fc3739e9307 f5fd0fbd347c9146a3356914145926887833b394f0664b2e5d098660848e8b5c cc86ade9b13e059ed4015a5481ef18d63069f67a52d67749e4abe1ea165d62c0 -574500 bee3161612969794e4cc7811c35fb9fd844623da6a5b5f2dc38f32d50728ab90 ec00c96d649a6290cd6b929e1a71251e4519498493fa0ee2020ed494012693b3 baac4866328b40b281dba068cb2d3682cde33b52ef2101df94ce1883d61bdd9a +574500 bee3161612969794e4cc7811c35fb9fd844623da6a5b5f2dc38f32d50728ab90 d97f6edfca11c6cdd984f126252ed5c39587feac95f4d412a947fb327ee9f4b9 baac4866328b40b281dba068cb2d3682cde33b52ef2101df94ce1883d61bdd9a 575000 0560ddebf2a1fefe36dfcbf14c0b9e2101445b34e79b4d2d2f7c329c1dc5c97a 58a5850806bdc8a70223873c23aa3a5975634c989d8ef4f4f78fc0b71c025a59 2cf5c97d7e1dac4ea45e91316928d92e4b74440d2c059bdade7bb7c1cf1d45bf 575500 077c9db46dee33b8fed0edbe55dd09ced1c04eb22096d9a7f0a8238b764a9005 a527ce25eff18c724535306c76670e1a44b010183ad970d41e4168c7e47e8ef7 db44f4bd7201dd8e1b9deb53e77c7a93787e9a992ad6b9446a3eb12f28bebeb1 576000 f9762a0e8b01efc84c09bf94e0eec3168852cac22bf5e0e657957ffbeb857c08 41b866640d3804e09ffd386d7f6b0cfcc5e95c65991fa0b753c875676eec7c37 363b120084d9530ed7d17cce535866b196dc4d39aba6ba1cc875778afedad3ee @@ -1198,7 +1198,7 @@ 598000 92b359d658152c31b8c2f32c4509f3ccb1cc18b4544745608da9a230327c109e 3f75a2b9ea70de0fdc330ebbc5f83301dd507c4e0fe536200402cdf30fd28a12 5788ceff503809b984ceaf32a496e51bba2374ba415e3f459590a1655cefffc1 598500 be474d552a4f17ec673478af48534ad3c65eef1752223ed3012534dcc4274db4 9c304d0d24348fa013c7223f1e05fc9092a773e6da14920e628baf05669a0f08 67e9375d6815cb71ebddc38da5965a779ecc8729333b33bef2c4646bc611a7d4 599000 275ca25666031af015670734cd4fa02ea0e0b099921240991498e684bc234940 83b44eaabc822a3d26f168dabcbb175357e1a37a025813fe30d5e6560418dc4a 3d2abb751cfd15a5cad35fcde5b52b4e82b32c11a567fa0860a25f83b69b5cdd -599500 f20a2a85028e0a3c65f118e50296794ae25821fb5dc0a59f415305d826a827cb 937a759ca109521f0ad2dd2bcabfbdcd08508b97d2928a81bfe79962c59f6e27 504abaa85e6013ad139e47771e947acf3c858fc49e0b99c5236d7f84723f3c6c +599500 f20a2a85028e0a3c65f118e50296794ae25821fb5dc0a59f415305d826a827cb 3dbc1d013d4559da355fea928c27fb17e921124893b7052f2aced8c8ef9c9085 504abaa85e6013ad139e47771e947acf3c858fc49e0b99c5236d7f84723f3c6c 600000 fde9cb0677887e2f966c3be87d1780db88353977fa2e426249d9b26b01be1db1 74fc8f58d336eaafad2f515f0b5a5eaa679c82160f2dc54f35fed44bb845c395 3972038fd2bc0007c3ca205a21ae11ecb66096006ab3cc9ac2350e2da7f1c506 600500 ed2fdfc9d3b07cd7e4d4fb46b5cde484b7ea5cbd436608698ba0be6407928d45 78eebaf2d54a3f5ef9c98b58e75325a263d7040a85d2757eaa6fcd9edefa8bfa ab51bcdc56ef14d0313de8553fb8ddb2b9f8d08f8e9fb42ee67b2365e2855cfc 601000 3a7b3e53a5c38bb7d0600352a71701c8c7b961a9936d319ec1f39eacbfa317ea ae8e3de2cdfe471244ac6698534f60a82a93e59b36ff22135ad57f5ffa9eddde 131208c6ee4f9db5dbcb53f6b21d9de4b1bd8a4ac785684e91ec23446ae01489 @@ -1248,7 +1248,7 @@ 623000 248e12a541844945c6b91e45f24d7f63db3dfb41016952e628c647bb82562c91 d2dcaa98eed5db5e34581c8bc52808819c5cf98bd564661252e24fb7f98218d4 2394ef40993563da36d854a0f5f06c0af1dce3ae7274d3a3d6655264d8e1da54 623500 0f6332963afce6ea94d654d103c3604c724a5a6bcdf6e32bdf9a708d10de519f 80f5b0685f010693bff7453273d0cbef3d878e9753b19e05a5d2fdb4984f8a0a e7705c345164e7069e9529e3e5d47c12222a3df70d0f1300e39f12cf6d361337 624000 3a250bcfa462ff8b750d0a725962879d47832f0c77b46dfcd27e3eb4bf352257 f75082779f75cba11e26f60eb9556caf48daa15221abc2b4a83a1cdfff9368f0 7cc8074a65f117e7942ce910dfd07339069627e317e1d4a31106ed5847b218b3 -624500 6a0ceb40f1277b4289334b6cbd593aa5bf593160ea960b4887e40afd2b06d767 cb0565ee88160d6c0a26057155cdb2f9e2b94217d229cdb627fbe0aae9aed145 9802ef2c8e15d18bccf977c41463ad4cc0ff9af9dff0a1104194dd4ff18ab9c0 +624500 6a0ceb40f1277b4289334b6cbd593aa5bf593160ea960b4887e40afd2b06d767 54386a3f312db13d8151cdb5ff628ac2e9e13d897287b553d581a6c74cdad388 9802ef2c8e15d18bccf977c41463ad4cc0ff9af9dff0a1104194dd4ff18ab9c0 625000 c28164fd18e1087787d2e3c7d67b8349aafcadfbf815fd7547fd7ae8da9e7937 319cabe08b33898fc3421e1cfe329711de03a92bdf21828a59594e813e71393f 894a1464c80bf83652ceab26af7dd40661b1f157f1a1f77be34cc57fe01f0505 625500 00c9e51e1237a00f30562f40f8d7696876a62523a7888f3019103f97d27c2afb cc7d1fd4e2d9a95e3a9a7e23f44a96f6840036265a29cac5b4a364ae1ee1b806 de6b94caf4e70ed1bbcd7722a4fa7e0cae7b2490f07a815eb2b4c9278e0b3600 626000 452cd22905dce67c27114fdc0b6ca64f4127abcbaff999b7aed68be214fc9313 c969541e23ade41ed8ab864eb6fba11ab9ba5c6f29374e666af4912c2c076de9 1c307caaa8f2730c6bd3c202a15e94a9004ab2b6f0ae24d58ed678afcdbaaf00 @@ -1348,7 +1348,7 @@ 673000 3109a32670b3c1a796f9c6cdf5f3744848e8ac3ef0ee2ea891fac0eb69223ae2 baa8971d22821acd1fee4649f702edc70cf1b072517f4b69d6bf4060cefa34cc fe51c93dc781185d8a9fc3efe07271096264f598616d69407d0d85ba17ec633d 673500 8064bdf0c36a535d5d7788f901ac0713b627e2f8b80c4b20d26cee0daf02ee6c 5548c9d616e98ed4fcccb300d3e35a78d66e61aa95c6465fc66a98c1e40405c2 b5aa467ee5592fa80eef3af90b239407d7e31fa4c6cef603ef50598548666cd1 674000 b409ec86b27b1a828acc7f056dcece326a7892314cc5b0d6682d21c06d4e4cc5 a25e0ee6404f9db371913c15348e3aa8a9ad4b3cd99cca3fbf1e8f95b6e152dd 5d62ac697208e75078a5f465f2feda182ad6a988ce953ff4909ecad0feb96e0d -674500 0c8142e02a8e0cc1667a81f4c4d08ab7577102481f73d31b9d8c67589874e970 0e31001e8d410c86f7a525b201f135bf6902048a0a4a25d3f283b2b1ca9e0b63 ae1ef0b9fa438940e44e4804ba785686e04250c675fd4bdb76b927156bfeb9ff +674500 0c8142e02a8e0cc1667a81f4c4d08ab7577102481f73d31b9d8c67589874e970 e615eda6aec462572a43acadcbde8bccd88e07fd0029bd953e04d7022dfeb355 ae1ef0b9fa438940e44e4804ba785686e04250c675fd4bdb76b927156bfeb9ff 675000 f200a64f03ed78fdfb3a35be9133cc144cb7621be76f0a470a6cc451d31de7d6 2dec2d8e6cbe5d122786b9c571751d54ba1d597e23dd4aa03ebc50212c68cf8b f841d17cfcbc629ee12bda00e988164571dd7a3b8f9c68951620a62f378050ab 675500 44927533602536ec6857a62ddd2e7ca31a05c733cd0699a078c5106620da51f3 989564e602ccbd682fcf993e4ca7691f049bb6adcb099860f9577a83cbe436bf 997061d34d9e259b99c7911924177d59e78f2c86d0a57743e5ca07c1f1495ad2 676000 1349301af96fd291f3f6cac4d6a6a94779a2015ee9d63989d79c813e7bf3ec81 c196991fb4a511513fcdd4300dad73d556daf8eaaea1411a5c4b0d0382e96d45 e332be471e67a22109327b11ee3002dd4d151fcc0ea5355d6189e3529bedba04 @@ -1398,7 +1398,7 @@ 698000 8a0878bcd828268633df687a5405b2b86051640a122f616231d8d6146d4c2ab2 27a9f143cdcb85bc01f31868f92a964337c451cd1a546f93c29361f245aff07c dacf575151c578d5b0f283296f31337bd7a1b976607fd492dfb0a88e0411b9ce 698500 afbb603de0da6476915e14cf182c6c785ec6514b17d9ba7bfa74e5a228f6d8e6 f730e6ed2ef1334071ce63f9ac851de557383c98b40a72f8bdfb29c49bb7d571 70863c81dcc8cc482907c82781ebee38697b9c01791ee71132212a49ee4cc875 699000 4e3bcab244d1ec2528890ed24340027a9add680ccac038c42e9a5b4880368a57 1b7062e806e70df560b7dd19713440125dbf814412ff713c5bafc8776c443a60 7caf82dc9c49db7c7baf08b8863b2577aeb18da4679d6a26ebfb620b94b32fe1 -699500 69c03ffa655f439caaa38a36031f45c27f6afa345fd8d380064ac4106a47b9d6 0522b34e7ce87f078124a74b1f26e25c44cda27ab10ca9884d777a91cff19df9 770d8310ba9272994252c5df67d39d32018ed69a29cd7cf734a9e8458412f476 +699500 69c03ffa655f439caaa38a36031f45c27f6afa345fd8d380064ac4106a47b9d6 9835287f527b8d7075cb42cd361e6048b9defe40cd855bf186641ac16a40cfa2 770d8310ba9272994252c5df67d39d32018ed69a29cd7cf734a9e8458412f476 700000 19c87f86c5d859f1d4ba642097f626a5c6cc8420f1b438ef0ddfc52d77b5a7ce e7cef1ed642d40f49563c66d9428c699a66241a86d05aba5cb6fc6d6218317a6 0c8c3f94794122eb5e615582ac97d2bec3b09ea1c5262861c7d7c4db6734d2a6 700500 c22be0aa764d1e0d90432e726ecb95a769d691a7de81ea480c1bb9e74f43bd8b b0c38cfcda8312393e4906e1068c7a323defc33624e99c8c8f918771010a417f 422cc5c68ef275f1f6d93266cce5c9fde6c342e1ca44a94f39c3555ed4059759 701000 b2505b0ce33e22fc06044bc95bcf1bcea363d91c541451ba7ebbb07079c9b8e6 36066185fdc8a919096d36245786b921b24ea4b9ad0949d3685c7d54fd3faeed b8821bed4a54d18bfa8803cbc988a6328ffe601f98282b71ae2ae265c57de22d @@ -1448,7 +1448,7 @@ 723000 6fafd8c865b3d0bb05f18cac70fb93007cff223789fb46958b55a205ffbbc959 cdc9d13b0b9a5fa827d2572e9c3232f498e8b06ed8627199c61db9525469fcdf 2bf56e3e72f5c449653b64c5568cf6dec1602888a9e77631b68b814e5268d29d 723500 6ed55084a271a39809b6f3455a08d082fb7c56ad97427307ec207135c7c16ef3 cd4a3d7e1dc9e293cecbcf14b969480c0c2f277819e9eb2286d1761df7320694 a0ce856d8b19fa250998213ddce8e945e25238617d9632b1345fc257bbbfcf4b 724000 c1b649d3101d61bfe8b949f443e1035a3d5944310f83e94785592c4cc91552c7 452655726058f019fcf400a89e464688ba4bd0fcf267493e54748b146c7dbe1a c21245ea304822f3c688f672f6068b2c67de6c3f2658a9e9cf7a509cc190c489 -724500 21f5f4bc2fbfbfff183a3eaa110c1e3f826eae2f58d32242919026a8d1ea6206 27b9e765e888343c7180fa9b5066ea254d8b5765b2d7e4a51ec62a8ecf02c6ea c681b8a5fc3f74d6349426ef2f01340c85c28bb4fc8857fb74d284e6b3bcdd75 +724500 21f5f4bc2fbfbfff183a3eaa110c1e3f826eae2f58d32242919026a8d1ea6206 d15908ddef7626667600c5eedca9119d82e0da5f4cf56bf6616edce895b38d9f c681b8a5fc3f74d6349426ef2f01340c85c28bb4fc8857fb74d284e6b3bcdd75 725000 5db006a94bfe731764372f332c2b23f9863f7741c0aacc4d92769f353cb4a4d3 db57165deffffe98c3cfe7b95e119d0253a6e984d11fc2b1894ba4bb3010301b 93b86dfe0990138a22c323a851c26bdbc1ae9d2c71b7db6468afbe0052c96799 725500 f313538888a7b2cbf72adfff7c6aac1583c44b477c27810920835e1f36104ec8 c811a4d09b2afb0e9e70bc9416e58aa2c3dfa4955ec4ecf03b3db9b65450e858 2a5cb9561d2f20edc69cc6010ad5ca11a07d77403c5f090e404bb65a879d3e29 726000 f9f289b08641492431e4ff87acb944092bb1fd4ae405569e0f3f14e433aecc79 5c10e47957ac47afc2bd4fc6daa0c7e30f127f0ebdeb1b52149756d9f996eb76 770901cce9162461c95f8f5506586075d2e0b19b82f94eb83bebeb8733146728 @@ -1498,7 +1498,7 @@ 748000 55f61b3e6a5434428b1a062ee86523b68f5459e7615c29d83f01eee310ec66bb 4927588d5f0600d0a418298312581aab6d41144ee3bb87a6875d7b11c676704d 92182c1111a64f08ba98870b439de9f81627d117715b3ea650bfb5fea98feaa4 748500 cc910d9ef1a087c0c9aadfb77da9051aed5124b7d072b976f4d34dc74f842f14 f1b10cb29bf15f5280b2506a480c07a610de4dd63212ac5fb1a33894c2fc0353 d5d083bee08926e2bc17c9aeec940906bdf6b0f37ea7d6c2c23b2d4d881185be 749000 70c48f09a23f35a244e22e7d43f245a20d1d171bd3958ffe261363536f92a087 5cf7c04ef74572576b5debed4c20f3446db017a0360142b325a330909c904b09 e24e68210d96e24cc04563ac6fee29b4991f3b13fa04d3b31f83506a03fb2a68 -749500 33d54681aff8149655455f3331792f7a4582c0f0a436b9d3ec0fced7a525ecb6 95e2c8c804a409d62130abace845c696125f8a938bcebe60a45d9c76442fa6c3 9c16bb3f870ee8e50900d7310541f629e4e087ee581467f3dac27c7601a9a881 +749500 33d54681aff8149655455f3331792f7a4582c0f0a436b9d3ec0fced7a525ecb6 382f51b24f05dcc78ee7b0e02e1389d1247a30489fbc317e6588238d78cbe478 9c16bb3f870ee8e50900d7310541f629e4e087ee581467f3dac27c7601a9a881 750000 8e0b562cbf9f5d9e0539f9964745265261cce019e73e22cd0db86f0dc7049110 03a1b08260d16527973210066d867267be1f3d4692f3bc680afadd2b1653f995 4c77b7a73824f489244a9a1ba383b413f23b932a2b7cbdfabe707ab95c66f5fa 750500 a85d11029aa82c4dfcad63d3e6e32c4525f9d192fe8ed223ab9f05a3fc4a5d11 1e1aaa3b0c05e04b991026c5a9b6a56228b007a6f936902f7a80f1b8f48eacf7 79078573a0874c4d42ed9497435e6a5e9fb2a6ceafce103a28a3f4b0f9753dd9 751000 bc48dc5090db1a9a8016b89fcef45999f9d6c87c8982dc4ed52e4b583ac2f7bf 94ffd27371d8ad63511d87f728731b0513ca8d8b948d8b777d852ea9aab4804e f0b84e3b614d9701a514808bb116eee3547821b42e0d2f6d6a3d2ed2863d951a @@ -1548,7 +1548,7 @@ 773000 53c1e8e472ee4d6bad6411fdc74d9fe4fe2564d0baf1bc5107b9dc4ec6262afe 8d48f77bfb9b49f20dfdb2168f0abb988b8ddcd8e9e62ac35ab0a2968b912986 e2aec43709ca010a47522638f0624907813138e1e1b380f7bbe6f180e628fd60 773500 2836b1c2239c528ef1ca59823417c6ae51c93040e1a5e3ca11742dd10350d3e6 16f14274772f96d6d2072a33cafd5c8f9cf4bbe37111b3f620e04bfc42392829 0a71b92e9860fad2bd7f294d271466c0e66a73c057d4b8ad4fb7e0da53894584 774000 69a397d817d7155b644d650da51d5413ed2c133a3cbe2b54bbab7ae7e5a82914 c50ff677b8441b9a940984cf5ddb46f4b690ffbc9703ced2b163d89b929830b4 f8a641d436f1f789a2f605267b1acccb8e851946b22731e19a4aea620672b3c9 -774500 e7569a38cfb85227d2d2189a89c59518b64da01e2fdc89bca8e4759269fad47d b72f3010914018a60019f151631c660311b949fb400e20696b900603404cb82a 131c227374a68de26401bd9fb82fdcd47bb947602a40990c87ad1830d5c95b10 +774500 e7569a38cfb85227d2d2189a89c59518b64da01e2fdc89bca8e4759269fad47d 3bc601776ed5afb50fc51058a988d114287afa8fc4ce04c8d09215ad8ee3e9a4 131c227374a68de26401bd9fb82fdcd47bb947602a40990c87ad1830d5c95b10 775000 d62bff072790320b532267e13d16eaa2b6124b12e9dc9704ea8b3472c33a7584 2ccb3c701d5d6730cb7fea0a703c1228f75c58b95dd167e135689d020e686cdc 4434ccfb2b3ee14daec33d99f0e1a4f1e48f35ac1bc270a796db881fe872258c 775500 69206115fd6be6c73b95c85875329472d8550ea98bbcdad27b1fff5f13f1a383 1044c0b51ee23082e8268ea9f57e614ead985939009b2d6595f866bfd407c543 36c58dd2f153bb315fb5ac171b2d7ea231c405a995705a9aa5448887e72c46d7 776000 acae9ada07a40fbcd1abe244a88eea4497d892f56bc6c47c9a3256960c48a674 fa6f6390e5912cac9e116a1dc8ce23ea3acd3a45ab8c372f265c2a813a1d43c6 766450d063de6aab1e43fa81768c6d063e83fa9f1e3109eda9cf6dba976cf44f @@ -1598,7 +1598,7 @@ 798000 f3370335ede3598caea04a87041fa7c1b51e5c9e1c5e0d50bf2bb136a64cd167 e6e1d946fc72e48f0399f980e5a4f7e544b4eb2997739223c355e3b15af48fed 647618c6d3effcc52dafc6a6705ad58695436d48ef25aaf8d684220757bca52a 798500 8f2f93e0248a8d8ded2c5106fe5034916127161f1a554e2ce307c5b6afc3e00c 2db41c24fb6ddfebf0b3bb5d74fbc1cbff4185082e7c22ef66c336467c652180 ecfa971d637bc6ee3e0f461ddcc77ac59a408c30dfd2ef3dae3d43e16c15e5bf 799000 5c376ff3e907391741b0ce9601a65e616d6183cff6bf744bdd6597c455b306eb 9b86110172b3879f17995b766972b505bf547f40e1113cdb52533357eecc4ef7 52173724bc690d27ecf672136ad648668707cbe81735bd2a77202a7c765ef32b -799500 bd143703c66bf324a5cbf67f9da778755b4f7a598450c328fbb011d1eba4d96c 83480b97e6c3221fe90a83591ec104492b37896fa34943c4f71265cdeb5659ba 07f30ede5076d4d94c9e1e8e46bc5402d1fae50effbdd0a50fe82d31e2e5bf5f +799500 bd143703c66bf324a5cbf67f9da778755b4f7a598450c328fbb011d1eba4d96c a4c63a77ffa25dcbb59ef8e829106f61ad3875ad2b9485ee6653a83691bc9ef2 07f30ede5076d4d94c9e1e8e46bc5402d1fae50effbdd0a50fe82d31e2e5bf5f 800000 e951054363c21bdb8e2c65154dc8453a7ed6908ecb10ed72fab814899d3cd345 9a0b2888559918507acbb704a78888f3293e34ec18cbc9961ac7842ca297984c 8252634f061e18d4e82e3f91d044ded94e90d223a7de0a13b6e772c5c75eb612 800500 956b9c5b3c055d3ff4ca81de618186166629076e317b2bc429faab8ed5a9bea2 9a80628c0558276ab328fbbff05e76501ccc20593000dc13d57eb3ac4b618838 f65f6f7cfec65d2c895982d1ecbe70336c1f8405783317db7207dccb3a5b0c66 801000 3abcc1a5f4b6411fad8b518e4e0266bebf4d74ec36400e0b242e299aab5d8d43 6e72ab4aef323f82c48dcd697cff16bb1f0ecb039a1a892a74c57abaed498d92 21dc9821cf54c46293bd6e575907a6e5ec525713f4328952b95cb5d9792d7131 @@ -1648,7 +1648,7 @@ 823000 6631367fed6a7ca98d2ca58e0ccb8060e9e0309df1bbb5d76ea337c386f3066d 4ef109d1b5fc3ec978f34d66b8d93cd3ba0b278d7ba9c6ddf4fc3d56039e0fec 88fe2323f91fc57da58b494933952f12aa11b292953077ee9664b6aa32d7c3f0 823500 b924862a40ef19454769b776643bafafdf407500c16dd73a70a61ff7d033519c dc8d2c04b3dc1785a7a76698674830e8aa8371dcb815083d849851ecb47f1805 7232bae203573f6c6689058ddb2b4d2b06ac19ddba5caed5a07b08c3912d6ad8 824000 d9ff8b7426f57da2db3d9f855572b493eba90e61b0ff3b40beec0b46578679cb 95e502ccf5b34258f239d7a5aa86f16c643e189873979210e0cee9c5acda128d cd794aad8626da79dea81ee006ca4c52b94aee1f55ef2912cb2f4807c75a091d -824500 b668014cbc4e38dbe8870d15c7ece604e8a698dead63136af5954cc403a13921 d79c1357567cc361a4629f57d3bb01e99929680f5597fb20e976ed9da246d732 b3a4d6a91d00cd7ecb1890525ca19214242805f0ddd04555b4899008c735337d +824500 b668014cbc4e38dbe8870d15c7ece604e8a698dead63136af5954cc403a13921 b634009a41de61587a78dc3ab8aeea26b6d107f5e59df2e927321f31c2751347 b3a4d6a91d00cd7ecb1890525ca19214242805f0ddd04555b4899008c735337d 825000 ab26157df7834e458aacbb394f8f6f34fd489cce3c7a1e6251289401acc59062 73352b8b59b8fdbe1d83e82c2da9ed6282c5788802e2eaf3db7e7647e04d83c6 219be8d78268674671c9953aff79dc2f3bfac601cd535dc6839ea7dd550b194a 825500 4447fc4bfa77499510c1f033998de510174732f103eccea27ffe544577472f5b f15ba38703c021fa9419af02b8210ad9a9658b8866f70cfd734e282daf996169 9d3ea35ecad6a8d38b11e387681a7b6f3ec972492c9914e5a75093bc32288bcf 826000 8b30104ee7551d9d564a9142e2334aade0c93f1fe7846f2d2d21380096a5a1c0 dafdfa617b0bb3f7980b4df7dd4d0159144b7973976db5e60a28308c0e9a2216 ada7a2c9ec028cbe84830bbbd0e4b0d4b503bd78b0567dc69a6e74e91ce59ac4 @@ -1698,7 +1698,7 @@ 848000 c6e8ae1f92209bde14bb652bc8478d5592d0f6741c3d2f2f232c037494d81f70 b7c0aedb71b645f0501319a9842e1fac4873184f50a0c5b758fd9f2cc2547a1e 69295041487a60c8f00f631c3e56114c9b348f5dc7ee790fc819631e55fffa0d 848500 d302c73e4d2ce3e318afb5cc773b089956501f00f64de08073bde92b2f3a99f3 0a8901df9a3d00b66ed1bd0b117645237b61fd34c63fc45a0604daf2ac932bea 4b93992d98ad1fd9b9557cdc1568803133e96fb9dd51878d5e6958a170a02867 849000 0ad8844c1a45d6846464c00e9c6853719f80056b6f0fb70821536a133432ba1b 6478dd9c136dd28bbc4a49eacb7909c179abfef94618dc6da67adb4ffe69c6dd bc7dcc71f8572ab902c0c42773f396d327657951178a1e3376556a12c8be2391 -849500 8ddd724ab7ab24e5ce2f5355c2c4bea780fe7a2b4a01fd04d6a0be5bbcf6059f 54da6435a5de096881e00dc1907cb0b66274ab5b976fe6b67ccdb70761fdfd44 f71d51e6094c79459ca8b568389c91d23560f0daf00a023a460315511c97b09a +849500 8ddd724ab7ab24e5ce2f5355c2c4bea780fe7a2b4a01fd04d6a0be5bbcf6059f a8ac1fba940445cb8dc5f6eec18d1546f36bc441db187b088b1054ce8236d17b f71d51e6094c79459ca8b568389c91d23560f0daf00a023a460315511c97b09a 850000 b5e0c35c2d33ac37932b6d187a8839f1bf846817dbf5f4c58b73418e9a93941e e9f2c9230ca20ec14c17a35fa24d9eecf9119c5a38809c420ef099d9cd4ac61c 58c376de138829f5c2cdc42a78ed1936686cbb0cebcaa4f0c2ae8bf8d9e6f4fc 850500 7c1ea7bb106ee4a55d64930589f44b2e9fe63ab9846eb3caa545fd3b5597ac0b 9b2b304003bc1746f27de0d9a7cadc9dca7d6c87b6cd5c88da09f45282298480 4adb35a77d7e23f431c34032f15421dc3a75e86bb025ff7a470eeacc0feeaaa3 851000 78c3131d573b6a70a648b111fa904b99707c622bc56f842297953968e50bb804 9dcd68f3d2c985c324ae53f03582ffce484a70724e2c13602f84099737641cd8 b7e3f52bca1ede78075f9934b0bc416ab5b99ebc2dc32ce3007f9857131a1bdc @@ -1748,7 +1748,7 @@ 873000 34692e36b62fdc785dd9468d43a0a637aae66ea75c592d5c92e3b79245efe449 e97152bec752a6cda91c4153cf191e6a04135a2d824a6ef8ce6d64f640a97fab 0ca6b7dff238551d4fb8495eb9cc85c22be5098f65245cf2da2ddfd4d4731eff 873500 af2ef369df933f912140c7a4ba01d3e33ae803b7b2f4939f8a98405fa4127b90 3e30270cf39cf279ffcf99ad4b0cd55c85872bbf82654d03f6a9a40867ceaead ac2375ca321b3bf357d1bfcdb51faf0664c89660abb3bdfe5e63eef55c14202a 874000 7f1cd90d997b5a1da4daac3691082770bc7bad48acca998746980f0b57ccf21c d7cba24bf85848378fbc0f655a1795b9baea22b97a29b3bb1b74fcbdc25baec1 2e4b750cd6433607f340cb88227e3d9dea81ad791931f096c1f57a9ba4199adc -874500 c15fe484c8c031d1327d24f1b563bae0c6ceb1f81b8c0b37c1a3a6d3ea9c12a4 77f11329dff67de4d40f655a73c71a76e4637b274af5ecadd6f8f2ce7e265d7d 246acefff1f0368ed146b59c7ae6e3c74ff4e2c0e99c996942fa9b109f5ca498 +874500 c15fe484c8c031d1327d24f1b563bae0c6ceb1f81b8c0b37c1a3a6d3ea9c12a4 532b3b617b128a1da69a7390fa37d292771bfbe039436bc7f34cc60d51ba1289 246acefff1f0368ed146b59c7ae6e3c74ff4e2c0e99c996942fa9b109f5ca498 875000 6d606825c8c4902999704cd9839f60f072743c33ef3cc8fe5b075e15ad6f521d 0f98e7eb858a741ea9b7f9260142cd07d98f3ef2fd0f5897f0dd1196506f28af b1c7dd3bc7112815fd1d6f4c8762dbcab3e87cab642dda4c9447a037d7fadc53 875500 8102b25248d5cc9fc5e8780fa7782a5f37113d5797ec544bcb6164d922d91ddc 5331a1c3f2f1e95e9acc0acb83ef4cbe04785dc7a319ce069d252cccaaa748b8 55555d9c896142ea08db6eb683d05328b1d060bbcb4dc5aec81965a740737360 876000 2a6d640eb47cbc93033640e4eece162640b36cf256a1cafb406e2c22f0c10fb0 34f34e19ede327aa5be14240436f18ead4abe6f226c1571429937380247402d4 ff5805c276bef1199b7adfdc679d716f30cc2aa8dd02c51a9c914f28424d4e1f @@ -1798,7 +1798,7 @@ 898000 e303ff088305156ddd6d2b5d0c239e459d5175585902840d3f6713a40b2490f0 4504065e186d009dd784aee6d957fbe295c8eb1c3bca23d860a92c6be32a9e16 0d624b8f5443456d6afa38e9d8f65b44e63bdde4857b2dd7d86a79657350ce62 898500 4400aba3a75afc73ab3f6f8328a179905fbae533dc9a75a67e8533dc34da8281 f78290551a6f5db3989f2c6f6087b5746c0419604cca77a8bcd63268455aff2a 493c6c9538fdd84f4a7ccdec7da1656bf3397863b566af0d053cdea28ddf4429 899000 30d2245ee16163dcab5b9b71fd37c6e0a1a5a3924f621dc4bf2213702878da82 83f95bf132b64bfdc4bd75ca04fd972d5caff941d36a7792f55f478fe140972a 828367c69dcbc2bc8db30bd6a79fed31d5b0f465c1597faa85b9fd0299a7253b -899500 f35505a5677e09578cbfc9c7900bc40b1add13a8df9f70781a95b00ff972add6 a71b0bb9f424c20a026bd94aad9922dbde345382c0751bb892ac7cc9cf0b9722 d6831c7b98fe9fe24be7e4e5e01e511c9eaea623a3c9378acc6f424f4675ed31 +899500 f35505a5677e09578cbfc9c7900bc40b1add13a8df9f70781a95b00ff972add6 c2e16965e43b94444853f16cb48de52c406448aa65a2ccbad61163a18f2529f0 d6831c7b98fe9fe24be7e4e5e01e511c9eaea623a3c9378acc6f424f4675ed31 900000 e37b70b214a685698666a18c3de3362baf0bd158b6f972e77bd306e62e7e4bea 7a6f099828ed54a20b3b9565c1548ce0fcfa4de8c6131ed4caaa629d96e17864 5a5155ad28208bc00f7e8cc3e48057f389d7e52db71d4e98ed747b4a58838f81 900500 a2473a95b679ead1011918bbc526ef833ee8b03a5aa3f3e11198e30d11d2efae 9736c820b1d63362019d39a77218d604205e38ec79a117c117ad12d1dd1f0075 eeffa6fee4c89d0b7bf4aa5816c8f2d5c4bae46c937fa58f1815c732aac2de4e 901000 dda19f6a2f7a7da12753b2d7c334e3df7cfaf74a44ba8304b3c5f5e05882afc7 bc0f02a893b0609aa80e08392cffd1ad14ee3b625837d16be6869b5e405139c2 4c98b101813e05bc7c83bed737947884c949e7b299a03b9416e93491b2b988ca @@ -1848,7 +1848,7 @@ 923000 438bd2d6867e38f68f61f9dc64952993f7492e39771516520eedd7d5d9d4054f 40b95ef95e78ae4c9e99865bd4e7a4f7d106c8d2aba90f54aed550f14aa9ce17 ca62e3ac3b194977d03c66b015c7975457db5f6c849f7b999dca95161d06064e 923500 6c205a2902c4c350df7de4e96c6815eda103645b9181fd9e8bbd6e53b5ed843f 9d8c87504c9db8490188c7d8fb0e6aa1950a03a80cd2bd0f8baf0297a73ceb27 c3cdf41378c92bd85ca01c42ff115906b51ace69f122d3b1b6b4a5f922d92098 924000 821de00a7dd17becc9dc0ff750b9e74237ec391e9e2effbabb71d33fe96e574b c87cec5b256635170e6428e3040000d705decb654b84a7ac9d1566211e18dd36 81890bcab453994fcd82bbe934219d642b127460aff6fd52a37c957bae1f0ca4 -924500 fc66fbb75f4f01611cc4bc86249e329e5f217ec40e0f64f332ef508f4d524fa4 13e45c01e9098567eead7d1e2840a44cde36926ba83c270e6bb854ff079fe864 af0db78afb9fd983d191c7482aef99fd8fc3f83ddc7bf969250a88db0cfe3e8b +924500 fc66fbb75f4f01611cc4bc86249e329e5f217ec40e0f64f332ef508f4d524fa4 1a9d440004523707f292fd87bf077df59c59e3d39e7f799604765343197f722b af0db78afb9fd983d191c7482aef99fd8fc3f83ddc7bf969250a88db0cfe3e8b 925000 b290fffcf3f8eb763704f79a4a6e5fd76a853a3cd013efe2e41fafb9177d223a 3d9b89cc34b988fb0d1df0135f59df3495da0221277ed3abefed3558408ee132 ba6e53516126dd7d723c11edf28c7f60eea4c250f4d9183b09cdcb74df0496d5 925500 3a1fb804b8f62e4c394b4fb34b250986d195b4a066238eec560443219bb06a25 3024ae8c2825c85dfe675f2b66b4576a6ebb934166dda6a12016fa8f79f12a63 4d687963ecedcad164e63649974289bbf8f463acd84b790b1aa611ce7fbfe681 926000 819094082ab3ba4c3a715880ca1de8c9b7036d68224202838a077d1c48a0fa33 afb6ae704efec0cb30127cdc4c608245d88b3bd39e3f09b30273420046051679 471b7d7e14436515e046998af8ac65f3e9ed8339f31e292c2c1f793eee400ae3 @@ -1898,7 +1898,7 @@ 948000 de7bbfc82a59fa0c6691020204c4916b9b102f66536e061a3585824472bbf2ac 2de0049ec5f874e752ed146e2c7edf63f6095e53a8a349ed06c052a341d87e1c e9f976098892480b5662a211469875d3957bc09297ca5445ec32118373d80d62 948500 ac2e0e3c131538ed118a3123795a2fe51803a11c3b4b08a7e47981884b2f62cf f870ed2d50bf25f95cee956ed54551f4b3e92d54abeecc3f0aa5cc15c5b10a80 9dc10ba06c9e3657acda84f512e71e2623e92153f355fc85f292efbd7fd27293 949000 e1e69e1b1b21e4f0a18b04ac9cfd9f8285db96ff6f4e9ba2ea5a454d7b4a51cf f08f455608a96421e2c42c6fb44348331ded8f44536def80ddc2aaea53f811be e9fc9f8f87793b08608e8537c9e2ff487a6a0371c40f601076866cafe3819747 -949500 5be555320df6b2e99d8f77952bb45df07ca3f9f1bffe4a4800a156af93d0c629 5801c09b3c3ddd4fecdc69bafd4b6ed5599f5b4c3d480b6cf9e319be1aebcad1 77b78279551add5e0960ac20f6beca37c1a18a3f4d8bb4afa3ee783d5e05d95a +949500 5be555320df6b2e99d8f77952bb45df07ca3f9f1bffe4a4800a156af93d0c629 989e6b9308da79b0b768c6216474a6d1700eb89a59771bec804e8caa61089dac 77b78279551add5e0960ac20f6beca37c1a18a3f4d8bb4afa3ee783d5e05d95a 950000 e227fbd4fabcb18eb1e600e30654fe09de863f77f81c7634c2815bdf909992a2 5c5fdf4e2450ff02361822c4702cbecdd0cef3c818ec819a8ada6c7791516396 2900534be4fa7b504bf8f6a1047adeced6250f63dd441cef1e1d684511f104ac 950500 9c0dd1fb0034c4a92f5b77bcc7e5818dcccee55af147ec6edccd499465ed8502 94d3663c2526c1645a1e7430614a665a7f35183275b7167c5893d6b1fac7b530 8ffc20f33c23109237f1f1fbafaa719c87402f09f90ad22c73cdf18ce0fa5cd1 951000 2e932c87fedb78048a70c47b4f33425ac91e5edf91ee12421a4dc6675c50b084 2b9e81d117f74eb48f91f5ef0c75c345f0d1f8685b2caccdd0e739f8a4d54d04 aaec22e07e78f82d3fd5336adfb33c5cf83ddc95df01a0ffe6624bc222724d80 @@ -1948,7 +1948,7 @@ 973000 55ddd462f4830ae58cef001b80805828381fa6f01763551fe3bf41c47bd06e33 48e54fb3fa548f31b6b8012129886ad14d438d0e6af6a05a82230ef00d80905d 5f353708dea02d4fe10525399c823d4a027a07834457e02f86b31404ce12bc09 973500 0a3ae4c2d5937527041e62d202f1f3eeb575062e464a3566f6e3d4e9811236ba 5fdd512a86c7668309807bdb7146dcaefa13813bfe05f812935dbba0c7c04d62 1c086557709d579b3773cfa821406e79327a0140967713b73241bff2a2a28d08 974000 55e80cbd096b8eb1df3fc9fdc1a4db0685f135deef48c22236a3be1df8d075af 69b5c8b41f2e5b28a329e3cb10293ba29312c252fd97e2a6e9257b2cc225354d dda002ddf0995fd3a122f864c5c55971d5590d465f019685337502e34540dabb -974500 57983b1af96d8dca16423e30c6feb4451abb992c59eb7daac3aec47f0c10404d fab5f619f442fac58344026a8e3bffca1b547084e5aea670cd678ccf1e4f7be8 a3859c46496083689d30027b40cac019d0daaf008145d6f168139dc7fc696bdd +974500 57983b1af96d8dca16423e30c6feb4451abb992c59eb7daac3aec47f0c10404d 67c8b4a9a90a48fbf8bd43f41d290fb38c4318f00d177b76472d176fa4960836 a3859c46496083689d30027b40cac019d0daaf008145d6f168139dc7fc696bdd 975000 789decbf3352b728ca2513866842487ccc080040c301c20e219a6169af17f8ad 8cd8670e216d098ef817bc6f4ac83b0de623fabe5b0bdba2bd588c28b40b7b04 bbb05c69cd49f0bcf5a87329c75f69efb90a91b5dc0ed931fa22d9b41992d3c0 975500 e4955374301cd615e606fa045946f8e1b09dd05be8d4cb90ea334e1f0bb9b0bc 73bfca0d4522e57aad1864c6659e0906da259865cac1fadc2d4c8aed47f23a12 ae8b93c18324c8f49fa73de8bb19e75ea2c04eab0e8cbd71d591ededc819b2da 976000 911ee9db7be3ef0f0932647a9ce131e21d7eef9ac7c3a40fb9da8f3d328a3313 a2d82537257e03c3256edd144045b2767b844046c07dcb75122d4100830f7800 b118c6acb7d2f8a04d82083a9f25d3f87e468a7d1d363a374bf652a3db866520 @@ -2062,10 +2062,10 @@ 1030000 60c0681496f782c6d175671a609d285350517adcf1351b13c5993690101b211c 98d79fedf73559704a2bc76c089dac5604ca5de734220992148b7419f8cf48b6 d97446ac79f5b498bc81d03d6563b6696b0f5a4db11b3f8bf4d53e625ef228b5 1030500 c7290f8c90153a075f2957e7479522dc8b16b70427da55f51e6aeba41c86dbc6 82ac3d69040e6be1098fb05b4a50f88979b2518135024c0a129eeaa33e2a3024 8c8ecf230f23fe7364f9dbfea6dceb042a65d4d2b000e1f5ab6f84fdc01a2553 1031000 10d5f1e3d7ebe4c1e0ac25c126939110ac48a9b03d8d48a299fa356f802cf5c2 2e2aebc460ba1bd99198559c4e3ad33b126b0e19a4dfb42c5eb35b6ecaa63737 6245b05af1438876861c8e1775f8e135a021ae14adc7ee5d3c4ec8b30cebfd29 -1031500 36faab3bdc61f3100234c00b4b537295768c2d23815813d169ae2df6b4c0c769 2f70b464e2c6a88cc966d392c0324e4dbfc50ed6a85f02f09cf14c2485f2f84e b189fb3e4cb7e86cd172866294cfbc4cb759bb8f350b8835a53ed7ebd419e6f6 -1032000 017ec62875e8d55eef392f0ef3b1807a184c872643ac98bd38ee650618b77b25 0a3b5e3fccb43dba43fb467f8d0d07f8921629fb0976b929ca4da686983a2deb ab1e4677a28c6dd28026ec874949eb480dac7ae6bd6d9174974cb125d430a669 -1032500 99ff5e99a1b61800e956c385dc96e653e42d4a04a4793ad7ac502b518d5213ef e3eebf3aeb13c3f16888f9203037f931efcc0441dbc8ad833d275461417e0b5f e8356d391e5214499afeee845cc93f2b797280a8c0f398fea831edf5c4055149 -1033000 a92f1f7987e1e91d78a8c107fdf9ee32a1e5d6c05c95ec946c3e80c645e9c3ee 528ca55f0fed1a23181382a79cd0018929612f84cbe0aa4954d28466c548f655 7b58191d1e838bb06560bbf57f883a5dbbb0a82da83c2d80a2f77cfd30cea5a0 +1031500 36faab3bdc61f3100234c00b4b537295768c2d23815813d169ae2df6b4c0c769 91a7fd1868b39ef068572d0fc34cb88d1ace1f7ee9056c0feaaf39eb95b33335 b189fb3e4cb7e86cd172866294cfbc4cb759bb8f350b8835a53ed7ebd419e6f6 +1032000 017ec62875e8d55eef392f0ef3b1807a184c872643ac98bd38ee650618b77b25 c6d29b289e5a207d5cf5005bbcf92b0a178061d632fcb55446c5df96b4a56745 ab1e4677a28c6dd28026ec874949eb480dac7ae6bd6d9174974cb125d430a669 +1032500 99ff5e99a1b61800e956c385dc96e653e42d4a04a4793ad7ac502b518d5213ef e25e7ec45958f315088b8d91d968f31aa8ad1a4516c8d10022d148973ee4c13a e8356d391e5214499afeee845cc93f2b797280a8c0f398fea831edf5c4055149 +1033000 a92f1f7987e1e91d78a8c107fdf9ee32a1e5d6c05c95ec946c3e80c645e9c3ee 010c949ffaa7017730cd93d692c33e4f3cdc5f118dab1e526648e7fb2db3f2dc 7b58191d1e838bb06560bbf57f883a5dbbb0a82da83c2d80a2f77cfd30cea5a0 1033500 030e3cd7b93b70312a5ec6cbaac9f567358078422f5b53c197cc86d2519ab70b cdcbf7bd8b051a4eab6b41f351cd6f9573b8a9ae7408b1ab633457ad9491826a b752605382827e7074e446aa45510fb7432771a1caf9b6122717fa7fe004d9d7 1034000 d15e32207ebde3b7911ebb3db34ca537b2f1e15cb1657544b30d13829390a3ba efc04e7c16e0ed1fd15e5d8c9068b77361e03feab82ebe7d73e0240877bfae72 8e618f8996635c8a7f62e323a584b9e33761d1025c887ff02e72119dedc270e8 1034500 b9d7ff12e0b634c98dd84165b76639fc92b5c86cbf793d313f0fde5d203eb8a3 57c20ce8035f48f0e305fc7e239f86f33d6382b558d68a65e1a72eaaee1e3087 9c0eb7689751f5d0419e6735d941ea1c63d785c1fdc07e9b343df87344d86c95 @@ -2078,3 +2078,428 @@ 1038000 d4914856b50ec1c683af57b7ad17dedb0d6d496b1c3fd9e8ac44254f5097da80 da3578419c83ca27aea9e5aded3f037ea1796130d12a7031b589ca9ffe5a5fb0 982d02d1adfbafaaeef3ead73a8b760ef8cc4c18913aa2990df5578627e0c63f 1038500 4ef9de168a9cdf6e4074492cd69b15621990a9b1a731154a27c1df6c6eaa2f93 da919b8ccf4214f215cbfdf08bb7e568cc9329097d2275628cf7e870d8c1e9d3 93617d68bab22ad289cde335ed90604618792bd53cb844254c861f8a0f1e38e2 1039000 aabc1d300ccb7c5e20f99c58679d5801a86dfc53f489649a78d61d2780c1ed52 740ebeb1c46972cff11c9c488dcedb4b03b1b26af5bf11fd2f455cd50be8453f 886512ffb3b7ce603349d7ddca6f133e9de3b328f097b2a9b54933be8547e4b5 +1039500 1983a2e59f7e6248803264d5a3d5d5d215ae8532edfd5d532c3a87d5dff90aa6 28ee7a4caf5585b7ecba4bce8b0a067927189f91264b6f61d40ed0ac070c4fea d36c42008a876af88c8756e4e1b81bbbd2967f15cfc97a9caf7e70f7b1c480b7 +1040000 f3e2a0b028e42ae82e49bb92ea4695af9e8086a42b0fdf4703674709442af77c 766f9a2ab585a28d9fcc8a5b1a5ac73cce4a34a8c35ee49017ee1d005a2d5506 415a4eef34189b66dd62945c61ecdddbc6617979b767027be748f1045c45929b +1040500 5232a4ede825823ba1165ab340ef035a7283332854465224f7f46aec64bd1ead dd2390fd9549367fcef416b69e21b513cf2ea238588cd4e493b698ac0b588306 c419f9db6f156969425a0e1a9a4412f7d3a1763f9e045a9e0a628ddf9cbb6852 +1041000 c35789e22c2cfa11323d5db2a608eae5f48439961d510bc279d1e6c2222e015a 1a30dda49c5a3b1e8fc9c1b7e8c40e75ef527f13e83a398a41cbd3bed39c3a21 652e2ffc28f71b7bf7d1fdeaa36a973cb7afa0e8ee3964a68df5bdca88444394 +1041500 fba66082cac0bd85aa39fe56c7e3f25b58098dcdf71ad064bc1293c6a5be326f 9365e5fd1c055bf56fc73a599ccb8ad2d71c6c889da5d53a15ce287c9907efff 130f197d253f4486061c8b344933d4e6b9888af946ebfe5bdfa0d66be7afaa75 +1042000 f960f144c580e372fbb20aebc7c7693e1647dde35631165f03ceca0402fd5394 f309ff65eddf5e85b4ea098a6d47a0cbcfcd553aca7e5092af04df2660216ecb d7fcea9da8cc94742d3a5e0b39100433fe0ace25f448153aa6fbe9af7aab2f21 +1042500 bc1c318eb954e6ffd656b40aa2034aaa57510a47c70a26d4a64798b4242a96c3 f49366d3c65adf67d855e79a8b5f321bd43e969beaf8da624aaa444153e34804 1e1cab22f6b5519ae4265e0283f1079b2f209ce8c5288e9d2a247084e46a41ae +1043000 8e675a672f934f13443b463b09308f9857256bc5535c144411f5af2df9cc7ed1 320a8ccb3a1d44f07f16bf989a3348b980b2502e9dadbc1f7467779384e49ddc e2fb1c4a95ba177748c3732b0420eab1881b51fe2874b73e589cc7a08d565065 +1043500 cc6046ba969972c5af0389612e75d8b289c113b4900681a7b26a19ec120f95e8 635b5848a1345f1cfe64bdd7d463d9cd09f9d075bfb2d04cfa805ece973dcdd3 172d5cfd06424e6ecc06b0eaa4b441d4257c20ac8826f65b6cf20a2c57377b11 +1044000 df415157f07298c695d76b1ef2bd2ba6c6459dda30b6aac026a8492240163319 1430ac6d0d2753b35eed3cbc8885cebe65214a9179480748ae5c3857bcaa72fe 2d4b8f1a666c3f94f22ba93d18eca27b596ca5e66cdc3e7385c68fa151feffd5 +1044500 dcd1e4bf92385427fb83f6430ada423739f5e79b50d9d54d2da7682349099d4d a565daeed39c5a0623391382793c6436a274f39b859797088521d7ae5df1b7ce 513aae8157476d212e99a19ca1c8e88008358b43434156e37053e69100e127bb +1045000 579743f2d5aa7780e4db1b3015190a235ba6d5f4e5ebae8d00142032a3db5ce3 310cd0259443ed2aad00773a3fe718fe05e30fa6a79be5d48600bd0dff0ea09f b7ecada86be2ad137b8e1f896dc2673f40b1e834e09351d6d40de96f32494ebb +1045500 8a9aa0f90288d2ef021cd7bc0ff79e851b3027305f2ef6c90bcb67be1d2ca664 01bc88af745ea0e33c5cf5d22cf1d6ca2cfba216e43b16fe090d7806b67da16d 340015f88c93cf427fe0ecac9385c31f6be182d4f06007091144e44ac05624ae +1046000 c72ccab7669a1c77adb96eac880c3b8b5505f76f54875c9ce63e5ec0a4466e52 c5f2bf64430c0a2cf5b0ebee135d44a84b63dc5161e5b6e3bf22994c6a2448bd 1f87c9f3afa87d527a897813ed828532601560b0b67e75e1fd040af0df8c7b18 +1046500 3573934e82012b7ba458286dc61fc094ebaea2e6a44b6f75c628c223610200e3 0d902f09a9ca3b972e3820f74d83df311ba5b35e8c6fa1229ff8da974aec6e63 f360249b4cdd69f59573d023c5faf8b0fc1e6a0f5f9967b96ac34659ee72ffef +1047000 9380a4a18403d26d8ed097c1ee3c8d9deb40423a40c75ab5990088c7e5c6be5c 175b7c5aa160a7cc32bb88a1623cf5c740cd1963c2d52c2e108005e2c895a4b8 dfe7420133a6092210dfecaa74b30f29f0c980f74fd6205c0ad325b69d5cfe94 +1047500 b3eb44a8d8c32ff51230776ef692ae2df253ea590e3ce094021965a48b923a9c 770af1fc30b4a95ac9afc82aef5959f9425d91fc27dea24aedc5f1d1bbbaae6d 6f6dac8855fac467d526bf3b7fae68e33a594acffb42301e8cfbc7fe6838163d +1048000 47a84fcee4a633f734f7197155fab73b0d6066752fee07ba18a3f1b2d2aff2bf ad93d2d3692df1b72ab9a4a0a306962127780d114e8ba39a8e102568906b61df adaf5605fc79d9153a915d37541d51b61fb849c9f0bbcba5164bcc1e930c9aa6 +1048500 d80b9eef45c8bcdcfe112f4f398aa4141888fb4bf69794b419757256f7b9bfb0 c252f3198f625fe91d91dc5e3032446956d8de987b00d5d3ba008c3e092f6763 8518048f6083c29fb1e001fbe778ed185b87a988dcbe0c61cfa868365939b562 +1049000 be562935777742d22230f2b13f1d885fcd3f3966af8baaf182673075aede0a9a 7a8940e33f897394ee39c5f9edf0b04d71f28a3e07a65011496024b64a91a70b a90c364c7302fafc86ce15d51b08167f9232c44e2a7744a7a674508a146bf7e2 +1049500 450bc6a5f1b7d502c9a86ecb08ed3bf26c87149f6b6242deebf998ec1190dacb e496811cc6cab5c2b821d21ba29b71ca4256b228889e352e779a82aeea96df63 64fd7f1d78833ec1260e9b39249e9957207845d99bab950ef921a3a5fafdda46 +1050000 a835e80973ca0240c06703a30433a139d200453a7296c24a22b62792d17ff2a1 ddb62effbd97a0caee235037f11b106feea0f693a75d98707f43cced9fad30c6 95c578d836ef48bd93f58757d6c3b093acaa373f9654410f85dae1aefdd5d3fc +1050500 631b74a56a6719158926aca09aa8ab8cd89b61e563a5b6386ec6de5e782e926a 1e1c4fc04badc617cc382d6aadde8ae735277694e233a225634e2be077c97a2a fd4f6efdea193b035f4b5947404483b6930997bf8089d1661d9b9ef48c9887aa +1051000 1ec8fcfb9b6d6c602e2775686f04f1d39a768064ee6aeb65930bfee5b1a94e19 4f2f38f9f74bfd1ea8daf0ac5ffa8afb485436d5e4b35fd0742c454439b21488 f6311a3834e71c30635c01e0c45aacfcb2241780e3aa13f2c834a84f5afda969 +1051500 73133e5c1408263f8053ed9a93ae7164dffc2381d3a7fa24cc78c29665b3bf39 a47a6e2a98fef063017953ee09b4471622b986b7fe8dc6d52adda451db9c852e fb14519af510b672ace64d3d250549fad14d1ed623dd0544bc541b7e3710e38b +1052000 20e08cce79f51cc9e5b0dd212f6cc3a0ad742244e58ce252600d286fe2415cc3 edcb3b3a1aff133bac74770612727bf2f15cfafab7c63dfbfe6f2378debda004 d47a434a2ba0524ee99b5664f66792b81fc9134f5ceb00e69efdf9a46f8142f4 +1052500 37e19650eba3eb3e2967c2585147cc37714d24ac681a8b78d11f946ceca3c083 069c1246cc4290b4748b26b30446f3a7aae4ca9bd847d0f1be6a8dd07e89d52e dd01920c16ffd5ab35e7d670ff88cfc9bf348f0c85238643b8f04a2919978c7a +1053000 8a22777c8f3ee2b71fc33926cde2363be651b56f4886962d9aebf6e111ef4af5 2789aab47bf324a74e8ba9fe94951e5b3e8caa995f93f1c01a9e6f4e95783bc8 0b4d50b5fc9dd327976276cce10c407e52b7fb70cf03d233ed3e88dcd1d8d4c1 +1053500 693b78182f2e9dfbf138a54fe519285ca8b5665dd630b9651d63010208cf1250 efd0a291bdd8f0928a31f4083021b5daf1fc5de4f7b1ccdf70b2c7f62c80c5c9 9800ab253ae43ff7d243ba35495517747e70d7da20a4a0d4691808ed669a95ca +1054000 7d052ca1210218d7316d2d9b82c15e8e57d59ac3d444fdd45dbf5e577f9b4c69 bee8ff913f9b231c0b34a55bf2381184d18389d43b1f6719227fd4d5c80d8b60 fcd0429b0f95329e6c482907dad4a9e4733c8860c129ba977299d6dfbbe45cbe +1054500 1b00ae5589d8eae631a21b715150b89a3786a33166cf0fb11e79f1c12b493e5b f8d95559f470788377237801e29369ebdd9b682ac289e43fc18ccb751ecbe29a 1d1b84b14c6aead094be828f14e8d90bb451216f84ce7c325641b3277276ba7d +1055000 6c92f01ed8c5f4247722230e045ae10ba6973c3f8d8ad66684852efdfd801234 59fb8eb1e18d1ed445f7378eacd8b02e92698d99c1ac4d1544e35d127134424e 527e64783b51c20f17908f8d4a5222f837061f839e5a35effaee8625110d96b7 +1055500 655d624dd686c5c3f95a7e48687d3cc7f7e3623b02c1f8db8727e54186e16cef 508f0be15eadc58ee080897002ad681fc2fd2f4bd4e175a319807626603ed601 2a01b2336eb82c2d66c72dfa96f1bb4778d0a28b7c169c431a8030ffcb18056b +1056000 af11656c7cb4f7ff056efc8255205feb3ea12f96da9ac416e33b034e93241e42 a9d081e5eb78f1018e0a86b8c2c333989d375adb3f217df5ce8fe0dbcf84c5d4 6e3b76382e6e42804f19c5552c36c46ea24829dc035c16b0a138254a2c192aab +1056500 4f7ce26131a4923137977f716334a07a99d1fede466564c89aac75415eea0eb3 da79ba315f20eab237343f360bb5cb32c210d3d909495e847a1b8201dcbf114f 1649fcd866bf63938016938d91a53248bf9a50db3fe7af3711beec8fc3ac573f +1057000 1fbe16214e11324f46064f3754e3189dc4e57e9aafe221ea7fa45627f0db2f2d 123d5e7d330c6dc7cf7a4b9efc6375736de9b6acd14e75205e72513a19e938de c7dc8a859791fb06bc5de694f4586affa038b1b065ceb3abec61ef4e27dd3c3f +1057500 2c742e483d8a978656e28a4b574fcac3264f040a569e8e141fb3b5f0de9585c7 301d401df39b752d5e5a7c3d11b8dc6f985b7f836a4f8e4a318631c45d6d4f6f eb5eea8f78367516258e9e79be1c491b84899dbd73b9469c862b115088f44e89 +1058000 71060b474bbc2cccca3629b7a682061d4c6883c35750878c998c2946f99fc70e e853025a32604033563ba0534f00dfaa3a7b7ab8a58ba1ff273f5171b8b0b467 72afdeb47d0f75352b8986ec6b7c7a8a4527a72fc245f7469a6f12df141a2ec4 +1058500 86d1e3325a942cdad7e74813a1d548d16aa30477ade1436b839e5d8787886226 2c6260122193c565daafbadd28503bd5ed077ee4113f877b1625a3b6b9d86c37 b18663868cb27f76a39e3a91958c7c935cb4a8bb3146bff5b077c733f96a5780 +1059000 6fbef62faa5f95b74e45eca92924aa2a1e156ba4761cbf0faf84ff5c55b585e7 e452d37e5cb40bdd6156883b30656ce9ffb57a168d81aff12f9d50fc4c6ed068 cf0917a434d3d21f0220e2d57e912a534d10092260015e7d23a6265029134e5d +1059500 d2c7aecc7fc0bef185b164a6491d39525e61a7b36eec25184954116e0c98ab99 af7a5135bef5943c1aad9b8ef09e192a0230a8c4c6c1ae8fe4421aa5e5df0499 a2b06bb577630f4da626f630c564ac204b5715d128c1f6184d2dba2701b623c2 +1060000 45ab1dd2a8e66e19733811b7439737685770d6dee337e3161b6d7175254e8673 4965c6b0942bc3ef57f11b6f2e0e0bc8552e4c2e2146b645ff7524aee7ff7f83 a321dd68f9f4832159b7865b31e56b694c7dd29b17bf34854ef2221f752bc613 +1060500 c5761a40449ba6a74e1a5129ae07924b51b8898ff1eeaf9db8da2aee647d0612 7fe668aaef8d9836bed662b34b8f7d0b4c6abb9909cd0f722e205601dbc3e405 5855421e292165c955804224dedcd01f53fb528de99ab1a07047abb368618d7b +1061000 e297b28ed73b1a92602b1f2eeb5b440754345478353c815489e4136b343f6241 9506b5c030c839fc12e0f6806232bc7abdc76cf5e9945e232246342db52847fc 378600fbf9567f87c18d0467dc47dc8ce24571ece51eee6b5d839420fb2f695a +1061500 228ba4157527381a8bc94e12da1976385e9edfc9777445a702b90bab7a28050a 93fbe2b3a2689a91ef35e326b757903b0a82e3cfea2577d06dcaeb8735b32c39 0af1d2b58d0291856eca9a5620d87ca3f062e4dfcbd9d2a2d873f27c4f14c13e +1062000 706d3ce4695a317869634ffcfc35ad654b2efd84f844057e402ee7941848201d 602273004dcbbc377da2f7969fdb13c4e3728bb7e3e98fcf571e0a0aad4abc01 7c947a2202e56c27a5a1d84e14caccaa04e3d3ad4348338d3a00556d895bd946 +1062500 c3fcf4e0f04dfddee32165ed3126c9a6a91504ee311d6c10bd10f14d6fdc47c7 0279a0d50d4841649f97562751ea348f03242056f4deb13fdb4f9f8ef2801b95 394e7dc6b68233af02094e087ea557aa5c7cfcb9c68e001359bea783484c7a71 +1063000 a0c1ccd1f4d73ad8d77e2de61032f30e86a3a8de6718a28dfc1863b617f39358 fddecb6cb2ecb7722f31810ed7ab2b186bcaa57bd0619034b200483e0ae6d91b 3480ce4516b3ca0cf73848fc929d2b0a2e07570c0679a8845eec8d4ca1982587 +1063500 2330e271b8eaafc1658c9c51dfd6b495f68551a65b96619cec0307289834d85c 86b93f157059c9597dbd98a08f8a62b53e5be73f4d0061fed3fa547b508a0643 7ce41095c1b455a6d3f74d2f75f1b4e6573de79ed67758bafec649a6bd1d0531 +1064000 fdd490d245abdc95953098dab5ec68ceaeb41108f5b622f2a6e0c64565c3f1db 88bb5a1b5754de10c0ef37f329f91d444628e60cf45c79078504a405af8a0ddc 9dbe60c9362c8eaedf48c075b83a2987df3e7618680dc7f05aeb3fa406239355 +1064500 9273b1a6243f98cc99a790fc73ebcaaa46c12ebc73baf39d18fd037430e44600 662cb00f6441b43c4e6a03fd0d1efa5e77f8d821b944a4b35605d111651f940f f9e42af8cf6d67cc2befc29bbeac8ba24e0e65538e5b75feecb6093abc36ac67 +1065000 0d5ce5340d7ed40fbf374b9315977e6c6f4a472bec71d708a0aa1120e37ee262 f725da7aed8c1b71b586e0dcd03c08512fcb6010425cadffa259e83a01a5e9eb 383bac98458d28ba49fc1cd8cee20f3f5fa4d1a0edafb65c2012141006d8bc67 +1065500 05382e2643516f8d9e479666209f071ee9553c77ff42e1cde7065014af248ba9 92b27fc524cf24d169800cc1a65a445a09a813aa2bd2b0b0fd30f594ff1d147f 361e131b2011b987a2d878b76da34429cf4012911de3e4409717610c65210fe9 +1066000 2f918d5a92e7f96847cb7efdadbf96663ebcdbf3900ce837f35be2fd5a9bf3f3 2e1d0b02fb03d9b852725dadac2d1a6a5a706d4c57aef1af07475a1d895858b4 e92e7725b210930410a6990d6a4169e15f7283c3b90231498b342e330eadbcb3 +1066500 c01960d7eba3c4116ccfcfd56e71a8772f48b6dd44b1e3443b81976267e82c86 1621f414c5a57845322ae46a288a3b30bab756aa0e4ab80fb9c781a5d676e29d 98031c71f74e104385ff155b9fb02d4870a2ee5cd2f2669023f32cda7f53fd9a +1067000 28c2c19ee01f452eca69cb5e65f005b32bf80eb83faa7ce7c0e127738b74a802 16e252a29879548f52ecfcb71a2313136d5d937f79b100850325c7bb71814254 f7874698a0a8d98e3c59d4a872d4a40a9e37ce2a2fc44898e75b6b17540fb490 +1067500 692144c9c45467b66ccd780438153ef077a79dd48a58fc3715023b1f76236abe 75acf1e86e7a85c042d72c6167da99efdde8d137b59542220891171bf1318ba8 59f3b75e9af5cd4a728cd137c3466f90d8145af4a7748e3c40017bde52d2aeb1 +1068000 a5df3d842f3898395622bcee46f08dab2f76c2456c0e09ba25dd29f46e140c18 6875b9ab0e23047bec2cf3f1a2103f5f6bd143031fb18efa2cdd5c8da187393d 25a6556bf508526d411a5c9d1620113dda46a967e53383d9872e35b658aa546c +1068500 a48cfe7daae6a39e0022c457cdd41a79c2dd56edee7b10204cacd0c03840870b 2f7b5f49958b7b145b8f9d9bd13f0eb9d7ad69965ca98583e4884e715c219d2b 90c0696efa53e585a3e8c211a7c6aff44711e986b790d86c678c0f74f6df3fec +1069000 8a58edbb5fc50b3c8c028ad46f8cde21dff8ac59b4862c23659dac18100eeb6e 1fa50519622ebd66f3a9f69425671320ff72c378205483bbb7c46112501d7b7f e57be6967d1f0ed4233de06f706ef4db292077a8bcb424c220cee997c972270d +1069500 1c2047a1a3315ef6e285656e79be2d74599448d84b1aa15132051f8d2fbe9c5c e1232e9e501512b3241fae5eae73017481534a82d8cb12593db3dd5aec16da12 81a83b4f14907692f70b637f043a19916ade4c7fef1d2b3230956281bbe12407 +1070000 b2c9ef97982d02946b78800c9dfafca9b3aae244e78aabd17790855d97eafdc4 0bee49ebf1bddebfed4b7891f616d8ed7e9f94f1a0ada35f068152fb3e715e74 6d610254493a870bc925369c82e431a894e0965d0b7e8837ffed73f900906f70 +1070500 05d6e0df5eaf44379f74a59b82cf48593f554aabdc8ff1c8e7b9e29c0120e3f3 bdfd3c96915dac1ad524b75e5504827d27603780d0ce36740f0a7ac99d65269d 0a1e76f48f334f488865b68040f5806662fe1a8b97f984a0b3febce7429b8ffb +1071000 4843769a45f8e41c5addea413a9d60b3b23cad4470c645e154381dd8a052ba16 584b8d85b79c7bc04c451b77200b1f5a43ac1ac675f19df8683fc1d517fe344b 465ac9dfbcfa23e16bfa7def9c4ba8dbad6323c07c0e5bed6f5cf745a710e2ff +1071500 a054cfb37aa34581d4f0af31e90242d2d2573ebf4f2528ddb45a108d85d30654 528c0c00da0f2ab77cdaa4c68bfbaee752b064e3d9f2144b9d53051c6fbc1c80 94289e5393a34623406aa76d1abd7f360e197dd2e47114f17009c335681500cb +1072000 c5ab550bb8c7ebda7617718ba4bc5a91ae505dc653d176ace9aee3ed3b7f621b fa4c7b5a4a1d2895fd3a7dbc42e092d76238c371a1679020b35d6f0b16a8358f 489ae2288e0c7a43c63c8ea05496864edc3c6c0215ef402f1c90f44111e90dd8 +1072500 e3ee28857f0079047b39c8e5b5ad5e73d500dc14ec31dcfd96376a781849eb43 3c2b1e6690dea914e5dd9d7dce63a31fd1c2ce13a024fd7cd12b3e253ea41d05 a6d2a1cbcb0f6682ebc431b44dc136e188534972d471c47cb162302dbcf08342 +1073000 e4b3f78f6a5a5920108980e51beb7bf63c7fc53ee4e775dcbfaafeec8baaecd1 9a780fd47db384f0383a248bc13aa05c8a4151acde039dec571a4f855261dfde 8e07358f76aa7b0cc75ebf6f316e62bd7dc42a34ba2a83f4097ba92cac23a6b6 +1073500 82b8cd32ad30ca55c5a9f817dc7cc8e4973c900cd1860abe9950fc97c907be37 5285894affcf8d17d63784deebcde89272601d347e386f933ecea357004e28ad e93bb24b4f7e093aafc9e5155875ce05ec410beaaaaa79e6731dd6070e015bf8 +1074000 9d64baf4c05e3ddea2b624b0c6e78f23064069c994a7af29b30214fe07e9435e 85f0cc4cbfd0a8c625ceabc0c09361a6dad5cfd12942a6ad8cbdefe67b562b60 fa9751e72968610ef51056a04e8467f0de3d53738ee53de9d04f649636313f0f +1074500 e7edd11b9db357df9e63378dc7ce5125b004787fbd2dcc48e056c90b36d3fb58 611419cc6f2ccdc1557de599d1969298d6523edf6e486c913eedf8fee7f20e51 7c40e42807f2105edf27806ae4bd6053b49d176449d24be5848afd2b5d79da11 +1075000 a670ddfd0da7ded58fae374fae1794bf524b7fdc0885227ceaf9af9081e49733 62d34c01429af38f299e33c02ef9105c36b35d802cd6fcbcffadd48c562dc099 906084d3e66d7860153f9573c36e4bd86c73b415208129ac889a73b871e34be1 +1075500 2a728c2b869c6736e65263cba12507ac08d6b79036584d9c7a2c7d603539e7f2 50b4d0639716fb549d4c480f3c16d05cfbeffd048c6dd7a0743a213379996be6 c6b1f37b4c1436ab3f6741d39ac1345c478b1a5e07f6316032ea4260879c4aeb +1076000 cb1214126b0bd68c93c55b527dfed9ede59de69805a027857a0e05be00124e62 f499de1cd286882dce0e7f8865db42df1e9601622cd8aac36bef68421e2a7d0b 194ac3bbd52aecd7e8026c704b481acf283abc7eb6744a28fbe5264c911b6681 +1076500 119025bb4b9a57e4b0e4b7ba09653a531266b343307a5af0bad57bb23564dfa1 b0e3ff0f7d53f37d61b7a3a947dfeeb5674bcd948db101165edcf7c98ae29673 e0f12d9cda9239fb7ad33e0126e19752cbc461096c8a89ab8609cc2b74d5d56f +1077000 555eb72f81aee04384cfce568eacd6eeddcb81a68e10f2f1626994d7087f1d3f a2db17ec89ea79c806a67e5a28a75ab1bca017ede8114fba789ec241aa2a6539 58fce8e993527826fe22ff6646349b98539f84d8a3f265f0eb6251fc88e4ab37 +1077500 b3f4dc81c85325ac81eb531d90b6cf16d7e2b75f5f305b95865642b8c1fa1bd5 e901d71fb07f0742f446af43a1224585786c2fa127cb36fc21f20ce204cb3dab 7ee5c6c519439b93cc020a5796151c243647e1cdfc5287841c816e533a6896ba +1078000 e6deaf52d4f8f8f266a00deda4f1279dbc9277b1a606fe9b2289105397ecebc4 861db344c44d180ccdc6796b3806d286cc8727c6979eb56f2c4f247f9d946b86 31266e9df5dc02fda025e579e9aea8df2391c156be5679e1bcabce5e55ec79c4 +1078500 9f2d0cdba1d04e199eeda34745ad90746ef7311d77f742872e063bcd3eaed840 d01de4885f8db9ebc727dca5271fd08c6e94bde5d870cb990fb669900717e628 6b79f91c0360359260172b317fbfea0b740f5e4e4a74c802156c36bf7ceab627 +1079000 ee4309327cd6a09377c1d7191937e534175acaa0c58e45214d447fc211afd7db 453c958e5aa1885090885b796333a33a604139c543af74743ee1c02e1e04336e 2ae246868edfaa771b6cb0adabf985990052f2a83ab1884a696ea787be1d134b +1079500 9bac2ac5d7f12eb3053d9d7bd6f4c38341ebda83efc459d3c2e9920c2a5bd043 b5dee71d79dda8da94546572fb87fcc343fb12ff814c2caeb4b13251372fb748 18aa74065ac38a1b9a33cfe4222b712562a679eca94f034d30ae519cd78c6070 +1080000 ca8e6b3cd314c5105c309a544b94f5fedaaa60c6b46808f9fa0c22941289d964 adb321e1035a0cfe67cd1a768815d957f685ab691f8bdcef8067a3fa29ea86aa ab441886532f77bb3a48265fb7a4818021cebba090470449e4a594d60c9427fc +1080500 33b9af6f0bf1102108a3bf71c44f4fa582cfad503643fb07746f787ec62820df 9b05cb5fc9b583ad6158a61ad62f639b6da0d66bc14956eb1280fcd9a3b5dcba 413bf906013a89261db0b1bcf1b69e747f7e8e132da667d6d89e3e900529ccc2 +1081000 d5da79499abf179c0056408eccb675189282708c440b577fc538b9f5de65714c 727ace05823f44837d22a80ee33ab955ab6fe7f26bdd0c2b13d78e3bb113821d 1cf655be595d6bde83a254eb82fbb5eb8d07388ff1e67c2eda7ccda1a38f3779 +1081500 bf215331b8e106c752e71dfede00fe8c205be5a2a1188b7508545dbd22bfc2c3 afb288c1f80857918e77cbb5b0cf65586195aede8979a8c45811035294ef60f7 7546df9a854250a75216e3fa912eb6be62e2b6316d9a9772006c0e3201f5fc29 +1082000 f78a537107770c21247246007ce08a45e7dcbaa551b9f12a4cc9079b78b64045 88decd3918e4e6d5ce1915868f881049380dd9d855001ebf28664d8f4fe279d8 6d638afd79ef31d972eef1ae1a3afc7ef155a4bbda0f59727213edd0c68d5112 +1082500 84ae75ba3565ac37619c50e444bfc6fd544d6e585e433c1599a3865851967a75 709236907668df31fe07167937dfb81ebfaf44e50015f6e95e071198db66258f 7f32390a047350b63d0bf90820e84852f21bed9f887bf62f71b199565c045ec3 +1083000 c4fc7daba93811ac701a8042c15c8b64bd0e0695b085725cce4f8ad1c4646a50 8592b9641c2c78e11a0d94667c0ab1f4894ceefdc061c7c6ea9031da0254f422 0c2861c131427bae71cc47dd83821d5ef9a92344c0e40c06c7a17a0713ba0bdd +1083500 0fc14672e22643a8475457e39fa6273f33e8fbfdce9b5b22b350cad9b72b3b9d b0a5953f75c83d3a16052880a0a49eef8e40861b38aea8e26b711bb041b79f1d 3e254c64a4a4b287645cf2bc6e4ac87d35e2c40dc5de078b35a7e356f6d519f6 +1084000 fb57fa6354268471642b38417a993ab3c3fe495aa009f09b04285d023c3db9be 3db1a48975fe6b178f5436173dc44668bad3b413797c0df6d1365cf04b9239e1 9b4a23a29151f17df279396195029c0f94113a87c2923a2a7546ab627f3ebe5e +1084500 ac08c1808452ce0919a2813f507f09277f8aa3cd68b92e35e07130d68e78d6eb a23ff63e907d969af55f6096cb8b1635db6adf7aea9669c0d54bba686dfa9da5 fa187cdd47558624e1d8e7fdd9236bc2acbc26da1fed791d9f498d8699c4b664 +1085000 1abe79c82ac99781d44e236aba1c6da64cd2382ac3a1e42c5a629fb8d1e64dc4 67e01558800c021a4161537ffeafa2e81d74312b4ca25b6e3d4949bceaf14e6f 34cf0270da07e5323cb595d5412ab8b5584a2908bc754b92da6215f5e0bdafcc +1085500 5e308a1c6ac06aa0b635006f3e0dc89e048d8bd61d01ec97119e1adab66962f6 86ef3554333cfcdafa174d6854f606a9b4d0bef13156334e945ffbbc6718e5ff e03b94c7244413e4dd45447bf3226bf49e10d6f6032a237d764537890eab3920 +1086000 e1dbb1b308af5bf26d05c6347326d261d4f85e56ee9a801506645ad3261a7e95 c157e047c28284048c0b2a8a02e8625895a1b6fb4dc7e3141935e49b9a3179d2 8a58897e966b46981a64466f050eb149f28aaa80c671340e81bd41fae9d55c2a +1086500 693b5d2436bb03ddbf301330b6013a0906a96dcb44232a1d8eaed495b50b3baa e290955c58b9b0cde36bfa0697baa3ac1b6f91920ca24f819343fc23a7a6a29b 2b8aec5ed80229f613e86a223eac110cde1e2b5065a0e0ffc305c5b5381d0b1e +1087000 06f21d473d8e5184cabab67cfd0ae5e43067bc4e0bfdb10afbd01ec633692e84 5d375954e98c188ef10a11224e17e8ef39bbd7cf71baaeff5cd98ab151850b97 4eccc4003110d4618cf843d3e3c430a5a3f67862e12cc7c43c2c4ea30c858235 +1087500 52937bb1263169c9fb90bcbc164b0712a0d975211186deb2ee478a1acd6c9b9d 3c3811319f2a663e8561ea4a27336215b1215fa638bc167bef784f8d23aedb85 501c1d273073d115ad93e6bec524d198ec54e82e05b7fca1384b6682059af275 +1088000 48b02487c9a7ffbd22ed2f43cd8acb8be175798d27cf167119742611513f5a79 7f45d21b188dda1bf12e084f1cd52ab4b9fbefc8c3fc9a269e8c5d923aca3c70 e4d9c64af66e25fba4cee8b74e36e824be4165d3067319b8056c7da215c77316 +1088500 099b96d7bdea5e8ee60f5f80e876f0d41814b067511d7a09c908097a1191f61e 1afe7a92dab5934e92344079bcdc92457096786734b64e8fc61a76e68dddc3b2 eeea636691ec6840b11f22e2e0108d570f937115a2968a421832f7fc3a91c1ab +1089000 71b75133d9c405fceffd1445d1d1c2b5f7bdf1e9ea772c4fe9c7ad1745b18dc4 4d8160f9d99563c94824a4396576844661f8eabd4a0248659112fb4a8b14d9f4 35d6379981d3604c174e37c1390238b0d765ce7cfd4a5cdc2e4d690b263a4229 +1089500 73b592869e9121d39bbc74022204290faf811c37dd7b1f377b31042636e3b1ba 58005bde06a6f8a0d72b84e8a2b4ddc227ef9060d5293f7895abcfa545035e48 7087e0bf7e8063fadcfa43610ffd6afd79a16eaa6d002400eb4aa828c2cc5a57 +1090000 31ef8e17324e817ee4784d9c4812012521d6179d612756d4b14a16eecd40a293 c2d728f7215a43d95c5185ed221d0273b5dc99fbd9d6f7f243e14bab876f2230 13172dd44d381e32e368138d44f42b215fdd4673b09260c9d8551b520ae1e65c +1090500 686b2caf7f33fcf3f019b5746d9a146c10fedb7e8f672615e0b6e6ce5113d5a4 47f370504009b9c383251cf39a7f0a87b7630c0e8bd9fac80bb6019137a96286 e4fb436b5acccb15018d9f7dc8f18834c76463b0bc566f1f7d410bb69a74156a +1091000 c6892f956bf40f0e9503dc0f249ff860f8d030a2dbef90b04c0c9a2b5883df84 39de090cedb5a8d5b9f272700079cb039ebd45ad1256f7b4d48a82021d05be41 6c3c5a22398e694febfa38d5df32585e3835b18b23d79f7bd69a8815e4164c92 +1091500 6ee9b389ea350889ca2ad7b760addcebb3669fe449bbfd45d331f2bfe1fd91e3 596c3088087f434c7e56f7f1a864a0f2cceac34a21139f5c0b9224835245ccd5 e646be1688828df6a5a37fcab547e74b4f054c442b9bc437eccbef69952284a5 +1092000 ae131361b7cf2eab6bf3949bafcb0135c9be361b80b059e91037f6e695eaa655 d7eb8ddf3cb2711d8649be5fa0e1f6b35397fe783949070c1cc71fd97df54be9 1e053b228604a3cc97764a4ef6c7a229ece936640385b4e162142f999ff2cae9 +1092500 655d30044d9437dc51444aeb1c8796c237fa730d4ee1b92ec6cc76def475017a bc43c30f84657322b6dac014b80856f457020e1df7c275abf07c8b5f21117cce 4c8235ff2555249fe401f4c7cf93b33951da23697dfe8c4c87590e8c44bb8d95 +1093000 27d7d2d1f9abffa9b22029ca4b1475468194cfcdbb7006f4e585fd91e984c859 c8fb498fced5cf205903df41860a511801abaa2cb879dd98816c02b85fc2c974 56e05a9fd09d5ce5b4a0f58edeb13fc561b8251faf67192cd6f1c3666df88632 +1093500 70999f0d29e11b28c6fa32fca38cd31e05e1a472dfeb6fccebece8814d0efc02 d40511f86e8b9e54f25e7e514d1168042405d14a4b8875ed922c4bbcc050f59a 57a86e678a5ba87c619c922512b2ccc984767e5406e4ff3a35f7107b4957076a +1094000 99d91b7e696a6b0b215b4f8f0147b8d3b52fcf42065e61113a1a2eb13c52dd97 9a37f85b8140076a138af87244a768cfc4c045cb3993786819e24585a922d796 ada1c5ecf8b4457fcdd380626de3bdd48d8c95af717562f61b434ee2577d9a38 +1094500 5dded8e857a5c9bc83b4398474a7937145024e3230d339702661cfcf05361d42 58a589c26bedcf941981bc4b433ded102f40fc2668ceb2e81d00288e5beba6a9 996b065a617762b72be39f01d784d921fc02829bf970bf34a2a6d19f23eab87a +1095000 a5a48d0965f9622d7c3ba991ecd272a834f053b32257e2587e4e9da849dfe3c0 81703ffd7a8f0894456186c979d6f5706586a4d0518e9de2de68c822f086f16c 464290e916c37793e092ef0ee3be8503ac5bd9468001a2fee5effb2071c9ec9d +1095500 a235f6bb20a438fa3d67dfe510c843aab2cad4f49f07adbd1fda0b693aaae9b9 934cbb1cff86d8682c36350b5e83313fad85ec15b087f1a13706d7363f9a3fcb d1c53c1f49f40e8fabb19409ca2330168a5e43d9eedfc8144e3cde9bded0c1af +1096000 63000c3f4bdc50a56e493e39bb309ce54ee258ff574007978441bca92aa69f0c dba99d75f52fd990e0301d1f84a74c9e146826d9ffd0da705000e4c039fa0fe0 14e2035260de3e558e3d0899b399684457ba033768f7655300a4a7fccc790df1 +1096500 2373e0b0e90f23f606c59c162d943598a849c29a3e617452de9990790e5fb506 81320530cd616af57f1670c5de33e7e8f654f2aa2913f7f4297a36ed7a44ff14 90be350d50a32473def133853a18ae8b5332c333071e3dcff07ad07e15e039d7 +1097000 dafc272207365b827fb4dd9ed07caeda120548293561e2ec48566d7258b2f9f6 f560a00cbf2f687d025806daeae718aa74b97f6b00414c4abf9a71d73898bd4e c2026463cb5bce549a185e7bc323ff5b8f91fd4a22b064d36752b4839963c3da +1097500 f9a416aaa0aee2e869323282d455d7ea61b9c0183bd12565490e96945ad0336f 92972344a16f716fbf7bf03dbed916042f42a5c0c260a821c70a2d43a328a8b0 346ac0565710bfbb9d3989420a66a61b5deca63e6617d1b69a013dcd048a8122 +1098000 4b4df3051200b1b344f956ed69a5ccb98a1cf7000bec0ac946c268e19385adf5 376bd8174073cd92176431177894273de568ba8443858591c7af2af9f78224b6 365233e16a95cc466030a46dbadc0ea92b87e31c70fe6d1c959b4078ec069672 +1098500 f18ac1d6454b181f279d1e36c106be1292ffa5f0f30cf3af824366b53ea3755e 1134bf04bb8b18633fabbb35b07682ba4b8780ae8cc505070a1be1483db573f9 dc07084ee0fdba51c2f7425278f761387d95906f4b2f52fac5b9951a0d1c59e1 +1099000 8f4364828bf4d9bd4a1bdc8dabfdf7f3535b28c63ab47c3d2cfd8ad8a594be21 8faf1d711d89328c7847dcdaadab2d45608e741b7f40b85716650817240eaedc c2db5228e20dd25cb2d8510cf04fac1dc174ca7981d0e4b8dbfada47a0b52bfe +1099500 da297c6457abceb7248d583bd51bd3c184fa2591b15897d6f2a8ed9f92d95db6 12844b70679f87cce949af3c2cb6cffda2c2a76c3a718daaed46fb2d83baa0ad a80e86275387ed469cfba007538760470cd982624c882e3975275b21960ac9f2 +1100000 4e8e78c7a26937f5c671c1554ba789e0acbe8b49f734a4d299e267aec787fc76 6f6ee9ababd774f9abfec595f94ad830aa434e0802577fdfba8732f7216db05f 8c0afe848836cee94e822c1c5b7f7df14e85340f7c2a4922728e856e5e9f11f6 +1100500 943f989be35079cd2ee59cc67b44be493e4098f58e304f837360495c96990627 78909b8e2aad94dc3f9d70f84274556a385839d6567684099194dfb68a22ff96 2f1ba2dd07608289b77e02fd19b7006b12db5c3ccb4f4a1a7ad4961a0d9a9b6c +1101000 61a5247a1fa45485eee15a9eb1ab96c2e05d1e3e3cd269b83387e338b26bf702 09771314b9219cd5013b1113e92cd70e628c086be2d6c9242f4f452a60176ebe 3f04bb6a4ffb41e7dccabbfbff14dc5a2e2cdede0038a03c637aa8508cb92897 +1101500 18e769995865e33ccca1bcc726049918063b1596c54aff284f85d672c5cd7002 e7f5f83d5574ea0dc92225440db5bc8c99c0f72c9868fa93dc0ab70d1105a893 95ae0b826bd9ce72a6709a63d54d22da651d0410c2fab0f142decd57eaf88b0c +1102000 7a6f761152ad006076648ff9d5b695b4f0c9ea5dbfa3b118552b70331a0affd9 2dbf7383d6279637c6b2a4d63b2a5d02af980dcf36053fda28945eb1623a876f beb0defffe46b8fbd2899aedafd241c68dec39c6fd2ab61b777c4edda1b27683 +1102500 990ae9d33f56df9cb671e4c8e5a3653997202357b95b39959d15faa093190181 572b0395709d54fd751fe00d9a8cbeb5fcfa207c1c425f0e03c65abca4455490 f0a4ed9883c2a39302d6a8c3303205efaf9d4faccf527062a4c9b6d109c6fa6f +1103000 5dd650013e4d42912ceac98114fe8c14acc3f9e29207dcc837dc5aaa87683df6 e6e9d28aac999dd8bc5c8cec4a31d47b0c0239f2615b3dbce52d7cb96ae4a8f0 6e0e6de8e6f0321d988e295c7afee4631ebb15cb26d35116ae820027145f4848 +1103500 a0584d8d349084b8714e13b7c48c032d309cf9f994907f496aee51355d6113d7 c9a998fbaddb79d92b498137b61e76a53be5ebe0fddbf448dbc1572568c5721a 6ad353368e346de09f45b29d7282f1f12545a4dccdea72c726c455ee10a7203f +1104000 8ab87600ce5dd8869c02e921ea46b0fdf96f1eb677f87bb7a7d3a561a1bfa13a f60d5ed448b46c33d5c971242dfd026773605269ecf5de300f1f94f7000ff5a9 fd8e151d9531401b5397830d3e8c6877d93d900200abc6b21bdc1c9ffa217090 +1104500 48ffb083ffc3e32bdd1bb695ab7bd2d0ecbbf0e50f5ead698701ad9bbb2c4023 df1592443e7bffe6a7e194ddbb174a823a7d603308a56df2034873698fbfdf30 7394641715344beb23060c5a64e4121075af41be8c741835e28199d2c3c85133 +1105000 589b888e8e76a82be86f8205e2e3d27dbdb8fc225d1f16377e1fa42f99158b78 1073db20228c899dbc812d2a88b9d58800a48cf5026cea00484a75b19d2013ef 9700483dddd0e115c932b521b0dc58ee7934754b22af82f9cdd6e77aab765d47 +1105500 64050758e0522a344d1c286a33dd354cb721fbd1493948e7a8b30b35c0274367 a0bea617b74ed716dcb67bfe828d2f4a461e6bc20e2cfa74e520d0f8048f4410 0fb49c436351dcda0add474e8c3a48438f223d3c77dacc1c7a4b7f70eeb65c41 +1106000 25e35e0f4cf84176542da7990074722ee2f729bc0a6887cfc426fe82de48dbb3 71d87b21dda65f206c1b0e1d104c23180e0e13c843309a8be142a532d513c42f d9c3771734483219e77208cbcc96126bd64d13017626a2851913c02ca3c3f8e6 +1106500 1ccd4a10149ed927a232ad8e22136ab3275c05960ad6f24ec5d87e0fd3dd612d 1cbcd9c959b27f62b4cdf3e31be6b13b3df186de6abcf97ea45efa613280246d 80e14bf0eb251df042e8af90b2ecc9574f4efdf0a34787379a49b360887cc89d +1107000 acac80b17b583dc83aac4238ab566d20901cc0a65f71d3faaa18b1150ba859b2 dcedd2d1ae00ebe366ed6c12bd5fa502b5549254b92b4b27723304623ef42429 276a5332fb437b515e759bc6f77d121c810fe5f8899d49cda692169469eec8db +1107500 df574221b2824ded1b5993e191778ee0f6ba617822452e1514395f1598e50bcf 54920999aa45d3f09abf9dd213e5d216c00231b58a87c645dca5ac4ecbe79cfe 122635bb6b920464bfe8276d750a3700b82be30e69543300a49a8117040fc6f2 +1108000 8d593016830e7d110dc92f0a0580ff4be234b97345ab09408c900c503ade9c7b 4656fd2ad319aef388879fab289a939380638b950387afe465a6b60185665202 536fbd05cb4a9831f07ab792affc5bc6a605c89a56e623de6348564193aaeb5d +1108500 73233f15f2eab59ddd7ebeb3be2961cf3e92a0cad6f5157c68de8e7ae44ede00 8ab3089335168a1e8ea9586d29d99298c2044af7391d67103c86fe077130693c d2313b12735abe042e57f783d70a6275b825bab7e9c9b19ff1c6460fc6186f37 +1109000 9a573903007fa291a0f0d45151bbfdae663827ba265a2ed290ba1f43c64e7417 96fafd70770999269562691f91669d1073e9c2dfe7950fd474584aea8d154161 d6d0856865fa5deab2864095db4704572b40213d3a96fa378b4886c4d1e561ea +1109500 4814972bab857dc8e46dd06fd8aacb5755a668cb59439307dd479a57a6814ddb f6610192271f24d6f470842669053f42ad35d8cc88d8db2c706c944d38988ed4 ad076e5488128897aff87888e74e290071e2b7707f5e31968ed659b26c6e8bc8 +1110000 fd8b0dfe333f42e24abb11267e1169fbb312461aca136dce29ea3d9067af8a08 342b5d265f5fd5b406d7c558dd924e5f4bb928b2168432af9a0d725d852edaa0 34326e5e4e279e7a9882760e2bf693c5525acc78aca623a78876f0ebfabb237d +1110500 ddcde0a59b0676968eee2118c96ec169bcab836734df576170e69d219a8e69a0 9b675e782ff561f49f4172f618b3f222ec02893c1e1eebc1aec0f7eaccfeafd4 4dfdcb5f358ca6af4f6c88a055b814b30d144cc003c9891bfce27e19ba010333 +1111000 aa71ca52ebab08b1ebcdd3d74178d5111b5965452b53b0da7225b7278c386aff c619fe02fa4140f273339394f0fb4bfd932288d725435f47e079bb19d6571371 ab9a9962450788969f2ab78e048c950cdc679c97385d9e99bb3f45d6605b6b08 +1111500 543ebfc4a20da2592719dbdebbf424544e497ec58abf65b4fb6356152fb191a6 61b012a00ac0313330f92978d0365dc331c73be7af762b5dc7ea9881ec11be0f 013df69ee6e580a5b205a5889a23ba88407e5786a9fd1df8f07d604dfeabfaa9 +1112000 0b8fb3356b3f1bd10cb2cc2410eb9a5e63dc4e902da92e43afa8bafeed0f67e7 007b179b9a91de2545148cb761a841ec8cf6a138d0dce8851e832fe38339444c a7a733242cb715a9c918e4bbacd9473a4c93fefd931822a16de2a631fae81d79 +1112500 4ba3b8106c0ce3da080cb06491b46fb5640db7d7930f7696d8f4c96af053d826 5eb4191d7bd977e9bc93e416d828db098763f29ba69ccd093c418992dc4c0693 fce3b75e67debca86c1dfeefb26fab6a38f1c29639b916ecb034170b594b9750 +1113000 7c523469e3f45e18f7b5d921d50278cd65a221e87142ecb3f9e1c0de7efb3f02 3a2f78d06754af9c1dca222dea8488e82374ae5a1e265e927fe663d62d8f1a6a 4ac309f47f6a3e75c4abea6d058312ffe34d7c6853f4a25181b5c6985ca1a574 +1113500 99a8175318bd2cca935996f3982c789ce6d781fe4bb66d4c0add5cbd21124552 3cfcacaa24b3c6905f6c4d09d319e5edfb3c14cd989c473ee87e3ff620dc16ce 658d9f184960b8595dab1c5ab5d4eaf439db20093c855881615757b1e943bb89 +1114000 b0779e071b9ee0ad0912616e9c267c2813f2f3df12d27d2ed6ba4d440a883008 affe19ca4782ffc24021698ec88e59a8c3af7152a7fcc8e5e5fbe5e2453413bb bddc37109e17ab827e6dd9e18eb8f3e39627aa287fb933c89a1a5588724b4e95 +1114500 50ac1aad785d687dc562d836d7564accd2155a0a13eba165dd66de5af8d93699 49f30c636c3d2230137849072c53aa4d7b80c3879de19f357bc6d7f1927baf8c 8678beec2aebedc5e16c77ab83f55319226aaedd076e12056c3ac529e2f0793b +1115000 882f457fb70ed5c5af4c9c7d12ac0c79398339bcf471f00faab5ca3700a2b233 2dbfaaed70ef9713de7d086141e356e55b25a5cc68abf9d7c2befb7a65ec5f7c bda2f774f9a119c931e14c5905c75cbd9e138e45e9096261ace34880a40a6fc3 +1115500 5bf062536cf52861ca54591dd205454a2d6a0018c9eafb39e9d4656506e4240c c97cd141809e7bd7e43d1d2e8384010d28043a61f453f1b5ffb58f75e6736c86 30809bbc15d98626360f7940f384ff59e001bca4683af96b6f4eabcfe9a25ba7 +1116000 fc1cdec7557b6c6eef3e34f6049bd034e17c662c49d626e2f95a3ceac14f612b 0f5c324765751cc0c34c1af57ea47231f63ce5a6e666254d6abdd8a21f3fc439 d4891ead6a9add27e4c46330b8bda3cbf0ddfd1e2a54d754a7c308a1a1c6b5ff +1116500 ca65a5db9ee37dcb15521c45c7139448482ad33a7b9cb4c7f474f1459ee60759 844ec003738c32f93d343a2d3bb0a39a26d7a9f6447cbf22e7ecf2949f00eef0 73c7e8aa2f472695197ea0290fe2264e66957a620743d1ce97f4720d4de2a7f4 +1117000 bfe0ab6e8d174f9a75b5c6ea44dcb3e4a20063d3326c9cf984e49aa4c2514d8b eb5d352168388404b800b83b7484374254cd01ed883b430d288b356f3e0e853f 424d7992768b9d71b8eb1d39f07716f95753ffba0cc22a67948cb8ea6a9d62fb +1117500 56782ef3ad747d52d5a3bba0e2902e0e45b283de01f844447ab79bbae0f92573 efa60d46e6b093c152d3f58a9e420e6f76be8e9a291dd015ec2c382bf46eb85b 04326eeb78f0c933d74e1e11639c0961a089e51ff94b585e28188c692839a8c0 +1118000 2274ad79c5e39b6217642067faa46ae3c99b7daa3366c00db5e0b941e6513727 aa63d8dcd6daeabd2ead0328cd1039fe9808f002adfb8b000ab8026f7dc94ee9 9a3d1e6de9605f8a98228782a9e82ec87519fce725485b6efeb3bfc0caef2ac3 +1118500 8f65398ce001d8a8c115d35b8ae7b6137afb65794e48215e39a6e53a749a3050 dd5f02c89a360e656f2aa78fa2c2418edd153324a259ce1d1d2624b3747bede4 22b51378bb77766398c19e79835a439fdebc2eab839dbe880e6d7d038955613b +1119000 42360f9c6b3ed7f8f17ba5991865d6e987fcde944641b8ea5ad175ff9fe0d687 55756394f1a3555e4539f5212be0a40616b1e4fe5376bc125a7db34188fe066c 37285757a587203458f7b69254b508fd533814a1673e3e5160cedbc389d9402f +1119500 d0c2ca3f9953b8709c59940eea858a290d95bfb5a70219f1877ded31da9c3174 d53baf30b237ab7b9490c86148e891b6ce68c0f571575f1322e85b9d04d7b7ab 9a8272d7e78eeecc81a332ce129f66d2b0e65f2d072aa500f5d17cdca29361f1 +1120000 f0c0d84d13c72a4bb148f629494e5bf1413c3ac72fc137b3833079f7bcfefa07 f1f1784076870c946c827b0f4c3caf35afa4e0dc06f1e8fd351e036fb77e8875 838cd849130903b6c839ef4ba370dfa742bb532bebb785d644e78328cd6f4df0 +1120500 2d6b0e1ff1369e94d42ab53acb0ca8d235b9c3328fb88378336f8e353764fb50 deecf80760f89e0e2e147745b5ea3a76f9c8c89476fd7e236356f489c615d625 db4217003a8f5c504630ebcf4263aa97a4702f076bf6707da5d4453291fdef78 +1121000 c49f642ad2ad1234447bb1a48821cde8623c80df71534ce3ec5f230d7639ea40 4cb4ebdf36fe3ecc00b6e6bd5034518683bfe999e1176a628664434b9e2f28e8 6b4d3efdb71174859744262287fcbe13f36e0158ad14d35f8fa29d62d35fd84c +1121500 d0b462eda3715fdcfbfbbdb326bac0e831d60d9da17bc5d9bff5baf674194a36 404f1695df6e3557012546d2b00c50d480c7ebedb78da102edfb6617a33fa7cd c05a9c31b34293d87b3c93a6a7da334f1f159fd72e677a74b62137a328172d1a +1122000 32e2d73452ae2e06c51ffb55606c207077c6608a4b5d39cf31e059abf7de9137 745da3873852ea18368fb1857cc52b4b4c95de421bd08906b6d2369d4d4e22b5 81f91efe575453bad3307da56352a39f4ac08c7c3e19b2d5248e9da0aaed6525 +1122500 1be53be5574c15522a3b41f2ebc60df0427a98877bb9b260f416be2d9d3acefe 8e896702c534294c58ce6bbb20b0a62b6db5fd60e5e0e1e17c13ee2a35ce50cc 5870707c293d51277ddb8e561ae090866093f61c5f0e0c80ac9cd87c248c2d15 +1123000 01038707f7f6aba51dacac7d359a048f8dc61e9197d9b93a70a8c2723ac3fd4f a98cc3d4b4923ca8cbf1ce8ea36d9ca81b74b5aff50f57210ae66e183f067476 c92b4b1dca9be3d4fc25ad3edd9d33f08ebad7924fcc51b1e60a7ddc01286b62 +1123500 bc27a40263b51c55b6bfd56a859deff8be00e4d1d782f161e16d5d6f544b7dd3 d70fdd2c075b3a3aed86581c27cb727982c7df9f95d590f915909896de3fa196 91ca5514e4b657a750537a93a739147578f32b523eb25131d05a8b46f578e36c +1124000 bd6a924108e1c96ee897ce9366d2037df8a78984c4ce449508ab87ba028a2190 9573ce3b59847a39a2fd91c222636538b4d466c194ca2ad0905b96c83f5fe86b 7d40600ed77299561afb98f3d0d989f02c1c77f942748f86b38a8e59e17600c4 +1124500 c7c4d8a688aeaa072e27ec017b59dc6ae94cf89e87fd6fdb472a4f8fa84bdc82 1e711cf9776cd339abc21cf83176fd5209ac68388246fc4ec21bc515697a8e58 06712a32afd23ec1a00ffc630a7669ecbdc9cb961f74245a6cb7dd834a911e27 +1125000 7709af2e0216d8aa32440833af12ebf258f3fc20778895e718e8e4e1de77af24 5e0b766a520519550d75af62c74a6df46921d2e4408eac2604b4359b4f93bf30 13bcfe304a34732c86f070369868404068f58da05067335960586e757ac96f2b +1125500 7e2e6e1310d7be6beaa3a98db2ae77b963c9f1b05057bf088adf0033af0f4b2f 0321c756dfd069cc6a7bcbc3aab9f8d05b9623b608efade8eba6b52bf0d5110a 1caafcbc33fac6047e87e88084d2d82c9bed973c51bbdf9c9d369e6f7c7afec5 +1126000 2a769e90a6c21f54b5f1c29b6c90c8b4aef9f95ffb75cf44134286345250c6d8 9389346bb6ccbfdb27338afac824810ceb0852aa222d1b3ba8f902e482a3343c eb6896bc6162408b38d673655ca51c329e7fc599fb489d439676b2c037a7a587 +1126500 95b1db3a3c11f179372018ba5f7ac3ce44f190140c3480871f9c7d1bfbc0b05b e332c14b1905a46078e87fdd4265378f846a32d19cf72af8aab94babb4d24b1a b09358e5be70e30599f73061be30cf0e5b302611dbddd08412158511dc07e5e9 +1127000 9fd39c22a0548d671af10a2265e07085681148cbaee019e51b9dc6df7b95bdbc 71f0d4ac47a0ef52d215b7d6ab7dc3b6a244c2c7b02b0e84879aacd98d3a45d0 bacbb9e1efc49035d47b6574cfae9430996291f32278e343bfd90ffbadbd736a +1127500 aca1d9370f7988e5b26ce715608935b4d940565d2aba407b3c86a440967b6016 515df887b0c36fdeff248d984faa19f1e6f928f749d34e142e7873b71e489329 989d2ceafd9adc2bd137186244e2446edadb43d9e0e187479eec736301058496 +1128000 23ef957d32b7de302d8b8fe62343ebef82ce0e74c1accaab45b197d6505beb6e 70abd8bd0823cff0b60a7136d10f847b6f932215feff51038b79746fea9bbc2e cbfedb6162af1c8c606f6b18f003e8e028917cbe21876dceae28e91c38e97f20 +1128500 5135a80b7b8bbf5f67135b47d36411cd996c578e416f6a2bc347925b35f539cc 68a0c9c18d02a5bc3fdcc64d1e023ef5d06712653b7dde6b288eab044cfad020 f463ed605ef95321fa7cc20d3bfe2bac95a2b1d3cd6d531dec43a55f6607864c +1129000 7bed85f6f5298d7213f3f1eee883c197b7a30185057423bc7eb98ce797d0b278 f3e7a7e5b8553e3951448e69f003d2b872111f2a30de161cb36eba2fb2c206f5 127538d092e54ab66ff117051686c0e910c29c2a338323f835d7b1cdb3c89d40 +1129500 47cdad710991d54df8425e6c0184936eae6b07bc1fd885fc16066ddd13b512a7 5311a77697579a62ad2becf8b8833083075ceb3b567240fbfd8a182b11d4fab5 576063ab3816c76a708e44cd1d20ce999445a2a0658a10eb0416e84186d0e408 +1130000 80453c86a86faec09ee4a14a6f8202672728d466ceea6bcfcf5c51c6144c367b a685204657de06ee9079ca365134a185bfb2dcee1a9227cc99fb7ea3ea492a87 c11d4fb4d2552b84162b6f7d93a2a44ff0582b0cd607d5b35570f9a8d72c16d0 +1130500 80891bc449402be48d217aa4ba5e274f9514dfcff1981820e1515a9c8a2b5e25 36ae1ea8df2d2631fde76330af6d357c4ccf91dbd790703ff0940d429f7da4ae 42551ea15a33a92f62262dddfe194bd175fada62c014b1072a23660b464e0433 +1131000 c388137edc712616291477f0a1237d16c4100b1570949824397abbb835b59f0b 34e4612b5f9d4252fe2ee1a17c23c653df33cf7d7ff98bfc19df777c3d1352ea 5436b75e49bd806a465407c53596edf01c4cd273a15ded7719911123125a53ba +1131500 dd47d02207fd2deabc026e1e2ac779de6ab9c3a74a0712e01b72daf28bd7bf44 58bdbe8f017609e13f71c8fde89dbecc7647c8ddef31de1f69b9944ee180d5b9 df9a6f654131d5f982a22ab0447d41b0f4b4314b6288d0ef6f740011b2a7bdcf +1132000 90be07184a0407c689bdef995559076a64de1b402b0e09f408f30d4e87735316 6224524eaa0373d0cb15a9a3afa758d0051f538282979c304508fe90c7f86e44 f1bdaa1619c5df03ea9229a4f29c9868a6d7276bc422067e29cef396b146da5f +1132500 bc4a5013265f513675619177b1f242ad3d1b91bfc13c12de5dea6dc06e631c0b 9a184c28e056693496f6431e735c343a6089a97f906e8514700076fa58f57448 0a6fab7b4903cb31f5b203126bacd036d948937c1a594f6e440dcfa6b4286d26 +1133000 d7523298dc28919c8013c0ac727af6acfe6f4ce267098ed967c153c7fec7281d a4962d509d46a820a49fb810e77a35e1c8098b884d7e75a4cbc8241906340512 adbe563a034f945b386d6a57415256c4e6312258b00fb1279e3c69cae994592d +1133500 917c8b09c13690e991b7c881b133c45a44807f66fbad298a380c7270c4895143 5a2627f0d04569122622ad639211acf7a9314d0034e1b45f8dd2058e6792d35d ae5a82a7b2df2017f125f25a28e6a8866cb1fbd768e2a03c4604d9dc7c70475f +1134000 60156f72aa21b858f0cb2e173443fba18ddf9a3a1345ca548ffd9d3278bc03d9 463ce4a3ea346e1bf1bd475cbb015480bec09f46f8429ca41760003c149b7c2a 85c195a267889281a7b4a03305beea7dfff57ad94c1c33eb8fd51886da795bfe +1134500 fb12d064f7194732f32ed8f2a2a7de53ea1a73dfe7a7f9031daa353ed81ecaff 8db7d73911ace26c761f021b18cd0670bc65885047f63eaf02a7b136d9697542 23a12687167ec8ae699df6c1dbb543cc915fbc27cf0544af32e5fc720c1539f0 +1135000 e8cdca7a706da7e72d3481d889032df6c9b367e896cb435b090c341db78f872a c17484ddb08956e8a92f7d8b8454ef42d8dca86210198888208d913cdad86276 56b4c227906e56bd07f8ca64dd6560993dd6d44c4b2ae0acee8b2d67d6940f86 +1135500 e071fd474ca9124f3acce8a34da0c3da54ba34570813fb2d473de4f83a00c978 a475045ecf13b579c43be5678fcd325aefef54afb65c9fd70f4c205c53b28b91 4155bdec9f7ead07e7e67c41e92843d579ca8cdd87bc58d928510ca3da521ed6 +1136000 301ced24976685c5604fb0c5632fcc8060b42a4077c0a2213c7d6618fab10206 cd7b93520dc055aff685b0cd6cf84099a23217d70c382f326af121665b7fa041 9e5abb36e2e7dfd446ba3f558a87928356cab471ea6981963f6b9a7b4e0dacc6 +1136500 29cb8c1e61205e0f50cf6a33c9ab5064194f8ee509837a4fd03630d8fbe47c4e f136af606ba628428daf02f03b7bf1195860af32197d8ebc619f2af2eabc58da 28094c0dd898249184610a05766117b1a80ced32bca94512a00f5e62d066f07b +1137000 a5d6dfc5292ec2095d323879c1004c5d0cd9fe24a8d9da46d9cfc997a81696ee 138ebd481cb3d2ba3a8d3516ff77f282212a94e724f22b8c643a5c2f1b4be27b b430d46135be570ccf210c498321fedcd8379479b60221d636136e7aa6ad8004 +1137500 3197450712d51c8e4434860aaed5df6856956be1fb454121e1fdba709d2fe40e 466f5128a247f328425eb70da14d1e94a1aedf39ca2f3a47a4ba4630fabe6cdc f757fda6ee6bf2bf4064874a1895b7b1a782773a67775c920add0f42d1384ca9 +1138000 6b3469825708a51d51ff35d074b24826b4006f2d03a17d85c160d5527d0ac2de 81e512c4a960ac2c015eee72d526c1006d8d3e76a9045354313374a453b84c4d fffe12c111da7cc6e183007a28cbe897404ffd6e3f2f39fff98f80ba2d64ce69 +1138500 8bc75de348dc53012153c4a7bbb4cc46b535321bd2d838ab086ef984172250de 4adc04394383b517181f06bcf7d282c7e417e87fb033a2c6a960902e54617ccb 30350c2afe16ccc2450f0397c1f274fbd604b222eaa89a84d9b91eaee541600d +1139000 84020d9883b277ad87e2f1f25b1cbf4a69974fcba27f53566f9654dff75522db a8362b8552adbc873b556625497fdfec61a2530c5490012b4abeb32a1cb5b14a a5c550247c2e54401bd7bfc218413d8a1341cb5f1386cef23152dce3cca27f36 +1139500 9ded14555f8d10456d0d610d57257976026c40f1093b7a2b73db0751fd372fbb 61823f1cffbdfcda10c25599155c7f13680dadbcc8398370c6137ed9cd53bbdf 0801c762d88f5d3cf8de403c93cc7dfd8be134d1028fa30979ea888468474bfd +1140000 fc25a2ef77c1c7f16bc73b8c642d2c665212e53c366029fdaa34201e9d9df72c 86a90eb020592059990975301163f067f4f8da82e8fd54f3340a26b58b2963bc 6cc1d7e664b62275a99613753a738bec9ee15323847af0a7f66ff0d38082d28e +1140500 b5a309dfca7ed54eda6ff5620fdcf83b562599037b0cda262dcd4540b030c18f 3673f48b09a77df28122d68f58a17e2c2a65b4a13779a0ba86eeb76af8afe768 c351f4a5fe0034fe39e774406f2e0b27fa9b3efcfc55de2a8d4bc76a57578dd3 +1141000 0a6e1793166e49cf47afc188169fbddcf3db82f5da0133903385589d500c5213 c5bf32512c1a0ab3e7af1b090c4352a24c59682b6d9e1faaf7c69434628a83a7 5efd80052e3c7e7ffc92affa9e291f8137e5515bf01e95057da7eb0c7f441bc5 +1141500 9db6657cec478f59f2886f72f9fb3749e04cf199b2ff6b9aad7758a240e1bb31 15aeb06f9511d7be48258fe65619e4253a403d082f1939adeef1d65262520c16 7e1b6d17dc37ee5f2cdd49ceeb689e0258214d6142010b886e4490585479d023 +1142000 b9c2b2e3039de930b2a1ac8ffeb960f30d67946bc25ab8bdfaf4c8f8bc06bb9e 5310156a21ab1bfe648e5433ad49343d2684738b05472fc195241bded1f7ef5c a6ee7df606cbc7c6847fc5708e90f5a63fdc780459d634e688ffc36ac0a3429b +1142500 2145d2c0b75c047a079dc107b483c404da4632afa25e37c39e1938b3fa9c4e3d 4fa230a95545c7830c8d1e44fc87850f35ff2909d2e6f1377508f906c9776cbf 2dd9182c4f53478dc4f6bbbb34d8982f2bf098867289eaade77f1dab26eb6f62 +1143000 d620ef2353e299c7f748667dffb1adcfc1836f6a515566a06942c1c08fafe6ac f314ebafdc807008276023f603306f1e6666987a1a14c2fca71cbc10114048e0 db6be669508b812e611d801b9ddbe83aaac16104f9f257f5245519ce69219f19 +1143500 1d4c446dbe2eea70429c527c6be0ff77bef1137dca59e8bc916dd340410819cd 7e801b9960ea228ad28ef92254c6a5b34488ec7cb4c60ea4dfab16257d075417 bd5c34381a48acb6375e5982fb0e6f39080db92b66ca2471a208b90cdce9e5b8 +1144000 a11f1a7543c2806cdd476440d615aa5f961cd01c2bbf0a05ccc6bed89a86aa35 5e70af2c87950e2760e5b0432838422afca1e48ccc2a475c83e9c4a249f62253 335648b6ebf0145e37a2e843e3f180902afd7a78e54d381297931a2261173cf9 +1144500 427c2e0f1546121426659a34bf4ae095b704bcaaf9c845e9655ede00480e4380 e3c52560c8d5491c032b970a1ffbb2c1c74cdc4827f7feda821cd606cf727e20 d769b3a1ca2188a6a0c56781cb21c09ab0d9e33dc5dcda6245ea1f8cb691ddfe +1145000 e3145febfc927893aaae986ca6732c2d55ad48eadcacb80f8951203d1643956c b0039030fba664867c196308becf9bb0b6084e0952c1797cd3ff5227be30520e f297d10fed930f10886b34e04ba52ec73e45b3ffe5840fb631fdeb5de74ad448 +1145500 a150fa0eba6fcc051ad3ca7f73a6074bdfe74fd3facee8a9db3b72151b501c83 6059febd4d638869ab99957aa42138030341abdb9324504951987a654ba402f5 6cfcf8c239a170a383abf8df2a1a279739ee93532cea449c22386294f5b7060f +1146000 8e6f1981d338c4b9a3df95dcaddd25cf2eb91fb9529b5d16a30553028e8c1f43 9defffce246e53e68571372eb9dfbb2a473d70b83ded09121181d7894b085b8a f0e092d9db5e3e5bd641dc487d810692b3bb73bf9a15791bb6bda9c9d5029f5e +1146500 179f8fd38bcc00de826ed507f71ccd82e3ffd05180056f7d30423945306e7222 239e813eed3a8dd81ffed425e5f1890e770170bba6d810e7875b3487c1369b7f c740195e9d7ac90630588a21e5a4ecca5e93abec4f310b59a353d0cc3a3426d9 +1147000 270149ac4b828ae6402c568753871ac5c9ea404aded9ff47ca543ed97a514f97 b8841ab2a2da9b17483f7c21bfd624ecae38d5bcf204f9eb8486bcc381e9d97a abea8281dc544774e498bcd8c49a6333236b28e924016a91e761c30541fb5fd4 +1147500 202ec673bd1d6bcd5582e5c6f16f9e58a2a7324b7aab4eeebad8ae7d9df458e0 673de6df4b377ad563ee7303ebc6223d98894da53015806dfb123c25647164a4 7d01b0b78f8de52ccf26c7ceb368dccbc53ece76c1d87c4bf7ee6f5de4a8b63a +1148000 d9802ddba71145e597dc3c1692b4b38e6573dfa5ce250e0df5eeb1b639f5afbb 1a397365203f553d45b8e2934741c34a4243fd42f2afba3df58d66a1b4de07d0 832b674f0cb1e6f69dc99a89524bc659b0708bec49c6af95844e9cc56fc83bfb +1148500 98c224ebb307a70e70be5a6375d7f24492e6cfa0667cbef1b96e3c8f94eb89b7 a4f81ce1d5a9b6e7c8c3f01e450c46b03668166781bc66d90bc06da71468117c af03b89a1393b938c68ced340769567f62d15d0b76dbbccfbfcd6c8865aef6f2 +1149000 666c210cd5060d008e4f7cf3513a19511ee5785cd4ba03f56a91314879af3e69 ed011557483e008514a66f064171327cfd06965c1ac9b94580e5d9f93ee7c00f 9a6f674110b1f903d220333bee512cdc08d51f2e24cabdbc4e192f08f62367a5 +1149500 d7cfa00f07e2995e32290f675a0b5e66bcff647293843e99f15ad341e9f874cb 4147f48aa175f7058e3248b94bb15051b9077f89f89c829e6261b5806eb0d306 56d3ba1f1a90cf8bf86a5d69117b9d56378c554885bbd54268a193ef5755d998 +1150000 846051c51358a3993bd83e0b23613eba6a023b329d35c6105cc3c57e8ac204d1 a17e4b385452287e96d790d8e8d32100c933a8a1fbebeb59231601c2114c70ca df50ea3fdd313b6e4e66a562591cef6ca2219e875ef95db0b6e544bca81c514a +1150500 5c5cc0a581c55bbad2d4751e5a27f21bfe6e1aee9a8f06f50e4010c1a9940069 9491981f50a5e28523ff1819632c71594b9dcee964760f2d430437dc754d1502 b97120c4e1555ff840038a0174c4cdca70acec82763735954ccfe5182cee8b96 +1151000 6897a800ac0b8386ae8881c9509f6edfdbc5453925fca05b0a40b7d8ce3b60c8 3c19fd1a810ee36cdf8288cba05bb14454261acc946e8654d1e645d95061d9e9 2e8f5879adcab869dbc04afb8ef8372f9a45bf73a93e797a8799190b17c4e315 +1151500 4d5c605d4b3b8f422ce59c2ef3034ac8c4a052067a49540792e643f90a59ecaa 650071c2699ac59248f79ec425687831ceea160ffca218a272380a8c7680403f 9a8c2d20a3c0fb8d02f717a368fafd034ce79cd25f0c81dc9dcf1cb9725424fe +1152000 8578a233da4cfe0ab59adf604b1e95a7bceec3a5883a600f424b58224a042bd2 03c6dbaf11808b647778be55d1d2a58dcb7e86efe098a461f17a6004cae4fd06 7b777269338b83cc45cba5e1cea4b9108281d2666ee63a6b1fdc0653c2276808 +1152500 386c937110e5e385e3fd54936a81965136e9f684efbf5d7cd0be0696f62d78da f31e34a9f7d75840b454ecd81a3316dfe3768baf7c03b1ddd24730d67723f0b0 eea3067db670a5720dcf08717acdaae897f7e34ab2f4f8ffa29c0d9195d46c99 +1153000 8420338bb4666221a15fe2d84697a330cc98ab958113f64a37c03990bc953daa 0f928fe675bc23ae7c8e30875a8a8b13db012fe515f50651c8b9bdfe4a3271a5 8d5df0dd7d461e7cec4338487b5b5231309f158dc5ec6d81d0d8b10765644bf6 +1153500 87efb4e16611a1568cf0319d145c06a9ebf49886be3c9ddf000bc73f8814733a d6afb469f35ac307455a741f92206bc4c5df3333323b4f126036e54335422f1b 9e651274e0c3b21f7256560819810eb358190a2a506de66b00be336f258e8258 +1154000 1734ee39a7e0e5976745b577c011bf4101be15f1a8925ce266fbbed0c0227054 090b966bfba292abd873c50349afeb605a310e2b22054cee83f22d82629bc544 0d0948dd0efa0bf4573643646ef01f8b7bde618f2c16a0a364f15d3deaba232b +1154500 e7d65297b923f8f5bda49fbf86bc310ae2908d590737f6c38c7f4b76da9fd09b 4cc6c0d5455807d36774ffdca61ed011323c6e085b0d65901f4dfcd243677c5b eacfbc6f708b20ad2c80049c185921460e7393e09fef177aeac60337029f4c24 +1155000 5e158905621b38c082ed28b8033391eb59fa7a0685d30c4d3964ddae6e2698ca b6f6be1dd46efcde85853050e48ac6b165a899939c3d2d43748f4e22d8dd54af e2a24c10f07f1ba2345f96be0980d8735d266353aa10abcd84a24f56b124d676 +1155500 87bf1d707cc82d836039acc5b7afb94e4afb39173dff1da7c9737cb12b8a6fd6 16f834dc96d90345161b3eb959a28fb5560fb517148ee7be03c1d9923e854fa2 a01658b15ca91215782370c1da51e0bd83d302a290a31a446858878853b5ce45 +1156000 f1c5bd2d3602236bea78ff2e92fe1cf2e8b9e3c4100ab33b70fcc95ddf4300a3 a4e305f26bea67336f1c2402694c191b5c60971bc84e4e3e343de2e6a7297202 71c82798dd11569a3a97935baed28ab9efa0f3dc5d10a403ff59f8c79eca38cc +1156500 4c0a404332dd33ad1632afeea5be131776ba024992db41aeb769a6fa79adf3c0 016370c88e8b822ce9a42283c9566e20773c3c28bc54fc2c5fcf98321c7a8cb3 8ebc886c31d9bbc1b7213d60f5286563fa02ac7dd3fa7b6884a798dcbde08d2d +1157000 7fa41bf4eaa77c953717bb955d2e061be2c773ce2d0f642580ab3881c9fb8673 496a01f8e00657df24ee40637eced09a8f167a48123632b6e01bc369faaab801 449c27eeecff852d5ace0aa8585a627e91b9fb2b06b324858207223f2e802365 +1157500 08ea4ad620948c48dc1ec42a06ead6235127cbc35a12deb76a7b3344c3a95477 ec5b6799664ea074557017c2732ac65a965ac0e9e5c83490e8dba5b3e449705f 7e62b333c0b2e31f8266c7ca923e3b49b1969f2fd38005099b016b72fa3fa7f7 +1158000 148ab01b3a3be90a479ef0f6f57b58affbb8467027e5c1f5ecd548c8f6aa3c9a 09b4e5eb4069bcf0c39801dc7211ccd0e8aeca612f4180f2e2e9fe073b8fd2e9 3d65dffd115109fef4ced39129c63ca7fe4a175387cba528600359e99d16d3af +1158500 831c15c8c5655cda2c2b481273064dfd5ece80c913e0d1a545609bff92cd4bca da3e6e48da50274c26eaacce26f2e3be2100cfcbc996a3e2d0bab535d7b1ad5a 0d5add586bdd5d39ba3140b64dca56f01be4224f578c30cc590667206e602123 +1159000 60e07356ba84702f42a652dadc753caf51cb12a3e868978f2b735d0543b649f1 ca8fff227d6bb6da93af849688c6197a105d6f7dba98bb1d6413f0d527410fae 9ae55b150fd00828a6211359379d2928d6d439f9a8b7ec16e07f0b391cc1917f +1159500 1d53afa49a747c3deb87b45a62a682b0e99957e57c0b33f40b16b08866b4fbaa ec281b3d24746b1430d8764d6a6ccc5001ebfe7db9e4ac9015ea3ac55aae22d0 3d1e4385b3926226298d94f216eda71d0a13524ab7eaf95e0d6af08bf72b553b +1160000 6455fed407287ae515275fbf3363f4642e4b388a3d0a8428bef3a1a6f9dada16 1a77cf13f3877f55c1a4e17506097d102757d35c69fac9eadb16dcc768fcaa81 550d0c9147fbd67b7b9e252e8abd77d4ae003a88ab99b70e6f63c900fe44011e +1160500 01f38d6700634f0da4eb7db3b20bef90d932874631958157f54a813b5b36f88a 09390dd36ac673cad13bc27913a8219d2b24cb4c3a0a773d6aa36b21b4efad3b 195d06ba23cfdb0b94d40e5f1c13cd3c343bf1b3459237ba0e9724a8e92d3bf1 +1161000 d7e85737906e1b39a5732d3a7f02791f33f367b92ee2814b502950bdb7c1ac78 6deaee018ba0f8395291060170e6fb999f0d4b22fad5417100f14a911507f036 ede15dc5523ed1503015e47dc9b25bd675dd3f3a51b98925fee35e05de2c9d00 +1161500 0e545c48cd0b6e27221c7c0d665c1e2078a4b026b5303d7ef0686fa3ab9916c4 da0f35eabb8fd1bb701c196ba9dec94ff5f3ca958a05c818f1b92ad5b8a047d5 5e141cd592d5e9fe66c4e683b9591815c6b8334d0882ec35cb7b6acc03fdcbbc +1162000 5a60b52bb293b27f5e2a343df501a6bb69b84a88ee16980e514488481a5cef35 ec8a3a0bcc660caa13e8ba069cdc3cfcea705f24acacd57effb94945718b3c4e 0d9ca288997a657014b9d5af3c910698def6b402b236fbf1f076c6d32e55fc2c +1162500 91207c4da535c0ae6e8e346da11a7bd7ead2348b8ab39f49a0413aa61270f667 0f43a683cffa00f3cb64e19f83da801fcaf357f19fa8b2f9f41d560556f9d0d3 59bea909492c4a8af6801aa3492b49871d33386c7b911f3b0925edd8a17e4434 +1163000 2837d380c18ffe8caf652039bac366b10af7c162730bdab38bd7f14af0b0632b 7fad18bcf33e557079c606a64f13ff07ecff8c78becf2c90bb02eed566cf20a5 c751822d8d898759e0972022b96db97118eb8c83ea12baa0841cfeaa98a88d9b +1163500 3be2c89e0c3fa2bb82769b31280ef94139be26f03bf14b54c02943430af8817e 701db33812fb1ef3bfd3248b02cc743394b96164f0fc36381606924eafd5dba2 fd3551ea49aba673a693c832329728113fa90cc10694ea00acb6d5d05c400ffa +1164000 a5bfedbec80c9cf269901ea1c524dfb2868172dac1431858eae9949da6b8c67c 616f029ae6acb9c483b65c8e6ee6a52ed51cf80194b176905105bd90f362565d b5a7c96b365c880b46e72889214ec882afb029ce60d4c84473ca509382539b1d +1164500 ec5c0278dc136b23b284bf1ef30d6cab0b24aaaa891207161dae7ce84d032efc 1a6c9c192dcf6eea4ba6f23490560ff723894380a5ab9d21a29aa06a8e2c2cad c58f545f582ec701da23c32da030c5ad5f8cc4eefe43084f9ac23f77f76bc417 +1165000 c38c9727e3dd513927d08945a6dec41496e7bd62d03d256e261e8d23ebb5a1a7 387b63592f92337534f373bd895c03e860937750ed5c5698ca878517760914ae f5bec834a0cc7b11a5265f27285ea3f83cd433652c2b6358416eb41cf7fc13c3 +1165500 82082236174f8ddb37b88fd105580d79a77924efab3fb2888e05bd7cfa8f0c4d 6d32276470bdd968f35925a2c6b9dce9b27ecbc5a3a8e71bee4b9697c88ab254 2d0a7a3d9b3263acd17b11f2e1d11880abed5a8d5170ccf5cb21e2fc3982a379 +1166000 a0fac4b306c379866b4c01b909610b9e7e1f2ca794fb5c590aaa2c83a666effc 4b67f68a8adf5d50d262ceb7a95cd82ebf00065db0ab242f696e0a082b7f8151 fa111449ad59977279759470503b67df2cdbea065862f5d3b6ca61b62a34fe1b +1166500 2c79c6b923aec6eefa4951ed06fac160d02c82caaa0a1c11bd49fd6ff59d8ead ec655e3e7f55442ae0e5282b8f91a6d2a88ee19668e0df9d92eed382eba50069 7e597d5b821b7140cd3c10445409fc1f11b4f209df0b7f394c31d7b7f9f954c8 +1167000 f20f0ba0c20fab2a4990bb6d31a736d1f444457af660cdc05d133228e8d15047 2166fd932a979f00318f6616c3c2184055c29c214d49a68454be63731fb380d8 63c980d73fad3a22262d71955940980544682a37c1939e259463faae424f1b6d +1167500 a401abd7e22dd4c5857bbecffbbdb575ef2f3b1cbeaccc1ff90aa3cb7ba4d03e cd245140f4ed7ca46bd7dc30295cce6db884a18f06a644408b3122f53d85eb7b 20c8c957ce0424d4a03c4ce971c2e1bde4732d10fe316b1dcf52e3683ea914fd +1168000 169f9da4c456d381a672847adc804eaaa695bc4c50a4b536ee753bab29ed0224 8fca11c8318d16f1364d2663f6cdaaa47a92d008daa7519846f22a68fbff6d44 e66b572b3c4b692d4c2ac327643cd16fd00a7a4ecb91fa4bd2e97d23030301ec +1168500 54757c8dd834113d79ebeb28a73535972d005c345e33d34d9b9f0d1b5092d71b 3fd4ecda5d6a11063d66ce9a849038ff370c6244d14917ec8c87b2cc3e8e9142 2b9f660ccf344bc479ae9cb412b7f1af7d18e08d585f10d4eb41f77ec366e438 +1169000 0408e4fe84a28338f1ac1f36fd6915bcfe05dd3a08ec6c1248c5df58542dff6d bf97ed6cc13fdb2e9817a702a24b264aaf746c67e7a7bf077376dc08ee1ab9dd 1103ca26dab6666385aa27a932c63487da46a44a6c13ee27804a22bb78d9bedf +1169500 e8e952c72e3b1730dcfcc4d73c5c7ca6f64806b1c350cf127e09b05c5e03dffb ccb974938643549c6dbd2eb11bd60cfc7c4a977f88eb2f935ab81f111500dbbe 392391fd3ae91091d658218b2866be420097c4bfaaf209f37aa1961e3e380927 +1170000 74283d0f2aad17892d0d4832778bd1f3a55879d8ddbe1314e410bac40f6a6c02 59407452382c4869286b028e35e69940a81ba9c9fff7eb427c0cb4650b18e7fb 25ec2c456054fef281ac033f1160df826f8458a5f7f24be4faf503b6ab9ca070 +1170500 038c3e9a4f8af3e1f89208f1e10152279998e4c56c28ee571b64c1b1a2576b11 1c50f607d118aa4bf311d63ea309ac5fd6c023bd73937dfa60ae685684d5d0ca bca5f157ce2ba2f4b2fe57e949e84052ca934dee1d685460e7a207b1ac4f1dcd +1171000 657b4ad8cda15f1fac5b96ee4c78d30d24a202cbff03b05eb42b8a64a9fb3f85 b5ab985da7441c00c83a521cc8191c7b255e45996560aa7b5614c9a85ed10382 441326a82f1c67280dbd7d42d06c41e7f2b131c9b591b7b9f95bee52dc354bb0 +1171500 57a6596c7a9b14774681db13f91c27e8d10a2a4a3afb4932bc0e99a352d616b8 a37e46a4e94337bc220479a47c7bcbcc512f9235e06f7cb3ca4af02e2d1784c2 2971d7353bedf68e705796a109ef562fd54215bff4d23e130940de8ff28b2abc +1172000 c8c332595916c25863c065b8164053b7306c9b91280395899646a89ef5c7efb9 79045e4de4c46ea93c7531b2983c6cca978a870f81e69caab499819eed84ff97 1ab7491c615a897bf0e521a4da4b85476a0a578946b53af637d95a25426ba645 +1172500 de2a9b82e5b0fed78938dfb45b5d03486a9e8f918bd1d10e9a5dc3a5d2ebd375 ba34eb6149f1c2d4a8fda76bea4c0126d2ffb924554b02d46a7dfa3af7a42a95 8cf00395570c76499738996b0ad071319f08337efef9ba5cad46f908b9b495d0 +1173000 ba3a9dccb5269e6c3c3b4372dd5473799a479d5f1bfec6f1495704a031cb7257 a5a363ac0a854dcf3b3d461a01bbcd7c23b527a5ff7b1bd80c2556a39b1611a9 be41baa05f09e1eecb3149a981ea9fc7772546695219c581cd96e3acdd89307d +1173500 6a87a0bcbe00703055e2f8d7e23d699ab348de2af5af0eb3aeb62957a5e634cc 925d9a962bd2f3ba4fbb524d3e783d0d88c7e44097b2ee2e224459b80710367e 5bcc28481baf168220c48e01d8a015d469bef8060d58ebc3eed690da7f271a72 +1174000 f27b5113e31f85ad0f85e24fde10a7828ef3e8e841b6d52cfed03aff2a91eec1 6bb6b3720c1f4b5117c00fcf6a3fdfc39e8dbefa10ab076a7ae984564f4ee7a1 481d1cd64f14bb93f23db0109d6fe828a568896018615b04af18d5659600c756 +1174500 689dacdea09e8fa04512de546a254b5fb31bda1d56480e88953538cdc1083659 053455a8fd5470902eb339674c47ba7210306bce1ea0e8a513fc1c5f2b00b34f c7036d82e4b1e8ad57f773059a1e117a0b1d438ffbc8075385409a36c275b52d +1175000 8dfe4fa221cae2226902551cbffabbe18c43064b94dd4467ed086ec8a8d89e4d c3e19a94c95ee409ef63067af77d24f5c2f735162b5db991eaac5fbb15880214 d409da21e3de08775ba5958543bc10b1a2faf2e414438419c618e3781b79c2f5 +1175500 8911e671880ba1ebe793cbb19058778ca53caf6bda9cbc91b95f4814268d7cd0 7b9c386e2b97caebd5b7e3fbdf6a1f38cdeef152f40ff7349f4c45dcd2617e96 2a487a17738ba746ee0af68c61583275efee71756a37128357e43ef51c0c2b81 +1176000 1fd913c3319e09ede8cf2a61a1e91efed1d7726e7f46a5f17e7a726a7c2fea5b d17a1abacbaa6734cdf2728ee47e79142fb7ed4a707b333bb9810ec459170c6b 50ccfc31535da45eaaec6dcccd6159d3510e5df67795c59a408cb5201439bcb4 +1176500 a11bd9a24a4ad6d13027b77ed5c7294d91ef927de9fa991efc7e1bef6f633f20 a70b10a3e84e60f705faaf2e604a983afae005fe53e55a66f747ff47bece72f7 c096ba0d51513cb221e53105461803f0a69fe4d0dbe84970eae8204e41008238 +1177000 6ffa6c3fdfebe30cf1a7e8ef456d706423ca7370d250108a345c921a43f6d361 e96c39acf261f3f79139e4cae812888ca292b61de0f49a6f14f724458ce941a8 0d27963c7629d5e24f8848666af214eb3753764fb839bd5b3b18b6d5c9f4b4f7 +1177500 21944d33335de6e7be3eab1afed00a8840ed09059769a4cc8c95ada2b739bac7 d88e2a0c9645654dfb23354a9f0f90e41735a796e184a969ee32f38e0761f0b6 bb28cb1b9f1156ec25ba4346c69f25bb4a1a30f230199fe560394344a08ff569 +1178000 8766dd180ff2d647439a5cbad9b1f79ab7e85c6c9fd748eca22f707a7544985e e250fc2eef43908fd12d91b90828486f99db25f9fa749deed0b9959c3554f667 eef4af40225d005aefb2d36e2d6b6375b78ddbc16712d82598e2e4ed351c41f9 +1178500 0bfe9b952084a9906d48fc53724099d6bc735bed7b327ef362f32eebe8c59b08 4053aa9f0b929b2d3f7475fda64edbfa8a5567c3280fe8979da8cddb43e194fc acb4f384b6d271f82cd521ba1753b687b27aced918d9e5c37e4a0a2cfd91a226 +1179000 9052cbdd7759a7dc740c100cfbf1f599192393b4dd166177eab203eef214fd5e a64cb29918db51c90ffca1e590956df66a3b47eead5018e56b6f894376d0f1fd 583a6a580f3062017f6a7ef8b0a51fe13b2f40659101a4bb3bd4cc3ef79c327c +1179500 2d24b0b8f56ac3c5d7016923fcbb74c9a7f2bc5cae1302edcb2a02c9ead8e285 1e8ef0170644ce900729fbf779c85a9f7c4e41913f38bedc655968799c0ec061 843a1a3ac0fb093a840dd998812c3ae7e2bd420f8e10dca85e7b153a2c99f390 +1180000 5d7b2c7e019293bf5b7f4c5339aec0ce4e22fe103cb50213e8e7d3f4da3b29c7 10773667c0417cb9c8fb7028d932e840525495a92f5f0872ab2270f4dcf4c4d0 5cf1307b81e3621a6df541defdb59171a59c04a70662ad0423a8549204447215 +1180500 192f605fc1077bfff7cf2c321b49948c1047dfae2e0075785af9ac544f92f694 00007009dd28ce5b73abc87ffcf7a0b893273d21f0fee75e9c0806c7a8c03279 6f937e16a2bdecea77d6824aa2e0c94b6748c876077a6f5b8903f60f4e08892c +1181000 1a374e98af0b8e62c01dd4f38fe2db26a78f29a850c81bff299b5b2b36a2c1e8 1fcaf382ebd711e568b7c74da96d6af9155a7db2480d209272b97a0895ea2135 c1862a830fe189293718009b7d9be0f1c68937306aad6bb8461454ae426bc875 +1181500 26bdca057d861936576e6b74a4d152c8765986d87bc449cc90dbcbcbcc9a6f5d ddd1296eecfed70ca8da34a5842984a1839fd9dabccc570a7efb1ca282eaf76b d6eb9dfef771a4155e878e6c822d4530fdf1bb31b128334e050776427dc740d2 +1182000 5818285e1deba2ad0092c2296332d3f87d8d32706f23c279b91f88d5da624cde 9b6f0d5ce5a1572d44ed11029ae3eaebb31c089e8368395fcf87e3fd7fdbda0c f7ae4edf69cfcf1d2c91ee9fa4794e005e7a77110b8c1d25d56420088a3a96dd +1182500 3cc479687fa03c61af76c9529c4a59980cbe72800d208470868ac6c213bbb901 def26e4190f2ecfb57068e1018c29d229418d811db11f402c03be4b42b47029b 603f78ce5ea7ab32b6bf1b14097610f4b9715db5795ce1e14030dc9f54aa3374 +1183000 d382fc4f1bee42dbebc5cea14116c3c5ae49134e7aaca0b7984665e383408a42 74992b46fc95fa3cd83a7f8a3f04ae118a65423ad1223e4132e5ef989a347adb a94cfde8c01f50523ff4e224def5e62d484efa688d66d55119eb3dbd5760242e +1183500 c94fa0eca5eb2cd5e49cfc3c3b6455c0c7c1dabd3159be6d8b31964d660c436d 2ff08791feacbc4f71de50eedd199a13d0cba2f1a1979d09ec4ea3fd0e1f712c 219d8c0e4f4cf92a91cf10261885b1e6a131e94e8209de60e451330f4503c243 +1184000 55d6b513e8ea740820706c608a1300a2e11537e85927e3db322372cbc2f15b4c 41a0a526c959d3bfe37d878a1946926b8d4ea7779d935f28b14e177f4ed7501e e26accfad135a91eb5f5aa1e5727d54f69f3bf53664a4de6e095ec1b9bff3791 +1184500 ead2b73eafbd44710fa0f467b27005643fbafa61ba9006a52b743fef01a4a248 ce3e80f0249ae41473c922571e0488232d099aa1d14deb15d3556fc848f161fa 18875885f1b9f0f9542b1dd0f1c810af88d717192d957d98542382ac0cf8f0f6 +1185000 117e43c2e1bb661a94b1693a5e65abb4c967d23d98d107b6467dc12acb8121f9 11ca26896eec8e59ce0f1a4c3cfc2a056d0b29a8320b1d2be9de3c52fe562fdb 39ec38423110a8e3c345c857bccff9993f90dbd81fe704e9cd0af5b51d71516b +1185500 edc207e4f6cd8df599cd92763399d54312c087d869b988e58acb2a7c7697c9b6 8847987eed302ffdc582ddb25eb1dd0312a460bad2cb2937f550924250ba4245 40f4125eda5a9b597f2cbbafafb4f2c811147bc21118deb44eb82119fb11c50b +1186000 636a1e6cc5e6cd0b8d6962a6938a5c4210b18abbad4b387db2991f19e51913bf 44f3ce5be9b1959478b1cd4b950ab6f484f8a7bea84d929dbb449b09e7a70d77 12a3037a891e443b6de0297c7824648db30905aa82ef27d068c93dbe52087d13 +1186500 93ecc2ed75e31e0c625547a64ed9a28410b1ee36180fed190526ee1c3159154a bc65d5313633caa319e00e6b89d3b6da03a7bf145b0610abae9b57ca29d49820 2989f9e7826c7181c3f038f4bbf4be3977c8fdf6fd5b213d987ee8efadefb31a +1187000 73a13946820126396821e45e4aba3c6bd00385dd868dfc231879a9f289e432d8 70cd2d89d96f32832b303fb5b524987669d4f1d42f980045fba023149250ce9a 520340c83c1a0103c5dc14589a81434be1e5019483d93dd3051d9f6f2bcd44cf +1187500 1275b7e74b6e09e17624d97233c8b020249f3dc83e46959ac2644dac308b214c 647ae3418ee33df97745e1b0bbf4988e5d185693c4f4e88d0f5331fdfd27f4e9 1f32a375bd1887fc7d103f840e73f8404fd58f42617c8f99cf7b694dcb7c2396 +1188000 939fe50612a46a4bd71bc908c29e6a06969e60f2e09fc9f43c71c983d5ee6d0c 973e51ee6dcc5d468d9cc41af7be8c5b96e4e6b8febd4e88fa709668648170e5 43004f78454ee7af5f1b8473ac84e7a55345e36135e11af5c110571ef5c68c4e +1188500 aeebacfada3a01155a21cc412216669133e574ca1609bf2bef4d304b1d398ef5 87af14122b8c7611986d70fcc5e7d5fb399a3f189acf0a9267f8305cd614e4df 06eb034f9432dc5659b535d58acb896931cd67b75795dd71fe19f7cbb76463ab +1189000 a199ae235f847a54e560fc871b1f31b157aefdd9676ce85f6441699d9d7b4d4d e0dbc15129d6054aa604b2273f5282d41ae17997471f7b1778cdb62ab6830d0d c5049c19edcdddb7928c54cf2e596f2b4c1a0eb465ceb038654af7405ad5705b +1189500 15faeeb18f50d9834a21bf6bc87337313c3023f9e97e57b2b872bb11093e5e44 7f0817693d1f896b2dfe3e3f8cb01d1d785c0c1cfb0d600809f9a34efcc98029 61d9a31baaacc0b2aeba6aa463aa129bdbd39b584f13a5580d31018240117f53 +1190000 4c3d4c5804bd332f5432bbc684638c1a9619e01f466011d5edfb0e8c6fddc2f3 9986bbf517e907075faf988942183d7f0c69847453c7f88d16384ea57235d729 74378c41b1c4f6040624b76a5e00603173ced294d606b35dbb8bfe9749131902 +1190500 a9c111f86338a7fdc31517a1d3937d58f06f1c8d017f10ac32f9d3d11ad1c325 8cb224499e2baa13802cb52756b23d91f15b4077f5deae46dc2a03387cbd6a46 f0c378d94008c2fe87acadc5a6c2a4ea5a674a5c23332349a639adbb7adf22df +1191000 3b267b1a605a610a6ec582c24a74a48f86742d49663aa610e95bcbab88c39e2e 2c119f6ba59bbecdea8be203ee12c602a48e164c4e04a548ef2a697df3bf5a33 9794cdd7dfcd809d929426c4bb8c7781bb842526e03bdc7a373b19cca8a9c101 +1191500 f6b4170e43bce232de89a23cea7990b8ceb252c3409ff6ff8dd7e60bf0374e54 b28fb17ac22be6b22650067508d40f76dd45874c54d338c6f899c847f96b964d ff0ce6f473283198dda442332f1f89f410da5cb95386fa4af537092c70f4f9d5 +1192000 dc2735b845593d0491eb7da24396d4502afe30f971df0846bafc4033ab279b74 a09cba4c0ca978cdd91ef0bd389cda7fc149bea4584c3bf6d2ad8b0fb42d9f67 59590ceb37aad4b20901455b57109307a7ebe2cde59cf38b65a84bbbfe474ea9 +1192500 ca874ec4839b67b9fc271df0d6a94ded0c215227eed274fafe76fda87c7a1cb2 b8d910bf6c4848fc997c4395d74dc4697d9acb51c5bec82ce89be2e2d6d3007f 2b05102ef1e2044bcd33e2091bbe5a103422af759f386f69e562880122efbc42 +1193000 e39828d1f3b1ea228b77858aec3499a61fc0c38fcfbde90abc691094cb4a5cba 7194b64a38f2201cfe792e77a476a441a644adb9cc150c71b6774121f56cfc36 55d733c0425b71ec8a816cba6181e37f86b5e99fa9686fe4fdb9ed4732ab53e3 +1193500 f60bafc979d3bab8617315835699a3b3cd076fe21b020b1f180a51171a39281f 1517a86f5af92008fdb2a3eba9ebeb43f4e10f0159ed8f6da8a0322d38b5b716 0786f05e09539d3e834f11df611dde2149a526a21a8fe6f4048f8eaadd655ea2 +1194000 e1a3ecfe4dbf8f7872cd7e1520dcdd61e85008d8e5ed2c8ed4f3d2a78c3a2688 cc95645c91f1cb8570ffb26c7004574bb7dfdb871ea11641c8dbdb3aea81fcf1 47df81a73a940195968e78cb2d376c59e00cad21074732a6f17ce5633988ea99 +1194500 a96cd5f1088624b66f4cfc79af7b645a0bfdd67131d61f7cbf18b3b89a493e81 8ac98e05aeca7a4d484208ff256923aab0a94a0776cf59f3ab22ac49f5a153e6 4f63940b20dd45dbde43cd9effd174fe8d1b58d6c18d4671cd26366f2fc572b2 +1195000 743ff73d991949f4943313a570302b813c1a783fc7ef4808194ba95a5d0f342f cd294af7b1de400f09820a2d0d430745205466d9ddc183b8271b40542108805f 4ce13e06e2291df5f3487a6b471c26b0eb994bcefe6d3bae889e88b786e32c32 +1195500 c224c284a418e9c6170393789ce17221b65b2cb4d01d78bab846023b01337c1c b2e46eb9bf71fbd3559c99029d84df9410d8ee1541662ba79303029dd46189da 6f9b3fdfcab00fc669b96bb50858ba0c41fa7922f7407da5e9683dd3adbe216e +1196000 4f5e727fd3c0c4316ede3129db86b088a9fb077fe6eb3ec9ad84f40e89ddebf0 cc941087965fca35754518a5d3eb21be92bb38882150dab8476b47cb95ac5241 274de1abc69b95db66bb8e1d0fab6cda37df4a00cb676496c08c8751e1e6b86e +1196500 8d8c392d670e068ed6621469c7a4adefabf064424208671109d94edfb0f2e203 16d66ea77ce1b52ef738ab4fa793819f09ad930124dbce9dce4e5e2c701c3d41 3879592b2b19c74ce6f54476140806a4ece95a60a6e107dc2095af40a8c308ba +1197000 1599a2fb940450bab2282542cb60c30afee5c195a4c63fad5ae4c6c2c42f74b9 f022f651ab7fcff2fbe8296d9a2f802ef70de273d05bc7c2dde74666b1ecd05c 04a77a5c3839707bb9a7f96ec74f9517c5b57dc6c4d1a5af5256bb667dec44ea +1197500 4e570d3ec2424400ad95e0c98e9dacf5c35196d851df3eb410d5af0b58fe6f98 7cd9e67d5115385506704d38c17ae7409ba050d47cf8cdc4736adb935cc0a95a ae20af61def9617941f12b4a704115ad1a030d951db13abbc77cf9377ae3f78c +1198000 d090b0121d9b30c48647797b366e547aa147195753b6d24c9823b004a35d4f40 5f6b352ba1f84934e13d2f144c8313723fe382d05f720f25a175fc3684032e92 fb7e3b75ad79622ea55fe9503327f342125f6f51f1a6aeecb249332bd0a9443a +1198500 33ffa7f777060cb4a65edc50deade02100c9ba4b044351b7cf8483335f1f33a4 6312888eafa2beeee15eba13879b11e753d460a9b54bd14c16cfbd92fed6622a 0c80a80a15684581a2f10b63a58635ae575217b04101066ed6875e519c2cc8e3 +1199000 353d93e957b6057d7db01b3f632e511c7578276828b7ddca8a9b7d67634ed8fb dfdb4de68f8101d07d679bb367c56bf1c1b915e14b4daa404c4d95538a0ce8bb 40637f00a3b42632fb1db462a591de02441a347cbce53949400ccce24f5e3171 +1199500 682a160df8103cc691e287e65f4be0a07b93e61d933b7e1209ff3bf99655b105 d27be3af785c5fa03a5bf9f1dca4e93dced046632eeaf81687f3970f6bcad65b 1f6f004a1c5eb2eff165d443fbd316c86026f6df169756d8dc150ba658ecf903 +1200000 c1b07af1fab1845a2ab1e3bb273ad66169b6b3bd1af2327379e2bc913a57a27b 6168161d84ad2c05258ba98bd5f125765eb6e5b3746a25a657b712f052574546 2dceab80adc689ab13f19acf91bd62c81a765ea139f308d9f7ba071e7fe69209 +1200500 57f14edb3fdc4fa1dcbf9126342748bde2f783ed8c28825ae7e192556ae8e06e f8819073f7249c9de5fcf2bde49844edd20ab2116fce2789ad593f3ceb6cdccf 8c37c36661f15ce079164c889b5c40fb44e56a521c3d71d20bb784beca77ebe1 +1201000 c374118765a79f12494bd96e98e93fc6499bc691e11f2c9f1f4a0cfc58c3badb 06a83776d68aecccc42ca548fc39c219c77195cc341b031f28e30a65d1ffa09c 8ca3a3e18e51650cbbe8a32ae8cdb7df8f6f6c1af7775f3b6893fac2bcfe6961 +1201500 84d2cc64256c37b71ee42179c4598a2b2d71d851980c58c86efa015f1a9897ba 3f9d847cbbfcb5ab30c95b80a3349d98203d77ae604dc1956b3335967688cefe a5b3f7126f474b4b9ccd198a939d37971dedeae13c2a188878241908821880cc +1202000 7671d4923c6b0ddd454d720c329186a085724a952428f0c7aa16cad524eb930f c235db6ece38cc8563b23d18894a95ccd0e6bdf45a91cd42cfe09be43caace85 daaee30565b5d0a688f5fb2ac4c85485e14e2d50ae1c1d850915c1fb288582f5 +1202500 a441e857ffd0354c034b6b89978ad9cbff9d6260f64c813f37f17f70997d0671 c464a1d63b6581ffa5d4d5b759d76517096e471476efdb2bd66dc0daac2b3896 f51cccbaf8435354aac6d7590442d4a5b61e9e7d4dd64b7cdfe7ee318b22dea8 +1203000 b6ed108ca0807ed83e08de1b09d97fff24f3324379ffa6fe96246e7e0ccba389 43e06f33d0ccfe29ba4273718e04b1669785c358cd115f18a9db51abfbc48361 539399ed00a0170f912b1ce300a6310b64bc2c763bd48185ca757170661b7550 +1203500 5b86125becb1d321fd779f797c29883e10585255a94eb17f9bcb13164878ae9b dfe795249e76a22336f504a81fd395cbcf8ee20b13a0fc5e535e83b263d08693 d6621f11da8480b404fdbc7006828306c95638c100dc3c17da5a514a16070613 +1204000 bf649eb811de0e27de67035b9fa99ab1b544d7e6fdb95ce0f1acc9f2747fdffe 9d7e910cb0a1829c2e128bcb34f0eb4efb23d93af505b80105ddf24c067c42a9 02f3d080d4303a08feaec8663d8fdb7d51b5fd14db5dc2b10bcc356a5d91bc61 +1204500 d532244026be94361f684571a88a86381976ec48895ebab3c6e89904757eb545 1cae7cc323c38086d23a5f52ed955e7d1a599fa56e8576ab9af93ba3080aa9c6 7633e6cf24b610f3da21f5c93e42c27967ad537d4f57c4da02c6c4624c573e6b +1205000 ffe6b3cc2291010ee068cf7ece1f88308da963143e68e6000bed9bb87f7ea927 1c090e0fa384ea69d72a98fe4f245adad06cdf5137c6bb437dd914e3a0eff1cc 89fbdfe7e48deed06b7881bda0149f33626d6f7cf3f71e36d2ca4fe1790abd36 +1205500 e92c6bf8cd2bc60b739572ce92b73cebf0eb3d1e97131683f51d609e825427b4 f867c059c7955cb423f4c17eb99458e68c88c9731557f6c5502af42158d6f81a 831658f6e79456dbe33fc7ee192c7d9ddcc55c3044055af42234075208f35111 +1206000 e27579a282e3c8783343c37ce8683a95f7a3bb5f22bbcd6399339f8971499872 da86a9074d32a4667f9bb18d0977c2bf66c295f1da1e28660cb3f38b4c240fed 5d3db6dc05b9784b2bc50d5090287a931861788646ad73358dcc8327cacc0712 +1206500 a7375cac24fb500c4b0f0691391fc513a28437b869e9b48a116fd9540a5d2503 de227f2a657bc6b1d6cc5b83b752b119b93cd45be9301bb3ca2ae526d5736a32 779d1a2d00459d8ea8534d204b8068e6c6ea89d55b3c40bb65558a459a78ae88 +1207000 ea4cb230795e26b0d328f96b34127605f9a7550ec30ed5e31e035bf08958ede0 315a04b726807c402571453c4226eef2f2bf74bcae3fc0ffcf0c250d3736e474 04f12ad79f11830efa024e8f3e88191b4b5ed27019dbb719e5081cf45bef132f +1207500 fcd48dafedae2769430004e6a2a05ca9ca9383f225cd6489cb772f8f90eea897 8a9bf5958e37b74e62b75009d9478510d7880196e4a1d155e7d5a902b6fa5fc4 9abedb4e07aded52a725e9db6eca1b1c443fff5f56a067e2f20811545abfa5aa +1208000 c6ad3736510941d1c452cc13ea3365e5a2dbcb283e5c9b1d544bcbddc24c7ad4 b3265e745e59c3fc5a70a2439d7c9e2d4972ce203d22ad3875cbee1d5d868af7 a00f27535e8deeaf494ed6d125e6cec2850fd9d9d662a4eb8dcc256f100e52a2 +1208500 ec687d27e52ac5b858d7d7ff52ef3c8cda84db7ff6d936af0f27e2c360741d35 ed4e3072b126d4cb71535379d0333f87f69eb36160c34ca09c2f27da619754cb 9a7af586566a2982537e5eff850050df32ba4b92b51c04f7d6fcc30732f54458 +1209000 29ca922420f0ee34a0d2b8db0900be89d53bc701d01bedb1f521991a9eb6a7d2 ef7d6974ea39ffd59e5172f03177cb683b201de4b2bb5f2033d8f54de7fc6909 0f0b865288a21d201d6c5838b5728938aeff38f6fe38ca38c2fb58c9ba9cea64 +1209500 0f58a34dbda8c95dd444206edddaab95556a446f0ce720dc050c8d018c125f39 054cff31c9ad08caffcf6221db3025662f7eddbd0257fec6fdea36f2784f2e76 f44e1b6a5a56c05b9d0a07c10257f34c06f2a4d49218c8e18e45e757bee05ddd +1210000 b94e4bc2999403fbb8de9cc45a6d3feb4dcdf8183843b54aedb532975d459d2e 00c2ec796652dfdbd07eea2cf084df3c9f09a34b3b2e2041cbd16a1bac24961d b1819df4175d18348f009ca621238d673c1258a1a334ccc21f0bd3e6245d5a36 +1210500 65d1e575763ab257869cf3836d24033f4dc201af30420d753da99cf756afc957 04297b9ad1a6a46395ff05e3646a0774ae926119210b7f9518a34ee451ff7876 b7a78eb78dc0de0269e85aad99f6159e0c62cf1896bbbc4d57644ee6841e66e9 +1211000 63f7824e59c39582208dba5f1103259d967f57347aa09e9c11a5faeaeddfd1bc 16f8e67d3344c9dff651e1a2798f7dd1b0e99e7cbc11f5e44ec98f6880cf443c b57a7be6b38c613f08919ebe694196097ee2bea41e01401fbcb98a3904362926 +1211500 d899dbddf39d3b7ffb4f7fe28de5acb406d425ca8e045d3f781add82186f937a d3e071c935166ebd9ce6c5eb2c0ef7830b6774887cca37a5f1d36a2b256a05a2 c6a78f9b427a055d4a667cb08a74bdb1ab24077de9e7992c570e96c0af7daa4f +1212000 f90c9ee5bc12c59ec108657fe98e9324f9c85aa1f9cab7204edf6730d70422c3 0150577230ba870ebb96c21f7e3ec7ae1dff39cb722ed7b48cbc60d330be744a 088ff4328e9147a7563fa07206b6171840b291d53785164da29e62623b1feeba +1212500 f8cc7adcb309ff208a7a740eceb0517c8d3b3a88c06ce005b37f17ffeb4905f2 ca2fd2e44948441520e2e9bd79528e0bfb8077ce313cea0190b229e2a8977d5b de0c8389fbf4d54b78748152d6a1b909a032a7292dcb52068fc18014d973a5ce +1213000 754d66c3a3828b61aa7e5a15c8fe95981fcc17ade1030484f91c11c8610afa8d 0a736f7cbc44dea49246af39c1db3b9f98a482f3263278ccd9d7e2c42427badd 7dfaff65e0b6b9ee50eaa81d8a30304d9f258f0da1966d390cf169bdd9cee31b +1213500 a44133bc1878ee0a11110db3b1e216a32e3c1dd7871242184906e37707c4c3a4 9a49bc0837e480d6feb51cdb641412c1fbf83ebd07aedf5f5b52bcadb0262efb 41d16e41364828cf2cb397e50f0536c53f9a165f51dbac05ff80eaf2ed63f6a7 +1214000 c7f3ee494d1792a08f56d2fd18e1f95f56479b60c1bcb2474e15aecfce885b73 734768c3ef0c14ca94b16b233c3a940182424b44b080c25aad3d40ac4e11706b d5c86bdf7324cfc88d3f8ccb52c4ded90c0d1066ab853de04fcd009e4b273430 +1214500 0dca8f5f370d6fab809f569e4e07461526ecd6ea5b465aca65e4b136cc4fcd4d 0b346291e2f62634535850941b4c7a870f5566fffadca6afa4e0f6eb70d60c46 a6db02502443d06baa680202a74708ec013288dc5b416058dfe6f8a061905ea0 +1215000 aa91d090e9109a62f7bf56969cffff445b7458ba7a5d37d333ac0f6ecf33bee7 fce092c00141d26053f0cc948b1c9e6909798b2e48a5d6c2a2234455e1260ab7 1f39cd37ed092c6703ec9a4d52d68f4193f0c09277b8a60b4bbf7e0ce0a502de +1215500 4a3cba5107b521f2fec4838c56ba42075bea7b56111407c3e1a5d29f268e39c5 d148409fb60d5fda12f14be6d10aee9d40193b64d09c2990c3cb5a457ef18cf9 bf15c48150f64d7002923b94b5cacf0ba7ebd9ec8d5e47aad52fab003e70506a +1216000 2a224b00ee3a56ee499bba718b11b688f789d44a11c42b566464204f51f2ec33 0769fbba3f55367e95375dfefa08dcab6f53c9c5e5609a0422f73d75f04a4f53 40d9e49dd70d4f1aebce07bf99ed706b3adaa207d2eab29c843e7bca0e69f9e7 +1216500 d9943902065c4b0823cd64a62d37b532c6d62d0ed1d8828927ac39089207b9ae c83f557b4e2cc04d4375f91003054dbca728cbd9626fa9e9420ecc77aeb70e6f 32fe72cc551ce71177df0895e2f384649fa4f137e4d6f7b6c93eec53d2eee53d +1217000 382d47307ca74e43ab3cf0152c65cdf01ea2348b1ea1b25113e6b5fdda458a34 835103782e04e0e8bd18c741ecd1a8238eee814973ab7ad40eebe58e2fffc100 5f1d7ac4471b7dbf2927f5a3dc7212cc025e8deb674f87559ae7bb80c81ba2c4 +1217500 2e165b64031b2e689a8e6cf9b24f4a928d7f9de6777ce918aaaf99991562c603 84f608ddd07f0e6c7307570ad6ec5bb0b7361c779d1c18e8cb0c9e08a29cee0c 0ea9e4d3b33c19fbda78146bc486343b4717edf67573392742a697bbf34778ed +1218000 c62fb3c42177536ab92a97c2d8fc21f72ca1499aca8bc9b604d8265cd8630771 375f71108b5160a7a7990288ef3394cdcfcfcf77955f21f28368d101ba93eb66 b51ab010fef2ea591827977f896d80a4dd63cf94bded139805169c581849068f +1218500 a162e27d52028d27ace91149cd6526e41f6ac23e67378f81f51836f7326fed9d 28c6848464f675c93a357833cbd7af6fe0d1881723c9b1dfa731a7ee2c08536f 898dea8a454aa96a0931532a0eb7e181de7f83359f7433c520e4693b5fdf4948 +1219000 fe267680bd06b3bf83536a78e7f41b7a389478c9b1e221deae145bf8a08d5b47 4466a5245e8e0c00d39be14b484771ebe4ac618cfaaae42c566a084ed3870da5 99adb8f4eb21b3a3b58279d7c08f50b18b854f9e52adb5c026bb50cd2c004818 +1219500 ad07e8ef4af3453d3d595897cd7d9283361f64307bc92456b2a1f9060332eb66 96b8bad5bd9a508c33ada23b6457636e9e957d0c1a59c718d421c0e782608c4b 3a38aa150c4c883cd5fec2ccc3020dc934f5eade8c9c10ad69a167343019cb43 +1220000 811168c51f99a36edb27c7d8a8d5a27a84afc5e7e0b4c62f7d62c2de71992f81 b52360cf74cf6f0afd8c3601dd3d460f1b86f69ad46fb1427c8dd7bf349535f5 05948b8b422a7a908e9e0bccc308395e705291d56d9692768932b249d33175e8 +1220500 ec2e7364b7d3725307b2626ccab20175924a8a2a72cdeda71f90514033fe8cb1 a3103d1dcdd0593825cda1fc75df41bfdc4f184c135dc0b556dc23b20267d4ce 7d120c5a47519a8a6c44338f75ba47ed9f8878b848812745c6befbfe8a7c32f0 +1221000 fada98b054fa44944ae7f458255ac03af0bbef0f4711e0fea4dcb3071f4af719 ff619e93f10311744a6bad4ce2add55afb6c258beb2570d825489a6901c493b4 b6ff3aa01bcdbc9e4206838490e78dc4ac9ed06171dcdbbaf7807211fb3047bf +1221500 867936e9456a796ae62e181d029e150d63ed8d7fa0b91dc96f0610101e96bb07 f283a4dd8854af5b6419c79ce98c6326283ef8b8f3295d8912c5465cb99c9b7a af190d37c2900db674adacdc741c59fbd8431bd71cc6cb70cf420f616964b083 +1222000 92d956413724e3e5fc5e7386ec1f9717fb6f080203d7cd464cbc1cc46e40b1a1 d2212c160766ac9464f0f3b7433614303114af00a95d746177ce70af39b97fdf ac8bf70a3e63d097dcc407247331b10d4fe125d9b53358079b3e0ee7900af8b8 +1222500 988b9749da4643c17df869d68c4c6afc39c6427bc79eea82a2c2d23262319003 b2e29bbb854e916e259c68907d86603bea9f63c174cca8483cd6a806e0687cc1 016cda454ed0574524c3ec1cc40c5aac64f90ab0cb7599669ad04793021a48af +1223000 ba1cfd983bae07bb33f094aa313ad4e27773ab1316291ed338ec784638a17fa0 6a6e92ab4ba2174d2fa9ea9d518f1dba0d7b4b02b6f208cdcb191cc8d9743ff6 56a23b35c73f1a6a2f63530304cf2b4a7b314d8c44911337c7529a3bb72c2999 +1223500 c9d4b54460eebaebe3dac55af5a41c92b93f2cbce7dc15a6a83d0ce32624da27 a7dc5399fff2ecf6f31036f2859a8fd6dd455cba0f36cb066198d196366a07e0 38742e5537cbdede5af65f69ba51e038fd50a4861daf98eefdf2547f92d30091 +1224000 9eced849f18584d868e2b2203d7c8e670ec4b3de64040d4a83107bd4f83478ac b7833aa659aced32c8af2cede17974e2034248b77e1d8234e353f25aa2ac0f58 e61b4c8274aaa6954ffa72836f4b6f2a765bf42dc4480dd60321addfaefda699 +1224500 e8efa9a9da8c7457cefe2c10edbe2ea4b9d41b1db527fedbda3cd04321a5c111 e957aee3ef528beac7121c3104a2a43fa436c729322b813de1d67312680d4083 bb24fb54ae90008799f9aca682ab21eac31ae86d517e2d332c7a9ea814a61730 +1225000 4e12cd3ab7e05f9e285315c668939da5701bf4fb82d36d6d3e594de1cd0900c5 eb57dc646237d51bd9a1a2f8cb8c7f9d886f4f2cecf5d357a84ed677a2f261d2 1d313c9945672934be9457c33f639259391e674f70a03af4dcaa90adaedeff33 +1225500 c688db4d88ed9d2df5c2f27c6835603c51901d117b6d1b84e758ed295fa48944 9a8422e25e95aff28f97a49c8c92b710d2444263b8d2da7a0808d175c0ee4347 c11b772a420b555ac5e6b924ad5c423f163ebffb82dae741a238d989b634e52f +1226000 c4e1d256b6489e0bfba212ee15761336138eecf8979b7723efa734ee1ff26b18 1e448b947cbdefc052935c120b1f5c6ea572b9b6e57db325ef6854f6d3163c43 a7577442c1b52b71f18ec372828203737f4135d9860b9b1cd4c37817e8a241d0 +1226500 97c6e37ce3aaede301449d315b6121ad209d7c05bf1e1009e28ca4c9d9103c60 9210e0c390ee24dbac3246141271a88596a901e27e827c8ea57e3a5c7a75e4a2 6eaf28adcb51c7a25e69644a00d3aa5cfadb46b5561f47befd9dd8f469dd0373 +1227000 329572ad3b9215cd69211538c61554eccfdad3bb5d2580d7319bd4e610a178b5 f2ac70bcea88b98c36bcdd15d050ea30f4ab11690e125ea3b9edb317a05312ba c55ee0f1638c5e7164ce7f58f5a39b36fbd7800576af58591468dd72848e4e9f +1227500 a116bdc25d0d36cec3fd5feeeb19ecd338d3c9db329114bf9a97e30f08bb96e6 2d1c9941a6d1fcb265b5ce131b77f4f24b3c41005531012ed24a89a271ad25fa 2589707edbce375faa11ccad06df92ddde9e531d1ef0a3633d78151b3f9d0f0a +1228000 84f4f33c057c0e992a875e7a96f06bf7c348e70730dae4d4c92ade46c2a7e116 049ed2ddedf886363d6fd427bf42206e294ccc455ff2f83fec7c10f74cb38a5c 4970249edfa5de8eb69588783f9ec8d9b20467efb4f4924d17894fb2ff3dfdbe +1228500 ee665899f35317328076349a0e1fac9f7306309db28405491d25d713ef0ec391 aa0414c7728282a0442c3e947fd2ecda18b07d55d6e58dad3b9990694c03ea59 442edf2d4b8ad64233ab02566eb4aeb90c3646c57b3e2110c416d2ebfe7237fe +1229000 c365b766a114c397342a1d8b870e5b95bb68b5ae78c7d8b0cd1c21c87b51e7be 5fb8fb2fcbe30e1e3740688b4acf3ee827844df7e8c18ecf438975088e59d5e7 5fbaf49a80bbc4c6b6b3fd09044864926b2aad7f3b13b54030957b423eb20d76 +1229500 e2eee37aa2938c02f852b9ea2bf88737f87203154bfa499db7577fd97c1cbd81 ed8ec1aa4e346b93d4f5a9016a5582df83cda6d59f71c910a778dbd8087039f6 a4dca6bda7027ce0c275b175ad2a725c65ddd4cc03f997deecac29824b1bbe19 +1230000 6f65311001ece9092002e408d232b04a3958a801ce14745bbb33bc50b3d3e434 e92c307817b8555133defa5001453f674d64975f118469dac59022b47b1b2875 ef025f195d124354b0987f05b7d46a547e19cbff077dd162bd1d4cc4ebc51f2a +1230500 756a4e8628e68dd8833f1160a9438b5082b81dc62d57e2fea4c7f2ad73d4d361 3f201a9f0e46b64d4ee464133e142ec08efda7d70035e2bc87a9115578f01ca9 00419dbbd698d08b0f89b4669237468bc366a853ef0bfeb9074c29d1ed4b4f73 +1231000 c8e6f0e59ddf904a7b2d085ca6cd5b1f243b75ac09ad637ba72a91125d6211d8 2c3762cb6d023147d669b4ca877aff07b7194d6da09215863f4fe199f67198c6 9bf01e88b22df0e00bff6bda68ab7087e573c3155dd093d7461f14288455ff04 +1231500 61ef9b1c57fb9764e6bf4805a520b4fb74566e1fbb4eee699f517f62e22e64b1 acc8c1c0739411ca10405ccb0c49b403967cade11fdbf8811a8ebab9e46a6e27 2d9742b07b1a54cd422958e68b59b0cd5db43a876a5063427f138386d4a7fe2d +1232000 391308af085a5484df59509f31a00f63833180fc69dace72a38461c8e51c0a86 f98e065e8818fd81b6b3f0a8da64ab17013dc010096e6c34ec3eb5f9fe8a3724 fa28fd3a2fc93ccc283fe42d924fc7492ec45cffec7d3eef82ea249e8a1aa855 +1232500 3f8da017a3767553a874c1f2f5596700b6eebde54b1f27a119de031e94a5d70a d00e3a3b2a29c5f0f0ba83c5066cd3b0f4794a98768be0c7326fb82b17679185 994cace05d26e4ad89d275f8f45e9aa058fdccbe54d0fbbad58d87df2059089f +1233000 248b1955a1c0cf58366a949e73cd07abc509709e30a427a55e2edfff5d8c8677 88110fccf2c71332b30536569a6fc46fe183d3a2847ee627213ef66bbf0bcdd8 ccc0873dcdf1b09702ed7b3e6ffb8d00e9afa59d77e4f7f86ae0566879565b18 +1233500 381e2949e83693efbb0e432f83034aa5ef6cd569428a3f5dc0ea46721d58a571 3e7cd9eb6c797ee4f40837dc8a437b417036a2ee6f6d8d0eb8cdb9d0143bbe51 c2a8f947967184ebb6a31b47961bd4f37252e5ae81380562dcc6165a85fc9a49 +1234000 cb6e218e6b06db72e9ebd1a779c6fbda5c8967d527731d8e5ab48676aa9a1d97 27d02fde617293d42a4de35098f148deefd85340bb2b038a2ba17602eb26fa41 db87890c8ffa7bbf7c093729078598d598ad11b73a393bae34836641a393ba5b +1234500 5b0df15f60febb52c49aba4936bf83f9bdd2654d4ff883ae326c081fa7b3fa8c 802c5a78bd41f37f08ed7c395023a4661d743d59f98c6b7afeb231716fad6829 3b035a4d24d0cbdf71c38dfd81423d32d8cbfcea642da34d64aed0855044824d +1235000 48f8a254d98836c4d8559df0ff42f13c8b62ea04052381bf411cf47b99900884 d59adf1c51d0d1f8b261320e990593686f75c1f8f2f405758179b058946873a2 d83461b796e705769281bb9e53d7b7c951f9073a399cde0c567aa9916456a534 +1235500 eb8ac12b006d0cfc692173d0a970260435c7c7ac1e67bc54807345a13f7557fe 1e716e5508018cddde941f3079be2608509a9e319684ef8144245f613ff46713 6db77cbcf3e70b684552735f0ba034057ca13ad7cfcb8d698eb9e4f5a188060c +1236000 524ce04d135aa08543baa6052549f6736395eda2ab3b5d8fe5fab430c014562a f1ad0c14cb9cdea0f4cd5847d1c256cae712d24621a29afec0f54677c1510706 d2371119849dec5a03d380b18a65b43981676db7a59ab13f989991317cc0ec12 +1236500 88275a75fc986491ce9dd6d2cb83243060e61d6c4e81ebe7e7c7643fb8bab0f1 2a73a779cade5defd59863657468f9985adabf08572a23192060672b14e2de75 4e2f3e795940126c02e8a0479561df998e82ae5ac4839f07f28d130e9a32adbf +1237000 4b99f3d475c781dc2caac67ffab7c53d84dbeff79678922694955a9854590018 554600aac19287681afe0e9765da07a02f1a1aa493dfd43addd9f31edb78e875 e60302e3377c7fc2b9109912f015bbe23b4b2ac8ad628c7d6e3837ac71f7b1a5 +1237500 73c09a49ed9f47f700d4554cd0a94c1b01b802a3cb3c61946c74d40a443540ff 1775952f2d8dc63bcc08ea478fd4714838a31f7f683a8b83d5d26435b8b3b6c3 59f24ceb689173661dfaa9bf80b396831d5e7dcde15bf806ed7160f75a988274 +1238000 29489c531b3419cea99dddefb9b19111f5baa184f287ebddb3e760a2663014d1 dce39dcb5a1a2d072fc999d3f662bcfb16685cb8922386cccba187b68b6d5947 32dcdcfc9c0d815a79435b769a35954dc71df347a2ac1a810929f765c39218bc +1238500 c0555685b80e5d5d0f53434a8ae44eadc953dced274ceadc80de36c44078283f 16dbb1b2bbd5d13aee22743ed27c7dc4dbf1dbb221cb45325d188889d6101dd8 c44cb9916bdb7e6c7dfa417da3be72bd5987cf345024ebfa68402bf3f3994189 +1239000 a3f94a2821165fb910806ff75928c5255a4358b5062288571e00e6646abc5203 175a8f872f777325f2444b94ccd55602b3bd8204733f86af40713fb0a0474106 c637a21fdda667d21d172bdeedd54fe7f09095a015229dc6854eb37d917da596 +1239500 f0bd39a43ab257a944d14fe21c055e28b4bf85e32795aef2df130ebb1469fd29 d550e50d0236841193db7689afd67e5c127c115dd776caeef23f44f52c24eb65 37a0103ad87b07e99794b77907c10c398e404dcf02858b5f33e990c54815f489 +1240000 b67c1f025f7220f11d05c5b74ed716a09052a39ae5c9c0d81f959bde2412df21 7dedc1388bc5241148978f52fea051ebbd5e53bb1c6b4c1b6b08859d0aad4b2e 4d83919d062a0ff402a61cfcb2ae65f5e821a51a10da6f1b8663f15827757347 +1240500 80ca7f4b0190576ff892ba63370d8c90c8f1574b68eef75d1bb9548f4d697376 3f8b9364517f8b827560a267f8745d0a806d99e681c62a29eb40c7d111fc983b 8f484667e640bb16315af1b338afcfa136eb57e1a31ccc9fb860adcf1556563b +1241000 5cd717cb334be09de942f4047874ec8c688ee393f5dc13f68c253c628810672a 8d05f82f6117d614c90a34bbbd6da0a5245ebbf2b2834fef6388d6ab651e3ca7 ee5f33765c74cc445bfd39a54232159f4bf473881187f1ae94589fa3159d4a4f +1241500 4bd53ea06156b6ecc8a0070ea632740d300d6151528de74b398c4f409fdd1ba8 9ef6c928f41fb210bc7ebcb5be662d72d7d948cade0b351028cdd78162501d14 eb751a66f7169b70a75897c6d081aac3c73ce976088d52fa3db8a30d2b4f5ad4 +1242000 f6295866a6038a9c371c5b6e52a07048c81ad8ab72f640c958fef811c2ffbdfd 756f74642fe42be36c16ab56489bbafe9ccf2371e42cc4a5f4cb630458f1b643 46a699b7f76280ce6eb0e7a806d0137497c244d0434f466fc7e55bd0a82758cd +1242500 3e8a274212a5fedb87e2418a0371405cb81c862e031ef973006b451a22c7b675 1790d1bad665ba26d5f736c53dd47da21215c5f0c683c9812275bbf133c5408d ad3d79038c8f93772dc3b5572bf0451a3283f5c2699de24cbf94e8775bca0b1a +1243000 3756bde16fbf4ff5515c43a0000e3ca2de2e6b07e577f3c4dc1da8e12ac7fbcb a95d67a204c1ebc44542f1d37e33f9793d52a1a65139767be6286cc878e0c115 e24d3bb6b9974c05936502b8cbf1a3767a034ab46cccf08277f1e43dccf568a0 +1243500 940cae25d2eec6a8861d9251472286c8a9f39f2b71b2a29fd3c9ea6f1abe492e a5f95df00408129542423b39e2a84e712404bf0ee4385c552a86cabf31701ffb b4a8fe46c8f3478ef6f39f28cd19e87279baa2e4dbba4ac9ed4231604cc8d97e +1244000 d361b001439ebc3a1119a25e8c6c07de4e8bbb5319a5934ff8a204a5d20e7ab4 423470d98066acba4a0a1bc5d6b0e593d86013581c23064aa812a14412522925 cd7d391b8691837f0fd613a16c4be66204df9d9c6f1d2c5e3665062dfe410308 +1244500 352c6570c4e0dc0d45567f5328f464e77d08a08ca264bb5c2d390ac164bb1ea5 cd1b268988aaa946914020431f90b3b0fdb04cb68f51ad4ae51f2d584d9a5e80 2ed18bee66f75a782a11f536e317b9f215e4910c1a0a3d006d8939f323718261 +1245000 8e6877ac8dd351b54f372db8edccff5ed28a56dd0196100f6b460c8147d26852 d8675c2f64d6b783610322ba2f7f4adb1fe7d73735d564207f6b3d05f4027cf2 76a3be64b31a57a9c12fe53f8ff6fb96a08f0538ef7e036eb194b34d3e2034bc +1245500 311eb3483c9afe64f8e08b22fdb61f64f2a03b00af63b149d2d1204dcb1c4606 137d75b32adebcc920a1788ca0dfc6d973c63f534d79fe82837ee8e886d8ba4e d0bba748e4021300262433f2f88879e03056b96edd06fdcb4c2d38194d1c8e65 +1246000 5509b7ea30bfe33c501747d1830cb8f446067a775ecfc8b96d22573d345af12c 3699f1e168c6144f9006bfe7f5f6873bf11cdc13abd24bbee12c0b22220f1091 2e220129558c543cdb78d3d05c5c3de4e52220dbc185985f738cf792c2eb2f41 +1246500 243eeac7144a8a164bc11ff86125c615e2b878a70f9083c93935ed4a54c8d3a8 332b707161165a53d71255777700bdb9353cfa4ddba816e7e0bc621d27c83fae d266d2b937563694108338f8c9273c14d5842310e18fbe68a4ea05c6d5ad205e +1247000 043654128e4e21603e9df5a5215bc06f01366271ed51ddb230950d5417b53a8a 0ecbfd16d1139ffb326979ebd7507ef4736dbe9986d390247adfb77e3e7db8a7 7e73896fbe8dd0ce540401bb6e2053f8908dd690c6616e32dc28843be1a0a235 +1247500 ffecd3df8dababd8bd3db48e30f034341293cd141e7f5eb2cfd3383e83717261 435268905ce4ad84beddad2fb00aea84a0019cb391ab43c98801ece328bfa3d7 27ac8fbe9c00697d9f8a73c23705f6f6dedcbd5dc6835bf9625370a0d621a118 +1248000 a83cf72b2c589f475d70120ba553f1fda2fb58c80790498df9a5e7d3e65ba98a aeb9dfaf149790d172d3250604ae939ea0ad7d87e546b6bd8f19a4135a533738 4667a1d7f3b0124e63bce7a56f4a4a3106be81ee934153d30f4c600789dcc69e +1248500 84cc34f5d56d431bc44c537f09573cbfc332cecde35e2210b83288d44503ec7c a338c370b445a3cfb9c37d064663765caa41c015bb8695338df876426dce6a70 6c0a435b32c133032291c0a6fa92934a6301fd057e394a8ea65588b6462534f6 +1249000 d296d197045790f4cc6cd4e701589c8bf96e087240e5cd3aa47bb75d47face58 12981ee84a2aac6119210a2a460804cc8cf047e63ade62c6a4c0d72db36cec9d f58a8a0337779f01926284a056b3c9721a2e5463cec8fd5e87f67446b8440d96 +1249500 be1e29d4530cb278d1266acccdffd6adfdb6ebb990582ac12ef3b9306fc7be59 2fe0458f1f910fe8dec95796083bac90af2b52a317e812a2280fbf973c6d6890 ec51dd3af87089a3ac9ca8026d4a860aaf4a7f366bd7b00b74d57fc796dc1527 +1250000 ff909ef870867e5408ec24ec40a290802f79bea220c8f4a92db22965fcd4f626 03e5b1fcdc2862ced4fbac3aaa81d1e0085c14d6f6d06c6ae592f74afaa16f34 c4f52d30fd52f73e6c5a8e27d3727b17887edddc5400dfb9ca1cce4703e3809a +1250500 8f0c2debaa498a5f78b8b247d1867ef6ade586bdfa823596d09f72abb489a91c ebbc2c14544a97d0bd12993dde913e52f2ef78450c1ce0fa2ca17274b6850836 de78b1c377adec4d78d5e4875569e052cc1d4eb959149a28783d3a14e05a365e +1251000 e484a8dae7eb5135538bf13009824a60f2e01446f7eccd39d7b6ba4ab7c02f6e 832e2c77cc85a51df16361177033632ca54768944daf778522cfec04a1968805 9d3db1d547f74210714713bf27f88dded8e2ac50a618afe41220ac606fecbf7a +1251500 d39df71c033cc3435949073db5f0dfdcc0665a7cb4f948704c30a36198d4354f diff --git a/iguana/confs/BTCD_peers.txt b/iguana/confs/BTCD_peers.txt old mode 100755 new mode 100644 index 4049e17f0..34569c8ee --- a/iguana/confs/BTCD_peers.txt +++ b/iguana/confs/BTCD_peers.txt @@ -1,5 +1,3 @@ -5.9.102.210 -89.248.160.236 89.248.160.237 89.248.160.238 89.248.160.239 @@ -8,53 +6,84 @@ 89.248.160.242 89.248.160.243 89.248.160.244 -89.248.160.245 -78.47.58.62 -67.212.70.88 -94.102.50.69 -50.179.58.158 -194.135.94.30 -109.236.85.42 -104.236.127.154 -68.45.147.145 -37.59.14.7 -78.47.115.250 -188.40.138.8 -62.75.143.120 -82.241.71.230 -217.23.6.2 -73.28.172.128 -45.55.149.34 -192.0.242.54 -81.181.155.53 -91.66.185.97 85.25.217.233 -144.76.239.66 -95.80.9.112 -80.162.193.118 -173.65.129.85 -2.26.173.58 -78.14.250.69 -188.226.253.77 -58.107.67.39 -124.191.37.212 -176.226.137.238 -69.145.25.85 -24.168.14.28 -73.201.180.47 -76.188.171.53 -63.247.147.166 +65.15.37.140 +62.75.145.171 +176.9.13.13 +88.198.15.19 +51.255.38.28 121.108.241.247 -36.74.36.125 -106.186.119.171 +82.229.201.131 +162.13.4.69 +78.226.160.96 +115.28.42.60 +178.62.185.131 +167.114.249.196 +81.181.155.53 +76.169.236.235 +67.165.77.192 +75.130.163.51 +72.55.148.203 +96.127.136.18 +88.198.53.194 +63.247.147.166 +88.206.186.58 +217.8.62.188 +46.231.137.186 +217.215.190.134 +2.86.63.69 +59.147.43.232 +104.42.224.48 +24.168.17.50 +173.65.129.85 +84.119.62.223 +59.147.43.232 +2.239.61.146 +176.28.45.179 +73.211.90.130 +185.48.78.78 +77.21.104.176 +46.253.169.134 +163.172.156.107 +74.120.222.234 +192.99.233.217 +162.255.117.105 188.166.91.37 -223.134.228.208 +149.56.122.72 +71.1.13.122 +88.113.76.138 +81.205.30.207 +203.189.127.54 +68.190.213.46 +98.202.147.55 +89.212.19.49 +162.210.92.46 +115.70.19.28 +68.43.220.127 +79.227.171.148 +68.46.103.181 +98.207.117.83 +79.200.255.204 +82.8.59.60 +71.241.204.215 +108.247.198.39 +156.57.141.221 +92.26.168.113 +71.53.157.49 +68.45.147.145 +79.54.185.53 +110.202.11.148 +91.82.171.9 +74.14.104.167 +95.116.195.148 +90.113.82.59 +98.118.105.12 +82.241.71.230 +98.161.16.55 +89.248.160.237 +93.211.231.89 +2.26.181.156 89.248.160.244 -178.33.209.212 -71.53.156.38 -88.198.10.165 -24.117.221.0 -74.14.104.57 -158.69.27.82 -110.174.129.213 -75.130.163.51 +89.248.160.243 +89.248.160.242 +89.248.160.241 diff --git a/iguana/confs/BTC_hdrs.txt b/iguana/confs/BTC_hdrs.txt deleted file mode 100755 index 4b400eb88..000000000 --- a/iguana/confs/BTC_hdrs.txt +++ /dev/null @@ -1,207 +0,0 @@ -402004 -0 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f dece1ed3311faba0f3bc7792930799ecc20985ea95997c5e8edf1a876f17aed1 00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048 -2000 00000000dfd5d65c9d8561b4b8f60a63018fe3933ecb131fb37f905f87da951a 41e27d57bc7a3a7694e3cb13a92984b37dc4e98bf3f935b58c68227d0ee06702 0000000067217a46c49054bad67cda2da943607d326e89896786de10b07cb7c0 -4000 00000000922e2aa9e84a474350a3555f49f06061fd49df50a9352f156692a842 83c43672b8617e4c4a4bbfcfa99f8877fd9db36ed19e57ff7c686f182b60bfce 00000000a86f68e8de06c6b46623fdd16b7a11ad9651fa48ecbe8c731658dc06 -6000 00000000dbbb79792303bdd1c6c4d7ab9c21bba0667213c2eca955e11230c5a5 66f3cdb93a6b871f468a44456e12a11ba102cf76be74ccbc61d615ce9c076acb 0000000055fcaf04cb9a82bb86b46a21b15fcaa75ac8c18679b0234f79c4c615 -8000 0000000094fbacdffec05aea9847000522a258c269ae37a74a818afb96fc27d9 4f93ddc7cc1dd0427dbfd9ef7080b70e676553c566b358a807b9abd4006b2196 0000000072e011d1731643b13159a274aa0d4e15024d534e1f62804a018d242c -10000 0000000099c744455f58e6c6e98b671e1bf7f37346bfd4cf5d0274ad8ee660cb 9d4c6e97e3959c23f38ed37798743df5a4d47e34683cab54603f3000f934b511 00000000f01df1dbc52bce6d8d31167a8fef76f1a8eb67897469cf92205e806b -12000 0000000011d1d9f1af3e1d038cebba251f933102dbe181d46a7966191b3299ee 8b8feb0ba990705d4378e1b778e62db2d417c8985ae569b7fb3e6844e8a58852 000000009bf236ddb082304d8ad0954cd3292792c4958b643f2ec3c1ac3f026b -14000 000000002d9050318ec8112057423e30b9570b39998aacd00ca648216525fce3 9ccb85438e9350235b1d30c01ce0b2f3e408ddc5193e73badb3977a3d52cc134 00000000b44efc0402c4841e13c29e2843776abd8ca1a728b4d12a092966e87a -16000 00000000679a1ab3af6da03f13a0bc96d7215e65458b2d2edfa030b5b431e8b3 38f5879424c92f6160f4adf7bb8ca8d0002dd1a7ea82a47cff891ad2eba92468 00000000bfd11dbf1115ca74217c55ab3938e59b2cf91d862c00354b65023043 -18000 00000000f914f0d0692e56bd06565ac4de668251b6a29fe0535d1e0031cfd0de 476ef2170dbdb8ab3a921d8ffafcb87b521002dc33e50863a469b14f721bae1a 00000000d50b1d5fdcad186077855a0e5dcf357b246238eeeac208052a9ff3c5 -20000 00000000770ebe897270ca5f6d539d8afb4ea4f4e757761a34ca82e17207d886 23551ac19182c7d69112344013508171046ccdede1f5c4a5912e151bed6803fe 000000002434a3edf8dee4fe506d306c59d3bf41f73d979f30ed3f7b7c34d06c -22000 000000004625a14242beccb38c63a1f770a76ee5788764e6c0abd4129bbc1b9d 67ac3ab11d5d6bccec6805f1aa725b464c45b75cbbd2d29c7f35ecb599c220ba 0000000082b75cb83e6b30ffd99d598b2b3869ae31c38d56e6856cea95ddccbe -24000 00000000f04fccc81f37002707e9501a3f7bdcf25f65531f386a2da8af20122e b0ea761af31989e9f6766d8f3ed5e64af98661011b31b6e52cd223a715ba7351 00000000057136237ef09824c432d8151cc23bcb009cecf49ace17003fe574be -26000 000000006d6c151db6d4d67356d590a897a11cd7d8111ee989de6f2f548410bf 56aaf4660baebf6c881604875dfe216fb720330f27a8ec011aa97aa03c0d0783 000000006aee625129fc9ad7ba7930b89c80ebf22ce4448d5ebdd8609fdf0a3d -28000 00000000172c5ed49d7dfc29bf9a18a53fa2d050fa37aa210d6d4080fd0c7e67 999d77cd45d68a64d152b00d003953142d2685d3a19286844c05ae72b41df7c8 000000007fbe48fbcac0d33fb16cf7e254508e14cf51b1788d400b854660aa89 -30000 00000000de1250dc2df5cf4d877e055f338d6ed1ab504d5b71c097cdccd00e13 409f89a04968a0af18c834c55fc15685c24b26e4f07f1dcc129de4db3e77451e 0000000050a8248e6eda4db7b5919491746c06e2ca458b22c35d8d72b3f3e5b6 -32000 00000000049172ba3ec1b673cf13e3d0049c1c07bb103ed3fa300e3833480055 9c91128d2961310ee1eb83ab25e7c3468cfceb08a8689fd9ef27bacfbb73eeb3 00000000a34346ed69d4a8e1d9221c63943aed2338857e72a35ed3bc4fe249b6 -34000 00000000495968d19210d3be15bd24fdc19805a0ef15026b0bb4482b04a9da3c eaf2fe87514eaada77c27a8796dee58e55918ab4d3d97511eea08fc323064caf 0000000025dfa76b856cf6313669d4c6399099abf65402c2d849400427c60b04 -36000 0000000080c3deea35dc3df90a5fbe5f27db52f5e01018ae7d62f8b454c71335 d3092ecd06aeb81f6ef6e323b7ef660122dd72d9c33c6d7208c2acc30f417636 00000000351f0ae03b547ed0f9eb5e92f6cf6870aedf92e31487465e52d56af4 -38000 000000002dfebce284d1e08b6cf04452530891579b7377669865889498de8f3f 18a63c2239c8d7903b8ea3c153ad8ab8b723e705018a2e13ee5ca443ef11cd1e 0000000041b52b3217479dcac62e5cab86fc9f45511fdeeb0106bbd47e5b0851 -40000 00000000504d5fa0ad2cb90af16052a4eb2aea70fa1cba653b90a4583c5193e4 546d597a9a0648ef89a77811c4036ee380cdca1febb0e95da45003693e6b3d5e 000000004f5399dec71dd54b434bbb35a1c30488a37eadd9be7ee61399b4ac90 -42000 000000000f80c09687893406279f62da437a6a0b95b8dc096b30c10ce088fc64 3890d815c8a112f061307bc03683391523587a5edcf6b60c9656358e3c4aba97 000000001865924e539fd6744d6814fe81543d93000e7e9e70c4ed8c4c4d713f -44000 000000000122898b31073a770a97cf599c00672fc8d6ae15652235862f8b76d8 0a1e6031ac37b5b67989d210cfb64eee7268c4cc3d94c253e9618e8b3862b6bf 000000001611e0eb1961d279254766d3581143cb9144464df1d709805fb555bf -46000 000000001dd39771dbe4f9fc6da07327f13f894dd2c1a46cdfcedf930fbbc52b 73fde83c7450255681d866ba1d8ea043c7e5a6daf605093c2dde3430a926242f 000000000a882eb77d5d9a0abd7f189f64f9a18c06952d8e32f03df3c50dbfad -48000 000000000f3d40ea2bfa8d779010e52cff4720c072ec4b12ed576cf5cf93c947 9f34e4674f86609d74961eb54c1cc2f98f5590a6450863ea3e21e346719afd86 000000002085503169f527995fc46d02a5e33666493c46ed4516dcc0b96fd53f -50000 000000001aeae195809d120b5d66a39c83eb48792e068f8ea1fea19d84a4278a 6916dff98241e918e453f0eb52856de9aa9a960414b2993c8e97d75ff44cfc3e 000000001c920d495e1eeef2452b6d1c6c229a919b28196c103ecffebabee141 -52000 00000000082bc4398c4aa5bd8d9fc452d60d533ef68baabf594c9e7d6649049f ab884b30d7ed5872d1d90a2e25a8b095bb39434ae0f80a32adfc97eed69aaaf7 000000001ab16006f0e6372bd266b8dc97805aef21d0362048377cf03f80909e -54000 00000000144197f54afa21ae7db2bc93eee604432101fc0ebe7966a52bb27e61 17646473198bbeea3d60633c6d1c3380e5d119e1e9a2eb504abb615957a6836b 00000000100403d4ad879391f3fe2d80f2936eb2dd6389b81ade62ca6e3dd0bd -56000 000000000dfa452ea45e0426dd8914c35e24dfd4399037c5e6deb9f18f58d6d3 37e7e05cecd7df0602970dd7f985ed73ae216bd160994b4d07577881f299a4b6 00000000002157f86eb59fb1037319fa879c0afe087ed79e019cc29560a224b9 -58000 0000000013e3791d288d9db814c52fbdf240b2206eb8e19d7dc80013c60c0c00 088e663cf7476201f3faf37e38fd435ac69e7939c4b3dadc3a065ac7d0466147 000000000e52b80e848807d7d0a7085fd561b613e5045a492da9680d380f84b0 -60000 000000000b554c46f8eb7264d7d5e334382c6fc3098dabf734de37962ccd7495 7bf914410170e1fd75df6efc08af8617306a4cdea1d5c950101c700406783815 000000000ea6be82e57bd76b1dfaccd5de0ef63d9a0980310a5148bc4bdb6753 -62000 0000000006dd4bc72daabef992f860e703820de119af3e24a1ea6f6c81521011 bb58902ef76cab599d025523bf078110cbbcd99212f3b35953b637dbfb3b5630 00000000014597753c3e08e3b1d191c14dbaf96e6cf5727be128dfd4705b5afe -64000 0000000003d7055b51d7b9ab693de84c03201fe0396af61dbb30bf31445d3f55 e84093b7fa29447382f1354e788af857b14cd0d4b60f01c7211c8f537ef310c6 00000000005e61abe20a48deb7dc94ea3ff37ea7b5a57b1519fb708ea5967013 -66000 00000000071d7e8a0f4895e60c1073df9311d65a85244be1ee6369c9506281af 01318a72a31c85ca5b8b59fb235307588e85f3cbf892fa36d50f43887948ed48 00000000009cb106f888501f42e729cee5062c533f9a75d28736ba3290bd56dc -68000 0000000000d991791fdfdbccbbc2a73d2f86ccf78e2d0a7ce7675f40b5986b3e 08b4c9998a1a39c87016dd387d313a73a1d3d4917ec3941952780154436fe6bd 0000000001544eddcc2e3c5ef5f75c65c1adb99865f7f96b877ede591a5fd6b4 -70000 00000000002b8cd0faa58444df3ba2a22af2b5838c7e4a5b687444f913a575c2 42621404a60ced6d1bd83116a726657ca1c23450322e3dc8be8f82fef75b326b 00000000001337176fa420cb4a7717332d0994491bbed7fd797e45a02b3a7872 -72000 0000000000eb357d4c6fef6ad9a6fade126985ad36042a99cf215a4454545977 c4df76d0f20fd07e30b763b28e60ef25f00dafe41ebbe08dab7fefe730915034 00000000002ec11f3242aeba3465cc0a350722d355d42a6415222c82cb336bfd -74000 0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20 bd262f98ae8ff0c5a9fda8b744e000f67ab181f10e9daa192d05521505db3d25 00000000001ba557f4e72c127725d7ff26be2cb48519c007189d45691e650d0a -76000 0000000000571138ff757a28ddf9b56f28c4a461e170660bb5ae79a556069bb6 18762c4f10e41503af7c19f320ab05ecc0c6935d6976cf8c38123c294561edfd 0000000000393b1b3943fd383fc68e8f509265403345e3f6589d8683d4a1fe49 -78000 00000000001f3fe62641b473673c9ababbe207046a109f0861af95c905a918fa 61b897997332e2256ea43b37a6d838957181099b700818b7fbd6d0b990e79683 000000000000883080e6717f944f2ed3bb6f2fa0e2723a8486c476acc713a079 -80000 000000000043a8c0fd1d6f726790caa2a406010d19efd2780db27bdbbd93baf6 cdb9b85b40849062327de45286562a3014230fbdd615b332de6430072d63763e 00000000000036312a44ab7711afa46f475913fbd9727cf508ed4af3bc933d16 -82000 00000000000c9d1c4acc114afb58d55db5ec44a963263cf6247220b7a3f85c5c 5a91827586e71fa53b9cac1b98967fddfab0e732a1366cdd4131dcb29718fd1b 00000000001e0f5b8021e95bf59ef9279c45f5162a0e41074a145c5825385625 -84000 00000000001385326e30864192ba84ed2f9cbfadf0698655b1c25f93c92f22ad 1e82db93950b485af0c98a91f84f5e2db290852015d5b8deff93772f4b5dbac1 000000000002c05ab3ea86dc6a8167dd6be5450f6bd4efb431535f04c57d5ddb -86000 000000000000ff4e1adb14f07774dad6b34968a5e19d1a2fe1fc9157e7c2b85d 50800ab18837ee3f87c6edf73c625b26ea2133354d9bb9423670fe755174da5a 00000000001c1196186701c95370644621416e575bede6e0a7dc47525035277d -88000 00000000000ae9e98b82b39a912cdc0ebed97c26376780ac996c84d9ec3264a4 9dec8129d35ae538ac5fe73c0c4496f3e42c6673ac010f9edbf2296d3c09e168 000000000010454e08817326f7032770eb75062476e743cf2715b7510b9ec96e -90000 0000000000071694daf735a6b5da101d77a04c7e6008c680e461f0025ba7b7af 76a46a23998e76a022eaa9b7ce6a966153288c621432c25c047d479f8c4958a3 00000000000bbe48ef6c02c01e4cf6b332825e7943a0cc15a5678b0a92858a20 -92000 0000000000001df90b0c523a4d7e4731336b00cf4ba9d8e02d111523df80998c 158705b4874dd942efa31c146f7483fead8f2b8692469789247708a6cf19efe2 000000000007e96d8ebad5e4e36c737ca121a1bf77078cb815f6068e59cf9861 -94000 000000000002a4c42580d51f0ddfd867eaaa790781c484c633a69167d17b48ec 3474b1e5c321938d9091b0798efe7e18ab418658eb4b958841181c97da91ab88 00000000000271be2d9430a96ce054a55d6e7ea93970faf2dc256fc24f42a0fb -96000 000000000002c86b568cdd2d0f4b0430cccf42bcde3361f63a32e23b5d839e99 86e2f364192a51944f2cf0e35af7557e6b0e1fc578ab34204e57552259be5dd5 000000000007b4e174a5dd07f1a785a5d0a52faaffd9d610ff65f64270ea7674 -98000 000000000002272a6dfb695d9db936d813bf0055ae92e920c2791d4c5f7290f1 c0d37a94957444d44255048391dea29cf12ab99b294a14cc89429123ff4021d1 0000000000054030f5e323cd782b8030858356486a369701470f6b1ab5854e28 -100000 000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506 1012e9e419f5b93f096cec8df29b860bf0207e2ce09931d7d5c1a2eb6e030d67 00000000000080b66c911bd5ba14a74260057311eaeb1982802f7010f1a9f090 -102000 00000000000335c47dd6ae953912d172a4d9839355f2083165043bb6f43c2f58 3f00c2b2a78004e5f9e9d20b245f5aab5b5bca68345979b00b16116002769ee9 0000000000035107dce8eb675c6fa9a08c7617c109b3553ad8f208dda24065a6 -104000 000000000000a9887c91956b638bb3c0651321fdb24715354c3fc6633f5a16a3 16cf31820595a465b545bcc1190508ce091086d53b97b5e71bbff9d420bcb319 000000000002a850bc55fe565089f1631752e487d23e1e83f33dfecd12ae3ae5 -106000 00000000000058d919f52d255f394ed0aa3a344432676fd30f1aab4e10c22fad 2d3a18e763ddd1f6eabc79b722b5bd98097f0d2c89abb9f449c481e78749d983 0000000000009c097e197c7b517d36483026639676b01c14fcd681721721d300 -108000 00000000000167cea0b43ff7ce22f330d3e302832187eb31c61b15bb1511e118 5d8584db379287def00b37a2d6fc9bc381eb1b723c6ccb5f7f1ac2b8ba4d6dc1 000000000001110a03b89e33a6c0d71f89319cc1215997406bbc74ed9a6b12f4 -110000 000000000001bbda3f22ef8e476b470a2d3ae16821c23a6d22db77318d0799a9 d6eb660c646bea29b93ee23bc569178dbee16b36b182df7e99ba18dc08489374 0000000000018d067c617c2e262e544bae4807e413122b1f4814077a15ac57c6 -112000 0000000000001d69b3899a49f37799c375a7471829953d5470f468f48ff70432 6ef68447cb6145c71a404ce44e3e7f1e2c45c8ec8f78080dd6f7735ba6b75b2e 000000000001035d056c81d4edbdb2763e40739fd0b2f9cfa06f657299f4f66e -114000 0000000000003195a1e6dc48a540264d37e9ef79b552bd78ea4b93a3b6e7e449 084813c7a679421b7e1eeae9897fd25bad3dc19a1e702818ee0a94a1e5d01c42 00000000000086f38ecc2a8f8dff3bb9e1a2a642e965d4ad84e5c00e8cb7847c -116000 00000000000007ff257fb2edd3fdbd7b00c127a66dae1288fc5e26c402d13bf7 d2334cecec9805da62d511a4d2eb3743fb8f69c9d9141650947ff326a241ced0 0000000000009b84d74ddd7657bceb5f9705d25dd29b5afc5318a3c689472a73 -118000 000000000000774a7f8a7a12dc906ddb9e17e75d684f15e00f8767f9e8f36553 b969a1da29e137da960fcc3cd0fa4960fefda1bfeda87edb4a430e62b08eeacf 0000000000006013206f2e7e1d5694b0b4272b89229ca3f9dc2fa4ee6d19c4c4 -120000 0000000000000e07595fca57b37fea8522e95e0f6891779cfd34d7e537524471 7c49116af07a77ca3fc5f5003b68585b9b689eed77154c1af88be8b467506fee 000000000000218e1979853b278e527b6c447603942b461014964c4368c27482 -122000 0000000000002fe5f29af38282ac1c8f4ea2bf8a0855946150130419491b6c05 0efb5e74991e099c041ee1e22da6bdb06ad21df739595e2a8cf7e21a7163304e 0000000000004ce89031692cee278dc09e09aac24fb2ff514fcac80e4013a911 -124000 00000000000023e9a0523cfac29afe07a07acf81e273cd892c51ff8318846620 962c0106ebfe5e7d2b356fcd2f78a2180a6e136660cdcc85b195aadd311f291b 00000000000021fb283d1722b29e809e80e837b89e25d159362166161dbd0fe0 -126000 000000000000166b7d480aada35af1e6f9a2835d68f9c2fbd272073dc6c9d5fb 15471893042686f902f90d6f2c0f3dd617fcc662abffb433bc608a9c261ea746 0000000000000205c2c2b5aa7dbe0bccd98bffd4af38f9c38c0ba9aa8df704eb -128000 00000000000003b8ddd8692769e1965554a8bb030863e0566a28bc0dc952864e 3026d964b955a13f24bf1f795469f839da4a89bdef0de03372c5305494c9388e 0000000000000ae8912250b0d92a9fc63f021f490b8e359d01ad883298f99c06 -130000 00000000000011906b491883ab0f16f0e690b133ca860b199b775c3cf6581c21 e8b17a15e52032cc813e52b283ea9afa020a166a105f8eb86e8202c8747d7476 000000000000012f983ccf25fca1659dc99a24a455a60a7fe3e848475a0b67f7 -132000 00000000000000a7a0483857f0d951983ff2834a47c38fdcc22563ac0f8f707b 14a632498c78a609adc8cc4f2eacc23ca48cd4e18f7ed2652c5f143810a593c3 000000000000029054ecc6a343125f6f526f774c7189caad04bf299124acc2a3 -134000 00000000000007e3e442ce1423496a064a7c34342ba98be164ac0c9f9b872213 e1dc2c77415d565b094abe960ab93118a6b8c4340f15ef57de7f61d45ee03e52 000000000000067ecbc0c0a94418dfe5fc75bd6e04473aeef9b53973720f1679 -136000 00000000000004da0d6d69fd474fa08fe2ff3111ff1e9e01f72899dcd9d897f0 00030c8c4775f8a50c3da2622f653024d45e2cfffaa6a202a50cae7da8ccc596 00000000000009a3aab1d1d5c4f1fbddf45a3c1d0484fcb5f0773d0755f42353 -138000 0000000000000044c7b6a5511c0b2ae64ec545abccac8053f31cf7bba23bb886 37372808d4a8d98e1a82d630db5ff9a6b2d5e190d28d7ca70f2acbb55af312a9 0000000000000285b609d3491293ee7ad5e3fc3155d0d59b066522c752e539cc -140000 000000000000086e28cf4717a80066def0ec26c53d660582bd997221fef297db 372dcb64d18db0dfb6ea202f6718a40b5886bd69f4bbbaf760c14b2cb9bd125d 0000000000000697dee71229cfbce9ac011b900f65702f62ccb09849f7556e88 -142000 00000000000006379826f5f10cd23739b9c29f87ca10f199f9f4b72006311f85 c0cba7384d1aecba968211e8d91859f80c901574bbfa5a6abae9bbcfdaa5894a 000000000000024966c57274fd19fe22bd4d03326a4e64a6150e496e09fa265b -144000 0000000000000681a73f1bb50454cee419048d24e1091bcddadded89df53fd07 3922c45217b67d3245660060e7b6ff7a13ecc1eb66b7d62e4826834afdf0d0b2 000000000000026ba4c837d96f9f1260e64733054949f22d9189d27003c10ef9 -146000 0000000000000188cbeebda87456f040370995dc11eb3a1e76b1577b6e0b588d d49ec8d5f2b91e3bec87165770d8355d78e1934a8916637df186420bc1ff95f9 000000000000036479e4b26fc6b54b728f505df6ec956c68c34deea22f5f79ac -148000 00000000000008be94b219a94752bde6a6a1c5b9d72abf2aaab53df7d93c5fa6 efa0fd50c1e7d8dc91040031052abe3cc851ab4c6675e3a4ce724d95c478d34c 00000000000006994cfacc4d85ed1c84921eff8673e4463ed71a1df22ec6c662 -150000 0000000000000a3290f20e75860d505ce0e948a1d1d846bec7e39015d242884b 5d8aea62e24c35e0266a24ec1200f47daf86fd8f3977ce7ab7132745a403e4fb 000000000000006b1c90f01554b0aa0b2b3adbe339b175c23b8b8ce8b503a89f -152000 0000000000000aca2b3a267dab498adc48afd15b60cbf21fa58dc26c86a6dc13 fe846c807abd35fb49fbb1d78136c0edf0debdb45ed086155f00504e72b9a7aa 000000000000049f8324c2da6a67441d11b6d3303529354351a9bdad9d4d8f1f -154000 0000000000000a7446d1a63b8229670aa02d1d9fdfd729b89107fe5d88dacd8e 44fcd84719ce3be98a7d64e0ee3bc21d4e2cf0de2365370eb71d434ed9baaa85 0000000000000cfad9660f9068486ca4fc83ba6e5fcef0ecefc8c7eeb2e0e15a -156000 00000000000002adfcffbd5f09744ae3b930597dd0ea684cd37b816783ba3762 7233ce2c246f20142d71b3972b9f6d8b51dc15ad134ace83ecc24e2fd9f8da28 0000000000000c5103789361bed6a8fd64d45f81c63dc3eca73d4c73a2f02779 -158000 00000000000000e50d56f13c7ce64183386abcac63462ca745b711be27568f52 b60615c9c91eb51eb52c8bc80782d6bb528a19ed309b957d28c1fc20372b31e0 0000000000000cdbef919d1caf804a847486022f9b24f368a47061718550bf01 -160000 000000000000066c6e629b2fb49c7fcc52b82fe9833f328e0c3943856facf231 7dd93cd9bc029e52f8f2ba78ea2029a920e8fe7cab865d055e4737ef257f56e8 00000000000008754857069b7a1df3acd1643a7ffe1623eceebcb7346ffd6a63 -162000 00000000000001a83f5b20cd132f38f792fc02a17eb14d494c780ea9d1c82acc f87730a51ef49bf3dd51f6435344f9a01f939b00c3a280fedbe643d031432ef4 00000000000007df40fd05a7b78bf3a920786711de165006d7c9750ea4043dbe -164000 00000000000005a38f162cf308edea0a0a5d000bdb2073cba2386ebb1df7a2cf 06cd95a118d1293cd9aed19fa23bafb1fff0045d1dee3754f6442719706e0cfd 000000000000094d462f1a0dbca9187bca75238108e11433be19c9c92da29a25 -166000 00000000000003b3402f35327d144a465f3768d6e6cb06cd8a2d8fc1328b2477 e3282f15a892df27073c8c0fc76fa4648b624d47db47dfdcc1ac21d5ebdbaf0f 00000000000003dddc13fe8cd12a0b31f6a7c23a42da5052c3d65ab4b764a84c -168000 000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763 524d8a0ef4e2aff9bb36851dfa1b359efe49f8848834fbe0791931c8942282f3 0000000000000a40136ba56d6b514769534831e9ba805fef4d122f6c8d6da51c -170000 000000000000051f68f43e9d455e72d9c4e4ce52e8a00c5e24c07340632405cb b9f6e63a249962e7e4a422104077e0396dc2ab8d4a120806a7eec97d676b8d7c 000000000000074cb2c7d9585396b1f64b7e2c6bdb33e354b8e580c21238b76a -172000 0000000000000837e82c3a4ebe35a1d1d943e056234dba7c629922c6d4052d4c c1c8170cb5acba5dcef1ce4b12f3e08db2acece327461af6d92bd557ed82fa8a 0000000000000443d106c7a849bf6c703002756994eb9c93bbfb20b54ed05ac1 -174000 0000000000000504d3e701deb624eee4370f50c3d688fd1c27be5bbef07d76dd 6fb97ccb59c9c83166a6599be85879f97e46997daea452a895bfe23b6e645429 00000000000004fad4496c734994dc487c1397f22545287ff848b1a819f68303 -176000 00000000000004659b5b8602b2132b62973994079a1c828df6ef8d6427e4686b 24ebfb8a7f8996c1ce2d3441420e898aa6fb6b7f6a1a11a30ee708585af56d8c 000000000000094af92e179f0401e679bdccab2e475072a60d28872ce735b3b8 -178000 00000000000009eae2697a7aaf57e730b707b9f4530449c16d924d534d41f297 8fc623c7e53b100d697a24e3193411d0cafc14af70f20aa79c27ef5348e9996e 000000000000048b777caca656fc0a79aaa095e3b13c1717f9d420efaee17faa -180000 00000000000004ff83b6c10460b239ef4a6aa320e5fffd6c7bcedefa8c78593c 9e0f0850e7deb21dc15a0676c2d55b2fcb73b66bc9f02e1b878966cee4a74aa8 00000000000002b833041fa0a23d7f8c2442781ff33062fe5c483288cf151e74 -182000 000000000000068dce12903c1447e4c5b60311b61e443a25d5fc82c77f4f9a8f de9a4ba8ef86cab92ab5f6b5d6d8c180671036e603999b2a0b983b3eb5415d2b 0000000000000a6291a6ced756c7b8b46e75fd01d75fabb1c10d76ebab5dbdb2 -184000 000000000000060405a235c6b968ccb18fd6b3800ae9742c2524e28863367359 25b40a18d6e6dc6966618e0636a16cd3b13d321632ced8f3935c9597a98d75df 000000000000017c48347973112e2f48dd6ebad919d5385782b55b0341610a01 -186000 000000000000072ede9629fd1fd1af3cc2baa0e637f1959f34884be0e160dd1c 4cab848ccdaa00419273ef25ee9e64c164f6919ba04fb1fdd54106f1afbe5f72 00000000000008db6520c33d4d75470b1a5fc5ab34670655b6a18f0ca7b860d1 -188000 000000000000004cf0c72d6dedfde88ca4c3dae129563210072ee68acded0ab1 68f7e02181e36a230abf6983f967813b89a0e0f98674158a50db6996e29db510 00000000000000b5944dddd5dacf2665d004e5a10283df8b9a387725315c70e7 -190000 0000000000000708bf3b261ffc963b6a768d915f9cfc9ec0a6c2a09969efad1a 4c2cea5a930fe3af893a641eaf1f92899f4453af2b11455515c57406ecfa27dc 000000000000086f0e0e1666a9f1874988cc16d1bdf3045524d72a0cf72684d0 -192000 00000000000000af130d565291ba49208c546685c69b48a293aaf06387fc22ef 9d58ad9678fae8bf7866d6edcccdc6678e8da63aab98df7f5bcf641aa9bf24be 00000000000002b1e750d5b58c4d7976ecc430fac70b24b4a8b4246867b43b00 -194000 000000000000046242d4984ecf2217e9afa113f2835bffbff118f2df4d80b216 22376dfb11c837c1d70067afd38bd70554e6576fdadbab4d65c113d869899aca 0000000000000368a27aba8f6ca19496fcaf1e74728f34a6befd4b28ce734681 -196000 00000000000006ae59396d4a289e83fe1b9967630752a5799f064620af7836a9 a0101abab5da4a3947d441bd4838c1dc04fa824c67feb850384899e5f116af56 00000000000000a0b861ff4767ada7d0310823e9316af4208275237554c247d0 -198000 000000000000000f2ad431ff18ab1673d911395c8fa1f6801e054c5dcb54f8fb 1c7d1751d862cc8c87213435c51d9b1f6992945a097ed059c626b87cfbdc6efa 00000000000005e980307d69776708a2899ea7af6fa376d15b0676dcef00eee2 -200000 000000000000034a7dedef4a161fa058a2d67a173a90155f3a2fe6fc132e0ebf 380b65fa49998421330f6187ec57d31a132c9d1ac3e119f9a55c095b7f65f746 00000000000002e3269b8a00caf315115297c626f954770e8398470d7f387e1c -202000 00000000000003282fe1d5533e4275fd9f51e6ba0352ec01f32914e9fbaeaf55 b65f823ad7e038d1dc64c4144e87f5f77f1910351122549ee79ab7600ee2227a 00000000000003acd024ceb34c283d9a71883d1c5a74d50608a9636d2c6fdfba -204000 0000000000000423eb625dc140272ab97fea3ba6baf1dc56de77deabcc492872 eb34c90dec6b2173136c797b36b0115a9448a68c047bcaba89df75f0c4891b93 000000000000020aef81dcf0ef072f2f8f77c9e0fe57efd67442ccceef89b323 -206000 0000000000000130b815d40fd6d8851438cd21ac9e428615ba03a1285ef1374c 568b3aa80c5504f24059cd0fc9f177b33480c33eaab9041f7c976fcdfa7d4bdf 00000000000002dea49a5d979239cefef6bc38777d7faa9542b73df4e6f9ee6c -208000 000000000000001db5a1515a5f8534c941b1628f60466e6b709b3b320254afff 11800801a4cc43da007a66aa7d7d96dd947086bee56917a6f786bb4fee5746cf 00000000000000b689b3f2bf7d6da132855d5eb8859c440cb09ef591b2c835ff -210000 000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e 91ffd7a5cf624d50981c4db059fef7cb148e5bdbf81fac67fd9599e5be55d3fa 0000000000000198b7aa4172cdd1e5d80207535da5a2d4acd80242c07729dc21 -212000 00000000000003d906e4131c39f7655b72df40146d2967f5d75113a09610de61 6ce91205ac2f4832d1c7cc99b9a935b80a52af6db0089d2276e4dab5427c9bf6 00000000000004bd7804653f46d187cbc1dd55b9d3fc4285ab450b7175453a38 -214000 00000000000003e6427f9fafa8b0e1af0859f15cea90d911f64445d296a2781a f2c92f620050c691b8bb71976dbfd6c660a90f5ca5dd5723ae9add7e057f2d12 0000000000000246c4afd6fd3204ee2d81595ef621e3cbb3e36a651904c464b7 -216000 00000000000001f79a2db15d0ec6d951729e044749372caf504679bba5b1e65e 265dd035294ae9ec29783deb5d1488d506fa341a202980b3388e18ca037843b5 00000000000002b5171738a006b7d9a3157990e13427e29da9a0172e3cfd51aa -218000 0000000000000569070e338293af66258adba29dcdd5f33212314dff752ff458 826c3a82b4fbc764b486ca1df08bfd3209fba9ab9b37f3fe77f529c49eacbe85 0000000000000427e9d7228b14d95965b2424a73fb2d46aee0dd3f064c36cf71 -220000 000000000000002fdd2c741ed50bc3975a640ca419081711f30f553939641303 fbb6729ca1783f40e5f7bd0937f4969158d671dc0a03850ddfcf2746dfa04057 000000000000010d60d852a95461b8204241633a372490b38b33fa6fafa82df5 -222000 00000000000002c752a481ce0c45450ab046e640d38d6532178721e7700d8148 e4cbaf6e4174fbd3f1d361396f5d136851b4f6542ea7fddbf8d8025a5c203986 00000000000001e591318e4a6b4fd712e7cfd4e8a87bb65ea1b3c0a3f5a87ee2 -224000 0000000000000107ee276d037218bf1780dbf6d4256bd7e05c66ca133bbc9ac5 4f33a3a088c3ece8d87905a2c14baff172b4cafcf22b1dbdc61ad570adfffbe8 000000000000039882763f89f40690e59c60124f94f3d3cb33f48a6869bac408 -226000 000000000000012c614cf477c3b155d339f29d565c0258f9846c2f4dd402ff9b fdde99179a5cc0891675e550a3803c903b65acd5c4a223cc188b4598e158c506 0000000000000083785252ea71c4d69ab32aa45334721fb116bdec493fd72687 -228000 00000000000000efc4311c93fafbccedb6fdc682b566cba9519f1736b9788a67 960fbe213f3d6384eea60ce0c0cdbfda4af95e6d276596f05ed412edd7dd0ee5 00000000000000e62201a56eba803dc5510affd2cf7cbb35d8ea90a513ec5eaa -230000 000000000000012cfb19f5662707816e122ad60dd9b1cd646c6c9899be2c9667 74f1a551b24a3b99c6df3328285be3256b410df8e534a1fe06c88485e0a705b8 0000000000000200641676d2831f4ce9f0f900d0a60d72df7b78d09dbe91e777 -232000 000000000000018f47636e1c3a946db77624880ae484ffb0233f5aac6316b3bb 532e37e6cdf476e407938b13ebd723793e57677639368d32bc378767d343384c 000000000000017bf6d8208debd93d57c0bc951c0f032741fc1733bca49bb0c2 -234000 00000000000000597f9263ea97bed4d3b10fbd55733a73bd1027f1a9b6c1451a 7e5e7cce998ee02fc54ac72faa03d127a8959d346e028b04d0eb24f7b09194ad 000000000000001fc3ed9921095a06a7bc3ed2db0400341a6ff7a12ec4f08912 -236000 00000000000000f2f5e55e89dde082cecc9b4a46a10bbb4197f5e35b16612db5 4cc95beafc27959fef3e9d31c47112e6ab83a12843cc35bfe341f94b92f5995f 00000000000000a661436a3afba0ae9027f8ec858b45c87c309b22f1e53493b3 -238000 000000000000010014007d4b51ab60063684665401e448c6b0b1971a7398a442 0d8403176d4a29713df8b2bb56f1457e927391e9cc4e83122770cba48611de3a 0000000000000089c8544766168f329b696c69b273419fc305722475f738be85 -240000 000000000000000e7ad69c72afc00dc4e05fc15ae3061c47d3591d07c09f2928 6ba437006735b0f9856fff92c4cb943a03f89022aa06321eb39484e8ad0b521d 000000000000006e77df3985d9f69d92289b28bd3510e8b124ec24f2bc91142f -242000 00000000000000c95233d37a8c78dff10afecb14060347151b7eb7a04a2a5a3c 4f837013584761696fa661ebeb6dd7824a71db18ab0cb8785aa43e2fdbe7d9ca 00000000000000ccb81f6bb82efc9e2adbf5525bb9d638a1fa7981fc5a9d0a3e -244000 000000000000006ded1526017d5b87ca22e1bd0da3921872cc99e9ec77ee5166 3ad2d2fde08f4b714d4bf7bce1e8aba066c27f8b7fe604e4903c940c52674b0c 000000000000003e7b0ba0ab332ef6659061f86fe63002f81d14cdd2b787b48d -246000 000000000000004c318a3ad2ebac28d140fada215b11f5b7d8e9151ff0b000af eccdaaffdadc837852f64c344ecbf0cca417df84a73435ca7ea7ce21245e87f0 00000000000000349dd94eadbc44ee38ecbf5e97227e37f3c9a7ad24f7ec8dfe -248000 000000000000004d945017c14b75a3a58a2aa6772cacbfcaf907b3bee6d7f344 8903f33f0671e4d616c52a9b7ff9fcfa52f2d8693de4d861171f9a9a4ebf60b4 00000000000000172fb9615729d960ebd66864c60f04f564e6b2464142460a58 -250000 000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214 fca9f44b3b916d15b3f443c421ca9ba2ab375fb4e04c67fa0376356bda89507c 000000000000001b3f536a81be90d5cbe8b79c2c1df53d1f91540cf5cb5a7c58 -252000 00000000000000200e99940b296ded4ce16462bba1950453b29abf313ba7cc47 e73cc4a756a24389065d1449aced46be359a3dde08d21771d6acc4cca13f7bfc 000000000000001ce1ddfafb3d2d71c7be37dc51a069f6fd3835ed5d0bd3cc3c -254000 000000000000004753be91559a2c74c6cb8a5d2be6db1df2ca0b2385697e53ff 53b9c0602531b91799388b526a92a080f416a050b11672d1d0445fa679675774 00000000000000305aaf9a4a98b6762204fba13dae98142875ff7557a51cb176 -256000 00000000000000252b217c0ce5c4d96b825b90dacbe8e4dcf5f6a8ba6749f3c2 3f5c51e6a34ee0efb91e840422f1a0cb9d369159ee3a60878af73275f8513fa2 000000000000002ab7b60009c3d6a4bfad05ad27e27fb0aea72fb9a3bd3ab9d2 -258000 00000000000000159f682a983465761f471dd24300746efe8db5642411f1b631 768d77dcefe6edb2ea15685557687aa1d56090364caa056a50500e9dbc003057 000000000000001b86532884bb74b3d170f05aa29367aebff48e139d561e2c35 -260000 000000000000001fb91fbcebaaba0e2d926f04908d798a8b598c3bd962951080 a3dce35682fb3ab81208ee85e060fca7df01ac1f1571963cc282aadba5dc7ae5 0000000000000006bda8a9646243754929a49cbe92a1312ad9623468cf99b9f3 -262000 000000000000001002ac67e026c523c3779b1ff2e3b9e2b7bfa6022ee1afae2a c84f3300243a15c28cb92da4a463a222994b4161ad7924d3ed4a229d2bea6ba2 00000000000000153388f79e68c8a5b974c6b73d0666ed6d75461af43c75aa81 -264000 000000000000000d05c31485c532503939ca0b88d7e322dff79900ee6cdd5ed4 0fbc45e463dd17169de0fa15142c8cc76b2e17ae63337522eedf481e67dede59 0000000000000007f58dd8567278c80bb9f964c293f02589e83dfceb8775fa60 -266000 0000000000000009d755c65d58c7c1fde9167ba632a85574de3bb11c8a862e35 2ec325ba811b0f3ab51d3634509e01163fcda807fb4283b22ff9df612640d05f 000000000000000c29b5b02f59257025f48808779bca45a0f1414344fcf59807 -268000 000000000000000048974ba0669938f7f8463650cd5c48c027aafd88c00a46af 8db51a37cf62199eaddb7b4c6eb8f3123ed0b86a5794e893e40973c96661b2b0 0000000000000001134627e5ac79f7fce271a5fdca76d5470758247ed65020f3 -270000 0000000000000002a775aec59dc6a9e4bb1c025cf1b8c2195dd9dc3998c827c5 c2346a70b37186219035dc71a1646401c8ba43c4e7acd77331e0fbdefce3b76e 00000000000000072c426558ed4a3431bfad3398b8b114aca7c0581337992105 -272000 00000000000000050a89e2ffb28757d35e14615f23b981eca68906c8c71f65f2 c65c9f220b58b16cca0692250d1e0cad5ab362f4ebed32341c48607e6fda97ab 00000000000000005ae2b9dd4ea05866eb5f5e8a8ea54e25a217a9c6bbb5024f -274000 0000000000000003fe2d3425e9f9b906f02f40b3db90d908ba0fbd1e44cf43f8 30ce70e30cdc5a67101f02b4f3a5c03a6884115dbcdc7575c9d67074410a0c53 0000000000000001dd30fc52fbfb29a7e7fa0c40da666b2ac5b010cc7acb3674 -276000 0000000000000004b8ed801f8a09ba8c1248a5b1dd1533a35124a80438573f59 e1c5aab0f6644074f689bbf82342ed9506b1a0870e16693f8ac4262998defa15 00000000000000017c2574b167a6be0482d330d8b3788c3ecf30aea1ce52a579 -278000 0000000000000001bcadd1e4b4d01063a17347dfca126c63893d2aa37d82eb7f 64b4ff707207f3cc5ee178ae31fd21657cd40058e4b229c73eeffdf0ee2a3554 00000000000000013efa0ef2b6d85ee121367173cc9d7eb375717e9782f4a6cf -280000 0000000000000001c091ada69f444dc0282ecaabe4808ddbb2532e5555db0c03 e2b966c103fc51cde523784e0ced0ee2cd3278b2e7b3df1f63a33f6b25a01ca1 0000000000000000bc7b8f8b4a60aeb73c05de005797af3b78e84d61c93f3d15 -282000 0000000000000002337ad25e6a9767420766309cfea79f13dd9c910bcf5ca063 f240c2cd23349a0e763f38e584f1dc0bbf1d90472771442fe7884d4985067ee9 00000000000000012781d061268f7e1fd21424013a0b48fb5b2e4b47ad44f353 -284000 0000000000000000eac86582f121e5431734e2ea36bf73347022c99c1adae37f 2d1a44421e7e34d10bb7b5c32a59c9c5a3b14573e3d0a46c90e322bb05161dc3 0000000000000001d6b73ce478f8801d837f94d3a8462e67e9c5d7898b5cfce7 -286000 00000000000000004388ae444347bde423f2f3aa6ef335b50909f5bc27d31ea3 e4ed93975428acd1ef1ef7bb927ac1daf20fb8c2d6adab05336992b6b0d0f4c7 00000000000000012f5d301e9e40642ff62d5ac36be969aa7ac5f3f4fec8087d -288000 00000000000000003c395f08779c3ac1301488b8a18c0999c008129a55610785 3b6fafbfdfc0b5178fa61259550f1b2103a5540487a626fdde1b6d9a0ba167a7 000000000000000125929e53afa23bbd42082294ea2035244570f993f4fc93d8 -290000 0000000000000000fa0b2badd05db0178623ebf8dd081fe7eb874c26e27d0b3b c58364e3c15d72620ef6e6a109ffa90f96e245c2ca97ce9a7dba1853fa82d3ac 00000000000000006fa3f3b92c95c83ddd9026af8e00227c2acd34b35a7bb290 -292000 0000000000000000620671231acb6a68134a0396235dcb0e53f4fc82bbaa1184 facb26fe1435fbbfc5a310535d2908aef9062c0a6fd9b68916079a8023caf2fb 0000000000000000b55300241bf11d4e59066bdf0af3baa1d5e61fef4a897305 -294000 0000000000000000cb2540b3f00ce422887904c75b24bf75b8a73817302a4138 b809bb53b2bfe7a4f5cc8799f0ed01ae9c7ad62e84337dedbaa254b645bd8d22 0000000000000000b2b41965d8307c588f5fcb4833ad51a7bb98009a4932d222 -296000 00000000000000009570102278e59ecf045c16ec8c8a5ea85bf823d0ec72e3d0 65ee22d627de991a1bbb6a0991a651f104402ced579619eb0f7a377d55773e7a 0000000000000000a330622827ca24512b9be55a9be6a489e5c5c22fdb735d9d -298000 000000000000000047d2f2eb7278e3f4aded9acaf502f5ec27bab5018b5871f2 017018dc979c71efe3f45156cf325f526282b12e166ddf89d268eeb58ecb2dd1 0000000000000000889350c2e7875fd9d66961571d80f4d8a1b09cb24c27f3fb -300000 000000000000000082ccf8f1557c5d40b21edabb18d2d691cfbf87118bac7254 f7d092ed2a8dde8b8d9cddd1506113821128e2e159b853639deab2900c4fa120 000000000000000049a0914d83df36982c77ac1f65ade6a52bdced2ce312aba9 -302000 0000000000000000072268c9bb18603566ed5012378c29bb4d37e34cead7448d 120995054ebb9c08b074422fba9ef42e8bb2bc30cd60258c844b966505f19a8c 000000000000000073fae68fe1d836d0267e1223de5d84f95adf177f5e16a337 -304000 00000000000000003558a1ceec3f5338c0e887b4171410195a7fa0a81bcaa628 19e4344dc468e4e7c8dc4007d8ceff0addaed303635905de439366142697ea06 000000000000000035b5ce4b07d7e44c04d197aa38db69d34707e6887b319f47 -306000 00000000000000002bb3265a8bf67ec2aa436c297ac7e56fcedd4dbaecccacc0 ac5028bfbcb9b75d7d6899a4011df8b145eeb608f5a49416bbef4bfc5c4a9abb 00000000000000005c3cad291bfb86105e4b7c480f630a2a4752d3277d9624b7 -308000 00000000000000001d55aa114bddd81938d09e2dccd432dec59a4078ca0bc0f4 7e4d47a510a28d57b7f11345446c8e54c6a6229d8b5769cd379ca605233d134e 00000000000000002584ecfe801597c83fc011536fbcbfba8dd4375eef09e4c6 -310000 0000000000000000125a28cc9e9209ddb75718f599a8039f6c9e7d9f1fb021e0 4648a8ed4221390d9a2c0fed720057624e3d33315588c4cc2bc9b8033d8c446d 00000000000000000e50e42984c1baafc6cf4d3e4d74d37e056dfa79fc63b5c6 -312000 00000000000000002bd1fa27964e31fe9861b40940e7ece2cfa359765b219a49 e9d2bd7f66ce893da7326ee58375c74646d42a908e8c4836316e557d2427669a 00000000000000002f3e589b149d8143eac0e65221f46ebc81413bea2ea696cf -314000 000000000000000008ae6cb20997f3c4aacc50ee2f0d08a0c3691907fe7357a3 58ca25e3391f26df92c47b9e5f6e19852248734b369cbba90b73c5e99e746470 0000000000000000291b836b50bb1ed8c086095ea8161635655685e42a45c9cb -316000 00000000000000000d77a89ab1069e47d1213ae509de95ee0d9ab095a725f7d7 7afd93faff66fc592596cb8bc2eee09e0a0f3e7f594b9655953b24922d3bb75d 00000000000000001c08ce6cb65c5e41420500579753d2249d22e8fa31aa03f7 -318000 00000000000000002583a647dc5f084a312e12bb90a70c3fe1eb1e4d419f35b6 498e6e0c39a2b4e3e112d0f79db25bfa7b482df8826a817e893738f9393b19c2 000000000000000025cf9c14a1e976f0e2c827ee18eb7273c24a5a4b53d10e83 -320000 000000000000000015aab005b28a326ade60f07515c33517ea5cb598f28fb7ea c4e88ac94f5537333d613291ce13a4161d96533fba812ba61748b95d02095695 00000000000000001bbfee4521419de4f79c19580027b00f9739ee7b2f0b5c57 -322000 0000000000000000177da809382f93ca1c4336811e4a910050689d317d62264e 5acfc8fe0a05892c2c92f047ba55547f125245877c2d12c6aff9f1d74a60e088 000000000000000009e46e2aa51bfa1fa0e6961ad8ee28b03716fc0616937cb3 -324000 00000000000000000b9880c40075d763b2a5f04fc01444a6278c5d2d442cda0b ab36c74346782a0047a2276e588492a5609d3fd7fc4f2a26645c70166db0f124 00000000000000001377803fa65444713dab6cae2c10172727775bb425c6a160 -326000 00000000000000001e95e7216072cd53353b964054b592f7ce84d3743aab125a 61a2e1cba22bc04a885f62544518c46f0eb4e7a39668028d67ff48b2aadb9b7b 000000000000000002ca091c068e0adfa158fadaa03ccf70af7d06ef2a563e98 -328000 000000000000000009cb9a303d105e7b96b36546a3196f6f79ece4b43712cbb2 3a7260ef08d756e217dbac41123a2d9c29e9449ceeed9690c4f67bc9f891011f 000000000000000010139d8c1bfa1933154b6ab111d827736f704cf91fa0e322 -330000 00000000000000000faabab19f17c0178c754dbed023e6c871dcaf74159c5f02 3f57d68b53b69e52e5d284e7566c2d0575c4bafb08e7de1cc0f9defbab5d78e6 00000000000000000271d56cb074731c2ffe250c9f9482ba47ab1a898122199a -332000 00000000000000001799255bc0c35f91f7d4fddfbf7e84dedf94fc59cde9b7f2 d833c527d933a4443bd9776ecf69d12f386cbe74d025812cb0eee5582098c962 0000000000000000084f645a8b53cfa7ec7faee3fabf3d1a853152584aa9c2c7 -334000 000000000000000008d1ff7b7673837e9d7e1324dc7ab8498405ea583f43f53d d28c040b4daea020a13a9720212ee698905b106bb985b46fa7fe3aaa3a45586c 0000000000000000199cd3ccb5feefff667d6ade51eb5e92531018d5b9cf197f -336000 0000000000000000125e3e6f327edcd7163b486efc16e79b8a996270127b54df 204e1ee93f97f61493e1de727c872cbfc11b7c51c42aca4f78e49ead1fffa7ad 000000000000000011bbfbfe73d56175a1906ca1eec461876887123e3f69a42e -338000 00000000000000001983dc4a87df627b63cdce28e5321cb867fbbb74c0e87e8e a10621d27b01bd6be869a6972b56505b2833076c33b04e8b5722e09b35091de1 0000000000000000030d9281927559e9ac954e63032101239f91108375eb4e61 -340000 00000000000000000d9b2508615d569e18f00c034d71474fc44a43af8d4a5003 3925a6d41b5ba3ee2bb450f109e6e0741fd3e21776ca9d1fd78ac3ae721e24a5 000000000000000017e6362910c6efd4dafe37d551a17db50608f19f52fb7bca -342000 0000000000000000007220892af98a563a1c891c756e94be3f14edddcf637c3e d4406c4644692a1e617b7e140714bfac57b4d5c1da5efcbabcf8867675cb7d07 000000000000000007a0870fbf18c6b9f23c623f7f332c1a06bcc1a260399940 -344000 000000000000000005f0a16f5a9f95eeb95c5eed0eb221e8f5dc5a9943a03aee 0b62e591128428eb437643cc5047e000149f30003ee8c7e1ce4cf57faf6d713f 00000000000000000b7c96af32f1e4317e3069ea4bfb02697caa6dbde7216f9a -346000 0000000000000000068d33fd865621cb7eedbf05c6b235191fa1cb8ee2c797d7 9b868fb539094f9e9185fe1d7683f0d6712247a64ffea660ac384ab6abead41c 00000000000000000f0b165c17e8dffc545815d7ea4be64efabf3a0d23014350 -348000 00000000000000001598a651988bb3a45237c4f801cf8049be20f74aed8e827a f88007d47bcb3ce6f2940440ec98237963376db32cb7cb7ab5d68b40717f3b27 00000000000000001462b7aeedcf2b5aac482d416c707d651d5465ac090002c0 -350000 0000000000000000053cf64f0400bb38e0c4b3872c38795ddde27acb40a112bb e59c9c36cc8fe49a7fc817551bec3eaebda6a5a21f337dc1f77fddeaf1c4c7a4 0000000000000000075f18b37aa8c6fe753d6804bb03ae91ba0d86c9cac3fd67 -352000 00000000000000001635a4b5f27d2ec458f7bca550d71f490b93e98e7a07cbca c191dbe07764711eff7795883414db7d14381de453776edfb75abd6f3e7bb013 000000000000000008d042a9fb824233bc40aa214bace9c05534d741580da39d -354000 00000000000000000cf8af9be2709e9d7adf2c33b3789aeeff517987f4be22e8 4b1e12b9f948003447d072f31f0531794e578d918f024580fbbb52f29d412463 000000000000000005ce357b2bb22f3e2e770a89d9f81af07e65aa28b11034bf -356000 0000000000000000138ce5493b612b0e90b66e2a76714088d6b3e6a4770215af dd4d81753ecf9b2ea599ede6307c8b4e0f7eea8dd9c677887d16c980270d13b9 0000000000000000153c94e6c7510bf67944d7b11e56de38c4c06850ee19c047 -358000 0000000000000000073aceefab8c381c3c4edb4f87a6d5d2ae32184278218429 9167ed0d73ec659f60b8b526b66078ec5c2eb263b7957a2bc1d16c36566d749c 00000000000000000c203f910ac1def0be1d848535518369e159a73002574a2c -360000 00000000000000000ca6e07cf681390ff888b7f96790286a440da0f2b87c8ea6 64d55132d7d41efd3c82522714f8ffc48d16b97ef1319de1b773d8e683ac70d1 0000000000000000144eda4e110a9389cb8e6a301366445ffee980862faff5bc -362000 00000000000000000bfcad6c331dd152cfc713e9e0790978a10e0bfda3e030d5 18a58a96470360af27c405f7aa63392676e77b723f524186926bf72b649c7070 000000000000000002f032a6c1d8fcc634946d36c10e1e1501d5b954eb82f726 -364000 00000000000000000e20bcf213a0bbd6be88d5fede6b060c737f7f8b7f1df504 09ec4fe62e9741db9583a5c93ea9b19663c84d0c97f34407e2e5905eac6fadd5 000000000000000004cb2acf1a28acd9d1e06d71357ed177ad61b9e6b8562ea4 -366000 0000000000000000138e108e780fdb71eb4cad533b46445ab6befbf9687f561f 02440f43691a61e3b6748396acab0cd04d6e2f7c52da764bb5ab8ff2f5b52551 00000000000000000affaf111f8dc332f8b2c3390c9a073d938dd1bdc5aec5ec -368000 00000000000000000d39970aac12754eb89c2dcfda539b65562e5c3fec102c24 6ef2048848f4ba32f43a8c9ae7c96ad44dac0cfb96344434acc96afcd57dbb3b 0000000000000000125427dedb152b12f85f1158054c6239b68169177e2155b9 -370000 000000000000000002cad3026f68357229dd6eaa6bcef6fe5166e1e53b039b8c 64bf9a93317f4241810ad1fd317b3353941c4c1d45e393485681b817204bcf23 000000000000000001ba6a172df04cb3a90e8badc70b7fdbd4a7b903695bf47e -372000 0000000000000000028093cc8035a6bc4e0d1b40932c2f8b50312a3fc86bf3da 1667a87afc743f41a0731091f2762b73d82cd28244fac555cf26623ee0922543 00000000000000000f2e596350c35a8a69c1f74416c19352cbacf7ef6f5baebe -374000 00000000000000001016aa3783721673bebbcd1efa49946b52cceb09a81465a6 083a4b6e7c05729940cbc80f545dc03eb45ad8c1b9990cbccbb80788835ded3a 0000000000000000029c559f066604a8e5ed21932434eefa57c8c9e6d6cb9e30 -376000 0000000000000000106e9e99cf4fce4e8a4abc97f3e883956e26d76b3a1133ce 1d5cccf38607557a1f0529cc6e1e447a6c179e1dbb9312f4fb8e6e75c11fb434 00000000000000000600fd599dddf15b50f48b66ccdea01ea56d2c093192062e -378000 00000000000000000516cd5b5f4b7e528d6e61c643595cc818f1d02f53da4281 a6816997bbb1524ad10392a1749a2ff4dbcfde9a54ce6e7a5eb020d33c0421be 00000000000000000aa09631f3e8649893da2525f739b6b088c76dc8e898e4e2 -380000 00000000000000000b06cee3cee10d2617e2024a996f5c613f7d786b15a571ff 6e6daa40b94422f281dbe453dbb9a66607593d5255dcd89ac17da7126a0719e4 00000000000000000bf2da5c23edccaa70ee183262cae2354f18f8a3201afa53 -382000 000000000000000003cf98590769bde40ffcd6800733ab47dd406d8203e65a89 dd7ef79f7cc85f27f2fc778e458e42669b1a0edc6fda9de066b75ab72859dc13 00000000000000000c43df306ac280360bb0592d2a56f2b1a9e4c8e870907bf9 -384000 000000000000000005dc7ea53e2f6eeb09798cc9d2214f09d249661c36c288b3 e58fa7e82c9b78bc96e506097a62546f80a8714575eed182322b5dadc08fdb48 0000000000000000033898c26a795ca3d35096d2d3e025823776277db16d977b -386000 00000000000000000d94c8c0b0ddec874d2a597e988154733d9ea614292c08bb 1744bde331acb42ff7fa8dc19cbfd8fa82272905fa9f7be058701cf2dc494bec 000000000000000007a2bea4f81d4172715f7ebdad1ad4021e3cb1d1c7da7c21 -388000 000000000000000003c5e9f4f84dc78b5ca96b7f2d89e9063b5f74543b42b9d5 5265b61950210ab7c9680de11d7be5bb02d3b5d3be97af2627c0cc0308104927 0000000000000000040a0115208109fa1a4a80f351e7aa474cb26c80506740be -390000 00000000000000000520000e60b56818523479ada2614806ba17ce0bbe6eaded 46bab737096a1e1bf800d9a0429688c8e676f3a480c850b3a5622bf580366703 0000000000000000055265fb53f189394aaa2c88ca37548c693c17965c9a45e2 -392000 00000000000000000850dc9d4a9a8d45d618d8f0dcbbdcc8a6fa88a6a90dfe1c 21d7a6c6c4b6e3c389c9d0046512b348d1f2246b8d9d5004bc1244cafd7d066a 000000000000000005b076c1bf4bb3c1bbf331c0d1a01461e9429a1b71f40821 -394000 000000000000000009ae6157a480e351cdeb8be494362a3bf3cd1c4feedf8ad6 e871c05b4794191df935d8a585fbabba5cb981ff5936d49a1078aa8ad925802f 000000000000000006d90033ca2d3e257db9853761609cf17b00cc6a6e705f48 -396000 0000000000000000079226c668cd1db713fb78ffc127b422e12b47baf205b478 f9542a8a8185328b82984691a41509cf245d008d875d158e6d770b703c08b5fa 000000000000000008e53dbc34ec365608efc9592fd982d616a9ef5258c72483 -398000 000000000000000001c6bd9d2dbccc3f16ddb534119de0aeb7d0a8c87f78e001 e73b9cb5fb81415bbe18e2601f261aeb8fe843d53ecf708219da5bfe096df418 0000000000000000029b38bdf2fb2b7ab210931ef90b0886f09d7000f54ee23d -400000 000000000000000004ec466ce4732fe6f1ed1cddc2ed4b328fff5224276e3f6f 6a5623df8be9c601913923a45a15138c81f2735aeb58930706cb6b5a729ae890 000000000000000005421b1b2ee6d06d037557d7f5ec96852542413cfed40c22 -402000 0000000000000000001b7da4ed218caf465ca9bb08a33712e8fc3fa508e6264c a713821d1bbb65b279f1b3419e9ee55faf8edc18af03d027089abc31b8789b69 000000000000000006e4cba5d6971fe5dd734dc68e158bf0a6f4d78c11d0e91f -404000 000000000000000004f9f0d6320d54c1f108130998e5bfb911f521ddf34da82c 65638c1d27075ca7bddf5f5bf7e6a1bc53b1ee60aa678c629091e3da60fe59a8 000000000000000001da1eeb6fa89a81b7534309e3dafa425db27e4e4e3bb972 -406000 000000000000000003b3efcefc5eaaef3b21671228233be52db1a080022462c1 9f141ccc21d86aa7ae67a18f7b405d6c4a24a367e4fe5c3bcaea08cfb20de64e 0000000000000000031c610eb5a810af32b531569c5fe681d0c2ddb7ae56be80 -408000 000000000000000003cc3d3e5b5d9b577b83c2b8d6f4257398c8f4aa8b2be649 0859f04d6ff78a9a631d5747e29d40e72defc3b4bcb58b046f73bc8bbd7aa50f 000000000000000004f62eeb625ddf5604eb9c3d9e5f214b643d23be2b83a99c -410000 0000000000000000060d7ea100ecb75c0a4dc482d05ff19ddaa8046b4b80a458 diff --git a/iguana/confs/DGB_hdrs.txt b/iguana/confs/DGB_hdrs.txt new file mode 100755 index 000000000..4a7fc4878 --- /dev/null +++ b/iguana/confs/DGB_hdrs.txt @@ -0,0 +1,1470 @@ +2936002 +0 7497ea1b465eb39f1c8f507bc877078fe016d6fcb6dfad3a64c98dcc6e1e8496 a6849515c6c79f97b395d345f647bbdf3c082c7571aa673299bb0670c6a7640f 4da631f2ac1bed857bd968c67c913978274d8aabed64ab2bcebc1665d7f4d3a0 +2000 8aa91e06c2e39d604f906141e4c73ae572badd1aa4cdeb2063217ac449cf6c95 00b5d9dd06809a5594e7204e21f5d473eab6e77c341e2f6e85d4983357041c7f 9460da9a6737a71149e3786265a2aa1decde7bb353c8059119c51f4810b13ce9 +4000 7b9606c42e645fb94b8f85e23e146fd0c145720818ae2719d778a62dc18b5751 21d1cf38b8178e6af609e997b40f70317876cf932face45513cf5cafe3bb0199 65e1addae1d540f574eb6827cfd5670da01dd2e6350b99259f7d22be8179ac29 +6000 f728232de360035cb7b423df2ef1767ab32334309587e93261d4b25a49ec2830 779e951faeca87b022e0c1b64f21b53312d09f114b3de7c27a9ae5335a5b0868 f1f9fa72f6376f8529562c2e7c89dbceada12602eb60e669450ff3de8acebdf7 +8000 e64fda15e29a29592af5d0816dabf9976bd3c5d3a08f51ce0851b14a98a51764 ad59a22252a0a0672a34bbcccbec104149196ed1869c7683067487cd8e75ff14 55ed65ccd7bd7da3a71117e604899c3b9171232495b798c2eb2ebe8434901e4f +10000 12f90b8744f3b965e107ad9fd8b33ba6d95a91882fbc4b5f8588d70d494bed88 1269856115fefa3f1bccdc3e0c3853952dc2b8b31df231e7dead3c8b2d69dd40 25630aafdbb5a1d343b3208fc185cd1042325753ada798777baf8d5dae940475 +12000 a1266acba91dc3d5737d9e8c6e21b7a91901f7f4c48082ce3d84dd394a13e415 24552c759b8afbb5afee718f4080ce996b7f0b9d4261e48f48554a3605981634 7dcc378986b7300b16713991cfd74897f57dd91ed9632845a4500c199c86a1c6 +14000 7d7e4109daf92a608d1e874373779418d53d22ddd9edb1a32dc707e862475923 701590999ca3fa8aff18ba413b6cf507e71dee9d74f11db61471ad4e1e8a54f2 9907e409feb3fee31ca0da25b453b86b8ac69bca31ee9e1b39627a5faaf7512f +16000 5ae8373d92eb53e87754bfbeacb8bc3ab5a9dbbdb00f70c416cb4be20665317d 1d84eb6ad655d7f4cac06f1487d37f53091ce21539b6e29f435e99eb4c481c68 3ece93d545c89fb6cd2003b904d123f87a658791a733527890d46a22ea5f6236 +18000 25b31fde8f35005a02676cc18ddb0dbd3316af4c18ac34ea5a606b9bf9f06764 2cb2b5c59f29050a331118c5d9536d8745d093ef6c3fba63eacb44cfaa85fa77 7362be6c71dca2064c13ef5552141a735f5f4ec732bf4cee468b6bd3fa939736 +20000 a82695f2b9d1622ce449698dbfd8ab3330ce6dee80e7ea619c919b1c156e1ebe 631c7694bd389cd68d0b885c2b7436c38e37a6e1bcc13019d2dd6d4775ada431 41fb3d98d75382afee67f1aa81236720696b24c71aa4298ea075beecaa312f1f +22000 9754ca7dda095560b79990e2430a4945c8f96f7c20f8af3189fb0edba6e536b7 439d5325591afe38359541b1ec0653f2f0763ead441a8c7518e2f090b437c2d4 804eb6fbf84eec842e96c635979b96918daacc025c44bc47a88d39516eb57641 +24000 603de2d7c338b5cff732623530d94287d0dd9b7b396e30ae12b46365280e11ea cb13785a0b849e6894f8bff99f5e7e3b5539adbfff1b0b4aa107eaa346f40144 b144cda2982dd83c0899b70b292b3b7acaf7edb00f1a89fcf50f71276b95d009 +26000 a876c9d65dc5ea583bb672b85bf0d4fb8453a663e8017cbb21d37593dd2cc039 1186950663d8bd8a3b806bf00e73acaaa3f5bb0bcb25dc0da0a605ff46d0bdb7 14043564632c35a93a09b72514c6696d72fc1b091c16d7e0a46d68ed15756041 +28000 e3d7f7d388763f5f8e36671dec95133ecda824f5f96eded6697d19e92fd812f8 5319c8c3adc8ac2c50ebaf2be52cef4208eb49e947ef71d688b0407ee4447288 0fa1bbe411560e641231581af176cf42afec04848536d2b597fdfee324cfdb2f +30000 17c69ef6b403571b1bd333c91fbe116e451ba8281be12aa6bafb0486764bb315 d361f38b71655d14920c892029bddc0ba7be9605669241d89421435ddb9bf3ea 1fb025ad4cd40a788d04d97689713f0b7cb84c8cbaf9a7125a8b9c322682c5f8 +32000 7ef11adad45a7b750d0f1b2da935fef12a7b394c5b6f3bca5e85730523442fa9 730371fee80c1f865888b203f0262572d9c69af54e01d9337a6fb7e6425ebc93 fc3275c9d08bf4fe32e854e7ce8f65b978ed676fefda203871268d3d79380e91 +34000 f85d07151b3da7cca441ea46b0e6b6c1fa7d70a81d356c3cff0bd2395e8957a2 7bf64624c9376cdbafad8e9f036f218ac50ee87889285856de33c09ee942d6d9 51a91ac92555e19c653b169f716f664e731844df9e50aca55889469a31199d38 +36000 b4a3c2fb3d25b9f65058f759fbc424b1f2f392f2595c5339bc78c47cab7d0141 5f1d6a4cb759cfb7e9d183f5a9487e071813140e18a57fa7f45048f3b7a05420 20f9ef2e26c6385455df5e0246bd5be18379a183dce95c67b3dc22aace94f21c +38000 b82e155b3c5284c2ccfbf44b2de584716d9c9911c07040e59c0b90ceaab567f1 b2925d316bab714c130c571d1743d3025e5613e03621cc4fd1a806a3258d1448 413b0ac977b4356b3dfaa6c970630e779e326f62a338c8a9dcd2b786f9980a9c +40000 cef9045a53ecc3e3f499ac13c78c0d193b6852dcc58061f405a53ff658c1d78c 0910b62517d1be08858d419823c8502cfab5468302efa8340afb0e47f0bf0daf b431629748cb7f5ea6aa825a35aafd108ff21f48355399d28cbdbf39c6a3080a +42000 cd401d189bbaa55fb036102a03d0da0d328c1aa6a243345df87be8163d432ad8 23996e829460842f3caef903f34aa5a7ba3fa5376fa8a2364811df129e4d3cb7 9e04ccffb6a149d66d28e8ba40848e4c9ae423deaf8e620655c07571696e908f +44000 e6edb9f0c3bb105f4d48afbe4a64c4a144588f465021e67cba6aa66bef7ecf64 e93aae943404150f2c8fef8ce71e312c5769e5c08b5c8eef7466e1b66f1ec3d0 a48697053d9a4ad70a09b0f9f028f8b7035c89a43b8b19cbefa1019c4be51b88 +46000 0bd611cbcc3fd4952c64145eb0adfb0ee76c17a08bcb83b24dde9216cfe1dada 393d3af6f5f4e8db4b6dae84c6972bf66f5eb689c1db8189e53e0a1e53fe0051 0761a3e95547fef8992ff1d8e89531832bd729ca42baf1b991725a8216385fb5 +48000 4a8013260787c3fc9d6c6493a43071cb34b4c4b8fd02ec70b0de955d276e7e73 c669fc3f9c8f5abdc897988485c576198813083d7fb654629de7a1d3ae68d13d 6c1d97d48d95eaf389c94d59e7dcdc0cbf606f125f50101396f1b5627d1ea13b +50000 e77a35893a5611c4154cc71f7a7f949e074143e66b05cac2bd8c1db1c752c2f8 d43f2d479f49ccd4c567f261ee0030a6c1d7698df8340111256bb689c4ef3965 225827b9fe620d31e22d80f7c0c0cec11bc5d12466f8393499b9cfe7299b9afd +52000 2de8189760a0f272150de04eb993b9c80fb92178372968e53e0665552d02bd14 7caaebb8f3d117a1686a215c649e2f5d05a4df10133955ce522fd30102732373 bd7fca9cd852813468e83b7755849669edb57cbda707efbc1bfd57a6fc728f22 +54000 282fe131040e874a7356f023630993e8f3ea14da0beecd5ac1a78340d8ff465a d6129c207df348b83c467f887dc75c91190eaa08f1946bf661103e89edbb6e00 2d3a4248885d15bedf2f4289f20929bebe96180a557f1df086aa492e8e1b8720 +56000 942c6db3edd545c621f9a3a983e1cd1dc3d814c6cc25583398eec28c991aa313 49f418261802ff50bfe92674d4e98b92d160fc910ff965c11f1dd6c6954eaec7 e67f5ac88463200f6252180b081230d0632b0aa818cca3b331081baa55d7e7bb +58000 c7c999781ecaaf8b3aea28c72e7afa28f32ae02a62273d948a23f39b04a9d220 d4b9d30b7e92e35b231cbac78716487477920da4bc8f11d6dd2b17a09cebdf44 ef6fd14e266006260f0f1eba6db9fd01d09f1f3e0ef31ed5d19e7dfe01de432b +60000 57b2c612b60462a3d6c388c8b30a68cb6f7e2034eea962b12b7ef506454fa2c1 1644672f46bd45ac6f78bb3dc515e83bc72e143ec5f3683602fc9c8f5000f24f 77ce0c805587996eb7f40a8cf0f37162fa4021dd7e8c0f075047475e34267e19 +62000 b74d5610a2593c0b38da67f9dc5434235800070bc94f59f3923a480ab1629c93 4e37a9b88c174c19012b07a8bb8f1b99747830ecb3c847befd606b106b1bbc93 4cd6ccf42d24bdd63e28a9e7b54724f554ce03c093b0a716b6dc0dd43e71e110 +64000 6f1e2726629de0476fa92afb0e00c5a03940e881cefd6a7345b94ba89c9a2129 8d7ef4295e69280b680c26b9afcf9ef253ba03eb6259a71145673b80e57f8d29 62dc396ccb84c898fded2beb67180ff3c6bf624ed7a1a6f5c3ca261d2df5ffcd +66000 4edd69f3ea48b19e13e0fdc1cf86df5b85bda8e9de19aaff08172092b4573007 2cfaae5d36e0cb823f9954206f8be872208594b4140148b1f021f0d34dcdb723 a5de278b2eeb03ce88ed84d94546db879a28f87a6a0285041bd46c55a0934819 +68000 78d17de4b35006a962fc9e634bb5e6fa459aa95f7de042c5b328cd8256ed7d72 7940cf3ad9784f5c0e67b2b5a8e2a53629d554cf0502447484d887e7451d3de4 008a1c18d59cff5118a1fe14f77897bf1ca4cc95e3338b530f4f24328453fb7b +70000 248cd4bc6058aad95c92cd6fc48c2909176ac5b2efafbf8287cc590bda3e729d 7f915019587fc6f21c5ea57981d8f0eb0db1ae2f3bf8feb49cf15682bd0e4de0 e8573e610e7b4a002c32261abf4984c1f05a7f1c5b9a859aa5d1a4a0b2fca7ec +72000 e8e6b872905a4cdc16ae4d746a59cb067bdad58b52c7ade6cdb650a664243082 9b70de33ae33a15a2e2bc07f2695d44163ca8f082402bc0a0d50c764623f7c2b 0fcd9e19b51a26818e87acc6328a42d8aaccf3dc9c7d10d10b0d834a11a111c5 +74000 2ed8382cdb1a5ec680197327123ec6e69ebe338c9eb8759de45e6bf627638310 a8ba76de1f7ac4d5388ea7d654f366e073aafaa97a94a533587bda66601e5aa7 38f6489e753b035a34fb8da895d500f1f79429881848cb1c66921e745f9002c7 +76000 b60a066e3f772cbb8d27ebbce8ce2ff3b57c077fbe67860bc0b0dbfe27f21510 5b6b3737b4d29c79cda2f817b62423fd2768ad2a6cf3ec91a8d59567dec9f48e 8415befb66e8d927137c86fb8d2a4c092217884f7a9551b976b1e670a333b86a +78000 0c71c3f5f19730f98bcdfa2d8e925c7ed6b196aac977ad27682fb4395b247afa 196fa909804a728b3f266ef39ff1c9fcde3a4c708c23536768cf5f6e3ac28965 020a19f8fd47ddf5494fba50e4898277a81d49c98937c81e54b25f3c8aaee5be +80000 17d59481f6d35738d577773ca7fe2249ddc742013bd1dd39b677b3e1e88fa413 541ffe884dd21076a359680ebe09c44df1c524b953c869febda98369c6412ad3 12e9c967c8ceaea0445fd72444d45d85da145dab0bc5e82031f78fd565c17e6b +82000 8259ce88949dcf38223b9c6e0b1fc3592dffff20bf7df5f844462f8b02ed4f19 ad721dc4fc3d4da2b63efea29c4a2752998d7443e032b8c02fcb8f7b3a2ff7c9 381ad78966b6cd4a60717a9d0b6f6c788751c9a29ff8fc6d69623731fef9d3e3 +84000 6a16e85fce703e920e8f01e7ab54f649f093802b86dc548810a0c3273ed83690 94bea3b61a033de536e86c022ec11ae80543f720f4e6ea4d960828aa0d5221aa af9469089fd421e25b77f538e18714155897c945751d8b4ef883cf16b3434161 +86000 197f27aa76b27f2649fa2468c4dfc3201f4512348c2517bf9c012da5c3a9bb34 efb0840e7a38a6acdfc7ddf6d4cda37dd344a4e779e76cc451d63c786067dd29 ad66edd4cde2214b62fe97a2ccb6d562109e9066ae4bdfe49d2fda7c6a987c29 +88000 8124f5daa65395bee2f49223af7e57f4a1987d87134b49c9701c9664021e5bdd ae87f04813d6cadcc1b6705ff0541b8b406bae222a5a206d690e04c4cca1b1c5 8f9a2cadfebc60fb4ba1c746c4c5f1e15b76583dfeeaffb7dd4d90ba537a8e4a +90000 e0dacef97a9aa9c27063f47f2239d213525ea69b0eaa39916e317373103b3bc8 8f68112d80f3a19eb69b12cdf13796f1cb5afd53d884f18380e2d125dba1c20e 53154d55dd544fb9e61bf14719bc5030fd45eb3a7df69d9cf41fffb64834b39a +92000 875704ae51328fa7d7f347e144ef1b902c939fa923fc38daf6d2e56a79ca7268 72a99bfc438f0f905b330923178215a22d0edf4c10cbe6b5ca143941abe9395b afa1fa894c0e526108e91fdcc6f37fac051ea71f8fd902b7e48b2774172c1608 +94000 92820543ce85bba638dfe73980ca9167193d203966bf0bec9c41c76b9631b81a 47ede733a1b8977f09eeab25dc4c18489c2228cf443717d1c8366b5815ab1ae2 f5717eca950d7f73057594a029c74863558804a57e38a312d5adb6795a3b5758 +96000 0354809c38588a881f194dd33cb1d1bb1cd3e65cd4009153b779747d973f64d8 98efcbd8de17164c3f22c34b9958742d0b691b68042c65d5da9b4c677d0316a4 f4edc053fff9902c7e56fd95a2f3ffbebc25b84e33670efff39ca127eddc0e18 +98000 e02e7ac3bb9bef6e0a4ae4be9bb5a4e68e6da6a37c95d93c89e91cd8a8380e95 9ecd0602c412a7e82ab7b8b263fb4d49f58a3120b19af2f7c5b34ba17ac27db8 0c90178e86b4a41277476fa830ce82e05b218e3c396646224e37f9750dc5e4fe +100000 236eb6c24599c6a6a2a3f2263086e1e67b2fe29a37bec19be89bf24b33f12cc9 34f600137ef0941ae9919bc55875a0619bb9d935105023a5a77769dfc88e3299 2a4290e827bb81a41210896d6b04e524787f711653994458dae5da4ea91d1d63 +102000 de82f8f234afeb3e5ca5aec900abe427de2374a2de80221d92dcce0d608cc496 72188f16da77cf55445b614e0dcc075135f6023a8d24b8465ce49761442946a9 87704a7b7473f70a248a1f3d3ee4b3fca5cf452cbc3cedfee5073f65f6abfe6f +104000 8382e1bbb997607459a1f68567372c63e1665b401240ddb75c567c6bdf66d72a ab868df9eafffbf033a76793b764fd340df1a833401c5563d750d2fe10beae7c d021f4feb4ab08b16e5fcc32b4dda84ac869e3dd0ab06324172d0f2a6fd3aae0 +106000 bd7bb7eaf3aa5a7897f069c1d5e74fcd4acccd92a6ca86ce6247509291938a45 48e7b2a3e4b9fbb5fe781e661d9f80cd8b538c163485e638dea585107608e17a 10c8c0a71017124af4e07469c1180df0bb180f8c7f8891b532650e7880a929d0 +108000 ac72260801eae2dbe3df786bbe32bf562bacf437d3fbcb40d5412c4a0c4388d9 9cfe87aa2189f585cf714db8201b824ef63c60f69277700a809b857e231cced3 1754ea08ae5cc1c6bfdab599af17c552780df1e81ffd9398553077382df72215 +110000 ab2da24656493015f2fd288994661e1cc657d90aa34c755514af044aaaf1569d 64c6fe33c4d174edd616575e6689d2e3db87e51eaf7a61f9e62bf975ac20910e f3b0c2e072ecd67076a90a413c7225843e18051edaebce18e73f131bcd28fbf7 +112000 d1a6ae4117d69ba3d2f10ec1f07ca2883cd5bd4fc4e3215ea4b03fab1b11b827 c45a6358e74abe90687209942b9f46c4b12ecbe0704049fe0243053db2b0dd7f 1befb828f539296feab89e72fcc6ca9f9c8b0fa34d23e2f7e16a897f51599d12 +114000 d483d25640b4b9fadf45a5213b45ef7c429364054be1507320667cbf10ea1ba8 ab7f09dcfc1b38b075b88609938d02d4472f103ab279b51f516c5420306dab6d e7722a0160ec1e96fd7909d5d48ee560e4f7d61fe8ce36add92a7491f8b690f5 +116000 5339f0d7d8bbda1ee9b646b1550114b765edc6721c7031cac814b071849e240a 65f19060cedf9713a4e39f065f665cc7c2dde6d723f77675ae740f54861fa2ac 6b0be546163887864bb1d4351e966fcc4076bc8f0c3619284f7c2042d8fd71e7 +118000 7a2acf967bd7163ffe18e446f537722ba3ac2fc4fb67f6fbdbd412c4370fe783 25c742c560b0d570500ea2b7510e7b8f4ac5835eb38fbf8b2918398b14bcdd07 98e81b203973a939e3ef8a324cab027acb81c07593382b6a7cbb6729055eaeae +120000 e1c452d91b60c81b5bd20e7f7fdc54f092ec594675c606d4e7eb0200e973ab03 7d814f302601e3a2e12de6043de986ce9f051d4e8358e6b53fbaee21cb1e73df 7cbd2f2f625d0cf9ead8e0bce3d5dcba36ae3c7e5a8d1c7517352870399aaf00 +122000 0e6de1d1923098b576c9a5dba8e85d83b4dbe67c57a187cf26c19952c7a6d9ca c1a17c19215229c64ae75b9b922a4ac3e89bfab90f91c103c570d6f489185762 2c4083f2ab722e647c50f29c8ce20dce5bb6ecec79d694d23f39641dc568f32f +124000 5666dc0061615096dcd6ecb7d041140a25f29d1aac6e69f22e57e0b0f2f55362 2ce0d2088edc27aa780165f71785b9e8450edff96e53e85db607ded6f51af88c 5923e0a0cc32f035f1fc58218a894d0c8d103e5e7ca30edef3ecabc55f8ff970 +126000 69f9e881578d4b41b28144f5adc1cbd7be41b647cfbbf7a6796113c7939bcfff f9e5103ea5ed6dce63ac37c4609caa848bc5ec2e9dae4955df7abb2671003766 4ad3f0a18091c72721a235986c85746637a5ac3a2cae8dc30f9b1420398e901b +128000 faf9e4c2b0f5b0e09e5250c3db245bce604c290052d3139b720bba73ea954f18 ecfd6ae92bb69faad5a2f95355a8719107e9aa9c961de39eab03308cde09b853 9fb290d509e77346beebeab116b7a15c559ccc45bf9de618f22ce059f412cf0f +130000 a26ac18f6a6ec82e9ba0cd1e943e9bea665f075d1a9c50bcbbfc9c08711cf14a ceeabddcf9dbade91b06fc66112db6d4dcc7ed68404256a85763d5779820df5a 13dc2fa1498be00fd04cb3954ecf4a5a42c25ad8add32e8f0b700991368f42a3 +132000 6e8f2c62ddcea238f6f1e308e36f82962aadfd272a72688c1bcdac980b8972c9 e26069439cdddf28c0ec14df72b548ca82e8196e90ed8c274003a52a7cd98b18 58e26f30cb9fb0f4ff3dec0cf2fc6440f746d76d2a85b85e04a8db613e573f58 +134000 5a130b5f5d33549c5caf2b430330dc3127907df7a42e414be0f465e6d4c7f77c 2a28cc7c03d2f02ebabf66f73f9278560f488cbfcbe0c50ea90dad6b5d399ccc 2c75f41edb77ebb24ea431f43bcd5f2625fe4cfdcf3d680ae3bc737061fc087c +136000 30defa41b1c5e61b338c9d9d0254323cfaf2439fd3695a57d2408e2b6cdfe7fb 252b93fae5637d05e4c8b93bc3e28e4ce7846724bec0741cba23c3ea2d10d062 381dbce1e79ff9e17c8f8a9aee73a1fbe28243832eb07878a628772a0dc76831 +138000 b3210c46ba0708afa630c598be049d04d29fa7b65eda096758ddefac75b64f34 e556dcea444997b8beff65846970942d146b11bcb2513c7a9be9c6bab6ac92e9 d51201b8c83ce904c27c9fde32cf850245b50cfbe1530843ecb5878759455ca4 +140000 f163fad48cf070cd4e48ffa14e64a0d23b09720606fd88dfa06e78a37f14123c 3f832a12d66750e640428d7c8cb6eabf321b125f4d77497754996202b3e26810 20a13872e2d82f3b58142d681833698969d7f3c28eaef1039537aa05afe393c5 +142000 de7c3ba23d59009a641dcf482c078b5fc2467ae60ab7ba7c4243021eac4aade6 08417d947b59f4c50e0a4f17888fa63711440f31c68fe23bf0a635b6511085ce a9a4f5073363f12bea131a0c0aedc238bed638cfb6646f6e4a06de299fd2e9c7 +144000 ec323246d54cc0f9f7b01b38a73f2d4dbb55ebfcd389a02a6493cc07693bdcc9 b1914db512fc306f91802ce14144d587e3f023a6a27d8fae5c9302b09aff76e1 debc5aa8beb879d7114b64355a666cf648a2e1e0eca7ca3fbe1cd1fa1a7ac6f5 +146000 910693cfecc2ea59e8e1201bc9f0b5a799f35cb369b9ec155309e82433047305 5e7df96c4adcbf24a9ff3c384329a2d4feb48c390b46313f885337114b4d041f f1f2d650275da7ce4210b2df39f8c5d186d1063af57db785a484ec4cc5ca91e0 +148000 b90650a3488990c7e07ff0c4fc6c91873f98b0b9d96d4a605758a08b95e7dd36 ad1e58090c14ee049b86bd7302ff7ba4b82eed263a71049d88447bde86987d58 e756a0935d3800307a92392fa915407025516bfb26bf30e9968ada4204011646 +150000 c652b775c9678167a1a0088c1e3624875d226dfa62a10128bf550dff904b4111 7e17dcc0a184f9a5c1e618ed10db9f4aebe1a4a14aa250c21bbd7b6224b5e6d1 1d0b1603577aa38c49114060c6f0bffe3fa4332649ca368c347e3c8708ca4f89 +152000 ba614c1c8a50be2570de8b62ecf559492bb590e21010c43d0cd3e19d72448fac e0157eba504193a2d21a127a47a24ddbc3a622b4840c2c9a1ff1ca18497b3080 2bad7f614bb2387844f6598519b85da6cda39283ac063bd2ffdf348389141235 +154000 a61c94da4864fb90f5f63c740a5ffca513322ad32ad502a703e5b2967d05a0ea e8590f16848ba7c07bfe5e9240be0c343448be0bd2fe9a43b44495abbbbba4e1 0000000000001971145ee16b655588b5c2bca56b50452f1d5fb4c09299bdda57 +156000 bd163e75c007dd7c0288a9b1033431a23f45591c50f89f6323514f3cde5f43b2 de4b9f71ffe40ffff47f2f8e77e211104e3d58202a1bf0dce35133ce17f87ea5 932b006336a4412d755d08cfe20148fec7272b8828229182f18d93ec0701921a +158000 28a602ced1579b0bb1ebc0bc9b49d2032083a8109643e106b3db329d88af9547 8aaab58a878c4c477b3cfe7f767b051a9dfeb108d9b13f261ac40e0c1b401b26 d86364726a4f80215e7c9ca2a8272d1f7ee3b527eabc8b4d7cc10fee54e38103 +160000 8c37cc35c34cba1e5e5d0d01214a3f918c717b20fe7f1a6facd11edec32d9399 59d06b76329da811e5dc78e1e5b1f59da8373830e1bcb94077439b223e1e00c9 9169592e79614f612e86cad2333b45a8e88cfd591b545f5c6e7ebee373e7be0b +162000 00000000000000cdfa5fa07e2a2fd340384a746912ba7c44c0b464a691887aa2 6bb179806455179857a083adce7a3066f6370b9a9727b8ac8b5ea43c04e15b69 05d015f55e076427136e34a7ac76bbfa556e94e2f45f01cf0e2aee6a02a2c320 +164000 ba66d32aa87a94727897920a6f5b8c8359375c11c402155b40b4b16c9f5872d5 df41b575a55589f325850c08dfaca2bc2ccdbe717262a288456685b83a2c7e8c 0a490ebe91faa03f61d8557d04eabfb3827416685a6e1ddc095538e81dcb871a +166000 649d1aef123332703091f08750f6b7a7e48c57a8dd683f1acbed0c203a860b2b de6318aa00dea081cb9b8b48870d43470862e956b79bda7b6a93f60784208d32 e77dd130e47938c93690dcf0ccb48c3e2fc4768f1c212c39c1ee073d9efe8d18 +168000 000000000000033552ab9c118bd89adc1aeb8dcdc42a154b8464f1d735599fd9 8b15f7b8b55af75328b525754c7418f9556994674d35ef8812f3d241ae642158 6880b4cc82c3f95db765763d5524c8496918d4560121b593d4bba0c7a3ec56b0 +170000 452681d5e152199a0dbf66a06c51728006e7a50d8fe5e2c7784431ecbeb4116d a52ff929a0db0d3ff0929dc233d738f8f510470ac18e01fa6051cc7080074c1c 833a3ffe81656662c93b4e2ba592b8ad7b51f03f189f4bb9fcafd623ec37eb51 +172000 0000000000002c3c7256ead9b6bd69f8abd6b7c8fee1e8c42fe7a2cc108c996a ae6410b554288e13feeb6e30894b19a5cc4d53776644246ed25bea49f319b1c0 c5ca442d5b185ec24fd3b5e047239b579d40ceba3bd6e3f6205793c90e9de783 +174000 e58f5ddd7266dde8b9ecdf40c2ae8969c29385ebb6421aa49ab5418459c3609e 52a779749c27cabd74c9f4dc8ef8f82b502c1d44860a4e22037ad2f88400b944 4e822eb65f4140d8d9695e0489b8af067808b27b71aceb74fc88542c1703689f +176000 715fd12180169f2eaf1981738e94ea83a5e03dbcf2c1ee738d0699cfb940005c 09d06b4afd0175c58f650be234627ebb56808a6d3a02375436b1fb7709a6bfed fe5b8c8019fdf207ce0da27a8299723c6de4a9c166ec2eaab329c97b5ae9e78d +178000 c378a56244af50953236534b8d0817efc1bacb33d0b12363136170b75dce5ec5 fb6c0a79ae351cafb31a88ced34f9e522d559c7151968b161a3d0b3ed101aa95 275b85f6a6c94bee17bdc2a3073e571c33eb5582194be6c830d0664f44e36665 +180000 3d09b17250589d4cad15b2b79765257ec7899ae448b1f31dd334613524b16b7b a733f6160142dc71e3d43f77c265adf6dae5007cc7f86d78c67c35316ace17ba f6ea689222ccb1397ba3f9d39ea17690d4d2646fe296a99b4850dd0af52ade12 +182000 7087f9850dbac3ade045c3c21c81bdd3638d8672a22c3de9d17bea16998bf12e 5c64997cbd59ce376a0e3a207cc9d0e8101bf767b692bb59054c8ae89ccc3bbb 8e8124d76cc3d64eee7552edf9ac53cd64e4899bc201d8b22c660dfb5cef4cbe +184000 0755c36d70fbad0e86cbec039e19d715b21343c4318400dad7ea54217a959454 113b380a74dd3aea7a11f13c9e658e29f5d037f4ced80d7f0e80326c4e1929fe 69e170c8e00f780d70eaddb6ef5a06e6eb78c61ccbd60d9efffbd320b6b9c415 +186000 87a8c797423f07249c80dfc8484e17499782484701dc4b27f2156b7a64cae985 3911ab89a07ba73d4dfcc16b8c381ec933d2274d39bd2dd1def12d27033002b9 000000000000005e077b301e8cbe6671f302174fdde1f087bc552f40075ef3b5 +188000 d114fae52cc28a10727cf866c146fd7c521c62f5bd44e925491ad42400009c76 45114aaaec660f5ec75cf4d373a6a2e080d17637a86919d6b3bbd2745261ba56 6e452f859a3961e5d1038c1eec002b4803dc828d02144538f11f07a387ddddce +190000 9b89cd8f0315b39986cb65578cd8a9bb3d3b50e8e8e13cc4f30235ce7caa646e 3a812bbff58ec8471b1097f4f0c5ab73dba9b50e527ecd87bf00811e772d21b4 d395de0c248f4d78078e79d390ae7ab3175d1a303a7acd0c34b563f18b0404ef +192000 02fb618e4acbed625ae671e12bf87d0c1c4bfbda1f41770b3e2175ab039fdae7 7814f33a1e23bf7923a7497bd1ea8c7b3b972698cf7a446df74d53059c402925 49ad1905b8adb5c0ccd83a25e46149257987d94abbf90f34bbd4cf261e2903c8 +194000 5fcfd4b6e926b5f22fef06c96859228c50b6998f44a93237d6b3c3ac588b2e0d eaae45722d794abb2d7da56c144cfb96100aa3cf792cd44c7dfaedb659e2d72d a91768d278dbbab7a498ec28e39da9f0355641348bb03414f95f5473f54e90c4 +196000 df486fc3a0aa764abcb4d7478d307b3ddb75cd7e91c7978e15d32df639cc27b9 3098e68f9abd002543750b39cd3e4644c928195158d39c02cbcbfd4cd8689eee 2a1848a77ffe3b3fbd9f1ba99a5883277cb929de51373fb2553afbcc34537d1c +198000 77664ac405b48118827819a1ca5d7bdacf168fb493f8b00f289b64be786fcd64 f5fc9d842016ecda6898b5b388f97276eb5b5cb4526738e0d9f61c8771707c97 ac4528c9aca25a07739bc46c0c55efefb1e38eb973d357d3916b2815f63c0e63 +200000 0000000000000e8acbba6f1d21394c5df111dd836a17b750f29150f72be02802 e667c16021f6eeedc1a437e09e844753757e93b6f8387f9357cffbd639eaf0f8 00000000000005dec06f771460cb243a480448a93cee74932f8cfc94a9761aaa +202000 cb9f1a413770c68d5305e5f169883a9d4d46b270f724dd0ef7598c88e63cb826 86e5537f66bfae4978ceb44e89d791b10ce11c8bd3a2f59e05539daafa9763e3 078c6fad80a92264729a1d44e5feeb30d8a4e12eee9ece4538ca0fe78ffbf151 +204000 1fa8581a00df7e584827133e896389385610cbf0cb55b8381d0ea747402deaaa dac809a8ebe08bfe008c7f931b3410bf8e6b180b4713e069fb8d7ff69557f0b8 04eae2a74408450c13787c3dd834d772aebbc47ba40ed9def4c202f3abc88488 +206000 0000000000003e1da6ea51728ce8f660884dbd0426753718b73cd8e82495a396 8ab0b6724999e3627da1fbf09a46d55aaa646d144e58bf88f0c25152a8cfc88d 0000000000001b9cdc7d2ca46e138643cd9977f58e237c94214a3b9972260012 +208000 000000000000034f55ff6b6cdf9cc702839f46ee317a5ee830b826784ba03dc0 364d5878e72372031ac0007db1e9b1f011f7ff18a4ae40f7757da4f7d6b6cd74 93e650365867598dc8d3e9c99f3f655c595e6af5bc59f6ea5c0567e27addfa5b +210000 cb0d87ef967cdde1da1b59bdca4e3701f0181652a7953d6c115ba820e58979e9 c7d59fe3ddb2fcbf7be555154f7a5cc362f825f233f5eca03e076ab5b5999b55 f6f727a9fcfe7525d94bfdc202146713e30a48a446e0bd6f7ec79c4511c3e752 +212000 06f7f3bc31bcdbda88e9427d70daf8b9408efb6ce4cd0131ec76ad601b397311 ea24d4123df3849dfa8d3b936001fa85c6caa2c8f232f75cf68ad0447c3d2568 5b796d868bc261335260f8dca7245f0e94144902120f36d3feb7686a323054ac +214000 1a1f1ab990cd9212cbe66893a43777f8700836374124076a9b9a7dcfd2bef0bf e952695129bffa225e9ae339aba8e1a4c1e7d982a25d02d9e3e0298ced126fc5 db4137f616b8733e1f5e3d38a0a46d6a94994214de69ac96f4d35ee17008ccee +216000 a56536e4d0947d7f5e14b7f397356c4902998702f1b3757405e4a1df4a0c757a ce6ea34e9e82b16092164f18e4fcf332c047a3c433d1e08cc3c5481dc192e9c8 64bb5c0411b59e0cc166270fadd0c5107a73d4ada465aa8560dbc9f39f9184a8 +218000 8c024c9dd7660417e5453e40de80ad2de67cf91e1f0a44d6b6094ec4049ac0b7 136ad4ce879846db6cda6793d2c6d96e4cf0af0f46add08ab9d3204bb423db5a 698adca2ccb20f301dcf466cc47b56abea2c2cf7a15f65631840c8c3da473145 +220000 65635285d462f28e752dab958aa48ae7f5d9c7d2390fb8c26786bdb0d5968a76 a777d857158be75b02632ea925439117c05f1d05dc6a9b656092a0b92ca2dd03 eb99b7756f86d95d22f125e2f1c7be7911e51e72f5bcf3cd4cc1dff10e0438ee +222000 9647eb2a4eccdd5e1760a5649b433d365c060dd26c8abc01437d7de36436ea89 912ff557290ed2256d8418b0265ce16237faabd86a1131c97d5421b2ec353b44 5a125a883ffdb5298ed509efc71d3778cba9447ad24bd61ae423cff690e7f5d4 +224000 ba971813ee6891793f3daa66c301c921092021419c95f948f99406c67eda8d17 a53c7691a7d664683e0cc25c07cd3f5a1aca7c0cbf146193792a152e625eb3fa 017e2944a9536ef488025299f83e2036c5d005d256d10b3bd850a6a1ebd2ea45 +226000 00000000000021a44f6c936b95f260b57584bb4bc2c96e3f56f5a1456afa3857 bf2d20f4c896bfa5f60ff50f596f3986717fee41ccd51341c39ef93ea12329f9 ded2c6bd6cf29bf382616fd2af24863bcad9c84020ac811c7c1ac2867a224a75 +228000 3b2307c6a33804fd760ea70bdbb5d8d98cc1a4d290ca66464476244965359611 1ee341750ebcc93c3577e83bb53e9eedfd9adadacb7fcef9d75cc35c9f25e0ce 0064a261ea6e4017f724402d0829e403d21694c95a8c06f00d1e54c7bdeb3201 +230000 00000000000031472421e32f8b861d4392bdc9445e9e7e9a3ecee1dcb4d35502 334411544d7d83cd7849807811b349fe159e4e7838bd32ccf9a7b11a7371595f 00000000000035887944819799cb5a1759ccce95519c0ec505d1457aae0fdd89 +232000 f2c075a680bb40345180137cd34980641e4803815a45e5bc097c485aceeb7276 8a3d755d1e0aaaedeb655dba727fe471b73b28ec5a20577df9cf0bd6ca8d8eef 6857338a102ae8a6435c5a00dd1294e7be061489384208b7489b76c44b9ff1ed +234000 4d0b85dce3ecd9d36773201852a9a32994fe341bbef75af062881b1f920bfe12 fcb92b65238277ecf359022feaf041af90f9a3d57a7873190ccbc633705ed90a 74d40e99aec7d23779efa52b22baaf38de6b2b4ddd58c1a4e5b154f9bb572a72 +236000 0000000000000648251374a1a8ab8d9d1467247dc66ca69df0fde665a4a6863d 106b9083ebc5c7873cb0b77f615947779ab19732725a4d016d0a5f68e69d4844 ec750ef71a5e78c495424629be7c9f288c09f3566e61e82add14317f493babb1 +238000 ba9b59099d7211a503736f7088f7c8e99f7fdeb3170c63cfc732fe5ff39212c7 0ab728623b31d78f0d1258f54cfb8272f3e73b5309f257d6553cb170413ecb4a 08b093b85ed4533969b3c41b214cdd9f6e10cc1d7c5adc668ad253a8b0f0ec0d +240000 df9319294fba5a9be548ee4ba0f0554900b22961fc75894fa073ecc254c78924 72e6babe2cd40cbf8b5bde508bdfc2a346075d820267b900ecf00b5bf2446d1e 00000000000001464ad1eb044bc4c9ef2838ef14faf835b156d039694e2e8d1c +242000 e0174f0bc1409d0945760fbf9ba576eee957dd1e30e98cc569ac833a1c6c3290 a3cc78ddb53432755fd19e9e305fe72ce53b0a7fbe75ece480213a93a6b85579 a34a6f93f4fa962d25d76d5365cc3618b49dc6e75b0a6a9dea97da96082d4b7b +244000 68d95cdfda0b7753be98571a4859c250c0d9afb49753eb7f5c53e91f6f3442f3 e26c41b024353dfffb18a941c4c2288ba69880dd7fa61c2f5121b929caad2e6e db15c61cdb5fe0f9430def1664caf584dbffd65c29e78cb05701773fb7d65d69 +246000 c476c8e6cbcdb28eaad7550f222a3393d96664d95c4df8ddb99646c0fd3193d1 a42725a04b1a399267b03cdeb5c3e92a547512a2f778b0d6d74f9c4ebde642ea 455c0bda89fd12a006a8e365f756c2a9a1587eacc758911a36b4f4612810c1a7 +248000 4aebf4e89ccbfbd27082f5106e458838d2dbfdc5e273db916f1187f1c6bc746f 259fa025270ebcc98d5b4eee572ef75d647c22945025b9b0e3498e815585616c b2ed7cfbf5841bbd6f88748ad3df4c1f8daf2e024aff6e4ae3531ba7577f1e46 +250000 301cb89611709f47bddf383aeac2d3fb03d1ab187f695e6b56bd62d1681c3330 93c9db335a385f1f989af80f22a8b32c88430012bcabf7390b59350c59982481 4c4aca67f5d71113a160b884324635707352aad3e2c17a6dad0b4f75bf4f3909 +252000 0000000000002e743dee48f4a878ce3e7bfb424693fe5254df8b0c5f8993eefc 9fa9a5af4c6a0317f8ca89a8d729751b0ef588a8dd6dabe767fba7515c078cf9 289d2687b96ecf778fbcfcb0888bced3bc2cd3f0d43b6dc00d6cf633db620978 +254000 e8d3e713b1cb069ff1ca8c322b378f4fb8eaadc8210ddd7820e4e6063d07e239 297488b42c3bb44675cfeb685e932fe436023581f2690766cca7c78355b6d38a a2d2a38faa8d8d9df19430b64f08c4db6d5ea5901cab75e9167df3e2959b55ea +256000 880a59c34f1a5885e49d56148079483398884a3a8fd08885e58fb1e267c20a44 61bdfc7126eb6a339ed2bb976b906ef79aa229332e4a2fa1dda2052353f0ed51 0d9ab969beb855e38f4ebf6de58d4c9f49aab2a5e832e31763c60053995a3340 +258000 c3fd73e480f300ae4544d5c4ea2ba9c55f618a8211c2b9475083c3bbc20b4535 05b5acfafacdef5aede3815b6a15d732e55605f38c2cc722540f7e27284b3dbc 1f5e0b82676096ec1c6e71c3c6e810415193e10ddb534ba349f434616e168f30 +260000 85b23e3e30f689da8fdb4b4ef3d668b8fef7eaa7b26635766a6bc076f4ac5ab9 7d7bc179bb3086ee1b32642d4b94298a5b376233a86ff3e8d7a198697aea166f 94f014292ef91683e8913a4331b90cdbb9ac6e3162f231d504b3a28b2a5333d4 +262000 8d011ba4d91d79006bf7a2f45d243b8f3cdc643bed0fb70edd4ad5fe5d876115 c00ec197bcf3f1275ecfbc7e4daf7b7bc7ceff8bc1d91b763b330ba3cba04594 0000000000001208e76a9e7f0d3f67a2a08d5485e34ab4c1da910fc73b65cf28 +264000 b9698d9a8024ee028c5e6c9aba3d8331f535a14e6dd8dcfc71d35228a9bef238 c78f9e87f9803ca2cb08b59c49050b7c65819d84a42b87fd557356f7593566d6 eeb6ce9dcd5a7c45f7a54e704c4846bdd1bfe4d7221b5645395dfb2be69735e0 +266000 0000000000001174772f67efe452ded5f57cc890690560868954f90f6db0baee b0914cfbec007250dd87bb4d10fbcd4c75e1c132beb78f34910175ce11c21a65 0000000000000b830aad3e924e5f18d4b0d3b93f9f8613ebbf685b330f99410f +268000 000000000000035168bffc13abbb4af858ae94e52e9c75bbcea32b1c940879d8 6222ed49d4788cd49fae926487b2db060e456b6ad1bcdeaaba460055a7ed831e fa305729326fb45f6554a718149348ec881a16118ed5a3f80a3cb125cbfe0d15 +270000 bf32a64daafe4c433d7bb463d630c06ea0028c28ad5caf4c7fc841d2740358de 5eeda05d8ec7c7046cc3bbe0002378f7379584197883d43bf6a5d7c5d0a2ccae 30c1fc8f51f5ffd29171075771ffce770bd5a4f85e37fa427732c029e873fcab +272000 95a18d7253b8ebba9df87433d075e71ad5e1c043bef59c95ecd70c21f0b86703 24b431c31ac860df6fab315f6035e57b4db0ee206ac10fc182529019d9841fc8 7477c2f6d2be54102aa096c2f92a1074f537f1fd4ea1391f6a91428cdfc32e26 +274000 7cd46f49c7dd85d1c50d84d70818803ef281eda9ebd6cb366d6018e853b4552a 14332d6fe38db0113546cfda248a8c3c516b7c6cfffa41b9e184d0ad7656b23d 2b8c130ad517b1eca91e576a5bb00b5f93bab7e8bf87c54510db02946e62e077 +276000 0000000000000596139144e67c7f1d52ed1fd909e51120e5608295b16a779688 fd183e1a2b6379fe31c91d6094a88970787a2926a88949ef00813ee9a40b0416 47d5032640cd21ee5f1d19fd2f5682b2dbc5bd54c368709d729630af60229fad +278000 0000000000000165f8c4e0ad8cf43981d1b9f91f386aa18a51d9e43d54650420 0b96b4ea214bc87ab98ac4c2aa97da826caea2f93d35145c39306ab506a79090 a8a640fa5f77366f89315b2669dad278182264de7cb125f27457de1f9261982c +280000 3f041aef233b37b68d3e3661093b6bbaad4ff75d65383983de92ef85ba5c969d 2ee1ee31b3d9a3399e8f561d842703efd37935fe8c259f39ebcf58bf30c0d040 dad6fc9acaea0725300e6aa0083274178bf28e12a508f675fbf6a44b88b49ec7 +282000 8076477df794bd8ee71e8dff12c9c783c82d35b669d89f67630c60a56227b03b 5528b0bbf8c242e2ad0d886bee4f7fc7290a09c4c2698473b79b0d2d08214d7f 3aef73390b2e35390d3ad863624dae351a0a1bee399d7b4f4d135972ed10aec6 +284000 000000000000082b335f957681951a575c536f9945b44daffa95b01c70a87ed8 a26c454f6e9f975064e748a20e27c2bc5f822de4e21c57575f63045a08f2cc7d 91e4f57e0d79d582f0c98cf468c4c7f7f084006b695a91f32b26c3db32b8c40e +286000 000000000000050039b46e0e048e8bc48d2321b821abc357cbf317f9d78e542a 9be3697c1ac19927e0eb6d8f42503d7fa500baf0773d0b84c2170eeab10278fd 00000000000018c214183f6305d00d76c9e235861a30166f5047027f0e193d87 +288000 eac3bcd6f174b9b47c7763ca7d6376489141b879578e940746c0f698b169ff45 95a779fc1024e94235473eae262437da498beebb0a5b28dc684ea306f57351a6 ac01d1e3aee86995be5ad414dc34d3e259cc98954803ac34915a18e6460df8bb +290000 869635e5644288b9a1e5cb653717ff3b1298958ab96c565de32ae9244f4fa76c 68a8f802c99d4237a6fb79ca7bf767a8a9bfb1ad7489bc4df03c97205f2b06e6 fb08280e77f99573fa1cf6015bbe7a57db08d2f0fe2804e75c847e28b01cefe5 +292000 366f4156c8de9c5f8fea069ddeac25126bfd2431be9c3d214c55c9990adaa07f 3ef1da71359ede663e46d83d1574b3f04c7a5e8a901d1b46e225d9fe6ce3bd8c 3897c2d30595cbf05f43dd60bcdf65fe76ffcec96ba4087c995ba14b7bd334fe +294000 274477b9a4c7b3415ef4d0f5d69316fdb2bf9a8777778b15f4651f5c8504ff0d a65c863fb94bd57cfddee49a7bd883db4ebee623a9c167326d0ab3428d8a8392 8ee7834eb683ff69c9260bba82e2cff77e5af55fdd13942ae5963125c3872ea4 +296000 b20d089db05040cb9089b5dd5df7ab2ea115414357c59698616434c4f1fdde70 03134f54c594dc9713b4c20ab7117ef2c5be999c103b6da766a5a2985e20c393 481cb3db50e343a0c8c89d4e86dba1db1122c9a02c1d877ddb5905d2b0897a20 +298000 e304fa6da0dd21ee2013ed81a81e1179bbfd03d60819d39f12d2f85ffdb7714c eeb3abad4ef155921f28848635e62f3bd62a0352bd9076228565f85ddca35503 6bf1852513735420259bfeb68c432806afc82c7984786928cfe0ec7bdc0f8a94 +300000 701771ab8095e412122d1b7d49c60b0ef871751bc26a7d2a9a68d59dcff5edef 93b54036fc92292c43ca6482ab5b8e4843bf05d20309f5a672f887eca73c30aa 3b39cad7bc993c76dc13b4cd440700b96aee63fda026b721371979c4fa33bc99 +302000 fb6d14ac5e0208f00d941db1fcbfe050f093cfd0c05ed151c809e4428bc14286 d9bdfa59f53110513eed5f0f52b5076178fcf7e19be091d3792f5002b268bb23 3f119b9377a4c0a8e80b25dcae5ab64a251f0293f6aebd2665b373fe8c4ea914 +304000 774437bb937db791ee6a979db95cc734f04f3fbf4bb55752c463ba8fdc14fc4e 3645e04d20867f36c9784cd64f25ab431500687cafde3e906dc11478db3fb785 71df6c71fe8e1260c5f491cd854a8eb1466a29c2159f2a21511e2e3590d440e8 +306000 519b5ab74ac9d49f2f79a0af0025d02af86c2e3657c7f30425e13c7d3c2a9956 536d8ccc48c1d4bc1ffabc579acd266efe2f746907c483f7d6ba378594e7fab7 8d11f896eaaa71e5fd2ea43fc90a5a58c6d75119615cb362ef055e4c894f6fba +308000 f0208d77f465ba4baf6b66570493b41357d19979ce28c9c35b68b652c3becc80 40c9d16a0ff7f8cac3d6d51326afe8cec5d6aad0ad9a0735666cc4ae39ccf38f f1b59fea0153e043e0f40292e9103390e94e4b3cc36701d67086376438edd6f8 +310000 cb3f9d03453e714dc4ba2b1f8e843e862434d099ab6fead781658883c8ceed5e d049c7c8eb096438907b09c7681eef4a38777069afba359503296d12dbfce701 aa9ae6967e8142eab0a92b3b9836923b1f47e4920d1e393e921e2d2ad0615a21 +312000 a5b397631308481e4386208990f1ba5a3e060703cf1747ad75d6f6aa5ebcfb99 8db22c621ba0e562dd84c0c4afed59a376e33eb32f11549638fac4f33b4dcae8 20dfd289db77a5f04556fe3b407e46a074f53b8af52a695cb95b602449bdb83a +314000 5a00dc074b2b3e66f1df11d42c06fb4c68172b40499ecfd7c06c9c0b66332cb7 ed99575d01cfcaffa4c45db5154c316a3de3e295cbaf58fd0064720b66dedd6a f99c3a73dcfd7ce159503fc44ab469e5f6c4d546bd3bb54b88d22b0871c43601 +316000 f5548dfb720195756c4f5456e253afa2b6ddd1caf83119c5011bde7e0bfa4e4b e1bdc93616201d1b3602314a2417322c1ca21196727bc91b7899101647f0bca6 d19f5f5bb49e5d589e85ee1534e7de12a40a0041e83d05fdf349db62dd25fcfb +318000 e8ad857543d4698dccf183eaf563557b665b06a15132f73c44d9b37b3ebb7f84 7817bde05cd8a238c1dd2388e8493c564d9c3648cd37ad1d96ab590914df4176 c2ea7dda7ef51bb317c2aaf1855581abce3962cb4fec1ecd54450b8a06d18554 +320000 b8748ee68cf379ff7470ad78d1fb1edb7b9c9cc5dc4dd3faeb08bc1cc450f50b 25549a804eff33b9992c68bf55dfbafc7f6724751d4873ec7e40f1d0cb814aa5 997cc802b3877a64cd61aee3f64af7586b96c1f78134ab5f23080df877c5990d +322000 da895bf25c762ec0fd4488b3b1adaf6676203fe329320f3fd80a75279883b1cb e8549faf4325b89a265bf8865a8079b0787961fc5b021687714f1d1eec2475b4 ec757b1fcf826f302de955ed078835d961bbe3ec631c52c39fc2a55dba644fe9 +324000 9c97d35a31be228dad9dad31b863d8685fb99c61e44e18a409d60e380856b763 cf901f056b8fcbe2633bcf212faab85ad37e4861c8c6fd6cc5b8387d57bae8e7 a61d9adcb9f34b1c0d329ac91092577141d7a28ed9ba3a707fe25f87dfa8900a +326000 0000000000001d70f04bb8740c27fb53d505fa92bec4130dff2cea8a96dc6d49 01dcaa0084e532fcb68cf090347cf9443f2b0a83e3d099df60a31bbff96b90e5 2adb3ffd0e28138c475d88aeedd1176a4436bbe41a274ca3d260695e83f31f23 +328000 00000000000002667786d9904617913f9261f693d97c75465dd05dc26f1d630a f6399a89da9de489ea4dbbee2fd1052cdae5acfc89bd5459697113ed7b4e40d2 8aa6becadf6d5c6bbbee5c410ca45a376bdbe44eff1ea9caed28c4dfe6d7d084 +330000 4dfb851a19a90af6ed392f54f3c84b842dbddfabbbdee8f9f5f8997623b03594 89b46b3e1d1b9da801840c05efdf17b144c9ed4247acce59890bb25ad1102a2e d29752f815c0caae74923ff745df494461ac3e307de8b31988c508b739d4ea9a +332000 20d7166928cc878888b61680d02c07b46fe77e65d6dfde5db7b40c7df2e32c64 64e53c94dc485dc45cf6d37a527ec1814c2b713d3f802c2e68e023d2f1207552 dce405cbe1bfc281fac0622d31f3a7b956e087a0bdba9c36064d6b2e270fa3a8 +334000 000000000000017b559794cdecf6eb1f8a7c65c0592309f01a6e1ed8faf436dc 41162099ca63e85f0a255850f8f15c4176b2e7467e0d8aa1112a2c547b1b590a 0000000000000244476c86ac49ae4194eefa0064cd0d66ccd732da52363455aa +336000 8eef489706a60261be627161ca233f9df77da83fd5ad7d26914377d8443c5dfc 64709681abd6e5a8935b12666820e9fbe96f64f4e4e82b9b033b2a2b4a55a4b2 ecb9447306f71160a594c723c898fa51ee965e25d389a1b4a9816c172ae00e1e +338000 0000000000000025b373f943ee08fd58dc8e1f972aadd03066bdd078903606e2 98da2802a386247cef8ef641b5a594a891787b6b865bc20f88e73e10eef817dd 0000000000002524e81186523dba51ad32241d75d3d33ee15321670fc8ada501 +340000 007ce97997cda6be9fe22a9573e09efd0bda1dc8983134b2ff329a1239099d0b 0f4e9884e7f27effec9bd6560f1790d8095a755936d7436227aa6eba436a8e31 abd56af3cad44b766dcbb824c4e2f3b0321de953efb59ca952e0a33b28432b1b +342000 1417ef613841bc010f41e2240dca4e8cdd0959ce0ee17b2b42ce747f411ef28d eb1ec0ab83b4e026afb3b3b84eed62244cff62c385c98d385ba07d1194a1d025 902dd84eeba614bf338fe06a76c9e84b1d25cf13c34cb6026adefa34ba6f3894 +344000 3000f0d35cd1bae75a427a690f9bf46b08c7023c787e4d7af430a7b4fdd619a3 1e3e6bea0a878e2339277aea02dd6e1e38a8eb6dc1473761fee0c82ca7165f3f 805cd83205da601ccaee15cc646563a967840ce6631b4943dce208fc24ad8c76 +346000 7f95df0943f148f51c3ac4e7a951893016bfe9979777fd9e22139d62e7e3d64c 3dd64fe5cd8581bb1736ed73fe83d9ec0af0e747a4b108aabfa64d202da29837 42a1d3a819dfd4e18d8c28e11b9240f1f2d18a8391d5cfa9a5cd11160c3fc58d +348000 dbc456df3caa5b640d720503ad00b1453e1425470b98f21dd38c8acbab6e3d88 93218af80d691c6bdca2251d5cea810c7d5537e7b77b1d6f22c8361cc6f0c99d 9ac30b7e96101028d521019d9b1c29f4a1caca60654e20a914e4d5f99b87f040 +350000 23ffa9e21a1f8275f13976ae33463cc375a2ad1a9c0d5581bccc76d018f29c74 eec4ba46ac5328fed1e8ccc7bf23c0c18115e4c107cc56ae80364c5e53467821 41add7c15e8fdb57dd997f66dea2dae1b36447285f0c05acebe2b3cc553e80a0 +352000 7a54abeff477d741bebc21eff13a2264cbeb95ca0c6ecd632d1de0ff0640f057 9be6bc71a0bca6d5998f547157dde267f96080ca467bfc4e16702b9d5f4299d5 5e5fb272e60ff6ad115451fd8dd5abe7ee3706c24907769891e84cf008ddc818 +354000 0000000000000ee7cf02338ab03b0a769aa38313f004865b97e1257543651a71 47d02c69ce50c7f9bc051ef1328a934f24f07777cf5de1402ec9b49998c55cbc 6f91c36ef6c4903cd29fbbf398fd5591e569fbc3a93ee51c5bbb1e8cca8486f1 +356000 f3afb7c1afbbc8aab47d5d5be28fea25332897dd478a07ec9b4e0039b79468ff f1c5ee117d1d018ead7048587da1de392617759d726e4ed375dfe4a53491d418 f37379312044d9a425e9090963ac26806c7eacd7961dde1128d016da2b2da663 +358000 f5ba5ff10307b1ece172fd642e496e8f371d7d23d2fff2eeaeb436859369d1d2 8a51fb0d1e7c5773f19aa03338b09bdf3f74214f2c9df818d2788ca01a3177ad e01b4648e3de8b3cd7b6a49e977bb7024201ba2093b529c849ed968d26d3cf7b +360000 8fee7e3f6c38dccd3047a3e4667c63406f835c2890024030a2ab2dc6dba7c912 9c7f9c243fa6475fc668e393896583c463e1b8f2030d41b7c48c7c4d6b608ece 2eefb13881581c83729a812ed1c2aa0c59c852400d20678bba602f2b7f478b4f +362000 0000000000001893f78eada9a373e645c7ff2cd524a3d325b9321744d0018796 84bd1981bcd986a6db8dd8dac26bbd3f16893ca9335c5c8ffe457343b794458a 0000000000001abaf7e7c06fd99b8ce21e1878776d99f05a06d4935a9cb1e735 +364000 859c9552c0390b014191eaa180ff7925b1ad3049316e3cb9a9340fa1806a2fe1 1eda6d80e819f2f1eaaf6f287a79e401c7f850c83d8a1d816429e702ccd901da 961cec480a68cd02109d8acd64130c699925861dbf4180b7e5f750de05e8bccd +366000 ac3c35ae3b06f89f9992d2ab7d306c08c06a871a46e2aa050e4d6726847ff34d fd11c7b9d13831be6e5d88cc4c22531257be8e44933a5b3ba1231ddf427af717 7490a7b721dab156ed3e0e49e17e8dbafb876fa410a8aba48ebc3021c4b27daa +368000 ab549e5e21050819e2ca74ad053e48df67f207a119dcb268e230c8cfd4b0936e 782393537f4fe7774a3b344e8cca10daf6cfc030047cf1ee2af0e95f3a687ce6 85adbaeaabd84fa11bf1e1185a41231536a52e8e25480c9f637a64cf2b194120 +370000 b1010566a8af27737c64ec685053dd508f840ac64349e03b725d3c485135881a 6b99d6ec44889206720e1eb91ca10fc9c65e929e80af51b9598bc305ad9bb137 97d5c46e30b3cc139a11098d9853ca2830aee913fcf50ad6dd757ad0667742d2 +372000 3dfc7265b01ead0006eb7afe86aac1e9c65191ec3788c4e6b071b19a0e296dbc 86b42277f155c3d60f9cd2a9ab6ff7254dcff735c86fe2d443ba77df9d717305 dd9fdbef614f9da73df165496a08dd4f8a2cc06d0f7f79015a156c3de0d29c74 +374000 4d8b6fbddfa3962f5e6a235a75a29a2ff9daca55c0e6754db69abade2d703ae8 176404f8aef06155ff3cb292f6ef3aba6bf2106ba80e35dce15b71344369cf1e 36ffbd94241c98788a48653f9e8c125719b85ffcdfffbbc2d71fd68b293bab25 +376000 d885851b508d3b8c51b1b9d5a138960e3424eead14ca7732d153d8518dd16d85 a4777d4aedc7b1f806958855ea0030cb2164b6152e943f4f1ce7dab8cd50fa22 efeece82a34ce0ab5e1f3b76d1364ca3c112df106367fb53368973cb0992ce98 +378000 b790f396acd16079f00d5dd0fe8bca6b432bab2712c51fe0a38c7e28d6b936dd e2f5d569c004e8da2dc216be1a274422d6e04941c7d1756e089cb8faa795176f e076d8336a6a1a94bfbd5a0c4d8ad99f5ef674d0e90d1494f24019da3885ced2 +380000 979ca975406faeccbfb663bdc949edb34e203aaa72a3e5f116e53621a754779c 94e7a0b343834fafd0c4c5a7af62a279686dd01a4da28a689d0e407fd93b03f5 b8e5a88f902ce12e0aafc9af9b023c231aba43d6d788632f67d719187d05941f +382000 0000000000001a899fc502ac666509a44456ed7b992fbf1c4033afa3b7a852df c2897634c32baa1702391065d99f1f99d3b6fd92c54aaa815d8e67578644814f f71ca138e76adf22c64620526f9e20ed810dafe00ffc360e73664824ae76aabd +384000 0000000000000705b6b53f92625170e87d22a45df88797837ff1212ea8682f72 0a937a79cf0c88019d097d26824673270a82d6a80c8564dd9c0d491661f22625 000000000000038dee22b155f59ac7642feacd331298576dbc8a7504bd7db6ef +386000 f6cfffbdc1a842816b540864167076213db9b6a84a94eedd2049689ab1a40243 a4da7215958e334d703d446dbb5a83b28d549f10fa2a8da485d9f5cd2feadbd8 d90fcc40ec1d4a6e08df243f1acc0fd7eb2ea13c52d92766186dce70b0723f6c +388000 71302131904b401c1377973242762c577fb77055872b77a7fda8b660f56f2055 aa74d7e53cfd86053fc277c71ad536797adac6bb8840c1dd8267d6df1bedce00 d8610e1db92f2c90f80f629c65c82ddc333deb5ef648c5a557f87dca19b38c79 +390000 00000000000008d0ced814e057b2dbe4a176535939f33fd6d423fc7b6f3e4f9e e2a9a7c9973f8fc932dbee2cce90fcf951863ea59fa8410da8ae8de71d3d32cd 2ffc4ba70b214fd7759c50d9a1f7b5941140ccc195104ae1b94e34a4d5c6571a +392000 0000000000000ce6f5bdad9c1784e566c6819ae5f4f0f7c81fa9f5bbb00f203a 4e62604361baa7993fd59f1434821adb13d7525c35cb541e279f8e9b9ec844dc 0000000000000c32f5d3d15a10f155679f79b4c7e2f276a8225f0f707df58cb8 +394000 00000000000002a92c2dcc0a86984f9fbb278819db7a490654c89db634530d51 5d3ffb58d508f49d930089e5abe448fe8c1156b84ff23cf71551a0677a8b782f 8d12e9e27dcde87a45c5998193e6651f826a9e979e03d823e07696c586c0e66c +396000 af2756b80f7a8b44bc55f3a3c6bde0092cf0da9f4334aced5153e6559bad86fe 3a4e2df28a3b3c0cdca4e6f91b756f2e93090a1396e498ba7ff50086a56e64f2 00000000000000a6c25524a08498f86dd44ac3bb25c0bbd41c67549c98af9cfd +398000 00000000000007a46968f838401952e78487b082debedf5d2f56f8d4cc5d3d75 f9fde351eb20f5f3d1332778af36710ac34e4cb86f808f75d4cbac9bab741884 37288d701ac603c5bcb010e4f29b443df41b500d00e260fd72339c0713d493df +400000 596eeb60dab06afccb354f63abbd684e11fd46339977c7943528e4aa34ed0400 a241e2b170333d988efc6b561fdd344bb6ff72ed37e91a4473d5fdd768cc88e9 cc624c70aaa74f9ed28a714646600e9e23df7fc8ddef477de225f9b75f5cd390 +402000 650f3c12ebe0bc1da7866e70205eb3c76d36e6b4209ddb002f5eec0f413540f2 b69e0d07cebfeed5105e5537e28e8f251e3a0bcf2cce050d27d583df0f8263b4 92444039c274d8d73e5e1aa82f052be39a5b3f32bf37c2cfea960c163eb6802c +404000 42be343940876e8cec10355f95422a6067fe3dedfc296a8db2cc90f2f5fa9ad7 46588c8c8483a58fde9628f569b32428c60fa4724f5b47e72961e59f5547778b 2519f7db4e71cdcf2fd34c0f22860072894858e822e61c97729d524b069f0410 +406000 0000000000000c551d5db31c6c727239dc2f21d45fe1e22d287faeaa1ca88919 cb8331a74aefccbf7bfde2d4b5a05905bc46da696605b56c324e9f6427507afc 9f60914446d80707fb92eff933267dcc903590a2ddd4ce9f55069451652ff61e +408000 38b26f32c20633af0bd0040c6c970c69fefa6d44c96d0386b3ae5aad7bdb6fce d94e35c2f872f0b8b660d227f3438f18b33a6627287edd471181103c29ce40cd e201e4e259e07d4a5229cf375d2dc91b2820ef3c0d0be9e0ad0b5330bbf2d085 +410000 2bd775b8cf9d2f8aaf8049950024fb3b1f2c78248fb8ae0f40c4f7c57297f4eb 48b1658735b166258292fd66a87cc8cdc6a570e81bd278dbbfd6f2e010396b38 2456cd904fc01818d563535f51ba4909740a4b8a0ea9bb8a3e717eb04d3925e6 +412000 1de24a310a07ade7997a656317f0a983e58bd4aa9e6ed955b82e5fc4c3de4b9d d67fd86433e8963fdef988f925982194e6d3dbdfa4d0ba9d049d44c2921d54d2 f21bfad73e1d2f712ea2f950a33616558f71396217cc92ac6fe66509256bcf1e +414000 8c959f514b6f010373151bfef8dfd26623853b06e0de8fb0ec75e97d36c6a277 2e13542fbe71ef3a1b317973de7bd76bf0d0b879314545d7e83ec5eec176ee7a dce5fb552d59bcf3eec3a42ff771c8b0957c68a8e7cb62e08bfd51e958befa88 +416000 44ccbb129777eda4844e50d417d9f5078a7bf8ab3e2c1bc60ef00713457f80b7 e9491f607b3442b78b1b53960bce6098afba67dd6593dc1961a90531f81aaecb 00000000000009932517cb16d7ff43178d434ee8210cdcce1012645fef0f067a +418000 000000000000076e90efa7d7990624681472dfb5a8755c5deee3f8472ee24360 6b0da6de59de58af81e6256081ed06d02ff244d3a2ce91a73012c990ec8c1c84 25f9018e7188a9526335f7f56f4ba8c5719bc9c12d984fbb1da3dee04b022bc9 +420000 000000000000049a65a53b85aeda204eddce142b7bd64beef813efba388f074c 7671f2bb25a0862e82525026b32400213acad281f07af05825a37df47b878367 4aee6afb51ca93cbd15d6845cf743d80b606c0d4acc39960c36cac1cc4f37015 +422000 0000000000000766c44bf5a9f117462d32625aa943b26e62438a5224fa4d1021 f654b0259d2ff6a730a6b00f1ebe415287f17bda277249516cad2cdb19ad3257 13b554fbe20c5f21e316d6d3a6cc211a0b79590adef359771c4e9d928224a0c6 +424000 0000000000001f92dfac3668c9ff036da44342eb08272834c3379a119f30dead 67e34ded0e0788258890f67a3a56a8a6f19d9da1eba5db7c5354879a7fb3e5e3 0000000000000390d4ab005adb45380cd5f0eb3ace5de7ff95acff98236658b7 +426000 3b12dda7936f3dc5ac0dd4c02691783942f441a1061e4f9b613a5e6a182cbec5 4035e8fab0f02b172dd5e84fcf24c0c9ad27099a4251dec498a364285e3c0972 000000000000140b8e42ad7ef50a45a41017e3252fa0334ecc2676ccecb37327 +428000 b100f22e7cd30d1e15e9fa396c0f7ac28d9324bc5913f75b543b8ee7b99d38bf 0a7bb67b5f4a6564ce930a1b4bc42986af5299af7268ab7df53e2e4935e0698c a58c97c6fb0288d339c50e0ef88ce5db36a97190458fd0d9ab79b5d37b70102a +430000 fe7706b900ef4b3d8d5d95911f3d497c9394fe8020585b3869204a0f4eea60ad d5d109898c353cf1e4f6fab6d68a6c11a9a6750dddd760d8277809788ce51f3a ef0169255923d30cc660d11801602e786d3d4697c15a6ba7653f4bcde25ae41d +432000 a96f9c111bdc82732fbeff2e50ff2fee2e53b29ee6ef5c443eaa652e9b0d49ce ecc9e5258ecc66279b06b2f636b3c5b326cfa80effdcd78b4e839ac826f3c628 0000000000000e884d80b7be46250d9b2fcd88c5d81673aacd5fb34194ba9147 +434000 b1410215126e71f1361651e044327a0f370e6dfb9fc0affab25fbf6fa6a1db82 ef3df7c25a5fd127b5193ac09b163af58ceba24277da0399ebe8733f9e3c628f e4f79d9803280eb85bf1e0d5ca8470b13a956147d24d8183194ea6b42f80e568 +436000 0cb6b101c65f20869b174082e963b20d9ab645351fd00051940a2abbf0af4d18 94d68fb51fca2340f3caa071c59cf59e1bd8a7d499b4f41f3435c1e2ac5713ac 006caac7d1c0de154f00a3ea3f6fd2f57f2173229120a3d60ccfbc1d39d44491 +438000 d8e692a6db4b95fbfbafeba306f22e705c84061ee3693a5af1d25af15961174f a5c4abaab79ecdb395d79574bffc0c792298bbcde21a7816d23042a6f8ee874a 8806e4946518f2a796bf0306c8a6af1512381cf338ffec0b15a5b5a3c3937938 +440000 00000000000010cce43dabe41742d1c461ba8387714cff1731d60036985ac859 afb0751473ff147c3c9de71d5b9756d766ce9c2c929c070da064494d65b3f78b 00000000000006dc69f3c2c335c08b905443013dec7fb6ed97065127d542f79a +442000 9bfb45abe7b68ae44bb1c6b66ffea9bb6744687568cb94a80f139f867f537d50 7276084a407c19ac2760f40faa5b5333b193ddbcd2664f7ff43ac3a95eb8c4c2 3f59bf60e25bfe1d9c28f1e03f362eb2a0629439506d056b8609d97a0cddda60 +444000 5339c600cb6b81b38b4e5412ceaf8dca473d3d031c92351cd204344678c9abc1 c7ca23121464ac480bf13d6a23712461c31a658a15acb06c70d61ec2d2c65b38 4ce64e7e1106394fa97dccc1f53e4c16f18db8c5fad29d5243a9bfc568657075 +446000 623f953dd0f5473c47b60a5c2de9f826edc750e3b3b91a26913318f026524745 972b02af32f897310f4c930dc94b80de1f9ded4e7397270dfeb9a1477e9070a6 a5c263431ba4a914d8fe0877afae132d87689d354bccfaa2618ce520d0755c0b +448000 c8ec7cfe77317ea53ee224570fa05706171ac353e32012106b714876591378e0 424b6706b6adf6b26d0a51b7820244e482cc33304886c8ae664aa50555605d25 f30e7caacfc4896ab9192858af68c7464e522ddc67d7ad4782b412bf0ca8bfac +450000 ee9e1b718a21cd8d380093d3c999b1221a7fdde4b229ddbffa88e89210881fe8 5ce8105c61bc663dff8b020338d9d214feb9a10d3b6b66b6f4704a1675481c2f 0000000000001847b6ae1892dabe76dbee659393ae6e85f4267cd95fde820592 +452000 96ef04189f2f962ac855bf4c158004612ac789e4f5db36e6d1b99a7fa5ff9a5e 48aef856af418766906260f7e521f18276b5ce2d88b24ce28739d48970051be2 5ffedf64d096d17d6d920bd21018782e62022f84e5427d1e6a007145e577634a +454000 0000000000002484cab59d5a9208dd85b1b72a0783a813eb20492906f346bcb4 6ddb2e2ec1f804afbcdebdf68c5e2a27f2826d381afa9a0bead1faa0a1903bad d4309ffee92348de639fcea1971604844ee2373a7d25015db00959abd234c502 +456000 9ae18a34aa085829856745e24982e96b7f481d0a015fb5ebd90ddb4468e8feda fb6341028136eada71f8949943234ee1ae83fa54e7d88e18f0725a36f4b54ce3 4baa8ee8b1a776cc52464e3b4645e995fcd0a9e474a03bf4c8790bdfcd2ad924 +458000 bba10dcbe6b580d5bd9560d5446e6b13dea3233071d6da74b5bb65d107ce551e e5f37eb863af9fa7791afb4c263e6e06aa41b3d8772482556daae5c6fda4d830 4cc11fff5f22804b7e1ea5147b225d49a31115ea0504fcc4aa20339c53ee1dee +460000 00000000000012f35371fcff9f36eb48f78a526e7209c71dac33e793eaea7c7e eb0ba6301b454fe6e82fc36e7ec5cd55f924376212341e86118fec5d67422c9e b2dae2c507e6fc130414d9efe6a973dd6d26592731e7809e51e0f0af117db7ec +462000 e0af5b8ede42b5bf396432e98c772ca7e4e07a9360f7e1329bdebae47c4a4a00 22aeaa5d84a6c4dc0aaf5cc552d264ff9a0528e96a2fa2f84debe58d992cb3e7 f87bfb0ac9aba560d99419f3f46548339a97ea255137e08bd090d175fadf475f +464000 ab275f4d2b2d543a42400d103ff561b73b33deb32b02887b04d30fb6121a32d9 fb0950b5d4dcc1b4aae259859866499b54bf81cf867257778c34ae1fc053fcb6 af7d4b6c46b6e8d6694841e12855d58a1188cba3e8ce1114818e05b90ec9dfe6 +466000 948e6f76d7ca9e2d6a0719155976356aa0e15201cc5be58d17878587e86c12cd fd37aa1cb159c30d1f965df65184d70db9b884806f5ae357fe98178e59957546 b5d39841b82ea3ffa15d0d1384319379809f2526ee06b31998558ffd89d0b907 +468000 413f1486f413af2159476a4b53e6323694d6e1b3d2b49b44fa5011c44f4e01fa c0876c8154094c7ff863c5163a7d485de2794e1914a93301be86474cbc8a44fb 2110bf1c1b2ca7bb66a012b9710c7226cb452d668a66c5565807f97f5719aa26 +470000 644b96ad0cc1c65fd4f2181a652daa456f3a7ab3bad12119cdf546d51763bf28 35ef105091a572750e6014b903f6688e8dbc85df7610de207225265512ab9c06 16b8abc8718e47a938dfadfba1ca43f8f368f606bdfe7671be8ef6afe2cc22a4 +472000 462471dec729d1e125b746a8c9ec10d0651d29bd901d56aa88438bf69cdeaa61 e1fe3fe571fb3e4cc6491a76763b21c278c03e2aa02c51bf2f52247f348f7cc6 8789a0cc69f647c06b8282df52c622eae9c93ea70a9147c37e38ded98b366de6 +474000 40f791c44c5d5a12c868c3b0574e9f12c63f0a65d8bef72ffe845d09ac709efd 7fefcd442ae44061342ce8f82f7d5d4c9877c0c34a6ae6791b717038c9a968fc cf888d4309f6ccd6735c13424267000c1c3438b957256052f62f75ae625f0c7f +476000 0000000000000e02b867b8e5b783bc45f22c16241a9d602eb69007793bdf6c7a fe047a6ad43fd425b4a24a8c3880c32eb883072696f1ed6792e61d511daf4327 000000000000048803de9aa95cc6a9689993dc2ec049b7fba9c21968b9fa4b1f +478000 7937e7650ba68a35ee6bd7b592444f223f152744792746469d29b57868cabeee 1ca6c749ed600c3a1a7a61555a3f2a0de3ffee9c3606698fe3d82ecf64e8b387 ea54931268686606cf0c16518fd157e4715c98cfc5fc3422648afa3713bebdd0 +480000 1c63ebf9239d366b465b99a60b0735e25808ad63b451aaff8dfbc27f8547c8c2 bb2985e55d6702681280e2813688090469e7dafd559068441107212a78e02c6d e9c14ad6868130930b3958b126f6bcbf0abb0882a04eec27f413355fcb209d73 +482000 0ac9af01669b0f1d4241239f2897609b579d7f2d05ff191545d3791e7130700b c8f2fd859597cf2a7a6ce536f4a7240c2e34dea2225ce0633acf400a4eeb17f8 0f0009e6627f4623e124ae934b333a24fcbe30c6b3ba80a5ac96075cba8622b9 +484000 cebd04ac7d6d6a4b2fc384ec27c172ec7ae6446150e3e658e8901a1c239e1247 eb1e158a49e87bed8fdab704867a5759fb3d614dc5d972c06f4b1534078657f7 80f86200fc9660be569e012b478de625c79dc54f96d46e0f3532204ac887ddda +486000 407862312e80538e2e516834010d91cd3a4cbb8b15f9ae8ffe8595dee6cc721f 51350ec706ff43f65527e920a84fe66c23a4577ed0706bf6b2caa610fb1df3a9 00000000000005611dd2093cdeba097910b5bf7a5f8dd90433e819356553054b +488000 00000000000005344f3db01ba241198abe576ae3ce7eef07ea36e5f653dfb73b 6885aca131244571049a43dadaa8869bef202a4624f1f1bd34eee8d5c2a03abb f616f3900e30b8e64078f54fdd1c6edb61d70718f0cf6c05df264fd8230ca04b +490000 5cf3d9140f846cb110d6bc774fe0e27a8b92c1867e6a70d961abb37213221c38 7ff0a8a7d9ca08f088eabd18bc0163010f140a5858d20066fe1a6126b52b3089 e6686dd09669c143e9d562d4198b6a2a9499fed4ac68e2c13c57987e5e6d850e +492000 fc0296662b6a996d548b09a7c41447f13c072269bc1742c8af7eac51560c96c7 d8146bc3ffc06c84f867b0caa2a0e7a50d501164c1934b647fd7f4b053a7f5e2 10e9e917df4cbb4f29da43a804827fdaeafe3191e63819f100bb339fb46c6385 +494000 d8700546a4a08cb28d08bf416aa4ad84459eef904b53b4b1395b4d209bea19a6 766b83822f5095c9825a8d2afcefd083c1e2973341fee9546933e68c531fc074 0158b460a15902e56cb8453a98723a9576fbfd19fbe9adff8ee643239b78b327 +496000 19242fff29830e421e70748458dcbbc496dbca676a85583ed6592793621b9623 36986ae5c336a5411a5ade840fc74711ebae0f3f33281ae4c47438be3d2f86f8 00000000000008abac41c760ff2263b23eaa94d11e4c0e5b2700bb22370df17c +498000 f11876407f905da2493868d397719b3db7c5beabe6414094627bd15814fc575b 246b8f36ec4f9be0b15a40dd1ee2624d8df97f858267c51a64778b8aedb97267 000000000000183f04e7c1292f2d077eb87a3556df17e4f208304cb59358edec +500000 745137430c905f1a82a59cd733832c543724043fb2fd60e532bac21b21256bb3 589e31c84d29b9aeeb0206ac733e3bcab7529507e7f384707d63bedc06d0a46c 0000000000000314a2069a5d8f3b54cd7402731fab19228d333bd551a61a9ca9 +502000 683ff7be53bc10b00573c40f67f3f2a95490cf9d8ad709793076a2b7f6e1a4e5 a533c16bdff1ebd55852594f6542083d9ce0f9020d71cf4e760b7e2e9798be7b 024d6fea5c648713e64249ccc3573577a250f47cd669f65cf9f242119f2608af +504000 923973b6a323bed061dda3f3f9afd3dfa104beb00196ce88c3ea2df8742071b9 ab8755b0f894fb18ce04b581290ed27a423054a8a09fdf20aea4b0dc4e287e1a ddf2ca6c3f0d6e713b4d4a0081b56309eeb65cf72a9c1018d8428d247b2223e3 +506000 d40f5704d3f326c6e3a7a80114e353f6be84224822fb246de286414b9da764b4 289e16551c1b41b2c710e5a7091256886c89f4a8eac146e815bfed57dd3ea275 36b63b71e2b7465459737cf408a50c076d086a8411acbbe5340949fe62f1587f +508000 009c07991e21a7feb1f1e1eccefd04875983664829b864c1eca36b3c972a2345 4eef4dfa947989078d3a9ea2ef13a757d6a89ae552b71b8042d44d191946b3a5 5a55cdfea797f8455a68e5b5929e7d2db8b9bb7b3849de1dcc2278063481275d +510000 000000000000056778d0bd33a3cf5d957645a99960d7e4ccca40589196fd2635 e3fd58ad40dc787b6dcb5ae06b07d1f779e6d89c14794810055c96e7484b849a 31d168da685e34f8c07831c870adeb79977da84d3d6a4c2d8e8cecac4bfd5eea +512000 377268638dc666ba7a80e9f2dfe35549ce17fede5b21890890beaaf3f36e7ce3 65bfd14d6adc93e43d24aeed127e26501eeb6737d77dbf9de368d81f04cb9105 0000000000000f3707f7b5a6de5b03647b8cba7f34d1d873d95058545569d959 +514000 00000000000002a3451fc79a33eb0ab8486548bc4c4533fe25c0d27f03cdcabc 21388343a5c5c25115596383b1a655fbcc0707db7308a305c1cb46ac7c5dc3c0 0ed7488da1822364b136bd64b4dc6509e9601e5f25d5343135d1ee48f5b07465 +516000 923fc61bd18a6223eeee3294cc59f4a75429b98b2aad98ac70f37ed220e39281 e82542e2900a3e13b6f0e28779c0c606107e91267373e1a886891abdefcb610c 5311470e086560a5042fe78f5677733583c5622e1684d80e01d90a74d79daa45 +518000 77b9ace10cbd41787ab3837749d9e4ce0e074a481d0b6d8128f31034e9c2d938 0e6042250afd584335474d1dd474aa17aefbaab33c99b13e2f2167db3feb7823 98c232db7dafce568e267b235c9ca8aa04c47fd6506eb9c78c199f8b38938c5c +520000 b970a5312eafae49909d2d07ff43d71f5716e209704b56bd9167e2a797471a18 557a58d528269f1cb906e5afc14a26485772b3eb868d0502c92f753fe32f3575 d8238988b97122f564a31e0f0a7e99738542108172e259db2f9b9df5ac959dd4 +522000 aac775fc58f1c497b9dc7c2dd19211199f7eeea7fc0d6fa1eafa3f4001d67529 22a608c0909f68e72803b4cb1d37e339838d1860293be8bb59515e35fd1b2056 ef0ffd939b15a986fd78114be991fdbd0aab33d082fa541aa2c9ba27c0f045ee +524000 eeac75c870b10444c08460e0b00964606e621a3dda7a1e5227e652a937d74fb1 720744b37e18b11d9ab3b4daa956940e2f920f82d891487675f7c2e48d169883 6484bd29e4f7240f54f61bd48406f36274d7cfe41e0b96b26bd16baedd9d334e +526000 8135b14d652e0647cd4fb3f2555ac06d7b961a9e347b43562bf62e2e2e9fa927 62766b6e516e1f3469d5cf7a420200188ca1591a8b1eaa3bd421786707c8c8c6 af538fc530978b3dcafa8b5e9619e6038c21cf1f03a93c7f753a11e3758ee628 +528000 38e77264bf7388b3d0ce5b11c7558e77c7b2463bfd591765e6833f805813b6bc c818615dfef8ab45328a379def693da89688cb84bb491b702b8821efd2cc8511 f944da5b968009c119958ab5589d2dc1b4d6f5ebfc949b0e72c131d3301b243e +530000 0000000000000ade1c9d4534c00be524ac76a40d73eebfeabc390843985c6f62 7c185046f60803d0344f8ca22600bccafab43f392ef5bb6f716a54d21fbe234b 27c33adddf3e0d0d4ae2b70b9981f11934a37df97bd68d81b7adfa99c3c05d33 +532000 efa8271f1c3164a21ef17f6ece9bc4d21191795b29a765f7464d5ac1ef3343fb 5fe4b09eb97184e592b901ef22e50164ffd72da3a7d9ddf4fe9f8b97a71eae4b da385c7aee9b619595dff793d48ea42ea5ccdc86b65eea005df40791ae639ac5 +534000 cdcca0d28c10e127dd703769b3f569159d3fa2046eb21fe0ebed445f557b2b4a dda03bc20a6cdd39934d664778b3853888158a71de2a7098b8c330844c1048c0 0000000000000d991476c784d0c9d13eed7367f92d134d7adbe3c4f548062e8d +536000 0000000000000663ba338d4177a9f60758c545590129bf83b29452598179672b 70b072d9c6d5c28bf37c64ffe593b4a07823abf2e8978f046145e28921e6db95 f7d59b8d1978619799489eb8503743f67997b9bb66f767f6d875132b4607c8ec +538000 7ca32265601fa8243ea3d75778d7f6df1a1e691f14525a62b5523516bc8a7cd5 21c68b97ae7223fb9f03d97559ab0e7ed6f12267055eae2f427ba774bf5cc110 d434b477864b1019bcf8bd52e22373a66c0a1067efc1cd506df9574ff27e5662 +540000 d90c35e1c197bcccf3a00de2ffa5d603ad5d01ed14169ddf262e9dbab2c97bc3 28586d0d0f988397a21f1f3a123f85f8d6cfcef475616bc4bb42e97ed5af5fc4 977ac72abcb16ab217f9d02d3b32851081668d8c997426e20c4ee774afff6059 +542000 8231df05a7520012378517a484324f19ab4389d4ee4a9ab149ee78b615ad28f5 af7670b9b3428935d02b2ae3edf55a18cad3234b70e562e5e2eaa01d6eecfa4e 0000000000001167bd8041a61e12619ee2048156a070558ddbca43670a63837f +544000 b4bc785eb8dab12a8c899ee8b24a6b21f4ec2f2a509f347d822f9c66f33e540c de6b3d4b4047f10d5dc2256788633ba375acdf45c0781e29ad88fb3c89a35628 707f2db6b1af33df3c1df524a58fa6e82a82b04c2ba2cbe3bb92ae29d03941f5 +546000 26a54020556d33285228cabf722c27f8bb8954c288690743d401e7ef45ea67ef c2d22a15fdb5335bc1fe3e24129101776b2cbc6c90b35ef500879d92c0431923 15c483aab4218be98f4322a3ddb8cadcb164c2be63adca3e86c5669aadba8ce6 +548000 b79fadffd64c60f152ef89da5ae2485706c9db0e42d3a88a18e719fe33e829e0 f1565aea8fe76e2ad005efc722e3f4dee13dbd44794fa8cd562c40b6e4ad7266 613ec04fafab5e5fa40307229889a04ee0e6178615a0246af2b18b88468ca5a0 +550000 bde46ef12a48ad06bb5b4cb77e445ec5283417d8f47c0857e05354e256eefa56 04bbba09f6758a4175a407342a1310b88c2ad23ff4e022d4b060499a8479e7e8 6cced1aa772e361438c285cf4af5feb74517f7e221024ecbb77b45f139f98765 +552000 58a6d617b8c8ce97dd27f6cadccd970d40fae81e0ac359d0e39367514eaee7e5 0dc426d1dd8d462ba048fb7ea97bb0c49dca111c9f5570cbea8f34c97110b626 e74213bfbc7a3e87a7b0b306975c42fb5f472f306ad5a9f4f7d77286c0b26d8c +554000 8df0dcfcc065966bcd500b02d2dc154b4476531e764e98b889a02e4dc2188ad7 4a9a983c7fc4d060a58ca71dd91167e3559e7cd4e3c09a803a4edc712d0507c7 0000000000000b24c6ec9fc3e53f7007974f4a803e60451e01247e444b480e76 +556000 0000000000000eb687d67bb3eee33fb335adb6259b62a0695b764eab0405c3c8 28a6f286f3af402dbc42d63b71453eb07ef3ad69eaea1767d22b9a4b9e037925 af4bea80f8c353ce84bb4976ce519389cc15abe0a44572f0205c6859b285cf0b +558000 000000000000022135c2e5f9f97c4cadabacb153a741e82726db51f8bdf25534 9c0b0fd6cf4a3bb72338d32bcf1c93c7181c13a993d8da7f180fbdaa23fa7660 b9563e6e38a72b54fe9dd961ec7688c67ae6fef68456694e720387111c577e84 +560000 861b77582ea2ee45507de8ae15419cc220f58b986194e86fa81b2cca56fc1953 7237cfff53125d082ff9dd2c1e4aa1c6a2cebc1696934adb8c540269f4d0b253 00000000000001e2f6796d9ac4a025faf1982bac8f54385fe354729f60fc12c6 +562000 ba549293a5621efe817e356208cf9ab02a43bc20e89a6259e3b0ba5fbfc27d32 aaa4e6c6e67d0d8f8174cf00b30e9c973213b39ddf346aee9df67340551dcf80 5d7631dd019e0f64a87f6e0b25bc5460de74631dc340d6a9c2f9fda10e64a771 +564000 00000000000003fd357ab0305f6ea6c298ce3eac1833c40038178f64490f6c45 8ba76499684860647f273829f1120722deed809a248c3c6c5adcca4606e2c456 00000000000003660b4d5ca6b1c0a00eed3e06a684fde6c74ac8bc8c0c37b4f9 +566000 00000000000002c695fe0c87b06d1d8dc674caa0dc6a194c679f6d10ffb1671f d476b2dd208ca9949b6a09517ec1235f99f1b15226bc5551aa7f1fad808ed05b 000000000000016918dd0afae965fceea577e812fae26dbf2649019b4163343e +568000 45013a7b78ab887a36ce4372f125ecefa5b7a9bf83ed61719912239d2decff18 8178a99de01dc1bb329dcb536986138cf71fd149835e3c8b19ae59c5898a2d95 174f8881f3701768f9e22060d38b6c4c96479c703be0e979fec65d8946b429a3 +570000 59bb418a28bdb7e9bb643682a381da08c89430047366dbc786ef5def499c038b 28bcdba2a45264145fde1adb93194e514775db3487a532119472405c8121ab64 f6f4b00b57051d6701b6cbf39f9f3f8cb39958e01f0cda996b453e7935153e51 +572000 5af9f43e41a88a08eb2933555539638bda26a56ab8156bf9e5deb1d72cc1be54 84658c684fcb000dbe86d4db89e5db2f01c9523bf703214342910963c03a97bf 2a88e7507217f7ed4e3e810985c9596336d8ab5a1b6b798b7feb93f6086f11b2 +574000 3e3c673221c24e52b96d3c24d38a14cb5368aa68c7b04572898b7f33ec0aac8b 928b6807902af4a2effe41fd568025cd39ec7d50ccfc47a5f3a58b133d0b74d3 fcaea9d5e7385831533f9f02ad4506c9a9d97ccc69890eb8bdc92b0cef897dcc +576000 ac9e7c748cc1586bb4b261d1ba0aa91b82eafb76d6c17560a353c8a502440931 7ffba5677231cb9fa0f400c31dd7070060182353c0ba5387dbebc006ac5a19ae 1dff1dd5e25b2a13eaa26b78570e099f8b6bda795cd88c4f9f2b8a9bee4af47e +578000 e4267471de71614346b31996b2ab52d89647e100b946ed4be42f51f18e9be7b1 618f8bc91b09815f71dcf72e109b9af8adead52d14134cf9021cb701c5e82b84 4f00bfc600dd2d5aa5b541a35f5811a356b6fb6621c4a2048e1c2255bae7db15 +580000 c424045b92d01188804225a574fb4d64137fa3683be69a19e3b6342239a7a3df 45d523a06ab83685283aa5e7c1ad63a0db7f4eed2226ebdf771c270918b2d871 99b4f0f863708e59e9b4d320ab91492f694993025b60be00111b60ebfcf4f53f +582000 99ca5a47402a24c77b75551d3d6abfb9883c8714f1238096966460bffd6a9481 3097ded1399c2a845c88e118b6c5932023f512c6cbecbf6eb1a37fead3bd2468 000000000000013af92f5d184464c4d21d7d52af4ce72418e76030eb855f641f +584000 ba31a9a0ded732bfcb129fab5156f890017864dc5ab7f10d2577f1b5efab8619 3abe039318efe0126c955b527f52bcc03e4f1232102045ecf1ab44ad75dee7e2 f788f042bbbb507f132b193a2f16ee1e2baa3a3607f341f0cbe6ae82e67e9a74 +586000 0b175aef9544d3854e8db368b3acc43acfff58433275468547b2e6fab86cf871 bbb6aab0c1e675920e7acb7c4213742a0fc2a92670808363c9d4432f353386c8 cb37e87afdc62877a3d737380c7dad6dc5c27f735719ea36818180767a780ffa +588000 da24f8b96109c280abc863a911ecc9f4a9c57b28fdf484696a869d786340733b 5b1c8340d051c8374a593ef1cf4d1005348d8f2f8ff48c247dd25271c8ef7572 0920f2d21efe5cf3a508f4836e5dfc97ada859c84b6d25e12705937fc26a2c85 +590000 50c339fd8bd69b60750142d82eea04f87978387dd596f7a9eef58f6069e6bb21 95d4804b1c074d6953d241dc9226af440e50c4d244e811a42db8dc97838fde90 00000000000005ed749dea0dc8d79bcd5b1e78c69cb89935bd6b144eee92f295 +592000 5a88363b90b74d79733f430ac6d7d105a3e532100c63e5e835f2216c384f041d 29d5286dfc9f168969a718db45a6234d1578e2501291313aecabcaf11c2ded02 bb4e23ccdd29b1b9571dfb06f2ca83410d9bcdf2a7d17e492eb0025c7f615d4f +594000 0000000000000298080a5983b9d1d4f7fe445371ff8161f281c1543c9622db47 4b4952ea3f36aad6dc3898b11739777d07634e1e55741da89bd66668b3f9a256 0000000000000833b7551458ab79afe41b5a35cf212a094a9570356435383a48 +596000 935a984560c80ff62d076b1e484fe51a50b274baa58a0cbcc096d0974ac38350 efa2f2be6c7aea93b99a872a85f6598c85d5efc0ca031c17784b59addfaad542 64ce3ebda95253641cd2fcfe184456ced99cfb523c44ea57847ca4948638069f +598000 9a797e2ac0a23e345358dc3ffd23866468a09e3bb02fc0dc2070e1b572eafde9 b1ca3c128c203d2587a2f44b3f034cddcda22fc9d35b0b7cddd4b22ee8c1237f 741670d93a42096aed97adca7f3ececec68add33d0918d437fa69cdc48aa9279 +600000 292bee9bd10c2d02ebebc2a366f8828f79a8f2369c842fb090f8537e87b73487 5a4bc16bd32f35060a8fa12b4ede3406e2ced5169121c4090bee5fe0de91c268 f2ba98810ced38290d5212448cfa57f6128eb04f6a44c5df1c55ce89842625f3 +602000 a50f1275a70254ddd7f5f6163c8aa0ade8dceb176b987b9c655597da87d938f3 f8a91a0a012f2e839cbf916c0d2432d7356a53d615d6905cfce9d4c6efe0b365 48433ab11e5a15d450aaedfb431939b6e4b7c7eeed84f8cb63e6dd36494ddb53 +604000 7b503db95e2d7ae67d1bcf2ffb4106c9c2a48be134c3b8a2ac56b53ce76e8776 b5660b1a7ea7944103df8e6ff74b0740886cc23a003e648cd8077fcb2f9a034f bd84e660100b7464a87117b411a58ef7bfad82f0a3e937ccaaa40bee6e3d9c76 +606000 ebfb5e6d5b4064242d0baeb6f5b9c56f8c06995a9d44e5c8a75b3fdae07789ee a5f4f6a562474141f1430776b8b76adc5e5bc14c742b308e5f6ccc443777228a 85b576f0486455a00a5271534f8d4b4c0a8988784f762883fb3ccac24b61630f +608000 e344063f2dffb21d53e5e42ba77dc717a164c4a4a1916ee2dd59b10bc9023c33 ae11a0ae7f8d3932e87905645e415a8b09afaeb28569a1878e748ce2ec72f8c5 ec44e12c9d7c998816632df5869aa0d6560b4bba6dd74ff132061727bf3f3746 +610000 e169ef08107d1ebf01821c4a7b0b9c832a1b9b95eeb8927da634757c739b8b08 0315f028cd3a1a8e965eae51289d2ef8d2967bf133339a2714ad2cca8a2a9a49 3f954a95e5cb8265b4989d87e78d80b4eed3dc99866cc9f875b4ba5afcceffbb +612000 00000000000001375e8993331229d8283995fdd27dfc6f1ce262782d2ebf22e8 bedff38baef7274b735936b2191a2829a3681d50ae369e5da5a1389a906aa86b 00000000000004e8f1930eb775ea38345bda859e8c903cda34928b694fab679d +614000 ffec99c59fbb45baaa967f9c824253888d01b23e3aedac215b2891f1ce19252f 178841ed0a884eb75c0373dda993edc9e01c5a6abba40e8d381430f341185eac 13f88f048de1f6235a3bc8c8241136c57f06654e9ef5c47465891a87562963d7 +616000 28173d0239eaeaf8cb1f7499c77510de467159fce761f0d05594ff88c6dcb64b d947d938989979abb488b69415dbb230db19e45a95a8f3b0140deb0598cf2d12 58da99d406251a7370129b4f9ab202bac4391b229f80a9add5c91fc092d29952 +618000 640b6d2eb5a193c641b11b4340b0ec152319ecd3f5cbb0db68cb36630f2ef038 dbff937ee92d0ba07a9bd89bdf5926434e9d457af28d2d97c810d0a242448ce7 c791ccbd5da3c9be7d280cfede96d1df56aa4bb73d8b9b7399623852fc03c172 +620000 43b70aafbaf9e6b1d5c8785aa50f271c95815d07012c58cfb61edf9c6e997dcf 645fde1dd38b9c9ead8836b3b8f7e1bcb27aed38aab45d59dfd62d26c5753ad4 00000000000005cdc8b920609435a6e182734af140c0b749eee819087409e816 +622000 b658fe69552fb6b57f179928ae981a07895b7c6f913b4573843d4191905a36ca af608321c5d95a7f933b4ababb47b9dd96ed83511a25ad0a84ea665d77bf248a 26790ddcef496673c4bc1b5db8cb00dd5fe97f2d3aa037dfb106d10db5c3a52a +624000 25756ac516c8202d8a0f860b7f3fbdb8e1824199c7153f390e946b224ee5c92b ed5e2576f752f03cf4c364f0834055ac48681df4993da9b6f6fab3a72758bc74 4fb239345b85d392c3ea66f8cd29eb3e863fa79615a991ea271aee115c0d321a +626000 000000000000002836a08ab3cce447a3eeb27f98176f37f05f8556dbfabe46db 8fcc49e48243201a208211681bf128de7fd5d212b7e6b2c5cf1acbda9e408fc5 000000000000022a6c9a5d0a9ac607743ea28900dbe4e9d8fa68f6110915ed21 +628000 614fce4793b254f776ee3b82151f75ed3df62b05e0d29a0474b26f1411421407 630730646885b1d08b40d46af8adae46a1aed5efc3498833d2db3f2346932afc 0a6bb61ff50db7d23ae7bb2b34f1143299b67680d641da2f13a12ea1dc39cac1 +630000 4638808476ca45dda1d93017fa89f69a123aa86c3639c08e7733b52e245c7ca3 8c13882b4a148520b09113edb81ae5983cd844e7fd88f1f1e315789f4d3d1202 df467172763b533f3fb354607fcf40a2e20575896a1d2f8c9b959c53228d8f73 +632000 2044dbfd5a08141f595b3bb613fab07aa093a553a5a4b9e261d7a40df698cbf6 6bd6a4ed612d0dc231a6bb22a906cac9553b08d3b7275232ea4f48fdb8e4b578 000000000000003e8520ddf0833823ef495f5aa031343b0fc6cd496a498882b9 +634000 40f0f8e85d574271bb44ecd37c5c14499a0d0ccee282e0d73928915fbc3106d8 bf243d5478ff122f3d449713c965a79d436e113f26e583896e2c73127e7413db 60843708c37dd2f0432898cb15e967452487d8792ceec67cde43675440793e47 +636000 65fde403d979f81c361ed11b05013bd3528630fd6bc6ebe26dd35df6114b0f0a 14abae40590265aeba8940b035b7a20fa0d4cc30806f59ba33418e35ffb13400 000000000000054b64f850a261397ff3a7ccfe854b7ffee57225514496455477 +638000 30ac5d2f55314e4be6815e71c00a0a06992be929a127cf866855364ffbe1123a c79af9744faad8d52bff7098b5c18cfef09f99f967cfbcf445e0e0928aadbd77 367e8d75bfaf096ce572bcc26f5e853fa8eb698c7c080ad8ba39035011a20538 +640000 e16a4ba2ed83fbd64d5cb18cb384f9a6343f06bad2d249fb9fffcede111e3039 f25b312d690691765a402182e59258e1b6adef90e6dea5efc17bb3f290c25a02 000000000000047edec1eee2aa3886c1c07c68978462b3127bb407ae975b7b9d +642000 2aabc670a413aaa4328bf7471a524944bb489eb9d958bd04a299593d3f6b39b3 b268d27a283705f6832013875fdad2400fbbb91c4318e4025e27226ad5da01e0 7561ec83bd0086183d6e11d1513542a4c0fde4e4ad854d97d09df4e05d7efc79 +644000 6573eb6ecc3a30beb6a7a73c451043c9b50e3c0fce7cd7949fbca83f917cafe9 abac53fbaf3ac80abe0c0a327a81e121a2f069752d7c80917d52f29285a79edc 1de9231d9b5ff15f3ff88c4c4e59e841eed57cda583639b537eaa7e428236d80 +646000 00000000000003def10daba895a0ad61c688c1b12471cc3f1d57fbd7669aeb67 4989dcc8e91372c1e447ff9e0ef4b16e14a7405f4dfd8aabe5aeeeb793d50ae1 48a85f46b6c93b05cdd4a39ba20194b1e08d8f47e6b6fe71595b9c41220406c8 +648000 56d4c9e44d6d0fe50b34cc1acfce08469b4c5c147b9a406aa133e7382f188e7c 29ce61db723ffeba55c0ef592a2865dc7728800fb4e41d11f6b2682035a35a97 f64eb427617db24cac6b48c69e78ee7968915aa9a140de7642c02ce9a79fc82f +650000 22ebf3a32ab8f9792ac560143988d4cec3838be49727ba8be1a2f2b73e024170 ea065740b1451373551cff8efe2583852a8a10e377c56c517af178283ddc0581 600cfad8d17816cac93efb27daf8873809d645450af4e623fbfbd89ac31626df +652000 71057e2fe73d38f4de7850c9ac2eccbae7e95aa899b0a588da20c2cad387da25 0a3a8dc543b8cdb242d272fb9ba1b0579002a95395fddcb1a00e9307bb60394c 12c418843c8573210d00e51ad8ca7652e9b155e827847d4975d5dd327cf439af +654000 305fed865c9b79a7e974523d81cd8935a2a49ed5bfe302d331c14ef737243661 221578a6e7f800b63d9cb02f1eb7f1ef5f02f84247fe484b20ce83d04073a0d1 09f966b8d8be0a580fc6e176c7316b8c3bac3cce2623c925fdf2aff317e1b66b +656000 db7d6b8f4c43b60a3773024a9b70a20fb9e6e609b19d97b8c778fa24f7265169 a083e6fa04389b343e11a8632f986540e3b9ec0cc549e9a643d0ff5ca799adad 5d8f3f1918de23d163014213fedd1ae2c8bc0adfd625dac57f72eb9f53658b21 +658000 00000000000003fb2751d092f56f199d2867c8942c04bf9ccf3100d7c167d865 ef7d76558072188f97c054952772e79fd7dd44d28166a68fe4954f6362342c8f 2e1c72b95121b0712839cb9a109e5264b214c1f024d35ec050357dec1526ba07 +660000 000000000000001a66a1d67537293209a1dfe7538f38fd5e20d62ec14cbaddcb 003126596e8f2e6dc2b4ca367d9e981f5e178259428bcf92e172be4a2a31ec2d 035c17c14e3c007a83a5b68b39a38ec966612ea1b88d6dfc3cfcfffbfc6c7ebb +662000 6a2cd6766e8c3d2de26d173d04dbb0ea63c9abbd5bda4939c816218112c9891f dc462fbfd7179b1911402ce5dc9a1818f6e8cd1d0ae5a653719b7d87d9c0fbbd 0ebabd710b1b0318d7af3822542fe1f747cbf92872be7b0cce6510d968b6af81 +664000 000000000000012c80d80bf87e12c12726dcee4736548c6e2761b6a5a3842c0d 9d641ab3b399685510e1772d544070bb6f78e63923f2a93d21b73995351e5daf 0000000000000161e0cda3de0ce270d8bb6bf84168474aea7c92304afa972ba9 +666000 00000000000002c85edb2630ef04389e6e716dda6dd84b510fccb4cefecf23cb 3a9fd3ea1acbaaeff98dc64eb62b6c65356be27edf52ab68fdc33799f1546f7c aceb4e6bfab44e883a135f470b85584d48dc3327492346ceb7f43a009c9a0758 +668000 3248a0be871d285e7e60e331647cfa16bc62b4ddf181bda988cf3a7ee73df7bb d1325ee1529bc301043fe524ae4bbcd3835526515ed149f5a62c63e828e1eac7 c35854207dfe8f44a232f46a05c4afa9ab680d9023810f39082cb3665805fabf +670000 00000000000000e0a774ebaae18e3a704acaa2b844cfdf1d4709f5f5afb455ef 9642ae6874275e6e535f111adf8d0e512837a3708b7dc2f410753fb548c53d65 1628dd80b01a258874af81ff713b74ea91b3ef12120a1069f6541956bfa6c59f +672000 00000000000007de1ce1ad62e5a64fdbadaa341713d32cdd6c163723855897f0 a6f19bad910ddc1bc567b03bb67cd2ebba7f2299049d3cd8f78c7d3167692568 000000000000038f5e160b357a8a57ad9f8f2174e4df15465f552d91e6556aec +674000 5ba81bdc3c878cfde0631f351ebf506b2e85742d07e96f9602699e12ecce7fe8 31f6568ec5f731b9903efeb36b0d1694c10045c1628f4c2b53db438544335cb8 5878b25e1064e9dbf4e0836c49f0b6256f9abe99bd7a95ac7375cba1b9e3f58f +676000 5f78bb94ee368142e8c3082d86d5067f77604d383ac2367ab09ac57f6ea17307 b6933d3bf26a0642502de1424c6c97ee33f84747d4a1beb227697a8cdca404f4 02ffa07b9e739ae99416d6b7ac4e40553c5c2db7310ad4f5a4ebd5a297f8e512 +678000 0d5216ea98f1728d031c8eb819945c5c6e5472245d401ccfeb6a52036dc2695a 0ee2189f00682746a8f70ba05f4d3bdda0072057f77d131bcc4e4b6bcd0c95f0 25c7570cb3e289b975f3c201386e4464fb419dab897d70462e5001bec941d571 +680000 cae774d3d57a81c3b391eae82612bf60273aff055cb45b1a168c3996203aa720 7ca39b75cf933b67dd455bf468d6310904f5a7f2277a4ce90cc2ec1fbea4710a bf6017197a15c8ac284d10cbbf2a21c045dd05fef3cdbfb0c6ff1e3988f770cf +682000 5516f4cb305f75f26b26a9c6c91ce7844eba81a8f7bb40f988d4bb205aa7ec28 e318dd02c518a082862a0ecec08343f7e55e15eee7e90b602cfb6659e4a9870b 15f853494c03c484081b7e98f8e690961376139521de197dc7ccdc2355e4be19 +684000 9cff3c43e796f956da6c332c5faec719559eeb9aa55863560c1be8e5066b15f5 24caf8f6d824cc5b2058c185db2d05366fa3ab7a2438e34ea2802b687a2a5a26 ed53598a1ae500df65ff5ffdc50d830d8936d04e203cca581b2fc87b2bb71308 +686000 04bb4081041091dac0ec738b4b7aa052824e216d6e0dc9360befbfe525d7def1 e0108f79ae9bd518a139626075c5e91099f05f4e3323a85ded6cca78844ba802 319ce99ec6c663c0a63a1130c0a1a990105b574e63e13952f096ad098587fa75 +688000 00000000000003e60a16c22766337e51104b39e1b691cec22e79896453dc5f5a b2dc148e54cf524b8ff99b3c5d3f56348ebf2e41ca75157fefeefd907c81f280 5be671175c2a170a44604a5b3412902dec789f51b5f38ddd153f42596025ddca +690000 159fca14c29494170a9a44c720e4978e4a939178f6916d47fa2f9b03ce319725 4834500cc4e42e4e073ec73eba345a501027013779e0ff46c8d5b5ee04f58b38 a259fbec74b8425d2469d1bc8d8b5b162914a072490cc311162680794fa8d4e1 +692000 49e0cbc50e05634616ac86b3649dba8629832820220592e232c133986d9cce9a f95a2d77ecb8986fe99ee42dfd8b2a00d132d2a1b212b27e6550fd0607122dc6 7b4ae8508df80d1271f64a19fe6ac3d300b6ee34bbcb807b71167d012fc350fa +694000 2f5f93672e6a7c3c580c79edd426d109d89d4ea1569041f6501023f2e94e898a a0670fdde742236a3cb98c288aa27574ae014ac4b36789255ad1cf67311aa7bb 486a4bf617327a69027f27eb9f3b7bfa3a49ac9c9ea9fec60a6853d43ff81eed +696000 7b5a127d90adb36bec0c67e76631c5d66398616f86651f262eca0ff2d9248159 3cf42263510d0ba9540fddbe6e1eeed6dbdf185f53b5fe1bef274ba578c8a97d 00000000000002fd27db0c6ee637cbc4dce25e25a0c75013dca3d2a4c49b1d9b +698000 241af6c7b061a41c602285f6587b057af70c660dfb472e6ce1d1207439178ed2 09cc452a73aea02c12ca72fead805631dd673d03c22f0cfd06e5f48a76a3345b 1397786cebe9521d1965daddbda53c507549207f4a44eb5b3cca3c8704ebdac5 +700000 c68e02db2c1ef531d37158b2528bf57f6e1c8596d383e221a8ba4529bd02c087 f9dff66947fc0424517d7a070f6c83fe0c7d740319280d116d5205f100eb4dc1 2ac02e15583388a3b23747884844fe73b978177c9795cac9b421bd79ae6266d2 +702000 f7b9d2de0fb8004230df44b74d2077e249c2ac85b08eceb4e32d0a8128fe3e09 ccd92edac39b448ac332672873aceb9f123e701591772186592540cf10c7fdd9 1e725cfa91350c8dbfd1a509e1e22a798b6d2b092e2b8d932a8d38106ae64dec +704000 15b5386f33a79cae29ca7d5f5d036e12b985452c2186ad04ecf8c5f5a545ae6d 52a7f6005664520286a71c7b7d8dc5c42e5294ee2c40924861d0a2caa249adb3 e72863ee0522f087b14382d21400222fff517f641c353f1ea7085e7115b9bbee +706000 dbe25cc584c79332413e450e43e08bce772c5964144d7166a968787ca4bbf212 748c53e94bc7880afa1fd6492c54865e1975b110fc0b9ebaf840743d1aeb36dc 80d36a949da8eadcf40f05c58394ef7e6a520a40e3b7e9c6f4fc09130b7ba5c3 +708000 4b9259330bf55be5fa0859e4ecc5b328c717e677423fadcdeab574822223ac36 32c2c981d6cb6a17af4a913a8aa496f2a5b2d9e9fdd912f78ee55fd4867f1db5 a619285286356faaed59410ade4f2442f560afde17dda565f112cfaff21b907e +710000 389de706a36553489cf2da8f16865148493a348db47ea660e890f542251a1ba2 45f38afe0e474a5c79c1beceb11ffdd08162428c1adfe31a04d8510d2520535b 9c3a303a8d174deb9ea304521210dc7dff6bea56f81168448d5b60fd223f858d +712000 f43cd26323ca2576bba25775f34569e2c2c86f49bbac52be36c40d1f963008df a11e0d0d56876b997b1efa15b2c8e32eb518e0bb346cf0957a56488310678c10 bf4ec533071a74aa8dd8ab8807a6ba60c53026209b54969b8e1a9cc9fd09d7b1 +714000 470bf7bf36b41fab27e5592c6d5f8fa19eec7040b4c6813d4fd3644af454fd15 37859fbecf4dfd78aa387836234656b7e46a9a594c49689b05f11336db738726 1470e66895cfd8c277867a5536d3c92a6dfda064fa083779dbc59b689d1cc2bc +716000 1c3f684f319d95e30bad47036c316367898b60a3c86bf4ea9f6501723694d1e8 6c6c030bda7837eecbdf7cfb83af0c85073151f9229cb56af5543d58d7e43e25 a46ecd43c7f11cda74eae19202afc40055a20eccea394a3679f9c7099f9f5d25 +718000 c8edbbaba66d015c23659aa033d25852ba0ac5904448dde2fea69eaf22884564 65d8100ad1024a6badbd346a32490f12231c6e02180b267c280f04219d47e1c4 0000000000000275c2a34aa7634ac03799e43219a1b14d839e509a78b9800e96 +720000 ea495aa588f91a0c2ae7715b3d4d1b6f434f52dc72bae5cf62b3ab5033aec9b4 a37e840df4139320d08a196d9e326b2e498753956c3b4ba037b9a0b75ba0eda9 99fcafa3c15298a71b327e5c10dc2f70c0711cd67f819dffc0a1c91755bb4dce +722000 e429a1fe50db22db41db643cb4014864da1563d914b59381c9c5bf57211ee778 149f0d4b743485b3fe0cdffa51a1656bdf0b39f623f44e10d915755bcfa29905 7e2f1c6045d1fe29da2f2d90aaa32cf2b75d856e53492e50bd936fa861314fe7 +724000 93984dea18f33c4bb08052bf4e99b4a364b8dccbaf1c2641d545c2fa5a8c73b4 8aa9c0b2b3f4072c7f7ba7493e5fcb129ff83196ae50490528f6d0d1f5e7e4ab 2481c50649d168ab039008a32d9ad61c0655e946784a75ceb964245b5cc476d1 +726000 2478d9c6ecbfca1fc2dccb1e3eb4211eda09cfb3ae7c9639d5f455adb0764ebc 5171d8de8b4740c17d95f9444f917d360f656bcf55f1d4628cafc620f964273c 1d99244ee688ad95d0b780e52ffb60aef9cf62febe5794f7d29cdb8d3a646b71 +728000 ac1839c1d3a341deb7842f7a9a89d029c5c4222dc4e9c68d68d2a41006bda322 2457952819ec6dd320c1fe00d80f529afb32fc3ba49546231e81334450896204 2ddc3c6828ab2b45fb37655096aa5066d80b285e1fcc262dbd6cdcdb34460cef +730000 14dd69744653d3674cae36f51409132455f3091d35d42199f65064a9b229be7d 7e29553e34fdfa1ac224fde12892c1671aa2bb3faeff86cdf9e730365d79699f 00000000000005f820ba66f38e153ff8da563ec6fcc7afc1bc8c026f06cb6193 +732000 73324c876da6e86252897c24ebf5ce6ab8f458f2f0f9063c5cee29845fdbb8c0 50ae42f2dbe7faa1a21ac36ffc3c59b3dafdf67d568c2961eb3226c0fa4afb53 7541839357d107ed0c9311f6a5c9bc722e9a9717fd9f765ff00ecdfb6b1cb4d8 +734000 000000000000015d2a91e16fa89a98f1370ec1802dd3827b4c1afc24e050a4b0 139c51306941436669cda826ea4bfb36321de75cd449647b1488e72db0d02cd8 c6ef6c530e9e927075e51b1ddb697755cefb4ca2edab502d51eba970c54f4972 +736000 0edb70ad3165ecb352c419db2f32d5703774938252796436bc9667e88a53120a 8c413c74636aae8d84b8a9746b02f83c26be205cca3ca7429510fbc4ea7c2e0e 3c4dce0c5d47876eb212865ed3fa5c344e6b7c3fc44b8e614e031b515b7f304f +738000 1444c89984f3637d494a2ff5e444f3e3b1a05498c994629e22acef1000d0a701 d6bd1f53e52c15fde3167ed2cdb4a489326af40bd1f930d1d48ff9ec823c78f8 7f8fbf4bc725ba52c3a85f3eae044048d6a5fe75a854cbb8638d5f1561fa5f12 +740000 679b137b3b2756d54423294ddf12e2ea365d42650043aacbe8da225b7b349cf1 aba9767649b13ab79908bbcd4db660b07dbf796d1d3a323dda2b352b54c598e9 2ab1c4fc894b6304f45a0e7723521bdbd75eeb9d38b22f4047a39fb20e708ee8 +742000 a34040a2ad78dbe58528123e0fe7db696f49a831ab7cadd96639663e8171cd8d 2ff3953926e6c58e180810500a3bd814602b5989eda3be79141dae2fd72d77aa 000000000000000a1895e9c362457ae3d65355287d40472c75b062d801b3dd10 +744000 00000000000001c5da9d022f17ea9b65cf99123a847cee8650cf72c8c1312ad2 650824b1679bf8df438c2b4c5fdb53d53d3b46c16a87dac8eed48063b4579a77 9af9f82fae2ffbe7d018da550fa6c07db76ed6af114054f5fb80f87718dd230a +746000 00000000000005f815b75dfd0ae2a1a5c69e69c84054875a893f4ab7daefe078 0fe68bbd2e12060a9f063f2b0bb36627609ae98c0b257e450b72785ccd6404c2 e5585c06a564f1c00a7c756ed566e79714f10c100140b7cf2273c8058767bf76 +748000 241cffa7b1987741e7d14d68c28f27073629019ecafb2e46944f6a11fa9c5101 5286a151f20178dfc8baea42d3b0a55500b93ec05e5e33dbda7495f715a8286c d15ba1d00a206cff9c07aed7cbae1837b18fd5cd125d193b6db04dc7c2f0f02e +750000 e4f248c31f690b4ede6d08821e551f4dd728a71942f9b6096c914f877188409b 86847d7e6c08f99f95359650235594d4a59ef00c6e27dc742f36ca3f108e3aae 3821f9e374848e147196c14c18ce59cf729f807df5258020f2898e3551f42c3c +752000 4fce847ca3066bceb25d9b78b76533a3cd9582bc285bfcbfce8707bf5d465619 4fca584827f9111a39b25af4989a9f70eea072595866fa3c1ce6572d65497d88 1c7c46cc8785d4a5e79e1726a2cb41a0b6cd623763734a11dad406ab309e903d +754000 3e7e3ed6a48b424e29fd7ec6e7ebbf057a728d8de0c7b7bf76357fb4374d8ed2 2155537428acfa012dccdbfbb133712b8d2bd2ede69eb40d96d31b9ad5746f9c ef522fc22fea354aa530c544f0e2ad6b21dc8765de35121c2f70e523ee1e4b03 +756000 b4be56afbd1daf9af75a8fd9d0cbae50152140bddab27107cbc83df90cf78a5b f59d0a883d0d7951cdcd0540242f8d1674a94927d3928b4511a0f46aa2f30747 000000000000007a79813192b8f15c21cb17dc47a304157e659fbe17fb1e5a2e +758000 00000000000001ff9209af674a31ce81abb26103042a0e64b9086d7735e2b018 25c01a545cdeb3caf8f05e50a5337a3fbd3ff5a627016c7f23fadc808b634495 9861b01274cc4de8b238fde78a3969fbe81e91c0a3f19412623f24e52ac0833a +760000 00000000000000e3750e91b41dc63e8534eefc8f1081ffbcd37a687347e49cc1 37f364e142cd898160699961a0d974c0b04dec997b72c16798e9df4809683712 0ad7a9eff14434d5c86677e9afdc2cf95cc7ae8947936c7671510d522cfc4cc6 +762000 0000000000000147057f1197ab04d64141de3b5384636d4a19c97f1c16990602 4827aceda46203036fc7b27c527cb9cb2eee31f7bfd36f9dba2855cc0b537dc5 5c68067d2bc273a282974fbf8a44e103a53bcaa177f74647eea6e0ea89080b47 +764000 95171fd14bcd07bad4a022c5c0c8635b978182b885d583b4cee79d2630974ccd 4f80695b5a2ea0faf15e747903df8d1b3543316ef6c71ad490cc2f2eedfda193 0000000000000714f68ce6c3b2fd378f651f6f77cd61aa24457cb3191ea4d830 +766000 9e4fca846b6938b3ce4f0d6c65805d4e60ea5531a38ab3d3aad9d9be35eb2f9b 9b1bbebc87a357c312bf806d5b34a00495d4193e6dba2729ca7d1daf57c06818 bdcbd1502188d4547b1e59072532148f958b80946e0143dd62a61af836840a70 +768000 5e1f1e71dbad5612104a108c5ce343ed20577450467c2dc8f402841f74826f23 bec9a1e1a7193106a337f4250c1d636bc352ddfacafd3babf571d9cf87f92c1d d7cb4e0d162bd7a4aeb5f96591049b0a604e83bd7739a0cff0c9e1b62a29a126 +770000 e7c81ae1b0ea298311c8d0e542f3b3d0331ce219d2ae9d3608c1d113fea86062 30567cac5485a002067c6847b672f01c6c940f1c7a6625da1f69ac47e56d904d fb45ea12e730d73ccc6bcb6396608c69eccab55a97b7e8a35412df5e55369340 +772000 6d2bedf9849fca0ffdd3834bd51de4bd6f46452463e04a1ff6153078ed0c0a71 53ed7ca85171019c5e2fde6c225aed53dfcba3899f7495a1718f87bd32b4d1ae 4804a09fba06461de73c9a0574b5cc58e3c5d54361e2b9c1c11fee9538d46002 +774000 11bb7d8dcd485fbc2eedb759cc41aa25c86fa1e9c9c6ae2a7f152dd066b0fc72 241dbd7b2e9ea09d18ff5451e50e169c95efe8acd320d70ffac9630a8fb51c14 6e71de9cce7d5d9c5099e48c0a8a5e81077716a0ff3808c7d6b3642df6b150fe +776000 9f46f4d7501f64d0db6bdf0d844ed0bd424bb5b5e95c4fdb76b38c2bde81276c b0c68cef494b32f1b770f174d8dd40d4be5feaedf26347f2628b305a421aaf12 1aafa573a07b8873449dfd26fa6d3b942394d125cddd025128afa8ab84c96f44 +778000 46d2c4dcb74b7c2ff5aa803cf7e6a4d28cd3fbfc7f43e959bf0b2ac2d60a931a 6881dbbde992ba42cf195f4fd9ec63440911370aadadeccbbe7e642ef7e3c186 90ec91fa65ed0a2992d0d7b5f52bd61fc3e5ea498b7805641b09ee15c1a5637a +780000 8981d111a08593ff12be3ddee38250a5c46c08510be26e50956ef94e8717b854 dac48309192ba0a45f7eda9c032da1f44922c9c304472df90785a06153b56e6b cc45814e1e91e2b5b180b900e92221abd1b2b6729550779803556425512340bc +782000 9a0edf178b5edae20980265079346bd9c329450c64d415b88e6a3586a0ccb86b 3a1ed11627f31e9202b806741ab9e32b52fa8144bb3cc4d067e300fcf75dd95a edd30a893e59358cc03da23dda9fd8d5dc28a60fcbd712c37ee3845d39052c51 +784000 d4b9cac4324da1aed67533c7bfd11b96b5f9b5fa119b555c65050f112c68d22e bf3b1bb2f33b967c9abd43f16e75c1a89be8f37a284597bba1ded2a76d547042 5286ba8c793e8e54b8323f4c6218d9f6407bdfeefab3ced40ebaa8dba27f4241 +786000 fdf1acd69dee6e3418d750ba4661fa05767db6bba231a0e654765381c576b305 f53acb691e7c0acdcb1e3497f8a3bdac6e12b56202b030832fcea01ec527d19e 5622f04ec7898ba7fefaff76298428e098f0c75e8481eb4ceb596abc01b2b091 +788000 5e88fc3d39a1437f381741fd962a585f895b261d832ee3fda6804dd304cbcbc6 037d5c6d01bd21cd60cf6a91d7a793e1321835876df5fc3a88ab8255fa36bac5 ce544a62132da187fb2dfd76a3c5b3bf08ef5ef53490dcdedb7b8c73aa364fbe +790000 8f89e64c8c6f0cb0e11c18a4e205ee7d51a5a512b5f55278c63cb71e179eb69b 80179e3303af654764610ce794ef29c2446c142c61ba2a96f5bff7b6f51c02d5 7fb48c3c9c9787efca9c6258b671b162a2244e29c595970f65fd80318326b372 +792000 8c6d4ac1cc6fcb0b2c9110c959c10cf1609f5de0a7ee115473ccea5b6947e5e3 fb375a40805ab9b0eacd340b0d926632d9406d4aca0b783ed046de8de7a4cbec 268108eae7f7190ccddbc05ca51c659fca4955ec7caa8102b2a5d6f7a3f9ee94 +794000 2afbfcaed2330f168a7ab88f45e23feb9007c7c3596fa271fef5c8884b1d8ad8 32ade8bd18bcc674551e39ca6c6b4763af81780171813587f6a9d5edf6c26611 2b8b8b858bd5b920f1a9b9c20619194490aa7932f7faa6b16657181189a8c899 +796000 65c11805239d4f4b41c35d124bf64c9f840f28c52cc02531fae01a43cbb5da76 03f0a07124b191e1934ef5ef9bc0dc425393d0777a36566001dd4fb39a88f703 a49d1e728ca56d1070b32232722e04a5e1686a0d13b64aec5853d68b41a9a01d +798000 91dcd52f86a60820ffd082615ec2962f6b58abfe67d68dd0ddaf1225f4d62f75 04cee0002446ab283171ac8f0f59e689e178ec6b699df245c67e748a539a0d33 723d96d512f50c2d95ef3b220255700c35e85621df842ac27ac36eaac331fd69 +800000 cbd4702a5eb54723edbae45659871449b300b3da9a30e5e4c6824fac80cae3e7 b9972349361f4364abd10bc405951ec76ea088950884ea473ac7d6ac97f2b275 000000000000044798e8c8cd42085e5495fc2a6b479303d5d1b56bb5e326d8a7 +802000 11361b2af62c0b0cade8b8398108b1edacad2032430c5c0381dc2a47c0ccd622 b6689a7c72fbe845864274b75e061ec6145f929a66a11997e642e871a2339b9f cd81d957e821fa3ddf1dd08851edc10fb396f6ed867c27d07d822ff40a88ff7e +804000 7bf1ff1823b568f518310c0bedf964beef3587a11559ce814ecbb3fa27bc8ee9 0117f0bc6e5e2b63807d7a995f228601ac9584a3e78fb586cbc804ecb03b272c 2cf21ba92db1548881a6177c14c946d158cfa5fccc07e82234e1d9aa743a2254 +806000 b9084fd43623211a95c599a3004c77032607ae97b173399a1d40ce8cf99fe23d 98c2a95722db872b79849bba06d5c314be5b1fa50ed11518d218af8e2c37757c 28a0d290e5288be1b5dd46d4c99843e8df89c58cdb10edf25aacee01fa1dc560 +808000 04ff03aeecb02684ef4066360a75981f4f30c87b3702e6697b282c3ac49e53ba 1464ee93ba1866eba30b620523ecccbd5219ef58b90a07d4677ddd2a1290a0ca 7e8731fa0b3b32e5378ef77b20470ee058616451476b4329f528c164be7a7684 +810000 805e5c63d5d5cbee626d5d1ddb10311a4dd728ad083cc303b32d97e581d1f6b0 a027bc425476995cd606b718487343fa3a111cd53d2edfcf2011f3bcb1ddfa8e 8378db357a12ec589778e7d05b9e70a9e981f67e2ba1824118e45bcbcf9c453b +812000 dfece70694564fbb84ba2a3a972be83b54b3cf66c0f6fb3f7bd5ca86b0d063db d072a0053ae8c83c5114adeddd9b64a564f285eb60ba99ed5145a28360e6274f c1b71b8c725f5c60c582c03e688f27a56ccffafa2cd30fd0f5031b5a98e97c8e +814000 a0e48e323495ff53680cc106fb68abfc47864447645ddc2f1cdfdec487f4479d aee81613062c2f7ca8b6ced56a70d111a62e84c16aa3ee7ca1df2771c30a656e ba5e9e52e4fa8718ece66f9968e5580a9eb505e8f544ac9831f989b5e5fa79d2 +816000 2f62673ee90cb046fa382801b1b15ebf0aeabd31410eef88b501cb165b7eb729 a97db0009a174173726dab64a8095e46bd08a3637ca3b33bb180d11de0932105 93ab70ab4b84c60e0b5ce6448336f6f3fbddda75f64f52d953f66beb633aca34 +818000 4f4a6a385c8456e56a89270a1b3dc0c39ed8346aae5357a2b56ca525697f0b07 a0fd901bf5623cc1cc2ebd301f7d8812a37e90223c032b7b78ea1f252c443fee 00000000000001eaf0166d3a5f40b6c2c15c1d479dfec4d126c5326596f8d149 +820000 00000000000007101a61a61298f59958639566fd00015ba7564acd19d54019f7 5324a468a796bec3e4acea8a3a70b8a934f96bbe4a51b441f902e44bcf58a16d 27f15b1623874be0c7a7b2c63383679e3251e31d295d3e141a4cd4347c771f66 +822000 6cea36ecaae56ba9ae840033c9485a6da2e4738be12c5ee5d46c8a4bf37f74a2 283616c7185fbe722b03a0db8bcd5a8cd5d5746cbaecf5c3c211aeba20ecb730 41ae05ae06f9fbdeef27c795af2fdf01061799b4a39019872400c4defab158fb +824000 00000000000003a2dbb62f0e15cd1222643536d3987e16ffaed5e08535226738 71d66b99446ec5bb6e5621cff4a1c5532bc15ae8fc0fd7b53418cbf76d45a76e 45c94cd3ab4198078aad9474b166da6e5283f83e9aa7dfed2d92449d224d683b +826000 2e69b6830e5a8aaf5d2b9150087b51152ef74be231b7eabfc89b79f5f857aa84 cf39a629ff2377728aebc704c27de294c585dece4086d6f6a59217c005ad0ba2 ad7f9ff19bad4e988b0648189c06a7460d6179974b441c585216c346f84df82b +828000 e44ce989c0f7af5b55d689704f0aa8cf30a3d9f0f2cae0fd8c6fc5b159afd31d 7c8cf4d183ac34bd8c2a7a328a5d03990b716943266bcb9430ecb3fa52c3780b 457269af183a15c0876fda6dbdd86206753bae38ca61f5640787860c882ed3ea +830000 bac393c8e5519be4132a745d3a684a030a288a687610210ece332189ca3d4208 84f8aa2ccb1940090787e6531d2ded2105ca9afe9cad213e03e80fa1b178036c 6e419845ac5ce5c67f15cebb30e3eabbb853ca910f76fef61dbe41ec8bc0dc28 +832000 dcc4e710dd222410b850c5f8374dce0d779053bcf72a6b84e2c2e0a85ed34b3c fd6c2ad70726a221de4e33e62fee7cfdeaad0fd44ceefce565aaaf6f7ea651f9 743e554de11f76b3c6898b7862845b6b8cfacb498cb56e88c091d442c6784b01 +834000 a8ee29c4f65faa797ec11fa4216a53a047e54ec032439e4a43ec4b4996207351 b6608d5b241c6f519a32ff2f6884a06a4051240a803d8c153e5e81d75b291d6c 6077bc185d8e3cf246bfe3eda21d5b5c2a7decb76554317a94c92e753d79c301 +836000 0000000000000557f4f77b83df582afa25fde8d7fbe37874f1f6ba2adac0b2f4 124fec3a07838817851d5a81434ffed06f9c6399200f2a67f76e83b0a279bd79 e917168c9ba562f169bfc5e82c9c00b4f7ba4e3f0b2b4fc6e1066dc585765018 +838000 00000000000004ab94358c8c9e3b9b1d2dec21af70b38f8b2a551db7c0610902 6ecfe3433c9f0cad28a3b0d08ce065a9e854e77e43b2ed01a776b721c9715c7d df2d49beba35bde3d23f72c6ed0997d4fdee366151b6aaabb864e0dce6906a75 +840000 0000000000000018c2ce7157d4ce033a756073af44c49c3289f1a3316a734f05 23bbe6069da82d3e204e80974d6d60e347beffb9c648bcb0cd5702e1b0f37745 4b77a93acce1b413cb4803dab7c51f8a222a3de14229c0ef49e18920825ac289 +842000 20514db1a4951e848ddab930e62f2823d41926d9f54b9cb53596b375841f4a32 3e464cfef551196f53c743490f748d74c7a2b5800dfcba19d389ccfae31f7cab 000000000000076a056a1c03ffe00f940bcc20474d3a5c9f33fd98225a316759 +844000 fba7ca1591b8e195dd0201bb95157d18f5c95665faa142fb9fd1be21aeee2cfd c07139e147d17ba66cc9d58cdb66c94bfb3766cc2b2463043e50019301a68593 00000000000000d63b5c6c3dd62b3cfdc83ac9add238cf00db50d10a79b65967 +846000 f7a7ecbbb76c3c041b4a1addca15ed126de607a0450e9b668fff079fe413144b c9b455ea432cddc074d9439de735f89289d7c9f6a37d668c995df3d9a1ca2471 8cbf7b906af016356a77182befaf5588b507fecbdd0d0d973e05b5056a6a7411 +848000 00000000000034d2c155a1863dc1ad7b4cc5715b7689b4884f6b47b16b51ae67 f5583d029b1c5d406d58624e17284b190f093ba0b97ef9402373ead56b07a124 bcf6eee3d759abc82a293290d48ee9f4439c72f3e3d39a97fb70b34dc5955116 +850000 8a201d591f08294da50ff96d9935e29c73f1b682c400955ffdcc39f0a6e38a96 7e909a08373e3a8ef757c633008eefebd9322954c66afd02c09e0bf63a5a160c 8e8c116c74bffb2a0953bbc82e3809968e7fa8a5801863b89e69099f76d89c1a +852000 a12c8b9b4788fdfdd90d29beb9e52f2b6612e5a44d616983f5a7c2d34becf6eb 157db1519be2e2d2dde7da8ece556fd130465c28f0dfecd9ef4de1d3633454de 7e9eb7d5f47486dde488feca48683e8f38185f833e3ecc4f49faa06ede1ebfd3 +854000 000000000000056710800cfb7f1d90b9c568c931adada9710d8802af04fe28fd f88f5327c4bc5186055dc757b1e15c3e981b4f9ce45e49508d81d4c942519378 5d19ea5b1878307d3306c0d37b38f40380642e256b47dae54ab0a9b743dd190d +856000 3f53f6baa2ec6fdc7e17f2ba7dac7a139f892ccb9df1ff7fe0e0c705a321283e ab4b9c148ac8e8e7af2fd4f7fa554608aae1b020821cb0bc1792a267d66856bd 8d045b1dc696cdedc0811d36481f0867bfe3190fd13a831ade39af2b4bf776a4 +858000 4be84cbc3d84fd0fe057239a9344bc037872c53d0d4f087fbe7cf82a941ff76b e3b7cbc4941d07f6533ba201cc0b3e2ca1df8c9ada87f2bc4d960af994a82768 0000000000000602a80f6719dc96ad1266a439f0fc3a3b09c0a6372a52fd53f3 +860000 e994ef4ca02c88d5e190264c71c47d40e5edd84617ecf15645c176f81b22a97e 0e7de2f452aa6cac47c52b4de7f7d27fcdadf608c1c6e064c2ca10215d183964 b9bc052a793bf7131271b4c8c77a851d8058cfabc848c21cc0d918033efb6b76 +862000 e968a74cfc2162df249130968e24007d262f2ee27c6d9761268a15f9b4e49ad5 95aefc7bb9f73f7fb0b8e1d9576d8707429a0c5a8ed1db627f3c8ccd70896aea 00000000000007342c7910c0aef7e052954a3dc27074f7b5d9e347e23a83597b +864000 411e255125381d064cf1565f1909badd73ca025ccfd65633c9b4b4d2e0cc430e 40abf1dda866bab49067243af1916795b676306db4aaac4303dfb3d27f8585f5 6db7fa3dc68fe1d907f8c066f8cb05b91f26f4c01671f8837f535bcb18a42472 +866000 e412d1847b9811346e1f3bafd9630f42fc5fc5ef0b041d30b115e941d3814900 736c5d7600dd2cabb265a103751982416ad6d07d746e0d5792de9378c12ac760 0000000000000b105cd3611987e6ba382a4ae38146ef7cb71ee742144106f3be +868000 46800756fe67e5c9c1c03efc58701d4db28d83beb46c766e3490ca97f91b667a 89829e13d278452728c5fe19948a83e8af477416f8a1f0a45f294040569840ab 0000000000000973fa168dcd8a9296091b69ea8ebf793449b71babdeb39ca3de +870000 00000000000002ce9966896edd240aa2e78c7b1b785353c359bc008d9857cb69 50f39b61fc44c46302844378f8f80d281982dc12a03ab426f92e0e03239db366 bf7ef09cf1a71d96beaf728b834d7d5acd61bbebc71d300c50939c08b386ee64 +872000 ea326ecb7ea6cd07b320c7db4de3ede50879e44899f9d1a1bc1e503c9336fb5e 1e90c056cca2188b528cc8a07ec14a01f4e7c84712b26d963d3895e4b4869ff4 ab92e15cab9c4a03b7de795f8942a2c92a3a4ceb46278dfe9bb7bc1a4462a5ae +874000 25ad7f5bbbbff329edb379cba0f908e1e107710fc74b23d8629435a05ba52fa4 1878b4203a4b11ce410259dc952a2aed47fc0dfea6f7ebccbdadbdb1398f9bad e01d9173e6e63db0472b09f3b48125eadf7c1d5f003c95e8cf68fe42686a926b +876000 587fcdd82343c26471be43114d41969c4431c7633e66496490eaa687a25ddc8b d192b9a9516c821cb6ba46299cf89ea86ab7275ded921a434b083e31496df5e1 963135be1f485d16824d1cfa97be9ee96a1aae6c9cbecf8cb6dc46e1883e5930 +878000 00000000000005401cf8b3bb7d0ab56ffc41508eb2a13e10fa7e95b6cd4eaaf2 b3470f65bf8e9cc3679c1b71e20e708cb4ec7ab87e1db3520318c47218e51534 85970e8661ecba69626abd65212826d784d70f810304b20a23b15c78271f21aa +880000 d6f5531d374175822f444e8df8c6c89ff690d6ce9c59d3fd72f4d1fa7a46fe93 33ac58068445619118d6e9e7e0f549bbf7c5a02c64ad912a5137a2baebcc99e7 4dd2aae62ff4d53314cdbe7d02c1ab70e0b9ad13b0519c842c2863da456be0ff +882000 fdb9a330920ab08089f2f131595d7213c9b2d968891991280b225131c5d32864 20316d253a41ec9b81d6183fba373ad575d8fb16c6cc1b25d0fd49668a29e244 6010b0688f8f3918346aeb5ea02c5421edca87e6ea5509cf6d3b189ed7323100 +884000 00000000000007e7e50b31a5087f1199f83713f086f456105b1bec6ded0213a9 f853e77386f63be5e59233fde12efc625003a768efdccf21d37c20f2d1cf4567 ca3e98c3bf8d26a1ea1781a88f9c85c7e3ef980c80cc08c975d73febf0b1bde7 +886000 345de81f1ab9490fd881f7ecbe123a660e5774ee10e463164343deb4e7d283bc dfd57fd85c7ee88b8d1bfb589e45806542c41d079c53bb8bc0b45ec7d998beb9 b3d473f0281698ae53bc32741540e43fb62d9650d865e2fd0783b07b4c4cf4c9 +888000 0000000000000bd17dd826db8340155809acbe31c1c26d8352fea1feae565386 2becb31507a0121ea98cbbb3c9934d51c70ebc3577c6e1072faf492566fd71e8 1b73134af43d6fba8700c52332c811973279ecbe29a0d665f65a555e56c264bc +890000 e82f64b3bcdab06a2161d49642d28a24dc8a677554305495f65d79405b281aab e9587d8fb92495acac8e5870044cfae760fba081520dff1033936767155f827c ed71618fbbf187ed3085ed8ccef7c7e030e88c34ff858a711ea95b3ab18b97f0 +892000 a95a6294220e40aee2ca9f5f7ce9201af4d317d0be19b44f3d7485a28bc3a109 7f632df23a81befa3886e7c8cda39de37ca00f80e2874ff392ddf9a39f93fafb f1f3627dfccf0736ebcb35ad6e15d06955e7a8d78fc742d450f96d5847b2fb17 +894000 97566e1f249173d693e49f0b33c9226415115db4050080e25748c1b956f6decc b2b98d5275512c36a6778746c0105f4b79650d76b91a6991f049b2500e307e9b 4de506a549488699eb50900e59be0704021bc4f1397d1cd10378d2ef5b28d7b5 +896000 77cdf66fd2ec3e5b66246887ff5af8442652d7ab056965c14032dd88dab18913 95dcca7ea3cca93ff0cccb9491713515bc487802491feb175920f9d40ebb2ca6 7195ac0c276fb4c5493706c6a3114d75e7727fa8b150a927035c2f6c330a3467 +898000 7a58e602650c4b8a37a82e07d79415c5e78e228a4d0db584065f9e0e0d862472 0873bdb402f1e884dfbb8be707ef80f9b30de1d2e09dc48a8ec49222c97cba14 e3898bb716d860cdbb330d0d5c301d81a9e960d3f75bbc77d67ff63da822f8e9 +900000 11a7336b91bf2994321b8bcd49ab2fcbe45afa6399b406b59620915db0e11a11 1e6fb7e3f8fc54577274c962a33f9f6a5e6f7dea720ce6583e516cf128de93e2 f9a91b6c5b3eab9b3756952f43f4aa8241eb1a54b82fea89246f4c4b924ab324 +902000 44bf138f5aa5fa580022eafd0d66e4d49d0efa9f7ba56af170ee6f8d64d1bc30 dbee14fef421a7ac92c655c0702692f73121e929537f7e353a103b4cf095ab2d a4266aa032606804206e83e77de4666fa091d416cd6f9e6d14cfcb8ed7893732 +904000 000000000000069dd33454a68badcbc94af9a666baade63bd1dd798684bb7bac 083d9af7e18a0340f9cb4578ab6aed468055aa22c9e0c483d02d8a8f1dd3d0af 000000000000050093cb4bebf0eb881684a194d5a267df2903d0813ea03ac2d4 +906000 97a86fcfb5694f0c709f710fdb7679d99a8363b74dc5d6176999471d1949e04e 96a06ff98cb786eeb0a5a65245804f78164d0d3ad3da0aacc3b43363a1bd312f 4399f85f74a503b643e8d6b476632355e5560b582afde138310ed81305cfeb8d +908000 b299ad833de5291ee0b713638cb8d9978f6e7c82d3452daf995105899695b00e d394ce9248292252984dadb9df99617239f1b3a6cc6989ebd0908fd06d94c73f 35d7cd53f4ac846b35d2e239f8b192867f3d672af46282c88d3759509c71e814 +910000 f0bb33f269c70a94bb0263ac333d1d5a4bf58c3bfa06573bd8f49bae983af54f 40d343228625d68f23bddb0d91561a35501bb512248cc6e93e71e7b4c040ad8e 83ebc19069719e0b1d2455c26d273b53402d0f25cf27c96ab2eb5acbf28cb0c2 +912000 000000000000081aa70758e4c45530e2ec70e82398e5cc93b3a4d13a1b5d956f 6e73bff35f2b78c0aa8e5395d503282e40803ee39b1ed9ef505318b363073775 822b1b27e3e24f60fe2c20e4369a6fd70a957b0f5dd64eae5503dbb39dee7a0c +914000 a90b93ab0f4448ab9fbe43c72fe81cd5610edc5c88b80d2d3fa38624104eb541 f0a07c01433f5d93da04913c03feee03dc57c13d65705665976cba74431823ae a1e384ba1bae35c1137d859f27c0df191d9b17a8e4a81453166dc00ce7966627 +916000 a3a30bfdb06973f0694326463f5ef1e5f677fad4868f52c4cfe207b1f6f60408 f77af1d4be774494e183f21249ae1f3c752142371ecf7ffb9f8fa327ad39de97 7d1d7cdc687c2fc0aa91dce5f808435f42206316dd205fe1f9b4c987b4c6dddf +918000 ccd999b2f52b2e083d4031df7d0512aafb449c94f5b38302360fc23127a6e2e8 e138cf01c6d1ad3347f6dce71cb1325ea09a22319c121fb055fadeb5af0e9ddf 8593682e124fbf5b148a68567e6a7701117a82ef987457cc0a533fcf6d7dc02e +920000 4f568635eccb43fd505cbd0d0cd48ec0773c8b4e360fd212dbb1c9ebabdd9cfb 5ac4df635b9b459db028c8aa510ecc5957e65ed72d239d50fb80e1dcccea0ffa c113d52374f6f6aab3b42743c93eb12d7bea561178e0d6251c60ec570c8ad347 +922000 0115e03863abde3f83773ea2007caab448e264196cdc3f314d076917a83eb1ef ccaf1c314d6a6f2fb6f20156d96a59722dee47df7e9fa913eb9a74ed6114dba1 9d4056ddc1864710b8d6bff1f33d6d6f541b73eb503e5018636f1c6f12c80072 +924000 c528054f1f6dec7ab44e245c9bb299b67d60741bb58d74b7c3c55116cb9cb2ab e3bfdd5daaf143aa4416d98de5b8129fd6212340448103ecbb23acc5eedefd20 832322d286c1537899a3c4b847b5efcd805780ae1a4e1709494ba0bd197ab3d1 +926000 8a922256095c1a2c5653092d17223d7ad6149db758670e4b80ad553f04215a74 6dae4b99826afb3ef791b2507b228ca05ace0645087ea64509e7c272d2d8fb57 00000000000001e951056c8ab0238019ad3fe4a1de44f708b934be84971d07c7 +928000 535bf8748eb2e757a5ebaccdba58839d3687b546d6cb25ba772fb0badb6257a9 0e3df8b158b154cc168810e29a240899cc27dcc731fe6db3eadec91e6b19862e f95ea3f6fce88e518e1790330a86c46cf147751e82aba75272c68c13b69e952b +930000 172bd6d7dcf607a85ce287662bc6558e48961070c70d69abb901da0aa18525d0 c0bb9727c574249228d4ebc997541374d7c7febb92779cf951465a2190103d31 00000000000000b792c7354337c37a207b39574a18ca33db9262445eaddab28d +932000 901491592454428051b24c8ffe920e2fc0ba8267ca625ff1b3c16fac93495d8d aa6197e99bbd0069c4ee7a96ff49db9ede5ff746dadf90b2e4eaa9c49f7b413d f8d1f4c72ea89e61d47809d2f46b7ff2a61945e62a397f0ce2072f6aa87077aa +934000 472dde05b82ca4ec8bbbd87afc5ee789a86c6ca4a7fe71a50920c2b7a7b4cfe9 3bcc28fad65b439b9d9a74c941ab8f201161c5e93c5995cbdac836314561edd0 051147b41078c9cc491bbe6f7748058919480a7d40197ab8a6ccf3a9cb40db0c +936000 58c77b73f8ded5be2589876d032b6d9e4f67754f40258165bc3dbebf6634ccca 79cfd03fe445f1a26e2c2b799a486c28435987bd5f58fe227004fba70b86aa3c 256d7c28c872ee8b19d34e72f467c1a5a3e52fa242f3eaea3573fd1377a8cabe +938000 41493218ad95d156c2837a9ff283d476553b9fe95b2833adb0213180f6ecab53 f754852853f33ae0e0d6d2712c2543bc075d4bab9452147d24e8a990ebb3b2c6 8f5169ab907f36e31b4565bf2878ade8068e079166e4f7913faa7fd2d0fbeb24 +940000 6018fbc7ce578ae3efb9750bb24f02c786d0c1c39c553ce39264c2f5b85c0aff 16e641784cf79ca95b51df0eb8efecb83907da6a84987e489c20ed3249907dbb c6c9be1d0e5a57dd1b8657523d4ba946a673c4a79f97fb142d2a0aca9d3a6fc3 +942000 dde513c528c17a61e43a8a44124ac43b173e599fe3c2a984ff8274f553c1eb70 9c796fe0313eee5bcd3bc49a00b8f7058b7c195f821ba00ba7607bc8c16e23bd 51aaf2dd2587c0f6b7ceb75d448cc73cb6272ab9eab950887c0b06598a64d2ca +944000 25e5de8347644027572ed2432b6829818a9e8747ac76d2a2941e84336c1e6554 f937def35359338c4de7568108ead77528acd7f4624bd839739cf8a5822a23ff 76ba46a62e13e250a121db81ceb38f02ea42726599ad8c08977381021d6cec0b +946000 55025daa8202beddbe413927cb83b619334207a5e8e03dab45b83ef0de14b8c7 7635e377e010d47b5459873262fdf0098e5ade92089a1f5d679f5a36ffbdca44 2c82974810260f455c267069c8e61176384ed04d232e14bd9fc6fbb47c78b419 +948000 240cb3ba8670083fa4121c0b3417205c5d663468419325da914526208d8db3a0 49c5b30e95246e98e1ea1047807e497c67e3714a8f35e585ccc67ff506257f36 e66e6de474f3a235e7d72c0af96d66c61ff4ba6c67e0758b56e0c50adfb41c3e +950000 7daa0be3b5cde264c65a8967a6c48f89c9286fa33cead08d078716cded4ea4ab a91a1bc7cebaa35fce2e0cc7754c4bfb20a59776e80b803e676c49bdae11aaf2 ef2771eddb4ef8138a976b51bf4bac1c7d7eedefe7ba7e8798b2b14de0e473ee +952000 398ba89c72483ac30ced7f45e8a2c6305449afdd19522638e8237920b097bfde 8676d55ee5b5ae51cc746de70b1560d912e1e3b8a6c5764f67987406b6332330 d717432c5cdc8fb39f2f65c066a16f91e98c8a79a8a7a099bc3372d68d6f880f +954000 290078e38547150aaf284a335e3fee28452918cf9e6b573cae66e5bc707047f7 cd390bf2fdf17dc1293c031fa1c01638aa2657a6f174e4ab3fdec7c95f4ba1e7 00000000000000ff98fcf7694c5863c5733620c328ab4f3f82d0b82ec24252b4 +956000 00000000000001a49bc5bcf075140807335dc22be20cbfea7f1efeebb60fc39b 6b7cf312314d36792ac5886a34cbb6f43047f95d267f59df5c6044e223e571b0 c1d9cdadcbb649f8479de450aea28577d43c147519dced9f5acf783c510d471e +958000 4a9db4da0a0815798885ad397b3783f0ad2cf5646714128143ff5c01147e5f7d 04577ce17df57e251ee50d58aa3dc5130e3d67a7c1293b8329e4c847061cd6e2 a8949e654412e23311ddadb76196179e4d3ea07e7b1ca419d89affaa83fb4720 +960000 5310ca0111e2f0af6bc83396a8da20001c51ddaa4b71c802ffd07653ec31b806 cd5c470182b2e43ae662935b878cd798a8611b40ba93de822a2eae16b55878bb 16b16e4a93f2a7d47b8a17d34fb80a78b841ce7396b93197cbbba8a693f7372b +962000 441cbbb9f99d05a306a011f220e10edd8cf925618bbeb8bc89b780c4c4ffd180 660f8a1274407330b7db5c5f2efb982c4db38f5d48074430ddfe6438510d2c24 5834f8c5cb168f9617ccfdabfae6078429cde99a39dec00df3899554b66da7ee +964000 a220bc59e7ee2b9a2526a7708233bef12452a3d6d86fe17b1c5b1635765a4c56 66cbc126ada0b4bf9fc80afaa9280ed599c158eea34638bf6308311230ae8500 c65a8e473a78852e695df68e63fe8b9797136a44fe9fed5f173294e339e01f14 +966000 bfdb632ec93ca7037353de20697aa8ac8b4fc76e10edee9644d6d7f2561092b9 821e57befb99b405383ce828cc4b8613f70cd91d85285f0837d8b0a0ec9421cd 871659a2a77b6e11482b1443d486c1d01d25ee0d2902779ebc3081d445fb1f8a +968000 a9a9e6af091e2d14c41aafd5e7436c1111caacf32e626d03b7f888b8afdf05a9 316878afd8fd8281b8800560dddc1e842b0c2b7aee9e5a0731fd87ad234ed624 3f6a1258c025538da78cab3c475e1a79295b2a830da6ed204d5b323069587dfe +970000 e3feda88979d03671cbb3d726f977a047a9eb5bd6481e86fe0ed0c316468c2f3 7c9380793bcef461d80c46d96c2073194eae602be019c3a14e85331c131c56bf 7973e51f58977f9425d91ee2c97d7ea023faea5da1d026a1a8a5be2735a07852 +972000 73feb1f65facd62d445243481fbf74e9d28b26542961834525e01a0702c43ba2 9cadca8d1f84baaea259705ed3520933e822fd7214be29bab8a7ca394d604bab 988e49345f17d408be168046810af88df15906360c05258ceabb66f62bbcb604 +974000 0a76b2a25ffb0a6f477659700571453df3ad87870a4f69d2279a4b10d75e518b f2f4700ec86cf9aa1cdac8ab299d172592d7465cb903c2beb692959b96317668 0000000000000257297065fa3f78eedcbd7a3bc7198441be9920863d7e9d5aeb +976000 d999df4ee4281b2e8df653b6037bb8c3801ec6325b3d3e07e961dcc83ebc130a 7aab973c18edae9c348991d2cb76b95ef7704571e6cd5789db4479b7ec68c001 b9940ef2ae903d58ed0e8dc588d7291fc1de697ffa421430f68fd73ffe3418ee +978000 a0c40c6ff02d8eb7c1029888ca4a44376276440f1d75226f7f1073128f5bece2 ae2630cf30e7abc5e7959ab0e298ad817d5fcf88f26ef505f22a438565d1e390 2e03090edf3fdab7011911bc8ec3c813ee79cc6097f37dde3b4855125410ead0 +980000 00000000000002cddf5b7ee51ce9760e05f0ca506cc5ff4a7ef746ace1b786f7 65810022a673dfa935a18f0db60b2771cd37b2525fb8f409d4df8c1c8a88183b 00000000000002c390298a422374e1bb924b11ab93e4c000e476c8fd3ffb1ded +982000 635979909809d861650ab5c78346d1aa30324350effa12363f153ad475e78678 4aeb15134c4c75154b21bb443e0dd4fe2dab680e76ec9f9369baffe910eefce3 217cfb3a6a93cc8e9b75a91d3a82462b7b52b7c9f4620d2ea2ccd85b496f4ad0 +984000 c1f06b6d5e56b12c6ac4c64dc168d82fd4394c7071529d9105d724aa1efad19f 0bc9dd758b54804bc65ed9140c9362abb75b70d7e2dc5b952f172abf2dea0516 ed88ed61a4e4d60a72934a3f78457243336672f7fd620af04896baf063c59bfe +986000 0f530cc3d722aaa3510296f10449f04c1c979b8633fccb2b09108dbf3051316d 1eb5af62979ed1cb90494da19265009fd80d2d76325917062a2fb1d57b33fe3c d5deb337bcb6695f753ee0a2ec896a114033d1a867a66ba88094d97943a9d23c +988000 9b1eb252157f04aa6321ac0a5fc1e560c7a9202222a14f8c3dd63c880bcdc953 e9a5c87fb9bd16c4932485ffc3bbd3c612f06ea045a5e3e9552346698b68f4c6 3ebf5de249b54b31aac14ae008d2e3fd369537288699531a44877883993dfaf4 +990000 3d607bc5af041d1a225a1f677431522071f8d8cc16a96964713f73a0387cf4fd 3d53fc98fff30d95d7fde8e6c8800687f21c44ea58a5f8219ea56f382b5d1fbe d2651fc3230a9c1588011d21f1f7904366beebdd42c0a77b2b35f5217d0b4d2f +992000 0000000000000d7d93184d6fb315b9911c734a3aabcd54f8a0e7d8f95c33a45e 8ef9ac99ab76dd3abc031d92a362425e4b84bd4b45b922933b723e1fe6390ec1 f3ac72254a3515f9c53c073327add651e6dc7de374afa7b6d248b68ed6373155 +994000 5d48eef5c6a9ffcdfa8bfe5a2dba6acc3e6a789337b0f0d628f3073651c3e5f8 4fd6db2f41baa4aee36fe1ff40d82e7941693a575f41938eb5079a313deb7b7e 98301cb8abde93371dfe19deddc48a8528db9b2b18f370b66e119e187d112f4f +996000 f4dda8af729fe774c226a8e3400495c17b97bf502f261a9147d84a0812e1a485 9560571e369fa1bab46178e37520921ac9f3135d70ebafec5ac7ae5c78467aa4 000000000000028fc946b871dd67d6e075acc3332c410d6bc20d95b02379d96f +998000 cee5bbe1da15d61a296cd0f4ff49ae7101e9046c5c51fc595166a4f9a5f82dd9 6537085a9a407cad75093674dbecb341ea211198bee07d1e4726ea39487aee6d 00000000000003b5c5a83cf32073f42dbc5554f88ceaae2b6f73aa0a458f0c31 +1000000 b85849392739f50e1fc7568b16eeb1bf37f36c144d7ec46340a4c8a202253ade eb9f5805aefb2cc3bdf77c3e463c22051c1cdea5580605a69ebbc05bd324f790 87b9625692f3dee0af767de3028bf1eeb892ec367c026403c72e11532364b044 +1002000 0c03f6c1bb341f5411532eb6ca414a91ed09869e4e3ed949a6177a5c69134ea9 75e1d11071db13e31a0091fcc8215109ba4ce45dd8763c1caca639d7a54b9e8d da59898d7a92b9f5cac35b0b6577343fe894c438c9cc648d2039d7328c9d3826 +1004000 000000000000060625b5b7fb7686951fb2216c098d6c62ba835e8a3bb975fe82 49d3b69df248ff8c68d9c402756aa656b3d929f198ac03ac045b1eba60a89117 4e479d705517bda43259d6443c61152933d61490350a0684265d7f5fad6a6245 +1006000 b55609b383101301370fff20a56ef30a4802ff2650604183e2c00f3005a54307 fe03b93ca9e4f7a951c879dcb341b058f294efdce6e1e7ef15545280eca7f231 aac407707e841cf6a259a0a28678ddc07b24ec23f6645381597462c023afcd18 +1008000 0000000000000c4f144feeff2e21e7177da0dc66ff0f4ac690b12b5fad80a92f 38be0a7aa91433587708d93326d2d30d377689dd7bad4cb58168f0306d134f05 e3d73675291c533eb44c9c27f20d105fb49223a97d5c15f0264005a6f770c018 +1010000 0000000000000394ce11ffccda9a68b501e1ddd156892c186fac9bcdc8caae29 98fff788d4c00575bd7dd96dbc3656f7b8d5d3c43c737b49bf1229fcb88c88c1 32b31e59b3554d3583483cd918df7e8cc7d15df205da84b09ac330fce8610851 +1012000 58beaebcc1a18ec99439b8d2be685d9cacd1cd574ff0f822ab960e0897c5b707 61d51bc4b1e27bc7a8ec2653895268745d6afc998e9ab503e2b6f65baa9d147f 70916b7ab9067188d0558d20f5e2eedc8cf5ac3693620e46f05bd85cd9057356 +1014000 c600046e87dbd737a37195f379583d4cc8f3fa04b435de9f1ff7e2a30b51cb15 879e0278defb37b923be4a7bca396491d6459a5357e9db8854d0f245026e19cd b40a80ef78da9f3f1ecc285f3ec8dfcb7961f3192755e81ea7fb4902965b9f88 +1016000 0856bdd80e0149f4af0592667a272a339b6bd6d697e650539045629e4cbd7253 93394b7a2758340a85754c8736be28ccb3439577c884458dbff238736e860cdc 2d251971ad89a0a5ee589ad498c11dd8d618f65f5e3ea31d017c06d9fed51a7f +1018000 0000000000000bf86cbe05c63c06d833551ed6d5dac55ed53a20d3c6e1d9d449 18a92e99db7a058f28ba95faa0d2ef0b431ba2061a285be3886827ea8ee1e319 22c1974395165017fe1ad841f3c74f6de52b73d9b5aa744f1c878e2916d616d0 +1020000 5b9270d90237b1a9d35f5f2afd0ef9b5b0cde3ae96f74fcdfa98c5c4e6183457 579aa6a6ba753edfab67bf754a5b2a6edaf6905a95b80b414fac759dd6973f8e a58eebda7851b1d153dd14992ac66864479fb28427691ae60ae07e595e86b61a +1022000 00000000000012668bc36dbeab617ecea31fa2135515ba42bf029f7e560efb31 54f2b3330ece0f8033695371cfb11bbb09bb26d2c9754fe197f7426d7b277050 e1ed760f2eaa6c9c3a3edf7a17b7144f23d78c5e7cbfb4a32a3589c11b2b2c92 +1024000 000000000000073b4db82d2532e8d7eaf3d7b6340e8f91ba2a5baae5d8704b08 2306d3ef5aeec0087548488b0debb01c9652da85d02434b060299caebb3496e4 e8155a34b9ea77b20f327477b244b1d5645422422cb236bcb70c2360228ce21f +1026000 0c71376d1f9b4a3a5547e61d0c18a61e9fc326806f5bb70c3ddd03bbadda4db6 ae8801369bf61045aa46598c7e649e5b986e0736e002ff0f4c79a7c950144d9f 8d33d40f85dfcb8a1458b91e54b41263d3326263e23ea5095f66e8086dd889d4 +1028000 0000000000000010daa0b3fa6df924dd3710296a1b984fe075e4279a470f5e5c 8bad85396ad123bd32148260585cc8bbcbb7e084f294d78964e8df28330d3324 00af944cc5a0b1edf1cbaf1ae53218fe9a2465b1d5b0210927a589b376f2fb32 +1030000 00000000000006611055fdbf92d3efb1db1097cb911ce317b889e8e254165018 a3be475f58aeda5e715b5acc32ee912609b68e5b7407710eca8f6474a94ebd31 f44b1f585d0884fffae4dd97e506cd1df134a9a1c64951475d36566b200dab9a +1032000 0000000000000319b7ed3c866833269154192548eb46cd9c4b4c1cf844fd90b3 10aa3a5023488f0e7b616d3152f458cece6f68491657dd60f2b50c3930ff2c95 ae80d5454140e37dee500740bca2ed77fba21ad469f481e537bbe11e303956fb +1034000 1fe57e29fe2aad7a2e772eba0b0442ef34476e6a5fdf2e9b338370a8ba209124 efbd28213eff15abe23640ee62876d4ab96a4803977cabb5e67631e11fe75ae1 24ae6ab43aa989f35de54b35df52a4d934393dc6dca160a32a3a7f398f3d910c +1036000 2b5e5309eb6cda0918bda3ffafd1829cec0d26d89820fea29d6b0baeeb3b883f 650b0ee233666f9e73af4a6c1a0232ba9577554cfcece2d16f50556a0ce9f8fe 4d95452b89babf03fd3d800f1c57db63b3a062c6896b47d8fd370fa8b1f1ca05 +1038000 000000000000081622cb843b52c753967a78b4c26c74b72290cb6d0afda16dfe cda865c3a653d5bc9d0ca0ea2477e26b2da7fefcb8f36fe80b126405818501f8 1e4927b5488f619976ad5747f8309981817852dff936cbe537f1fa56f69aeba6 +1040000 e41d16dd6508f769490a4a006e80c06e9c74f0877190a910364a7e721638c2fe 95c04339f14dcfa85e4a6dbe7869abe922548fd497b81ba2f49e0ec7f3b8e103 4f3e0ba123afb1a08994a70273fae6d7cc59cc625a410ca064553a3c8ca40502 +1042000 2221b0e25d76b6f25036f06d2546bc6109e69ffee8b9000dd02b600d888cf6bc 9c2f4786de717179887de51371346e87a72963e73f991388bcd3b9104189bf63 be895985fcd58246b0632c1acb9d9f5bf5819b727aee51cc7d22dbb947942f4f +1044000 07abdf1a959c69ad1cc28c95b2509f599f3a4a8479cc5e162b8285490d13d123 db9221dc8c1f3cd35f884b0b19da4d8fb0195eeefc694c0eb7ab6aa952815c80 953e93da8adc6b13eea2d89cb716a4dd83ca4d8b540f8bbf9b3212b6e7228899 +1046000 0000000000000c297f92e8e2375c07624998751479e12ac49f8cf85381cd06bc 46d11a7fc825933db66509fed8646ea42a5d117fd5ca33fa34271ba1430f5f71 932ffccb0d539daadecbdb82c191e9483afbbd8732a6342bc65bd15318e99ccc +1048000 1598448a15b69cbea1ed2dcfdf25b072d1552b1ba158b24553723cd511e7cc6a c9c9ac2fe1c6e0119665e179a4c4cb717f66dcfe184a98907336569ccc7437a7 cc3b44bd4d05d3107e1adc395be3cf7160fd8d32cc6e88c864974577f606f032 +1050000 1114bac1d986fa60fdd79de041a31cbd1777bc5726115a3a32159042eb17e92e de52d8cc84d835fbfc86404c8ff3e07218265cee5f9acc0baf0ae3aa7788d771 9f6d1c49bd2cc4f81d6aaa1b35e0649a5e9fb0b9cc48a37016f5e52061fe0f8a +1052000 8c66d24de25fdb726c6af543e7b27a979012470f77a9f205c01c88ee8a7fc238 668a7c8798a6f3b14f02d1dcf7263b752214f4d5957f420b7ba8ffd0dee36f9c 4ec4c0dd228a7f23c4bc54734309c7b1a9827c6f94e8ead5fc66fc00453ae4fe +1054000 e8ab5aa10d26dcf6fe495b8d8f8f2a33a277d402fff6fcf836f4b91dbc319451 28fa280a499a5ef899de1247490a2d46f782a9b7985d61f32beb194c058c56d0 0000000000000860d9c295363881fde577bf228c080b6ecec3ac3015b519659d +1056000 092da3c55cf82301e4f4ef1a2a791555f10c0d8160c1c48c945a3634b24d25c5 22676611cf103312ca2aad5550519d9594e051f9d0e50bd421955785bcc5aadc 93ab4864f5623391acfdb84244a9cd4494e64c5b305f32dfd5a9b4fd3173e973 +1058000 195f70372171cfdc14e0d7bbe5018204fcc3f635217d9308fef7619c6caa1f78 1e4af7cf3dd72750a44c0e5e0a82adcb6c0f276935c02124429cf99429781b82 00000000000007596013979a9d5c1d6e54ba578ee16773d879821ebded8082b1 +1060000 00000000000001d7c26a3f56310db26f5aa105a5006bd5f965ef5cf4c9401c01 2215934493fa43f2741364f36d076d6031867f0f7a666185ba352475af9446c9 51332a21fcfe8dbfb1f216aa9498dcc92a21eebbc36a46bf43b75beb08815fe8 +1062000 8dc898cd0715e764fa75b5b0748958bfe01f4f198cb410db94c4023b4abe28ad 3e590e1bdae8b87a0eafc5ee2ff5e578d8dd043f46f8cefb3beef9b96e5866aa 00000000000000185be9aa3ec3ee69b3643cec07bf8c6ed151f5560d622a627d +1064000 00000000000001beba5214b67c53190cd1445b0b948d7af772e7f77d9bdf725a 920be11cb9978cfa503d015476af6650a234a71ffee114acb7993a81dd891884 0000000000000256be46091e9d9b69aefb48351069d5af9b953d9d4214775550 +1066000 e04b5fa9430f1bb7a1db66f529c0001cbe7abd2a12d62ebea8c9f7d248a5a1c8 ea5fb6d0253fa47d6773cbc9e4759de56b24d589aaed091422246beb27d1734f ed49f99de12afd05d7521517272c7da95b7baeb19c5e34ba7d003fabb2e9f798 +1068000 76068ecb4df8eb6a14ba1d6d8c81b939c4062426872d59fcd777fe1f4899ec6b cfb432fabde3e907603acc100066b3ec294e38f0f042354816a4ed211e1dd71b dfaeb38d55221ab1224c27309c0adf41877c6c732845db0b22bd2b1ce44a2229 +1070000 0000000000000d1802225f532f4d4caeb0a94b31ff484c5ac3702bd7a201c6f0 95cf9850cf0f8262fbd26efcad4286e7bbd5fd8dfaced99dd5208abf8594aa35 0000000000000c2ea185b551bcf817850e9d509063cbe39558ed0339b422c34b +1072000 2218feb417c1a268d16751ce3a4f5df1a1f38e3a091c80c0230b9c5093f5d048 5993ee97d0be52513d38ab3cf1a9e8cc05d48d33ea3607b6160d824eea458ee4 cdc15ff076e0bd22c514524cc7c33dbee994cd217d30fc40443415519a43e616 +1074000 597e3869d18889b6fded0306bf0b8c3869ae5ca167de7198ababfe914d42fa54 2f96380ba70b3961ad7bab468fa042368a09d60fa37b4aa32f79242f4f7baeed 5781619163a08060940d0810e9ec0bfe6c3d2c4b6b8e35374b315fa2380da49e +1076000 1d282ba524af1c0518fa5cf399646b8764b5caeca4fe39796225539bb0541a71 1b60f904e7c114144c23a63853a54c5bf70e44404b31dcf83bdc7d2bc92df7d9 4e73c1c9f06dee0a4d495d19c2167942babe56f861b282b04b0212cb59a50e02 +1078000 030447d396787e870780a0417b98fc65ef74c425cfcd2712773c77dad8b33af2 7171008bdd5e0938c426832673fd54c46329d5b31a444075b7c4a506be14ff15 00000000000008f782ac3e10672a852c53347ece5960c59737ae6fff1afd274c +1080000 5ec5344ba3e65f3ebae8715007afe1e32f5886fac01da90559b8e9575f55d18a 7a7e057e3e0cb25a716eb7d6d6d1cc49c062ba7c08debc743d4b750babfe8979 159839326c12a8daa4b1ed4bd32a43f7153a9e751ddffc6a68c95941023ce8e2 +1082000 a389955877b15f43fd752e02b9df6a6d189fb8008540ff3980bf9b6cb617d87b 567a0eaa3dc08b26605cd0522bd94033e1662009bdf4275ff8bb698670f18b2e 603fb141952b9c988efb067097a7152cdfb919056bf260d557282b57534f1009 +1084000 80959dcf50c331c71d7e915c16b2ca0d7105aa8fab573a101e3ea59732d2ca32 f0df9cceb73ae311735ea48988b352ba3a4a8a44a46c87b6b05c853c127060f7 2f7f5a797dc6c0699bf7073908959f5822e49656cbde10386fa0930b52663493 +1086000 6661ea937922d60d6b1a10c967784c3860eb8f957fe07160aa81938898a69992 7a86e5daa2c6428789df9234f33b5b44d6e273241f32176e98d419e5fde2cfd2 b1877b051847638fe9fc29da4df5bdf7238ae09a8c619145d376abe4ce61a4ca +1088000 62e7e96d1761aefe5c9cc7eb0d2ee7206eee1e5f34fcc4a9597940ea406bc8e6 d48b8354f2ea6f0f0ae1e3494715a732cb3ef5daf3e13f793fc4ce97bc3700e2 7f836dda0fc721e11ba4ccada08b276d4768b2de62c554b1f81697e41cbdb571 +1090000 7c4c9295270bb913dfa5c15469f7c42518c0f88d300f6c3b5cf18ef4841bc060 112523d331f3489ea4179e434d182b485b39873926af73b892ab689e0b2d8b4a 3bb42df76584c121399d189fef4bbbb0fb391e40723959b559b508c8a0833d08 +1092000 a2ebd6db4c041cc39d5134ff22822a57d0a81f945e34149e83037da7f33b6628 aaccdf13cc0b64a412052437a9822446ff6f9c0cc007e953b7e7f7f21e6b8837 981d4518d508771c9f7ababfa7f25af437aeb11311159d0962d5933a4a11b886 +1094000 7d446fe71960210e7358005d8766da88afdaec4ce4a2c94814e36fe6da5e801b e2f4e1b58c1ee772a3ac53a5cb870012ab897162caee6e818e937ef7ca6a2839 df6e23f676bf0703536c7449f4c56ce56250a67bcccd4a587d5097a601853aec +1096000 8386285cfd7f66db3009f006a582fca6838bf6a9326b705b60d1e07bccb74d66 061dd554b1be20a7f99f4074fd1dc9141ebffaf8079a9d254005a4d8e86325d6 c35f9719a798daa2b8f1987c97840d6656d221fb6ee0c119b4f7667d5cfa0eff +1098000 f10bf94330892cbaf7f23dc80be6f03cc497c1b8ae49263f8de35d93f718619d bf00770562bb1e64768f7550b90c32edfe3072197d04076c08d638e02aee71b7 efbcc183c1da39aa5c136e3cdb0b120e68f0a3ea45d2318c9af93b6a01252bdb +1100000 b4b6536e012cf7f80a6e46d8801a5deec3106c8988272be8907f726e94c38407 4f3001895ba1381c925eab9bef4751be3a0b60047e467a0aeff65f9e0d08dd8d af11979060b419606e3aad3ad3c38c6cf1da7518789a625db2b6ec6a2879227d +1102000 f0768753fc2d8ae67d58e23004fc4044199800425d517dc22513502115db33b8 45b3416cbbd86f7190b88383e01140d9156a1a2c8fef2ce5a82414b976eda6af 513df17032693fce4357e5fabb9ceebe4edb18d8858a5fc89a1a08e52cd2fe47 +1104000 313c1439b0ea902e116cb6b79ed85658284a705a7d979ab990961130d0ddbf9c 1b129dfad460697708f2f15629b7f5a42bdb7a8a3103e21120d803a4c96feacd f6e229f2b1edcb011aa9130374e80c5b4f83f164b75cf4000a2ee09906f65c5f +1106000 eabd68445982df7639e6eff67957a227557eca51a5c15b85de66e2eadd90d7b0 9d8c020b72e04f8dc467571751719259f839e496473117ffd9f18bdffdbd4982 2b83e7a26471f9f1d2ba2e65dca844285cbb5606d968b1145d8a70a306424106 +1108000 16d0bf5b114325f456aafa5fab364a30f7f6c163352ae37f5e0ee95259972679 cf184f1f0d19ae408ef42df2b23e00bc0d00c8501bb9cdd6b3b05c5c4a82d3b3 b822a8d6013ceaefd565676f8eda7fd2ff66348485565114a983d715aada5898 +1110000 5277c86460a0808de9278dffcc900161895214d9345b57aab06dd0b70707120c 37729fccb89e71b0d241ad8f63a4620c29f660857bfb5798869ab9742332e548 b7a9258d04341e236b1ea6ca85e0da95c8d5607d54e2601e542bc2d878b39650 +1112000 261871f5c97cedfb3f78b57b2eb78aef51f4320196cb85397fbd00840cf013c3 ca912c400744a34fc4af03aa5f8c6fb3ace4c19d2e3a1dcd2c05f262fbd1313f bc8df41bd045ad12bf58ed71345526a12e26c483535c3e4acdc003ffc2da348a +1114000 530298bcd36a231d5c0d5fafcf5787b1d71ba2e009282cd2231aa6439e60a8d3 4c3b023faccf63a36185db533ae7f5857d37cbfd295f8163e300fa70ac9ae8b6 09659fb00a4277ddfa8b5c46117cce0cf82dc0560834aa8c1cad2455d6ac8859 +1116000 ae8e36ed8e94ee103e84f7726560162f6e285836e93965aa3b6ed02258d939a8 5fa77d2d693e43ec77618f57836de416cfec4770ae8b48a63b5821114f3e80fc 81f21e65a6bc754b2046cca76b08f8f2af7c715b9fe85d1b283ea6d85bfbf151 +1118000 485d7db1e831d348a6995d5c62a5d637661d62ce2a5d664a4c53c5e1a25f0620 66958330956f0fad1e1d649c82d103adb3e66dc9243e99ad05c422ffc7c388a6 9a038d33ad64ae44a6a5f0f998c375999676b2cfc6c99d7421eb67ad27f434c6 +1120000 91e743524774afbc588e90589baae89cb79ede724ada964802468e205521b09d 9cf86e87d074025cd41a8e20a48ca2b23cd31009fd23adf07496d883fc11f666 0000000000001137747f36d488399dce08b09f19bd62fb23aae4150509c10bff +1122000 95a60693f4d92d2467c5e7cf1bb6255c7a2eb209901d39ad12203742c9b844d3 3d13d244779d039b9c2d52817c51311418f01e93f4bf9b995c2c1eb6c57a5b5b 1e70d1542532c1b21f8aeccb2aa80af061d1204d2c12390bf471a091bbe7e621 +1124000 e60562ba0682ed40c22322ffe30dd96b33879ea733f678d4c549ec3214baaf94 aae578721cf956e197b7c1e2526c4bcf4bc3763222e75b7719fd6f53275afded 00000000000001d1343ab9cbed083ff4403d24b0b0083e19cabd6884eb6a6972 +1126000 13ca43f85b0e04fc0c8df2ded068a8186c996cac62b2923c5474c2e1a7014994 95c2d4f99118dbfeb0860840a6346f833f267cb042e6dc98bf081ebf27dda969 0f082f93ecf510b315eecc510d57c193c9c637fc4b6f694626a210fe7a0e40ab +1128000 0000000000000739dde63f402e4b72f183bb91779a5119e53feea6f3691accb2 723549dadd2cd83d120f7a0ed7975c702a6f950ebec9f2db5acdd6a9bb23e9ee 000000000000086aa6d6fa1d1cfaee4bddab8fd6e11b8268c2d8da508127971f +1130000 552a1d6e13e95b1107cbea534875f3bc5c9bfce8a5e3a042ec15a6b9529f793f c84831f7b525aa5c0d74bf377ad2c09fb04865859be940febab2f9a35894bb9e 1649b6591d31ee7ae57258bdec16e34cac3971aac03289566cb668b416dadc3d +1132000 f28c51dc41cebb8f4f6aef464073c1a2fac7fd9641824041f6c72acc25243b19 a6434b5048f6e2c3e182f552f6348c4298989f7d313eab18bff0b381037c3be2 0000000000000792abba7ccec188d96fc583b2311ff3b78fe2605f3d3c3f76da +1134000 0000000000000bec7381169ed4acbf804504d340cc1374852165ad258949a315 1233c3bcfb8bf1014a6f18a9fbcdfa703da1f4bd6543e24c9e1fb1877fcde758 c50c932a53f1336f900c4fa0d74ab0cf28bf409c564eb0674c59f9446e1c5d72 +1136000 00000000000000eb11ac1426e1f3264cda8ef0ba4c4e7a1748c7188d74105338 80211b657499278f260deaedb3aab2d79773a96c086b236f59b9d3cbb1b73283 d7a39a7b9a11cdca810b34914d23ceead7d4d85351b757099ef1f8d3725c0a85 +1138000 c0ef4ba022b6c5fd2bdc9567d3422d6c814bb2dc0d109e4ec3db0e55a9506d8f 31dcfc635ef11ee5a348990b4b12ee128565304372cc4b66027e23cf11dff0d6 a6e3d5b66983310ad80baf2d52775b8f26e159cdd1f76cb39d2093f298fa79a5 +1140000 1c0bc261ffc8ee8dda509e556e3eb16fc026343f235fa686f223ae2232ca0341 bdb25a7756173a5b0553acb89a5073929f05c1e0f8f5d5df81836ed0432a0c18 88cc256b8c66b2c1834e41b2be13998e97c072a27017a07021fa573ccd65abf0 +1142000 000000000000004d6e7e5ba6a62279d5c0b5f564d66b75f0a9bbc441265057c3 8eed747613cef4a4ebf0997e33371d7920202e1469f3b1269b1f2e4e644059fe 01019227fde3da6b7a0e29fb3050a2a635a64bda474153e6f9159c6e569ae3ac +1144000 a09b7584ef29e0734d9571d5e11f0a65ee8f8bb175308beb06e3cb5663f4c117 32ab004335fd89d6dabdec079c23aadc60b8ee258497989b0a507f12979e93a0 51f4e3b0e6756cbe3ccec57b1c3e2518d2d5b9b95d79909548e7d18d0b2f735f +1146000 bca3edcf8120c3a0f9dff735434b2a91e5c556f1058d7e82019529d96d516a3f 286ff3d66ba01319b1f25ae1cf6456a5d95720d1a167219543e4c6074a3948c8 00000000000007a6a3a473b6cf577f24f9e42be5e94ca17526a381f3d2169256 +1148000 5e5435e9dfe9642691c8eba15b9da0984d690af023ac97e2112d1ec67d83c4ed bbde8f7386092e47180ff6d35d84a1e44693939717388a0b929da98ae01d655e 0d87282ae733ad34ae817b7db125a1d62a782266057b8b3b8f67ae116960d794 +1150000 a9a663e9c678f88f7bd1026a31c006cf33f597bd24478af85b56ac902c5c85f1 34a699bc669691dcf4df48b44301d2e2befe1127badd11b04516ba413d4131fa 9e48d4c32a5752b50c7ea80c5de6869f66092ec5a387a648c2871e73ec327164 +1152000 0000000000000bb8d87f73465a5ab2abf1d8c970e3ef9d48d81289b903d2f69f 3ad1d33c4df04db4b68e92c1dec531bcf0a28691e7622e97d2caf3adc1077e3f 2075af0b8aa6035b5a346fb2e782919894674d01b20000047015aac29bed74d3 +1154000 f00ef49ce8e5dd2df0ebf09148883d3ad96d0dfc24a9dae3f4043886911fa549 9bab858e0b5045e6842604dae3b20356afe3cfba5f4dca0e32a988eb8e511d9e 00000000000002e89b57f81563f78cde364aedbe1347bf96fca6d7ffaf329970 +1156000 3b918e8df426f736b3d1dd0f4c801b1f8f260bcee9a36dea3160300c9dc05d6d f911aacdf8debf8d7cd1ce35149ca6f5f5bee9fba0644ba4ba095259bc94aa39 5cb5fbe5d95204b9da8f5d8953f76480737fc2ac12e72d05fd4db61d2cd8225b +1158000 e0234355083321bf4a21282cd6e01a8ff258a3f9df1fea85497205de61c130c5 19b28788eef1cf04593cc19f8b2087721fd3a274763f209b379bf33cb2c05f13 4c2b68a23d4998962edafddae8101861942b4e7ea77b79f630886f733efe29cc +1160000 8fadec3454b2072ba4e44d06951ea54d31e74e0c9172b5d5e9b820964f06dfaf 487ab043da3f44fb4cc51a198415add6f50157aa6f4a09fb11a7c1fdf7ae9fc1 4a40a8a2e8663a5ac5798812cd55d1a6e46cfc3fe38d21490bc2c4e4064d9aee +1162000 7ea4672a87013b2b360f14d385e6418802fb5dfbeb9def8602a2421b592439bf 7e5e7d1bf8f63201d7ce6fa7ac613644d681c6b48d7f7dd66423ec00dbfd4b55 0000000000000d1333741743b3a3213490bbc0bf9550c9949c76a2509bda3e04 +1164000 c5af5f48537f80e37749fb852b8af46d0b5fe1162278128120e9a2170e835d66 93ec97668dab6ead8a616c003c0b38aea86f153694d800fe0f1ac001500b6757 64943a2931ba9811d6689cb469a1844d270818149e9cc376d49ce5ace10b8953 +1166000 348a09da551dbcacabfaaecef80a5936bae9df2c487df47afa358570d0e28ef1 fbb7443258ce8f28078324129cde443725670180bb41be20bdd2dec711e90a74 0000000000000a76a0a26c6b9aa9bfc8944d2d05a82b5c72f7f702520983637e +1168000 dedefd9a8d22b8dfb26ff823bef38087d047c0fcf510883149359222c8eecf05 d40c6654bf67c9a539543af8a65dce6c31f01cf8b5eadc9a53729748174b3699 41e155472d195eb88b0e3022aa73912b1a74e0f4ccf1cfcb5f184c48bf0b5756 +1170000 c15fdf4c824d8f2e6c906b2faebd569c9f77503b8522843ccb06e3887a3b01f1 6f3dd4f0874be0a04f3d3b23fd28e19ecf07237d91699b9361a8b32b5189dc1d 854565a3046403728781c48e9f8078cc01890a7cd9c7a8e44a564f97b9f4afaf +1172000 2d9b311d5de93f09962dd63916e8a087d8830062fcc880e65e3eac9615498d82 c0dc4e93b3f45e8e02021d74e361c800c94911acfd5db520e920dfda32aaadd4 0000000000000294300c81b07628172a45607c1f9393f7417392f6082461b015 +1174000 97872301cfcd54943f1885d1f9a163c86aa0581fc8a27e756353648ba2d2ffbb 66c1d2712268d20063d866f99a33e1d1423348d6601f1feb819a8893fafbe88d 6a606841ac087bf9c16750913fd02ff9d8a6d1511d0d8257a4f050e160465215 +1176000 0000000000000b80e84f9874bac72abe29ac3c79aa5cf4ca42f63017df97953b 247396378ea01e20913558377f53b810dcdbd550116333819929649c9a26a71c 7e2e5eff6540874327abc57fd6058cd04f8ee8b824ca69bf323fd3f9d83f7147 +1178000 f9ad4bebbade22acbbdce8a5c94561a96806327f02bf9d32587f537dfd819d9f 2170861299c71c927bc75f7f47f6a104c14aa41b969361cae041905778dbd4c4 d2f4695100ad53cdf51790f6395e9c0dbfbfce21f37000e00f36971c0f4d0e23 +1180000 2841e96fa4e1febf8651681d3d25c1f544ef23fabf2afe3e17acc1aabaa9c4de 42a7992ae0394521636647dc342efdf79790ba17e0098853c3dc84289f399c17 2e3b67250135d55b6eb444a00b5bfbf3d43834ba71b6f2fead97ddbf1b4e22c3 +1182000 00000000000009c6293403b9ffd08ae3b3f3c97c99374ad09200e6b9e47d1179 2cce431706a673d0a8f75ffdd55b3e900e7ec2cb6bc39acd9bd19ffa151570fb 9cee55d2445cab364d9d95b15470b4f97e8237774a587cd0db951a4b5eac8722 +1184000 0000000000000a677e10bc06d0c5dbf69d802ce2eab0f42a7cd905e92564615b 1e4b13c1eeeea5700c61b6231b5d50e99b8da9b48ec521040c014c44171bd53f 41d28b1485be3f05a4a8b6e305e0cd5c04b470e87d783b3fbc0458945ed3122e +1186000 0000000000000519a4e39e9f6afc97caccdfd954faa64b2bb413546d4974ea15 a285bdae15efe7d8c0e3aa4040736dc14e64c0aeb5d68ab98f3a9fb9de18695e 5d763e91d1451040c50d2b7005f59694ad6d3cd31e48d3f32395ae7997376c35 +1188000 0000000000000cbecc25c00c1a7ba9567ae71358b7af0b47772bb9a24fd3056e 1e2cba42937a9b10d570249cc5cc0888df6ead46601c9400a61859b789a94676 c792c665a4f110ce2e7c8a675675e927e762697f9fdaa25802adb96a3c552455 +1190000 000000000000151e635c75dc1b6b417429a2ac94a23437ddc78018eaef13aa66 602f88c581d193a633453ce9a130e4ac0224080a1bae55969ccee90be8e81f32 3f4b4dc00ae833df37d7e7fc08938befbdb7304a217cb89a6226b5728235eef7 +1192000 fbb717d2204f624589cf23a2aa23e19bdcaf6d443ddeef82cd887fcbe90308a1 08b5c8c0bfaf399f6a30c4da228422b187b45b438d5696c693ff5442e123bed5 7a9a585dc253df793c19c1fd9bff1b91ca40a0cf0cb4292119a49d2e032dd225 +1194000 0000000000000e2d82fe58453cb52eab800972ce00391e42c750a998f638edde 31e10786bcee51f9f4a4f7df1afe21ee442374b91e2322f3fbf790a07adf9302 dfd0b3d5354d167c0a76bfdbe545cf529f6c1fca854f04db83d76d2c4a63fb8c +1196000 bb8716de4c5aedfd5e985368f28ee17eb92dd5b9cb06a139867d4c9e0313f1fa 8611cee4a6dab66b812e9dddc49f05678a35d87189368326cd02263c9cf771bf e8ab6b4391bdf086bd49c00dd6af6421ff59a70e00071119c99d3e2553ca0218 +1198000 0845be32374c00ff23d1eff031ca3a107ecd7653cb401bcd976d49b4e828c667 0a876856dcb7d01b9c13e80360dee9d12b08bb9609c33c6fd7645a9f83a9411c 4382058e2343da79d1a3439391d4ddeba35c6ca7446234ba52ceb74c562dd2f7 +1200000 000000000000083784693fa8994f64417fb2feb608bb2d0c93b60afeffdd48e3 5f9012746ee765c0359d766ff671ed3fb5953c8502c79c42027e82b31e193be2 92db7818bf6aee982c3dc73e95b92b47cb0cf68ed831930202624c3e5dce6f3a +1202000 000000000000047ee2205c023ed4017e919d4e3e067e57414d61c42bc1630533 431c61cf3705c206d164b8510025521db26acfc6f2da0a17609366900770f150 3933d0b9b15b4a925fe873f846046b048f81622d56567935372070b642bafd40 +1204000 c8f3e4ce9218330f5ef973147f097dfca37e6e55e55718afdc96f327c9690924 54420f5d3dcb334866709b61f41d58f63778191bb04d92ee9813dbba4dc12090 9a22b0bc8ce08f569916434ef2b80411f47123a1442bf23955d75c20ae104a0e +1206000 d990e40fc70fd899fa425257a1d0296a6d3196f703e179993e345e626125b125 251284b34fbd9dd9490848ac0b43e30b5a5612c47235c3d6db6885a46eb4994c 36d0acd932ef7bdb54e7639ee34a53dac5b8005218e5c1c49b61f73d8b9cb5fb +1208000 0000000000000d6085e6d3bdfa68e612db5e5c2a14447fc048dfd76e297e9526 d2516f8a9c7d9d8416e04dbe30612e70df7441f75d4d1aa1491ced085ea51649 0000000000000c055dd1dfcab2ca20b56f48e1339353f1fa5233cb98dba2cc40 +1210000 c73ea1d45b5af6fb010d3e893ea2d3edc840754061473982221f4fe7f497251c 4a4677cf466ecf3b8d883b3374f3fb57f0ba9c228eda6537f54b7965a0fbc975 554215337a19dacd08b295692e7aec9af5ad1932a71b1a8aa25291dbe8dea1a5 +1212000 2d6ab84dd3f247be4a0e11db8964b715f5a36a25e1fc54761a57c65549ddbdc5 3e871323e04277f8db69dbd8357cf24e2250c130709bd7cec825d68ca40f05ad 000000000000100b003d807a082b0e5c615317b331847d33244f2ed555846651 +1214000 e9a0d5a55c49e58aa660810691da4acc1c0a1ce2e1c1271584481ff886f7d566 b67521d03457951500db8bca64af3bc1a5040f055869b248eb240445465b01cf 00000000000006ae5974a8d305779ee978e27aa96fc1a0888348ad4a768e22ca +1216000 000000000000007c274e953282394a5cf9321323ae3a4882aa514cbdfec4b7e1 1e85cdbad00401bf9853340f54825a3105e7ec9f5243a503660f3590962ceea1 b81fea27e9cf4c8b82f5e93484e4e7d42f568c5c93dc93bae1bcc1187a810969 +1218000 8ab43a99ba1a130bf4b4e351aa05d3be6af009a51587c2d16963f4f792c1a941 fb07a30f6125ea5c26e57590fbe46fdaa5001b966c82b8317054d39a077d9c87 3dfe55038c6c770e0806219a6b84cdd26a5eff2f5b4dad60d636c5fc46cebc87 +1220000 48d101c5a5ab3b7a6923b40b9ab9ebd7c78d191c45c72913599567c25c95f579 70a4ab250ca55c82d4fcca35efefdb58d3715e78cef074c2165680d61d855a33 de9ea2657b33eb53873e7601e79483baf38a16ab93bbcabd785b55b24595d208 +1222000 a3827a0a540d497fda59b21f6f91d3164f8ca72af4c734421c32a79ea403881f 040675317e23edb055f4afb018333605448fdf4c7bb9c50ae358beb981df9d2e 7bf0f666993f12883ee61dbd6cca3f6f033e854c224d1e575b87f1574bfd5f85 +1224000 89f78648cc14638eed409ad20d85dda870db1e00e96e06bf037bf1fd4d277ea9 ad78fa4827a45de7da9977ee497f9fa04b7b6dbc2ef33edf4ba510a450745e86 9e365edd4fc9a234475b01256e9c15d45236cda715da1d13c2fab56b6d51a41c +1226000 32514b77c26e59bedaaee3929955a6f3a51c76e3dad3c21ef2af52fdc4227b57 bd9cfa38419348c6cc2f9cac7331b0fb3f74703682e46a98fc7b621b84a55124 00000000000008ba1328ba1b1ea2c32ba36f027ed72fb70f61d9e33b12299e36 +1228000 6cb1df8d8d178cc221fe5e9e9f80407c5f40bcaad6f26b1c9b34ce7140302051 ee505526b00289180f34b3c26e52ec154816e6949762f50fb4cd0ca24b7269ad 000b0f5888502ec6da1c1f6f7ac5d35286aef83e0ad40de1e92344202958830b +1230000 604d2356a4fb2009ddb657710767d48431930d6b1ad4de91560d784028e66420 88cb030b268fa37e4bcc3f8ea8b072d3a1f3219b07915dd095d5cdcb19e0cd2b b41e7d30005f2c32d3f39b00aa6df2eea1f08b397474e765c61bacdfee56b66c +1232000 0000000000000813ac7a5da052a2ed21d4a86cabfe3675a94885643498165e0b 3e4ad53e71f365a240865fd1a47453dc00bf0a4c401da61cbbcd03b1c42d1a3a 4cd70770283e59d513b98400b25f6a129dd0e1f7bdfe35c795c90eaa4ac0b856 +1234000 41ea6ff76f1cfe9ae409f645defbf72f705d4e081c16d35f989064b8037ad591 0fb595e654521a1613e927d1b2bcd5afce051547d7dcd8a03c0966a092ae58ff 496a27d154e9d6953b8354edd4707c3f42cc050e9b79f47e848ce1aba9379005 +1236000 5890e9be3564eda545a25eceef415857ebbad35a09361bd6982a7357b2eca948 009c68771caadfa71510842f215d074b1a882e7ed1466090b436019a751791b9 08bbdb78ca8b43d9af116d608728790a2b6e54f30facdee3906ebf6fc6efbd51 +1238000 6edbceaa451ca0f63516b2b73979d82368aa6f8e75edf3990df4f98f6095bb31 1bc854c309016d90708679ae6c7114cb000db8be1e15adeefa7f297c3544fa89 00000000000008642f377595dffa8f6af1346d2acd793c9464f1350b30484d70 +1240000 03e32445093a3ac0a6d3859f375a3a3ae714cbd21d6f1a76c568b6469a6df4f4 1473ab3c6de2ed0bce4c68809dff386be395545c41f2fcfb30377b103a95d39f 000000000000070295976919a50d10fd37ed72df9e8fadb4fcd7c6e29762039f +1242000 0b4d89e9292cf5aa96708ec2d9c36a4b9ebf684b76cfe1cbbd68df9de7c475a0 5b9b84a84a58ea50ae032b03c5fb248eea134890f4e0089f575946e8b84bcbd8 0e1f2514a19ab6d8efcbbd7f20dd309b0fd1b9c143f21e53605f0ca0257baf9c +1244000 4bfead22c2e12cc461b6a95acdb3dce2e503bb4d28eb1e62fa5421f00348c7f8 ea81b6ac47f695c48b9674abdb2d5366ff1e6525cf500de56888edd6bf5fda9d 3559a532d10b3f4be3309675f56e004ec507b5f2eec4fc08b81ce6b016560128 +1246000 00fdb1ff8e6740ac545726228a481145895e4be406787963a533a4a8226ec530 63d67ca9b41219c7095133cef315c97f6d59b1cf902a6c25e697f20cf336c53f 61dfb035a91d68790273cc98584e05dc49e7e5d88fb298414b71c81b0462e5f7 +1248000 c8fe0f4a77ab0aa2835f89f5fc714ad34a9047b8eccab903840f415589ae802b f412b32ef092989e895c66cda1094a31ea8e34660bee1273285b6550dfcbdbfd 8e6479ee28025cb4a9af4142c47ec94c2528fdfc0d35925071d91eb6b08643fd +1250000 00000000000002500502de1406b15d13d09d8f1e8bd14527af81f6ac9d7960ad b6b8c4d49d0320896f5d79b84de646bf4f5593311bc630917d8d97ac181ec42b d2ca0f5aa3029b2578b4ec0dad9fece8705d8e6e7c6fc36f38bccafc26dd8b7e +1252000 00000000000001ccefb9e33cecdb05467ec56b5e4a7dcda605d0d2d00b942d2d 0b256a26591f3ff5dd0530a0b2a2362c50ff86d92229d2b68b25ec2f1be8f22c 0ba8a748fab0a9044fe796c5a13dd60ac7bc5be0af9b3018180b7c3434f84f89 +1254000 58c00216b60ae1d0482a803e2001641fc424cf0a01865cc9ab04c407b9bbb311 1c2f83b52ab2ab5a2f899111f71a028d294d69991a01eb9ba19b75436889f809 6f393dbd60586561627ffb5a3948c80213b94d96f3ae59ce1b529d4914f32dcc +1256000 fb11907135c8a8084328ab6f3ff63c185a77fd27a9ba16fec7d13298a373d658 2b89b09769d3cb33debdaf1b798e962546320a32b2f2bc57c7366819b45cedd2 00000000000004e937bed96d097465c35356ed672ec56df75027ac75c07344ac +1258000 a3e052a2b15f27de158747199ecdde8a988c43d9dec449547d003bc4cadbf9c1 9c2f6e3e81b910d87f3393459f0f0901db0fad49c13d80485b5d6c2e470beb01 e8a133fc210941a110d3a5f24869eb597e4fac167587dcce5ddbe4ae53c4fe99 +1260000 d7fe7e808ed415c9fdd19959226d1739c1c21b03ade88ef6e64a29dbe2ad1b4f 1b22f0018060a6a2c05dbb244f6f0ea681957a372f21cd94516f543f857e3e62 000000000000083d2900daf286551f07a6a2481a54d52bf44955a4cfe813397d +1262000 38eb265f4b20393404eddc21a2ea846192390fa257ee0418e6680fa60cdb0233 d5a0e509ad33026f90a0736b614cbf81f4ffdbbb474ee30741782c014c7d41a3 b79bd6d4ef76f1b1c81f0d5682fcc986f41827272a044cffca15b32b0167a0ba +1264000 f636e6e620a7f3b6bfa98818e13f63c700bbf6923173a366412653554269924a d2af0268c0515517a420f8114bb9c5ca3110c65fa00ee33f7a9f64fbf0b492fd cde90874ba5a85f2028bb047b6554286d0ce6cd8a61b01027c560faed5ab7778 +1266000 00000000000006e7efa19c80fbf408f5146495f63b14c59e459cf673545d1c4e 6369c0f7f8e1d7bb3206582613cc22c376f017a3c111f4d7062de9745947d5a9 c67841d289022deb309d35260a1f910f5448add40cfda1bdeb3d278675bfaa2a +1268000 f31575717259295b38d4a0493623d30e9b47dd7e91efa367a1385f4554dbe5b3 aaf96652fc8d22f85cdcb44d62ce69c8cca2852ecaeec48ec3d2c2302d7ec846 8e70598f6f65b127a1e16af248dc178de0e77986593d22863fb4a93265ebef5b +1270000 2b157ff7ae8759c4f7f7e0674a33256ba1cfd50175dda6808de73de20fe17cb6 edd511ad46ba2dd892891b4c182d4eab4f8112df9cf1f06ad6d9e5e278d2382f dbd0444a0b40d9efaecf023f3ff188f3ec1bbadefdfce9b79df363fc6d9bd126 +1272000 ab2eac0672b4a2cc7babcc1fd74c5a8621d5b17e1a31b43fe7535a085a09dc7c f1c0122f1c8f34d0c51e8d7c0f56f7d466e85e3f1055a9cd88e896e85b0d2341 20312bd52a3307d056e9809fc470ae92951acaeeedae570f97c636b523612039 +1274000 000000000000034b074b0bff788a33effb9f3170c677e3f44c9701edd98081d0 ed0c1c1e06befded007bc4049eebd525fbd93c1e2c81c3b576791cd003dfe041 32fa93db04670780263231c582f80814cd2bb2e9e2b6d9a8241de5fc59ac73fa +1276000 0fc97111fed2115129247cc872e8c01f6d75041832d6513a6c240cf0b43af10f 9e23ff4d0b8dd2ba2c0f52678a92ebba44bdb94bb666ee58e503f57b30195f0d 0f4180caa9f460ec103c4f88598594c5e8c389a0372d4208632fe3d794a0e254 +1278000 8fede5f934d1aab952d0119d99c39705d3a221117db2b8273eee8adae2402d11 86d4b591450e1296f3824bef83384586eea8a08b9bf49ce03620a89dd9363174 6a688bfe90cb3a9502c527d72a4561a15b8ffb77406a6aabd7749e48b2b2a9c9 +1280000 59f516db159ec486b1b52ec68fb473e250d3756a17f55034eb1c1900f785a7d8 1daa32d4fae6d0c012617bb50aae7b3afa7a73e9c79f0fa21b3d35b67442498c a92398b969ba5aa61a4dfe717149c1fa9b9125777313143b76e66dd4310e22d8 +1282000 7152a56841088001632d0d547423c265bdeb266b5b82d1256813bb876a424459 5bdd45c9041f6051c82f1a91b879d174df5e406c9c9866987163af6a9e9b4007 bb745b5242b9e294d41971c3e5007b72ad9e974d915d905a8c020f6e85414d90 +1284000 fd1ee7916ddba14480e510233e9fce2e5f1f8a072ca3b9076885a4463a77169f 3e1f0950105ab40c15cced6669dd74bc933d95c8d43b730971e084ec4f6ac88c 00000000000004171b3cd14c4bc71c4a6691200f0b05c5e36e0a62666d505a3a +1286000 0000000000000073ca244370fa5a117dca860a0051745c322a134112913f9856 7caf80bf9d44ef580cfba671395372129aebad027c17eeb7c9260f55b623ef6f 710ffb2fc55486617aa02f23423f5d9981c6b4a0bcc27fc0d15535424fb3efb9 +1288000 00000000000000195f8d36a34a38789234248078a06eaf82fdfc0cb26460bc5d acce3f818f63f360f7d6208b352d0afbdfe26dc66444670b38d5a68e14a086ca 7437c4b52539e60bd7e463667793cfd14ecb4ae5f27a7d385f2c78d19c43dc61 +1290000 d777542a59248b7c322bf29a61d50fd6bbf12a0c8eb041f6461fbe5f02c24fdc 163166650fb254aa4681fbcdbf9ce318e9d73c135c1ff3a1ae4e8323986c6a9f bb522467721839a6fd7dc131fa36f3e995fae9a9fafd66964bd81936b9fca706 +1292000 9b78d35ce831e4fba539cb07a16721b5965444f7539abaaaefe6c9a645c3da69 2750a86e12129fddcf19b4f66afa1d8e8ffb45fdad69b90a96a32d7a3a7e3a0e 059d08897c60b4b64c7949c4103b45cf081694de323ae923244c41c631a7911c +1294000 77860228ac64bfa4ee2928259a5cf1d7088e1f35eef90b18ec58f83077ce2f10 fb3dfae1a95abde5eab017929f73e2b5413003d525b19b6249fda6a039a3965c eea120575ce3a0d20e570125fc1e0faff4ee2ee280bbd26cb0c90d18f866d8b9 +1296000 5c8d8dcbee0a77d67a72ad05bc31e4447f8207419e10dcae00c9ff8d77acc53e 1b9014a31b716c4a6f295aa95d86a530bc4156c074362be5c19d0e5ab935b7cb 00000000000001fc69b34ab41bce92047a1904d1aff3e6a60eef98c68f3e5744 +1298000 4239b81e7d625cd40c77519e6927748eaffdec1171f399ba2aab1f49c65fd994 f613b9756def95ac5946235683b03ab012c56e522d25fa55a1bd04dc642cd49d 7ebc83beafa84464a3676cb6f18d2f9ff0bfcee5d55f56fd0d72e106ad92d9d9 +1300000 0000000000000020ff988770a99cf91c9ddabf97122329a9cedc8c5d4d774a12 9526a68633dc0b1c7a691994eed466b3ec70abb57444095ddeece975b9748659 855600c678aacf052877a47dfdf089143b0a8e121f6841e1f4027784d2c420f7 +1302000 c9bf46fe8e45b516f9a11340890c87f646d59c0a5f49e3d52dd8ac47637eae58 331a1ad27de786508641d979b18ce9ae8524820c0eaaaeac8b7f3de68cb28399 051f690642d6ed647072e9d68b4816a1430949a787a571604118b40edeeb0141 +1304000 98ab964872d1d66be0577c777dd0d08d9c5e317d5175d5dfcd7292266749aafa 81465c84134ed4916358cc903ea0ce5d295e783dd1f2ddf1f0c449db6ba95020 12b499c41040ad06dd428d14de3c964d546503880593128f7f7755fdbfa6780d +1306000 c9c9d82963aff7cd697ed045d8e5b897b83ab9c9652bc4a46ae501afcbc04f18 1a9cf75ce4e48d7e1ae6f9413089d4888289c8ffe903f39bbed3bea8a33036d6 000000000000029aac71defb20528c6b922b4733c20866e44bb94a1573c65519 +1308000 6bdec1841eb0d17f08b2f4426e465f501b299b8ae15c43bd2210fed66b5b8393 aa35f85738e4f08cbaeab81fa78daa00eaab1de74c892cdb47d36c067a71556d 592e6911a8873c70d59c649f3d55bee4acc016fad2afe124993f2015aa401d8e +1310000 151421b4786ac8136831828bc2f224748487aee2024839627d6ba89efb83288e d4e8784026a417f6082e48d756fabdebf8874730574b5551ac2bae14464a55a6 394d089985421bbf563adb885f86a08979a9e7d7ea3be66fe53293dfe211ab1d +1312000 1d91c4c39efdb50ba2f796f134a902f32ff95b51ddf245eeab19a5b3be22d7a8 19dfc546102b9a2c3d5116f5a4e487e62c5b78575970312a540cd73b271c6e7d 000000000000038a3d38bf9c18949b903c062e4bf38c74e4e1dfe3cabe1e8621 +1314000 08dbdfc265a1dbd5ee9f3dc04e9b9284a7f4c0094cfe291f1ee2d847da810a40 085620a6658b200dcfb3cacfd46080c5d73de36df8d72c9e3f64e33d90e6024f f72a81ab276b8edd7fad77c3c97d53e411194f5417b8ee2a94c433a0a46f55d8 +1316000 9b675dffaee6bcdd3fc35e4b3cdff35cd315b6702c8c404c50843cf821d19e5b 2f5208c011d83da922601087c493b25bac85382655d73975749331c307697940 87fa6edb57113e18ca1525bdcbcc80c1bc20ac6cb7963bde726939d31339111e +1318000 5d77bab8a2800feb03bf40b8c15367d45bd0dfb25e2613c357d1ff421fbd2c12 d6dc1fba31e6e55897836fcb010ceec92d0612d03cfa0552273e88cefc84fbf5 7906893e60b6574068cbf6bd4176e1fa09a20f2c063264db61380e3365851939 +1320000 82e3de1ce124fdaa61f06d7536e873284f9ab395e191495a7b76c8343be961ad a9c441c0b3a00a646ceeeacb78743eebcaf07cb01ed23f62749c63bed119c769 5f1606cbf0520c82c2f4c2ca861cc1abc8cc2d205c429c2e976794e0fa04e7e8 +1322000 1e57bfb8f551d41b1291dcf8f7a3a166f7655793e08cfe655699dd0f8cbba895 71f4aa8ba8acf0f4a23fc32be1df447c3ccdc021730e9c2ab18a34ea83981828 efd8e6a53fc6ab61037c0c8beeef8c3a15f5127a9f7468f7f16f31297f937d69 +1324000 cc12432cd0adffc067176c33815047ac8942c2df3501d25efe3929f68f878c07 c9fa7babb64b8d21ad535555f7b4b645efccb8dd7219e8e2e6d77d25709ed526 e66c84a0e9f4ff88a05427fb68e098ab3f57a25e5c5b20fe8414f848aff5562a +1326000 000000000000018b4099f8c5bdf4ce6c57b946e2c17936d3c9d16fd53ef75ddf b6d7e65e01d444f94fc521d778e001224bada723bcaffcf198275cb71aa9166b 487a5a64d0d428c866272cf62fc450864aa1c50a48ae74caf9e09aada52f28c7 +1328000 ff9aeaa901f76d26adcef900575bb82122477e37aa330d3d7d2d72864c90c416 bd2d25e275d2d7bcde857ad3ec573bc08409e6eb42eff47bbe22c7fc562008a1 000000000000011b3b09f01be672872498ffdfbb73ec32cf13e59a5024e9ed4c +1330000 3103f0fbd9b22f52d44410cef6def3264f1a487b0e8e1d397c0875030191b896 cd7ab1c4855096bc2c43c6eef6bcf2ac54dc88b06974d41d6913894d57657eb0 6a037dd1bc80bf2a270ee178bc38c0873c9701c0ec95a35587d072a6d0d54d3c +1332000 13421b201bfe1732fd35aee1502c5cbcbc3ae235e42cf80e856fcb34c9256333 a8738570fe05dddb9c6de9d24d6fe699706458e68c0a3ef1bcddb6d1841c37e7 000000000000002e0acf188684acf574c1cf4bebd3811069c4109de6518f0fd2 +1334000 00000000000001eff29cf9cd5bda48c6f1db1d7f010f7d43d9c8aafbdb3a5976 3a6843f8c9b2e02313c01e45150090cc574b7ee788af5851408b62e3824b5765 36212221bc3f8faf59a5e9090e79c6963589ccdebc3ef5073011253a90ccf4eb +1336000 52a290189ffdd17ba0f001c0559eb8185ce44eeed257aec945f8227c24cd64fb c1802987a5984a03831ea2281ab91692ef03eb39c3e41328e16358a7cf0257f4 2a863017974b48cc77ba82fc46c9358d26a95f2f63a69fa0290acc6a7fd2e698 +1338000 1a8ce61fde31e1e8443ad0071b467b137e3bd44b81493eb7c71c2fbf895a3568 4c562ffbdb2513276d729de72adc73e2de1a287231ecd6b61a91881348ca3b5d 261ebb71bd43b2bcca02b2e196ad57c7c53d3c2aa25a496000313b8182b36e18 +1340000 0000000000000075197a6349d0d6cd5d620d14c112a355cf389e4f4d0a609fee d7ad03a11297e15126edd20cd1cc6151db982948b9f9f40c9a0724ebf8cc2f84 b95aea178e8e646e07ee3fb3777eb5f5d7c48c70d3790b49a4d38c42ec54cb44 +1342000 000000000000015789f72698c55e03a96909ec0caff7740b38f60a12a61b9d8d ec17efa912b9c79d9345770a08bf5d3b8e65115d0d98ec2fb5bc4c0eb9185846 3201a37bb5aad5012c802e75466818a5b242fde004dc96aa684e8563d5c334eb +1344000 600a519d19ddc64f8e46d8ed3a21c580194dbd3f170d9eda7c7c60ed5065ae22 c73f3f6a07e1e8db1743db2681b4fe18bb5c7947118a9c5d0c06405b6fd2fab5 000000000000006fc089751f7ad3d2679180d3af6a95b40c269db34e4743f184 +1346000 06e7613b3e3fff44fc5cef2cab440438115c36affec855738793ac8456a03923 42c6cc8738e6d05d4a20fc5dee27597575f3e6784f6060d124b62c1eb13662d2 0548549e3dbaaef29e675eb4c10afe9a764eb122bf510de4b8c75e6f802a8574 +1348000 c701549ec42e8702c08d0ba0fa52dc17d42217e6be6adafce964938c4edf7d18 bab59a9efc94027f76e13b3e7e38f91dd3b28b30e8973ccc2052c42893660f93 b01f258e4a793cc50774412f7f5bc7b407200d5d159e206594fe504d4f6ef8c1 +1350000 1a80ff7a8585ee7c2f11ed497106ef7701dd38c716bb9d6c829199063d42f25a 737232ddad848ebb785154b0b858f23911377bdddd9a17033b1d31970403e5f4 d510bdad1ebee1a21d6b58b53b7dac9025eec2d1f6ffa416e51885ba60fee5cd +1352000 df32d0bda492b078ca162858e798a4d6e9719eebafc904e992b0f499b0e30966 e6c45cbabbd9db81ecf4f57958febdae83a5d0c4544632ce38b7210e67e207b5 2fad28a1fb00bdb1e0411d4c78ce94f81837583a1b70f46c83fdc5806ecaf64f +1354000 3ccb813ad5e6d15b00e840705a5891d291a28404dc6f2b2f66f46af2b4c4acd2 37b1fe3490f723c77b2b8b911417569d14681168a82dedfac1e0084a8a4be3ef bd1cf06a909624c242bd8146f3f245625915bdc6aceb0eee139e7fad718e0d1d +1356000 eb72b4de18ecf8917c669a228f03bccfc13658e45eb95711b922624d7436a35d 263771930d4ad0073c40ab0c9983e20e25f2f629375d98cea3900e0751acc5fb 726517c454962965ed5d512cf40aefd93e2098262b12b3bfb54c8ef09e816f09 +1358000 57ad9b466fe53e32267df082b866123d989ff8adef985e6672e978d6f9db7744 759f1d0bf2cddf1efa629a160ce758c8dd756167e96d3936d506ccef45d8a7e4 000000000000036467eb6376f6f604bb58993645a94d3455d19f5ac360280113 +1360000 05e45942013ebd3c70e993b92c7f23a43828fe3e1fe109f3ce5b0f666e5fbf2f f66cbd4fee55e820d5d30d4a365fd7e92f0b34533028aabab68c5f154e2e0e77 738828083936036fea84fbc7e2c43cd75df50226c6c7e7efa7738a4c8c0de76c +1362000 3383337d7fd102235dadcd51a06db2bd3d346a2c069d6802e658f981f59fecf5 8d9dc783049ad446ebf14470d6bf4e199b9e4ece2b9872cc9c05d670e57ab0b8 4dc7800cac7041636b614b54ccc5117be3a656646648e19b586ad5c7835516e4 +1364000 cfc9feb5cf03caa4999eaef41261ea3fdea86ef46b3d812a733cbfe5e54ec8ca 7e209b6263a16f6023daa35d4a372f0e5088a405ee74193094c3f53e830c8ed7 c94289249bea955180a99954f25dfb9c55e545111b046b7a8856a9977138eaa4 +1366000 f9da5e65e2469556777a3c2ae789c011f2023de3c804878ff6398a3dddff82f4 6bf8525735eded465676fd8298e0f1674275b0326f6d423da7bc83132b108eba d23082b57f33e857d890a50ccfec78efdad3d5ad90b5b3e681d2af382d644286 +1368000 58ea46b2f99474072e3dd73f1956126b27637529bece4bcc7213a5e45a012da1 0e08efa55e5e6d4b8e152fa9d134228b7fef85fe0db9f11d9ac725d3fc7ae533 00000000000001f656914d9a4ba5372393efa587e24ae0e5aa3ac1e0dc1131de +1370000 7d8e17293ffe76ae8b29c933886b892991e4e90d01020a1bd13378237f3e31ba 06eb5acb7c779660794b7e027b180217ea5d18b8e2c5159b68b3ac7768932e59 d900f027069a97eb3cb826e3136a35635184ff7eee4d522028c5f62bc1ad274d +1372000 c82687f85e6d6e8d7e18c6ff90d010b454d0c0dbee71b13863af9fb96e6fe048 b0a7ab7cbfce21e481d2b279d84e6a8ef6ed3cf6abdf0cda327c6c919d2e7992 820f31244cb6ae92bcfbaea5052369a619303f7115923f5dc7ad4d190fc09cdc +1374000 0dfdd8f4dd75cca7be57cb523a9385008f0eb0e5f4b9e635479b1e09f0779b19 fbca4f1c999e86abd2bacf2fcf24f6e9dbe2b05df5ec75592fffb551aa0a211e 000000000000028ab12cd596d018b43d63f9b93d9c838025bb2dcfb3d764e52e +1376000 00000000000001312a525750260e292282c933d2671ff6e15d4201504681ae28 a6718bf4acc924dbd9d5e32f57c5a3f5b4b4e3116f47b1411b2081e38bd5ae8e f731bd71d445e72a34dbcabf2716f2889924ebdf01f61b6f973d004ed22e6e2d +1378000 956bfaed7f366ae410fcee1c58182197b3733c666aa89fed818de7b490eb0d73 10e2327392195585c5e4955303fc732bbec2483aef3a09e450584b0a93f3fc28 3ffc7b5c4e7ad34c10059d20a0472a00af39bda3dcd145098f953f2aede67c7d +1380000 00000000000001969b1e5836dd8bf6a001d96f4a16d336e09405b62b29feead6 1a725cb1ef7c7161f7cbfb1e2c39871eb9979d5ff06a4fe1dab85eee42411c22 d088e9e43b23c9513e49ee7f73835317abb03906d72592aaacc9382ae318893b +1382000 bc0e7aabbb3a3b25fdd348c8e77fed435a907bb8b921268ec63c51675e587496 c1b5c80d740a59b3acb06c70a687e882e8eb25d7266aabe0474f8e8b408c2bb4 722595f43a7d8929013d90ca765903a8f1033eb0b410f2debc6b044b6444ccfe +1384000 6c4ee2cd93c4e1cdf0fe9aeeaea5bdd47c1b8a86e4ff5153a7c4c40256a8603c edd1b01b350359e01c5a0353ae910e0ab01f901ad67036cbfb1ec3ad347243a6 1a95c9b13ea8360ab9b51e00ebcf29b5f81a919325958dc591a3e1ef207e9717 +1386000 c5423dcc85aa424139fd6a170c65a2662528c24f6f5ca8986236ef9cc24a1cb4 5621cf4c9bb2163814186bb56410cd9e481d816a8bfb8079882f1be74b2c0415 0000000000000228702af84598655fc4214249970da34a6d70a976a00b37fceb +1388000 c3385750f5f8739f01458af620ab58cb75131a4f7c3c24983b7e250dc6238add 453ad7ba53f397937c9b3b14c51b3621ff909bcc05837406c4e902bcb85cb7a7 00000000000003bb810dcc733347afce3e31018c031a1d994a257659b79db130 +1390000 e5a3b292e4412da1101b52648236ca36bcdfba953cdbf4c5c598714d94c1584d a43187703c3a9a3e9cd6e242f8ee95b0c24a0911d81a892d2bca58e18d762e0e 9f43db3b9443c0d307d07d156da0c64aa0fd9eac8318dc6690d1515a276688bb +1392000 0000000000000173a949f0cf245fa0830d0010ecc988520d694a5d5fee7da499 ff18020b0b6efd798273f713293d053c842a3f06d8f755fde23e787f022f4bf5 dd316930a4cc18ebadcd87be910883f41daeef3535317e1784cc9bd562b37514 +1394000 361b7ae6498bf1dddb9ac29c5db96e79f09812f88aa6a4a362fb3240a959cdf9 491f7fe344417982e997a88ace8198b741c5b175dd9fa40abe67afc929bf7060 300f3799a33fc6ee78337a81f7623823c813090369ca7617d03865d8c57e33c7 +1396000 00000000000006fc7a601b89e70c6e464d659318d338c46fa87da702801de789 525bd36e6f90be4cef1da2216a54d0e747d17bda938fa27c4e44e25a807d67ab 00000000000003ccfe66ae76371f183d84260282407a1c63659b32b1ae4078e5 +1398000 0681b61d7c2686a64a8d50a2d01c156ce4353631d5aa094a5cb5864ceced2f51 3a8752b73494fa34cd336a2afd0e676d8e1d1d21cf4fbc22dbcddf70b057c75f 5cb3aad6821de7f9fac981b778d5387699cdfbd7ec431942c0614c0245469dfa +1400000 1cdc20a5e53a84c427d903eb7f748be09a0d3a9d8faf46ed6603857c0f424840 01fc6fc4c02c860b0ed437e02982d259fe7082d7fc90b8b94d514fb0deec805f 4b6f68cea02925bfa7eb352a81d4934bfc372b4e8554e05a20e2b5213a4f9363 +1402000 f49d3b94c0f4ec2dedb9df6913b19dfe7b654a4b333270e6a2a7a2788e00cc25 e91d9516e95a0eca33470adc3d9dfc491efaf9fc8d4d789af07ba5087e141f32 805153cde11a4733203ea6cb1a6c17b2add1ad9682467f7c054b04c0e98429bb +1404000 6f3bae07bfb24b32af60db1e82eb55ab532ad09b4dd402a706bae4f3a0c04040 f0970c9eb710694bfa7f75d7b126f3d6f4f5e4e1c36f66330192d3cce4947569 a483ffdf9699e8f56a54c6c5ed1eb3137f9fdf1f3a2d9f92defad47165ae5294 +1406000 713fcb444dd7664811a0323760a53d2afdd6d30762c50fe29e2cda65781b3d75 e7fce267457f00c8fe94fdc193ad6a4b75398b123224ddc6680aa6c8ac1a969a 97e138c5a16b8c005a3365d4e712c7e683a38befd07deb172a81bc548c5c829a +1408000 2a576c686625c0cea0020d8f07b6ad0015b4a4a5c5de93c94d8756f9e86331df d13fcb5d6ccaa1c06bd917bcfe58c06faf899edef4041542de6051ed169aa481 6205ffe2d5e6d44f25c2299076f235f6d63ba316bfd17779f970e9ee3940b8ee +1410000 a72e0abdc7aa14bdf8f51213c5995652ab724f9b765824c2abfe9b366ddcc06d b890ef23412cbd6db48f1c6b0049590262567f2ca640596a3a5863381b05b5b9 36d439928b93959c6e9b110b8865fc92b0e6ab6d6939fcd0a0ea86bade168131 +1412000 7835b0a2eb2dff8400d71f5657fbdeb037ab67744f932c4a1722d7ea08993952 9ec84eaef6865da04f99c9fe0273916e1dc1a98a1bb1011b9d156e1a34cdde40 30c98dcfa20de50561cacdc809e77fa10b43295755c585129ee8ce127bc16d40 +1414000 2b6c3f89359826dc4ee20a80cc5414bed834c86c7b2fb39e124ec363fc0e922a 19d90d0c14297c9f506927b0b20a982d0973ac5480e3805ca1e90e39de0ab180 000000000000040f49e52ec2e7e90d394cac9f6d6b76db5421fe077f26d10c85 +1416000 4447500347373035028853fc540fd71a89d8283591c53710c9d6702fe737e8b6 b1a0262a5fd64aef05ee2c9344510faba3c325cecc1d9dfbcc254c50171faaa4 6def491f71fda6b2e7078c37a749aa3992ba183faedf62df79a9458ce8896684 +1418000 fb547ad2a473f3e6d2da9034b17b8adb0cf15eee43e92197ac39a00fb3eddf9a 57218805442be2390866e921b79be898779e9db2be40c000ae362a5acb5b180d 2be08a34e6f8a2bce027d9e88cee48709f6668f265d5db9ad5ccd2a66c7629f8 +1420000 8d6976938fd66711ee2bd4c3071707971df848afe63a66289916ecd047381938 6cf18dd308bd20f5855491bfbd9656a3a6899d5914a0191c8fca4e0656cb5b15 828d97f89ff9f7385bb9b62d290463b4752289484f550c3bbd6c8d956d78b143 +1422000 b0ab61f04fa3e6831d8d5fbe394226ddc2d339e01cd40c4514f3c093d0258cba b7c12454d8d5cda6c494db484ae9b7a19d7ac14de2da3a75520cae44446e8323 9fd836987a62ee199318772b9886744d7da88972c82e5d9eee39b7bf0abd1c84 +1424000 238623b3dc7bd2ceaa0d9161da15fedd42404f6ebb4f9c495dcb2ad4e3d4e7d9 c3a28942141f4c37a82689ec6dfe0305e94d3ad9ef6d05a34a9aef9af6391763 6854801b68816c1a99e403e35236b178a98cfbdde64aa74a156dc655137e2dcd +1426000 31194570e71d155ada38ee98f171e41ec26998621a7e2fcbd5ee05bfdfb4a6c8 010787c33d43f30eee6f680a20e64c683b9238a88ac500e6a82c275baa00e812 996407ed412f17ad1c7866065dc1f127349e2ab8ab03bfadbd71e00de32dea47 +1428000 5d367cd06b2f6435f304fcdb06af3462fb65f5f7706156ab897e14d77fd3d86f 190bcb805f807c0e2623c0cad09d75e6ce34c641841c7a493b75980d2ceac5b5 348c11469b8748e2ee815d317fa0b6945597c0c7088c85e867cf4b3edda64ac2 +1430000 0000000000000934d3c8d4a9b7f4632065102f465d93a04da5a8f29732bd292c 765535220002a8d2ec57941fd9a9cd4787d022c4b8dccf73b7e6de9d35346fae 1681ab3c52e9921b655b71a5e9cbfe6bb2af04529789d1f5ee6fff1475d35672 +1432000 00000000000021154d9e3b33e319b29f557cc5091e7fa8ebc935bb431f9d41ed 8adeb51b0f4a4b1f06a6e5a76d58b515f8bf6ac0166b34f9ff51c70af1cf6ac0 0000000000003b3900c829f838b4f4440c669139a484d7f6813d301b0d5f7f66 +1434000 58c58ef632f999e5ef1fc1e14d8f4c53ac70f0f469466dcb0f321f5d795f40fe 55477019155f190e40d48869f21d7f680dc749fa35cfc1d7e575073650310a52 00000000000002d74069a7dfbf8f5bcee2de782dbe78528d5496d982675a20d4 +1436000 1bacffa0fa3e53c747fc437a2e536b42a541d492f3a12f2d7be69fc9f8a32b2f a322b89afe50931ed00b0b97c18f902abb233438f717e74948fa4e4478905200 e84f82207b7bb5cdcf68b688d42f2597f5750dd5893f1966573557cca772eb7b +1438000 2c9f2be2f2a0352c2f08dd299899966290d1ec2d9ea475b5dd50106272367a1b 2d11f82cb2bdb492964e0aaa1e630caf91c23290ed453caab8521ce670bc6724 e933249f5d755065050b8f3989559e5ec587f83e08c3898bc88023f3c529d6ab +1440000 63f501741cf3f53f7e5fb20b5589926e111618358cbd3ccca18c25b8e2a49c14 27e17712641361b448facfca97cdc71f61c87b8d3ce4cb8ec1e969103aca883a 7e1f7dab34498af570eb5795343a7969ee5009dd135763e7bd092d49c6f9086e +1442000 7f6bfce8d3e9ffaaeb627bb14afc4da7083171b62422aa44095b70d2195482e0 c0494f7ffb6a72749db2ef7c66ce956871d3a596da66d5708cd01fa634cbb2f7 9bd0318f01f38a13ef6c48f51fa3a280a4eb3dc4356b05165763890cd02639c3 +1444000 b44070770cf2fe09477e45bb5ba4c2c546ab200e84f687bc57c41ee20767044f bf31ebb190ed3c2ec1c65dde987a82157a8423966cdc6201c8297b2a494f8038 1fa1036391a4361a0f700b5bb2c2ee5047d640784ddb3923ef85514783f85c61 +1446000 d1b3092bd397158dd9bf6e3aadcdd414e5244f19082441cdff7bd109dabe08ae ebf796b82588b715e5f35aef0ec1196d0c003cb9160ae70890294cb3161c084a 0000000000001118322be274964101cfecdf11b67a92d0bb868ef3ccd2cd873e +1448000 a6ba88e0b64b89fe2d38f1b0aa701b347db488ab7a56e1c314b5badec401c099 ce4972c2991ac7bf94152a77dfcb01633ec9fd5035a127740ceea5ce099f625f 01a0b0777bc4c786156567e05ca2ceeae87b6ae32c71c78f2449ba70bd260c82 +1450000 2fa7e991ca9f696e100f44ad18691dc8cd2099efdb24718a12140f35cde8dde1 57753f9ae8d74a9d7c440df17ef22c5a1f409f250e8b43882bfe1c5123967094 7116bdad8a5e91d3a22b8157575b89e6b534b0cec8318400d916cff4a0303568 +1452000 f4bc25c3916c690c4e957bccd4a76de57de712824df34470d1d1547b78ca9d9d 0a37420aed4ef3ba005f6f192fbdaef1376987334e60b304cb195c4e100de4fb cfb5855bc5c5744a83c875555747978e2e5cbd079694ac987a84ab98c2568e02 +1454000 b7663ce6a6fac7b022d06e3953b34618b9ca71668c83da0cc167c81185ca0d7b ac79f619bcbfc36002f2a90a0df1509be2dc9e0778c74e6c5acb8f09836f1fa5 ebc577e4b8e481a2e970bafdd12efe79a7eb1b251726a46ae34ed04aae8101be +1456000 b1d5c70c0643e00cd6bec650588723358c323833a6261172578a33b049d1ed5f 5013bb4b909583720c3e9abaeb2367923d0db59236d15553a0ffc7b38e35a0d3 d59422c4e0c70de875185bf7a2bf8666db63b1986ed3d029901f7ee44caa3a92 +1458000 f28655febe04a15a50247837fec03081cb956ead9b5c52dc11aea3734d50fb02 1bd05d0ffd0b81266ce7b675429bce106b9c6fc277e59d8e7ca58e7add736fe7 622339d2d59b215816f3fbcfb3eb35a9314f11c52465fba096d774d636918320 +1460000 1b878715486d03f4a0a391e10f6a8edb480e075a610b1d9d8de17c3802558196 6e878cf25854e403e2321889b2f1fe52b63893410826eaf2b3c0004a657800cf 00000000000005e1925ffd90009a366f5b3907a8f699a7aaf5b3bf64ea9e06ed +1462000 346c30833506862aea71b999dcd4f1235f3fc489458b02ef834fc1b1a179d7ad db33d4e99fafdd7b842921ed802c1a77cf5b7dda14f1e7d1df9804746364ad05 8d13488b84478232177823aa6ee786d660cb1c04dd4bec8dad84a34e24e35852 +1464000 0000000000000fcb221eefbe8e518e5a6addc99af8054e690eb9b5197e90b5e9 65deb1bdde218cd4e7441c671e367013d1708170f3dc2ac763e18b2a4ba43ad8 d13d10f2bb84c954f6ca868b93064f131605d7570fd6c1e25630bcbf83d6cb34 +1466000 535548c3686025cb8ed650c97ae0d36072cee1adde21b8722c4344fa32ced049 21ee13c421b1c45bcce2a82be98f5612468cf644e6d230e3be81b289545fb998 5043f57bd731ad702dfa9d3ad752ef4ba1ba3ff625cddf2220271d05ac87f29d +1468000 f030a7e78c96711a69c1b2cf59866b49f38522574d4fa25ec521b86789f4d193 4c78cedf2a21ea74a4975c6dfed6a9e6a47a541d3af8a65904d315dc5b66de49 f8d8c3623f78463608b23c6f28708104e1ee3f1bd2521e239de34a17d6ba7d7c +1470000 41bec65bfc30dafd0aef8ff16f278b20269a1645c91a2bd2c21066a8667d12f2 0a492e2f1cbe98bf792b4a567037774c323967f42e433bb0ba0217c387dcf6b8 00000000000003a06730a44235e029d9fd1b24ef658759cdcf68facf1aff7c3d +1472000 c82461db01b74f7ea79326f797efe9ab81a1b835226bf5f6a5415f60f3827422 66e77b014c1c2b626a9f01d9fdf169c6a1399d2f180a764a3eda24859ce55159 bb5b7796b8e205c27d6ddf680deeac388a290cf60bf8bd8f78e926ecae1a4a85 +1474000 6866f37bd109e3bdc9b598badba81cfcb2c1bab5dff49a26e0d4958b3d038abc 02531e494cd771f91e11082cfeaa88918855ac2a92a72fe1945c13dfa7003b2c 0000000000000ec7d9b51839d4f9d830ba15bd81d36eeff3f077e4d497a170e8 +1476000 03813851244b63a39781ef186f3165c0cafca2879163932b10f0b85d7fe334b6 b8afae6798b1f9ba2fd72c335bc05227cfdbe28f0c98c1df2be9a41b4f827d18 639c5eeca70c420f9da7bcc7e1ab135cb5323eacedac9d0182b5c6c636cc162c +1478000 f5f0c6f31bf96bd32d52e435282f6dcd51741967536ff272c50255c52ca9e460 5148bfd97451ce5f9cee80aa203f1fe105ea03de532c47db04f4742c43d9db2e 51f4bd7de85a56f0565ec90e6adefa5b1568381ab8e2052e86bfd3a588a67526 +1480000 0000000000000923e18190faa93ab6bf633d95c5f931f03cd56fbbeba93598ea 1790137059f36e65a6b882e20ce7383afc814cb7d1e8187f3f8b927a1b1680b9 b2ad09c34b9988bf181df2e14fe49b05f397c5215b08fb0a365d177fc73c7045 +1482000 f404587798a4e3be094a30740e9be3e328a283525844e87b2fadf0755efab082 2f978a065cf2cf295930e3602150b1d72a901199991d53560f57ab459f7bb37a db7f8bb65d0d48c211aa47b342f27344c624961f90f7eee38f7b463a194513af +1484000 994b78f8f5f8ffc872a55ca20483be66d0c1e2ac69e666aa264d9256d71545c1 7461800220f05cba420923907a84c6ac81234f4b46a5a5fa25760e2400a92dae f86d37a04a5e155083f2d354e56e470950da3b5e1583fcec8643b7f2dc43054b +1486000 ccd84fa7a7ea037c2537281f77388a03fb6175e666d56475c33d268a06ee0dbb 1d67f88b20a95c01a2f5c6bfd598297c776b23444eb598ee6b57e88203cae4a0 4e0e6607516c13605d4defce7fe12784ec26a90422f0c8f5804caf95f41465d0 +1488000 00000000000008ff34ef4154455c7ef44bee7aba3048779bdf53820481afc980 9b0cd5699e60cfd92ae1808ef7fa12e4917ec20e067d2bac5125dc639283698e 022d4aa30fd93a9e079f71cb0fec2b712da42a5003a41e01d3c232fde317fe7e +1490000 939e2fe1927487fcae356db8592071dff664efb8821f08cc3190c5433c28e4a9 77727f4e40e584cdcc95ec46489161f35efade91b72e65307fd163c8071e2967 17a47ada7f566346df3470a3f66af6f274b1137956279e2259e156c6b36144a3 +1492000 38b562726bdc95a8d6efcbff4abfe22c212e138ea1ac2b920d2dd69c48899f87 b1c01d97984a408d1782041d92a14cb8a7544781dc29379f16de45ad745975b8 4f758a35389b4fe6ccb2ce460dad368cae6ecc3d8b2fffb7c6910998acf18cb7 +1494000 0f56f2422667271419d71c58f7775ed7860177c47cbf78972f913a4b244cc278 e75bc745c5a27dbde641076ecc7697aac97d0cbc763aff20858919548fec1411 bf90a89da27c0e8973bb0b3eaf91303c345f3e6dbdae7bc56565414da2327a42 +1496000 7bfe5b510e21413ea284a215c3ae1f1a4a249dcc46b3a2513e5147046c2c7fa4 28086f4606c82f24a20025282a84b1c5e762f13d21e25cfb933a425a56e317cc 7984b25b854f84176871bcc18f589dbf4a6bcc0fd59a054dfc73d57e13e26854 +1498000 8a39de53b13615068207e8cad9c4f57b30f781c0c10242ce1bdd7196deb3fdfb adb18a9488a564e6a74fac21ab5fadf311bee1e39953194e61261db186745915 05d0ce47f66b5cf9e5b479ae4578cc96cb1043b483d330d61461ad5cfcacbda2 +1500000 af353af43bb01a5168f7d344681de8389c44d2e431841a1943a1467f8d851a8b e8fe387884693f9fe6a672ae1afe0f3af8767eb70ef80030f2745ec0116ab880 2d57c084b7f1bab94703383a680322675200de5d5c6ce76124866c000f1b4840 +1502000 873349bd58b22d387f543017de28608ae122675562c16e9a24fa907bb9e4d1de ac2e00ad015327828aeaf04371c90f6c57c7bfc85b9d53fd89c0e33d3914fafd 000000000000100325fad86d15102d4203d37396459f6c18e0aecba37da5352b +1504000 f6012b8051735171acfcee349468193a21c2c0c7ff1e53eec7054e7059e66c7a db82b3b9248eda76b5b4cd84660368b631e280b29554db7896ea0161166daec6 9aac9fb068a4dfb450f6eb40788d52b900ce617fd3015a90d6bd91ef74cadde6 +1506000 ec194c6cacf6f8bd705f86be803922c654da450920cc2645ab3cf33d6ec6334b 0e714965cec1839a2eb8ab5402d3067b5c4a4ad39405a59907cd584cee2eba2b 4d72dac71e3fde12349cc519056a0b454c4e7d0a7af94f6be4d79c4ba2a3cbe0 +1508000 25b0dc3381a01d4baa6f9b2dc41d1a2c01da5c5f3357fe03c4dc58a616b22dc9 158ec61d150378b4f5d7ac74e52c3d5afea0c04bd273a55f59bffbbbe060ec22 1d4624166f2c9f33a973c79b697f5a82a22825adfdfd0da7ed505536131ae6ce +1510000 7e874a93689d7dbc4c153107da32234f74a9bf5a3edb773fd25dd601ad1a5322 263849b447e8bf942fe7587d48343611e036516f31198e8d9dcf43954a729417 85e24553835c68576a1713a8952ede7fdcb651c7b16f559b7e70dca18f7e2e1d +1512000 ec4dd0a76098a973ac0419fb3f8cd35aaf7168cb867f5ec8fba06e577d008317 3541cf319408e4f167a4d898f8f7d15738da70163563df7ee7cd011b4a037690 9e069671131570deff1789a2948b7301a3ea67298d73210e247236c430a64f95 +1514000 13c1e9dff707552dccc1ab602102b3fefdf1c35e5d14a2f159442516a5eca5f3 867443991abc49ea6237ab06a350c2c3172b00d8ac8fe30ee4be44fad1f2a0af bef9af97b95c14de2b51b88f7e16bd74c1268bc8a4cf435f5137cb54ab18b4fb +1516000 00000000000011df75a80f5e38088e29c2fb1efd58d99b4ee6ed7d1ff4612cdf 4184ab1f262ba23c1a15a432521827f03fc51e93664ca66ac52f89e31aac2c9b 8157694baf2e11edc4f0fa6199d568d437a68fa5557d7ebd7a30c23fc8ed1414 +1518000 528268cbc95b99e86c0c0ec8bea4da43aca9d124ba96fbecb50d6adb9d04796e 3450be4e44aef9592ddb51d3a3369e668edee6e457d16ea7bad2a7708bc5fc0d ab33479495f78cabb69590e30a58d6b5c81b5459d6b546d244cb5f4039f79ff7 +1520000 6723bf95832d45a8675f13559ce0268a864619b0c17be1e545b19c64012e62fd 502d5d54304620b293b62e576b74c961e9b82cb957fb1a73491275574d7977be 00000000000003e3f1636295fe048493ee8deec403dbb4c58f4a02ab0161a09c +1522000 d4c2434125f101a67d5de6e82951847b91e94e3f1d12a13f656e0916aa25dc79 c32acc1b663703c8aa9948bcf1d3ff64f74b12e352908fac610a26f2e3e05567 42e89dad9ea7101561408283b2c67dac7cbe9745974a54aae97f17a959916e0b +1524000 b1cf947ea471c0831602fba3ee5d8e4bd8731d104a999aa56c5d13fd2dc1d457 789fd4547ea276b033b811d9f6ddaf347dded3b980583594528b924e8b5b1401 0f13d1334adcc96215928cfd138e053a9ac37893b489e6a09ea83dcb1abf4206 +1526000 a0600928053fc682b8f38afb4a640d43fb675d0b042980392a64987d7fb5037c fecda52e733f347ee80bd1aa0e89181803e878c9f3e30c35a58a9f79065adc14 4d5bdef577a63045defc1d3cf7fb85939ee56b7a145035bf0424f993d161e91a +1528000 00000000000003fd1b9a04a66a4d3c1148288445651cf2731cfce5e93e8142e0 db96362942364f8ad2bafd2f9236fda5b744fd18a9a0cd5e65c7f462ac42065a fcf74c381ee50444ee9201c74cb436d5d35df67cdb00045488f475820e8ba644 +1530000 fcb601e899c2709d0a70471aae1b3d273e90bf26f76f9de97352e5d5bec743ae 1e7b2156d53d7fec368b4b6e6a124c3fd2cfdb10810820d28fd383f1f028afe2 78098224adeb6de9760aa8cdaaa5c786453b496384aa099ef06b4dbd02d2f3db +1532000 e3373786ec053ef896419bb3f9b24331789f1a2697c1f6e859929e55c722eff6 93cc87575dd669a6b25dcff68731cd7f467361d37a3aa1de8bbe55d694116c04 9f49abf4278ab2708521ae09f90b43b4e8aede54a680abb863b63d9e25cf768c +1534000 b3ec539dcb5dc56b51e7d0d75fb3f2feb5175dc2d1d46a6f0374199d85ad261e 8f0bee3d4c4accefe62e63fe969e3adac45480a8874fcb06a6ab8536c4197d8a d2ee876e0a58c5482f3ef289e0a34ba563ecacda8594309dc6fdececa0141156 +1536000 fc943b084eb59bc1a709ba2f04b1f16d6d39604633fb95ad3687d5bcd269ed81 087968c8c3e8740eb1d0a263b008f6e456e699a6dff1638a01620f6468e870a7 b1425bc8a0c7b92106ea243ac38d6a5811ec356d7bec8be001dcfa52a1523631 +1538000 d8f0e4b3423fd5e2156175e6a1653a5f32700b3d3806864d55247873fa902b3a e57437e74de9c3e5b45b4310cd7e8b9f3f9b13c5a120e01445c3da3d94202d69 322472ab58927cdfbef27ef71fc6cd3b95a2ed8e5d3493bfe9d4008b55ae14b0 +1540000 135eecd91677b7b74e17c3e28e3fe04ae998c7d755b11f0c9880800034a7790b 5239b93ce7471f4d92577411a3ece0cb600ec9c996b5812495ebe0255aa772c5 2291f209ca5459d6bf01f22fd7fd87857695e86991e79862ab0be29c30c8fc97 +1542000 00000000000009457dd5c574cf860ddf2ab2d204232b63255a5acb641eba25cb c77b1523d1c295607f6a9044762023eb24ffac14defab3ab8e373b16e73b3bb4 79e3b8a9b5eb138d51486e706a5884d762d81ccfd18e6bce10b5557d242cab53 +1544000 8ba3f1c8874aca7889a89ce7c11601adc678b49f416bf62d0e16c8f3722e286f 604887ed33287b8e5bf5bb0d59bc5b072fe34e3b5f3c8ee737f9efe1ce2e15d1 e6d868cd1c01028b0b3845b05382b77a28b3a8bed9a8d61a65e0b6d6adc7613d +1546000 72d739f010984c53405c33b742df67352235f91a4282c54a5b246584ab458f5b d47b562b31b47e2493ff92c07077f6de1d709b1487fffa3efe7c54d6f62116cf 3fd59beedab46efa9533fe56478a6a83b3feb011ca6e00c96bb3195dbc2d74b4 +1548000 822bf4a0843e474720be8da29a921f2cc9bf69e4371cea7659b3dece87776122 84693f9cc17ae9229bfdf9f474576de52c8157104e3a02b45424019e6116881e 0499ad8d5b86d954e47f1923a46c659f55de7e37993596ee3f6db86d4bbb94ed +1550000 8570af3d63bc57a24e4e36a6ae8458bb5462d170bd95e87450c0a2d35d6ec8e6 ebe4192d83640a51f1413fca9de99bfe2ab42b405a41e4fe8f2ef8613e29b1d7 0afdbd2125e539db6dc58061919b0ba5b485ba9c86d4079835536b902c59ca66 +1552000 c632be541c5719bb0c4df357cab20f085caa179a5db32cc8892bbc45b98e7af7 472c51119164fd257d9ef0d6ee88751938c520ca6f80a8a2440cbc40dd43cf63 e2f810b020980b8a29fd6e4d4fda12a50e56e981227a3c0a8f0ea0298ef3942a +1554000 4131b4030840fea8ea0b889bab0c5f02f881e3a49a4bf6030b73ce1f4ff184be df72625cb259feba836c02f82f1fc6fe4a5e4e5ec10543356d36ee9cfdcc5e6c d06fc985acbfa786c0c94d57f94c2ee6697a5023efe854ea906301a8e484eeb7 +1556000 3f95229df699adc5409f6033ed8f6458335efae918fddef6a44816832b0f5bf4 6a7d087984c022e1a97458c41b5c246b4535ac9ee183d5288842d803cf6f3c88 4626186b2453133a7897ef56a11bea1005a293f6a014974eca3d53ae12f59074 +1558000 7c43a369639493e3a96cac1e07200bb5cc9edbacf85cbf1e3194bfd71c8a6a91 1d2ba8eec961514929014ddf949e5e3dbcf1da0d3a819d23532cbbba64e3cff3 9fab75164c62a222ac7c94d5162a21a0ff2ca7b6435c6de09c5644b6151b393c +1560000 87203bdb56aa12ff7a7a8a5af557d7f6b4a3d4e3a9fce29154c0916a8fc452aa 460678710bc2dc809d30b7df86712e5447b458a65b1046c81683de189d372b5c 0000000000000216b46c89eb195003fdddb35b22ab8c5f699543c03d0f3b3f60 +1562000 8418af3c64e7d0028d75b26a897ad2fc4d841e7aa7e9082a3aba64ea852624cf b4b84448000be1203b917b57de6a1dbb4afe50f23a991a5079e723ab816a983d 00000000000004647d130554bbd4953feb83dfd59d248eadbcdf38b66695f227 +1564000 eb1727dc73dec644f5e9b04839a2098e1773fcfeab778fe2a50bb6db021528f9 db67dcb645634511cd4efc78ed70f5a812c9f89fc3e2200d4ff22045499cd2ce be1c5d046f26f4d1ea3b52b6816f47b32ca7393bb857ecca0037955808cc3816 +1566000 0000000000000e1f73322122fa01e4f4b6bcdab7c5d1664f066d9c9211a4c58c 0314ed243cdb2788dd7e397ef8352f94532635e0c68554c957885d4a5c5349b7 32410949d72511af91269d91a1a3b8ef46bdea1d12eda25ae74866dbd38e1763 +1568000 50790047fc31004c7c86c46b2a078ada5c623026d2f2ed075442f91a8aea90da 13512ea8ea6b05224c7b8941909774e35429e229f4b842684312b1bb6a753c98 5a25800fcd22436d385eb4adceb04246363fdd167777cd6fb062a8180f35954a +1570000 00000000000005bf84b99b82d0b0e54c672eeb398ad7c7e64d9d84784eead039 82ffdd22aaf87fdad558da03e98176ade68aab3dddae2d17c4877f6abb1d143a 00000000000006180186f5c1b857ab839c8c476e127ff0141a09c248be0a655b +1572000 7cdb180cf6e4239cbd403ffc6989685ad45b4680288a52da58e5f257916182e0 a1363b4d9fe2747d93cb27b1aae3a7720fadafa4ec60fc1cf91fb546c570c009 cae1f3a5c783b230f73df2ad2df9a000e4bcf8620ed0288b140d96a4114a77d1 +1574000 0000000000000370c1a6b15b925f81c41fe8e224e57aadccf70c3a43b495ad13 56aab435d3d4a9db4e7daa0bf41eebe8503db47f21d6626f21de3bc0e7d55bb7 1edebe9de2c8ead409492f3ed76373fd8d93e58b1cec4b770702845acda204a0 +1576000 cebcd21dd1cd83b2e680e14d8ad48a1ce025f1cef277858821ef869e47f71eb0 78a0ab7fbf0addddbe8341b3cc39bc2b0f46689c88c483359d4e1a42769ebfa7 5b9d2ec39b9fbafdc63339f1fce601b6cec451fd3c373447110c8f85b9d85eff +1578000 5d808f18a5ba362759a12dcfd7401669c7819745206c76b71d47d7be140ec46a 5ddd1e45a2b145ff9709bb83ae579496d62e62069fa8aabcc5988a4d088404c2 66bde40c1afd861b8cad39432e6d57473efb53968512d0bb05f6aef07fd6defc +1580000 75c42ec16447bf1e04e6099e50c621bd444c31edb528a0bec0081654dcc4a1d4 26e0993906b4965a50110197666627649ffc2b0745f0d188dc7032a410232ab2 bf4d9f01b21bd5120e6ae0d93ae5d712b5d6d2204ec8a9513484bc37cfc221ae +1582000 fa764692d7cc946a53ffc51e2aab55590df7cf193dc0c0e7ed9976a0e6b49216 a8fcb7e1d0ee79ed6fe01d6e5025bffdda19e2892f17d2dbb0edfa8489d4a572 bcd8190f4f739d2df29a266e1a4c40bea655c895e20dd94dba7ea5b3e384252c +1584000 b423ecbedea00b1d449caf8f4579cccbe930159452956ceac915fa53fb0f30a6 82ab9113606894a7bc206e550e716d30d358728d3ba74c2de1f8a6a8320f44eb 6a6a19a3e195480e6f89d82ef30f08b4eb2d55b614e189ae38f7415827aab6af +1586000 8f7315754c100647a75ec551b1206e33dc911cb8da9ecb61132fb0f821904354 3351baaa86ff3ed55793c358450047185c6c7c218485aff2b7c98bf4ef277324 9e94958e28b434a531b2e9fe67ef4810824b143a935f529eec783cdab9c326b0 +1588000 00000000000001b99a52b362b385566eecf68a068cafbaecb4818b3a707adf81 03647f96eb99c8c365635109b1f77d005bdb8a4efc8ba674b470c5e94ec02e52 96a70b0fb630ccde9dd1d6194aa0005fe4e3e868b32a44fa30fd30bcb8110c68 +1590000 0000000000000064e0e9cdd1e98327b98c440ad87139af0b482238824be13a2e 2da91e22c638cc9e802b0e46242e20f44a38dc05072ae23be52cc331e5d97463 0000000000000aaa3e34e372a7bf13d372bc6ac085c46cdd0a6d617af2b01063 +1592000 f01f60632a079a19fb511ac03e821aff605b99be959b0bc341818a8f8b4e9660 7059cdbadbcd0d83e5f0abadc07f5149c656d92ac522544ae03064aae9fd4832 26e3774d4850a5b7c1f4869e036675f0bb503b0f17cd85b67d60229615192437 +1594000 fa525e0042ff06c96ea0880ed0c40bca66a74bdbed6b16c2d841be42eb9ab09b 146c82c8a1ce6bb32b30403195123410b76c264f26a9b6992f89855d391a397f 9c50e59eeebec614b36ca5b75de3d792d090623c3f8b64bb44f22b41eaa81810 +1596000 0000000000000621737aaa63de1f9b13403365cd79057a604d101a284606c7dc 0a91f746f32ff792b62310b180a91d8232ae7bbc324660019fbaca3e741be8eb 000000000000075c0715c0e1c55051f7759871bf305edb9831985a92044ccd76 +1598000 bb122ed7c59f41605c58a45ade975307f4227141b6fa27a34f8a35d3961cf7c1 d53ef1a3b5a3ffc245f232ba5194ca86a702ba330fea666463f35ffd6ecbbd90 022d30b543a558de92d36e4ff91d551ae0aedf75ab4a1788c4a833713a90a3d3 +1600000 98efd15a6deec563359366dad7dc180f4b8041aa42f9a7e5fd907152648131e3 297fd33f60efa068f1f794dfb912b24f8468c16f2d06ebdd1c5c9b2520170c78 00000000000001a936fe5bc1716c876724a4e1d09634059d9c2383dd35995f79 +1602000 bebad0487f582414bf8ebf1e33d638547608d3835072d4ae1b70b588d717ec71 08618117c8e3dd9f43959e6a4ddd88e61bd11946e8f186632e0785feac658e0c 2b86bf408376daa54998555765f2038d618d7f12670d6d9e08be134999578590 +1604000 0aa4f86e4e804588f0dd60dd1896a7d6541853e71f18e61db966295a904ad362 a9dc69d359963e058c69a3808c5f1fcbf15e0745d513f3d549defbb9b9d18ba7 8dbea55182f62fa66389480df1f05e412f22998215e92bf1d432e42fa179d2c5 +1606000 85fe2de4b42f992ee52590c29a2e9da5ac3882d45c99a6f1b3bb337faf4c17bb 930616492f5fe19027c285290d26f6d8568528e481eb85418829c467619d7d8d 5a81639aa829cbd5c7a89ba1d7fba03285cb2757d8b911500bca63153fe3706e +1608000 bc0cd9862f32f51261bde7be29a5576e4b9b13e944ecf997451f7dd703170aee 63392989e27a845ef4cec552b0b9a4295d8a0345f045e9c38998b2766ec32d51 0f1c924b3bc45241b34ddf9b2782162a435d191fea94f0f8d361c089b7b480e5 +1610000 a1cc4137aa69b5e2b10008632c070a4f95e3d3275dd789773b5959f22dbcb0fa 219e6de86105ea862c3addbbf6e8c7bc05db613ffb69680a1a007805182b69cf ed5d6db0d8ea989e1eacc65c0ecf4d91127d5d25fa81f99867157af92a721b75 +1612000 d80fe4475b9b56f83741355cfee1292ec23465b3e46085b3153722b126af4549 1e8416cbcf511e703217afa327a95d88fa85210646987e5a86c316ff8b0989b8 dd3fa726484ed9ecbcec23aad7e7cb338ee9072c065e69734e3c0f72829ab5e1 +1614000 b18953cf69504921f19758a148ea9e7f872ca2006d5dd849a5753c4116cd6860 cff14f1fc61061e961ea4ee88e8f2648a57103568c3895325503eb1fc8a29b34 dd382d83d2f0776b368a795979a6eb16c679eace5c7d9880c3631b3356dbb1cf +1616000 0000000000002200435b2a7fb1d9d07fd395625ac92ebc0d1b63add27e52383a 273c6c5e5858284df21c95b1aa346c7be9a0dea983ff217ebcef67c19b273606 0000000000001f5f42819f4ae7e78d9eb6ef70469e3f81c13b1937959348f98f +1618000 1046d339cb03ded0208ea3c4c1ec20165b2c55adc97d6c55f3e612deaa56252c a3d0d513e6bcfd1c78aa59c88a5d524726e3b8452f600c54afbeb36699f53cf0 45e4f4943a9c25effc2277e732d650c5301f963bc9d0172d83745f11ae10d8cb +1620000 0000000000000a54e42300b48abd011a7178cc55233c08d3e9072c4563fc813e fe70404f5aa91aedfc30ea02f955b1e283be7374b44c92a86c0d3f972548e12e 4c57fafe3f835db36798e9af0852a84144a287a2a1024e804371ab0eee8e0188 +1622000 000000000000060a53729f316e994a2ce2fe2431df352f6b28512efeaaff199b 79bdf3c4cbfcd99ff52f60f9f81252de4cc5cd38c7c389db4e11a3011347ffaa 018aacb3ad1437e429a6bbe8c8a4cd77f3eff6cafd4286ee999c5985a45d9c08 +1624000 6a138de92e8181fdf2bb8d944814cdb03cb176294b5fb307fd313f34fa71ea0d 5f40fd637038b273d82d97539540b834eb2107bf5384ac6af0bf1dd308c0daf5 8e742d11759b53b53122416a1cffcdd9aa18d0238d334f1ee8769eaa5ded2d8f +1626000 374c849991d3107d7e885e36ab0f3ae77f660fe047be610ef86e228a2ea54c21 56c1bb8af8a976ca0725d3a81078903e0606123a84ac8bc405fb2d110e135682 36031f909663f508547c2e4c6e3c315974ef67ee5da6130769407d5d443e4f6d +1628000 07a68e876f0f8283d8a7b5e9ec5bd4f8c6d0211469f29143244214f97a530772 cb88589fabcd692317a81ea73afa47f39579316c8e47156325ae58c696002f6d 06115c2311346c01f3341307b4b0a4f1348a207abb8b85a4778f965f4903bad3 +1630000 1bdd86da0b09993a895272d3332939bc3e4b94b588058e7df2d29de89d5f09dc 7c6f87c995b968ffa60a40747e5211e9cab4ed53dfd88c8fde1d27b7b3c2e324 417b89b22aafea8bb2bf8fc8e40bf23fbc291ab247fda25ab52c5b4448aa13db +1632000 6843732609ac1315d3d969f5b1b61c24f725225163bb884305eb42d2e0d43fd2 e8c29e6a255e2390fa1ae4830d73484682b5a409ee68d8513486578b2bf5c434 eabe25aa5a527cf19e0bc5d15c46995e6a7c6288cb4c3ef3bc85890f2bb20270 +1634000 7462c00d96b3ba68326047084b61eab5b6c64e9733b795a87000d9e6180cc321 cd021fafee31761a2a88e1b94e7ede8e870f9750cc27c1b321e52c3584b7c390 fe7269dfa7dc1a6f8e3ad05eec61b29f611ed7114aa981681b98faeb45ee503c +1636000 00000000000010942e5d47d90e183f2f4c4f0e6ef1a1808b5e2201ec0bba80d3 7104ca278b28c5ec83df55daf3c89942e2d648c37999155a219b3d98a2778481 6b8bc4d6ebd526cef1847b4bc71debba66729f0fe0b4471ed5a8def42505ff91 +1638000 468bca0ab1aadc7ab533b535cf39ca39ea77240cc0a8302b14fe956037fb0604 b53c25fe895c13717288ab28b9814a450113390d441febd43a59853f54d17073 b8b43f95ba82f3f94c5cb0cb98755df7034b740fb920a8ebec0a7ad99c3b93c8 +1640000 b5d9ce2caf5eb6569d1f698586c1fd47420e1c7acf0197bfd8847d3bb882fe7d 88e1ec617352302e7ba908318967a16f1d74ae2de703c4d14a726d7816dd2a34 0f5a5617d6b898823f7e9066026e8762c2fc216903052c302eed60d7f5ac04fa +1642000 9894be451660c827705bf9380b1fc73b9ee45d2844dc694c4db651cc38872284 8f14e5f86f82b64c05442c9ed75de9f0f561fc167439325326ae9a2473ef5492 6d40b1481d2e8273695d0605dce49dea4c6a718c86d5b9fdca0ec4946e4a073b +1644000 12eef2426a7d02704e92108132212d2f115986b622752b6096847582ce3f94fb 34262f7ecaa6c036593d83ee47fe325c519ad3fcba172791f658c33728413047 734a1d551b46e1fd7cee4f93d69d47eb3ebbe77ca1a37fcbc7590c8125774154 +1646000 e45b521512ba23cf326008c84f33e0a91df7a50d4db4a235b4b0b0dce4699f36 4e970a5de6d9416881a6e8e6d2ebf163f5423ee797d9649a4808c69b59b89d1a 1c57824b1cd2d71ae3d6dfc973c97e910fab41f29f208920123de14fc34dd91e +1648000 a4f5cf8d992922fa39893ee01a54a58afad1c87929969f62cba145176139504f 110e7124c264d16ddac23ed9afd2460dc0371e00cf80ad8a3244803e3b32fa11 00000000000005a8badefcf37c6a273f24e3034df543c1e2b6f930c6fda2479e +1650000 afd2bac9cabbff200a007da085631e20b4bb7eb1d870e1a219a354754b7a1221 095d7c8a4ad70d1ce8408fa37e3cab9ed49dd648905b3c65252d82b80e285079 f4bd473d5db3ba297b535d76f8989ec5a8cc8c4a030c8b122975835a036c9f4d +1652000 b658cc375f20a5e18fb6ad57b22ded1290ff8d63d8b6c4221d8bc9357c4b401b f63009646361ee9316904d18af7e4934519c13675644dc51686c159ea9535497 0000000000000731021cc17cbcb263b9382485f74a14d884d46aa9071ff503a7 +1654000 528581d972810a59599369579384ae28f26542c2fd92c090c33bae09f8456663 528c4c7934e04e27b31596901e7f18cbfb782dd4e0f0c5c53c8400650f7afc13 000000000000095dd1c587fee4ab7bb32181948a3327594bccb95c3e37443187 +1656000 dd8d6d13f33b7bfc7b80e5048b8ed6478c19875ca13cf570742b88f0a275f54f 3aaecfbd6bf35de141fa20f116aefd3c625a23a98df430454ea94e2d584b6fa7 754101f76cae8fd4a997dd7fb3eabe05cc106d205700d496ef5ba1f3765fea05 +1658000 e71f9b4242fb3340196847d93e789985f263016691315f13c930d07a29b67f28 a6702b30d58a0f0c8b41a417c170e0c175159888baf4b30f8d5f27989f7dfe6b 000000000000014d31286260f97eab1d880153db9f7f98bddeadb24367e64d51 +1660000 2284884b4a1b69bc05249acf5a767df155f9e91ca17bd733df586f254c0abd03 cedf35f3ed57d04eaebce93ee41e4454cd5f2f9339ddec3aa6462af6832f643f 8c6d5c05dbb5f26fbda327b02c9fff33e5911dc723bd4c8710e8909de1e4b741 +1662000 3d4ebe4000611e358e7865aa4dec7c4ae96294335a9eabc2d855e42eebe7d136 85ed6961d8cbb9f7de9b7f2a826eb09ed9325f2e54b8c90c3cf85b285e951640 dcab786bffcda83be99a2e52c66acee0784b9c7bbea838c000daced723c942d6 +1664000 1e514646cd426e6f1cb1f38fc270c6009f3f0b522cf258ce565b897f5633a527 4402f7a42e824886edb6d67eb2e9249f9b1049c61569e3148c055847bac6373e 6c91fe27d522d6da79bc06b28237b47a7662770e11e89d294d5111575d11c4a7 +1666000 afcf9dda89a05be10bb00800eb3a8aa6905a6a36f2c3a8914d3b984bbaeba0e3 c6ff2d162f86640edeb5887d1c2e3f4fb74541d095bbe4c277411fcde7ce8c19 25a26bdbf85dd54ea6a1f34db4ac12ede724e6f1e88ac96b11493022ffa69a97 +1668000 cfae74f24b03a122994087afd773941ceb13f8f889688e40d5fbf37bbd4148ba 4db54ec40d6a7be4b4520cb1178949397b9ef0db22a88805fc1ac3a48481b255 0000000000000319b53ae02bf0d694773f316439df09e5954c7168f64647aa53 +1670000 0000000000000a528693dfa988f41997687928e2b04ecd8024501b1086d738c4 0fd01ab3bdd0573b6865b409c33118a427a7fe215a465017793140188cc54acf 08dc4f34e33e6aa8277f58f43936b63aa1eea441eff123af5392acaece22871d +1672000 064bb51a0880aef7face60b608edf2e958e04ade71ef703a2376148a989bc314 24e356cef9a30cb64924dd4be1befa361ea62216413715348a9476790841e56c c79b6a3b944c508f8d956f39a6fbf2b4ab3234d0befb82614bee757de00f1076 +1674000 894a11baf95f76eef02007857534b12fa932f43fc5e96ec2edbbec01336c4929 555aaf5827053ba7d9275437b5b1e7ad612b15ea8dd2a8c649c30b485966b7ca 5c89bb6886ce107419b6599414343a2982f162d74f595ad382f1dd93b909847e +1676000 35b5212a90079dc700f1c0df5ca30bc09c604acec3009de18b8c2786067fcbb6 84141f421465c4e8e201c73f186c8558265462c5e69ac53c8f4c66911d6fe128 000000000000068ad8e01c3b48258cba41cdb3e6c050a58c9c56eb6423effdc9 +1678000 00000000000000ebf73ab5294ba76e17cf26528cf296632952065f5230bad9cf 44e6b789ae23600ee69c1b7122216bf8cac774953c1c2dedd9f4b775fe501e4a 7219824e00729e2deeb417ae5ae4a7971bf35c1548c214074dbc78d553445b41 +1680000 553eff2091d9a1df028eeb5dc4bd5842355e4c8f70c42608b7bceb66d16b7ae8 b531a9a564a2e803e4232fb2e170a9706647a84f7754f71a10ce35c9326fc74d 588b8139ec44bb8fd9578c37f309aa5379ba3e8ba37d19cb684d4bd8fb7df757 +1682000 0000000000000048218a90a419491cb30cc0d48399e11efa82512de4d4d3e968 955fabc85db69d3f33a2c3016161b9345275af2f85f28bce20764c12b47e8f2a 05c39ad2cc8a9e57398e4378783a27434f2468977d57bc14140ef586b5371738 +1684000 07b016b3b85f7142b6874fb736a58affe56b19eaea357bb9e10bf4b06c04ea4e bc9bc7bf4e81f78b4d9b398dd16a5273e1ed61e3a987977d36b940ed5a3e6f0f 4baf21a016b5ee163f7094565674bbde993255e8cd46e60e1b3648d1ab636c90 +1686000 f7027c00c02be12f0edffc95baea83f7ce412f125b4bc7178f291fc51ed3902b a9b76824be324ced77219763e45848137c998148f971aa6abf79cfd584f265ba e4eb1252522366aced714fcc02d658dd1dc13aec6aef1bbb317fe8973e843f13 +1688000 d8ad171575d6f1a8039111c652faef801a738bcf6e5bac69a14f4ebb6ba0c24c c91f47a65b7a81cefcc5911fa6b981d1f486218ad7b271debd38c9df9d8a57d6 2c341e0ed3d82fa58a2971ac5cac1bfac302f91b582992913962ece6571422f5 +1690000 603a1bc3a266cc32f6d38c97e9f4a0d3206cc3eaa0d4d563cf4012aee75b971f b67ce5b4826b001d38116cbdf551a8157c575e49705e17f092e0c0efd9fb3ac5 0000000000000205aeb711325997805f64864c31c7bc53fbe5aff15b72caea78 +1692000 94cefe1be3f2f307d0ca52415fa7ff74082e8c83dc3c82d0f3f142360bfc815c 1ccc234a8896e5e9816aeed1fb39dde2c621bf6d0314a084318f585041ac85c5 0a704e66c22278d06499f7eb47aa2b339ff0fba22bc77f30d092fc7bdc37354c +1694000 00000000000002485fe04b115ca86caefd2b07ce75710d458cfee89c3ca1e4b1 77910a8c8e7441f40aba56fd83ef99af21a47c21e485198e1a3582e8d348e92e 5310a7ef4bee3421a3ba3cb11a4f2e1394e011918d563705b9b3a2fae621c9b1 +1696000 9f9fe46c1a9f08753ecc239ed02cc41bc5195692e5d227c694ed117c7fb7de21 541fa17717dcc4ae5d94e6adfc3ab6c6fad79b9dd82b538d291e7c30cc0e8499 954b606d842771ff674288873b48a7a6f566412a0ff7e3692284665f67e9a51d +1698000 8fc5752480354fdab6bf0273f6002d5758e21deb7219a8031215e77dea6b4c30 26c367680e1a15962de028ec9c6456b7d7c38a6560679c69247e650d0471c760 febe793e106c15f9b0f0b6d15171ee82edb317b4f3b1e99f614383da3dfd2a75 +1700000 000000000000069834ceddccc356b743970fdd07a7596a8d7bd3b30fcb11ba32 6558c0c917e2a6cab0f064e2725f714f27037807e01c0cf5b9b076f02c2a0780 6bdabeaf95e2b37a8eeab4a0fd23822b3452cd08a88df89f60d20c21a939c6f1 +1702000 0d2d4b4eb137921369fba3f030f159a3e9a68d01b0f48117791e116dbb5f8aa1 21dc003d571101a9376df67edb07039be44d51b702350ae5f32d5112077a4dba a9e27f820cdac53c703377e30a01393c743c9c9a0a7e5fbdf3a7e45489f5822f +1704000 74a76db8ebbc2e20bfc5f32732e3881cc66fb5dfa51e98e60422c3a27f194583 f05293bbf233c1b33272fcb650f606d350231b316f80d31004cb21abfde545ae 7121ef09c8b2a6e4d11e92eae86f8d9dc32a577ada399fae62e859fe44ff6c40 +1706000 0000000000000d699fca7f6d2f15b05621e533df127389423c8a7f987e559d11 74daa1a29c8b0502fcb553321592f0184114d99ed4ad6cc6c799eac5f1d34817 000000000000015077d2cdbda03f26d2ec760e75443ede5710cbde44576bbe31 +1708000 0c71943bb01264f43e52844378252ef4e1589b9cd3d51e4a469b21b108174d56 0f1ef0b45c83df405dbf3330069548385ff0aeba259ed5c6eadb91c5fab034a2 000000000000011572ebc38473101c70fa7610b065bc4f7a145b918870e1f308 +1710000 0c3dc309002345109d2913341263d678bfe7510739bc40ff85500e866f77916b 10b0f6bf02721b8a69c71077ea594af794d6100ff50aaaa6dfbc00a55f646264 affbfddaa84fadff6b6dc5e44d96177c6a3a02e8cb9fd9a09e0c01951d17834b +1712000 aaac99b4350bbaf7fd8fbe4ed0087806a86ab8e96230c64800603aed745a8fc2 d6ad03f248db3f7e9d9c672ddf1a874377ae404ea7a4928a7e296bdef4739018 00000000000003b0a303fc327d3e7abff7ea7e987df987a7ebb4fca94f49a487 +1714000 c66121e9e235d1cba91cefd9032e4cf966669759f80e4e3b088dab7b20b773f1 1235a5a21d003467bbfe5bf2c22fb91d5638225d18b1cfb73be64bef73a01132 0000000000000780f7953bca96cfc28733b4c645e829388b90f361e35b9637c3 +1716000 26ae44268adbbc94f42fdec772700433182b412908afc167375160d2742759e7 6ca1f14476b680b59518e83326692c5ab293c3f3f8823c336823687363cf2662 2a58e86592041aad3ec7641fd9399ce2a41c57dbf6b5b6eb07f146042262fb3a +1718000 0bef8626c6fe929b6f86cb6de9515a3714c6403cf85545989f32b44afc42c88f 3745e997da393971e67e04896e15d9fb3df485356a68c75f6f579fddefe44347 0000000000000436c36b96ad95b69cc0b7cb4831063f9260c7144ff6ed4ac9c2 +1720000 7f1963bd1aaafa64dd35bc00c089639586933b39a5c2b519a467964bb60ca7f6 05e9e07857b0b58e23e3886156e7f15aac5b99f2796a418d89c898020dc92f3a 2c204e967cde82acee5df4d055d06bf6967eff80fa3e1958c4e32ac42aad0bfe +1722000 68ab803dfb88bc634af70f9cdab8eab372f2eae210112e2195751eef42ab165f 60c4b9c818c8ce362ed02745040491bab38a8f9a61ac0319f02f717363571c50 f896085de22a5479aaf9694adb506c167006872f54d825dcc2ced51f01c3b2d9 +1724000 5078e028657e84355c48a75c8bd6bae82a41b1ffc31afae683daf5ac0788de78 b9daa9dc319c782ffe12ee846d886292d85a0675504c919c1bc2a2864a0f877a 000000000000073b6fcd8a59a612cdcc3fa4b0f6c30e02b92c6afe41be86a2e2 +1726000 ffab05a1c814b6f36521e9e97f3a49299f40fc260bd180648ebd607707bf7461 451871b0586fcfe2d4e603b9f56cda1005052d53b7be33bd8bda94e6175e2938 000000000000046a67214cd00fc299d4411cf8949fed272186a578a79dd0e408 +1728000 987ebebca9c8eb17a419f8104929b81b3abac034ce1610abb8c0f3310afb6c73 50e46edc5762276f7bad80e9b3d72a901ddf4cbf806ba91f9be46c1fab6c347d c429dba4c703a55d7342bf8a4e861b9f1581c58de36946c7d9b7fbafaea2a1ec +1730000 0000000000000d762a0ce63dbff13ec2df0084357169b1b3283f2cada418a2c3 f9f04abe9787c2d9439de5261b9e620c1f8ea80b24dc0b935f4f9f38a2a40537 9af7b531a177712e8c744cb6fdca0cdf022d9e23c8f3a80c249dd672f461bdb2 +1732000 0000000000000868990fe197b781498ea9abbb9c5ddf707658a8e7120da16e4c 271def83f334ecf729a288555c5a4aa6c0c4fd797ff618b53278994eb1f1e183 7246c9b2c0e6626f2bae276f4a65dfa9d0458199dea90c59999ba7724a47050f +1734000 000000000000038300de2ded156b2a86137eb09c66bb5325ecda8f0e02a2f1b9 13a3ad47f0c8d63a63f8eb0799dfd107d4d40bff8aac52d66018d9187f32dae9 00000000000000285c6ff04d22ba1411f7077204d4c66e0bca57a48aca5ec0fa +1736000 cd56911268b4edd11e71b6da4b32963c154b11ad0ce9f851c300290728f75b47 a04d05e4ce296d5d63df50d914e5267ca83eebc25469b98d729343b571233187 7905345cd9335c2676e87621beaaaf2fa27293a00a4d0d4f52285397be81dbce +1738000 0000000000000c0174ca976bfa95c25add135b4eeaee3679672a9227b8c8be23 184ed4a92ac7712908cd26e4e4f379d06335c8be122d032976313691346b35bd 00000000000002a20a6f64882acf5f17c7941afe411e4d85c51feb343d537de3 +1740000 45cc31e29833a1923c26303d5b8154e5338b66e0b111d315a74c61ed45419e4d 35e7644ec547f84442c1298b219bea9f0ff2f862f44a7ce42296ed6943aa4333 e44a821545fccb9205eb0111d6099a804959e02d82b5db3b17439de550bf0053 +1742000 fa283a1e327ce252f84a6aa0a32f43ac50731452b63a56f31888b4774ff25981 1ccf23649352c947ac0a33da9ad4f122737711f7aaab28af1becab8f0e2a5151 00000000000005ab998f6a7fc7117d34bc16b18c1a17178f8bd87787ed988952 +1744000 69fe5e8cfc866066abc85322cbcec86ce9c28a38447d233433198c1465069faa 10bfd3c6a6eba52ffb975e14878a48564a17115491be57302192cce3faca262d 8350280f0d15b1bb27aac5a8aa9629e4dd0eb6ea733757c97e252c6ef3896739 +1746000 000000000000047f8e67bd36aa76e7c2ec58aab9b44e8b22b3ccc774e92144d4 5d48910b174ac09865a8670eccc47f004e351b83d9a15693efd25175219a2e3f b55c7b90bc0806bb80b7c28e29a2f1e7ec4c3a01e526d6c46800bfd86e853d63 +1748000 d1a0b858e595d83511b7adcc9c76bfaf6b4ed2d993af8351b87c72b2b182d10b 91b681ddb3da93803fff9a40596f47023eb5183592fa123431a6b7b78df13e95 ab883f3c8af5491890c87e46a6a1dc78f7deb64155dc8fe997bfb3df40fc4e83 +1750000 5967f952a7336c4f7d7e92dc51daffb132c12fbbfde2b912ab8e43a20a82603f a18db12cc3822c084ab36e6472731ce9bd4241c8321bcd160837683a494c73b3 cdb2d96f03873fc679198fbc527681a6c208ac4d913ba0ffdc00505d50461c3f +1752000 faa998e0068de9b59fcd3f26847bf28fe95d360d4202caedbc19ead0a439edce c5a47510944e834b26bc285a5108e06928d679f1a623a55433f5a1965c5aabb4 781109a5e4a57e42d019f39c9d70e0605f46181c1b5887cc5880c66566da49c3 +1754000 9f11e7ef44e8b80320531ffc2b13917439fc6db41bff8a72084e6196a7a6ce34 1758f817f28312d913ef0a9036f04d091d0b9b26ee52e87f3b461948a99a1cd6 131a57cbf42f388a0c6ec6e8d66b85941d7faa47dc2fedc69d683d77ff19fd6d +1756000 41593bf5714fd22e0896f8a01eb9d58e0b318823d04e2243900c6b2f90839547 1930f3b755a588cf5286c26675e93c8788eccd77eee45c8c75ecfd93157e44b6 0000000000000018da69c51639aecffb48f850beed410591c6663d6f7f4e7fb3 +1758000 50702f86b7ee64357b60ffb54b25e876f7f0c24b4564fceb9dd0bbb3b747395c 867d763f98668614ee988b8511bc7290caadc3606781722eb72421673029a116 c95f8bf9faa37387a14dad24b6d3fc2a9511e080365a2face9d43c9bfc93e7f8 +1760000 e827e196339000ba47fe30aeb8be7e52c48ee0f51880bf8b8a262bc82240dfb7 6e55e63facc6dfd202f7d56ca4f5d7b25e6d749c9e5671836c73a4dee6aa9b61 00000000000003a2e806abb79ab17bc10c054b50f997f4ee7173da96b729fd08 +1762000 b6811af9510da19ee4b8a2c4bb40a212964439c70348b5c24bedd03aa3f71c8d 80f07c19dce2f311e056b379140a141155d56d11f530895a6e397de36c33f74a 054d8c654bede54eeebd5a3a5fda78f930f3af1f11bfdc37bab7bc1615cb2aa2 +1764000 5400fa0d1ce714aaca6ca7cb06ae6630999bc2748a627e0302b4ae5b9e6df8d8 ff29e4a66626a82371200a85c8fe89198de6067e21f9b14f6bc970c7ea4c28fd c807a413c95c29b469694fc659936a5b72e353b2a4e9c57e2da1f54f32b5e5c0 +1766000 5ab513f46b44146fee625b30f784526f979a3cbf8ae97ebeaee0cc754d804eb7 2f7de029bc0f5918bddfdc4d5a0d4f922326687e8e35c603d237c602a0099d4f e3c0d52acf66ad183492c414ea5ee1d43267ebd4d4dfe089ac851373fe290341 +1768000 55b418003b551b30bf147ab44b8dd9e20aa70d5e08f5bb0dc9837c53d0848204 36dbddb04dbba625ddb66d7793bf9096ce61efac8e3c50276c15c5beb30d3500 00000000000001ff95dd4f212c3b260296f3ab386050f02625920a09024fa4bd +1770000 80423623e1c7a4889c70ac1af8701e46836b09f619c20c8ba4c997306294790c ef30b3dac47329e3754a0ef8073e53343abb4bcb910b3606e6251e6ad7628e96 29f2147f3fae5cb2b5ffb1181cd1cc4b2f77869d8a486b5bc7f7d5c55077f411 +1772000 03867b2332fb7cbc256e44332d9f2464b36d5916ef92b3321b7549f09e48fdd8 4c718c3bb58756716cccc6aeaede5418c5a7481e2ba493fb63d2dcd219c51daa 94a4a9eb5881301c8910aeb52b195f76b0300ee3aac323deb2f3db64d27d0b59 +1774000 007ebe7bbc2991d9a1c0d91fab0938b49057b630955c2a6deb212a14b74db3f8 1de071dc1c89c7f76d19b14623bb523907c50526312b2b7019cf037922fb2840 7761ea19358a31035a3f40f1191289e19b7293c0e0249a6c3b4b4b61ed57f5b9 +1776000 eced1af56d5fa515fe52a95c6671fbb2197d17f70b3dd4be8059f36f1e161000 5190057cd788ec6a81699621e4548f01b8d1375dc7782bf60f37bab0724a4a29 64d7098c5267b5b2aa981dd301652132858da187f1e1adee7e404a3189601b2f +1778000 9e570ebf09e540db9790627e5c6a3cf9c5f60e2dc47b717a6b8c5214b4c16aaa f16a011a5936bd7f743aa1a298fee15d366130758949ea414d7cdb534713960c 6d9e3d89d7d1e5fdc5e54755250672e0f260804f5ec0c37d2a8e5e071bb86843 +1780000 cd1227816a513c0ea699ba10406ccfd2a02414b1560843d8f63de3197d606a82 d69739ba9d8c3647e35535399e8593465c577b23d9d0faf644b252d1e90574ea 00000000000003660e11cc1f1653afdbc62f6892f4ad181ada8d29002895789a +1782000 e2db77f963cb74773f75c98451ead624fad18aa567343f34341e3bb4930f7ee8 28df021de7b13853c7666921ded95bea4b0d5a40708ec24db7b39bf556941804 909eee2f26bc06233f9f548a52efbc9da00e97bbf55388ab4186a17361a0bc23 +1784000 320a609c82ca9b6fc469dd931367f6716703f9cd46e78c6e4765c9c3cd86ac1b d3b3cd1dcaec9c0905b617f0ea3f75a6c4cd9448c4fe11354add8890348341f0 f47c594dea4d50ffdd7116f87a6173d5db0ea09c264334602abe4d586c6a8be2 +1786000 e6190384f212b7710fe315068697e5eebce4e47975021b81b832e16ac53417c3 058648aa0f68de5a5ffd994c31117602f1736c93ff6a84732aef048577b771ad 00000000000001f98a13f75056661ed6f6e15e1d60aea67bb4153223b1b083c3 +1788000 0000000000000022585e2c66b494e44f39eaf79888005b1d654ec8270f52a119 e026e55c9f66e23fbb257841d841be465981111c43fb8912a93aa870b1683cc2 af6b1a3330877aeb908fe758419aa7364b5c54018152056577aec9a63cfb515f +1790000 00000000000007cf04434c3eaa295824c63524012a5466860294101e9b55f9b5 57445b93022fa4bd2cf2baeaa3112e4639d86ae1887e688746c9144e4e0e06f6 884692683b9c17e2babd939ad1bfbf63c99b3067755303b9d2c63da908b91b0e +1792000 e8d605d2bb80a4019ef785c17e92d047b74620a14af7034f60a19e6967100d02 604a7d423e90e18eb1d2d62f02d26a1903ef2fee44f5045e6a41f2530f3079e8 00c130e6c65c7b300f5d5b82017b4a13452fbc380d7064f3100b8230de367da4 +1794000 996c69f051ec83188d6d599d21abd706202ee8b6936180b9f218403b480c1e83 5f9d39cd59c92352434c33042124b9264def73d48d00c3a97ec1c43b50bb2f3d 316be80c966cc764af965aec0a6556e268c521cacdb3ac5a9afb1fd3beff359a +1796000 c6c53a0ddcac706926fd3082826d895296a5f779d1026f513deba013085eee11 44286e2ff6cfd5777fdb8b20cf4bf330ca70a323924b90175613ff8f5943e62c c48c40b6a3d9b9a06103161e06117877ee2674b2b8efe5774e78473c80598b90 +1798000 2ee99a5d62a99ac388b51b30e3ba7a925873dcd1f89591b859ce156d665e927e b805ae2f7023bf563abc7bc305af6875d9539b5d4d3be46361546ec412b6e941 9a80b9109ebb19cdb9d0a71deb211796e83df54baf163dc83711489d2ee08f2d +1800000 72f46e1fff56518dce7e540b407260ea827cb1c4652f24eb1d1917f54b95d65a ef59d3e5ceaf19a7eb12931986d95baae5f7b282206bf6a06a9d0590b152f572 87803072718d62ab010357a7c20c7cb6b6ce3c60362eb85ba3ed4b27b5244f8f +1802000 0000000000000a85d788494b17beed0340e3685e95f22e9c6fed2db7f294c25c 43a353cecf386c77e9e9e44d067f937e972c7606c64bebce30043770ac953b3c a31a5af4bd6260e40ff6a661d855e41b17d0becb3d49336ef8631b0b303a795f +1804000 0d8fe751adddef63680fa6d54cd1480607ff1b1d6461676674a70e7db20739ac fba8611de6380ac2cd43b4dc2d2e5dd6aea47abc56bbc5e90a577b28727ef694 dd1b1408c98ea0858e6efd8f915183bb69fa121f83afab769a273d2860fd987c +1806000 49ffa055bf3f4b863b0f83dac4ef69bd35d56da565cfbdac725eb100cca489a9 46ad630178ea201cdd8c41a08f1cda76476f41859de398ae833c9c2a56d98b3f 0b16e69c26cba9f5b79d8a99401f6a5d56208c85140ee711d68b459c1fbd4fe3 +1808000 fe8be20a0c94a72b933b65e9c9480346e24a1598715ff3199eeea761634598ca 1621b075fe2b559ca9190c7a8cea954a75a5bdab040455dcd62392bab89426e5 cdc7334f3cfd33ab75758448169992d1cee9bf8cd5e88ab4cf838fa4750dcd75 +1810000 000000000000031cdf0f4ed4be9927aeb9dceb0b87a3057385945c6550b7a2cf 392d3f508f9b9ed5d207ef12c380f7b0be6acf174780f1df912595804919c456 7629f7e15eaf242f8d05be6563df3c55b7b77714282bb8174a2beaa14e6336d2 +1812000 b80fbf281206706bb539da3b63d47b3dbd9b9632690cca1b4c4310f25058fbad fcee09eba1f8be5ed8ade83683c5359134d5e40445078e258366a2cd27c35234 028dbba633abdd5900f67e7e447677abf036bc4f2258298de53b0390e70ea16c +1814000 000000000000019f88500e6280b4f3dd24a43c49997ac23e821e174b9faa98f7 a8b3862c598a1245eb9065579f9153624a3446048e9384f62083da4d06c06970 63cb12bd953798a692ff71c3418d5e00dd988648245dd875d7a4cc414a557959 +1816000 5bd3f61c5fd681f7ee1a7ba707fb0d4063a0fa438f48445a5164d7bf04bbe0e3 0980871726be9d4e0bb9a073b7378f47a26d72060b320e3d6f783fa673144cbb 83a76cee9fa12e576e204d2ca322e0d0edf96e12f53cec5ea7cdb9320f5c1959 +1818000 61cc862cb60d8fce8fb5d345a6f372674fea0681ec682e052be1fc3735dad347 bcd67d26502ef46f62f83620680d88727020dee5a1a2f1c05524bcf75dca3133 0a921ab744ce72b74fdb708764808bd2cce99fa8166b4bd19a7fde0534a2d2b5 +1820000 978d1b01f2f99ce1d54bca7e08132d693eebc4208d6525bf55938ab214ecf67c 70a43f1cbe483c4655a13163f7aff8eb118a159624b76aacdd5d4a137b5871f6 370d346478259f99a706ea15dbcababbfa91f6b6688b6f2742374ff7856dea45 +1822000 00000000000003b05587a5f65d59036da390d93a86af4e0c0256c47c2f914343 5831b69e8c8ef5b226c0a5556e0aa77c7e75cd76576099da4d87788a8bffa0c2 21e2df8a74f8703e76cae9898d720c18f5a4e1d572292ca3976ec6f2bc0008d0 +1824000 861f81f846f1a5d20a02089d7ed76ca1e61d11f4ef84f50e62d5df6375f2a64b 9ac53fa8198281e2568aae7546470bf6b1f15d678f216d90b06f4c54e41a1cbc 0000000000000359f4b5bb6b212943e5e022e83bac1fd34a7d1634f68910de21 +1826000 35a55d73e3a1b8f835c86b1601515e36e33db50e03d894a4535090cc21ccc26d 8e509e205ca4c6287c01acb93f5d2d4ddbc12a19e9649c4a9cf7c3e34ab9d799 acfc351d47d8d1b17a61a60865288e53e9d744f2e77cbba59cf80d86201ddd6c +1828000 0a157b04f837f51730e6279979054b82007be3aee27786b04d4a187e1dbce8ef 8dcc876e7bbe7f578457527ee61290da765b72bf0f5b52fa8cc76bf541f2247b 467d0c0c75a17702b357cb2f2665b2080b0cb0b28a8720adac2d1a75b13a58a6 +1830000 7a29489be83ef36dd78dcd66e8cbec75b846dfe8be2fd4c58ff3d69be02da43c e37e4028bd233a7b61a355d9b10ee89114d830f58c8d496cfe63e96ce270fbc6 68844b382bc42d7125109e62cb578970f77835b67f738a65e28d6f9a623000c5 +1832000 27138065165812836b91fb5da903fcf5f4a45729b8bc212d800df2803000f66e f6a7660c3e7eab3cdbd260d99bf6a4916d615f61ed72955225e75900d81092ca 8a375e9cfda384fe888ec4e8543212b80b103fc9447db004602983e5b41c9908 +1834000 cad689292a76406a4984838633d136398f3c62c5640356f49fa5227be6778b71 449d57ba86914881333fdc6b6b92d66d508a18c6ed3444d7977eeee6de4c8aa9 4dd79d3ae5855fb837f70556488d69bf9651dbb383efb9627c3a0157251d4c8d +1836000 8fcdf7b17078eab6fc791e7cfc990ae0f982ec135d4fed43ad6a2f4b9e045a0f 4e81b6a1b36ba0152182d6192bf6375219ffcd0d53ea19ca145e2a85ab82c14d af7b1d6d32557e8c6cd1f103f1e7d10cc99fb7a9d387df1cafa25a545145b65a +1838000 f09c428ec3609ec25ebbd13244af0f3d25367e5006aa3cea0322d0f32f0f99ca 64453bdfa148e68e50767a0b0797a852695a9db9509967c2c6ff9c90c6b37039 d6fa9d7a0d820c943b44f53ecea4184ffd88b9d10a20ecb3b4788a28f90fe058 +1840000 98808ddb13610fc63e5e6bfb48c001c68a86eb58541e7364644bd5eb68672ca1 729538ab66901a5153fa988b79dd999d14b6553d93884a8e13e9953532f8129c 00000000000005bc9c5f4d1f2d16009a641a779ecb19a9d79fceaf6030325c89 +1842000 9ec8c2909a91c09b4febf435e2536177aae864815b1d7896355199364b692d67 61ac53d8a87a763d8de90e049f969d016e8bd29a9957e9ec7bbe2eda2cd8aaa0 df482072a9ed316b28f9da99a608a3d0f1c5747d9c7c2cd68c457d143d5cb984 +1844000 2aca1a18f848d362c14a43a021d3ae652aab3aca2896960453da721302c50d6f 165e489baab580f630a24945f475210bd3455c2e4487bbe55584ba4e57b37eef 0dcd4805a2a0ddf83638c8e1c28c87eb604bee4a154553a64a6a9d2ac0383556 +1846000 836e884c359991230a3da99e47561e474770a1cf5ce0085ab0afe41cf3654af3 addbd1193279a257fcb968cced9b008c94bf13196487bf2d2f03369bf442fea2 0000000000000554bf6598ef137c67b47157c0fcafb170a88f5f53791435d12f +1848000 2538a003b7a3d0b51a210db89139611be02680c8084839dc0949d246d41a9fbe 311a70835435ec04078e4eae8d40938399583c9f22c05b21aa3471ee96b68d59 c96e8306bca9c09bd214c0b7e6a9c4d05badc3a6c08124c93eb09d57f6e0d7e1 +1850000 d0b4e5be68bdc1a1509aeb4188810dc38da3edc1c1e9cb2a19521cdab7137fa0 cc01a42ad3b3bc09100fdc94f7c158ec22f654274bb469b2657f549649698126 29a63ff18c5d7609e4ca9441b92b666943fe57cc71ecd7c37e9c3383c89aa9e3 +1852000 38717040d9d4a23758086c2264ab4048651c06a150dec74e96fcd674c2057de4 89ce3d856a7d913675cce185c6eab6e6c967f5cd3f33d6f52becfc1af5501fb2 f324d0e6e82e327535724e3c6a5f6b80c083b3b7f6abbef6a4a75da1c2b9f36a +1854000 471cf0608869a8becbbea0dfba29ecb6afa8fb7e2127e1e1f140e6a7eda4dde3 1c225c7fc16f101b56b6139533a7ce32cea1feea501d874a79db05750d55195c 85af929253317cc5c790da8b958ee73fa7cbbd4418964bcbf2ebc29dbdc32c88 +1856000 46cca1670bdea373b5676adfe38c8c84c25509bfb426e02ece4f1b2aacac30aa 9d57f22a2fab0776970c993868a88cd266b40ddff61c4a9cb4466de3fc0266a3 169702332d8775ebc70bfb52d10c8c071e1cdc9dda20eb682a983421b73edaa7 +1858000 00000000000003eec470df705b6cc35d968a8d9f0aa39cb93997a08dddc7bcc6 f6cf6d6c59bd70567c3a3b2b64ac4b2f6eb0e8a5f1364a975889ee2a810acd46 70e57a441f84158070d10f6ec6f25d520aefa43a2d25c1625eb89050281dead5 +1860000 5360c67cf1c057ebdde99e687eb2df3354173fc7deda194b691536a508287734 b7ea3dc3f271f2aa9d4289791ca9998377c6845888d1d6050901caad6f28d491 00000000000002eb1838e98016572d23a63fec29fa7bd35fe22b09e044f3772a +1862000 000000000000042b3e0e4f6d9bf018269da386b1e8ea0ff695801c476f5de6c3 b0b661db19b70dc4dfc9e20b62a05f0fffc1a39a82f0f67d6a19ea53601518e9 00000000000000badabdb02db581e6f7ce2e61b28d921535c6d338161a0b2a32 +1864000 0000000000000b905536607cb5cd6aba02ec6538587bec0de2c5be961623d4c4 5d99c9101d4bcbd81046ade41164216a2bede2e745f550a14c48bcedfe74ac04 8b77f545d353c4a5a45b69f4603b1cd5fe1f5c4e177f20714b78c0d24e5b59d7 +1866000 6b65f9186aa2e07e96783b8b9d23de574293ea82f1ad65220f65368558700759 2dd7aa5ecaa98421706586313e48277a611c09bea72909a8f6969ee6ef3d5c22 d302ce5bcc4686b9796616e7fc373331748c3373ac42afcf19f12f0fbb126550 +1868000 c1c4b525d8e3262ba42457b9b15388d99e773210d8ba8119f38fb6cfd131503f f7eeaf80e86b9c7dbad56a6fdcbe19fd542e09318f6125d74750f28fe521e022 ebd3315962e268c454e201551b862aed3b5c55e5a0820e986cacd8ed744f181f +1870000 377ece6ff8f92094375959e0ea0922a17c1970cc24ed700cc72e540b0d3fe020 4d9e8b35d2f52805dbb17f7ca1b31d3da9f667067d8de8ba4923082bdbafb090 6980424787ebf03e4e6bef72d32f0fb7e2e387a13bec5e9207a91566d64bab0c +1872000 458c4812b3b6240257f7949e2f989bb40b54c2ea8e819c4c248c332c70a80d6a 1a2b02dbd0f4141d923bf7c7a1ad20dcfe0f3061c7c9315f07acb20aab165bb3 ac35488f1fe06830225be7da9e7e30b68fe8b9718af43d8bb1136c945ddf6dd0 +1874000 535b016fc0a49dc096e617379b6aa2c3693f1fc4cf2d0b82f7082560522c734c 18d51d8d67765ff784dfc05bf66b131667f962e85a08f6312e226a2666790d52 84106e775cde82dc34cf28312eba7a87a7e356dc4d164209c1c8e77578e15717 +1876000 b89258797b25edc5f7332d8494fcfd236e7c974e146f563acfb33d24ee94f433 cac087690f39327f5cfac0cb0a76c9467c25e7b65d343e02b7b1667f4fe1ee86 2add3dfdd4edc5998e016fe70579e3f9d3bec243b06f6e9ebb2dbc793a60aadd +1878000 9e7eee7ef5d203618668fb2f7354401559ae5a5bba9d005fc55ee8880f493789 806cc1e099e16302928c70171ad50ba9abf9859540170fab57f42eb1bdbcd5e8 d218a1be89429b7f43d3e5c6324554fc56165daee6d629cf84928f9be7639434 +1880000 647870da2bf0765db582b011de1e614f53c112a7fee5203e350fe804d41eb5dc 22b4a9fb76a47e682771e05c242c667b3f518e6bdd4960fcc0ddfc29b1a95920 1f214358c6bd42b81723911757fcd80458e11dc53d131e6f3c83f2d51a13bad3 +1882000 0c8c60e7924fded5d5d3e10798e4e110fb6e6437b2361972c4c76dfdb7470e0f 360554ad2db5fccb4ea6934f3dd32e8e939e8b422d682449a29b976839d22b8e 552e3d0cc601ee04fe4f51c849ddcba998f760a6aa8d42b8a88e8ce06ac712d0 +1884000 ba2fab5b0c37b185f4218649c7b3a48bcfb79514c7e7b796a3d33a843106472f ba3dc9c743da981ca75559ea8411630f7e9469c97a877a2e4c7ae98f0052f701 1efa2b4ee2b57cdadcb89006e840820967516c3bb16f5364fff301bd2abc3207 +1886000 6f4703eebe635c76997062840218619e39c9ace297978cb72275eb12aedfd502 35412b8ecfb391134a1ba48813af7774d4b6fa9eb08a5bd75cd99db67bc65a4b 3c356446cf35df8f4d3b698564464fccbe898966bf9c91190b67e47968985926 +1888000 c2ca5be093166b0410efca795b4f6014c8bf1b592edf31daf5ab8ed5a932149d 2c15323031dadbb95b6947c2ccd87c895f22e73117f6bcbb62f7905af729fc7a 54f036b8353a6377f31d6e99d2644419e9c58a32a7076c9d081fbac427a6555b +1890000 bd44b7b93bdb5e17ed2919a160f11426d8ca6cdd86c20759983e9049374eb13d 003c2c21115b15de4f11386334b8f33cc1efc2bb601ffe9b3b0861b25e3b6319 b80c1bfa89959a78250720ca614a2ca9da72aa1b4198fc3652dd5303f1aaf24d +1892000 b31077ff184339fd08068bdb5e81ed908dce7de6e265bdfd6238072f6bc15687 364806bf73651ffe8e54298824f432bd7db065239d682585a247fe026eb266e8 000000000000020d92dc3170755ad1b2e1dc68a307ea82d62c701a35df0ea0df +1894000 0000000000000318cb045c116e78447ecac08f5ef9ad119ddab2e57fbf27e692 41537cae8aa4b99b0736434094168b7705332d23a17ffb6c641802ff97fc6c2a 00d9aa5168f3b23edf786659c0b4df2f14bdd0d2d42b5c0693478b87ed2a1063 +1896000 00000000000000ba7c1100e14c42e280fac5055ae180dc321514d2b69c9e7ccf 677c7e59d065bee0b65c0edaf903c744b8b39c7a74b6d15505e75c62497226ca 00000000000002245f6fe2c7c6b4728a7169540a4700f3f8b521734f0e946327 +1898000 00000000000006655feed02653699af0b28001ae90a78fac458009d28a3289fb 500fbb9489dcb7d19e47ef5a0392a6b007d621d7350c162413e25015ffd35586 3cb8fbefbc4314ba918386f8090dd1273312e381be4bb15b124ca9ad21408fa3 +1900000 66d74c12a3b939fdec4f6f6bbe30a74a93bf5171989c264e19da00785b05eb8b 584deaea14f8bb72648b4c9c2b236b8ed1d3ed8967e58c3feab6d9b60d018674 b6d3ee144af89c6b20acfafdfea0c669c47f02a2aa00071bc4ed62fc1b4d0ca1 +1902000 0000000000000029ab5944391916f70dca9e9ae5c8ec5b86c66477fda17dd651 0912b0a77158e391328ddf95783f80c78b80040a4ed1e0771353d21bcca201bd 025d788554d652bef966d2e0029a803584e8a67318f641e95f342fd2ad837a16 +1904000 69da2147fca5cb886e5574e16b5db501fe08303d3e3cb26fced493f6295a739b 1f86e067977e22c2d7522da4b5ed249d07a0bf78f6ae386e5a5de19dd67b0d95 688c10f0dc874116266086bc75d9fa04ec4f30131da199921a9424a652584a9b +1906000 d15a40771fd8331428353502407b4cc18cf129afde4e320e85f0c531c5b68c7d 989c4a460dd1d25c0927ef2b8cc026ba3e3c54b98e8a4c5337b08a7798d26cd3 e9cdfa6872f9aea6058dc50f8331bcb1be2981effb761151a0d4ca90558b6b85 +1908000 006dbc9aea0fc2eb6c6ded7965d37dbc390ba166d84b82d92b49fabeb7235530 2cb666b28e1052cc058d7a51660454241d403baeaa0f2e08c505c31d171c21a7 dcfb1aafb49caed0a526f1cbecbde360a0b44a449db6f61e30de41f71592cfef +1910000 42b85e637166cd7e5e5668018930755d7cd5194f2b2fd9eb224bdd48c20514ee 7c79c9dfb85818a8ff49051739c0575b0e2520a9e36b1ffdbd19cd3c75aa9450 5e60a6dd473091c622132cc1c0fe021cfbd4378db2b90e5c997d4f41685a508f +1912000 0000000000000246b7f196e2d3e66a9fe8159ac83619e2400f485003d596e776 418222d9f310233b64059b8df5bbc68032f81fe12862f7399bcdbb08b522af45 00000000000004612e6f3fb250e2fc793fcabbadf8e726e3b54d714c0a9af953 +1914000 5ee31d18df0c95728979bb0cc7fd72c9e3ea4e3d8dc50931519052b061a61671 c87a2fa277bd4b9c1669b00924a66ee275644c87e2542f710158da3e2889d629 db843e0143f8ee8ad00b07c595e1ea1ea5d3878c01730ac7d490b4ee322e55e1 +1916000 dd5e037c44239180c8239e0c21a5fe0f3ca8e62c265d240a345ef91b3545d868 cbf17bfcb8e6a79b0a44943ca6b0ea111cde43ee44d10fd132d8d88c8adf6fb7 56ca180f39fabd7612d3e5b830b464b19790eac706461c967081fb8c4741f4cb +1918000 649ede60759b60398aa2084b17c06034f83791d86424c7536295a039c85409f8 42428735a89e52f2ef51994a7482b79bfe87e4a74a7c53fbf27621c6b0be253f 1564c7aae3acd9de404261a69321b288f88be3a3fde3af80c2365e4b1533cb8d +1920000 919ef92b123a427226547826c2ba0b78388ce7eea9996ea226bee94ddc0f8715 ce27f0a2eae720977de1fc19a643cee661962987090b27b4dac3df9999e5ad61 000000000000025f3dc9cdc2dd86143cf6ef9ecd075ad08dabc069738e64c742 +1922000 e211c8aa7a9ba65f1e231c2714f859c5c6b27e48c3d659404105bb94f06848c6 d385754df618d5ad2940358bd70b05b502c366269ce5b9dc4d0426e2141b7d49 84d79fd6d7b0a2c6545f4699f0af2d2ee5e15a97f1d1a07486ba45d64cd08c73 +1924000 b350d926e89f6aa0d2ddef6d8dad2c812e7ec2d2bd9694e97c2dc4e69695a378 c0ef2730668416b2a62041743279647cd64db6e501d24191ccd3a684c39b9f8e 8d9c1f8d0730778fe9f6b56bb5bffc7989bab634c45546890962db9c2246b4d1 +1926000 fdf21d34ba257a4ba75c8ca79129c3bfb930c9ad0fd36039d17428822422f758 2618bf010dd631eb035900c8330705c40e324666b484c3cceef1f3d7c46bd233 17bdece0a2ca25c2d76e3fd1b5152ea91b8d6a423eea33e073780baaa4ed15f2 +1928000 ca199ee996655b50facb7a0c5813393401b705e527adc0496ff0eb79e4977ecc 37bdaa8670c69eb39975775639275d63ccfd3fc17d8437d6ceab5dbcd382bd71 cd89175cce355ae43a4c6b56c0392cd722bdb77ca1e4cf5f2d7408b67e2a64dc +1930000 00000000000001d3afe5ef6f4641a194cfcea3bdb7c434a8963b901a7bec16db a1eb03eab3bc84e8f08a8c1fc90851faccb906060bb67dd5d2661bdb45792950 00000000000004f5907ae2d027ced300e376d913a2f06d5f964b06aabde2def1 +1932000 a02c8d5bdccac6e5c946884eec1510707d0e5222d8d50be18c7a8f15578e6b1f b8f3f21ee815d065acc07786024fb6299ef5726171e4fcb84dee59a69ab1f0ae f4fe03d62ac4f211e8c451e455f3402b12135de388e2ff70280b4217fbb51abd +1934000 d60fdfdfcf0306f7bee189a533ea31c89f22296274d60637d5c1a66733cbbc4e 58c83c638b633ffb77499dfa8ed28064d686a3dc15e7999f9fe98d24df55e7bd 77791b2f90e8539e02864f836f4b003afbfc2a77921e7d802ecd9366932ab65d +1936000 e84b406f2e5083cd0a544920bc8cdb8a9316ab7dce8eee983a51fb6564f68f7e eae9a79755efd783218d31d72ac768bc882d85c9d0315cf72175e128d89fe071 1e6b0bdabb47435318a934495412e5921bf0c8e563a7c8e558fa53367ba8f1b9 +1938000 40cacdadef393fcced7aa3d9b1541f904d6bb771602f5e96cf012045a3aaba48 a1ef8f6e8c4e8e6446687557e11d6f5589f9b999b4d290c8c154a636ebe028c9 00000000000002f395e695fecd4df9d97a71e15f5f78b3d03d3a83e6f1cf59bf +1940000 0238474d4cf0e671aa8ae6e1a15c5e7226327058959fcea58c0345579bafb7e7 c7f87e21f77ed3faa77bd8a82861976deacf81984c453b46c1507b4377be3a63 000000000000026d77787df81a5a7fa6b744fc9b51de4e4beebc5fdabd3b4176 +1942000 9c81cccf8aaca215a7bd5411c0dd51a75215e0d716c2807ee2b3693ecbeba60c c5a9f0ac5229a0b623e1c97132e5511873df014e4badff8ecc488caa9392493e e5f15927dc347a88d05382dc30497a001a83ac21429b7b4b68bb2bb186d5d371 +1944000 0000000000000408b62caf73dd76162376954a839d7ce458d28af1dc86ee9b40 0ee69b783dcc6980d43bbc1337df40672956e581942c52eed84077f1b5ad1c62 4f2960be10e0fe32a7681ac62f172c9d11b8e34e8ee49cd9b89a1cb7abc0f614 +1946000 2a4beb3858c3f2fcef4733390b73d3c8f3fb0afb8227f1b0bf42d6ce8d8ae521 8bcb7447ce917b189bfd55092ed0497df04e10b3ef349c068d82f639c0903953 111e2d7fd24893d56526dc7cc3a104abe9ee3b97b0535df6d183fc0d5b8d9155 +1948000 00000000000001c3dfb1dc276fe67c31315ff57f5bfeb99b93e4dae3719433e9 cad6ce9d862d0df7d682da81f810f2093e5e34240a4d15541043968aed06f83a 00000000000002d68fddc13d4e6d55bb299993c2f616208bd4b9837c36a469c1 +1950000 1037a1cab7e8222780afabc32e37b127a7e8171ef981f40ab300c66ab7a82d2f 951c533d855a4a9445c54dbd172879c09ab6b788248ed528adc2b6d712325120 73288c1ec13f1a47db54cfb6b738eeb0badc26b1bfd5b0546516c4a7bda212dd +1952000 6a7578e3844e7d3f679147d4b7bc0f33bd6ca8c99b5eac55fa45bca9ed62820a 85d3c01159226ba2d36a72e1a3ec8c3d920ed4fcd56b9cbd5a8a60829458023a c0d4daa02e09fe0e2e9b6c945e188a9d59d417d8c59e0494072c232ee5f7df62 +1954000 af0dba2631ed620439024f3efc1821221642f0b38e1122574d88cf5aba1ac129 2c9786d81c791b00a65d0bb6bc126c8b7838a10ccabaa85a1f419ab8df66afe1 a8349345d778760f0357fddb08aede9191bad031a8edc931b1337a72d851862f +1956000 30e1c7c4093f1ac63a3e27818ea6083a08aef02ff078ceba7978e9af9378172b c918ecdc4f75a08f8d1fca3f4b582da6e3bfe72272b104524c3c4b015eb73df0 83d6a59cfb60ab2213c9e7fb0361bf95fe566f18d47c14203e71844d2e4cbef5 +1958000 a7459b7bb0de057a48360a6874200f072992ba9fbde99010fbdac82b6f3afacf c0cb548800fd402ad57d1e11040b927ec3fcbf5eda93e7cdcea5be3768615f61 1c39313d564186be23c21097d73e3c0545c6143e0a7495dd0deb47808c17006b +1960000 000000000000027b101669f80c7e0524fc44885ade99d9f0ea138ea1e52f9582 bffa85ffe24c6cbbeb479e00755d0821258c8e736f1e597d31fd00f32a127ab2 3ffb716c4b88184fc41c48f3a6677ff226a37c8bab123f8042727eb0121c3076 +1962000 f3a8fd8fc176980ebac30d65ca49890af10c556d52ef356674b9d8e13e682df1 2512ad05f2abab8ff356559833d29c19a09de60ecc41ea33091a26123832ce86 78bfd5441290a0be940ed739267001ff6b3ef8acdd15db5f16407369430d7f27 +1964000 00000000000008e1fd1e08611495541a4e4a5022d0e3013a2696c0557efd7ec8 99d9335925887581120cd1b12c653a7134a0b9f7dc9536ce598381bf22b10614 d04d6df1e2dbff85fabf04e297d5d47c7a1fff8d63b15dcd4cc637cc2cad3a47 +1966000 000000000000071d0da970ef062462f6888058bce5cffe1b51c7096c28a34eaf bda5315b7f682364beb76538082f19ab938ba10c7f61dbf9fdc6d0d554ecce6f 0cb5c5e78667c12aad56ebc4652ec742c086add6afe35e1b582b384d5ec3342c +1968000 ea786af1c4e20f4cb592afe64b690f95b314745ba0d02a21afedd53b57974571 0a2ac891a040241bd2faf945934990ee16c817bc3f608e6f8ae85267e4496b00 0000000000000206cb8be33d218ddec6a7003eda34f1c0addf9e1809483172c7 +1970000 cc0bf012ce854b7af85b36b5a74955ff8da0a39d1c9d7fd7f7539af0e888daf4 26f24b4346f6bc4395209b200043965fcd2e0a79ca107eca7d4cd1d6d7ccbd50 b6da632fb85fd963c31c6511d37607fc496695ed25fb0656be23705a8485184f +1972000 00000000000007dcdea91851ae7c13b491038afe864461f850ec13560e730038 5cbd8cecb22d3f9ee51103724f4350ce4273e789dd803b700d363f3a01518e65 ebc558a3cbde1f34b46e0f1c2ac1573fe9cf50383661846d6acf74b2a2813680 +1974000 e542a9db37c19586c38e4d4d39b4a4dcdaa108a866e1977e6aff6ab4df415fb5 2a4978c6d374a12fc9c08ec7e155052de612e2447eccf06de9bc3f8a8cac4cd1 3ab8e133430f41b5856d110c642c1debdb4905995cf27a07e3423726ba84e584 +1976000 eff548c489dd7ba1a75c7ddf8ccdc0be586a71a67f4012043a38a6b4085d15de f2fcc7ba107e6fc5ed855fe9793e235548af1c306000661e06d89581a5edf916 000000000000013e29fdf97f34de46eedac7f4d3d1c75d4507d11435d0c7c010 +1978000 21e8c6e722e60da92492bc1b6421d6ba5d0a85895593e995ec29fbc878851915 b6624e75717bfd4a0e311f3c8a4650383fcc04774571baf1ddbb0b032f661086 000000000000047720fce2ab85c593022c3438891fc76901aeab1a2e8ace35e6 +1980000 3325c34a684b3a81d3dd6a8fb1c4dd408283f2f56ebaaace7b96138308c7d6b1 a3a89be4f63f529321d3a3b87dd3ae6d8f5c7324df75818c0cd308e8d37235b2 a3cf381f3502beb2d8eca88b840a06af1057fc9efc0ef634e72ffad64ad7231b +1982000 a9dc13c233bd8a2c8512c4054eeb3bfffc7c46d4f13c12d91ce60a1158d05295 e1e21548e3454c78e4e482cd2b1cca710c35c0a63e44aa67d822c8e03ea191c7 6f18f22ff900916c81ca1cb036d39e69ae59dc4e9717dc6cb3d1162c5814fd3d +1984000 d21c11f1ede129762d89636d3a5053fc3f364189d283033ae5032382728382da e3a237465f57808ec66c357257876584aac205fcabe9d849caf13d84826fd518 2106389cd47ff70e030b12faae5b9b0785d69a1caa5567b54c80ed94176ff3d9 +1986000 0f1210a4ebd44afb9564ed9e51be61d88ea6432498c7197cd0088490fb12f44f 9693e0c961d0241d5b97b3f84f8c82253bdbf1bf4086b4678fba0f9144c18300 fb9abeb80c12f348f82a03219069b8456632591649d2884f07f37efdc155e46a +1988000 5c00617f637c31e7d38545824d9c66b4d7fff9603a18848ffad543bf4cb09a30 64b204863d34e3151707df842c7cc79ab5105f5369e38370716dd499059a2c68 dd92d0c5ce15270a1229a547698c2ff54c75cca1cfd12bdf7d9d9854c71d789a +1990000 9d50c35bdbb715698662a69fc0a1e5838b6fba720cc0ae796108bbb4ba06302e 767f35f1947efb630ecc34141df77afb23c45c5ca06b96f0fca6e928d5ea6192 00000000000000a2b4a4e690e7c89587cc022fedf7f9e14f99882854e742f0b5 +1992000 03161724a6e36dc7989e07177a65bbf30f8e7414130df48005772f61c84debea 3cb502cde296ce4bb87e05846008bd552669e8ba44fddf64cdbb736b310bba34 00000000000002538e4313a837c776f10f181dd5fff963205f5305187208e8cc +1994000 f2f094bb285e011aa9bd94933d44a87559c9212edeaf3ce59456dcd560e3ec36 7d708039934c607004e8cc2fcb381cd50be36df1e01f3bf123499cbf7ae4647f cc487bdbc9cfd74909779bdd989734d01875e321cee93e43548ad0508eaa1c57 +1996000 dea9337439382a9564f47c21634b4799f37fb7e091f8f77c629eb78253839904 ee7b9fc6321886e2f11d8c881ae8753e8f33544c0946a145090b3ed913eee948 902251ffeb6828272ff120219b1ef7e900c845875a887a8c97602fee2fcf27cd +1998000 9a6267f9f3c221814651e8dae1cbddc7687dc751d8e86bfbc40d7f3fbdd62b8b c8f097bbfcd29ebc7717c5dcaf4d64099cbf12edc532ab8b0a1e3638fa4e1795 58fe038d5fab98350867c2d17b4235ab560823d435c3aa2ded29fb85ac312d2d +2000000 10f522ec60d8af2e2cbd9e2268260c33fb8bbf9cd9f176b4fddcae7493c6791d 641a9a2efd9045e8d049865b861a23629977a4a70d008c33d94f2381b21cef32 00000000000002173d0f6ae6ed8328607b5301e071fdbb2cb5756673ee86472a +2002000 c0f5314895c927c2f718604f852a6226824b0739dbd01f116c1e0be6eb30fc82 c7dd3027d575e87f79c0cf59d8da5a370204f8c055521ff75029a244ee6083d1 aca8fcb9fb50ae0eac9cfadcaa0ec6f62197108fabb55c79b08e5f493a65a509 +2004000 f035251d35e257e9a017995050ea47a8fb5b831a045c6f1db6719cdc09bb67f5 3039637f3c5598904d5d27cbbf3dd3abb34c581659bf937b7f19c7e833376aba 8b8aacd93539f449d25db10a7478b19a9b62b72ab18a588dbdaecc2d3a2552d8 +2006000 ce24c50cc79008484b0d66ff3ac2515a950f1bf61eb7c73d2a61353402ee5d3c cb7a82d8125850a3a08313f689c618c68eece4cd8b8a165ba0cadb20f1a21c72 1c081815b35f0fc9a137d0cb8a6d912b99679b31c4a34d97c62991d7a308a933 +2008000 cb74dd448c9fcd1b043cffaa2eff8f98e07a447d50930860bf0b3d4a8985ff1a d82e1022a4c0ec4e0ebc911abe4333b5271eaa8648484dac6772a7fb4088926f 559b4389c0559f2643c934cf402c2b98ceee7f7488c49891208ceaf2490e9036 +2010000 daf40a2d8062ccce4ab7e8f517229a7fc30d5dcfb8ac2a9cca55444a79d8031d 10f8c4d331eaba5d3b885e164590b3aeb953bf6579da94877a2f3c5a43412bc3 3be717f414231623c3855a7749566646d22a8dd323af7283f0ae25b3d68087bc +2012000 00000000000002fc24bdcf0d17defd2e3c8a1a0f71193b410208ab3d46130d0d 68e49e28495e2b4a928e4ba91cc5d1404876f196c79cef5aca1568e3bd60027f 00000000000006f2fb1b106e2e03f92279449f96355ab3ff20121ce990bfe5e9 +2014000 155076504e268b6e157bf7dffe4b12a92faaae32cda7cd9e20ec6baa79300be4 891d12d8ff4eded8b4ca1aaac2997c7142f1ed7e167553a4c2a6bfe5aa426fc6 730d07ef778fa878e710bc9fd511db07cdcd4bbfadb55150e8dbd2e53fdf3f1f +2016000 a77774da6e74066dbd87be11099777dbc70aba7a2e283d299ff42e9a376b80d7 57669ec6b5c8896153e27a8d2c881c898a8cd8cb08e5798e74a746622091684e 00000000000001376cce863de7d70c78889be274b37fcd9a447e70f84e367a45 +2018000 ef55e0d7b5097e90de194f2dca0999481143de300ee1fd505af2b1f5270d99fe 367676410f8dec949bc53b01b3b1dd0f895b22d230f938c1ba0b16bc87ab02d2 0000000000000237addaccffc000d3ac36583d0ce5d69ba2508a40940fc9d829 +2020000 7d6a17a4badfa817e2cd32f728335e52a4fe97985c9c69ab6b920af5a749fb62 e5ae332c8d1dddfdc93536a33fa171988f47c726588ccb97b065f4deba783fcf 69ce461f44ab2a8f338c86bf7cf9aaca00c73181d396eb6061e65e87c445f69b +2022000 d913ba2c5fa439204387047ae63e138076250f6c08dd894a4cdc5ed66a9098bb 7377c67796fe3519f75a407e85c65378a026eee9748523ef14d99b82ef6d024f 6e6588b1d5e466f4f2716798a20d44e939c7a629c05e0032cecacee262e60b33 +2024000 30ad4bbd7a905cd40bc51f7194ae9f917b568936705bc5607e30ece2e3fdb0bd ed8285fce40e386fec1277eb0c77f63be76978c312d691da6a034503966a83ff 62a20f472527321bfb7d65ab01a8e418381057cdaf0b2940396d89a3b18f5738 +2026000 c22a3b6abbc163f96fda5a27e44b3c1866569338c1ad69a9b924620b97d6772e a3aa641ade5f1377fc5fb5a9effea08ac3d4db7b570231bc5f4f4404f3cadc7d 00000000000000d9f9d104dcbad06477eb456842397129dddfc2879cbbb386b7 +2028000 3ce8d6de53d922694e9d60e1d6982d07b33fc299b7e4a0882fb13046d00bde78 8c5916821a6b0b819c68ed62eedcf1dd266fa448c8a0855507b8770ce451aae2 54a2cd94872b626f2a4398b202bb2fee42db9d46355415be0be539dec382151f +2030000 13b89602f17635b42d8365305c0a7a83a857cac08ae92f685468dc6df297ccd2 41d91fb33d36630ba871f040a6628b0d5f04699b04a3dc297d2d7d27725283d4 00000000000008e28909c370cd108df0681a8875a6be4938e260da0095877164 +2032000 2eca80dc164a78cfe0e6625b1ee786faf0878879797a0892e9450a7ed00f2a4b 7608ee2ba2cffaa8f13cb6b770a7b3b221538b41f3709d4c944bed4b43781176 1ec85a8250a36b4bc5a8fecabbb62f69ea5cfd6e50a4aea288439b4e66500523 +2034000 cb7c7df24141564c7a5435409f2b76d434266628ee62da752bf88980b20ec92a fe50e63a5448398b0c0ec78ee702daae0d09452dd2a0a3d9b739627fc2a671bb 00000000000001f3ac7a595c1b38d28eec07021526374a03d058d74b54244f86 +2036000 000000000000048ebf045acd2f288378b61a3a06b1e454e1ea905c95c4dc9fb6 1231e92c84dc48961213450548198851d080cf89546b0c60680ae25dbc39bae4 7bf5c655ac88f7c7bc0c75233eaad7a8572a9c5e988c47f43d9f971c1f7e7573 +2038000 7599661de7d1584e64c33b34fd478fec2d96b2989d8cdb82852a3100f70c228e 7c27098330731b8b109de6506814213bc65a2ba64e7cd46f84ae9f0ddd1d139c 522d7d95fd0b4931a180af616eebca1f367a78bb2525afbfd3963e6b42279a4a +2040000 000000000000039ea70efaa39d63f7bdfaeadc59fd24534b26c6bdfb94dfc8b2 136b74e8f617ea5f7dae9f9994728617810a89952a0ae37117b46707b971b935 d236c5f825c34938588fe17a6a596d6ef58ff5ae03683e893fb9972c73b2710f +2042000 5e673bd49e419f9ff34b8623be64ef79d84221520b9bbfe9083bdde6d31ee9df f36f7ea7502ae14880769aa142e3761e3cbb65f5cb5a85754765d11d5e82ba17 00000000000003f3f026b2dc1614ccdf0877a2a9d5ce58d3b66187cea352ca65 +2044000 914af3659ae65d269a4d4537539380a1b223812ca050c97fdfc1de5442220e99 d10f27578c0b7017cb05f098399e623330c7d814f3b4298d5dc387310e518d39 000000000000035afaa93d9dd26c64e4ec3577cdd1dfbdb3059e455f92040313 +2046000 00000000000003f6d9454ddb4bcaa32f180a88b0cdfd700bb37fcafe3b550181 fc4fe8f54805db2ee24dafb96d8b61cc869f8862fcc7bd3ed679e8f842604ab1 9d1cfb8c0afa4d5f241d5faa9818dd1e6732445ab1abb9d32cd32792dcf42ff5 +2048000 000000000000016e5fef7412ebff8d25d13d31121d84be2538bd822df975f2d9 7299b4479ed9b9e0c5c5808c9a1b107f931ba4c818433e1d5c2d1cf442eb85d2 9d0e3b9ecb2574c7af54def376996d55dcb5ce847935cc36e2ce644a8dd55f4e +2050000 25eeb421e039f2efa39b8a8d4f36f6e8e0dce7ef07effbf23b1fe4f6002a1ab5 bf2011af48d0ca9f105039c3e687268b88218efe4a902abf20c83efccd1a78e4 b7e21331b0342728e6011f6445b79ed9f2da5a71e30527f3a2e3c2f351d70bab +2052000 000000000000020f197032f35656de534b19286e2f827ecd24926d2598fb25ce 33e5f59a7ebb9f2d1f1d49473367a2d213ff33e9580db5dc630d37e95bb09b6f 6746384ccb2b45702622795bcedcd71f0293be9b1db31f8cd3799f0a695ea1d0 +2054000 000000000000013b120124754b8d6393bc90b7e872f89e5dc5f147dd2084e79d 1cb2bb3e51cd9e6d406746818e20a309f1cb257165c154f4355b5c8aa83e2a89 893b135ec8c6a3aae37f2043fc4531787d2c6bb72b4190d26b86b02b88d7ec88 +2056000 000000000000018e99af446f74698d8055ec4e097f1f99002343b834b668ac09 503d991dab303d8f3c8f56cbeff4f567ea63e0b7dc21da753d63827304b715cf 63b2e29e0f55eed4ce77e13e23ceab2b0be3a59e89603189bdc38986d4927557 +2058000 8abb23923cfe3f91b81e33007383c8aab9a952565b162a2b14c1e055147abfbc 860a05451a8d2173c795f7f8c306cbff81c112de823fa53d6f6faa24975d3202 56e059ca790789dd0c269e793262e5e0207a214e67a156e8d7a381f8115973b4 +2060000 000000000000007ac418b9f58d5663ef2e035784680ba67b4dfb277eebdb213b 73190d1962189b63fe632b99f9b47fd5d8de89e132bc2e389bb942be4cc3da27 00000000000002ce72cd3960b08c9ade45bab32e01232e0158a0b0ff588adde3 +2062000 fe68118f2f53a00f34a403979e2377a8ad328f95e17649ccf7b01fa8efbe282f 4cce62511b8886df71133fae3ff98a2dae9d1466a8ddbfec546eeabe1b5f4bbb 00000000000004e41ddc7ea4def8cc88c72859d5b4436302b4968991ce6d81a9 +2064000 000000000000028281a4a75401b4fdfcbec8c2cf90d6425fbd9cd3f01a009f3b 084596ebe2d0a42692dee3f115823caa8743bcc1f048de3bc843b6e6b9a73561 00000000000000f313c4d375be4805c8e04e5e3a0d084a5b20fbda8cf116e1e6 +2066000 e13c9f1959507cbeda0049d4cc9d3b9610e2908c9567e6ee4e9433f3d9c95b39 d3513d10a4fd5bc32f1f22c58a16708282edcac003b18dca0551fc4b6c3c7d9b 35ff3bdfc4fe87cb0b230ba722142e35d705b67a47da7e3540912fbe478c971c +2068000 25752961298d4a41663ca949d81ca6a71080bdeecfc56bb982d9a390d4435fb3 1a5413cdd3fa6202eb6e4af3251651b4dbe7e940236541721ffef60945774890 8856cfc0763ca5c0223d662815382d1acb976065408a46b44759186153025d5b +2070000 98ad6c5e17db41d816e5d48bb874873ad0f9bca7ab7be3da3c6afbc11ff3545d 28b35f0e8339edc4682faf9a29e7d0e1d52be9f048e2422cc9fd0690738440cf b25d689ae7e4561db5f6bb3ac8a97e207eb94b3afe3d5d06291eeccdc92d5979 +2072000 780b29b5dc443c06c2527c0cfd83486938a68495a737400c42c6eeef11898410 002d2ab4136fa21b715080192aeacc622b153784dbf1168cb350b116a6a1a7ca 989e9586d9186070987ccc57a8dc70c7ee293555e0bdf7e27a49b4862ddf319f +2074000 f6074e4b2d5796e47c73a538b4e79fa7ba1603b514cbd47603621286c3175ea1 362f3f949d3e60ec053fca913fbafaeca9211fb28fa9ff94074e60ecd9c29690 40407a01c901943812d27ee97ed18fa6fe8997ccaf074b1a7536c7f39fa02526 +2076000 add28babb0d8e03dc2f22d6f0f51c3589fe4d42f6caf05bfe3d28f5636f2d855 6366eebbffc9a23e387570524faac2a82f8cdf95c56baac065eb0e3d0fff89d1 c59e566c2403d7999bbed99e1518ff13c60cb0472cd96498dddb7602843bd5ac +2078000 2d96a415a9bdde51cebeaf3b439574a09b2fa3b718fe97f99b3ede1c213855e4 4812ea5541956d8c5a67c6a69e2304f1e272efa47bf1eace793da231bab24e0e 000000000000009a665aae8d0aaab20347ac02a3155574ca8ba528153762e12a +2080000 dbec502d5b91d9495d38a9ff297d2e534de946df9c14d162cd8271bb4ad1f241 321dc0ee5f0d9e1d6c484f573de3f45540c2d0cd0a05f902a3dad1b1a31007a0 ae100d85e8446c85e6c3e4d433e81b9c895f751f7f75744050c6d57761dadc1b +2082000 1430c917c24680c979452efad7164cc4b160e49031cc0ee851eab90fe2e74ebe bc918307d8aba6452d80ccb135098cc521665386978798987bb4ec4c1d2f33cf 50f4b68dad2b15090685c21c35484225ca6faff170cc57afe07088fd3bd81e47 +2084000 741aa4739ac0e5a50da46a04375e34e1ef7600650a5e1dfc9f495c1a82db4721 f198ddd052ff08a20800ebc0cfa2573c76e523e39746dad88d86cbbfcf72c31a 01721f3efbe19ff147f8fa8e9c43a67c59c39566a1ea2ed3ece98cd674d7a398 +2086000 59d043444d84c343e0954c021052f5abb2673b89a9eaf8f2b5c170c4eb7b019e 491b35884a1307204b7be664eb4411fc6b2a9c6e9b4f9a329ffcc5f7188a16c3 000000000000004c20518257eb4352fde1dd41f675627cf4919362a287376bc2 +2088000 f28cd1baa7c01f49a831a462da16e845510b3265f2059d292a23202b766b123a 5d3a0864d3c2ad2dae84f2a669677fb6d6230979fb827636108064dfd3f0e574 fa53e73d76a0719c4b389a63551248eee8ef9ca63f31c2bb5d1f913a5ab97822 +2090000 1bba26fd3405f42cad89f3c7dc6ef434ecc678d0afb68ef9f257772c63733dcb 3bd3a929f0e9182e4afd71ad2731353bda98bd5c36c1f6dcc1ff99c236ffa76b dc7afccdcbcfe0e0d4995454eac313d15c8af6d43530bfe596588931762c30b1 +2092000 00000000000000997895af551c8380aa372f5a0e5a5f03ec22f1d800e4556a01 e57336db396d035b9a44fe3de76950011edc3fec22924c6473df5753a2f25c36 94c06a2ad97b352396b865e896c43f6cf2157d2c74dda924365c20459351e21d +2094000 4b58a9ffaabb63ff8eb185c1c2470765367ddbc2c2875703dc74f2cdeabf1818 76e6465e531746007afcad5c74699062428c1e5304a199d8f5752fdff3c3ebe8 a1c67e1af05f6414f454b47c2c15b4e0a0a57f90ab79240725b7174d80d6dc71 +2096000 7e0a297bf4f9b0c5758bd196025d5737f252a799abf3074472317e161d84e7c8 8d43e83664b1e0d5ecbd0a1a8641449395269428553215e1424d76cad312df24 51827a90c11fc32257afa6c84d52507613da6e8f587738912cf40532a5d23601 +2098000 6c70b547fb08d0fb8f056099ad02efcadcb2d1c5d51bf70f37cf7894eaea1d55 4f1222e88632902a751ce5e546a0c2dd0b919d377e14a2d26495c497d3e680b1 ba53ece7cb5aeeceeb564902e8c2b3864ad4d791b23f6b904df040b508daa650 +2100000 f73ad3dd4ad9fe97d244758b9d564fe6a631c5bfd5e99b54b854c8a60ca93b03 7fc7c654589eccb5844e0d852501ed6c4d544b3eb4761821ea00a94a06ca2cd6 04b5d512757a5d30d040bc0963cdd26076fa63a35c78e36b8591bf6ae2ccd7c3 +2102000 00000000000000c206f2c535a5b169e83badbbdc3d9904e4c7485269242ce339 e665c2e09d119d65475346afc0f8ba71c5490ebd57cffddab049c5e8a44f1cce 000000000000018065a936a76dadee99c6009afa4a8ae2d82e8b1823e3a55a2a +2104000 c746e6f414a545e449ed347c9607eeabfd46b56351d6c874f0ee065dfe492b52 e74e7e0fad279c6089fc925f093d3d1ed115e9b4ad26405878c56b6b9142783c 3ee70088e26358aeb4271782ce01cf7c1b0d9536f33cc54a224b68f471cb8878 +2106000 a7d95276fed7bb731b83118b12e162378d5cfbd77377838e7af8b1abb3b481f2 06bbf1ba1dee1e04e81579b3ced6b5e0d397e68e2ba18ee3937e551a701ca72c 0000000000000108a650e53796edc4ca820a3f52c071897465b0bfb48dec1916 +2108000 81c9ae6579071ddc37614ea87b7f6f1ff778caa35e2638b199f92826f50fd705 51256fdcf7e67ba2b3f77dcd111e73658b69eae653b1753e4709883c7c4499b0 2b014d51dd2f3bac6ca18975335156ff51ee71334a51677e1dfdd98a67f813df +2110000 9e88b323f0bda72dc35842388775d26cbb057f95a833943011cf40c8c037305c 4161dd1edb9a0921959236af710dea879b72df990cccccbdb637545943c5e53e 8203db0df0b8f2339ec3179895650fd1bd227fffa59cc1a634cb4c9ba78da783 +2112000 0000000000000205b95efd622b222892dee9e931091d965473754e1a8bc3b3bc a09143e93496777272638413ed70416118c9edd9e47a666b85bc3ef4d5f8b37b eab756311950ee40d5911555747d2b6357334c123be573f021f3999729ed592c +2114000 838e42f9aeb28d103cc8256525d8475f17a863e962ce3f3d2af0d222e7348098 eacd0088967e25fc4acf4eaba8d7f5979d6cd3f48dfe88f2e930dad06dcd1204 06b7128f8cc3b8922c461800f05b8034ae4348858456914898e3fab5a7f6d861 +2116000 d11ca1fa89551ef1c257c1713b014c16a0e0144f20ad9d20f1890372f81bbe30 1c6dd3acc8b652a894ead5ac21dfc27f33d2030880d97f08171a0ebc3e2ab844 f8ee7b3592938917775a873958e65fd100b551778cb79f54252c27b9f7bb1141 +2118000 25db0fc82bf236d31382fced0eb522842fa38e8bfd17ea3a1386909387f248c3 c429d2ec8312a73ce1bc50cd1b5f0efa40509019dac8bf94d79310807cf60f12 0000000000000077dcad4dbba24676726e6e77f186a1f9dd458ef4f9271d74e8 +2120000 8bb2bb45c61cc26644368df4c8a970c3c93b69b5cf6de80f22cafb5dc2df6405 d69a773a2f2e6df680fafeb0a16acc13b489b0c089c53b30f4bca7b9e251c8eb ec041920fc101e978d9542c4219a375cde706349131a7458783971faadfa0f98 +2122000 000000000000040b98a1e5a679771ae19f550e203ad5c9fa4a72d1ce3896a7d6 9a863fd416b7a237d6ecdfbb3079f087e1edb396482350fd45fbf52d2aa673da 37bd3c5ec32972db1aeea4f65c1e92f8afb4f71e53e045b29fb4f9dca347e9c6 +2124000 e524aa87827627494cae6b6f6c9774fcee9013a64afc541dae87fe74b3145062 a876bc4096d9ff3ba3cc1b3808a46e58b0c46a21a85503dbad6c747e40224435 0000000000000126971a877ac6abdabb06ea820b6cab220ed0e3afe11a64eb94 +2126000 3d5460626f03c60046f544a99365ec13df8aecc62269c1bf92e622e408a18d29 28bdee515fa47c5dba4b612073a78d641234b30071f1a0eebe2befd7d7041514 0000000000000257cdbcc2da6b29e1473fe04da40e1b9c22ea5eac4aa6b98cf8 +2128000 3ec0225f1ceb6d608688fefbd8fa183fb9d411bd85c87d5067a8d7cf75a0f180 4dcd7a26628cb389fa9674b447f404f609632c3975bddf9bd687567209135b50 8b920dd291aa56f83d0551b3ccbcc02a0913bd02d01cbb5e31fa4b0258fbd1db +2130000 be1977a497ade77f75ac3203b62ea5a953ce6ae533f28d29bd7b40bf36ce4acf b6be3d850485bb4577f662fdf940fb95f1aabaa761cae45ddd5f17841fcc72da 0eb29e2ef04121812fac1eec5c4ca2d47c1e18a35af35b46ac8f783ebcf4111e +2132000 9b691ae3ac7d651dd8886efc6c3a546bcdc49608863f55343d64d62320b9b9d9 9511b8ba2dfefeacd1c8804e521915f82bc441838ce523e3cc579772b9b96e0c 5472dad238ebb7da9fb71e8ed3a0ba4e94b830de725391de716ed3e699d35087 +2134000 ac2541cb13c6b54e981ca60a0c8a7d02962120502c6b4b5b2c479e4daa3dc684 69e9dacd2290d1454260d7225e8e308d071dfbe8179767214a756211d0a60541 c9053272cd984e1caae847a8578956fcd7c3b6b71ad6ab960928e4ecf2fe2063 +2136000 0000000000000175fbef519f9a44f7900637660c66fbb10fc45990beb40bb7bb 8244c4c0437d16378c8520a0cc90ab5a98a4b911f568b4fb577900e3106dde4c 35c809eacb6ce98cba8845be2662b30335cef6c20597b8e4cfe2f1d934033115 +2138000 98190d1013ccd474c2bc4f79bf0a1db76e94efacb5d5ed377868d05405724634 d2fa6ecc56a4eda0e27c33c0a6c3ef90f69cbef13077623c03728460c623ef1e 7338dad0c599568163a655e907d10bb795b30e8cbbe7e7645c2c4ae3e7552c75 +2140000 01645e2f3d98669dd31ce886bd6ec6db91d6d8adbd9f9520c3148402d4f7ecaa 2e22541b905481c860dc3168fa39afa3c06a1dff2751450b2e038b10d4d0d598 dd24a362a24af87b77d8b9a28fa7eeb667de542855cee4fbd77bc0c9d6c13546 +2142000 0000000000000110ec033f27eb1fe06f0c6e6db3ab2774a91b967275d8615ea9 7b05a166c9d7376c82036f8187ed55e879d532f8d2fa7bb301badff34721f4a7 8cf61e43022413b8f91428e7c8b5b17b93eb22edd3bf21856f56cd02e289afaf +2144000 5c192c4b578b7fefb2f9185ec5cb49962dbb6621b94190f7dbf423225c2c0618 9fb04b1649d2dbb3aef5075fa97e2b1019b638d1f2e02e5411b9dcbb3f329e01 0726899ca5940758f7bae956b8257bcf92fb198d3a0a6965ecd05d8bf8f37c5d +2146000 29d33e73de7e86715d7c9bf34421af0751c5545751846ca8019c7f9f7db03582 d1ae6a79d35c3f4f4a152ded534ee21a2d9dc37f4051b490764d14b04e213ed9 819652fad9b50cefdb1abf4b90fd093ec63e0a58bfe30891876f9ac2a602d60f +2148000 0a6618157bea730851d4018131bc584952ea36d338b86da21bda0149106462c3 26d09866eb5c0107303f22e2ee21ffb7e7c51bd77167396c598748470255b026 00000000000000feda794e10356937f60d371a76f2dc4d0283bb4d281f03d239 +2150000 20b67adbe0f1b4ab49afb4c06d0369d29b4acfc5fbb3754a248db8257ef40fd7 9de0b19e368a36da0a45d880c3de31aba063add0580b10170ba8e4b17f190af5 0000000000000484249e3da8195fe6880302a5fe0a7628857f8cf3691502b57f +2152000 78ed3db08c6db7cbe3c833f7f0ffc86f53b410ba428111e0ca90bea5f7491991 05e2065b4e77753f33288704c0b2cd5a1a779d253b049cc20e305293dc589ba9 ff4757b244d30d3389cc72f5cd0d4e5670d8c0643a70df04083ed805ed1151ef +2154000 0cb39d08c58149dbabdbd3f67de7c4e5cc2cab48abc779c75bc89312fe90921d 59434d51334a9a4d677797ba670fdfd7c45296fdc8bf3451b7bfedb38bdcb47f 92162255ed09c17c994c75f48edc9e931384cbb06c384fe0121419b22e5d843d +2156000 00000000000000752b8c4f82dccb9e6f42e8d6a13173c138ba03b4516415f025 fc4c68b08fcde96699cc92ec2745759d69cea96d7a92ff1710b8b47778e941d3 6a8dc23ac6a000cbcd9b21561a1b5cbb2f624d7e39873328ab13ed920707102d +2158000 7482c82441eff2e93cb6c8b3fb766da41f88e28483413fcbe5364db7cf8d8391 d7fbd904a036f75be0522c085ac5b9272a6e678b89ee4a5ff1dc983fd2c91d7a 000000000000000da80a5636e1486a904b349ffc8ef0b65ae46fb49b874eee27 +2160000 00000000000002f41e0da7f828db165e2558321fb13282e6712095bd0d809f0a 4a6a5eb17f46a407bcf5bf1fca1d43491881ba2384d1a3b9e3890e9d01af84cb f078aa082397467b1c27881b03152494f0ebf2a4bb20b88327a3d68d87ecbf14 +2162000 cf616332b648520f1638defe65b4346e6947bb98192c322a8b4035e0b5fbe0d3 e5b9bae72b6811d2f8d4c33f60823a154c063fb3b9b9420c983634dc1f97b0ff 78dcc8e3c20cc4874ab26f5c1979e89546f69d02ec5fa99e79497d4dd6cfba50 +2164000 0b4922c8421076bab87a4fbf0d45a30970fc68bfb9fd80a53967eb1834e2a0db b052802b5e3124e0784df3f6454b2a83a5e17be2fd421a191d944884d97dcec9 1c9165009164828bf6b117793d5e5bb5f90049f0abbf78c1e00646835d55aa9f +2166000 d565ca95c9779d652fc612cd215f14aeb0b2beda2dd59b694b655a9771876b7b 9e5709e5e714a2eb612862563a3324b15ffb9e5f169b72c99edcafcf3d243f2e 3d9b79d47f7fe61fa6073cb5258df1c3535e063fd26ffe6781e9f8459aeaa52b +2168000 000000000000003328b5ae1c6379f2b8699ab04e307bfffdd7be423dee4da775 71dec8685aff408ce7134f119b9401a8e9cf206beefc5f7f37ba6ae997db6eb8 5ee8726678e91e806062c26bd7a6fbb23f257ae03ee9e66c2fa14095c8c5408a +2170000 0000000000000180fe9bb364367778e1e787fc5e75f0b158d8cd1e0a3ed84aa0 3a84f6dc358b6ad63c24dc9e9ff3137f7eb60408949ae53e22e20b9513a8d180 00000000000000643a1e0c098cbe459e2dbc435ea4620171fb129089c4e0117e +2172000 b4283850889d4273f37b1383e155136e3de596e243f90fb474782f9e62949752 af56bf55c67ede573ebba50b5bd6eb21d1303bd637dcf9a258d7f0d3e8e723ff 2636d0b73917ab28c65659b1d410712f47b0e2782af7484793d8c08761e4d3cd +2174000 93dd6c6e6627a4b299c80fde2a72b7b28a58ecd706ff9fb63fcbf284d8809077 0d40b3098409262b8b3b1ef72687aeec7bba9255f7bde82700b4e80cd4fcdf55 2ef2039e4ab1ae87e26738bb5e975cddd3cdad736a1b2306b3e0d30d291f57ee +2176000 2604a245ab1a75203efbccb5f799ff7a4e7c2114162d9c46824cc37c7965bc65 013dd3da9f77d13abad1026a4620aac37e64d35298844d61ee46648e4262eaa8 7834bd500f6a4159ee98bff009508788b88ab0d4dcf45d002530b908e77ee57d +2178000 51a8b10058a677960b05ec2ed776736b78d4c28991b101ac5e1a5b3a91483c82 42877ce04183a845c6d7bde14c29787eb1340557e406daa305cee14271c9f329 05e2eef4dd5ebdc060a28f5f996b3c7a49ff47f101d13edd4ceafea19ab42535 +2180000 c5b3592d5ec4aa17b1819b2bf3741f48e28a705cdbc2454c4d9bb61aac4a9fd5 b3cf943b41b79550925548bcf46588a9a23865309606aa852c4b43e9af2f6d54 dd14fe814bdae8b22c329e1a5c4bbc90d3ebeee9eebbb7454581480d95b0ec1e +2182000 ca737d16cb2568678ce9a429dfcdc6ee33df645d6ba1825e2403e3fce0d8204b ef7f2a7c5603e93a0ce6be12de3e29f8fd25f471767135b9d7e7a23176d9e97a 0000000000000576383d4161a0d6305d998c30229e438598948671027d3a6ca8 +2184000 37b754fb354e5d93642cadeee477083cba9fcf022b7598c845f79266c81654da 8ae773291567c31197eebbb6d3e2a870eae4644704474b55c049e51a72385949 16abf701eac822863af316a251693ae45803196a778b2b0a95c9cedd46d37c4e +2186000 00000000000002336c69af604defd8e7eba3a869ce7744f7ca83f680dbc67d50 7c86d668225850d683a3d0ec4721986ea37b0fb8490b0996c175cf1dcd3157da 257fb64923ac949d84285cdcef6e4f21cca1fd61160d1378b1f6158974c152e9 +2188000 00000000000000a57e75fae92d97fe3c5752b7b805f00bd31d34ec8985bbe34b a784f379554e248b0d7ccc0f2ac2f824ba9091cf68e530939f5d97359d4009f6 e9a749b84874315bf3a30dcf8e8539e07070f043f1c4bff9dc0dcba71d15b734 +2190000 b2f6dc7b16e2f4ef02b085af5afbfecaa5cec1f6b459ac27cc916f79869f135f 936a22875105275cdd14dfbe3e763e1b678b23201b490e6d399c5ca3b75955b6 3e3ec0d6716d30610c4a9cf7317388eb8a29fe3730a11d96ddadfff157afb6e4 +2192000 bc6e3059a0a5b456b59bc2031187af5c87788db0080e5ebf5b6d649e0f2c449f 413f72c2da39c63635744a416fd4bc400ef41aad29d55b0f9a1aee21fa88e0a2 959e4a9a8191da86ac1b63d9e4e690333cebcfc96155134525067ccc50dfa49d +2194000 00000000000001d964379e52c7df39f8e2742d40419ce340c107d034c16679ec eafda1c083d62416ea1b1e5cab52178501c9d0edf58cd6c283c0eb10f915c8fe 00000000000002346dab4cc0367e60973543d527ddf522aa1d3d695d8a70982b +2196000 76cf1194780dabcb07569e72a44cc27e8fdfa3e9eabe62ac837ff880ccb2516d 0284df7ff149f5f6d94e865976043f7c80885cf15f4f9691328e82e0d7406551 bb638007a4a876ba57d7457a66c021ae0ca6c8e5440c339338ab2fb25c14ff24 +2198000 449218872d39dc0a3fbf045546e4779928f2c72d654fb104c19784d8a93e5f02 a3f38a8e2d6ba569b74f14591de95c6c3103e92fc307d7ff3f5e84440d025dfe 583c742a66820d03656b71ffeeeb6c3bd180ec61554af16b68b7f1042b9d3d90 +2200000 f2cda55b21320d1d896cfbcd27f803bbcc682f671cc28ed45cf1e835f4f8c722 3ef02f74fc4981d08df2a83c14c7b2c9d818874eee04cc4f0bd8bbf606365100 084178d231365862e0e3fb2ce4e4352be11b85fc5d002320c519b829b2c62a02 +2202000 1edb2cc56bcca0753ecb26d79f51ce8fd51aa0a703def1b991d260af249bf5a1 3b31e8e96e873c6bff1fa6a1bdd1c0cacd0b4cc7c25b5a1627b38a19d8840237 b979aba704e56f57807b74f6e5ef1704372f97902d52427427dc7c20be605174 +2204000 823734d6c69e132154c2d5c9894898ffdaf02469f649930d81a09c0c5daf0d2c 8458fda112c0d55cb910a87af4e32d863be4cf63869bbb12dede5c1f591b1443 000000000000004796044b9af14c7691c3ccd7e84d7bcaee98a5e24866f69471 +2206000 d4351417645561832e8bc65dca271891add88c04fb167571c1b2de122f5039cc d9281946e81d8c85e0dd5a67e9891f9f20ad3b6e6e9ae0e7326231b471eb54ed 0000000000000136e9514cafd47b1637b2e5022413de5d76f271b30e7d765e02 +2208000 e33fc2b723fed7b68df257b43509fda64e05a330cbb8d82ef9475f52aaa2be94 f432319faa53d8029df6edb0683905e560a274eda3e85cd5b43a55452a364667 9b2768cdef13c732bdb38a6d5134da36d76bede1609138f694efee7417017108 +2210000 d6c12647f7774ee5b327f1850b02d71bdcdec7ddcf80b52c686cef596a3d3bab 6df03b37780f1b450f6ba0ad4411ca11b84634c4f5ec4b0af5233f6bc11b6fbb 0f70ebc56a88bf1788873f3727bee623a4906f5d405749e0e9776d094edde58a +2212000 8c381bc31894141d6287b53bd8ca39667fbcdf941b2dcd35623de305dd1a66a6 4e03d66bdda7925d59322477615cb485882d51699a767e95a6904f61c972ae6f de3a76fb7a420481115e09b90be7084ba0763e40ae635c6cb31dd0ccc3bd26f1 +2214000 00000000000000952b44bfc2b2d25fcaaa8b0af51c4859094d8f43e795891bd1 2bb16f267acc18e32d7d4db9e35cf651eced25eb295603b694646f66ea140c8d 46aea4cec40b48637fcfcf7750f706c12655e78f2c19d1fdb5baf428fb635154 +2216000 0000000000000049a82ed6cd99bbc8f8fe2d081cf8c2ae3edba16fab7e9b34b6 83133d99c1f05503e81300b05086931e76e323b86aa4b667c5ffd7e77147ea0d 55ab328463488a85b9436c386a6bab0203f0a168a8810337a901ae86a37e96d6 +2218000 45a0777b4fde04c9150c79c0b417246ae0993028fbc023451b67019fcd9109a4 0205336c770a810c59ec15d9e6afa58e36d4a35654dab43c3f38b932cbf808c2 7e75d78ab9ef2ec04a8867935f17be8357228b93ff3176f956fae5f19ae9ac94 +2220000 7bfdace2bef1211cffcd9c49c6bc0a0e0296c4f32525120dcda2dd98ef32ece2 5566b1e38ed4b7a09f46f44118cebc297264e047cad316867cc2abfc8f26cc18 86da6af95a1fa4e82129be08c771b91ceae658932d265a550fc28a442fc880e4 +2222000 c3921cd287d3679074d9337c0844f9c51e4da0a05fff3ea7baf782b76877e655 ce16b2f4f9ac357a9feefe4a65833f818fdba480cc8e5d321d86cd5a6dc63ce8 517814ba776c27d09244b8aad6f43bcb5c71553f1839daca805a291a1fb8be39 +2224000 00000000000002b123149dd9c1d825aed7856c31607a020a7bfc2b88ab008a60 8e29fda9f5a31d74e7c285779edc8922320783ed3a80adb568583558d045c8a7 e5ede448f2753a1b117566370b81971a688cba5710007fd00ae441757dd49494 +2226000 257a2bef28da91113c81c9c6ad177a817db40fe26f005f61f745b238449b0d29 ed90aae3a00e6179f324ad4d171d0b9f5bce90f47221082497ed6df3c718b4f8 ddfc39d789db3610169e1a76734627a545bab07458ed7fa59c94b888310af3ac +2228000 64cbc13fd6c8c88b4474cf3c8e1f65d0bc1a26b42da823f47c4109efaca3cd9d c31846f2ab6cb396eafcc806c58b556265ef9b4faad85ddc25b6a9ca9b58ee1d 00000000000002f7397c95166a61121e4ebddbc342e16cd1ebb5eed95aab0273 +2230000 000000000000010a3324310e3254a4b84250661bbfa047d5608a7c70f53d9617 64e52d992f4268fe6f7e53ee40957bf254dc5c841050993ce9c731a1f1a95295 96e39611529a21ba3e99e8dcce77a80870c1d6b772f5462d79db3c5451b10685 +2232000 b92dc62b2d39c6a33c42f1465bcc7a47a10e81c4a78dd001ffb97c23a4751703 2bad0d69ad5fefc4ce583fa877e8e4e7744caf9a528cdfb0ae1a15770e310059 d6c59ab4a254ba2d0fd66ab56ebd1a2a49bbe5206133f6c71c41a1e89f848e47 +2234000 4a40359e16a1f7b018cb2a401ac64aa7b638080fe6326363f957ed7044ee18bd 8094f5b2eee70601a3a3d08b3d46922a9f229380f49d5b550227ff0607dcdc77 a021db4fbe022b5b7e49661b4470ece1fb48d362e58dc940269637a49cecbadd +2236000 4b59fda78b68be91eae4fa46ba51b2c75d21814e6864d4f4e5182e2171dff9d6 5f85542230cdc254cc8aab368f0427ad3f4bf98e229e1ac9bbe81ec531f9cccc 504088d9a9bf3b5d78a2e3b82bdc46d94c4207b4ff967d97b07725b9d2b4eaa7 +2238000 989a5f1952b38803a8dedf95317100cc4e488b46972f9e88a029fe6c2fd555fe cab4fcb67fc635f797ac9239afcbbd3f6c2e031694d1da665a31f6dbdd853824 0000000000000026ae6425beb5f98d9b90d5b667c2f9d8d18ccb8047ec4eba66 +2240000 c48b92d109f0d4c90ebf355aa0252fd24de660b04ca7dd996dbbdbf243a8e4a1 eb8f5ea2a52a3aa4441cbc8e7932c29fff52cdbfad45e2adffbdb5b8205f42dc 63e907875b0a1864c16b4f2a088c82e3d86c11282d7e52d39f828b542672eb63 +2242000 0000000000000172569a54b81e9d3ae41e1c8ca69b0d347bebc110a1bd62dd12 91f37eeba3d92d85db29e46e78e7d3e3a6829e914e52d2a52c12bb0537c72663 3d23533a0ff2b28698ed78d9de69b372fe8ab0e4000d0d3acf3427b688d4e127 +2244000 066c7dab65ba6846c247327adc179e7e0ce79153602ab4d5aff436e93f73a6f3 6f46bf5263e08bc497628bca01faad76ed0b352249bbc7e5d8e3a8bc9dfd93fe 1088aad9cf7d3c2e06957e3b9b06dd611b19aa45cde0fe9417a95524c932fe75 +2246000 fc5bb6823f28e73b8351dd9001437ef7e03e644a0138520a30638992e261c143 28f6517ec9d0d6d8bfa49e482ed6785ee91a1c8e18e05038caf23be803e75fa5 0b34fe13a9a91f899df4ee79ec4c67b6aec8854ac30c58f40fb0310fe21e94fd +2248000 03ac9487d29cf1321427c4a82253dba2ed664c36a18cb03a0ee88f89bcd00fd1 614a19eca38a4e5cb38fabbf9af88370fc1e84989f699b74ee0e5427e0c61332 ac613f59573fa8549d235dcc153885fe372d87bdddc9f2820d84871a3a6429d7 +2250000 2695ee013263d21c30f51fae0126c22c20d8d459dcd553100f370fbba6b9fd27 922794d4b3201c1d59062bf90b4f12d6f9c08bf6059bb966a1a238f277324e11 5fc2682d410e6a922b28d4d5a840d0956f501393ca2790cebad4a444ba2c5b3a +2252000 c3fcb18009a26524eb998dab3fe6ea113e60c7110cd41219d9974b180dbf5633 d13124b2bcd5778ac6c7ca395b3ca4e33f8a9621b622114a94a96559211ac492 8dffab057990f621aafa8f2a448d016d8e51f3cdf2efe4ff0fcf1715d44fcba5 +2254000 1b31cf6b0cc8b76d1e68c0531281b43b92ba924e904cc8b0901b3a6656a4a055 5ee603eb1eff70c339523cd08a1966d6c4ee7d0a7cd3f069853959959e14565a 000000000000035f080d751c74b0877012c86f3d86517d3ba3d95a060a8fb5a7 +2256000 0b3a7b5128018fc807af8b12cfbbada9bac024190e231d16b3ad412f4e9ec546 a4a67620cbbbda005ea66803b4c26fdf89dd98674d1d4048bd3b656906ab5365 bcab475069ebaaf890a50a4bcc84a326f7c3a5d7996cd1173170bdaf791e19ea +2258000 bf2ba37bdaeea14be46adb410f42e8153e00e0819c9e3e04316c8607f3748620 21de0126c3e24c466875c15a9a8582bcfe329beae5dfe24b712ce3545573e77c 00000000000002fb2e9ab3b09646caa4f6f277859c6c2ae8f33c0d67004d0847 +2260000 02afabe5991e74cae247c00d4e1cfbbf6f83d876bbb57dd0c77d3287ebb57bfa 01f1230674b57d8d2d1a9755de2b936eb4da99da83443a2cd8663f9caa3d23bc 000000000000025ef36be98c2f41aab610a0d3df53b9f9301b5a4f748df22805 +2262000 2b03a8a347c34449d621a86dcea066adc3321850d23899f5c24f19352c4815f8 8b00b015a4b4213f7af608f9942d79fe322bf6ebe5f5add8485b64a50cd1d66b 1e0e0735729e5d25b12c46d6f8766ad2dc496cca59ce993cba7ac6e4e017ae16 +2264000 b8259725a5838754f29fbd9c12f845be0cba4ebf106eb9130b621efeb3526a54 9e7d3f2eec380e06da0af3c60cf3dd2549f91661e70f188315ba0c2e47262783 0e16bf9ceb79e2da8596929f934a1082da88694ae6b52e76418f96da7e4f9576 +2266000 d63e06101cd0a5a767cc4155e8604e9b8c9796fe4be0a6a5b1b61756a95962b0 c213a40db4a1d2b09ddc56e2de489f65227254e0754e671955914420d64bb659 69024420b71b46b778dfbb4dda5f49bfd570a949540775298923e5cd2ca2afb0 +2268000 9fb4ed2e7752fcd0b2d1480108e02f9228d6b1d7ccae7ece5f4db22feb976799 d171420cc891ece733a1e843155e75799a7f8a344efcff9b55677cac0078e8ef d10051a7df05230b0ada8079656cfe73ff6f4f891b63a4f1e026bfa9a481cde7 +2270000 00000000000004175acf6448c6c5b6cc7c6123fbf999b51fccb39f89cdc08c9e 8717837f8c51bb2be08c97d1eeee2a9bac32c7a4ddf94cf57a2d1eb894b4c99d b455248ffc02f4cc4c2206621865d892755835f0e71284a28d4db398d1445439 +2272000 b6fb740f45cfec46403570b3963967eb9d50c2686fba43abb00c16e07afaab51 6ad7209b6dfbb011597804fde53f84b97e907eb31c49ed04541ea1e62e299801 00000000000004c6cbfa02aeb19da02c9d530e165d46513e93ef78e45ec26ddd +2274000 63254e4ed58baa30e67829670ac3656c0d77a112a94f9091e6c89f16ca120808 41d0196de274042bfbc28072a30b49da64d0e5262e60ecebc9fe0eb82c5e72c3 9ae01292651188fca426e69d82554cd5340f0485e59530cbceb45576bb72d151 +2276000 00000000000001c5ca33c4c35d6f69fc239d276ef43672050ea83e9cf07223a4 d2dd76bd8d549d9defd7cb305de3591b63fe44cb9142542af27382c63c41b382 70cac811e04252071828a563454efd9782988c01ad9a2bec4a3fa9b9d1f0bfa4 +2278000 b28af4c81bfa824a1fbfc5cdab46f625056230e8ecaf272e4eeacf3aa912c714 c87797e0e61536acc1988410338b2e15e131025fe62bfdbbb51ef542b907f1d4 9fd374f14bdaf38ea46a78ac444e2adfa31ab178f090521250cf1d0f44d84971 +2280000 9dcb26847613689a96e5e7a8a1c373021e3f827cdf0b4e335445014c2fc41cb4 92a6d9ad7a610ff60ff066dec181a65e83eba984d65f09cf0689dc723306667b 4929b6bbcf2eb941fc87a34ae21c33cde523a12872f51f3a5d87f43f43437662 +2282000 00000000000002a054fbae76e9c4de6474e9799a484231a2a567203546212d2c b89b934f53e99d0c3431a963a4d05862b8dfbbda769fb1e41959d82cf477c481 00000000000000c7720e1a9a59e851ad50de6e0b228238bf2257bc34cb2cd383 +2284000 2e1f493daef87b2c36eb5a223afdadc3419adbabbd70b5068ccc71149769fde6 7116bda8f6456e08d5831092847263bf1853fa53df46203530f0aad490251c78 0000000000000295c45f167f2d564b9764c45668f05846291fe8f8de9ebe8ae5 +2286000 6ed89a326773747a0afff20eafa5b89aa98bfaf4afed61ffb9e893ada94b9c03 8b4b38025f59efd7af4fcd8da06f65f26f181b62d61908d3195367259902ac25 57d03f8897e868e170a4b7a575b7cdd20503a07077ae1cbfcd7d9c326edb1a9c +2288000 6ca67d06b79fa2a2fccab16a3e7052f245d16f67f00856aaf5731a52ab692f92 3c8a6257b41c8a6c6d1488c1d39784d5e480ca6d6bbb81c7340ea97db4a2604c a57236a2ab8886c19d5315da4209c04de9f851dd902bb54c93313e43a8586258 +2290000 73b638a786ce733123693e328e0ab922953f2952bd76246a0e010488e4b54d3e 609d124302c6b1bfaa0294dffb0a3c2060ca632ddccd0a01d82df14c2abbd55c f1556edbe89a251e0846c5451ad6b949173f8aa552ae339b3f1e75ac74d5e5b3 +2292000 0000000000000390f0b1eca1bcf0b601fecc939c74592659327908963742a5f6 a575e0acce09c91bfea3bd2ca55bd12f448debfb88821c8fbfda14a516479454 c0d4b90f761ec7ee96e1c93d1b348640ce79679f71c144d1ff103f3898c4d48d +2294000 025446adb7f6ecfd4227f941b73766b18536a2db01ed8be4aa73a22c2ffd3193 6ef67e5aaeabd73c34fe575776d719d612ccf5afdec0ef01fb48b4332e6d992a 778f3a59f26df0d9a2f0087cc394374b9ffa1ca9b8cd96e0efafdcd1af9caa7c +2296000 00000000000003f7528fc3d3be72a4fbdc94b017db27f715abc497538677a0f8 31e261654bab6326e138b57921ced31de37cc1c66ac88b3fd9e53f99fb7c63d5 00000000000002becc24d78a6e2d3b5785074f5329df59fe2962673d5cd2d9c5 +2298000 ecc960b7df1343583ac7e79aa184c10dfa382f90faf4bdd62ce8bd47d3894e95 9b9172c4b4b8c8662e6f292307c61853cf603f548e876b14645b2ff706d69198 366d23b5cdeceacc554884c628eeb7305e2afd5ea988c05192cbace9cc8bc2bc +2300000 6048af620731d1bc6c38cfd85df2d5b194af25acc3b109d2fc572b6460219922 7f7983d44c7ff41bddbb7b140c2176644434629a38bff4be7b475b5a8a35985d 00000000000004dc5da39440858b2f59881d05fa536d670e862e727012cee63f +2302000 00000000000000eb2122d2a50529ecf85e85806e6ca91c46578481f243b45664 1051eadbdbf9a1acba07816bf49f74558cee60a11080588902b01f7570663a82 49e24f12cf7bdace669b8e2ea634cfd3b770e0e7739a085c59cca657c664ebcb +2304000 00000000000003359f61f551804c9ef34ad6faf8088ab1ac14fd51694652241e 57d4289b1027773304aaf3258b45910995373a990d2002e630766eac4e0b97c3 b947ce81d9354f3db52941d7d5604a9789046e4100c7fc4419a2cc737bcbecb7 +2306000 0667d5bdd0c057a0008b4c8938ba982590a0fddf4fd20716a16e1267fcc18c59 0cb3de930dac8c41f0d20ee4cdbe1d8327f411c35f418f5556981d1c6b9e1c7b c94dd98d19cd2809991f0682e6c83c010f9ec659023e9b955e2c23fb3775ac14 +2308000 2e4825fbf65d7b0e242f4ab98bd6c760e09cc0bfd55e69a808f8baff83e2f854 01abaffa3c6b2d01eee87fdde81c5d639c14cbc61a617c21cc90429df42c8d1d 90cfa3bb584f835fa224d51199bb0d2bccc90ac441cbcb81083554bd97c30cf8 +2310000 7a6bf88de3e0aae61cf5db3e9790f9a30940ad4e6d40177daf1d0503bd37ae52 99be0278cf8def72102a08d35de4209bc248dde0a93f87e902a75ff1bc024a22 898138400b77125492edc215a8ed0fdb7e46d85a4bbc20bbc8a821c0eb479427 +2312000 110fc44714e3661fcabc753f0c2df79fbfa8a7bb013cde61ca8efac56f1c2320 d623c90da2d62b15674a89cd17c3f93af16c56eee791a904172fc26b7840477d d9d9be9e129d125cbc63106dc30daf1e4612c6a159130b410edf8a74bcbb7430 +2314000 0fc8bc5fe2c22510f0c7a5976eef840f09a3195b843654a6a5eb06910159eb31 85f604054b88ce1e2e2fa5264dc3d10bc1d71a7f116363182a302eecdb0a2a4f 000000000000025588b0f143d34c86e89715bceb01a33353e82f4a5a23100b1a +2316000 ae604e00f5c0ddfe6b00041710bdd34cfc6e9c7fcea68a1db1d6377e4f3cc305 99e0bb234274528addf1d780ceaf63f735a08ce19e172ee59e7031ea7934c183 80087dbf3963c772d941d09942b020c138b2e8279efd3f145f250d3df7f00e18 +2318000 525b56b7af96fba6ec005b2b53ad6cc52ea7ee29d22b4122c06cd1cd9724ddd7 05ce76753cdddc6ee9e4b0e3a4053dd003941e080a48c0a2d2597899be01bc82 00000000000003e8e59fd7f5f2a38d3a76a51e6602b501f74b7ec4dd7575fa0e +2320000 4ad6fd81fcf67292988874b532ef25f4d46769c82573270fce8c76c773c8712d 2963c2375de42aba191712619effdabb3d8a1f0424b4a2653f1ddeb07054e7b8 5e880ab2986d3b9e9a7703c753a532ab13da26838f823f8275afe007db47c0b6 +2322000 3c715297e72d97c0757e6dd80a9981e43a99721895ce526b3d90dda171f2db70 ca7a36a59dc2aac28c2d074d4d82acc9f967ccc399e7d967ae72008e0cc20625 03a329fa53fe8c1a5bf97d40f21c8d9c20cb34d464f5f6958046068e40576ce7 +2324000 0db233f33e96f05d6dbb70ea3b35e931c7dd35ce31742e36b47a6752e02cc474 8cb7517f5e6decb478319c3a79c00a6b7d9dc56563461b18fc81d3f0c05239d3 0118aaa13d88780481840a1081095bddbf9cab4a735c173726bf78b9e5bf1753 +2326000 9f9b2920630307574a86fbaa2be19cd845e55f6e5da01f2ccc70259e1a2f35a1 d31a35f201c0042fdc1ca7147be91e0244a8ddc9350983f97b0fb55a81d6e5ea 333c707f6b3f0f0d538e12ddf24bfa695d30593137f22d6e5346a9d7e6e55ad6 +2328000 5bd63418c69a99eab17a88782a70553c9457a51b74ecbd3cf17fd0744dcce713 7249bcd0f492ca1b1c3693e251dca8e46959be006a81015bd9132710d33768ec a8900d3c3045136a697d511a9ff5e6086e90b333f4975e94fc9b8762b9b1b605 +2330000 5f53eafdff14d6172a92eaf4e5cc3c480eef860662e2adba42bc4348a424f4c0 be5834746a9abe50df679b2aabe0f50aab3abced843792c51d0f549c4fc7ccf9 dbba9e330d3641c774bf239744eab530d2cc3a4f46abdc9d4f68dafb8d1aa13a +2332000 e4d1dd5b1427bb74edcb12f1447e37da01e465cfa7bf28324f160b068fe8a7cf d9a2ec2dd8ac97e1d58076c9b6d61ab5394752fdfe3152fb35f732dc566dc5be 00000000000002097b1e4ae642e5482ab6b362ef2005763b59bbe31cbdb12411 +2334000 00000000000002361c78196db3dc30ac487637ad398f7da36c2c09114999d1b3 3ea4fa9f8a5d9defc0a7cf24a235885070fcc995b82cba643876c648ed82f5a8 7eb6f3d9b798989ac5bab674cba25f46de8b5ac37daf3b55d2bb9df9734169a5 +2336000 00000000000001aed22ba2eb84326814757afb9f71994ddc18a1e2f13085f394 77e44d635ac498998fadc455816fcdbd577bde05b1b59d9c045b65c86e1aa7ed ddb2e70d46a050949f0f435d4c78f83e3b9b0ae552558c0086e8f57dc8e15326 +2338000 242533073f2764290a269dc29b1aadf8213cc3d6211a0d41860adc840a9090a8 f3d1f9bcb723cbe2ae69aedee28b78c81975fb1f0b7d7fb901b524ecf84df7f8 44ceb6f80ac072fafbfe43ae9b59842374841d3b0680b7730b01d4b72d4fa9be +2340000 6e014cf5243291667895f8be6b04eca57d908707ca7f4d9e7a35b44fb8ec9640 16c4cd1f1e56c436e0add97d032d08459234efcdcc198348b3aadc00722859d9 00000000000004031d9530c0de102955138e7110d54e8d760b038b9eacc34367 +2342000 420da93ba7e7886edbf4af682d962340af39438878857b255a7038ce0eb2bd9a 7b2008d3066036fbaaf33ecafc851722aab13c01051ea7854a26c79e99981fdb 69bd321fe2d6e168af5d506b0ba7aaff1b9f3bc60dd159ebb97daadd7330aaf0 +2344000 411836e44f075e7e9671adcef7576773f2bec77297a02bdbfcc80ba4f831f30f 880b55125a5a256a015d4f355dcedd5e09f2f7586f8e09d55c5068b5a01a8210 00000000000006e3d05c34a4b59ccccf2a732d682506dc8d137861928fe48d85 +2346000 13d2e39f335e80d84d5a40516cfd9d0dfe3b7ed492f7289c2d39d54ee9c003fa 27dd931fb4274333d45cccc18aff481ad729b4d79dbc1e6dc1ba9a86438ff433 820f0f2a173559567342ccd517882da085dd2036209f67bf0eb439a881f5c481 +2348000 7e7bb7394dda5f53cf67a17f8de07091b565b5f92d8065935142630964507b22 0fca8aec1317083df70845d8524ac1b97108daa3784b135b4816da65659f6302 8ee3bccf0f2ac0e04e566487f3558ca7a1bade162337d82d7fc1e92f6962fa15 +2350000 1ace0a0f8b8c547c0cecf4539c737ac4e491168495d12226c7b51e2e1a2e4b8e 92d6ef2a7de76374034ee87ef93838418c3e7d2f3532ab9b31b2858e8b2890a0 ab932a97f939572c11136f6711c6cdb8deded8bd5a76f0fad2d27ff4ddd7c705 +2352000 2cb8a64166fde879c2cb9f49a9ecd0e8d4823dc93863a0148393c14e7c0f4d2e 4ab15985d3b79cfee45a2b1be7cf5b02ec19c40875dd4f1f5477e171c3cfd3be cc639068a7c1a252d74dfe9145c3ad7c9001226f7669572000ede6bc6e5a44e3 +2354000 e6eefd5fa609638a94d93448fd7d5427ba948d02030553268752df8a141048e8 5ce8cc8c0b09d2d6f04947060383f48c9a6f2a4611db00a0728c7370b01c0454 00000000000000477fd2755120b9410b136227a42aa8bc44c4d8a6c12a780d9e +2356000 9a6c631a7e592d579b97cd9abbf20169d8a9ae8b7d70d7aebbc2fd462c474cb5 bd95ac5b44171ac4e6449bc3a67a0ead1034c313e39273b415827132e03b66cd 9258152c08d233a59d0c77a0e32ae29b2e6d82edf4d6463d520226174bd06373 +2358000 98623a3a13bd5f1329a67c063ea9ac1f38226b832bdf12ee354c9deaaa55fbd5 6b0c4cfef66d384c1e89676c04085ea3bda0e5d4a53f5b7acb470127adba05ba 00000000000002e06ab1f00bfb4ae2462f078b17068e8322fe169d214da16d48 +2360000 ea49fa06e50ec87461eead60f7ecc30fc64a79cc0ed8f10b65b2930ae2bfab5c f9ca3bf80eb80abd5af1485468c0f65d3bff9c9fc02da92c2f6c71af903f7a64 1e4fd7bf9dbfd1c408a83283282be122c4a43c247610e14ae34fc96ad91e4ad7 +2362000 c43b637e8d03af07af3469c1f4e4e56cfed2da43eb3b88d4acb698b965035524 da6feb6580049acce461ec0a8656fc1e419c37001de4bc4bc49ea40456e6c215 2c6e90c49af86f42f929c28a8c4cc35bd4bccd3811be63d65bb8bc97430017d9 +2364000 0a70eddac25141e11ac97f770db732f9c6f492ed6a660ec3fab792cb6a6547f1 57fb253f827ebfd5fc24e5cabf7c7db60b5e1835c2b1ed4e29c6118746d54826 fe04e7b366b05b8bbcd0a56a7c4660d7031463869c29d80738d582b8c6b35085 +2366000 498d488b6262cdd841b33b464e3a382edeadda61dcbe39621ef6fff1773accdb 41106e1c81719360edd0279a71ccaea2f733392996a851854dd388ac7af1f18d 1c20161061a2d3a79d27e98a2e23da9a598caf01923c74069151a5a490f422ea +2368000 6184a7e0244110e5752ee2c76d1837c82ecd9fb08d920be18f0f3be180f0e51c aa6d425a3354d892c2375b3e7cf8b6b5b429485045d27d4cf85f09233b98bd29 00000000000000be8b632665c66c196d2e4c68df402627fb2695a6a493fb0c82 +2370000 c0c37910cf39a107a28f9a517ed84bf2158d11f596a5ca8910d4e349514fe7e9 7e57a451753b6ac29bbef4387b65b1bdd11e7bab941199ac632b3488d750bdf4 00000000000003899ca0d00f0ddf56f65a98120d7698fd656d2991dbc8b890a1 +2372000 22bf1475ebd48177995d759f46975151693ffec7bf0e16c8eeab3c7e3d8c4404 253a41a3500c4841137ef78e2a0def4aba5573a16ed2ba33ee851f67c8978ec6 694edc2ba3b8e9bf9f47cf5115f5f0de602f308a99e40f6bcf1f3160fc760732 +2374000 c5c78ff8dab818260346c2fcab322fe9391f30d44cfc5194968f19700fd1b960 327be12eef0c5fb0310f71fcff425d85b5c8cafcfa94f7b088d40a1ab159cd0e 000000000000043dc2f42b30fb57f664c513ed332bdc3689473f2b3b7ba2dfb7 +2376000 000000000000031e2ed1af1f2d321241ce3d5934a203ef370fd1d12b903ad098 d5be99d2e460c2d53e72670640427c6ee322bc8e6a4bad231c8899d2eaef3c20 efbd5356aba135b6dc7baee711202e97a3b625253d006b6a3f0d6fd683b54e2a +2378000 3a7d52a369608c0155c8311e0d5e6acbf2cb32e4b278a872473a44fd4bede47d d8bfbb358a2c4d6bd7aa2b6e515d4c30eb895b9e2b757ca8c583fb718583491b b9c80d81f4e1e7dba2629d09805307e07c44e22a45eaed0d27aabbd191f2125c +2380000 7d1bb4ced7ad977be8228b6207673ffeba001f5c0fbeb240e659211313fa152f 272a427796e54055d5eb4263552853d5a73c75be5b40238e912be9f26eefbf20 b19b005da789f993ccc90e768563d7bf04bec7fc53c38818a803642bf47269ba +2382000 404dad419d2ad3bb567900128e4dbaac69b04f91f6dce0337c6987047e09bfca 1ec73e487d35bcc07a5f0da817ed9319725ebe99c0f2200534227b3dbf6f9952 00000000000000fcf8d0e0168e44d7ae856321cb91ad8b687c508943f823c342 +2384000 d35fe5f9237db21d3b6a9a6a4e4010423160d7d11a0e0d24544e11f6231712e7 86977b9010ef85cfce69f3e48095e2f1d245d29ce3d23f362ae9f4330f35b18f 00000000000000717123444c57160208c05ffa408cd6e5ea6ac27b35df27247a +2386000 944af5db980774ff47942eeacdd3ebf8698051ebe6fccbb6350b8562b4519eed 6bebe57e6ac987ab48e1a6fa30d20b2115b7c5c383df40b51dade8238f646cf4 de655ef6d8f0f3d5fd748bdf5eaaf1a35d7ab5d8bd0796d7a996aeafbf408def +2388000 855e6e23c3c184dc1d6e33792af89ca87b6988e6dd5ff38aa9a024aac1ea4a4d 8801c38430e97ae80383998cbf5dc9282e8c92c97141b25844a6f94a7a10d93e f57d71a041d836484da6670897813ceef1ec2adb1a2f9e579d613e6356e59b8b +2390000 aa760dade67ec468e4e8ab54f8c4c2885acb396be35f847729b5c777e3768f62 8d147ef46d800a3d79d07b7113bc3723e543396b2ba9040708bc729a9e0d6056 6c56180100aa4994077ec73092614828e1ad768056f5d8db26ca1d15e061a45b +2392000 0000000000000127cfebc21cbbba9c263de7bfe695462b91cb7f85111a669e34 638f7b64f4caa8f95c0711ab715aa5217962bbd2e140899a9ab3277277c84e44 0000000000000713318a8f8534e1b706d417c6c520322a860b67eba3d80840b6 +2394000 000000000000018d79c94216b3675c802bad6d3826d9fe5c3d2d92dbfd4d6428 30be3ce73ba9b122f72f28339c0bdfbab3588f831847bdd47454510c93c5d0ef 0e22821bd5be7890afb1343bed5921828faf68eebe983df3e73fcb7778e139da +2396000 9f8f5f43ff9b35bfee58fe177cd7817fa20019a9163fde81fe199204cad4b4e2 0620e4f3d63735f8c43824e1e9adf2f0f307528d0305ba8a7b3dbe5b0db3f922 7e7f7e84129657bf521a09dcf31029afeb2698d36141166a1f5deaeeb4a8a4aa +2398000 843e912debb536f88b42cfe2065ba41d3a89f34e8afda6023eb848b3b03bed37 d27c823968cf48bd32cf6fb795f5240391977c5db1eaef1c8ea9a7a0a00db130 65f760e8cb4c8a3187faaccb394fce432c0cbec8e9825a8c1a5b947f482ac8d2 +2400000 ed5569553f6966c7b6b75e78734a7499eb8b3ef619230262c374ef25e903328a 82dda677a55454fa41eb748b566f121b0345699f5677178763886355bc0b60bb 8eb93b175e42deab2a9f461b5e450e7b9e399a8a0f1f1c3899ff7e9e5272c553 +2402000 640e929110453024f248ae614a52f4e778141c820078277c5f47cf56e03f0923 18927ea5f45eef49be9dc22cc2144881b55bd6219f02b7f573f308a1ca66ad0e 00000000000002498df5e251295b1805db9726eed556ada60526c4b56c4769cd +2404000 3a1c8f7e03db05209a1d162cf97eedbf0a83b6e40d3b9710f33fa5a725e8e819 e5aa1920f5858833d34ba6cfc4f5b56de2392c81467e5c294be1f47b8b23a88a 8d55c8107283057006f8d68661314a75d54150f142e2e7c82945e14bbf8de5a0 +2406000 b9556ede4e82d4f37c190e681b8d741ed8fa7ac7412efe7cda0c70eb013c366c 460c5a319d974e55ac5463c7c34d94fdf6572099285872c93c2741d43dd896f9 e456332dc4a61f60742f6f99e16af2070e206e7db750a7436fb3b70baff248f9 +2408000 9b2296f46a3835677874678d1a6a6c093a4726c77b4ad3fbc129e3617ea4074c 8d22ad2bcfe296bcae8b4797a26e7b1b7ecd1027bacdee6a7d7eaac20bd5629f 7225fa04b228f88a74ae2f39f1f2b65904831df8c12b103d640dfc57e0f0a7c4 +2410000 13d61bf6f2fc54abdba1f48bc29e49f09d1796725779da64fcd625332cdd878e 5ac30a6359dd7cb4f5ebd9255176fab5ea4e80c089f49c1d7550dccf1a84e270 7ae3a067250cf81aee6282a655bc1e36bee8cbfe451c4a9edfe3b1bb6c7c867b +2412000 db3882c6d8ad7d9b362de8052494343cbc4ba97d7bc76b29b63dc3bdc61e7fe0 4cf6c12ae1fcfcbb8bbb2eb53a6b1c3632458e70abf86193dba87e64d4faa731 0000000000000207863fede888c0e78ce83f507a7664a936dd20bc4db6ee57e6 +2414000 9b021c8a8cba65acb6fb039c8d67ae5ef1ab83d12b13b59d4db4f1e41cd8c356 888902ce12a18464742a572016ab7ccfbda63cd7f54c970ec778d1131f3595d0 f71460f377c123868d82008ae1c927bf472262b44d86075b88c63a63b2bcc2e5 +2416000 5e888347cfa91b9b24346084db1b390a78562f1c470f84a2350677fa001fe338 216fc058fb85dad68d5218638c412b742fd8745d0388b925290ef3f6b350f698 32d28a7356328a0d6ffbd99bc4c2a65686b9bd183f259d6feed34036a7d878f0 +2418000 000000000000026d4e83c8f0c7540f1a7d7f1a9c9e33525e5aabc83bc3e47e7f 97a10b09aa8cc0efc74c5544038f9632909cfd96d4cec9f6c07f262ee5e8fa30 517030686cc30b506f8b24973088626e27cda23c9b1468229c3e13737005fe9b +2420000 bbde55f2ee55c9c505d647d0dc82dbaeec92d1b93c18f5ced42428117b1df1b6 1a3564b5768a39ef11cd3a7e2e834e76fa7fb33d31ad7b5b9b3e6a0c04cceb60 3738be94ab37e10c3ff8b109525e82e36d45c57bc2959b39f808fb11e9984aa6 +2422000 00000000000000e335b2baf0a8f0da550ec51b0e86567ea225da48a584c5d937 eab08252b67cc3203b72d6ee206573a506d8edb9507b8d89d5c374e0b8a7921d 95158326e82749eb84cc066dce9f414811902635fa98d111380a87729bfee513 +2424000 722d4abcb05742920b1e9b1b097b50e28281169fcbe12802a898319a4604eb54 3ba334ae0d3902a27a968d0d00ba0686f978efc2786cc12f4b3224eddbce5a30 639587cc0b356c2e6134fa6a14b63e02d86e56f2e0b67b26d58da0331a42bc3b +2426000 00000000000000073e2b5c47886f90190aa7bc5118e40e7103f9ee102e73ed38 06cb6f234e7d6e1ea491801e97cb2fc24cdef30c7626e7d83597ca1ab7e977ba 000000000000018e4f3cf85c2c10c60f9def79fbea1b6b01479dea286efc3eab +2428000 3bcab501776766d74575a2e4eac72860adff5a7cae2273f6bac899d392c9b50e 0e63fdc8da05dc9a6df6b41abf5ba03b6f91c0f1505722d935774d55858efd91 2af26de32209a90ff29559d43b2d14c88f27c93647f313b812c8df98c8ab5c0f +2430000 0312ad2bcb7c08d426eb58798fd6fd139ca610a3bf78a9807bbd22e07c972ce7 c644cf33ac095e725f610ec532edfdcc431a074ef603d4652414e93998baf0f2 48439a7f1a9544795ffed3f5c789c3a5aedb5fc94af0e276daae1e8904f9d9f4 +2432000 00000000000004230e7859c92645e37cc4ce32b010ab47dee01a787ae0eecb5c 62905725af8f1b809f02d4cdc80e4d75acf447357931359c230270e904fa1551 76c282c37365e1ee8301c5c15209b6c82e1457ca4dddde324c3b88b4e6e10eb0 +2434000 ced0d30a96b1b41d4015e0e9c51c61e0c65869cd52f8e33d4e8122b3006339cb 2ebbeff627a0174f885fa913741ae639daf8d018aba5eefed232b4b965105a77 040ec99b3677c5bb7a0840ecd1ce5ab0a5c544c2a66791a32f71084123ea6b8b +2436000 039518dc78aa3be7dbd39af4f76a796a85eaeda3e7bd44a900a80a777059a84c 4883ff350ca5742e0609010027f7e0193a646759fbaf6602f654871e29a123a3 f32508a0e00b4232a0267ab798f9a735eb713c558ecd7fe9d3be747bedfa4afb +2438000 000000000000002bbe4ede3d69c78f59b7f6918574b66d67e3b59bf642239e77 ce6d2e0528933b617df485774e8ab682d5f91bc79982e16800601ec50389956f 00000000000001d05aba292bc838e27d38c1468b238d29f09fe051dc174fe874 +2440000 b2fe75157c97ca83e56b2e9081b2356527fff26aa5de387bee6eb802bbb7492c 8493822fe11ce2acf9f0d4bb5b154a9a1c7b5adef9ea3fad3aeeaafce765169e db96c1f746b2a1ef2002f4bb59e13b67233a8c5eeb7dc72488ec814d972f9f23 +2442000 3aee0785c75fa4809d7eb42a221831802191b54ac1feb493da39634ad6db6c89 39918749bd6de837154bae33add09760977de9d04e535b8efef5c0f6e48fe974 0000000000000485bb6f5b376161774985a2432606476e4503dfe10e9c807110 +2444000 90f7a2a7b8a8acd07d938f3dd2ead17972c21f07abfae2f7f6d6db6a065b38a3 f6e15353f970643ea2337659f81a58f5a4c7618d03a9aa1075361622ab736fe1 c86ad44c820c5aa493cffa9c011ce05b6c05ddc79f801cb34e60ae80a52b7bde +2446000 15c4c04f041aa19282567ed5b65fea89152d70d6651893c41825b6c8167332d4 7b27d3d6477e22b48396c7ecafa7f195f983443fceb59696581c89bbf53af0d1 0a52d39ec3de6cbbabc5a21a32888d5904eb1cfe1c5ee0d6c19b016886679cf1 +2448000 fbb4c449ed26932e25a1808126dbdc5d697963f105a79ddf690eec655f7f864a 4f5e2db905e5b4e17778658e85d6bcbc5c9159e1732b1369b72606138d8a6310 a2d2263269b1788406f8598497b2b44988fe6df5d5a92a943c1cd028c3846159 +2450000 09cf9232ad44e6afc6f000cb536ad920a744d030587faab8ada220435b7aff8a 9779b337b9786178ce2b52c795873aed09f21f962e0d052eb96f07c2154ef7ac 1d11f7d4db8aa83a5c11c09764c7aeab41c14246c262f3b0b2793571fa5f5d35 +2452000 4b92eab46dc8bf7d10f8303531890f32da455ebf51d63d16b54d7493e1f99f3f 57ca374b2942c57e8d70d929f24c0b8ad8935ab351e45e305c99a007f898ad5a 000000000000035f18c3555e89376cd8db18b558950457e23941907ed151e795 +2454000 678419cb9b3c0672707a81da3c5773d921a72dcd68520ec2e4b16f969dfed39d 3b0bc6d457ee96e8679a4108a364d12c1d9eb927994759c836a3b91958e0aa6c e764664f9b41c34a6904e027cacf7f7129d4382526135976a375fcaf02545ce5 +2456000 a25d12c0516bab785d23dc483074a1960333b9006f64b89bc61197156ccac566 52b2b3d9570e2b24bed1be738f28df7c12907c54ee93dc13c581702618c0c2bb 25d3edb3880147a970009797d4c918407fe12005a1172819de54c80a8c4ad414 +2458000 a31210ffb4b581348b242ca8116d97788de3d34371ec15fe8176658dcc0b33c0 452287fbbe48388fe71d7b44db7c09701099fd0c81169da29647c3a2082b936c ba9bb41594c8641d7686c4dcc11dc0f304f18c9247dfc6f272a6d2cd47bac4f4 +2460000 061efcc385ada1b51c9bdd7d663fce907f265c64f5a6ed3f0291f91805b374ad f70759b744896499588f278d7018280d89331e741eca50a3d9f8abe28bf31ed8 aa8ae1dba58c83bbf492e2d3c2d154b0723b527409cf5f9d38fa2d7d6f75c4e4 +2462000 00000000000002a80ffa9a2e0eb6d7bacabd916f7081beda45f16e4b8b66e56a 02fdaef830c62625342358b2c2465a60d6421ed50cb255410bd4f845b85ef1d0 00000000000003cdafaa2d6fe726353d460f0edbf8cb65e4a9e39bf6aa69dd53 +2464000 1a7fca8cf982c56f1895886ce011287dbb796147af98ff0872a6df97535bea3b e6e19207321627680aeb3a636e9c7759df9bdb4483435b9220b4dcc92251e3e5 b6a823925adb523ac8d859557accce6c596edb2babe68ef62baee9d6252c0a19 +2466000 e7abe73b01a74ea086ea9fbe4b845267334f787fcaacc18a9ed5ae27e38aa67d 0b46237384bcad34c7fa7aaa0407cd82dce9894ac6b70a532e13a9cb61b0a49f 980284a148c4845ec7e3285ca404719146aa675e5ae27a781de577845aab6275 +2468000 df5f54657bca9e457546f815c9bfbcc7a15d7fe9a5af9a6a3c0e8d5e728a8d30 2ee34434c7a855553dfb210cc7a8841cd916d5f3ce104fd46445a48f2b0afe39 000000000000020de9236bffe2b3f6d6ef1075cae44afdc6336e569b3411cb62 +2470000 968aaa2c3d7a003c5b33ab501c37e111ceb25251d63efe640d0d20b222b1f471 892be3fd83b39df1151e828b11df0f6016050a7d1fb6e9aa1255bb41e250b262 be695e617aeed1fd3e683339376d8bd1e089cbb4b5ab3312f9edc3a82c76aee6 +2472000 2e998c1045841be9bc9f0149fe903f37aebe3e714d3dd87293f20cb49a91ad8b 1f2863fc7141b5122dbcc2463cfb0d37c31010c43b5737d9983c144643863c29 dc6add3134eab54060edfc51a82a9098a6025d6811373d59eac689f2c82d472c +2474000 5359fbc63d194a77da93380b8e95fb96e738991577ce208c442684a49df721f4 fcf5d8e88a0df5b2664c3eee840ac825dded5a2d66dba6be78bfe7df8b0a6c73 000000000000007c8576a6c5dac2247cf8b7391244fd885bc9c7642e3d259440 +2476000 71bd05b6f7464fb260b1da97e24c669c9b9190291e1517c88ab7cef0746ffd68 3f98c8a8a11e2ff916dce64524be669799bd842168316403962b6d27ee41d9b9 e33a67ef2f953a2954761f59466b0914ccf8a3002fb34dff3d01800cfd06a747 +2478000 afa7adaf9d6d4c26fced952ba3fe451dbc087f2b2f6d06b3ad5a61985ad6f066 c54d806333bd40d2adaf6602569971d7ea791358a329000ca961c4bb0f97fb7a 9f8877ab0dce00f103fcf3da4eda3d1018b4a6d8789258b8f1b26579281e3a98 +2480000 7d2ee69744349c7bb2e84e7704c896f08fad92f31f280f7102b0b973187535e7 e26642507dca965d51e98f29f7b7d6e5afb957a5fd114e602e749ba27e956cff 880bf7a3d6fb3bcb1fbc45208c5cb46e5752cdae95f9c411fd632a3991338d27 +2482000 8485fc148d5200211ac9efc65e8f8e8f7168bcf080934d01a779102fe8f4f996 36e460e423d128ff3a20bec1f721b9e0cf55ade5bfc5b4c520c6ec7cb7607dcd 170e6d0620793920940c9a1635ea52b84de099f1d3168e20a2cf77b68626666a +2484000 4cef521afb0bc3b0418c573742aa06cad0194ce682a818ef585b7a367cdfbac7 3a0c672dfd81f158b86a97eedaf928b1478a82d76b6eb3a510ca78fa024b58dc f961a366068b20ebbac9d39070765e354d6f0ee1cfb6288729757b80b879e876 +2486000 e4c966608c825a99d53f09dc2e4ce1a27bc10394fbf01cf23b8a7cb62ae38870 3e5960ce81da48c3d26127ba30de9ac0561b6a4ba8e5fe1604739dffb50b75e3 6a22fa87e6240bed535197a6c76466d5c7b1b32040e6c3e6d9283b6b54a1e01a +2488000 00000000000002762133b2c9df669ee8d3cf9e6fc8eebb8261ec8cc03c7b0446 ec5c334e0676189fedeea45cf703c37965bd2c865f4df0141d900c9317555a7f 000000000000016f0918d7c8835e1e20569b05e7d5695ed14ee6b8b48bf10d8b +2490000 a61d53f36c8471e062faff446d12f3d6cef89c10c41bb3a5cb4c15b292936f9a 2b4faf59dfc84bbf616d565ff844f9e03a8a20a7bf3f33a7ec4713d1eccc372e cb55d18518d6e7ec33329310cd871054e8026a3d46b861acaa6038540a32d0ba +2492000 00000000000001417776abda067ee3ffe6764ca4be6b187f1eced967dffc8afd 640ada4592515ee599356216f9a993145b6c2c2b6bc21ab2436a369cfaaf2329 f921e203c45e22104eb964d5c52d98e636bab93fb097965533d606c0bbc763bc +2494000 5ea96c46d4e0cc1a5b7cd05400929df293b67c3d1e217e5808de9b40762d4f99 0467e35e7705f65d87464a4c9378dd172d807ade4abf90a36b17980f8501c455 827b4beeb90c965b7c91563fe6a601abc7d27fbeb0c01f396c5476d470071b72 +2496000 000000000000037ca77c2d315b707e622ae50c376448e51647f92c2762d87c53 49460025ee355a23c74df494828faa7b83978f4dd4fe786a8a5e1e6a8792ed56 5e36e97693809ffe5730619b2fc36066b49b5fd7f3a9e2e1a07b4a557f767628 +2498000 c2bdf74380e601487d5ff3d2df118808974bbc9cefc1b3f45b739d834aa8848d 7daa813957dbe701af322dfe91694d0e1e356b46c3ab819e0a7300c83cec4f83 2bdfd3c4a296704c3a295e116a0c296acc2100a19913c741c882fb0be8769e14 +2500000 239a6e786001523e8ba4485b4fc1665e911a5b9b093260d194bb9c9b394d244a 63f97ef01df47c369fb2840c81194912ec7672c60ee1f7694957807fb0301388 4c6da4fab1011f117baa462067cad15c5bd4acf95b907d9b5608f56fe0e1eb4d +2502000 bd84423d44511fdb704978ae5b632fb3cec85091e766bd89a74643cf5d11ade3 f8ad67dca23c4628faf09b3ecd5f17c5279a616858c329707d36e161def6cdbd 000000000000057a4a2570e96664cb940e7f19d2be024ba6745f3c57db6e66ac +2504000 63dfc0d3e3592b81d4951d35af4a1064cad7c90f895387e5be8775f761e20a77 dbbf8702de7619e5a03ba62e3ac18b2352ec0d7bd0247f9eb8d8c810734b39b1 0000000000000b5bac73dec84c438ce818bb83eb48899176179824257700d024 +2506000 1e199cb19e8472eb4492fc10f4ec103d25152746dccfced1bffbd3366c0fbe2e 32a2f8ad9e892312e59faf5fe7a6be110ff667a45ecebf9ae381b273022e5fb8 90e5b947b1ba83efa097c9411cd5ab8d5c09c92ad45348d8261a576d5bfdb070 +2508000 e466c4fc47dd2456b634433b8ae28bd6947e8ff558a2bfee503b0d23a64f96b5 00303f43f0703fa2f29cae63f7c1a966247c677ae3491825b5e12f968b321832 bbe873f808c550c8e950584f534023b09b9de6d519dabc8f7b779e797843f18b +2510000 1b8101130542535d1e73ad6d90da03198378e2b3fd664a5d52453c8e407a4c04 3c68908419410644fa7e7af5bf46428c149b799f235a75a8a5d3eea8fa86a6c9 daab4c501fcb4f77681120360a2931cc2dc60915df0c49122de14beabc00e8c8 +2512000 b052b52646c62837effb4c8f5f294f51246f3a74932ae767e7daa81b9e528d43 e88e9efcf55adf33641aed2763daaf5f20addb1e43491dcb6bd07b4dab50905c ff46ccf87a224acc80ea7a095c530f7756885da517b9dc516ce2e479f31331fb +2514000 16693a1ab3fcd52e4502abaecc06bf3ba4768b81cbf6eaff9b91858b0fa9960b fc067b49c69c2002f0af94a31c5e395defab081c2fbe82af534d50f36dd6a0e0 723841eca1262d4f04aafe078a9c713c9110bfdd89fa9f516c277b7c2709a883 +2516000 e16285493ac1b570ffd8e8414b26d69e990ff0e3dac7cdbece6b25b24126f311 4204f2cf96258d4980b30633855fe754eca64af092607f2b5e1ca98ba8312acf f6a547af9d5e7dcd0fe34a92bda6b557aca7b42f57d9c7712f864cfe99e872ab +2518000 6384b68f894e460d834198f5237b11e78de4433d019e039b4e4e3ed71db58fc7 8b42299b19db867cdcd18eba4e696d6294696f0ce125462ed8cb3a3b394fdfce 1168f4f5770d579c8c222a0f03dcc1b7f2acb3a4336d0c7fa65d48a4489db521 +2520000 e9b3e3dded28f5c916f2a1f359a18c9be834218166054fd7c15cc6ec39d0c2ea 6ec1ba27dca0fbe3ab9a4e1773151638a733669f84feca7407ae342687540302 149012482f60e3c26facfd309c6f9d3174809d1300eeea2daacdd1bfad69823c +2522000 367f123850956410c43704404d0b4b6aa9550c15f90e98ebbbb0ca4eefc2a112 452cdb15fa053abf4cc49b85b7386b6b6de1efc5152573e4d80f5dcf94fca676 000000000000038378c8e4addc36bb1e4170ff935baab575d071a4e29c015fd7 +2524000 001d515c6f489de648c2b92f14bcb3f3dd65b50efa217de5a181f230f54a200b 2eccb264e6a859ddc5b37d9a6b91150b52752d2dd628967dcc5c62a0fec91356 b443735006c12204129363326992903cf317275a06c0d53f3d38cddfe01c7196 +2526000 472c47b61e06f21e443d48022f6b917ba4b9cba2881ce0d7c5011aa4b666b527 8135a5f5dcca34fa3d5a80cc4a1d43668fc820992f07cc98f864f2601917907b a464d358ac9a07f6296a979009a68c9eca681b716b825aaeb9a1ad658f8e3d3a +2528000 4596c51ac3e185815ab206ba659e51f3eb17d02e1bfd8210680bb06553363caf 12f84820ff7cf86abb627e6a814414f99b6a92b5c49d740c93a004fcbb75851d 51bd2ccb457f85e9f835ab50bab3eaaa907cf484aec8640f30caeb50c23fa18a +2530000 00000000000001fbb56c3b076a7f8c7bb0b5704b24bcc61910ad49e7d1a75194 bf7dbe5e12b77d7810c0a845ffe189819d7285ec33c95d89e2ffdf08d66f0eb1 00000000000002c3726035f9a1b1f47c060e5b95e15a0ce0d9bfff664daad301 +2532000 40b4ad5b1d036f348530f6af36d16dea1866f4c9ffafc6f3fbc758bac5dcabb5 e57662441893737200a2184e0ea6d5320e35285b49826ecc347bc820a4f3a8cc 0af0eb3050c58a7f801828ff3b1d16e4eff2b1dc51d5ec2555c4619b635e2556 +2534000 0000000000000152657f59b9dfc10822794115e10c34b86e4d1ebb0c0cce2eec a9557ae22fe739adc0abf2768bcd5eebe93fc858d6982472998d45032eb7c1c3 88ed63d403d2be91b5e0aeaff4d9f777bb6d487505c805b795365d4a9a69ec00 +2536000 0000000000000406b35fc32e36e74621c7c6121104d9940e97563527d8e4e51e ca6af88f6c412badf58cfc39621e2df373a44f3157b32c2ef9d126b101d7fced 7630624a98f57b691a362c4583d05712b4c2a47ab6acda219f8a607e9bc56a1c +2538000 c452034f0072875f5e5d8e09f66659dce3dec1c1a6ba64549abc31f6c5dd65f4 c86abbe21e6b7c533f2b8cd8c5f83eda17e66bea3f2257fd6cc99e54c0260506 21eaa5fa2157c0e1078a23b3f348f2474495b35d2ead2bb504a17cac61fa2a41 +2540000 5fb6b48f82ef61a3809194e8c0e90aeeead02fc30867d1b69f7084f3b01c6ced 78a6c0a446da71f43d7b417ea18114776f3ee338064b5a29ea88071e6102395c 2088b8583532fbed4e559bac973600c417f583d4a97acc6a600da510f9394b66 +2542000 7e18ceba2cc1590dd50ed375780df513349c08ce9f2fe048ddfd4bd4b711414d b806eb48acd3809becc36d623ceda04bd8673dae879f7edb0a64d8e098e0e0c4 c4a67c507e097eae368da8c9a449496744c4b0b8fae275a3f844a004ffaa8d36 +2544000 6950e6df532eb5b7249dfcd4fa5d3fa58d79cdd805e681450e793016717cb884 69252ec987620ccc69aaf0665953b25d6b1447e634355d076febae03cdfeaf13 20777e4430b82096e4d3ec961f3fdbef8ab2e38a8edc4e56be38ccce27560988 +2546000 7ae4b311645e70f3bbbf69f380aeee97dcc3d1d9daaf57218c2439b55d7c418a 64c3a1e7dffb9b870e11c908b0baa69f15192486b96034050e0303a2fba82883 859d143f03f55a6128a91ca5c40ee4101c232b93f8642a06d23637b0004562b0 +2548000 f678d80e52c943d1601670c8537c5e97ca07bae905abc050e69b371d310954d6 12ac52a74c19ccc24c620aa356f050d2a71df2f6c2354d3aa0b4aee7e48e4ba4 64a50a7fb01909ade7ba323268d28de6855b2e1ac686aaa4cbb1ec066a6865cb +2550000 67cbab6817a8f3d125e90bfebcda2360880796817be570aa06727953d62d3106 40d28120de4b8603eb4b4a611bb33bc8bfdabeb847b45b3bdc7cdf7e44703270 000000000000017221631fd79dec84c5654e42925446f6fb1afd58e5aec65891 +2552000 478c2a765f8bf6f3c7727acc5a9b8ab71b946641f3269afb434a996c47718129 8cfeb6b6d0126bae5b132d940eabfbff51a4854ec6bbe969a79e937dcf31c699 23cd9df2645b5bc655e5e9ca48f93ba326020b1e5cfdb5a38cb0523762974ab5 +2554000 43b24a0e51f61b77c2c33143cd770f4e894ae02e24892f375a39fe02538b02e7 9ac92357d70fbfe7d06e2fc9444ae991a299ed3328fbb6929b315b61ae4f6393 43c7c5b2a353090734008c11bcf17af751e8c18abfa78339469bf34f4ae31334 +2556000 9e5dd4403e6cf41f272b1af5ee29014cccc2086c1ab3241d4b95ab84c87bd165 140ea84056fb6b5f8f5e1d47369647d5f1f34f77f12fff2b721737b80978a1e6 00000000000001f2c41eb57e3f4b94b5d69442589e878c1fcf75ea4fd88b3432 +2558000 b23d6da4908587c0bc82fdf486225d1393886725dd690b4933ecebfdc9f12f97 fcc2ebef6dd7154ab8722e05d4b5e07220602788cc6378444e5f8ca7e6216325 000000000000000b90ac8328bbd00f5adf1db5f602db7b3e712f7cdd03bed08f +2560000 000000000000087893f3ce73e591390fd2d5992c1bec92b6d121892b2a71e15b f2bfb857e8a6d7cc979dcca4f82e13445f61ae495f44e226306d90cfc6b8e3d4 d0a16a9e5c37b69044daec54eebcc7285e1d50fc31d3d7c8f2d0230745f9f486 +2562000 d4ca46e5a138b5ff2d3ad0e4138c91f22a957c1c82e47e89dee0a0a21186b5c8 441b41ea840c990495855da2e8d4e2e6a3a5d344d2f4a4b08ec956c21e31aa54 8ec151f363777c25793f188307dce5deb0b331a1e4cefee52dd07ed4930c0bb2 +2564000 a45131ae00b08ee1b9d5c8d6d1fcc2803bdbc57946f8f4a5c365a86eed0ce52f 590ebd565501906ee447c29191416247498e927f0fad4262d7638ee3817468c3 00000000000002d1b471cda4b0db1c0a9ca426a54bfab463da1511ec6e53bd75 +2566000 2ea7c8f6b18453454ca0fb38b6bf8cdbadcda1f95f5c480b71aedef5644e6128 a71a8ed499559410dd20bc52d26343c2e2afa5fb39f5f86b42c51f95a98f0cb3 5971dcac774cef5acc715e896967857f8bd8f3f94bcf36c6ffaa89101b827c3e +2568000 e9ed03c7c2bc2e9b0c3b1c58037bac2cb4581c8686893c17c48adb91c35a68cd ccb9d316430d25dae811e340f98e21cc11a23ff6a239766491573cfff9390960 616f35cb92ea471dd50224ab99fba3526dddafff518684daac55d3e0b402b72c +2570000 0000000000000170e5928f3907a6f66671111da73776caeb147ea7762534b495 ad0e47257127e951765fde71d55b88bac8e154ce537b9c2166334702e5687925 000000000000020e642c0507ee9c828a6dc6e2a9f9b1f0e9f0ff522f7264fcb1 +2572000 000000000000006ee50f24bd56e57003206903e8fad2d49e9d20a84bb0982a53 eef9a76c8d5023c93742b89be0345e5ae8ac32c9f7645b911fd0d2a1fb5da381 0000000000000202e25ede1c3a2ae0334113f282a101fd424dc2072258f35f99 +2574000 06ccbf054efbb8be7e5d25916a1474792dc03c035c3d2704f241af40b5ad24a1 89452c8b83b18363941e9eabf547c5e85ef78b76d6bd572bd4fb2277030676d1 13bd4e4a748a3b2e4d00009420d85b0b59b1d65eb0d9e6f7341ab0662b415282 +2576000 ffacea06cb98adf2fd4e1b73dacbd1a41cb1c125e5e72eb1d6437c9699cdb7c2 ace8a2337522bc4a5d0f328bae512ee87f7d5a9e8b600d721f2bff253a0a1c96 00000000000000c752048405a37e29c0dc56feeeb26fe40ab432077e09c726a2 +2578000 5444780479522b1d609b1e5b086541e56378a18280f9a655f5fd8436f84262c3 fb762291d82d47f8fd8540e7a5ea4ffd96dc9120cf247c7e48b3f8627a85ae31 000000000000045b7fa5647ccd7e6b5906b75d6c566b4e5ec8e70ac0b1803a4a +2580000 00000000000002ff37c4e1bf95889d9985644c999e12018969c97318cc1b04de 3f821adb3fb5dd8090a190b93514b4ca87b807a7c7891362d970aa63646b3281 a9ae25c422aa7dcf8eb05eacb23098fb5adef93c554037433a07482bb484f0eb +2582000 53e9513e004a089687d6b92649ccd5fc93797592400a204457ab2a24fbf578b8 7a86212dfb7c03b5bd3a49e9b8818c1aae5a57f8ef1444813e7bed767d80e749 e0b5008761f8418e2d67f806be765087e90529dc47f123fa803b117f3776c408 +2584000 1bc19c3a70b21d9503cca586fb194e2e7a78e342358bb030ea710f3ec5529d68 6bdc419973252240a7654d328beb061797fd2bdbdfc1f6bfe9fb3cc8d88971a6 a57f0789a11fc9727541caa3c3dc2069ead6468b247128e22f0517838e9da915 +2586000 3d780f006116a82754cbdc48a9ed9fec6dfbd47cfac083a152117ff76459a419 09def4c7344cb46c5b831d41792cd46542eb32534666b183d2a96e76f04e845b f5442107faac601443ebc7a1458223f046104dfddc2b61ad68fa04c17d201274 +2588000 755e4e001c4a419c287442a0391dd68d7740974ad1e192077477aae051048b8c 052bb5e88923967c76c98e04eb7e74f7d77038f14ac8d6f02d3968146e3f7e42 cbb5f0aabf89806a0a4ab48248a2ff40e8e0d34026a4191cc4aee1143312f904 +2590000 737db2c929d3e34b11847ec4d1733554a07ca13f908c16b49d2dc49d4a0b7ada ddac7e5068c1d60c2efc43510436e530a5ec3ff72b1ddfa38631efe8e762e213 a0f0f3d5aaad59c2a767f6d0e859a81ac768bec1639afe8d468060eb91b60bd2 +2592000 00000000000002f6666617084b0e266f921522a68693f8fada745faa67cdd442 e7da7c2ea2ae023d6144838223adcad56a79b0d58aaca5067aa8686b67e17193 7a6c224454e398eeaf11eb2770bf282c3520b72d19cd71c432c2eee71bd8832c +2594000 00000000000000cc58595dd894e700fe5095271104d43a43db4a7a63f4b5c561 d71c3dccd4c9dc488a8ee8d6c41341381fb555cd115c7b524eefe2ae077b3102 ed17e5c02b615d351d01be3e6e9693686fe9d33ba6b711b908dbe953600892ff +2596000 238a776edd2864ad7678a768a6cf2cbbdbec665fd049654877f6aee846edf5d2 f273e0d87d3954ec51f320fe058100e53167a33dc1dc365f6ec356f14350e39c 7be364a1206b83fa91a2677548609d6e9d592fcaab4c87de601fe37f90c9b592 +2598000 3d9c95e74e570159b435f65eb2d9797964bc02315b504d01365297328f735045 08201f96306af5543d944839b19766e34c156c903c1cd0d282c26dbff1ac5d07 00000000000000f44369f4eb6dbc22644f208e0b67d44a4486759df2b197c70f +2600000 e4cd35742ba676ec33782cd022c66f96db2b93001de073c5fa07f76831517f65 311ac26eba7ce6003c532b0c8715fef22ef7b0b1d8c31b837d2f2b8bf455ba8f 950cd0449732334c2c03e7bb49074069e6e4cfa58242416ae10ae437d9708dd4 +2602000 bff2208dda3f59024e53917a1aaa8910e4ddbad1f78924a9e4571ceba913e3d4 bd8fa916b17cad400be0d7c1c58491c4a5192f231749340c4e5018493afe992b 93e05a51a28e89c7a25a54a352cfbc98e2085859000a1f3b70d29e54e2f1f3eb +2604000 00000000000005ec79de4731d857456824e2cca5fe47d816e9690669dfe6f4b3 c53c506699f74767c172a8bfdbbc06e78d46b995eb798bd574b08bf21a2a80d2 00000000000003a2e12aa9ab1e6ba8bbdaa9320e4a2aef8925699690905d4faa +2606000 000000000000042099a03f19e619e55640ef18ad3e0c153ffe5955a4529ff5f3 4888eca185d81b8103ee06880e3b9624a05d1395961746cae696fa19dd18db78 10a113b4060aa1502eef1e1356c18c9eccc485ae2f32e57696dc54443fb0349f +2608000 fbfb2ffe9e4a817ca2397fb6b1836957743531d52f503418e8bbe02e4f9fc445 7d84443e2a91d978bd05403b906ece2715eaaffa0caab5ca06cc86f061cca217 0421e13eef97386387421665aa72885e43e2f45d84276a2523a9c7b4a493ce29 +2610000 96e882a3542f8544d24a7b1a6d4124808391c07ccdde70378c5db7a72f0be66d d7dfb5cb6a6644840dbfb70d4215dbb76a271a5f3550c9b6f2194713e9469038 be4df4abba49369c1950176c1a20e8f9642c97d5d7c6872ebad79a15805635a2 +2612000 921610bd9d97a710932e90d1aebc21ce065d8cd72df35f4fb1774df38efba83b c3b91d5cb58fda9438b7160f56c8f23bdfaf0b07bb1ead1836ad5dac4cff6585 de261dd91207f2abfc3e33ee0053795b50c8385a172ced9cb78f688cf9648851 +2614000 de4c29909829e801f7d7cd65657eda970cf51a68891bdac48fe3a861a852236e 4363abea54c2b9bc283758257fc675a9ab87b24a1b9a3acdec2179b15b6450f3 dcbf7490cfe4901d4a1a3527a32c09f0f231c0c9ebff38fc995ae791b294e836 +2616000 382fd8a73e3a3588fcdae754e3d582777a53eab659f6c01babe25b4d55438e64 505311853a29dd008e875c2f575ee01fd950e393d2f5e5a83c903a583e37746d 0000000000000307bd40796d3599e5adede4d9977c1b00246e6be088337a26f7 +2618000 92311cd7ca5d49cda00ad2b1f45c5ac2481a912c89e72690d0898b5a0b224ec1 c7780a3b4d69271d5e74df5bd334357403ec4dbbc79c253d2ff712e7fb57be6f 1596dac84a9358975c6b09a78471cc45c4774dcb3ec9993c31a71d682de17717 +2620000 00000000000001f706f0588d48723f220576c92fe37b2253add2ffe70928e8e5 119d3b9d8617a9f318ac9e24c6147aac71bb27894a84b6a376f0aa21a43bad26 aa84cfcbd08b56778205ea880703e9960fa6f8d1cec5a022978675c14cf4a1ff +2622000 4ce67093b134678cfa3f978f4fd3b678d58c22bf52bc265d971fc2e715fa3b69 da57b60988ddeb7a2c4702cf2a9a78916c95772be00f2173986e121ebafed716 495bf01f61e6ebf0be36d7efa1513b6bf3507bec881bf3d4c7e07f0732b6d663 +2624000 00000000000003430cba4d6b927d844c476688fb5cded8c5fd6d5acc86fa7c7a c7335d88a3de3dfecb95cfe76f15caaf73298d46de1aa9a7c7b3fdec5fe9a032 014590870165549991ea4cd9ae9ca0f264d428bac56f7eb8bcf78a57f7e8dbd7 +2626000 70d7eba195d57e52111a5bddf01f5018b2833d9dc40b1babf50e8f5e43e951b7 ed819937aac1cbdad51abf53959d32230e54e0f5befe075c5220779b1b5678f9 d98fed3b4295eaf485f2afeffb946a0b0dd4c24377e3d4a7c3f402b86ae79c99 +2628000 830df802e526e3b3e953a91bd2cd89bc056f2ac3277079e2d986eaf6781638f3 d099541f929a44e79b4b96137003a83364f8a9502c54f132990fad5afc7ae63f 3c3bac827b95eccc114b517c9e35bd041d91c721cd972c888096501c982c11e3 +2630000 c07d98cc3ec73efb8c7297583f1bd8d0f4602d1bbe6bd2ea8e9f9c24d59a993a 13babf3610074806fb48b8bbb238cb9026938546cb684d19b581105e3b9462f1 0000000000000289a65c479d3763d8a0258fcc6a212d1bed7e40f7e3ceb91c0a +2632000 b4bca7327fc48137025fc858a8bee60d1fd237c9409553388d1817858dc55b55 fabcabbbd3054a28faea1212c38da16994fc89854acdbc761038a7c2ad2e463f 42209c2eafd5aa54d401c0f15c0ba5ee421b3dff796fa4fe4d10e8aaba53212d +2634000 0000000000000209a0bd224394530b7125ca882eadca7406aa0a3e2e20f0ca7a 37233f1c5d5aea9325427cb83f5d0dd44e273d6b34abdcb0b13956e73a631eb7 333b291570f87f16a56a7714c14aa53955a565308939181e0e5c5163929df727 +2636000 91aba86f03c5c3b849dc4590593e36fdb797b94589859a2342443b0cb434d405 87fa4882bcd4967dcf80377f174a95d06b1c280686d2113f280b90588fdb6114 000000000000011798241058c375c6da814236a6687ee29a968736c0d759a8f9 +2638000 017e01e7f4c4c6018760f91263d771789817c0e85311d634ec3ec504d97da747 543e5c2c8bcd67a58593ff22ee07ba57bde65508af793c74bff6c98f19cf023d cad12dc4345315f037733d4f6535ed71dff05eb41b8690d4a1cb455915017107 +2640000 00feb5d17a727114a883c702cfea0956ba168a16eb57bc141c9c02c97d0b2a5e 0cbc8c158dc02e4bdb9c3daf29b505f1538b53eeee1b3d15fa8883d78bf9584b fd3bbcc53178ef6e7c6fdfb37fe511646ecda19c1e6d970d4c52ed820ff585b7 +2642000 5daffb0d7bcf9c05ee111a127258e3551ad2eeb933c4463d9098688474bf53af e2ad7599a5ecb5664e97b8345237afdde42503001a2170c2a29faf1f0af92451 f1ae1f6aeb88181da0844f16c22a6f0db66ce7c45ae19449fe42aa990039aa3b +2644000 00000000000000798ccd561a114e42b15f02cd0ce2c8bd3f79b9b1dd227a3e98 8591fe0c47620f1d4990b3a546826fd7833a7fd5882a63cea6ad052b1b3d5fd4 146cf888acabc4686dd504b32005809f88a016e250d35d1a83f529cb03f02ee7 +2646000 f85fe5c18f673a223d865ff2000c906777c62ea012f5d77716899bb0bcdbf63f af77fcd2ed4ea254060072595675737052c888aef3c359a36129d82f79d2784d 08ebacaddba0ff3efb9c923d3592cdf455185896bd41ea0874d5c82a02a9efb8 +2648000 5e21259735f6fa67795f3e6bc44d0c5c9aa03e7993269ac5398ecfbdeb58ffff fc74f5cedcbaa4fa57fc49d0d2dd9ec223b678325c16d66254d4460b0f4c510a 00000000000002ccb75bb3011ccbee0d16a7a0471a35fa6ccc9bff3c1499ee00 +2650000 b0c380fd6253bd2a42a5652e027fd8a39d9bf68c1fd3da1e67cb4a132977ffa8 5343f8ec3d8b97b551859da20ff0a34beba07ee3eddc599c3228927011bd3422 14836f4f028406e04021237a8763811fb9162ba097e164f81af3b72b96edf295 +2652000 534f5245485fb89f1399b4b499fb9daa0354a93a6fb98b175c10aa7768e82a89 2f5c69158153f069272c5ab0262c023d675bc32c6bb86dad1716acc205107e9a 3a7c6471c86a80485e5e8f3ea71d382849db8fccb2110229680e4f08ce59875a +2654000 70522a192ebb306290b7df9334c2845d8eace639148285ded4d125def8f50949 8a8a96ce8e95d03f8a59d2fbb9dc75e8eec6c8411a61991848f9672d036a8941 c4cfc25f29f5270288c997c6d863f4311b643104d1997e12da4f77f84a2803fe +2656000 00000000000004b3b17dd7528c53c41d1be36e7eaa748f676f9f6c2dbade0c92 317a304f7154aa47ede90c3fed376e2fffaed3adf865d165fc5f5851ce0ac1eb aacf28ea2e8efa4f2fdcab644d2976a9a30f6651043798926a1f35dea19683cd +2658000 00000000000003a924a45ae0c4ecf741d7bee07acea9ad8888b8f8d4ee20e2c0 fb05ac0a7806346213c38a6f5aad7a4860dbdced7da2767310f2ac30e8f3b967 31bf864e562336885a746f85d17978533b48f0c4bb9dbd54f2bf38614d27dc10 +2660000 de5677a1ef57bac917baea8e7ad05a8ee58d6533d302868c8bad2558da18d0ca fc7e72575241fab7d472dbf7ebd4e71c8a985e08a8b3228eef3252c2ce888d4a 9163f7f531625a02ff4da94a24ef2c6a0b77716c340c9c619df6d673815ed009 +2662000 00000000000003f1d397fd29cedb0848dd0169da5689012dcb566fcbbcd7bc81 d52956b9df17007184bf72c0151288827a85fa9e9f19ef228369a499265d1772 00000000000002ddd40204470d40aeb23eac20a214756d5dd8ebd4e98bc79c14 +2664000 5561778ada6dc344046e71b797a16d3a8ff999ad7eb2dee6eb60c94a3826a6f9 51141bdae2ce88326b3be4253a99b00dcffc796ad14f9f28efd083475deb127b a6516de19960c432192801f44ad25b29e790ea35139f709e15cda5c5a2f69e5e +2666000 385a644bfce0461c68e3b863778a7d2e313920136b5ebbeb3d987a9f49af0f19 344597d13e62d35318ff763361cc58392a0c93cd2267c0026fd7bdec897ccdd2 fbe9d2569575b97f2bb2f5ba95c2508dd88bef54ecd6c378c936f47d619df92e +2668000 4154478ead30ca76b1601ca82d1f669ff43aff50f06c07fe12fa3e8607fe0fae 57ee4454e5842b8e63f1bd9fefa96e7f9b3bf8e8efaa6f051142d4930b4bda2f a196a66393a18fac61d52fb62ace57b2e6cb7449861f22a0a7b8b6ad45cf458f +2670000 7f96c6c9ae763a61425467fb3e6fdb80bafe15b8a337fdeb5c8f699748490845 3c41603007046baa0d3c406b436e2a1ecebadb3629aa94f258b68d2992a827af 7af15322b2796bc614af4775833b400e152596b60f53fd848dbc6ab4da9b7beb +2672000 264191dff75ded477bbf123d27a1dadf906d73b1f98d6d08c24d7a6038d3d07e 5cb9c5ade17579d6e94ea2396a88d70821aab07e582eabed3586a0051be115d2 731516f504c56f53fbf6b3a639e33a3ce8f4828e191d62ce6663fe7245d95ec7 +2674000 76c6fa214b218f779e22635253903ec89cb64775a97fe0fd6fb5f02d96196f55 4bbc9bce2ee44a238ba02db142400e2263bd9cc7333c80e696bc154ba064836b 265e93354f1e98779252b61cfc1cf49776b2997d5cc8e4a34b8e67f7573b3987 +2676000 08ebf5799b4c087ad53c0cc7ccc7e7f130296112c32b3a0d92f1feb889381f8f dcba55054ac10bca96adabbb45d8b41148aa3a7d3b7ce9d66578672fc2a76389 f4b62d9729d1ba4e098a3ee1f442745eb38221ec4ea281f639cb845ddbab875c +2678000 f19da3c150ec333fc19164b2d571ea9119d5479781dc76063d9968b32202c911 c8a7d53b5a34873c673b6f3bf5c0b1fb100e37303fce8615bd9f1665dda95e75 000000000000038d59f35f6f343f5a426479a541a14c864dd6ca2beb6ff2d14e +2680000 00000000000000f552b698222c19b28b9c8aebdaf776aaad8ad3bdf83694b22f 39d1f0ea9c733ec16be27cfffdc543736563addecffe0a36c90b3a131cfd3f4d 000000000000026aad941e8d7db20f7b9c6627c9b8ee1b25377c68986cc0a81c +2682000 571ed956bcca241f0639112c21694723862625c41dfb14f28e082d16ef19521d ada956ad8c19cb3935593ed00a837b69facd948f05baf57238aad632f3191cbe 6eaff95dd74c4df86e2a95d7178ec8d68494850fd5208f9ad1e934c862395b64 +2684000 24e9235dc83795a68e3ad0daacef5f49dc90512d8820eb8c1ba0ec2a71a34d91 465213c8e45d23e9ee96774b1e31a1b4e753636293b0a27ca40507b16017e77b cc181794cdda3b235d71e6f8eef955d08c0a336d8c67dc192359652d92b5b23b +2686000 dd1060737705ab8bacb362c89f5681d2f8e3d8668a7a638b3239b80ab4f3db94 bb521ad237cd4ac863e10ccf6efac139aeee9718af20491831b5875876cd5383 e951acede0fcddaa6fd5a283388efa783a3b9b3a34049137a7502d49cf9b3bff +2688000 36384a03e32f7d7fffa222d7c292b7fd6ddad0928c8fb0029e74c6d28ffd1e89 efb9d75232ffd0d24efc89f1e845d8059cbb8245c4287e09f1a1fd5929ac89f6 1636118a6a5ef31eec6f2cb4385ebf146de6f4f11010e0d08963d3dc2d16ea90 +2690000 663afeab680c4cab4489cf147e9eabba90b0668189ca4a3ed41542034fcbc11c 5f0fbfa04c87cad38652e2a65d37ef9a0ef9ad3a5aeee81d1d91f5ca287d9467 03bbec3c4026b5f13a0b799e3a162a46820aad89fb783a0bc15dfa4565cc1c4e +2692000 7c2ec6172cd2a11c853dc54cf423b69eb3fd1871e9715f936b0ee27104541264 c34ae733ff4b22a8c1b745ad3d78811a2171aa320dc173904a9788119f9f0a69 c2bb7c9bd6f1b664904406b5ccb04e3fec16f081ba7f683e6d775e5aa8fdf578 +2694000 00000000000001f0af808da508e57986698df79dee2706ce4b7b779bc860acec 5f2abe429d82f854ff5c62f26b627e92312ca31963fea5d85d5c25cfb12bf470 086b1f4ff484de4666cc0dea111e4fe0d4d2fa7e7381de1b8c93fd902f60b131 +2696000 f25aa7ddaf7517d00a4882e81d1b365898c8b95dfb5296b0be38774aac879998 c39d6828a92b86bee904d68794e130c67d649f4796b4ecaa8a3175bd11699305 67722bfb450fd44f636b9e57517ee50040b94ecede9db795c3ef6a7e99af22a5 +2698000 80c947bb975fa37ad0c10c5fd3d837db8e5222944264f610f7ae871281939b4f ec700c07d6259913de09fc5b0f0f4b9b31aefe021395f1c4f430efbd5dc8d20a 00000000000001b2601a04dfffe4686232e0d025cccb89e29901386ef2185c8e +2700000 b6f5ad74dc4d013f9d2729341cd559d2141352aa25566b7f0951553487455a1c 65b731efbc43106c7d9a20a54f630394bef1aef60d1eac81e07cd22f80d291b5 00000000000000a82de0bcbea92c11e03b6321fb97403d67b16161e09b700dca +2702000 00000000000000edecc85ea93e2c72cb09366ffed545be09f2bb07e13dd2be35 e26584f2d370af8acedb9c52c2b3dc999ce515aea6de1c9cd80ce35266ba8c8e b1114c050721e67fab1c74dbe674c5dec2eed29222dd7f2b3c38eea325808d7e +2704000 9750698c7cbf782b86af3aabf68dc0fae936866870dfdc2d5614678d8c16699e 9ff650f3326e2f7615d772003e00b183db0cad46557b079ce18928030b1b279c 3b49fd93199cde7c4c5735cce5c852273a110ce825e4aa65804f3e719fc1986e +2706000 f84c46e7216b1d8e96056f1bbd21913bcc7f6f1c39899ee90b18fab31ed2acc2 8f1a65c8f0cffc00f552d4e5b0c926f953e8890b7fe6ad29395b419fd959787a ad24f093c8047fa93e857c5b99438d7c3cb5b9278c9cac05e116299940a66645 +2708000 71bb97f3cc9adf72aec5d03a532a947069418fe1860198fd0361ceda1f019b33 51083c496f15d37817ad0a61d63407c93016da3f678638f442eda7097b75f97b b8e0f509b768ab62464055285435ed65e90c091b2ad0b5be803d0df6cdacf4d1 +2710000 ef789c33b6186eafa76cdf2583f83bed160bd148ad1cd0aba3120f8034af6556 103d29673dad6250035a0207a12b733cdedf0242c1c3952571352ce1058c0819 ff4e427b2b891b479df0b89c9c230f1204aca6ad8ded281361945abb561f8b44 +2712000 7127e25ada40c2987efc3933804ff844c8615a169fda7bb3e3105c903056d916 6a155b9ae72666bd98c46c842b7aa66f61fefaae424df598830071c29958d9eb 000000000000004e47e714f0916043e5ea99e8d2900ac6048be9ee6a35c09477 +2714000 00000000000001eecc22f766d62b5c6e47b875e7062a4e17eec712154c547f54 e5d32ccf41e9b0255b9228e839d847b765277d839813f1e7bac39531d6255e1c ca22fa7122e4204f2bfdbfb88f6e62e51b3c4f4eb302c8f900270e084009c3af +2716000 8ee2073aa21ee7762831a639a8d37aeff268e2f656ac521a7a54a49879768ca3 0e525da9e744a9fb4b4d7e6f60d406b30da23a5d0533761af413de7fe887778c 8cad390821bbb65f7dc3d11cdbbd9abab0858a3adf05d705e3bf6fb4b2cebcee +2718000 0675a6ad4926342c03feab1c80b70081401f5ba5774bef52f7dd56b64cc9df26 c2c3843f82266d1610a2eef07899b89c4835ff3ba3486d79cdba29d523613b7f ef1db8e70a7ef75b58949da1e090c46bf814d34c47552dd659e62d0af46cde03 +2720000 ff1c0816e73abb133ebcae51c7cb11d95099ca0cee108556221ac62199a30371 d970457c2a2c7e1a713b440b639ffbdf62121b581d1f0a12adbd9ca06dd5c8bf c97ad2bc348669892eb1cbade0a349b345ae575fba515a2bdcd9e502f58a0bd2 +2722000 f4961e42a43d3a32c54c7f43105f0351e848bdc6280ffe0dd870bdfe293cd157 44aaacda523066806f991c150c3c52f1776463f3e5fca84a10b8611642931923 86c31ed20bca582955a6db0b61697a5771421d5dbc009db787a6fa0d9ca28861 +2724000 5e68d794a943026c130a55307e4237d7d2d03bc95538bb21a52ce805082fb21d 299044fe09f17e52132c5b3ff163f91a8c901f3edc03a4c522cf6839c2ac58d0 d692681db19113b7d404f3f4bfe38180af7c6b01ff1bd63057bd8f7ade2337c3 +2726000 d4c8030a29041ec8a0c1abb8eab7e4a30ff7518adfbfc348e5a5f9597f0e575c cbdcb783b1244371cb6239247a4b4016849e1a211e1bc733a9b9774a8de828d7 6d797ec5527c8df2e34d90df6a7a58bdbd6ff4ac707f7d40e190c5b91167b92d +2728000 46fe7ae9560faa760c9700a786ec65351c18df82783f0e8b8a0101ff3eac51e5 ff48677b4f3fc8f253a2125b5d69ff55f02074080663bb69023ffcc003b59d79 e7d555c267163fe4deea04692783530f823a2df297ea53bc352937256ad0a726 +2730000 000000000000001026aa829ad7d96a5d2239b0c6e91178d9c30050da47af6c7c 2fcff24c450258e5317ebc15a97581df23ce0d9cc25f62ee39057fb6ee2d893a 3f354d530c43432b1665bc320370eead4fc81d4bbd150d1856e5d37e53521d9f +2732000 aa8a4b3fc3c507b4fd0c588fd8dd80d29abac60a945e2571156f02ed461f30b3 8e0fe4b153c047ce88fbfdcf84eb0ef417012b16929347588e1ac74ad1fc8e28 00000000000000a24e28d8a86a3db80e5613d93bc7a21ddaa61feb26a1ccbb00 +2734000 12d831fdce4735d5c5aa57e0806ed4d5e8329e9b1f256c32c971a7b5b46cd42c f2c9d3269c54c4192827c3494e6297fd64e938c38dfbc54c6b9784ca506eac80 cc041f7208ab838a7d088b870c3ad67db29721c171d3b275fd21fca79369200c +2736000 0000000000000022b68c0f179aa03f75727e2838a9ac0aac10a1dd02c7ff31bd c1a6395e2047f195f6f8136a4d0be1d2f4fa7e2f1f4d3cea145260ada85927a9 a0034bdb9050be689a8f865d0d0f837c89b4e8f668169fd0fe379494510c4901 +2738000 20f4b81d7dbcc81c8ea4ba22588dd9cbab4e9aadc00ea9f1f3eb41179b0c9958 2e2b0028effa8153b1c95202ee655ef69ce87d257dfafd145036a1dd00a3ead3 6b0d69cacf748d5743c0755875863146b5cf7c8ca2507fc694f3f0b7110f87b7 +2740000 00000000000000ac05f512d8473f49279b0d250759b816d24e79274c2fb4290e b8a087176a41fca0203fd0940374951ba6cadbc699478befaa6db998dc3cc914 6b11cc101b69e18fe7b7a576bb397e12954c4a8625104963478a7978b30ea9c4 +2742000 aef0d2ae505ddc6234f4976b3c723d4fff8e0a4d952cb38659bfca9121839de7 c61e33d6b2e5d5319691731980d3a6736beacdbd883b8e0d8b786e6f7d703d52 000000000000018c2b0808a279eab975830575edaa8a6491956bf849151fbf76 +2744000 a5c259e89429a7cfaa4d1aec04467e592041f643991739a6fb60a47807f3e7dc c2c9a298eccd4a25fd58d49f1a8fe9aec0d5af4ec2ddba011539462950aeebef cd35050b2efed21720d3e569150a95603ce26faa62c035f4642854191008c484 +2746000 0000000000000173463abfc6d42d89b4723ac467e26f1985392537326969307a 330dce398db72746c577d3735dbabe39b049ab9a5ba1aef258c3c97be052bbae 7c9bc1eb250462de79c7a3cdf18ec0390627c570c7cefb956d925dca35316e55 +2748000 4e549dae26a2c1993c4f9a9ed17d59dd3a1ea7124238b3c50dbb814dfa1d3698 4e8890cdecae1ad2ea99f90de78bc627f0dbc3247f6af82cb4da1d4f00fcd01a b0012510bd5c42db2e353641e552692d7fefae9588a02a09d5378991b5a0c632 +2750000 c362bd2b66b3ce34981404b456301ab75412b79f22600b17709c278ffc261b3f ffa39427b54f78210b8effa095413e8d4083345b1058ffd147312dd9d1baa039 945f5f204b5ccb106f4847987036a544ae498c8985be8cef729eb0dd7a3d0d7a +2752000 90494181147280b0bf55a9fde8fdc4a17d62e52c76c7dd7938e4ad2894ff26b3 3d3ec218783f0ded2c8f41cab02eac99c727582daa67a2c99528c9028a1eb25f 0000000000000131d04cd254a6d8bcefbd0484c9eab18e1eab71628478ac8c46 +2754000 64150ef29307279d7ed4e3caa25bae6293650d738d4de18ec2ee88ad3b026bd9 bd0c89d95d9953cd0d3949a5475fcea438b8605278f3b50fb61a92e4f0ea5ed1 000000000000016a6345ad29f81b17b6e6c951717b96c944412e62ee1242d99d +2756000 531a52b1a009f1fb1f2c73a6cc03f958b07d97daa95a194892cef69ace6a569c 8bdbf2bdc20064c5bc4962e1b4f78acd4b9060143f96b7d012ead4de146f87f8 7820673e16540e3d958c255fe7c3ec606b4bc9ab31dd2a15daa7b0ae3800fe1e +2758000 4827b4dd0b5bce496ce49ad73f79db38796efa7a9921a67e924d99f2b6f00dd7 1bdfe558c5afa6fd6d6d2265b7a0c023b0d5cd3cffa1b7c66ed72f7a18c57d96 2afe36a2075110a52a99cbb1a24aff4fae5567babb584621f5cce44aa97abc22 +2760000 fd30ce2c37c1c4e4ba1b20b275f51853878f1eb0a2b4fd97bc0032c03d9fdb60 18c24a2f9c29eff6c7f5a7e3c88a56016aaddebb9694eee974589dc5d9c2e245 054cba899e9313d0b2adfd401a96245da3e35d43832191edb4df0a43bf42be16 +2762000 000000000000011b021a94d3293ea2245e8467e0fa8ec2473337d49752348d05 293e96928d604bcd15684791e15509d311f1cfa4cee769a9008f8271f512d1d3 6c57edbc269e4a7095322ef479ec5b883866f914458ad9f0950db45d27b9aa46 +2764000 e5662587aa0400fc3621ba88a17430303723e857a8a108798a5d8778e3a3e052 280ccf9d135b2c18c453084f21e4fae6da67cf91aadd9249a6fec1c5a93508e0 fe946cc6aea9cbad42a3e5f7f378b0c3962bfba750c232f0aa34a29b66f3f792 +2766000 ae4e90630d65c7cceeec3c67bf76b110f49c73516520ccb63e79e99df9dc5621 11e6806ffbf843fd556b91e04e1b72c6a5fca0c499c46bda05d4f08e0f9a421d 7d31e511231c74d033ce3ffad754a5ca42811727739a8261182ae4e0bd296857 +2768000 7b78a59a2b9c8249bbb45388ac949182f98a719c871e4d52af0deef665a6f614 d2ed6842185e30e9b9e4af13e9ed389731a43eba3bd201b7293ffaa394bac08c 8237872a0916c7eb76b436fb78ee3b929b7ad9e51f9954cd0895a48bae5945f6 +2770000 5cd90e56b663c84613f13fb9cf1d88ef681dd19b62596bb63889c740d856ee8a dde2a7f962be12c6e4a242ed33dc59ab1c6393ee4cab36f1dcd54abaac58aab3 ac4a185ac98bbacfddfd6ac8f35288b93524d5e32d882b8ddd529e019411f254 +2772000 dc9e101fe7417bb7ca04cf6a696f9d2f98b85d939b8f8d791a4b266f463c1eca ed7f7f9d73f3cc3c8f2029f6449fa8e5bb29234714415cf7d45eaaf9837a74a2 a006894298f791d3950dda75224c3e690784b142aad626eed3d50ef80d7b0475 +2774000 00000000000000a989005fefa90c4a88c564d01a19d7a3aed6364c768ecef74a 99a96feeb487af0562419ac7c7db06ce83875c7470a70ba799ce304808a10473 44c8ee612584dfe6515ed773f0d30d48623778d43216dcb0cb26890ee62a2770 +2776000 68c7ed03a298062bafad9c436a3876bb3bbd1ac1fbea48768f4a014d0b3891da ba9acd561090ca38e9f33766150f0a9b41d52c50dda60042c45795517ac57d34 9fe862caf23d7a4aa4408ff403e4ca38c8f298c8576d714534d44635d122f890 +2778000 20631c51ec415899d2e7a11455fa11ab39a8621a8403194be596c6b5f29187fd b712fbfac6466005e1348b8f509acf7eefa6592b19f7d1d24c3ed89d6044178b 70d486cfb5a500d07163a977bbcd070ea15418cbb6a718d25964b6da2e04d238 +2780000 00000000000001b7ce36d8afe9209b1dddbb598aca199fdec7c531c25a7d0e44 875d9229d7d3a2b9abcc08aa000ca7a34c11a96a607311551cd6af15d4762117 0000000000000123fa8d29bfac77f84c1e17c8fa1cda77d7dd87743913518263 +2782000 d10cbc25e6ae6d80408a01ff8e27f79a0cef1a6aa9fa27aa128bfc73f814cfc7 cc92bbcbb1d44c04c76b58b1b670fa09c1dcd1f3c7a243a4ebb1035341f9daf7 f2a599122832ac321818d73870b4bec98480fc0eb4c2911c2d1d6658dd72d616 +2784000 0c1edb2c9a8b5f8d31b01f5f9ad02f37570158965e1aa84a6d2bd453ccfe9843 38d7937ca9b6150ebd20c5daa8b8179503aff841937d2c36b2dfc66a6f08a2ad 0000000000000253e4de16b10229163e0d2ee79628aeebe24f7d2a9d190ee04a +2786000 22b0d75f615af47b50151ac1611a20c02390c9baa6612529d57cbf8b41dba9f0 924bbabcf4ad871cb8a82176026708b413deeccf97f2d102d2f18af1423da871 2786424f3535bbcb32b637d1e5b574d1912f41af270794117ecd6cf4f378656c +2788000 00000000000001013cde86cff899c2d626f1aa0902432a60b80b5fc63d8a9d7f 24a7a70d9d41396f3feb87e663a05ea01b66d5fbc91f8ee75454f9ca284de232 00000000000001388081b6e5f8479575cb323388e084297e50de3897552d398f +2790000 e9c6d12824d43db3e1167ae39c2896421dc44cf897b98bd74896a336ef3787cb 071b5e14a1c48e2dd868461f2d82c12d3bb7eecfcda9a583f984c38238661e9f 00000000000002214dc4ff371e2048b6581e30a169423c4745dd1abb433e97c7 +2792000 000000000000016dc34f520b9bc56f86833b09f1cfb69bcfd4ae648ca5a7a610 5b92d5eebadc8dec9f968ada8a5051a5b335ff2b0c7c52e86cb4ab5a028fe527 31c587735d677ba4e6b416c37990b23dd62cd1246a3166037a60425d40e9ae06 +2794000 a74b6c44a0d4e29732810a7f38570de04f58b8ef34cb213d0a11f58c3d0ff559 2629e379fbdf12ad6eb21ae18044a87db17bc73234a2acc1677d712485068f37 cb6fe7c4174e4b7e4049a4a6d68029e9db30c4643091748b3ffab28c53160599 +2796000 00000000000002967fc03af6ccee2958421da825496a7ddf6039f9d7b0d6dcfe adaaa0677a6b6f5ca278de2744b6ae3c864c5cb847a85bcb4c43ee2c2c1494db 6aa6a0de392bd499fb8bc3ca665b88271ace059586b9cfad37fdfce3ba62b11d +2798000 e811d8b601443c8329f2a065bcee56dd6fb154fd5d10d9a5524572237b05aff7 b2e8ae5dee335c8ba4d21048872fc0a49ca0012e69da464d2636f83f9bb2ce00 1319e11a6b7db003dfc38b8660f76178a21b3bada87dd6355747fa0c327b99ee +2800000 99b08a2bb086a355af00782dffc2a94f56e225426426b3748063e4c703444a45 a7ac2ac758081f02d572f3b1eb6920842ab75a6a1acf22f99250f2e663401aa0 6589a4350abc7b6b156a67bf97af65e09cf379bb87f466362b6bbe9fc9275d67 +2802000 428b5dfb17b9b6c3f39dd961ad12f8c5e3c0a7a5055200735183192a880fef59 a8e7bde0be3d022afa989991d3966b596dd4160dfddc3ae57b1c448b85fabd65 81980aa7b26fde280e8cb24c0d3ce1b1d66dd4c495c95e5a84d7af6d8618aa63 +2804000 f283d033a40c265dff683f68dc24052e3c7084dce97f59478d14d1f05e91d4ed 436e8a7b5b21d6f14b07c415ca33324a09a672d256010d6554b169333f446ced 90762b7288fbd5473b6837b23bdba3a7ef5eb78dd6298e5a0eaaaba9b6cb50c1 +2806000 2e3f31ef4f0eae370b66444fdb0832865ff7a72162065d5ff2a58236c49f57bc 95270e9ffcea924822703978b058bcfb11b5cfc480feb2b5bce8e51482bdd86f b9fe71665e39c5f0d07dcf24da2ee6d21141909c57e6170df17357a9d7b63028 +2808000 cf2f5cdb3049da505dc4e0d7dd6d5a97a5eccf26a8c185ba2e83755dd3180255 426a8160035e1c6b6410775e18be29cabd4c6280f99341f6b505b36101b922ee 0000000000000079683d7e16e04774fac459b6288a6029d0fda6d1bf57f449ee +2810000 be4a04dabb109b1dbf3bdcd2711b784e52e022f546e420bb1225b848e6741c71 3883d3b3a1681b8b14a26116046ef37835041b41a6ceb5b8cada836c821ab9c5 769a3d1e688cfe04ce4c8d8196a2e4d3e9264801976dfc1f182ed41df82fc149 +2812000 abcda8ec2b316558631cb7efb6753c2af567debc2139798f9e80b15971b03ccb 2de8ea4775d39dde123db50c600f0583e6c600a5719f17bd5a6d276df7b31312 56cf3ff453689eb922027d9d2990844b1f84a4c8049f4e7a431e54c141cfc544 +2814000 000000000000012a24f1ce197ca42a0d92cde508965041da3b844c6b01380012 ad50258bee491354fd8ab3b98ab08aadca97488af8105901664628e72ed8d917 1f03123f438c545998f8d6d34bf4d9b923b6607786cbfd37ea3bbab573fe7f40 +2816000 f2b895d7fb9f61702fea9ad984abde83e8dd952014c0c552c94e0ae846528b64 07bfbfee78c1a56ec63d70f694835db0f0caa5bc4a602948e0bfa2e1757b4337 038e35d200c5d0b9a5611db296a80270f805aefbe2c8aec2516017152284fb39 +2818000 2a7737b213e6635c7f29c8ab0bea1bb09aece0a9d7eb41dcd91514e1559c6714 c9d8c4ecabc9f8c58996c5619e51c75f401648f3fb43651477d0e10a6f5e6c3a 89ea3a14e3adfab27b98fdf748dd8e529f61ba7bce669738067be3b94db13cdb +2820000 610c7f533d18c65540fa0d56836102c90379e9ba8204f6fa20f0e7788b61c1b7 a5b1aadb9cad49f4ca1cb863182e47c7f300d142a7b0a9e83762b47f2285eb54 fa55bccb58d71a1eec2ea9fc4581ddd3e024d9fd02ada15e320043a3ae0745d1 +2822000 000000000000001f68a5d613c6fd026ad9727159d49fe5b1f9d060932ea6855b cea1f30ae335387bcacf234fba43afb4284f4160d058e544813ee2197766d0d4 000000000000009f0291bd1e9777612b4e562b1f8f26ab724adfda90bbd17330 +2824000 00000000000002771af49315ab95e9e213e766ce96adaa3e02b04d6a17dad167 c3731ae27d9de6b43accbcb67760a5f8a407b7c22341bce2d354914584acdc1a 18dadc72870f40e89ec9b7559d7e38f9df5c02effb26b71d6467bf19dbfd0ffb +2826000 fd776504b993711ebe1dbb28a73f3bfdc835bc70b773526dcfdfdd985092fd2d ac8685ae690b5c14e125106e3e0bb870cf84e5946a63b356358746818eb4d29a 047d03537a774580019fc3fc98cfdd7b863b1c466118a52a34b9a96223be138d +2828000 0b1ed21644d6125f07dbc924820b085a25d9fbaf4015019afef86527832e0909 13c7dd7f09e06215e2a0a7464336326633d95519b399c84741fa7edabb8d8174 8ca8540f916b20964d22d920f1324c71ad2724498603a0d53f404e44503bda4a +2830000 0000000000000272cca7ffb792a99c302ca371c6b9f47faa43f5df07cc4af5d0 be5f88927798b05a30924f6a88ac01669d29910fb7dccc8f2e2459324261efb1 00000000000000d7fea50209af09ec0a1fe6b6a63820dce402f79df88dcd06b9 +2832000 f4eef9597b736a461c58487e6c731a17bd470c3296495545068d02691559bc06 6dff8e1df717665583036d41c7e903cd161408d674085f9c815456b7751e884b 000000000000021e94cb5dfdd279fb28736c7fabf079d62e95f0da1f82aaeb3e +2834000 2515d5fb9efa2f07164e32ec0b3e096e03099a65fd2a6e56c2abb5acda16fde5 910d866899d0ee15c95e7be18719e6cf35f81b4629a1b37e000af5f06c0a3ec8 81597ec681d91aaa4d785e1f4c3ebf07daad0424e1b466cd1aebb3498d877398 +2836000 e07d7a0dda6bb4ef301bf38acbb42029d4923cd7d26846f64c6644775ef403a7 16953176147364fe849f5aefb59d527c7d0020ba0aedfbc52942f9500ae9c586 0e75374d553d569e214032452d0e0f6bae956ca26510ce597b5f0917aee70c3a +2838000 807cc61a5a807364c15fb2de2091b7fbfc2a1fae626085e0411b36a0995bcabf 488a16e2b545542630d24d4350cef963851f3dd03bce73802c5806237f5a4061 62a0dcf847b8486b83b9a0fc41f9a6135e925586278ef8b340818e54838ac296 +2840000 a2a8140abc1fdd6e123bafa0ea17342f054161819332b256169e848154d7f5b1 4939eb5b41f949af9483046949db6458506f111be7c8c85d7cf2651119146f78 0000000000000068033a1974c5487ee804fa31e3518fadb9fd323713988d2178 +2842000 cfb8e3098793eaaba254387d81df49e981629063146d6047be4d52432ed2a9fd d96af11fcb56635e880a28d175b1905f207ecbb24cf6b92c4d7d74a4cd2526c6 000000000000001fc684901acc83e84f66d213e868d69834fd475a8a453a3d40 +2844000 00000000000001f309bbe2e857228d44c9ccecf80eacfe527108047cd2a0d10e 61d03ca8611b4496901941f4af6adbd9a8fd676c8383f9ce90f4bdd57c41d05c 4e22abb5236c46865a2178a62c4d09a3db79d29822200d0dcdf73b231ad0ef16 +2846000 975bf2b9df83a65617da434da7511468f9351f494d4517ea496fccbfb2ccec1e 247fb4674dbff25b1e45e539e104a0b98821f8d2a6380f8ac19f8eb108975186 fc9977f7cb7e0684d3cec633712c7dee83cdebcea9069071ac9bcf8904db166b +2848000 d56ba65a659cd7b5f0f37ceec4cbf69c652a7a20a91b0eb9cb0815844cea18d3 d125c92e7c62683c2ed578334cd2b98c9d9f301c2ad0bd9a297a33e25a46bfca ad8ee5702d97e83701974b05f043e3e5a54fe5bf058f7250f48c857acc75845f +2850000 d8620d49c69a66da02ff610f5e274cc421e2ba948e93f994b3631940f046be90 de05f9278e390cd5968dab7727e14cd6eeef3a45c293c60f1ec6a908d8688755 4960c3ef0e5eeaf5ca3530d582d28b255a122569bc83a6a88f26f8d440f29806 +2852000 00000000000002503c86444b3b4c32cb2f59db9066ff027c8d24f74a1bc6f614 d27bc94febf793cd6b50f7a9578a983931f424d1bd2cba6cc38dd4c7630b0ef4 8a2ef878187d3b124f263d0461a857fd0259f1f3e9af8360f0c266a16d84d32b +2854000 00000000000000e4d74853009c7906fa216175f722c1cf5621cd8cbd4cf43ed5 65dbeae8ee1dd551d367b51f52aa3dd9c2b208e18414f03af1193ad5194a8370 95a78299619673b15cd83a41e0a95e57dfc31b41dd92be8e294b7ebdfcde1f39 +2856000 a784b9c315dda7ff41679bb522e1c8844fa0cefb4552d76f400397468d310f19 b1a50044ce70dde3ccd6ce7f0a680cfd4a60ce14eeb622ba1f23eb4d918c7abc 022f9852c9445eadb0b5cb40a5766c23f56b13541c2462c49461ea27502a01d4 +2858000 5f231902d4ed3e813a06a4b471a71ceec14d8001cb04f2b49eac09145b49d728 b2fea1a23c06e8f299f30bdc2b8230bbd673af70c07b6452c79884a699f1a364 ba67bc40024ed6c66ab0c80aeb9048239324bf2730396b9a23cfeb9470d12d54 +2860000 0000000000000244639b144452ec1f4d1c684c1363fdb346e59a3e9b68490b79 be0e3df353c391b82bf432b62957c692c2a76f08aecff6d90e2c5075b03d4e6a 4cf302d99c9d1164089fad929c917061a6186db693b7ccc526fa7594fa9beca7 +2862000 00000000000002f5b4521968d41b7bc8a2ddf5ce0dd1453c73c52190c801e100 ae84c89405101bd110ec335cd549037d02bbe1d6cc941fcf2e4e31cc0af4e9ea e743610cd36aa4f16c5a149fdaa1cca9ace5e90769be1dba6950e64345bcc308 +2864000 68b785beb46a668090eca25953fd32aa79796d7996eb74a74ff44c59581dbc0c a7adeb3cd0bef442cd490d39b96ddce5d21d8d876ac0b035b2e838f9946ea7a1 7ad921e43a492776920a4416de252ba51f6991c918ab6c52149e1b4ed6087d51 +2866000 710c1faca921e1b3a152b694eb5ddb2a97a3906c24dd0b01d4cee44aa48763a6 04b79232bcda0cdd27f182b9e69efd408e8f31690c0b7a62e8f5f5637352a17a 0000000000000105e35cad5e71f49ead744fb3d969d985b38d37272f1c20ff14 +2868000 e1b81477fef947bad776c538a744f248a6ac7178dda9783f9e8ac01f57f431b3 aec2b72610f40220231a06288ba13f93ff76fa26dd8497f1c65209f8996ae27a 000000000000024a4b27e1607ddd40b91a6962333a46c9e562d556957e737d80 +2870000 e2a78dbc777caca1d6d62beb58d679858c148fb8d56536aa125768ee2dd279df 4d7b17e6a3511d7763306dc900a69e73edd7888757647e2cd4ee707b5372134b 1f6dc471c463ef685c37c71f236c4d6ba9603fb41cf85f92aaeca8d0490701ad +2872000 9a64eb92a008a98d475c059a285f8b46badd3799cedf71f8de3f9f52c0153106 0e948c1de6eceec53ff969313adc68eba0ede1d70a00a40a2be24e29e28224bb 096fc0ef5d505d352f5527ae9f73588f3f801441521c7a95185495248a080a0c +2874000 000000000000019f4a9c3edab125e8aadb950ca1cc14f2949267c76b6dcd06a4 26ce10e124e9c86ff65d8b54b3c3fa4b77c91aa0fd0f3c4099d63cd6862fdde4 15637959ad17d871413271ad3eb2f765fb6f316f22240c0a1629d522f9ef6cad +2876000 a030560add227c69cd0199a67397f68477a049de3d7edd777ca69d5c40699c8c 265efbe701d55739b4a43b005ef058c82c046bfacd83302c65184121388ffd1b 29278095b0a9420308333b302488e8ed76d690117201f38a17268cc65191026d +2878000 0272b714cbcd8db12e8b14a6d9d10de37438f79af40c09a8b96394dcb6b4fbb1 7f20628b0f532e626ccdd02b8cde92cb754f5249a4f5b4f42151ab80de5975c8 cfa5f9a29dc771474d0f271a8593bebf2fb075c6caf5966391d02f5fa2a42ddc +2880000 a6fc8c26ba781afb6d2fe114ef298fce25d569789f6f92e19071c8342ceabfda 822031213ee68d245dc6a2af337b15760e33eb6d4414749b0de90d475b30174b ce45c0c6f80026fac9b3e57b70aea63c5f66ba66742f756b6d70b14463225118 +2882000 97f6820810b53ed8c0e45e3402aed9e2cf061ca01a6c3d0ae75011e6e800fdf1 53800d9d0d4da9a7fca0f94665c97c680def128a98f690fe618ca085d2590702 f12fc8f979f9208cc69911e3bec749a7906659deaaf13d2c31c67c134a75010a +2884000 51d70020dbcbbf605921a9ea849727dfef46916cd4522045ca62b188f5ef6c15 1e11019b5cdb9c44e1ca9d13875354e4bdb5e6bf62deb528118812cc7da0b820 4054aa6e72a89b665c7f4a029b28c6c5a0bb037c470d8c6c93087db5386115bb +2886000 f3fd63abc8671b15ae6b9775ac25a6b5e7253155c7af4df770271d25b35e5492 8817270f052766fa88a122ae1ae576c5e7b21d77263ddbd956d89c99aac97a3a 3a85dc49cc213f63faa9fcbabe2086ca812161b55ae18b5d4fc78bc16c654b79 +2888000 3a89536d38c50cc311fbbe4a4623ee573e4019a8d70e920d71480c7da2114a04 5cb21624a62282a590377c61e93cd4b0c180a6e077aa84742efdff68d8894c5b 312c339a36c3416917e5f8cd2a0a87f97d337ae782f1de2fa8c431d0990f0f10 +2890000 7f0ddfc032640a6a25a571baaa251e2c59f805903ef2b1804f943dab0ba53f7e 0fc4012ef779d3cac0ae784d5407600f877d1998f103130b2ef9d15f6d375035 0000000000000087b58a84165169b512b40239e75b1683d04a8e80d9bb71afe9 +2892000 000000000000017355da0c3585ac60aa467d60608c1d64b860ef5585a95f131b d75d762e5401ed0430864be717e521235ce63d7cb66a3da32828153624f6137a 0000000000000083a8343888568a06f70f032391f7a500db81ea76899c37b105 +2894000 194a0c6f6d7d1c3003b899536a2137bb7cd74e407b66b582878b84b6d6724512 169c28a2f570d408cfa43d6bfba38be386cfb87dbb2f1f92f2ec7a1f9e598ba7 517b023b0d6f3a469cc71e257658d0a51a03ef3cc57f039acc4fe29701878a62 +2896000 defa95ebaec20f90079882f71453a11424032515d5967af6954db4328bb5c24f c1377df3c7783b1af1528dee555dd27a77623d6b002a7b75a6d986799e4098c2 496dd4587a550a12c36b9d3c8104ac406267abb8675f08c0be761282142ea225 +2898000 08f90666f47794620e3c73cfd1d62e9b07f14a86850441841b2d4cee2ede0e18 95f677726bc56e5d95ab43b4289030f0fef27c19298364a593d82e1ee5c55b91 343e38f9bd2c1a3f1588f6f3162116471caf47f8c0b6d8c37d1629a5efe0dc48 +2900000 9888c9f637e68fae64a3e6381872394124351611e65dabd77997652c33c3d2f9 2a59cdc4074fa2440da85f4636b5ccc525abb6c38f9a3bc41eb52ebb0b4f9888 53c5d8e8755a74e938421f037a5ff36c17460884d7908726f12a1ac9a9e8187c +2902000 90e6498ef9dee80877cf16e80d2d979336e2bdd99152e7150c70d34213a8128e 4e495c1b747025922a8506f328baa85274a1dc7c459c5bda79414f1194477bc4 b728e5aef8cb64bc5e5d7524260cd0227f54239b241d826a2620d3eb4627c707 +2904000 f009311b6fc7d772e5d8ae87838e420f3ec55d25066248edd9570132ae921364 b38cc6ec38c7fa02041a9eeef51ea0a657186771bfaf26f37dd18a2bba68167e 99648c22221fce85fb69e075e0f8d2df654c92a66207c79d36836a6b59e20097 +2906000 59752a8cd3e68ed1bffd093c194f12053bad0b388d08482a8f5d2e9afd101ee5 0478145115ebc74c819cd47660325ec2f4cbad548a65f4099c9aa354f9bf1d38 7a3f679d7bd26bef31513d3ca673b748c08385fdd672d434466e95cb9664340a +2908000 4be6fc95ae1ec00ce7749f2994f1dd38d2250d346ee9839483c338d2381e1775 4eb0ca57bdb370a45d1afc3bdaae7a0beb126a7b223d198761d1f96bc56e2684 c3c9ef455050617ee4c3ced46659929f2fb8133b9b54d573c67ef32c82977ce6 +2910000 eb41ca8b9145c736b877aa398784a13a387d0c077873579816b3da1e51df0249 6ef3c7da34948f1b228d085ddcfc48e70b7b859de039091c6efeb10724b25375 7f0705e1a390adc604ce5097e2dd4c5daf18a00e880cef54174361b03b65ad94 +2912000 9e382902edd6153b091c5e5752d47cf377ff2493a79a73ab9cc7af49029a6671 008d27d77a7835f53aabcd180582ad547dfe5211ebc5142bc4388150c0580fed 0000000000000091636c4530895f83c180ed09eb7364e5cd370b93d946e3b301 +2914000 90f3b49b1a8d2d981f50581552c719fb2c950f4ed767d5eee41a2ef43912ff90 1aae9427b7207a1c8fff306cf3b368917d6af7d9369c05cdf3356330221add18 16caa6e7bc6786ef3681bc9b33f17e13e4a8ecccbde65c8d9bac5c633875db9b +2916000 00000000000000418965aa263af5209e0cac7401f26c268663d4e2a5e351399c 42bb8b68f23d848aded9d9e605262bf4e30e8d3c9f4ffc5d6fa9e1a983e50008 236a8a4207476fa644ebb49e102febfb8640694d5078bd395f79e1837e6f63c5 +2918000 43c17af3b58eb9eac43b05845a02224e0146564d51e65252f16d219fe0034bd6 07115644dc07e1e1fb582cff470423e48887c8e6486d3abadc88c7f33ed20f6e 167b4fa71619fbcaf208108d560113180e523cf4e9bf10e46950e5cd2314096b +2920000 ea0b9042409e4cd7ed2524ffbd7ff652382f2c57a57f9d42b0eca212bfdb97cd 6323069ee4b1a1c9c8fdfc21f4df76c6131990daf7e7651551e73075cbf97f20 82d96daf441b5a9ba8ce7bbd58222e27a1f6a7922459cb5ec9e5fb50d506db44 +2922000 12be2489dd0cbaa33fc88adf24fd9fd93aea3702873252ba3eaea7ea8d164558 947808c4d3aab7152acf78f199ddcc81037f8af2aacd14d2db83494787914339 0000000000000057ea1980fef409f1b415934c98f5495759be250256f3c8408b +2924000 fc8ef7dd4d0eda4fedd0e845fdc7cf998713436e60814509c6ff571e8b0d7545 065dc65cb4f66e5d688ef96b681f30827773137e7b51def2c45a6aa6d3d58397 99a08680c3ce638035bcdeb39a071b6dfcbee9e85f1c7bf253145240c1ec1bdd +2926000 22e99b4240d51923dd81221aad94959a6bafabeb786f5b96a1b3d2ae9c71e377 b57911cd3488895cfad0108447ae9dceb1ee5a497adcdea11b4bffdaba9bcf8c f8fcaafa34e52bfec65a82bc865680abb1ebc76d4d6b48c4403fbe713cf9e099 +2928000 8edd81a580e171bbcaa3a6d0a19f2fcb021d8fac5d07d8c308d9af7a3829d8e2 79ec0ca6bf89942144014ad390657eed732df689128d6c00610d459fdbe7b06a ff0c6b93a202c01cdae4c515606211d2f17cb937eca17241cd98677429b09cc6 +2930000 16955308c920ed00f2cddd35dada957bf40f17861d8b22850168d7654ae94f99 cffec1a28bb58f644a1194af003d8b91e865dcce50c53450cf5d9b34086b0e34 000000000000010c5177716c822275c29eb22bc825fcf532e4629d32033b82a6 +2932000 b9bc393deadbba22d04f2bdd16df448a2e1a39c4175d628ae12c9cef17ba9c40 8c9b13b6d0a7cf69ee59179be709529284619fba1ac81ef393e1de38762d181a 19e580a5616336e62d5703a6732698b4e7e100404023d196b2c3e416a0e2e249 +2934000 00000000000000755cc3ad9afb3b81cac0f3e0431b3e972d786a85a4dbf7998e 8ca9b9c13579dcde5441f078ed8920fe784d08ad094bec7b01d57777d50cee21 000000000000011b6d5ea14e6fb27f4635b6aa61c57bd3852914f4b219457157 +2936000 44480528eca6a4dbb675e31a72d9835b5ec539503e599764406a4949ee53bba1 diff --git a/iguana/confs/DGB_peers.txt b/iguana/confs/DGB_peers.txt new file mode 100644 index 000000000..28bb69e30 --- /dev/null +++ b/iguana/confs/DGB_peers.txt @@ -0,0 +1,17306 @@ +212.129.1.77 +178.33.228.14 +157.161.128.58 +108.61.10.90 +66.228.56.115 +167.160.36.126 +104.236.32.184 +39.34.235.71 +95.28.7.71 +36.149.70.139 +71.95.131.105 +25.125.144.215 +98.196.52.135 +93.127.20.199 +94.112.7.134 +78.73.169.30 +82.78.191.165 +151.29.224.128 +203.212.61.135 +73.170.147.244 +121.218.175.57 +219.128.62.223 +90.23.224.50 +151.74.251.28 +94.6.185.11 +201.22.220.238 +85.175.16.31 +108.1.94.151 +188.68.194.121 +80.201.154.170 +62.52.137.121 +25.156.165.226 +72.49.64.176 +81.183.119.94 +118.92.78.114 +104.156.228.176 +86.135.5.121 +46.159.10.54 +151.46.68.152 +114.55.117.237 +88.200.136.135 +174.26.164.250 +178.158.142.82 +109.30.168.16 +185.160.251.220 +82.17.141.219 +219.92.249.24 +71.210.255.55 +76.72.154.26 +69.119.106.227 +209.6.217.75 +206.59.251.202 +60.246.252.214 +70.71.37.150 +176.77.80.188 +201.158.29.115 +98.206.146.90 +217.70.251.174 +84.62.72.67 +83.85.145.11 +254.150.134.215 +85.26.165.246 +85.181.160.208 +208.91.66.8 +114.125.178.36 +71.119.30.24 +86.83.46.210 +87.102.158.155 +94.193.249.41 +181.103.128.173 +101.14.87.154 +69.46.195.176 +216.171.18.141 +70.27.45.70 +209.197.138.184 +29.73.204.5 +63.87.254.247 +69.43.42.16 +120.38.107.41 +97.104.141.214 +213.87.134.192 +179.188.245.56 +176.194.243.107 +113.90.83.115 +175.120.159.224 +37.59.20.223 +42.81.72.54 +36.234.60.175 +98.84.229.115 +77.20.66.68 +91.114.220.13 +162.221.207.229 +118.100.94.179 +217.29.24.36 +75.183.49.103 +95.30.237.147 +186.88.171.141 +208.91.67.1 +160.179.46.174 +82.226.172.82 +101.12.0.165 +171.96.172.46 +148.251.88.245 +175.42.86.217 +121.225.191.68 +85.178.131.115 +224.215.146.36 +142.196.255.91 +109.229.72.21 +95.221.238.70 +93.80.186.163 +5.189.145.112 +174.117.39.176 +91.188.124.194 +24.230.59.100 +5.101.96.124 +69.112.104.39 +186.95.200.178 +81.10.135.207 +82.75.179.105 +93.221.209.88 +67.244.140.202 +159.227.211.229 +207.118.11.238 +14.203.74.176 +77.72.144.197 +109.193.167.249 +81.95.181.41 +108.234.78.195 +118.209.134.72 +183.204.177.21 +90.176.255.111 +108.14.8.80 +188.187.20.44 +93.51.57.207 +190.141.68.49 +91.7.79.1 +123.3.199.96 +91.102.81.135 +111.95.117.189 +93.229.186.252 +78.52.250.37 +109.201.105.45 +178.47.116.39 +24.56.9.196 +77.222.97.198 +216.172.142.243 +77.40.46.73 +97.80.88.5 +1.9.103.47 +199.168.250.82 +190.13.230.114 +90.197.179.150 +254.200.66.128 +212.156.47.210 +109.72.237.88 +36.69.126.209 +128.71.158.207 +123.224.4.45 +24.70.0.188 +67.190.29.0 +46.28.204.53 +192.0.144.249 +93.62.254.162 +254.236.148.14 +217.42.138.114 +213.87.159.145 +83.39.76.116 +81.7.3.24 +79.42.51.42 +86.217.123.203 +79.115.105.194 +65.25.61.152 +91.205.236.225 +184.96.29.22 +134.249.71.117 +78.223.238.225 +189.122.101.45 +72.13.87.195 +92.242.132.15 +72.168.160.181 +50.159.81.235 +213.60.37.174 +108.80.238.183 +85.253.130.73 +46.39.55.0 +107.191.33.13 +161.63.219.19 +45.48.146.148 +144.168.55.204 +81.146.8.7 +84.160.180.185 +87.0.155.240 +93.79.12.166 +64.231.253.204 +50.165.91.254 +74.103.247.9 +122.194.230.147 +209.177.106.77 +77.105.219.75 +217.126.56.184 +46.22.172.190 +1.115.6.59 +179.210.13.19 +81.153.248.197 +76.102.131.234 +92.19.38.229 +24.151.52.157 +173.2.191.21 +223.4.79.136 +176.104.122.62 +36.69.116.166 +0.0.0.7 +98.126.61.242 +180.110.83.212 +168.70.79.201 +85.181.163.180 +85.226.244.4 +82.24.112.2 +121.218.79.89 +2.92.114.186 +188.68.151.16 +73.114.35.193 +188.22.213.42 +47.58.60.22 +83.8.113.179 +244.8.207.50 +124.204.226.226 +5.164.222.60 +80.219.44.41 +68.99.189.60 +5.248.199.235 +46.133.246.241 +137.124.118.72 +27.47.78.239 +100.13.189.170 +78.84.154.105 +78.48.110.171 +45.27.160.94 +76.95.178.145 +89.212.122.128 +37.55.8.14 +119.74.73.116 +166.230.66.50 +91.7.215.56 +77.47.96.164 +46.186.85.226 +104.223.185.184 +254.226.198.25 +37.146.116.43 +93.49.156.51 +220.249.249.8 +67.171.202.153 +85.66.172.138 +101.128.83.1 +80.88.26.131 +60.52.77.27 +160.176.20.248 +84.178.247.84 +179.124.176.144 +77.36.209.216 +119.253.64.37 +124.228.209.34 +14.200.37.7 +84.2.168.150 +173.57.207.71 +5.34.113.78 +85.76.72.110 +68.111.155.53 +157.128.172.169 +80.188.113.28 +82.79.234.31 +173.229.169.3 +212.164.146.33 +72.127.76.27 +175.161.227.110 +109.188.125.111 +37.214.28.182 +47.18.204.217 +95.188.88.59 +96.252.12.181 +46.146.184.148 +178.137.58.35 +125.82.163.206 +95.17.254.131 +24.35.105.160 +105.25.20.167 +109.190.154.241 +46.61.65.167 +176.214.154.115 +37.44.108.205 +71.80.233.61 +210.146.249.98 +50.191.140.20 +172.0.0.3 +188.134.21.71 +178.34.161.187 +176.97.103.226 +69.151.26.205 +36.69.112.47 +231.115.82.205 +128.70.5.196 +178.148.242.143 +77.152.251.48 +217.93.233.117 +128.70.154.103 +24.6.180.172 +52.178.27.143 +79.41.111.72 +50.65.6.66 +213.24.127.152 +105.156.12.107 +24.212.250.140 +91.65.124.228 +176.111.85.2 +75.67.50.181 +107.179.158.105 +97.121.39.172 +211.110.17.146 +110.244.163.66 +83.41.237.2 +177.42.212.90 +42.25.182.101 +41.176.238.223 +83.6.60.199 +192.254.1.3 +63.87.253.252 +105.154.181.129 +42.116.159.209 +173.175.165.35 +191.33.106.75 +66.31.203.99 +47.90.12.41 +254.139.181.166 +123.243.176.125 +98.195.248.66 +114.125.184.21 +131.77.218.144 +99.35.1.162 +2.94.63.28 +142.4.219.166 +37.214.45.81 +91.148.83.250 +108.59.82.117 +66.18.203.165 +184.58.153.145 +90.22.182.176 +129.132.179.10 +77.51.3.171 +93.178.236.186 +104.172.24.79 +117.69.37.113 +89.177.235.232 +46.98.124.46 +101.200.156.61 +54.78.124.50 +49.183.195.52 +94.233.108.155 +178.76.217.3 +88.236.139.51 +182.9.251.22 +108.217.41.51 +78.15.69.11 +1.9.102.15 +83.5.183.131 +146.65.212.78 +72.90.164.245 +37.201.226.29 +76.175.160.124 +2.139.38.182 +75.156.92.90 +162.245.17.64 +46.109.116.120 +31.90.138.142 +70.113.42.136 +87.206.96.153 +187.107.67.31 +151.64.5.115 +81.100.89.197 +254.213.224.159 +95.90.192.148 +213.87.127.244 +188.187.179.150 +153.100.225.76 +119.248.127.237 +104.212.233.142 +95.191.200.245 +218.183.61.75 +69.81.135.130 +86.111.136.191 +96.242.53.68 +0.0.0.0 +79.111.210.168 +50.159.128.226 +76.92.249.209 +73.197.103.142 +73.231.122.49 +237.51.250.49 +71.234.232.130 +50.135.221.200 +88.77.218.18 +81.108.63.108 +223.156.208.226 +83.21.45.217 +94.41.181.212 +69.124.186.230 +217.27.149.140 +104.175.162.231 +77.40.24.110 +124.168.234.94 +24.76.220.10 +254.69.93.71 +203.212.154.201 +37.151.186.123 +130.255.247.36 +84.77.151.215 +68.13.175.20 +179.188.245.56 +87.245.7.194 +80.180.210.65 +87.6.53.235 +208.167.254.202 +91.48.57.13 +50.66.78.155 +86.132.124.18 +159.148.142.59 +46.105.39.103 +188.82.44.231 +93.222.141.130 +198.27.81.25 +5.198.236.43 +101.163.24.233 +77.163.189.107 +77.40.116.92 +76.10.162.169 +87.146.5.203 +84.105.26.71 +106.68.56.66 +103.245.95.63 +180.107.230.128 +183.50.115.22 +189.79.14.213 +188.163.97.22 +75.87.190.13 +46.159.38.161 +27.47.113.178 +220.253.206.246 +84.188.187.66 +191.254.115.148 +94.36.175.249 +191.54.11.197 +190.79.130.213 +31.6.50.60 +81.17.174.82 +76.113.21.208 +180.165.53.252 +77.22.148.6 +14.2.72.165 +205.183.219.247 +69.23.249.169 +185.65.132.100 +37.214.51.246 +185.157.16.38 +0.0.120.138 +205.189.79.111 +194.249.178.189 +24.140.173.50 +79.245.43.123 +93.47.96.158 +92.255.126.227 +83.31.169.166 +183.61.146.133 +31.109.67.191 +0.0.0.0 +90.2.2.115 +219.79.134.55 +94.251.44.201 +87.50.82.48 +83.23.239.91 +90.104.163.221 +77.249.144.34 +180.101.15.205 +39.70.151.104 +225.174.220.177 +70.95.48.109 +62.107.128.88 +94.34.215.116 +70.69.36.146 +36.149.198.139 +93.84.211.255 +217.244.81.231 +171.128.133.206 +37.146.227.226 +79.234.14.227 +177.158.39.231 +114.40.139.95 +107.3.236.173 +78.121.10.157 +70.113.61.111 +161.31.224.170 +83.45.251.218 +192.241.195.57 +176.222.168.20 +173.177.115.102 +50.49.139.30 +24.175.64.146 +73.249.63.180 +92.243.166.74 +213.138.86.15 +198.72.192.74 +146.82.107.4 +79.111.28.247 +37.190.124.110 +86.41.83.192 +11.47.244.249 +82.130.22.224 +90.150.252.207 +92.127.190.145 +217.86.143.234 +14.200.246.174 +197.86.181.90 +91.150.7.204 +178.239.58.248 +112.198.98.69 +217.241.4.70 +78.20.252.64 +46.233.232.251 +178.32.53.131 +200.92.103.84 +179.98.39.154 +82.193.127.191 +23.233.105.183 +42.79.5.88 +109.43.2.219 +73.160.106.98 +91.57.200.156 +94.166.91.220 +89.24.238.25 +104.138.147.122 +62.235.252.43 +62.61.130.225 +156.207.75.152 +79.56.59.204 +81.91.29.19 +180.200.182.59 +78.106.0.191 +76.145.250.114 +73.93.143.14 +194.42.113.83 +190.219.169.143 +129.132.208.154 +188.77.115.58 +159.227.211.229 +178.12.222.20 +89.73.112.158 +90.77.201.224 +79.239.3.2 +128.73.84.157 +172.251.163.17 +76.68.180.62 +188.104.121.98 +217.96.181.144 +81.245.209.201 +91.54.70.154 +170.179.182.45 +72.198.163.2 +81.149.9.87 +115.152.10.90 +176.2.33.156 +107.217.207.67 +189.196.173.117 +58.240.252.231 +178.34.158.126 +129.208.61.192 +109.106.1.98 +209.71.187.112 +176.209.76.142 +89.193.28.216 +46.207.139.233 +81.110.173.243 +5.189.30.177 +85.76.64.24 +180.85.143.49 +109.200.238.156 +86.197.193.139 +171.151.82.30 +160.64.4.181 +68.173.147.35 +62.1.200.15 +213.8.129.147 +14.218.48.242 +125.192.151.221 +178.158.102.90 +83.142.111.198 +201.22.222.19 +63.87.255.253 +86.245.121.184 +80.180.218.21 +51.9.252.248 +168.205.173.177 +173.254.208.98 +87.199.167.171 +31.206.63.127 +22.51.95.184 +178.93.148.210 +78.52.193.124 +104.168.164.240 +93.33.170.142 +24.74.13.140 +148.0.39.7 +190.42.187.9 +27.105.233.173 +213.162.68.4 +79.227.31.39 +112.97.61.240 +80.135.106.20 +62.235.148.101 +99.230.194.187 +98.221.123.38 +58.56.133.98 +247.19.172.79 +108.28.225.229 +81.184.25.104 +181.104.112.211 +188.162.166.158 +79.184.135.236 +188.238.17.69 +190.134.134.46 +95.189.150.132 +194.126.168.60 +76.19.242.156 +130.180.218.219 +104.220.27.24 +142.163.92.14 +182.125.129.10 +73.192.202.185 +60.123.50.87 +118.116.108.3 +184.101.248.5 +50.140.161.83 +101.165.212.53 +87.165.67.175 +209.197.156.241 +85.27.125.82 +93.181.216.82 +71.72.141.237 +70.24.228.204 +91.182.12.54 +136.169.204.151 +177.206.49.168 +113.83.228.172 +88.147.30.116 +71.56.202.226 +68.146.169.173 +89.235.211.85 +41.176.39.196 +147.19.12.189 +104.207.136.103 +60.50.206.232 +178.158.80.11 +71.199.119.181 +191.179.157.158 +242.170.177.252 +141.215.80.194 +82.161.145.68 +89.142.182.169 +82.18.195.64 +70.123.112.130 +179.188.245.56 +176.102.195.216 +188.69.243.161 +83.84.40.12 +220.236.128.177 +109.129.224.18 +100.34.93.150 +149.138.22.140 +82.192.64.136 +186.214.98.40 +108.26.44.16 +108.67.80.117 +37.214.5.252 +209.232.227.231 +196.210.50.104 +183.135.255.184 +177.131.120.30 +62.165.242.162 +41.138.102.202 +104.238.169.89 +104.157.137.70 +89.202.166.242 +131.77.218.144 +207.118.93.73 +87.162.44.24 +0.0.0.0 +110.0.234.132 +62.80.176.70 +80.88.28.137 +178.120.17.194 +146.3.226.203 +67.187.18.63 +76.243.35.92 +70.71.225.144 +37.49.112.191 +98.228.255.10 +14.203.211.216 +70.29.0.34 +109.229.64.106 +180.251.132.210 +90.69.147.20 +60.205.58.32 +96.54.5.209 +80.12.38.22 +92.14.21.218 +80.77.39.181 +88.177.109.119 +196.210.55.253 +66.175.220.212 +119.63.44.133 +77.173.116.163 +121.222.251.158 +88.147.16.221 +105.104.0.66 +77.177.201.1 +201.152.203.38 +31.181.104.136 +130.35.207.72 +50.149.22.101 +128.71.205.191 +192.180.188.36 +177.138.128.83 +72.160.90.78 +98.127.83.86 +77.40.116.144 +146.52.75.143 +93.85.10.226 +86.4.137.92 +213.66.200.33 +27.32.134.220 +73.192.216.82 +46.186.83.147 +93.178.70.203 +75.118.205.52 +91.222.69.111 +97.94.164.127 +85.212.56.36 +24.255.33.97 +120.88.154.161 +5.54.174.76 +37.214.155.189 +69.223.42.70 +179.188.245.56 +151.249.103.245 +160.158.116.120 +52.19.194.56 +86.140.103.156 +89.13.93.55 +83.237.181.184 +95.222.48.175 +77.122.83.9 +67.1.149.121 +50.189.198.168 +75.165.59.73 +187.114.151.195 +104.156.240.174 +95.24.204.250 +189.115.186.244 +95.73.215.207 +66.55.141.100 +77.3.26.206 +89.205.58.251 +92.101.208.231 +180.242.208.9 +167.148.76.2 +109.215.152.195 +77.40.116.6 +71.19.252.27 +188.223.186.210 +254.194.199.151 +83.5.57.232 +100.14.95.93 +71.222.214.25 +50.143.146.148 +46.254.161.146 +81.183.115.115 +82.245.39.252 +193.95.228.71 +99.247.211.202 +46.105.124.86 +82.239.243.10 +117.140.167.99 +86.174.182.223 +81.151.103.4 +188.16.56.69 +37.78.40.173 +99.198.248.234 +46.39.230.195 +191.54.11.197 +208.74.176.52 +149.210.164.198 +131.177.217.139 +143.241.180.26 +183.62.31.188 +209.95.50.98 +46.99.72.69 +87.15.12.87 +155.246.209.18 +63.87.253.154 +188.105.132.220 +46.59.178.196 +146.123.253.27 +46.35.77.137 +37.161.40.225 +88.147.122.169 +114.125.178.177 +190.237.124.123 +174.24.176.235 +221.193.4.156 +217.117.187.211 +79.133.14.100 +188.68.194.123 +85.76.73.104 +173.79.110.56 +174.7.103.195 +68.187.116.205 +175.140.222.112 +37.163.202.87 +78.25.123.38 +31.162.188.97 +120.25.65.234 +213.59.117.212 +181.65.78.183 +172.79.95.120 +109.226.119.128 +111.174.146.100 +179.188.245.56 +119.205.162.20 +31.6.24.148 +188.68.14.26 +37.8.242.35 +118.209.15.214 +80.99.198.172 +100.122.132.37 +223.68.189.53 +5.71.101.213 +195.142.179.119 +90.202.206.208 +167.249.235.53 +114.77.188.214 +93.77.45.35 +135.143.95.62 +79.53.186.83 +63.87.77.227 +188.187.174.168 +120.239.8.85 +97.85.42.177 +89.0.8.108 +74.195.227.225 +198.143.2.132 +177.158.97.204 +92.46.173.216 +90.21.84.137 +72.83.36.246 +83.81.103.227 +5.137.221.215 +182.96.242.53 +96.55.55.197 +109.91.34.232 +31.2.58.76 +37.214.155.169 +60.123.50.87 +173.196.158.132 +87.198.114.90 +191.248.19.34 +105.157.204.237 +206.45.228.163 +213.4.115.211 +156.14.173.215 +192.195.67.2 +83.43.242.84 +87.252.238.253 +185.10.190.231 +95.29.76.137 +87.112.0.134 +92.51.9.54 +61.131.83.133 +180.165.69.238 +90.149.137.180 +24.46.254.139 +74.141.57.154 +95.70.120.151 +104.238.169.72 +87.217.196.11 +76.102.131.234 +87.97.0.228 +94.199.198.134 +73.80.36.106 +91.250.56.101 +1.115.1.3 +137.103.221.168 +149.202.193.188 +71.170.84.181 +198.8.80.45 +178.93.148.133 +93.178.65.9 +68.40.25.124 +24.117.22.32 +25.27.146.66 +212.89.225.138 +49.193.216.83 +86.9.168.196 +37.55.84.196 +193.95.253.142 +104.34.224.200 +174.45.91.255 +93.133.153.104 +53.74.14.208 +80.88.23.87 +37.187.131.169 +179.188.245.56 +184.53.32.170 +104.200.154.54 +104.223.53.135 +195.15.4.67 +180.229.32.135 +31.3.156.112 +178.165.130.31 +107.4.39.143 +67.85.217.100 +178.46.163.75 +213.231.55.145 +203.92.39.35 +104.238.58.22 +74.197.90.100 +75.70.171.6 +77.120.160.249 +65.96.131.178 +40.130.201.131 +130.194.72.84 +75.82.210.101 +149.56.87.165 +173.254.208.194 +58.250.131.92 +166.123.188.107 +183.5.123.230 +46.39.171.197 +5.13.13.198 +84.0.5.105 +7.211.73.100 +77.40.116.212 +76.127.11.146 +176.213.16.21 +64.231.232.206 +23.16.180.239 +172.227.36.209 +5.141.90.117 +66.115.115.71 +151.133.201.86 +70.79.24.232 +82.15.5.193 +199.58.178.132 +116.226.26.241 +107.153.20.121 +84.18.118.84 +88.150.185.82 +174.56.149.251 +212.230.68.200 +142.137.9.120 +178.94.172.125 +69.36.206.73 +90.174.4.95 +63.87.255.249 +177.235.119.100 +184.101.149.91 +117.140.45.148 +79.196.225.142 +32.169.11.9 +78.232.226.226 +177.5.71.225 +178.34.158.160 +176.3.38.9 +77.181.221.137 +93.231.187.186 +114.125.151.18 +70.112.23.16 +128.74.242.207 +37.79.153.6 +179.188.245.56 +95.79.255.196 +189.197.30.89 +113.88.22.241 +69.23.131.145 +24.230.253.14 +178.34.162.233 +231.119.4.225 +46.186.89.232 +78.129.157.196 +125.164.96.193 +213.5.65.29 +187.59.234.92 +112.97.54.124 +178.123.176.79 +109.227.118.161 +90.255.120.101 +95.26.178.188 +46.175.175.206 +65.190.129.84 +37.192.148.86 +198.8.80.171 +174.51.159.181 +196.52.23.228 +110.125.47.10 +177.80.226.192 +92.49.238.145 +81.203.232.36 +213.220.249.220 +73.109.59.103 +85.114.174.176 +109.120.242.35 +188.115.39.45 +112.74.214.212 +99.250.234.200 +37.115.220.137 +73.231.114.124 +46.53.209.146 +77.13.64.136 +85.29.114.126 +90.202.174.218 +180.185.84.249 +76.75.89.197 +33.46.244.82 +63.87.77.189 +218.38.19.7 +175.43.242.156 +95.52.140.49 +77.235.102.218 +186.92.196.71 +178.93.148.183 +83.134.210.164 +97.121.78.125 +217.41.63.179 +41.241.90.148 +86.61.67.64 +37.214.129.10 +117.87.47.179 +2.24.233.99 +162.243.216.227 +93.26.186.20 +109.236.90.144 +171.96.170.132 +84.120.106.33 +94.13.119.10 +72.13.188.130 +82.206.16.181 +74.116.186.220 +67.169.203.50 +46.42.58.166 +178.43.229.84 +37.14.204.55 +177.142.52.235 +181.64.192.105 +37.24.149.231 +215.119.81.157 +24.225.14.35 +219.21.195.80 +87.115.193.174 +189.73.224.143 +93.45.49.68 +79.143.182.116 +89.0.39.201 +202.159.128.66 +24.125.27.47 +115.192.246.185 +161.97.160.204 +179.99.141.139 +50.224.63.50 +37.214.31.133 +88.206.186.58 +108.169.236.27 +84.237.86.24 +162.19.122.33 +47.90.2.35 +31.129.195.13 +107.222.97.179 +134.90.156.49 +108.244.47.41 +63.87.254.148 +171.213.99.156 +171.124.174.139 +92.246.196.101 +192.162.143.75 +75.141.226.201 +100.70.154.135 +1.9.103.7 +69.255.27.161 +217.96.146.146 +0.0.0.2 +197.246.2.143 +65.13.189.227 +194.77.215.7 +89.31.117.250 +0.0.0.5 +5.115.203.35 +146.115.157.45 +162.243.227.180 +79.102.44.42 +49.64.193.14 +89.144.239.171 +166.70.8.20 +131.77.218.144 +81.158.175.156 +70.68.114.212 +93.88.53.63 +81.174.41.68 +82.57.179.8 +151.224.142.140 +82.230.144.202 +86.132.254.124 +165.72.27.149 +5.139.145.97 +201.242.188.234 +46.149.87.97 +23.234.22.142 +178.7.171.40 +90.150.241.152 +67.173.173.74 +91.232.169.187 +177.200.114.97 +142.4.208.32 +203.144.16.52 +79.165.103.230 +147.194.41.211 +77.65.19.242 +121.15.122.220 +67.219.95.103 +91.126.89.184 +186.33.38.5 +84.119.188.172 +114.125.179.112 +63.87.77.189 +72.50.251.132 +78.225.114.147 +83.215.142.159 +88.70.150.29 +121.12.208.45 +122.191.104.50 +198.8.80.92 +81.170.155.133 +74.152.123.100 +31.206.70.27 +84.183.99.23 +178.214.180.24 +177.40.178.34 +91.180.154.226 +187.111.234.136 +5.76.75.218 +70.227.145.252 +77.20.143.147 +203.106.219.211 +100.13.87.171 +188.60.84.92 +203.122.115.166 +188.193.95.80 +65.94.24.50 +37.167.231.160 +109.169.250.98 +109.229.64.141 +2.132.168.188 +31.128.8.221 +37.221.237.72 +31.180.227.66 +95.78.53.221 +128.54.174.31 +93.73.22.239 +75.148.217.67 +222.220.99.98 +50.158.161.48 +172.79.179.32 +89.0.253.11 +93.103.53.134 +78.223.238.225 +94.50.0.22 +190.204.206.81 +83.134.57.48 +63.87.253.154 +185.57.82.82 +91.233.19.241 +34.57.82.147 +172.214.18.253 +216.172.142.11 +0.110.200.142 +2.245.91.207 +1.9.103.155 +205.112.109.107 +188.125.246.149 +104.35.7.243 +67.174.74.165 +24.166.50.124 +2.245.160.249 +54.70.85.2 +70.190.111.248 +179.181.252.174 +41.251.149.122 +27.47.118.14 +14.201.137.152 +83.41.194.149 +50.133.248.247 +89.12.214.245 +175.43.242.132 +80.88.25.191 +71.231.33.235 +78.227.111.78 +94.197.120.218 +231.137.251.73 +70.65.206.59 +202.49.89.68 +186.15.42.168 +188.69.194.108 +95.208.248.130 +79.76.201.195 +113.8.121.236 +86.15.3.52 +5.80.179.121 +88.195.122.166 +110.159.96.102 +79.227.10.114 +82.84.229.234 +36.76.98.20 +114.125.176.195 +78.51.119.166 +125.174.218.86 +84.77.146.155 +35.58.24.31 +115.74.185.212 +46.135.61.3 +76.25.194.124 +80.82.202.248 +184.78.118.109 +151.231.233.43 +46.159.90.238 +178.137.239.114 +37.235.146.166 +67.11.239.1 +103.255.4.248 +173.25.111.238 +63.87.255.155 +185.160.93.175 +37.214.100.137 +75.164.233.17 +178.95.110.28 +73.11.194.236 +36.69.119.70 +78.220.216.75 +78.111.185.210 +63.155.143.241 +178.94.172.173 +68.234.91.117 +86.135.158.126 +95.73.52.198 +90.48.160.48 +213.195.188.133 +68.228.16.214 +164.244.159.137 +41.105.191.46 +108.61.226.28 +77.207.92.112 +178.151.6.20 +36.76.98.142 +69.165.222.140 +97.58.136.16 +75.118.116.50 +191.182.136.128 +31.163.55.26 +31.178.237.110 +99.244.177.73 +178.0.89.10 +91.121.155.93 +194.127.77.96 +206.248.172.82 +217.99.82.246 +151.68.66.143 +89.153.139.149 +37.201.230.118 +201.95.5.52 +201.79.214.0 +218.206.143.64 +80.162.16.80 +201.14.50.216 +98.192.4.26 +32.51.8.120 +77.29.108.142 +151.52.77.30 +93.84.216.92 +82.44.146.33 +78.53.78.152 +197.119.213.42 +147.183.210.66 +185.3.173.229 +191.183.169.197 +2.245.137.183 +91.65.126.15 +182.148.67.82 +217.114.229.49 +98.165.223.15 +68.113.233.62 +109.87.98.126 +67.194.158.32 +70.24.17.143 +73.202.135.79 +79.201.133.169 +69.17.254.58 +65.25.180.22 +114.125.179.68 +254.3.81.156 +79.160.55.30 +173.31.201.187 +176.58.121.112 +87.68.55.213 +173.161.71.38 +107.180.68.196 +94.25.228.15 +124.122.129.211 +31.131.53.15 +169.195.113.223 +72.220.38.235 +84.231.4.13 +188.199.223.30 +182.186.160.34 +25.1.7.162 +93.117.189.198 +183.74.38.165 +5.18.64.210 +77.123.120.121 +177.229.245.106 +36.234.59.20 +100.70.99.29 +84.85.234.220 +115.132.88.210 +92.237.30.106 +122.52.84.80 +74.101.32.172 +122.194.223.212 +0.0.0.1 +83.250.32.201 +188.239.89.43 +86.110.35.134 +186.83.21.221 +67.249.244.99 +171.253.71.129 +176.114.41.138 +24.249.152.169 +46.118.79.153 +98.225.56.230 +77.163.92.80 +75.173.110.74 +115.35.216.91 +138.151.74.156 +1.42.9.21 +24.135.179.191 +68.173.73.213 +193.38.164.231 +211.149.234.109 +53.186.124.223 +71.8.170.163 +158.69.196.61 +184.75.221.179 +37.214.17.200 +31.178.188.94 +109.222.126.128 +37.97.159.116 +98.192.178.2 +89.14.10.230 +77.178.145.18 +50.131.105.103 +174.1.20.102 +31.163.45.85 +142.4.209.20 +213.44.220.12 +178.115.128.70 +190.237.180.151 +71.86.63.12 +107.191.36.26 +171.4.191.111 +77.180.226.208 +126.47.194.63 +132.177.166.224 +209.6.13.94 +209.71.187.95 +98.127.94.104 +176.194.54.26 +95.38.165.156 +211.149.203.133 +125.34.99.26 +212.80.35.204 +181.64.192.144 +128.69.5.201 +77.253.178.185 +66.66.96.55 +37.187.62.197 +5.79.68.179 +162.214.144.232 +75.118.140.166 +46.184.68.149 +118.209.228.40 +25.167.181.129 +101.232.199.107 +183.60.175.245 +83.134.97.92 +213.59.116.93 +108.35.113.160 +0.0.0.3 +204.48.58.5 +82.34.83.145 +75.164.251.34 +93.221.234.206 +191.54.11.197 +77.110.148.100 +71.204.12.71 +71.212.2.36 +112.201.133.20 +115.203.241.14 +80.12.35.100 +213.179.252.227 +171.4.191.111 +81.94.192.39 +186.28.1.249 +27.10.78.74 +14.218.50.43 +157.75.45.18 +188.252.49.231 +100.15.53.74 +84.73.232.94 +73.246.4.233 +78.85.238.101 +37.78.152.207 +144.153.206.165 +71.47.205.43 +118.199.43.9 +61.209.250.108 +89.193.28.216 +172.56.15.180 +173.180.35.59 +60.6.152.90 +87.71.32.150 +178.7.1.50 +152.29.211.220 +181.1.187.241 +107.151.146.18 +50.38.90.86 +78.53.76.85 +91.65.233.81 +24.111.248.238 +43.230.115.113 +46.254.162.62 +81.4.193.138 +65.122.82.65 +215.119.81.157 +108.35.177.168 +92.101.204.137 +212.77.214.235 +216.232.189.109 +86.169.39.198 +58.8.155.168 +68.112.157.91 +149.154.82.143 +121.98.137.146 +2.31.19.169 +80.135.72.241 +178.34.158.177 +83.220.236.163 +85.222.174.131 +94.192.120.77 +160.171.125.185 +209.200.61.232 +69.167.20.21 +94.196.65.242 +176.95.200.225 +72.133.224.210 +81.165.223.134 +79.30.43.137 +11.64.77.213 +117.69.37.124 +81.4.229.54 +179.98.225.18 +176.101.159.159 +37.120.174.32 +172.90.161.27 +31.135.162.117 +217.118.93.148 +43.68.222.229 +142.177.86.19 +95.252.144.144 +71.180.49.190 +31.173.84.149 +84.178.235.239 +119.133.211.12 +173.79.115.216 +60.177.162.207 +185.142.213.119 +136.122.46.135 +254.219.128.7 +167.56.247.38 +136.243.217.171 +47.90.41.107 +69.138.72.168 +73.93.104.132 +108.244.47.45 +110.0.234.132 +85.76.73.228 +83.250.48.215 +66.73.115.64 +37.140.78.86 +69.165.242.216 +73.240.78.63 +95.154.144.76 +212.115.253.181 +2.22.50.177 +161.63.219.19 +160.101.111.179 +83.82.140.109 +112.114.250.79 +31.173.80.23 +204.185.72.3 +104.207.136.100 +107.147.67.163 +84.251.123.206 +5.135.176.160 +112.86.236.240 +68.61.181.236 +181.139.69.35 +81.97.200.135 +85.241.89.210 +181.67.37.52 +164.114.255.173 +188.239.82.36 +62.141.214.30 +95.26.16.140 +42.209.200.80 +218.8.223.179 +217.42.8.13 +73.162.213.147 +122.138.21.239 +185.54.176.242 +98.167.116.215 +36.77.228.67 +223.90.2.226 +82.215.191.78 +218.206.143.64 +27.26.237.178 +27.225.155.151 +179.49.102.185 +101.14.87.53 +93.196.160.48 +143.176.60.186 +50.89.252.64 +1.202.68.46 +71.126.138.139 +188.158.133.253 +166.123.188.107 +51.174.239.234 +67.215.234.242 +76.1.134.36 +52.192.155.175 +84.18.119.234 +79.18.202.147 +121.222.73.221 +158.222.239.15 +179.177.43.162 +245.244.203.252 +146.95.242.153 +188.138.94.6 +86.156.226.66 +90.60.78.18 +151.228.203.83 +189.149.246.159 +183.204.177.60 +134.17.164.102 +67.185.236.237 +186.28.41.137 +96.245.102.206 +77.40.117.225 +86.134.143.53 +189.26.178.186 +0.0.0.64 +93.38.185.182 +180.214.232.78 +177.114.233.126 +92.109.225.38 +151.20.68.225 +49.255.228.150 +191.17.29.196 +114.125.149.172 +74.10.198.250 +87.117.14.188 +167.157.167.178 +69.4.130.106 +1.9.103.84 +254.155.170.131 +94.122.254.101 +212.140.117.196 +91.218.192.254 +1.181.176.1 +37.147.40.195 +85.212.12.143 +114.125.150.132 +67.193.70.129 +50.137.110.171 +118.98.74.149 +36.236.99.199 +222.82.139.110 +189.52.85.213 +121.112.208.42 +80.12.42.213 +73.131.151.71 +86.221.246.54 +73.154.137.10 +168.161.213.249 +142.197.30.169 +84.2.177.43 +208.91.65.91 +112.112.190.4 +187.16.54.162 +95.211.138.15 +101.184.251.38 +182.142.43.177 +85.25.217.233 +68.50.166.6 +89.201.6.46 +184.170.76.217 +68.97.157.47 +29.148.176.21 +253.34.102.37 +188.122.17.106 +100.64.0.89 +84.228.187.106 +125.253.98.143 +5.139.55.127 +194.77.215.7 +172.98.67.19 +188.194.187.126 +95.71.0.181 +187.56.142.137 +82.77.94.120 +139.241.166.128 +52.69.137.234 +78.36.35.83 +58.111.133.220 +171.4.220.133 +95.189.190.104 +87.216.73.94 +97.83.186.179 +120.25.82.229 +0.0.0.1 +109.67.222.205 +91.180.146.248 +37.49.216.254 +182.45.125.86 +85.73.201.73 +132.92.239.41 +37.164.187.157 +88.18.22.169 +193.182.144.63 +88.135.94.147 +81.110.75.241 +80.1.123.53 +192.95.29.153 +95.220.88.244 +112.112.188.194 +31.6.51.49 +100.4.173.207 +185.25.45.46 +101.105.32.19 +37.47.155.236 +24.241.116.254 +179.188.245.56 +71.82.140.179 +115.215.51.18 +71.80.195.179 +178.191.252.18 +61.231.60.197 +46.59.171.28 +0.0.0.142 +82.249.246.200 +87.97.47.27 +188.62.172.124 +91.6.98.40 +188.0.188.74 +79.195.183.127 +31.180.245.158 +23.25.16.149 +108.49.208.179 +97.117.190.119 +52.69.7.50 +253.87.194.56 +77.13.71.77 +99.34.125.115 +166.43.133.127 +147.229.131.89 +177.101.241.42 +201.252.151.49 +31.163.39.220 +86.84.255.120 +82.14.188.95 +73.132.50.37 +91.157.152.223 +70.29.41.215 +83.8.185.20 +180.110.220.196 +70.209.27.44 +157.75.45.18 +58.183.4.214 +79.234.0.139 +87.225.75.214 +253.116.217.73 +235.128.20.67 +68.35.218.223 +66.8.215.80 +212.18.53.63 +115.215.48.197 +37.17.110.193 +79.203.85.172 +84.251.35.122 +61.73.72.210 +79.210.110.126 +171.77.20.16 +184.53.32.11 +217.189.252.124 +117.140.238.53 +24.183.33.107 +80.135.97.247 +72.131.30.33 +87.134.114.216 +185.160.115.32 +91.121.77.74 +201.43.115.207 +177.103.62.111 +92.39.199.238 +151.228.200.248 +85.107.113.247 +170.158.145.240 +165.120.172.217 +92.112.224.28 +113.200.249.59 +73.138.193.253 +60.93.169.83 +97.121.110.16 +86.202.218.31 +83.239.255.137 +200.158.31.29 +112.97.50.124 +69.242.153.187 +114.232.38.157 +178.214.174.216 +104.40.212.43 +182.216.164.245 +87.171.219.248 +124.120.207.153 +217.103.73.143 +106.51.142.231 +211.25.18.221 +89.70.164.231 +92.124.68.237 +109.130.152.173 +83.209.191.200 +15.6.191.43 +78.250.28.168 +82.251.8.238 +178.84.101.85 +14.201.207.233 +217.114.218.24 +77.179.142.212 +41.250.177.207 +62.235.239.245 +63.87.77.227 +91.115.185.67 +79.23.58.90 +105.155.235.244 +211.149.148.151 +178.57.215.184 +80.234.101.152 +72.181.217.90 +86.199.138.253 +188.168.148.238 +254.174.0.233 +50.107.155.144 +5.141.122.230 +109.239.49.207 +74.208.133.18 +2.83.86.10 +97.127.111.116 +68.104.3.247 +63.87.254.89 +49.50.194.74 +60.236.198.201 +183.161.195.249 +71.91.2.177 +92.226.122.184 +138.255.221.36 +63.87.253.154 +94.253.50.178 +212.159.19.195 +92.38.96.94 +151.41.189.140 +25.121.150.189 +185.111.211.234 +49.113.3.148 +72.160.90.147 +68.133.5.18 +73.15.181.118 +171.4.191.111 +92.239.95.120 +66.220.241.138 +109.184.12.218 +95.57.157.86 +69.165.159.4 +1.114.12.3 +79.151.138.210 +31.173.84.242 +59.182.173.53 +78.51.249.222 +5.153.233.50 +63.87.77.227 +12.13.193.226 +106.121.37.171 +82.35.28.15 +109.165.15.183 +114.125.186.117 +42.81.69.211 +82.95.80.121 +68.109.194.64 +113.76.171.156 +117.151.143.244 +165.176.66.238 +178.234.24.73 +2.133.83.42 +31.6.45.42 +188.62.172.124 +92.101.205.105 +187.199.118.69 +46.28.207.25 +5.141.88.128 +87.72.36.124 +86.5.219.17 +123.136.107.70 +174.21.240.69 +83.78.179.150 +178.161.195.243 +188.28.158.229 +151.60.151.172 +190.182.248.6 +85.59.160.162 +187.122.220.36 +67.43.103.242 +0.0.0.110 +118.136.221.0 +49.216.103.31 +115.153.8.95 +89.12.99.213 +84.222.251.243 +75.134.29.103 +92.101.208.247 +173.62.188.225 +109.200.248.23 +92.226.124.165 +193.0.150.215 +173.94.93.166 +5.157.127.25 +201.152.195.28 +95.105.232.42 +109.120.8.198 +85.140.2.237 +79.234.14.192 +87.76.48.72 +162.216.113.202 +174.117.17.165 +217.70.251.133 +186.226.4.238 +116.216.30.43 +174.68.93.191 +87.110.59.78 +75.97.243.43 +184.164.147.82 +50.166.108.126 +91.79.95.254 +93.152.140.29 +87.153.10.251 +83.11.241.98 +124.178.37.111 +94.137.105.252 +2.234.231.42 +122.102.120.14 +110.22.138.153 +80.229.146.133 +0.0.0.5 +77.101.242.198 +77.176.215.31 +67.147.220.161 +87.68.47.27 +174.119.217.129 +31.163.72.108 +254.56.34.109 +104.246.50.10 +169.0.180.167 +37.214.159.121 +85.140.32.148 +213.157.232.237 +5.228.254.16 +169.68.87.71 +193.251.199.74 +93.134.233.56 +79.114.201.200 +95.25.11.132 +122.3.232.6 +37.35.202.126 +108.180.220.182 +94.113.110.166 +162.244.194.217 +72.193.217.148 +0.0.1.14 +62.235.113.235 +67.215.228.42 +67.87.55.27 +125.175.99.248 +75.93.169.201 +93.56.174.191 +67.191.50.73 +209.216.234.233 +91.41.177.107 +60.54.39.103 +149.210.169.35 +177.233.154.114 +191.125.178.7 +60.228.34.85 +14.200.115.30 +94.51.155.118 +109.106.141.54 +217.207.221.148 +0.0.192.18 +59.173.119.99 +104.34.16.248 +31.6.51.209 +78.223.238.225 +82.228.210.199 +78.140.145.204 +172.0.20.56 +77.40.101.158 +150.116.38.121 +176.194.128.57 +217.63.66.209 +176.100.185.142 +81.214.183.78 +77.51.129.215 +134.17.142.28 +191.183.185.38 +178.212.129.67 +186.136.90.152 +98.109.109.18 +169.1.156.117 +95.233.11.213 +74.114.131.34 +31.201.224.201 +67.215.14.106 +73.154.233.125 +151.80.206.105 +151.28.169.241 +78.34.149.97 +68.47.96.9 +186.212.204.252 +254.203.115.98 +217.118.81.232 +95.17.55.225 +84.50.21.116 +91.64.49.12 +46.99.51.224 +89.0.25.155 +98.207.89.152 +131.77.218.144 +24.160.54.59 +183.135.255.214 +2.245.77.239 +176.112.17.175 +188.232.105.1 +221.225.215.118 +218.132.39.89 +187.37.246.193 +201.235.130.141 +188.138.103.170 +162.216.46.89 +180.179.159.84 +124.230.230.109 +101.98.48.226 +177.153.51.198 +85.10.105.215 +85.195.52.90 +190.43.242.28 +85.165.175.23 +80.220.233.195 +37.247.74.122 +74.216.53.45 +63.87.255.249 +86.107.200.45 +41.250.124.244 +160.176.0.59 +37.59.43.20 +172.213.53.116 +213.176.250.157 +0.0.0.0 +221.213.53.114 +151.66.57.27 +83.134.98.230 +195.252.66.164 +84.122.243.22 +76.99.191.1 +188.221.219.218 +93.163.238.185 +83.30.56.1 +89.235.193.205 +120.55.80.212 +180.160.208.238 +86.223.152.65 +208.91.67.210 +5.9.85.14 +11.103.108.217 +176.193.89.71 +72.2.173.59 +111.19.89.24 +89.139.127.139 +69.62.191.21 +180.113.16.75 +70.65.184.2 +85.155.21.252 +205.251.171.136 +86.163.87.41 +73.249.211.100 +173.78.137.215 +83.32.189.210 +125.193.127.160 +213.141.130.188 +109.90.233.211 +178.150.46.178 +96.126.123.143 +185.160.93.175 +223.155.189.229 +42.60.202.210 +86.172.142.87 +139.129.6.134 +184.53.32.91 +63.247.147.166 +81.227.127.72 +68.187.104.58 +77.250.240.247 +93.84.218.136 +79.20.177.132 +25.91.113.253 +166.43.133.127 +68.145.236.222 +95.153.133.128 +81.11.221.15 +177.222.55.54 +109.188.121.5 +82.206.16.181 +200.169.190.69 +52.17.153.30 +145.61.201.188 +86.151.253.117 +123.160.91.203 +70.161.125.201 +88.122.97.63 +45.58.235.215 +85.25.133.20 +92.52.46.192 +37.79.147.28 +176.49.58.12 +95.79.92.81 +93.213.114.163 +98.248.223.158 +155.143.84.52 +2.245.71.45 +94.212.25.44 +91.210.217.236 +92.0.247.245 +200.180.105.149 +14.103.87.110 +104.60.128.188 +219.81.88.121 +114.125.191.35 +154.41.2.78 +89.0.227.251 +73.162.147.161 +77.178.71.82 +175.161.227.110 +213.79.43.89 +77.180.230.9 +188.162.166.129 +83.83.215.161 +182.251.115.159 +5.157.127.9 +178.2.77.70 +177.32.17.30 +5.9.106.132 +69.125.220.19 +137.139.150.40 +91.66.164.90 +125.42.214.46 +100.34.196.211 +65.133.53.103 +60.183.26.161 +186.107.171.14 +178.70.2.31 +91.64.157.58 +83.5.84.249 +101.177.228.206 +217.28.8.217 +94.137.39.21 +186.209.60.113 +79.112.135.7 +58.108.204.196 +69.46.195.222 +98.109.85.249 +178.93.148.1 +143.158.205.99 +58.104.63.171 +77.248.189.104 +72.173.205.206 +82.114.48.17 +31.179.120.196 +79.167.253.182 +108.230.191.120 +173.75.216.132 +2.95.174.223 +91.105.238.172 +68.196.122.205 +92.245.163.204 +241.39.170.118 +83.99.132.252 +172.10.132.218 +31.6.50.196 +58.249.97.239 +50.187.203.251 +59.182.158.38 +89.34.237.101 +101.19.154.97 +87.15.141.177 +96.248.122.64 +109.106.142.132 +50.58.53.206 +91.54.71.195 +25.114.17.18 +59.174.146.0 +78.63.158.220 +71.9.184.136 +5.157.127.33 +213.57.47.20 +189.168.126.45 +46.224.228.235 +229.47.32.222 +88.248.100.82 +85.197.19.38 +115.188.241.78 +31.6.50.95 +78.134.123.108 +109.152.181.20 +86.3.186.97 +68.104.62.36 +78.46.189.202 +119.253.64.38 +194.24.182.27 +254.150.54.5 +31.128.48.7 +176.109.185.70 +184.177.84.234 +71.126.175.159 +169.210.77.243 +94.192.36.236 +79.187.125.210 +74.75.117.59 +50.171.157.120 +112.112.191.165 +213.227.218.12 +78.223.238.225 +200.97.160.153 +136.199.215.163 +69.50.180.171 +94.181.237.248 +128.72.211.244 +78.29.71.253 +73.17.56.135 +187.137.141.92 +107.170.218.161 +24.122.34.75 +67.92.231.9 +164.215.245.107 +84.113.163.33 +87.76.60.133 +178.16.84.239 +146.255.183.137 +185.107.165.72 +207.244.76.221 +72.207.105.140 +95.38.170.40 +93.178.75.250 +77.255.46.168 +162.244.195.40 +151.16.163.106 +98.164.3.225 +93.80.180.153 +72.64.153.101 +178.45.141.202 +183.193.134.145 +217.196.194.186 +131.179.31.62 +88.66.9.87 +87.17.142.17 +81.145.148.2 +65.92.15.105 +90.255.126.133 +151.41.139.205 +71.100.179.172 +77.40.116.208 +77.177.222.210 +178.94.172.138 +123.201.5.103 +143.208.176.2 +5.144.98.76 +95.82.177.105 +199.176.38.93 +206.248.184.220 +37.187.115.45 +13.79.168.143 +109.161.99.181 +24.72.54.78 +119.145.7.57 +93.113.192.203 +178.155.116.99 +33.46.246.221 +128.90.61.238 +50.149.51.96 +74.72.225.204 +77.119.128.8 +77.178.111.213 +185.17.204.218 +192.71.151.83 +169.0.124.8 +71.183.46.106 +115.215.51.5 +77.241.47.222 +186.214.130.111 +0.0.0.0 +24.19.7.146 +201.213.47.94 +118.240.102.196 +195.248.186.129 +74.74.64.161 +71.227.98.164 +85.178.113.164 +183.99.42.210 +109.252.14.160 +127.181.247.52 +212.106.58.65 +170.105.173.75 +83.144.81.18 +184.1.3.151 +31.154.81.26 +68.96.174.79 +23.242.177.47 +90.202.85.19 +84.237.86.19 +76.94.17.92 +95.90.230.89 +220.244.238.129 +230.24.45.148 +81.245.247.106 +78.156.165.8 +78.216.88.12 +80.110.82.25 +123.211.43.41 +26.191.188.74 +37.214.7.200 +37.219.153.191 +216.172.142.97 +24.184.243.173 +178.79.164.165 +99.245.240.217 +iguana_bundle_set: no bundle at [2] +DOGE AUTOCREATE.4000 +new 1st.2 +BTCD.RT1253730 u.2507+c.2507 b.2507 v.2507 (0+230/230 1st.2507).s230 to 2507 N[2508] h.1253730 r.1253730 c.1253500 s.1253730 d.0 E.2507 maxB.64 peers.27/64 Q.(0 0) (L.1253730 2507:230) M.1253729 fa9dcf690dc038ec898789aa123350628f29ec4c2be538f725b2df766b00013e ledger.a80cd39714953dca bQ.61 0:03:39 stuck.0 max.0 +ramchaindata have 2:0 at 0 | 1082 blocks 564.678kb redundant xfers total 2978.180kb 18.96% wasted +new hdrs.txt 472 vs (confs/DOGE_hdrs.txt) 402 +iguana_bundle_set: no bundle at [3] +DOGE AUTOCREATE.6000 +DOGE.RT0 u.1+c.1 b.0 v.0 (0+4/2000 1st.2).s0 to 3 N[4] h.6001 r.4005 c.4000 s.4005 d.0 E.2 maxB.770 peers.1/256 Q.(1995 0) (L.673274 336:1274) M.6000 abdde162c2e54c80948c5395a39f6ca239ae3a0763bf9efbc85a85d01477b1fc ledger.00000000 bQ.62 0:00:36 stuck.0 max.0 + parse error block txn_count.2, n.451 len.-100 vs recvlen.452 from.(146.0.32.101) +EAC 146.0.32.101.block len mismatch -100 != 452 + parse error block txn_count.2, n.451 len.-100 vs recvlen.452 from.(146.0.32.101) +EAC 146.0.32.101.block len mismatch -100 != 452 +DOGE.RT0 u.1+c.1 b.0 v.0 (0+337/2000 1st.2).s0 to 3 N[4] h.6001 r.4338 c.4000 s.4338 d.0 E.2 maxB.770 peers.1/256 Q.(3315 0) (L.673274 336:1274) M.6000 abdde162c2e54c80948c5395a39f6ca239ae3a0763bf9efbc85a85d01477b1fc ledger.00000000 bQ.62 0:01:12 stuck.0 max.0 +DOGE BLOCKS.6250 RECV 3707.250kb ave 607.4 | dup.1057 553.301kb after.3 0.594kb 13.529kb/sec 100.00% +>> addcoin.DGB +launchcoin.DGB name.Digibyte +NETMAGIC dab6c3fa unitval.1e nBits.1e0ffff0 +COIN. serverport.(127.0.0.1:14022) userpass.() RPCport.14022 P2P.12024 magic.dab6c3fa +start.1471732214 +ADD ALLCOINS.(DGB) name.(Digibyte) size 4044312 numvirts.0 +BTCD EAC DOGE DGB allcoins +pend.(4096 -> 256) MAXMEM.4.00GB enablecache.0 VALIDATEDIR.(DB/purgeable) VALIDATE.1 RELAY.1 +launch.0x1ce400008 coinloop for.DGB services.0 started.0x0 peers.0x1ce9de000 +begin coinloop[1] DGB +i.8 m.8 numiAddrs.8 + netmagic.dab6c3fa init.(DGB) maxpeers.256 maxrecvcache.4.00GB services.0 MAXMEM.4.00GB polltimeout.10 cache.0 pend.(4096 -> 256) +clear hwmchain +DGB MYSERVICES.0 +genesis.(010000000000000000000000000000000000000000000000000000000000000000000000ad0f7d7518fc1e90ed28bd0e444ccd8e24d94688355705ed2142006b49d9dd726a62d052f0ff0f1e2459250000) zcash.0 len.80 hash.7497ea1b465eb39f1c8f507bc877078fe016d6fcb6dfad3a64c98dcc6e1e8496 +>>>>>>>>>> iguana_rpcloop 127.0.0.1:14022 bind sock.37 iguana API enabled <<<<<<<<< +size.248 genesis block PoW 0.000000 ptr 0.000000 +parsefile.0 confs/DGB_peers.txt +done parsefile.0 (confs/DGB_peers.txt) size.0 +parsefile.1 confs/DGB_hdrs.txt +DGB.PEER CONNECTED.1:1 of max.256! 212.129.1.77:12024 usock.40 +DGB.PEER CONNECTED.2:2 of max.256! 178.33.228.14:12024 usock.46 +DGB.PEER CONNECTED.3:3 of max.256! 157.161.128.58:12024 usock.47 +DGB.PEER CONNECTED.4:4 of max.256! 104.236.32.184:12024 usock.54 +DGB.PEER CONNECTED.5:5 of max.256! 108.61.10.90:12024 usock.48 +DGB.PEER CONNECTED.6:6 of max.256! 66.228.56.115:12024 usock.51 +DGB.PEER CONNECTED.7:7 of max.256! 167.160.36.126:12024 usock.52 +188.67.20.239 +92.110.103.112 +50.181.25.214 +50.76.102.9 +95.71.78.78 +109.228.4.100 +46.244.202.244 +88.3.193.105 +66.87.99.109 +24.224.18.93 +31.50.204.103 +105.158.127.63 +95.208.248.55 +72.171.192.188 +78.55.208.177 +78.8.2.228 +41.251.218.111 +173.28.178.229 +173.230.171.42 +95.211.134.28 +112.215.66.73 +77.173.130.232 +84.82.58.78 +109.145.153.156 +218.250.211.68 +141.211.155.93 +184.147.141.21 +72.191.195.23 +89.14.21.102 +1.0.0.0 +77.231.219.235 +13.92.243.94 +148.244.110.9 +93.104.119.79 +248.245.199.94 +188.4.40.193 +24.76.184.164 +89.75.71.107 +186.146.153.110 +87.217.126.168 +201.37.161.46 +188.162.39.231 +82.196.1.102 +189.140.140.184 +2.85.58.108 +59.49.159.208 +181.57.49.203 +171.149.2.249 +109.158.202.20 +85.165.205.22 +89.245.125.162 +46.70.170.189 +82.131.95.26 +83.38.181.78 +89.216.157.182 +173.210.233.18 +84.135.85.92 +93.128.165.45 +95.103.137.123 +83.243.219.3 +188.131.93.196 +83.22.231.158 +106.216.179.12 +14.192.213.52 +178.120.203.65 +92.249.249.175 +201.242.41.172 +151.228.122.105 +89.240.155.8 +78.8.98.33 +77.85.118.243 +151.15.31.42 +46.0.139.87 +125.160.197.79 +177.9.68.134 +86.31.36.91 +177.39.37.17 +217.235.244.72 +numtx.2 len.445 tmp/BTCD/RT/9db5e1adb2273c47f5d9d87cb33027cb3977688bc21992c5a353a713cae54422.raw hwm.1253729 L.1253730 +37.204.72.127 +92.37.46.31 +42.61.166.126 +BTCD Q.(9db5e1adb2273c47f5d9d87cb33027cb3977688bc21992c5a353a713cae54422) +42.112.237.73 +87.113.49.184 +93.33.1.88 +115.72.193.11 +86.135.20.143 +95.54.189.185 +82.74.43.190 +109.108.198.27 +50.153.151.32 +94.41.189.160 +50.126.114.236 +86.134.157.123 +92.145.13.111 +189.151.142.230 +108.61.228.25 +201.191.195.235 +113.254.168.141 +193.77.243.16 +220.179.36.72 +62.92.112.6 +78.28.250.81 +94.1.9.162 +197.119.104.39 +181.73.86.156 +188.220.132.161 +81.154.37.205 +114.243.109.38 +80.234.237.54 +124.40.244.90 +200.75.102.219 +190.67.216.182 +117.194.33.218 +85.178.73.121 +94.189.195.54 +42.119.218.128 +178.8.217.246 +79.129.191.41 +76.179.165.105 +217.235.246.193 +62.87.191.169 +105.225.82.183 +197.117.160.173 +31.57.195.195 +112.215.123.103 +188.221.167.127 +50.153.150.252 +96.240.84.92 +24.216.240.158 +159.8.124.180 +88.134.116.127 +176.14.105.238 +186.91.238.219 +119.59.148.45 +91.152.30.22 +223.204.251.231 +217.217.206.202 +178.33.209.212 +14.192.213.244 +190.77.92.178 +190.79.114.204 +41.244.240.53 +72.137.216.110 +95.71.122.120 +92.157.156.178 +90.26.144.244 +84.135.85.92 +188.129.107.92 +91.115.55.194 +101.98.215.166 +78.84.119.222 +81.234.218.87 +77.253.20.26 +49.81.161.1 +95.79.204.23 +189.217.250.0 +108.117.162.252 +24.217.39.5 +88.30.205.112 +174.88.126.8 +68.195.171.102 +211.205.165.22 +184.5.10.222 +79.44.22.115 +2.96.253.212 +180.252.99.168 +86.166.50.110 +84.79.112.88 +190.70.89.83 +118.213.127.232 +90.255.102.242 +63.87.255.251 +250.31.16.246 +115.70.4.78 +42.118.109.18 +71.254.160.56 +84.147.117.226 +72.220.145.211 +27.55.211.239 +189.162.41.151 +46.190.34.42 +151.61.105.117 +145.52.163.202 +88.88.17.50 +159.206.179.155 +24.20.198.24 +116.228.220.90 +128.72.185.199 +120.144.72.51 +78.69.230.184 +114.121.154.67 +188.196.160.204 +178.184.15.205 +87.242.49.243 +156.17.80.242 +69.114.82.72 +89.37.62.17 +180.241.51.70 +2.96.250.196 +50.191.20.165 +86.135.21.114 +83.26.96.53 +83.11.171.209 +109.90.216.94 +95.30.175.90 +173.28.197.230 +83.185.91.165 +125.160.199.117 +99.242.169.14 +93.81.240.99 +200.116.33.70 +5.254.97.76 +74.93.202.189 +111.240.212.81 +85.99.37.229 +197.37.149.32 +25.215.93.124 +177.249.207.13 +83.230.167.102 +151.225.69.1 +46.244.218.156 +87.14.218.26 +45.56.151.21 +86.181.101.168 +87.5.22.81 +37.146.68.48 +192.150.150.4 +178.162.217.145 +95.24.41.110 +213.198.237.54 +78.6.102.70 +50.153.149.36 +45.56.151.111 +83.37.188.164 +201.243.6.169 +146.60.60.174 +46.109.129.53 +5.56.29.168 +87.174.21.43 +88.183.207.177 +95.8.63.0 +190.79.6.198 +50.169.246.145 +73.18.105.88 +46.165.228.119 +189.202.88.14 +178.73.196.42 +93.33.10.136 +76.164.228.226 +186.90.2.208 +188.9.165.185 +54.84.26.112 +109.43.3.224 +75.111.51.213 +75.156.118.46 +91.158.215.5 +50.92.17.249 +46.254.11.158 +119.104.153.35 +79.117.65.63 +134.3.52.202 +58.9.84.79 +71.236.205.20 +36.77.53.226 +189.162.241.66 +173.192.176.155 +186.31.38.190 +68.38.91.132 +186.146.136.133 +104.193.10.252 +81.100.220.75 +190.74.29.208 +148.251.19.213 +171.39.27.99 +113.167.204.14 +5.44.173.27 +128.90.43.127 +86.160.91.44 +74.51.57.173 +5.141.169.226 +187.101.142.19 +89.176.160.79 +188.73.192.57 +151.25.116.38 +69.164.195.142 +83.79.83.89 +148.67.110.53 +83.36.252.241 +119.94.224.223 +183.198.204.209 +75.18.41.253 +68.45.101.13 +201.248.21.151 +79.112.46.242 +209.240.42.164 +202.62.16.184 +37.46.120.8 +197.202.245.82 +86.178.41.209 +90.104.92.241 +36.77.54.235 +186.88.137.96 +73.171.102.18 +174.61.149.195 +90.0.104.178 +190.88.244.75 +193.92.113.47 +5.238.230.209 +179.55.42.75 +85.75.31.235 +219.79.191.98 +63.131.190.227 +93.170.111.72 +83.27.106.105 +94.74.124.50 +95.219.101.18 +178.157.238.33 +85.76.55.161 +173.74.170.43 +79.236.241.93 +73.246.93.168 +81.44.223.141 +214.104.252.143 +120.59.90.181 +187.136.8.147 +79.206.165.26 +90.163.244.24 +188.69.199.38 +108.19.160.97 +88.113.24.32 +79.245.223.4 +76.189.155.179 +198.8.80.42 +178.115.130.209 +31.23.254.160 +46.244.201.131 +93.138.0.190 +37.146.126.21 +177.225.193.106 +86.189.14.29 +190.204.45.31 +92.43.188.19 +118.68.183.197 +31.14.92.129 +37.235.136.34 +201.240.218.44 +187.255.236.182 +186.155.16.238 +158.69.31.37 +2.102.255.77 +188.191.23.100 +90.244.39.181 +66.228.50.86 +79.45.210.96 +178.217.28.60 +188.4.143.63 +95.73.247.153 +23.233.28.199 +178.120.157.94 +87.169.172.89 +178.122.64.75 +1.52.142.34 +23.92.210.2 +41.96.46.230 +212.228.253.143 +176.222.254.161 +185.9.113.48 +141.211.155.93 +195.225.189.201 +130.25.88.216 +24.122.34.75 +72.241.236.178 +5.69.126.45 +116.12.60.74 +200.75.100.33 +36.78.197.169 +213.186.43.35 +80.110.112.148 +31.208.121.209 +190.36.221.26 +125.69.36.198 +218.166.40.153 +90.1.218.225 +0.0.0.0 +109.81.214.244 +0.0.0.0 +145.133.165.175 +187.75.18.65 +79.16.101.103 +186.79.30.184 +2.100.80.66 +81.245.103.159 +49.49.140.58 +213.125.176.82 +88.141.107.40 +115.184.229.102 +188.108.111.118 +177.205.72.70 +41.95.222.186 +193.191.182.129 +105.100.15.198 +189.217.124.237 +5.104.119.177 +95.114.91.93 +39.255.148.136 +187.224.3.46 +2.85.50.94 +67.60.37.68 +217.28.15.120 +92.127.115.141 +222.243.244.245 +99.224.255.173 +100.32.32.157 +63.245.12.218 +190.37.210.73 +90.31.193.71 +189.219.123.4 +71.197.2.127 +1.56.139.42 +178.13.156.31 +27.9.99.29 +67.179.30.187 +2.85.51.146 +114.244.50.22 +84.147.127.16 +83.223.168.28 +118.211.231.131 +151.227.55.136 +188.143.73.66 +79.133.135.189 +109.74.162.141 +94.189.210.210 +104.45.151.45 +176.9.65.41 +1.204.248.148 +88.231.216.214 +95.26.169.115 +73.182.210.38 +176.85.59.61 +0.0.0.0 +46.127.223.159 +5.140.203.56 +213.74.111.185 +202.62.16.44 +94.208.224.23 +5.55.219.24 +202.62.16.185 +87.202.20.199 +188.193.66.115 +2.103.201.46 +113.254.170.53 +66.55.134.215 +79.255.228.15 +190.207.219.55 +82.34.182.46 +86.2.137.161 +85.26.186.57 +185.48.37.18 +163.157.186.231 +144.76.107.81 +85.76.79.28 +92.124.35.133 +195.154.223.134 +214.20.111.167 +81.167.129.247 +103.238.131.9 +116.1.79.170 +213.111.129.137 +80.130.219.93 +41.96.44.147 +142.217.6.115 +125.160.197.79 +BTCD Q.(9db5e1adb2273c47f5d9d87cb33027cb3977688bc21992c5a353a713cae54422) +46.0.123.80 +42.115.112.202 +45.74.37.191 +50.247.211.162 +86.31.128.135 +88.152.187.216 +109.81.208.9 +151.246.175.245 +96.19.205.233 +206.255.73.147 +0.0.0.2 +5.45.62.132 +86.172.87.26 +46.127.3.79 +41.13.28.225 +85.23.47.0 +94.214.154.144 +84.147.115.39 +39.48.117.118 +85.253.131.68 +90.171.247.95 +20.221.160.10 +177.204.181.73 +52.160.104.172 +109.202.103.170 +176.101.222.25 +193.140.108.200 +93.34.38.192 +87.188.231.31 +79.88.68.160 +202.62.16.250 +91.156.99.163 +105.226.24.161 +80.106.197.143 +184.58.176.59 +79.203.74.2 +47.72.75.30 +60.50.198.153 +83.78.39.182 +190.202.240.41 +179.182.173.68 +91.141.3.205 +115.234.72.83 +105.229.17.151 +104.200.154.4 +112.198.90.66 +91.241.96.80 +91.213.143.252 +79.46.237.32 +68.7.221.120 +124.237.96.40 +94.237.69.213 +37.49.195.93 +41.150.92.101 +152.7.224.4 +117.93.41.45 +186.93.147.31 +46.208.8.139 +101.175.148.10 +66.87.97.220 +190.177.79.90 +109.149.125.213 +191.182.113.42 +92.124.24.164 +94.66.57.14 +167.114.210.50 +68.186.235.174 +5.80.233.62 +187.200.216.7 +88.3.62.153 +178.65.220.234 +161.10.149.45 +79.203.64.189 +53.193.238.189 +190.37.33.237 +113.64.8.2 +119.250.170.96 +84.57.37.17 +74.12.132.227 +151.15.140.162 +87.123.84.175 +178.21.53.32 +79.245.200.245 +80.106.197.231 +95.145.103.100 +213.87.135.19 +68.247.63.230 +77.243.183.6 +79.41.177.89 +160.76.210.181 +92.236.185.152 +84.138.79.116 +89.67.104.161 +109.126.239.154 +201.29.103.139 +141.169.131.222 +188.196.185.78 +37.193.83.134 +151.33.30.14 +185.46.249.145 +94.66.222.49 +93.137.184.82 +187.143.212.81 +188.246.88.206 +83.22.216.151 +100.68.32.93 +2.134.151.183 +171.96.167.239 +105.107.10.11 +177.11.141.37 +173.75.34.129 +95.252.103.149 +179.55.38.106 +85.62.66.80 +176.94.190.132 +99.115.55.175 +124.179.114.122 +46.229.142.239 +5.164.175.33 +87.105.139.236 +190.77.15.100 +109.169.249.4 +87.64.198.235 +213.151.10.46 +109.130.11.141 +176.108.251.252 +98.90.66.93 +23.102.39.37 +95.91.216.136 +187.74.67.39 +24.65.239.116 +201.243.120.205 +177.39.36.198 +71.31.222.58 +167.58.82.108 +95.211.188.20 +79.245.211.20 +62.158.140.92 +120.56.210.60 +41.96.87.98 +152.234.187.32 +83.18.161.60 +223.207.223.48 +222.222.0.100 +191.111.154.157 +0.0.0.2 +72.186.22.189 +99.199.0.43 +91.141.0.23 +187.170.111.199 +31.201.226.136 +75.192.154.137 +94.109.73.107 +76.26.221.186 +192.252.163.166 +115.87.132.101 +177.39.38.229 +58.109.155.212 +85.114.184.188 +71.91.68.75 +2.222.243.0 +108.24.75.98 +125.37.77.218 +190.207.174.146 +177.148.198.206 +92.37.37.214 +94.23.213.47 +186.89.117.109 +151.66.226.64 +178.162.217.141 +190.203.216.244 +93.117.170.201 +37.187.27.4 +152.251.182.108 +65.19.193.61 +83.29.138.193 +116.86.244.49 +93.136.96.112 +84.35.252.67 +90.110.135.137 +69.36.215.49 +198.8.80.74 +202.29.213.22 +67.188.197.9 +90.202.161.107 +95.211.184.238 +95.99.201.198 +82.22.16.148 +77.243.181.197 +37.113.210.202 +24.224.208.222 +27.0.87.66 +49.224.208.189 +195.240.97.58 +114.250.97.42 +173.245.195.146 +213.137.36.3 +113.135.133.32 +105.233.77.238 +83.7.184.139 +79.112.77.62 +116.49.162.24 +91.105.23.69 +24.196.86.99 +68.7.186.217 +79.16.22.134 +73.24.73.220 +49.102.165.36 +85.192.189.44 +201.209.204.52 +82.57.120.206 +82.249.167.111 +190.252.108.184 +37.113.160.17 +85.115.248.16 +89.12.212.63 +184.180.177.220 +84.43.156.72 +5.238.193.243 +79.133.153.174 +94.209.4.28 +71.15.250.17 +93.129.131.196 +5.71.235.230 +89.182.253.209 +189.62.64.38 +213.152.161.40 +41.105.232.168 +117.64.78.83 +78.47.193.211 +92.110.103.112 +219.108.240.211 +100.119.4.182 +194.44.30.2 +100.87.134.150 +78.0.38.171 +115.178.197.85 +71.194.69.143 +109.173.7.165 +2.85.50.0 +101.98.215.166 +88.3.182.224 +104.238.174.163 +92.146.35.80 +130.125.76.216 +67.204.18.28 +109.43.3.68 +95.73.31.110 +81.4.217.106 +70.29.238.151 +192.153.117.80 +115.230.151.184 +186.116.109.197 +85.214.106.35 +178.44.18.77 +104.207.136.88 +90.58.15.188 +112.208.104.65 +109.93.163.111 +67.32.161.202 +79.184.170.208 +125.162.110.180 +171.250.154.38 +85.76.13.139 +176.69.119.54 +68.188.86.244 +1.0.0.0 +162.199.254.242 +115.87.132.196 +127.208.79.146 +105.225.199.114 +175.137.181.138 +109.121.5.170 +89.16.155.243 +77.106.143.102 +190.51.144.246 +186.36.144.204 +36.77.7.80 +192.226.172.95 +106.51.72.108 +65.78.170.163 +181.49.78.74 +108.216.28.224 +91.48.62.129 +128.71.66.238 +94.70.30.51 +37.214.177.82 +5.220.233.170 +77.46.212.194 +71.47.188.11 +79.208.99.94 +131.94.186.32 +212.112.150.250 +117.79.232.179 +36.85.114.168 +83.9.53.181 +171.149.2.249 +46.98.111.246 +31.135.217.98 +36.78.199.223 +177.135.31.118 +64.214.214.26 +187.252.248.11 +174.52.86.133 +232.139.5.49 +79.24.221.192 +31.173.121.85 +2.218.14.123 +93.151.50.62 +113.254.165.23 +84.26.74.79 +46.196.248.137 +92.177.39.117 +213.137.36.3 +201.185.2.118 +185.45.13.150 +67.86.22.30 +98.225.134.65 +190.201.194.107 +71.1.243.123 +2.30.202.79 +178.221.143.49 +62.68.98.105 +79.204.129.29 +24.126.75.249 +46.164.162.209 +191.36.205.39 +186.14.170.191 +100.68.67.248 +31.132.225.141 +49.196.10.208 +120.144.147.163 +217.235.247.159 +5.141.220.57 +104.156.228.78 +72.220.67.181 +94.190.41.3 +201.51.32.43 +37.112.82.224 +171.96.167.13 +185.3.151.76 +109.167.253.97 +104.200.151.45 +217.95.237.148 +79.30.78.159 +212.228.253.143 +162.156.12.78 +77.79.183.87 +188.36.91.25 +184.97.246.75 +24.114.65.30 +98.167.190.207 +93.47.132.54 +46.28.102.197 +89.38.35.81 +85.150.137.211 +76.18.138.1 +95.153.135.215 +115.64.230.105 +86.133.95.54 +109.43.2.201 +104.200.151.28 +95.237.83.104 +80.236.18.96 +100.69.171.221 +178.223.4.97 +112.215.124.145 +190.192.23.70 +31.53.114.101 +2.125.75.60 +185.132.31.250 +179.55.73.194 +209.128.32.96 +189.81.73.33 +81.141.1.94 +96.245.155.8 +187.71.53.134 +31.210.181.216 +58.179.179.121 +198.27.81.25 +202.62.17.29 +217.235.247.159 +109.200.105.116 +37.212.78.20 +94.230.147.32 +74.129.51.67 +86.95.134.254 +71.79.59.180 +179.232.147.95 +154.98.227.46 +42.116.94.38 +59.172.134.35 +81.155.43.125 +120.25.220.239 +43.249.128.178 +153.163.198.9 +76.27.82.111 +84.161.245.57 +70.197.9.56 +177.205.76.64 +86.178.41.209 +2.217.129.142 +86.115.124.76 +85.192.155.40 +50.23.65.53 +185.65.132.120 +186.88.105.155 +74.110.18.17 +83.131.227.230 +2.122.179.220 +188.69.193.229 +90.1.201.108 +36.228.0.209 +79.116.46.102 +113.173.78.173 +79.235.240.183 +69.55.253.225 +87.185.5.10 +109.222.133.209 +71.97.31.194 +94.205.1.88 +192.0.246.12 +95.153.132.252 +78.225.114.147 +46.65.47.27 +191.242.108.6 +2.25.83.199 +67.219.165.208 +107.153.110.3 +46.166.188.201 +62.210.142.205 +186.93.227.223 +96.31.213.190 +117.81.188.30 +68.42.43.10 +5.14.59.177 +151.238.38.228 +128.70.67.115 +79.50.98.29 +204.210.192.216 +49.237.141.56 +157.161.128.58 +91.48.43.147 +163.172.5.218 +97.107.170.148 +5.71.235.230 +87.112.213.139 +84.6.14.89 +158.181.103.107 +217.253.250.52 +186.14.225.8 +151.227.90.42 +187.189.89.65 +46.217.87.64 +187.147.162.219 +110.115.32.92 +0.0.0.0 +109.43.2.172 +62.84.92.133 +217.235.253.237 +46.98.12.7 +64.238.142.34 +81.153.30.185 +84.135.89.49 +109.208.162.161 +171.96.168.43 +189.208.224.10 +87.146.1.30 +131.170.5.3 +184.147.110.200 +95.24.125.242 +83.87.59.199 +73.148.83.188 +95.141.27.42 +189.187.23.217 +100.3.40.210 +189.144.214.86 +202.62.16.6 +80.30.27.202 +178.40.244.207 +217.235.251.141 +37.14.206.225 +177.32.113.77 +31.10.148.216 +76.97.73.147 +138.186.31.224 +50.82.8.135 +195.208.169.199 +31.215.252.166 +87.102.171.10 +71.220.184.56 +191.34.104.210 +106.51.68.190 +188.27.207.162 +88.217.180.79 +145.249.122.58 +85.241.84.162 +114.125.189.65 +68.118.145.246 +31.5.84.134 +78.8.79.103 +79.245.211.138 +189.27.245.23 +62.210.129.149 +95.153.130.87 +50.203.141.242 +115.87.121.70 +120.24.185.169 +122.169.144.108 +79.203.109.201 +39.36.126.201 +50.115.175.125 +42.115.32.180 +147.102.7.140 +5.141.222.22 +121.219.34.189 +189.250.43.81 +91.48.62.22 +178.64.4.120 +5.42.93.15 +113.254.170.32 +218.10.254.174 +90.26.107.13 +182.87.167.75 +42.3.196.180 +93.205.27.117 +124.122.40.135 +93.3.222.243 +110.137.164.148 +80.233.175.26 +201.248.29.162 +151.250.29.8 +27.55.88.115 +90.191.107.13 +124.171.65.134 +136.19.111.83 +201.4.93.39 +100.96.96.80 +59.60.142.66 +128.75.207.123 +101.40.2.34 +200.82.195.152 +60.36.104.63 +94.68.239.19 +186.241.88.87 +213.10.208.153 +190.201.211.71 +49.15.134.85 +93.208.97.238 +125.164.131.170 +174.136.99.162 +70.21.184.26 +79.19.139.179 +108.24.81.3 +192.169.99.5 +189.203.252.6 +190.71.185.20 +195.209.48.241 +73.194.194.246 +86.128.193.18 +24.246.1.124 +139.192.136.198 +0.0.0.0 +5.142.17.20 +79.250.34.211 +125.253.100.212 +98.226.165.234 +2.85.63.4 +156.35.41.121 +24.157.203.140 +184.65.51.56 +208.167.254.83 +86.145.48.164 +95.53.33.237 +95.25.224.237 +66.115.115.71 +37.110.42.40 +179.43.169.226 +36.77.56.163 +213.151.0.157 +83.110.15.125 +92.24.138.189 +121.97.142.141 +219.73.15.219 +199.48.245.136 +197.37.109.104 +41.96.181.99 +24.207.31.254 +88.217.181.55 +BTCD received.(9db5e1adb2273c47f5d9d87cb33027cb3977688bc21992c5a353a713cae54422) 62.75.145.171 +112.215.124.101 +87.185.17.73 +83.81.128.127 +174.116.154.161 +112.198.90.66 +24.6.230.63 +217.30.64.174 +79.107.70.67 +88.232.120.46 +80.135.27.68 +70.51.113.56 +95.17.245.173 +190.53.24.149 +99.121.207.38 +187.10.148.221 +187.113.141.19 +81.141.9.113 +197.202.207.40 +64.237.37.121 +186.89.165.251 +142.217.0.115 +92.54.117.105 +24.36.232.237 +104.156.237.45 +83.61.204.226 +104.245.235.99 +197.229.24.58 +BTCD RTiterate.1 offset.230 numtx.2 len.445 +95.26.99.197 +83.185.84.90 +25.30.29.187 +82.150.59.202 +217.44.16.68 +BTCD txid.(bea6e13bf3e2a8fd110d7dbdbebc381b2e3d41e937e6ec969fb2db3b6659e86d) vouts.1 vins.1 version.1 lock.0 t.1471732213 1 +107.153.110.4 +5.83.18.254 +42.2.89.228 +41.105.224.24 + script type.0 scriptlen.0 +42.203.128.15 +128.71.66.238 +171.5.189.218 +117.52.89.217 +unspent[460] <- 0x1de9653f0 +84.161.57.134 +149.154.194.207 +1 RRjK2yufHUbEBDSBGny9Xgwz8bxiWBC3m7 0.00000000 h 0.00000000, cr 0.00000000 deb 0.00000000 [0.00000000] numunspents.461 0x1de9653f0 +94.68.53.253 +83.238.218.135 +88.232.141.237 +BTCD txid.(5859a4f02452c290a319caa7787bf56df27736ea801bc2d3d8aae852cc2ff23d) vouts.3 vins.1 version.1 lock.0 t.1471732213 1 +37.79.166.32 +111.69.249.244 +79.245.200.98 + script type.0 scriptlen.0 +219.79.24.40 +114.221.101.214 +unspent[461] <- 0x1df020700 +46.172.223.168 +189.214.6.82 +86.216.248.101 +1 RRjK2yufHUbEBDSBGny9Xgwz8bxiWBC3m7 0.00000000 h 0.00000000, cr 0.00000000 deb 0.00000000 [0.00000000] numunspents.462 0x1df020700 +190.236.62.194 +114.215.108.16 +78.12.45.89 +188.29.165.91 +21201.209.186.95 +104.129.28.138 +0290.26.80.8 +88.207.15.213 +cf189.33.207.221 +90.231.249.237 +128.68.191.167 +b380.107.67.242 +125.205.241.137 +3e79.245.220.195 +53.193.239.40 +e4202.62.16.79 +aa181.62.175.109 +85.212.88.66 +5080.215.234.95 +83.5.157.96 +213.24.135.217 +c237.24.152.116 +96.51.33.189 +93.116.236.201 +ad254.159.87.143 +119.247.152.218 +51201.210.134.209 +190.205.77.192 +0f5.254.97.91 +101.191.38.98 +193.92.193.216 +ee189.157.62.249 +24.112.51.69 +8378.194.124.49 +79.44.244.208 +cd91.61.91.168 +190.206.173.34 +7782.176.210.145 +116.14.165.116 +58190.219.122.15 +143.48.117.192 +6a178.234.120.45 +0.0.0.0 +1788.254.73.55 +128.72.218.191 +6278.226.118.202 +83.254.56.120 +fa254.107.115.127 +94.132.250.81 +24177.134.15.73 +88.75.246.64 +69190.72.183.146 +1a78.43.75.120 +185.19.23.255 +188.67.232.196 +9f177.158.244.187 +167.114.210.50 +2d109.221.4.90 +50.100.47.236 +e3178.254.189.80 +218.18.250.73 +104.200.151.35 +5e219.73.12.245 +99.231.166.10 +7b5.141.203.4 +79.101.223.117 +1579.245.200.242 +93.104.125.110 +1781.182.88.122 +83.36.209.130 +2846.59.37.170 +90.191.107.13 +c9180.242.27.12 +187.212.0.46 +8c78.8.11.132 +92.80.241.212 +ac148.240.4.249 + script type.12 scriptlen.35 +77.218.228.54 +93.170.111.46 +45.18.172.187 +217.253.224.100 +179.34.61.194 +95.211.188.21 +24.114.54.208 +91.48.40.244 +50.141.78.149 +2.24.124.97 +88.254.126.246 +36.83.169.217 +93.220.95.29 +46.198.202.96 +81.141.23.236 +1.190.67.181 +182.165.46.188 +188.246.79.155 +79.183.22.252 +122.105.192.219 +190.201.165.99 +199.48.243.62 +115.66.217.157 +178.234.10.109 +5.165.99.135 +95.159.217.77 +148.198.187.153 +89.142.190.82 +178.168.98.175 +68.197.64.6 +113.254.165.210 +77.54.234.91 +107.182.228.5 +14.192.208.7 +84.105.251.196 +59.58.245.158 +110.168.231.209 +86.176.46.245 +186.90.170.255 +121.214.138.124 +79.245.207.48 +91.221.191.67 +31.132.225.141 +185.38.0.66 +179.55.38.56 +82.176.12.130 +82.240.26.30 +114.244.63.142 +201.242.169.121 +201.242.65.143 +24.224.18.228 +178.59.210.188 +151.80.206.110 +178.0.4.123 +200.84.239.151 +193.191.182.129 +120.144.12.147 +5.89.197.88 +113.254.165.199 +140.168.246.252 +188.134.46.175 +202.62.17.29 +80.215.178.164 +178.234.138.208 +109.43.0.79 +112.198.77.150 +79.40.96.252 +81.141.8.117 +217.235.251.238 +78.137.13.183 +79.204.185.44 +181.208.17.17 +188.73.193.11 +172.206.235.188 +45.18.172.187 +95.137.245.107 +113.187.0.202 +95.113.55.151 +92.102.77.39 +54.84.114.124 +92.127.0.85 +87.185.27.131 +115.87.57.186 +81.141.9.194 +27.130.69.137 +69.167.27.161 +79.19.139.179 +unspent[0] <- 0x1de965ab0 +186.104.194.203 +79.245.219.154 +1 RV6H9qZuGy1wPeNeLisvdAeo44ZhgNdWZF 25.18000000 h 322.37935027, cr 25.18000000 deb 0.00000000 [347.55935027] numunspents.1 0x1de965ab0 +95.153.134.7 +46.246.53.6 +2.85.61.30 +87.20.19.191 +109.74.173.65 +2189.237.21.10 +1.0.0.0 +0285.178.67.47 +87.245.50.14 +cf109.172.15.13 +110.184.11.142 +94.242.253.47 +b3148.101.58.204 +179.148.153.247 +3e86.184.140.225 +69.164.198.161 +95.89.172.77 +e4131.246.225.154 +185.54.176.240 +70.52.148.148 +aa213.55.176.159 +177.133.204.246 +217.71.45.241 +50186.214.224.142 +158.255.208.153 +116.252.202.50 +c2198.98.118.241 +189.230.248.129 +5.138.217.118 +ad178.223.29.34 +76.214.117.231 +142.217.13.41 +5124.86.110.55 +104.156.240.159 +89.182.54.95 +0f223.204.249.139 +46.147.5.238 +ee91.48.57.111 +88.241.49.194 +83190.207.231.49 +178.121.115.104 +190.80.140.20 +cd53.193.239.184 +98.124.243.45 +7766.25.183.201 +85.175.20.156 +89.178.7.220 +5841.105.238.117 +46.5.17.18 +120.164.44.57 +6a23.19.99.99 +186.92.215.94 +17178.234.212.119 +109.76.80.59 +6277.168.118.113 +84.55.21.83 +155.138.228.234 +fa37.235.146.166 +87.1.100.199 +219.73.15.54 +24184.166.27.254 +79.245.215.231 +0.0.0.0 +6989.243.57.163 +188.67.255.22 +79.204.180.184 +1a95.141.28.122 +83.152.218.44 +9f201.29.97.210 +2d79.102.35.55 +114.23.246.230 +e381.162.122.102 +46.167.64.6 +5e77.172.117.134 +66.188.53.149 +118.208.67.20 +7b49.248.141.218 +62.113.202.175 +89.88.92.232 +1599.230.140.54 +124.200.255.10 +217.118.83.145 +17180.213.84.12 +79.245.218.167 +79.245.216.198 +28190.37.151.167 +74.87.88.186 +103.11.51.223 +c995.78.56.67 +121.141.52.83 +8c190.204.33.20 +178.120.96.199 +89.70.125.85 +ac91.150.150.10 +95.153.135.34 +46.159.211.91 + script type.12 scriptlen.35 +82.208.124.9 +187.79.201.156 +189.223.24.154 +unspent[1] <- 0x1df021380 +216.144.236.178 +183.44.24.92 +109.88.174.139 +1 RV6H9qZuGy1wPeNeLisvdAeo44ZhgNdWZF 25.19561271 h 322.37935027, cr 50.37561271 deb 0.00000000 [372.75496298] numunspents.2 0x1df021380 +217.71.46.52 +71.234.30.181 +45.56.148.19 +96.126.114.208 +219.90.169.227 +91.127.155.195 +152.236.18.53 +196.210.126.224 +78.173.51.220 +89.179.246.179 +1.0.0.0 +78.12.56.55 +186.93.42.117 +188.0.47.153 +213.103.202.73 +181.39.238.154 +189.13.228.11 +104.228.212.114 +216.144.236.234 +95.174.118.136 +5.254.97.75 +189.205.155.95 +162.219.176.251 +117.207.3.59 +79.206.172.204 +14.28.137.110 +91.158.214.192 +36.74.241.234 +151.238.70.86 +83.132.173.152 +62.4.196.157 +93.143.130.111 +193.186.75.63 +178.128.103.21 +188.67.35.161 +83.32.1.155 +109.74.155.246 +178.33.209.212 +88.71.238.22 +70.75.235.215 +104.200.154.25 +78.35.142.98 +89.212.229.112 +50.71.224.43 +119.76.74.173 +86.174.218.202 +216.231.140.113 +130.120.193.9 +95.106.184.230 +190.74.248.142 +37.113.132.32 +223.207.201.112 +36.78.195.142 +72.131.109.127 +50.46.209.204 +120.180.45.219 +118.232.25.14 +183.18.203.23 +104.156.240.206 +223.255.231.154 +182.249.242.1 +173.230.40.101 +213.176.245.198 +202.62.16.164 +104.207.149.1 +79.184.49.72 +78.238.254.189 +177.39.36.198 +187.149.224.11 +78.137.13.162 +5.141.220.191 +37.213.209.241 +188.105.65.2 +24.76.205.4 +84.19.166.59 +68.9.115.43 +36.83.38.210 +78.85.255.60 +186.36.78.101 +111.106.184.29 +69.172.159.46 +1 RV6H9qZuGy1wPeNeLisvdAeo44ZhgNdWZF 50.37000000 h 322.37935027, cr 50.37561271 deb 50.37000000 [322.38496298] numunspents.2 0x1db5c0830 +174.53.83.127 +89.164.158.156 +186.116.109.197 +>= RTnewblock RTheight 1253731 prev 1253730 +59.45.80.70 +186.151.63.70 +BTCD received.(9db5e1adb2273c47f5d9d87cb33027cb3977688bc21992c5a353a713cae54422) 62.75.145.171 +67.141.24.177 +186.212.213.173 +201.208.230.192 +87.158.141.2 +84.236.0.48 +223.204.241.22 +67.0.16.80 +104.230.82.88 +178.12.104.141 +64.219.84.21 +41.105.241.176 +54.165.27.102 +186.90.4.216 +173.199.65.48 +37.23.144.85 +82.232.14.27 +46.146.133.151 +176.65.127.64 +2.87.62.80 +173.189.166.149 +186.94.18.103 +95.81.195.38 +99.224.242.213 +223.204.242.4 +178.128.79.128 +31.181.197.19 +60.26.198.94 +79.167.251.27 +222.230.78.84 +190.255.14.124 +150.254.137.21 +180.252.107.21 +93.168.54.86 +254.198.167.212 +36.76.40.152 +121.45.12.104 +87.189.108.93 +39.48.56.63 +202.62.17.244 +78.10.239.51 +66.57.162.154 +112.66.50.86 +88.13.185.135 +178.223.12.7 +49.199.160.43 +70.44.97.147 +191.223.60.22 +84.198.202.93 +201.229.73.182 +82.169.246.212 +177.114.215.199 +223.204.246.82 +27.34.30.7 +190.201.29.210 +184.146.154.164 +145.255.21.14 +162.255.117.106 +181.73.86.156 +76.65.62.190 +218.142.99.184 +211.186.254.91 +67.140.13.51 +167.56.119.30 +174.77.224.21 +189.82.147.136 +77.243.183.105 +75.61.109.29 +46.31.38.113 +213.114.131.16 +24.166.104.143 +219.79.25.40 +78.35.139.197 +83.4.180.229 +184.5.8.134 +91.77.226.227 +41.96.65.27 +80.213.211.183 +0.0.0.0 +100.68.7.223 +77.51.51.85 +79.185.197.97 +89.117.26.93 +113.254.169.206 +46.190.63.53 +190.38.26.230 +109.228.149.33 +189.114.232.39 +83.10.98.169 +86.46.62.112 +103.254.148.9 +84.86.163.70 +112.198.90.3 +189.223.10.118 +174.92.36.11 +98.195.116.168 +112.198.100.11 +178.79.159.234 +86.159.35.225 +79.107.73.84 +0.0.0.0 +114.220.77.71 +171.96.167.117 +88.230.39.45 +187.170.156.12 +176.9.61.40 +84.154.93.193 +62.176.13.153 +37.161.62.109 +171.96.167.157 +85.26.186.30 +37.189.25.190 +110.168.232.103 +138.186.31.199 +89.178.177.95 +98.204.235.141 +171.96.167.66 +5.70.192.218 +223.225.157.133 +1.65.140.21 +70.197.4.246 +43.165.193.4 +93.137.123.103 +96.240.92.38 +77.222.113.102 +73.243.21.197 +182.249.242.24 +31.53.121.172 +89.18.181.101 +149.254.49.93 +208.54.38.181 +85.222.168.41 +177.228.70.157 +25.87.60.111 +109.79.186.146 +33.212.156.47 +201.208.169.134 +24.135.35.202 +5.184.57.137 +219.73.26.172 +108.81.43.50 +67.136.44.155 +88.217.180.105 +198.8.80.85 +95.24.99.127 +188.198.90.231 +100.88.8.110 +212.224.76.87 +78.225.56.77 +223.73.100.116 +198.14.244.224 +82.12.235.3 +77.243.183.25 +79.102.32.183 +2.102.223.238 +164.127.106.144 +79.54.215.101 +178.119.76.144 +77.7.151.32 +186.95.54.108 +109.209.255.250 +90.153.118.51 +181.113.99.121 +83.83.156.158 +2.30.40.79 +187.147.58.142 +193.168.1.102 +114.92.103.127 +81.44.47.135 +84.103.165.167 +179.54.78.187 +211.162.34.197 +0.66.235.206 +213.119.47.44 +152.250.88.148 +92.140.7.202 +2.85.218.25 +59.167.185.184 +71.84.43.181 +178.27.122.63 +116.109.234.74 +201.29.110.137 +50.81.122.236 +46.139.162.104 +190.38.76.64 +108.73.25.52 +5.2.66.120 +109.88.174.139 +185.45.13.149 +84.19.166.58 +172.15.0.107 +200.109.173.48 +82.3.89.105 +106.187.93.132 +71.127.232.3 +108.61.199.17 +92.157.132.151 +93.135.177.166 +118.68.183.197 +79.245.204.58 +70.59.17.67 +176.27.24.255 +174.0.80.58 +86.105.208.208 +69.130.145.90 +94.21.136.99 +93.70.165.126 +186.244.214.184 +70.208.6.72 +110.115.39.1 +177.134.11.43 +201.242.105.167 +66.87.97.216 +13.82.55.134 +24.204.194.99 +80.215.204.11 +81.37.70.35 +152.78.159.104 +210.117.92.53 +95.160.151.93 +2.221.77.195 +78.190.40.174 +114.125.189.252 +186.101.219.243 +79.114.2.189 +95.131.177.10 +174.126.221.216 +91.7.46.221 +187.234.38.167 +25.60.76.161 +91.139.221.236 +82.140.203.198 +201.208.217.173 +94.253.158.247 +205.220.163.91 +88.137.69.182 +216.186.236.171 +187.255.243.31 +190.75.169.137 +101.116.48.219 +217.71.45.38 +181.49.78.74 +155.138.230.198 +41.105.239.184 +92.156.199.252 +192.214.119.58 +162.216.46.105 +95.73.119.160 +181.51.139.104 +109.88.139.108 +174.58.201.144 +85.139.251.113 +173.65.180.70 +173.74.166.180 +68.252.8.213 +25.45.28.229 +175.155.181.198 +209.188.41.47 +13.92.176.214 +128.69.235.138 +100.74.170.249 +79.40.147.80 +180.248.225.211 +46.188.125.237 +141.134.92.64 +190.38.128.4 +1.204.13.122 +124.122.58.68 +172.77.23.103 +177.96.173.98 +181.167.138.145 +5.101.96.124 +210.146.160.42 +94.109.99.175 +93.232.125.163 +84.74.174.199 +88.217.181.126 +42.112.94.187 +69.231.32.212 +37.187.27.4 +95.94.90.176 +175.39.47.204 +41.244.243.113 +217.253.210.45 +87.112.147.66 +78.137.11.16 +178.205.63.24 +86.20.7.201 +203.98.92.90 +90.198.172.54 +88.184.162.93 +41.251.127.5 +5.140.151.235 +83.55.112.89 +114.88.20.31 +80.107.28.73 +209.222.18.59 +210.55.212.21 +189.26.142.10 +164.132.114.152 +85.2.192.58 +37.29.88.98 +188.0.41.32 +180.140.28.245 +212.54.195.10 +197.5.8.74 +180.183.82.151 +178.234.227.61 +95.26.126.37 +1.162.58.141 +175.38.196.103 +85.178.86.218 +165.255.209.173 +94.96.72.32 +5.107.185.176 +83.254.46.122 +184.75.212.106 +74.37.253.136 +2.85.189.49 +37.191.165.193 +79.30.200.54 +197.246.171.176 +82.170.44.250 +46.153.181.49 +78.150.5.84 +90.191.99.12 +23.253.50.163 +109.43.2.51 +83.52.88.212 +81.153.142.238 +37.140.122.89 +110.168.232.154 +185.132.31.70 +81.230.143.200 +201.199.205.220 +198.144.157.113 +219.141.185.129 +171.4.193.144 +87.178.160.210 +121.206.126.21 +177.205.17.74 +79.24.64.63 +49.145.241.19 +83.61.88.205 +189.251.27.103 +190.204.35.44 +178.79.41.195 +185.3.135.82 +109.93.171.166 +91.14.34.70 +173.189.165.44 +82.176.217.214 +83.58.96.125 +201.22.42.227 +186.31.38.190 +178.234.117.58 +186.90.84.129 +41.13.94.190 +188.19.174.10 +87.105.113.85 +212.255.255.216 +193.51.6.5 +188.252.211.72 +191.33.44.16 +84.77.116.152 +84.195.192.97 +199.48.245.187 +148.31.163.57 +109.74.170.77 +176.65.127.95 +176.86.236.251 +2.81.35.223 +91.64.101.150 +56.26.14.187 +147.30.158.158 +189.70.85.114 +79.145.57.93 +8.144.96.247 +171.96.167.30 +198.14.250.141 +213.111.179.40 +37.146.238.207 +1.54.59.157 +177.33.80.128 +75.76.66.211 +107.170.138.159 +91.48.50.43 +46.121.67.177 +84.147.119.76 +121.214.119.39 +81.202.115.42 +36.77.37.99 +142.176.53.89 +68.68.99.197 +171.149.2.249 +78.0.2.28 +75.152.212.205 +87.112.49.81 +190.204.138.145 +186.91.34.215 +79.245.206.218 +87.117.38.224 +100.67.2.192 +212.54.218.233 +171.149.2.249 +86.177.241.129 +68.229.235.123 +70.98.142.254 +2.62.48.147 +117.151.174.71 +85.25.200.102 +37.6.118.149 +176.217.230.27 +189.159.80.196 +95.28.56.184 +99.244.51.28 +90.136.151.55 +5.167.170.167 +98.28.128.199 +178.234.73.55 +176.69.119.54 +104.42.224.48 +39.35.109.251 +217.95.238.41 +85.115.248.49 +202.161.24.232 +173.219.77.171 +95.133.238.251 +105.156.36.240 +160.81.171.46 +96.83.29.78 +64.62.201.6 +201.210.253.39 +187.253.36.222 +107.197.166.48 +91.182.134.93 +154.122.77.205 +95.94.22.12 +213.87.126.149 +171.97.201.79 +201.205.37.36 +108.6.244.111 +165.91.74.108 +89.12.186.187 +95.105.179.120 +79.245.194.135 +53.193.239.158 +91.150.105.103 +1.178.246.229 +146.60.52.80 +93.134.122.186 +76.73.3.178 +2.187.202.96 +213.87.120.151 +171.149.2.249 +24.115.186.59 +67.248.113.187 +162.243.72.148 +188.162.238.144 +77.46.104.150 +151.236.243.19 +1.162.98.165 +84.236.82.109 +177.112.244.104 +46.59.178.254 +75.97.59.130 +187.143.152.243 +88.198.34.136 +119.224.16.252 +194.126.91.135 +105.236.200.24 +150.101.96.8 +109.133.158.114 +188.38.20.253 +2.96.162.96 +193.92.20.199 +178.234.232.56 +208.107.40.102 +45.56.39.12 +109.72.232.52 +104.156.228.86 +74.242.207.146 +203.87.201.150 +31.163.171.61 +82.211.60.143 +49.144.46.25 +95.134.62.105 +110.168.232.253 +89.164.200.11 +213.179.252.75 +77.28.221.221 +53.193.238.2 +178.115.130.126 +36.83.63.4 +130.25.45.30 +122.62.209.126 +91.125.251.114 +94.25.171.140 +223.73.103.224 +95.109.87.61 +93.81.56.225 +188.162.15.1 +193.253.37.245 +2.61.133.195 +87.143.227.193 +74.69.195.164 +78.148.161.220 +188.158.169.194 +78.36.111.52 +98.238.145.154 +178.216.252.11 +37.229.96.2 +62.74.26.240 +209.54.7.184 +96.126.114.208 +173.183.76.104 +36.76.4.71 +172.98.67.40 +213.5.163.102 +63.142.161.25 +62.31.208.119 +192.0.194.24 +179.212.185.123 +179.156.221.228 +162.17.238.97 +25.212.159.235 +71.190.69.95 +94.13.182.188 +151.224.181.140 +104.156.228.79 +86.81.111.103 +180.159.137.110 +75.189.135.43 +12.133.228.183 +89.164.225.231 +217.95.250.194 +108.6.204.184 +5.220.228.6 +2.134.174.247 +74.111.201.30 +85.23.36.108 +46.229.173.230 +50.159.60.56 +0.0.0.0 +120.209.131.70 +94.214.154.144 +24.19.34.151 +2.240.75.231 +190.211.210.173 +110.168.232.46 +100.36.231.56 +52.169.229.251 +84.27.153.252 +79.208.127.61 +88.19.208.245 +104.207.148.231 +113.254.169.78 +106.201.17.46 +104.156.228.115 +81.96.92.136 +24.135.13.180 +190.79.128.30 +87.6.44.211 +92.124.56.6 +121.98.132.121 +79.235.240.183 +37.113.168.57 +68.12.3.89 +0.0.0.0 +94.22.75.142 +209.188.57.202 +76.169.236.235 +190.203.14.155 +186.188.89.194 +178.198.214.231 +113.173.78.173 +189.105.227.187 +37.113.168.76 +31.54.226.182 +5.232.19.45 +79.233.162.230 +83.162.243.231 +86.151.81.47 +184.2.186.230 +79.16.139.147 +173.21.141.204 +39.48.143.86 +37.1.128.188 +128.90.88.154 +46.166.165.39 +71.177.2.102 +173.80.52.199 +69.253.5.33 +178.216.190.113 +201.248.244.231 +79.173.62.191 +5.151.152.144 +186.95.154.86 +118.68.183.197 +104.237.143.215 +79.51.92.72 +71.52.48.4 +188.29.164.13 +174.71.59.223 +219.73.93.18 +79.245.222.47 +124.122.52.91 +36.237.28.108 +130.180.219.150 +94.139.17.207 +250.31.16.246 +79.245.217.68 +79.204.141.9 +200.84.64.62 +124.168.172.177 +177.228.7.57 +84.198.17.157 +178.122.204.244 +78.147.75.63 +104.250.122.42 +46.253.253.126 +100.64.10.106 +95.81.213.232 +78.132.70.52 +151.228.27.238 +95.103.235.87 +37.214.14.94 +209.95.50.25 +97.121.165.49 +201.192.161.241 +95.24.214.142 +50.102.186.96 +124.197.6.10 +50.151.76.89 +77.173.22.8 +162.255.127.179 +222.65.218.221 +74.141.80.174 +151.227.55.136 +90.207.63.129 +190.204.34.118 +78.88.29.120 +31.51.151.170 +31.170.106.199 +188.32.207.210 +172.56.7.118 +184.171.212.55 +178.92.103.221 +92.40.183.177 +179.156.218.183 +93.190.139.37 +125.185.242.142 +91.67.130.158 +81.146.57.180 +60.205.112.102 +205.220.163.91 +88.254.110.55 +212.14.208.27 +1.39.60.213 +12.37.199.41 +108.61.221.226 +112.80.127.215 +96.46.195.24 +37.146.122.20 +41.224.164.213 +80.107.16.189 +79.147.214.108 +67.53.205.187 +115.28.42.60 +67.136.44.155 +84.3.93.11 +79.52.3.121 +62.46.200.51 +87.178.184.126 +188.245.241.79 +95.39.196.110 +73.43.102.217 +83.61.94.153 +111.88.32.19 +220.246.221.8 +186.91.83.87 +120.155.176.207 +183.149.49.252 +123.63.144.247 +93.34.34.141 +189.69.214.201 +31.11.78.216 +67.231.54.138 +213.140.237.233 +37.140.99.18 +109.226.90.179 +5.15.206.164 +172.248.91.252 +167.114.42.94 +213.16.190.75 +87.244.147.84 +106.187.36.44 +171.97.223.159 +24.121.46.171 +85.93.207.253 +216.58.118.36 +89.242.139.28 +178.0.4.123 +95.89.214.31 +85.76.102.200 +82.169.206.126 +78.150.3.98 +217.113.237.234 +71.208.235.223 +188.196.95.176 +80.249.81.117 +5.164.188.41 +31.185.4.33 +96.240.81.144 +181.44.114.97 +78.132.24.222 +178.216.120.222 +78.98.71.27 +78.43.68.161 +108.61.169.107 +186.147.161.15 +90.218.109.93 +0.0.0.0 +217.129.236.80 +77.105.50.192 +62.101.183.24 +188.76.15.37 +180.172.140.92 +115.198.14.122 +81.100.220.75 +190.77.15.100 +37.47.18.5 +213.122.124.131 +77.54.234.91 +93.143.214.74 +171.5.182.161 +198.254.204.153 +81.250.103.220 +179.43.151.66 +105.226.137.23 +95.43.216.3 +23.92.218.130 +79.166.4.165 +96.252.50.154 +205.220.163.91 +115.25.138.225 +43.249.129.196 +176.214.137.187 +101.98.185.172 +178.18.110.174 +94.20.241.217 +200.117.136.218 +201.4.93.39 +63.142.161.9 +77.243.183.20 +49.177.161.18 +196.217.160.51 +186.146.153.20 +23.241.17.48 +85.7.164.87 +37.151.42.182 +37.29.88.7 +84.35.203.85 +68.172.226.49 +96.240.236.32 +72.39.10.246 +92.76.239.3 +98.160.114.23 +77.254.100.185 +109.209.194.113 +130.211.249.48 +189.202.71.152 +82.103.141.140 +178.234.237.26 +14.192.209.247 +37.146.127.155 +134.249.158.190 +81.141.17.139 +79.146.10.254 +188.158.185.100 +171.4.186.77 +188.104.80.117 +151.55.15.80 +77.105.16.104 +217.189.224.20 +75.110.29.6 +99.120.77.119 +213.10.246.244 +81.10.149.108 +122.168.251.156 +188.208.112.70 +92.76.72.105 +79.184.14.112 +83.57.76.197 +91.48.48.77 +92.80.28.97 +179.4.168.182 +81.196.245.79 +217.235.255.172 +85.75.102.179 +173.74.166.180 +78.3.55.85 +116.89.62.24 +25.7.70.98 +188.129.87.191 +108.127.162.82 +174.5.185.35 +178.234.216.61 +201.143.101.125 +88.229.80.202 +85.26.186.204 +188.0.41.208 +115.87.211.67 +101.160.57.60 +79.114.108.172 +67.140.66.136 +176.50.134.28 +182.89.227.143 +128.90.88.111 +188.208.112.70 +217.235.255.224 +79.204.163.11 +160.176.69.211 +189.187.115.138 +197.203.78.235 +95.141.28.169 +172.89.205.21 +159.118.242.230 +95.179.62.63 +186.93.214.168 +178.234.63.213 +188.162.36.173 +217.118.79.25 +87.198.180.6 +66.55.134.213 +24.122.34.75 +87.103.52.73 +208.167.254.37 +109.88.146.44 +105.184.225.62 +73.90.204.141 +212.255.228.189 +202.80.215.115 +119.224.48.233 +176.114.191.253 +197.27.8.202 +42.115.18.149 +93.84.8.44 +1.162.86.234 +103.25.46.9 +152.23.21.142 +76.179.165.105 +62.133.162.222 +98.77.43.229 +78.80.76.82 +68.61.121.174 +186.95.86.120 +222.76.117.248 +88.91.76.98 +201.208.13.107 +109.43.2.115 +80.215.210.194 +81.30.71.45 +89.151.161.58 +171.39.68.224 +111.227.127.190 +179.232.244.239 +100.64.97.198 +66.32.255.192 +83.4.148.220 +110.174.123.194 +141.58.46.18 +201.253.41.90 +50.254.73.145 +71.7.113.19 +104.159.144.57 +121.208.106.107 +86.56.60.16 +46.142.40.17 +91.148.91.236 +95.90.53.237 +94.66.57.107 +223.207.122.199 +70.169.28.217 +202.62.16.168 +177.231.121.64 +95.147.181.131 +213.162.103.191 +190.202.250.145 +213.151.0.82 +84.63.33.137 +178.98.128.31 +219.73.15.219 +212.71.239.55 +204.11.237.73 +212.251.28.139 +109.151.26.71 +93.81.218.153 +0.0.0.0 +108.49.147.47 +79.152.183.84 +162.216.46.43 +182.239.166.75 +73.187.107.193 +93.127.76.65 +194.219.60.132 +89.38.35.81 +178.234.246.180 +83.249.178.255 +178.120.203.65 +172.58.139.124 +184.64.170.246 +46.19.139.182 +174.109.105.111 +231.255.154.44 +178.41.95.247 +68.7.186.217 +118.216.79.55 +175.208.141.224 +178.121.168.9 +197.27.90.215 +94.51.32.217 +81.240.52.24 +174.76.158.194 +114.125.191.209 +93.169.165.183 +70.79.67.146 +62.198.196.56 +122.82.162.156 +195.147.224.24 +186.77.195.134 +188.81.148.12 +188.73.254.84 +90.190.117.187 +37.213.170.13 +79.245.216.86 +213.7.35.207 +123.201.113.207 +91.241.96.80 +91.229.61.46 +92.17.118.188 +100.16.34.113 +90.199.36.236 +71.251.78.65 +179.197.169.12 +24.188.239.178 +99.183.185.69 +197.117.90.127 +178.222.68.33 +171.97.184.18 +197.202.234.106 +180.246.168.146 +188.19.161.137 +71.19.249.4 +68.235.182.101 +114.79.37.118 +106.192.7.54 +36.69.19.2 +78.250.126.154 +203.145.92.95 +62.102.148.183 +128.71.91.85 +78.28.250.66 +68.52.132.102 +73.214.142.184 +69.18.28.136 +185.128.41.158 +94.74.66.101 +182.187.123.236 +37.24.156.235 +46.143.69.22 +189.183.55.56 +36.78.196.123 +46.31.38.113 +90.217.93.166 +79.133.157.203 +180.129.159.1 +41.251.208.103 +24.186.232.5 +95.221.21.83 +15.107.231.112 +79.16.214.237 +151.249.96.73 +46.195.49.136 +89.210.24.145 +198.205.1.101 +188.73.252.224 +192.99.160.163 +83.165.85.219 +92.100.44.40 +53.193.239.251 +104.244.157.16 +177.188.17.204 +197.203.60.143 +114.88.20.31 +217.235.240.122 +149.88.75.65 +184.90.64.40 +186.90.98.38 +187.15.73.13 +174.77.224.21 +37.113.168.28 +209.107.214.62 +81.184.126.146 +115.70.149.131 +87.140.192.50 +81.109.222.243 +188.134.13.5 +78.250.241.41 +92.232.213.133 +91.115.55.194 +174.58.228.93 +202.62.17.10 +0.0.0.0 +95.52.190.92 +178.223.0.82 +84.55.16.81 +217.23.187.1 +100.10.59.5 +67.44.192.24 +79.245.200.52 +217.87.92.166 +69.108.3.158 +190.204.40.157 +81.154.204.185 +37.47.211.56 +70.181.47.97 +78.21.195.37 +95.91.241.81 +27.145.177.83 +83.27.161.92 +178.234.90.237 +201.6.172.44 +223.205.74.62 +81.229.37.193 +150.117.170.89 +80.47.94.236 +118.209.134.35 +43.249.129.196 +195.214.190.171 +186.119.252.108 +27.34.28.186 +83.248.25.82 +119.236.248.38 +156.241.140.131 +65.30.11.62 +87.64.212.160 +69.167.26.56 +91.156.41.30 +78.230.39.234 +99.121.49.140 +94.96.41.4 +99.187.33.246 +66.41.56.235 +36.255.113.156 +66.69.124.164 +82.21.95.51 +85.76.86.40 +5.13.171.55 +37.115.172.148 +224.245.98.190 +178.16.215.164 +178.243.204.40 +104.200.154.25 +173.74.177.35 +76.178.149.21 +95.72.3.129 +229.163.111.67 +82.20.144.232 +128.75.237.122 +86.57.197.105 +151.227.121.20 +190.156.192.88 +171.96.168.116 +41.150.141.127 +91.40.70.81 +82.54.32.17 +174.93.226.111 +61.195.99.101 +187.152.220.146 +190.38.6.28 +104.156.240.153 +186.93.165.61 +180.213.84.12 +68.145.81.59 +212.90.62.251 +191.43.19.200 +124.122.213.230 +79.235.241.133 +47.67.40.201 +82.168.170.109 +78.111.190.48 +87.185.26.148 +177.34.78.53 +83.61.94.153 +141.130.226.62 +80.121.28.99 +50.66.152.76 +131.173.60.240 +112.215.123.68 +190.38.48.14 +93.107.13.106 +173.221.226.116 +96.26.11.23 +142.166.71.215 +177.134.174.140 +86.168.201.42 +87.105.66.67 +178.131.84.160 +37.45.3.23 +37.229.121.72 +209.160.123.88 +84.31.242.4 +37.5.141.129 +179.209.225.212 +78.150.6.212 +151.66.229.34 +84.184.209.7 +5.80.54.19 +223.225.182.127 +65.26.54.236 +98.227.60.68 +173.185.69.84 +89.142.37.216 +5.42.17.207 +112.184.28.67 +190.198.36.172 +83.59.146.4 +188.183.117.146 +62.197.218.214 +46.244.218.156 +201.79.56.33 +186.88.71.213 +71.52.82.247 +109.240.39.103 +73.90.208.150 +165.255.122.178 +108.117.169.213 +191.223.196.53 +93.124.12.6 +60.211.181.34 +149.210.40.55 +32.117.64.178 +71.15.250.17 +197.229.28.177 +49.32.36.161 +178.184.63.128 +229.244.37.192 +24.171.125.63 +197.203.21.66 +189.97.76.94 +91.48.62.50 +217.228.64.245 +65.93.5.186 +200.84.68.224 +189.165.50.103 +76.202.180.86 +73.198.40.189 +79.41.177.10 +91.213.143.252 +46.10.100.20 +155.138.236.210 +217.89.0.213 +84.117.17.168 +81.153.147.190 +106.187.37.124 +79.116.46.102 +41.244.243.202 +193.107.94.5 +50.83.133.238 +176.58.22.253 +81.132.37.244 +92.43.188.173 +83.149.35.11 +79.32.103.236 +150.40.223.126 +84.135.83.89 +99.246.216.151 +5.80.240.84 +128.71.187.172 +84.81.98.206 +2.94.196.192 +109.221.51.167 +178.122.238.20 +202.62.16.108 +82.19.207.84 +178.120.180.77 +109.173.87.23 +188.146.72.127 +93.175.72.187 +201.130.5.2 +178.44.12.28 +40.87.147.250 +188.69.195.72 +84.159.232.37 +82.141.118.195 +223.25.25.103 +143.48.117.132 +197.6.149.103 +75.73.58.145 +66.228.56.115 +109.93.83.59 +93.104.105.193 +79.146.50.229 +79.245.195.18 +87.5.71.70 +86.81.209.28 +41.141.46.16 +217.89.2.42 +78.239.107.25 +184.134.70.35 +96.83.29.78 +145.97.231.240 +195.37.12.20 +76.68.162.94 +46.167.124.185 +89.210.204.47 +151.238.37.180 +27.159.20.249 +78.12.60.47 +99.250.53.196 +101.171.127.242 +212.228.253.143 +87.92.83.95 +2.5.78.51 +87.158.138.61 +163.158.223.125 +149.254.219.192 +79.112.46.242 +178.234.15.238 +88.254.73.55 +62.1.29.53 +212.228.253.143 +5.254.97.86 +188.162.132.110 +178.43.55.232 +83.60.248.55 +24.135.244.72 +115.135.47.10 +92.162.158.94 +112.186.124.56 +95.108.54.55 +213.24.126.141 +82.141.118.195 +223.204.248.206 +176.58.133.196 +104.156.228.71 +81.131.226.196 +151.72.136.1 +86.184.140.225 +46.98.12.7 +207.192.254.156 +124.170.23.36 +95.71.68.207 +219.237.242.60 +188.73.252.67 +128.75.237.180 +95.73.250.51 +46.5.195.24 +70.139.70.171 +87.95.233.26 +85.245.55.58 +91.67.99.12 +92.100.121.16 +91.182.0.44 +176.27.24.255 +200.146.57.130 +115.207.68.8 +91.63.1.128 +79.54.215.248 +83.143.240.35 +84.152.149.102 +191.32.0.88 +82.229.26.235 +84.154.93.193 +217.83.12.218 +91.154.8.178 +73.62.248.49 +24.217.99.228 +208.54.83.214 +188.103.157.164 +120.164.44.57 +31.3.26.210 +199.119.232.215 +89.245.109.97 +36.78.250.164 +198.23.103.69 +80.147.25.206 +209.160.123.53 +122.73.59.85 +201.141.39.232 +86.129.252.132 +52.169.229.251 +186.90.122.140 +189.82.147.136 +39.48.73.31 +152.234.187.32 +87.204.222.96 +67.60.16.219 +37.45.82.110 +115.28.138.90 +62.165.226.97 +138.201.65.88 +84.187.91.201 +83.78.9.216 +86.210.212.108 +176.104.184.50 +37.23.114.113 +109.204.154.88 +188.4.237.14 +84.152.140.60 +127.180.48.132 +181.29.63.54 +83.36.226.52 +122.62.12.87 +72.160.29.62 +79.70.51.138 +220.253.4.142 +62.63.82.172 +171.96.167.213 +93.43.160.238 +105.156.245.177 +216.172.138.189 +105.224.204.200 +80.215.170.87 +108.177.128.150 +196.215.25.200 +187.243.164.218 +77.73.137.37 +177.99.84.95 +202.62.16.58 +129.10.29.163 +171.96.168.32 +46.130.27.222 +14.186.213.191 +95.67.188.205 +79.107.58.23 +128.71.13.113 +99.186.49.28 +91.63.31.207 +80.213.230.192 +218.142.95.189 +75.126.73.56 +72.171.192.248 +91.44.228.200 +77.163.189.107 +41.251.48.199 +188.69.211.24 +177.229.231.37 +105.186.106.4 +94.21.126.37 +93.129.11.176 +190.207.68.49 +179.215.223.24 +198.84.201.135 +115.50.117.30 +83.160.90.35 +84.26.33.226 +171.149.2.249 +190.75.207.59 +14.209.137.220 +151.32.117.143 +37.112.87.206 +201.22.23.138 +83.57.228.86 +174.77.224.21 +0.0.0.0 +142.162.40.54 +31.181.188.236 +194.166.190.1 +64.237.51.168 +80.43.133.125 +109.227.43.129 +190.96.153.233 +201.210.140.73 +95.109.87.61 +77.254.148.133 +95.211.134.28 +80.213.122.68 +81.156.145.142 +86.151.81.47 +24.212.88.112 +50.162.194.86 +88.136.64.229 +190.73.75.228 +80.61.66.72 +37.78.168.147 +213.230.75.175 +98.21.141.197 +144.138.64.50 +81.184.126.146 +82.234.175.33 +71.31.111.170 +36.76.44.84 +189.219.201.55 +87.146.24.200 +90.227.32.48 +81.182.25.190 +100.68.1.55 +162.216.46.112 +24.119.48.249 +75.111.51.213 +87.205.196.58 +101.184.94.136 +83.161.137.46 +91.78.177.167 +189.150.138.34 +68.226.144.118 +178.234.49.0 +50.107.118.90 +78.34.4.22 +83.84.22.227 +80.189.22.170 +184.99.69.164 +199.7.156.142 +212.251.18.150 +118.209.75.208 +86.210.89.109 +43.165.193.4 +49.145.123.121 +24.18.171.156 +24.152.231.246 +190.204.5.222 +90.113.251.171 +95.24.56.149 +109.187.90.176 +89.182.24.153 +109.43.3.12 +222.243.244.245 +187.0.235.105 +32.149.215.132 +0.0.0.0 +217.44.160.84 +70.173.107.212 +109.74.162.200 +219.79.189.186 +193.106.215.193 +178.57.98.67 +187.152.220.146 +217.105.20.145 +1.0.0.0 +94.178.6.233 +95.49.168.186 +2.28.195.45 +88.75.32.126 +150.27.127.98 +189.202.64.210 +84.215.98.187 +1.64.26.102 +93.103.144.91 +5.135.36.128 +184.75.213.133 +185.29.164.212 +39.35.182.28 +76.107.228.95 +173.163.0.213 +69.162.195.208 +78.55.250.20 +118.211.234.7 +189.149.43.148 +190.77.242.77 +67.141.24.177 +23.99.59.71 +84.0.103.181 +37.213.220.12 +186.228.165.88 +88.71.176.152 +180.254.111.93 +24.246.95.6 +114.252.227.89 +182.111.195.163 +223.205.29.44 +181.112.107.95 +181.65.62.148 +177.170.155.183 +80.244.146.31 +85.72.83.210 +89.13.106.135 +1.162.89.72 +186.91.204.203 +186.170.85.58 +158.222.194.45 +190.198.36.172 +31.2.118.96 +112.205.152.222 +109.169.168.151 +70.196.196.25 +162.216.46.41 +108.212.84.178 +187.4.110.82 +2.96.253.212 +184.17.153.7 +178.55.248.191 +46.105.158.205 +121.224.229.225 +95.79.62.224 +95.221.211.55 +81.89.56.170 +37.78.59.60 +32.149.215.132 +45.52.184.11 +93.81.9.35 +25.128.23.157 +198.18.1.58 +120.141.142.237 +31.53.121.172 +73.180.62.121 +75.162.140.28 +192.77.248.3 +105.109.155.75 +190.99.218.59 +217.89.8.225 +178.115.131.56 +115.239.127.175 +190.198.5.210 +78.55.239.95 +83.20.69.109 +184.75.213.117 +209.195.113.177 +78.156.104.205 +87.100.158.128 +59.167.196.135 +193.33.91.218 +98.191.243.50 +92.112.239.165 +179.34.94.5 +223.25.25.220 +91.232.105.11 +94.51.110.100 +65.78.152.16 +81.240.52.24 +217.121.192.4 +178.42.208.214 +217.73.143.165 +54.210.100.216 +212.73.174.166 +86.175.85.205 +0.0.0.72 +197.228.134.60 +31.162.230.3 +84.19.166.55 +110.168.231.201 +62.167.128.54 +202.67.37.22 +93.139.171.57 +31.18.159.118 +50.53.104.249 +68.168.178.12 +209.197.162.172 +90.191.163.182 +83.4.80.106 +94.20.241.217 +173.74.172.37 +190.82.204.230 +85.155.6.145 +2.122.176.75 +186.185.169.209 +76.113.42.159 +219.77.166.186 +219.79.189.241 +79.245.209.254 +109.218.83.221 +88.23.123.143 +37.115.192.181 +95.174.98.218 +75.134.13.245 +94.209.121.137 +95.113.48.14 +189.157.46.152 +100.68.86.132 +89.245.126.176 +178.45.76.81 +174.25.200.26 +62.163.9.155 +85.49.23.66 +198.98.118.241 +77.234.44.156 +179.43.169.226 +85.217.41.209 +109.124.211.182 +83.153.29.186 +89.154.49.154 +165.255.211.181 +78.0.3.149 +173.245.195.98 +190.231.63.41 +86.147.60.147 +89.22.243.128 +213.152.162.170 +80.108.46.24 +128.90.88.11 +224.200.154.18 +91.67.34.202 +254.42.196.227 +79.245.223.174 +80.133.45.20 +208.58.41.133 +105.237.9.149 +79.200.67.185 +223.204.248.96 +89.39.78.192 +154.157.161.160 +178.215.168.129 +114.76.137.117 +173.75.18.157 +83.134.86.173 +62.158.150.131 +184.64.19.148 +60.17.235.231 +42.112.80.24 +93.170.111.115 +194.28.39.72 +141.237.27.57 +109.93.85.149 +216.180.181.48 +172.56.20.93 +76.242.145.138 +95.24.100.172 +85.26.186.204 +176.58.130.226 +85.222.42.211 +151.95.16.217 +36.74.94.208 +178.128.244.47 +167.160.36.126 +176.10.42.45 +178.234.51.251 +67.193.56.206 +188.95.206.133 +83.134.225.71 +186.14.240.71 +46.28.53.172 +95.67.173.63 +188.69.195.143 +196.210.126.198 +190.206.197.37 +79.67.123.101 +46.238.214.54 +47.64.20.211 +31.41.247.133 +125.142.30.68 +37.142.185.136 +189.138.63.24 +77.110.147.13 +82.119.13.10 +212.183.61.11 +94.214.163.25 +254.185.71.201 +26.162.173.209 +188.193.79.183 +190.39.38.49 +24.22.111.227 +71.175.81.45 +181.95.121.26 +178.93.129.60 +68.45.101.13 +81.154.58.116 +78.153.4.77 +206.248.172.100 +208.82.41.47 +50.172.89.183 +181.24.43.245 +98.223.62.66 +24.252.75.158 +2.121.201.171 +89.172.238.180 +192.214.119.58 +1.129.96.141 +107.11.145.246 +73.224.21.143 +184.155.200.186 +36.69.20.159 +62.101.183.24 +89.245.125.162 +202.62.17.54 +188.0.42.195 +188.29.164.228 +99.253.132.72 +130.180.220.8 +100.69.227.171 +54.86.84.160 +100.68.65.92 +121.220.62.161 +96.238.148.171 +188.77.49.237 +78.46.23.222 +109.121.29.102 +197.228.235.128 +2.12.99.12 +176.249.222.22 +82.176.89.129 +46.55.165.57 +79.200.222.225 +193.92.252.13 +118.209.158.228 +124.122.0.238 +178.128.243.39 +109.212.175.142 +183.50.224.62 +219.79.191.143 +201.209.130.164 +201.231.215.30 +164.67.192.103 +180.129.159.1 +192.99.217.31 +73.90.210.204 +79.45.210.96 +185.107.252.224 +105.97.224.170 +100.113.28.102 +66.96.100.24 +60.218.122.249 +189.144.45.28 +37.188.130.172 +100.65.150.99 +171.4.185.126 +81.141.8.117 +98.223.11.108 +2.92.58.180 +108.110.155.247 +14.98.83.166 +164.77.40.254 +50.153.150.172 +89.153.45.155 +203.222.146.55 +99.37.3.74 +139.228.0.80 +53.193.238.57 +193.107.92.232 +81.247.79.74 +81.214.98.49 +5.200.52.133 +212.251.27.178 +85.53.81.54 +217.123.121.141 +125.160.197.79 +104.200.154.26 +83.37.72.115 +181.1.68.23 +59.172.132.204 +108.75.178.165 +5.66.253.16 +185.37.192.112 +94.41.128.125 +136.243.217.171 +87.81.138.30 +107.220.18.70 +71.236.243.108 +93.164.7.181 +88.141.114.61 +79.134.38.179 +151.231.96.75 +188.29.165.196 +80.92.31.43 +186.213.104.163 +213.96.202.231 +45.56.151.17 +94.99.209.193 +112.215.124.182 +79.131.163.147 +66.26.153.172 +90.7.252.111 +178.222.27.190 +201.243.34.211 +83.55.65.150 +64.17.79.28 +186.93.30.93 +80.116.34.167 +93.169.135.5 +41.251.212.137 +87.144.11.117 +173.20.72.21 +69.243.228.52 +128.75.199.166 +96.45.237.72 +75.189.230.76 +231.157.187.212 +188.143.13.98 +68.34.214.8 +91.134.233.254 +176.248.175.132 +81.203.228.217 +171.96.171.118 +65.27.83.146 +95.26.230.15 +64.53.210.14 +188.114.23.6 +125.127.86.95 +71.53.155.242 +178.217.115.50 +89.237.38.235 +163.157.186.231 +79.184.121.102 +58.7.79.182 +186.116.227.215 +87.185.4.187 +217.253.209.157 +171.96.168.28 +36.83.43.11 +91.122.166.250 +112.215.124.84 +66.168.28.90 +1.0.0.0 +171.149.2.249 +46.176.102.2 +88.75.132.88 +217.116.211.114 +43.255.83.123 +80.135.14.197 +187.200.126.254 +84.2.110.235 +79.245.194.74 +179.55.77.60 +177.247.47.140 +50.153.149.124 +193.161.15.69 +82.236.72.55 +93.125.63.252 +178.65.14.106 +213.113.185.135 +155.133.16.26 +46.29.144.17 +149.202.44.159 +124.122.6.109 +68.186.198.147 +62.36.238.183 +81.154.204.185 +79.234.100.103 +1.0.0.0 +70.78.222.93 +84.19.165.213 +82.238.200.36 +37.6.242.90 +97.117.164.169 +83.4.104.110 +95.236.131.168 +72.211.166.102 +0.0.0.2 +46.253.252.140 +187.34.142.244 +169.0.73.53 +109.43.3.230 +91.179.123.166 +189.140.140.184 +178.164.143.158 +85.201.209.80 +63.87.254.188 +5.13.50.74 +92.144.200.122 +0.0.0.0 +78.87.102.229 +175.137.91.173 +117.207.10.37 +92.9.51.240 +192.99.47.172 +171.96.167.85 +96.48.106.63 +5.142.41.37 +46.217.84.125 +90.4.183.69 +145.120.12.175 +71.222.115.159 +174.126.221.216 +196.206.78.112 +213.87.123.163 +219.73.26.166 +217.120.200.182 +41.138.182.233 +2.62.31.79 +14.148.92.236 +191.33.57.182 +188.195.221.38 +178.35.140.252 +83.254.175.251 +88.217.180.135 +46.2.49.102 +89.22.172.159 +2.85.48.166 +197.211.52.27 +31.10.151.160 +81.183.132.39 +146.215.226.94 +50.183.63.188 +174.61.234.134 +108.252.201.93 +90.194.75.240 +188.26.139.49 +77.163.189.107 +208.107.130.112 +121.72.232.206 +24.0.101.211 +31.23.125.144 +78.108.105.3 +207.154.20.231 +79.152.140.12 +71.251.60.74 +92.110.79.41 +2.54.231.38 +173.219.7.133 +200.181.174.247 +174.55.206.7 +46.246.160.217 +122.105.192.219 +180.171.232.19 +80.234.141.228 +184.166.55.59 +80.135.30.123 +58.11.119.219 +201.19.190.183 +98.247.93.2 +98.21.117.65 +159.203.31.42 +46.72.147.197 +191.241.136.54 +188.190.2.136 +213.105.38.228 +181.41.210.93 +1.162.60.24 +177.249.151.161 +1.0.0.0 +109.232.51.32 +82.34.182.46 +80.131.62.65 +124.237.96.40 +181.164.39.82 +138.186.31.43 +187.63.6.45 +77.131.8.180 +190.36.51.51 +50.23.131.235 +77.105.24.110 +243.8.113.116 +172.56.22.46 +128.71.31.119 +67.245.82.244 +99.53.229.135 +182.178.100.105 +89.185.12.216 +83.83.161.46 +86.20.3.141 +91.52.13.182 +61.140.238.47 +201.22.42.227 +91.48.63.23 +32.230.230.72 +66.55.134.215 +5.80.54.19 +222.152.161.106 +185.29.164.237 +80.130.206.9 +207.204.233.23 +184.171.212.55 +87.112.147.66 +185.42.39.117 +2.62.52.96 +85.232.217.179 +84.103.72.150 +5.141.203.74 +253.167.138.14 +177.98.29.222 +178.120.162.160 +37.214.62.162 +24.144.61.126 +82.19.44.100 +192.241.254.114 +36.77.175.202 +108.26.55.253 +79.245.195.228 +119.86.47.160 +179.7.160.222 +112.65.211.229 +70.173.239.125 +98.199.85.134 +80.213.211.183 +176.97.36.140 +91.19.121.248 +24.217.245.101 +98.238.145.154 +79.125.205.26 +108.161.118.177 +89.168.217.136 +79.114.109.234 +188.27.207.162 +122.57.235.244 +159.172.226.177 +107.203.104.144 +254.92.232.178 +83.117.200.125 +70.53.183.31 +189.223.40.145 +37.76.68.108 +78.147.114.195 +2.176.151.20 +181.44.114.97 +78.8.109.43 +31.214.240.56 +53.193.239.36 +176.127.67.214 +88.167.140.73 +188.220.132.161 +167.60.146.106 +92.209.191.40 +100.68.88.0 +177.19.119.96 +217.195.246.98 +0.0.0.0 +36.78.249.30 +124.170.124.221 +222.252.59.19 +69.112.244.114 +79.30.99.74 +181.10.83.104 +79.245.207.112 +115.178.215.30 +171.39.66.125 +79.245.197.208 +171.97.145.198 +190.98.11.234 +91.67.99.12 +79.204.162.138 +150.27.228.7 +46.233.200.165 +77.58.253.73 +187.132.1.39 +79.245.212.85 +113.254.169.222 +5.52.11.13 +190.205.194.65 +69.165.128.9 +109.221.179.32 +128.227.44.156 +173.98.236.230 +217.216.123.34 +24.114.70.184 +112.65.0.74 +77.243.183.116 +95.113.213.5 +31.129.70.174 +90.69.147.20 +202.80.215.19 +50.168.101.34 +217.121.210.13 +72.202.129.75 +97.127.120.204 +36.78.191.143 +27.34.38.27 +80.106.197.231 +189.203.252.6 +188.196.1.166 +104.156.240.142 +31.149.73.49 +187.0.235.105 +52.11.78.65 +181.49.64.55 +128.70.44.218 +173.252.255.34 +100.91.29.206 +186.170.116.234 +186.203.2.32 +109.88.65.154 +93.104.127.247 +171.39.64.12 +83.168.150.119 +92.20.145.13 +2.146.174.242 +85.15.5.3 +212.58.237.100 +178.219.90.233 +109.88.155.108 +115.228.246.237 +78.129.153.58 +109.88.132.44 +181.64.88.109 +1.126.127.226 +125.237.122.51 +187.59.190.103 +82.56.22.225 +172.137.1.106 +152.23.21.142 +87.69.111.245 +99.112.7.5 +83.222.45.113 +178.254.190.206 +62.16.243.132 +201.83.108.195 +181.232.25.197 +114.96.153.143 +213.138.93.0 +151.72.136.1 +41.142.41.167 +177.249.194.77 +179.198.46.74 +95.111.236.135 +91.14.34.70 +182.249.242.10 +71.45.32.188 +88.196.236.26 +28.36.255.86 +189.114.235.27 +107.179.248.207 +209.245.155.235 +178.132.47.176 +84.188.65.226 +108.111.67.194 +95.85.55.153 +108.117.169.213 +104.238.187.114 +5.198.44.176 +124.198.205.11 +98.213.71.84 +41.143.233.44 +223.204.248.171 +93.156.82.36 +201.211.29.167 +41.239.156.148 +81.245.251.1 +24.230.59.100 +125.37.79.46 +5.88.72.90 +100.64.12.2 +201.201.215.83 +188.165.205.135 +60.228.7.131 +200.121.41.216 +193.92.31.61 +88.117.78.255 +90.154.75.175 +89.104.6.79 +190.62.160.125 +112.198.64.48 +90.190.69.165 +200.8.53.77 +216.158.224.240 +208.54.5.254 +73.197.227.38 +25.52.41.130 +201.167.47.254 +220.246.220.125 +85.242.25.243 +31.201.179.254 +42.136.208.211 +37.113.15.208 +84.138.78.96 +88.141.113.130 +31.10.159.200 +217.128.25.131 +2.147.213.24 +177.247.125.211 +99.225.14.89 +71.195.120.65 +62.2.218.10 +111.69.162.148 +109.43.0.79 +216.171.18.187 +62.98.223.129 +197.117.250.77 +0.0.0.0 +85.218.134.32 +173.45.173.72 +176.11.151.238 +109.43.0.198 +190.28.189.103 +85.26.42.127 +46.175.68.4 +77.71.24.63 +37.233.31.253 +213.118.105.27 +55.211.59.42 +178.65.202.255 +62.183.127.182 +172.65.249.192 +189.158.82.6 +46.98.124.49 +37.27.50.204 +190.204.175.75 +79.245.223.80 +82.47.20.169 +41.105.228.16 +212.251.28.229 +25.51.249.200 +188.61.142.25 +185.53.178.9 +87.78.23.245 +95.24.52.94 +181.27.150.162 +58.44.186.69 +187.246.242.110 +37.48.74.42 +223.204.246.232 +153.120.242.171 +93.81.24.169 +151.227.114.46 +74.84.26.219 +93.138.126.48 +81.130.224.89 +23.92.218.130 +64.191.29.26 +5.94.119.65 +189.165.16.244 +50.168.210.180 +91.48.34.56 +91.63.19.156 +0.0.0.0 +123.79.153.212 +108.40.13.187 +110.171.204.110 +217.89.7.46 +223.204.240.178 +73.27.251.141 +128.90.43.153 +169.0.170.28 +110.168.232.50 +24.79.43.15 +79.194.202.151 +90.154.75.175 +188.7.6.154 +217.235.227.209 +186.147.108.177 +92.80.10.182 +113.87.241.181 +195.169.155.126 +184.155.218.183 +188.89.24.254 +83.143.240.44 +62.47.227.63 +188.168.145.223 +99.122.104.173 +187.143.157.80 +173.178.61.115 +180.251.217.73 +117.194.52.63 +24.28.92.13 +25.15.9.35 +165.120.45.108 +83.11.178.19 +92.97.161.7 +82.249.77.22 +181.65.62.148 +186.213.102.132 +72.194.212.147 +25.152.243.103 +79.245.210.38 +99.95.217.55 +91.7.43.15 +199.202.216.171 +109.43.3.149 +84.111.148.18 +190.189.29.32 +100.64.30.28 +24.225.138.67 +165.51.103.243 +92.73.203.118 +82.225.55.132 +45.79.10.59 +106.192.22.127 +77.29.141.165 +41.250.109.214 +95.19.21.165 +85.75.79.133 +78.215.210.112 +22.29.73.140 +217.131.108.228 +199.16.96.145 +190.201.194.107 +190.39.10.186 +178.157.251.246 +93.38.167.117 +220.233.131.66 +100.78.98.103 +41.190.3.124 +62.28.52.105 +1.64.29.50 +41.48.21.132 +181.24.59.235 +79.245.210.198 +108.61.76.8 +77.243.183.93 +158.196.212.164 +82.236.72.55 +187.255.237.97 +219.73.15.192 +151.20.32.245 +95.90.255.153 +118.209.232.218 +124.171.101.99 +87.185.13.113 +5.15.206.164 +25.87.60.111 +68.53.27.112 +83.250.224.227 +130.180.220.126 +83.27.114.96 +1.204.13.122 +111.242.76.47 +202.62.16.62 +101.109.199.119 +159.205.212.242 +213.60.67.126 +85.144.100.5 +201.37.162.92 +194.126.89.193 +201.233.213.167 +93.119.110.247 +190.78.7.231 +75.75.125.55 +185.46.249.145 +160.178.158.54 +95.153.134.144 +81.167.129.247 +172.89.123.176 +152.249.19.96 +87.178.130.45 +93.123.247.211 +46.11.86.170 +186.88.157.110 +77.65.10.166 +189.202.67.14 +223.206.149.29 +123.24.208.165 +46.118.177.40 +25.69.38.113 +70.168.189.146 +99.228.186.52 +70.15.174.156 +142.136.106.108 +193.92.228.153 +85.156.13.86 +189.188.237.104 +95.19.22.94 +217.88.13.199 +1.144.96.140 +81.198.10.79 +178.254.190.132 +94.75.136.231 +38.211.54.78 +71.53.157.49 +192.95.29.176 +73.82.153.96 +62.232.5.242 +100.40.69.188 +162.210.196.176 +180.156.150.143 +110.168.231.245 +79.70.9.80 +137.117.213.153 +178.234.77.146 +84.133.115.69 +84.19.165.213 +62.1.215.212 +94.244.17.63 +50.153.150.216 +88.15.230.239 +165.91.74.108 +2.122.179.220 +79.112.231.20 +162.156.199.110 +14.198.159.194 +187.74.82.136 +72.24.168.79 +117.194.42.216 +100.66.17.228 +47.54.76.217 +201.208.21.151 +79.25.166.110 +84.236.18.119 +39.48.44.134 +222.170.18.151 +76.17.122.180 +97.83.54.77 +190.22.140.51 +221.216.240.245 +187.161.83.96 +85.135.243.220 +90.211.152.125 +92.196.42.65 +31.57.74.31 +187.147.251.197 +188.207.95.41 +95.222.188.217 +190.159.95.190 +71.36.220.248 +36.76.18.26 +80.11.226.53 +78.163.123.228 +189.204.164.169 +58.182.120.211 +93.86.251.111 +84.216.199.63 +83.20.48.4 +81.175.210.63 +119.237.90.152 +79.147.235.72 +137.135.48.99 +160.171.125.185 +130.215.124.85 +198.18.1.10 +77.29.108.119 +189.242.129.27 +188.162.132.133 +77.243.183.94 +78.125.179.134 +24.214.182.28 +81.234.23.242 +124.122.253.86 +95.252.203.179 +189.25.60.50 +190.142.81.36 +201.208.98.13 +106.187.36.44 +171.39.41.252 +188.83.111.148 +190.37.177.83 +94.190.41.3 +96.21.54.26 +155.4.130.140 +188.251.165.89 +71.244.110.93 +113.254.169.55 +69.123.225.156 +56.99.107.117 +66.60.133.42 +91.225.98.162 +94.41.64.71 +92.138.109.194 +142.161.114.127 +5.151.152.147 +151.24.152.4 +209.222.18.51 +144.64.86.12 +49.195.176.237 +92.131.11.116 +108.161.125.223 +98.209.226.86 +95.81.250.253 +70.208.6.53 +84.231.84.105 +110.168.232.221 +181.51.166.159 +151.74.10.81 +213.233.96.10 +5.63.144.156 +171.96.168.126 +128.69.7.182 +70.70.34.86 +68.184.83.28 +84.236.38.116 +87.1.245.196 +181.208.47.253 +109.245.151.167 +184.75.213.134 +186.95.46.68 +165.255.172.58 +219.73.27.5 +100.68.93.19 +202.62.17.115 +83.22.172.58 +179.234.194.69 +118.211.230.64 +178.9.240.143 +95.28.183.3 +46.254.11.158 +74.193.208.180 +193.51.6.5 +92.148.135.217 +78.15.174.21 +41.174.160.149 +93.51.148.228 +24.179.14.89 +91.48.61.225 +139.162.24.133 +24.84.188.5 +108.244.47.41 +88.3.38.194 +37.45.160.140 +189.153.60.95 +37.27.50.204 +96.233.67.164 +156.211.215.134 +108.80.58.111 +108.69.112.21 +186.90.98.44 +173.89.84.54 +85.25.194.85 +205.170.14.244 +213.87.126.214 +112.198.82.157 +86.138.53.33 +82.176.127.213 +94.10.73.206 +162.216.46.135 +86.130.140.227 +86.152.54.251 +198.204.210.68 +108.251.123.134 +186.214.224.142 +84.119.98.171 +186.88.157.110 +189.178.148.244 +130.15.199.115 +190.207.190.244 +95.28.185.134 +88.206.187.1 +80.47.247.96 +85.206.100.75 +190.77.79.214 +81.200.14.126 +187.78.67.179 +177.228.65.109 +109.202.10.42 +85.76.167.169 +46.166.188.224 +109.75.178.93 +213.67.148.249 +92.157.168.181 +201.157.91.73 +174.58.249.186 +198.18.1.95 +91.148.77.205 +79.133.142.93 +109.153.188.99 +208.167.254.37 +77.181.3.3 +83.7.170.93 +178.164.195.234 +72.136.101.25 +213.24.132.13 +181.162.51.72 +188.17.9.40 +182.149.130.239 +75.114.240.23 +187.143.212.81 +109.81.208.158 +87.0.202.64 +21.106.179.117 +148.31.163.57 +183.171.177.23 +84.125.169.134 +178.198.242.133 +119.9.105.164 +0.0.0.0 +95.91.207.113 +125.72.123.245 +175.38.196.103 +83.86.42.44 +223.225.151.71 +94.68.134.137 +77.49.187.76 +105.233.77.216 +177.228.88.39 +94.71.54.26 +178.64.122.121 +86.216.64.167 +49.64.105.88 +205.197.242.183 +69.254.108.4 +91.152.158.166 +120.165.82.23 +95.27.226.29 +76.124.76.145 +84.159.232.37 +178.84.100.142 +173.72.136.151 +105.228.185.243 +223.225.154.206 +85.135.171.158 +85.26.165.33 +92.110.103.112 +87.14.218.112 +109.221.221.97 +175.33.226.219 +142.4.218.175 +91.77.226.181 +79.204.185.44 +186.188.64.207 +26.162.173.209 +69.231.35.237 +81.158.203.27 +77.20.80.189 +178.167.129.161 +42.2.227.111 +186.94.110.227 +152.23.150.97 +189.27.18.212 +79.245.209.128 +190.29.231.15 +96.22.101.105 +85.173.115.239 +89.72.250.80 +202.62.16.4 +0.0.0.0 +186.91.170.42 +112.208.190.3 +37.235.146.166 +216.40.70.98 +64.191.29.34 +86.85.125.240 +78.164.97.108 +91.158.232.111 +218.142.99.184 +24.184.24.162 +73.19.76.93 +104.172.24.79 +101.136.198.7 +91.105.176.20 +98.67.92.79 +176.46.93.116 +96.21.254.147 +46.244.192.30 +139.195.25.65 +173.75.249.15 +85.25.210.25 +25.69.38.113 +190.201.12.159 +77.119.128.157 +5.237.19.68 +79.130.163.117 +75.161.240.113 +89.0.7.35 +190.203.160.220 +190.93.250.41 +128.90.23.4 +165.47.80.207 +83.202.33.220 +75.82.46.205 +174.139.74.218 +186.91.238.219 +92.144.200.122 +178.0.63.141 +76.178.149.21 +84.159.235.173 +84.104.81.56 +77.88.251.253 +62.109.37.226 +75.159.1.100 +70.196.196.25 +91.61.74.165 +94.112.241.242 +104.45.135.147 +113.254.168.101 +94.21.126.27 +188.113.91.140 +0.0.0.2 +29.108.45.223 +50.153.149.88 +92.37.51.148 +95.81.233.129 +124.217.188.204 +50.245.144.205 +88.8.65.219 +88.128.80.4 +111.95.163.140 +45.56.39.12 +176.9.61.40 +93.82.94.46 +201.191.195.235 +77.29.197.123 +40.76.47.144 +2.136.28.141 +67.53.205.187 +136.243.62.98 +217.208.179.41 +79.245.196.100 +140.247.0.75 +90.203.117.109 +151.15.98.15 +85.76.42.248 +65.27.65.178 +213.166.200.124 +71.82.169.191 +151.237.43.222 +201.211.22.44 +67.5.176.5 +111.91.74.57 +160.176.173.124 +87.15.222.204 +2.85.58.108 +50.247.211.162 +79.245.217.213 +124.122.237.67 +89.153.235.154 +46.167.109.219 +79.203.79.28 +72.58.199.221 +93.190.181.183 +217.174.155.155 +5.141.221.243 +78.92.198.142 +189.123.189.192 +205.100.213.40 +77.231.221.177 +37.188.232.39 +112.198.102.141 +84.147.122.57 +2.135.127.246 +206.75.168.223 +206.130.91.237 +116.16.95.251 +37.72.10.137 +31.181.184.129 +92.222.28.13 +69.42.234.159 +128.127.210.88 +37.5.43.90 +178.162.193.97 +108.45.158.161 +77.162.138.28 +77.89.248.90 +5.18.63.57 +24.62.53.127 +85.156.13.237 +151.15.85.80 +176.33.109.91 +1.4.206.140 +104.157.189.4 +121.225.226.92 +217.235.245.112 +190.36.148.66 +46.253.253.84 +201.209.130.118 +162.216.46.141 +209.126.76.117 +104.200.151.54 +93.80.197.95 +87.5.5.78 +92.124.31.153 +176.212.178.160 +90.4.173.86 +222.64.139.107 +84.99.129.241 +38.211.239.187 +119.250.149.37 +88.105.204.1 +186.179.106.1 +113.173.78.173 +105.208.244.120 +104.210.0.71 +178.194.65.149 +222.132.2.70 +186.79.224.179 +92.237.244.8 +190.157.73.195 +62.231.188.129 +86.191.215.1 +70.59.17.67 +62.92.112.6 +83.5.143.28 +188.25.160.13 +0.0.0.0 +187.240.198.232 +79.140.167.244 +174.97.26.213 +181.90.26.16 +79.184.207.243 +2.62.44.154 +46.0.51.72 +98.238.231.31 +120.144.26.14 +72.241.236.178 +37.134.72.93 +188.143.32.39 +69.171.107.214 +171.97.224.32 +108.54.103.176 +107.194.30.116 +171.149.2.249 +178.234.66.23 +158.42.125.14 +69.36.215.49 +94.50.196.101 +217.151.54.26 +31.61.140.244 +193.161.15.76 +73.55.215.101 +124.104.112.150 +217.95.239.51 +76.104.64.62 +83.78.9.216 +85.71.44.226 +223.204.250.206 +169.1.121.116 +177.134.229.189 +89.241.140.97 +188.196.134.227 +71.62.232.70 +46.44.37.124 +142.217.187.68 +178.94.172.164 +176.58.231.221 +193.238.38.144 +24.48.212.145 +100.116.210.117 +50.106.174.52 +134.255.109.40 +86.45.106.149 +92.249.92.85 +81.154.37.13 +66.87.97.55 +41.165.4.106 +109.182.51.122 +95.26.169.115 +198.8.80.155 +64.61.51.178 +110.168.231.226 +58.33.130.50 +124.229.133.168 +83.149.46.90 +202.62.16.20 +195.174.63.110 +150.27.127.98 +84.244.18.20 +65.27.245.94 +199.16.96.145 +78.173.68.47 +186.115.229.57 +85.51.153.198 +99.178.135.101 +41.249.165.237 +190.201.165.99 +190.177.98.177 +99.187.33.246 +73.35.112.73 +95.237.97.7 +79.235.248.242 +81.108.157.78 +193.34.145.124 +80.223.135.107 +188.18.28.45 +177.228.66.13 +24.44.203.215 +58.11.70.243 +113.240.247.242 +80.235.62.161 +146.185.150.70 +108.61.19.5 +65.27.89.177 +181.130.118.110 +79.245.209.9 +71.95.186.175 +217.71.47.220 +93.143.248.105 +95.223.121.159 +186.93.167.188 +24.192.24.115 +101.114.75.142 +82.19.92.224 +217.226.243.86 +186.87.6.195 +78.209.19.92 +91.148.114.172 +50.142.234.175 +91.134.233.254 +39.250.103.108 +202.62.17.179 +128.78.135.164 +179.212.185.123 +25.193.218.1 +197.211.52.26 +190.78.147.223 +112.156.51.76 +178.57.99.40 +58.182.120.211 +41.244.241.221 +90.151.144.22 +121.35.17.81 +50.23.115.93 +81.153.146.33 +77.249.199.235 +200.162.249.24 +124.197.16.81 +79.141.246.80 +118.233.230.47 +105.233.77.88 +216.114.224.73 +52.71.215.53 +212.54.196.101 +91.232.124.59 +72.42.106.23 +86.94.147.16 +178.184.63.128 +103.199.41.194 +2.222.34.104 +85.175.20.156 +124.122.29.190 +117.151.176.6 +87.0.208.206 +71.250.245.33 +210.55.212.46 +5.139.75.217 +95.91.206.164 +2.93.226.176 +176.193.188.215 +86.38.41.1 +59.58.238.21 +187.188.19.71 +50.153.150.134 +177.249.153.191 +95.90.53.237 +190.73.47.192 +186.90.15.65 +192.99.13.67 +104.129.24.155 +91.127.56.126 +217.71.45.211 +71.127.224.135 +79.67.194.168 +13.93.150.42 +109.43.2.98 +207.172.224.81 +78.147.75.63 +208.84.132.253 +190.198.3.63 +118.90.23.40 +178.13.79.48 +176.58.103.240 +216.14.119.122 +204.112.179.114 +93.143.252.213 +49.15.136.120 +110.167.219.173 +217.253.222.163 +100.73.22.72 +216.209.119.6 +31.42.237.209 +185.46.249.145 +83.143.240.45 +79.30.246.76 +150.69.145.157 +118.98.96.151 +76.11.216.201 +91.44.228.200 +80.11.226.53 +208.44.136.67 +198.211.38.157 +67.170.218.234 +190.38.178.182 +186.87.208.254 +67.181.167.196 +147.62.114.140 +209.107.214.55 +1.0.0.0 +119.236.139.193 +222.152.161.106 +97.101.86.80 +50.153.148.140 +88.132.143.170 +168.1.6.18 +79.41.223.165 +78.8.13.6 +94.66.57.24 +86.140.40.180 +94.96.41.4 +220.220.88.5 +89.71.115.25 +77.38.95.104 +188.162.39.231 +37.112.7.17 +62.63.91.96 +187.143.59.112 +68.246.2.180 +24.152.231.246 +2.187.200.134 +153.183.217.213 +70.168.69.126 +79.208.167.161 +88.217.180.9 +93.143.136.165 +86.115.102.42 +80.131.61.109 +162.239.34.236 +91.48.57.111 +158.69.31.40 +188.226.144.233 +67.149.247.90 +182.165.44.216 +81.159.65.131 +79.47.233.208 +88.241.49.194 +186.93.225.184 +86.19.224.63 +76.19.17.188 +37.24.158.219 +85.76.176.126 +5.248.84.56 +68.4.194.25 +231.255.154.44 +80.57.219.95 +201.210.86.19 +109.43.3.23 +98.207.163.188 +93.202.162.111 +99.228.18.37 +197.116.68.113 +69.138.11.33 +109.98.63.224 +112.210.102.141 +213.211.143.17 +95.17.252.70 +174.60.14.63 +178.66.204.156 +72.200.198.145 +92.80.196.123 +146.90.135.129 +213.220.206.204 +46.246.150.244 +140.168.134.185 +172.245.17.12 +5.233.6.23 +80.113.129.139 +79.206.171.53 +83.4.148.240 +101.99.203.102 +171.7.219.199 +104.200.151.3 +158.69.8.194 +80.103.188.87 +91.48.32.205 +85.178.71.102 +93.113.93.207 +209.91.43.78 +24.204.194.99 +80.174.238.232 +50.148.74.47 +62.197.218.214 +65.129.14.9 +186.89.90.196 +46.246.204.126 +5.200.52.133 +37.78.189.109 +189.194.112.230 +178.93.150.194 +53.193.238.248 +77.2.189.231 +154.119.57.252 +184.171.221.233 +66.87.68.1 +79.50.152.125 +182.86.80.146 +201.29.101.113 +53.193.239.189 +213.47.88.249 +98.160.239.93 +89.131.174.242 +200.92.5.63 +171.96.167.66 +86.129.69.231 +92.40.183.177 +186.94.97.240 +97.117.164.169 +50.169.246.145 +101.80.128.236 +220.246.220.111 +159.172.226.177 +86.31.128.135 +74.218.235.108 +164.78.139.233 +193.34.160.72 +93.210.122.68 +193.168.1.100 +46.193.132.28 +65.118.121.91 +31.61.141.53 +104.200.151.75 +88.152.185.158 +201.4.90.63 +198.105.244.119 +88.254.164.183 +83.44.122.82 +79.19.6.37 +188.76.105.164 +80.110.47.213 +181.137.36.56 +80.4.97.103 +217.95.253.103 +93.104.103.129 +37.48.86.181 +179.5.8.19 +212.23.185.22 +81.196.32.176 +172.89.205.21 +73.90.211.0 +62.74.23.11 +231.210.83.146 +46.101.128.131 +186.15.8.16 +24.246.57.236 +66.63.176.223 +180.252.90.132 +223.204.247.173 +91.181.167.61 +209.188.18.43 +190.252.136.95 +81.7.79.148 +117.208.209.181 +186.92.34.75 +128.71.78.96 +79.245.196.125 +219.132.169.77 +200.56.38.193 +180.251.253.5 +186.93.59.201 +100.92.135.255 +37.188.236.106 +178.93.35.14 +79.204.180.184 +50.153.149.45 +202.62.17.210 +68.196.158.116 +162.210.196.175 +24.138.129.215 +93.79.197.70 +46.98.111.95 +83.132.22.255 +180.242.27.12 +217.24.135.250 +79.16.92.158 +90.204.155.154 +190.45.238.103 +37.215.59.175 +185.3.151.60 +94.141.162.11 +41.174.166.66 +80.107.68.218 +212.74.198.2 +41.96.38.253 +0.0.0.0 +67.85.63.112 +36.88.141.249 +145.133.165.175 +81.32.245.39 +46.246.219.114 +5.141.222.49 +177.133.210.69 +197.49.157.92 +178.79.79.120 +83.29.92.182 +31.44.253.224 +185.3.151.123 +176.193.197.136 +87.152.129.52 +115.87.121.205 +77.49.159.77 +105.108.27.121 +92.144.213.82 +46.109.74.73 +100.42.160.78 +95.24.99.127 +186.54.141.61 +223.207.119.134 +188.73.192.57 +70.51.25.253 +183.16.3.173 +37.24.146.248 +94.242.222.251 +49.32.36.161 +41.251.33.220 +79.141.170.4 +124.122.237.67 +79.16.172.241 +79.186.217.121 +178.128.177.165 +114.79.12.121 +95.19.21.165 +93.156.81.50 +178.165.128.117 +68.39.187.73 +151.235.136.86 +186.207.213.206 +85.229.184.205 +111.240.211.83 +188.221.40.209 +191.112.243.63 +178.234.12.95 +190.238.98.73 +93.150.78.97 +179.8.129.14 +77.165.247.110 +190.239.38.166 +189.174.114.178 +93.205.17.169 +95.72.134.13 +84.154.167.152 +62.2.218.10 +95.220.229.126 +5.164.173.159 +94.134.4.178 +117.200.204.157 +178.221.184.6 +77.20.176.135 +0.0.0.2 +91.39.197.227 +171.149.2.249 +67.165.120.50 +97.90.203.136 +47.217.159.177 +105.226.137.23 +67.83.72.171 +41.144.196.62 +189.223.40.145 +220.173.185.231 +109.161.89.199 +176.41.228.17 +77.70.68.47 +91.202.135.145 +83.185.91.165 +31.150.218.95 +171.39.43.113 +95.91.240.232 +171.96.172.138 +91.44.237.157 +203.217.68.236 +174.58.253.59 +202.62.16.108 +142.160.113.197 +5.42.105.143 +180.252.93.87 +206.183.119.36 +176.51.208.129 +159.29.194.242 +0.0.0.0 +5.100.81.158 +217.197.250.33 +82.72.102.219 +124.150.29.101 +77.164.58.243 +188.37.186.128 +5.140.139.49 +67.85.63.112 +95.179.62.63 +23.240.234.72 +213.108.208.79 +187.170.158.202 +201.41.173.2 +68.195.171.102 +92.251.154.55 +2.182.202.55 +178.65.132.42 +46.159.49.34 +1.189.194.115 +36.78.249.200 +151.18.52.171 +99.246.216.151 +67.5.248.216 +2.110.116.27 +14.97.145.32 +37.201.6.202 +71.181.32.76 +97.127.124.25 +108.80.58.111 +84.24.170.40 +37.6.110.7 +176.212.176.146 +86.212.45.38 +191.234.38.103 +117.198.131.128 +87.81.133.34 +93.126.80.151 +152.59.57.53 +198.23.200.184 +84.251.165.229 +79.192.207.150 +173.79.131.221 +123.201.196.249 +112.226.70.121 +88.232.236.61 +79.117.59.4 +203.166.254.250 +83.83.205.251 +171.4.15.49 +80.106.197.8 +92.93.148.140 +31.54.226.230 +93.81.75.134 +41.96.150.179 +108.61.226.7 +86.159.138.213 +95.160.150.34 +95.189.3.132 +87.116.161.14 +94.7.141.205 +78.47.149.84 +202.62.17.10 +61.227.229.211 +31.132.225.143 +187.14.108.85 +84.41.36.30 +189.238.214.70 +173.192.176.136 +113.172.95.150 +155.46.1.20 +5.28.189.174 +108.54.168.63 +109.236.137.250 +31.174.206.35 +68.231.74.249 +87.113.49.184 +36.71.162.49 +1.0.0.0 +124.148.165.65 +84.81.98.206 +85.174.61.34 +14.177.108.83 +62.47.227.187 +124.122.2.78 +179.55.38.106 +0.0.0.0 +49.85.204.30 +103.199.34.164 +2.222.34.104 +37.122.196.148 +69.124.57.26 +217.23.186.199 +68.204.242.231 +180.71.101.17 +84.154.93.193 +190.73.126.123 +24.119.202.175 +104.156.228.183 +77.231.219.235 +81.104.96.169 +25.123.50.89 +81.243.118.53 +201.22.154.139 +72.143.235.149 +110.168.231.205 +95.85.45.116 +217.235.247.220 +212.237.86.137 +200.52.22.83 +217.164.143.91 +124.122.109.4 +37.24.159.36 +212.251.121.125 +81.141.22.113 +187.233.168.97 +95.146.118.86 +81.141.16.237 +77.131.2.240 +78.150.15.78 +74.75.46.110 +213.46.74.143 +103.219.4.203 +78.105.113.132 +100.68.210.170 +171.101.162.62 +65.185.44.222 +23.94.218.151 +187.170.125.234 +83.26.161.110 +201.114.25.237 +84.147.126.42 +190.75.97.64 +122.100.181.33 +90.1.218.225 +125.72.123.245 +83.139.146.2 +253.134.93.88 +201.230.90.141 +190.67.190.71 +189.24.200.232 +107.221.196.68 +202.80.215.19 +190.73.253.30 +105.236.34.70 +106.68.25.233 +181.194.27.123 +79.224.70.165 +186.90.50.97 +173.210.142.135 +94.68.173.226 +69.165.242.28 +172.110.5.36 +79.180.7.46 +178.19.96.59 +45.79.195.172 +128.199.217.67 +84.147.122.196 +186.104.156.37 +95.221.121.107 +88.206.187.54 +167.61.27.101 +79.101.223.127 +36.86.63.180 +67.118.170.102 +79.245.194.74 +92.127.108.147 +113.22.90.62 +177.221.251.80 +54.195.241.227 +69.35.163.246 +113.241.227.205 +100.68.108.228 +201.240.63.115 +200.8.206.85 +92.134.68.137 +77.166.187.108 +95.160.73.67 +213.168.24.2 +86.153.95.169 +24.38.155.231 +190.36.148.66 +58.70.1.212 +95.17.245.168 +114.88.165.216 +190.199.48.6 +5.254.97.91 +71.35.70.44 +86.208.73.16 +212.255.255.216 +77.239.67.88 +79.147.194.118 +90.4.251.196 +151.227.86.5 +70.80.71.149 +72.69.190.182 +68.52.132.102 +113.52.90.168 +68.4.208.136 +2.96.241.150 +71.52.84.91 +88.17.165.46 +100.82.113.161 +174.21.77.135 +181.28.55.24 +84.147.117.137 +104.207.136.13 +88.226.55.195 +68.164.80.49 +69.179.143.48 +82.74.131.244 +90.208.124.138 +81.242.194.187 +87.115.29.13 +213.139.53.11 +99.224.242.213 +77.7.149.194 +78.94.32.194 +216.172.138.189 +109.169.168.151 +46.190.34.51 +193.173.216.141 +86.211.114.37 +128.71.63.187 +181.167.138.145 +176.37.244.102 +88.113.195.162 +180.108.78.32 +89.3.175.167 +37.45.105.227 +66.69.125.175 +80.213.211.183 +171.97.215.109 +85.222.174.131 +46.188.33.88 +31.3.159.108 +25.178.132.137 +92.52.34.44 +190.73.156.224 +62.199.144.11 +71.35.66.229 +5.239.187.160 +77.171.31.33 +86.142.225.26 +91.226.79.70 +95.90.203.249 +42.168.94.253 +75.174.90.85 +93.220.95.29 +37.110.210.152 +93.81.87.179 +41.144.196.62 +68.61.208.100 +213.151.213.120 +198.27.97.180 +81.141.5.247 +62.4.196.155 +82.60.153.56 +130.215.124.85 +79.119.13.49 +201.209.12.17 +213.23.160.162 +50.153.151.12 +181.111.47.128 +176.41.230.232 +72.78.180.127 +139.192.136.198 +188.251.165.89 +96.2.40.126 +190.38.141.44 +100.68.200.239 +183.16.196.195 +68.246.191.100 +213.5.52.72 +119.76.74.173 +190.203.238.156 +88.25.138.178 +90.203.111.252 +109.88.137.172 +89.151.173.175 +94.66.57.206 +186.95.58.130 +14.153.1.180 +213.108.149.97 +37.145.47.214 +32.51.15.77 +158.181.103.107 +92.62.226.213 +213.168.24.2 +86.61.35.42 +87.244.68.187 +82.221.105.49 +177.39.37.65 +93.190.137.119 +24.107.14.224 +202.62.17.103 +112.198.64.20 +95.97.189.200 +187.233.175.136 +162.220.221.43 +89.142.34.204 +45.78.195.224 +94.157.236.220 +97.121.188.193 +24.93.199.96 +89.201.4.91 +83.50.179.222 +36.77.19.150 +178.217.27.193 +2.95.4.185 +81.17.27.234 +167.58.64.174 +104.200.151.76 +120.197.109.127 +41.250.70.94 +82.45.94.36 +191.17.69.226 +87.0.217.236 +190.73.156.224 +185.63.217.216 +100.68.42.202 +50.163.28.210 +71.19.252.27 +91.67.95.126 +190.62.100.198 +83.55.84.121 +201.11.58.115 +114.83.91.209 +209.213.169.101 +122.195.51.125 +77.105.51.215 +189.97.76.94 +186.62.199.48 +154.161.77.185 +109.188.125.42 +67.5.174.176 +192.151.148.186 +92.226.50.36 +99.112.205.199 +89.65.239.145 +112.210.26.78 +85.222.169.120 +114.79.37.51 +60.168.166.4 +68.2.69.203 +89.173.7.7 +151.238.64.226 +187.143.130.145 +177.223.6.146 +94.59.19.227 +92.246.211.241 +80.131.211.219 +92.208.67.183 +101.23.211.146 +201.141.173.60 +36.68.171.218 +87.117.198.189 +83.255.120.18 +50.23.115.115 +82.56.150.176 +86.6.159.7 +1.0.0.0 +87.103.104.253 +36.68.50.157 +173.160.188.78 +190.37.53.226 +109.236.90.135 +180.251.194.182 +94.11.72.96 +190.142.46.110 +162.72.168.31 +198.8.80.172 +98.211.161.99 +181.54.174.26 +111.95.163.59 +86.157.212.54 +85.28.95.185 +201.233.142.118 +223.243.44.185 +213.87.224.181 +95.88.49.98 +201.191.254.230 +95.19.16.26 +62.113.206.152 +97.123.149.144 +95.49.170.59 +94.68.201.168 +71.176.111.234 +2.62.1.52 +196.210.182.77 +86.166.166.183 +149.254.218.236 +111.95.114.153 +85.21.246.137 +78.151.93.233 +14.201.56.59 +105.233.77.29 +95.174.112.248 +5.141.188.165 +172.98.87.34 +152.115.56.228 +84.198.202.93 +75.132.213.248 +77.254.137.179 +89.67.104.161 +177.228.85.75 +151.224.96.67 +190.198.19.209 +62.227.200.68 +178.43.55.236 +2.62.23.162 +201.141.197.113 +128.39.168.83 +110.77.246.47 +82.36.186.247 +64.145.94.121 +182.249.242.9 +204.83.97.27 +81.131.148.40 +71.198.11.116 +81.184.126.146 +190.99.132.11 +189.70.85.120 +92.232.213.133 +187.190.149.24 +213.104.98.3 +91.59.157.5 +87.203.127.183 +14.1.200.73 +74.46.175.215 +128.90.92.90 +187.233.168.97 +90.46.77.211 +217.34.229.35 +77.51.168.226 +217.235.240.122 +81.155.44.48 +24.66.164.123 +67.61.226.128 +88.81.90.161 +201.18.124.164 +76.88.140.57 +101.99.147.59 +80.202.240.76 +73.42.123.157 +78.148.248.150 +81.141.4.217 +178.157.238.33 +77.172.223.31 +79.245.223.4 +81.141.16.237 +83.170.104.253 +93.230.48.203 +192.167.1.4 +201.143.101.125 +117.82.95.109 +173.230.171.42 +202.80.215.47 +171.97.185.187 +75.172.14.95 +88.232.5.214 +190.231.55.159 +50.40.217.241 +87.110.50.162 +71.86.177.48 +5.238.238.134 +176.10.63.196 +78.0.6.52 +108.81.43.50 +115.79.200.157 +188.23.146.68 +87.226.22.203 +143.177.130.57 +186.205.38.15 +131.94.186.34 +213.22.179.152 +171.97.220.88 +62.212.103.39 +178.221.145.105 +78.132.85.156 +221.163.72.245 +71.54.170.137 +88.217.180.120 +1.0.0.0 +46.39.230.225 +190.199.35.111 +18.111.20.175 +187.170.145.98 +46.44.32.20 +107.138.93.38 +93.47.133.195 +171.4.193.144 +190.36.128.114 +103.27.223.89 +99.228.186.52 +85.140.0.78 +24.17.41.205 +80.117.234.46 +188.18.15.9 +193.92.162.244 +66.177.82.24 +188.25.174.94 +75.166.214.12 +58.10.204.156 +198.8.80.33 +97.121.143.100 +188.18.14.133 +5.68.180.88 +197.134.127.130 +96.240.86.151 +174.91.141.219 +77.117.102.55 +111.75.99.167 +174.62.75.38 +77.9.170.119 +14.203.72.239 +70.30.52.78 +189.26.209.43 +179.94.175.165 +73.90.205.121 +186.79.30.184 +75.156.118.46 +79.204.151.112 +81.5.98.104 +0.0.0.0 +104.156.228.101 +174.52.86.133 +121.214.11.69 +46.159.144.158 +70.194.133.202 +93.181.13.101 +96.254.64.47 +178.36.6.207 +27.159.20.249 +99.229.142.108 +93.156.85.152 +250.31.16.246 +87.21.89.166 +146.199.167.59 +176.248.174.118 +83.209.227.175 +176.14.152.87 +97.114.122.123 +195.38.124.224 +151.238.70.86 +76.23.11.16 +84.192.131.77 +216.150.98.41 +213.79.35.221 +81.83.11.251 +188.198.161.33 +41.150.126.77 +197.116.88.51 +84.188.79.10 +31.207.111.218 +201.210.191.90 +95.189.22.182 +80.236.18.96 +188.159.173.48 +2.62.19.20 +192.0.0.2 +62.178.107.69 +96.49.76.100 +187.244.193.17 +99.43.85.101 +140.168.123.154 +83.45.160.174 +95.19.21.165 +82.194.196.253 +91.48.62.202 +85.212.65.71 +205.220.163.91 +115.117.126.224 +46.159.168.3 +179.7.174.165 +104.228.3.233 +79.191.27.114 +222.228.145.118 +79.112.56.241 +94.25.133.48 +187.254.153.218 +46.236.145.3 +37.14.5.90 +95.17.250.151 +86.17.238.232 +62.165.44.46 +203.87.201.150 +110.168.232.186 +87.103.52.73 +92.106.138.114 +177.188.209.220 +92.224.245.246 +200.82.209.75 +176.219.147.221 +182.15.219.243 +36.84.13.160 +87.14.218.112 +85.75.133.89 +73.214.19.5 +47.89.29.74 +178.222.73.219 +199.7.156.128 +109.111.243.164 +91.48.40.154 +92.4.80.144 +188.130.136.160 +190.74.50.60 +109.98.165.225 +40.127.96.154 +179.236.252.159 +110.167.196.251 +53.150.186.201 +94.180.149.108 +75.114.240.23 +60.93.52.103 +91.14.44.208 +117.212.122.217 +78.8.148.124 +178.254.191.97 +188.103.130.30 +79.94.135.249 +2.187.202.229 +92.4.80.144 +98.247.82.17 +2.223.240.102 +97.95.202.36 +80.233.175.48 +84.159.253.190 +179.7.160.222 +5.143.133.236 +223.92.12.38 +178.120.146.6 +79.245.210.198 +218.86.161.254 +187.190.9.31 +93.123.163.96 +5.28.165.169 +188.73.192.30 +1.172.122.137 +93.100.39.93 +71.9.253.183 +109.203.146.219 +109.236.87.249 +109.194.99.77 +93.137.178.190 +177.17.121.175 +213.49.118.166 +67.70.137.170 +151.75.247.137 +94.216.219.178 +184.20.11.173 +71.202.52.116 +77.231.221.177 +77.248.238.60 +125.238.117.232 +14.192.209.4 +5.18.59.69 +219.90.240.193 +186.95.68.180 +217.235.247.159 +198.8.80.135 +24.114.70.175 +124.168.147.253 +31.10.151.160 +199.48.242.40 +83.26.30.141 +92.20.147.219 +77.105.60.148 +77.183.59.192 +92.144.80.67 +77.52.137.36 +79.204.148.117 +174.53.149.224 +124.171.175.152 +196.217.77.156 +77.9.114.209 +87.145.6.215 +128.71.195.108 +113.254.169.53 +49.143.138.98 +115.188.90.227 +115.70.4.78 +151.18.52.171 +167.220.196.200 +183.26.225.165 +171.39.67.3 +78.23.220.227 +13.91.97.67 +23.29.221.59 +112.87.150.52 +114.218.143.23 +202.62.16.128 +87.206.73.74 +156.241.140.131 +73.90.205.121 +31.179.120.196 +93.138.0.219 +92.106.200.119 +91.177.116.22 +91.115.63.103 +186.91.40.63 +95.114.26.116 +1.0.0.0 +98.193.70.55 +24.155.223.251 +52.41.9.64 +37.78.218.36 +67.184.154.245 +105.157.71.59 +57.40.230.77 +66.63.177.52 +178.35.140.252 +137.135.57.205 +89.242.113.52 +171.96.167.131 +88.200.136.162 +41.96.128.249 +212.228.253.143 +190.237.183.46 +82.197.214.31 +99.197.201.17 +193.92.162.214 +110.168.232.10 +187.79.220.69 +14.154.130.95 +191.32.70.254 +196.210.206.2 +171.96.172.161 +36.228.0.15 +186.53.5.218 +106.192.52.162 +76.4.181.219 +181.223.157.1 +93.33.181.113 +181.56.231.230 +79.147.194.118 +70.21.184.26 +72.181.176.144 +190.22.132.88 +87.185.5.211 +58.96.38.219 +76.188.205.173 +70.75.192.84 +171.96.172.138 +198.8.80.159 +77.7.205.190 +180.154.153.136 +14.20.208.82 +5.65.70.202 +94.241.244.103 +108.53.251.199 +87.114.4.176 +123.201.196.249 +182.239.83.217 +220.246.220.129 +99.162.89.78 +89.247.168.201 +60.50.60.169 +137.175.202.108 +199.102.52.141 +176.184.17.43 +90.191.99.12 +52.43.103.26 +212.89.231.162 +23.99.90.8 +141.134.88.149 +91.203.224.238 +101.164.115.94 +76.124.76.145 +112.215.124.102 +41.251.10.68 +62.158.230.71 +71.233.46.161 +93.142.241.147 +115.184.241.47 +31.165.68.177 +87.226.22.203 +174.35.172.33 +0.0.0.0 +96.42.233.155 +93.130.157.247 +77.71.174.94 +190.255.15.213 +144.76.80.131 +79.101.135.191 +92.37.143.70 +164.183.100.67 +213.229.68.54 +188.82.171.37 +87.5.5.150 +113.91.239.36 +189.24.147.194 +115.87.206.178 +91.113.63.204 +94.242.246.23 +122.109.70.166 +173.31.28.160 +112.215.123.199 +188.69.199.38 +1.52.142.82 +87.249.198.29 +115.87.121.70 +186.28.160.243 +86.95.37.125 +75.114.240.23 +146.3.183.92 +186.92.79.138 +75.114.188.94 +187.149.94.117 +176.104.23.247 +93.136.52.207 +101.160.157.100 +188.40.132.58 +216.14.113.63 +37.79.250.153 +223.204.249.191 +146.90.128.2 +112.215.123.68 +108.223.93.209 +68.9.115.43 +123.3.242.122 +178.222.13.145 +203.109.100.180 +94.23.213.47 +79.66.123.46 +200.8.245.5 +213.155.201.176 +189.203.175.93 +84.22.108.241 +24.66.37.121 +217.235.248.39 +188.30.191.234 +220.173.178.6 +186.117.166.66 +219.79.25.187 +59.172.140.165 +79.198.45.189 +77.221.3.223 +178.234.10.109 +189.133.15.40 +83.22.64.57 +92.20.147.219 +24.184.24.90 +91.7.25.178 +171.5.190.70 +107.170.103.218 +212.71.251.82 +186.90.61.39 +31.162.226.180 +97.83.176.11 +109.145.155.47 +176.214.237.6 +192.169.99.9 +2.34.229.181 +78.132.70.52 +82.168.244.104 +202.62.16.48 +122.121.187.21 +90.105.199.214 +178.234.112.98 +83.7.184.139 +188.167.239.0 +87.158.147.150 +79.191.66.221 +106.69.243.28 +81.158.21.236 +159.205.255.59 +46.103.220.87 +24.91.145.46 +79.22.220.247 +213.152.162.149 +0.0.0.0 +216.82.207.195 +82.55.110.9 +92.229.102.229 +37.190.51.43 +46.39.231.0 +5.138.59.135 +92.127.61.67 +77.243.183.19 +128.204.198.23 +86.7.187.242 +87.0.202.64 +176.33.107.67 +81.171.71.41 +81.141.4.205 +101.99.43.251 +44.50.90.233 +184.147.141.21 +89.37.46.253 +161.41.101.111 +197.119.49.155 +93.215.69.236 +88.206.187.54 +82.213.132.233 +213.96.29.221 +178.83.191.233 +80.39.236.96 +78.22.130.71 +93.205.28.195 +197.117.250.77 +190.36.192.92 +5.140.202.59 +178.215.114.169 +65.31.4.167 +78.169.107.179 +46.142.129.19 +2.29.149.62 +94.66.57.130 +1.144.96.234 +202.62.17.197 +14.2.14.23 +94.3.94.90 +188.107.62.61 +78.145.233.123 +104.174.85.252 +128.75.237.122 +194.33.80.12 +64.134.224.47 +198.27.97.180 +213.227.255.94 +181.67.78.116 +80.71.250.255 +181.62.238.228 +140.168.123.59 +178.127.18.12 +91.158.213.84 +192.30.89.167 +208.167.254.71 +181.45.165.48 +2.125.75.3 +185.18.140.49 +178.121.168.9 +BTCD.RT1253731 u.2507+c.2507 b.2507 v.2507 (0+230/231 1st.2507).s231 to 2507 N[2508] h.1253731 r.1253730 c.1253500 s.1253730 d.0 E.2507 maxB.64 peers.27/64 Q.(0 0) (L.1253731 2507:231) M.1253730 9db5e1adb2273c47f5d9d87cb33027cb3977688bc21992c5a353a713cae54422 ledger.a80cd39714953dca bQ.62 0:04:45 stuck.0 max.0 +151.66.241.195 +89.230.50.96 +186.79.224.179 +120.59.90.181 +5.167.37.199 +93.212.228.76 +74.119.170.51 +83.162.226.231 +50.44.184.78 +31.6.45.119 +90.0.19.234 +87.242.49.243 +46.98.119.33 +2.235.105.143 +81.231.244.196 +46.29.155.69 +150.101.230.179 +37.14.20.75 +76.75.71.45 +12.247.29.158 +95.27.77.137 +189.41.50.168 +79.200.222.225 +190.177.79.90 +71.193.134.45 +2.146.128.134 +77.168.163.194 +178.234.146.7 +125.238.118.21 +121.135.125.6 +109.10.42.135 +99.248.251.175 +201.67.2.161 +95.69.221.181 +218.142.75.243 +73.90.211.41 +80.103.93.63 +222.230.78.190 +85.230.77.92 +201.210.169.170 +50.106.33.87 +79.206.175.208 +118.98.97.185 +216.84.157.50 +86.5.124.225 +202.62.17.95 +202.62.16.98 +212.178.255.116 +78.132.33.246 +61.0.80.138 +104.34.13.253 +193.107.92.137 +36.83.30.100 +151.224.62.223 +85.49.128.43 +95.17.252.153 +93.169.65.197 +77.247.181.164 +159.206.179.155 +62.28.52.105 +79.21.114.72 +79.109.68.82 +189.238.214.70 +5.175.208.105 +94.205.1.88 +77.46.166.42 +107.77.72.19 +117.79.232.152 +71.41.55.254 +46.146.200.184 +78.132.134.30 +37.140.34.39 +178.120.23.138 +151.246.175.245 +5.156.4.175 +90.57.154.134 +78.225.68.197 +79.200.205.172 +109.230.44.230 +88.112.142.101 +189.35.206.229 +109.98.7.137 +117.192.218.30 +202.62.17.226 +70.74.244.109 +24.237.33.141 +66.228.50.86 +176.94.190.132 +72.38.223.95 +14.177.105.14 +24.184.21.63 +95.42.118.20 +190.207.77.25 +97.127.95.119 +63.87.254.155 +158.69.31.37 +0.0.0.0 +93.190.138.125 +46.166.188.208 +91.153.132.148 +217.228.57.165 +104.131.230.130 +91.125.175.196 +109.188.127.98 +96.42.237.66 +18.111.120.219 +166.137.246.122 +192.0.220.162 +46.98.12.7 +205.185.223.46 +43.226.7.45 +77.51.66.64 +216.144.236.34 +87.15.42.16 +82.242.146.58 +78.83.62.131 +143.168.37.247 +95.73.121.11 +24.19.34.247 +78.132.93.236 +157.234.138.190 +31.10.149.202 +87.98.178.140 +213.87.120.151 +179.186.154.239 +94.223.109.110 +79.24.169.19 +94.23.47.197 +79.167.166.155 +223.204.251.54 +222.247.234.104 +201.211.225.122 +84.253.206.43 +207.204.233.40 +181.208.31.78 +79.204.158.178 +94.234.170.181 +62.113.206.249 +112.215.123.124 +71.204.55.160 +140.168.123.59 +24.186.214.154 +24.87.77.185 +5.65.69.184 +190.202.250.145 +62.178.142.138 +0.0.0.0 +198.18.1.95 +79.224.0.44 +108.61.177.98 +121.35.194.150 +71.195.208.134 +86.30.167.243 +94.66.222.49 +201.40.215.107 +193.238.38.144 +206.190.151.241 +46.65.39.5 +121.224.229.225 +160.177.60.179 +124.189.116.101 +188.18.14.112 +60.19.29.21 +41.144.65.47 +124.122.211.138 +78.122.253.28 +62.98.108.210 +108.97.6.214 +189.160.3.51 +151.229.236.167 +93.104.96.127 +93.141.228.45 +54.201.183.106 +199.119.232.215 +179.179.48.73 +1.0.0.0 +98.110.177.46 +106.68.169.229 +78.235.150.223 +66.190.169.246 +73.140.155.40 +89.179.245.29 +67.169.239.87 +85.117.108.204 +67.87.55.27 +94.21.205.204 +75.82.46.205 +180.181.123.211 +46.40.58.96 +37.27.137.252 +141.134.88.149 +195.208.169.199 +113.22.95.194 +23.97.232.97 +109.166.137.102 +91.59.157.5 +79.245.219.183 +67.236.80.43 +121.45.82.86 +109.209.161.4 +2.85.179.46 +120.164.44.57 +95.86.230.196 +189.103.250.193 +33.212.156.47 +202.62.17.132 +5.165.186.57 +95.71.8.110 +48.121.64.127 +176.252.21.38 +41.105.28.186 +77.95.54.152 +146.52.16.145 +13.92.176.214 +62.74.26.165 +202.62.17.22 +109.43.0.171 +31.34.176.124 +98.173.193.245 +168.70.60.110 +84.228.22.159 +190.37.128.143 +109.177.205.222 +89.223.38.46 +178.253.141.119 +91.182.2.84 +90.209.150.21 +168.63.185.23 +179.232.197.231 +179.7.166.165 +93.195.217.161 +79.107.175.200 +178.195.18.254 +37.188.229.37 +190.39.10.186 +213.211.39.184 +148.255.183.235 +42.98.152.105 +156.210.18.207 +103.254.154.250 +79.255.228.165 +178.254.173.143 +187.78.56.13 +112.198.77.34 +78.253.251.14 +77.168.116.193 +92.133.138.44 +2.38.64.231 +0.0.0.0 +94.25.171.140 +173.245.211.34 +95.71.9.39 +31.185.4.33 +96.240.92.118 +91.185.53.129 +189.59.173.141 +79.235.241.29 +95.134.62.105 +116.25.162.131 +122.219.223.82 +36.76.56.110 +46.98.122.128 +109.30.252.146 +0.0.0.0 +94.5.235.45 +62.84.249.76 +36.76.110.20 +78.122.253.28 +220.246.221.16 +188.89.24.254 +81.61.62.168 +91.67.247.232 +104.236.120.54 +124.122.27.16 +216.246.242.233 +205.183.5.208 +179.35.93.70 +93.81.135.76 +179.55.35.82 +60.166.235.168 +37.205.56.35 +0.0.0.0 +211.24.19.36 +87.2.84.39 +69.123.225.156 +113.254.169.220 +113.159.116.23 +91.181.197.181 +173.197.103.2 +42.61.246.207 +93.87.214.15 +77.53.37.165 +201.209.91.12 +62.163.89.142 +162.255.117.106 +188.226.171.134 +27.34.30.7 +94.3.48.179 +37.47.195.86 +159.172.226.177 +190.94.79.132 +71.9.247.75 +36.230.23.41 +184.88.116.74 +86.202.71.200 +145.255.21.173 +123.138.32.162 +82.131.40.121 +177.244.254.125 +77.3.125.36 +90.26.85.134 +5.141.202.140 +79.30.205.60 +82.56.79.206 +162.213.158.169 +81.47.68.213 +27.110.174.2 +62.233.161.171 +181.223.156.207 +100.71.25.195 +98.215.49.232 +41.96.245.97 +79.117.118.39 +94.8.255.224 +94.220.38.10 +70.214.105.111 +124.122.211.138 +197.202.249.150 +87.244.147.84 +128.90.92.104 +71.17.170.92 +94.209.4.28 +170.105.118.44 +46.61.46.86 +109.190.196.220 +109.201.219.106 +90.58.17.41 +8.8.8.100 +2.85.184.196 +103.47.132.46 +79.133.129.102 +190.203.199.46 +93.39.98.104 +84.92.49.138 +36.69.117.25 +95.221.121.107 +211.223.75.41 +58.7.217.226 +46.40.58.96 +190.139.245.143 +85.178.70.123 +109.90.216.220 +101.86.158.232 +5.254.97.83 +69.165.156.162 +66.244.243.71 +197.228.244.171 +89.201.143.8 +124.168.83.112 +109.221.74.155 +187.79.121.208 +147.174.212.205 +159.253.108.76 +105.107.107.89 +108.176.233.203 +95.127.186.240 +216.137.247.150 +144.76.80.131 +5.39.155.176 +95.30.80.59 +70.197.136.190 +92.47.117.145 +83.172.105.46 +46.45.177.105 +198.23.71.77 +178.223.4.97 +206.188.68.250 +73.173.136.64 +130.185.25.195 +37.79.249.241 +62.93.77.25 +151.230.112.174 +70.176.212.107 +140.186.42.40 +78.238.86.112 +89.210.204.47 +79.225.96.36 +79.151.214.170 +108.216.30.86 +254.10.154.56 +209.169.116.201 +182.182.49.168 +182.85.66.175 +189.204.176.165 +89.254.228.135 +172.98.86.180 +136.169.137.19 +96.26.11.23 +76.84.44.204 +90.33.0.92 +85.23.221.237 +94.51.47.247 +190.71.165.230 +93.86.251.111 +78.1.239.22 +201.233.213.167 +5.22.154.41 +90.191.101.40 +94.20.193.47 +177.39.36.136 +228.255.168.189 +77.189.0.87 +188.158.250.232 +79.245.222.98 +91.63.29.70 +24.16.227.151 +5.140.103.127 +2.97.122.142 +24.93.20.50 +162.105.147.153 +77.131.13.180 +81.137.228.44 +80.131.61.32 +114.124.32.33 +217.131.104.197 +114.146.9.91 +58.186.101.71 +79.225.117.161 +50.100.64.201 +113.159.116.23 +187.78.56.13 +79.101.163.235 +76.99.37.97 +177.43.27.207 +88.217.180.158 +190.62.160.100 +89.240.128.124 +80.174.238.232 +91.180.156.211 +92.111.224.150 +37.33.16.164 +186.93.233.2 +201.75.45.103 +176.253.92.248 +181.113.152.188 +151.235.168.3 +66.87.105.231 +93.123.163.96 +37.6.241.197 +171.96.167.221 +88.217.181.124 +147.229.5.69 +78.172.234.18 +83.59.145.113 +79.235.248.242 +91.97.49.211 +173.171.103.93 +85.59.71.189 +123.23.72.83 +203.180.120.138 +121.214.190.242 +112.81.14.147 +77.174.148.62 +25.3.101.63 +106.186.117.73 +31.186.114.70 +94.194.29.231 +194.25.88.251 +67.163.60.129 +97.122.182.147 +114.244.33.102 +95.232.214.73 +100.107.21.121 +213.198.237.54 +27.97.24.174 +37.6.124.54 +84.43.200.43 +92.11.32.51 +182.239.98.182 +201.32.61.11 +193.151.12.139 +18.111.60.56 +88.156.16.254 +128.72.238.171 +37.244.213.39 +79.31.221.169 +201.20.78.54 +0.0.0.0 +37.193.83.134 +78.100.87.147 +187.78.67.179 +108.221.194.216 +190.37.54.100 +179.43.128.34 +87.19.2.177 +37.47.8.4 +107.182.231.92 +89.142.139.140 +188.26.45.216 +0.0.0.0 +2.135.127.246 +103.16.26.207 +86.153.159.91 +109.43.2.126 +187.244.78.152 +71.97.33.233 +151.75.250.108 +88.170.196.80 +100.124.150.226 +78.137.0.103 +89.239.99.253 +162.216.46.78 +76.24.147.109 +77.254.205.10 +82.50.151.8 +2.85.50.0 +94.193.47.208 +185.124.230.193 +69.20.161.227 +81.246.133.24 +181.39.238.154 +46.147.184.84 +18.111.96.248 +63.155.2.193 +96.60.248.198 +78.207.218.25 +81.250.80.26 +153.172.192.46 +245.245.190.57 +67.0.18.218 +62.84.81.3 +103.28.115.235 +5.55.208.191 +217.123.88.45 +202.62.17.119 +94.177.81.33 +95.181.3.196 +99.172.17.234 +162.216.46.27 +98.90.67.180 +187.14.227.234 +218.250.11.174 +88.217.181.124 +78.69.188.169 +201.191.103.189 +141.223.152.249 +79.245.201.136 +67.177.206.230 +66.241.75.28 +95.84.178.168 +213.105.38.228 +94.181.233.37 +91.124.21.30 +79.141.166.17 +66.55.135.221 +108.61.228.169 +190.39.194.218 +119.39.236.134 +95.145.103.125 +2.229.136.11 +178.44.27.186 +218.255.254.190 +79.234.100.79 +46.158.242.81 +5.165.135.68 +186.91.130.118 +151.238.69.129 +122.175.144.74 +190.36.221.26 +89.146.60.241 +78.42.188.215 +72.14.177.91 +146.52.3.167 +146.52.16.145 +179.215.223.24 +88.207.0.181 +148.177.129.213 +87.168.167.96 +113.91.239.76 +78.88.29.163 +197.202.240.7 +187.161.83.225 +146.115.178.8 +83.11.145.235 +81.170.151.88 +88.6.13.88 +187.3.247.42 +220.137.43.135 +109.43.0.64 +213.151.1.230 +213.183.56.124 +87.109.45.12 +90.76.58.10 +14.198.159.95 +171.108.129.71 +189.129.182.159 +75.106.106.17 +88.14.212.76 +196.38.233.200 +24.96.26.254 +196.224.64.129 +84.147.123.215 +178.234.197.80 +91.224.96.243 +46.163.71.123 +171.4.232.251 +65.130.211.240 +190.207.4.72 +83.185.91.165 +86.19.142.124 +50.99.242.140 +208.66.28.37 +5.167.77.185 +112.215.124.182 +186.87.36.127 +190.88.244.75 +85.2.91.156 +93.131.97.28 +93.87.184.75 +72.80.67.77 +67.168.77.63 +24.212.88.112 +95.221.214.198 +175.136.176.196 +45.49.180.110 +109.43.3.23 +31.6.57.61 +77.11.217.57 +190.8.243.40 +187.78.53.57 +202.62.16.219 +80.237.22.69 +188.0.42.111 +209.188.18.43 +37.187.155.143 +118.209.232.218 +0.0.0.0 +159.253.104.154 +79.32.146.219 +87.185.12.225 +94.21.136.99 +198.199.111.146 +89.230.159.154 +67.204.56.10 +151.31.139.77 +62.158.154.188 +250.31.16.246 +104.200.151.80 +24.122.34.75 +82.181.13.55 +213.220.249.220 +71.176.46.169 +93.138.18.133 +184.88.116.74 +41.200.200.28 +94.113.72.197 +187.233.132.132 +46.5.0.161 +171.39.41.252 +187.155.97.233 +142.129.40.169 +54.200.198.82 +121.219.36.217 +189.174.170.55 +202.67.40.25 +194.47.109.200 +121.236.66.181 +171.39.26.245 +105.208.129.73 +79.24.119.90 +171.92.213.16 +151.224.152.231 +124.123.86.38 +81.71.91.126 +178.43.29.179 +223.207.122.199 +41.96.46.215 +189.239.115.156 +37.214.145.68 +121.211.89.111 +185.128.41.158 +41.246.123.128 +91.125.251.114 +104.158.176.65 +142.217.187.68 +173.189.166.182 +194.105.229.67 +174.16.185.42 +117.207.3.59 +69.165.254.195 +82.76.49.200 +0.0.0.0 +81.4.227.11 +2.99.222.116 +37.59.7.79 +89.65.234.136 +41.105.236.122 +79.245.205.193 +99.243.37.210 +188.73.192.30 +117.202.139.192 +76.99.37.97 +108.61.228.160 +183.15.242.154 +46.208.8.139 +62.240.181.147 +184.75.221.106 +69.40.145.76 +95.90.54.249 +52.53.236.222 +84.189.218.207 +161.167.37.106 +61.153.226.82 +79.224.0.44 +68.202.102.68 +188.207.95.41 +82.73.127.246 +31.54.226.230 +86.137.159.144 +85.174.34.176 +188.143.107.34 +190.37.97.133 +95.137.245.107 +109.197.66.62 +0.0.0.0 +203.87.129.142 +186.90.170.182 +78.145.238.131 +81.35.192.157 +190.26.40.17 +107.191.33.13 +74.51.57.173 +110.184.11.142 +0.0.0.0 +94.216.201.100 +83.220.237.57 +101.39.6.57 +109.175.113.175 +190.79.237.7 +124.122.41.109 +95.153.131.236 +69.197.181.114 +82.242.146.58 +74.111.229.219 +79.206.165.124 +192.151.148.186 +125.113.225.243 +189.177.91.251 +188.159.148.104 +177.39.37.153 +191.6.118.35 +173.198.238.83 +73.134.127.76 +104.172.170.74 +90.212.244.231 +BTCD Q.(9db5e1adb2273c47f5d9d87cb33027cb3977688bc21992c5a353a713cae54422) +189.59.195.43 +186.66.4.154 +174.28.153.216 +178.16.215.164 +122.149.208.35 +92.22.215.63 +83.138.249.88 +79.117.87.152 +188.17.112.90 +128.82.31.114 +109.209.194.113 +85.114.175.186 +83.11.67.88 +91.127.82.222 +62.68.106.115 +81.171.98.35 +184.64.19.148 +202.67.40.27 +91.141.3.205 +213.19.46.138 +67.43.116.233 +186.90.170.255 +109.0.0.31 +94.242.246.24 +108.23.17.119 +95.68.68.208 +46.139.162.104 +91.105.23.69 +24.65.232.255 +174.33.168.74 +95.28.186.141 +209.188.48.220 +109.43.1.168 +172.243.168.80 +89.172.205.251 +85.177.101.54 +115.88.119.132 +92.144.81.208 +80.229.146.133 +187.74.82.136 +71.218.165.31 +107.203.48.251 +84.154.166.32 +96.231.58.246 +191.23.3.239 +163.125.49.31 +84.154.93.193 +83.149.45.46 +78.15.204.86 +64.145.76.227 +90.164.181.147 +188.143.66.100 +91.63.7.2 +212.54.195.80 +130.180.220.46 +37.212.159.101 +68.224.6.180 +117.44.175.180 +211.91.223.39 +213.87.225.204 +188.168.145.223 +64.145.76.166 +180.94.82.42 +194.33.80.12 +79.130.190.240 +88.251.131.252 +52.78.24.7 +177.237.153.199 +24.170.254.35 +93.81.215.149 +37.147.67.237 +205.221.255.10 +36.78.194.162 +212.110.12.247 +201.248.244.231 +203.217.68.236 +104.237.143.215 +184.20.11.173 +80.229.146.133 +190.37.53.226 +70.215.7.228 +86.173.82.203 +203.111.224.35 +86.213.175.91 +94.23.29.195 +171.97.179.130 +181.24.41.5 +218.85.98.82 +93.143.246.250 +69.167.30.89 +46.46.208.61 +188.162.39.235 +78.80.54.23 +188.36.48.170 +179.198.46.19 +95.25.80.102 +77.162.138.28 +95.81.196.114 +5.42.92.88 +86.31.255.144 +105.2.95.87 +91.182.27.151 +80.31.158.250 +83.30.209.69 +2.86.47.118 +190.219.162.2 +79.245.208.136 +5.141.222.85 +178.62.10.67 +49.147.99.6 +90.60.115.247 +159.20.211.202 +49.181.182.80 +151.62.24.33 +37.47.38.27 +197.202.231.20 +186.212.36.105 +71.52.51.171 +86.135.18.75 +178.59.121.172 +91.148.114.205 +90.208.175.48 +88.123.48.123 +71.127.224.26 +101.184.137.186 +186.91.139.45 +101.184.130.85 +24.76.192.85 +197.37.149.32 +183.102.244.241 +151.228.170.206 +114.125.188.231 +61.90.25.159 +86.128.192.204 +41.244.240.73 +92.19.38.229 +94.216.207.28 +37.146.123.6 +188.69.210.86 +172.94.99.73 +125.165.31.1 +202.62.16.28 +37.146.127.175 +174.6.78.67 +64.71.77.50 +223.204.246.6 +76.25.23.251 +109.79.58.72 +188.31.153.62 +79.222.119.160 +146.52.50.232 +189.250.37.47 +87.7.63.165 +83.13.133.86 +35.62.33.205 +179.55.88.37 +172.56.23.96 +2.162.177.123 +190.39.45.189 +24.99.180.167 +104.34.30.248 +79.245.212.122 +80.101.191.202 +76.10.150.110 +181.24.43.245 +79.47.224.126 +86.211.114.37 +188.4.215.51 +89.104.6.79 +104.243.34.106 +95.26.34.131 +31.57.94.128 +112.215.124.102 +125.69.38.128 +186.95.6.151 +181.208.95.168 +75.108.167.179 +190.38.198.253 +209.188.32.147 +179.186.112.94 +54.165.27.102 +109.43.0.18 +152.234.132.59 +35.9.171.155 +50.51.197.8 +213.197.38.170 +86.152.54.251 +82.57.5.189 +80.131.60.202 +93.129.140.155 +69.7.91.24 +134.36.208.166 +84.251.165.229 +77.234.40.151 +61.90.27.245 +190.28.189.103 +113.254.169.130 +87.168.108.59 +78.235.150.223 +5.238.246.218 +5.167.32.244 +94.222.242.178 +50.114.6.16 +193.92.193.140 +128.75.218.21 +1.144.96.140 +179.177.124.224 +112.198.77.130 +219.73.14.96 +88.152.186.122 +88.196.236.26 +184.75.213.132 +78.25.120.68 +177.201.61.252 +201.41.173.2 +113.64.8.2 +176.104.36.109 +25.13.191.166 +2.97.162.47 +80.229.35.19 +40.115.45.107 +121.211.218.102 +58.168.26.66 +80.106.197.192 +84.236.59.214 +116.114.142.67 +124.171.136.150 +95.19.24.198 +93.156.81.50 +45.63.61.127 +198.23.103.87 +189.114.232.39 +189.229.167.181 +159.118.61.183 +45.55.151.50 +31.181.236.89 +163.158.250.139 +79.41.170.156 +108.61.229.10 +88.25.236.29 +190.3.209.72 +108.223.6.145 +95.175.104.22 +83.26.180.72 +202.130.109.150 +78.139.196.85 +189.114.199.175 +186.90.89.83 +68.229.135.60 +82.131.218.204 +203.145.92.88 +200.109.43.18 +41.241.224.53 +71.53.159.168 +192.121.166.87 +101.183.63.236 +104.157.219.89 +202.62.17.78 +203.206.37.169 +186.90.208.129 +81.153.89.132 +47.67.70.34 +85.166.223.81 +181.65.33.95 +95.174.113.172 +186.42.104.138 +190.87.69.166 +76.10.161.23 +176.58.128.13 +188.108.36.227 +71.177.147.37 +37.220.84.192 +89.178.178.93 +76.68.254.64 +171.78.136.68 +25.67.145.206 +156.17.119.7 +210.195.195.68 +160.76.210.181 +84.165.3.177 +187.230.36.79 +79.45.99.172 +68.129.158.12 +71.219.139.245 +201.240.242.139 +186.119.174.41 +113.97.132.45 +92.225.37.221 +95.175.104.22 +171.149.2.249 +100.105.53.177 +93.195.208.18 +108.61.48.17 +105.228.147.187 +59.101.186.240 +176.38.117.15 +198.252.123.121 +70.193.167.238 +173.65.129.85 +92.75.124.244 +46.167.28.138 +158.181.103.107 +53.193.238.83 +5.42.102.21 +81.108.157.78 +109.90.101.71 +66.55.144.245 +5.254.97.90 +181.167.112.208 +216.155.131.195 +113.254.168.141 +217.88.3.79 +172.56.9.204 +94.66.57.80 +171.250.154.38 +93.171.161.108 +92.69.227.130 +109.93.84.203 +92.93.148.140 +125.208.174.71 +97.82.95.148 +71.9.248.87 +120.22.205.53 +41.174.167.165 +201.211.181.115 +86.131.238.37 +123.118.140.58 +2.88.117.241 +18.111.106.205 +46.103.168.112 +178.184.11.84 +130.180.218.205 +85.186.135.106 +100.80.184.135 +104.200.151.35 +95.132.133.114 +106.192.7.54 +88.217.181.157 +195.209.48.241 +178.41.95.247 +77.218.226.1 +124.122.19.135 +188.162.37.144 +185.45.13.150 +92.108.233.53 +61.93.52.22 +177.17.190.131 +93.81.182.89 +93.139.171.57 +151.72.136.1 +2.85.62.106 +177.242.208.166 +69.167.32.159 +70.174.26.142 +178.93.129.60 +186.59.92.166 +193.92.113.59 +47.55.212.189 +86.81.26.232 +199.48.245.116 +163.172.137.241 +202.62.17.60 +186.88.199.92 +27.55.91.64 +88.17.166.160 +71.31.223.116 +178.164.155.102 +79.100.168.58 +137.189.91.71 +79.185.83.6 +60.218.122.249 +62.176.13.182 +162.156.115.215 +85.24.169.215 +74.108.73.130 +94.193.136.252 +100.101.141.18 +87.118.25.232 +79.204.167.160 +79.250.37.162 +190.79.151.17 +105.224.161.218 +104.200.151.30 +95.25.143.95 +37.188.230.20 +46.188.125.237 +86.213.221.91 +187.204.32.239 +118.209.183.77 +84.176.248.102 +93.141.164.210 +93.120.33.100 +109.43.0.139 +190.78.24.228 +118.186.151.51 +176.154.77.92 +112.81.12.8 +87.79.171.84 +188.69.208.134 +109.124.202.134 +78.125.183.215 +85.178.86.218 +171.96.167.179 +188.163.65.21 +91.140.100.221 +95.19.29.26 +109.190.9.138 +190.39.175.89 +91.232.105.11 +5.141.169.226 +209.95.50.146 +98.203.0.178 +64.145.94.121 +213.87.123.136 +2.122.165.251 +109.201.133.140 +198.84.201.135 +86.210.89.109 +97.99.207.76 +201.216.15.82 +197.211.52.27 +95.246.254.103 +95.252.134.151 +79.45.100.128 +94.11.149.91 +88.137.73.82 +104.131.170.147 +88.167.140.73 +108.202.111.84 +82.181.13.55 +190.56.114.113 +2.99.221.25 +46.216.100.240 +71.30.197.75 +190.201.120.214 +5.138.18.24 +2.61.184.34 +68.148.177.25 +188.26.139.30 +140.168.123.167 +94.50.196.84 +50.137.141.201 +85.228.201.142 +104.175.162.231 +95.19.18.117 +83.82.131.238 +78.157.215.233 +31.23.47.67 +94.68.230.137 +53.193.238.248 +94.54.72.158 +213.87.121.70 +190.36.247.207 +123.148.105.78 +24.27.53.213 +143.48.117.186 +86.128.158.98 +212.190.177.186 +109.194.110.54 +189.174.176.240 +81.202.82.179 +88.141.117.52 +109.81.211.44 +88.69.90.177 +87.0.208.25 +83.85.203.206 +114.125.184.144 +78.137.14.11 +188.158.167.162 +190.38.157.244 +121.121.121.224 +100.9.27.223 +79.70.37.23 +177.9.79.75 +197.225.230.167 +24.253.97.161 +65.28.240.121 +76.21.107.113 +166.170.14.126 +86.81.111.103 +81.141.6.218 +108.71.232.32 +121.175.188.133 +179.5.11.54 +186.91.87.81 +78.148.248.150 +189.41.69.166 +188.208.105.198 +24.17.172.33 +173.74.190.170 +128.72.218.191 +25.4.3.201 +24.175.65.6 +66.87.66.220 +178.141.162.104 +81.158.189.210 +96.30.159.45 +69.167.31.166 +93.147.216.154 +177.42.121.198 +202.62.16.152 +79.157.252.14 +76.21.107.113 +128.71.102.82 +93.34.48.75 +69.7.86.218 +70.30.19.40 +2.219.68.243 +190.205.166.112 +203.164.148.154 +151.15.56.129 +193.253.170.86 +190.73.40.185 +24.231.137.146 +41.174.139.14 +200.75.102.219 +190.200.107.145 +171.96.170.169 +150.29.142.101 +14.98.83.166 +109.43.3.24 +201.211.225.122 +50.81.149.145 +53.193.239.251 +115.239.120.141 +188.114.163.176 +79.245.216.10 +71.19.249.4 +84.99.198.192 +91.228.204.51 +171.149.2.249 +50.51.65.134 +50.48.150.80 +74.12.45.62 +76.99.37.97 +75.189.132.144 +182.87.167.175 +70.44.128.63 +88.196.10.83 +62.232.5.242 +189.214.6.82 +78.138.106.240 +77.28.14.8 +73.90.209.112 +81.162.122.102 +79.255.224.173 +108.252.164.33 +190.203.14.155 +197.207.33.170 +92.133.75.32 +212.174.163.152 +209.107.214.80 +60.211.184.242 +24.40.146.45 +186.46.206.91 +91.148.94.105 +94.233.97.100 +204.186.68.213 +197.88.129.16 +108.185.135.18 +95.25.10.41 +112.208.185.255 +5.61.93.226 +81.158.203.27 +62.149.25.99 +66.237.51.224 +2.228.69.84 +47.88.79.118 +188.129.113.90 +46.59.172.34 +217.95.236.212 +24.137.85.148 +91.185.117.103 +24.17.139.255 +186.88.33.5 +1.0.0.0 +84.92.106.61 +110.168.232.136 +218.30.116.8 +188.174.91.59 +84.215.211.115 +50.0.0.56 +128.90.92.104 +190.171.121.223 +188.239.15.25 +71.90.53.87 +174.148.152.154 +145.28.186.232 +212.198.177.53 +69.172.72.115 +105.229.140.158 +90.54.252.148 +89.204.135.163 +200.8.52.205 +81.101.62.218 +104.157.135.129 +95.113.53.138 +175.138.204.119 +186.92.251.74 +171.96.167.209 +188.69.198.224 +190.203.32.110 +82.60.153.56 +151.53.183.73 +104.156.228.71 +171.97.224.32 +5.237.52.187 +51.175.41.140 +146.156.249.160 +5.239.187.61 +162.216.46.79 +24.22.111.175 +172.58.16.128 +70.173.209.163 +188.16.122.219 +1.0.0.0 +173.199.65.38 +2.6.43.143 +100.68.139.112 +92.241.152.185 +2.97.165.140 +171.97.198.46 +95.141.28.120 +95.18.39.118 +94.191.186.178 +46.44.3.174 +202.62.17.7 +109.228.92.211 +98.206.56.123 +90.205.138.179 +85.220.18.205 +188.54.228.4 +87.7.152.225 +74.216.83.159 +178.221.180.123 +94.41.57.154 +91.180.129.192 +92.157.155.123 +31.15.157.135 +223.227.19.176 +250.31.16.246 +176.92.4.24 +176.49.127.211 +72.191.228.161 +108.24.82.4 +186.92.222.216 +36.71.162.55 +213.151.2.192 +70.67.20.129 +114.79.37.125 +79.167.174.105 +24.114.70.184 +111.241.89.140 +37.45.176.243 +85.222.168.41 +21.106.179.117 +78.90.74.65 +77.43.228.161 +81.245.102.36 +80.235.60.48 +84.104.85.140 +79.246.240.229 +89.204.153.239 +112.215.123.37 +74.207.189.1 +189.217.117.45 +93.123.247.211 +0.0.0.0 +159.255.11.52 +173.244.16.243 +91.134.120.210 +81.141.8.254 +95.52.155.233 +24.246.57.236 +109.201.152.243 +86.95.134.254 +212.83.191.197 +180.172.140.92 +181.42.16.241 +223.227.246.32 +58.44.187.100 +67.248.195.131 +213.152.161.40 +82.75.141.118 +216.4.56.185 +120.22.163.204 +188.162.39.180 +71.208.224.19 +95.252.27.29 +188.221.189.125 +217.88.13.199 +165.255.85.246 +82.151.45.31 +37.78.112.147 +213.102.150.212 +178.234.235.67 +84.44.131.103 +105.228.79.241 +178.206.88.22 +85.23.16.56 +179.229.178.122 +151.24.155.96 +201.242.164.67 +193.92.127.190 +81.136.219.237 +46.129.112.120 +37.201.195.214 +177.206.0.121 +36.224.107.193 +72.67.20.72 +46.147.229.101 +61.136.176.26 +37.212.159.101 +113.195.251.160 +177.16.121.49 +201.198.42.134 +173.182.128.9 +91.214.131.89 +188.0.47.15 +186.89.49.29 +64.247.87.184 +198.96.94.12 +5.153.133.34 +46.146.115.38 +202.62.17.253 +62.202.41.207 +1.0.0.0 +176.84.8.114 +2.61.133.195 +213.24.135.217 +2.85.57.6 +91.127.18.187 +178.217.61.229 +79.245.222.54 +37.190.51.38 +87.197.162.200 +92.209.186.41 +190.177.79.50 +85.56.6.223 +94.66.57.164 +41.96.150.179 +5.2.64.14 +204.63.214.118 +5.156.106.61 +1.162.23.172 +116.231.133.47 +77.49.129.46 +24.114.81.205 +75.144.36.41 +94.50.196.84 +94.196.198.83 +107.222.140.101 +41.105.236.122 +75.168.7.211 +100.75.135.9 +103.28.115.236 +87.171.199.84 +2.84.13.138 +154.20.188.72 +186.91.130.118 +31.57.93.197 +195.29.192.134 +223.227.9.239 +213.227.252.124 +111.69.136.191 +187.170.154.194 +217.44.16.102 +85.222.168.41 +112.10.225.195 +189.156.67.120 +190.205.166.112 +186.90.15.65 +200.108.51.202 +67.44.192.24 +92.237.52.138 +120.209.131.70 +202.5.158.177 +85.192.189.112 +46.246.27.154 +95.25.49.95 +87.185.8.189 +109.90.101.71 +79.13.106.74 +125.160.196.119 +173.72.136.151 +93.178.76.184 +113.254.169.130 +93.233.152.57 +78.144.191.65 +104.200.151.45 +49.146.10.81 +186.46.224.196 +88.206.141.108 +190.200.61.206 +94.197.121.40 +79.245.217.6 +2.240.130.103 +2.95.20.67 +104.238.169.9 +93.208.127.67 +98.119.235.95 +2.85.183.249 +81.44.162.170 +73.90.209.45 +80.106.197.69 +93.143.218.109 +185.93.180.126 +202.62.16.49 +112.65.211.240 +95.142.108.188 +85.211.8.234 +37.47.217.13 +109.221.221.236 +95.236.175.233 +84.0.102.77 +190.37.161.225 +188.233.169.18 +5.140.218.85 +69.131.31.129 +164.183.100.69 +91.205.64.202 +188.76.15.37 +192.155.95.192 +86.26.86.157 +91.7.16.25 +187.143.212.81 +77.173.188.205 +65.93.21.22 +100.91.109.186 +210.129.18.130 +84.147.114.223 +24.164.76.73 +62.183.124.221 +88.208.1.194 +82.28.121.36 +190.236.62.194 +178.43.81.171 +190.62.152.218 +89.212.241.225 +68.229.235.123 +178.122.64.75 +197.110.210.233 +104.28.201.93 +109.43.1.114 +190.70.91.241 +187.240.118.122 +41.150.125.109 +203.184.41.205 +188.129.213.220 +95.151.54.119 +68.172.251.98 +196.217.160.51 +37.6.225.42 +113.254.170.50 +1.0.0.0 +71.231.218.6 +188.226.195.109 +83.131.227.230 +68.5.130.116 +18.111.35.103 +109.208.182.118 +81.247.76.128 +231.112.130.210 +98.248.40.222 +177.7.102.99 +92.113.189.236 +95.26.205.91 +176.104.35.147 +93.79.71.20 +72.79.77.139 +190.213.142.25 +73.252.3.47 +162.216.46.125 +162.213.195.228 +162.213.158.169 +112.67.211.172 +41.48.191.235 +24.114.73.133 +116.205.23.233 +0.0.0.2 +110.115.32.92 +179.197.172.50 +138.91.165.233 +80.131.211.219 +88.14.20.177 +50.84.116.21 +164.40.228.53 +190.77.79.217 +186.144.112.38 +2.25.69.36 +24.114.76.239 +82.163.165.25 +186.90.184.149 +58.8.219.112 +5.14.222.215 +5.132.7.24 +68.87.76.243 +80.107.31.185 +114.98.87.245 +119.73.122.163 +79.245.219.88 +1.54.140.99 +109.74.162.200 +60.17.17.253 +141.255.56.249 +65.185.68.233 +185.65.132.120 +195.211.206.164 +201.210.136.83 +83.9.96.10 +189.188.174.83 +90.191.107.13 +176.10.63.196 +77.53.37.165 +171.96.167.227 +203.217.27.155 +71.239.236.145 +88.24.199.135 +2.181.155.234 +68.180.0.197 +99.247.170.15 +25.31.60.102 +202.67.44.10 +142.162.162.174 +179.192.193.202 +187.243.164.218 +175.138.150.222 +212.107.130.19 +24.79.178.91 +90.66.29.221 +203.98.92.130 +209.54.7.184 +86.177.72.232 +107.140.146.255 +202.62.17.78 +174.117.209.16 +172.94.99.73 +80.204.143.24 +188.221.74.104 +87.185.22.183 +189.226.123.32 +84.200.17.236 +186.91.50.237 +212.106.255.119 +224.40.3.89 +84.147.124.207 +85.229.198.73 +76.90.104.41 +190.212.244.19 +41.105.238.99 +189.47.90.126 +181.162.51.72 +128.90.88.120 +49.76.15.28 +84.142.125.8 +73.198.40.189 +76.99.37.97 +37.112.79.133 +99.238.196.59 +80.174.72.157 +114.244.45.88 +201.208.197.14 +193.92.127.190 +193.173.216.162 +139.193.221.33 +109.158.12.15 +64.145.94.48 +95.28.160.27 +185.7.46.146 +78.250.186.8 +69.159.104.146 +78.38.63.156 +179.126.249.236 +81.240.48.1 +244.209.195.105 +110.168.232.79 +5.14.221.9 +151.250.240.128 +2.217.210.28 +93.222.175.111 +49.145.140.122 +171.149.2.249 +123.53.89.184 +187.61.214.202 +92.224.245.246 +88.217.180.105 +108.62.225.240 +92.44.150.250 +71.201.35.156 +139.216.147.57 +187.233.182.174 +93.143.233.193 +86.197.141.131 +217.233.83.164 +84.135.91.85 +217.120.206.46 +151.20.124.54 +199.111.185.207 +52.78.91.225 +31.150.160.86 +206.123.150.137 +186.95.106.66 +110.167.196.251 +24.165.181.252 +62.98.9.235 +85.222.175.183 +176.84.165.12 +190.22.129.121 +0.0.0.0 +24.115.240.34 +2.100.165.102 +178.221.162.236 +179.110.98.186 +190.181.64.234 +1.204.8.21 +217.64.16.147 +93.137.203.121 +89.245.125.162 +62.74.23.192 +31.28.57.234 +82.123.62.119 +0.0.0.2 +209.188.5.234 +72.50.144.23 +58.11.110.34 +92.37.172.246 +205.148.137.165 +80.235.62.90 +37.115.172.148 +222.243.67.252 +92.24.149.39 +187.143.158.32 +108.12.25.189 +50.137.239.137 +108.19.160.97 +112.215.123.103 +186.93.225.184 +2.83.192.141 +201.242.121.142 +200.82.219.161 +90.191.168.246 +190.103.63.253 +2.103.0.246 +109.111.243.164 +77.168.116.193 +171.96.171.107 +176.210.249.150 +41.128.142.187 +166.8.189.210 +166.188.190.201 +125.24.154.62 +188.84.48.223 +104.229.193.72 +68.226.30.59 +219.73.101.145 +113.190.33.241 +231.190.16.139 +79.43.216.64 +209.197.6.177 +187.26.79.39 +24.114.74.3 +182.99.255.85 +82.235.133.55 +85.178.128.44 +94.41.64.71 +209.205.208.34 +159.29.194.242 +90.7.193.85 +190.73.66.101 +151.20.124.54 +88.9.101.254 +106.185.55.134 +78.225.68.197 +94.34.208.109 +46.98.111.40 +2.137.111.25 +109.92.122.58 +95.30.170.195 +79.159.102.102 +2.134.151.188 +181.92.15.216 +68.247.75.133 +150.117.170.89 +104.58.140.37 +79.245.207.167 +70.81.224.17 +84.19.165.218 +84.236.120.253 +86.156.8.126 +89.164.147.115 +189.59.116.231 +67.3.70.193 +23.94.218.151 +90.0.44.245 +79.143.165.131 +173.165.129.125 +176.93.171.12 +97.90.202.210 +94.10.79.126 +50.17.187.172 +86.85.128.100 +91.179.13.23 +86.173.80.107 +62.45.107.249 +109.204.151.99 +200.86.31.106 +0.0.0.0 +104.207.152.123 +109.76.221.45 +84.152.134.167 +186.91.142.193 +125.165.31.1 +188.162.132.82 +58.11.101.70 +79.204.182.114 +190.38.45.209 +86.80.230.190 +84.198.138.27 +85.242.84.158 +77.254.199.139 +94.67.207.249 +216.218.29.243 +78.35.153.26 +89.182.23.25 +79.165.175.137 +72.213.129.244 +0.0.0.0 +78.144.145.162 +172.15.208.80 +86.20.157.128 +64.188.205.179 +88.71.238.22 +85.140.1.122 +0.0.0.0 +109.88.184.11 +5.141.201.95 +94.181.94.128 +97.121.11.235 +93.55.192.12 +193.92.193.104 +179.7.171.165 +187.149.83.67 +0.0.0.0 +62.113.202.198 +189.202.73.82 +212.228.253.143 +181.128.111.78 +85.23.16.56 +31.132.225.205 +200.93.115.124 +42.130.174.45 +41.109.219.175 +138.99.148.20 +128.71.175.210 +178.92.103.221 +46.72.208.82 +170.152.244.231 +90.201.158.28 +217.23.187.7 +188.238.63.233 +81.171.71.145 +37.79.250.236 +105.155.44.171 +187.10.148.221 +79.152.183.84 +186.14.2.70 +87.202.44.226 +92.37.46.31 +82.60.11.203 +41.239.159.32 +212.71.239.55 +209.95.50.146 +113.254.161.101 +1.0.0.0 +109.221.205.158 +169.0.169.119 +187.59.221.156 +113.185.5.149 +95.141.28.120 +220.141.132.225 +50.158.229.59 +86.179.6.141 +85.51.145.189 +5.139.143.43 +217.89.4.240 +178.41.66.119 +170.0.21.4 +99.242.164.212 +117.193.62.6 +95.189.25.41 +37.45.88.138 +78.183.9.101 +209.112.242.83 +5.28.25.30 +71.52.54.197 +37.0.37.37 +67.177.203.222 +76.187.186.183 +114.96.99.19 +200.69.176.198 +31.132.225.187 +74.72.30.82 +50.153.148.174 +0.0.0.0 +91.103.38.0 +218.142.99.184 +67.136.44.155 +41.161.91.217 +83.26.249.88 +90.192.241.230 +31.61.140.252 +93.134.99.101 +95.215.60.22 +95.221.21.83 +39.35.33.24 +182.16.25.196 +66.55.144.246 +25.5.5.161 +91.182.48.19 +193.51.6.5 +91.115.63.103 +76.169.199.180 +99.253.26.181 +120.56.106.3 +180.251.194.182 +105.228.120.31 +90.9.145.61 +86.172.239.91 +85.179.131.77 +79.224.86.119 +24.65.229.207 +67.141.21.99 +213.87.225.204 +85.26.108.232 +110.96.188.37 +190.219.127.173 +86.202.71.200 +181.31.207.140 +50.5.127.178 +37.24.152.178 +178.92.91.59 +181.54.60.125 +5.141.231.188 +220.233.77.65 +91.158.212.23 +178.234.233.200 +96.127.136.18 +179.212.185.123 +101.108.114.192 +78.234.188.9 +178.120.131.163 +217.122.124.200 +45.63.1.236 +84.26.74.79 +88.15.230.239 +205.197.242.145 +187.254.159.150 +75.69.160.21 +36.77.19.191 +83.198.46.116 +90.104.92.241 +81.158.189.210 +186.91.198.52 +213.226.219.55 +74.109.190.39 +122.17.0.22 +69.128.222.166 +109.148.240.225 +217.235.255.224 +1.162.96.155 +194.65.46.7 +217.99.240.219 +222.254.29.181 +1.162.89.118 +113.162.145.181 +188.69.194.196 +114.217.17.35 +89.151.173.175 +89.230.65.93 +172.5.141.163 +173.120.226.13 +37.190.39.194 +41.96.104.28 +216.58.117.236 +222.47.197.29 +94.191.185.112 +201.208.13.107 +78.232.43.89 +186.90.67.226 +198.100.148.190 +109.77.111.172 +164.40.231.252 +109.88.154.44 +92.100.128.83 +176.31.126.191 +79.245.194.135 +119.224.42.248 +54.189.37.6 +178.126.244.130 +5.135.36.128 +1.162.95.90 +213.151.2.186 +98.108.240.147 +80.81.242.72 +134.249.208.212 +87.15.222.204 +68.233.247.206 +189.202.95.142 +75.82.43.75 +59.40.135.128 +84.127.218.248 +78.55.250.20 +136.159.160.254 +76.18.138.1 +213.87.224.108 +79.175.68.95 +24.111.193.89 +62.152.54.44 +188.165.82.238 +86.115.102.42 +77.182.14.34 +84.177.180.24 +68.48.26.79 +91.148.113.76 +67.169.167.174 +104.131.142.198 +85.178.129.138 +67.80.146.83 +79.16.92.158 +113.92.2.25 +201.229.84.90 +89.26.78.16 +176.210.249.150 +213.127.93.143 +197.225.239.193 +2.137.15.53 +2.62.10.239 +109.153.188.99 +122.231.161.40 +88.236.9.175 +86.194.143.131 +212.251.18.47 +2.85.61.239 +213.67.134.6 +46.40.3.22 +77.28.5.136 +85.244.119.66 +212.54.207.204 +91.152.158.166 +162.216.46.83 +89.178.173.167 +76.123.100.141 +94.50.225.189 +189.202.84.78 +83.209.227.97 +81.11.221.213 +84.154.93.193 +50.155.70.199 +89.38.35.81 +188.0.47.35 +5.239.189.169 +217.131.240.122 +125.125.36.49 +77.251.14.224 +213.87.127.200 +179.179.63.226 +88.0.193.105 +90.191.107.104 +217.249.8.127 +113.13.96.143 +60.228.7.131 +177.225.193.106 +87.228.87.106 +89.148.221.72 +223.205.250.2 +88.246.172.162 +175.33.51.90 +105.156.160.16 +18.111.35.103 +71.30.197.75 +128.227.44.156 +204.186.126.127 +171.97.232.160 +190.96.207.71 +173.54.222.61 +2.104.151.66 +188.2.75.7 +222.183.51.191 +254.85.113.235 +109.214.70.45 +93.80.192.247 +85.179.169.40 +83.134.9.165 +209.54.15.175 +114.124.6.53 +121.208.89.35 +74.195.24.126 +77.181.48.236 +194.105.229.79 +178.198.214.231 +79.198.45.189 +186.93.214.168 +181.10.83.45 +201.6.131.6 +71.192.103.83 +109.201.152.244 +213.139.53.26 +179.55.87.12 +147.171.166.52 +190.22.130.27 +95.18.37.144 +123.16.221.44 +174.148.11.181 +197.246.171.176 +37.150.246.127 +172.15.0.102 +89.36.109.189 +182.89.227.143 +71.220.184.56 +100.68.89.183 +209.73.136.231 +98.215.49.232 +62.227.194.150 +138.91.165.233 +172.88.252.206 +87.5.0.248 +91.67.236.178 +77.120.70.123 +45.56.39.12 +79.16.234.212 +0.0.0.0 +2.121.201.171 +77.49.210.153 +190.22.244.92 +75.174.90.85 +92.144.209.103 +79.245.218.167 +41.132.252.67 +176.52.8.50 +78.150.15.78 +24.12.49.237 +24.189.15.109 +201.248.248.9 +201.119.148.239 +171.96.181.31 +174.66.3.25 +174.119.243.201 +223.206.69.173 +45.56.46.176 +79.206.172.204 +67.44.192.186 +188.158.169.194 +67.44.193.22 +110.149.118.131 +70.193.167.238 +67.245.82.244 +99.4.121.145 +25.191.20.230 +115.68.116.26 +37.229.90.67 +186.83.12.194 +70.189.229.36 +123.16.210.191 +219.73.101.145 +189.153.44.62 +84.20.242.6 +179.55.35.82 +141.134.124.89 +84.24.63.74 +213.16.224.169 +85.76.98.73 +82.73.127.246 +117.0.121.2 +37.229.90.67 +112.210.36.207 +177.156.187.106 +113.254.169.237 +94.4.193.51 +78.100.87.147 +109.226.126.1 +84.159.253.190 +151.20.54.200 +74.109.186.240 +88.231.216.214 +101.116.36.225 +84.147.113.190 +91.48.37.59 +72.191.14.137 +94.69.53.225 +94.50.197.11 +180.137.141.239 +100.65.40.61 +37.188.233.210 +195.37.133.6 +100.4.151.242 +118.140.106.58 +BTCD received.(9db5e1adb2273c47f5d9d87cb33027cb3977688bc21992c5a353a713cae54422) 62.75.145.171 +83.5.143.28 +ramchaindata have 2507:230 at 0 | 1083 blocks 565.112kb redundant xfers total 4225.637kb 13.37% wasted +194.105.229.207 +78.32.154.221 +85.102.206.164 +78.111.190.48 +186.118.34.106 +BTCD Q.(9db5e1adb2273c47f5d9d87cb33027cb3977688bc21992c5a353a713cae54422) +BTCD received.(9db5e1adb2273c47f5d9d87cb33027cb3977688bc21992c5a353a713cae54422) 62.75.145.171 +165.255.211.19 +100.68.47.205 +188.18.203.231 +94.177.81.30 +90.151.184.124 +184.160.95.44 +79.66.126.192 +83.59.144.92 +84.154.93.193 +153.34.162.179 +190.38.148.249 +190.99.132.240 +212.215.224.17 +189.110.171.228 +188.239.15.25 +5.254.97.91 +124.234.84.44 +101.39.53.222 +189.204.177.58 +93.136.52.207 +41.13.228.209 +217.95.244.224 +98.251.223.23 +92.251.101.228 +37.188.238.115 +115.87.132.88 +37.252.127.221 +93.107.67.54 +202.99.16.22 +95.19.31.118 +84.106.253.6 +200.44.196.213 +200.106.89.56 +62.94.37.53 +86.212.5.83 +37.214.147.64 +41.141.65.94 +231.255.154.44 +67.181.59.52 +122.56.33.171 +12.170.41.202 +69.123.132.73 +101.73.92.57 +178.148.11.106 +108.161.125.223 +7.99.150.241 +42.115.112.202 +41.138.68.56 +89.254.236.121 +181.55.116.136 +83.163.213.240 +201.152.251.21 +213.45.49.161 +173.245.221.74 +78.151.193.140 +83.85.139.25 +78.223.119.211 +105.228.120.31 +178.37.195.27 +24.52.202.171 +69.34.135.229 +62.158.135.252 +77.243.183.25 +193.51.6.5 +46.8.157.22 +186.183.160.125 +130.234.206.24 +90.171.247.95 +90.216.200.56 +181.90.109.168 +94.208.224.23 +202.62.16.235 +94.174.9.29 +105.184.186.83 +180.252.156.92 +176.14.105.238 +79.204.138.25 +178.162.217.137 +50.124.7.101 +105.237.92.26 +217.235.248.71 +77.181.67.202 +81.244.67.231 +2.106.197.126 +198.60.192.203 +172.56.16.140 +109.93.83.59 +164.8.204.206 +80.131.61.143 +68.7.182.201 +187.37.140.36 +2.85.190.33 +31.61.140.246 +192.126.96.23 +190.42.58.145 +177.133.104.179 +93.125.88.66 +66.27.145.33 +109.43.0.90 +46.117.146.30 +68.101.51.124 +70.173.132.2 +95.103.163.175 +213.103.202.73 +193.77.222.200 +5.144.152.186 +190.77.248.84 +136.243.151.210 +31.163.191.135 +53.193.238.189 +176.51.149.113 +178.43.55.236 +31.23.114.101 +87.185.20.94 +109.190.65.26 +77.180.215.167 +85.54.220.250 +187.76.101.115 +104.200.151.21 +186.90.2.208 +179.43.134.2 +85.216.83.42 +83.44.53.138 +178.213.170.179 +149.202.44.159 +181.53.51.250 +85.4.99.184 +91.210.228.154 +100.87.134.150 +105.2.95.87 +104.156.228.106 +113.254.170.25 +109.74.170.77 +91.63.1.128 +184.196.189.176 +0.0.0.0 +98.23.36.117 +5.30.69.217 +81.156.49.21 +186.92.42.206 +24.155.201.9 +217.95.247.139 +78.1.135.191 +231.25.196.155 +92.40.250.89 +89.182.204.27 +222.65.60.115 +189.188.200.85 +109.184.107.220 +80.41.226.120 +68.247.175.72 +172.56.35.48 +93.109.240.14 +62.195.196.17 +109.81.210.29 +193.92.113.59 +217.95.244.246 +24.43.219.20 +118.90.32.199 +50.163.71.222 +50.204.92.20 +212.54.195.80 +73.11.157.169 +1.52.142.82 +77.4.123.65 +114.124.0.126 +80.131.61.147 +180.183.78.160 +200.109.173.48 +186.147.138.125 +189.218.127.228 +83.26.30.141 +87.178.158.126 +5.12.117.226 +117.195.26.85 +90.45.1.225 +46.159.55.58 +74.67.4.49 +168.70.86.30 +40.45.199.182 +120.156.17.55 +92.144.208.211 +176.65.127.119 +37.227.63.102 +1.53.140.105 +74.59.25.31 +209.107.214.70 +94.41.64.71 +71.61.74.28 +182.203.112.237 +194.105.229.51 +84.248.15.13 +88.91.89.94 +190.36.142.185 +177.133.210.69 +128.199.90.150 +79.17.250.93 +190.204.35.44 +95.93.101.100 +85.247.50.96 +83.36.224.90 +188.187.163.21 +37.201.6.202 +2.138.143.40 +212.5.52.32 +41.174.167.165 +108.176.233.203 +82.77.161.202 +173.86.39.226 +178.117.89.113 +81.250.82.21 +94.70.5.65 +86.218.197.161 +85.237.174.4 +62.249.146.6 +109.251.79.19 +165.255.212.151 +73.241.142.127 +202.62.17.51 +191.184.111.49 +90.33.25.232 +108.61.177.98 +111.69.86.174 +177.72.51.158 +46.28.102.197 +67.86.22.30 +117.184.152.115 +94.65.84.87 +158.69.126.193 +83.185.82.143 +60.51.44.27 +158.165.52.119 +78.43.68.161 +82.142.112.229 +109.169.229.160 +187.200.176.71 +192.153.117.70 +190.198.36.172 +174.49.110.107 +177.205.65.140 +162.124.179.124 +184.97.238.93 +212.251.28.147 +107.204.205.115 +118.233.235.7 +92.141.13.211 +94.194.29.231 +0.0.255.72 +217.174.155.155 +198.27.97.180 +101.183.39.28 +83.185.95.8 +31.174.69.205 +197.246.171.176 +46.158.93.79 +109.43.1.169 +37.122.124.42 +68.232.186.171 +79.245.219.75 +82.235.133.55 +188.162.14.104 +128.90.88.111 +80.60.124.251 +199.255.211.45 +187.161.82.160 +94.50.196.84 +190.31.72.99 +70.89.142.142 +108.24.86.234 +124.73.67.105 +177.157.52.241 +92.76.239.3 +189.144.45.28 +105.229.179.226 +92.100.195.14 +31.216.4.218 +99.197.201.17 +217.249.134.16 +188.73.253.71 +2.102.152.141 +24.0.207.196 +88.217.181.105 +95.221.16.31 +79.41.170.156 +162.255.127.179 +98.223.11.108 +87.11.82.157 +120.56.209.210 +70.215.195.68 +177.96.90.235 +71.31.219.197 +83.149.19.188 +139.0.138.197 +2.140.8.160 +110.174.123.194 +202.62.16.2 +113.254.169.102 +163.211.239.49 +25.150.39.43 +188.67.72.26 +24.212.112.98 +68.180.0.247 +0.0.0.0 +190.77.157.248 +95.141.29.55 +218.11.179.53 +123.57.15.153 +50.97.94.13 +46.164.146.229 +191.255.75.75 +171.97.198.217 +179.206.137.230 +2.27.252.8 +113.185.5.219 +117.44.175.180 +87.185.6.49 +220.246.220.129 +67.212.175.124 +104.238.180.11 +83.22.116.40 +91.179.53.23 +184.75.213.134 +95.137.245.107 +71.55.98.29 +88.232.3.134 +78.52.77.247 +86.89.192.38 +189.144.13.93 +2.62.46.234 +32.51.14.233 +190.39.44.61 +41.96.91.221 +84.42.44.243 +195.149.108.47 +42.112.88.62 +219.79.191.98 +145.120.12.175 +173.89.14.220 +178.222.183.202 +202.62.16.223 +95.24.97.176 +99.248.251.175 +124.171.172.128 +79.102.32.183 +32.51.14.233 +173.192.81.187 +93.137.217.239 +69.65.254.34 +75.76.66.211 +112.211.71.79 +173.247.188.146 +91.52.238.180 +31.162.134.45 +100.68.38.19 +91.33.207.56 +37.6.242.30 +93.73.243.27 +198.27.81.25 +79.102.32.183 +31.21.146.153 +207.179.164.139 +151.229.236.167 +223.204.240.178 +188.163.73.109 +223.204.240.178 +31.207.187.18 +95.25.39.141 +188.162.36.185 +66.87.145.79 +86.18.76.197 +178.65.247.160 +188.163.24.68 +151.72.136.1 +85.217.41.121 +178.65.14.106 +92.225.63.145 +2.83.157.97 +186.241.93.247 +85.229.185.207 +186.46.206.91 +39.48.13.64 +85.151.220.225 +85.127.120.155 +78.149.251.8 +104.180.224.241 +85.6.207.160 +178.219.94.51 +179.55.32.49 +93.205.27.117 +52.37.109.241 +185.81.229.113 +50.106.172.180 +219.73.15.59 +76.30.179.116 +112.10.225.195 +171.96.170.153 +89.42.107.153 +130.25.88.216 +81.153.89.132 +188.158.189.191 +46.244.217.69 +201.22.187.49 +139.193.221.33 +191.43.11.225 +191.102.196.35 +64.237.51.174 +87.98.178.140 +2.122.165.251 +64.145.76.140 +193.92.63.7 +178.234.208.247 +186.117.166.66 +187.95.127.151 +172.56.15.18 +24.184.24.162 +2.125.57.174 +92.55.105.130 +90.191.99.12 +25.16.26.157 +84.152.140.60 +109.182.104.245 +5.233.35.110 +173.86.39.226 +176.33.105.89 +64.121.250.235 +186.62.25.143 +109.43.2.140 +171.97.196.82 +94.96.41.4 +178.158.184.222 +188.131.34.151 +50.101.183.116 +208.74.1.9 +5.138.55.122 +94.208.224.23 +79.46.67.10 +39.35.109.251 +91.39.32.112 +114.124.0.126 +189.241.106.61 +192.0.203.126 +24.216.240.156 +90.39.140.211 +254.142.100.172 +91.140.52.140 +109.237.103.127 +154.69.72.35 +98.19.169.52 +24.92.213.63 +209.202.73.79 +78.1.168.144 +80.103.188.87 +83.26.28.36 +95.153.131.35 +139.193.58.22 +195.64.75.134 +123.190.61.215 +92.84.12.209 +115.152.154.77 +176.195.241.216 +45.50.43.165 +94.137.0.24 +93.137.137.136 +83.10.88.80 +104.173.205.55 +93.77.17.218 +213.67.95.128 +70.196.132.76 +151.28.181.143 +63.104.240.81 +188.18.15.139 +181.208.22.54 +70.81.20.54 +110.168.232.83 +62.165.226.97 +171.5.33.189 +86.197.147.26 +92.157.155.123 +92.24.120.135 +180.140.17.174 +176.194.17.251 +78.0.35.159 +83.89.104.40 +89.217.239.176 +75.161.2.197 +185.3.32.186 +95.175.104.52 +67.208.79.69 +70.209.72.10 +101.116.78.128 +95.81.253.151 +72.105.145.66 +108.250.162.103 +31.96.46.73 +84.147.119.180 +176.8.52.211 +95.153.130.235 +184.148.241.101 +128.68.161.107 +118.136.159.10 +2.100.80.66 +105.186.110.98 +121.208.142.172 +77.51.121.67 +109.241.213.159 +83.134.97.101 +31.132.225.141 +90.11.159.241 +109.241.147.183 +186.188.107.216 +42.96.176.198 +80.100.1.187 +24.59.157.255 +190.77.73.12 +178.43.50.5 +184.75.213.117 +50.173.38.87 +86.26.86.157 +98.126.5.146 +178.55.136.130 +89.102.26.229 +100.38.18.167 +177.249.155.35 +41.244.241.253 +37.45.103.181 +85.173.134.61 +42.96.165.239 +85.241.198.54 +151.224.62.223 +5.141.221.53 +213.137.36.3 +92.73.203.118 +193.161.15.72 +60.213.89.243 +41.13.28.225 +79.245.218.167 +94.179.125.146 +62.241.245.182 +49.144.46.25 +86.9.138.104 +90.6.231.45 +190.56.72.120 +84.175.233.214 +91.48.40.244 +46.175.68.4 +103.255.4.53 +78.15.181.215 +122.73.59.85 +91.14.44.208 +188.18.15.219 +218.27.203.199 +178.210.51.98 +188.123.253.74 +119.104.153.35 +95.72.134.199 +217.27.54.42 +122.82.89.79 +77.105.24.110 +128.75.210.244 +75.148.179.209 +191.32.34.245 +97.81.31.177 +189.24.148.123 +181.162.19.254 +41.250.166.187 +41.251.221.21 +93.79.71.20 +80.1.185.61 +91.150.245.34 +23.92.137.33 +5.54.7.186 +188.17.193.48 +193.0.167.145 +209.95.50.97 +186.92.234.251 +25.176.174.243 +212.253.65.223 +178.205.63.52 +78.164.118.0 +64.153.59.199 +142.4.210.129 +109.91.206.6 +159.206.179.155 +200.106.89.30 +186.82.153.43 +101.98.215.166 +89.151.168.174 +14.125.239.220 +190.203.65.246 +87.146.22.186 +187.255.236.182 +173.244.16.2 +41.96.89.43 +113.161.76.161 +88.65.91.147 +122.62.210.108 +62.113.206.152 +189.217.204.123 +213.151.1.230 +77.164.58.243 +213.160.169.153 +115.152.146.107 +58.106.6.32 +39.250.103.108 +74.213.119.35 +158.222.241.196 +78.0.12.66 +84.22.108.241 +79.9.224.238 +82.57.16.52 +82.58.170.32 +36.74.94.208 +95.141.29.54 +115.184.225.144 +108.61.152.244 +25.42.99.19 +93.80.142.128 +186.83.197.213 +41.174.131.117 +222.65.44.73 +139.162.20.227 +190.199.129.169 +141.135.41.37 +199.202.216.171 +94.128.255.47 +42.61.205.227 +90.29.84.185 +158.42.126.69 +89.239.99.253 +105.184.10.27 +79.130.27.17 +199.193.119.32 +82.50.184.207 +178.19.158.26 +178.222.8.65 +174.58.179.241 +86.204.82.192 +206.169.102.22 +219.79.190.85 +128.177.161.144 +212.54.196.101 +79.172.215.68 +202.62.16.144 +64.145.76.134 +109.155.227.178 +162.245.22.23 +110.168.232.246 +179.222.248.68 +68.193.116.242 +81.211.118.130 +86.14.132.229 +86.111.120.129 +202.62.17.5 +151.49.108.86 +91.177.116.22 +39.48.50.240 +173.199.65.38 +37.190.36.10 +171.97.196.203 +75.129.6.150 +231.210.83.146 +141.255.15.154 +73.132.239.109 +213.87.133.82 +2.85.56.108 +92.247.60.137 +217.39.183.41 +128.71.78.96 +83.240.41.109 +5.145.95.45 +86.171.220.93 +217.70.249.76 +151.226.64.200 +151.230.117.91 +90.207.95.206 +2.62.35.78 +178.4.211.187 +71.204.33.161 +85.51.138.99 +37.78.101.92 +95.139.68.24 +190.39.14.8 +197.202.255.216 +86.186.191.244 +150.117.170.89 +186.95.6.151 +182.249.242.12 +94.21.159.104 +190.71.180.90 +92.131.148.36 +179.232.147.95 +12.151.91.2 +176.127.237.83 +86.25.209.25 +201.209.45.23 +46.236.145.3 +99.110.210.240 +79.40.102.202 +206.226.72.88 +110.159.31.31 +88.200.247.127 +81.153.202.81 +217.71.45.101 +145.53.197.222 +162.156.115.215 +193.161.15.73 +73.47.89.19 +42.115.18.149 +58.34.146.122 +0.0.0.0 +177.249.135.65 +5.39.99.50 +142.176.53.89 +110.168.232.48 +188.162.36.224 +92.113.4.7 +92.163.94.164 +90.209.234.107 +108.96.66.88 +172.56.17.27 +80.188.117.115 +198.23.200.184 +185.19.27.157 +87.185.21.124 +24.189.162.153 +95.71.0.160 +223.225.156.95 +191.223.196.53 +83.199.217.112 +187.23.218.40 +58.39.109.101 +80.11.226.53 +114.97.131.146 +91.48.35.145 +84.107.232.152 +155.138.235.36 +105.156.245.30 +68.96.191.5 +25.171.12.62 +191.182.113.42 +119.86.155.192 +186.121.1.255 +2.62.19.20 +212.255.118.19 +82.54.210.233 +187.250.136.52 +197.202.240.7 +218.212.97.65 +25.220.76.115 +5.140.21.35 +70.197.85.37 +79.107.58.23 +180.252.90.132 +190.142.121.228 +84.52.183.80 +212.233.149.86 +82.158.241.150 +150.214.205.42 +87.15.42.16 +213.230.74.187 +2.62.62.72 +37.145.180.158 +191.17.69.226 +104.200.151.91 +190.73.40.185 +213.55.176.247 +212.21.9.197 +190.158.119.242 +178.205.63.52 +80.47.245.93 +91.224.81.52 +99.115.174.219 +245.245.190.57 +190.131.116.79 +89.232.118.141 +37.146.127.175 +174.4.8.138 +24.49.105.139 +41.224.164.213 +151.80.206.101 +85.178.85.135 +5.141.202.203 +85.115.248.36 +181.75.40.195 +95.174.116.99 +188.73.253.198 +190.77.226.235 +52.71.215.53 +188.29.12.44 +151.24.155.96 +50.53.104.166 +37.146.224.252 +79.107.93.229 +187.126.97.243 +92.124.2.226 +190.74.29.208 +83.30.77.252 +86.202.71.200 +1.162.58.141 +98.214.40.119 +14.207.37.172 +82.238.183.62 +83.78.97.93 +190.77.229.35 +167.61.25.72 +50.154.169.160 +90.184.89.145 +95.81.227.84 +79.117.18.180 +95.57.148.143 +171.96.168.12 +65.15.37.139 +117.25.7.196 +95.37.105.91 +87.92.76.128 +50.164.63.3 +5.220.228.6 +138.97.160.250 +174.88.244.168 +86.26.5.243 +95.55.22.224 +1.36.146.93 +25.13.191.166 +47.54.76.217 +91.140.10.159 +37.213.68.9 +171.97.188.17 +46.0.19.2 +109.43.0.212 +134.249.158.190 +86.124.151.161 +91.113.72.233 +186.91.92.251 +118.140.106.58 +212.200.65.246 +78.8.143.184 +197.104.12.43 +86.131.100.88 +108.61.191.195 +70.59.17.67 +205.197.242.148 +70.189.69.77 +100.64.161.107 +79.107.69.247 +86.10.20.12 +37.146.127.100 +79.245.206.51 +5.135.36.129 +173.189.163.125 +79.107.114.31 +178.117.43.95 +186.146.136.133 +87.144.206.76 +217.71.45.14 +108.215.118.91 +180.241.158.5 +90.212.241.153 +88.3.38.194 +187.143.90.134 +89.250.14.157 +209.160.124.170 +220.246.220.215 +95.19.18.83 +107.211.177.179 +179.126.245.239 +71.3.13.165 +182.165.45.89 +52.24.196.169 +217.77.220.249 +97.127.118.149 +151.33.74.174 +14.1.200.132 +181.167.109.212 +83.22.120.238 +68.220.69.84 +83.11.81.25 +146.90.79.77 +69.165.210.94 +94.41.202.79 +189.202.44.164 +74.116.190.9 +93.109.240.14 +91.95.18.13 +82.34.93.93 +91.67.247.232 +5.149.16.157 +193.158.162.212 +106.38.255.120 +181.64.0.89 +120.172.28.196 +46.109.37.80 +90.11.159.241 +91.140.16.52 +79.44.93.198 +63.87.252.153 +84.154.93.193 +78.106.75.71 +37.29.88.7 +79.234.106.204 +117.151.175.8 +194.50.159.203 +104.139.226.97 +114.109.116.141 +92.144.213.82 +62.21.26.111 +217.118.93.88 +171.149.2.249 +190.78.110.138 +176.249.157.191 +41.96.46.230 +1.207.128.245 +46.166.188.202 +49.144.116.253 +93.129.140.155 +73.211.90.130 +119.252.188.52 +2.85.56.108 +106.51.72.108 +178.234.227.146 +178.128.36.69 +76.75.71.45 +178.203.232.239 +5.42.105.143 +98.223.189.214 +142.217.63.42 +78.132.88.146 +165.255.172.58 +250.31.16.246 +5.149.16.157 +197.34.211.134 +115.117.126.170 +124.12.49.8 +5.139.75.217 +89.233.112.8 +171.6.27.97 +29.220.17.208 +87.69.111.245 +86.217.8.243 +95.151.182.164 +116.14.165.116 +91.84.113.0 +95.189.13.190 +189.202.31.148 +94.13.34.142 +1.0.0.0 +178.57.99.198 +95.232.214.148 +60.240.236.55 +45.56.151.111 +201.211.56.186 +86.181.102.49 +91.134.120.210 +93.135.74.141 +24.0.103.120 +92.255.230.162 +75.3.153.154 +73.9.4.206 +173.74.178.184 +187.74.68.143 +84.250.39.13 +190.47.110.47 +222.228.4.35 +46.5.0.73 +24.126.75.249 +89.16.154.73 +171.96.168.254 +220.246.221.8 +95.138.194.14 +220.141.117.75 +171.96.171.107 +86.181.29.135 +37.235.35.100 +117.208.209.181 +168.156.67.100 +77.171.59.152 +42.115.18.149 +96.31.215.232 +24.115.186.59 +78.244.37.129 +90.46.58.166 +37.24.156.83 +99.111.18.127 +209.197.163.222 +80.107.22.91 +180.136.190.98 +101.160.40.41 +178.234.245.216 +82.243.166.92 +114.133.4.189 +68.172.251.98 +95.24.212.203 +108.177.128.150 +79.245.219.111 +100.68.125.96 +151.238.37.180 +83.149.34.184 +77.51.120.101 +87.229.54.82 +2.61.181.130 +71.89.20.64 +79.245.216.210 +94.193.47.208 +91.141.1.188 +31.10.151.179 +117.206.174.179 +108.61.228.5 +93.143.136.165 +5.138.127.54 +79.218.31.115 +99.247.185.16 +98.17.225.200 +5.141.217.158 +71.209.53.226 +72.198.42.61 +95.24.235.213 +101.100.169.84 +163.211.239.49 +162.243.227.221 +185.45.13.149 +79.245.214.82 +37.134.219.49 +190.37.64.129 +5.42.93.22 +37.188.130.172 +74.84.27.148 +110.137.17.217 +72.47.175.158 +208.82.42.226 +188.103.183.100 +37.146.127.230 +50.197.49.153 +2.1.33.177 +176.33.104.186 +190.21.51.211 +178.223.12.104 +177.17.138.227 +162.216.46.174 +181.50.132.106 +178.149.203.187 +181.24.69.91 +37.47.252.233 +108.4.60.70 +178.47.254.52 +217.44.16.102 +125.163.145.229 +82.38.241.21 +79.245.192.78 +87.168.179.186 +62.21.48.27 +75.142.234.5 +46.0.45.154 +188.165.197.47 +90.154.75.175 +105.226.27.52 +79.245.192.12 +177.229.23.223 +178.128.243.39 +77.239.40.91 +66.55.134.194 +109.62.143.55 +91.90.15.94 +217.241.78.52 +95.89.215.8 +89.36.104.213 +108.61.196.252 +79.245.199.92 +94.133.86.200 +62.113.206.152 +83.49.92.182 +184.97.254.204 +202.62.16.234 +217.131.104.197 +46.0.198.198 +186.83.248.18 +37.187.242.213 +113.28.12.51 +190.227.30.241 +31.168.172.136 +78.70.59.132 +77.49.142.238 +203.164.148.154 +86.172.4.51 +213.113.185.135 +104.238.187.114 +104.45.143.132 +202.62.16.164 +85.25.223.7 +46.244.192.30 +185.81.229.113 +118.208.67.84 +174.58.249.186 +0.0.0.0 +122.189.64.32 +24.201.122.219 +174.24.61.63 +93.139.175.187 +91.48.61.15 +5.88.72.90 +83.192.113.203 +85.114.60.215 +83.5.143.28 +200.109.180.49 +120.196.98.141 +42.115.236.60 +81.10.142.169 +41.96.4.94 +114.244.35.53 +179.156.218.183 +190.137.24.255 +164.67.231.133 +80.249.81.117 +5.141.221.248 +136.152.10.116 +95.88.141.238 +86.208.11.209 +1.0.0.0 +220.160.191.91 +83.185.91.165 +197.202.255.216 +190.119.56.148 +97.127.49.14 +177.17.121.175 +58.11.101.190 +217.95.230.231 +2.85.187.74 +178.191.229.72 +88.180.208.180 +146.52.22.64 +58.11.110.34 +75.192.234.101 +202.62.17.151 +75.83.158.235 +84.154.93.193 +68.39.187.73 +201.242.109.86 +77.51.139.220 +71.67.165.191 +93.219.151.251 +80.143.81.125 +2.62.62.72 +93.129.11.176 +65.190.50.239 +84.236.15.97 +115.228.246.237 +151.238.254.12 +81.153.155.14 +179.55.32.8 +0.0.0.0 +24.255.122.199 +178.221.180.123 +90.186.174.74 +86.212.6.18 +5.70.148.6 +86.194.143.131 +5.139.58.56 +176.99.71.5 +80.213.11.23 +181.110.113.118 +69.7.86.218 +89.178.177.95 +37.112.78.248 +31.179.120.196 +118.68.195.222 +42.98.191.221 +173.246.8.253 +139.193.221.33 +46.166.190.194 +98.219.56.84 +209.144.254.123 +87.81.138.30 +93.104.105.193 +31.52.126.202 +68.69.230.94 +62.49.252.145 +101.164.234.148 +101.160.47.83 +79.246.232.132 +179.156.221.228 +188.18.15.139 +91.53.106.221 +199.16.96.145 +2.61.133.195 +96.81.223.233 +178.164.203.161 +50.153.149.16 +46.246.27.154 +190.140.130.125 +37.6.237.251 +0.0.3.6 +18.111.60.56 +87.95.107.189 +108.61.152.245 +2.85.178.120 +111.241.99.206 +24.155.200.227 +104.238.180.11 +84.31.33.151 +176.9.140.183 +91.179.215.94 +86.158.209.42 +178.0.63.141 +88.254.69.172 +181.46.165.102 +202.62.16.12 +5.167.102.27 +85.247.35.163 +78.9.102.168 +151.61.102.189 +71.197.170.183 +38.121.251.20 +117.207.10.37 +109.88.135.108 +73.179.71.188 +172.58.39.120 +50.101.137.64 +213.176.245.198 +159.11.201.195 +178.234.77.7 +195.240.131.215 +173.230.41.42 +95.81.194.234 +85.140.176.143 +67.173.24.183 +100.78.98.103 +5.64.173.211 +190.237.183.46 +42.112.80.24 +98.87.136.159 +110.138.34.135 +79.245.195.253 +50.247.211.162 +76.6.147.56 +92.249.134.115 +181.136.157.228 +77.7.205.190 +186.94.19.198 +212.251.118.230 +89.235.56.141 +68.96.191.5 +177.133.78.208 +74.111.105.96 +92.37.62.98 +24.114.51.29 +176.10.60.94 +88.19.18.181 +106.192.5.0 +107.181.128.29 +79.45.29.32 +75.101.100.249 +177.68.173.236 +217.131.108.228 +189.219.201.55 +188.129.122.191 +151.80.206.110 +190.229.108.36 +46.63.216.18 +173.75.34.129 +100.68.131.66 +145.131.208.97 +105.158.120.123 +89.151.169.61 +200.8.52.205 +190.79.228.216 +104.200.151.7 +122.62.12.87 +179.34.29.109 +69.165.156.162 +85.220.18.205 +85.25.200.102 +84.11.144.166 +67.83.2.182 +98.28.46.106 +179.210.103.88 +217.123.121.141 +216.209.125.125 +84.147.114.207 +203.176.181.33 +2.85.57.6 +178.54.197.81 +125.37.79.46 +95.141.28.169 +80.107.67.4 +125.24.126.173 +201.6.129.43 +58.187.57.52 +186.4.128.144 +73.48.135.29 +223.204.250.101 +188.108.130.194 +99.57.26.137 +109.154.152.180 +0.0.0.0 +112.215.123.124 +79.25.20.55 +98.164.86.165 +190.198.126.70 +94.153.88.241 +92.209.191.40 +174.2.194.186 +67.71.133.140 +100.66.51.177 +68.42.212.98 +109.121.7.134 +83.82.131.238 +200.8.99.39 +91.215.78.147 +1.0.0.0 +178.148.203.30 +174.50.99.85 +31.17.30.35 +188.226.204.112 +171.92.217.252 +189.202.91.14 +68.87.73.163 +94.113.7.202 +178.47.254.52 +50.153.151.123 +96.44.187.26 +62.176.13.182 +71.30.196.94 +213.16.230.227 +141.255.21.94 +36.78.198.100 +92.76.228.68 +86.104.196.53 +220.253.89.142 +79.114.76.22 +178.150.3.240 +180.242.117.178 +213.152.162.149 +219.90.234.171 +117.203.81.114 +188.174.119.70 +37.112.218.15 +50.153.150.1 +78.38.63.156 +187.79.200.234 +104.207.136.88 +177.137.167.60 +208.167.254.37 +86.135.19.3 +50.88.91.130 +208.53.180.26 +78.62.146.147 +86.181.1.146 +202.62.16.121 +73.90.210.164 +191.32.70.254 +248.245.199.94 +201.236.113.219 +52.248.212.93 +198.1.153.15 +95.24.33.153 +78.88.29.216 +159.118.77.129 +73.7.239.158 +79.216.199.109 +2.96.25.54 +94.205.1.88 +217.197.250.154 +175.40.21.20 +183.30.111.123 +86.151.81.47 +113.14.73.198 +81.21.249.40 +77.164.60.140 +2.229.75.216 +109.79.58.72 +109.92.81.247 +202.62.16.140 +186.146.153.110 +151.66.140.155 +71.185.172.244 +31.10.150.247 +178.173.7.237 +121.214.119.39 +184.98.199.232 +173.75.18.157 +89.204.153.44 +202.62.17.197 +125.112.171.217 +23.27.13.13 +187.87.77.243 +91.67.99.12 +91.197.146.250 +190.62.157.176 +190.207.190.61 +109.111.140.19 +75.152.212.205 +155.143.147.21 +84.11.144.164 +0.0.0.32 +85.132.87.161 +52.90.103.92 +125.69.8.237 +171.97.215.118 +84.189.192.218 +100.100.100.87 +118.209.123.136 +24.209.137.120 +98.15.141.103 +199.19.95.181 +193.92.113.47 +98.163.251.27 +118.211.231.131 +80.215.178.138 +32.138.112.115 +59.88.129.78 +111.95.163.140 +78.111.190.80 +47.217.159.177 +217.235.248.71 +67.160.195.220 +178.223.171.189 +29.108.45.223 +146.156.249.160 +50.53.36.50 +181.162.51.72 +176.199.122.249 +151.72.136.1 +222.222.0.100 +195.174.95.103 +190.36.190.28 +50.135.244.2 +178.222.2.10 +178.164.190.218 +79.56.106.208 +188.168.147.218 +202.62.16.64 +78.87.95.95 +90.222.86.81 +64.134.138.159 +218.205.35.53 +5.133.176.37 +203.222.146.55 +202.62.16.218 +86.130.245.53 +78.165.227.42 +100.69.17.214 +94.54.72.158 +195.29.192.145 +185.18.140.49 +113.254.166.97 +21.106.179.117 +112.198.100.11 +92.97.90.207 +178.24.63.237 +77.248.238.60 +89.37.62.17 +104.156.228.80 +151.55.147.127 +210.55.212.139 +83.27.163.130 +195.209.48.241 +46.159.1.127 +145.129.149.65 +85.217.41.209 +24.135.73.174 +109.92.64.31 +60.90.120.130 +77.49.136.244 +178.137.185.208 +41.105.28.186 +42.61.166.126 +85.99.40.135 +128.69.235.138 +185.29.164.61 +187.56.144.147 +52.169.238.25 +173.245.195.111 +185.48.37.18 +181.120.107.216 +72.216.45.166 +200.8.53.77 +46.159.36.10 +85.144.64.171 +91.77.226.181 +62.158.154.188 +122.187.103.15 +76.18.138.1 +109.97.162.239 +31.63.155.188 +162.68.190.223 +187.161.229.36 +210.136.5.67 +5.143.167.245 +89.121.179.113 +37.201.193.149 +25.22.203.199 +76.250.56.155 +178.188.9.202 +120.20.202.77 +50.48.231.111 +223.205.29.44 +153.136.25.157 +186.207.222.41 +1.162.60.24 +84.161.252.57 +42.3.135.246 +92.37.201.10 +186.222.41.103 +93.208.108.138 +186.95.48.195 +197.37.109.104 +36.239.41.91 +109.188.124.237 +14.146.39.92 +193.158.174.91 +100.68.136.230 +5.138.55.122 +0.0.0.0 +91.21.203.222 +85.168.205.103 +67.140.124.139 +190.36.194.224 +109.43.1.135 +87.15.222.204 +83.201.51.38 +36.76.35.216 +69.223.42.70 +182.187.34.145 +104.200.154.27 +128.0.0.54 +113.104.188.225 +85.76.128.44 +108.182.95.189 +202.62.16.167 +97.88.162.194 +87.79.212.65 +88.8.65.219 +86.139.7.170 +42.116.94.38 +71.212.63.169 +195.149.108.51 +71.164.199.248 +187.189.89.65 +178.252.57.123 +85.23.216.110 +70.79.134.194 +25.172.59.240 +78.137.174.34 +79.222.101.47 +79.131.102.117 +123.202.107.106 +92.49.133.75 +82.126.49.125 +201.119.239.242 +70.197.129.122 +71.80.65.254 +46.0.44.159 +37.192.171.50 +177.233.177.253 +82.43.78.46 +91.220.173.26 +223.204.68.138 +116.193.158.122 +187.155.99.230 +87.185.27.131 +37.146.123.212 +129.110.242.89 +173.219.77.171 +172.56.22.249 +87.185.7.106 +123.129.254.11 +189.79.209.234 +82.181.13.55 +178.45.113.144 +83.176.148.252 +190.82.245.27 +91.182.0.44 +76.170.53.72 +104.156.240.155 +176.33.109.138 +130.180.220.122 +93.125.88.66 +201.170.156.229 +177.124.173.245 +69.231.32.212 +189.147.232.220 +79.117.48.111 +69.179.143.48 +101.40.2.34 +81.242.98.251 +94.72.62.224 +75.112.236.68 +119.236.139.193 +188.232.58.11 +71.195.208.134 +213.5.52.72 +92.133.138.15 +172.248.91.252 +104.197.72.254 +179.198.46.19 +93.194.84.118 +138.186.31.199 +121.215.17.3 +190.75.92.230 +99.172.17.234 +91.219.137.216 +186.91.43.38 +153.161.150.230 +217.235.237.26 +25.127.30.249 +79.141.166.21 +79.113.137.142 +173.172.151.247 +196.210.56.104 +41.246.41.68 +119.130.27.80 +169.0.117.131 +62.4.196.154 +177.97.187.165 +217.107.194.54 +88.206.79.214 +94.66.57.202 +187.180.169.226 +68.186.235.174 +185.18.148.4 +5.149.252.26 +152.23.67.227 +36.74.239.195 +24.53.67.105 +192.241.252.210 +77.78.23.237 +90.55.57.179 +189.232.134.204 +37.215.159.106 +31.50.204.103 +95.89.215.64 +79.245.194.81 +189.197.67.115 +80.174.72.227 +191.19.88.251 +76.68.232.114 +79.119.47.8 +87.95.11.242 +202.62.16.73 +167.61.98.176 +190.62.152.218 +130.180.220.46 +120.210.184.66 +79.113.137.142 +88.152.186.167 +178.56.209.2 +80.86.87.204 +79.36.127.8 +80.107.29.138 +69.20.179.75 +5.140.13.16 +109.43.2.243 +107.179.248.207 +188.197.14.187 +107.182.231.95 +109.93.210.107 +94.37.247.70 +128.71.63.67 +75.150.28.89 +172.248.91.252 +151.64.48.160 +104.131.170.147 +109.202.10.42 +78.146.143.123 +182.108.229.218 +80.128.88.254 +2.85.61.239 +86.169.67.213 +201.47.219.161 +178.43.53.246 +80.107.30.197 +93.94.148.199 +99.238.196.59 +83.254.163.207 +192.95.35.246 +97.127.39.120 +180.210.200.226 +195.9.250.147 +64.188.205.179 +171.39.69.171 +131.255.112.176 +93.156.85.122 +183.81.13.190 +95.189.9.85 +209.93.108.242 +62.98.178.127 +217.99.188.138 +37.135.16.141 +77.163.109.238 +42.113.20.70 +187.155.73.125 +94.68.139.93 +124.227.106.124 +50.203.141.242 +83.39.202.42 +191.112.47.59 +68.65.103.71 +219.79.188.205 +198.53.141.197 +71.34.142.200 +46.0.22.79 +31.201.253.64 +94.174.159.109 +188.226.153.233 +80.215.200.241 +92.145.155.223 +84.154.93.193 +91.39.197.227 +41.71.184.18 +46.63.199.81 +84.193.177.2 +117.6.131.125 +92.222.28.13 +93.72.183.16 +37.213.100.21 +94.223.152.62 +37.213.71.140 +117.200.201.23 +84.147.118.100 +94.21.59.198 +185.45.13.148 +178.234.251.139 +76.181.115.35 +49.228.198.59 +76.68.254.64 +179.155.216.113 +72.63.101.200 +67.231.54.138 +68.3.159.220 +5.167.37.158 +190.73.10.170 +68.9.115.43 +171.96.171.156 +130.43.80.74 +93.104.169.149 +99.229.64.113 +69.43.208.70 +201.248.11.43 +110.168.231.241 +72.186.22.189 +76.21.96.22 +95.24.99.127 +89.212.101.38 +92.225.34.190 +1.0.0.0 +117.93.209.83 +101.136.198.7 +188.222.42.178 +91.158.109.188 +76.187.186.183 +95.142.108.55 +213.125.106.138 +200.8.245.15 +216.46.41.138 +212.251.28.139 +108.244.47.41 +94.191.185.32 +91.17.26.155 +100.66.131.190 +93.33.130.151 +77.51.245.192 +86.129.68.208 +173.21.63.162 +217.235.247.119 +60.250.10.233 +46.142.47.195 +179.147.86.195 +59.49.159.208 +182.132.220.206 +23.251.65.46 +213.64.27.201 +81.38.22.105 +99.121.207.38 +84.147.126.143 +93.129.140.155 +74.100.84.157 +37.201.170.227 +176.154.215.97 +77.234.40.151 +93.185.56.179 +176.219.146.177 +151.235.181.110 +88.65.88.121 +92.47.26.152 +116.114.146.23 +109.205.253.91 +113.254.169.130 +50.163.171.86 +24.114.75.45 +2.134.174.62 +88.152.186.90 +31.132.225.190 +231.210.83.146 +188.104.80.117 +101.39.6.49 +93.39.97.59 +84.76.206.154 +171.4.198.206 +202.62.16.75 +91.7.43.128 +151.25.8.74 +68.8.249.60 +52.71.215.53 +186.118.100.170 +183.171.177.80 +83.134.98.48 +40.76.82.173 +86.88.39.133 +108.117.62.253 +42.115.112.202 +124.122.237.162 +79.245.207.164 +24.121.116.253 +91.148.87.53 +85.75.133.89 +76.89.170.251 +111.242.52.251 +95.30.53.63 +84.82.225.145 +77.95.54.152 +176.58.231.221 +216.14.113.63 +86.184.140.225 +185.108.128.3 +49.83.47.173 +76.68.163.250 +82.229.244.14 +111.242.54.89 +201.209.255.211 +91.148.97.130 +219.73.101.145 +108.46.182.48 +90.197.186.161 +92.192.83.55 +93.201.239.193 +178.120.203.65 +91.9.209.17 +95.111.236.135 +50.66.152.76 +188.103.141.76 +86.164.95.63 +91.7.39.143 +79.40.96.252 +217.197.250.146 +79.32.103.236 +111.95.108.231 +79.245.199.212 +95.145.144.147 +188.79.3.188 +94.253.254.7 +83.7.113.197 +208.167.254.100 +2.125.75.60 +179.197.172.50 +95.153.130.87 +101.184.112.62 +202.62.17.48 +180.191.224.162 +190.62.159.200 +79.195.168.14 +24.114.70.50 +82.73.120.15 +201.208.212.33 +179.232.197.231 +46.166.188.201 +200.84.131.93 +213.125.81.210 +79.117.106.84 +104.156.240.172 +109.165.138.145 +91.21.200.178 +95.71.111.52 +68.204.29.211 +190.75.76.205 +201.243.217.28 +97.94.64.252 +37.29.88.140 +88.254.110.55 +191.19.120.6 +178.158.184.222 +85.144.12.110 +90.113.251.171 +2.146.143.174 +36.83.51.219 +186.94.188.207 +70.173.209.163 +78.49.253.175 +177.134.11.43 +37.187.155.143 +101.184.130.85 +213.87.123.8 +98.209.182.231 +189.105.158.187 +98.121.75.244 +67.68.123.177 +14.202.196.211 +84.73.147.5 +76.21.107.113 +92.124.52.219 +201.173.65.201 +109.121.39.75 +195.140.222.81 +171.97.183.72 +20.157.183.255 +113.76.115.9 +94.180.161.197 +205.220.163.91 +188.69.192.118 +92.249.221.0 +192.95.29.176 +2.139.192.228 +216.58.117.236 +71.176.43.77 +151.49.91.178 +216.5.152.147 +79.245.193.107 +141.237.253.19 +41.174.128.82 +123.138.114.2 +99.170.114.28 +95.94.96.15 +31.61.140.126 +184.171.212.128 +156.57.43.228 +79.225.117.161 +36.78.199.70 +129.10.9.128 +113.91.239.36 +83.10.159.120 +31.10.149.114 +77.180.215.167 +188.18.15.206 +37.146.201.20 +84.114.151.72 +194.50.159.203 +83.42.119.149 +58.7.79.182 +33.212.156.47 +5.254.97.76 +67.0.250.94 +222.65.39.59 +93.34.48.75 +86.148.216.229 +74.12.222.217 +71.47.114.174 +89.45.43.211 +78.51.17.255 +188.18.15.170 +217.25.228.30 +71.53.155.217 +71.33.9.140 +212.251.28.139 +83.149.47.250 +125.160.194.46 +37.48.32.73 +172.56.6.185 +50.169.226.165 +1.207.146.4 +114.77.174.108 +186.90.86.42 +219.73.26.172 +193.51.6.5 +36.77.18.75 +92.20.112.174 +53.193.239.79 +79.20.18.148 +212.71.232.87 +151.15.56.223 +71.33.11.9 +190.37.61.70 +157.201.127.254 +5.141.220.138 +96.42.38.90 +83.149.46.90 +86.208.73.16 +88.251.166.250 +217.253.212.162 +46.188.125.237 +90.217.183.159 +46.253.252.140 +50.106.33.243 +188.18.15.65 +87.152.212.58 +189.5.55.39 +109.93.33.170 +37.78.168.165 +190.79.40.206 +200.8.53.167 +77.243.183.13 +117.67.3.217 +208.167.254.90 +84.231.84.105 +77.96.246.116 +77.67.46.89 +100.88.3.214 +93.120.226.6 +86.130.246.211 +101.217.255.185 +41.249.160.19 +166.137.246.108 +176.104.38.33 +190.37.91.49 +68.146.221.41 +92.109.24.225 +105.98.10.91 +89.72.186.220 +176.10.232.140 +211.30.183.68 +171.96.171.107 +91.32.199.61 +82.126.49.125 +31.61.140.177 +37.188.238.115 +86.173.54.42 +60.25.175.39 +5.254.97.86 +37.213.131.56 +178.44.22.162 +45.79.149.192 +78.224.129.115 +79.133.129.102 +178.172.215.92 +186.88.229.47 +79.203.64.189 +201.83.109.150 +95.39.196.210 +62.116.254.204 +93.228.87.241 +213.87.122.16 +193.92.252.13 +178.173.7.237 +67.230.39.93 +23.239.25.147 +14.2.14.23 +105.100.85.26 +81.141.21.164 +185.42.38.225 +87.202.135.151 +195.154.223.134 +112.210.45.190 +89.25.167.65 +37.21.227.11 +187.254.159.150 +47.32.96.52 +46.167.107.113 +171.97.194.250 +76.216.184.8 +64.191.29.34 +208.82.42.226 +116.1.232.151 +176.85.59.61 +80.200.131.25 +95.153.134.146 +62.4.196.200 +84.176.235.19 +109.110.94.220 +138.94.57.95 +2.218.14.123 +188.108.36.227 +72.225.20.7 +79.114.108.172 +79.225.117.161 +80.212.50.182 +180.183.160.228 +96.39.207.56 +68.198.99.74 +82.112.137.120 +90.110.135.137 +79.130.203.130 +118.90.23.40 +189.140.180.53 +90.204.152.12 +105.236.127.85 +111.240.227.9 +219.79.255.20 +32.230.230.91 +1.175.232.51 +64.153.59.199 +120.24.185.169 +188.18.14.125 +38.20.8.96 +90.216.182.26 +181.54.77.177 +105.5.197.77 +124.122.61.248 +221.38.63.169 +79.70.26.227 +178.234.88.157 +216.110.120.168 +0.0.0.0 +5.49.28.53 +188.18.14.178 +82.9.15.148 +37.134.158.32 +87.0.208.206 +179.7.160.80 +84.236.82.50 +213.176.234.14 +213.183.56.124 +104.254.104.5 +188.103.183.100 +163.211.239.49 +71.176.42.18 +74.134.153.46 +177.184.139.118 +213.87.123.56 +190.38.26.230 +188.19.127.76 +77.29.197.123 +109.43.0.198 +194.255.110.178 +202.62.16.66 +122.49.148.197 +189.92.62.67 +203.219.62.171 +37.190.51.5 +14.192.209.137 +1.0.179.142 +90.203.117.80 +104.156.228.84 +79.102.202.104 +201.124.161.204 +138.91.64.57 +176.150.128.73 +115.87.56.117 +218.30.116.8 +183.47.125.144 +142.161.91.61 +200.75.100.36 +121.224.229.225 +94.230.128.122 +88.15.2.57 +105.107.52.205 +173.216.142.39 +207.32.206.67 +173.189.164.156 +94.207.129.207 +93.195.137.34 +75.98.126.115 +118.90.85.93 +62.195.196.17 +62.36.238.183 +108.24.76.250 +70.208.32.36 +128.75.1.128 +178.120.49.152 +37.146.123.192 +76.119.32.70 +170.0.21.4 +186.92.254.134 +178.36.6.207 +217.71.44.53 +37.76.19.42 +24.224.18.228 +92.144.200.122 +24.170.254.35 +95.110.236.41 +190.36.138.46 +24.15.87.243 +176.193.160.41 +69.231.38.87 +171.96.167.130 +173.185.69.84 +1.34.103.14 +89.69.126.16 +79.245.220.35 +92.127.108.147 +181.208.31.78 +78.13.64.28 +92.110.103.112 +78.157.65.184 +50.23.115.93 +92.100.204.158 +123.190.61.215 +92.157.42.221 +186.93.166.253 +189.130.4.227 +2.132.232.228 +91.179.119.190 +121.15.56.23 +218.142.99.184 +81.141.6.224 +178.234.67.104 +188.29.164.216 +59.177.175.205 +94.21.126.82 +57.131.89.131 +111.94.244.38 +46.166.165.39 +110.17.0.209 +87.79.199.100 +98.199.20.91 +92.148.36.246 +178.204.1.82 +66.87.96.217 +78.129.153.58 +200.75.126.234 +71.251.48.92 +108.61.228.21 +93.41.14.10 +197.117.114.68 +31.96.46.73 +184.170.255.187 +79.245.208.136 +78.66.84.178 +88.91.76.98 +109.145.153.74 +73.132.241.101 +1.0.0.0 +181.59.21.30 +183.12.166.251 +92.102.120.195 +128.90.73.134 +83.37.72.115 +187.143.157.80 +151.55.7.75 +220.246.220.125 +151.227.114.150 +78.137.174.34 +91.7.44.125 +79.245.217.24 +68.134.210.96 +78.220.216.208 +190.156.180.182 +94.21.86.206 +79.204.180.184 +185.2.179.240 +88.107.54.205 +78.156.104.205 +105.227.165.81 +111.241.97.118 +128.75.205.8 +103.253.43.162 +37.200.92.183 +50.80.243.103 +79.141.166.15 +69.130.145.90 +93.230.205.141 +91.158.232.111 +94.66.57.224 +164.74.58.74 +85.88.202.114 +95.153.134.146 +172.98.67.20 +77.179.231.56 +124.122.2.78 +190.186.112.3 +45.32.129.168 +213.74.111.185 +96.60.246.99 +185.29.164.61 +217.71.45.22 +86.212.65.214 +176.24.60.151 +207.119.225.105 +81.11.251.22 +108.23.17.119 +86.9.138.104 +79.146.128.43 +178.234.30.31 +98.122.56.215 +187.200.123.61 +82.226.240.57 +67.170.57.32 +46.2.49.102 +186.91.62.227 +138.130.241.44 +87.4.217.139 +187.202.15.172 +37.79.249.105 +85.178.93.221 +84.55.14.160 +190.142.152.122 +14.201.56.59 +98.160.239.93 +187.190.186.18 +182.108.22.88 +2.61.133.195 +187.187.56.36 +24.207.64.162 +202.62.17.245 +188.67.230.211 +77.203.119.51 +93.204.66.246 +71.195.120.65 +141.131.252.254 +79.245.192.59 +58.8.242.163 +67.193.83.131 +5.141.196.246 +78.85.72.68 +201.173.65.201 +108.24.83.254 +128.72.47.100 +207.192.252.5 +78.151.57.134 +200.116.36.76 +174.116.154.161 +90.153.118.51 +92.27.248.94 +84.216.198.17 +12.247.29.158 +85.72.168.211 +31.48.118.22 +36.80.103.175 +171.213.113.252 +151.225.66.52 +182.249.242.17 +144.172.235.179 +190.39.10.186 +130.89.77.168 +209.160.123.53 +186.90.132.31 +95.106.184.230 +67.140.4.30 +77.85.116.203 +109.43.1.89 +128.73.184.221 +114.97.58.74 +98.207.163.188 +217.235.238.188 +89.240.128.124 +115.99.106.249 +171.97.145.198 +66.115.130.122 +190.28.183.251 +84.19.166.50 +119.224.87.37 +91.231.21.78 +190.24.59.161 +190.235.139.236 +15.186.104.145 +190.77.75.9 +213.127.176.114 +73.191.186.27 +193.92.228.153 +69.253.5.33 +2.134.174.247 +190.79.132.37 +81.107.240.220 +78.111.187.63 +67.169.167.174 +177.32.101.231 +177.36.168.50 +201.37.161.46 +58.44.186.69 +5.43.176.207 +86.42.140.17 +117.83.20.249 +68.58.47.220 +139.194.44.166 +73.70.117.18 +31.207.199.172 +185.129.62.63 +177.206.252.93 +212.187.90.178 +177.106.0.107 +149.3.24.191 +173.192.170.116 +190.206.197.37 +79.133.153.174 +204.186.129.48 +80.95.64.68 +96.46.202.110 +84.19.165.218 +95.19.22.94 +71.15.250.17 +201.32.5.18 +87.185.22.184 +91.32.198.55 +69.23.98.139 +78.26.93.122 +189.217.249.33 +99.247.170.15 +151.227.54.162 +200.84.206.45 +90.4.251.196 +80.219.197.66 +178.131.184.75 +139.194.44.236 +189.217.160.57 +93.135.90.2 +92.12.164.32 +77.46.228.58 +176.194.27.221 +177.228.70.157 +109.158.202.20 +254.190.88.199 +190.229.108.36 +197.18.147.169 +92.237.146.213 +28.223.140.98 +46.63.156.159 +168.63.184.39 +31.44.253.224 +174.34.178.131 +94.226.215.40 +87.217.126.168 +96.23.253.67 +111.241.97.99 +1.54.59.157 +178.55.149.199 +89.142.78.84 +141.31.147.116 +79.33.213.41 +108.213.238.112 +31.57.84.147 +80.234.103.93 +209.95.50.66 +113.52.90.168 +81.145.244.98 +151.26.120.138 +128.70.235.3 +79.30.205.97 +138.159.171.254 +174.55.113.100 +110.149.118.131 +37.45.82.110 +206.74.9.110 +128.61.86.50 +187.14.108.85 +114.198.13.191 +213.22.179.152 +194.105.229.70 +181.223.24.193 +109.135.1.235 +89.142.141.19 +23.227.197.61 +185.52.76.43 +76.169.199.180 +73.3.210.99 +99.231.130.235 +219.79.25.31 +234.7.160.60 +167.114.42.94 +98.124.243.45 +94.244.17.63 +186.91.87.178 +87.158.138.61 +37.47.38.27 +174.90.222.192 +190.37.95.70 +190.38.134.241 +94.3.75.74 +50.148.74.47 +93.125.88.66 +190.156.180.182 +1.0.0.0 +87.92.110.226 +188.163.24.68 +178.234.165.128 +2.85.188.243 +24.209.235.10 +92.147.30.188 +68.38.91.132 +64.145.94.112 +70.209.70.192 +50.153.220.5 +146.215.226.94 +178.124.167.131 +189.220.73.190 +201.210.182.250 +71.30.9.185 +0.0.0.3 +31.54.153.0 +113.254.169.222 +188.36.178.82 +187.143.114.225 +98.246.183.126 +87.118.142.138 +93.41.14.10 +94.66.57.206 +1.64.26.102 +184.100.167.142 +219.79.190.100 +95.84.178.168 +79.142.77.138 +68.186.209.40 +113.254.169.156 +183.30.16.244 +41.251.78.214 +188.0.42.195 +68.65.103.71 +71.9.125.166 +213.168.88.39 +151.25.5.74 +114.217.0.193 +91.158.200.74 +217.122.4.85 +173.189.163.204 +116.106.235.35 +86.174.22.100 +94.255.70.244 +37.146.127.228 +193.92.113.58 +37.145.102.208 +88.173.83.141 +174.138.218.39 +87.168.167.96 +202.62.17.3 +77.203.111.184 +91.67.40.6 +24.189.162.153 +70.176.41.65 +79.245.215.246 +185.48.37.101 +36.76.56.110 +104.156.240.173 +201.152.251.21 +92.193.80.218 +95.91.240.232 +100.64.50.195 +171.5.32.218 +78.88.29.160 +162.216.46.35 +219.77.163.135 +79.151.51.157 +184.175.15.101 +77.49.238.199 +77.248.226.28 +36.69.71.187 +91.63.17.1 +101.172.213.77 +87.64.238.245 +92.8.171.136 +98.209.198.101 +188.18.30.133 +104.156.228.88 +46.130.28.226 +184.134.70.35 +181.59.224.240 +194.105.229.51 +94.209.48.166 +191.112.222.240 +89.191.161.146 +82.181.48.178 +172.56.30.174 +81.102.142.185 +209.21.206.225 +88.11.161.104 +5.164.152.212 +107.153.110.4 +78.238.22.5 +89.137.112.181 +50.148.235.241 +201.243.34.125 +217.73.143.165 +179.55.38.56 +171.97.216.85 +89.164.233.118 +78.234.188.9 +5.233.32.47 +93.108.204.241 +190.75.200.139 +90.197.186.161 +181.44.158.219 +79.31.221.169 +86.145.165.213 +77.166.82.225 +46.177.87.147 +75.111.215.8 +27.55.216.169 +219.73.14.96 +190.207.219.55 +46.159.30.181 +122.49.186.209 +88.232.10.222 +80.135.30.123 +91.48.61.225 +186.147.119.217 +114.244.63.56 +184.171.221.174 +122.195.1.17 +216.82.207.195 +91.145.155.116 +46.175.29.24 +2.176.151.20 +89.182.174.121 +68.9.115.43 +95.109.87.61 +87.252.255.14 +218.85.97.34 +195.154.52.96 +70.75.235.215 +184.166.237.78 +112.215.124.145 +68.246.169.224 +79.133.135.23 +74.58.134.134 +82.142.112.229 +200.164.98.231 +176.110.250.220 +91.67.247.232 +82.67.66.5 +123.108.230.29 +188.143.19.122 +86.145.165.213 +84.232.195.44 +86.138.235.114 +25.31.60.102 +36.76.249.192 +92.20.132.221 +78.225.238.46 +91.243.25.4 +202.67.40.25 +85.17.24.3 +121.220.62.161 +178.236.62.13 +194.44.26.217 +50.153.148.144 +77.57.13.122 +31.52.169.179 +178.162.63.137 +86.145.238.190 +77.49.127.161 +111.95.163.156 +82.73.214.43 +101.160.170.84 +37.110.17.100 +37.78.114.15 +109.173.7.165 +88.9.101.254 +94.51.32.217 +63.87.254.207 +217.73.139.66 +67.171.191.122 +178.173.7.237 +190.252.136.95 +217.235.230.186 +92.124.37.166 +188.109.30.153 +83.128.24.180 +91.40.70.81 +25.5.110.117 +186.95.20.215 +143.160.105.28 +140.168.123.154 +125.211.213.132 +87.93.111.108 +86.166.84.223 +62.195.143.219 +177.97.221.235 +160.255.48.163 +115.152.152.76 +2.25.181.198 +198.147.29.138 +178.234.195.60 +63.142.161.7 +71.35.59.89 +91.69.121.77 +86.161.148.170 +84.73.147.5 +201.212.212.92 +88.217.181.2 +188.67.32.137 +95.237.83.104 +84.22.5.78 +75.139.130.110 +81.141.17.230 +93.107.127.131 +81.249.78.103 +89.254.228.135 +42.61.112.245 +79.35.129.75 +5.254.97.75 +87.99.37.114 +88.136.23.202 +216.144.236.42 +84.236.19.157 +84.220.209.247 +46.254.132.34 +89.37.62.17 +178.121.32.78 +190.201.14.18 +178.204.62.112 +186.116.227.215 +84.154.93.193 +2.85.179.46 +217.131.165.253 +162.104.104.66 +192.77.248.6 +83.220.237.121 +85.178.84.212 +2.84.13.138 +82.50.151.8 +188.143.7.32 +189.250.79.133 +120.140.50.159 +128.90.23.4 +72.64.93.117 +107.4.96.165 +174.71.129.109 +203.98.92.130 +86.181.92.47 +85.60.236.130 +79.141.246.80 +124.168.137.32 +185.54.176.156 +186.119.252.108 +95.24.121.58 +198.18.1.15 +90.46.58.23 +63.142.161.20 +171.4.72.224 +88.180.60.218 +80.212.50.182 +0.0.0.0 +32.97.110.61 +90.29.148.68 +31.181.197.19 +93.87.184.75 +90.176.52.35 +14.192.209.247 +76.242.145.138 +129.10.9.64 +78.15.202.45 +77.97.142.87 +207.81.63.135 +81.171.98.35 +202.62.17.69 +42.104.32.32 +95.26.202.211 +159.118.77.129 +100.76.86.176 +173.254.218.226 +92.19.38.47 +188.76.162.80 +81.154.37.205 +202.62.18.90 +92.148.231.170 +112.198.100.11 +94.67.213.230 +81.47.166.253 +111.241.99.206 +206.45.157.108 +223.204.247.173 +188.232.3.241 +109.121.36.180 +176.8.52.211 +165.255.211.31 +201.209.4.88 +122.169.144.108 +115.77.131.85 +119.162.11.240 +202.67.43.8 +58.7.43.189 +113.254.169.97 +65.93.22.223 +2.24.137.179 +37.205.63.243 +188.153.14.179 +173.27.142.32 +186.90.26.100 +75.137.110.60 +94.70.17.152 +188.73.192.6 +50.38.90.90 +186.104.168.59 +99.58.56.103 +78.111.186.34 +162.156.199.110 +189.69.228.213 +188.162.132.92 +188.250.46.17 +46.254.11.158 +216.84.157.50 +41.105.238.117 +178.164.143.158 +110.17.46.185 +109.145.153.74 +91.201.118.181 +111.242.50.157 +209.95.50.21 +2.85.48.9 +86.147.113.242 +201.32.5.18 +70.89.67.173 +188.6.144.132 +219.90.169.227 +118.209.107.196 +72.209.204.141 +145.255.9.104 +83.248.48.163 +146.0.32.101 +69.227.211.207 +83.250.224.227 +209.195.122.166 +5.175.208.105 +23.243.180.110 +84.147.123.11 +24.117.149.151 +190.205.77.192 +80.203.58.200 +212.89.231.162 +139.162.20.227 +104.200.151.4 +177.228.70.157 +79.175.64.115 +230.88.48.35 +84.167.70.224 +92.76.239.3 +86.130.241.50 +186.115.66.232 +37.188.229.58 +198.18.1.10 +186.212.36.105 +5.2.66.120 +108.170.186.184 +188.77.219.159 +190.198.3.63 +36.68.180.135 +95.137.245.107 +92.127.114.4 +138.97.160.250 +67.253.255.191 +81.26.143.178 +92.44.18.79 +46.118.76.11 +163.21.61.34 +23.29.222.45 +100.71.25.195 +87.79.212.65 +95.181.3.196 +119.252.188.74 +95.71.9.39 +189.243.241.227 +179.24.39.24 +79.70.37.23 +84.99.129.92 +189.35.206.190 +178.213.168.44 +108.184.133.213 +105.224.102.135 +2.85.178.120 +91.158.215.5 +188.238.162.173 +120.164.44.57 +87.92.110.226 +37.244.225.68 +92.37.108.18 +174.0.80.58 +83.252.144.230 +89.146.60.241 +209.107.214.46 +193.92.127.190 +25.120.64.106 +193.173.216.141 +187.15.127.73 +162.216.46.187 +190.66.129.132 +96.46.197.79 +87.205.196.58 +107.10.92.11 +79.52.3.121 +109.227.46.236 +179.55.87.128 +60.229.177.248 +79.101.135.191 +110.139.78.73 +95.55.43.88 +79.203.115.225 +14.20.214.162 +108.238.96.103 +209.95.50.90 +92.127.18.55 +189.15.77.212 +67.168.77.63 +179.235.245.192 +92.17.4.80 +187.161.80.227 +101.160.38.192 +79.161.65.123 +54.223.76.165 +84.19.169.166 +71.166.60.163 +176.255.5.71 +77.250.199.106 +5.83.88.145 +60.213.89.243 +31.220.4.3 +216.121.249.83 +93.108.204.241 +188.49.9.231 +140.140.20.200 +186.1.246.2 +91.44.228.3 +1.0.0.0 +95.253.13.97 +76.68.207.219 +213.152.161.138 +151.227.55.136 +173.65.180.70 +193.161.15.94 +172.111.156.67 +162.243.72.148 +71.218.180.93 +79.206.173.126 +77.78.23.237 +220.179.36.72 +199.7.156.133 +41.96.129.229 +172.78.213.101 +213.74.106.1 +191.32.70.254 +190.211.210.173 +36.84.63.92 +91.229.149.244 +178.254.187.40 +186.94.39.37 +46.142.129.19 +18.111.41.60 +77.166.187.108 +172.218.139.35 +186.60.146.216 +180.110.159.141 +93.82.90.128 +174.97.17.97 +104.207.136.5 +120.144.4.208 +186.91.34.215 +36.83.149.142 +67.140.84.221 +75.172.213.12 +190.36.82.218 +151.66.225.227 +92.127.116.213 +81.229.125.221 +185.93.68.25 +93.137.254.149 +136.169.147.161 +77.243.183.9 +177.249.147.137 +5.42.80.220 +94.21.170.123 +94.75.136.231 +171.96.171.156 +201.210.116.14 +100.91.33.157 +201.229.57.249 +46.226.185.175 +181.24.19.226 +70.20.39.39 +76.73.3.178 +183.44.24.92 +37.30.58.138 +201.208.216.108 +181.59.197.112 +64.145.76.134 +87.112.242.103 +85.23.5.167 +212.54.195.80 +197.203.22.242 +113.7.121.63 +100.3.201.60 +49.49.249.174 +142.217.187.68 +223.204.248.114 +162.200.76.207 +2.4.131.202 +186.94.182.133 +94.11.104.13 +68.226.111.155 +14.148.92.236 +178.210.209.60 +190.36.211.35 +36.75.1.100 +79.245.210.43 +112.208.64.95 +81.111.5.210 +196.199.187.123 +83.128.11.52 +190.161.42.141 +219.79.188.196 +84.244.33.51 +152.78.66.223 +184.172.109.21 +174.25.126.49 +191.109.61.205 +209.188.7.224 +171.149.2.249 +123.243.36.179 +223.204.250.124 +187.78.66.45 +178.58.101.109 +117.207.4.174 +192.183.236.233 +78.190.78.63 +62.205.137.36 +46.244.202.244 +181.92.35.237 +78.226.118.202 +162.216.46.120 +106.66.184.84 +2.85.183.89 +182.182.97.227 +151.228.122.105 +186.46.200.125 +77.2.6.244 +88.217.180.135 +41.105.227.179 +117.217.169.19 +59.58.211.249 +187.59.190.124 +205.197.242.148 +66.193.240.253 +197.202.252.228 +189.157.253.81 +162.156.199.110 +79.206.173.197 +180.241.155.216 +109.74.169.196 +131.203.121.56 +217.120.80.97 +195.74.244.138 +95.25.148.21 +71.250.245.33 +186.91.50.84 +164.68.192.164 +81.132.3.126 +65.32.59.185 +77.243.183.20 +121.121.101.115 +94.229.74.91 +85.101.4.148 +25.212.159.235 +79.130.179.236 +194.105.229.242 +125.24.114.91 +37.209.150.125 +82.176.210.145 +5.254.97.85 +85.23.98.164 +24.208.133.42 +67.68.98.253 +181.137.36.56 +87.72.126.139 +178.234.70.85 +189.153.4.109 +93.35.112.145 +41.235.159.49 +82.34.217.209 +82.27.214.236 +62.158.153.239 +46.98.112.92 +95.236.131.168 +87.19.217.177 +24.16.13.108 +31.173.83.71 +80.110.47.213 +79.183.6.26 +110.114.190.209 +187.3.226.181 +24.184.225.173 +202.62.16.28 +178.66.204.156 +118.240.102.196 +78.9.100.214 +174.62.75.38 +212.129.1.77 +85.117.102.70 +105.225.124.150 +68.189.20.50 +53.193.239.1 +5.143.135.222 +110.168.232.115 +63.87.224.147 +72.10.210.38 +77.130.254.107 +117.79.232.195 +104.131.114.226 +1.47.75.216 +75.162.150.228 +114.76.65.209 +50.131.213.69 +105.237.240.41 +46.189.28.54 +200.195.171.66 +177.183.118.253 +107.182.228.8 +84.246.161.125 +92.194.211.133 +72.220.124.246 +95.18.51.131 +51.9.32.185 +193.92.105.49 +62.74.26.187 +67.228.177.213 +87.10.184.130 +90.215.81.198 +213.87.160.236 +95.168.128.13 +92.231.191.53 +5.12.141.158 +91.140.42.47 +175.136.48.78 +154.157.161.160 +182.50.248.181 +78.58.144.203 +192.99.47.172 +213.162.103.191 +36.78.190.197 +74.100.204.172 +186.204.128.46 +71.190.175.162 +217.66.101.17 +120.59.93.93 +222.47.203.227 +197.211.52.26 +212.112.119.23 +92.214.205.46 +24.91.145.46 +202.62.16.229 +124.170.29.11 +216.171.19.177 +190.201.27.160 +174.49.21.212 +71.31.210.43 +178.254.173.143 +217.235.245.98 +212.129.1.77 +24.159.124.124 +85.212.65.71 +78.132.75.22 +202.62.17.140 +76.99.37.97 +176.65.127.34 +72.191.195.23 +101.136.198.7 +184.148.244.248 +188.129.71.159 +60.166.229.77 +45.74.37.191 +181.124.105.133 +125.79.40.69 +99.184.34.61 +64.237.35.84 +31.151.218.186 +176.10.104.243 +109.93.1.102 +41.223.162.5 +60.26.198.94 +182.239.166.75 +190.51.144.246 +98.127.234.215 +176.93.163.131 +110.55.1.112 +90.191.168.246 +126.153.74.146 +73.39.122.227 +83.198.46.116 +185.34.240.121 +78.150.104.86 +212.123.186.174 +49.4.191.16 +120.195.96.242 +178.25.213.158 +98.121.109.252 +1.39.60.213 +62.216.195.237 +82.16.205.72 +80.213.122.68 +95.19.40.148 +78.8.245.213 +94.226.55.18 +31.61.141.136 +1.58.98.107 +74.108.124.159 +31.6.21.180 +181.90.74.240 +77.243.183.25 +24.230.59.100 +217.95.239.51 +108.61.228.160 +187.170.125.234 +109.188.124.7 +92.37.212.138 +73.226.22.158 +75.192.234.101 +94.181.229.228 +181.134.89.52 +112.215.124.80 +109.121.20.56 +178.234.178.80 +50.153.150.234 +83.46.249.179 +79.245.220.155 +91.180.129.209 +90.1.218.225 +186.90.83.237 +2.82.39.168 +186.95.52.224 +190.39.175.89 +93.106.134.14 +84.152.140.60 +79.245.219.88 +186.116.109.197 +197.117.67.167 +173.176.114.28 +79.183.15.169 +98.90.66.195 +213.111.129.137 +79.204.129.29 +172.58.139.124 +206.47.31.95 +121.15.76.179 +89.241.192.31 +37.187.56.220 +49.228.198.59 +2.62.2.103 +36.85.145.19 +91.181.179.196 +178.223.12.7 +186.129.158.136 +108.57.197.21 +216.14.113.63 +88.141.107.40 +46.73.248.237 +94.242.222.251 +95.232.234.3 +74.96.106.156 +1.56.204.181 +82.217.79.241 +190.78.61.241 +154.157.161.160 +88.217.181.49 +178.198.214.231 +171.149.2.249 +77.243.183.87 +188.162.14.48 +202.62.16.163 +37.73.252.213 +159.206.179.155 +125.60.156.151 +2.135.235.29 +136.169.141.42 +5.238.159.124 +31.57.94.41 +36.76.55.203 +108.61.228.113 +219.73.15.59 +67.181.167.196 +68.39.255.10 +86.10.225.82 +86.104.196.53 +188.0.47.26 +70.123.115.240 +58.212.134.44 +190.203.161.165 +217.131.108.228 +0.0.196.15 +190.205.162.178 +95.25.56.22 +86.136.204.35 +93.175.72.187 +191.112.243.63 +95.55.22.224 +188.83.111.148 +90.48.44.131 +60.240.1.229 +58.47.179.3 +71.251.58.161 +96.225.138.18 +186.95.46.68 +77.96.242.128 +172.98.87.38 +100.42.160.78 +25.90.67.202 +181.24.9.202 +208.167.254.12 +75.111.65.232 +167.61.86.118 +115.87.121.70 +46.149.182.128 +171.101.162.62 +119.77.150.187 +1.0.0.0 +2.134.144.106 +178.234.224.118 +2.240.48.24 +23.241.17.48 +83.61.236.237 +109.81.211.169 +104.156.228.174 +59.58.244.43 +58.100.64.156 +118.71.187.220 +167.113.103.254 +186.49.111.128 +95.90.203.206 +24.230.59.100 +83.30.0.203 +201.211.94.247 +150.243.99.3 +178.195.242.251 +5.80.54.19 +114.125.175.120 +201.209.135.23 +140.168.123.167 +86.168.89.159 +36.74.245.236 +112.210.106.111 +79.204.159.71 +176.9.4.50 +85.72.180.72 +188.196.185.78 +94.133.144.52 +90.1.53.178 +105.236.46.30 +70.173.7.42 +154.122.15.92 +192.100.100.137 +90.203.150.53 +109.201.154.148 +78.88.29.222 +219.79.188.102 +98.201.118.51 +46.101.128.131 +71.29.26.245 +46.172.222.26 +79.185.197.97 +194.105.229.89 +79.100.113.22 +37.190.37.125 +79.30.205.60 +186.116.109.197 +85.52.212.70 +219.73.15.193 +63.142.253.225 +86.197.146.225 +71.90.53.87 +178.234.94.211 +83.153.141.90 +78.178.112.5 +150.27.228.7 +122.155.168.126 +79.245.220.11 +113.28.135.125 +85.155.3.94 +177.131.171.131 +50.53.104.249 +86.31.102.68 +36.76.121.6 +77.222.109.76 +82.238.165.65 +24.65.226.161 +93.39.222.60 +213.87.123.163 +88.141.114.61 +79.204.141.76 +146.90.79.77 +66.55.144.245 +128.71.78.96 +115.127.32.42 +189.198.24.238 +192.77.248.6 +92.25.36.254 +213.227.202.119 +211.27.219.141 +89.154.49.154 +184.155.115.18 +80.192.72.225 +88.107.68.132 +71.89.196.163 +168.103.40.150 +87.147.153.162 +121.16.192.128 +2.103.209.142 +190.22.167.193 +178.223.71.185 +112.65.211.237 +94.189.190.29 +83.134.186.185 +31.132.225.141 +105.227.137.4 +79.255.239.227 +100.65.79.232 +125.90.135.86 +82.26.126.122 +95.168.129.156 +5.141.201.40 +88.137.219.174 +177.138.187.162 +151.74.96.104 +31.220.4.3 +5.170.114.84 +85.228.248.154 +100.80.155.184 +181.137.36.56 +112.198.100.11 +178.22.65.158 +91.84.78.147 +77.222.113.102 +46.0.39.78 +109.81.210.230 +5.138.162.117 +36.68.171.218 +250.31.16.246 +2.28.86.111 +85.155.212.110 +188.95.28.3 +176.14.89.216 +184.20.199.30 +95.215.158.237 +84.238.21.219 +71.53.153.7 +101.98.215.166 +152.78.157.141 +94.205.1.108 +83.220.238.207 +80.107.65.129 +84.41.36.30 +183.247.75.124 +101.116.78.128 +0.0.0.0 +5.171.61.131 +82.233.229.5 +177.137.238.202 +223.204.250.14 +31.50.240.201 +2.62.27.9 +113.23.124.101 +95.153.135.34 +95.245.11.217 +180.252.98.87 +139.192.151.240 +97.121.143.100 +188.51.43.179 +89.99.255.240 +62.21.3.96 +2.102.255.77 +192.81.14.1 +181.194.63.67 +201.216.194.193 +178.210.212.151 +66.29.187.52 +94.66.57.24 +109.43.0.198 +46.190.119.252 +196.32.3.15 +187.161.80.227 +24.8.142.47 +87.98.254.192 +192.241.215.76 +188.17.9.40 +116.12.61.150 +86.31.57.106 +89.178.173.167 +79.204.159.140 +70.173.239.125 +140.246.4.3 +86.208.11.209 +24.30.124.52 +94.208.224.23 +145.53.197.222 +96.46.196.49 +37.190.51.5 +45.58.202.38 +178.234.241.194 +94.157.236.220 +91.48.59.38 +151.238.56.177 +117.193.61.200 +209.91.43.78 +29.108.45.223 +95.72.228.21 +94.112.35.42 +95.71.9.142 +53.193.239.53 +70.169.101.156 +188.247.74.196 +86.132.88.171 +114.244.50.62 +67.173.146.85 +76.27.67.221 +190.62.100.198 +40.118.96.99 +0.0.0.0 +187.143.152.243 +85.76.73.210 +180.252.81.57 +188.25.7.9 +78.148.189.100 +191.33.44.16 +187.250.177.62 +37.6.243.64 +77.243.183.15 +162.216.46.27 +217.235.229.86 +205.185.218.227 +8.34.97.15 +113.254.169.130 +92.17.214.10 +46.238.214.52 +109.92.125.37 +88.217.180.206 +186.123.250.58 +189.166.241.69 +122.149.136.199 +254.192.10.101 +62.113.206.152 +100.69.120.173 +36.76.40.117 +176.199.122.249 +79.20.244.62 +162.104.104.66 +24.189.254.177 +93.120.154.125 +112.198.103.94 +190.77.226.235 +190.198.230.55 +86.181.101.168 +87.244.106.224 +69.254.108.4 +99.234.111.172 +220.253.89.87 +91.181.197.181 +46.0.90.17 +24.212.112.98 +71.238.102.227 +88.148.186.23 +89.36.99.226 +50.204.181.213 +105.236.200.45 +71.28.128.9 +70.49.81.155 +125.105.197.168 +69.18.28.136 +24.65.236.69 +188.73.252.150 +108.61.10.90 +113.13.96.143 +103.50.157.207 +104.45.135.147 +201.248.109.236 +176.10.35.244 +36.83.55.99 +152.249.19.96 +89.254.228.135 +220.85.248.156 +100.78.243.198 +195.174.63.110 +197.116.38.201 +109.182.97.110 +61.94.63.89 +169.41.33.208 +179.55.32.8 +99.121.48.135 +184.56.117.246 +94.11.119.138 +82.147.165.14 +131.91.7.2 +83.217.12.1 +111.240.210.236 +182.108.201.32 +83.8.244.143 +118.209.66.153 +86.97.88.173 +84.147.123.11 +105.184.225.62 +74.141.80.174 +70.54.86.241 +86.23.123.254 +216.166.10.199 +160.19.5.157 +106.192.29.85 +86.161.148.170 +68.125.54.178 +86.179.6.141 +92.127.1.148 +94.254.224.32 +190.91.55.65 +95.232.37.242 +178.128.243.39 +81.200.14.126 +2.124.60.67 +190.71.165.230 +188.0.47.151 +171.4.233.46 +179.114.28.83 +165.255.35.68 +100.104.254.252 +76.4.176.37 +95.236.166.58 +85.127.29.220 +77.220.33.116 +198.18.1.16 +178.120.36.242 +14.192.209.230 +79.202.59.93 +177.0.180.207 +151.28.169.207 +168.14.206.117 +148.31.163.57 +91.124.181.151 +14.192.214.217 +176.149.188.145 +178.172.215.92 +190.207.68.49 +195.113.196.64 +185.42.36.99 +92.40.183.177 +88.207.15.213 +174.69.98.70 +151.238.38.228 +117.222.10.207 +73.175.164.127 +178.85.54.148 +62.238.179.251 +95.37.9.26 +0.0.0.0 +79.204.182.127 +68.40.175.1 +185.65.132.100 +100.71.157.158 +186.188.74.85 +124.236.25.166 +81.184.33.26 +171.97.145.198 +108.61.68.149 +137.15.153.59 +37.213.220.12 +61.227.229.211 +0.0.0.0 +84.154.93.193 +91.158.150.69 +156.121.28.112 +181.132.90.89 +87.112.147.66 +187.147.251.197 +189.159.210.19 +91.150.92.1 +97.123.237.123 +79.116.200.114 +90.212.241.153 +24.163.68.6 +178.184.15.205 +80.116.90.228 +37.24.154.229 +14.148.96.47 +2.6.145.158 +202.62.17.198 +213.147.116.34 +47.17.155.157 +178.234.72.31 +82.151.220.178 +2.95.199.107 +113.161.76.161 +176.61.119.227 +178.42.41.138 +52.37.109.241 +78.94.32.194 +93.82.89.56 +54.84.114.124 +198.48.210.172 +173.9.191.245 +100.69.128.142 +176.51.149.113 +94.254.199.75 +201.165.192.20 +67.174.42.236 +108.177.128.150 +107.161.192.3 +190.22.128.210 +176.10.61.174 +183.38.36.58 +171.149.2.249 +125.238.117.232 +199.255.209.211 +141.136.220.171 +176.82.173.185 +68.45.101.13 +109.43.3.12 +187.233.182.174 +201.244.175.90 +201.229.84.230 +87.218.108.163 +85.102.97.66 +175.138.150.222 +64.134.147.95 +135.0.22.158 +213.176.245.198 +91.48.62.226 +107.222.190.99 +68.232.186.211 +186.62.36.185 +103.43.148.10 +86.141.164.169 +190.39.14.8 +159.203.56.201 +37.6.99.125 +108.233.142.124 +79.245.207.48 +187.143.90.5 +171.96.171.253 +84.20.242.6 +84.99.129.92 +91.44.239.110 +84.154.93.193 +94.189.210.210 +2.249.76.108 +86.181.101.168 +174.28.36.46 +36.78.203.186 +204.152.208.30 +95.24.97.176 +189.140.140.184 +191.248.94.241 +87.158.130.183 +172.98.85.45 +183.60.253.194 +91.48.36.208 +110.168.231.209 +101.80.128.236 +188.4.235.122 +139.218.216.7 +86.164.180.209 +64.231.241.210 +223.204.248.127 +109.93.59.176 +83.44.52.2 +183.97.21.147 +218.10.254.174 +93.210.112.103 +151.227.121.20 +78.132.91.153 +178.55.248.191 +41.95.222.186 +100.68.176.85 +79.194.236.237 +186.28.160.243 +46.98.124.128 +2.87.138.159 +93.113.244.166 +217.234.15.117 +189.130.86.228 +186.88.109.110 +186.92.11.234 +69.62.229.169 +124.248.207.76 +79.204.170.104 +109.131.72.221 +77.2.6.244 +86.131.97.253 +62.238.98.194 +184.0.10.44 +1.162.19.7 +178.234.145.196 +69.167.25.171 +183.188.194.186 +100.81.249.115 +37.146.123.203 +88.223.67.197 +82.24.182.116 +217.83.63.88 +178.206.94.207 +46.19.139.174 +212.43.117.91 +109.221.52.26 +95.180.74.125 +108.125.214.137 +71.231.4.16 +190.200.107.145 +92.127.115.8 +68.197.126.71 +37.219.113.144 +119.94.224.223 +88.75.39.23 +71.52.80.53 +93.27.43.182 +178.33.209.212 +186.92.228.115 +85.178.89.74 +84.133.115.69 +59.177.171.125 +84.147.117.137 +93.201.233.37 +45.72.146.82 +1.0.0.0 +201.243.110.123 +104.156.228.158 +85.15.5.3 +188.27.70.20 +95.232.214.103 +109.62.143.55 +62.4.196.178 +96.46.206.30 +217.235.240.26 +82.39.170.75 +186.85.81.206 +176.188.61.87 +46.238.37.253 +109.189.198.251 +217.65.48.86 +213.67.148.249 +46.70.136.199 +86.213.185.31 +37.190.115.240 +88.199.98.126 +198.23.71.72 +89.98.91.183 +190.207.56.101 +66.159.126.13 +45.217.148.157 +66.220.156.78 +114.79.51.163 +84.28.195.200 +79.175.93.227 +118.209.218.191 +172.111.156.67 +95.52.178.191 +189.159.94.1 +85.76.6.141 +79.141.170.4 +171.149.2.249 +54.84.21.157 +90.204.87.69 +50.83.9.153 +175.100.138.174 +178.128.248.1 +71.53.157.49 +173.189.166.246 +90.217.248.209 +181.176.46.99 +190.12.191.87 +75.54.50.55 +25.15.9.35 +190.142.31.90 +46.233.224.228 +37.238.140.55 +186.94.241.77 +121.141.52.83 +151.238.38.228 +151.66.226.64 +81.141.4.205 +194.61.68.124 +181.162.55.198 +208.82.41.47 +64.130.98.213 +61.253.83.10 +72.78.180.127 +17.234.139.146 +83.192.241.120 +79.204.149.175 +79.206.173.127 +95.141.28.168 +77.88.251.253 +94.70.5.65 +89.233.112.233 +79.245.193.41 +50.161.176.139 +112.210.26.23 +80.213.212.251 +67.193.83.131 +188.52.73.139 +177.228.66.13 +87.218.108.163 +198.48.210.172 +70.197.79.205 +105.225.199.114 +109.232.51.32 +145.249.205.251 +75.89.23.142 +176.84.46.160 +187.121.135.227 +178.140.25.85 +86.241.192.71 +220.75.218.153 +179.179.151.186 +151.72.136.1 +177.96.99.229 +93.100.39.93 +54.89.21.44 +83.56.202.88 +5.100.81.158 +2.29.149.62 +113.176.61.195 +193.173.216.202 +62.106.112.213 +1.25.124.164 +97.101.86.80 +173.245.219.43 +105.224.251.219 +201.75.99.9 +212.14.20.148 +62.74.23.49 +79.255.234.97 +49.199.160.43 +66.55.134.205 +37.213.130.13 +81.167.129.247 +92.226.44.87 +94.51.21.12 +84.83.129.43 +88.243.13.85 +140.247.0.16 +85.192.189.179 +91.179.166.223 +187.180.169.226 +82.126.49.125 +92.113.175.86 +87.50.118.59 +125.24.126.173 +88.198.76.188 +50.179.9.127 +37.47.209.113 +59.35.255.161 +94.124.5.10 +178.24.36.208 +188.4.40.193 +79.245.221.139 +46.227.12.142 +141.101.181.28 +217.235.237.34 +181.137.36.56 +202.62.16.202 +80.107.29.151 +165.84.8.160 +138.68.17.92 +200.44.213.166 +77.11.24.112 +85.150.137.211 +45.56.151.17 +81.219.27.176 +66.87.99.109 +217.89.14.239 +101.165.182.99 +85.132.87.161 +187.184.200.144 +178.150.52.182 +63.29.83.160 +79.185.83.6 +94.66.57.230 +24.201.80.101 +45.49.180.110 +223.204.251.231 +190.199.212.56 +109.43.2.207 +23.116.250.206 +128.78.219.231 +67.190.233.238 +64.24.149.69 +25.52.41.246 +117.194.61.67 +78.87.91.243 +37.55.224.162 +50.84.151.156 +112.213.118.25 +24.48.42.178 +190.255.10.225 +78.111.196.163 +212.85.133.161 +178.120.34.128 +73.224.21.143 +72.61.215.230 +186.91.255.210 +104.45.151.45 +62.4.196.157 +79.143.165.65 +82.209.148.120 +77.85.130.228 +37.47.211.243 +95.26.230.154 +178.43.32.146 +85.140.2.62 +96.240.86.151 +5.249.110.239 +73.203.113.197 +219.73.12.46 +108.233.142.124 +89.77.214.93 +46.129.112.120 +50.46.209.169 +80.72.69.226 +113.244.80.141 +79.177.240.158 +155.138.231.104 +108.234.78.87 +104.238.187.114 +81.231.244.196 +90.79.109.176 +71.219.139.245 +84.251.240.206 +70.75.192.84 +128.70.25.12 +151.15.31.42 +128.75.244.118 +100.68.31.17 +84.237.53.11 +31.207.228.214 +69.55.253.225 +223.204.240.178 +46.59.37.170 +118.209.134.35 +178.116.237.19 +67.253.130.12 +186.14.169.249 +254.228.44.227 +99.244.163.204 +90.186.174.74 +72.136.101.25 +110.168.232.207 +91.21.209.178 +71.57.102.33 +197.20.81.222 +171.97.202.78 +189.58.16.26 +176.15.167.33 +178.242.208.101 +69.164.195.142 +207.192.254.156 +97.81.48.175 +0.0.0.0 +95.250.249.192 +94.74.124.50 +71.189.58.203 +188.244.193.15 +96.49.76.100 +178.234.164.253 +93.156.82.36 +201.213.75.106 +212.74.202.184 +79.198.46.110 +37.4.169.70 +112.198.90.4 +193.92.193.216 +90.110.135.137 +231.190.29.94 +93.47.133.195 +100.105.40.106 +80.42.27.32 +97.82.95.148 +91.48.43.50 +106.66.131.0 +25.7.70.98 +89.109.26.16 +86.58.6.204 +42.2.89.74 +121.214.35.106 +23.92.215.194 +67.249.179.67 +186.91.225.145 +70.194.133.202 +73.191.209.26 +31.57.93.197 +187.143.152.243 +104.34.201.105 +109.156.59.69 +168.203.172.119 +188.69.213.71 +37.201.224.198 +63.87.254.166 +46.147.175.80 +176.31.53.252 +190.181.186.26 +108.236.229.199 +178.120.223.129 +93.196.163.245 +53.193.238.248 +37.78.82.173 +85.222.169.120 +190.238.254.2 +186.22.84.72 +67.248.117.76 +80.236.18.96 +95.237.150.252 +31.162.201.168 +98.240.120.30 +62.143.41.223 +186.118.101.80 +88.14.181.193 +108.244.47.41 +180.126.103.255 +92.76.227.125 +78.35.153.26 +42.117.24.196 +79.42.95.37 +2.85.49.89 +124.73.75.194 +208.118.217.31 +5.68.34.214 +68.69.138.30 +141.130.202.40 +14.125.241.61 +78.150.104.86 +95.179.16.46 +46.254.11.158 +81.243.96.100 +190.38.174.14 +91.115.16.137 +77.46.104.150 +187.14.222.253 +75.142.133.235 +5.164.174.111 +90.227.39.82 +80.61.97.239 +2.147.177.10 +87.3.231.182 +193.253.170.95 +50.124.52.72 +81.141.18.79 +180.117.230.141 +119.181.14.100 +46.61.20.84 +68.4.194.25 +63.87.254.129 +85.105.19.41 +145.132.7.244 +73.15.33.81 +83.32.181.154 +171.6.27.97 +202.62.17.108 +185.9.113.48 +113.111.207.228 +177.45.14.116 +115.87.235.103 +91.189.87.130 +78.12.50.49 +113.254.166.97 +107.5.121.128 +217.83.52.206 +92.147.147.139 +217.73.143.165 +101.136.198.7 +46.238.214.44 +195.128.182.25 +81.4.219.185 +121.208.106.138 +31.6.57.69 +37.229.91.22 +188.143.66.100 +109.109.158.248 +200.121.17.156 +24.65.239.116 +203.198.80.62 +113.240.247.242 +199.19.95.181 +182.149.179.75 +86.133.95.54 +196.217.77.156 +53.193.238.76 +90.46.77.211 +210.55.212.77 +86.156.30.44 +46.219.75.126 +88.206.186.25 +201.139.64.199 +83.220.237.203 +90.57.159.167 +37.131.65.81 +81.105.205.39 +88.114.111.212 +70.126.98.88 +131.204.137.14 +139.192.129.27 +142.196.226.85 +25.123.50.89 +66.90.147.7 +207.98.91.108 +140.186.20.196 +168.63.186.126 +94.216.85.214 +78.88.29.88 +200.84.105.129 +89.164.183.243 +27.77.240.91 +66.41.56.235 +176.9.113.75 +172.56.38.36 +21.209.82.239 +178.43.50.78 +186.35.26.47 +128.71.79.146 +67.44.193.89 +178.254.189.106 +50.131.48.25 +193.173.216.141 +46.166.186.237 +60.242.111.104 +114.96.144.162 +179.35.67.146 +46.166.190.221 +153.136.35.20 +37.190.51.38 +2.206.2.53 +95.72.230.232 +173.199.65.38 +96.229.213.18 +150.29.134.59 +115.28.162.137 +84.187.93.208 +78.148.79.165 +202.62.16.0 +200.78.5.105 +121.211.218.102 +85.7.159.117 +83.202.206.217 +186.237.60.190 +37.248.255.139 +78.164.114.243 +108.24.81.3 +162.216.46.184 +200.229.216.6 +188.162.36.53 +89.164.233.118 +186.93.181.105 +89.100.186.76 +109.194.110.54 +108.27.213.19 +201.208.197.20 +201.66.83.187 +190.37.117.153 +223.73.103.139 +120.22.163.204 +5.152.218.204 +186.207.213.206 +80.215.166.84 +95.96.146.121 +109.226.84.229 +100.68.53.91 +31.3.26.210 +166.156.10.96 +85.23.98.164 +115.188.71.106 +188.67.19.102 +212.84.112.95 +208.167.254.71 +58.70.1.212 +181.1.157.126 +50.46.209.169 +95.27.239.163 +169.237.99.175 +46.176.81.91 +88.141.107.40 +95.91.255.151 +2.85.55.69 +231.190.16.139 +95.186.235.168 +159.206.179.155 +187.170.111.199 +23.239.109.42 +77.104.194.95 +100.116.146.73 +76.99.37.97 +181.24.69.91 +94.21.59.198 +68.100.121.75 +104.35.225.25 +108.19.160.97 +87.9.217.120 +86.197.147.26 +190.200.116.19 +78.235.24.172 +99.137.226.94 +154.157.161.160 +79.70.38.26 +69.246.109.194 +108.202.176.163 +219.73.93.18 +176.10.33.23 +94.96.79.172 +139.192.181.8 +79.203.93.193 +189.202.85.78 +31.132.225.212 +94.26.100.34 +197.211.52.17 +60.168.253.88 +50.153.150.172 +98.193.70.55 +192.101.101.104 +188.108.35.232 +41.174.144.142 +79.130.27.17 +74.61.120.185 +63.87.254.188 +193.161.15.72 +149.154.199.79 +5.151.75.13 +178.223.62.69 +94.179.125.146 +90.26.80.8 +74.108.73.130 +64.121.9.200 +193.190.253.144 +89.104.6.79 +79.204.158.156 +190.204.3.155 +50.137.46.45 +31.11.78.216 +84.19.169.166 +62.16.243.132 +78.90.92.70 +101.80.128.236 +94.65.51.187 +84.106.163.174 +169.0.31.3 +212.219.189.18 +118.211.237.33 +174.52.24.82 +82.75.39.122 +186.92.246.108 +84.240.28.167 +82.72.102.219 +250.31.16.246 +81.182.88.122 +110.168.232.151 +85.244.49.62 +88.74.61.114 +162.227.231.91 +96.41.140.116 +72.191.48.158 +201.9.197.249 +88.184.162.93 +77.222.109.76 +90.39.140.211 +46.246.160.154 +201.243.217.28 +70.29.108.165 +105.229.179.124 +24.8.153.132 +118.208.25.245 +143.48.117.52 +50.254.73.145 +90.26.208.13 +181.56.181.162 +71.196.66.185 +82.26.154.43 +81.141.17.126 +83.29.7.121 +190.36.215.59 +68.104.181.13 +188.210.249.204 +83.220.237.57 +24.179.14.89 +24.119.48.249 +41.13.80.201 +93.169.65.197 +73.184.42.174 +209.188.48.220 +104.219.250.54 +83.10.234.176 +128.71.102.82 +0.0.0.0 +77.171.22.122 +187.35.183.226 +95.24.43.219 +78.161.227.14 +186.91.238.219 +174.93.28.202 +5.135.108.204 +93.115.95.201 +190.77.92.178 +5.167.151.214 +31.163.148.219 +5.47.144.159 +212.85.68.147 +125.238.118.21 +199.115.160.26 +50.66.152.76 +188.129.66.152 +186.93.181.105 +84.6.63.86 +89.204.135.212 +97.127.89.147 +79.173.209.150 +180.190.8.178 +177.182.78.243 +81.153.146.33 +195.50.30.202 +93.156.80.127 +190.251.201.110 +91.43.38.212 +77.46.228.58 +109.196.91.128 +165.255.85.43 +89.182.207.98 +5.19.254.181 +36.76.104.175 +163.158.245.3 +212.54.195.80 +91.182.2.84 +91.61.80.32 +82.141.118.195 +36.77.10.132 +176.24.60.151 +92.148.98.65 +46.248.87.63 +188.129.70.67 +162.216.46.43 +84.104.85.140 +87.198.43.146 +41.105.239.184 +178.222.8.65 +178.197.226.73 +75.130.163.51 +218.138.216.16 +110.168.232.29 +197.129.165.52 +110.114.225.201 +171.96.168.53 +100.94.186.216 +113.193.28.141 +62.47.184.52 +121.135.125.6 +113.241.227.205 +79.194.202.151 +93.138.19.90 +38.117.92.242 +90.255.102.242 +217.235.245.98 +178.254.191.36 +145.255.2.249 +92.52.46.10 +176.33.105.89 +180.159.137.110 +212.110.12.247 +178.223.29.34 +78.132.41.173 +209.107.214.55 +184.157.211.92 +201.210.136.34 +104.156.228.166 +2.110.116.27 +78.146.2.3 +189.223.40.145 +31.10.151.14 +115.73.156.101 +62.98.172.194 +12.51.221.142 +199.48.245.187 +40.45.199.182 +37.145.251.42 +191.254.234.6 +133.42.108.166 +171.97.186.106 +87.100.189.136 +85.254.74.162 +178.16.1.124 +186.146.156.243 +94.8.234.216 +113.187.0.211 +79.41.6.65 +89.68.115.216 +46.255.233.35 +91.33.212.176 +190.103.63.253 +68.229.239.219 +83.7.130.162 +155.138.228.234 +99.121.207.38 +202.80.215.19 +87.158.147.150 +162.216.46.113 +223.207.234.13 +140.168.134.185 +93.208.104.246 +210.55.212.7 +173.192.115.17 +94.197.120.199 +122.61.96.54 +74.216.74.20 +197.202.252.228 +213.89.44.226 +189.232.134.204 +2.102.154.95 +78.220.216.208 +200.93.69.211 +160.255.48.163 +130.25.88.216 +92.145.152.61 +124.217.188.204 +69.108.3.158 +88.17.163.232 +186.92.49.124 +109.159.67.244 +94.41.57.154 +200.8.39.149 +141.170.129.22 +181.55.226.126 +92.84.1.150 +217.25.157.66 +95.81.234.123 +99.118.169.71 +172.77.23.103 +120.156.32.20 +151.61.206.195 +201.34.228.37 +79.30.99.74 +96.23.182.66 +92.126.225.41 +65.25.112.109 +121.86.227.139 +87.119.241.58 +62.210.139.248 +72.187.115.150 +189.97.76.94 +92.242.84.158 +83.26.142.240 +101.184.130.85 +104.131.89.9 +109.43.3.23 +223.206.149.29 +37.78.29.254 +188.158.167.162 +220.246.221.177 +201.248.98.151 +187.56.144.147 +92.100.204.158 +89.14.37.84 +95.91.253.107 +85.240.98.217 +62.249.190.35 +84.147.122.52 +68.189.20.50 +46.166.165.39 +171.149.2.249 +37.212.78.20 +75.108.234.202 +186.94.24.202 +195.135.248.102 +91.117.36.36 +50.137.239.137 +2.81.19.210 +86.172.4.51 +176.109.8.20 +190.140.129.211 +178.222.27.95 +95.26.17.187 +24.16.13.108 +151.61.110.190 +204.84.244.11 +89.104.6.79 +151.95.2.248 +142.4.218.174 +178.226.92.114 +213.215.125.154 +86.178.41.177 +89.106.38.103 +189.40.27.87 +186.104.156.37 +82.5.155.195 +178.223.114.47 +78.6.102.70 +68.229.239.219 +202.62.17.243 +46.55.193.116 +64.145.76.166 +95.19.24.198 +187.143.131.15 +151.238.39.63 +223.204.250.123 +100.109.114.160 +2.87.138.159 +86.95.134.254 +85.176.131.41 +209.95.35.100 +120.144.147.163 +217.235.236.36 +77.163.109.238 +183.96.38.106 +31.181.197.19 +177.4.68.247 +190.203.222.36 +2.31.98.84 +113.254.165.199 +190.37.54.100 +120.156.80.113 +186.92.64.175 +68.61.104.159 +216.240.61.162 +90.255.102.242 +176.248.160.233 +186.36.78.101 +187.11.111.61 +62.83.250.234 +2.218.14.123 +184.100.197.229 +83.192.225.244 +83.134.97.101 +183.54.47.126 +88.152.186.240 +37.191.165.193 +220.253.92.215 +85.181.25.208 +50.107.118.90 +202.156.248.94 +90.208.127.105 +81.184.33.26 +62.238.41.246 +178.248.251.129 +201.248.97.184 +186.90.183.61 +65.128.50.200 +23.125.138.238 +66.186.168.251 +184.75.213.116 +201.246.92.20 +194.219.122.5 +173.28.195.191 +178.120.104.120 +176.187.33.65 +180.107.236.181 +217.25.228.30 +5.28.165.169 +189.238.253.154 +217.118.93.107 +187.37.140.36 +77.253.40.105 +219.137.245.93 +95.220.11.10 +174.69.37.131 +90.18.99.84 +93.156.84.193 +14.162.138.171 +2.95.134.41 +200.8.87.43 +178.234.175.101 +31.6.127.45 +0.0.0.0 +84.240.28.167 +78.37.212.27 +213.155.255.181 +81.97.211.72 +87.110.128.96 +93.156.85.152 +108.61.221.158 +213.114.133.63 +37.27.50.204 +217.235.254.55 +108.125.221.233 +152.238.212.218 +88.75.153.134 +177.124.186.20 +89.66.61.243 +97.127.95.119 +79.245.222.98 +125.238.116.198 +212.42.202.126 +37.188.142.133 +23.91.239.26 +18.111.100.175 +86.46.47.134 +91.158.212.23 +67.160.193.96 +94.174.159.109 +86.56.18.204 +190.97.143.230 +66.87.99.95 +72.160.42.110 +186.62.36.185 +84.19.166.58 +74.67.101.115 +37.190.51.16 +89.14.70.25 +77.231.219.235 +174.108.114.15 +91.59.143.68 +79.16.139.147 +53.193.238.159 +181.24.4.134 +93.205.23.150 +95.174.113.68 +72.130.92.25 +88.81.128.158 +187.79.198.101 +190.199.47.211 +79.245.205.64 +193.92.252.13 +193.92.57.219 +46.63.206.177 +117.147.4.250 +5.71.5.180 +78.37.209.224 +107.191.33.13 +109.131.108.79 +31.183.159.36 +109.241.213.159 +110.168.232.79 +82.19.207.84 +77.43.17.201 +94.155.117.58 +80.43.133.125 +5.42.93.15 +64.237.51.165 +108.24.76.250 +66.169.237.102 +85.238.199.16 +86.132.88.171 +188.0.40.33 +2.95.142.104 +179.34.61.194 +162.242.173.250 +37.26.143.177 +37.79.250.117 +99.61.58.22 +97.90.203.136 +113.185.7.51 +71.240.162.10 +188.73.192.30 +223.204.247.93 +36.71.166.125 +108.193.141.115 +176.253.217.115 +20.246.56.181 +83.40.223.27 +82.73.127.246 +82.251.136.117 +178.234.114.206 +92.76.244.169 +86.129.252.132 +121.98.152.41 +187.161.81.97 +202.62.16.0 +50.168.210.180 +176.205.157.226 +86.77.231.45 +191.43.19.200 +188.207.95.41 +37.14.15.170 +110.227.17.198 +79.204.180.51 +86.132.237.173 +14.1.200.115 +186.92.215.94 +85.176.46.211 +90.197.6.250 +87.100.131.44 +176.102.193.48 +186.32.213.185 +104.183.119.254 +173.244.16.168 +190.94.88.199 +89.168.217.136 +209.59.38.102 +75.64.200.17 +202.62.16.87 +188.129.57.138 +5.14.200.53 +24.222.58.144 +137.166.125.55 +149.172.246.169 +154.157.161.160 +24.220.96.106 +173.63.168.11 +178.234.168.79 +83.143.240.37 +167.174.165.94 +37.215.7.171 +122.219.223.82 +92.124.24.80 +37.190.39.95 +75.129.6.150 +197.228.88.93 +78.151.58.22 +108.180.22.192 +42.119.127.122 +78.147.114.195 +88.150.198.102 +192.99.151.16 +24.226.165.139 +75.108.234.202 +81.211.118.130 +213.49.96.80 +50.97.94.36 +201.207.87.223 +94.207.183.36 +181.50.213.128 +101.183.63.236 +108.35.213.112 +71.53.153.55 +72.51.88.209 +172.15.0.91 +77.203.122.218 +190.75.117.251 +202.62.16.1 +83.139.147.91 +86.56.9.1 +50.158.63.41 +220.253.2.201 +71.70.211.48 +190.78.218.159 +193.92.113.33 +84.79.112.88 +71.176.44.139 +151.25.116.38 +93.80.83.210 +183.26.251.60 +187.154.152.133 +51.9.232.233 +68.87.73.163 +2.222.243.0 +88.65.95.26 +86.216.248.101 +99.250.53.196 +94.214.163.25 +86.172.239.91 +58.166.126.122 +67.233.200.130 +167.113.103.254 +187.250.9.145 +87.79.205.210 +122.168.206.143 +35.2.251.113 +79.206.175.208 +80.81.242.72 +178.32.26.198 +92.157.198.24 +109.165.84.236 +41.246.123.128 +190.79.44.71 +80.71.250.255 +179.105.217.189 +78.148.189.100 +24.114.57.4 +97.82.226.119 +93.190.177.85 +94.179.52.195 +93.87.184.213 +69.164.195.142 +190.78.104.60 +37.229.88.114 +87.168.106.206 +109.201.152.246 +41.142.197.132 +76.228.232.120 +85.242.169.49 +79.134.38.179 +191.6.120.88 +45.78.219.84 +220.253.0.216 +82.208.124.9 +80.77.162.65 +60.25.173.119 +222.228.130.115 +101.184.48.161 +188.171.57.57 +188.143.12.35 +47.67.70.34 +104.156.228.84 +190.38.44.218 +186.129.155.222 +153.136.35.20 +80.229.146.133 +93.79.187.183 +89.247.168.201 +50.254.73.145 +89.250.167.173 +98.213.71.104 +192.253.243.51 +62.47.227.63 +5.42.102.21 +179.126.53.8 +176.101.222.25 +213.114.129.89 +110.90.60.204 +109.88.79.228 +81.200.14.126 +91.148.114.205 +202.62.16.58 +217.118.79.25 +67.70.149.240 +187.170.154.127 +212.139.246.181 +83.143.245.4 +18.111.35.103 +75.156.96.161 +46.18.123.126 +184.99.115.161 +46.28.51.116 +83.144.94.122 +71.200.192.224 +195.241.134.120 +77.243.183.92 +53.193.238.160 +83.4.229.104 +91.52.13.182 +59.88.79.99 +177.138.231.246 +84.244.18.20 +81.36.182.81 +60.10.247.252 +75.168.7.211 +89.155.203.172 +50.251.4.31 +222.0.0.102 +79.168.193.22 +95.86.230.196 +217.235.251.6 +187.255.237.97 +89.142.141.170 +177.95.14.136 +95.152.37.74 +201.211.225.122 +92.97.90.110 +96.240.84.172 +107.170.138.159 +152.238.65.16 +124.229.130.174 +201.208.21.151 +200.84.137.217 +89.182.123.180 +37.113.199.194 +198.91.147.54 +125.27.55.204 +81.155.43.125 +27.43.252.75 +181.29.63.54 +1.0.0.0 +193.161.15.78 +41.96.104.28 +100.65.121.11 +193.107.92.153 +209.160.123.53 +186.121.7.132 +87.8.219.205 +207.47.241.87 +213.179.208.77 +110.88.108.160 +69.65.254.34 +223.204.248.206 +112.81.12.8 +50.35.92.164 +209.165.141.252 +31.61.140.245 +200.75.116.199 +183.30.15.163 +80.106.197.192 +73.146.130.93 +121.223.199.60 +121.208.89.35 +186.95.154.86 +114.96.96.201 +190.77.76.253 +178.44.12.28 +176.195.241.216 +79.204.150.29 +186.147.61.75 +104.28.201.93 +155.138.233.252 +61.90.51.135 +179.43.169.226 +172.98.67.121 +109.43.2.138 +78.137.13.162 +84.135.89.49 +167.61.106.37 +115.135.47.10 +192.166.112.137 +52.169.229.251 +178.164.253.11 +139.194.44.166 +177.134.15.73 +66.235.1.218 +85.75.79.133 +27.34.28.186 +179.43.155.162 +58.160.139.253 +31.6.57.80 +177.17.121.175 +85.247.35.163 +94.34.176.169 +202.62.17.22 +84.13.116.48 +80.187.103.129 +50.54.85.174 +202.62.17.127 +47.88.79.118 +50.46.211.57 +79.53.221.91 +60.251.32.152 +1.189.117.58 +71.167.108.24 +88.3.193.105 +151.228.27.238 +88.217.180.11 +201.67.210.116 +201.210.86.95 +91.48.54.39 +86.177.158.37 +25.22.203.199 +125.66.41.200 +2.30.40.74 +114.79.52.218 +92.16.184.187 +60.50.198.153 +212.54.223.95 +90.56.25.32 +90.218.208.79 +2.146.174.242 +90.205.98.105 +181.28.27.4 +217.253.210.218 +190.146.5.134 +2.187.203.89 +80.215.178.13 +67.190.233.238 +125.60.156.168 +79.50.152.125 +187.142.223.82 +177.249.135.137 +5.137.233.47 +46.121.67.177 +46.19.137.78 +77.243.183.8 +186.95.47.222 +178.33.209.212 +66.87.96.76 +79.245.222.88 +2.85.61.39 +62.152.54.44 +209.121.232.187 +145.133.165.175 +118.209.235.194 +62.47.227.187 +84.251.64.249 +80.219.197.66 +180.140.31.185 +37.46.230.100 +181.113.211.83 +86.133.178.92 +98.253.214.36 +70.78.40.232 +77.117.100.177 +94.189.195.238 +37.215.59.175 +84.236.18.119 +66.55.152.52 +99.122.104.173 +37.6.243.83 +78.145.233.123 +167.61.77.246 +84.195.0.111 +151.238.89.113 +164.67.192.103 +173.28.195.191 +5.15.206.164 +191.33.243.231 +46.191.185.225 +128.71.196.136 +70.194.70.48 +128.71.134.54 +81.141.9.239 +186.244.85.121 +81.61.16.6 +186.183.166.200 +46.39.244.44 +197.202.208.42 +187.34.158.87 +178.222.148.59 +93.36.81.178 +80.236.18.96 +198.8.80.164 +67.198.179.36 +186.188.64.207 +67.238.252.38 +109.65.9.237 +146.160.55.12 +193.191.182.129 +201.229.79.158 +189.202.76.142 +198.8.80.218 +83.37.92.22 +66.87.98.165 +108.111.102.250 +192.3.141.136 +36.77.37.99 +5.133.254.230 +171.97.178.84 +67.236.80.43 +124.169.21.253 +77.49.129.46 +213.55.176.201 +72.105.146.83 +54.86.65.139 +217.249.21.32 +82.192.198.114 +213.87.225.27 +98.238.145.154 +50.49.0.1 +93.47.2.62 +101.100.174.138 +73.90.211.41 +112.162.109.20 +202.62.16.255 +101.98.191.129 +58.8.154.202 +92.142.11.171 +178.234.176.195 +116.89.60.24 +146.255.159.37 +186.90.184.149 +84.161.246.83 +95.30.48.155 +201.231.176.74 +197.202.236.30 +133.89.163.229 +62.183.126.179 +100.73.71.245 +80.200.250.228 +81.182.26.155 +186.228.140.191 +59.56.8.45 +91.67.130.158 +13.92.236.203 +91.221.65.6 +189.252.164.142 +159.29.194.242 +103.48.97.248 +91.121.70.66 +14.192.209.173 +195.154.65.167 +111.69.81.202 +68.168.178.12 +31.57.94.41 +118.209.110.212 +98.126.0.139 +148.198.187.153 +171.97.222.55 +109.8.200.248 +41.244.240.69 +164.40.228.250 +95.179.35.205 +74.240.79.103 +95.138.194.14 +31.44.183.14 +162.213.36.102 +178.44.236.21 +194.187.251.43 +70.112.32.101 +93.138.35.172 +185.19.27.157 +108.216.28.224 +171.221.163.237 +5.135.139.202 +73.52.143.18 +68.5.217.46 +86.42.137.31 +109.204.151.99 +212.183.108.70 +191.19.117.188 +220.136.53.97 +124.122.2.12 +81.134.82.110 +83.7.20.194 +177.98.228.211 +96.245.4.9 +100.71.157.158 +79.245.217.242 +37.136.53.104 +124.122.211.138 +95.89.176.134 +37.146.123.156 +79.21.245.28 +152.78.66.223 +203.66.126.1 +79.141.166.16 +87.185.17.73 +0.0.0.0 +92.127.3.155 +93.143.187.180 +141.30.247.183 +109.193.145.224 +176.31.180.203 +173.192.170.77 +2.97.122.142 +112.198.79.88 +82.60.11.203 +200.77.107.132 +46.44.41.97 +85.15.5.3 +126.12.1.77 +201.219.191.75 +203.212.152.229 +62.1.164.209 +71.68.5.90 +177.16.140.114 +187.112.20.93 +79.234.127.67 +95.239.99.126 +82.79.88.31 +37.146.190.113 +188.119.211.100 +104.129.28.242 +165.91.74.108 +213.219.104.114 +195.82.178.218 +76.97.197.140 +46.166.190.194 +84.86.23.22 +104.34.125.117 +77.105.50.252 +185.42.36.99 +178.217.115.50 +187.131.95.225 +87.242.14.89 +223.25.25.183 +175.100.142.47 +176.103.211.236 +93.138.71.210 +216.110.226.63 +79.131.176.130 +193.227.251.74 +83.185.84.90 +100.113.28.102 +108.65.141.214 +78.150.104.86 +186.144.225.108 +37.188.232.39 +57.131.89.131 +50.143.117.165 +124.170.19.167 +93.39.149.83 +37.201.227.156 +178.234.146.7 +79.200.222.225 +177.96.85.194 +36.86.63.180 +114.125.46.34 +178.32.26.185 +69.166.161.250 +188.213.169.227 +62.178.7.135 +5.141.221.183 +173.75.252.241 +70.196.129.23 +115.87.247.225 +113.254.169.220 +41.150.248.217 +95.30.80.59 +178.120.131.163 +192.77.248.5 +217.197.240.194 +91.185.53.129 +80.131.61.147 +75.168.58.165 +192.99.0.112 +83.43.246.222 +188.29.164.101 +95.17.247.131 +181.119.64.254 +178.222.24.255 +114.79.37.72 +95.236.166.88 +173.9.121.186 +46.246.19.242 +219.88.65.49 +79.67.123.101 +191.34.215.26 +79.197.191.41 +164.132.209.199 +92.110.52.208 +209.6.192.104 +101.185.87.56 +186.107.73.130 +74.100.47.75 +67.44.193.168 +96.225.148.137 +88.208.1.194 +109.10.42.135 +46.159.239.247 +109.208.182.118 +112.208.225.223 +37.113.160.11 +217.113.63.81 +77.56.46.95 +77.234.82.79 +184.20.11.173 +179.177.177.13 +93.204.227.82 +83.135.241.11 +115.188.71.106 +188.143.60.184 +219.79.190.210 +84.236.36.52 +109.43.2.109 +84.106.163.174 +85.26.186.30 +180.242.130.210 +95.211.155.225 +84.106.246.14 +24.156.31.73 +73.179.71.188 +176.58.136.154 +84.24.102.45 +1.0.0.0 +41.96.52.112 +167.160.164.214 +114.218.143.23 +210.22.178.170 +189.100.45.65 +82.12.235.3 +217.235.251.238 +92.80.28.97 +89.117.26.93 +181.194.27.123 +135.0.20.85 +177.45.131.88 +108.61.199.67 +219.79.24.240 +85.178.51.221 +86.212.5.83 +85.247.160.74 +5.94.119.65 +88.6.13.88 +186.108.112.216 +79.119.17.84 +78.61.48.176 +24.114.26.172 +88.231.29.243 +190.202.250.145 +80.106.197.207 +219.79.188.14 +50.153.150.172 +87.113.49.184 +188.186.39.140 +80.131.63.94 +174.36.220.106 +5.158.97.8 +83.5.160.224 +101.200.151.162 +213.104.46.32 +138.36.34.163 +62.4.196.196 +36.74.244.33 +97.127.52.128 +200.138.71.22 +71.167.191.109 +37.150.165.82 +173.192.170.67 +5.79.72.105 +109.43.2.140 +109.73.43.230 +112.215.123.148 +109.43.3.39 +79.208.122.196 +95.73.28.217 +46.142.16.204 +227.210.163.145 +145.28.145.152 +76.181.115.35 +96.226.61.13 +212.115.253.154 +78.8.125.79 +187.140.217.21 +176.209.217.252 +109.90.217.195 +67.182.144.108 +37.79.249.58 +68.193.116.242 +191.254.234.6 +209.95.50.25 +90.56.59.43 +177.132.187.142 +212.200.65.246 +84.154.93.193 +78.253.251.14 +2.218.67.174 +31.174.69.205 +77.77.50.63 +188.122.246.208 +128.78.135.164 +85.222.169.120 +79.245.193.198 +46.193.142.190 +83.39.92.86 +112.87.159.115 +186.82.72.175 +79.222.103.245 +46.166.190.194 +98.142.66.58 +179.156.218.183 +83.11.145.235 +79.245.220.195 +69.167.27.161 +93.137.124.147 +62.74.23.12 +69.141.154.86 +24.212.93.93 +98.101.237.46 +110.33.102.160 +139.0.138.197 +68.193.116.202 +189.211.246.193 +178.184.15.205 +219.59.135.164 +95.244.96.56 +105.225.199.114 +79.50.98.29 +190.200.240.27 +113.139.79.149 +117.0.49.88 +25.116.244.128 +110.168.232.220 +83.39.115.25 +93.57.249.216 +128.177.161.144 +83.60.172.49 +179.222.224.108 +71.29.26.245 +186.88.241.210 +79.204.180.184 +81.250.220.127 +120.140.240.116 +177.229.231.37 +190.207.94.113 +93.126.80.151 +190.142.31.90 +125.37.77.218 +99.247.170.15 +77.49.79.137 +70.215.7.228 +106.142.47.247 +178.127.253.18 +62.1.143.44 +190.203.65.246 +84.19.169.226 +83.7.114.111 +77.247.26.208 +188.129.213.220 +82.26.34.42 +79.133.142.93 +27.55.88.115 +176.253.217.115 +222.162.108.144 +203.184.40.202 +113.254.170.32 +40.76.82.173 +182.187.37.119 +178.93.48.46 +178.43.52.150 +184.162.58.31 +108.113.101.175 +112.210.6.172 +188.26.139.30 +191.33.33.18 +176.9.61.40 +199.19.95.129 +109.212.168.135 +88.187.138.71 +109.161.79.178 +68.246.194.124 +52.78.91.225 +88.106.253.43 +112.67.211.172 +113.254.168.101 +75.82.44.230 +46.147.91.137 +125.24.120.47 +87.164.217.139 +86.85.128.100 +188.233.89.176 +92.11.183.52 +118.210.113.6 +110.32.157.40 +178.149.46.197 +71.53.159.168 +82.66.165.132 +2.176.144.177 +54.81.224.18 +217.235.230.186 +223.204.248.96 +100.68.117.31 +66.169.148.98 +217.253.220.162 +79.236.253.201 +92.101.105.71 +96.49.76.100 +46.159.209.64 +77.52.137.36 +95.174.112.11 +92.0.231.128 +87.146.4.127 +65.35.47.185 +82.66.165.132 +109.169.168.151 +63.121.62.186 +93.140.224.115 +194.169.217.249 +83.13.133.86 +139.192.129.75 +200.84.68.224 +91.148.97.130 +77.171.22.122 +83.220.237.57 +95.81.205.65 +216.151.183.78 +93.38.167.117 +36.86.162.114 +87.178.175.168 +188.250.136.112 +77.119.128.97 +94.185.135.34 +36.74.239.195 +79.184.207.254 +200.109.59.231 +190.62.157.176 +41.96.104.28 +219.91.159.9 +5.138.127.54 +151.236.242.23 +188.98.192.159 +173.189.163.1 +100.78.98.103 +70.197.7.158 +82.197.214.31 +210.129.18.130 +24.79.178.91 +121.99.160.130 +24.231.17.254 +109.111.140.19 +93.104.169.149 +178.120.23.138 +31.132.225.205 +190.205.222.49 +186.89.165.251 +92.80.200.73 +71.70.226.95 +174.71.32.244 +93.168.213.17 +69.167.31.117 +50.120.8.21 +79.192.251.34 +85.76.79.28 +125.37.83.89 +5.147.125.65 +76.97.173.104 +184.5.8.134 +79.245.206.72 +41.174.166.196 +86.147.224.64 +88.77.1.157 +89.242.139.28 +111.88.27.168 +171.25.193.78 +91.48.63.226 +84.55.21.255 +177.133.223.80 +188.162.36.4 +32.150.40.90 +36.70.48.210 +200.68.240.42 +191.33.43.183 +192.170.1.4 +79.203.87.39 +186.88.186.16 +5.14.194.114 +198.18.1.51 +186.85.1.164 +67.140.213.8 +171.4.81.119 +163.157.186.231 +93.196.163.77 +14.192.209.137 +190.205.167.52 +62.98.108.210 +61.213.121.42 +87.112.242.103 +108.61.228.25 +198.27.82.134 +50.156.104.49 +54.89.21.44 +217.89.11.177 +66.188.53.149 +181.75.40.195 +151.28.180.184 +178.207.224.252 +199.30.185.2 +79.245.212.85 +213.151.0.82 +178.85.54.148 +46.176.112.27 +70.209.74.11 +83.60.174.72 +190.68.183.200 +70.79.24.157 +73.143.120.108 +171.4.184.140 +70.34.11.21 +178.216.252.11 +100.66.131.190 +218.145.173.108 +67.182.199.251 +85.139.217.55 +89.70.28.135 +171.96.168.30 +82.5.92.215 +5.156.4.175 +83.26.89.42 +41.142.153.188 +179.186.112.199 +78.98.214.170 +1.204.253.80 +5.156.124.215 +212.123.185.93 +90.194.75.240 +187.34.136.203 +81.111.228.164 +81.11.206.102 +188.18.15.180 +193.92.20.93 +109.188.124.7 +79.198.114.37 +196.211.119.214 +104.157.242.132 +94.0.38.32 +0.0.0.0 +184.75.213.134 +31.162.81.207 +100.81.35.197 +205.237.183.36 +50.153.151.49 +190.9.240.216 +189.132.24.237 +86.146.123.80 +46.165.246.200 +83.31.57.52 +97.126.38.56 +186.79.241.103 +223.227.246.32 +77.248.84.5 +181.24.35.51 +188.246.40.2 +62.43.212.93 +82.230.65.12 +171.97.198.46 +96.44.122.48 +109.77.182.203 +188.69.199.38 +105.5.197.77 +86.16.176.137 +121.211.101.176 +41.251.220.194 +124.148.118.48 +82.25.176.33 +174.136.99.162 +213.118.105.27 +62.176.8.215 +176.87.121.247 +188.18.15.64 +86.178.211.193 +155.254.235.24 +151.238.52.50 +83.22.61.216 +46.59.37.170 +82.52.158.131 +80.236.209.219 +199.127.55.171 +125.72.37.70 +118.208.109.196 +68.231.74.249 +78.35.157.127 +36.76.55.94 +189.107.206.81 +113.96.32.121 +64.145.76.167 +62.98.25.89 +109.88.137.172 +114.215.108.16 +109.93.2.133 +128.204.198.23 +211.136.222.57 +172.90.124.116 +96.244.12.80 +0.0.0.0 +199.202.216.171 +104.200.154.26 +24.38.155.231 +31.183.14.233 +190.239.149.101 +179.198.47.220 +190.203.238.156 +41.246.51.68 +91.93.11.153 +179.32.69.248 +2.96.241.150 +110.168.232.50 +67.177.15.50 +67.163.146.87 +213.139.53.46 +190.201.109.99 +93.210.125.203 +74.4.219.215 +80.215.178.74 +197.202.209.134 +190.140.129.211 +93.86.136.126 +68.206.138.97 +112.198.77.135 +121.208.89.35 +95.73.190.107 +181.162.55.198 +82.158.241.150 +77.51.66.64 +188.29.164.228 +71.175.110.253 +85.135.211.80 +189.232.134.204 +179.187.89.14 +95.99.238.195 +77.203.119.51 +80.106.197.69 +91.8.193.111 +93.73.125.152 +79.198.45.189 +62.68.98.92 +50.72.250.47 +171.97.189.86 +99.197.33.146 +188.4.50.14 +78.9.156.172 +177.39.37.65 +207.119.76.66 +76.173.208.181 +85.179.173.80 +109.43.3.230 +91.115.187.17 +79.151.244.92 +173.189.160.37 +62.176.8.215 +84.147.126.42 +79.245.195.228 +91.178.224.89 +151.49.75.194 +188.162.37.26 +190.68.183.200 +209.107.204.89 +73.7.122.117 +94.216.217.158 +187.200.123.61 +91.124.21.30 +81.110.133.126 +95.86.239.138 +189.202.78.78 +83.220.237.57 +177.207.114.240 +186.14.129.137 +49.66.57.41 +178.95.214.246 +88.198.76.188 +213.152.162.181 +173.74.166.197 +5.42.95.250 +23.19.79.130 +5.167.79.226 +86.81.69.156 +105.227.167.3 +179.199.129.201 +95.71.22.141 +81.35.54.190 +87.169.122.230 +104.200.151.23 +178.58.206.162 +178.234.8.212 +213.7.17.74 +95.183.85.115 +109.79.107.129 +82.74.167.14 +37.113.168.28 +128.71.79.146 +24.246.57.236 +122.151.50.134 +188.234.26.113 +202.29.213.22 +212.251.28.139 +80.183.101.157 +120.156.32.20 +80.237.22.69 +1.204.248.148 +151.64.1.25 +204.178.113.252 +86.17.238.232 +172.68.96.165 +193.92.113.47 +5.238.230.34 +84.147.120.84 +24.151.99.148 +41.33.235.119 +181.118.72.21 +31.208.121.209 +5.79.74.140 +96.44.187.26 +173.238.86.61 +37.113.168.57 +109.121.19.193 +0.0.0.0 +119.251.82.139 +188.87.142.99 +180.183.183.229 +186.89.49.29 +93.194.71.58 +36.75.130.218 +193.254.34.162 +85.1.132.170 +175.137.91.173 +156.211.222.209 +70.196.132.183 +105.237.83.32 +2.97.164.235 +41.250.166.187 +84.99.129.92 +86.185.14.75 +178.212.100.247 +94.66.57.27 +212.228.253.143 +78.245.193.210 +79.67.123.101 +52.78.24.7 +188.77.55.46 +109.43.0.75 +151.226.78.106 +189.24.151.35 +86.166.52.98 +81.43.191.176 +178.137.216.239 +103.43.148.10 +177.96.213.99 +171.96.167.73 +84.226.234.132 +190.199.197.254 +78.21.226.145 +167.60.134.211 +37.45.88.70 +37.145.232.126 +71.93.59.159 +84.236.82.138 +70.200.190.164 +79.169.141.40 +84.251.165.229 +95.24.91.53 +86.212.111.166 +81.132.37.244 +73.180.109.228 +193.92.20.93 +79.245.214.184 +108.232.181.15 +109.165.42.43 +113.254.169.19 +110.202.66.220 +190.186.112.3 +97.90.183.17 +71.91.70.113 +130.180.216.24 +201.242.162.244 +172.56.4.34 +41.138.68.56 +60.231.48.88 +179.232.147.95 +109.77.153.128 +198.50.221.149 +2.85.51.232 +79.117.71.64 +103.199.41.194 +123.3.163.71 +197.202.107.125 +95.239.99.126 +71.63.37.224 +151.225.135.113 +64.62.201.17 +188.168.190.74 +109.149.126.247 +70.190.28.26 +93.143.248.105 +82.131.68.200 +108.204.67.22 +93.127.48.67 +36.228.6.80 +24.218.234.20 +2.12.244.159 +223.207.119.134 +112.202.50.229 +203.206.89.35 +188.78.186.212 +178.234.246.44 +74.90.209.198 +201.208.98.13 +176.113.149.173 +176.84.26.59 +92.40.250.84 +217.249.1.121 +130.43.60.40 +104.157.135.129 +79.45.233.9 +151.236.241.194 +124.171.173.162 +5.139.222.77 +107.11.145.246 +109.43.1.135 +110.168.232.79 +85.178.193.205 +178.54.197.81 +122.104.159.157 +201.173.65.201 +76.64.18.82 +66.87.99.2 +125.24.120.37 +184.171.222.88 +5.135.108.204 +37.212.160.109 +67.80.146.83 +37.136.202.241 +31.10.148.162 +91.158.213.79 +206.222.164.91 +110.168.231.168 +104.207.136.107 +223.92.214.153 +199.241.147.35 +46.146.115.38 +250.31.16.246 +74.90.154.237 +177.240.12.199 +31.54.71.64 +42.61.252.62 +186.88.92.44 +50.124.59.224 +186.95.36.43 +199.48.242.61 +2.28.195.45 +109.227.38.172 +152.7.72.48 +186.92.248.179 +118.223.43.61 +89.78.254.207 +165.84.8.160 +178.64.4.120 +180.183.183.229 +190.66.153.127 +89.254.209.164 +212.21.25.27 +103.27.223.89 +206.248.163.100 +179.55.32.8 +83.30.209.69 +220.246.221.83 +188.108.111.118 +5.165.135.90 +91.63.19.8 +202.62.17.207 +91.7.22.201 +37.213.70.95 +42.2.227.111 +105.107.80.212 +67.162.167.86 +73.38.48.239 +220.85.248.156 +2.121.34.225 +50.120.10.162 +125.24.101.151 +201.209.130.155 +70.89.34.105 +142.161.114.127 +118.137.28.43 +110.184.11.142 +95.145.103.125 +73.211.90.130 +24.208.186.109 +197.203.5.205 +171.97.145.198 +14.186.213.191 +81.48.238.194 +70.174.30.142 +178.0.63.141 +120.180.45.219 +193.92.100.197 +2.99.34.210 +223.203.188.130 +178.157.238.33 +75.111.215.8 +84.236.59.214 +197.5.13.228 +188.245.241.79 +50.180.178.143 +78.169.234.167 +37.229.91.183 +91.237.77.7 +93.39.91.238 +88.25.138.131 +205.251.171.136 +1.0.0.0 +199.48.242.8 +178.43.58.190 +188.0.43.233 +5.140.202.3 +103.255.4.64 +46.46.208.61 +83.112.210.21 +0.0.0.0 +108.252.149.152 +46.185.48.82 +79.245.214.13 +123.63.112.110 +188.163.24.131 +178.45.76.81 +79.245.215.231 +95.236.129.178 +98.194.215.103 +37.78.85.207 +92.208.67.183 +72.60.12.140 +14.148.46.127 +201.29.97.210 +190.74.248.142 +120.59.90.202 +24.96.26.254 +85.244.118.150 +120.56.109.97 +201.210.10.223 +86.197.21.97 +195.37.133.6 +142.217.6.115 +75.142.1.84 +84.236.15.97 +41.96.38.253 +74.76.194.100 +107.191.46.128 +39.48.27.86 +86.70.223.212 +109.188.124.120 +171.96.167.186 +186.89.53.167 +95.24.235.213 +41.249.53.17 +14.213.195.165 +187.247.107.215 +188.223.250.197 +70.169.113.9 +77.231.219.47 +187.56.144.147 +166.137.246.16 +131.255.112.182 +97.127.74.43 +124.150.98.24 +110.168.231.182 +5.70.77.193 +2.85.58.108 +192.100.100.115 +212.90.62.251 +104.156.228.108 +222.228.188.6 +174.71.57.33 +117.200.205.85 +100.2.255.15 +91.61.93.48 +79.64.148.127 +141.237.243.236 +166.189.91.121 +91.44.232.13 +0.0.126.218 +217.235.240.122 +81.156.118.97 +91.127.16.235 +208.107.146.195 +188.159.173.160 +76.99.37.97 +190.38.186.76 +108.65.186.145 +42.112.94.187 +66.85.174.122 +178.120.157.184 +176.65.127.87 +182.182.109.245 +93.152.158.179 +188.69.196.255 +179.232.244.239 +78.51.17.255 +69.167.51.243 +172.79.72.216 +77.243.189.253 +83.149.45.42 +183.18.201.7 +54.172.149.177 +37.188.132.154 +79.245.220.203 +76.181.177.144 +198.8.80.218 +92.20.112.174 +90.181.200.180 +84.179.243.107 +36.77.18.75 +88.137.75.34 +5.141.203.27 +130.25.45.30 +109.147.94.141 +89.142.2.248 +80.39.236.96 +92.127.119.0 +82.18.233.59 +87.244.147.84 +202.62.17.151 +78.13.82.80 +91.182.134.93 +128.72.123.20 +89.245.109.97 +82.56.79.206 +178.162.217.130 +68.207.37.135 +77.48.31.3 +231.210.83.146 +79.204.139.188 +83.44.53.138 +60.205.112.102 +95.127.152.2 +85.113.39.64 +2.24.125.125 +88.206.141.108 +94.181.67.148 +62.113.206.249 +79.146.106.66 +195.238.101.211 +108.21.116.66 +79.70.51.138 +69.231.35.237 +217.235.237.26 +94.191.185.252 +85.51.145.189 +109.144.227.143 +71.238.202.231 +202.62.17.66 +87.189.140.13 +110.149.119.241 +99.241.126.136 +79.170.89.58 +190.36.92.202 +81.35.251.152 +186.183.180.97 +124.162.30.45 +94.64.205.245 +89.153.1.213 +77.67.46.89 +68.96.181.142 +68.101.63.60 +24.114.69.36 +171.96.171.253 +171.39.69.171 +216.244.74.178 +194.105.229.207 +83.245.240.17 +5.138.144.189 +216.151.184.103 +86.147.74.55 +46.254.11.158 +178.128.206.129 +59.57.222.232 +86.138.235.114 +84.161.253.213 +5.80.234.3 +45.32.232.66 +81.17.19.34 +2.187.200.29 +104.200.151.43 +188.18.15.195 +93.170.97.98 +171.7.219.199 +46.254.132.34 +31.10.148.162 +109.121.47.80 +192.99.62.23 +88.12.142.229 +5.42.77.196 +79.204.167.160 +184.151.61.218 +46.130.27.222 +5.12.220.50 +80.121.61.68 +184.97.246.75 +142.217.180.205 +117.84.187.192 +77.89.225.54 +188.113.168.4 +213.57.182.69 +179.26.100.83 +95.153.135.34 +93.169.30.86 +62.183.125.159 +196.224.51.163 +197.202.232.7 +2.121.188.157 +124.168.83.112 +84.154.93.193 +190.22.162.98 +188.77.145.114 +97.127.2.214 +151.16.21.252 +218.205.21.202 +82.19.92.224 +113.165.165.184 +188.82.75.227 +111.69.240.177 +2.62.37.83 +217.118.81.30 +96.46.203.225 +79.245.217.227 +223.204.241.22 +213.152.161.40 +62.68.119.27 +128.90.88.220 +93.208.114.181 +173.210.233.18 +90.214.193.0 +92.98.76.210 +59.172.143.195 +108.61.229.10 +92.147.156.172 +25.16.26.157 +95.46.98.50 +182.111.195.163 +92.246.191.31 +5.63.147.132 +189.179.175.181 +79.245.200.104 +31.6.57.80 +89.217.242.69 +188.73.192.62 +77.51.144.205 +201.209.91.12 +50.38.84.70 +68.252.8.213 +178.213.170.179 +88.169.104.241 +217.112.161.55 +190.21.155.130 +83.52.87.240 +186.116.227.215 +60.225.188.206 +183.39.64.25 +91.69.121.77 +112.111.128.3 +120.209.131.70 +65.129.56.69 +178.189.173.49 +24.0.101.211 +177.16.116.101 +92.134.34.180 +91.154.8.178 +186.82.153.43 +115.79.48.153 +197.229.46.7 +179.156.218.183 +90.29.101.248 +67.193.56.206 +77.57.13.122 +24.116.122.179 +50.46.213.211 +85.0.236.97 +5.28.20.179 +178.162.217.147 +100.71.65.247 +113.254.170.11 +95.17.250.151 +87.15.170.241 +179.222.224.235 +50.101.183.116 +190.77.90.242 +91.127.16.235 +89.143.141.4 +109.251.79.19 +77.168.163.194 +234.143.150.203 +212.183.107.208 +95.114.37.41 +171.149.79.56 +187.202.8.56 +118.90.37.15 +93.130.56.37 +222.164.214.15 +89.151.173.209 +108.20.213.143 +2.221.74.97 +117.207.5.212 +158.69.31.40 +95.21.79.107 +117.7.167.41 +58.182.120.211 +98.160.114.23 +85.76.68.236 +219.79.254.117 +84.52.183.80 +2.85.65.201 +188.82.231.177 +67.234.49.71 +81.157.210.221 +166.170.14.79 +95.236.128.89 +180.140.28.245 +188.36.48.170 +37.146.123.170 +79.245.204.42 +67.136.44.155 +2.31.43.78 +174.65.11.157 +50.203.141.242 +213.22.179.152 +109.205.253.56 +64.237.37.123 +75.140.152.181 +93.138.85.114 +188.107.62.61 +217.71.45.215 +61.195.99.101 +71.212.232.185 +152.234.187.32 +60.225.156.149 +72.38.6.170 +41.142.207.223 +82.27.233.79 +104.207.136.113 +184.151.61.186 +1.0.0.0 +86.31.57.106 +212.67.170.226 +99.229.64.113 +82.34.93.93 +88.78.18.175 +25.91.19.207 +184.75.213.133 +86.73.39.118 +78.207.218.25 +197.210.173.38 +24.45.172.109 +115.70.4.78 +37.24.154.229 +97.86.255.96 +188.166.147.168 +104.238.169.131 +84.133.115.69 +83.213.55.195 +73.52.242.44 +85.23.98.164 +167.133.202.239 +86.19.150.145 +124.122.109.4 +87.204.157.2 +49.145.71.12 +31.10.149.218 +88.254.126.246 +178.62.145.250 +73.203.113.197 +25.152.243.103 +50.46.245.151 +78.53.136.141 +178.195.56.130 +188.101.231.41 +81.157.210.186 +73.40.221.24 +105.184.10.230 +125.69.38.6 +109.157.141.252 +41.150.128.219 +79.117.53.240 +183.165.136.45 +66.76.255.133 +177.99.84.95 +88.22.86.253 +107.152.98.157 +186.79.38.60 +68.198.99.74 +67.71.36.206 +50.153.149.36 +78.26.188.205 +192.0.144.103 +213.7.32.192 +87.158.143.162 +2.62.52.177 +186.92.255.117 +151.249.96.73 +190.38.23.220 +107.170.172.93 +151.238.198.76 +72.174.209.234 +105.228.121.62 +86.31.128.135 +2.85.59.104 +187.170.157.129 +189.149.6.216 +94.66.57.230 +201.243.226.15 +112.215.123.37 +177.5.76.109 +37.24.158.191 +197.87.208.47 +117.194.54.107 +171.39.68.129 +186.89.83.70 +50.88.40.168 +92.124.8.63 +190.207.194.163 +120.195.96.242 +188.222.36.28 +135.23.90.208 +121.35.17.81 +253.167.138.14 +179.212.185.123 +176.8.179.202 +179.55.36.161 +181.208.26.200 +177.148.198.206 +151.95.16.217 +75.197.252.114 +37.188.229.58 +78.111.190.161 +190.36.128.114 +70.54.86.241 +189.157.4.253 +85.114.175.186 +84.104.98.246 +194.19.240.109 +84.196.100.202 +46.246.150.244 +123.138.32.232 +201.141.33.181 +88.207.220.253 +93.138.19.90 +113.225.18.114 +46.142.50.74 +120.173.14.19 +93.107.13.106 +176.84.165.12 +2.103.0.246 +62.205.123.238 +100.100.113.173 +79.251.9.3 +84.177.180.24 +18.111.126.201 +81.51.251.96 +112.198.77.197 +78.21.38.182 +217.105.20.145 +107.191.56.184 +36.236.88.233 +105.226.169.107 +89.168.6.239 +250.31.16.246 +125.125.36.49 +104.156.228.152 +94.254.224.32 +109.221.204.226 +84.216.199.63 +94.137.218.19 +84.181.239.37 +84.25.136.77 +109.43.2.140 +79.245.208.163 +75.159.1.100 +181.121.80.135 +85.102.227.198 +79.245.194.135 +178.1.153.222 +113.243.203.175 +188.146.70.112 +98.167.22.186 +178.42.44.41 +75.159.1.100 +178.1.24.241 +110.168.231.134 +89.99.193.144 +49.181.182.80 +91.179.166.223 +110.168.232.249 +98.117.192.12 +123.67.81.131 +0.0.0.2 +37.54.21.113 +162.216.46.35 +95.139.206.250 +160.76.210.181 +80.107.16.52 +92.148.52.184 +109.201.154.189 +65.158.198.6 +92.144.208.168 +223.204.250.55 +2.85.179.46 +87.123.106.67 +108.252.164.33 +109.182.189.41 +207.164.79.45 +173.29.144.124 +185.3.135.178 +94.145.151.183 +49.195.99.89 +87.185.13.113 +47.17.155.157 +118.136.158.190 +68.118.145.246 +86.194.143.131 +37.48.86.160 +83.100.202.42 +95.153.130.116 +24.189.254.177 +107.191.32.198 +219.88.65.49 +182.165.47.108 +103.238.131.9 +176.65.127.10 +71.179.109.158 +84.198.176.240 +71.34.71.125 +81.18.49.210 +185.104.214.53 +46.59.177.107 +177.96.135.126 +68.4.154.250 +212.115.253.74 +78.96.117.209 +200.164.98.231 +81.37.241.98 +60.240.54.44 +31.10.151.14 +65.112.8.201 +36.77.59.253 +200.77.107.132 +188.73.192.47 +216.177.129.122 +70.213.5.94 +94.205.1.88 +189.165.50.103 +84.19.166.58 +178.43.50.78 +92.37.17.206 +31.17.255.251 +212.72.144.126 +212.251.18.47 +105.156.14.51 +174.98.201.21 +112.102.44.158 +114.96.28.171 +174.50.176.242 +193.161.15.76 +128.75.199.166 +87.111.6.35 +86.148.36.53 +66.115.130.122 +177.134.174.140 +37.190.51.8 +109.43.1.168 +108.61.50.107 +37.24.158.147 +171.149.2.249 +141.237.253.19 +79.208.102.36 +213.122.124.131 +87.109.16.70 +177.81.235.242 +95.183.85.115 +5.156.133.110 +37.75.166.253 +189.83.228.101 +82.249.77.22 +92.26.77.28 +92.110.97.56 +36.255.113.156 +93.141.39.214 +200.82.195.152 +130.43.53.14 +186.167.32.27 +46.0.46.61 +177.11.141.37 +71.209.2.107 +177.9.79.75 +83.11.239.209 +114.244.45.88 +75.117.39.181 +186.79.30.137 +46.158.242.81 +2.127.225.136 +202.62.16.49 +85.26.241.7 +151.15.56.129 +24.98.68.43 +190.73.253.30 +208.54.64.211 +23.99.90.8 +84.6.62.25 +177.229.41.202 +80.202.76.7 +201.19.191.32 +5.79.74.235 +37.140.14.92 +121.45.198.248 +202.62.16.168 +87.152.195.142 +183.12.166.251 +95.18.60.88 +60.50.60.169 +138.201.65.88 +72.173.141.238 +83.4.184.111 +98.225.134.65 +191.33.23.113 +200.8.77.51 +170.215.41.19 +83.60.174.72 +176.11.151.238 +98.100.240.64 +213.151.0.38 +156.57.77.35 +83.30.246.219 +199.193.119.32 +176.82.69.50 +95.135.90.160 +155.138.230.18 +70.106.182.230 +79.67.199.149 +95.84.130.70 +181.16.74.62 +71.175.110.253 +87.113.166.62 +86.127.154.130 +108.26.55.253 +36.83.55.86 +189.156.67.120 +72.39.10.246 +87.117.9.241 +69.80.100.38 +100.100.0.49 +174.19.164.170 +213.49.92.12 +80.83.238.50 +100.68.67.248 +207.191.212.133 +79.245.218.167 +195.154.168.236 +122.49.137.82 +186.118.34.106 +46.19.97.206 +190.204.35.44 +116.210.115.55 +70.196.193.231 +86.61.8.196 +139.192.136.198 +89.180.26.30 +178.42.43.193 +177.107.242.133 +68.119.227.133 +91.48.37.22 +81.24.212.14 +190.200.114.238 +70.173.239.125 +186.46.226.17 +95.17.250.32 +77.248.0.110 +101.114.75.142 +91.61.71.110 +62.87.146.101 +78.88.29.1 +119.224.86.171 +37.54.65.152 +193.92.188.195 +98.157.39.248 +83.87.161.55 +92.19.38.229 +115.188.90.227 +178.184.16.210 +2.62.56.197 +91.226.57.133 +188.29.164.13 +70.208.137.58 +109.227.1.38 +117.192.218.30 +70.30.52.78 +88.19.208.245 +151.25.236.22 +37.113.168.102 +178.115.131.56 +96.225.143.105 +110.159.31.31 +185.50.48.82 +197.5.8.74 +84.222.70.181 +201.83.108.195 +41.130.120.57 +122.195.1.91 +146.160.55.12 +172.78.212.255 +64.145.94.121 +50.48.190.138 +78.129.221.48 +88.200.137.188 +111.241.99.206 +81.158.30.57 +190.183.117.23 +92.238.165.41 +178.62.243.138 +50.46.208.60 +1.144.96.234 +1.129.96.155 +78.90.220.111 +91.48.48.168 +24.253.205.115 +187.143.59.112 +186.14.128.205 +187.56.154.88 +171.97.201.79 +178.254.185.195 +92.246.211.241 +128.72.238.171 +96.240.81.144 +89.212.48.17 +185.9.62.204 +110.77.225.169 +24.119.39.222 +85.76.115.206 +172.56.15.181 +88.83.169.175 +36.77.55.167 +84.19.165.213 +37.146.191.103 +37.146.77.45 +188.77.156.44 +173.74.166.197 +86.212.4.36 +189.114.205.176 +79.204.147.215 +79.192.207.150 +193.167.1.101 +202.62.17.0 +179.7.219.137 +1.0.0.0 +2.182.206.105 +62.74.23.241 +176.14.89.40 +99.228.124.143 +142.0.134.7 +176.31.53.252 +24.57.236.248 +79.218.14.76 +70.75.192.84 +87.143.228.125 +85.178.89.74 +82.129.188.193 +68.99.85.75 +47.55.212.189 +111.240.207.209 +24.114.64.51 +37.78.112.147 +98.167.118.75 +79.206.175.208 +197.202.255.157 +189.5.55.70 +218.59.140.116 +58.178.1.156 +81.82.161.242 +186.87.101.123 +217.122.16.169 +125.253.100.213 +87.113.152.249 +104.156.228.100 +31.54.228.197 +212.54.196.165 +101.160.17.69 +80.213.10.20 +66.102.133.150 +188.146.72.127 +64.233.245.39 +154.5.159.216 +210.55.212.38 +176.193.156.136 +94.23.213.47 +213.229.235.159 +113.91.239.76 +88.237.179.137 +25.161.124.26 +83.23.227.159 +5.63.147.100 +220.76.226.249 +147.86.207.1 +50.168.103.161 +176.65.127.119 +95.30.21.96 +193.92.113.47 +25.20.113.106 +112.37.27.20 +176.209.243.162 +95.211.212.195 +58.8.154.35 +94.181.34.121 +174.70.46.51 +172.56.32.22 +178.255.69.59 +92.48.112.74 +36.69.21.247 +187.189.254.189 +212.26.187.40 +183.12.164.74 +95.145.103.119 +93.113.244.166 +143.176.138.223 +109.192.225.106 +46.249.59.220 +95.211.188.25 +18.111.102.54 +178.184.26.58 +187.188.14.229 +46.130.12.191 +91.105.92.239 +95.215.156.54 +2.240.16.118 +46.217.85.84 +46.10.123.227 +108.84.14.1 +178.198.242.133 +2.223.51.94 +18.111.109.172 +71.100.135.84 +85.75.79.133 +217.118.79.46 +202.62.16.34 +2.248.159.250 +13.93.150.42 +77.98.223.82 +75.117.202.183 +151.72.136.1 +50.153.150.144 +109.93.159.179 +58.8.154.35 +192.95.32.112 +37.140.17.102 +62.87.191.182 +80.135.239.44 +112.198.103.161 +199.48.243.62 +5.248.192.239 +186.94.109.177 +118.140.106.58 +93.138.115.72 +172.111.156.67 +109.210.209.73 +213.21.47.192 +85.99.37.229 +37.229.184.145 +64.150.245.177 +95.89.215.8 +209.93.154.77 +45.56.108.177 +78.37.253.157 +116.252.202.50 +82.237.87.66 +79.208.99.94 +109.93.237.13 +95.84.130.70 +50.153.150.252 +109.93.229.2 +74.110.18.17 +223.73.103.231 +1.151.121.137 +188.17.192.99 +216.231.140.113 +83.153.141.90 +49.49.35.156 +105.227.35.18 +176.152.32.37 +95.114.2.51 +79.136.64.123 +173.34.203.76 +109.43.2.115 +50.132.197.203 +105.225.29.41 +188.222.188.84 +178.120.161.243 +78.21.195.37 +43.165.193.4 +79.245.209.189 +182.39.244.18 +117.231.147.111 +188.69.196.84 +68.195.171.102 +95.232.80.9 +46.55.162.158 +125.162.110.180 +46.189.28.35 +83.5.182.110 +5.138.219.104 +31.44.183.14 +92.37.143.70 +83.149.45.208 +37.146.123.156 +107.170.90.53 +69.178.106.243 +77.105.61.201 +98.227.60.68 +100.90.0.219 +69.80.98.175 +181.95.86.188 +94.209.34.7 +168.1.6.18 +5.141.221.248 +79.50.98.29 +2.101.114.120 +67.63.55.34 +79.245.208.90 +31.132.225.153 +109.88.143.236 +186.83.12.194 +87.96.161.171 +81.162.122.102 +148.198.187.141 +70.89.142.142 +82.227.229.180 +94.180.197.48 +76.170.53.72 +198.252.123.121 +82.139.112.23 +178.65.220.234 +112.111.83.41 +79.208.119.139 +84.196.55.99 +169.1.121.116 +212.112.150.250 +55.134.238.99 +112.67.211.172 +5.141.221.96 +69.7.90.64 +108.61.196.218 +109.121.21.84 +95.103.165.22 +75.151.200.156 +163.172.137.241 +178.49.192.105 +83.16.104.70 +104.238.134.31 +184.43.40.204 +152.78.156.223 +62.158.145.34 +81.11.198.166 +107.191.32.195 +5.14.202.22 +77.253.40.105 +37.205.63.243 +178.234.31.36 +81.240.219.181 +91.214.131.89 +79.200.67.185 +5.175.208.124 +2.139.127.149 +2.62.14.71 +79.204.144.230 +98.207.141.82 +197.37.183.200 +25.69.38.113 +5.82.242.101 +82.141.118.195 +203.206.37.169 +108.53.251.199 +186.35.252.4 +141.255.15.154 +72.202.146.227 +186.188.89.194 +68.111.91.91 +188.67.72.26 +90.131.191.120 +94.21.162.25 +187.230.36.79 +5.81.250.60 +89.212.99.205 +87.245.50.14 +194.44.207.38 +109.111.243.109 +202.62.17.19 +198.8.80.164 +190.139.245.143 +209.202.7.202 +68.204.242.231 +92.28.233.187 +201.29.108.171 +36.77.19.108 +99.4.120.232 +78.85.5.166 +217.88.3.79 +180.252.111.99 +2.99.213.60 +68.118.69.220 +80.41.226.120 +5.143.190.221 +0.0.0.0 +89.254.225.194 +191.184.26.86 +122.82.164.84 +69.143.54.161 +78.43.172.91 +89.240.86.71 +110.166.247.71 +213.151.0.135 +71.229.244.243 +188.16.237.62 +93.204.234.163 +173.230.77.55 +68.169.143.146 +217.14.178.36 +95.211.184.197 +81.157.210.221 +37.14.20.75 +86.135.18.75 +100.88.8.110 +152.115.56.228 +79.133.144.79 +93.143.193.80 +77.49.142.238 +188.18.14.171 +151.250.50.227 +24.54.240.178 +201.29.103.139 +71.7.113.19 +122.82.1.124 +106.69.14.251 +202.159.132.94 +50.35.92.164 +115.229.86.166 +176.115.8.183 +109.165.42.43 +24.122.223.250 +201.243.107.40 +41.224.171.232 +88.27.211.144 +173.182.128.9 +95.46.98.50 +85.155.6.145 +77.243.183.116 +151.238.36.143 +58.174.48.97 +216.186.236.171 +79.245.215.220 +192.198.202.218 +101.39.46.97 +181.25.4.150 +94.197.120.56 +173.221.226.116 +188.54.228.4 +176.109.8.50 +92.133.138.44 +31.162.230.126 +37.190.51.1 +71.83.111.138 +97.88.161.169 +178.47.182.195 +85.59.90.160 +95.55.43.88 +121.219.36.217 +72.213.26.102 +201.248.113.36 +25.80.14.76 +91.48.44.193 +212.251.18.47 +177.39.36.104 +174.35.172.33 +82.39.255.68 +190.22.239.126 +65.94.153.250 +107.170.198.224 +2.234.147.237 +5.151.152.147 +179.55.35.142 +67.174.42.236 +46.229.173.231 +14.192.212.169 +94.69.53.0 +31.23.81.184 +105.1.203.194 +79.20.35.156 +188.78.64.145 +92.241.152.111 +90.255.187.231 +190.38.39.114 +187.223.48.111 +201.29.103.127 +46.142.44.83 +5.43.176.207 +84.18.235.14 +87.185.2.181 +186.66.52.24 +89.153.94.121 +202.67.37.42 +213.151.3.243 +110.17.0.246 +45.32.129.168 +108.204.225.33 +31.11.93.241 +197.7.35.83 +86.173.80.107 +100.68.86.132 +200.75.242.225 +151.95.16.217 diff --git a/iguana/confs/DOGE_hdrs.txt b/iguana/confs/DOGE_hdrs.txt new file mode 100644 index 000000000..96544eeb4 --- /dev/null +++ b/iguana/confs/DOGE_hdrs.txt @@ -0,0 +1,675 @@ +1346002 +0 1a91e3dace36e2be3bf030a65679fe821aa1d6ef92e7c9902eb318182c355691 b882d64c2dd006da91a7c1e650b4f85c2c8aeccdb76ff4097e29749fb79ef9f7 82bc68038f6034c0596b6e313729793a887fded6e92a31fbdf70863f89d9bea2 +2000 82be6036bcb42cd08e5b0e8f792506f5bbf9b3e1d91f23135a9af7b45944cc0a d374be146e2a8bc642ef4ca37b9284728ef3546c3b2bdfe205db9eeaa4f8a5d2 a3dc0c03e4ef9da6cad7368a52745334ad600fb688a701152e71a20520a0be04 +4000 0ef21338533aa9937d0e0294d1b8694c31a16c4231d4c685c7e09429c8bc827e 9699a1b3f2973405d59451db8d3ccef0c9151fc65b6dba94a7f61e7f5d122dc7 378633503198d86f53a1ef5a744dd74eba3a49cf3c5211c6e18070ceb5bcc527 +6000 abdde162c2e54c80948c5395a39f6ca239ae3a0763bf9efbc85a85d01477b1fc 6b272578e7105129e65fe120eb020a5cdd45d49213fcfa428f14096b0ba86111 a63da5ccd2b5cc560cd4c8c437bb25ff16c0e7cd3d10067ee8502fc52c3044cd +8000 10ce57dc3dfbea4dbfe4a371a7765b01400e3f12732c260d34e672ee5ba715be b4d8c73ac5affe1b2a28296d3b286e3e628bfef822d2dfe3c9feea6dc3f02387 7461aab806b41c4286a4408957b977f3a20cf8bbc7c25f0ed0ef5fe04af6611b +10000 df22f3865880940c9435f778887c2206cb43f93c0f70ebc9bb0ccc8cf994c631 fcc13cc65a23473c3addeeac19963b3333628f86202ddf4ec751f4e34656d2cd c1a2df7f2a4c60ec4da3346695825fa97e3078b32d810c460c9e817d0f38fda8 +12000 dd532b899cd5d9fa59304ba45216b81bb259fea548e1b3ceffaeebc59409cddf 71f4549aa5d38979c516f3f779451ba0cbae417f8810b4dc988737ab16397c95 0a58b4ddcc0ebc40e1df699bf0ecb8a3793f691eb6a7887ac973e55431c74e9c +14000 65194ad19c4657339b40759b80679e41f1328729e202812beb227260604ca5e8 c71f0882c30c73ea51a1a34ffc1e3605b48d65cd5e753c5bda63291a20bb54aa 964f9c59503c4ed09e5a2d26e17698b0bf971a6e8f3c65d02d6de319c37f1e89 +16000 f475bda5aec5194f05743f1e0e3984fee27438374927154a1af13a15620fa9c0 2ad3c1a0d2bbb5f686a98c8683399efdce3cf5a26e4c6b889ba5736d01ae69ea 12af604f4f1f1e53e24e230b7fe3f3b17fb3fcecb8290c252f8b0f34dbbc1a1c +18000 6345ff6cdddc378fa3a0f4e7e0f3c7de131672ae71976d1407d0f4c8cf3b7ec3 0531e372e009687f32063d5b350dbbce2ef054a73cfdc50bbd215ef66909b3b1 0b52da0f5e8ecd8ff6f1e2f1c7494b50e61533f9f1b735b35b5c6a07737d36a5 +20000 c6666c2809f048a56a0edcfcd063db0634e87d6b478e51ac984fe05fc5cbcc3f 3b3ea2dfcea96e085279dbb515a11bdf6318ff3a5ff252cfddd84cdc95637754 8820bee31da255841f3a5e0b5b37532fcdedf46ef07be08fa2626988fd70bc63 +22000 d1b780428ea0be1e987b9e539ab8a0a93d466d6ad48561a65aadeac0df9bc23f 31c8bdfb3b97825b4746679e6816da93c02f0faed8adf2b81e5b80f52c7936b3 de714b4d57f46f14e271193691e6907c5c46b57124c303ff40b18737d5f55d5e +24000 001e7bc546ec6e480c72555b1eadc0d8ffbae698a2252da815e79e349ce50254 16528e197315fec3ceb9ed29396418ba8dd1d09c664e60a458a7303a2e21c9fa 177e30e7d7bfed75d75e5bd0a98d1e34ecfc66ae8797790a005bf6484cc0d497 +26000 e517dc97ef4190c54c4085bb4f15c8247855a57c07bcac0b21c748f9fca45d93 ef7561a2cc0783fc068728809f33dd6b826beb7caa2302b2c5994147a32261d8 02651ab1b31758828a70bb04c405b4673fb0113634ae7c3d4888cd88fc6fc864 +28000 65ef173c81a7bfea8223b8818ac5bc2d61f56db93f017f418f3c981e7e998f8b 6444c0f8041e281bee41c94b0246d0285b5d0dfed5105c47dd90f0b35b73fdf6 cfb1e296214cb9b87d22ec392f49c91ee0b1eec8728e4a00d14bcbf2ab549df4 +30000 af3a3b47559ff99e78cdb125dee11cf0def1460d437363c05b3f0e690a256e39 c23b7ebf4053f3abc90ecae9ad50b2c3e1f2f840caa4bd8b44e5acbd71dc0e91 39d8bb1676e5feb64f4c5bf9ca73de3fd9ef0be29533fad47ef64c9b22b248eb +32000 4ec72ac68e11bab88ed68c613a84eab5304ce85cf610ff680c7ea4511eae7b28 73f7b0103d6e1af5bd6936fd13676df4e4197bdc02b9de2ad63f0442195b16fa c43117257b6d756362de3ad11d2bfadc9aff38d6008f24a53191f73f5e7b3917 +34000 911adb9e16e5fe8a1c9269825209a620274661e20f9fc1d311bee19aabe2fd66 108a11cbc77c7f74e8b5ab2c00b752189955d50f131b4a4eed5c382ac68850ed 0f51817c3c9e0c01ab145905bdd38af51dab975abd94009a441329b97f689ce7 +36000 f61b7f0aec19e4b7be616c3cecff6b7eb7d137c2418bed1c3f66dab13d76a6d1 14e3ed9498baa8e0919b2a976c852a0ad1979683fc1f8f52e954d2f7287d9884 a577e9a4d15636e2f7f53927fbd98c43de672fa87051c043ed4c9e4fccda8a20 +38000 a2a5c0fe79c15d0748fd5bd288a10ded030f547d8b5d7d26fa9359e84fb54fb7 6d60375ad7d2f9dd1b661160a26ac59405328ac95e8d3f50d6cd76774074b8a3 bd49f2f2fa31cbeb053ccfbac46151f836147f868f1fda5fa1e972a97c272cd8 +40000 d212758f0b5310bbfd025fe8697cc4dba008afc06c53f78f899b274d284110ed 7cb6f2ae7b5203fe3de36f254ce557c472f5e935901c0dcb99ad99f0646f9d73 7b95d948fff02e1d446c4db5c1396f63ead85a205db18da234614ede237f63cb +42000 3c6142a4b2f848ed91931010f86255e79a7a3919f4c7cd8986333f05d72cfc02 eb176cda2f179e404152b1aed3d77e12bb6357a61ab7de41cb791582c7b93694 c623e7dd01d362eda7b6f183640487507b9ba9be262a62617916615011a4cf33 +44000 2e363c3ac026ee4da862d95a1db4252b6dda45e762e89b1ccc31abd6024aa478 7cb467c84fa4139d6e91e114878fc04618fc23f0941978594924b2fb5c1daa69 c95cc239a30fe9d955733ff5b4e7afc0972a6fdc0eb1ad8a63b8fbb8af715f9b +46000 fce28bd8bc928b484105396c7853a04f2b08895d0b951c25825bf5343a36a806 ecbb5333f6e69c8f697240b023cb8b54a768ff8953a7e18437fcce144e5d4583 4b1d470bcb36ef3d5a1701131825dc1d0525ccc683623c2b047edd7df23bfa84 +48000 8cf4d158f62993209907f0c62ed2064d6b1a61eb5d9db8f45964b0bea132b7bf d66250951f15d040b3ddd5ab1b5aeccbc7ac3b0617a3974711a1b669e33baf7f 3e44624b76d487466382fbeb1dde7326ae018841921a2fc7d8def30bc2aa59ff +50000 e4cab588a33147a217c8bc2f923fcd1f642fde26c7c797a5c2c4808c4c617a7e f063eb047f37a5df20bdfc82cc1c83e17521725f8a6ecfd381f15e9c194d01a7 616c39b41068fbc9bcf152d76cf888c8b6ecc9582ca351ce1b7fb01d963613d0 +52000 780c3317aacc7293c3522729d33afcbf79e6846cc6f7ad5aec1b04ee2eec26b8 a2e22f41358032363d895547a320e3e0f07e735157dd5095ecb15ebe02c7acf6 dd3cd243bcdeff46e357ef1472068ffe210dd5dda9053b3c053b91e181422917 +54000 5c955a95b39e23926171b57a1aeecf4d5a4d1b8dae7428d4ad6fc1977990a464 777d610b8aee1cb96c0d445e3b2a9c4779067b1ba25d70dac19b71afd4b44199 993f2a52b64c4627e5eecccd908b92a51541a59f39824a30caf37247b5814df0 +56000 b6b54c1dd6ebf853ea6fdc82e5a696ec4ba5b886b1a0aeecc7517cb47e550849 a80fa37a6e13da6844962357fe7236528680ff78288f629d5f79e16481396e6c 50078d51b1a9c205cc37d6062da3fd126f8512108adafac99b6560bbc094cdf6 +58000 3fdb0f50cda1721b9acb0913ab38185108b1cb403df22ade90bf0873f746db8a 59a405c8d38d2efb3c128ced9bcb18a5d5820ec7e111e531c2213999a98f90b6 4f5115af207ea2c7702a232609588c3c77277d6204e13c8fb9676821dfe45823 +60000 dd2ee5e997165d0122bed7e097465ede1c48fdf526a6cbc1b5cd5ba4b588072a aea0cbbc83ba767ee8a8b75fbde9d52146f96bc5744048209e1e5a65b4dd4f10 d8035dd7cbe69b005b81d893e0aacdbf58c2044e930a8201ec0c5d138d153ba8 +62000 c30db1b575ff2105d798f4c90f208fc550d177843f4e3ba5b017ad5c3ad5570e 58aac58c32c817da67b22c71364951f2b11e0ea5e0b10100db63f1df40483e5c 94166a7fea646f0b1652a4cc821f6d32577e8dd2bb016126cb4e58677f1f3312 +64000 996e1fbbb29becab638f306f82867d334c9f1fa150c2b752c4044ea528fe4673 61237f4e18c838bc2b06b2bbe89aca0815bd100e512b921d0f85c5c82e667ab6 0cf119c2308b05378dd21fa82d331a178ec1d43227301ce72ab9e4e3d86c2498 +66000 0298a246d6ab52f2c1023bdf5945b2abcda21fabac3057d98f722cde64bc6e8e 95ce25e1953af229957616dcf930dc80d08beb8eaf2a5b21c720d743911a7d2e 9dd5dba1e507c79a03b821e20a3a1f76db36fdce7e062029e306a99fb0c3ebd3 +68000 c9bafb15ab26a5cb639c9d65cd57f6528b073b8d3df534641921af26ecdade14 e917cf719eb000b6763524364586c5646598fda81580b46cc8a607c21cab9c30 424931395cc443ace53ea6524f0144b17304505a9ccea0bc8ce11e340859c8f8 +70000 5fa9e2f16f30762fce9c0bd6d7a94b4d6e5338eb22dc238ca04b827766b770f7 662b2025a5c9b8835d223aeba57dd9a4d64aefb3e0a548888000282df0a975eb 287bd09df2d445a1da3acc8582e1019e9bf77bb0fb1b8e3face8ca1df7a6a6c5 +72000 95fd877615d9f769832e8835d24722ef16dee5a7181bc9cbfe7b93e662cf3393 116f1343a412206ed4baba75ddf83d49131f3d802fdc1c240e5e82cf9ad171d4 15045841da0741ece63ea2fe8c67f19a398a3e5fa8a46d0e9acd579096867afd +74000 e038fdcd38e0c8de7de170d984e31db6e26c7fdcba8870968184bbcc52be2dc0 910eba3aab9a1e5fc8e25458e4fc1bc156f7ef99bc0d40d80708c81cc91e4357 9144759bc10dff54915b82c0f36b0c9b7f8b746c665db64823ca317f0472af9c +76000 2e9b7fae66fb8159b7bb4cc8e018d6b524f37def6f116b591eca6ce03134eaa0 f3f967df709fbe4b5b80826f5b29ef8b1ba319aa14502ec5662fb924c2ec0ff0 533d52346fb177c4634d5cdaba494a6de1aa4bf62fae65098f6197095fbf2064 +78000 ee48d12c1c7f0c70f31458ff9a6ceeb27f98d92dbc1bda72e11ac1a9a8692682 07c7fd21b2ed45091ddf5164d885c2c8be5b05e7fea8af964a705cf528c6b3c9 3aa7ad12a62a8b42b7447b217762b62799b0700f5e9488f3aa9603dcd1e1c400 +80000 7cf00395602e1643db1188609fe5a8e5a4ea069ded36a621f6d566bd6b23b4a2 4df506cb20c6b1a5d1a17f79a32c08771c4fc16d66a6d577115bee9164bdd72d 0f23823dac05bf924bbc9739113e702e0210548aead448539a6046e81a97522d +82000 908682d9cdc9c138a4021885dbf5c6577eeacad3329ed0b9ba3794edcaa48df5 6bc6f8ec1d0dead6800e7de283e7d2155645f914b8a3ec21f1544da377f2b5b8 5252c000acd8f18f2ac4dd4e00643ef6a8a9a107cb815419af2e9f21e4e165dd +84000 beba7dbfd798bc27bd612a204fa6aa8882705690527d15ed28d96cf984ae9e70 22aec88895a32bc703773a7632fcb85cffa726cd34f41fcbac47e2fc77d71690 cac3011d4f3fba09b528e1f7f5fe6ffe89b003052c1354cfd8d6cf388d34d674 +86000 94914263d1020f7d3a233a78edad6ebb4bdad18764a3ab488cf59e8cc267106d c89ce8a9d630aae7fd2e61af4f37085b4f25866659c7c88687e00d658013da42 27e4f3aa931bd165382802102d701b5f598d8973711c0d755200d8aa95becd3e +88000 3e8cdf8d9f5642afc10a31eee8a4bccbca638bc18e2a1fa2c58549a10c322dee 0431e8e025c993e14e47b78ede734817b1e262afd2de59aea29d381f8c7a02af 6bdb3a181329176ad588dd1bbeab6fdaaa415863b3831a5427c71cabc0fe5860 +90000 8c83e545f62250763c77fde090740f70099f9e8009ce4e794b7a8f86e24a0ada 8c4e7437ce87fab8cc62c02bda2d60a290744f74aa628f971e811ea121207ff3 35d2dff4d8b8622c9b7a8e9fe73029035275b902dbd0e06baa65aae8df289d04 +92000 3fb7861f78c9f130a25d270eb619f5fa40520463195c79d98be8267f48413a76 7d9f9b07c19c70bb9c5b6801a1f9c6990b9f7084eee15aefba46370607c58c6e 75c03ab9d6007302671b62b9d8a7cdc635f88441daa09ab35ec05b05a0661bad +94000 eb17b9f13df9beef86f11d138db7c3f538ba82f5f15afab7f4f14327d83dcc22 9d3ae1446330637e817557bbb8c17b4e17cd37df09d7c60be9456ffe1fc36ad9 31b8aa87eeaad204d720b160ee0c20ed9a400ca7460177b32a9f2d60012fc282 +96000 488e726d4d5651f2b642ca8296ea8728bfd8552a6104a4871318b4f661eb9d8b 00798dcf86e66a29936ecfd7b25071c9535097e281cff4a9c30c35f9e733344f 10541dbc94b9536391477478bb61876243edc5fbea4c571683ad75999ed9946c +98000 08a0ab71ab17af4edf68b3f2cf39b1e111f93cda504f45c5e650a6842c0d0057 43d73cbf6e721aaf6d0c4a986db00e28f6144128159dcb38189612f7105e92ed 7f6c71d5185b56b38fe5079fe6ef403aca49c28c7eac9e9fc593d8c56647c8a4 +100000 13ab3b961fcc500c03f51279385c42e9f055d48a37dfa72d0073c0d3f595036b 42eb6eba385202144dfa62dbb6d189555cb10a03cb5e82e2cbbd0cb0702c7068 3a4e3dfacafeb690b20f46b7302b235413d235e1083cc816d5c143e714a969e7 +102000 93d35e7873e8f25528df1733658d01fbe97050916902ef6a516ddcff1aaf24fd 0d9658216550954e327dabf585bdb35a7f6ebde7c3bea3224a9663b527a8b724 22ac24e32d54336acc5902f067f4fb7a1cd84835f76203c4b7c9f6525f7d646a +104000 dbcabb8844ed7366d65767add0f1b97a8d507d8d821c59e021df0b4bc88cc4ef cd6655afef0f61b00b38e928157ca6f3135929ccb30f294a9d83ee16407c5a81 4d14a671a143296139f73bcb5c4d92fe7c0ea4549e97b903e4aa689575c053c1 +106000 4f165a06e67fe755c65f309fd2eacaba720dd2dab553ee40e0c74db15e2a0611 c737cf3a0c6b4b3f42091d02942fd0a45946f68d582593fc76084271ddffd506 fa82525a8620ed3112adba6f8d6c4f8dbcdff6525d7739334f2ed7791b6db6c1 +108000 4155ee2c199392f76155ffcf3ae0e349003fbf8beb4247a91e81564ae8c518f0 191813eedab1037d35382eace2b553d3e586b4c9f6d51cac83d52da4d351353f ddeac52ed34a6a2584332fa9f849db275263cf2789c4e4828b097c202ca299da +110000 265c9192c38d9e457df32c4ae4fa0c99e50b1aef13710d30f704c13e5583386f 15f9f17a69ccf778f85677b0eba32cef866a6c2615fa14da1b044bb33ac1445c 531588368135ad722660be4559f44b8757cbc1eb3cfae5631e6d8b64cdf2451f +112000 7f5cf2309f6d12d8df4213f875bf369836a901e7c1065d04440e5e9f5f67232a 04704da6ef73d7d7b1b019acd167a3ab2caf678559098a8793bcb49dfab6bc68 16062a5d88e55b8d1220a153968f531c1823e5160660c81b8dcc68eecbb5050d +114000 7c73f67236297e0c4f54548d15f99772d1df419b0baacdd4504db1996dec8b7d 1b0a9dbcdc30020d47b8f69f61658fbcad3a1a6565f7a92d2912c1bf96934970 5ece5097af5dbfd55c93b4cd28bc4f18bb912dff107d340219352aac1c60d68c +116000 86a7c2302e8a0c970052b8ef327b422854b7d55c87ed09563e6756497b80072e 194f538827565a1352bba4498623e1e6cf577e6bc7c39b3c4004c3c9b28064d7 b542658bd22fe7c03795ef2e3a97afdb44b3865bd3d91e8406b9cfde59fd42d1 +118000 c6886c4bd895c2a8877de9c12252f0b2cceb77072d86728f942baf9cc4ecbf5f 206c11c95d97e925164af216623168dfd63cdac09aaee09e57eeb7d0e2ebf17d e287f284b84a7a8cf1320346ab40fa49c30ba742b97421a7a4dbb755be4f8f3d +120000 d49a0b86dd02d9cd84377718c6be288d9013b2b37fd3eaf2659376b18e3445a5 8384fa74c0b7946e3db6f4317f984b70a2617547360dca2e159f4fb4f60a62b7 34fb875c8e4489e362cc954be689e4b9d5ce21dba45c24509fc46d34e9d8e987 +122000 966a9405856e3d7de23388dd923c2115eb7f43e9bc8861f22d43883493f1d454 2a77879fc6a1093107f697e33a6b3d58a97e1930141389d8888855217b95257b faa9310ef6eb9650385f52e69f10eb9351cbba248ca2fb2790ec0e880bb68222 +124000 35e502307b19af7a3eb9afeaf24f413c97206d57fd4094e1f00323e78b2ff4a0 edf0fc01a75679dda76461cd1fbb3bb5122648ecc5a928bb448f94c2043bff5b c551906de7d90b2111aa5fb2c2c3fb7016ce79eef382172a39734e982c709867 +126000 486079a68f7639d912507c4a24e0092446d81494aa41f7d4279c1a587d54d30b 5ab700f577bd76a596ce2fcba502aa17bd9dab94c61e68a1feaf5aa358e53144 de7fdab9bcbfdfeb20388f9cf7db0b68f924097b2bedb5a6331ca4d804c9e354 +128000 10a5ed5c282a2a3104302ef0d7dd51b2d9b6b4b3cb2f8b3b4eed870fe9e8eddb 5743ea7240e7b37770e258542f2774431c98e1f3125ebe2d15b80e2cc3781593 4743a924db312302a17746321e3d80a764d2b24b547bb199ed6b7df6b85ce293 +130000 ca47b0db39722a147ce865274fed187eb20ead005b47d89df73ffdd4eaaae6f8 9bc5ee62ba00c326010e469dfd43e6c57b2b9aad0c732141cf6433b0070ae951 87a7c98c5fe374389403ac638208622fe3e684106ff84425b13ff29909db2ce6 +132000 297b40ffad63dbb41d5ff07da5a591e86fa2e4da891236f575f8a7b6fa2779fb 252fb92226615a8be738949b31d25bb5661c7e577bbfadc013dfdc4508657f86 dbce81fd2c552c2108f15e0b233cea78bddd2791e66eb447ddbd6eaecbcc609a +134000 4ac8bafa5d112c71f2e4b7b8e8997f7419d434e987233e60a8a9b595ae39b15b 8fc93e459e1e0493b712f97ab7e29edfa6a9c5a4278323ca0771bf8f0082b33d b2d532aeaa52a9e2bd7f88962e48cc6bee471299f1388f1aad07a022dbb392e9 +136000 0dc99c6028aef8913cdd7a3308068cea27d5fec18bde31c06eb5b55634351f5b f20c02f172703cc061593108aae6fe0da61e1cfaeb7855937212e1a5151dafd4 912b26d98c823b5f93daf1730a112d104cad6f974e6930c83af362a0a1224791 +138000 317cbe6c07ae83e610902b85bf48f00cd73db01b5d528669559d401236616d0c a77d4d1ca7b09df2da712e8ed5cdea9cef720edcb7007f5850ae16351c62befc b456ecf03dced8613df938e626233eb7b8083ff07b562e5b63d2c40870e1a859 +140000 74353d26e27f7addc0a12936d56584117081129e2c10d4893353f9e7f99e0c16 458e90e083dfd71ad857d3e91e83862436402d1d31eaea8c288dc7c717604f13 6072ebb5e136b144fde8d6d059a4451a6549e572f7495684dc4cbe9139d7ae20 +142000 e8e5f08ec077684ee559a84f82d53237f402ee5adefe1d9d6e284df0673df6d0 a708d8b9314fdd0e48d5c0122795b819ad871e7aacdefa54dee816b188d25dc4 c036f449ba22f697e4de8eef7b62f47e70e998953ee5dc84fae987a656a6fafa +144000 24744899513a8d2263cd179192505928624925c9b992aa68a0fb6c3fc7319d3a dbbf5fa29151c68968ebddabead718ad6dcad720644298df4acdbf8f8de47f55 3ecc64a5e1a72955748e4b97f7ad24d91fe094a785bbeb5cfe25e7163b6f79aa +146000 fb738fc34487b83bba12f4857fdf3369f3a1f6b57c144631f122cb658fe227ac cb9df8e42c59ef187d0af907f0eb16e74ae5d389f2a667dfeace0f530411d657 72a85aebfaeedc0eeb15af34cadbbde6865eb0652f8e4a01e68a644afaa74991 +148000 b90ffacd47d0388ef2ac2fd4228a08de0768829eea1139c2c171db3dee012023 c1fa8ded71016d91ad3f7e76a2f47def6420992c89e5f8490c5a36cf3faf4e8a 88353577b26ec4678a81192d1efb00a60b9536dfa8a5c78fcd009b85bf66e478 +150000 078459d0169cf5a9dfbf901b888a8352be285c0ac2c82b29610bb7ce7c94d481 b2dc71d50a0d3667b238287b3b0b74e894a8c8ccef57b7ed8a75ee83bc35ccaf a67eccc1b79e9678d2b75fa49506f4846e330316bf3c37d80a34d04a33d36750 +152000 2a1f83d639b3a9406dd506b1ff14d73cb0179d249807e8e16518311959573172 80a42229dc20276949536feabd83e0976312e9a47201996d0c6a6bd587277ddc 42b2161edab835f070c3793734b03f1a24fcdc9e1a94b19a1819b32a6a7b132a +154000 47646e8937414cbc8b4be0245132c25dda8d2eba75a637bf6b36de782e3f6e9f 1d7a0aa5848ba9fb87b4ec5d1f5b0ebb97a63d5d1ca73f0d07fefba7b1e8358d 14d4c1ce6ce95cecfad1cfa8724e9a23363c8ff0fa1c3466a27d211f398c0b16 +156000 dfb6ae85218e982a8b4cf656a2b604bbb2f676f40d184b75aada484acc0ed692 c164d079c0692fdca8ff475f5c3ed01a5322bc944b15dfed09894b42897ab125 5223dacbc9939b78c9ba20e1145f4d4c3ad97d9f627c64406c7955bf4c232fff +158000 c575b3e3ced3dd44477346f8481bc6ebed68a55555cf35520b2dcd30e07e87b3 676dc509c4e10007745804e8e63bd4e434067d733ecae6bd60b1806081eb513a 59e6970ee00381ff4452eee7e51f59ceb9e1173dd0280e6d2487bf4f3ef24970 +160000 97bec12dfc5faa5cbd3bf9caebe437fe60910fe1bb66bc9ed0335442206e2064 e99bc1ffe8b6a1c01b3394aba641db7b95d2255523ea112164d927d6bbbceaed 7fbc880e66ed96f8d6f07e6c86e35ec4656c6965455f4012b237ccf9714e5941 +162000 0340f804a5967f036cd6546df3db88472e7b2ea4dfd0e12e7d7c3d6978666161 0d9a021f9122d90b218889aaa05648641154bfb58f8ad0ec7e6444033a517670 d8bf0a176f576518ec5078e48c04a9645701bbf2777509c976f951c5e2580ed9 +164000 18ae9e643718113cac8f39277da295002eec63f15e209b5126dc88d12c846583 e957fda239096acf6dacaa6cdbccbde79aea6242cd1a61cc43c7a05d99aa0dd0 cd1bc5278f0e486f415720decd52d794d5e68da413cef2a1d1a60bdd3561b4da +166000 affd50f42c36fecfbac56e18e6e25d76417d75f4ca2512bac1c54ee961434b0c 662293079af71cb06c72e864c582a726c1ba47b30708da7a78bbeb4f7a22f85f 0231f68cb612252ce037c2a82aface3f7992626f59329540919a3bae40587ef0 +168000 2e798967f337225724dc6794753bd7d1a312daa08f8d6b30a302ca0f0da7c22a 5d30d0201e1be915e0ba3d0779597915bf6bf2a1570d03460965e1cb03410981 d2fcfe04b77738839150a55e75fc38e1ce92daec94022565c1ccc0e087793387 +170000 1a54716955a6a86d84c8663f0632b7bea2b53c3fd71418b8de25be916833c548 2a3c9c604a7bed0639603c87eefd0e0cbf5ac3243c418427cd6f364017498e87 e963318126416f8f26683210a541b89c2434682e9290873a281b953aa2d07664 +172000 d00a3a8f7df8c83a49743968a71be4e615488c4ed392cec33a4a7cf0b28f5274 e46d6b1e4a263257c601bf01198cd0865dfcc8e23f27821020abc4f0834a5e8e 9bc4c53500c61e07b94a6a0ace6621f39c38167224db3e8ce68d7b7db1dfef8c +174000 8e6cfda97593cd988f5d80bb27d0a5965533e96ae7330050c96ed15ac1a96850 7f48fda405b1db34c9bc7544fe64b687adfd0d44ee097c02b737783cf8f0996f f6e209868ea72a05982c794392141bb038c94146a77b7ccf1bd71cf3e2c5d28b +176000 e667c9c6b3dfc7305515599a802b0a75be1533fb9bdc752443ef28c88ad0091b 4ad5f995fb2bd092f83ccb96cf444f4529796204b6ad58a7c2aad99bd270ec0c a4258aebb52d4e9402c3a6707394fc9a8b73f4c3eba3828a1ba4c210b6a3656d +178000 499088a2eea1e65c9f729dc61a9eb24dcf850072b66758d71f5e0d3572b188c4 54e0c2a196bfffbd89dc2d1324ff93e617c0dcd705e4ec1f66ae81d634b48e98 92b75e4b4edbc327935e7abd59ce0fb2a58ef5a8594785e8977fab01063380e4 +180000 4db8f740c8b2d3b9945e63d23b37529a4938277002f226542057410603134880 48d09d7db861e7ed66e9d875825b162d6d53f2d51fecb92cd0906f15466d0573 e41f880ee86a0a78d1bf72174db1341188447ad0faf57a0842b0cdcf04877c0a +182000 0bc4a1491459e8bd921a7621db4f48e2b4827f8c5bbd3309ff8d2f575a9d4d55 26c62d5fde2975e6f32a19b0ab965d3a43ca39c9d79a86b771047cba3ab7ff08 71dc888abc5d929a6382cbe09f201da64650a9782f14148c776cc6a6509a843b +184000 695d3e834bf4c4c02f8956a555de5a64a74e9f958a5040165caaaadbd2cda8b1 f7ed5b2070a110bd23d5217dd7e0d4fcb70509f6c4f2e31adca6356ef300265d b25a70b13c2655a3aa76d64bb718690458a901f3586619590acc673783fcf8fd +186000 de6c4642fdc419acbd03a5ed5ce302b33259075c795e81bd05f08ee1cfed3cd1 a7e7ba54ff8824d07fd458eb39ac72246a7bb1009ddd8278aa4b12db2589070d 903916c02ddc3ce13f3eaebae9be71c5ad4ab51487e490cf521fa474b3d96481 +188000 cef09be1d7ec1986af43ac8d4588578fd1a5195ecfdaf5732abcd07b3e9d486c 6850038d3ec7302e9086cfbf0c2cd9934757e81221b09a35c0a1d473fcd11817 e69d4c3ac75174f18bc28ebaef424fa5ddd17c971f3018a8908e69e4860f30df +190000 12fe04c83dd3d98e22e2b90246d164b2f48f8bb3180ddf899e0f86b44f9b29ad 0974214d12551b9cb956885e144cc6943768f8df48e990ace740b3921d0a6e9f 551095c910a44dea891a6efde8e614e8527ebd309625304a86e44a186db24889 +192000 3653f17e50ac2ef004236b2081a0c998244a3c53117d9d83d1027f6c2f777a11 6aa11e6059149a273f29c502223b9ae14f9cfc347b59bf1d24b71fbce76b44a2 192a0871cce5e893f5eb664065624ebd89c6e1b647b3da135222078dbed77139 +194000 238f2c41fa0d4b3116e087feb0fb25c87492a313b77af5e9ba40dd2c4f83155c a3f17c4c27a01b2f8a6f06f0e21e099463edd7f1e34337ae7ac8758b14dc634d 23f0fbc6bfdd74debda97838dcb457445e9e84b0f21c7e8b2dfdd4c2f5c1e27b +196000 61f5903b3c5410245584289da0a0106dc03ab4086224f68295808f312ceb0ed2 459334fd6fc2a08db9523899293899244fd4ef830aceb2ff8e9719d5ee376d68 de5fcde5fedcf20e1384024351a94e5e760dcac137b2e42d0fb3646d2fa04ddc +198000 be70015cf8cc025d3205c09476962e557fdacabf8c43112d691959a0d6bd7a69 15bb85ec3fb6f731d27a3c14678f9f05f79c3f21077863dc74970b3b709f94ba 867955f232e20cd323285ddfc0aaa0f3f64909075b2033a651b9871eb3f4de8e +200000 092fd3e76db5ff35fbfefe48d5c53ca26e799f0654a4036ddd5fd78de77418c2 1f8bad01adb386f222f74970966457fa356020f2875f3e3d827f2d74c416ad8f 985ea95b848b49cbb7271f95b11d1ae92ab02eda522206619ea55f5bf8dc1885 +202000 12355741ad69c01e1468c9ef8b8344db57671b4402a942ba8301642cd35ad0a5 edad866259af4ff4ac42a64b3ca4fd9ed211f91842bfbc7f6c11e67b917180b3 4930bd2752eb1866ca5a5fd1a27f5ce4ccccfa705b51338d899c5fcaf4338411 +204000 2f460014518f2b5aaa503b79e9668fac0ab4a501b5d4857caee5af6d802bffee 21337d64a3d21e5de0a43349592d433e4807792f433a8d3946dbe9689f5ff2eb 7f9fe2db6454791655bec301d05677e968f454a50528ca18078aa8172d134a90 +206000 642d8d0c796cefd47f3dcb64565054a85f0be068081e090ac2ad1cd090008c78 cedb848300096c203e6aee3cfe6f3618a706acb5457a5218113195d01360b7e5 5e2a3118fb626c041d5faabe9e07e76189f0d1c674847ae4d21d2a3f846a1688 +208000 2b669fff146f1f61cde4cd35aa0584ac15764346cacaad4aaa11edc314690887 b658b1fc9d9b5d783ab0a5fbf5a6694cc0623c911bb7082f7e9e682e07aabe32 3d092cf86a5485b7e9138f12bf7b29a77dba46c1a758f0a82c3c78a588d42e25 +210000 ba9d3f795407b8ba2794f22021b7d60a8a2a24111690a2dacc3cf677ccccc7b9 8dd00d7f140f92bf50b9296d6e89deb033c679540704ca06143ea030434c6492 b65a4edcb1b8f501c368b08713b868e5747a5423eb8e4a62c8c635b9f8e7ee3a +212000 cbc470aaac6c6f75e389be25b1bb96e887e0a12c723107d27f055ca63f8e5adc d229b80320f8b50808d7e4591e6c194e16762ef5ae78680519602667c4a309c6 e3c1dc9347d486888edca410ea7563e0bdba5002d335a0434081e199863f7922 +214000 bcd5328fe706c377179e0a1117e5177b29ce820420575e6df8950fa94f434884 35b64dd93ef909ea1ecb2bc0762686113748017975fb1b5c507d31e2d4943fc3 baebb3507dc3117ceca6056b7accf1842549f33d7ba81a6c99f58bb18a835560 +216000 d3342e53a761de20064081048b4b7c4454098f479764de90a338a0bf9c14aa3b eb4be70848a4799f678daa72c4fcf9098f4ee9b9c0253516592ddb6026bd6ec0 484e6fcc4035f115d3e8ff1d50e3325fc34363882b47a91a15b335757b485fcc +218000 871d2667d02fd73feb30a72a6466c5c78510db602210b38594014b5607ab7f02 56d7f8506fc492993b5f9005a3749baae02656533a9a54b6f0ad6e6749c4f9f9 a79fe99787f4e3116f8161afb7096f2c88d553f638f2834ed97dbd4cc57d79f8 +220000 329b685538f7312c3d137e882899a947644a920a776e467d67312377c270b42d 6518dd3fb53fff20041b20c93cd8a50c90b3888fab9fdb8fb17b421a4415524c a7dc6dbc67a34443e2598479befaaa88d9a842b5e3013681a02f600079ff8697 +222000 f8708886e361c13875d2712e611eef71c2062b82aaab90383e283833ebec2cb8 1c164cb0dfa6d1f26f0be180b94163a086488d43d905a3659c447e9e8c42c0c3 8bd478f9bbd6eabaa61060bf9fd58b9c14d360aba505694cf50118fc236d37a3 +224000 7aeeb11b89cf0390156826c2bf5a9d0dec253bae68896bf5c306c0066f6efe8d 23d84b06027c0f9137da8c7a84a0a405c6e17c009cceafe6371390f48acd0ce0 9ff0a69abf6aed89a4815e2e6c4e2cfcc75a812f679238e7022e5f11f73ead35 +226000 0659c0a8e54ff5c229ae7a80e0db00aede21d83461d1e1a85b8ba8e5f8f21368 235eb1bf7c0b87c4c930561d9cb544fdd7eeca9455aa137abddca61bec06659d de026f25f5383a75db9b592d49464647ee30c97c6f417051cf180b778e0a9446 +228000 5076f470bbb9e47655a9f72df868cf896f126e12d97de6e55dc516c86514ff4b ca1b781dc490da9465f035d8f324321bc8c7a8d210152dcd8a83bb3823c3f9ff c01e82de926fd20c495f0561f833515b3d9548e4005b0307d1842bd1f9d5d5e3 +230000 15be13dd64b8516a7aab4b60901a5447834035a027fed1e07b124d79e2fc584b 5cdce33351d7768a13023bb0d9ecb342c1f8891e641a79e32754379c1fe19cb1 62a54a870ddfb2065b709e38942e77a2fe9bf5a327814a8f41484ce18ed9dbea +232000 fa73bddc755ab910455fef43ca3edbf02b530f10e965302c7bedee572d8a2e5c ec371e08c209cf9e14869395254bf045da1619a0f146150b804634b7e76ae722 751b02c572941cb8c944decf39cc5d7a6f1979d6c7547cc1934b007b939e76c1 +234000 9bbc7b99c8796b7531f07de02e7cffa2df02ec7e56c1c4a9d52dbff35aaf4eac ba3b2981deb3f83bad5c5f7016234d4690b044074c120d52cd41d6654ec57d9e 93d6f04c453ee8f4099b9720f434dca576ad8db369d5db39ecd055eec06b0021 +236000 dc9461b62fd1d3aed17de0a29878b220ee6cb9e2c2b4c47d93f9cafb97204d8f 522f7b37ecb693a4623d310ef48b208791a40fb7fe84a56c7dd1eb6356ebd668 bfb5d9a184f428e518835f002f259cb98d6d425a4132e1aa2c825cab92d1c9a4 +238000 96da41826450f85c1ef090dfa67e981c68ff4d2293932bfa48ad15a0a5c17f98 e64bc01df6e9a8002a6a1dca0f9fb839ae48bb0a5ac4113391262806c2d0a466 fcc127cf0525e7dc7857b5d86f08e00722c555eb2ececb1a36d41bca55ac3545 +240000 d27669717323f3d8f5bb937fa76b62f04f878ed370850c5a6e8da21f5a390008 2286934f8fe12986db7c9a9f6e21cfe0c884ca24170fdcb023284656501c3aea 42113a4dbf08343652ac2aa2018079383e79e34ad1a4375da7361e77192a0a0d +242000 4c55c8de7486480e47a359a59dd3c98db431e1c43904c6f1811021889aeb7907 de1a48b266add613d3925876155dfa9c53dd8c2dd2d8513502b167fc15a7861e 43ea1d54803babb09472381db5b7c5cd62f6f5a3fc5938e473019d340e90e39b +244000 7c6d2cab4f86c44c5583c5ef20b4dfce32efc3a28b23f959aa8fc8ccf90c50a8 de4a2417c03ce2de4d0c4bb88986008687fe21cafce2b6e6750e3c83940f829a 8f3369d87c870f482c1ec0ef0eb63695ea46c52aa55581862831117fffc8cefc +246000 130a26fd3bf652cc22819f2d3f1ddfabb30962c1efd91f204709dc4420981a0c ef3c26b96869df2623ef1cd480ba82e1f91b181f4275b6256e23f1916f49b889 159f8745d6a50e53dfa3e95825148d318f5af99436998244c882671d143f4904 +248000 d6ed148b7d59278f9f3f244538713e54dea7a7fb417ecdffd36f3f6e83ec009f 8ae0e08f1fb70c9292037ec6ab3abd221d5498fcac245547ef519ec7df515533 d164e368cd66ff08158ca830c4286b63ed97610bb73c58a05ececc2f73b8f460 +250000 0e4bcfe8d970979f7e30e2809ab51908d435677998cf759169407824d4f36460 1dde8106970f967f1805b33cadd874edcd4160ca6f01634cdb7dfa304f48be5f dbf868dd0beac41b7350208820e781f9f487fa9779bd5294ecdaeb809b6e8b5e +252000 490fe3e1d784e703ba77bd5ed9ce303d88947841c1f73b94c7584dd0a473dff0 607db783fb6673ab710d5bcf166936f68b54c1443fffc86a2d9ceb63696b695f a9c58a4deb04d7e002736fdf76290cd3f79c747e9cc19a3c9559af13f6cf5339 +254000 40a71ba1523bce49a7f13ef82cfd154f68397e972bbb739b858a6043f45b0190 017df614c3e2b81197d84074ee535532d1b3f84b127f5557476a5e8d5731e6a5 41aa046b1f874baa9c1e5ddb5706047641073a3c76107462043b95ede214816d +256000 541ad7d4d127287988371923029610ae4ff30ea19d1863a26a0f358cb6283281 78a27081babadbe5db46459a94ad57cfb920591d3dd46e7ec7442890f7314c65 f3b75c852bf39706ccd0a8fa05d8999f3d57b3070d7dc029c2c366b3f340b7a8 +258000 0b9e938aed9684444f7fc5359f7d00421de6be126d5833e97fe496bdcceb4614 afadb8802733bb3d25003e878e4650049d99ef594172a0186f9a88391ef2068e 198f308c2f3322642d1d06e162fb9e8ae34ee45199ff8971d6b6853fe30893d6 +260000 759862daec67224cb5df163d1067f3156c14b6b955d2ffb346403f03e6bfeb20 feb4980eda96c532d66effeab0e5127fa637ac5c03117513319b429f1c138f91 d54768616761a1866fe479eaca1ae9d03d06f1dfc34f2d1836495c638c9c9834 +262000 3c840da827ea390592b032c30ffaeb4e1d1cb2dbff974a44fd1a37385469eb15 154a14d6138c594df5f9c6472917a8b80970c9c6bb5175e116dc492548f0f614 edf33b3cb7aa36bb8c449200f6a63bacfa0f02b9c30f5dfc4e615e838cabce6c +264000 1e53cf343deba6b33a8c184d57d55de00ddb7e722591ff36e9479f2d602f4cc3 075d09a4950994dff6fc3b0fd5c1c00ef2b6047c6cab2b063afe5e3a318e0cf5 d4f41998f141fd058e6e72f061a009bd1cbd7bde946236679164c7a60e965958 +266000 f4527ef6b3c0eae24dd1bc115473ecb79ea147ca7d7a273d99f15a0a17d3be11 6e96135af34a05044e554cba71ca4addb6ca654645840d44c4565fd61e311277 a245d99c08cf9352a74648c5a79dba83552ced25f48ba896c8aa544a2e924a56 +268000 23a0b683519c0aa04d8b82d502013a3876018039c53a3848427d34f4635a8b5d 4dbb009a877ed8da9f5485491a1a1ad05c683190144b146b30a91bb8d945664a a68d2fb5d5b4b15b8d5aed42ad4d3b233b6dc9d717efc4d04ac4d0cb199c96c0 +270000 284d5d7a2b48b5cb812b6f08abac2135b67c39f16c72c82e987fdd1ac65edc6c cb385e8d211517166f965f9e597f91b48d5180164bfdb7058419e85af114842f 1cfd275a43af56a832811d89aa87504c1439b9376ed9c367e6c23beba322bf95 +272000 99175d0ffe7ad81a5848d82d99fc265a181cbc9e76a24d8eaac54e98da2b26b7 ed9e03423a6322fdf524b426cfe8b396644ab6ca6e581a91ffcda38891284582 377c94e94b0839863e02fbc31bbb8f414c61843668bbca2e65a19a89bc01dd8b +274000 d20ed661681393c796624222db7a686f93978f1554686e29f94afe2fe02449ed 93daf4b869507911a5a37e1684dd05c453ba6ffdbb93ceca9bb709ac69773dc1 7c6822731b70aec6472a524862f215f168f745ffbefff98b7039d8c72f59b3a5 +276000 bdd0c01ba003f61d77187085c39b56e3db2e768748aba8b1230040b3416618b2 73494f9adecd52a1e8af6cec1d08029bfba1832611b3056554c620bf556e3f83 56c8924acde77eb288e96130b981dd484f46a2d7a5303d42bde2590d2d448be2 +278000 f20319559a4095b4f5e53f5ca76da72a7fd738186ef05c5be090197205795f72 425295e0e3b1a7d392173a9db0bb245a5fc135f7c896a87454336a00dbc8f7bc 2923e9086b664f2feb42097585aefb3d66af8df033d5cc64c202eb5c726e2c9b +280000 42ba3ecd82c6b9b090d7352471d3dae297c601377f9722eeb599a653738d9cf9 3365e53d00b64d447cf8cc8d95e54bc3962a54a556ca463ec7f792fb5d119378 ac68e0d2c65c3bc9079b0830b676f191884988690d4bf5caff9da15c84769687 +282000 647ccf606b1676d29ecde6bdbb7f7ccba849d82aabdb1ada44c9472a18734813 cbc964066b9006c1152715d16d139672e415e8e4034c69d72ddf9494cde13118 a7a937575e5b111a5d95dbef19b71cf1d4f2bf32639a0a633a1d7e7d3b9a9089 +284000 4e802380f3b1fc2fc631de5b625b0c0af7bb13348d6f161b92c411829aa238ce fe465de610bb3e2d981e3861b15f95c38c0d0ac728ce67e09ef31e0ca5d2b6e5 af1d2eff2ba497d764a04ebb0a281ff20a0f3315ecedbb4df79529a60d8d35d9 +286000 938f1072ca2f95ab4b7e0e85e8cfab067f5c5e5eba8266ba89f34d6bf4c24b92 91f3077483f09edbb9fbebf6b66efb76fa37286b7c3edfe786a364c5c240f5da 7fdbf0490224b41351a43e98e2dbd4464b131f1dea218a58bdf908baa7cd05f9 +288000 50c07f0ed115a1621ffb1adcbb1708cab74d6a6f8ba582ac5354d87da1aa6f0d cafb572da2d6220f380752f6dc2b350b2f724b631e054c9c6e8d6a18f0e18c6a ea49c67327fb67876bf0a6dcbc1fa02c1980e0993306e8a96f0039128186f925 +290000 4f7b1dd9d461bd5fd9fd64b3e1569756c016dd7c4011beae3387b6af1cd2597c cf17eb22d621b4735aac4f66e79b438f67ff8e1f1a38157b95d6cc7bc54600d4 be64dc684ad4f2c7cc6f5e2d95a4efc1161efaed69f5127e01225278da06350e +292000 33dfb4be3a08ece139a6b9d282f8cb3c8d9afc5744dacaff3ab2da48b924fc97 96d9ba084deb5af3236d2fc8c6b1b3a1ef8181aa0be416f018819b0e0dc7b120 e8548cfe0d8833dc40afecf80c072571f8517122047410782dcb805a479a7cba +294000 5a4b80144acad15b663901d6683c8e466b8521eb86b8bee4d750d7a90b90816c f4f8dd1ff9bf0cb84390ef4502f6cc862b005a1ff713507284b007bc8003dcb1 7cd41d4ce03d0085eef70a0028f8a5c295f5d7381019e7377885cecf7f6aac1e +296000 cd95e7b249e56f3b995699fb93b957badd9cb6ed2a254d509edf4bfca4a9b9ae 3bb9f046807e0825b6e5d9e4431e6da9fb936f7ff6ef0e0356e0d58d7f7c9850 c29ca0677163c0869fb229ebb1e82e5613a73f58cee7405f979ea7d0345ef759 +298000 f7c4d00fe4070f2303e00e732b0817db7e9fb75073d406ef79edc3baed8bef6b 1a6bc832c5ae74b4e55dfbbd709b59312925fa51cf5aec76d9c3ef8ecf385b04 222995a61c02f9d4533ca46be37608f365ebd3b973701f1e81a40f0720026b5e +300000 7c2b3b8cb1629fa014a29e85cd7b0fe7876ce3def8899ba4c0945c0de2ad7902 2472f26793f1868b3ea13c4d8385a075b47c1d969544baa73fa66dd7afc57975 5fa807599c8062358d943116755f1a644eda019ab031ff32e73ada7c771a2e43 +302000 c99ae28210c1aea65df1476e2f7fb3825aee5d521decbbab03e9b9e34cf7d1df eeeb30712ff68e5d31af50e42f7480882675ae722677670a8017023e56d98965 21ddc97639d4de3fc2b84668eef7a87c885b942527fe237fee345b7dddd3ba47 +304000 30e530ddee1ebe1681013d525932f41d2492ab081b6d21c133f624539f8faa64 5d19c509c5ed4f6dff2ed6a1569fb7e80fa87327cf360b5e9967155d63afdf5a ecd0d0b8aed56e09acb5a1d80fb44f115a98ef3daa9b7218464f05a692250197 +306000 a48280659b2ed2a6eec10fd36d9503b92b3ebd587f75003b6373c127cde4c9f7 bd19e12594434b863e77e882afaa687b19b28a82d90c45c91ae3321d7a0c68f0 ced1a2b382ed4b6da703e519e6ba32f6862aa48c7dd8454c36ab8a910894b338 +308000 ad4a8b755ec479f7fedd2bbfc9b3a9c96e7da784c157a680a60775944420e9da 90d94c7b1037ba5c3a6064ca24585101dcf43f64c9ffd9d84f17a8fb01240809 db1ccecf9f1bdc5a4d4c9c04faf0bc6014bcaa9f91e00e2ebc049d21439e251a +310000 3d79688d5f6aacdf66d67febd525adcf12ea4236e4790fc4b7f4b517272661d4 03655829a63e984bdab1c0dd5a39d03acd0a1366373367c6d275d63d7e0f0fe6 f9e932db5ed3a97aad992876ee715e8c434571871c65c33499f355fa0b1f9e31 +312000 5aaa006bf736bfed0e111a35ca95bbbfffd10b27fbd7b68b79383b9537e097be 0cbf56233f3e5e272c117cd3bb857f2858c59f027b7d348233c1afabebbfcc35 de9e03ba71f503c11470bb0314de2f412b19bbc667fb94609f862ad1b53e344f +314000 f0ee411e94d8b8079a15de6924ed19244c3c44e7a7b486bc4428ac65c63e9287 205044ce3e5a3b8c4cabe9049a88c6be75ca40a052b8876695065aee9a381653 04cf89b9d5a166d5f970554d7bc90dd484ace5ac620a4b674e944ca47d0daae9 +316000 fc9b1499450b49ca255d4caaf4b473cf6acd167863714d1047fd00daf975d94b f911d872849d513b1a28aa4eb46eb0d998cd0707cf65199ce8175df9867570ad 19959d7b31d33b2cfedaf4ae3881ea8e25c8d6479e3af245e90ce7ca420d24f6 +318000 b41eea4d8b13391cc9185d3b4c031e1532003502ad75ffcdc9ce656db7a30bbe ee8454cbdfea08eabb4c406666810dbd2237138abe19a20dd03c9e7e534a0978 4cc3f57040b98424b919fb6730f1f90d3a711858032f945dc63d89548a7bd058 +320000 ee7e03b9b9eb9eccd53c0b934b9494d74571ea7897f0e8102ed668736181278c 3e29f19e4ad9893c6f8abd6a88d8f6e73bfbc5e7f5b201f1000237f233c9ef3c 149edad39bff5c2550be94d1525e00f6f2cc7560b55647f14964518ce8f30ef5 +322000 1315789870b087df2e70a70d583e228aa2cf80b5aa000abf3d2aa747f50a168b 6ccdafd2c194d263f35f6534006171bdd40b73a6ee8528b29e2230f3ebac0934 fd036bf9f4a011a6b0908f7b430d2f4f6db3411e84e6b19d4b3fd1d56b3ca960 +324000 40bc4581cc7bd54a3e1ad99588d7c30e6ffb3c23935b79dd5035638f0f74eb7c 9cfa3f8edefdfb5d05317a16ae4bba54c2f7d73379a8a08433a0167de5163ad6 829844d2d23dce48e250cc8ce7ffba65c70dca144521bc8fcb8fcc4506d5ee2a +326000 b9d02a251a1450eedac4877e1cab5826c994f434660652d9055a280cffa095e8 3142555742ef603e829dbbab7bf1780951124f39217f2cdfbb66abbee621bf64 55c0b10e79768295e87f371025aa790b4ee7894707ddeb4dd4718c865bb94e93 +328000 55c1676ba7698966bdf301475fa9d83b311ce0106fc00fc2fd78ef55f7182002 c5039eacf96269c06de541f700ee0eed472f47dc5ed5fa9c8383a42f209c91f2 4b363a51504c89ee55e5eef07a18965fefb3103d9e9c90a096a325e9d63c4f11 +330000 13b03ad9dd673a7c15af3af510c221f83b79e456c83803f723c18cb25010017a 685dc3f7ba5834187a5dbc6d10c73d934ce17b95c4439d7c35e223ddcb8b21b8 abaa6cca26fb074febced19bc66404439fa3032ba9a86c6a3947b66ff21dca51 +332000 0cd774a288085dceaa941f2dddc892c3cc419e8225ae88c265b14406151acc52 9f3c5503908a2fb596728149312f71417e34ea4bcae5ed010d43cb92eea966f3 7b26087daed34cc5fd3c7d5303c7bdf597c898140dadc198ae01f60c00f7c8c9 +334000 27296dcee62f60c4bfb2b57880e21bc0cfcd1c35e3cd19d20cdf20215ab9e1a7 bd22074d01aedf877de235c25246a4eadeb031e48c89b77babe2864dc0dd27c6 8ebce97090c3aff2a394a32e000c54fd0e1537d7b70402db8594971402928717 +336000 aa6cdfca65d8b6cc02d9fc8fb1b2e567e0aa78b667d06805f37cd6e944e21b98 729ea9fa925d59d47f89f9fce66baa93aae6c0b7a837790e7dc07e87e6b63e66 c298c742a89f83d0a53d4d20ac992b2d5595411e6da5c0dbc8f66d85cd94f0d1 +338000 9ba7df75ecaed8009722a8da3a8bf944a0cf2aa199eea9c8b1b02c120d202540 e70e1f510cc21b456cf446879fb44722bfcf002ad2e6237409bda513a5653d52 f921ad475991f4758d6a9a9f3feaa9fe8d3b877ced843be5113862eff2e819c6 +340000 887da0b72ffb0b7260bd5abc08882045cb59f076f5e5ed9ab1f74b11903b482c 9e0d1689099a24d085884737f17425dc905a64461c16d249e7d36eb96cfcd0b3 2b233cba7ac7532374c680cfc9222de15b7287796e4409d7c1d50e148980b1a8 +342000 81c820cd4c1da69e4164be2702acd0130c3706c6982b4dd45a4c2938fcb7262d 84dd9eba8e7ffd85325423f06e8536ecd7818ca62f2793ae5ff0de088dfd35bd a6f60241a7f8dd45e37fe9a08e5fcb6c785405eccb7cb2a87a4f2f4d560d63a7 +344000 5e5db00246c85ace93e082023e245fd4bc86f45decb23b4becd80d6b3e7cf112 b3003a22fbd826eb1e5f74cfb3db188c7b59db93e97c9a3dbf1f9832f53d0993 d29b58f8b24bfcfbf0132b5d66af5f72495b17e3d8e78c4345a93c192aab4ee9 +346000 bb0685e4a3a07d999e9889d06bc8946bdcc5d2a5b2f0432217b41b88ca6fe284 beffe5415981a29bc78070c869f2bd8c0acb1c1dc00b807935f4a56d196ff130 5abb093f8c8e73fedafa58adab9044fdb0fb69fb35c266cae0e3638ac8f116ab +348000 d0e78d8ccc758bf0dab18c0dfea1b51a6f5694b362a2cab0f88ab7d11e7503e1 9103b31c1b29b48585a751e5d34e9fc582270143814efbd92635a2de53df1a9d c18e56428df680856067f5de8669adec0312fbb79d82509c9463919251e75aa9 +350000 2bdcba23a47049e69c4fec4c425462e30f3d21d25223bde0ed36be4ea59a7075 da9e8348a26220cb05f1baf37eeb466899e4cecac946a71997b7ef0b4369b5b3 fb1b287b816b225f031b0ee0ea3bc566d55fdcc85e7819580bf5d18ea400b05e +352000 7e951f11c2a5732d57b9a7325e62843d72cce710576888195f63a6ae2c2a0656 3f63b7b57b7d82fbbe7ce010f136c9715c04c93db67a07e5850d1d0b73912d95 7bac5ad9df26f2934fdeea0bcc8ce5174f581f89b358dee4caac095c59e8011d +354000 06012b99b6f94817eaf3ed634450af8ae30f3e64eef4192d2c01bbe407c99f50 2034a09edb32bd604fd7b63ec2f21b675bd3341b1604fb51d19ec5a7f4bdff99 abf9d3433ec7d1d563f3a71263b0287c54bf15a979399948a4559f204ae75227 +356000 729a75915f0d70cad9e9720baeb3b8f7687cc11041f7e633a72b5fdbf4a49c07 5503d3f503c948a95bbf1806b9db61e76ecfe21f2f4e340e54e24c4aa21bba78 b379ccc265a13df358ee69116c66101a3abbaeb8040bfb567b20bb24529252ac +358000 e24903130d9b583216cc878fe8447bb6343c51d0c93fa14877101db93abc5b44 6a5020f79e81bd546523adf8be25920cdda4ee6a841a34fc71c7047cf71b8a64 ca6db290f3e6ae6320eb02c74d9e76689f830283697ab861ef405eff3d94defd +360000 1cd832a4bbeb2efd6967a2d997c266fcc5e3ba8520ca450e601024d046d347f0 640be3b0e3339764e708819cb780ec463ba732b2c436751b6b88a279950ed22d aaaaedc3e0b1e896bfcc273dc3e6c6adfb680062ea38e3c231a9b47dcf052d60 +362000 31b50d22ec7bb03127fd426c67f2ead053247dfec4cbf227897e655985aab62e f2817aff47bcb4d04696c6872aecc88682661edb51a6fd6657973eea201adfd0 c51161286a9c2e19badbd553dcab8a6ba4cfdf8751a9c5a70da332d97faf23b1 +364000 f5b580b6d42726d9b35ec1254dbe6d59440f372b5a2a6b53e9e0f9942feffba5 7f6b91aab55e7adbaab898587838b728f5a00e7b41414dc1a6fc8f2b9273465b 757ae93a20ca92595d07fe37b05bf3b4aefa48d14d1e6602eddecc73744c3a6a +366000 49025714adf7a2f6e4beb5ac959f363a6f84b717cb007dd0bce1aa2ffab95997 068d85ef7849249fe48d525aa9097254bca1c081cd62ebb7dbf10f838e58218d bda9be4968f490032f5c6991bd30799daeaab48df3b9dc2007531802b477304b +368000 112ff5ecd9aa3ea07644dd8fe004d322083a8ef7506ac7c94cde9c3b9657afd4 d3bc37ae580c2c90b2b7b9c18d92346c84b3df1e272c8d6a893201d07844b80b eac7006f60ed62140f6fab0c20ecca6a8257295e81666736032169f166019906 +370000 3bb40172468e228aff88062973027870cdbca3b1252ab6e095c25d92335d2474 13bc05b67dc8600f26dea9a233d073afdbd5c2b634a9b6de5cbc567ad109ceb0 e9a989371d6f196c54f26f3a5d7c83c67d2cd512e7d668cbfbd1847b7411abbf +372000 0f1395fedd1d4ae584e4c309ebac802ae834c0bd78a8905c96cde1e147038d2a f65ce9e03ce570cde0644bff287eb02493891af134756ed9d56941ddba1e02d2 ad1abd1fe42fae718a5744b7bd0d38714cc8609cf447b32bd9fb55bd42af26ec +374000 f5d80e91db049134f7ebe42191ef75510c26f7e1f5efe74a52e915142456b58a c7954e87f56aaea06f21521151ce91034a3e35e57012b459b013231ece9577d6 f52d0b46af6c495a04e315c2927f6eb5b67feadfbb310f224897ba304d367972 +376000 7bf742779b6d7e2632292c8cc3c6532f11199ad50fa10857f543d87cfb0b08e6 83ff3d12b9419ca905142495ca1801e543c30bdec844aa77fd4a3a2799cdd74d c43f85fe2b8dca527fab4731c8608ccf6e4774e8315b5c48e44c95b51f88d502 +378000 b7f6a9b74b6892ca67296bb74f6b2efc45daca29bf012043b0e7786f6ff8e910 04b44e9100d3d545beba781fc12372a33f3e1a7eacb4c13695ca82392135d732 de8b849e3ad0e88d1de31f031eb54996399f90e665be559830d2a139423459a6 +380000 1f916e4b8bf03a5af4c14e0b33ca0c84e028621292b07990ba7edf33b7444a72 abdfe5db834d22cf8d0080265beca1dde75ba83902bc4167e265dea0249266b2 1da9421691e81aa4ca10f28d7299bf1bdc0dd9ccdb6cdfe903d8e48ebad9fe82 +382000 da060ca786595c64a906bd789dcf05616133153732fb888813950b4bb0afc4ad 952696dafa83e908f03072ae495a44a4b96a63ba769e219370c34bbd056c9e44 37c81624579170148eb112c5ccc0372259cee50b804caa58b7d07dbdfc03279c +384000 3853756854a1597c36906a28f7b95c0baab6208ea2e3a554c05987342ba17e80 bec74ff1e2d82bb83b071ecc6d9de7c3e9e089792a35484e4b628478ebcf44dd a692435c22dff844f566c9d67ab92a8e5919a23a1544461b3419b5e61b905ad4 +386000 29f3e064b15ce56a3bba9db56c28cf4edbcfafa2f4a976cbffdddb4d6ea17c44 a9e30fe9b655e7c26d91d11f253dba6a1558501222ae6444adcd7ee819b4de2d 01cfe95dc0a64666a8214ab0571f296d42d93f82d3e8d4648b635c435a506969 +388000 83a9f932145de6f64ddeae2b31c0496b0584b30212bae86e017dd6a8f52c3a7a d981daa5ce4a1bdc73660c6ab9ab07e7d7500bc64350153c97098335c4b6c258 500f5efb4667041a5e0501615618ea26eb9e63cab9250357ca4f31f352db082b +390000 156139a6c9394d274a42b12134906dad0c0c9fd69484f4aa93c488d4c156013d 53a516b8691965a55dde496bdaece64c1c00d7611b1ff44ec32d0036f8752339 aa782aa4c5f53db55522752efa50a9281c6b058806360cc151edf149eaac3dc6 +392000 306f24b9c3b34484a55b4c1117f475eb334797bd31c6e725cdc2c83b92ef3b94 d8647e3bac2696d8923a7a8cb36f8d3ec3e1a56b29b343d67fa8cf4c65b10e6f e2258f0faefe6522eecbdf1c45dd287b8bfaf0bf5ca56046e1148f4db3d384bb +394000 f9cf6c5b44ca9450d93c1c31fbfe9e70e44b8dc946f33f1aaf4b0d027550b281 496eeb73fdb61fe3466d42d661d0867e46f8e61e217d58f2650e77a46c048d97 ffb317a2a79fc209227ca16188db1a715786236cd4d3b58d97f05849c11868df +396000 b9a569527f0beb26cf861ebff524c9914073dde2efe2f272ec224e1a706b4eea 95386fb38c8e489f7b00d4758e3345f7bd7d7aa8bc6dcbbb454380c888bea6f4 9883836fed70a503eb9f333a67c96d462f3c8bd517e190c44436bb9548de0014 +398000 21ae11ea082a03273e09f3451c6aeb74de18c7edcdf491836a217464ee2f17d1 1a89d682a5ee03d4ddb2c371096da91829b1da08819d0b23656d1545dc7a1b56 5c5335653b94e2c49db8eedabdb1c6e2d0e8a19bad863acd6b7230149c792c8a +400000 4378cee85115fe9014b53a0b1d0a58b6c5677b26d8efddddcd590d129694e7a7 c04f0c6361046c98aaacfd102721ccaa5c5437f8528d307ea5b8c62f384c69a4 70587d814ddc1c813a00df96854c5fb8f95e357a92f97fb616ad5d1301e48769 +402000 235c380eff9009711c797b7e316e3d387e348696d51abea9dc96fdfbb2c04571 aafded982fdad4ec7d825d67b279b4b9121061ae056f5c41e102a7ca0902e5a3 bb1d647d393a7467314e73d668b7e0d7dd52a1ce5a7ca39fd8fd97cb43971607 +404000 8af1b696ff2f67cf044d957d09010214b213f64077df1d64e2e0d103ebce65a4 270678edc46211686af3c1964d80f40529eaeb74f7f91e11b0939d696a4a9309 58264cd02f9626af233f358ee90ea75186adc569a7ca283aa7954593e9adb943 +406000 641651267ec057f3da28dc6192af0503d9e982bd842453c499c9d3fd8e5c199e 2d982ca8f820abbaeefbb767fc129288f31b62a09e238af9fb2b849753857c07 7ccb5a66bea5b84110ec9e71f703d45dd31f9f09dce3a73e81f7ae794d1072e3 +408000 c5226afea3e6116b44b89a0a9bb0b04ecf3e57f68a9faddcbc608e626f13ef79 50a1a46dd1ac0c04042e7ebb14dc7ee7891c249e51a5a6a4a6323f908e808ca0 2e0b555172ce846a646d48aaa5485bc26d2f9810038326bfcf786ac4ba426db3 +410000 0b483d9c35f2a1086f6bbd9bb40b75421f6dd7e1f66ac3e000ad51ff699815ed 38448accfb100568eab9e683c9f701db70cbb36b2fb6daea7af62efee7f55d40 cf6d170ca5da3d64d0e9a79be7ce92723393caefe4b826baf0215713f6bcbb83 +412000 ac520b41d70899fbcf727eeb558ef2631c6fb65f771fd482a8be2b3ac7397c55 32d03667fc912acff1adf1835a718e1733342aed8083fb1de68253ae44145aaf ab0372a6cfe93d9272f7511d5f8826f6565037cd0ff2576d8c82f7dac106e4fa +414000 a5ebf1289c1b1123072b8420d7e484c308f3bf1a748cf57c6528a826d4ee0533 6c903eba772b9b3a360408592b5bc6c3385affd9089447e07630d32e4cd1c4cd 5d92e53e854c959899f265512c60a0b586088428d86f86ff8ab7abb7a5c9daee +416000 46f0f49f51bad9a7f568e5f49b73d0f32995a289320d204e001593405fbb8b6a e56357313edeedec15783fdf9878e5912626a09f454779c77b3b5c3bc9863d54 35bee4532c82be56131c0dfbb2cd688c324eadca459cd4dbf2b9f42b636e222c +418000 64e1a50b602768b2c7bf712a7da8ab5ebee824d5076dc5ba09985dd84085b6eb 7a9f7428d631303d6076254afcda4ed4a6f66b668779c73d0f0f5b656e32d293 5e2c66fb6836949291185fd5d4e4adf4d50be7acbc6df09185d9eb48ec36a768 +420000 66d9a0de7a042f843aefaebbc6166d7b01b642b3b3e4cce1633d623690dd5d0e 4ce1977c56241f2b73225319ff0923677181cb99891d24bb8071438ec45310eb 73e140e9ba148a4b9c9ecc4c990a075f09f1acc1661837a11d6026ccb6600950 +422000 d884cffc21c9352bbbc0fa906e78af8f5a8fffbe10699c9fafef2314694417a9 fd5bba8a352c5d37d52a01b743e83df487600a4f17dab06fa937ffb940174d12 6e792c2c28b40178a53033e39cd87ddca92435e0753ce584975214eae8a3ed24 +424000 edb6d4d9502bc8402e863f33601a798b14f4440f5c56dee47189df4448322c4f 5950fc53f122b7d6a3266565f8d54bdbd26b598fe9ce2e6ca96cb9d396d5715f 859dcddbc6e59a209d724711ffcab15f55d9e2de457ceb4f2017a75ebfe09bce +426000 4c1c146aa8ad6df152b0c1e30e22d665a14981e08b0737120161e6b02b06f190 af30f04fa8a0906d657a8583ce0e03d3d522de0a3c1190981a0ca958ec03e849 be2da144b9605af0174e605ce8f30b7d11f1cbfd166b4f396c3dfc75c99d8a90 +428000 86c814fd645850ba863f914c36d1e0727baca5ce8162d2261a28dd975db24372 b48b339595d61a03d5226108e14d8c546fcc6797574fec9d3bba55b7e3261a05 c05d4e0d6a7296fb4b042534a23b2518097d18e2da5d2ef21dda11368d33e762 +430000 6234b634b3417055ac2a11e696d5a7f131519b133bb1221fa281495e5e5b1f46 c5b53ed4c96faeaecf01cdd1e4f5a539f08071a0318b9a9dba1efda935f65e16 cc9e965ba4927bd2ce72f016434730b745c5f2891c4cdee7adecd08f57a1bbd7 +432000 a89748e4394e6ffcefac7a423052c510b3dd793b0dc0f604c337f0743eb073b5 0e8bbbd5c8e47a655cd970664873aa15a013bd79489ec55fe7c760b34a8f4d35 df8d87a50563e3626889d856ec2fcff07ba59245ea321981bd7969c4f1a32ff3 +434000 d21127d29776f4e983be2fbdb3aad9f3cf60ec4ee0237e91069d8f8f043b1f51 dc4ee680561f9812215f097a988b8e75f12b4c096021ba854c4c6773b906cba1 53e476279e19d224581389558545e01e305c0080a083833fa8d94b0d0ec04ef3 +436000 e43997e8f7f58da3942ba7ea03ed101d6246e3706de8e29c3df2b190de940b8e 2575c455c5bd152b6d28281bfc685c1d1190a5d8fdc87a109dbfb0f64e996c50 6408e0497c06ce545082c95a47382e1e97e7a89cae2a529d65a05933ef859842 +438000 2aacd0a03ee13f0c1483bc4ea505983461f355920d5964bd7de40000b273ef00 a4deca882bf5f5ea98a8882419db3315581e75ae7f067e986594296ca1202402 8abcafc7634c1b23ce147bec1259fe7fb78239dc72a416aaf008ff18a724cdf2 +440000 abc955cdfd5f7d4bdcf8a8e7e55d8802d42edb4b948e76c2e168c956239c5374 533accec0e1a859ca318c850daaecf61a502a93935084d40fd66dcf870b0b2a1 3f76d36b4a031e9663e342dda5476b4534cd38cb1ee53f6a89489f1d2e7eb518 +442000 efbbbb8ab47338b1705a288d44791781d78d7c9f31628624d8216341d07aaafc b02747b4db5832057334cddeab58a3de4cbf5247d1c46cd4ddf456f2e5b5e4bf 619d1e53595f296eca36dd62f8bb4a98435cb71f93f9cee90a5b54aa10b4a50f +444000 ceb14178ab4f16b9fdbd926f1a293c0771d827635ec4109c06a006ba2418f040 73fe4ac7e87edd0e22acbcdcaa16842835d7bbe1bdf564b97edf16b03f0370ab 9e324be3c68748152fe9eaab5804a93e91ddb7150dbe6dd9cf804b3335c44402 +446000 10887ac91428eaffd67c9d9d0e121dd169136d2d8b691ab556e11bde74a057ee c99a472569b51de427d158260cdc7ccf2fc343e153b0d4ec13372d05d6a25f45 05b85704167a0a0c686adbbf09c82d7cc62433a08ef75537164bd7836f6604cc +448000 aa1bc25fd2d2925e325b12d35ae560f5a2602d468cc4e9124c6e1035c953de8f 5d1b3bca727d3c9ffafceb31856fd2b96114ebeba5d51f58f9033eb81314bb26 aa1c7ec1b2b4f32158fc2a0109900e2431d07929a8605808da70558faeb70bfc +450000 d279277f8f846a224d776450aa04da3cf978991a182c6f3075db4c48b173bbd7 734e9ab4cb3724fd1f2ac2f8a9669549f999d252cfcbdf702fdb0343b07b9136 f8be0edf37d489188b56fbf9903af118f61d2561c5b5ba6bfe78ec9708e2ca11 +452000 57785e4a08fa71f616e73d580c390336984864fd7b20d1fe8e1c7ad87c76b165 db72d4046dde84c9981a2bc8ddd03fa14529e2a681d16b19664745a7348752ef 704341915eab9b3a90c1968580406d78bb385dbf0937fce57c83438765018a02 +454000 2fca1ea8de14f5cd2b01f08b32f1ad79b2e701d0b26b05d25f923ed852346c16 e16355c618125089bcafd897253adfea970f1ba45a5897b15f1cf91b58966753 84fc7e7fdd9dab5824ca1463e2522340decfbeb06aa05b8ca2179a77faf49f6d +456000 f1eada2ff7c7580fd45be1b1152ddc7b6a07b11bf6982de33c1a5a1f42c825fa 0dbfeee0ee830764eb4dabadb12b18281c1ce402d4199698c0b9e0c7382a8cee eac43b735d643dd91619c6a4b4eedd31a92580dcdbb3cc6d2c5f2c994fd57aaf +458000 303de0a55c370d07c428c32817bf44ebff009b6e7d1cf1ee5b0e762754c7d39d 5aac7faa4823a84b5dc3fbc842cc9aa6fa90a49614a461649df03d0d3550f8b5 d4300221cdaee0781eb0b693c3867aa6106d460a4d2877f8632596f07833ee0d +460000 47e612435a646a18289f05f62e7656211f619127e2c6168484f9ac053eb905e0 acbb2097a617e202aa91e25f1abe9aba89feb3d9e24261923a10ba1b9c30756d d642565325b14dd17d8ed903ed24f2ce87d5cab2cf668969b839b0c72a04ef28 +462000 7e54ba4a1db262c1a1eaa3779823b56c1811f84c92e1cfb0d3e47193776701d9 5c7785d38d2175f1f36f23a2b03c9545dea4c79329d20533aa6fb308ae73c601 8e0223ee01e1069c94927896a6243039e1a8f40c31f12a17ad79118e7f29829a +464000 8a72a4de9b4c9b273283595695f4071eec2aac14cf309d88d31ce54411242504 13526f7f7de9a1882017cf0694d0f0bce8467863d188e7569d4c73b359f51173 51267906bef25b0a40660d4cc707479f089419fed9e0009aa6a37a139731ae64 +466000 a67bf00dadfbc1f0bf36b631fc6511940b58e55b06fef95436c46a49b0f905e5 4a80e8e34c9c382318ab3e888123b6ad216cf5bd3124bfbc5c08c240e1cac246 f97a04b772e7ddb4089b97cf21285d411c463383a1bc02dff7d3a1a2172981d9 +468000 91243e5bd687fbe3e9ed0413797402bcc54824d441131cef926fc99b23efcb0f 9d0423c709323f9c196fa468c97a10adca29c103c88a359c90eafa86ea671dfb b0c72abd3676b6e7e9074bea9b4c3c7fe1cf95ba843f55e7ef9b747b09a0a51f +470000 f7425afe0d9fd52e00a17037f3616df8529390016739a007ea6720a80a421ea6 425a7de5905a4733b5f06deca2d69b998a83fd46fec265397277722da250daaa 090b5103bc2f30bdd3477581d3b8bfb8e7874667f89433455cdf962b7c642c57 +472000 93446bc73335133cfdd400c1a0338c6bbce85acfaa983f5dcbb1257a584d1940 5f7e0cc60f48ffa7ffd12e0a06c0cfdb7c11c46f9b42ad72e28d92ffd9f0734d 586274ceb0eebe3878265ef4dd0aedeae5facd2a2b2eddf13a56c475752bbe18 +474000 72b77b8b260171475e4e0a167067cc26a9d7a909b7ea5ab40b93be962d5feee8 55398cb9832c29e22533ec588db86f62d8a468c9d265ae40737feb7ce223fb14 5004cdf2f09f50bf4b53c400c5230791dd1252efa9c382ea5f6d22e507fe75f2 +476000 e381bdbcf14891b3097f0cda175b789c969d42cba2b98c4d4ad728d13e5f8d09 6055c0f7b8928ce50baba5ca806b25ff9e84955dbd2e46151a532e40fab9a532 1b270c2a3ceadda2a448861663d7f829c1b5dd3092408ae880567459fec51f3f +478000 5aa45d6972d4d2fe2773d6a646134564e8d07832710151115c8721ac6cbc5ed2 36a6a717f70be6663cccc2e9253df0c1e4dfc515e7c0c05084a897a2bd262d86 ce2d65f5da16bfacf7bd455c08899ed9a26dd112aa3c6fe6d19ce45841fe6373 +480000 eebc4a646029a3df52c9672d508f10eec18ad73254b4edacd37810c6194b64a3 4f919090362c666e1dde805154a7a559366b5d87ed8a3aa51bd21761f5d9f6a2 da787cd4665c76fd8767c7f40bc34d7a1c3e636db23efff677daa12bf4daef17 +482000 98404bd3bc46d5c922642b16234e5a20180924d9b12975c092329f3b8221ff55 395ac8cc67627a30c220c2ee53dc67e365a9a167c6d0b65d64c1f7bc029005e2 1c5136ccd4c52468f496c9da6c5f3a854e693af8a6d4f6b8322eac1c9265dc24 +484000 6e0fe2a076cda4d0cf946e7f5a818eca669b7a38c57c058cc1179ea85edb36a0 54acf6ca422d4a3a8f0531a0df947a3c13f516e3e9b79ce5be7989438fcec28f 4491fd849ab16d6ad2de3c544470c76907d8382c8722419dc9ec1398f76f4772 +486000 c25c7202bd689119a258f88d4b77365bda92a44ee822f77d905432c0bcf7d6f0 032d7f465db011f6b6c385b723b5d59220bdf8dd490710d1d8eefff359b7e3db 908675bb41fd97923b7c569b33d76f8ff3d1e406372ba1c4e303c297306634db +488000 773dc276cca6263b55238a484ad930bdb661d233141b86a49add135f94837bfb 16b4e1081b82acc656a40008cb6ee004cc3b1d7072b06f0de073b8d7fa4cd3db 8dcbe9aa02f8cfc4ef04185e2c7b57950ca91fb6eb830507894ef449c434d2d0 +490000 be530af679d7420605e334d33b6559e2158ae60e9521bdce1a7fbf70a5749eae 4d1f0486eb2073bf239883433202be16889969c4c33fd1f7e9a022a51417ebdc f9ad78820c6c790390cd3c7b31048444c040df8c7830a7bedc75979ae6babdc9 +492000 d4857abde7bbabc954957e02c22bb41be1e7561f9b42736f5029ec9de4848d14 85f1f2c5d1308efb86fadc6633f3429eda2c4456cfcee34af31aed722085bee1 1585e7786f4f256db6927145188fc181e02b554128207b99027697121f29faf1 +494000 ef562b5f10683104c5016028025184f9e900aea8dc29f9f37cc1155447833b50 3e2382095c34215e413a1f31692a48eca9f699d26606655634e380bade2db73b 82fde165f67c734546794996fbfb49fb442ed5863fbe44006f466cb90aab2974 +496000 f1cfba323c329b2127362ac6db2c74ea3bc789e789e112ae942612809de96252 069df06260efbb4505bafffe486f05ed341cfaf6f21133d588995bdcf301c88c 4bbc0d554174918b20ba74065cba824a201224eec47dfe31b69daa0fbc8994f0 +498000 5401e8dd2526ad87eddb822ef4940e3dec3ef526a3ba2083990623ba99d07e32 725a15fb7ded0988de627b6eb10554e488ea8ca017d96942bafa00bcd7175e20 968bf0ab62df8839a0c075d6b4eda12c787ea1ac637472b3e471e29a6bfd7a4f +500000 92ae1083b7b3c22fd7b4ce2eae121d518f8e1aa81d0be9432ce5aa20a2954fcc ccc71ac0165718954700addb06f334240884a85bb5984eb49589df6cc71e5304 f46d9def3b8ddbd031db6bddc27a92de510a804c79c27fc3bc1a1cb99d33f3d4 +502000 5af288076ade56a3fcbb39eb0f50127b27c8c93a843ce5c210cb1259fb1337ed b0c3a975c5938e274eda46df4830db18a8ce3c36e2211824dfa95fcc37b1af11 5eb29411f83e21ce243821274fbd8fbba2d58f80dea1893d33219e85b89eba22 +504000 ab1a0a2fa1ba8fab2e9c05b5028a6268fe28c387b8246e332d6ac64b6976ca7f 3213ed78b2d3f7c811879739f4bfed02472042e871ffb2c4ea24a8859afc1a92 78f35464e21ada010bd622ade647f94eb37ea7ae909610795a3bb2d8c9299cca +506000 791ba2e7f0e32754dc89d32b4f6d412cd6091137401b819c1e6abd274cc430e7 643ead2e4e677472b67a280b25e71e0eb59f5b2fb1c01135a1f8880c851e5a90 877b0d2c4b7b1bfab5d26dc3b50ccef073cb1b428af732f848dc1d239bc7cd35 +508000 b71f53815842ebe9b558cc5f8d63a268cc703e912becc2a272f7c1edda2c8edd 03248c1b39465eae8a3c09699bb2cb1f55e6430731f6a1f0f02cc5c84f1b101e b55612e03c88ef1974da34e584b8c236c6e998a02990cb9ae0f5d6053c1baefa +510000 a764b5fb9ae94ffafbcae59055be8424f226ed7427b1f5c82ee7234099c44964 846ac5f6b7176f6889081be12bdec67af146da927eefa1d4a5674816b66bfd51 f624e45cb824530d14e6dcea1321c910fd45de291cd75ef1dc43ab2163d68b6d +512000 28797b58ad4f9cd4068eade4de3c67de5e04380320b5b709e6184351cb961ce6 aa5fb756b7bdb36b12fc07892e3b9be8e7da13f0f7b1790b7a02dbefa603ae05 75e63ccfe824d22e7b5c9279ed1a40ee4fbdd6d9459201cf6a67898527699d24 +514000 6c2659e9d81c11360ca095580118a642d8b0c9c579322edb65f066b35a269f85 91f4c2cee39dd7d0745061037824c929143bb88c2657f66305899979be683de2 d4ec5ac58c7f1a673a22c871d9d08207404083f3c1c17dc251c4f6b5210da733 +516000 d9a8966627864fe45def298f99f2281b00f7c08878ec35a965e205ea39c9ce8c 213f11d5617f665de03f08848e4d91b720dbd09937c2f5b43f37e22997ceffe3 0dcf5e77a02bb02ae361f80a64cb4de0bbb1b038db13c1cb9b944e5bc00d3362 +518000 81e7aa7124797c61ae24e674b35f8dd807f663df508c992f90e17fec28ab1d83 99815613bcbc9bb72d4f84c9851efe395000f4c3490317a8611ee81884c8dddc 2582e2c251d9b4a962e62cdf9efb80b66b9141d3f7f7f57e9b1e54ed4057a81a +520000 babdfd32954834fed16a202712c8858986cc2b39e705c73d65c55caab7d34d54 3f2e38ff121c660ddc94ec599896cb644bc5234b59d9a25cd27d6f33d8605c15 46d79614e272b6922a04ffaa5b0bb1f8c82b28c24d9fe664c5c91cc2aa768a90 +522000 99f32cd2d589995fe053ffaca283098950951a1c3928042b62a3666fb9b68942 f177efe13b3452748947095d600abdd49a5a4e4b37ea78ac1519feba49842751 1e6e4aae75bcafdb6fffee7dd1f5f2ad332d0f2f3d0829a316cdbeff0af86835 +524000 921f993eb65d7180cd95a6e984caa6366219f3c1f15f8f727afedec24ce8a45b aaa5a09f69e0a753bd89572f5b99c3c4a21fb4b3aca512dadb7111349a159669 eb9abd2f069dc66ad37a6b2716a4cf9c2b32834088ef3841d9ebd8931c30c53d +526000 7ada3c2f1c7e9793fe1222315240ba294a484e452e87643b8295e7013e6c3ff5 c6afa78d688e685b5ac9d88f7f8feb101263448479f1652bb7f6a667e0de1a6f 9e8a68c6393e3ff0fc8522db8dd770615149cc08e17f572aa9cd66c0cf7dca66 +528000 15922ed3df4925e83a28f70eee0c3f438f38c5062e43e56ede961f0d6b40108b 96d004be7cb043ff35f6978b35b1f0907587349f2f70b106ead651aaaf12060d eca2d25de6505eed2133ddc69cee687af1d78a150646fe98aaca888658bccb70 +530000 7cd71cc94593d01f40319e84fe6bf35f134fca081a45d835705214b8e965dbf4 e136bfabbf1cfe6cd06e052693b93dec6342ff27ddfbefcfe33a008600e6acde de0cc7d96ccd4f6eed9f893076e7d1dfb9edd9295fb1902ffd6044ae10064bba +532000 7b89881b363898098ebd0aa7a3a32f28bdc58811480472f6f6df43c0d11d9757 ff1f2c0c352100fd55188f57f899e671f4d9a7f41777e78fcec8a4bf0cb0ee6b e486fe4346e35fc2c19c3cad7f34c4750293a06aad99e10f2c47c6feca98437d +534000 7e1fd848a62ed83f1bf8b813bc20493e51836f0ba6dfe580115530c5dc367e1c ec61dac0333bde2fddf4105b5eda366c4325a050ab4edf4265492c965071698f 947175740142dc9b52d1b56484b1691a03b99a4d0536789a0f05013224e3ad52 +536000 ee2acb45101171ee41cae267e5c4ddbf45f2b2fea798ba53f62363ca303629c7 aa4222d582c2666c98e20094e857b03074a04e2a048a699692430b48570e3478 b2fc3b4f7e0444fe49872e31e66f8f44c52f643a2305faaad825ef6f7a76a796 +538000 c11c5e96b2384d9b5690ec3542d0067edbcf34fa83f95ab2a8f268ecab93b8b9 793120a64749a339d340a52b1f6d291afb6873e38c79ab8eb59df2f3c1d9f89e 6cf380e80b1eef5ad1d8eb8393dcbf7248ddcfe0a15cc5015f6e13ab66231037 +540000 6e0564a221be2c7862b805b15f0ec422f31f94217a56be19d40b9ddd7d55961e bd8b9ed64439d1a8b019f77b5a2a973c96a3872f70866e0f06dc7a7649e49291 155b7f553083df2b1b0f9da6150f17fd0678b1adbd0dd370ac5c1ffbfda1bb6c +542000 760dd0f723940b8976dc6b98f85de9d531e61712899dd90107b19de9bfeaec91 2022c73c0958550a86030052afd048e21f047b8ded013190f520be5b06d237ce 72e65f58cb915613d81b719a7083ea9b7b9f1309133ce1485168314d1887980c +544000 54b220ca6de759291cb2cdee9d0036536d785de07be186d7269de6360b350b52 929e6dc205ea23a5da7ecaf7e4d1c6383241ec8c287fc4b4c350d185f9ea2a43 9ae5073017da00fe041dfb2ae80b3e2016f48db27bf3bf2f5f0fe8ae595dc671 +546000 8e9873cca8e64653b3eb8acb2894c89c224c8963233115aa35eda6d15f9d039e 8e8126a6cd07babd54a4baa129fbcfd9cfdc66d04059de93ad63373064e4a429 4ad829d0ddd978c5a40a14d24337bb75481632a7003814ca45fb5844ccea71d9 +548000 6c5e14c6af1f7345e32bb013b022666a8f6bb47df3fe6976a575bdadf58a1fcd a54f0be2af9bf2337ce87d3fdee1bd782ec4939d0864389fa679da1be8b2d6fe 652c5281d5e079ed406ad21bdf6a008e8731992a0a95cc97b3e8dc78d55fdcd4 +550000 ea8ed5430b221549a6a26f104b424ffd782ff4c8409bbbc5eaf3d83932825691 6c5e9fd51d77cf95ccb20593d0bc0e386141f79ea642188088cabc47444a626d 2f4ab7a2d33b8cc9af6459ad9f8914f5a4ee599fd75f5cca3f531eade5e4ea4d +552000 786c771df6a381999573636b580c25f8331ea4067987b351528abda40b8bcfa4 d562acf04cef124684986b6af71230ac9a8c569bcc493141b277b5de5e285196 e712fb9c8f1d9d1712aa40f941bab97c05b1f702e4ce7cd6aeef72d612276114 +554000 34b938796524410bc5227203e171f5c34f38c89d23328b411b7fa96b36b80553 5c4909e63fbb56470a71ee2065449de2ce59b20c0897c0861b98d5a9ea49cf66 9121032beb4074cb6b5a3db83ed330afefd4b153a8e607edbb586e501cb12eb7 +556000 8fa5909fc9a06486cd1c1e3c065ebe8494ec5883e6b13299bc98620837f780b4 5071457719f38b6bb13c3076feac813ecdf11ce4a8b37cd0bf4ec9e4dafdd020 b6d88c1b36a448864cd44604c0828a6bb9610cf51f77711ea14d81a0725ccd14 +558000 ac1d8c399002bff0c0428e8b25bc117e352ef5008db422321348635826c15b27 bfc7db6a2dc7f094fa3ab6b4d5d05a25c405a320558141bc0afc1ddf5b25ac05 5ba51ba927837c3f6eb47184f7f7991c3197ed676e52a4f86403f7ef944b4f9d +560000 6ea94d731958c0fd57ec5d58570e6c8d72fb0a72fe63a9244fe18c32846c6329 a183d978a995f4173bf40542fefbf543a967f188f7811c761dd7356b7a97da82 82e96c3227cde6ef5319690359efc7cc460cd62ca0fcba7022064207b15bcab5 +562000 9359fd4c2e8254e94aa0fe80b42bb0f6380bef41c0e32e389ca93d8cb209c721 1927b4213e4253eca6e0bd81d4dde058446b6457d2f155214851ce55fbb63512 1147db92b7fb02ab3ad5e58136b1ebd697691eb135a29fbb806fde7b9a584ced +564000 266f482fd89a4ef17049b0c306e4a2ceb8ac173ec43bcfb522750bf915caee9c ecb164f66ee6859a85145ac0f36ff09bcf03c7d1b4817abc803e04c49ef2dc41 ccac887a94e7d452d9a3e4dc1e9a591f5d2ba0ed94dad4d8de6016d772415933 +566000 62fa44ec790f53dd682342571247a3063ee93ce636755ce13140478ba7d32b7c fd2999e8376eb1ce399a824aea1af412e4d4dc4f668fed28a67d7cc57a4bc7ad 53fbd85d28b6b34617b329c47b922bdd7cf2bc1f690b6671eb281fd88a8ed81b +568000 e410a725507b53aa130da04d487b3d6d4068c41bbcb021570f0b7c8b3a5819af 4fbb1d682e0d3d364a57e3517420e37fa2b2249644d9d3f645b8db09b576f549 18d372d29390adebfd5924a6ed4d428ba49918123608e64bf24f0cf79436d68d +570000 04c56b6d89df925e0815e92a150e0f7cd60753494e6fc44010dbea6e9d881596 13e61ba0f25377f61d814eb0110a5e6088918f5b7b74c4a86530bace8a078b74 fbee0231d6ddc190e19b84dcf279ced86d575b939025f009ac7c1052988aab4a +572000 354991380611300cc1834ea781c297902fbc4f260a2b85f711b0d2a205be2390 c57f980f1355ec7fd188551d5b8132faebf418ff91c89cb2184e25654a058143 645556f2d86cbb02225f9d253aa020f40bff312ad0f3e154ef0e934137dba710 +574000 6ee054b323694074e550bb48af598c53a73cd357adc80a2a8d0c4fed8b4987ff 7549f20012dfe2beb8664c5522d84366c7fe8c15c9387082f144a97fa1af4b51 30c7c327eb62cd5f21e7bf9129ffe056f12e153e879570bce6f5857c15016d9e +576000 78dabb5d8b5ac9b4b524d5e976bc4526e69b10c381c312d6b75ab936125f8c81 05485095579bd2d3abb55cc023d6adb6e5de4eb06343c3efff79ca8e785f8a49 4d045cdce0f87196c413e1211a6fd814fa512230843bdf2b1f45cd9a047fde01 +578000 6fe81f11813ef61765f050ffbd82b594f9c4ea60bf0d65285964d1cbfea06885 7252868dec9f0a57d473f6ffaefe66b7aaddab1f4eaa1ced365f399b0d20a025 7ede5327ded4fa690d4b6e997c00e84c768e8168f2a1e6e7b336de7d727f86c1 +580000 fa683fe120136e0d6ecbbaa21e780027e7ccf0d93c9eb00186d55df294d67686 bfea7204dafd6a380927e5bbf93dede3587068e39417d024b22c86e440fb67f0 32d44a55ff66ddf48c79b4226bfcf280c86387f2d64480351b48ce8af3e30666 +582000 536ce1924053b8e597fd2351b6db0ab134eb34a16761a1fcf1b860cc1c6f670b 2e671f88012b99d2ffd6531c3db82b39c043b040ca899acd9cf072faf03204b2 88a715a9b75d52764fcc00698b90374161a06025f439026ca54fd37df3decfb2 +584000 534c238db57a5689398637c346fd06bf6db4444d00d1dcb13356bd80e2fb20dd 7797aaf2b9ee1a7b34db5359c4d703d7001d0a67f3259e507c00d4537a8523f1 9fc6e197a137ccfb353c94f4ad863d01c2506fa48c4b108c50f8d70f54fa0851 +586000 3738083bf6099f28f6efa46375564231a46ca1e867971647534fd94af6ec556f 2caebd9d34e616e40fc7162f5d2ea6fa48da6dbcb5cf17455d349a9ba4a36b8f fe327eb2bc3594ebe8533bdbff353fc62867b07b5d558d35d545bc1721d18827 +588000 bbdcc4e2ab92bfc1dc437d3f79177af85405ee73e3822c6d92ca9d12205343c6 e8481b2e6f907da1b79609f5b1229db251f58d76ac6e7c414d6b1d986b50d083 0d1f5e16ed6784d9c46fe24cc756378aa23bd72000a96e6e9c3d346f5cf4b10b +590000 55a6abfbe459a67e9cb1d33835b0dbca48f56f6556d269452b4c87d5266f98c3 22ae2884752b63521faf79e651316a27adf3130aff2e76ef159e9c8769dc3085 3eb6d715304787b9ef4138a1f9840d7be2421a159a75d17322a02959e741b69a +592000 aafdf557dd7abf2831dcac8e407b47e933a27922bde4d3ab34c32cc6994454a1 64a670fce8c8c916466691fc4c1d4ca10910294d377f0548742e62c7082d83c2 13021f2e6f43aba425af02d56dfbe03496c06c9328d5273d6bd34dc45e621dc1 +594000 5f8ae230e313ab5f16fc86d29bf115942aed743cb0e06d201e61de7e0e608808 d944ffc56719d0522df8ce34e1c800af9261f864931820b49b35da5378de9ac8 57ea64d649a4bd387fa379b6a1dac63ff571aa860b6ab8f1006f33bd866c9b26 +596000 7d018ecab6c060097a2ce159d2f03c18abcc9407aa827125783079950906dbda 4ce7e94e2c976d8ef8af0e756c1d8222b884a6e9fcfd794c130db7a1b3dfc896 aed84a204d1a6fb934af3d3640013269080a81acc6309c28e16538ba7689f92b +598000 93dcc35782771c61da47cb56a98e3d3120adcbc31c0fafdffb36e3ea29bb1807 78457f6c3c39b52af4a385435071f210ddadbb7bf18f7f460054dc595b4d07a0 facefb26d2abf0fe6b94f17a188b286cde773411368bb103b4deb9141cd1f10a +600000 caa5446c05c8e51cf7985a6cb4da4dc2b730e4ec399dc95b2a094df6bdd4f268 2c8faf70e61e67bada7eea1b7a24f7de8defda472513ebf62af18938fae5749e eb058cbb071b0e4b224f8dd9feb82d1955028acfb864a61588866c240235cb49 +602000 7eefb9667cc02a7fea2bca2d5d0f047d4138175930019d020cd4e3f9f21a5f28 1cd437c640d256308305e7cf520b64bdffd35ad1c6396bde89d11681a08bc188 1ef3d2f9e8a6bcc0570a36bae11fa22f4a694914100d28bf3fb68f0564eb9c0f +604000 b3196252cd0d0d025551da83712e2aeead44d7386fd7ec7b0027f79f87fa9dbc ad141d77e3582f724bb4d37fa8efc36168103a7bc41b413e2a7bc9feebb9de82 5c2fd986a5342cb3275c9bf365140a2a06d46ddac47be255458c5ea7ba56d7be +606000 2a6db7a82cf59e381bc5c30c4e9f1321c8f7abf2f0234337bfc1f8d21964ac74 05e5d4feacb09029befae2edd9c6c4cded07164cb51b44246a5df622faf96c58 1dfe46f6788b75c67fe20d36f594258bd973ccc2d83e90d2a5a8812819e4ddf0 +608000 fc4a261f98223b70ef9819e91927e318817dc046f68bfe85527adc620298a14d 0f20c27b1b34c531dcac0e4bb784e7aff8f6782fac65e937704849c4da9e0f4d e651999b4319ebe5f82ebf4ed48416d295f7227642a7f13f4eb7d6a70153112b +610000 7a56d6b769559a5721aec5788a3e3a5d8b24b17a83b325a270f1e253cbbd830e cb64b3b5a76725695bd7f2893266352aabeb012b84f77c6992d57b7da50ab7bf 4a0bff67ccdf9f0c4114eb252819ffb1e46c028ac6b5c9133eba1a488f50b8c9 +612000 078ee369b41a707c9b0acea2663882f9c23249f5fb02f4f549bc7d3732d9aeb0 28a11a2c3a9d1e368248be4fe823e95d6212bf514349f4d76d3178a5c76b6f5a 1f1aa0787bd0546054c708500e3379db8cf2c37b4eb98d3ac47b256be5a3a4fa +614000 53f5d1ed4aa215b9743ea7b94c4861be6ff4f8dfc9cba4cfeca23472afe16b81 82d66002974170f1eba6d048fd236144485a9f14c370aabf3a57f33b9fd2b233 4b8c22728111e5bb469881b9c73b031de0508fdaf3aa989f6bef8906ad560f7c +616000 0b797b912920ffadef6f83f362300ab178c0211755b6ff499f9887ba7a2231eb faaed33f56d929425e84f5e481434434ad9b18ac76f1cc7fce3227d4e0bd4711 295101e05d7354d32ed60092c23de7ef3b62dcf370e436331dabf0b70eae32a8 +618000 b4ef12b9006f52ae8711ce6fc1ff96e87716288d899317d2ddd0ec018d405d3e 657306a1fab4983d74b3da48459f633fc05bdc94591555a6366d42c317953ce2 e8d79be153a17f36d0e2b99db1587bf10ef62b411b4a5c41e44fc1a6ae4afb75 +620000 79de322c325e3af5ddf79dfbb40b3e9ee4acfd7def017a920cafebfeb307c779 86b972280fd2c31be654ae1ad874422d1327de54de4c22c8c784fe537c08b925 68a7fbe4a8d06f510fbf24d42b0cab5018d220232da75d8227b9af04a34d2b58 +622000 920564b758648d5deaf31ae63f8182ce8ff00a6410b8f8b84665e147d63505f7 d7948b38c21de9f438a9df32e1f4f045e99d0e466d251fc2c6f6f3c524bec082 c3239c0da15424d7db9f761541ce105ec95485af36507661f2ab00519dee6597 +624000 8750bdeac60c166ab155e4e943ac88d70a917a2532d255cc97c560ba680f1d12 3485743c9d629fa6fff891a6ac1f645bb5ddd78adadb747603b4d74fed9960ef c025c81565d46f67197c40a3eba87dc65223276e696ce6c667878920f48956cc +626000 bcdee40eca67eb2e56e2f3d3755e9326d3ad8ba16ee12d54a1d4028225b51cef dd17d47ee5562f8214dc4e8320560912add8bfec011f00030026114d5b2bc9b5 385c910d0ab0e8435896470c3941da045f6b26cb0b5d1aa7fd93703429bd70c9 +628000 48d57842f41611a08174787712695fa7667d76aeb395171b963557845c2093ff f20fcc43c1cb440bd96c986aee72bc579a4ec792cd687c08965be98d5af27390 3807bccf72c8918a81654a7594786f7ac31349e500db55ca1de7bc035c1b6e4f +630000 8f0f166538c58b9b23ea2d0884fcf9ab9026f93e606881540c05c73446217e23 e1f379bae0155b1067b265c533d26f87dce8ab57ae7c934a632f42f86e3f3fd8 916bdf2b1cf50716bea920cc640a2b3ad37fd12ccb6ef702c5f7ff878610eeec +632000 928de1ecba4dc13feebc932566b81df1f3f85e40b5fefe1770d29909416cbe79 98a67f3e2bd4874bf151704be4d699f7177d2ec3b1fe970e01fdff2e4161ca76 293ed6b7edc455434f56294bef05bdfb63e49b9a40fda244518a1d7875ea4759 +634000 7cf2b56b8d9588ded6c2dae42211868338d4bb56cc2d2521f0538ffbbf3e62eb df4ad8d75b3efaa68ae19621ceb8bcdf081205706292866f0b9dbc4e468f680b fede76d1b73b4715888d68a4a671b518e62be36e64bcd7ebb42aaf046ff20d8c +636000 16a55ea62aa9c025e8c05218ed7a8b255b35667bfaef8bfd4cf554d0bae16298 ac3456f629fd6c89658c9f9a9e08c48ff682cc21c05c816aed6b9ca31f22104c 28936b62879448c6c5c3cee62ad2e6c121457bbe30751004bfc5dfaa7de6865b +638000 ad1391db8ec9e07871c5f6130b208ff68c669f01e2811ff304b5f73223da75d0 b89b39b778aa1108d78361ab1e82cc5f5212929f2ac41b2319f1e97a0dc0e667 5365da3beded593b1d284f97e53478754e90da8f26112e0d908071a13215edd6 +640000 830fdf544a5b57b375f6e5777a134a9624e8f3c01cd3b1c9a2825fc3e5d3e4c5 8a141a9a85c17da463b551f56ab1ab3358c9a3eb0f403d4a6c7813e0dfdbb2fc 33c757da5e13e87f3b81dba4a655eea587d6143802bb9db0fdafcdf49aaa942d +642000 2a78f685c049dad5914bee96f7ee32f99a8cd878cbd5b5d0ec7334e6b0d95d5e 3b274c64ddc9a52e7a80136f05407f15c8156bbb816ef4e15496c7047112de0b 30312ad144fb22d9cb0fea96e5540f583d5e703539d76b25e21c07e2a1619dfa +644000 6faae7f7b07a70c18f7f02330b0e45a70e868cf2629ec74e23f5176048a635ba 38e6e16c8da57bdc8a407a9ff3482c248f3e1af324a8297411a2b8b168f2cedb fe6c488709afb7ab30ed95db84c68e7c2efe37199850f95c9426e8247efd12fa +646000 a106f669d91831d427e238656ac69749002d87f888ccaa3b8dcf168b05e195e6 b49f43302d7bc818fb3e7e6c3167ebeced7700634af452c75fa5fc8c7c12c64d f903ad1b2307d107149e5fb9b014971f7cd7e6adfb47dc81b24557fa6c34fbfd +648000 e877ea9053ea3b35f46096046ae8ea991b03acd6b3e38857b3afcb46e5dfe3c3 9cd4dd65ee1fc2f9f607c46fd4adab3082a535f5250778a8c7bf390265a4ccf5 328b2be5d2f35defefe8fa3798a0f7a5b0d7a2ef816f2f9869e6e439aa70d316 +650000 486fcebc9a7288676a7614e1b6fd085d5d71019aead17d354a8bc2c3fde516e9 3bea7f47f4f2c02044c24865f48e976668db4d10d0b45400155d18121177da28 f8d6be23c5bc8f469df30080b73a3452afb973a71e52050a4f93949a298d52f3 +652000 4fb21bd654bd461fed9765d4cecfc4f1f60a21f984c0470faa0924513b2c6959 9aecbd591b86b716d27c380634f04acd45edeb15a061330e2192a95c2c8f4e47 485e6736fa7cbef179392e473241377dcc4f5872aa7aaef13cd41c9703717c7f +654000 983e66909261693e49c42b634d36350da1f51703adc5a05ef0123d287bb15633 98dec397c220e1492e1d3ae269f07cf8d6db1386f9c7b81d1c61968d2f1d529f 2afabd36723c9bb28a1bdb657c9b675c2dbb800f55ffbf1b5b9d92b3c12a6cda +656000 d3d42fe7b2acc7dcb2ff944a326175f6d9dee04e2d51c1e851a950da7a630abd 300f8d211c071b15c3796f2b5f0ee62285fb09f9f4014353ba5f111f59e22d8f ad333506ff96dc5c5b60f5abc81d324a088a72b175e86c7a4ccf09374619c679 +658000 4010938fc493a5c5d749305399c4d83ed98b6ef7b662eb9a8c9203c6569530b9 46880659b91abc8a920c66550d15ab9ad818b4b7da4eedf6dad0b27731822835 dce33bf20ad50847093d2475e67212384b3e9a577979db1840c29ec13ab0ec59 +660000 ce3454f697ff04328304e4b5770cf3349432ec5f3fada6599f6d6e7eaf39e993 ed0121a303b3d7a018c0dd1b1178150f6a9626f808f6858a531f30c1993d945b f081ce516e7ea68156fd24b318edb72690c12405d7b1abd4c3bbcbc9b0dd9870 +662000 20b6ba58115bd1d34f09156f0868d1fe6ea04eac6dc3920c8846ae757e4a9fdc 85e9918f6485d404531444a565d05d6ca3cd40ed6105207380e24da10b5e10d0 1aacb9de824dbc7b68f4a42e7d86c04674b3f6c0c5648064bd543a361e48e1e5 +664000 60d6e0a0ae703716b4c1a7789d2225230993a2c71e6358fac25bbf2c328b89a4 d020daf4964f0dc11a821acbfb17e840a04a359c3ecb3f220261f202d5033049 823d7dd199248673184cf5fbc279ed8532d53f8e906c9c7f03957082774bd151 +666000 14bcf9fea071002c96f2088d434c2ce1963652a45dc42d3230be8f7663d5a517 a698e8999e9f76a236ce168a40b9f17e53a75fb0d7cbaff722d609332e6900ac 0ceaf669d2d81070cac765f54f1b0760b3faf05ebdf30a50e3726cf4630b4151 +668000 afe47eee83b60efc6abc550fb0455580181505105fa0c0bb610211070d3969c6 2c1a3c2e844a678b2081f5b114efff0b5f5f4a628e474dbf52278eed8b87ebb7 279d2514ca6adc1b03b2c87f1b65f41304b8e441d01168c25be8f6ae790a30ad +670000 5f28ce8d700f4309bfc683ab239a1b514862cc26571dc0a2928fd9ec7af20e47 95eddede986a9bcbbf38163e8d90ebb78b39f07ff8188d9cd963fff0f3cf35bf 76c9445aafb28c31580c2266cabb007868fe54d6a6f5750688df239c3e0f5d61 +672000 df06177209559df88a598168f45fb474476a867f2e2a47ef2c41cb1306072a67 510eb5f087c7c9a92a0fd54f3612b1e9ddf2465e82f6d03038ca11e94571a9c6 95e97856c06d47baece25a69443fe09a82756ea011ee9f297a2818f5ed5829f9 +674000 350f0592f04f354090d964cab260dd05226f24020e5b2e5a5bc7d31c7728f1e0 b428302dd7b831b5afe5900fe6743afa0e539f542dd0c8749b9bf0e8af8102f3 c0372d0552907847ff9aa3a2345f3d4c60630e7644e9f3515768aed4aadcc730 +676000 bb44fd5ecfb3e9b7d4678e0513856479e2f4ed56c3735ed699c3dbcdc6acbcf0 499750baa77ad2d7338213f685ce49fc36a8dad74becb4dec39994519778b70d 6bcb02219f58681e8bf5e3338aa87408e77d277b732809339e1051448801a044 +678000 503417cb876095ec641de8bf5232d5266ce2d5201e9b2b85e6fcfacd2091ef88 bd69adbbbbc7dba8d0dba9915046a08da034369be95b3e09759e1cfcb8ec485a 89ed5ff005f7e465af25a53c6db84b910de55ca162f9c726f8153cfa867a90d0 +680000 783d3dd16676839df44b4713fef24dd51d29403c63839fb35c2649771a540910 03e07f92f121a1ba0fc0e0604838f9d3643feff399a5a7ce3c5f7f2a72ba66d6 557fc08de37a70ab40eebc2262ef607c62f2c9be73877102a21b54cda7f445c3 +682000 2baeff36d017067e0e6a7ccf56fb9fb819f108019feeab8fe467bda364c3a2d8 faa78af454046c5426c7f24b17e7d37d5d92837586f9228f0c8bad41ea3a032c f8629999feb903fba1e4e53e97e5deb2d6ffa7654f9e25903f37545c16eab8eb +684000 2ca521598dabb4d7cc3c9a5b0bc73216636dd21a332ac0b8f9ae7f9ad6c588b2 f21debf3dea5a30979a3dbd0bea7805f6e87d3b4f223ddf1e0f43c965e27f317 9dd6b844dd5a547cc05e562cc1bb21afeb66c90b4b66df8d4800238e55fc93a0 +686000 39d5fe0e54242dc9f93579566457a7eaba8d31aa60b22425b9b29f9389a370e3 8aef7d5028b855e51a670a71e01c81769d0f047329ce25799b03cbd1836354fb d855727bc323bc032e5ec32222ccdb645e9a2e4c5dcb07a0f0ce74eb203a975a +688000 80cd55265b0e1c6ebb1bb0f728d79ab65afbda09f7cbc190d1853dbc99f3ac4c 76d4ceb0e6992e1a0447b1b2ad4a4a3173629c8bfff84d509c132c6a7d8c284c ee26038e6195381e95760bd15619ffe7b92e26c0c0171eb4b5afd982a70621e3 +690000 ada369ded0f7f88ee1c55df43d63be868fbf44b507a1ef8c5c0adc185fd321c4 8486b3469acfb5691ebd1a9bb48b8cf536b68267ff6a8f91b8028cdf79e0c552 955e79bc45d7afceab6a644a12a6f8320bf011fbd4bead4e0c79da7b4326efa8 +692000 730199a7a14c0bac6e81962099a14934a66103e417037a7639df92c6635b8e39 74eaea348ce94ffd6c674418b53d6546746babf5eafaeaf7424cdfbd3ccac2d9 5cc9c48da40fbd821ad6cf92214bbbe3bf6a92fc8fbb677fa3f42d8ea971525e +694000 9675f03656ad97faca422732b238180fdc63e2f290b875d0c985b1b6aea633d0 9765c80aa5a803264c00a2f54ee3166becd7a61e8131ed024a092c5896202e34 57d8b9ed8295f50d1c35b3644a58f0eaa5c6439b14fe5d88ad00665a6fbe335b +696000 4b8e235a390524fc95df0fb7b5cf919022cda162ed6083e694bd6f2cfae86993 64022974a6f6eed49fe694362c1d2cb38e6c85508bc6d2bd7ef40a4e1d84ea55 c89969ba11b69aa5c088174043ba8ff8c0a24f80d4bce7f7b6e707145c468eff +698000 28ee92312c3c43b5bf5647d66f01d2a405ab5859d53812b004c6f52ecada70cc b1b40bc316a7e179815506a938c9bc25869e15bede92b9ddc9f72a3e16f677ef 7dc23d2e88b77372d9fbffa6965925009b4b21eff231f07b8014a71795af3739 +700000 eac853ae22d59a498386241a3de69a36739ccc9e0a6acfd617b64c5ea4a0f4b3 02bf295491dcd82b60ee884575e14ebe7e82b8b301a36d622d7b2c0f6ecb380d e01678ccdaf67334d91ebd87ebc5d8b05b87ee30baac3a8422c086db2e2c1ab1 +702000 c82c0468d84c76fe6e1bf8e0b83941c8540916c55786ea50dd02251ee9779fc2 52941ed1012ad1f01564ddf7265a3483e9b5966ffc31616a7f48e2b9e592c311 4a28adf59bfd99f7f4b800f7c29d24bd5917e839efb6e51bfbd784d5458517bb +704000 034c29ae383a0c414d2719a7679768e80f698c8ad985ce688467c321ab64ef60 2a95836fd6952a0b050bbb033ec3f72b596b00b03373321e98b9b802d4034753 ac4ab323c6a94cd5cdca6837633f630f312612fd5d41a49623cf962dc26ac944 +706000 ef3e1ae1b46975a0c329c3b7f8c6c260f786f1683113683796aff8f37ad4452f 636673ca7970678cf73cc67285982b35e7e1a906e08ecd5b0628e1aacfc42b41 316a6d20137beb4eb617bef96d8be574a920351b0d0b8a22fe583b91a6a60dc2 +708000 683e76ab9c00371a40839958b3f0ae139dc2caf7537d13a4ffc1a0b893308bec 05df4985d6a5b87284d3b4b501152a0fd408a3eda7ddfcc7a451b7a4396ec9eb 35c50d0abceb444542a13f59eb17451882d35ec66106b8cba53dd9c484e62217 +710000 c74dfed3602166c31e64358635e84c597bcffafc38bbd460cacc1e33ee8faf44 a3a661aa92f04330b8a992e56ea68b565951b27d8660c42f874bc572004451c9 ac07d56d37a2a9ae3a23edd1a022f1c3be829b9a510b9447063f05959fbfe3f5 +712000 73d707220dc4d57888175666e41b0c2417670be8c70ad6a5e45fa4229911ee8f 23616c06fd3570d468682f02a010531bf42e5216f4f85cbc20677607c5a20451 756e64146a5ebcb7d767e72b62f59d99cb4a9e380c403c4a46d74c6ccd6af70e +714000 4308570c0be2c5145577dac3d513ddece8087e1c888a9edfa376ef62fc9557ac c9a2282f3c88d9a751c805e722750264eb0ae5e594eda7c0c35f95af1c3ac788 a876cf9fbbf6682b96631cae127d53825ff0fb3932e5e188047f20818144b621 +716000 7ffebf992585a7b02b0c0255807b57ae99dc8a7ee0452c8a1c5bc71e423e0d07 e0ee8dfc0566b47651c06330ce1a13ffac9d43ded7e5f1a2d1b678310dc7af7f 8e959336de823256ae445c939806a3cd66bfcd47e04bd1ea384dcdd0b3c95453 +718000 2402506604b9a49a6f36aa39d36f9347491553ae2858c457b4b485f812673a31 7c3db3800106ed3af60ae44d471a01bdb8ba3af680e39b5c5a931718ab0d2926 14b01627edbe2cf17ecd6b617e05a514dd519c477341b79ff215f2c181f127c4 +720000 b0e31bbec1ecfd1af0c0797e4f3670b5baf3f89f66d9c7e1f141720f4a07b4ac 7fc0adada1294cd007417a8cedb96a9f216d2f2fbc9f95bde15bf17c63bde7e7 91c58b50b0195e8e65fcf2528bf65412b4c5ec3caf2a37f7db1fc9f234fcfd31 +722000 47be2ca2be1f8d2614f2de2973808f70525fe41556ae2fa42821b975dc542462 c7be29f4aa82c249e6784ee99ddc298c3ef8034f31ccf10c15f98863d1d97209 8cfebd7848444889d2d9e2d07d3dbdde0e9d99eac924425d8c91460e69884af3 +724000 0b1847e00ec3f0498c078722beb8b314c6757b3e75ce72d611392197d314643b ef03f6823a5689c959c8cac5eb0252985fd1c642b9370c78a0e693da6028c616 da7ae48f6dc36e6bdbd5a3cf0b88d1d1de416ee518b81d71cb14570e1411a8c4 +726000 c9f128e6f64b0b948e0e9624e5fd522c3a60719435e52e6c29b200ea0610169a be86ba18679eb65803d666f0df2a13ee1a86a9b08810893f34b347f60ec08d31 f51b311eafb4d10393287cb5b8f59cf1c8058e8c7ff493f72994f4d483de0838 +728000 82fbb9668b2927b3a758aa792bda8b79f3ffb2e826e0b5e0f0125665ae7badab 9b3e5014ac40a3386215fcf405dc2d9abe2ea475b3c4938c6e9741d5100f1c34 8235c9c5fea19eea3495a4c1638fb417d813d67c39afdd75e65702c22f68714b +730000 c55c535beee562094bb1cdb02987d95a56ddec83ac5a199fdfe5e4b5d7e55d29 1da7d4b961ef1f62cdbed063eaec777d279de9fe4ff6465bcef8dde11fe4dbb0 fbdac90e8f6ed6845c60e2f4cc9e3f4b5d2ec84390089d50e3b777889ee305b8 +732000 2c1fe22096a9b847f788cb665dce5ae9df22714a49e73e603d3339b75c1474ee 583312ad2ea39972d656b3cd6925eba9c4dd0a8cbca066844684fab56f7605f2 ba1a15f4ce532423ebc3d1d2964bca31fdbe45e647541ac4bafc2dd35ea124bd +734000 620efee45906bb9858fec22f1cd3f659e3ab1fe30d8252be56bb2ac0bf5c1cfd 6a84340061083ed74a511a9fa87f3db86999461a90c9aa58dee90af8345ce62e 0539b5f1357cdb8356a3532c513d9864b72b0cfa7c5555472adbe54686ef1d50 +736000 736e8ab2df3c29a14068e9ca83f6dcc1f679889e1331104228c52e1b5f40fa42 8de052f0e55416714d7cb7aabcac530473709d7c5db2dac941c28e065287268e dd79b28873d6de973ffb7b215b8811966307c8881b89f2c10ff5b82d1d1d729b +738000 58cb76d31b597b0ee233f457cbec6bde79d0ad513803a64ff9870fa96c29a2a6 d790e1ea81cdaedd26dba60efa0fe5fe83425847b1f750131fd7ec74aa1f25e5 e7a8b88c6ee76f64532c7fb986f30f08e592766788695b023d0f82b12d87244d +740000 d709ea52011931bf3d1f0c207820855be7834ff30cfbb2613a003460b74ca2fc 4932eca0637b261f4c7e2aa9f388209818b0760621cc3c3a7ff041b184aab2fa adbdd47ac86c3f8cb9bfe7eadf62c26f05baf81d383da356a1e61085dc4a6308 +742000 f5b250420e4b1135f35f9ab2af2aedc3d2e2432a729957a7191a9313c635b75f c2448ed0f0a473e25967a59d21ee431547d099b94d2517d03ac4a541aaa2fd6a 5e2bdb58699201772faa683d458bf16543b7cfec830e89d6b2a41c5b1f7cdb49 +744000 a4710976573d8cda2d86e7cdc0525c6d94ea7cb36473c465414ca4d04087ee17 57f59c7c1ee2c8cd2d8bbca0cbe54775fa70ac98d5917bfcfa88518b0b9bacbb f932c1e97fb18491c2e78247504e76fe70d9c7ca0174eb9e9cad13876912966e +746000 10e0b5e5c093839413343508d620e6041d9ab22ac80965ffb964c8e62f19afab e3f1924fd147c5c121389de8e5f66d946dfc07cf647726d00ab4edef80c8d170 ddc3d1cfb7fdd3824bee442f79e7f50b70a4bbb27a202c603ac9f2a5b145caff +748000 065ddb892bbffe8a19ec99b512355826f803839214ebb81fa02a61db819bbce6 dbc0763ce723a38d4ecee68a8a1f6addfab8381f0ffaab87d00d4eba7c7eb288 4e964c4645386f6baf931979584310604aa6566684fe039c79c965f5dbee361f +750000 bac1aab7cc53ea104373df9b53fe88cfc8537936331de0a752e068268ddee7ab bef498215128321ef6d75ffbd17f94b7a8d7b3f0f9542f5452e12fcaa87e7794 0c25b5dcbee84838a7142f9222195274041840ef628cbd73f1a18ba20d0378e9 +752000 e3180ff221dc79876679ada7e52384c24470e24abb1e6f51398e84e6f4a7ade9 e3af94ca488c832f5735115a7cfb77397d955e61050246b84908b8a0836115d0 4eedf454c817729a54f3104106b3a1075dc32c6d813ea7b866460b8b5694ce61 +754000 7475800eaa63b5ea9b7e0ca630f1c9e6856d71375df491cb00830e8c4fb5cc5a d75370da5138bc16d6d8e707a8900e95b08cb6c01c30ae8661db6a7756efe808 bf87c16abf7443fb8f0b8c6e2b31ee2c7b0bac03604051b8a013c61d58df3253 +756000 4b0808ba57715d38f24de483044941b1e7f0e5dead88983f1e479dd172d72991 d83cd6334ef39f8d3a28b4a61b156a774be2a17e655bfcd5d0e9be40ec6d1075 7f538a259c71562e9ed221a4b3c93d71c9131ac1e0d91e32acdd06eb210ec43a +758000 01e5a73bbdf60ed14922d720a75617ba1cce9705a40e293c43a9dc8bd1c1be30 8e9db31445d5a5c62aaf0bac4a0702887d481f36dec12ca25e12d153947b0f1d a89a122991157498c46cc3246a9457154831254b65e287f2101e7180d4567214 +760000 2b89b6785d957d83f6f94f0d11551a30e923b08514ad4f611b91f03d0961d0d4 21d5e1fbe0828419fd12e404908a6b82bac7b7ae13bd5b26424cad97659f7759 60bdd3c84e7bf2004783c63a575b041697905bf5d0ac9b9518e85a3546622dd7 +762000 a6cf604f10e65e4e3260330cf63c2eb5a0da3bb100d8b73485200876a9b8d39a 22f6c1eb0b4074c962b125b6b0ae7c03b4900c34b7bf8bab1ea68f6c57a9e0de f70c6ffeca19955457002b137eee4370c972c0f7a2390e124e88283c5077667f +764000 0aabfc5c5f7e71517d6a6c3029c9a024fda43dcdf5a90b9ed12f2b16583976a9 1aed4a41b9909522266d1eae183c3a983a204e4bfc729b94307a60cfc33c8323 63da2e930dff60cb0e9a4e87008e68963cbdde1bfd0cf18d2b556f79a22a98ef +766000 0dbe437c3ca98b2f2720d03a194579a9a1c8604c50da802302989e4aad3e3b6e 5f131a3be1e31f5579fd09b131580adb34e846848e4748848e55b395d15e82dd 0ca69b044f822412c907a0cf0b6a9dd1b95c1dcca7cf872f592321e6781fe517 +768000 a56aa54aa0e5242f5edbb70b783e68c4db639b4126b9bb2992454ce8d7bbfe96 7c9b1b7ec1d53090b175a61afd9afbd11ea8d01fd7e2470d8c29ffcf0bca0990 4f400cfc1d5a2c1a2685b53964d0703bcb9a4c5910fe035362476cc412d51e8b +770000 2b4b56a935905b90e26a098ea4c45b4ebf7c34677c9761952cf01f74e9734eb2 df411c1c5d0aa2fd4c44e3fec4769463f5eb4440033ea8022728bcc9f16471ad 1bafa1fc4b7551d848586074b349ae6511cd6ea060539599a11b52617d6453c8 +772000 6e1e1be84fcd7a1d959fa6d084f2241f276f09cf44a31cec4d4999a4d3cbc7ff aba21af673921605ac30a0654b243a292e2b55ae1440bf0125c987e9c8cd4eb9 7fa90158e31700de3e1b23aee20a4574dfb5a7f312fdc7a9210bc0c05d6c3994 +774000 b04303948f8885914c8f202519e8659cb80c779707dda1b0c39bab53c00af750 090ef50fd6d91e8edb8661f49713f43ee74f990b909e60470f06a765ae8563cd 5df1a8e3b0b290660f5809ccabfe60393bdde8558c5805d7fe1ff914dc4c946d +776000 ca26330b7e4227985697ce74e390c21d3b6d20c53c25bd790f23856b28b4ee96 d6ce12bc2bb59a1f63e1d09f5849104051acf7526c94d53267878fb27674170f ebc9f1d23d4dc90c8ca3523f8fa1b57bc40b547f4b50d22c2d392d2084803ec4 +778000 550ab857aabba109d130e14747b968270e24fef295ca078114c29d2ac99355b3 dbb0ccd4a7f8a31a2c58521fbdb52dc3c9e429699a3d309fc564d8587f383707 c5761932310167366bb22dea73d4c7d01f5e2dcd7d3d04a24eed18084d8b2461 +780000 f9853fd4748cd756384c1506289b90c2b5d882c93a8292f716537c67a871adc5 babcc95e879f42c28276066302152f5948056d17acd4b628e78263e6e7dcbff7 46cf395fe9e2188f9b82abed2691ddfb36d4a6181d04f3208dea8a8cff3258de +782000 ea0599d4fd1e58d142f19c72fb90dcb2223834220de021b97cc11e71094b22d3 6a3612cd14888072c57a26f55a340deb0327d067175a706fa1cab16bbe158db9 1217aa9bb0b29a6756255a8c224fa1332165cb040d1e327e927a61509143ade8 +784000 2d661447d0b6252742df73b23ac35edeaf02cb9f0113c62656846a3dae9bb5ab 03deeff8908f0d42e8a8017f9b3617a5c88c68a121ee597f8ded08627dd5600e fae8fb4f366751cb82b0389f7a92e988e0bf6a8393ed7e6fded2e4bd3f3032e1 +786000 efa4550c98c8f0d65ae8495163950dca7b2f96faf8841182ffa63e2adaff8ae5 fb307714e759ecf729b0fd51001160778cbd7a186cb33a1b4fd7bddea03c7d05 dacc2b056818dd8a7caecfc099b733671a08e2510837b9bc773c7224e0d2806a +788000 6824d4a5b566248f4c7b7b06f4ad794cd31b6ae935d8aae851c7bf279bbbf571 fcb3e023dc8c5a6eecf608f2d93487310b1e2243a0a41f8eed6d9c4009d510f7 7f04930e284fddd9172fedf5da58a9e114e79723ec980c82d21686c83dab9cfd +790000 4a4bab5c17a9133d3eb022cabd20f2708035ec5a805d9fefde215c13b36c249b 34fd61ba4bc9be606607cf8b4ed34a1d694f2f9eba15ff6b002947db1fce91d2 ee9bd133d1664474bb8eb25ab80186436f4c5ca7f223c99cc6cade4246ea7115 +792000 99f347910a923ababbf079f2910202b133167e202cbafdb5fe6bf29e5a6baee5 f953fd8684b24fd205da0716d27109c3bde3da47745e9350f64c7ad1d30588ba 5e169712ad82caa74cddb85d8db5e433b947ee6fcf5eb895af71c7ce76cde9bf +794000 1982862314342afd90950466df9d70064c06c7ec309b69ff572b7cd1c0c42f8d b4d9ff3e31bd6dfea339a2a5d5e73c5e6a0335f4c11996daed34f56b4e6afac5 3c9e42b554729c8e26c4bb28cf839768ec882d3792e1b6fe1b098e42f6262392 +796000 477b8b7f9ed7046e1b1f91b7693dba9ae9c10b08a3abf0599cc12d50c3182b5f abd9dd9c226b52290cab0929d35a3e69401cf3fb7b3e5bc7f447bd4ba1f8b0df eafdf9af6079f2d46824bbb6e7ba66f4d7ee11e9c2416dc0d5e4323c79bf36a7 +798000 d90d29667140fc8558741d140974848c864140f154959ee4db32274b1f7b7160 641cd8d470f44524766e66cfc7966efdbc77bc3e4d2e218b890f49794ea6b694 33526f73fe39be2520d2f92d6e71a39308bdfd70b23d11be3f13392339720526 +800000 773fbb34e1bfe82467eb24cda8769dfdcd13a5b4dac4c8f9f6534c40301f7fbf 8f9e9f7e10ba269f38d9a4afc8d50258597eff8cb4ca759e35fa27185ee5920d 914caaee84ced43e66636b083a88e0b6ca9b906cd918e4182f31c8a7bc36f03b +802000 11cd60b97ad30c2197d3b8736091bd35009c806bf0079050af3bf888bca29bd1 2de064d5ff141c0b51047666468490e5a4d1938b5ba51440bc00a64d493d68f0 f0886dcc573ee53660d41d91f81c49d422a06f8867c2cf66d1e675aff782c2fc +804000 e8ae02f5f8755ea5280acfb28c5996690c9bf2439d717ee867ad884b4260ee3c eaa69c4a9763bf7054539f7c855e56c13645152d7cd815052f1772439a02b02f 445393d180a4c0786169c44ade9e0c335b2b118b615e39baa6bf916425c21adf +806000 cca0148029629c0d4da77c7183133dbe05430cbda851b16c995c0388db5cab0a befa5d834a5191fb48aa9cd7aa5e7b8345dcff4e9bd19db9d2eeab0dbd237afd cf497f6b52afce4ed3865453769b9584aed0f15817fb8ea423c84313fc6792f5 +808000 0eb377f9ba4bee37341f686838a32c7fc7aaedcec95d46990091b680ef2ed51e b51851fb5f0041982519a4d832fef9573d7888c157d4cbfd306165733a858f85 27e1a36a9b84be63fef14de274e4a2c057fd2d3b49aad50e3d9338a1ee7bb3cc +810000 0336dd9fe27ef2723bf450a5d725abfdc70ded8a66ba30908a25a6f24813ca1e 09c12a0c758ac6694a1ec671d31c6c342376d1b354880c4e1af2f6a410ff333f 9d269c146b7f23b77479b07328190ad0d76a5b7c2479cf2972b7c8c1de0b4fb7 +812000 1cc30267d226647e8dcb586a2376eac4bd250555e4c547a28972c243b660922f 7dea7b0b8cc239f433686fb6a23531b801888a6bcaac975087ab342bbf4d82b7 c04c566ae605f5315082319369dfd2036820fb95f44dcfda7a184aa0f5404052 +814000 1c2762ce87d0c5800f6dde4e7bf4c93718d146fe23094699eb14d4f2d4c4a2fa 6faa019edba2b5070a29115552297a1db453049947135fb63f44fa1726185679 b9b6883fd773e17ffbe32707fffec1efcdd4afab2c0571e9209a846166a484dc +816000 6056c12de9b68a8654c9dec0e9e22c01320c4f1c45e61df407276c4ff0562320 6c07473fbbb00482b54893cfb06ea91d28715a5852a3b62bd3ab47a511184c40 5159b88cb7bb655aba4bd859773ae613432d5868f6d2f9c081e17a0ed7d0cde8 +818000 7206d7c5fa4c81effe1638e689923953fc67a8d2d702f21b177241d6da0c745c cadb863935807203cfc91bf36086dc140955f34f3fec57298e65e2f224b2e0c2 4fe333f3c506ff95f5cb2204625c6cf722a05943ab3602eea6e83f87bb8fdc50 +820000 261973e4b40a1ad0add09a6eca168039f0aba7bd6411b7dc91cd91fe2891ce07 572c5b0b57d0a6c868075d3fef51fd9f2b7238d65b32910bce7f73a50177b893 a640f9898ba3223fc7f02624f80797b06344ac3f2b6134a96beef3bc985b0fcc +822000 4380550bcf3a4d0fa1616dc1586336ab264f7c47d513485c62ba3675fe7897de 40d090a0a83f1e21ede2dc6dcfd8069035da248944ae933ef03d446a28c4a3c4 f8401e4086ea984fef3adbabfa1ed536df9069543cb41fc4ffaa2815b80c82af +824000 d2f8a3e86fa5d36ff92e35bf2179d0c57706b0a9a7dd2eb8d0dd47155bcd37dd 0ddb9f8133f544d98b715596daaa6220de477d870732d1b2eb7700777525e82b d83177151ae5a5554c219d15a98b1517ecd2ad25282cec3146f740850196b38b +826000 339099025fc67c54f084f17cef958b4ccaacbea089d561b4fb80208bd0e77af2 bf38572ca270a8387c70c7ae71870426ceb58842969cde8e2fd350a016bb7f5d 235ccc481ed6e1ae9614682b08a0e3eb9cd1edff871489bf910b2c67a99a8608 +828000 38ab2c47d4e3108bbb3b4749836654043200db9a7977538570ecbe8e719d57a3 ad78d421a78b3963cbe9bdef1ad1a1e6bd5f0c99e05c22b388b8973d2a5a9fec 25af04c0341ab58eb18acf1a36dcf058a8c10e60639ef68f28a4a6d096b5f03b +830000 b3d728abe618c7b79064b14a86a4d971377b5a5930493ba6671c30b1b67ab6dd 4ded63c1349e5e2ff1a7e7738948ed116f854c5748fcae0e9e58f71c52679b69 0a0b7b3029489ac4df3147f2ba827517c088e7a3b7bf6474462f78024e72df58 +832000 10f5979a7318c187e87edbc56d717a842d4f1f9555e6cebb4c361b4d37921474 6e1ab12aa4530b3f653c6ece0d9710e1054d57d786ab37be14266cc679121b3b c0e249563e6f9c7f7a44b2a830a746cf53784c08af12571198fe83396596c1cc +834000 6958459899034c2ac6cf7f39282c501e0c65cb7063ec3b7107ea64bede24fd00 998143e547a92d007a2cf7d284f5b8d5936bb07879407571b71a8b8de8a79419 e20507bc6fa6e172a503bbf7f84f9a533ee6c621feac11cc54b307f16e9a587b +836000 a1851881c61b565c58ed27cd9efa033588b70031a739d2270b4dc4166d0522de 8add7fec5a837af86099b9a940b9e31639a9145c512c7ff226b7e653dc2ca72b 15ef6b2c57aa9ff8bb242a25fab6fd3959528ac6cbb854e44ed33fcab420f1ff +838000 3f1e966752405a9079c780a2c78e5322686df42646f352f8810824e3c91125cb eab6ba6dbd0d3fbf33ffb3e866f84b3a0119460e889491aa16a0d592a27b3864 8d1861434d37bf5b9cc33f757e5965866e02248fe5da1118bf40d0154d9b9261 +840000 e6e1eb4f70e5824528461daf93a7d96a18284e7e1da64bea6d122ddf57424604 c4669103655cca39e10d6a8efcd5e11a05e009356f90def7e189da7b64dc43e0 519cde11b6867aecc73d6d78e3d9cec7c95eb49423991fba0d23f90112502abd +842000 a125a44f56b23a716e29fe6ff00150201e62718b97e86566358cce0567fb3f69 e39c8f6c0f597fc056fe87633200d551a7dd489681b41596e42ea36d275f3fff c096a74f9ca637913198a2935450135d90aea66508827d2b9a008a3326d7cbc1 +844000 d4715f45775fa683d6761ab09bcf2c5ab3ea58fe0845db4928df6b8d5c3ef946 2c4d6000f52659267ae84e18914a4f3cae11132cb8724f6843adfdfb5877f1c8 f6eff6d3b00dc5324d7ee363b99e3c95ef005936c1f4471455aa5caac63fefb1 +846000 e9f820d135a285625a3fba06ae4c62f3aefc9dd7aadbca14509b9fc53f3d8992 172929bdba6b38b7e051c9accbf9c6e5ba7131b0a244bd32c77c1514ac47dffb 9afc8212f118d43ab6d90963e4de2bbe04b064e0cb1ece5be6fab4cc64c42f97 +848000 16d7de00e932fda3ae77db20c8f0a8e5df66a23c0bedbe263ec854cb851021ee 177f5c17905e8cf95238be43e70344cc835883b92b52b165cc7afdc86704b98a 29a8a223a1a58220877c912e06da207049fd38bd4ad78be88fc92e7b4007e203 +850000 8c8fb1a343fa97ae6db59077b4c33fd80831788bd8a81d41eb35bf19390c6d55 fa02d86484cc48619b779fa96429a9584305e048e4dd472d18d29b1711d01275 231129619e18f2b04c6e781554ddf14ec6be06f5cce54df6778ec9d18ce65ea5 +852000 5319c328231bb4456b16b290721607a3c7aa61da0438af6a1dfa7ea04e95a95e f04ef300f86762f3dc1010e76e87c63aae077a59c148af837d6caf79912b9b9c 08a96553b8a3ec1dd3e92fead780e4df27166af2ec3052d181dfbc43f87be8fb +854000 453c17833dea53c053cc41859e676eb5f52d1a477b0b1f8b37ed8f6bc314d0d9 11bdd1be0b3cd9d23dff39febee821159c68c8947515756e223a37325f4d960d 6a60745b70a36d09be48e5152b14005069c9a5ec8594ffeef38fb92224d1ef4d +856000 e7f1a2d1616bf780646a6b0b3886672dd2ec83c0ae90bbb1508b2f1c13c91011 6296da88df729e773051d1790815a6c2665a3ed33d89adddbf45548894624cfa 96900bc1dc3b9e522e18d7d3c3321a601602b0b0feabc3b268e9daf410b5ab8a +858000 f8200f7de56b54c44a197931e7a3351288f28eb3b279803f7fbe5582d686dee4 d1bf96d033c6d6d8e9c1b3a71b7f051460cb33d2a1a667cf6d0ba59a4973671d 6229c1242adbfdb2d724f35f3617ef287577fba4dae280d7c47af903ac5cbccf +860000 a328fc467f1aa0e955b8f826cfc91a22a37d9166550d3426127e1de6667a9f45 0b9ee034bb3abe045014eb10d0b7889b114461b81a98709c5ad5e193c92b049c 352efd7e76abc040cccacac04ec68829c3990aec4312401a9f26b5c8f6e0e443 +862000 709ec94558b1b52c3620906b0231c58d04b4e5ad6c38c4bbaa986b9022006709 9726dc449f130fad44a42b111aa53982a6fa48931dc95e300f6bcc74f86b6b94 59f68a624f5c51468b99c2904cbf6bf70628585d8213d52f426f027db07d1751 +864000 28c72f90621569db6f8bf0bf3deabc6fc606f855648d56564c36ced4e2758138 cf8b94e35c88c241b55f52d5f0a99bbf6107583ebd40d64140b599d7cd6a9fd7 78709d67cb89f637a614104169e1d1cc6795554fed612ae402f201031ac8a9ee +866000 5f5ebfa915859e0bfd2310e68bb7c90bbba04d3cb2b7d74f7819a99b31fe461b d1c0b574f7b8b930d7caf97f5f553d524c45c9661ad77f66117d5a40163f60a9 ad08f477e924bc90718bc3ca8e414439d868880359e86ca1de61d6a1c260a911 +868000 a823a36474d7a9849004aefcdb4bef1489719767525065ae5efd4af63e305eb4 4a6b5915e3619dc073a1ae44ae1b31224e1d2a5d655fb1692c78888889c0df5b e059ce356e33d69895f9112d1b96087335eda46dcf25fad79740b3bf3c32a2b1 +870000 b61cb6f93425594dae82ef2665403d437827781eae6f0350782f30e843163c3c 19e20f84e2ea70d8724252867d8c67e9cb447815ce23f19a42e086db4bba25eb 5d5ac63e9137a0def71dc299da41730bbf1282f33f55d7b3ece7f6430e621ad7 +872000 f45f94debcc7a80dd324b2ebe01d343a91aa5f45d631639ff30c5150f7fe19cb ea02e65af7e2236f143f39890e017ede148f66a1b5482ccb65bf0953d63109dd 93bdecfc561e368eb0351a7fdd8120d76f5a554bc75e479e8811bbc2f3bbd43e +874000 c6b5a0ada73a9e422bb872895e3a52a395ef11b8af56707b20e0b794393d6595 62e5ce3162896e4ad31f9c94a4b24b4f53c43fa84056e7177a6793020add4ddf 786ed341ba3751d8676629f22d09db0bf03967c1aae59c58bd299a2b216a5449 +876000 4f9cb91bcd2f7451a18692801830799feddef6666850cd71a765c844700df5e0 34700f08acb6aeaed563993ef07bb5a499d0fbfb6ebc89f0608158c32d295b24 6fae2eefc4360ec15c549cefdfc83bdd6a783ca8efb2051462cb94ff38abe1d7 +878000 5a215f8a28877cc55abec5b27932b0c74f1c6c391c69d90f99b9934ddd640120 494ef2ed94fa37b0882cc6bf3c386e0e68236e6c0dcc79b38bb49f0dbc269b36 e9a4840324d70d04e5d6d7c91a1c0e42afa8e115259c5e528ad7ae0709e1482c +880000 1935413aee9681a724c1ca2b2b14ac0a754310fa0c46fcafb47e207945abe220 50d00929de97ab49e2ae00c0736f3a02fe9ae5a27071b9e3007c633e483701fe 5c1e33c30369368d127892ff712f1d4483b24cc5f6b109f7a04c34b4fcce2ad0 +882000 1e51be63f49c286c988c03e513b6cb83cc017b6a326e46455a4293eaf442e3c3 b9d1d3697938950d9fa16204869837a6f48e98f03d16cc77b1adb375f7afabe1 2ecf66221e7db3a23578ce2bea1c64de87136a2bb22bb22b4fa23545cd3e54f2 +884000 1b3760261642b5fc154e987160b1e4543de9492d8a92fd52b723f0e78a8875c7 dd0d2c04df75029e14a30cf2322c903860ed107678d6a63803a9bb6c1d851b9b 9cd9ab86c41f658d0a7f4b5d854018c4d057f7a29fffcb1605a5cf016b5324c0 +886000 23171f1d5ebe910aee9f84e0da098d363ee337824cf78a8139a22ff5bbd3fbcf df7a7d058c37107f2f11d4b21f59255984e5e9833207fe3c2fbce5fd25e760e9 53587769a478b522bac634547b22755d35128d744e94486f7d09ca1b914c2e5f +888000 163105ea1a66cb42f4ec9ad19e31969e62e9f7830d7d67cb0019836ccc67b410 1e69a92f80a696c6459bba482d340261ffe70d37aa021b60b15c9d2116d45fd1 7bb91c449e1485c8b15446b2c93790b6334c2f85b27f3f01e646498ad90c9374 +890000 67d72faf3c193fec8fdc5899cc127bae6371ecbbd09df81fd74834fa52e09356 c03eceded53e0efbfba92911aaa99f566df0065793af05171ba84ec02d8e1a68 e3d2943f0320bff607449f2aa28aa6cf42a1c35b121f62687e350f56bbd95de5 +892000 4ee3b31bd1086bd91057f96ec8d0a8fb3a8269597da3c5b3369e3ce1cf8af1bb 090216b8623735f8d84a7de5baec15da7849ba37a210128d6d9f8c334f13d298 2b8d33be122e0df24f0132834a27124b4a3dce5d27e48b5a7eb4b328a3dff22c +894000 556013f4a795fb73d34a9c505250fc265d298a01f3804af718a1a69a26ed381e 54d27cbf1243b850a49d5b8c42b07b8a1c99a84bec1deb3c9bebd091d3dc4706 4303a086c3ef1b91b0d804f6ded3c089fb09f31320c785d1cc720bd2412ed223 +896000 75f266b5dfbf768ff247867c1059d3b9f90e64f7ca08cbf6d9d8975a048c5f39 6220ba7375efa888feeeb58a18b1c9e1ecdb54705bdb19301e2df5863f5b4601 532dfed7fab337cef024295daa2187cae258e24421657f21cc11eb36d8919695 +898000 028c6902f793c66b379158ea04667399e5d97ad01e84382dde8c743da80b3f51 675e6eea5835d7b24984eef58e045486f545e1acab2dcf10f43bc313463b091d d7f230b46e60140d7e5389d9911b1222523baa00a3c288016cc57031a12c119b +900000 5235e97ba5ae95c04300daed8d75dca2ed6eef9be42d433d985d3203639a4a66 b4094cd8ebc0fe2c4710960848b9703410e3230110789c5802ecc6272bd6120b 0ba1bd3eef58b04d21d7242268b6c687b0d5e5f86cbd49022b119ae84b00322f +902000 a2d0722d4b578a274efde604f6c2f1da2abb57d67cc5475489ec2e6df2391def 005823249238787d614a55b7cf2b7605ccf21b440d289173b7ffb0145ed49af0 abe4324ec17395b4875df7590e7288688b4fdf402f828b574b0e4eda2128361d +904000 2acc39ae27a8929f90aa91c10e2f17ea372611460c1a8a49985e55f72013027a 22ee218a6a29b7d2d69c07339b4085eb8731faa8343d3eda3d32b2a049fa6f89 bfefab250405be8b32982cafd52f3ac07c75b8e0b79e451a406deccfe5bddcc6 +906000 363d3c83dd4f62c58a0bcedd6689b1f6f322393b1baa030004ac4a286b8e962c a9ca330198a583c1eaf869b9bc7d7a03ea3eeb70f0bd87958d18ffbb9657d7de 0dcac67a6fa5e318ad7450afa9b2be007124721d9482bc383e39a63ac866d5d3 +908000 0a975a84d257dbc68138f0e334ded76846bd6d894643116b6a8b7d55099cc16a b0e198c6c137cfffc9849d8ba88f9f82e6a4b19dc2f471e85aa75069e2748615 c2046e6d4113bc713ac3896330366c05b06a4ec6c5b4edbd187c1d964bedaf36 +910000 22377c83aae2a4ad5d9962986b329683221231a6dd5e52197aaab5b38924f5ba 40d07899040394ba0327bcd2663929b465361cd03345395abc8620fabd0e983d e68da93818d9b3c0ce3438538e2a421081da7bffb5055ee904a8e523ad7904f2 +912000 73fece8eca21cd80ad7bacea9ffa40bf1d4b61b871c84d7804fce9c19e18ef5d 85ec12fe3013daa5f30ac21ce17dd3590f6dd1fccf6a36ad0f05fcab75e5e5b3 22589e4a9e6dc3b835f6452bced8be517a5d1fe6615b17b0be222ebca6d5abd2 +914000 5946f4c86bb0b8e0d2de1fc1d0745747ee660ae312b1ee11f2eb418e4200a268 1bfec804a7b0ae2f7e2abdbf62d408da48f937eed9669cae4786851416eb5b42 12818e830f5f621539a3a36c22a3efaeef303459cac9a0301a11eea0d2888a64 +916000 399f80c06a29909a2e3a65d850371d62fcb643be045a84fddb0fabf0f48561b3 0b023cca7d807e19bb25fb30e290a6992d8e467c082f9b222acb341115ff65e8 51d06150265d4e8c69a290acbfc14711dff32a436c938e1e4787dead34daa6da +918000 6fae7262db933c05b82a433d72b315b082e5c641204f84f469169a71c871ca9f 3fde995912a82c515e91bd967c54607b0afa2ab4a9dcdf011a959df98f345c04 a8b2c1eb8f4fc6bfb6b8f49581da77ec6ef9119e0f8130f1832984b1d44b32ca +920000 83f5883c7094413c44370d70945e0ca9dd6bb57697a7df48ea7ec10dff002502 2606f6eb6c5026ec8d1eb71caa8bcaff5bb1481c5911e9cc9acfdf9959a8e866 fe8c90c39ef1e2dfca53545908110b510907a1f53454c63387bd94e85c35b6b7 +922000 28743ed782732aae2c37c3a223a0a9fbe7310e37ba0d9b45e157ae20864c035c 6db5c41de36b9bebff4b837c02f1f915a3f7c544a6ccf775593dc0b11ff264f7 6ccd6e381ecd19e9e4d308be1906d78326b3f3dbac169655c036386d0d1754b0 +924000 285a6d1b58353a68547060b2d8fd863f7bed0b1f929bf0de69dc5d9ac0dd0b26 d4b26fa6d1ba32739cc5bba6369c17009b1cb5d7fe3c9b69b50d731f88cce980 6bd024c9f9ae81256c9bc9b664b9a3b2ed82e937aed6db32fe703606fe848a26 +926000 b57031ae691815f333aec1b30b07a2ef4d65137c1dfdd4d7806e888bdae1bdc9 70145c40e8a64a3958c555d43ab521e110cc87fc3d19c91ff78ca5b5644dea6a f77c5480f9ae734c566400f020485a688cdbdd7df2359a948a41ccebeaba49ab +928000 a9eff9185d5ba41bbb6f34812ed94fb488ceb4c0258493f65bc16ddcb23a14cf afa8f7d99362a866903bdbbb6ed9da7e935a3e03376460b88ff7e5cdbcd1fc4c b152a62950205fc46c47959fa78dfa8ca738d7d80a7018f631a5bf60a1e4e435 +930000 6261991bc3d11a34a65d44f79d7111b0240c4a4ecce54c6179ec6da3090ad2af 17609c2e8a0ced9f1b9b1d6d5b5dae9775f7350dd83b8c4a148b95378b0d890a 41bf916dfd0fa01fad4f6358950b9b2d858b6feeb7a0338d7c71b71f1f6f8e0d +932000 26ad8bef22cf0510cf5444638183ad66e0603af21309689782e3d3140250fed6 271d205d0ed17e3eb1dee1187c53770e978ec804f64622985da76d88c05cc695 2053b5095cf20e1c39760b93d82cbfe865e34fc34a2f5d56ddc97c019b41cdec +934000 aa7d8fd524145357596589996d893ba32b168928e5b108541040f7c2ff9c995f 957005247448549d0f6f628f275356de778e8df5c3105f78320814afd48d3806 f1715f10f0d4a8bce2f37b024dc23dfaae808364908312c8effdeba96f9d38bc +936000 0e669d0f40c872b12bd0ebc73acc86752d3b36558c668e77281979d63c3cf04d a0ba579e53c35861cf27e15395b63a7e8e0f2acc155bae96790610f1e2cc7988 a0fb4e258111a385c0a40a413fd8021ae43f8da716ae8ed5bf0094f45d4e9780 +938000 8878c145769dd7fe51e917228002494c6416adc331493535231dda42fa2b3c96 29d0785ec0794b2f49717edab081571a11446ff56e99c4effeb2f0ab8096ed8f 462964bbd472b987f91bb753b5262d4759ccbe7ac25c24ecf89cb5801719e5f1 +940000 6865a73c222b8a2d901910778e217fdc95e7495c108f9ef85bc4b3b43911e4f6 7f7bdab110f4b0fe7e32e67855006daac30d09ade23c276275d0591fa6af7da8 bfb8cbe12cdbaeebc85a9e93c72b0bd7163a58ccef50e1770b283eb27aa808db +942000 a242c10eb8915e26ce31edb918c5a874521147531719505cc034db15688d2b1b 7767bf46d1262f62866400c0b4595c43bb45c09b1444a4ad7c5870567ab58009 0bbbf6f20efc5f232663c074f9bb34b008e76b0a33cd5aa90c2c1d6315b43418 +944000 ff051c06e2f710fb43e278a815c80b23dd848d5c91f86bedd94b763e4aee219e 5d1d95ce98365ff447e4a877f5e50bc7b810ae59fca072b8fe7faa30cd041ed4 7b3302f8fb7bfa787642be66500b71870b81c850b9f11559baadf7f6ca712076 +946000 cdf473a23dd2ecb67fdc9422848be4b68ba332afa6bd98e914436a5652a731e4 18b292651ff7b0fabeaf11aa007f174d70d77d6788bd35653cf698173e7b7231 6284050c7eaf97fe0eac291d3008b9159061b0db021bd7afbc9df8cde82b1bcf +948000 540d4f310658a34d8a7e9227876f3567faac89ea31b5dd2a5499c24d2ec609ae 3df515c8178ec989ff550fbff4f0d44a898db139a22c8205235a462379bcd0e6 aebde7d7d3e02ae1707770bb8a5c15c8b9b3eafe073070d25c1bb1f61f3293f9 +950000 437787fc4592e1bebaa6f0eb6421af1332c30c2e57b12ccbebf6ca7a82b59e4a 6e195c4f6fc1ace28ef9a1ba3ddf1e488f0a8464ecd735c0d00ebdf8f3176e28 a2e8d8147b7e2c1449c31875a4bf33a8cd3369590bef9c2d4efe74cc97724775 +952000 b6daa09b8380f5e0ce453905814b123f3c0dadb6179ec33c907cd8063a43994f 0b1df5a2edc13d024c4eeb2ed7b2b5aa80e084182ab7ce5bf37f008f24730616 a09443ca2f0429b1e9a2507ee0b1eaf3f7aed7676612a23b2dc377c2a30565c0 +954000 d9d5cffa1894853e6767628b0e8b1b2089a7a1af484bfe36a0c93e8a8cfd02f3 1afe700ab2999ee3230beede73706fa99d8ee2386f2402611445345b938ed3a3 070f9d32a2cdd85306dd8835d77bce74654e39e3f68c1c978c3d6bc75bca2dc3 +956000 9441019fb3c4aa8e948a0da8cc3237224c09f3b7422de7e5dcb516077adeaed9 1cc1070e6e40959e6691e7fb5170f5e7d410ae37d867187193018eefdc9142b0 4a559f1d4686a14dced19f005fe77a416139db196019d6eef0091e88d5462f0e +958000 1772f29577d80fdaa0e7bfe4aeb587475462a179f90fe33c528451bd8744deb9 87895f5199e9ec7ace78990481fee3956fcf1863e585d4e40b50d5079dac6fb7 fa57c7f445f628374314b2e8f8803b1272f6f6571efd92db7d4d950c09fd893c +960000 e7a122ed2b0733ebc66d789eba549ac7358389e74d5183d1959344e6cb69d1f8 ac4f44523567f2d8882f7d6b1ece0ae05888e983b07077c944e74da6dff56b4d 407fcb4b1487920ff05b5c180abb8f4b32ccfe5741805c75410e14d61d3a2f8a +962000 9ad5b56bf3b691c6c9c9c1b6af89948377d977fca410266b57357bcf34210da8 6d79d030a3bba694d08fb88ed28244a5088837c5dfbfd150bd046acaad4d1aa2 88c34821422f031d579daeff05c7e20f53e3e274205b817c9a151b1b237550ce +964000 052939ebbf425d507c0e1520ebda46186f8f0db4a56331c7fd938f32a98a7b20 4af53813f04f22a3e4e93a4cf7f253b6b14ffa4ff30a02d8cb3660828254dd65 64f81d3481d21aa5e6772f40c6a4ab9ed1d1d8822974677e81c5617d9e78c8fa +966000 e770c1de2b8271f30083f053e2ab9f54a0e5d6569a874c9d6450d5041c2af02e 81fc83edddb0753955769487be6d1af8a281cb97b58d78e757638fe39d23df38 a59254477de919e22d1c4dd8d987d2e0b5b655eb86170fbffb0c85c3c22b5a8d +968000 451136323de68a5e84f15542b6c2a1ead5055097976e9f09f608f1c6bae1467e 1572d572f7e3fa555a2987791f4bb5fc609b5fc6c6768a9c579450eb7072d1ff 21e17d9642019c9323f5f266d7b91ef1901672a50dcbdf570b2c19ba27f75f76 +970000 6d7eb7e7d911bfb864a35e4e7f67a9ee592b8593215f657e479d0a17e6c4de66 64fc5d229ffad9354f708dae75f5709f99241139233fc19e7d1af451812c592d ec26ef3f2a42786f1c99ade0458fd46ffd97be6664c9a3c052a42778c34eec61 +972000 1d7f2d5754ecfb1b529d5669656445c9aa49bc38c21fe8f8cec0309a784e968d 6858599b253532b35c16a6550597ceb48ca0aee9f3072085698ac6133e8471f9 369f5349cb574da3467308fbd110823c10148b1ba70f3a492332b6ef5d0aeb80 +974000 8055004b10a62beb0616dde2179fbb986793a12a1fb562de30807b5eb492d2d3 272ad85f932496d33146958f66d85ada51c19305644f3dbaaa1d82438be99df5 6b0073eab2043cbe5e932d8a24cf0ac60718e65491037bb10d8d44cc9bbfe256 +976000 1dbd92518aae96605eed11345bf069401c697f334c591ebce9e2cbd674defecd dc90da55bd439334c5009bdfd6dd0220d5bb0a99e7229f679d393b3df28b1d2c b30334fa3300869457e4a139beae63dd2dfb88715e95b096a6277c1e676bd099 +978000 7641d4485fe79e8b9c22d4c013c916c52262b47fde97c1f50f64694b277517ed aee363cb79b1e9b10c4a6fbca991d5ec7fd4bb8fddf88de5827db8a22560df70 02b08d36368fe985d773c0e16f4beab0c432852041f6859c1fe2b8013f079b51 +980000 8001ef6cadf456310feb157574f547ad0376b8ceb277e6681b2e805abb95dcdb 0651b4ba90f8d49b2bb2dd00b5093d992f0a9e0bd3181f26cccc04df1db3e47b 9b2a30fc52e84b97fa57e691c4f8f6f130707a1385a827684c4993324b520769 +982000 1ee6bcbc39deb9127731d1e7ac05fbb6ca11f7927278aff85ad3549f02d0d0e6 200125f9609bb28fb602a6d9621882d6efa887854e7814d0f5f3d98ee6520ab9 5e4c054467f72af2b59caa75f9de5e4c0cafaa5a33053b1b677752283a68633f +984000 1d785392bd1e459898319b37f3b6e5f49293d408dce03fe0ff4a089672c40a6a 97fbd32a32c853194e62e396aada729ad135d312f9eee5e5b49959828948f976 315ee4372e5a9fcead8744d2e350b1fe75561f8f8e1dee98a506f9f9763cbd72 +986000 67265a492c306d7e2fdb1ad16c1b478b06ef486d37817622d25b7716c7b1d742 f4121215f388ee0301dec4cd84e08806833a0e1a9a61e2b1599d338e30a19b2e a02adf670a4b7c4f4d8406131f17b64874a7ed7063bcef2571011b2eea23c388 +988000 62cf383a8db3ba199d41ac6aa0dfbb327ff7a73f61b15a31c8dde20d9cf8d7f8 e652f4aebc63dc0312306bbc0a901e4a4b7606310436fd00425d868c5ace0595 b63921b8666425201b6a9de638575c8be0b575e3b8261b22b7e8a468db43e05e +990000 30470ae6b42a2b3bea8f9ad912f9ab85231dd94f7e95d2941a1d2df26d12209d 0393a695c221c6c2ae12d91f30f03e672e138695d7854aa0d8123f8ab9a95b38 3336dd215fa72fe503f605ca17e1bef7e9b7d34653f0a405bfae4c2971ebfa11 +992000 1fc3e2b4243fb43afcbe83873dcfc241804e1b56210cc148bd7dc46227262796 819ac912973b89b39f40b794881443f8b429b3514cc8dcc5a19c6d3e9151b492 b769eb2317396de2edb968560bcc459e0c889ce23322ec3c95981072952c8f55 +994000 c2656b56280b0b30355fd606af9f9af8d866bfa7fa4b8a2b7d378a48fd483771 d329fba0928f56d4be12763a2bf682c7074725e83c75a554ca6cf3c939d59638 3b6788fb63eab66bdff414044e4643dedbef0dda3528276ac8d90d7333600797 +996000 9cdbd5383f14038fc290dc63596042e044e0d177956bf9bb0b4e324c2e55660b 2c6deb7aaae6be8c4086c5304952aaacfd108690912a8a910bbd518008122d59 f66a3ffef2c6d7d5b66eff6e380586ea72849807d1128f969d95d5ca1260651e +998000 43ff4984feb75e4729cae1f994859cc771e32defb951c38fd60fa0b92db07cc0 635945d9098fe8c0434a1e8dd3ea50d2d42845fbc9fed6f4e778f54c21e23041 c6d3ecf222bfd73f34e3c697c6778e99b9d95c5bafb6ca3b6882855c28e85e78 +1000000 6aae55bea74235f0c80bd066349d4440c31f2d0f27d54265ecd484d8c1d11b47 335fb8139f2c86947905ba8c3fb4f8e5401cf027091ea863b5dae73c716c5892 4be1195a34882146fc0ffd155808cbbf231914c1eb8ab70696495a7fbb677e80 +1002000 692adac3c0b1b379d2f3b4b372ef52f2e10fbd9c1f74c451aa0e3b9fca8cb95f d9922c2abef486ea10fa652e805ff164a8fbedb454ce44b5e361946a64faea50 508306d62e6ca912eeca76b3aee2f5b4176e30286d2948cc7889438c9324b54d +1004000 18c1d72e63a05763e32bf927d7378eb2021059c7fca5ec5ad0e5d52b493ff660 96196c825224bac2eb159ed30338408f9e040600176112a05bba8a4a49897263 947b1e6fbe18aa03d2f3c622e321d3dc5401b9ec2ac9111195d934cfc973770d +1006000 9ae8ac799b67e9991c530cf3a01cff2fa69c84ee0536814a318496cebe0e16c3 0cf2502f32f8be5833d2cb7aeb2a4957a527ec816b9b540c3b784eb55efea85b ab96fa6178f988fa99264cc9c345ceeecb32975dee8854a42f8534fc9fa5cca4 +1008000 e217e486cd6ad7cafe994251eff68ac75f9471bb62d162878adff3d03cdc2b03 de2d9d4c00a4a7f301c4c1b520e6ce67077f5edc33dc10f05d9d62229d0086ef 05e6fe857ebb335dfb93314bb5fcb7c93788647e9e103fe3073334f77147fb98 +1010000 d12a21469d573a26efa91125cc4532d0f5f729ad682e5f66eb6f3dd8e4533218 f2fc5ba57286f60efbc32ba760d0f19645e79c05d2056792c8023400a8ddb0f8 f26c5b7d809d495816bc22bde5d89b77db2d276b0979079fe46e700840d561ed +1012000 c3b6feece92d888707392d7207a8437a0775c86fc2592e149f50c96d6fbf451e b78337c4fff8432389888a9bcf81ceca18e01efcbc695a40012e006e9da80640 36680101b4d5957983dd38a8fc2856df54ceb4f192f5eb97a68451deaff14d76 +1014000 54accd789afba0e286916341004413cd0f3ca2d1cb06a10ddb52c6fb12c4a32b acea2ee4a43b69ea43d54bc93bf9b92243563dce96f553b9667a9a807b0dbc06 22d5e6a2a46f21d3bc0b9d79d56cf1714e73ec08403fbc720247a84e34e4c25c +1016000 b7351c6eb24d91fcd9b766c925a07a7b0c84ba7334100463b14f22a4d7b37f02 aa0a739049a58ff826d771f7314be75718faa26ccebb906379d2637efb6bc860 d74599662b84364cdbed7e3b830176f798fa1633d887dea2cdd0d7811b3f6db8 +1018000 89ea8b38724fba38072cca542c15f31e690cbcec462d5000c0000419c7244f71 5904c4c17a58d0e0a9a24a3d76c79133102345b5ee5c1787e66a19c28af64bb7 b93778980b92a16f29730b4a894cc17f209268f5eec10a946af483bd3c02c876 +1020000 e06edaf4f4efefa3fd07497e52d1233a649f77c816a7b09921917d0fb5263ccd 0b61a2061bcb40106c7d4c1050fc14fa212d5461e08af3eabf95991f26fa94c0 c217d099c426c3e0ba0f09f437fcd293e181f92f4a9a78dde7a30c2e85af0c5b +1022000 042a2486f39abfe3ed062cd3f5002c0576fb96e6aca3f095404063f902617d52 80e082187890eaf5454df040f3cdbcfeb4d57ca94cee59b464b00c98c80bb761 3e68f4c8a8907977980928d8384c72da8a282be1b64a49d9916a5aefbf2b36b7 +1024000 b5e07cebc76c32360dd134c2c2ea99c1cd6518bb9393425455fc1c3507c0f570 cecbcf112c4962b9586bcd0f0867f3cac5e4fa889e33048eaabfe40c2cec3d19 9864da47ca8e3fe2d126822cd42a17f6578115be5780d4ad12ab1bcf9d60bf6d +1026000 46b28a733b5502495b8971ace786593c5b21676db8ae4a22749c257aa646737e 0bda9d123ed61847cdb0b2ea6203648c195a59940fc3072fa272b4f86647dc88 73af6b16a9e73ee273d22eb8515fcbf349c55a5a75f8de56d849fd1806012262 +1028000 2f5cd50d29ac396683d1ff64dcda56a8c033ffc9043f39d16499294c7a85152a a29f44ef25ebb2213fe66d9bc249205df14626a05d1cd9577a103fb6ec82b524 5a423bbc45e2d533a691ec8e3712df61d62164c1a207f54a21a7ff46477135e3 +1030000 de7236160c3ec658df6e2c45d5e42d433f813605cb16389a2927bbb0b3b43ec0 6a7b4141c3dd6f93554d0d52b6c8182560bdcd6ac423807a3d61b7db4319c468 d6e5c1bd24956ebd8d1413b6ebf826dddec2f26cf96530e56481dc74a99d9675 +1032000 5d7053aaf66285786c5df95a26e1e648f60b8b1f0a719171f0a72d92bf70e4d3 3d8ca3ab7c7bd1e6cca1af6670b2ed2996783fbcc99ae55336475a5f5b8e65bb 8623e9912c35e0857e4b79e6e9dd421827b6aec2e46ab9ce28e2f4a2144a7317 +1034000 433d5e81889ba6e9a43dc131d11f5c96122e061423ed90d380a81087ea6f9290 a55a7ba0d5cad30bde7173365c33c7d14f5d4e96981378f4fedd7501ef9b7a46 e3f96a984fbe3d592a176aca94910178a0c9d79797fc548c1051a53709b9bc78 +1036000 c3273782d4d040f5949e9133d7370055a17c590358b308f4cc1fdabb2d3d74ed d3c4db5262720d24671046729678e603f0f2fed266529e04683926880358189a 49ae1b4db6c3bfabfe44144e3f70cad2aff9a7f34b12efc13a0c64f9d8f8d6bd +1038000 e3000073cbaf248a827d58f1bbfbaa7acb80c864f423a97286c940d3c4794425 675e47998230a58f8b6fd0533c9d2fb76358c822be4cd7d7b8733bb267742de1 7ccd8eecf508e0bd7bc29594cd1820108ca5629f26a45d3b59c8ae9bda95857a +1040000 08865715e7841095a96fa33a154d7401428995573c19c75cb8ce5c717e949586 7cba97fa46cc364aa9f7bf9d772128b640bdd6c649ac9ae5b5121c6900638b1c 2dea0e2d52564040f65fac4e510522ddb4761fa7e97d90775b2591c7d579781f +1042000 92ca869b0b68b56ece79135bab224dd393352d9c2d32e9d6f2a2d7599ae83f29 a3dff25e5f99e3abf50fcc3790721495e4f86b0a3b5aece7802dc4dc370445d2 bdc783626268ce8a2ba53988ed83fdec92bd26b98595a3d7308c7b6a8dd86581 +1044000 8411f9d5d6682654f3476e07d5ea2d180d5262ad03877a09e01621c480f467cc 9dbf9da603f941166810714b391fa5b234572c72bd1ce27869685d8b205ee83f 301a49bd10532a0b27c6d130218c51f245d14464e52d6f8b0b1c255f6d91b0f0 +1046000 fde936ed9cdbe4cd22ef567c48726e82ed170b8157074b92aed62b3c17e6fc05 edd37806395f41785ddd9235ff701331f22508aa2774c75e4a1d961ddd226068 f82c335dd245cfb1f2e912d1494cea709ebefb8271d53cb04e9a8a9eb1b4432d +1048000 1879922c3cb1c509a2b5d043a74d7460c7ea64f8266030d4e58a3b936dbddfdf 872eec96eafe83b12461f2d611afbdf234ea75ffa4a91a53c52aed94eded0a85 a66cf186d030a945084675c49c912230919a6b8ff6d9174837b0fb759197209c +1050000 783068eb781e0b549e53d6d4327c123684201942edf63c37cd2bfa71653dc812 8f8e1a7471925f9f067dbeb9147b2b6b80f090e6fee3a7faf53561fb88ffe935 1509ff7b8d144fa9613114c0c5ad978b1978dca82f0fec3d005e8233d079d2bd +1052000 1b6582af92d33cee531c0f1400404706c293beb26efc88bb4c2474b4370cd44c 61f4c2d6b2c7ebf1591035e23703b9157bd2e41e1080f3665fa6d056688462ec 23ab3ce695457e5bc62839591dfc70ec7706d1cc01068305f2c08ad5967b12c3 +1054000 93223fbc40e47b68f7706f6a648e6fd03305f5ff6f1f5e68474ec81f41eb2658 ac5be4e284e9e8c5a23ef69efea2c9c474c6a7ff7b10679e92dbcd8d9905c32a 4b8d87e5a23ae2e9ff1f615b4a754f136b8f1cb01d80d45299895a7202e0c428 +1056000 f5da854e2ea890f6a7064cda57752a4d44fd9ca44bcb12b70b9df24af77b2465 99b4851cba732cc32c62483cbf3fcab44ea1415e76ec77fcb522cb4067c1b5fa 1a6c29d1e8f18a286f44378e8e8cfa9e581d7cd092b24483f16b827ccc625bb1 +1058000 185b20faf4fff7a0e30df3a0a4e48701076c0c2f624e4d23d263be1e0480ee83 9609b39f3f9427ed8362275dd7fe2b910e1255c87bf1b60ed51b45389b5f6815 72fe51ab195b5c35adbe287f255bd2e6265de6292d9dabdfb2701d5f0a4a9407 +1060000 8f1121a97a4bd2c3982dfe0b32c20a17e186993a593862da4bcf0a9aacf17a42 1c433b71c1e26dee5b960be83ae9bc25bae46b3629c70ed01f368565a68d91ad 26bdeb07fbc9acb6dd88b723107e35015cb3b14d6df51fd1978796af0184b7b6 +1062000 f9a45e73c905496f4779106e2f0c2c7bf81f7eb3db54fcffaf45090cb2637cbf 8aaff6321887527fb7759f133eb0b77f7c5001ff31f0e23bf53609a3f8d0a271 0d0261facbc9c888c69d25aa6b94bb39e93a49c07666dc74f6f98408c19ed205 +1064000 615eac81599f5ae66490aa420aee746e1ff1deba3cd5b68bfb46a3cef652578d a67f309b38e785e9084483ae80cca1cbec2f1896afcbfaa11fd741a53a168fc1 915e30205c37b284992df33eb612d5ff382af1e7b9df7cf7b75e71a3be6dc986 +1066000 a63337ba2d852562c0fff390b017dc48669ec7d9247d5fe7cc51f03e31a0de81 49e8f0d7d5a3846afe1215b4b348965a7fc17557d4f3fd9ae5897f14e0d9fa6b e837bd5a8bc2d55a5fa24386f50707177757ff878377b6834aa9d64266b8790b +1068000 924654e589955ee11e9b9c0074b37d8a478d082b4bf90fdfc204e5499b6138f0 684e110e5f8668da5df7dfae7f6aec803544c517992efe6d1113ebbc8d90ca97 240761bc77fab7260dfa1dee513075111542ccb283313eebf1e768f5864c3bbc +1070000 e59e6fb39d485a1f4fe2880a938ef07e6ef085e601e3ad7b174197ba1da89863 86ef33e3babdd8b068fec9e01b574968a6f1c5deeed1ccde18c259fd8c17ce8f a88e3ea0cadb3702a384f58b32268282bd5f83df9585a56e3b08b5c903a4e39d +1072000 655f8a8cf95d1e04277dc30dba389bb86939ab77ec52bc37616df6c66eaaa899 b63cda2f6ab392083136fb266b7b3576c86f076a6dad4c3ea9bb95946282f0ce f2f19ab3e05a4e5d95486576241331ccf3289aa4f61cab7bedfa6204900bcfcd +1074000 0e7772848819c1a57aa304d7b5e09b0e4dad0ae2186719e882560ff8add6a558 be36fc6bf86166a385d9f33b8722c8b6a1942f65f12d7269d75ccf8e5e36b2e6 300fbcc2d2c920663184e78cc326298e18914a73d46f586763405861746330bc +1076000 9cd3c1152474a7a074c0f95ede887f90a7de37e3293cf1444b6ce4704fa74d09 73aef07ba7ebd9fd6939d005a44affa342172793f7279b208ffec359c94da871 7d4b089216c7bbd13ba3871c6dedb8e26e79e78a6df696dd401557592ebe8814 +1078000 5bc9347d5d62d1c015a6ffcce7dd9259b516639feae22d1d27f59b5052b0944e 9573fd2455314f33bfc39ca7ebe3f97db315c191b5a93f98fa74af10bf456025 d8dd1dfccf4f5df66f398ee46224fed8d1947b6d883c69c6a113e8249b6698ed +1080000 aca4a0089622a3318ceb9aec9c8f11545081210e31ff44c09205c890b8e1d2c7 c60ed69b5640c68d285947d115dbf33dadd038dfdec6cc636d9d969018cfcc16 b2cd17b13694b1098b7b36812cbbf28792259810a338000fcb45457c2523b5b3 +1082000 496030268cd58d4dd156f795dea3e1d9e82778e6401e043485808a3eec3c96cb 94b46bce687dee9bed62997ddf86a555d7e279dc23e3a5705059940a6ae68558 a593562255653dc58fbac96a61a0b1915bb85563ed66c6d826e6d29e104d0693 +1084000 4731ab2bf3d33aca490f5345995c763f28887b6cb712b779d3d53a87315a33ed bb1da4cf878614b96e04b561dbe10ab399e5edd74333def296bd254f4a632423 0d0781356d6edc725f0154681de1558bb47458867bda0b91ff5d9a82e3872f7c +1086000 263a531021cdfe009cab7ffb3f9b522905af28cb5e6da95ff95ec7753a495508 fc052ab769070b1114a7776b9575dd78b3c3bcd19fc275156405fc348277c77a fd46b08765b1047563ee97cb5dd8ed52382e965c2c6331f58d2b74836c33b9be +1088000 a18d492aa883b206c6a454b46da0f1705fcf4bdf739bd53e1c42519f630221eb be1fd6a42c4d1ba7297cbfbad10d0d2f70ebab5d10784fdc8546dfebe8412116 1f4ccb557b14b1e5fa79a37430956a03b3de6b3bd6d4985c8f189483a9608f17 +1090000 1a9ea2b30471a120732d7040536e10b5efe1fe0321e4ca0f28da548b5228ecad ec36446f75757199d6bc0e71d6c844945e744298f8eb73aedbaac65e3090932b 8a141d57b3f9546aad9e31368dfcb3099357153a0e9ec713e751ad9164cb58ca +1092000 8db847bf15b9b43778da184662432583d49d17d7632784583f6cd5a39a69af38 6b8fffba10db66e7d9e4483948a560c4ee6f8ee9781d3b2fd7fcf09815ba37cb de5ce61694fa640b323e9dfaa86aa2ada5392879e60c037343878de533e851f3 +1094000 c43f7258f2491c5456d1b04a5fed2d03d2cfa677ea40eadeb1ef5069b2f97a9d bee389e71563b2786da73cb92197bf0d7d0ff92aba3bc97aabbe48e1cad7c570 72733dc48697bcb63475fff3e694811684e5724015423b9713d26d31f7b70fe3 +1096000 e2b2e0d2e6d246f402a09e68ba8e3ce6ecb74a66b97b944e3edd413eddc3fd71 d9d7509f8fbdac6a0cc28cecacd04411fa8e8a2a81757aa72af5b3200ec9d2d4 c4cb711e5206a7d8c5fb9bacf8ff7e5cfe68b1fc16c6caa9904b13fe95c7ce99 +1098000 7f1b117d512ed234c0dc5abefb5c7648f7a4a1eda20fce3e28c690f718f8a5a3 419c55cb934d716f868332c449fac4ae97011e48ecd2647181cf8f4476758e39 d40413e1af08f125e29f79c644fc9d3dd78932dae39e3e7df3fef7ca98fd4fa3 +1100000 d48fef240e48d9395d08c2ec4fe9c6d5554091a107e1c0fddedf5db3a435d96e 08f039a2cfcfbccd5e699a453e09b79b047533878406b6e43fe21f54e3bab74e 23a2cbee695543729f2b6efdbee3390b32eef1c0928c244314243c31e562fda5 +1102000 f775d583883a45db37d5a00b48d0d4da6546e768b0626501c0ef29146b481c11 565acad9e32124b8a328edd184c703d8bb04c640081a7a4d44882f83d8b6b635 25220d0eb173f9273e69b6ea6cee06be68662d4b778884a290bab69814934af3 +1104000 919f9aa560910c5326192afa0dc6f241ea58deb396997c7e926126eae25f4cca 91c36c2d878e626ca37a026484e2ad02ca00faf4050ac71760fa054efb0df863 80032914811cc31ecf0238ac323fa5941a6ad839bf98828e2e3008fe85cf0198 +1106000 098b21f84fd30e42a1932c928b69340d68cbb1654bae00a67a3be5ff16633a2b 6ec14cd2a44fb54a851214a6cfd88e46bef4e34d9f62b0d497a382d3d7040f84 37c23120b1a0629016b3d87e077ade3acaafa365ae73ec0186c83e0144a9d48b +1108000 ddfa81382b17888c9a3db416b624f64ecc89bb02f01dc1c580211fc12b9cc8d9 e519f356a156485e86406e0786b8fdebee1d0f7185845560419c2728148d1048 7f5277182b05bfe7d71c47aebfa610c3ccb21296e222e7ec921c069882b3a379 +1110000 bbf7304fee2f3f21339a692c69ac14d6d7cfe9dd2f9779fd1f15d1352d93dee7 698b90129d483595f918659f8c0283de625821a6aaebc71b4586f9a82cd61267 701262745980bd4e76ba63e5e0459465dd13aa2c742b99980d8fef3a74a8e112 +1112000 98c2de65f1b21ffdcca31f8086a6df16810a5c040e77d1048b142835f18a589a 41a903b8a526135e1e8fa2c27e8b3d0c7bb9b1747dc3d313fd55b3b33a5c7cca 9c221e7aaf7d3303ec37c1912fba3e4ab16a18931cd70c58a43e5c0ebe5bdc3d +1114000 70b57cfa5ef1869bcf189e7507dcc28ffe3fce16466879d0c041c86828fcc7eb 9236eb706a8f89db11d2e94ce21e02b101a750923e6c07eb7708799d40327ffa 5fda75a93be65fdc8daa5f21cc5b6e11e6bc179576be59d7fd677f3bb2592ce7 +1116000 1d78c2f5595ced99e789dbe8a89ec64948b3d3ddc114121c7aec683f1939b0e8 0ade1120f5bcd29624155309bfcaa832fa9fc5933b4f11e892a5ad82fa106413 80a02966578a0cbeab34315b419c2fc5327fc3bdc061c77261021092f4da4faa +1118000 e3278c13721eb379f95a40ff1b5782a595e8165eaac5e4e99a47f12e984437a0 348c6c8d4df37534bf7407c99ca89b2ef50bff95c3929ae8a0155c18ab4c4e15 f0e676d78d622bf9f36fba4e4ceefcc3cc7c162ab1f7c094343d37b8ab7cdc9b +1120000 3e3560bfc1f3b5b1702f8b94f882ddb9adf04dfa37408e155f28027f3e203b4b abd1415694905a5b288e8559975e7e6a46ae6c9960885868ab2bac9f0d8b5e93 fc7ce685a1444ae372c9fee88661b8a29daa05bf149ee9b92b3aa80b28d1d1d2 +1122000 ea87d48b0a54ee655afb14f90a673d49ecbac17d88ca214fbd57212adfb05f98 94e6002bcfe478327a25db5f72c150b2131e9eb9ac533d45df4b494e29883c34 6020a3fb3e602e4893864372129a06233b1e1f6caa55cce4092f1d405e42282e +1124000 50f729523530b772f8308535dedea00d4b7c4ccb2613504cca122840a197bdf0 b1395da8f9c79d1c84718106f4f57caaad1b51b2abe9c4c2a520abe3436604ad ad5feea6af630e69eb639d0c296b07bc9b4d9fdbc9372c65cf1a46cc265d1eaf +1126000 6414d9b41d21425eaba95e77e716fdc66400fa09423ae021ce99a4c72cfa0622 7dcadbf01a6d9845fdcbd2eb4f576bbf3f85d194c88863cda58cde0dc54ef31b 19bbd3dcde2c1ab73b75a94cdd7c1723e00384947fd49b3e29b3a895f331d3b4 +1128000 807b9a12dac45fc274e0c4e2113a73f293b8494cb141ab2b57f79148168eb4c6 0b00915c8d10e442c7db2a725f985b534c7bf2493ce19991565d7a9182f9aa55 b1c4109e9686c644ffe54a0874d412997be5e8fd1c07edba43fd5c878a7a4b13 +1130000 96e6d8053d31e1c06aeed70e61ee000b7fdd2a95631767c3eab704b595cec1d0 4bb1d548feb3a39ca3b0dff1736e759cf8755606049f02623cdda5c943d01ed0 8ae2a5b7254879eadde058063a58223ba6c7b09d1133575e63a8946e0be3c7c6 +1132000 404a66d09f878eff623f0d3b293dba66501e9e78dd6a192ff45338d89a65e58a d3577eb931cac229fe6b0134f67cb717005930fb7456541c67a4aff250438297 8eb320b125c31aef6f7c511f49e88ae0240592d9693e2ee3acc6722da73c8487 +1134000 c3b7c3473e4c5a26582a539f282192a394c8994526ca70433fd4c4e929afab1f 3f07f33f893e313eb46c8dea7ef9976566503ee276f6fc30ed5ab98e62a036dc ce3848aedb1ab34fd304d50b7b6addc681fbc3d34f76bf1e09e134a8773b7465 +1136000 da612a6dafabe1251209a6b7c6ecf325b15383f580958d2ea9670ca352b64b04 fd681d931fa8d74651b5a26a40800bed05d11bd8a18fe5398c2f6b1e09195195 d6fdddb714e603d710fd2f5ad90f05486d8db3471b7ef83bdec8aecfda2bb681 +1138000 66a96550bb53b0ca292b7a896a42e17174e5b9e94fc780557698f2c91961754a 4838f4c80a3868a550a2e9cc038749659a091f6cf25f7047f598dfcbff7bf886 6b31992438eb19474c1c29493eb26c40cadd73be32249278a012d6103b10648f +1140000 42f13c7e8086473f1372383cbf884fae51488878a14ae71d6c62ac53a0144eaa f4466d99afed4d7788e3dfa173b42de1783f50c23afe767b61fa6dbcd92fded2 cf847463eb5884fb0de36cf029b46a669b8b82203ab6ef41363917773058efe7 +1142000 84665466bdc339dce3e4af8e49ad3b48d03f23e380db16b9a6cff0a6d60d18f3 cd663660ededd5836376c8327265481c3f06758d528de76cda38109e8c571611 75e748bf20bf7b8b6e0010204c1a93d86111b5b0498c5656c82d853363e5e89c +1144000 c36d279a947273c240870cfd33b8255850600daadb4a7a2abaa30f5f9698f391 0cd61d1d4cd3ed4070fc3a53a5f3251b66d2125939893e91fe06cb421589f4f5 cea0ade267f46e1f009a3713441ab2f9c599dfe5e55aa09fb90a711325d055e9 +1146000 ab15c0a65cac436944f536f18519c6763b5ce657e7b0738bb7145edd62e1c879 4a1c4212103d9600844e2507c6f7b6a69338b1b33b5425dc164dc53a96848252 8fc413f14c644d3e88ed300407357c2bc90feb27082e0a6147ebf019c235b016 +1148000 c4f447cba01447f07ff5bf9b33bb7c46b571e6feb3e9b28503ffd38aed8a44db 756734273461ce3b5a12e28d66af3e98e17f3304efa1d0025cc540e4f17ef24e e2f53c04bbc9f754414ac173998ce0e83f1f5823b49c3fd3b88785368cbfa54e +1150000 aaf4af4ae3326676c4da9a3774221b56a965339d7813e790da5825a37d882acb d6a0440152be456c85c9df3c44e1a27dd70be3ac8f386c9f662e1d3634c0f88b 8af77393eb6ce3af0aca87c76c1b8dec92e15d65481fc22bda428c9b44551871 +1152000 3fe08961986241be83237438fd7639c3429c943a5bb5df71e6be67f4e00a2a82 0455cad8d6bab20b2ab9c2112e02913599086b0cdc8c9039810b2363136fad3f 48c84c75cdb2e77036ba58a5b4a75633be45398591fb6c817117922d5acf7343 +1154000 816e4cbdbedf72b6160e81495a355adc0516a2ad77d63463f509f66c9845746d 7b9cf359b6028d8d86f7dd8cc6f5ac4af9c514d1f639d413a8ac90251038e3f5 831ff5d6e74d9b13aa636c0269c79710027659800700b34512e8adaf23be3057 +1156000 dc8d5edd8a3716ca79274a4d84c5cd9a086206722e781a8d72e27c5bca986cd9 b988a48fc62d899ede5d97765d8482fc411dfc19a905f28b964ad8e892643e6f 5a46931804baea72cda0432e68703bbf721ce1746fc7051ffcb9c052c834c1df +1158000 6e5a89c1aee412b4b1238ed5c5d98cc3d69906c6f6e455c39f14912814e1f5da 54c08f0da4d769cbdd79e19a27417dac33040e70ad72822d22962ee07ed4fbc3 be7a3dc67b5230f8baf4cc41997ca7badc8671d085df00083ebb49d55bf3ca4b +1160000 40b61620404395b8c8e20dc921001ceebdd531087afa87ed80898f3f2fb2b4d6 094aecd2a03cfd4a98bc6cf388d9155a258abab42ff3a8d1ca1b983e5e99127a 024766604f31895a54139f7ebf3a9fdf66e2aeec28f4faa619c6a74b17c27bc9 +1162000 6d2085646cc04e219aa874832ae2d650255cbbf2f3e8e4b0ec23c1ef16d869e4 a6c1f7c3c5c048a56aba43df0211ae5d18f1b1e30b28d2c12c84e36d4f6916b4 687f93977105d1c37284f00dda7d7a09b77bfbb04506fe6d98b784a88536dfd1 +1164000 2a8332b76bad152d2ac334e1ad22c86b08bdf6237287ea2a6b4a3bef289c4faa 99ea7fa8fcdb327081161ba56d2b9682ad81de67ea25df60041b831c772a7ff2 36dcc24c31a05b83336b1e9c46d50b9d8864359d608b293e9ffa7e095cbe4bad +1166000 267843a6ac957d894c3090c22ce7a61370fc723d341f2e243e7ab44284796d47 626d44160fd45158d3bebe9109b38870ce0c7cb01ffcb3c050cd753c2c4b6b4b 8f25294d0fd8290d36a306357a578bb826a77418a43554ccdb2ef7848a3a1f09 +1168000 32da25240ba57316bc69141f5541e5c4fcb28a707e2a13b867da5d1beacd6f12 3cd12c3b7d07fbba379bc52b650d4080a91427829627a5e99203f6fb455906c7 ac866f768c7bc0387c2f0841514da6067f5409f1e29638b48f45d4d60a724ce5 +1170000 44ee47ba4d6662322681324c8a3d40eac9539a23367ec5d429f35ba5bce5300f 4448a91875c574d43eedbef336f7d6cbb88fc5366b1b4719d25a9cd4ffc0f97d cad25ba0a542337a0b6fff2158e3330b61b4f2dfb46ec9a64d59f72e1aba6fc1 +1172000 718fb855533d3801b402e9acb7425253f306b2b156a30e8799614dad2c574998 93d6b2a043db38907ae0153e7345929178a46e2778337ac92d7df02a939c7430 f859c11e01f1bbe486eee66f10d5bcecf7ec5bb53372a1ef296853073c005d12 +1174000 4d8b47ae664bf21b93e4674407b1fe36b1f9662a190876b725df3b029b165307 b7ffc6e254d66d3af96bdffe3fd4c665d97e4b70f200ecff019281e2413b3b3a 306bebb62758db79e67fc5eff918bc12d2244aedadbb699847c179788639537e +1176000 5414da04cec912fdbcb98f38c242224056cede4c86fadb4756dc1c18c146e93d 47584732af225aa538747d0be8982d400451c5d5825ca07ed207bfe9dfaa87d4 4779f200e608cf261b10ca08abb89085da269d4a418a67b9c156a23092a286c5 +1178000 f4275cf1fa001f2adf788c5dbd741e2b70c56a410a9d4f1aee0d53ae822b29c6 d98bcc542b6774c6772f927a2dd67c4357e99c8d713daf07dce7bbaa988cecc6 d45b672d9ba2a6e7774e95787fd67864cbb4f230d3b3cf42db8e4f1c20feabc2 +1180000 908f835c8f3bb7b398f627ffdab28656c8ff24ea6e90afe524d6b9df6798bc22 7af1d8c654c501cc3cee610726ab6a97f0a39df3e71a25a8743e41910939cbc5 024a7eb598a32cc2b9a96d33adc2151f0b1ade6e974a0ecbc7d5d1aacc5c27b0 +1182000 c16d5d7890b8eb7885434fbcbc97924aa4e5fbb7003065cc28d6a9b9949c6c8f 924ce18fefbd6d13c8204f2414b2cf8d23132ea5ad06861b2a52b8e7ba68fdba 6ef0dfe47cf160c5a2cae398587f0c1faba3e072ed9e5a6e3db2b74c5cd397fa +1184000 9c3074953af645c230ec529a0e28153ab4020843185974fe524184e2f163b62c b12c9faa284a9c346b16d7b364e5278eee7719237aba8e10f267fe2953ee02f8 8b34e8b7cbb03ab50441758eb5b21c7216c62b19dd0646a3ae12bdf855d3c23e +1186000 0a0aec9852b4cabffad2e6d0071baa128bac35f00f281fda12e3264c5e8e6407 07d0706462268a02961bffc8625c6dac3c9179aaf7428bc3328681485efdbb46 dd9501848dd42f189bf9fb796caa1120f55755ecf376ae5c71217e00235b819c +1188000 6df6e2b2154e6c67e393accbd358ec32c6706ac2fac48154c3243f176fe55416 845c6e7244207a60b2f442a3f2580430bd182c6a45b1bc08932ea1d085e9409e c4c9a49e2dde4967346f02fa07be3a5a516eedd2bcd5a10417fb29b58b75e225 +1190000 14056a5c6af59d55cf2fd262fc6341cc1d86c49143215eba5579be70ea2aade5 e170b14ab9f9cdfd97d97d1167e19d3fc88610afc9c069f58f738265ef36959b 8ac77ef0bb1a9041fdedb67ef25cfe42245c2b7b09b7a8565e019d096935ffed +1192000 8c791d70fa3e2a34a31621582da5ac6ae4ea925d35d32bce56a39f7af8de1864 db80b33058ef7b2dee29d12d0745a0a96e09081b0eae57425302c840aae04537 0c50634bce5b7b03b60c50b140ab3e48e9d11c06046a63b116fdccb4279e3cc6 +1194000 63aa3a87746b30d1f4558fb32c345d126b314553a74d96567ae4ed96cc359675 ac390cc3cab229d4af8b56761c6fcd93bbdf1cd8cb794323fb1e502699bc23b2 4d54646b8a3029a3e2895a2c1707f15b14982fbd570cbfe6b17a5a8ab9e5daa3 +1196000 4300e9c251bda934ec1a43f595a9e0cb9efe83ec0b05e755075ab6f9f4804c77 a25518b2fde2e1f1bb715502d31f9853404ebd2b9788466daf2eca77f8dc41a2 680e83e103330266f6c0bb3516ff2754627108a4a67e228f219b27caa8405398 +1198000 3cb2a9b1250ade4e6d754ffc2ea880f82c629ae324ebd02f39c81fcba66d88c9 0ac359753a49f26103ef607b01f33d001f2fda59af4e15826d065f2d34aff642 1845089c133e6473dad823a2d562f2b944ffe43fd95975ade9257e9b3555a66e +1200000 1f8ef813b31ec896e3f7f064d6637e251242ba95c1bb12ca339e55b0614a53db 2e9ad4ec5abe98602e886dad0dc1702735cd2314d2eb20c624d61bcdfc2e01e4 1f749c8217815ad82d45482d536e44bad2692fa049d3e1fc4aa66cc785746145 +1202000 fd08137c5d222e8ea5318523e3131416a17cc6f3d746ba76cffb9af0dc404a2b 98c21f59b54bd67d49b26275e2f4a4479147478a6b4045036a943e6da88c9ab2 c32b7f4ecde715160e3fc35193efd8ebaddcc0f018d1ba3a0506c6013ba9f074 +1204000 60c10b8fcc19ad21aeda00554210d53e53eb5cf81619f4426ed50c43915c2d3f ad32ba2f45327d861c23d67de04842fae1fa173d3232ca0d335d86e41958b4ee c7a9c161fdb2acb86b9c47c14871d057e17e721f21b0d02ead31aa01a42257b5 +1206000 682435adeb493baa1a41779ce748d49fc48d2d4f3e53f25cfd0ad25093995d67 95ad61abf923aecf77d5c9a6acf0a8d81014e2921016147c08a0804d70a18772 f810cfebb3231b1161768957a0aa99aa29d0fb1b2de2fecd82ff047539ec8f94 +1208000 3bb53d12528001bf7edc0bf46704eb0737732fdd2558005bc646d0f0839d28ca d8de349a058ccf4b7a0069f691c1a02ba415ad030dcde9a6338f4c53cc44640a c34d2888a117b2f6b8cb20a43c6428f0c5a8e97b5d3ace09dbdc54df3ad8216a +1210000 d22450f03646cbe7c96583e96a2f04182f31ab4590d57774e100bcac3bcdb315 20837c7f8dc041c0c78ef53786ce7a6b8450c7bd73187701c2d80d0e230bd51b b7456d328b9f5bd11497133282457411fc1093dab55617444b065e13a1da664b +1212000 834e77f14d154224c780114f99c5b7b16fb00f9174eb3028a9a66eaaec179a81 dbc6a247cdc5128f7c61ab052d32917b8ddcece407e4135647f2cd3f4abff958 fac4d1a0006257f8bdc6b7b6a627152a06d23d5f7cbfb2bfeecf6ceaf713f9f1 +1214000 68ea6a6a4644a54405cac088a05bcba044a42d09c35fdfb07f7d03e6858160eb 3b14ba281308a86ee887b1829955f177ea7f23d6c85cf60f0742adf56ebbeb76 08fee7196ef97c3ff77fb35e21dc81d752af582d5198eb926e74bd293faa6e42 +1216000 e259164075b303c8e31e370dff89a2e5416299daa2ff05b1fa1ae71b3961763b ffe61d88feedd373e0d7b1a0e5074e3b91f0bfaaef8ef111e7d08f9a420d8289 fd9b36e8254696a52eca50eed3228100d5e1005ee5a0e55b9315744bb291f02d +1218000 a0c446e68184fd274f6d273ae5f3f470f8d8bf08b052d979f4f6e7f084e0f3a7 00241b1061f92ed14876ca2dcceba119f6dfb075a8b7f3aa44aba0db7c11191a 73d60b4017dd6c8fc3f828383f12e7f77a8fa94fb127800c491870e2f6d38a5a +1220000 e104ac4aae8f834b5c439cb46cc03f409551c6e8c3d13a1325e8ec31394b4f53 dc2263709fe011b81aeab3dd2d5164aa28b241833371480d42bfe9a985cab0ee 9875bd83249b202163bb9f8f019f747cff4e15e25e4f3d2a847a2fd7d626760e +1222000 11fddf0132f313c77a8bf0d44d5ec70eeb07895c3b8945bc3783b551241a3ab5 2774f1ea959130a8d8cbb6d4a03941c1f51e5ef7a4ae39629adee4daebbe65d6 837fd9b92dec64b5097a77510c85387bc8ef207f5b273642b1ecec73bf6db29e +1224000 c0542b48dab5835ce6146d763b1c0eec9a2073eadf2f3b1f2913b295dfe95cd7 b7b792114d2b57e54d788f37e07c6ca98db6e275abce0f188b8c3e40a7b5de76 6c53453d619dc4756a81da2a04e4b2af28d6304f3d012b0eb07ee4320faefcde +1226000 a16bf52b2bf235ca73b6e3754918688a037ef1754a03b7d2a86f3d4dfd61c1f9 bc06628b5ea35c5db5b2e1b8310fd7e2d8b6b7ac4268f59b18c8933c3419e903 9be26daa710a0fa5e24ca62f182310728c285061dbd918e159e5ed5f4f44a0ff +1228000 350b33268b9d6a1d748f6c674a9df2627540afe75e27f8eab44a417120f6fdf1 5a9d7de5e66f06c8e77c342e5f5b384d47260cf35da45db568c1cea6b8614fda bcb9fb71da197672edd6461b0051ee4ca2d54ef5b1f21a55e8ed1d4370fb37a2 +1230000 d81b5bddc670fec569117d5f9812cd18057ca97591ec1c31ef55f10175b50858 e54d8217290980aab3c80de7c28ca51975345cdf963723703628ae132d2579e1 9da7eff9bcce5fe35956e80ebd6306aed5f133e2b4870ff6cc0f5a721207d2c8 +1232000 24f697587c9c21b6034ed8d644db9dc332296b3c052d230cd02e6ce7d8d322ce 43a51ea81e1640d7cab9918eae4f377b30044715eaa12f1e3e7946f2ee23e0f6 03095a947f69b4c27c90c43ab6598c5cff84f0993eed22aeb5d9f7d59ceb63a5 +1234000 736b87b916eb3d6088aa5905d36ae496e8b52a2acd12a136cc3deaf8d0212f31 0159877061745d2c4c9eb567fa5a69e5fe0ce184352270329b8ff6e277eedbf5 3d7b09eac86655536a0bde9523abd81053ec2b393198cdcac504b70faa289b0b +1236000 18ac4fc882b90cf38b425901a2e4c6864abb179129015479cbec560e1fb64149 c8427f632a23a72c9b1e7921d67f5e7993cf1f455bebb00065132a65ae05cdff b544df875efcc6efc35c20f56d3ee7f24a2fcdbb3fea8a0963c4ad15ad450faa +1238000 3cedc961ac50458ac53650557d7bef379e5502bfc988ea07598eb88b3bd4f3ae 45635298188fdaa3d1d86a03b94b0f56f3820a8d2f26f80e9cc6cd32b75c8f29 914c8a19ccee673dcd1905ff79aad12082cea9a3aab97277bffce89f1be52056 +1240000 e12a43dd53fb28a4147c189a4c0aae11112d93e620ad38e69bd9331e84c52c49 a2fd9cc800ae9ed7ea714d37913c46c5f1d66dda1cf93eb714cabb975b2868e3 bdebf7b88324c51ae845e02bcf02580c38ceb50f59047fb02719ebc385a36f5a +1242000 737e753659951a328dff0aed43514ea8b6440c79952804570e20da296166fbd0 cda211f0e9421a73348790478ac331068e4bbbb3fc9bb3ccfa91a5110b657a9a d9888c61316b6d1332370f41ccfd4d70d52ecd625d09d4608f34556c5ea1da1b +1244000 7a0acc5be7f00ed9286d6de9e4e5a3a544a43e2ccd953e3780ff9e821b7bee91 69765d0ecd6de8bef61d2cc22bac6b0d51c7ac108e60f3927067a8fd8c41ce78 2520013c728a765ed2066f61ac082543e438d34e9e64abf73ff155851accfb1f +1246000 50e967dd7b86892c4bb7995199c7be2bd18d1decc7d1978869fc10c2190d0d39 1daa67b817a121bd859a3df20a3a3975ebb7afcb297bc97ce8860c5afd1aaa84 f4ac64287ba88abf5875aac87555b6cb060338711a738b1dc08a51350577e7c2 +1248000 6481fb90f8ec8e4330ba477c02e2fb4a527f38aa48a2e21da5a1234674d3e070 822670b98ab372be13e36468c16befbcb67270e8ae08261d1a5b1bf9026ab14c 560a7f3ae4d682372b1d2b0d2abd66c078ac8da7c1c48d727c14240b16d22244 +1250000 00c7a442055c1a990e11eea5371ca5c1c02a0677b33cc88ec728c45edc4ec060 7f380dca723b15d15ddbf10ea3e9be59e99c852543312d1bdba5095421ca2939 b1e6fe2b34e0bc4abd1364e32d5dea4ba4d41b06773323bf052ddc7e26a12505 +1252000 103a7af12db58d849bbabfb7715cef02dbfcca5ed5ad3755f5e28925c5ab56e6 ade0c3010f755d6fc805fd5b0d31fd1286fae8bf68b0f2b847147a4b05813edf 6ecc45139cbf4f724522ee9b1e69b49788c6ec59949c33a753737aceff92b766 +1254000 8cfb553af40ecb7adf9fa14fecfee0a7736facacca56bbf326b34abd63a07b29 bcdfc92e8f675f083e744d08acb5428ee8be8aea0954b311f23f139d67c7f3d9 d206de317f699539d09da4b6dc1e0be6c20dab7ba000758727c376f1458a11da +1256000 0d3a316405604f42eab7d5f1ff536f26ebbcb75a5734358960b972a4e8ad6e54 994164e4b08270be050cbd9d00b2a4f2bc0508a91d72d16876ceeb7317189bf8 3c566db8cc14e218a3b7b5ecc732f04b176fb82806c2e8f7d44ab7c696aa261d +1258000 bc496cba390d486660dd8d1ef9c8a19e6436ee10641b85358fd738e97bf3298a 21f581ec6b720356b97512ffeb15e2bacd55b95b7a57ce1a3893a7d973b29d04 0c66da5baf9b6d6d5c1e2298d69eb55bcf3a6dff5ad5cd9a13f5fd348d6f09bb +1260000 bb7c346d95cee5d6ca9d0cbcf07b4fd927f364e6c34701ab3f11c05b47c39248 2db70d288e98ce1d30f4ffd3fbc72a997faafde3bafa5456fc95e043e222f116 ac9a7e7fb64a8be275125389b140fe2ef99888ec09d2b6c709f51f3a4e2b9b31 +1262000 94c1f56d0a81cd91e49f398b9f1e694fb74a3603f7b57e5c4b64f73c8177746c 31430c44a2de9b38253e76ca46fa556bbfe52fc90c213912b266ab6aed44f322 3616dad004c9ece7802064b1c9a36b07737be3fec4c78cc298d2c79642da5b69 +1264000 0f00faf2d601e9c15c4481611399dff33accc30d463023d3d665a0ad27f5ed0a 7c71fbbf0f6441cdb4d94994a3cccf11d29525dee5a60edb1b498091e3e6e9e3 92c6260f399c2e6f8ea6ac6aa9d3a885a91442fac624df06b26d88a212729847 +1266000 75082d0746a6730bff2f3bce77078e8a53e84327489a5ad7b0cbb87fa9a3d541 8fc3792f77cadab2dda9901f0568b77e0ff9236467eeda778bc3d1773061bc2a 6c7767621e64f7b61bec764a827840a6c02db2b06952c3a51d6d4614b5c86585 +1268000 87aeaf34c66bb235533dfc84dd9020651d75ab22be1227dbea1fec71940b7872 4fadefb7c2f97af5ed9ca1c32da861d54a836f5574d7f6bd8223b7895a64c11c 5475023db421f53d8e638211b04dd42be662bcea5af15c9b12d15140c0c09c56 +1270000 26c78005023bbefd0b9fe56fc033098acff1ebf669bae4bf4c2ebf8ada13a78e 529ff3fd3450ae8e8015d15f432acddeaecdcfae510231e6a5004e2333005fe7 79f1ef9c6eda2f5c2731686c2d31c425f96a565efdca7ab72899e581724fd86a +1272000 e4c3a3b3c23e08660f1b9252195cebc70eadb479c8d7bc2d8bf0325812beb34b e3203dda3d22769a05f497d62315b5c80d7854db5bc5bb93b43fff411f2bff77 bc967dda70cd9b641849ae98e82958373d14942c14a788772be46384fcd2ecaa +1274000 ae125d8eb03c12fc41d03935ee86c59fb42abff159b31e664a2af96884d380de 07b0074eb8e6ddeb94adfc48e158dd5b55c16e37c307aef180da4c25036ba473 f375b29ce3c9d8270f6f5fa7d0ce59f88d470c7912dbb51aae68a97eac370116 +1276000 27437b07dfe0bd6449e7469e7b04c81084583f4c4b5a48dae195b6108be74d23 405a817eaf315c87dae0e0db4af0f288f6974c4443e9b95f733d5ed3c4ac662b 085c2bd42576cd5bc8d8423ec2fe3b335a1b4d545c3291b6452ee0aaa12ba518 +1278000 92c08d0d52e400d9fa6faff5e1dad76acd0d58de05f049300a7621e4fc62c19a a79d83e5231b1d5e63cc8b3cdde98213ea5dd3438757807f1691092832e49596 c2e93de3699dfb040761d46729a81c09a8dcf1aff792b1ad76d9c1d29b6aa9ef +1280000 9e6a06dbb8daed36856c2dda1a2e3e7ef487aadf925bdb3732ddf6662d4b6a6f c845e23e8cf8edd4dbb1b8d80d25ba35cba1c792a05f3239f098e3dd1c99d216 97e6711104e0e785cbe67493085046f1e97fafcff9c10b2aa8f58ea7c84a5d52 +1282000 07c176b0be05d2986a72b506fdebc75f428c1bdd3901b61ffdbe83c698985b23 51b4093bf9aa6d9788b2f96048dfe59cabd375d10f2027a28ba29d6916587e96 4321732387ead2df651a7038e5a8ace7fa7bd7bb05e1ea617cfe023c422a914c +1284000 8e4a77957138d8fc431bbc1e3bd6720a97c2661cc38fd32cb582aacd21b585f3 158626181944aa5659e208bc72548ba9b1a7913917354653b4c87aee786791f5 6cb982fff19fe40976291937b262d3f72d7c04a373538c2c13eac67ab1ec3442 +1286000 1e6a2e37d40697d213fc45aa3021526173c08bd830340b904373b6d6fdf59f45 be2f192fd5344ae338eaeae8ae5a9b3148d8317fb5b049fa21a281d9db5adfce 1d5a69d7030a33c6122fab852ac9e9333eb595fe2fa2afea22ebd11004079f53 +1288000 fde5168788249809f279405b030bfe61c0c21d9337121e72f6a5c4bf14b3fb83 f8ee63fdb60099db5c3fc7abd99d13a94cd55a9974b80a881f7ea5eb2feedb37 d58f4928bf6ecb296d2f68265227221ec9081e403c64bca658607951c5da2249 +1290000 654c4adf641cd6ec860c3078fb0792df9d6876eca4aa3b1ff86d63dc7764e959 c8d38faad5a606bfad7f552b3878d5eda09767ad5963bff2c66728c69549b395 029f157c714f51b31bf9ac421fb10f761455c4a0e51852ddfc8de9524e5b5168 +1292000 081932308ee6145b687c5ba19f6033de729a063d7d997cb9edbc0c96eea9ba1c ad9127435435e4f0aadf3d427a69a33a17ec87c0842bcabcebd7c49f701d2b11 5b31df71f961a448dc4fda82cca416fbcfd4a40f8b7b122dc9f604f0a60bd27d +1294000 41a4ed261c099df98ef81bbf51a2fa12b3c7fd4675daa69365d821d619057e0a 76afef22733b4fdf326580550af8779da4911b596a4907679f8a031b2af83609 d9cf53b783138a91a5cba0c3e030abf31c7b0473b1e16fae2266162b0f9fa206 +1296000 c8f9f20b8be114b6e3b473829bf78defd923883f2dd9ae09a3d1f92c3f4f740a aa568dd3b4bf75fd9f0cd3507d9fe7cf2014a3dd51803e82f30ee7af954408a4 9cb292168440584cfcf8c7491074fac2cdc20907d10b10368ed8146743d2ab50 +1298000 49b852718c6cc899a0502ac2a42c23f9fc9f8a7321900ced7b0c1b588b3a6064 9f6228c8760ff25d06a3c0e0cf2d6d741d93176ade5c989f3bf4f40359207beb 90fbfcd962e2fb8ee48b4e02609cdffa84b5daf02bd6e9d0e35373a435de7616 +1300000 80be4067b5dc8e3db9b787ca4a69c09b3478b6434edc51bc8984db1a79fa620f 4d56fccbc10f43ea89df4b2fa824a73c5b2d1190fb5de164092279f697289e14 1bce505db4804a7b5b5851d3bb41f1899e2f8afc5e94460aca3dc5dd408bd67f +1302000 544efef97cf41b6bb9e3dbfda5227a212926259a550c074dbf8f1ba908dc215d 078ce0da1fce9552e18cc7c3623513e3230cb3a7f0cf6df81f0497152dc1df55 534f615e3110d94d01f09f8060bdf238d4b6666a6a59ce1646a61afcba3c11ef +1304000 559c02ca3a8a1af36c35f9b1a88ddcc62465f4e7d7e6772e4c6aea9a915802bf e566a5e40389fb7bb3b31abd9f3e321588abc0ec9b5a6137463dd3b555c85256 1e3c605c066cb6de819cbc168659de091f9e6260cf246b04c1a4fa77b48f25a0 +1306000 55e5690d2e3b225fd18cc1b84b730cdbc41d80972061681e04332a809a8ecf1d 9a57579a292cba61171c09a248a2024190eae53f339edf09e4136022ca8dd051 4777fa1536a2f56ce3f8887b0c16da4ea55f6d1f0bef5aae36b8064148dbf532 +1308000 2fd94d28bb9624b2a6c8e4238a1b3a78930c2cd9fdae20d9f21b0058ab7297cb 2de44af1e36d99659094c84d3c9301ba25153f94c28d8065163f26664975212a ac5470747935d4e3e40e71d255190c083ba64b32be0c9237a042730d1ba5eb32 +1310000 5714d6e455f010c7d4132c018fe08bf6bdd5a22e39c96019850a0c2e7818284e af45ca1ed5374d6974e849df9da7a3ce3a8f65a8cf4453f45a027e707d729f3b ac1dfc98a7261b9309e501f46f422d2ba2e86bee2e0a3bc47c1a314b71c1744c +1312000 739a491b2d55e038f03ec5f42fe6e8557ddc6577bef0c34dc97184abdab473bf 1fecd361f96b16dbe3895191bdc8f8fb8f2974e4ee5ebda0895e57ce692ab921 61b3326772ae4d2c0285d77a576ae1edd3728a661966b44b4cbf7dbc023793a2 +1314000 b885133641ecfbc276c99f706f23a7ba6ea6e6f71eb593b4fc1d684dfce5e670 b21e8b8524eed2751671b51991334123cdb8f9a653f7d0aa06dceb22705c3964 3eadc89169f9dc1ac5928866c8aa06b082d470ad9deaa50f875566c3efe0c547 +1316000 0c5db83c4869fb0c75c93b5cf487878c269dd061dc8ca30ae6d03ba0986737b6 c0b9d5f12babb0e8caa9c6bd0782fc234033d9fcba92fcacb20c23bcc03fde32 d3b9de940298773b15110df9c90a80c435fb7a7194d2a66ee44b88d8b68d2659 +1318000 c32f763bd21552047b4745cf03a303aace33bb62bc78729a21d850c2aa3fa765 49eca63282f36237a1e8a0a5cbc277387603cea3465c19e16ce307b9c5f43ec7 1d374f63b0659b3dcafeaadfc383912092fb76b5d91f54c5478cc25a27a911af +1320000 2c25da44a5de594aef804606f55a29cdc1d0a5d2d88cc1f42e8001ad41ff0349 1bf8caed1679113980cc2bab7057f1df38cd69568377b4d14355f21ca1d059e2 97eefee84c96f9e68a14e497228c72c70367c797371bdd943d90227405630306 +1322000 fe1d2c0dd906922649e1552a46f1c4f34c241033faa31d090b0b96faeaf77a4c b41baffc4739c4bf17352a01aac07100939119f8101bb136532905be8bfea689 4b4a06b3a536397da0b371820a1a8e19bd823395d619d865408aaedee4231776 +1324000 e4bfd9e20362334ac70e43e9c846cc126c673f7eb02c1d42c03e53f9141e0e97 0bb3fa61ae907bcb708d4e64bae54caf79559b2af9c1e04d005ae74b3ada2b35 c598d4fa405398e71a13a9781d84939273de1bed31536a664a57f8d3aa948b01 +1326000 1c75c65cdaf0e7f3e13b283db35b26e3e25828959e21ea81d7730c5cfb36f756 9363f3d42a9b444e65d329622ec89764537274204280815493bb3b01841c8071 3ceaf1f13367fed60ff9fe33c5d68a38403e49c64908bcff196a7b8abb7a7978 +1328000 9f45bb8494eba18bfa77f37671a86bef58f603277e0a7e0b39b66043e36fc7cc beb92a4af6a50dd342733c35e90e332cfef58d13fc8bebba63385a9aa2ad8bbc 48607c03e2b1b320542ac6d36f6ccade8885333691f38e9b59545fcc4f20bb05 +1330000 82af61daaa05eab442445905f2bcfd70b834a89c053fe91d8a3e9a6e2903da92 1b4dbf8155ae078c53a20c40f3f885cdba8dfeaa0a9c39418b3b16bb239999c3 bbfa0996fde3527147d66613a8526c2bf71c59011b8dbbd78a888e51314fc1f9 +1332000 e01456cee152846473cee58509ff4c4415e14577a6ef73bd8fa27f1dd044dde0 9ab20744bfde58199fcceae8f3450158c40867c075049ed3db4ac07681a1f3b3 d873192454870d3552e99604b7adfb5d1c5ed2810aa05a523e8172ab79166940 +1334000 14db391f5c253f7be4edd2a93104ad56b12d724936fba1b2ea5db1698a04b3e1 999935345b4e187ecc8b24e2516e65fe28e164bff6ba6c1b1ad0ec3dec7501e4 8575a61ebd69cabfdf2e2c6ac2535527f600d82be2f1bec30aad723118732387 +1336000 fc6faa8630dad297c095b2bcfc1c2a1b31fb9d096afbe054df9d8c30ba539429 22d09150e03bc5c4b75b6725fb66cd8576a07faae7e9671b4f013e17a60aebe5 b9a7908de62f2a8fa9f791de69e1d897c09016a5c4ec8c39ed09e0b5cd1b0a2e +1338000 9c86c8056bf1839ccdc2cb5ada238c7a6d26f5f18a671ee8564179a385acef24 54dbf13ac520773fe238e2a8869c33567cd934a2181e498d45b487b772c545f7 9185ab07659ae4965398b20e847912ae4822f0c0348d59d9333ffe735ad37e3d +1340000 3e64e6592a77bb5c0b14a0d19c7f6a8f8db13a2f9474b7a3747078692254b806 fb44259b26bd8eebc845e628aebf640c21a8879b2051ae277286edb12409a963 003b67554566c61bc5d780e758e76eef767d1d00f9190cac1e2970b60bc87a56 +1342000 d364616fc00a65a689d10b6cd502332a39da2057cb5a9bab5d42b57f58008677 bdf1d1f0f49816ea11467c259c222f43e4c6874c6dc331232bd7bad04c595fad fea0407d2af5f8d7a2b4adc0d87a09ec69ea6b24c1ed23a3613166edb6a453f5 +1344000 68a959caafb08b0ec9031f822662f55d0b5f99df16e261bb690877ac7a5840c9 f1029fe9123586dfc0a0d095a530b7268b25af57249400649c171a1a8e0d99b0 da8d5a7712a0ba4506a3c2401b3e676e3e3b9bfdce177b1bed2600297d315881 +1346000 09312323a05424fc100d01358f796c42444a1a80bfc9b1d4ef9c4935455201e2 diff --git a/iguana/confs/DOGE_peers.txt b/iguana/confs/DOGE_peers.txt new file mode 100644 index 000000000..86a282c2a --- /dev/null +++ b/iguana/confs/DOGE_peers.txt @@ -0,0 +1,127 @@ +144.76.71.141 +63.231.239.212 +76.178.149.124 +50.168.159.133 +85.172.79.190 +109.239.49.207 +23.92.25.116 +104.236.136.96 +83.163.222.19 +47.88.34.118 +85.24.244.205 +104.222.120.12 +109.233.58.55 +1.32.70.66 +125.205.136.247 +52.23.175.47 +188.0.80.142 +189.27.147.140 +211.149.148.151 +179.185.112.222 +81.5.71.115 +62.76.15.208 +204.91.28.100 +84.18.118.27 +198.27.81.24 +52.76.154.206 +52.69.7.50 +52.192.155.175 +82.24.81.133 +5.100.250.140 +114.55.5.204 +31.179.43.191 +194.135.90.38 +198.50.242.34 +176.9.31.178 +85.25.41.70 +123.57.60.66 +5.196.82.175 +148.251.88.245 +163.172.19.96 +192.30.138.66 +72.207.111.81 +98.115.147.74 +174.50.64.101 +159.203.107.139 +50.191.229.7 +220.135.22.146 +120.55.80.212 +157.161.128.62 +96.48.162.59 +73.253.240.20 +149.210.242.48 +71.181.42.73 +178.32.9.103 +107.170.82.106 +210.28.136.11 +82.78.191.165 +96.126.123.143 +23.239.31.246 +176.9.50.227 +101.200.156.61 +31.41.40.25 +94.254.62.188 +107.170.86.160 +203.74.121.63 +121.40.17.150 +79.109.198.106 +192.95.56.199 +172.249.137.148 +24.249.152.169 +95.174.187.112 +146.0.32.101 +67.171.207.32 +76.185.84.244 +108.241.66.106 +31.184.195.115 +176.9.113.75 +178.63.18.3 +73.225.31.99 +139.196.9.71 +173.28.134.245 +192.95.29.153 +182.92.183.58 +173.236.240.49 +142.217.48.137 +192.99.11.57 +198.23.230.253 +85.243.255.154 +87.189.43.165 +54.201.183.106 +84.230.4.177 +220.240.96.156 +111.201.159.247 +78.84.100.95 +71.207.13.6 +84.253.125.186 +180.229.32.149 +121.42.206.214 +213.65.111.18 +65.13.189.227 +98.127.32.237 +65.28.164.248 +71.236.237.133 +24.22.225.211 +86.21.9.55 +144.76.239.66 +85.25.200.102 +92.255.199.98 +67.170.74.103 +98.162.199.30 +145.131.3.54 +81.7.3.24 +77.201.157.202 +104.131.40.196 +70.79.168.92 +71.80.233.61 +78.102.123.56 +120.146.143.87 +174.115.20.94 +24.255.204.177 +69.145.193.96 +80.68.90.161 +24.121.141.96 +176.9.65.41 +173.63.255.25 +69.42.223.118 +91.83.69.247 diff --git a/iguana/confs/EAC_peers.txt b/iguana/confs/EAC_peers.txt new file mode 100644 index 000000000..20c915b1b --- /dev/null +++ b/iguana/confs/EAC_peers.txt @@ -0,0 +1,4468 @@ +146.0.32.101 +123.56.194.66 +217.122.239.19 +212.64.75.89 +94.123.162.221 +74.90.154.237 +42.196.243.236 +74.143.186.94 +178.221.10.58 +60.220.242.50 +118.239.145.167 +88.238.245.183 +189.171.67.98 +175.142.48.242 +75.109.217.10 +61.144.248.50 +187.11.21.116 +46.33.227.191 +93.197.180.3 +2.132.183.6 +196.210.30.187 +217.50.200.34 +86.163.165.110 +113.103.2.74 +223.68.162.149 +203.170.65.41 +2.99.237.246 +39.70.137.201 +91.127.189.202 +24.197.135.210 +93.104.169.149 +24.225.139.119 +86.174.173.115 +101.127.12.187 +213.163.253.134 +2.97.3.62 +105.157.83.165 +81.204.130.167 +85.76.6.81 +78.147.54.113 +223.73.142.225 +113.47.172.36 +81.201.57.48 +117.80.249.31 +99.162.156.48 +114.238.82.216 +58.61.69.16 +79.119.6.188 +100.86.107.102 +93.39.211.68 +188.136.203.119 +183.206.194.242 +106.68.77.3 +85.64.147.42 +91.215.53.243 +70.63.7.82 +72.185.19.135 +87.158.153.170 +74.97.191.25 +84.180.229.108 +87.208.37.198 +118.194.208.164 +95.208.204.20 +60.166.216.176 +109.102.94.41 +121.27.143.29 +104.156.240.174 +151.225.162.202 +87.95.35.182 +171.116.80.29 +27.55.223.143 +95.18.84.137 +23.104.70.141 +192.99.13.205 +188.22.69.142 +49.49.213.44 +180.165.145.138 +121.54.44.95 +50.162.94.94 +93.203.226.225 +42.236.131.99 +182.148.26.245 +212.172.221.21 +87.146.41.243 +79.117.87.152 +98.126.241.19 +125.24.111.218 +70.196.128.231 +138.91.64.50 +68.116.198.132 +151.77.234.163 +77.249.129.137 +72.174.193.164 +122.94.17.46 +183.21.156.171 +68.148.56.125 +31.181.221.213 +69.35.200.188 +92.156.194.143 +74.56.57.7 +80.248.203.155 +113.91.130.246 +92.6.234.168 +14.219.75.220 +83.161.133.33 +141.237.83.36 +106.68.251.58 +128.75.135.88 +217.118.78.34 +79.117.52.137 +222.66.175.226 +115.229.84.218 +121.102.103.231 +188.81.160.48 +138.246.2.200 +75.164.245.106 +58.250.97.13 +120.239.15.218 +86.130.125.87 +37.192.1.166 +5.70.81.3 +113.137.151.27 +93.137.194.255 +111.14.248.242 +203.96.43.66 +112.215.36.145 +173.16.206.215 +108.239.52.66 +62.19.64.157 +206.74.213.130 +14.223.195.11 +108.46.13.183 +89.241.66.102 +79.101.185.109 +83.36.212.73 +192.99.44.159 +78.111.216.165 +120.239.15.101 +14.203.72.142 +49.183.168.151 +213.24.127.109 +192.42.116.16 +201.29.238.136 +96.235.180.4 +75.109.216.32 +196.210.125.168 +87.160.143.46 +58.62.12.26 +79.23.168.97 +193.111.137.242 +84.228.205.129 +89.167.37.192 +112.198.79.79 +110.205.78.223 +24.117.46.106 +114.216.191.206 +79.186.177.35 +87.119.66.110 +77.5.90.99 +174.56.123.56 +101.222.255.201 +24.183.2.16 +5.47.98.217 +108.8.122.212 +217.112.178.222 +188.227.181.234 +177.106.130.202 +85.28.80.167 +120.42.16.235 +95.223.228.81 +27.46.19.9 +217.66.157.84 +173.254.245.109 +24.139.28.125 +101.166.161.123 +83.223.168.28 +31.16.126.244 +216.36.143.139 +117.25.241.141 +177.16.36.51 +223.245.100.205 +173.59.6.144 +27.25.219.39 +183.145.58.241 +115.148.191.187 +218.205.19.23 +71.237.255.120 +80.128.195.121 +85.178.86.67 +123.243.140.119 +221.11.109.165 +24.246.27.150 +78.11.201.122 +83.6.194.44 +142.162.244.30 +5.103.50.138 +100.64.15.235 +151.229.43.186 +142.177.237.185 +50.23.113.239 +114.79.3.202 +91.134.233.254 +205.164.0.10 +76.17.125.242 +81.43.195.167 +14.18.235.163 +112.198.64.54 +83.56.190.131 +105.237.128.137 +89.164.168.206 +178.48.204.234 +79.112.46.38 +27.38.210.178 +94.211.196.55 +84.163.147.76 +78.90.14.107 +77.251.101.136 +131.193.220.16 +83.35.177.244 +118.206.42.57 +2.61.171.100 +113.92.117.22 +24.94.110.229 +203.206.65.250 +192.0.0.43 +183.160.247.99 +50.149.31.242 +196.210.126.150 +117.184.130.188 +58.107.64.1 +184.97.246.199 +113.228.184.67 +60.188.148.88 +2.231.140.32 +39.48.57.218 +79.117.240.229 +93.136.55.211 +66.108.201.191 +93.38.213.239 +188.208.206.215 +5.77.187.188 +59.51.55.10 +79.103.24.126 +82.84.64.6 +84.238.159.185 +192.252.234.44 +36.71.169.241 +121.207.196.30 +84.189.51.225 +222.217.191.107 +107.193.17.17 +115.214.237.171 +70.16.194.160 +106.120.30.92 +79.216.29.167 +46.126.105.172 +81.153.89.132 +85.53.213.36 +85.178.127.3 +119.70.199.158 +49.77.239.90 +78.168.227.70 +113.97.50.95 +179.25.59.127 +212.220.56.70 +104.181.2.17 +114.79.58.36 +113.167.26.90 +180.165.90.163 +46.159.28.244 +222.182.234.187 +176.198.140.100 +78.251.108.13 +153.34.159.229 +116.22.2.216 +85.177.157.101 +107.145.245.252 +23.29.217.124 +112.109.182.175 +86.164.196.230 +118.210.66.232 +61.186.56.169 +23.113.201.151 +60.217.35.31 +177.96.118.14 +71.84.192.137 +24.60.119.11 +50.224.173.203 +83.26.25.113 +14.223.174.79 +99.152.2.7 +122.94.26.74 +180.165.159.172 +207.29.252.14 +58.250.96.113 +43.248.8.181 +58.11.37.86 +84.184.101.207 +91.9.141.32 +89.210.14.40 +109.214.71.199 +124.127.199.62 +213.230.94.157 +95.240.229.96 +222.43.201.232 +114.85.28.45 +124.122.111.167 +58.182.101.235 +204.11.237.245 +118.69.70.177 +86.144.92.22 +109.231.11.91 +80.30.32.174 +171.216.9.19 +99.115.34.76 +83.27.162.32 +115.197.174.229 +121.216.244.105 +24.52.236.62 +69.80.98.60 +178.116.172.103 +195.240.11.185 +173.176.72.81 +212.201.69.154 +141.136.148.22 +79.104.38.78 +70.76.166.31 +62.65.223.80 +89.20.233.117 +61.164.68.98 +193.169.36.238 +99.111.238.213 +201.22.94.168 +149.71.143.122 +95.46.235.119 +188.96.50.254 +106.69.24.188 +66.143.32.149 +183.50.87.87 +79.103.158.176 +217.120.136.41 +146.185.171.123 +176.62.234.1 +84.90.24.114 +89.34.206.201 +212.123.190.28 +109.252.68.152 +125.89.23.239 +118.209.161.250 +5.167.95.237 +193.169.18.128 +91.9.148.125 +151.52.142.63 +188.167.224.153 +121.63.32.151 +61.186.178.125 +80.117.193.112 +69.251.51.223 +189.222.89.83 +95.168.193.75 +123.137.188.200 +222.245.136.151 +65.101.97.134 +68.110.96.228 +106.86.13.237 +23.228.235.13 +50.137.162.155 +198.18.1.27 +86.167.207.168 +123.231.87.27 +98.185.150.233 +212.67.97.2 +75.141.255.61 +60.166.218.127 +105.247.135.221 +78.145.253.98 +46.5.44.52 +72.38.160.30 +178.34.45.184 +86.163.164.8 +71.207.19.122 +172.248.12.129 +109.194.28.126 +67.166.231.189 +85.150.49.130 +124.185.240.173 +118.210.105.136 +115.216.242.109 +209.169.221.74 +115.77.135.160 +112.68.222.148 +182.96.255.191 +37.187.28.68 +216.231.132.49 +184.226.244.245 +67.181.102.192 +37.160.60.133 +46.115.17.197 +80.57.22.53 +46.246.59.26 +176.193.55.215 +171.4.248.58 +75.109.216.239 +188.234.249.148 +70.50.179.182 +27.252.97.216 +94.190.193.210 +66.49.176.164 +205.162.165.147 +198.91.157.163 +197.28.213.113 +61.48.38.87 +83.45.207.52 +9.221.192.236 +109.126.230.240 +90.209.69.123 +141.84.69.84 +87.113.74.228 +93.205.9.46 +123.17.103.59 +1.173.140.51 +85.177.89.51 +85.26.241.157 +90.245.35.192 +182.37.113.145 +122.148.64.33 +223.96.144.129 +213.64.148.201 +108.202.129.66 +105.99.189.59 +182.132.232.175 +37.44.91.84 +109.66.194.102 +89.69.132.175 +203.109.167.189 +222.132.7.238 +74.209.28.90 +195.168.238.229 +116.87.132.37 +175.137.121.110 +115.188.29.241 +79.102.174.107 +213.35.192.186 +171.88.138.112 +111.14.241.81 +94.50.205.76 +109.167.128.208 +113.110.35.181 +76.103.121.93 +36.69.240.250 +37.14.34.187 +79.11.21.116 +98.118.3.238 +94.242.251.41 +91.63.33.84 +83.4.109.145 +2.40.8.117 +100.85.128.106 +88.244.139.10 +112.65.211.232 +85.76.171.173 +24.215.125.210 +79.115.88.35 +86.185.7.42 +173.66.164.176 +86.146.122.192 +121.27.152.3 +58.182.101.58 +203.109.167.128 +217.224.112.78 +151.33.74.249 +77.202.249.172 +123.133.235.22 +58.107.70.13 +78.134.104.245 +77.102.194.207 +197.70.223.101 +112.15.239.123 +110.188.107.114 +46.159.73.215 +24.52.198.35 +98.18.113.2 +189.162.18.169 +91.190.115.250 +84.202.218.192 +195.91.12.156 +186.146.156.243 +188.134.40.100 +88.232.145.26 +1.178.124.43 +200.169.48.1 +70.180.183.30 +83.22.247.118 +217.118.95.74 +99.2.202.21 +24.135.189.116 +180.169.41.142 +178.36.51.250 +42.117.107.19 +91.141.3.105 +171.96.240.135 +92.130.111.185 +92.40.249.102 +188.208.105.196 +108.212.73.204 +201.229.66.198 +90.209.209.111 +58.186.180.82 +142.161.9.133 +200.73.161.121 +81.34.43.77 +37.14.41.4 +99.195.242.79 +152.66.226.44 +115.77.140.136 +58.107.73.238 +86.173.132.253 +93.174.228.149 +31.50.129.226 +125.86.255.58 +77.3.91.136 +201.170.18.89 +93.56.53.201 +76.24.82.178 +115.239.68.112 +223.88.14.114 +62.192.232.90 +87.160.153.132 +2.99.239.143 +112.1.99.92 +82.25.191.84 +2.223.215.142 +123.148.144.3 +187.155.98.162 +82.225.144.243 +112.123.48.9 +120.204.157.231 +190.160.196.103 +87.78.158.139 +100.84.99.166 +79.178.149.48 +94.123.166.17 +78.0.14.61 +122.242.8.103 +94.227.135.62 +185.2.31.225 +46.105.102.43 +91.157.88.101 +92.105.109.120 +178.122.85.245 +94.217.200.159 +14.20.5.230 +71.229.224.106 +78.69.7.89 +101.107.210.90 +109.93.134.192 +180.139.102.21 +2.101.151.9 +110.205.64.246 +112.234.71.251 +46.159.90.85 +24.247.180.118 +91.98.17.33 +203.158.35.73 +5.79.66.130 +74.216.48.42 +81.233.78.114 +110.32.225.192 +182.242.72.234 +117.53.82.41 +93.201.247.195 +86.174.183.234 +75.166.170.249 +5.147.105.15 +50.51.145.43 +210.55.212.69 +79.112.9.134 +78.144.65.161 +58.250.98.81 +86.164.198.162 +112.208.109.144 +75.138.189.62 +82.73.159.73 +87.198.127.85 +173.208.172.242 +176.42.29.239 +75.109.216.143 +69.145.231.43 +49.188.233.246 +76.31.180.38 +75.164.169.251 +171.212.217.233 +100.86.105.29 +176.127.162.83 +110.33.10.38 +107.221.62.118 +24.116.191.33 +98.239.187.255 +93.210.173.249 +86.210.166.9 +109.79.163.127 +90.187.152.82 +114.215.116.228 +186.204.115.111 +178.75.197.39 +178.11.193.229 +49.145.102.1 +171.216.135.159 +111.17.104.76 +183.26.213.120 +100.72.47.231 +93.48.228.129 +92.240.209.105 +50.165.46.120 +62.235.203.80 +146.90.90.170 +81.141.1.94 +117.141.8.51 +151.21.106.14 +60.214.200.152 +70.211.67.174 +178.78.155.9 +59.126.155.196 +72.200.62.210 +86.145.250.44 +54.201.57.56 +185.3.135.18 +74.88.177.204 +70.120.214.67 +101.160.48.136 +93.24.164.104 +108.90.13.190 +85.101.22.253 +68.68.96.30 +64.237.234.64 +31.205.112.25 +93.105.79.112 +177.104.232.205 +109.73.70.170 +90.221.21.178 +175.172.143.75 +61.137.117.7 +173.21.18.239 +116.251.223.51 +178.121.32.78 +67.140.215.104 +68.226.144.118 +90.96.178.204 +49.144.82.166 +89.244.93.43 +115.197.231.8 +121.224.99.49 +210.186.58.228 +188.119.233.1 +93.23.63.159 +95.78.196.193 +14.97.70.116 +121.200.133.251 +207.172.230.93 +140.237.235.103 +25.18.78.4 +76.181.167.227 +183.27.229.57 +220.175.13.51 +88.160.93.133 +49.147.171.186 +179.126.48.181 +94.216.35.89 +178.197.233.213 +62.73.111.141 +79.71.124.96 +128.72.56.151 +46.8.161.58 +192.171.35.206 +93.136.191.83 +62.47.19.200 +92.228.47.233 +88.160.28.217 +97.88.160.227 +81.163.208.148 +189.203.252.228 +68.84.207.46 +85.102.132.217 +176.10.107.235 +79.31.171.56 +125.33.79.98 +89.240.55.173 +123.246.82.93 +46.212.228.82 +116.21.83.180 +61.150.43.96 +82.61.92.139 +178.192.152.211 +109.193.72.9 +79.12.236.83 +79.117.78.130 +81.207.50.40 +173.162.236.65 +27.156.133.160 +95.29.25.130 +101.44.114.203 +84.27.216.15 +120.84.104.23 +174.61.236.137 +31.23.179.226 +84.128.179.167 +172.56.12.211 +85.176.133.231 +87.236.212.205 +186.244.155.232 +187.192.254.185 +85.76.6.51 +117.136.14.162 +213.152.161.85 +95.180.72.140 +94.72.102.195 +128.72.93.198 +183.248.0.67 +130.193.98.153 +88.150.142.50 +114.79.51.252 +94.134.4.187 +88.156.133.170 +109.182.177.31 +72.222.222.107 +183.46.21.104 +202.62.16.167 +85.76.167.128 +128.72.148.62 +146.185.24.18 +183.208.96.104 +72.215.232.38 +176.252.148.182 +46.39.53.102 +79.112.74.46 +144.132.232.20 +85.177.152.200 +117.212.107.51 +115.164.216.198 +83.10.88.11 +100.64.42.254 +79.120.76.115 +85.164.134.253 +222.161.200.7 +79.112.50.167 +71.220.188.108 +62.16.163.21 +178.78.141.96 +46.21.99.26 +78.42.218.228 +109.215.248.139 +95.55.20.9 +176.193.162.191 +36.85.227.81 +41.110.142.32 +223.73.73.30 +95.104.205.89 +58.107.72.196 +23.91.183.95 +2.179.92.174 +91.9.176.69 +222.220.165.103 +93.128.255.90 +220.187.143.249 +222.66.175.155 +31.7.158.193 +93.133.179.0 +83.39.68.119 +120.181.140.132 +89.164.7.152 +223.68.142.125 +217.235.127.252 +109.169.61.43 +95.97.11.26 +14.222.122.184 +86.147.75.166 +87.144.67.129 +60.178.58.67 +27.156.41.179 +192.34.109.157 +124.114.43.54 +108.199.193.25 +24.93.183.133 +36.33.237.113 +58.254.168.122 +178.37.37.230 +95.33.4.109 +223.12.39.186 +89.176.37.177 +70.160.237.191 +80.203.125.122 +194.28.39.180 +60.176.127.131 +199.193.119.32 +88.104.68.94 +46.244.228.2 +98.117.94.95 +59.58.202.248 +91.144.143.200 +65.96.164.201 +178.33.82.30 +79.31.171.42 +86.135.119.16 +118.211.83.196 +94.71.78.177 +176.52.73.175 +83.9.239.114 +162.253.128.10 +86.183.97.230 +197.87.51.46 +217.251.237.32 +109.217.12.30 +89.43.130.224 +69.203.2.62 +1.63.64.67 +122.236.62.203 +2.100.186.32 +90.38.224.120 +84.128.188.26 +76.171.37.16 +41.223.162.5 +87.146.234.229 +183.95.18.7 +176.215.235.111 +171.213.23.3 +76.209.18.216 +92.225.192.15 +121.27.108.165 +78.8.67.141 +80.136.132.26 +76.179.40.149 +114.45.132.3 +196.210.205.11 +86.122.224.227 +125.237.57.154 +83.46.90.222 +178.190.182.74 +216.229.34.92 +85.72.137.156 +151.75.247.137 +93.137.210.138 +77.2.173.144 +61.140.199.187 +91.9.154.168 +86.146.115.149 +58.177.103.70 +175.157.28.52 +87.1.38.150 +109.72.81.100 +185.47.200.121 +69.231.33.160 +175.172.167.52 +75.138.186.252 +79.205.206.209 +201.229.84.129 +128.70.37.127 +77.116.93.241 +86.153.151.228 +91.9.148.142 +65.26.237.86 +74.84.27.148 +182.87.72.103 +79.210.97.38 +24.208.254.68 +83.29.229.126 +84.30.255.198 +180.139.97.152 +113.242.182.148 +86.163.167.194 +79.81.242.218 +80.213.113.9 +107.9.43.235 +87.113.152.249 +93.219.215.222 +77.175.85.153 +78.145.253.112 +197.37.157.232 +121.237.70.21 +218.88.109.178 +70.79.248.172 +216.211.15.239 +123.88.243.21 +82.168.4.74 +36.62.208.134 +123.170.91.124 +113.138.229.119 +213.126.78.58 +116.231.172.128 +93.133.146.171 +151.231.165.166 +90.209.46.184 +125.127.71.110 +66.41.138.67 +87.177.72.162 +180.165.62.74 +98.216.100.151 +70.190.208.67 +80.30.160.3 +111.77.126.134 +176.26.123.103 +117.25.11.132 +74.199.32.152 +114.217.197.37 +68.116.199.34 +95.39.196.210 +223.243.245.237 +46.9.222.186 +83.215.106.245 +213.34.240.210 +173.176.59.236 +123.154.43.18 +174.22.151.11 +183.208.177.11 +76.175.155.61 +76.70.90.27 +58.107.72.120 +178.120.134.69 +82.30.212.225 +210.55.212.177 +213.163.242.57 +84.251.28.218 +24.183.182.75 +75.117.103.95 +221.214.214.20 +78.147.10.108 +80.187.106.24 +183.71.142.201 +108.161.115.92 +79.81.210.196 +109.226.92.241 +212.9.28.178 +108.201.22.99 +86.135.84.207 +183.228.214.110 +109.58.144.112 +124.185.83.212 +122.139.43.183 +50.131.110.28 +65.73.11.115 +79.103.130.46 +98.231.192.96 +71.175.81.45 +31.173.80.46 +130.211.250.88 +86.163.249.44 +177.131.3.79 +190.192.208.250 +183.210.215.244 +80.171.128.162 +114.78.48.195 +130.193.96.241 +91.141.2.114 +14.115.32.206 +74.93.57.157 +60.191.62.250 +123.160.123.165 +95.221.18.42 +183.27.231.180 +89.11.228.207 +86.202.115.14 +79.112.55.76 +178.46.226.194 +76.90.105.71 +177.156.136.166 +67.198.167.72 +183.206.197.200 +77.179.231.56 +103.27.227.240 +78.12.60.169 +203.213.48.242 +220.169.254.220 +124.244.147.185 +79.31.171.98 +183.217.155.163 +186.195.101.141 +67.209.212.101 +27.147.199.14 +50.252.7.113 +183.31.133.11 +86.122.237.103 +87.153.241.114 +90.210.250.202 +14.116.14.193 +222.179.151.19 +116.1.87.207 +122.241.183.232 +71.211.205.1 +85.118.69.152 +62.45.249.210 +206.45.74.53 +88.74.97.119 +162.17.59.125 +88.149.237.76 +46.159.187.129 +105.242.191.201 +119.115.249.82 +114.43.241.216 +49.145.112.125 +180.131.58.25 +112.90.197.49 +86.171.255.186 +50.166.61.72 +93.107.149.192 +77.46.220.98 +213.233.104.31 +120.0.39.38 +121.218.42.6 +67.176.249.191 +75.138.180.45 +31.28.39.245 +68.151.44.193 +83.82.59.37 +118.119.10.191 +117.64.75.110 +2.81.46.42 +93.135.93.230 +79.166.55.34 +85.237.224.54 +129.215.5.255 +90.190.216.211 +116.102.8.34 +184.1.53.19 +221.214.179.3 +212.30.204.205 +91.120.71.126 +209.141.160.62 +95.211.212.196 +115.164.219.23 +82.148.176.141 +84.250.191.231 +84.22.139.7 +178.76.223.101 +79.185.158.80 +2.99.236.202 +118.77.176.248 +109.97.236.113 +5.81.104.252 +37.79.249.145 +60.170.236.194 +67.2.138.173 +78.250.94.133 +23.100.45.176 +93.104.191.66 +95.91.219.97 +222.130.141.77 +14.20.51.23 +46.126.159.201 +173.184.97.86 +75.74.218.70 +220.233.14.166 +181.55.203.13 +124.202.191.134 +109.155.71.247 +80.171.228.105 +78.180.128.217 +93.104.170.146 +202.112.174.53 +46.12.150.56 +1.220.171.67 +85.210.46.162 +83.139.112.72 +176.251.74.38 +219.136.40.193 +213.153.156.208 +116.102.141.5 +58.107.72.190 +188.163.110.60 +171.217.53.100 +172.56.40.69 +90.182.58.114 +92.130.114.60 +187.65.60.197 +119.137.114.74 +91.115.71.106 +68.59.112.196 +83.228.35.227 +178.47.107.244 +217.251.240.12 +114.218.247.189 +207.148.178.122 +176.252.226.206 +85.16.3.81 +88.136.64.229 +5.184.220.109 +81.141.4.242 +109.152.2.200 +85.118.69.70 +110.171.182.228 +67.193.37.34 +86.174.96.108 +188.102.43.220 +95.117.93.106 +176.253.16.145 +87.109.13.167 +219.155.214.217 +188.250.134.224 +76.217.14.190 +91.105.156.170 +87.143.228.125 +196.210.106.246 +49.146.202.36 +111.85.199.253 +68.193.14.234 +83.173.179.60 +79.130.12.147 +87.158.143.95 +217.122.233.29 +86.132.67.187 +93.87.120.17 +77.77.41.97 +91.9.154.200 +113.243.206.193 +77.102.113.27 +78.73.88.231 +178.237.34.188 +93.133.179.31 +199.59.114.247 +5.9.38.251 +181.29.222.3 +91.105.156.124 +65.60.163.136 +117.136.2.152 +183.208.180.220 +95.145.97.166 +95.143.24.146 +188.25.141.182 +24.244.23.19 +125.166.239.1 +92.145.4.225 +86.170.253.128 +182.151.88.115 +118.239.118.255 +92.69.252.201 +125.105.239.249 +46.103.22.249 +94.174.128.202 +78.144.84.226 +31.128.8.221 +58.250.99.87 +24.161.113.119 +188.126.72.179 +87.245.33.219 +176.205.189.177 +117.94.204.208 +105.236.6.16 +84.215.6.143 +117.90.19.55 +115.211.97.128 +100.100.48.17 +175.2.36.244 +209.90.186.113 +180.252.179.243 +118.250.34.128 +121.228.144.113 +173.226.40.46 +93.158.203.147 +92.243.188.79 +186.214.48.27 +119.74.105.102 +113.82.22.118 +113.122.143.208 +220.175.88.123 +183.39.232.239 +183.32.106.62 +121.27.143.172 +197.34.35.114 +114.221.159.164 +221.212.121.12 +90.201.187.254 +207.245.41.195 +125.131.231.103 +180.113.48.91 +99.151.25.177 +46.45.35.153 +50.185.241.233 +178.3.118.145 +62.155.180.194 +115.174.6.36 +223.150.136.188 +79.225.127.80 +83.5.243.177 +83.81.41.176 +178.172.155.55 +77.163.144.30 +58.23.225.19 +216.252.75.63 +173.48.184.39 +68.12.247.3 +79.71.124.16 +85.242.151.174 +217.43.23.173 +121.45.74.13 +78.85.72.179 +176.251.62.32 +81.141.1.116 +116.224.64.105 +89.21.79.146 +81.132.185.236 +99.158.136.207 +114.246.173.44 +72.95.228.211 +54.158.58.34 +62.221.89.173 +94.6.150.91 +178.56.201.96 +91.9.185.150 +113.242.184.125 +210.195.225.95 +81.17.95.243 +112.82.59.239 +87.126.196.40 +101.45.49.126 +182.202.5.191 +182.44.201.83 +151.75.250.135 +46.242.73.221 +176.85.3.247 +193.44.1.6 +118.208.115.50 +90.218.242.89 +91.205.145.3 +122.241.176.85 +96.241.144.218 +122.57.103.228 +106.77.176.213 +95.9.219.211 +60.166.219.117 +69.132.224.128 +174.60.237.64 +216.128.237.206 +85.114.177.184 +2.99.237.13 +9.221.192.90 +177.157.0.224 +14.223.173.234 +109.100.175.40 +113.90.16.131 +211.99.134.28 +178.83.246.122 +14.146.8.7 +91.63.52.139 +167.61.186.50 +86.166.218.49 +139.210.106.149 +81.155.44.48 +176.27.161.146 +62.41.96.185 +223.95.138.22 +163.204.176.106 +49.80.167.237 +203.219.58.142 +87.16.178.138 +37.213.142.183 +90.192.123.227 +24.193.212.62 +74.73.97.51 +1.58.61.148 +190.181.166.37 +109.163.234.9 +90.46.156.217 +58.61.222.127 +72.22.139.97 +36.251.219.102 +111.206.132.9 +66.29.187.49 +58.40.134.117 +119.48.63.154 +213.222.240.61 +205.170.23.10 +95.133.238.237 +180.246.92.81 +81.32.253.244 +14.18.235.151 +217.194.181.145 +116.9.26.57 +194.150.65.61 +200.86.198.161 +163.177.132.61 +178.149.57.44 +88.23.21.103 +49.117.68.210 +58.250.96.15 +85.250.191.224 +25.21.155.54 +77.57.194.161 +87.2.126.231 +113.73.212.250 +37.120.44.216 +82.154.141.164 +67.61.132.151 +184.175.5.91 +58.254.168.98 +124.149.145.128 +113.194.142.244 +81.225.38.86 +62.165.230.170 +92.238.254.247 +88.234.6.205 +88.13.95.74 +178.17.170.253 +27.252.99.226 +41.97.68.104 +80.143.156.173 +24.27.103.185 +188.164.241.198 +92.229.134.201 +36.33.53.105 +175.160.191.189 +110.33.255.204 +151.20.53.32 +86.20.213.1 +213.65.216.7 +122.234.179.174 +119.86.157.163 +95.27.227.17 +91.244.23.122 +85.76.47.29 +201.230.222.107 +83.240.6.145 +112.198.90.32 +68.8.226.175 +185.2.29.194 +87.145.235.149 +79.209.14.109 +188.96.50.182 +121.27.158.238 +212.76.188.124 +58.250.119.126 +46.45.29.207 +135.196.115.118 +194.228.32.208 +83.81.56.148 +78.151.195.180 +171.214.199.36 +1.204.241.67 +59.38.65.47 +192.232.176.248 +87.210.218.46 +80.213.216.25 +46.15.115.35 +177.87.74.237 +163.177.139.96 +5.64.192.149 +77.20.210.213 +213.87.224.181 +108.17.66.159 +93.139.131.95 +193.175.34.200 +87.144.65.3 +89.37.45.202 +196.210.239.234 +46.34.136.107 +193.107.94.207 +116.227.131.140 +5.157.101.156 +149.254.183.73 +123.16.56.166 +41.133.13.176 +75.109.217.157 +81.174.44.49 +221.237.7.250 +75.109.216.92 +23.242.78.26 +86.164.196.144 +213.87.224.76 +31.61.129.37 +83.252.181.182 +72.161.145.206 +107.27.48.219 +99.192.75.183 +109.173.134.212 +151.32.116.124 +121.27.137.139 +23.27.220.138 +62.228.28.27 +85.118.69.57 +158.69.214.111 +62.158.39.174 +174.112.212.94 +27.55.200.14 +80.1.123.250 +110.88.252.193 +89.110.28.132 +85.25.200.102 +77.251.7.83 +67.1.108.46 +74.111.225.51 +2.223.56.142 +183.224.74.143 +69.141.141.192 +76.164.228.226 +91.19.201.254 +24.36.70.67 +94.79.155.146 +176.33.0.89 +86.3.201.81 +109.127.180.175 +68.8.91.72 +91.63.33.14 +153.139.236.163 +98.15.181.194 +124.168.145.241 +223.73.1.179 +98.192.77.54 +206.124.209.246 +79.31.241.24 +114.79.29.75 +79.20.250.225 +179.183.241.13 +81.82.206.9 +178.190.54.164 +92.139.199.236 +109.190.15.126 +182.148.46.164 +140.207.223.177 +81.36.182.81 +61.185.136.56 +5.254.139.115 +93.41.20.149 +82.157.21.189 +78.28.118.242 +178.204.32.158 +83.109.104.43 +99.249.136.103 +116.19.83.156 +68.90.41.17 +176.108.245.92 +24.132.66.18 +68.0.117.149 +123.148.150.152 +68.82.209.62 +84.158.0.183 +149.254.186.177 +183.15.166.151 +223.73.1.169 +73.204.124.211 +122.81.131.234 +83.10.165.72 +50.202.109.250 +189.115.81.31 +76.182.102.29 +77.20.80.189 +118.212.118.249 +37.114.90.11 +66.37.64.58 +27.25.193.95 +42.93.228.44 +71.206.141.101 +75.180.235.99 +84.56.59.227 +167.0.194.64 +58.7.66.126 +86.56.237.175 +91.63.39.161 +190.56.83.129 +14.213.199.252 +1.178.19.206 +86.159.124.54 +80.53.117.65 +146.90.80.61 +66.187.72.77 +113.104.232.7 +223.199.203.155 +223.73.1.235 +110.80.66.209 +195.134.181.134 +85.30.20.166 +71.84.43.181 +60.20.138.9 +193.124.179.247 +123.3.242.122 +91.53.38.78 +183.15.170.124 +5.22.24.122 +90.57.7.127 +213.87.126.150 +188.163.98.187 +171.217.8.187 +39.254.8.231 +84.250.156.248 +83.234.245.130 +42.96.149.221 +119.186.241.215 +192.241.181.251 +98.224.12.67 +14.204.62.207 +78.145.252.237 +83.31.199.31 +174.238.64.240 +84.194.46.119 +80.171.96.107 +185.23.225.5 +46.177.78.16 +60.213.223.20 +107.218.84.189 +217.66.157.13 +96.231.100.222 +113.120.136.141 +23.235.0.137 +27.46.17.177 +94.137.55.251 +58.47.156.86 +122.4.157.122 +113.162.75.205 +192.190.90.239 +24.10.92.109 +210.55.212.132 +72.135.96.34 +171.116.81.41 +58.106.201.31 +94.215.26.180 +114.37.52.15 +83.234.245.223 +149.254.186.182 +84.119.179.52 +23.233.34.59 +217.189.224.20 +92.37.34.62 +95.117.71.35 +71.223.105.251 +203.152.127.192 +85.24.169.215 +86.17.210.82 +115.66.217.225 +81.152.10.127 +37.201.213.137 +119.52.28.131 +112.65.22.94 +125.85.102.145 +79.119.242.62 +90.13.123.236 +91.105.184.159 +188.6.233.146 +195.23.100.102 +68.43.94.45 +27.24.226.110 +49.144.156.247 +78.180.95.168 +84.29.114.60 +87.146.232.175 +108.24.83.254 +37.117.192.246 +81.151.58.87 +218.30.64.194 +220.98.173.175 +86.175.85.205 +37.29.88.57 +116.2.92.177 +174.126.51.149 +81.141.8.51 +92.200.9.70 +151.26.35.155 +122.67.188.29 +114.79.37.117 +87.160.176.148 +184.98.239.51 +218.11.192.206 +191.179.106.80 +89.244.94.126 +5.54.140.148 +69.172.173.70 +46.159.228.216 +190.160.16.35 +190.106.200.4 +89.215.187.175 +175.160.82.100 +49.77.179.224 +111.69.201.251 +91.124.201.136 +93.131.123.58 +209.95.60.12 +84.212.33.227 +124.228.27.86 +86.161.112.236 +79.88.233.232 +174.26.13.36 +82.161.239.249 +192.153.117.70 +90.177.134.56 +141.255.160.242 +199.247.154.206 +37.146.185.211 +46.246.55.12 +84.187.113.138 +27.154.178.138 +108.207.24.139 +84.154.245.163 +114.225.162.62 +60.166.136.184 +98.189.209.221 +62.228.188.220 +171.113.38.226 +72.143.228.82 +79.119.47.8 +89.75.32.36 +85.26.241.21 +58.56.118.118 +90.26.246.77 +176.33.84.179 +220.173.141.41 +113.97.33.59 +66.68.33.69 +188.96.57.179 +89.65.150.250 +2.178.131.116 +62.74.25.110 +204.14.77.9 +115.193.110.222 +82.31.147.180 +184.147.37.174 +94.177.121.13 +77.38.34.131 +87.189.116.22 +78.145.248.8 +84.194.250.163 +119.139.115.101 +218.88.94.48 +89.143.141.39 +79.247.94.23 +99.69.204.87 +173.61.50.147 +94.73.6.25 +111.76.75.97 +78.145.246.82 +54.203.248.147 +85.0.108.178 +119.176.194.81 +158.129.26.8 +24.26.58.44 +218.0.3.26 +98.208.132.126 +178.192.23.159 +36.250.225.34 +79.240.133.161 +222.161.213.11 +186.204.86.159 +37.99.101.59 +72.81.236.193 +117.128.234.64 +183.208.182.62 +78.14.11.129 +85.236.188.28 +84.222.70.181 +98.174.209.207 +178.124.173.22 +80.108.53.26 +104.131.2.105 +24.253.79.233 +5.12.198.70 +155.143.147.21 +91.146.53.35 +128.73.198.22 +98.112.98.11 +88.12.142.217 +61.150.20.206 +79.31.133.92 +178.165.129.104 +188.4.228.218 +193.169.36.233 +81.164.73.186 +203.191.194.118 +120.144.72.51 +94.102.50.48 +114.226.45.202 +118.209.244.185 +41.130.125.116 +177.188.216.12 +146.52.54.208 +108.224.41.162 +180.93.188.68 +82.131.67.8 +94.42.46.88 +178.93.47.127 +68.119.96.210 +78.25.47.76 +188.69.212.13 +113.240.183.213 +31.55.67.155 +113.165.38.68 +67.170.75.84 +50.241.208.49 +75.109.216.134 +146.66.23.33 +77.20.86.135 +2.28.115.44 +174.48.114.223 +207.118.78.203 +58.107.75.60 +83.110.103.164 +111.79.152.192 +86.71.2.136 +192.99.13.67 +123.148.218.134 +117.13.101.11 +186.30.163.65 +119.127.12.177 +66.66.231.190 +58.186.203.47 +24.234.175.30 +14.155.168.42 +114.37.54.116 +95.155.25.189 +82.170.147.115 +99.104.125.241 +83.153.5.157 +115.132.99.16 +83.36.211.143 +95.89.180.43 +108.61.164.73 +37.79.248.154 +79.30.246.53 +217.251.241.63 +113.16.146.143 +171.38.45.30 +88.183.205.16 +217.218.254.98 +109.157.37.217 +95.61.55.238 +222.161.201.133 +93.133.184.57 +86.167.229.146 +112.246.209.241 +2.124.244.56 +78.102.182.77 +83.44.53.152 +116.24.195.161 +86.145.250.164 +71.252.139.168 +180.165.126.245 +111.121.48.217 +83.249.205.93 +189.171.66.223 +36.48.243.140 +99.192.50.99 +76.186.51.247 +183.212.219.32 +91.146.199.165 +94.34.49.1 +89.204.153.207 +46.151.136.153 +31.7.56.244 +86.163.165.252 +70.210.134.42 +206.130.141.78 +86.134.254.33 +108.166.185.202 +114.241.16.42 +114.79.0.51 +79.117.64.214 +24.168.105.121 +87.160.132.48 +180.116.246.135 +1.39.25.250 +79.172.193.111 +71.71.123.153 +82.73.36.30 +178.223.174.244 +82.31.183.213 +204.186.3.95 +70.196.205.208 +59.58.236.4 +211.149.148.149 +189.71.76.250 +91.244.20.133 +112.208.207.39 +36.251.68.135 +81.234.88.76 +219.153.51.47 +221.213.111.112 +50.136.254.123 +180.176.178.35 +84.154.237.41 +91.239.69.78 +78.106.170.136 +59.60.122.184 +182.202.126.30 +217.166.164.18 +108.124.175.163 +70.70.25.20 +208.64.91.46 +27.25.215.165 +79.117.42.203 +223.81.200.13 +79.167.29.71 +90.205.103.236 +59.46.54.45 +118.124.22.207 +108.237.161.194 +68.146.161.64 +151.224.127.90 +73.191.153.50 +175.180.141.10 +80.103.45.251 +63.142.161.2 +112.3.85.139 +49.144.120.230 +128.69.7.188 +71.95.144.191 +91.52.164.59 +100.66.27.180 +47.54.13.103 +62.155.161.110 +93.38.220.23 +91.23.186.177 +149.71.152.68 +80.222.122.93 +94.190.7.34 +213.179.246.103 +223.249.171.248 +97.79.31.178 +123.21.30.175 +177.132.7.142 +95.84.170.156 +183.132.254.19 +82.72.54.22 +213.87.131.93 +124.72.165.143 +67.198.154.221 +125.89.19.105 +87.167.12.108 +5.12.120.109 +58.39.201.91 +201.157.83.100 +185.18.60.131 +152.66.226.93 +82.176.162.201 +79.191.68.186 +91.157.179.211 +46.98.79.159 +88.232.141.237 +59.40.134.65 +192.183.123.182 +96.44.123.29 +88.196.181.165 +218.11.176.47 +39.67.23.177 +46.233.249.27 +223.65.191.82 +173.78.127.164 +68.4.98.141 +2.218.207.134 +77.85.249.223 +91.16.246.222 +5.135.199.13 +177.16.84.89 +94.10.30.236 +90.153.81.104 +94.2.198.155 +81.141.22.113 +95.238.239.50 +183.208.181.242 +94.10.248.229 +68.151.221.193 +116.52.85.26 +14.215.13.50 +72.222.210.29 +210.21.203.174 +75.70.201.171 +93.82.84.6 +84.220.219.244 +66.69.12.123 +92.28.73.181 +120.43.185.205 +42.81.42.131 +68.188.167.246 +87.18.176.56 +174.6.75.59 +125.89.16.201 +78.49.254.62 +192.222.158.186 +172.218.169.79 +87.21.165.26 +176.240.149.156 +2.245.85.215 +75.163.181.211 +198.14.244.224 +27.156.71.67 +121.27.149.190 +93.130.207.244 +123.165.128.183 +90.217.205.27 +124.205.188.82 +111.172.132.94 +46.142.44.83 +210.55.212.152 +24.222.139.164 +5.139.189.98 +49.180.160.94 +101.98.201.99 +46.164.12.1 +118.186.156.238 +162.219.179.18 +172.12.133.196 +114.78.52.53 +89.212.18.253 +68.51.78.69 +58.107.69.161 +198.144.156.137 +95.103.211.92 +46.53.179.247 +86.180.0.145 +184.144.71.85 +135.23.122.109 +99.47.239.134 +70.15.48.75 +213.160.178.33 +46.180.200.104 +68.104.77.96 +81.131.76.42 +173.36.196.12 +79.71.124.127 +83.7.171.124 +123.166.122.239 +72.191.43.5 +91.197.174.237 +85.55.42.225 +49.144.66.115 +91.125.198.29 +94.180.138.243 +107.200.47.98 +81.38.141.140 +83.45.176.129 +46.158.174.232 +176.199.1.251 +88.104.183.143 +94.5.87.12 +93.85.158.107 +94.180.168.74 +71.231.67.102 +85.178.90.196 +121.16.149.6 +50.83.164.70 +201.69.67.213 +113.190.167.73 +62.113.251.96 +101.176.137.219 +176.43.117.234 +90.191.167.251 +78.250.164.151 +99.72.60.172 +2.81.202.157 +89.114.215.107 +5.71.183.189 +198.48.215.25 +78.14.40.191 +88.104.67.159 +113.103.5.230 +50.23.65.43 +90.191.204.214 +91.63.26.80 +217.66.156.141 +75.190.251.243 +193.0.200.147 +37.123.191.51 +95.88.3.28 +201.3.213.26 +213.121.12.103 +128.68.62.207 +78.8.55.68 +71.83.107.19 +78.13.129.91 +84.62.24.142 +172.251.117.231 +92.240.58.80 +217.98.60.13 +31.63.43.179 +200.146.58.44 +188.226.203.40 +182.40.107.127 +193.171.202.150 +183.25.17.247 +72.130.56.185 +93.222.180.213 +100.64.65.114 +9.221.192.218 +216.155.145.203 +100.66.54.155 +95.90.174.48 +101.98.136.243 +91.207.98.95 +2.33.91.238 +108.65.91.65 +89.164.151.114 +119.114.100.243 +188.112.101.22 +182.52.229.67 +113.22.112.101 +14.202.83.116 +98.142.245.85 +67.167.147.229 +219.132.52.45 +46.165.251.66 +111.161.11.173 +69.35.203.245 +109.197.188.24 +46.39.243.165 +25.204.209.202 +183.206.194.118 +87.145.112.216 +91.9.173.17 +78.110.169.123 +41.254.8.198 +182.132.195.107 +24.8.50.103 +24.246.168.197 +104.236.23.215 +67.1.219.216 +211.132.33.160 +112.95.40.66 +1.204.240.65 +69.165.173.140 +101.128.201.25 +49.80.166.199 +188.136.202.153 +108.48.191.29 +64.34.49.151 +188.27.58.246 +78.52.13.1 +86.145.105.149 +75.138.186.242 +163.179.238.171 +193.92.141.144 +88.17.160.95 +70.35.204.167 +213.87.120.138 +31.7.62.72 +122.118.215.160 +172.56.12.111 +178.118.161.14 +78.151.195.47 +109.111.146.57 +178.57.114.155 +111.37.3.123 +89.164.112.119 +85.214.89.85 +93.81.109.34 +109.209.109.159 +112.254.97.49 +180.126.105.2 +92.154.80.58 +81.44.139.166 +91.64.233.89 +106.3.32.153 +27.55.229.28 +78.151.195.50 +31.16.9.118 +36.62.181.94 +99.104.130.124 +67.176.6.109 +86.162.149.146 +86.155.60.97 +93.142.212.167 +183.191.137.120 +194.150.65.241 +207.181.242.204 +109.124.192.73 +100.66.24.211 +178.216.8.31 +151.21.96.190 +218.11.176.4 +218.11.179.141 +65.95.150.203 +67.60.35.16 +27.0.87.66 +85.246.121.214 +67.189.113.4 +49.74.130.58 +213.149.172.44 +177.156.246.81 +176.10.249.238 +58.107.80.228 +179.176.163.177 +78.129.160.88 +178.202.139.192 +77.20.204.177 +37.117.4.138 +100.64.39.6 +165.228.82.175 +113.140.230.126 +151.20.32.80 +213.118.135.242 +84.29.30.144 +195.123.209.184 +2.92.162.27 +5.12.191.42 +94.12.194.64 +74.15.70.139 +91.177.94.157 +83.37.210.89 +89.110.29.79 +75.138.187.189 +70.194.133.29 +67.189.123.178 +79.31.171.115 +62.210.206.25 +183.208.183.71 +117.89.132.179 +199.185.6.2 +79.212.224.160 +188.122.231.125 +113.229.43.58 +118.209.184.147 +86.144.0.204 +83.25.185.241 +119.246.6.136 +171.112.207.75 +46.9.148.196 +70.194.74.205 +31.28.6.198 +87.160.189.114 +86.122.206.57 +118.114.122.253 +99.249.130.91 +107.178.17.57 +177.81.49.60 +49.144.54.134 +141.136.196.114 +93.142.190.110 +60.53.67.241 +194.150.65.116 +58.252.45.12 +125.165.35.100 +81.35.206.42 +79.185.208.68 +212.252.170.53 +204.147.203.170 +2.98.163.176 +174.5.172.178 +77.117.163.66 +173.30.160.253 +95.235.39.95 +113.110.229.35 +125.119.239.216 +72.87.171.247 +80.6.240.30 +82.150.180.10 +96.38.134.39 +46.239.44.99 +176.241.152.82 +87.144.70.66 +14.213.197.246 +85.118.69.241 +121.33.54.176 +74.194.194.230 +117.213.97.7 +184.145.83.22 +198.204.209.177 +86.7.33.139 +14.115.16.61 +188.214.128.12 +4.31.39.151 +68.235.80.128 +172.248.206.161 +86.162.97.196 +99.189.84.118 +210.23.88.249 +84.200.17.240 +50.158.247.254 +94.134.51.185 +66.31.0.29 +119.127.13.15 +92.19.101.32 +82.8.33.150 +92.17.228.59 +180.93.160.160 +2.99.234.2 +179.43.128.198 +172.56.19.97 +89.143.102.34 +70.210.128.20 +119.179.154.28 +86.146.123.80 +188.250.3.113 +176.46.93.116 +84.25.50.206 +42.116.36.235 +115.195.131.5 +206.222.164.230 +67.140.204.222 +157.161.128.61 +113.90.17.74 +89.241.236.206 +87.241.111.134 +112.203.145.51 +90.199.228.223 +192.99.15.175 +194.94.199.114 +46.185.28.33 +203.213.42.166 +203.96.43.14 +94.159.241.82 +122.236.54.84 +60.181.57.28 +217.42.36.3 +1.23.150.213 +218.88.93.102 +82.158.8.125 +82.26.208.67 +9.80.104.247 +79.71.127.127 +92.25.33.191 +210.55.212.252 +79.185.10.125 +188.216.15.80 +60.231.34.233 +212.159.76.133 +70.106.236.215 +76.11.26.222 +82.3.63.108 +203.96.9.91 +174.100.226.146 +83.44.237.109 +80.109.244.241 +190.30.131.239 +77.118.28.117 +188.4.22.114 +67.188.192.98 +70.52.109.215 +98.121.202.109 +162.239.34.236 +77.8.148.184 +80.109.199.243 +66.162.28.202 +112.112.228.97 +92.128.7.245 +182.45.49.147 +82.25.51.16 +179.126.60.229 +80.174.238.173 +121.232.204.211 +217.66.26.20 +69.245.231.212 +222.247.163.137 +77.4.108.136 +61.197.11.241 +91.53.29.15 +25.30.121.165 +85.114.168.209 +84.128.185.125 +187.241.16.30 +37.79.249.241 +86.155.2.56 +180.141.31.134 +85.152.202.36 +84.30.75.48 +94.13.180.224 +71.146.65.118 +113.88.66.51 +27.255.94.220 +14.216.39.98 +91.9.145.170 +50.38.69.228 +72.160.85.133 +87.66.195.59 +188.22.69.237 +95.91.224.197 +88.159.110.121 +60.234.30.66 +183.1.253.85 +203.96.43.152 +177.133.212.222 +31.52.126.169 +87.109.13.217 +71.29.98.49 +122.241.178.61 +213.73.172.184 +79.163.103.195 +93.133.187.196 +86.26.88.35 +78.15.168.133 +89.240.55.44 +2.30.91.201 +62.90.52.37 +180.110.0.3 +94.20.32.32 +87.112.213.99 +94.153.163.10 +114.233.157.107 +179.154.46.98 +91.179.98.173 +82.76.158.62 +111.14.252.198 +68.151.7.190 +180.234.34.205 +67.49.132.16 +70.180.178.95 +217.253.29.101 +110.33.252.79 +185.38.14.215 +84.232.219.248 +121.16.164.78 +173.24.168.230 +93.40.239.132 +178.93.53.225 +66.254.236.159 +100.92.4.153 +86.168.5.138 +173.192.170.90 +118.174.20.178 +117.25.89.38 +176.52.33.30 +199.193.117.44 +200.103.148.235 +119.126.116.115 +27.22.214.58 +89.98.3.152 +89.143.127.176 +23.21.224.150 +184.164.78.15 +93.203.244.180 +58.23.241.46 +59.46.54.22 +192.30.239.222 +69.142.192.13 +180.158.154.82 +78.183.63.127 +14.112.237.90 +78.14.9.10 +174.66.3.25 +100.64.24.101 +50.153.153.99 +81.132.76.135 +91.79.13.144 +125.227.116.136 +70.24.38.70 +5.14.223.201 +39.251.0.109 +90.245.37.100 +77.101.119.52 +85.2.127.21 +151.80.206.101 +213.114.138.88 +74.207.243.85 +130.193.97.48 +222.52.142.181 +82.75.156.239 +142.105.149.234 +81.83.10.208 +110.90.178.32 +14.213.203.174 +91.9.142.130 +112.80.164.20 +91.9.176.67 +50.141.6.130 +79.31.171.86 +46.250.168.37 +174.238.99.94 +65.129.4.171 +113.91.6.156 +96.42.233.155 +79.101.58.8 +82.146.66.195 +114.88.23.37 +85.244.209.182 +123.63.144.101 +188.194.73.249 +130.95.156.199 +115.152.153.125 +113.172.119.28 +93.38.226.176 +114.134.4.206 +93.133.174.83 +5.89.142.118 +82.68.134.29 +5.43.180.29 +86.120.80.156 +77.234.40.150 +198.84.14.121 +88.120.143.1 +137.175.168.34 +74.248.54.51 +66.188.52.110 +173.79.206.246 +212.18.232.76 +122.60.78.34 +117.135.239.15 +54.173.149.132 +73.200.84.235 +58.250.97.187 +69.231.35.27 +96.93.219.70 +99.52.173.181 +14.213.152.159 +58.107.68.67 +69.122.63.179 +180.215.243.101 +74.56.186.129 +222.43.205.2 +79.18.137.77 +86.147.68.215 +80.130.241.25 +201.195.253.82 +92.100.212.37 +171.93.28.222 +113.240.247.242 +89.28.59.235 +96.237.59.169 +113.162.180.192 +188.18.1.72 +176.40.144.83 +70.124.166.145 +46.246.51.142 +71.28.131.232 +58.250.119.80 +222.124.109.41 +95.222.31.210 +195.210.223.37 +87.169.118.28 +72.196.228.88 +113.90.17.9 +14.144.154.225 +14.106.65.106 +83.255.12.95 +220.157.144.222 +50.207.105.230 +50.43.11.235 +213.35.148.226 +1.178.229.102 +217.251.230.158 +212.215.231.194 +183.206.192.211 +105.236.86.10 +24.171.60.153 +111.226.16.22 +60.181.58.49 +81.141.6.224 +91.98.74.120 +182.50.248.204 +109.158.40.23 +46.19.139.154 +89.123.59.98 +67.175.59.49 +109.90.216.220 +120.144.210.33 +123.91.49.55 +112.4.104.131 +78.25.120.153 +88.251.49.247 +188.32.248.85 +100.86.22.204 +182.3.171.178 +24.184.168.36 +37.160.4.183 +50.140.169.166 +67.168.1.236 +149.172.144.245 +103.247.163.7 +73.9.181.217 +36.33.59.114 +78.54.128.89 +144.76.9.247 +109.100.130.20 +87.210.33.1 +78.8.168.87 +100.1.101.241 +82.1.249.5 +109.24.150.220 +24.38.208.18 +89.210.65.100 +109.126.195.81 +66.189.11.251 +82.117.239.148 +113.162.139.217 +195.250.175.254 +91.9.144.250 +207.216.35.89 +124.202.190.253 +99.236.215.227 +95.117.127.152 +86.40.139.23 +96.253.83.44 +184.75.214.18 +84.169.207.194 +124.169.120.253 +69.172.173.96 +88.12.142.229 +173.182.132.210 +108.226.181.66 +188.4.230.163 +213.7.69.107 +159.224.88.65 +81.67.87.80 +2.39.37.121 +88.156.133.81 +123.145.174.47 +14.205.147.110 +84.228.209.84 +203.90.204.253 +5.29.2.69 +83.233.246.143 +77.175.143.23 +31.55.115.177 +94.10.241.65 +184.144.79.133 +79.100.185.93 +67.140.183.229 +118.209.1.53 +180.164.253.234 +88.149.139.89 +195.46.241.231 +2.99.227.230 +42.118.190.89 +50.23.113.234 +81.141.16.214 +76.181.167.227 +60.241.45.184 +81.219.115.24 +79.49.185.187 +195.154.146.246 +117.25.243.159 +85.237.227.61 +218.205.21.194 +60.166.216.176 +2.123.2.114 +88.137.71.231 +31.173.80.46 +89.39.206.242 +83.228.52.175 +39.48.127.100 +79.174.49.202 +72.231.213.156 +186.85.0.62 +113.85.97.228 +210.195.225.95 +46.15.99.20 +24.70.160.234 +84.168.255.54 +82.233.236.173 +121.218.75.238 +115.218.68.154 +91.5.23.73 +175.18.69.187 +121.54.44.92 +40.132.222.254 +81.215.70.54 +216.155.131.76 +14.213.212.184 +93.137.121.147 +217.246.246.125 +190.103.66.31 +98.167.252.83 +217.247.79.107 +37.14.13.79 +217.251.251.105 +175.160.185.100 +79.56.184.254 +124.231.22.153 +213.21.32.28 +86.202.182.202 +2.26.39.143 +194.150.65.105 +91.61.231.172 +114.97.100.116 +174.71.32.244 +117.80.102.137 +175.145.199.206 +81.175.196.206 +1.80.127.200 +194.118.201.249 +41.254.8.217 +88.115.232.98 +8.25.195.26 +87.160.184.74 +124.168.136.190 +195.250.175.254 +85.26.144.211 +86.128.45.19 +174.34.169.98 +83.100.250.170 +185.38.14.215 +178.94.60.24 +109.223.241.200 +218.205.19.127 +112.208.0.192 +178.39.137.250 +2.126.69.156 +212.123.190.28 +113.15.194.26 +125.85.114.240 +88.177.221.218 +76.88.101.20 +85.97.253.102 +83.228.35.227 +184.75.223.50 +193.107.100.194 +88.69.42.207 +91.105.156.174 +94.153.163.10 +84.215.167.127 +80.136.165.250 +180.170.183.151 +107.170.198.224 +88.153.220.162 +87.122.189.223 +151.74.101.6 +72.214.128.106 +175.51.165.78 +182.96.207.245 +109.221.28.11 +58.53.45.44 +88.231.37.9 +58.248.200.222 +82.73.59.240 +75.169.213.97 +172.248.163.133 +75.164.169.251 +174.26.12.186 +78.55.238.114 +178.120.204.102 +84.92.211.45 +73.8.250.74 +98.167.118.75 +178.56.221.16 +178.122.15.179 +54.197.230.111 +80.134.134.70 +78.50.138.138 +91.53.98.154 +218.88.93.133 +77.247.181.162 +189.71.88.218 +173.58.34.13 +86.154.202.194 +79.107.39.63 +49.3.28.134 +89.204.135.234 +58.250.118.15 +50.51.173.229 +78.8.70.169 +58.6.49.242 +58.107.72.120 +213.138.72.110 +178.71.200.239 +89.126.43.87 +108.222.164.54 +109.242.3.99 +91.156.198.135 +188.67.8.163 +123.139.204.246 +86.3.89.69 +223.205.41.220 +110.87.47.178 +27.46.123.20 +185.145.128.32 +91.125.198.29 +104.34.113.175 +217.253.21.99 +212.83.75.106 +94.212.190.46 +91.6.148.3 +216.185.39.184 +148.88.244.151 +213.149.105.124 +113.23.87.47 +73.250.192.173 +123.148.218.134 +128.73.93.198 +2.220.26.203 +68.9.22.139 +91.72.209.174 +93.203.236.47 +81.101.198.108 +5.34.225.235 +81.17.95.243 +68.68.96.33 +63.155.205.51 +198.50.200.139 +110.82.91.133 +49.74.163.76 +92.233.184.248 +95.179.96.73 +216.155.131.70 +212.253.213.50 +185.2.29.219 +119.62.11.128 +85.114.185.77 +86.163.165.225 +31.50.163.117 +101.98.204.103 +107.27.245.218 +179.215.88.9 +177.204.24.64 +31.128.8.221 +78.85.73.195 +68.116.212.182 +121.222.245.21 +87.112.98.99 +95.78.193.51 +79.187.217.157 +97.81.141.193 +99.150.254.16 +220.168.98.97 +85.246.121.214 +113.73.202.245 +125.161.82.68 +86.148.196.141 +24.175.240.24 +130.255.72.66 +98.255.222.232 +59.60.122.184 +113.71.161.41 +89.137.163.200 +70.67.164.112 +37.24.152.46 +79.117.114.221 +175.44.223.153 +46.177.120.226 +114.94.124.197 +63.155.222.158 +113.97.218.177 +12.219.106.43 +119.130.158.226 +198.144.156.140 +120.236.148.203 +107.2.93.213 +121.222.152.215 +184.3.221.45 +83.94.251.205 +61.125.233.143 +78.1.139.79 +76.10.167.234 +92.239.239.140 +216.17.229.2 +180.165.84.71 +79.117.97.62 +203.202.52.99 +184.161.243.236 +37.19.142.94 +114.111.167.152 +94.224.203.117 +178.37.90.240 +60.184.181.183 +14.154.148.220 +119.234.162.145 +181.29.37.62 +96.23.205.149 +188.211.144.116 +101.38.186.74 +128.71.40.158 +189.46.56.6 +195.123.209.184 +111.206.132.9 +110.251.120.124 +124.228.22.26 +79.163.102.42 +172.6.64.69 +149.254.186.41 +116.29.104.24 +80.143.159.148 +120.144.207.137 +83.4.109.145 +95.55.179.147 +92.63.131.3 +116.253.220.46 +118.114.122.253 +79.103.209.56 +174.126.18.34 +88.11.84.86 +98.223.62.66 +175.101.15.17 +70.54.148.63 +84.190.87.91 +60.184.85.217 +79.81.210.196 +90.200.147.94 +79.130.126.97 +37.221.161.234 +120.239.15.67 +87.245.35.243 +188.134.72.213 +74.51.157.7 +101.45.49.126 +86.170.63.39 +106.69.145.9 +14.124.216.61 +24.126.244.15 +108.61.123.89 +90.201.191.172 +95.121.141.44 +185.23.213.22 +113.22.4.78 +128.70.37.127 +82.47.207.17 +2.99.235.67 +79.117.64.214 +81.170.128.224 +90.209.46.184 +77.68.245.199 +80.212.189.35 +105.225.199.77 +94.42.233.235 +218.11.179.35 +114.86.246.111 +118.211.146.85 +212.159.107.161 +91.53.29.15 +79.44.145.29 +68.33.238.183 +60.182.17.223 +117.94.180.151 +213.87.224.162 +14.215.13.50 +192.99.241.164 +207.118.106.101 +179.187.101.18 +5.77.187.188 +27.129.238.230 +116.87.125.11 +2.87.239.150 +89.24.109.138 +125.39.106.133 +120.210.179.117 +89.103.212.13 +217.251.241.63 +114.79.29.84 +216.172.138.186 +85.76.44.37 +24.138.212.32 +91.205.145.3 +95.43.5.162 +217.233.112.62 +75.117.69.191 +206.108.168.134 +178.116.177.143 +82.74.43.190 +183.63.204.169 +109.163.235.236 +71.56.65.98 +83.149.126.29 +93.201.244.30 +70.168.69.109 +23.29.114.158 +144.76.9.247 +94.134.61.238 +69.35.201.184 +178.84.117.254 +89.78.226.217 +2.28.214.184 +91.61.72.177 +182.241.14.141 +192.99.143.109 +116.19.99.50 +88.182.61.106 +24.107.164.247 +31.7.62.72 +91.9.157.221 +95.19.183.164 +78.149.15.111 +67.183.120.223 +104.131.199.37 +91.105.156.162 +113.162.179.9 +125.78.9.227 +117.89.80.129 +37.201.224.249 +109.91.161.71 +90.113.82.59 +76.24.0.137 +222.78.67.200 +86.153.150.140 +187.192.254.21 +95.55.131.245 +113.226.125.55 +88.153.89.84 +92.231.99.60 +75.109.216.123 +201.102.196.44 +90.244.13.205 +79.80.7.188 +79.44.108.175 +86.179.19.132 +183.30.10.161 +80.39.62.7 +27.151.81.66 +86.161.70.240 +78.90.12.180 +12.1.191.163 +92.229.102.128 +90.191.167.251 +108.62.233.240 +83.149.9.106 +82.158.244.82 +94.96.50.47 +88.80.49.53 +176.31.128.78 +151.54.116.30 +79.216.17.74 +79.185.108.138 +37.104.13.93 +113.90.17.9 +94.21.73.78 +24.10.230.154 +93.32.204.69 +120.239.15.118 +14.106.0.208 +218.11.176.4 +92.229.71.141 +100.85.135.221 +187.120.42.140 +114.252.68.115 +76.200.118.12 +101.39.207.2 +84.94.36.109 +206.222.164.230 +188.104.242.14 +93.210.191.31 +121.16.144.167 +70.88.133.181 +2.237.37.30 +79.116.248.136 +27.99.15.55 +188.105.95.225 +175.44.207.9 +188.191.239.111 +84.174.31.13 +109.158.40.23 +176.213.98.81 +115.205.247.119 +117.53.82.41 +2.223.56.142 +179.176.54.113 +151.34.68.254 +177.42.24.80 +76.66.107.171 +2.61.192.233 +90.33.59.224 +94.128.231.166 +162.247.91.140 +187.112.57.243 +117.72.102.55 +46.255.67.16 +221.207.168.14 +143.48.117.18 +151.74.29.33 +54.86.136.147 +178.128.17.205 +181.38.248.118 +77.4.126.32 +118.239.118.255 +90.45.13.151 +64.134.183.253 +1.80.67.66 +79.172.113.44 +93.76.202.200 +108.85.48.181 +89.217.242.69 +5.141.229.76 +87.236.194.23 +67.1.108.46 +178.149.129.41 +67.110.213.126 +182.92.184.107 +94.68.147.53 +65.51.218.52 +91.178.46.84 +78.8.113.54 +138.130.228.235 +183.15.199.102 +190.63.1.134 +83.41.23.13 +86.155.2.56 +58.11.156.75 +116.102.7.187 +117.79.232.158 +88.156.133.170 +114.92.76.179 +58.219.25.103 +75.106.84.121 +71.196.185.190 +194.204.62.9 +173.52.58.82 +88.27.44.141 +2.93.163.24 +92.231.92.15 +46.246.42.135 +78.128.165.251 +86.120.82.53 +179.191.241.99 +71.138.135.165 +120.39.140.86 +67.60.33.79 +84.220.219.244 +79.224.21.225 +92.20.137.149 +94.3.137.242 +222.132.28.138 +46.159.143.249 +78.8.179.27 +85.25.44.119 +93.50.191.10 +84.131.69.172 +101.65.151.157 +123.97.122.170 +71.180.133.25 +94.71.121.72 +83.114.9.55 +218.145.173.108 +88.196.181.165 +93.138.23.240 +87.114.83.164 +41.110.142.95 +88.15.242.11 +182.45.53.179 +83.35.163.57 +87.79.163.86 +220.240.153.119 +178.167.116.27 +93.114.45.194 +75.145.79.246 +75.168.83.38 +93.128.30.92 +68.115.89.182 +50.157.241.225 +128.72.225.21 +86.162.150.83 +36.48.240.182 +82.99.236.88 +82.7.27.245 +183.37.27.192 +109.190.66.23 +176.254.255.245 +24.54.130.146 +72.92.140.102 +89.20.244.134 +37.201.214.103 +8.28.209.90 +123.243.44.137 +2.223.163.39 +68.146.161.64 +213.35.148.226 +46.4.94.85 +178.84.12.177 +216.221.32.175 +54.173.149.132 +222.211.222.152 +82.176.214.68 +181.38.82.85 +187.40.222.181 +78.22.244.54 +95.82.174.47 +112.254.5.242 +68.58.2.117 +86.164.198.150 +213.46.28.142 +52.4.231.179 +79.167.52.88 +183.217.168.112 +77.4.247.237 +24.22.58.100 +81.153.89.132 +46.200.79.142 +59.178.141.146 +190.48.188.158 +178.200.76.190 +49.145.102.77 +2.95.147.113 +49.144.120.230 +176.62.234.1 +70.69.38.133 +179.176.68.216 +87.160.147.197 +60.213.223.20 +105.99.189.59 +96.40.105.162 +69.179.143.70 +27.158.173.132 +89.244.88.159 +79.27.40.11 +94.34.103.202 +37.214.196.15 +27.55.153.179 +91.219.167.202 +92.81.165.135 +83.10.34.47 +151.80.9.33 +99.239.174.161 +117.253.166.117 +72.200.42.78 +87.112.213.220 +116.1.113.108 +91.9.176.183 +178.120.135.244 +180.166.109.197 +180.6.243.6 +217.66.157.3 +67.5.102.237 +78.70.66.4 +98.206.36.184 +216.166.76.6 +178.84.58.137 +109.127.134.213 +113.75.245.2 +218.0.3.26 +117.89.42.131 +113.3.253.122 +99.192.92.77 +78.145.243.11 +108.175.82.153 +119.128.174.68 +24.62.181.64 +176.199.3.75 +75.167.204.189 +118.119.21.40 +9.221.192.185 +2.61.224.134 +109.217.183.149 +87.69.15.191 +76.92.139.249 +49.221.152.140 +88.193.97.249 +97.94.201.155 +109.190.156.157 +90.219.161.217 +210.55.212.162 +79.228.43.210 +197.28.213.113 +78.129.189.131 +99.250.168.84 +196.46.136.203 +88.156.227.195 +183.159.125.210 +125.73.116.28 +85.255.233.221 +141.136.244.188 +86.144.91.230 +58.250.118.131 +58.107.80.216 +59.93.176.88 +72.160.76.206 +78.8.191.49 +24.93.183.133 +110.205.77.203 +83.7.56.239 +71.28.180.65 +184.58.176.59 +82.28.133.232 +91.9.148.125 +79.16.119.182 +103.247.132.16 +86.163.167.52 +74.32.172.127 +96.41.233.38 +90.209.209.111 +88.137.74.163 +191.179.106.80 +112.4.104.49 +115.91.171.92 +70.53.126.8 +75.74.218.70 +1.195.211.12 +141.134.155.20 +88.149.139.89 +85.177.89.51 +84.54.172.244 +192.171.35.206 +131.232.28.23 +60.184.170.246 +36.251.219.86 +78.145.241.75 +183.26.119.194 +113.57.187.243 +113.16.196.116 +39.67.175.147 +27.151.166.1 +12.250.146.126 +5.167.68.11 +121.16.199.225 +178.128.173.172 +192.99.8.126 +122.136.252.80 +46.12.5.94 +108.94.169.145 +176.97.2.139 +173.208.140.210 +14.161.69.5 +128.72.93.198 +206.255.162.145 +24.63.226.202 +98.229.142.71 +24.115.95.58 +201.229.74.196 +76.79.4.163 +93.92.57.196 +119.137.213.183 +64.26.67.254 +24.200.62.50 +105.236.6.16 +85.166.40.57 +86.30.213.189 +110.81.142.47 +91.9.150.72 +106.186.18.89 +188.33.235.77 +84.52.176.78 +83.38.235.126 +189.248.26.254 +63.131.179.237 +121.34.179.63 +125.82.1.208 +209.90.184.127 +80.203.113.176 +77.85.253.131 +92.77.202.54 +207.62.170.216 +125.165.19.195 +82.155.17.54 +93.104.169.149 +61.143.197.101 +79.191.68.186 +72.186.22.189 +194.166.130.16 +84.177.127.174 +91.126.196.143 +171.216.135.159 +113.120.136.176 +118.92.98.248 +220.162.129.203 +109.150.91.111 +109.14.225.225 +71.76.238.83 +113.248.212.142 +89.242.77.121 +58.107.69.113 +178.78.158.7 +89.35.203.173 +188.77.161.110 +87.2.25.135 +78.148.113.230 +60.36.212.94 +86.134.125.32 +78.15.162.205 +86.27.183.239 +118.249.57.37 +185.42.145.149 +176.40.239.240 +77.73.142.26 +187.14.131.146 +116.228.132.10 +2.30.147.174 +117.63.221.98 +83.4.88.134 +184.7.38.184 +83.149.9.52 +117.79.232.196 +82.139.115.95 +176.194.189.124 +95.178.153.117 +2.80.219.45 +27.46.17.221 +68.187.70.201 +77.247.224.22 +72.185.202.205 +89.173.27.117 +78.250.39.15 +24.172.207.238 +86.145.224.57 +91.9.183.244 +80.213.110.10 +179.176.53.132 +46.40.48.159 +37.61.44.108 +46.73.166.121 +197.34.23.209 +50.159.161.211 +180.152.215.18 +173.245.77.130 +173.144.0.87 +176.214.240.19 +199.193.119.20 +79.71.117.32 +213.87.122.213 +188.27.58.246 +23.92.27.65 +68.3.234.135 +63.142.161.25 +49.184.2.89 +223.72.72.170 +70.196.66.206 +58.55.145.140 +18.111.117.72 +116.17.58.26 +69.245.231.212 +109.81.210.206 +116.76.56.73 +75.128.104.5 +125.39.117.32 +50.23.113.215 +96.252.50.154 +82.161.239.249 +93.87.187.136 +14.153.253.245 +183.27.93.211 +14.213.213.201 +86.40.18.9 +5.67.205.28 +99.248.212.33 +50.180.178.143 +58.186.251.205 +183.206.192.129 +61.185.136.56 +95.83.11.226 +120.204.157.231 +5.65.91.242 +1.121.163.4 +111.69.86.44 +2.99.230.172 +101.65.7.217 +109.204.166.132 +111.255.217.1 +24.180.216.216 +31.3.255.197 +183.27.229.130 +173.120.65.119 +78.154.171.198 +194.204.62.89 +49.195.34.87 +81.156.145.142 +178.27.100.111 +117.136.2.152 +79.112.35.137 +93.123.163.96 +27.129.227.26 +212.183.128.188 +118.92.142.221 +2.178.160.210 +86.129.147.40 +176.195.4.141 +98.108.241.22 +178.118.162.170 +187.57.88.224 +5.70.81.3 +58.62.167.86 +92.231.41.113 +87.119.70.223 +112.91.213.37 +180.252.79.183 +103.10.66.69 +94.241.28.7 +178.37.131.106 +14.213.214.159 +111.14.9.78 +118.250.106.91 +100.64.130.193 +86.29.52.253 +113.13.113.152 +87.112.240.94 +203.219.58.142 +60.168.8.150 +171.6.179.231 +50.15.90.80 +77.0.42.27 +81.141.19.150 +89.217.239.127 +123.16.249.35 +79.162.221.141 +130.204.131.136 +75.130.177.162 +178.3.124.113 +79.88.212.63 +69.231.33.24 +67.172.235.111 +88.106.194.52 +113.172.120.125 +37.78.105.46 +98.199.191.238 +72.220.127.239 +12.21.241.132 +175.156.205.176 +85.176.76.180 +121.236.137.108 +216.14.237.95 +124.202.191.100 +54.197.19.150 +103.253.43.162 +62.155.180.194 +140.206.201.194 +58.107.80.228 +71.95.208.59 +46.118.252.56 +46.45.29.207 +82.137.61.112 +212.101.61.91 +172.56.40.153 +37.187.28.68 +50.40.127.9 +144.76.90.209 +100.64.200.252 +198.18.1.76 +119.0.81.140 +47.54.8.126 +94.34.181.63 +212.150.82.225 +70.94.197.54 +92.249.111.228 +174.108.4.24 +37.201.169.14 +54.186.69.238 +109.252.68.152 +62.24.77.249 +117.201.103.194 +75.151.80.165 +88.146.217.6 +88.111.120.221 +86.30.59.220 +218.15.201.46 +213.74.110.176 +50.141.114.244 +25.7.32.89 +2.132.183.6 +176.103.211.236 +130.185.206.73 +2.124.28.131 +98.242.45.221 +85.26.241.36 +72.200.40.31 +86.134.215.86 +76.31.159.249 +175.8.248.144 +171.212.217.233 +100.64.6.254 +220.253.66.150 +80.87.147.223 +121.27.144.16 +176.253.164.4 +68.104.87.79 +151.49.172.109 +178.62.218.238 +85.214.58.163 +181.1.42.83 +75.109.216.50 +175.142.93.79 +80.221.96.47 +209.179.53.19 +37.187.9.53 +135.23.214.46 +46.114.45.86 +67.1.193.82 +108.175.185.20 +85.76.171.195 +222.134.236.180 +75.118.159.108 +85.85.182.3 +174.52.81.217 +209.159.137.59 +95.49.13.202 +178.93.152.52 +188.27.25.134 +98.242.141.206 +37.182.122.207 +116.12.58.16 +107.4.96.165 +50.46.156.178 +87.20.40.104 +69.35.163.248 +122.96.229.12 +114.107.189.161 +14.216.235.22 +217.189.250.246 +90.210.110.77 +68.148.109.27 +78.8.195.232 +70.36.139.139 +184.9.207.140 +188.96.50.254 +46.208.34.175 +193.40.60.26 +60.180.16.129 +83.69.62.213 +84.59.224.57 +108.224.41.162 +91.99.185.244 +183.8.78.182 +50.166.61.72 +114.253.16.26 +113.89.6.182 +58.166.93.139 +134.76.38.35 +188.136.203.39 +85.156.5.68 +84.156.108.8 +93.103.178.88 +172.56.41.103 +79.51.111.212 +91.9.130.215 +223.84.99.206 +180.178.134.218 +83.128.107.136 +163.177.139.96 +174.28.96.204 +188.104.248.163 +54.248.198.196 +78.250.182.121 +125.230.74.152 +114.254.131.250 +180.241.17.81 +92.224.155.53 +63.229.26.163 +218.102.198.212 +185.62.83.138 +90.214.35.203 +193.44.1.6 +173.221.65.201 +HWM allocated 259521839 247.5MB +128.69.36.34 +86.134.253.131 +80.217.45.142 +121.200.142.191 +212.9.28.178 +14.107.156.133 +88.191.132.110 +223.88.10.183 +94.195.151.201 +2.80.254.38 +27.46.17.138 +109.91.22.12 +79.71.118.189 +184.47.195.227 +77.41.114.83 +79.117.108.5 +151.74.17.17 +61.140.199.187 +75.111.24.182 +83.255.12.95 +109.123.34.119 +123.148.205.130 +175.157.77.6 +121.27.129.53 +109.110.66.147 +139.196.186.74 +86.144.93.6 +71.58.198.73 +199.73.106.27 +210.55.212.157 +14.114.163.129 +83.10.121.157 +222.101.255.21 +75.172.217.14 +77.121.201.4 +183.208.182.182 +119.127.13.65 +84.103.190.57 +77.111.158.246 +80.35.201.149 +122.247.39.202 +112.215.66.75 +92.163.62.226 +113.89.96.176 +85.241.174.194 +67.79.5.178 +88.149.138.47 +180.241.151.210 +72.201.34.132 +37.6.247.124 +190.157.117.146 +58.107.68.170 +218.88.93.142 +124.231.41.217 +99.225.46.58 +84.151.80.235 +98.165.161.219 +180.170.200.145 +4.31.39.151 +58.250.99.39 +98.124.55.54 +125.88.77.70 +74.101.23.74 +209.195.98.198 +72.160.187.107 +5.12.74.109 +151.15.31.72 +99.111.238.213 +89.100.44.142 +37.201.224.4 +178.113.116.68 +119.185.55.136 +68.38.60.39 +179.215.66.175 +91.19.211.27 +79.150.211.42 +31.147.126.18 +203.7.43.162 +188.102.41.215 +123.190.164.200 +176.201.11.13 +58.107.67.49 +78.55.224.22 +173.66.234.202 +120.70.7.154 +46.148.168.74 +218.88.108.9 +193.77.154.191 +85.185.9.8 +67.232.59.25 +78.151.195.47 +92.45.123.22 +177.0.33.20 +77.0.61.128 +188.255.10.48 +120.204.128.213 +46.7.133.116 +190.44.37.242 +46.166.161.136 +194.165.115.22 +154.5.99.77 +31.205.0.64 +178.193.225.224 +37.30.85.121 +180.252.90.41 +68.98.124.214 +87.177.72.162 +79.211.192.239 +80.69.174.173 +68.185.223.145 +95.91.231.193 +222.85.118.218 +84.84.160.62 +88.71.10.110 +85.226.175.95 +118.112.59.46 +80.109.199.243 +110.181.117.197 +79.102.37.15 +73.179.103.2 +119.129.110.118 +86.153.150.130 +71.194.63.67 +220.185.100.176 +111.249.103.37 +87.210.197.85 +174.16.151.244 +211.155.81.20 +89.167.9.6 +62.74.25.215 +79.139.195.56 +125.105.238.102 +183.212.110.92 +220.162.119.105 +84.128.179.167 +95.211.212.196 +90.32.226.44 +74.207.189.1 +42.93.228.44 +76.26.93.255 +93.39.100.5 +89.69.1.136 +5.156.209.118 +37.14.15.235 +24.151.133.228 +86.162.43.89 +68.197.0.105 +173.218.131.56 +194.150.65.116 +210.21.203.174 +74.69.26.251 +41.142.229.35 +72.160.71.118 +72.238.84.70 +67.1.133.189 +178.120.98.54 +212.101.46.226 +188.31.208.106 +109.171.34.201 +111.72.179.203 +2.54.228.102 +94.9.53.96 +27.193.103.215 +116.202.143.93 +85.172.55.72 +188.120.227.5 +185.86.78.36 +86.168.61.15 +85.237.224.50 +118.93.35.51 +223.199.203.155 +79.112.12.42 +175.3.194.56 +79.156.214.145 +23.233.34.59 +218.75.93.126 +122.90.244.74 +118.36.232.186 +59.178.48.226 +5.68.55.177 +205.164.12.124 +119.127.13.185 +190.62.201.95 +87.6.227.51 +45.62.229.165 +84.18.126.222 +92.224.196.2 +77.85.249.165 +79.45.78.99 +23.29.218.115 +46.142.81.255 +83.30.116.110 +176.12.58.203 +89.166.168.84 +183.63.51.227 +94.217.200.159 +71.166.47.98 +197.34.55.181 +183.76.152.108 +90.199.40.173 +124.73.87.123 +123.75.49.33 +142.68.184.29 +50.158.61.117 +66.189.89.153 +14.104.23.169 +58.187.90.210 +180.248.108.20 +59.46.54.23 +5.254.139.115 +200.73.161.121 +85.244.96.40 +221.219.153.248 +99.42.120.150 +41.237.1.246 +62.83.141.29 +128.54.104.41 +58.107.68.60 +188.129.118.239 +78.11.201.122 +171.96.240.38 +54.201.30.196 +222.185.102.162 +79.194.193.249 +54.200.134.160 +88.9.115.244 +85.226.222.11 +75.97.7.208 +70.65.153.178 +92.145.4.160 +107.148.10.102 +68.68.99.218 +79.71.124.96 +46.40.58.9 +223.73.1.169 +68.231.73.208 +121.102.103.231 +93.102.165.1 +123.211.138.59 +31.19.225.54 +1.192.67.220 +91.153.3.250 +171.25.193.77 +95.174.98.153 +65.60.83.66 +116.240.149.208 +62.47.2.184 +113.189.242.12 +89.32.255.246 +151.21.106.14 +90.201.102.231 +104.156.240.143 +118.70.190.61 +24.66.209.167 +94.197.120.128 +183.25.19.237 +124.181.237.237 +60.166.208.249 +14.219.70.253 +206.47.100.41 +68.40.62.34 +70.199.2.198 +86.185.185.202 +173.68.54.172 +113.242.162.237 +85.220.30.219 +87.98.175.192 +75.71.117.12 +97.79.31.178 +79.54.146.3 +111.161.10.228 +95.65.73.62 +78.157.217.228 +84.151.113.164 +174.125.96.165 +74.79.221.79 +86.146.107.50 +94.34.68.182 +192.100.3.123 +58.107.70.184 +77.4.219.141 +81.141.17.160 +188.153.11.203 +84.60.154.235 +90.46.156.217 +120.6.105.212 +90.60.164.15 +75.128.195.15 +78.0.30.22 +175.142.93.247 +41.132.71.207 +87.98.190.199 +149.254.186.85 +58.250.119.37 +90.198.167.102 +187.120.46.251 +93.115.95.207 +78.106.167.245 +90.206.73.81 +178.33.82.30 +72.228.161.247 +87.9.254.123 +121.237.71.54 +176.250.36.10 +69.251.51.223 +217.251.254.47 +50.136.158.93 +188.29.112.5 +42.62.62.78 +188.104.161.41 +24.154.115.152 +188.75.130.59 +109.245.174.3 +84.187.104.102 +93.210.161.70 +2.85.32.130 +66.162.28.202 +123.161.226.87 +93.223.22.251 +14.202.83.116 +80.179.197.173 +62.113.232.104 +198.22.122.13 +24.89.24.79 +97.121.40.124 +70.196.200.179 +94.1.206.184 +107.27.136.190 +178.162.211.222 +186.106.161.151 +188.194.130.70 +84.240.40.51 +201.252.31.136 +90.96.8.66 +171.214.199.165 +93.44.92.93 +78.34.230.238 +84.47.21.49 +74.248.57.118 +73.110.46.12 +58.55.141.251 +113.91.130.246 +96.235.180.4 +217.251.239.52 +79.134.0.1 +189.26.70.101 +113.88.51.24 +72.222.222.107 +93.223.43.215 +72.161.61.250 +220.168.103.240 +124.148.143.68 +189.191.158.77 +123.231.113.158 +119.136.74.195 +112.5.160.5 +94.253.168.166 +37.14.43.87 +113.73.177.224 +79.112.46.38 +76.94.208.122 +41.132.74.2 +176.46.99.203 +83.110.200.64 +50.167.240.144 +213.194.210.33 +79.53.235.195 +84.229.5.189 +78.60.22.106 +116.29.240.252 +100.72.47.231 +67.2.138.173 +81.219.28.219 +182.41.224.172 +217.122.139.62 +87.10.103.6 +95.30.243.96 +123.3.26.23 +24.2.233.4 +174.93.134.244 +143.48.117.172 +86.7.60.184 +173.191.22.25 +68.39.108.98 +175.172.164.67 +2.2.131.57 +180.251.196.42 +94.222.247.33 +212.255.124.94 +115.210.244.146 +70.194.107.122 +222.247.93.161 +86.218.149.99 +1.85.213.251 +94.20.32.32 +188.22.226.38 +76.66.101.239 +218.56.44.151 +77.4.230.69 +81.57.67.165 +89.168.153.198 +86.10.115.155 +71.170.165.237 +109.193.221.166 +98.126.64.162 +70.189.194.130 +62.148.134.190 +178.8.125.50 +2.99.224.110 +50.138.180.106 +178.190.29.150 +194.118.158.45 +74.86.24.194 +24.246.163.164 +122.106.116.245 +49.87.233.234 +96.52.62.89 +24.7.145.127 +93.210.189.174 +183.13.120.215 +92.76.27.47 +188.78.127.213 +93.86.242.124 +62.131.68.109 +217.123.245.198 +99.195.252.231 +98.246.140.12 +85.166.36.156 +174.45.137.0 +122.241.162.154 +49.67.236.65 +196.210.236.153 +95.97.59.146 +212.50.27.21 +76.176.142.253 +83.134.19.28 +37.78.166.242 +108.17.66.159 +64.37.14.189 +49.180.161.10 +84.39.31.28 +121.27.133.78 +58.60.32.153 +86.122.206.57 +109.149.191.54 +189.60.9.28 +76.168.222.247 +96.44.123.41 +24.107.162.87 +79.130.20.142 +121.35.150.142 +1.32.117.92 +212.106.239.181 +68.188.219.194 +99.28.87.67 +85.76.64.17 +221.204.215.1 +118.209.232.218 +118.239.133.229 +89.43.143.111 +119.230.149.46 +86.200.144.66 +86.10.241.136 +89.164.234.156 +207.161.3.73 +71.185.41.141 +72.87.171.130 +23.243.223.21 +59.178.46.49 +70.211.20.12 +61.144.213.187 +114.79.48.225 +104.236.56.19 +1.85.103.178 +23.113.161.22 +68.198.157.13 +50.89.92.31 +120.203.88.78 +58.187.8.78 +128.70.233.66 +107.3.141.41 +162.243.78.5 +222.211.166.118 +109.81.189.149 +85.175.218.53 +119.127.13.15 +182.202.91.42 +46.158.58.7 +89.176.56.128 +118.186.151.59 +64.223.172.137 +218.18.248.131 +173.24.6.175 +80.71.133.195 +88.242.15.241 +24.216.116.160 +94.196.245.62 +112.4.104.172 +109.165.248.201 +178.78.155.9 +79.214.233.21 +128.75.139.194 +114.79.29.57 +113.205.23.157 +79.10.109.27 +76.4.251.44 +86.198.118.176 +46.65.52.236 +178.122.197.220 +14.216.34.8 +93.139.185.181 +223.18.204.212 +175.172.225.66 +84.157.163.26 +188.29.164.157 +100.73.196.60 +122.241.188.109 +92.12.83.253 +90.199.26.9 +81.157.28.160 +116.102.39.62 +118.112.58.119 +189.63.152.158 +216.113.31.212 +79.101.58.8 +195.0.0.22 +65.60.163.86 +92.81.237.130 +46.166.168.130 +93.138.33.238 +74.103.4.186 +202.172.123.75 +213.28.236.223 +69.207.169.125 +188.98.88.143 +79.11.21.116 +110.114.143.35 +80.143.75.227 +70.51.163.153 +205.206.235.191 +222.244.58.96 +176.25.158.63 +83.152.102.77 +216.66.76.59 +125.89.20.132 +118.194.208.30 +178.222.136.51 +84.93.9.82 +110.82.111.133 +79.103.130.46 +90.211.82.86 +5.61.36.16 +91.105.156.90 +210.50.234.28 +198.84.192.38 +70.160.158.40 +86.22.147.139 +128.69.134.183 +92.16.157.188 +92.100.205.154 +153.0.152.104 +119.127.14.182 +109.194.110.119 +86.164.195.8 +90.209.69.123 +192.99.62.23 +76.254.2.140 +14.37.159.123 +149.254.218.156 +86.20.3.141 +81.210.186.195 +58.107.68.67 +183.12.167.242 +42.157.11.169 +88.241.81.232 +76.101.247.87 +89.78.237.218 +203.206.89.35 +173.34.178.69 +122.90.231.42 +86.126.23.170 +62.102.148.67 +188.108.233.45 +72.199.100.23 +74.209.11.226 +37.114.90.11 +80.189.22.170 +118.7.187.164 +66.175.219.215 +108.16.167.49 +58.54.7.140 +101.172.213.60 +108.6.135.43 +92.225.194.244 +115.174.66.177 +188.194.15.61 +82.66.159.85 +114.221.78.170 +90.184.86.85 +223.246.115.125 +94.12.193.95 +123.20.244.96 +187.113.239.54 +94.34.118.32 +175.174.90.228 +149.254.186.125 +91.62.64.116 +79.37.104.149 +210.55.212.239 +113.132.40.228 +121.237.71.144 +188.120.2.34 +188.136.202.153 +192.159.66.51 +222.210.230.198 +82.27.208.156 +61.164.68.98 +61.241.219.10 +58.101.164.66 +183.195.224.79 +151.228.125.102 +89.229.85.86 +2.40.108.171 +86.176.63.83 +37.112.231.4 +222.247.112.166 +9.221.192.65 +79.210.111.103 +171.208.156.124 +88.232.144.235 +178.135.23.188 +1.198.92.242 +184.173.77.26 +213.81.93.229 +5.34.17.28 +91.9.154.198 +206.217.192.191 +74.141.249.186 +79.114.244.119 +59.79.29.110 +220.175.88.123 +93.134.135.0 +72.225.238.69 +83.68.37.35 +54.200.174.238 +93.203.240.52 +58.61.226.163 +94.10.22.147 +93.196.255.230 +121.34.201.244 +92.229.64.124 +175.145.123.38 +14.154.151.67 +138.75.249.199 +90.26.119.65 +5.1.20.122 +81.155.44.48 +212.201.69.154 +220.237.16.161 +50.65.145.2 +183.9.91.13 +178.18.107.67 +9.221.192.78 +95.49.80.52 +95.222.31.164 +46.15.116.65 +92.106.136.174 +216.16.136.82 +200.73.157.58 +81.141.6.218 +14.162.154.65 +90.217.37.235 +86.145.249.130 +110.185.167.42 +78.151.167.196 +114.245.218.41 +180.152.24.213 +119.162.145.183 +92.14.59.111 +74.99.136.162 +222.84.77.139 +184.20.180.130 +178.122.183.170 +86.146.122.192 +91.179.98.173 +87.122.173.99 +105.208.131.29 +113.57.188.46 +59.126.155.196 +123.114.197.145 +68.145.88.236 +31.61.129.76 +86.182.49.201 +46.126.156.16 +119.120.146.10 +68.148.56.125 +85.82.128.34 +37.214.241.40 +110.45.165.182 +118.209.99.28 +98.109.108.105 +64.237.37.119 +27.227.4.15 +94.190.228.64 +78.209.217.2 +78.149.5.17 +83.150.85.202 +89.144.206.100 +95.211.224.44 +175.42.209.13 +114.112.155.149 +5.15.197.36 +176.126.252.12 +87.93.16.124 +113.240.60.40 +128.72.198.151 +14.218.68.125 +185.25.248.195 +52.2.116.141 +69.196.129.59 +116.1.222.111 +5.54.32.180 +178.135.109.44 +76.202.217.237 +187.254.211.86 +193.0.200.147 +95.104.205.89 +95.133.133.142 +125.85.48.5 +109.60.122.11 +122.96.42.87 +195.160.164.26 +175.42.228.186 +69.92.62.162 +111.170.68.219 +46.211.92.208 +82.25.51.16 +72.224.191.66 +46.59.104.205 +206.248.170.110 +94.23.29.195 +188.29.165.142 +119.140.222.201 +180.107.96.19 +85.240.77.213 +46.53.193.106 +177.106.125.14 +220.244.58.200 +81.147.139.189 +86.65.173.35 +117.253.180.17 +176.40.227.185 +121.35.151.211 +78.134.104.245 +68.144.161.76 +88.156.226.169 +109.129.54.201 +176.215.235.111 +37.201.227.54 +113.162.139.217 +82.81.240.56 +62.30.210.130 +46.134.236.154 +188.69.213.223 +81.242.104.132 +46.129.119.238 +91.211.57.104 +80.100.95.165 +101.98.148.57 +70.194.70.48 +108.201.95.4 +87.188.249.237 +37.214.125.111 +89.143.66.156 +46.33.227.191 +41.97.102.36 +201.86.214.254 +58.93.13.196 +85.117.98.91 +183.206.194.242 +24.10.92.109 +198.14.247.47 +73.4.211.205 +178.124.110.54 +123.174.68.164 +121.27.128.32 +143.48.117.164 +78.85.73.124 +84.6.141.80 +188.234.48.50 +203.96.42.40 +87.144.55.89 +91.9.134.89 +201.47.55.32 +183.208.96.104 +183.230.10.2 +81.172.19.195 +188.75.82.50 +52.20.232.95 +81.7.17.171 +163.179.238.171 +218.11.208.230 +114.37.58.70 +62.41.96.185 +217.42.35.131 +109.56.121.84 +116.17.29.184 +113.243.206.193 +42.2.0.138 +177.96.251.170 +87.221.31.84 +42.118.190.89 +85.101.19.242 +209.141.146.112 +60.180.19.189 +124.202.191.134 +223.246.253.248 +137.186.202.167 +109.236.90.209 +213.153.158.121 +84.161.92.96 +123.114.134.58 +115.60.3.75 +192.172.0.162 +78.156.115.197 +14.116.14.193 +84.138.64.148 +217.210.138.51 +89.43.169.57 +112.74.22.237 +120.43.185.205 +91.32.12.5 +71.35.211.186 +96.58.177.239 +182.45.126.93 +123.190.153.45 +93.66.92.37 +94.253.174.248 +79.194.213.210 +14.213.201.206 +24.27.3.10 +49.236.214.151 +88.74.97.119 +58.46.134.66 +95.232.152.162 +174.88.0.24 +184.175.28.217 +172.56.12.211 +124.148.92.184 +94.216.220.146 +188.208.206.101 +67.253.255.191 +75.109.216.16 +63.209.154.202 +58.37.45.121 +82.222.72.148 +108.8.122.212 +182.132.196.69 +5.226.28.243 +173.174.83.45 +72.143.228.82 +104.238.171.32 +121.237.163.200 +87.172.195.145 +68.3.106.240 +104.49.86.138 +9.221.192.161 +76.103.10.48 +171.36.19.76 +173.19.123.221 +85.186.255.134 +69.249.183.87 +84.147.125.109 +5.15.91.79 +109.187.29.109 +123.148.145.219 +75.121.216.100 +31.144.45.46 +151.21.100.106 +76.123.217.133 +177.40.2.167 +119.128.143.25 +5.234.103.241 +98.193.124.53 +112.95.76.241 +185.3.135.10 +73.95.132.134 +101.201.113.42 +183.2.231.227 +46.211.21.225 +163.125.53.90 +92.10.194.171 +85.178.66.183 +83.8.123.78 +183.93.0.67 +123.231.87.27 +2.99.232.250 +116.21.174.185 +92.76.216.216 +83.149.37.74 +78.45.51.28 +196.209.216.12 +187.109.5.193 +75.131.210.217 +162.243.53.32 +94.60.128.22 +112.198.79.152 +89.229.235.161 +77.170.189.6 +217.147.83.21 +54.214.242.184 +176.14.250.142 +84.184.101.207 +86.3.208.181 +5.56.205.78 +115.87.164.123 +87.109.37.187 +113.138.229.131 +82.222.127.100 +78.109.33.66 +118.209.62.97 +81.111.141.42 +207.118.73.70 +121.74.236.218 +209.222.15.229 +86.162.103.254 +108.44.13.36 +113.118.123.158 +36.251.68.135 +25.8.252.23 +93.105.234.200 +188.104.243.196 +113.229.43.58 +93.140.224.115 +2.239.209.176 +109.182.233.154 +24.245.101.20 +217.118.95.74 +128.69.176.75 +99.102.81.58 +77.181.82.162 +223.13.190.254 +89.32.252.19 +37.163.244.10 +75.130.95.76 +182.140.82.232 +91.9.190.93 +93.222.180.213 +94.193.226.76 +72.177.207.7 +183.147.223.56 +24.6.102.109 +87.172.222.161 +2.37.175.81 +79.242.62.144 +50.38.116.145 +162.243.35.214 +50.153.102.199 +24.161.113.119 +178.190.168.250 +199.185.6.2 +188.33.58.65 +100.86.109.143 +74.64.33.114 +83.39.68.119 diff --git a/iguana/confs/GMC_peers.txt b/iguana/confs/GMC_peers.txt new file mode 100644 index 000000000..88c00ba9c --- /dev/null +++ b/iguana/confs/GMC_peers.txt @@ -0,0 +1,26 @@ +5.196.20.189 +45.32.1.137 +104.255.67.131 +104.236.84.230 +142.4.218.175 +58.168.10.110 +101.173.217.38 +194.135.81.138 +80.229.155.158 +85.214.23.49 +104.168.148.143 +46.105.118.15 +198.27.97.172 +101.173.200.202 +89.36.212.56 +45.48.9.204 +104.172.24.79 +85.25.200.157 +216.146.143.177 +203.7.43.162 +101.173.197.85 +111.99.55.252 +192.52.166.35 +193.192.37.135 +209.126.119.209 +155.254.49.27 diff --git a/iguana/confs/LTC_peers.txt b/iguana/confs/LTC_peers.txt new file mode 100644 index 000000000..7a809722e --- /dev/null +++ b/iguana/confs/LTC_peers.txt @@ -0,0 +1,14 @@ +37.97.159.116 +5.9.67.48 +86.107.207.194 +46.28.206.204 +91.232.188.3 +209.180.247.49 +61.150.109.231 +24.217.216.92 +219.117.248.55 +131.161.120.110 +122.224.51.104 +78.25.32.206 +46.63.26.63 +200.79.231.62 diff --git a/iguana/confs/MZC_peers.txt b/iguana/confs/MZC_peers.txt new file mode 100644 index 000000000..119b86f9e --- /dev/null +++ b/iguana/confs/MZC_peers.txt @@ -0,0 +1,81 @@ +188.226.195.226 +72.49.184.206 +84.22.108.241 +75.128.211.140 +176.31.53.252 +212.5.143.185 +205.197.252.41 +195.154.223.134 +142.4.218.174 +72.46.152.250 +45.63.65.112 +104.236.167.70 +142.4.218.175 +108.61.164.199 +107.170.173.232 +98.117.92.108 +192.95.29.153 +97.88.116.115 +24.206.113.66 +173.239.208.6 +24.107.101.162 +88.198.49.154 +193.107.94.202 +86.26.119.177 +198.27.97.172 +73.240.243.108 +98.127.109.96 +27.109.250.186 +79.64.13.216 +81.102.95.39 +92.14.74.221 +68.42.79.115 +85.169.119.123 +24.107.102.70 +151.80.206.101 +107.170.167.218 +151.80.9.33 +82.46.79.119 +63.247.147.166 +95.145.252.94 +113.52.87.159 +192.99.35.133 +12.35.68.211 +46.105.158.205 +72.84.241.101 +37.59.18.108 +104.172.24.79 +174.107.118.81 +76.106.178.145 +75.128.193.117 +158.69.27.82 +45.32.233.30 +84.22.106.192 +74.132.6.75 +45.55.153.77 +89.156.223.223 +94.23.32.109 +180.94.191.62 +45.55.220.222 +73.192.202.185 +186.90.15.65 +108.224.49.4 +84.237.85.210 +76.19.242.156 +73.157.167.155 +68.117.4.111 +98.18.22.32 +69.59.214.109 +198.84.218.9 +98.115.147.74 +71.7.124.80 +65.15.37.140 +217.44.16.102 +73.240.162.49 +23.80.94.149 +151.80.206.110 +50.254.73.158 +92.14.75.139 +188.124.91.76 +66.189.11.251 +184.17.228.71 diff --git a/iguana/confs/SYS_hdrs.txt b/iguana/confs/SYS_hdrs.txt new file mode 100644 index 000000000..dbd998a23 --- /dev/null +++ b/iguana/confs/SYS_hdrs.txt @@ -0,0 +1,80 @@ +156002 +0 0000072d66e51ab87de265765cc8bdd2d229a4307c672a1b3d5af692519cf765 e7154a5e0c8d684b5ea1334f5fdae0d9c954346e356d6f9088a1305b4eb380aa 00000ddd21c846f0bd83fc70f0503544f8779b6953e1ef30e3442c8de24a242f +2000 177d59135fdaacffcc7f0c5a55ba21410d8a7f3949c7f70bbbf60bf5480f936f 3c6e14e64f6d96152f6e869ab6999f599062a59f50e4882bdf5fc4f0b6d4ad12 9072c4e219440d5726662b589c388e64083a584b2cde8d43bfbc4d6c9c4cfe94 +4000 f0ca176b56b5049f64c2cdb15ec253d698f5804ac5bebd1a54a7b1fb57b8a95b 13ef6316512f80a8f2d243fc7ddb6ac359c1491e70ceed09490fb4dd5179bf62 60670221d1e61416ced153715d468bc007fdcc6244a2af80a840008e3da5d7f8 +6000 de4fb22629b591e55ec70761209e90a5e344994ab776311edd64e523fefe0c21 ea9003a3cf67cdd7e53f30a936cacba9a324c4411df02dd12a9ebf15e9f7b51f ef9e66610cba2b6109998ad90f1788a7367cf1105ce9ab09a1e69a0b820101ad +8000 132fd7654f0401f3050671a9b722f9dceefbc85a83400ba322deac9b499cd8b2 43cacdc0bf7dcce73b041c4e8f4c4aa87d7dcae2377372ae7ad8b8b3ee2b1d7d 29488016109e1b83c84fa450006c5428e0f15cc3d6722875ececb0e024eb43bb +10000 45e9c45102be0767d4e8be3933af8dfc20e4be61003dcb6f34a8cd21cac744de a5e428af9b918663a948eb824708b86a6cdf81d738bb166af04a273605fbc493 018a3fc6b2d0fd6468749c4e4608558e4a13dcc3bd6c1338c2b6335d5c965edb +12000 5ae40e4a0760eb6fbc2f18f13733d074fd0449dd4cb60422e157b3d5241f03fc 31f59a8c8d21f4f9735b8c1f1ba3417177b2b5e2d627bfa96dd69c93bff9defd 88cd1959037a5f611aebfe33c6a927a12ef7d96bb4c39b1ffd928729d9abb2b5 +14000 98159d9d969254ce61596279ba194a3676d0e89c12e01cd2db074b6446a3afb2 a29c159c7dae33607cfe01d1e6492721921446f0d2d2a65863b907d215cdbcf8 4c4f4705381a8fb6a15bbf14c1147b8e59bc8cc619b4f3620fb7c3f2b5576daa +16000 401e0069109c8998a09e012038492c197e16331c09f930da957713d908baf958 c156a911f080b006ed39500c30e788b86d421fec6566974f30912015ab7fd54e 7fee64c96a21c0a8435cee8c9b19e475f77c27b96570d6acfd0c6f52bcc8af5d +18000 8d6b073588a170af1a98689629130c33199f4afc2bbcbf46053e462b925a8e38 e4535d3d1572fad3deeb3ca7d7664d26c631a2e2de47e269222fa3c29647a3d3 4db256d99066bea91364d92b8daad7bcefbe32d4dfb8b2d22fa7cc27121ae9c6 +20000 dd24e07b348e8f8dcdd851b3e3bfca61303a02d29278eef0c8b8ed39341f1525 00ab3304a063d87c1a1011641b72228442b6bb3073a1480f38dbfab3d4989dac 4bfe27d71c4e9157f52a060f1d33205d3370f3018547180f1665afa5f3799a7c +22000 b8d6cbbf537fd37a57da7657e53d5d3657b761d8068efa6f74ce33f4ef3c27da 512550da3522bbeca972c921c465546dfedac83e8cdf1e5c43a866f7f7631dbb 2534e282d8baff568fb4df19dd35000631fa1756997c3ef354ffcf7e23f1a705 +24000 a9048ea78538c9c1d9a93f53030c1e3032974b9c8bd0b4f6f7ab6e7759cd85c9 e075b0a396761b5fa9d45478909668fdf3b44ced6f97b35e10e0dfe7bf20e278 3b898addf2735e44004df24df32e1f9a32b6796505c5946a77144d8e55574a6e +26000 f06feb3f9230732886a8c51a403614eac03d83317a669c7e5a0f60554cf4e0f9 c31f50ee3455ad8bac434de88701e3fad04d44fae8c48900b9001b5f9762728e e2296366eb1c6ec9aec24e17ae5342b3aa1e673b0b460d7799f4956d5d7da5b7 +28000 467a5450ccb04080bc616b85fb41872777f51ba2387052b462e17c2bf1a54021 9ce78add95decd34b64cf694988c7df82166292878c5bc87a92233f20fd59ebe 2a8684a8bdbd46d082d76cf53ffebfdbe317b94deaac7d7c3e9d5e4c0b98827d +30000 8c8606904d64828e5de90e9d78813d09e578b2157fcc8190a885fc886d618900 03543d3ac46a4efec2b5a4e2c4fd559f89efa9bbd0756503eccc76935c8659e4 20c5f1e2a6fb1970f3e91bed6ef8b91de5a61b20c9af764d49ad265f1bf0b6e3 +32000 642f185bc285def960ca94b300132204eb7a7442f842534d582ce52f35e348eb c810297ee175cc73dfcf33a25b4db2708196c92e3fb19837598942125ad03688 70b193ecad99743f056a0e4d540c98163bf077fa6fa341490854d3c36624d48b +34000 a4902edb7afeabda78ce4a7d169f2fb6d8efbd5b8de26db1c216d514ba9ea0cb ce010a27026bddd3e3e27c0229dd4b2eb8afefb3ff35bfa754a66ae13c4508f6 229e5d11a695a0efd41f062bac7d71d376abdf604c95af64f41d35f3b4a09a2c +36000 840f24491b2508eaebf25694fb99f7aa4bb9f0dddcba0869ce8b0ed9f721a72d 6c28b1f294395fa0c01fd1672bcad4f6a6f24c94842a2b2635cd66b1cfb198fa d2e5dc3ba356ff0baf8f31319ecab0ff26ebf26deae2c83aaca2811b23f1347c +38000 dbe0f9477252a72d883ed03bd6f21ab4dfa9cc26ab984e91b4458fdea43e485f 69c2fd0850b7c49021517c9f596a3516c7da728c2723b2ba9f8953b487530e67 5798988a19da261d8cbdc81c4619878733ead8a1b6eecd24808bb7a54c35b100 +40000 182ffbb00f28bb18e5597b7eeceda0a20d438b1266eedbb8a14688212b2ee164 0a992d0b1ee6722549f893be2f3054ecad19a08aa6a169339f8420a39a1567db d20ce50121c88abfa1e568272eb3dc65f1c56ee24255900d4e2d2056cc856849 +42000 a77e3ef4dbad28c98535d5bd42e865b70f08e8b2c1e23eb43addeb87108ca672 bfd3d6d7dbff6545f3d2e5876fdfe1d779d9f3059ac8e418200658934c3265dc 3580dc8d44660bc763d3e646bc7caffb1e9a16bf9d2300f3b10e402765344370 +44000 e5a49aedc6a8d98fe49365441821def78902220827f49d79e2ee6f7b3bfd0a5d 805b9b702640ce25d7ca9f4877e54ce135eccb3f50149d596b86cb29d84c34a4 1612f95d3763d4b8bd2dedecc3d4c3bc9bacbccbdd7d33bec194a1623c36eaa7 +46000 6c1edae79ec081a261ad9959a589363bf271a220221955f1413b1d6f01c13d6e 7ba55c250faf6a37302757e2d7627bb76211dda56c2c7b788c8ac0684162ccad ed7ae990969f18e884a529cfa42cca486ef16ada7b81cceefd3fca4417e4215e +48000 6b6ffbde243a0f14e5c6c5fc0fb253c792e277b26cbb336d1ae0f41b650497be 19d02baf9d97959d1f7d8e7ea1c2d20266f308815eb1b1f55d96e344c5c64c48 55428bd04d0b34e0113b0b5067e53996796a0654b1f469caf268439d016826db +50000 8450753e2445270347f733904dee79a53cf464e2d557af13b64e2e2ca4f2f7aa 0056f76ce453f8409fcebeb997af811f717e2c7fdfad098c70404b16af975962 0aa385a4899b8cd240994d7da4e6f2014291af85c97d9537f793fe8172f1a575 +52000 b5985c766605f950a639d3850b7b8d065f9c00eee1c7c47c6c6d0b6ee3df4db4 f2839acf8d11d409b1bd4f5850c27c8741d548e81f0073f277ee332402dba80a ba852e71391fb622146c94aefd7893568a0a736979f9aed3414c05e6fc9ba609 +54000 e2b42a69b77f4ee82462986da3f951a9cc8d462a6d9521e85f40888e1741a0e9 a44a8512ad26b5aa0b0009f2d81cff56a661f3e8e799c9775eb6aa57750eefd1 611d287b3e3aba4ff55ef898371333136fc15dbceb941c51e0693fbd95b2063d +56000 89f265898c7f81c02a4f597cb4ee6a2dfc89a176ad62b643926598d2d1f0d72b 0c7a0809b8710a7bf13de09b04e370882a07ae90955a253f5c6cc334c29d5312 6122e4ce11cf0827d554c698cc7d5a664ff8a9f7ca7042d5cee3205bfed5c2f0 +58000 9436fffe48f660c8b47d2b53457b10b2a3c723c675ef8f5ce55ca35b396354fb 1b8d6677ab227377c0fa58fb2f6ef4d43274a41db0599410c2498a50907f184a b913d94797298a4eeb55bfa09d1ef9d9476e00519e91f496188b4ade108fb808 +60000 ab97f89528d06ff007e3704b5df5ae000cb853e1aee96a1e8304e8158bd68af6 c97e6b0df7a0e9e99a77d7d36749efc16ace3886bd7729431f3c6abf37e1eb05 efe20d5d2e1ba0187dd3c008dbd5d96965b2167b37969b751cd56ded0ac867ce +62000 aba311cdc333eca601868b32591f592af99bd59970d5d74d688232e1163e3dac 19f9dd8de9e9c6f5dd8c48d17aa2c12c48ff8b9cfc93fc28f506408fb8c7e8ce 7d47fc09f3df6f205fe611c1f72115380ec03b38fbf930d32a23f5d6333b8719 +64000 add65ee6d2a7ec16a5a3225e8da5ad77db3598d0c6acf6d02345fe19f337c9d0 334bae92683b6aba273911506cca53dab2dc469202f3b51258a258594f385ea0 d76699680336bdbec5a724918b108f164d223cbdeabe852c67c7e8c7bd8685ad +66000 301d336019f33dc19bfa4919d3def6a30419ae9efce3d8c12278f587ac506150 6b2671f6e148fb007711d58847eb7813dd47c60a63f8e6b7fc42283f37cc68a5 bed7105f2cd56ce9b4cd52d132852872845986ad3bc50a912c9a05fe58c0afc7 +68000 92086d8116cc945693df7d1835e00b3f0f6b4effe612ca40b81ccee0edf0cf0e 4c4b1fe84f8e1f66bd18414de33f25decda4cc3f0102bdc0573a3495bb686e1d b50de4db2252d94ef6427a4c58b26d83c22638f2050a291b56a7f202e3008674 +70000 16a99fca907f6da1f3b6b60dfc3a967f10ea7aa0d87d6e5dd8aebde8f96deb30 437cf3776ba9cee32e3726b78d70485e6114f159f7890c5efc9913cb9bd7c54d eda78d5a23d448e1370b2320f748d39ccac5d4b80d9bd81d1d28fe71fd758d93 +72000 b8ed2b03228e1834c5d8d07cdb1cabadd1873076735ebd8c73f668cff6ad1202 4b1a235f0947f4d2c1340b25769e26800161975700216b32f661593ca3a3253e 94cf9b29ccbeac013068a274c6912b3fc378a276207ce8cc69ee1e8fc3531db2 +74000 974f73d108f391bc80423b2a1191f081851631040e2faa354c4e558b1462ddbe ae138a90692cd4a2441b963ef99049b21cdcc2f7a0536f0b9ea4c52561ee6e96 817b70326f88e0a156f025abd52be39f24cd8a55dfd303728f4d41a9eb222010 +76000 d87c281dd6fd6b459aade7329b3254b14e5344a15af37ced5bd5f233db8600ea 9cf270b10040305122b9604714d1a37cc4c50f6e6a902a9d44684578d450a7bd 6cc7d9aacb524da97b533d65453c93edeccb63a6962e62d99b90a0e2e4a4de40 +78000 e04f536c225e0602a17a77dbdf596d74d05c2e62fc144eb7f485d90e51efaae0 ccae9be3c0aaa85c717072dd40bcd7883b82fc33dd599612c1e33a2848fcbada 8d778fb32685a870125928b198caf8315fa6105338e9fd7233538d0f666c4022 +80000 035c0ac7266517dba8633526cf5b354aecd4d22d52c13920eed79502c60a1fcb dd3a790d16b70e6678492235825c2194e07b76d3f54da6ff49f13566d1ca4001 bea9c846d1a2ad7e162926fde61ec529ecc0f29194ed533d558b1ab7091cdd52 +82000 623d47eba7e618e3d665ce0fcfab19f4c50e4a5dd5cb810347627e62e5fa8cbf 0a4f74f442e22965e8d3d750a20ef98f322d7eb886326e3b34e7583708f3325b 56d5ade2a7069de08ef47670deda92ac786a8b4bc3f1c70681a284e3d782fa76 +84000 b1fcbf504f1eb693ac3617f7a55c6bfd9beff33d1aed2a9739414f4ff9da0eb4 0995922e8d718f6319cd45aba8aaa75563f1a93903f14d42aa3e228a87f7f8d5 f83a5d69d48e5135703aaa044b1fb95f8fb419e210087ee1dfba0714356ec4c0 +86000 ddbb9c3ded64f8255f7cfddf588913db2342d01cc00a2a68925379756bb44fe2 2c358fac4afde345c5d8763c0c112752032e901c22cf820e9ab34b295df58ce7 a831811a6363d0cf51b3618d6f3e24da2b3bc1832db75d0873ef432f09b97d27 +88000 ba12610c3a4889515ef70ad11879dafd5454512298ebb475adc8092478b3a651 cd1a155ad6adb1e1494173b311371b7bbc1c63427693cac3888903c05dc7356f da700025c112e38f95f2b7c12ca3dab0bb693437ca65c3ce586773c80ac9eb6b +90000 8d6ddddf850f6a929ca5a3a97119842d07bc2084a4f2ac8ed7e29de7cbd53e0a 4cc1771ef9d189806dec997d803c847d38982912d26a648c716ccd8792bdab78 11cd185c489464ee9c6d9715a2362dce39d9c887c4726ebb7b67193d03e3b6e0 +92000 c287af6c81b530db68d10c4f8696f2318916eeb79f2588ec15084aa3b1e8b15f ffabf3eeb5e32f308f3c93d4a28ed1557c3934421dfe583337f6394e5dfba183 67e2a81d81f9ee456b738b8c35245ca37efa5f6971f42ddd64612665d8da5de0 +94000 03a7d7a61ff1d7cf8accb669a6a905cd49879feb1c894ff67db5e608fc7a047e 34ea4500bea7e9ea0cf145e60b8698f86b90f7666cee4be233ba7a8633aa8b51 c610568ad1982268a65cdde38186b1510059d88ea4df6350cc74a31f3ecab259 +96000 bf3d4d47e9a4799cc385735c75f347e30d4c6062ede4e80dabc89a2d15d74275 559c8ffcf74da0226a74b5fd0ee5be7a6d14b0845420d482a8d5e4b0417a3a83 efb26bc864e039e7261c2a92944fe15a270dd16ba0d560e7ceea53837e5f4b87 +98000 52e2e829b5f4a9bb9663f3419468d4437c656a8b85c19eaedde50ebff0f67138 3fc82a97f2029a91860f279eabdf812b62802d4532b8cf629338ee268f558d9f ffdbadd77b9aa405b7441ed929ea7280cbdef4434c8cff6a569cdb9dd3401f1f +100000 c739b9d878520e9016edb179b796c06e3482ad43ae3096bcbdfa3df9d9a1dc1f d07eedbdf74701dd96b0ee5d0d6ba0cdd2f4279650662440404a9f7d9a13037d cf35be41eea83e28a710a660e90dcaae7b0c25d9411c91f2ef1df39291c32b22 +102000 52e3218efa91b431504ec55abcff7770e6288d4df347762be92bbadebc871759 de97c2632a3ea850d44bc46a9e5c4c5b5c1b1cee8f742e09ea1017ecb07b5ceb 907858693fe111f1606599c7820aef1d005ecb2999beb34cabf3364cf56c4b20 +104000 1fe62c64ee67bd3ed6014a2edd33429b738e4aa583b54ca7a9ba52fc5d56d763 452b1d0bd702f9dba5c5dfe4f40aa8a66f788082401e407c338e1bbc052d1d8f 08ddeec2023724cdac4bb4ae314537a5a9f3bda4d697cea80dda5a968f9064fa +106000 fa7e6a55e231e55fbe5c3e7a80484816900693d178542cdcbec6d49602c6456c 4e17c1bf3991b897491b632b19b90b00fc315a5b03e2b026083ff9451a19f3df d6cd8cc170a05d2c1a563d4514fe7f96702e211581ecc59846ad5533bc44e677 +108000 947508fb7697384ea611812e976bf093bd3e24f76d1eec009ae7e86e9001b1dc 20db3543bcf039844cee50a3e64816e15a49acfcfa57fa42e98602e2978e40c4 4985944a28f4cf89fc78bab0e751512fa37cbf28b28d69eb7ed67399a224a6c8 +110000 c82c074dc30d783647bb678f30b94efbb48dec3f91bd95e28afa84c02c693a5e 95bd70136a3851e48b9fe3f1840002c46c120ce9ac61e6d89932cc4a707a0bc6 db41debcbd74786fac2b9ca9779233999f3efb74e1668aadbd7c8c642631fe97 +112000 fae6502b6bf4c9f41028ed2ab78d456afe827b9db225965a3e25691cbef5a084 2e05c3c6dbe055da2143f9ce5e95f60affab884051472b6b427dd269f9846856 d0776ee42d86b6483662c2ea8932e6c45115074b493dac2b5e8bd8db7fad8c70 +114000 5c65e847f6fca20b2996b6d0d65bdc06a03bcd753e52a064902be6dfdb94ad46 612549e462e8965c9c65c3aac4a43a48d00f9045fe779e52bb22032fe797d398 a689e01984562305b07d380964cc5411ba15df46e69e63bb20a6e3464757c1db +116000 616d1c8641c51771d9a17a9fb35932abf0a71cade5f1eba4c74b3d6be25b3997 fac3e9d324f0e9362b7430d576cc2624ccbd76eb4358b4fd08a7515ee519556c 0dcf9915d49f18ac21772b01079fe482ca99fb978d53dbc6b1064def3e6c239c +118000 ef686075685980d5d7f952a13722b076212b0e8c30d969425e8f04215ad42907 d0c8b191df687c27c25348611f79ab8ae6ffee16757c992dfe0721028a463ed5 058837b660eccffec360b7d29ed59391a62c9384c6671ba342c79970b67ecfd2 +120000 ffb36f8b7e12e5cf3bc94745316d6132128b62035f2f16f7af7a66ff1715c507 586e0f1e7815c2ad06cbd99651f639654b6114febfb9f39a3953e68becb524c7 b31cdeca96e49131650721733a12f27d993e0f5fee5eeb3f8d88f93ee6ce9d01 +122000 cb193ea07b8e906f16e432d80cde626b7d05c8d96c05efadd77ae4393f6405bb 319f9200a81f8cb55a3a9cdc4ec516ef6d31b931c092ae562ede506d78a7b5cc 1a73648fa0325d828acdd82d5499ab18951c871675b70402f7e0b9a73f6233ff +124000 3421e7a215fb5ce90130625c1649ef527fd210f0a5b50521a9cc8464b2aad761 c5dcf21dcd50f04c20ef568104eedecceb624421a64ddf5c5002072cf672a94c 0cf50f38d57a2152b779941f0e05be46d5a5e77c2d5474a2e7df7b6f8e2b16db +126000 0e8dc1cc309e44b25e60d02fbf2d7462a6a27cf0e01f0d4507b81d60f13f830d dc583f0eebff8c52db2e09a351520887b703b2499af64f5fa4cffcf068ad0536 9dde2cbbcf166b9e1c3070c6f6a29a067ba906bd4c3ecb6bd7a3d4cb1b3fc811 +128000 6d6d9afa76cb187a06e9060d17e700192338240565285a5e262323b22dbc396e 5ab9869486eb481ae76d0ce2dc962e9552f7e848f9068eeffa78c72b3f5a2de5 8e200a2eeaedaaf739885dbc05429ee536e6290588a0fa8e5f935e2f8ffabb2d +130000 ab8a5b513106262cb723e323f3f958d43a28c181a7d659b7a213686a37608200 67cd2ec057914b1c8ee4c9ee12eff27e3d2e3319d1b9fa54eafc8c3af1771477 bd1f18ae3c1fa1f82ee8ce9ed99f5b0733b987c9c4ce2dbaff389156fd905a95 +132000 9a2774f3fc26b6955111bfa45bceed5eee9d3b31645e28bfb8ce94a40c20d5ef f2af2b97008184d3ea6a03a6c4dd5ac4b6ded644638cbeb23b1d52b8cdfa3485 cccdf1da0524789d0c535eb2d90b692e60bc0daea2172378e06286e99d3a88a1 +134000 03a45a57ae1d191f959a2bb6efb7194e040b37e4e1432ce130562b0e57f047de f2db588f0ed58b85243e5a64991c47082a233b29752d7d8f37927a43d3d2d7b4 a3c7e8464b0b5db6391f2fa318bb09d7c29273e0060b48b22c1b20f2ef865583 +136000 0292020fd226c0a5480668604f3703c7a6c6fac36a6b21a719161a7ac427c391 8f0b19dd6086f2938ec45f046384f1c9db0fc16bf5472d2824ab428b52d02a1a ed807fdb9f35d4481f920802e80e3444ce1d42e017c0ec6de77c06f5ea0f77eb +138000 0eb261942b14de5816a88b8678042755d1a488cc932b57cf77173415c5ae45c7 ffd6e003853bb9fab3a14f98fc11c5635506525e190e8ee7e52cc3d209b7623b b549762f3560eed5cf244535154aa6cf8a394248e718423954475c20391365df +140000 a6137bfdce2cf3135f78d3df158d11476d55be3c63be1fb6377b321933bf8223 95db30c4a686290963ae028e5e0cd69a6176cdb9532eaa52914999d5b096faa4 c867afd89f65d78702bfb505371c5d5788dbbcdda46cdf8724cbb5fb2785656b +142000 3a3753a81581a5fb38be88a1f3dcda02a259d8622ace9d59483ea23bc863366e 287bb1b1cec33689f893bc443e69800894c92c40306c2632bc480bd85664f116 c5872552e265172f69b599cbd8880deeeb6778977bbf37c6ac013e7c9d005283 +144000 a1476bb20454750d2f4fc8473a94e5b27d038b3c6316edc847ecb12aaac0d597 d251d5c0e9adb364a0497912ff313d3b6aa42a24e6a5e3ff3b052fd6e4ebd0c8 a387da6e4e35b1d85f1bfc2469c3b370c49abcb54396205d8dcb049e9f96fde6 +146000 ea5f516966eb3e1402d1f3c46181d31b645dd97872ee2bb7f6569ee9a5d7fcaa 96fd62fbcbca3b88aad1e1a31b3364f21e2ba70bcc51128a9057850a3d2b59fd 6f1bda2a99cf6df758552c8884f61a70b9bbd4582da93622da667973acaf48e6 +148000 c2ed216026f3964b8eebc32860b4f652ffcbdb9ef7919abd30a600b45213d2ba f0220bc5ec42c7438d7c940e0627a6a812e3a155f4cc3ec52d139d2558096dd0 b39f7051df105491dfb88c7aa5370141e573437b1fa2f339e8d192895edb2825 +150000 98caf6484c47c6a848c4be90c8f0bbf4c17b68f6a93b89a38c6b131e5ed916e3 3130956ca1ecd4128f7990a5455738d621ef265886f954b71aa1d4a08e0640c4 4b560c80523af6c40a7aeffa346394a4a882ff8bd4389c0da9d1913ef2964a6c +152000 362e4880edab5c4db558b49acbdbf7acbf7a497d7ecc4195daf7dd7c0f2bfd49 acd8a73af294fde5ed6a4ae753d717e8f418b75fedd4837d0314393151003114 a98219fb9bc660876498124425c0ac7448f2ed194ea3b0cd917440a10ead0fb0 +154000 4bbb29f7fbb3fabb8ae69fc127b6a1c00a7961df94094261806614cf6a6d3307 5e5d5d8da4a5cb3531f7fe11172dcc4bb23186304ec1d3f384d31c5b4d4c8718 b50b9146e961b233dc1b75569abe4223a70285608192867db188d526f2fd0de4 +156000 ead2066d3781e8e0e0b6db21d02e611ca6e1d0e568bcd3d95cd61423b7db58a4 diff --git a/iguana/confs/SYS_peers.txt b/iguana/confs/SYS_peers.txt new file mode 100644 index 000000000..28d9e52b2 --- /dev/null +++ b/iguana/confs/SYS_peers.txt @@ -0,0 +1,25 @@ +176.9.13.13 +162.210.92.46 +146.0.32.101 +144.76.94.38 +50.157.173.168 +188.165.3.6 +88.198.15.19 +192.95.29.72 +108.61.10.90 +71.97.31.194 +40.86.87.8 +45.79.215.60 +97.124.163.6 +192.241.200.33 +184.164.147.82 +162.243.59.178 +107.178.109.224 +198.15.127.242 +98.115.147.74 +194.135.90.38 +86.131.170.245 +107.170.185.5 +216.14.119.170 +108.170.26.210 +183.131.213.30 diff --git a/iguana/confs/UNO_peers.txt b/iguana/confs/UNO_peers.txt new file mode 100644 index 000000000..1be6bbfac --- /dev/null +++ b/iguana/confs/UNO_peers.txt @@ -0,0 +1,8 @@ +195.154.223.134 +216.146.143.177 +173.183.179.144 +144.76.176.12 +87.189.45.29 +188.138.94.6 +144.76.239.66 +144.76.64.123 diff --git a/iguana/confs/VIA_peers.txt b/iguana/confs/VIA_peers.txt new file mode 100644 index 000000000..4a24c7b91 --- /dev/null +++ b/iguana/confs/VIA_peers.txt @@ -0,0 +1,24 @@ +84.73.4.183 +98.115.147.74 +192.241.187.222 +159.203.208.102 +85.25.44.119 +178.32.251.114 +109.155.227.178 +146.0.32.101 +108.61.10.90 +198.27.82.134 +80.74.157.31 +192.241.183.16 +164.132.25.194 +128.199.47.200 +173.255.197.64 +46.101.136.168 +207.192.70.250 +54.201.183.106 +211.149.175.37 +128.199.192.241 +216.146.143.177 +82.164.213.27 +107.170.167.218 +195.154.223.134 diff --git a/iguana/confs/ZEC_peers.txt b/iguana/confs/ZEC_peers.txt new file mode 100644 index 000000000..2fc9018ae --- /dev/null +++ b/iguana/confs/ZEC_peers.txt @@ -0,0 +1,4 @@ +198.100.147.192 +159.203.60.92 +188.166.31.56 +46.105.126.215 diff --git a/iguana/confs/ZET_peers.txt b/iguana/confs/ZET_peers.txt new file mode 100644 index 000000000..9ec947e9d --- /dev/null +++ b/iguana/confs/ZET_peers.txt @@ -0,0 +1,8 @@ +208.94.242.218 +85.25.217.233 +76.95.178.229 +155.94.243.135 +108.61.10.90 +155.254.49.54 +198.27.81.25 +94.249.166.140 diff --git a/iguana/confs/iguana.conf b/iguana/confs/iguana.conf new file mode 100644 index 000000000..9be8adeaa --- /dev/null +++ b/iguana/confs/iguana.conf @@ -0,0 +1 @@ +{ "exchanges":[{"name":"poloniex"},{"name":"btc38"}] } \ No newline at end of file diff --git a/iguana/css/custom.css b/iguana/css/custom.css new file mode 100755 index 000000000..e87d2a4a1 --- /dev/null +++ b/iguana/css/custom.css @@ -0,0 +1,60 @@ +.exchangecontainer{ + margin:30px; + + background-color:#FFF; + color:#000; + + } +.innersection{ + background-color:#EEE; + margin:20px 0; + padding:10px; + } +.innersection h4{ + padding:7px; + font-weight:bolder; + } +.coin1, .coin2{ + float:left; + color:#000; + background-color:#EEE; + width:50%; + padding: 10px 10px; + + } + +.exchangecontainer label, #exchange_model #frmexchange label{ + color:#000; + + } +#frmexchange label{ + text-align:left !important; + } +.innersection .exchange{ + text-align:center; + width: 120px; + background-color: #009688; + + } +.button{ + width: 20%; + margin: 0 auto; +} +.shape{ + font-family: inherit; + font-size: inherit; + line-height: inherit; + height: 33px; + border-radius: 6px; + box-shadow: 0 0 0; + border: 1px solid #ccc; + width: 166px; + text-align: center; +} +.innersection table td{ padding:10px;} + +#address_to, #address_from{ + + width:100% !important; + height:45px !important; + } \ No newline at end of file diff --git a/iguana/example.js b/iguana/example.js index e6eba07a5..d8d59f6a8 100755 --- a/iguana/example.js +++ b/iguana/example.js @@ -46,23 +46,98 @@ function errorHandler(e,callback,name) { } var fileSystem=null; var files={}; -function onInitFs(fs) { - console.log('Opened file system: ' + fs.name); - fileSystem = fs; +function copyHelpFiles(callback) { + var helpFiles = [ + 'agent.md', + 'bootstrap-theme.min.css', + 'bootstrap.min.css', + 'bootstrap.min.js', + 'field.html', + 'field.md', + 'footer.html', + 'footer.md', + 'formfooter.html', + 'formfooter.md', + 'formheader.html', + 'formheader.md', + 'header.html', + 'header.md', + 'html5shiv.min.js', + 'jquery-ui.css', + 'jquery-ui.min.js', + 'jquery.min.js', + 'mime.json', + 'respond.min.js' + ]; + var rootDir='help'; + var $dfds = $.map(helpFiles,function(fname){ + var $dfd=$.Deferred(); + $.get(chrome.runtime.getURL(rootDir+'/'+fname)) + .done(function(str){ + fileSystem.root.getFile('/'+rootDir+'/'+fname, { + create: true + }, function(fileEntry) { + // Create a FileWriter object for our FileEntry (log.txt). + fileEntry.createWriter(function(fileWriter) { + fileWriter.onwriteend = function() { + console.log('Write completed.',fname,str.length); + $dfd.resolve(true); + }; + + fileWriter.onerror = function(e) { + console.log('Write failed: ',fname, e.toString()); + $dfd.resolve(false); + }; + + // Create a new Blob and write it to log.txt. + var blob = new Blob([str], { + type: 'text/plain' + }); + + fileWriter.write(blob); + // $dfd.resolve(true); + + }, function(createWriterErr){ + console.log('createWriterErr for',fname,createWriterErr); + $dfd.resolve(false); + }); + + }, function(createFileErr){ + console.log('createFileErr for',fname,createFileErr); + $dfd.resolve(false); + }); + }); + return $dfd; + }); + return $.when.apply($,$dfds); } + + // Called by the common.js module. function domContentLoaded(name, tc, config, width, height) { - navigator.webkitPersistentStorage.requestQuota(10000000000, - function(bytes){ - window.requestFileSystem(PERSISTENT, bytes, onInitFs, errorHandler); - common.updateStatus( + navigator.webkitPersistentStorage.requestQuota(10000000000, + function(bytes) { + window.requestFileSystem(PERSISTENT, bytes, function(fs) { + console.log('Opened file system: ' + fs.name); + fileSystem = fs; + copyHelpFiles().done(function() { + common.updateStatus( 'Allocated ' + bytes + ' bytes of persistent storage. Running the first time will take 17 seconds to load'); - common.attachDefaultListeners(); - common.createNaClModule(name, tc, config, width, height); - }, function(e){ - console.log('Error', e); -}); + common.attachDefaultListeners(); + common.createNaClModule(name, tc, config, width, height); + }); + /*dirReader = fs.root.createReader(); + dirReader.readEntries(function(results) { + console.log(results); + }, function(){ + console.log('File IO error'); + });*/ + }, errorHandler); + }, + function(e) { + console.log('Error', e); + }); } diff --git a/iguana/exchanges/bitcoin.c b/iguana/exchanges/bitcoin.c index 36fa64470..89b6ce232 100755 --- a/iguana/exchanges/bitcoin.c +++ b/iguana/exchanges/bitcoin.c @@ -22,15 +22,6 @@ char *bitcoind_passthru(char *coinstr,char *serverport,char *userpass,char *meth return(bitcoind_RPC(0,coinstr,serverport,userpass,method,params)); } -int32_t bitcoin_pubkeylen(const uint8_t *pubkey) -{ - if ( pubkey[0] == 2 || pubkey[0] == 3 ) - return(33); - else if ( pubkey[0] == 4 ) - return(65); - else return(-1); -} - int32_t bitcoin_addr2rmd160(uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr) { bits256 hash; uint8_t *buf,_buf[25]; int32_t len; @@ -40,21 +31,24 @@ int32_t bitcoin_addr2rmd160(uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr if ( (len= bitcoin_base58decode(buf,coinaddr)) >= 4 ) { // validate with trailing hash, then remove hash - hash = bits256_doublesha256(0,buf,len - 4); + hash = bits256_doublesha256(0,buf,21); *addrtypep = *buf; memcpy(rmd160,buf+1,20); - if ( (buf[len - 4]&0xff) == hash.bytes[31] && (buf[len - 3]&0xff) == hash.bytes[30] &&(buf[len - 2]&0xff) == hash.bytes[29] &&(buf[len - 1]&0xff) == hash.bytes[28] ) + if ( (buf[21]&0xff) == hash.bytes[31] && (buf[22]&0xff) == hash.bytes[30] &&(buf[23]&0xff) == hash.bytes[29] && (buf[24]&0xff) == hash.bytes[28] ) { - //printf("coinaddr.(%s) valid checksum\n",coinaddr); + //printf("coinaddr.(%s) valid checksum addrtype.%02x\n",coinaddr,*addrtypep); return(20); } else { - //char hexaddr[64]; - //btc_convaddr(hexaddr,coinaddr); - //for (i=0; i 20 ) + { + hash = bits256_doublesha256(0,buf,len); + } + for (i=0; iaddrtype,unspent->rmd160,coinaddr); - sprintf(args,"[\"%s\"]",coinaddr); + /*sprintf(args,"[\"%s\"]",coinaddr); wifstr = bitcoind_RPC(0,coin->symbol,coin->chain->serverport,coin->chain->userpass,"dumpprivkey",args); if ( wifstr != 0 ) { bitcoin_wif2priv(&addrtype,&unspent->privkeys[0],wifstr); //printf("wifstr.(%s) -> %s\n",wifstr,bits256_str(str,unspent->privkeys[0])); free(wifstr); - } else fprintf(stderr,"error (%s) cant find privkey\n",coinaddr); + } else fprintf(stderr,"error (%s) cant find privkey\n",coinaddr);*/ } if ( (account == 0 || jstr(item,"account") == 0 || strcmp(account,jstr(item,"account")) == 0) && (minconfirms <= 0 || juint(item,"confirmations") >= minconfirms-SMALLVAL) ) { @@ -194,18 +186,18 @@ uint64_t bitcoin_parseunspent(struct iguana_info *coin,struct bitcoin_unspent *u return(unspent->value); } -struct bitcoin_unspent *iguana_unspentsget(struct supernet_info *myinfo,struct iguana_info *coin,char **retstrp,double *balancep,int32_t *numunspentsp,double minconfirms,char *account) +struct bitcoin_unspent *iguana_unspentsget(struct supernet_info *myinfo,struct iguana_info *coin,char **retstrp,double *balancep,int32_t *numunspentsp,double minconfirms,char *address) { char params[128],*retstr; uint64_t value,total = 0; struct bitcoin_unspent *unspents=0; cJSON *utxo; int32_t i,n; - if ( account != 0 && account[0] == 0 ) - account = 0; *numunspentsp = 0; if ( retstrp != 0 ) *retstrp = 0; - sprintf(params,"%.0f, 99999999",minconfirms); + if ( address == 0 ) + sprintf(params,"%.0f, 99999999",minconfirms); + else sprintf(params,"%.0f, 99999999, [\"%s\"]",minconfirms,address); if ( (retstr= bitcoind_passthru(coin->symbol,coin->chain->serverport,coin->chain->userpass,"listunspent",params)) != 0 ) { - //printf("sss unspents.(%s)\n",retstr); + printf("sss unspents.(%s)\n",retstr); if ( (utxo= cJSON_Parse(retstr)) != 0 ) { n = 0; @@ -214,8 +206,8 @@ struct bitcoin_unspent *iguana_unspentsget(struct supernet_info *myinfo,struct i unspents = calloc(*numunspentsp,sizeof(*unspents)); for (i=0; i<*numunspentsp; i++) { - value = bitcoin_parseunspent(coin,&unspents[n],minconfirms,account,jitem(utxo,i)); - //printf("i.%d n.%d value %.8f\n",i,n,dstr(value)); + value = bitcoin_parseunspent(coin,&unspents[n],minconfirms,0,jitem(utxo,i)); + printf("i.%d n.%d value %.8f\n",i,n,dstr(value)); if ( value != 0 ) { total += value; @@ -223,7 +215,7 @@ struct bitcoin_unspent *iguana_unspentsget(struct supernet_info *myinfo,struct i } } } - //printf("numunspents.%d -> %d total %.8f\n",*numunspentsp,n,dstr(total)); + printf("numunspents.%d -> %d total %.8f\n",*numunspentsp,n,dstr(total)); *numunspentsp = n; free_json(utxo); } else printf("error parsing.(%s)\n",retstr); @@ -270,13 +262,37 @@ struct bitcoin_unspent *iguana_bestfit(struct iguana_info *coin,struct bitcoin_u return(vin); } -struct bitcoin_spend *iguana_spendset(struct supernet_info *myinfo,struct iguana_info *coin,int64_t amount,int64_t txfee,char *account) +struct bitcoin_spend *iguana_spendset(struct supernet_info *myinfo,struct iguana_info *coin,int64_t amount,int64_t txfee,cJSON *addresses,int32_t minconf) { - int32_t i,mode,numunspents,maxinputs = 1024; struct bitcoin_unspent *ptr,*up; - struct bitcoin_unspent *ups; struct bitcoin_spend *spend; double balance; int64_t remains,smallest = 0; - if ( (ups= iguana_unspentsget(myinfo,coin,0,&balance,&numunspents,coin->chain->minconfirms,account)) == 0 ) + int32_t i,n,mode,maxinputs,numunspents,totalunspents = 0; struct bitcoin_unspent *ptr,*up,*ups=0,*u; + struct bitcoin_spend *spend; double balance; int64_t remains; + if ( (n= cJSON_GetArraySize(addresses)) > 0 ) + { + for (i=0; iinputs) * maxinputs); + if ( totalunspents == 0 ) + return(0); + maxinputs = totalunspents; + spend = calloc(1,sizeof(*spend) + sizeof(*spend->inputs) * totalunspents); spend->txfee = txfee; remains = txfee + amount; spend->satoshis = remains; @@ -284,39 +300,101 @@ struct bitcoin_spend *iguana_spendset(struct supernet_info *myinfo,struct iguana for (i=0; i=0; mode--) - if ( (up= iguana_bestfit(coin,ups,numunspents,remains,mode)) != 0 ) + if ( (up= iguana_bestfit(coin,ups,totalunspents,remains,mode)) != 0 ) break; if ( up != 0 ) { - if ( smallest == 0 || up->value < smallest ) - { - smallest = up->value; - memcpy(spend->change160,up->rmd160,sizeof(spend->change160)); - } spend->input_satoshis += up->value; spend->inputs[spend->numinputs++] = *up; + // todo: update a vins array if ( spend->input_satoshis >= spend->satoshis ) { - // numinputs 1 -> (1.00074485 - spend 0.41030880) = net 0.59043605 vs amount 0.40030880 change 0.40030880 -> txfee 0.01000000 vs chainfee 0.01000000 spend->change = (spend->input_satoshis - spend->satoshis) - txfee; printf("numinputs %d -> (%.8f - spend %.8f) = change %.8f -> txfee %.8f vs chainfee %.8f\n",spend->numinputs,dstr(spend->input_satoshis),dstr(spend->satoshis),dstr(spend->change),dstr(spend->input_satoshis - spend->change - spend->satoshis),dstr(txfee)); break; } + memset(up,0,sizeof(*up)); remains -= up->value; } else break; } if ( spend->input_satoshis >= spend->satoshis ) { spend = realloc(spend,sizeof(*spend) + sizeof(*spend->inputs) * spend->numinputs); + free(ups); return(spend); } else { free(spend); + free(ups); return(0); } } +cJSON *bitcoin_vout(uint64_t satoshis,char *paymentscriptstr) +{ + cJSON *item,*skey; + item = cJSON_CreateObject(); + jadd64bits(item,"satoshis",satoshis); + skey = cJSON_CreateObject(); + jaddstr(skey,"hex",paymentscriptstr); + //printf("addoutput.(%s %s)\n",hexstr,jprint(skey,0)); + jadd(item,"scriptPubkey",skey); + return(item); +} + +char *bitcoin_calcrawtx(struct supernet_info *myinfo,struct iguana_info *coin,cJSON **vinsp,int64_t satoshis,char *paymentscriptstr,char *changeaddr,int64_t txfee,cJSON *addresses,int32_t minconf,uint32_t locktime) +{ + uint8_t addrtype,rmd160[20],script[512]; int32_t i,scriptlen; char *params,*rawtx=0; cJSON *item,*array,*vins=0,*vouts=0; struct bitcoin_spend *spend; char scriptstr[512],*voutstr; + *vinsp = 0; + if ( (spend= iguana_spendset(myinfo,coin,satoshis,txfee*2,addresses,minconf)) == 0 ) + return(0); + if ( spend->input_satoshis >= satoshis+txfee*2 ) + { + vins = cJSON_CreateArray(); + for (i=0; inuminputs; i++) + { + item = cJSON_CreateObject(); + jaddbits256(item,"txid",spend->inputs[i].txid); + jaddnum(item,"vout",spend->inputs[i].vout); + jaddi(vins,item); + } + vouts = cJSON_CreateArray(); + jaddi(vouts,bitcoin_vout(satoshis,paymentscriptstr)); + if ( spend->change > 0 ) + { + if ( iguana_addressvalidate(coin,&addrtype,changeaddr) < 0 ) + { + free(spend); + printf("illegal destination address.(%s)\n",changeaddr); + return(0); + } + bitcoin_addr2rmd160(&addrtype,rmd160,changeaddr); + scriptlen = bitcoin_standardspend(script,0,rmd160); + init_hexbytes_noT(scriptstr,script,scriptlen); + jaddi(vouts,bitcoin_vout(satoshis,scriptstr)); + } + bitcoin_addr2rmd160(&addrtype,rmd160,myinfo->myaddr.BTC); + scriptlen = bitcoin_standardspend(script,0,rmd160); + jaddi(vouts,bitcoin_vout(satoshis,scriptstr)); + voutstr = jprint(vouts,1); + voutstr[0] = '{', voutstr[strlen(voutstr)-1] = '}'; + array = cJSON_CreateArray(); + jaddi(array,jduplicate(vins)); + jaddi(array,cJSON_Parse(voutstr)), free(voutstr); + params = jprint(array,1); + rawtx = bitcoind_passthru(coin->name,coin->chain->serverport,coin->chain->userpass,"createrawtransaction",params); + free(params); + } + *vinsp = vins; + free(spend); + // add sigtxid to vins + if ( locktime != 0 ) + printf("need to patch locktime\n"); + return(rawtx); +} +#endif + #define EXCHANGE_NAME "bitcoin" #define UPDATE bitcoin ## _price #define SUPPORTS bitcoin ## _supports @@ -339,10 +417,11 @@ static char *BASERELS[][2] = { {"btcd","btc"}, {"nxt","btc"}, {"asset","btc"} }; double UPDATE(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *bidasks,int32_t maxdepth,double commission,cJSON *argjson,int32_t invert) { - cJSON *retjson,*bids,*asks; double hbla; + cJSON *retjson,*bids,*asks; double hbla; struct supernet_info *myinfo; + myinfo = SuperNET_MYINFO(0); bids = cJSON_CreateArray(); asks = cJSON_CreateArray(); - instantdex_offerfind(SuperNET_MYINFO(0),exchange,bids,asks,0,base,rel,1); + //instantdex_offerfind(myinfo,exchange,bids,asks,0,base,rel,0); //printf("bids.(%s) asks.(%s)\n",jprint(bids,0),jprint(asks,0)); retjson = cJSON_CreateObject(); cJSON_AddItemToObject(retjson,"bids",bids); @@ -366,36 +445,40 @@ char *PARSEBALANCE(struct exchange_info *exchange,double *balancep,char *coinstr cJSON *BALANCES(struct exchange_info *exchange,cJSON *argjson) { - double balance; char *retstr; int32_t i,numunspents,minconfirms; struct iguana_info *coin; - struct supernet_info *myinfo; struct bitcoin_unspent *unspents; cJSON *item,*retjson,*utxo; + double balance; int32_t i,minconfirms,numunspents,max; struct iguana_info *coin,*tmp; struct supernet_info *myinfo; cJSON *retjson,*array,*item,*addresses=0; uint64_t avail; struct iguana_outpoint outpt,*unspents=0; retjson = cJSON_CreateArray(); myinfo = SuperNET_accountfind(argjson); - for (i=0; iallcoins_mutex); + HASH_ITER(hh,myinfo->allcoins,coin,tmp) { - if ( (coin= Coins[i]) != 0 && coin->chain->serverport[0] != 0 ) + balance = 0.; + minconfirms = juint(argjson,"minconfirms"); + if ( minconfirms < coin->minconfirms ) + minconfirms = coin->minconfirms; + max = 100000; + unspents = calloc(max,sizeof(*unspents)); + if ( (numunspents= iguana_RTunspentslists(myinfo,coin,&avail,unspents,max,((uint64_t)1 << 62),minconfirms,addresses,0)) > 0 ) { - balance = 0.; - minconfirms = juint(argjson,"minconfirms"); - if ( minconfirms < coin->minconfirms ) - minconfirms = coin->minconfirms; - if ( (unspents= iguana_unspentsget(myinfo,coin,&retstr,&balance,&numunspents,minconfirms,0)) != 0 ) + array = cJSON_CreateArray(); + for (i=0; isymbol,item); + item = cJSON_CreateArray(); + outpt = unspents[i]; + jaddinum(item,outpt.hdrsi); + jaddinum(item,outpt.unspentind); + jaddinum(item,dstr(outpt.value)); + jaddi(array,item); } + item = cJSON_CreateObject(); + jadd(item,"unspents",array); + jaddnum(item,"numunspents",numunspents); + jaddnum(item,"balance",dstr(avail)); + jadd(retjson,coin->symbol,item); } + if ( unspents != 0 ) + free(unspents); } + //portable_mutex_unlock(&myinfo->allcoins_mutex); return(retjson); } @@ -412,14 +495,12 @@ int32_t is_valid_BTCother(char *other) uint64_t TRADE(int32_t dotrade,char **retstrp,struct exchange_info *exchange,char *base,char *rel,int32_t dir,double price,double volume,cJSON *argjson) { - char *str,*retstr,coinaddr[64]; uint64_t txid = 0; cJSON *json=0; - struct instantdex_accept *ap; - struct supernet_info *myinfo; uint8_t pubkey[33]; struct iguana_info *other; - myinfo = SuperNET_accountfind(argjson); + //char *str,*retstr,coinaddr[64]; int32_t added; uint64_t txid = 0; cJSON *json=0; struct instantdex_accept *ap; struct supernet_info *myinfo; struct iguana_info *other; + //myinfo = SuperNET_MYINFO(0);//SuperNET_accountfind(argjson); //printf("TRADE with myinfo.%p\n",myinfo); if ( retstrp != 0 ) *retstrp = 0; - if ( strcmp(base,"BTC") == 0 || strcmp(base,"btc") == 0 ) + /*if ( strcmp(base,"BTC") == 0 || strcmp(base,"btc") == 0 ) { base = rel; rel = "BTC"; @@ -438,8 +519,8 @@ uint64_t TRADE(int32_t dotrade,char **retstrp,struct exchange_info *exchange,cha { if ( (other= iguana_coinfind(base)) != 0 ) { - bitcoin_pubkey33(0,pubkey,myinfo->persistent_priv); - bitcoin_address(coinaddr,other->chain->pubtype,pubkey,sizeof(pubkey)); + //bitcoin_pubkey33(0,pubkey,myinfo->persistent_priv); + bitcoin_address(coinaddr,other->chain->pubtype,myinfo->persistent_pubkey33,33); jaddstr(argjson,base,coinaddr); } else if ( strcmp(base,"NXT") == 0 || (is_decimalstr(base) > 0 && strlen(base) > 13) ) @@ -455,57 +536,67 @@ uint64_t TRADE(int32_t dotrade,char **retstrp,struct exchange_info *exchange,cha jaddnum(json,"volume",volume); jaddstr(json,"BTC",myinfo->myaddr.BTC); jaddnum(json,"minperc",jdouble(argjson,"minperc")); - //printf("trade dir.%d (%s/%s) %.6f vol %.8f\n",dir,base,"BTC",price,volume); - if ( (str= instantdex_createaccept(myinfo,&ap,exchange,base,"BTC",price,volume,-dir,dir > 0 ? "BTC" : base,INSTANTDEX_OFFERDURATION,myinfo->myaddr.nxt64bits,0,jdouble(argjson,"minperc"))) != 0 && ap != 0 ) - retstr = instantdex_checkoffer(myinfo,&txid,exchange,ap,json), free(str); - else printf("null return queueaccept\n"); + printf("trade dir.%d (%s/%s) %.6f vol %.8f\n",dir,base,"BTC",price,volume); + if ( (str= instantdex_createaccept(myinfo,&ap,exchange,base,"BTC",price,volume,-dir,dir > 0 ? "BTC" : base,INSTANTDEX_OFFERDURATION,myinfo->myaddr.nxt64bits,jdouble(argjson,"minperc"))) != 0 && ap != 0 ) + { + retstr = instantdex_checkoffer(myinfo,&added,&txid,exchange,ap,json); + free(str); + if ( added == 0 ) + free(ap); + } else printf("null return queueaccept\n"); if ( retstrp != 0 ) *retstrp = retstr; } } - return(txid); + return(txid);*/ + return(0); } char *ORDERSTATUS(struct exchange_info *exchange,uint64_t orderid,cJSON *argjson) { - struct instantdex_accept *ap; struct bitcoin_swapinfo *swap; cJSON *retjson; + //struct instantdex_accept *ap; struct bitcoin_swapinfo *swap; + cJSON *retjson; retjson = cJSON_CreateObject(); - struct supernet_info *myinfo = SuperNET_accountfind(argjson); - if ( (swap= instantdex_statemachinefind(myinfo,exchange,orderid,1)) != 0 ) + struct supernet_info *myinfo;// = SuperNET_accountfind(argjson); + myinfo = SuperNET_MYINFO(0);//SuperNET_accountfind(argjson); + /*if ( (swap= instantdex_statemachinefind(myinfo,exchange,orderid)) != 0 ) jadd(retjson,"result",instantdex_statemachinejson(swap)); - else if ( (ap= instantdex_offerfind(myinfo,exchange,0,0,orderid,"*","*",1)) != 0 ) + else if ( (ap= instantdex_offerfind(myinfo,exchange,0,0,orderid,"*","*",0)) != 0 ) jadd(retjson,"result",instantdex_acceptjson(ap)); else if ( (swap= instantdex_historyfind(myinfo,exchange,orderid)) != 0 ) jadd(retjson,"result",instantdex_historyjson(swap)); - else jaddstr(retjson,"error","couldnt find orderid"); + else jaddstr(retjson,"error","couldnt find orderid");*/ return(jprint(retjson,1)); } char *CANCELORDER(struct exchange_info *exchange,uint64_t orderid,cJSON *argjson) { - struct instantdex_accept *ap = 0; cJSON *retjson; struct bitcoin_swapinfo *swap=0; - struct supernet_info *myinfo = SuperNET_accountfind(argjson); + //struct instantdex_accept *ap = 0; struct bitcoin_swapinfo *swap=0; + cJSON *retjson; + //struct supernet_info *myinfo;// = SuperNET_accountfind(argjson); + //myinfo = SuperNET_MYINFO(0);//SuperNET_accountfind(argjson); retjson = cJSON_CreateObject(); - if ( (ap= instantdex_offerfind(myinfo,exchange,0,0,orderid,"*","*",1)) != 0 ) + /*if ( (ap= instantdex_offerfind(myinfo,exchange,0,0,orderid,"*","*",0)) != 0 ) { ap->dead = (uint32_t)time(NULL); jadd(retjson,"orderid",instantdex_acceptjson(ap)); jaddstr(retjson,"result","killed orderid, but might have pending"); } - else if ( (swap= instantdex_statemachinefind(myinfo,exchange,orderid,1)) != 0 ) + else if ( (swap= instantdex_statemachinefind(myinfo,exchange,orderid)) != 0 ) { jadd(retjson,"orderid",instantdex_statemachinejson(swap)); jaddstr(retjson,"result","killed statemachine orderid, but might have pending"); - } + }*/ return(jprint(retjson,1)); } char *OPENORDERS(struct exchange_info *exchange,cJSON *argjson) { - cJSON *retjson,*bids,*asks; struct supernet_info *myinfo = SuperNET_accountfind(argjson); + cJSON *retjson,*bids,*asks; struct supernet_info *myinfo;// = SuperNET_accountfind(argjson); + myinfo = SuperNET_MYINFO(0);//SuperNET_accountfind(argjson); bids = cJSON_CreateArray(); asks = cJSON_CreateArray(); - instantdex_offerfind(myinfo,exchange,bids,asks,0,"*","*",1); + //instantdex_offerfind(myinfo,exchange,bids,asks,0,"*","*",0); retjson = cJSON_CreateObject(); jaddstr(retjson,"result","success"); jadd(retjson,"bids",bids); @@ -515,14 +606,13 @@ char *OPENORDERS(struct exchange_info *exchange,cJSON *argjson) char *TRADEHISTORY(struct exchange_info *exchange,cJSON *argjson) { - struct bitcoin_swapinfo PAD,*swap; cJSON *retjson = cJSON_CreateArray(); - memset(&PAD,0,sizeof(PAD)); - queue_enqueue("historyQ",&exchange->historyQ,&PAD.DL,0); - while ( (swap= queue_dequeue(&exchange->historyQ,0)) != 0 && swap != &PAD ) + struct bitcoin_swapinfo *swap,*tmp; cJSON *retjson = cJSON_CreateArray(); + portable_mutex_lock(&exchange->mutexH); + DL_FOREACH_SAFE(exchange->history,swap,tmp) { - jaddi(retjson,instantdex_historyjson(swap)); - queue_enqueue("historyQ",&exchange->historyQ,&swap->DL,0); + //jaddi(retjson,instantdex_historyjson(swap)); } + portable_mutex_unlock(&exchange->mutexH); return(jprint(retjson,1)); } diff --git a/iguana/exchanges/bitcoin.h b/iguana/exchanges/bitcoin.h index 42e1b6902..2bb2c5d9c 100755 --- a/iguana/exchanges/bitcoin.h +++ b/iguana/exchanges/bitcoin.h @@ -25,6 +25,7 @@ #define SCRIPT_OP_TRUE 0x51 #define SCRIPT_OP_2 0x52 #define SCRIPT_OP_3 0x53 +#define SCRIPT_OP_4 0x54 #define SCRIPT_OP_IF 0x63 #define SCRIPT_OP_ELSE 0x67 #define SCRIPT_OP_RETURN 0x6a @@ -39,23 +40,6 @@ #define SCRIPT_OP_CHECKSEQUENCEVERIFY 0xb2 #define SCRIPT_OP_CHECKLOCKTIMEVERIFY 0xb1 -#define IGUANA_SCRIPT_NULL 0 -#define IGUANA_SCRIPT_76AC 1 -#define IGUANA_SCRIPT_76A988AC 2 -#define IGUANA_SCRIPT_P2SH 3 -#define IGUANA_SCRIPT_OPRETURN 4 -#define IGUANA_SCRIPT_3of3 5 -#define IGUANA_SCRIPT_2of3 6 -#define IGUANA_SCRIPT_1of3 7 -#define IGUANA_SCRIPT_2of2 8 -#define IGUANA_SCRIPT_1of2 9 -#define IGUANA_SCRIPT_MSIG 10 -#define IGUANA_SCRIPT_DATA 11 -#define IGUANA_SCRIPT_AC 12 -#define IGUANA_SCRIPT_1of1 13 -#define IGUANA_SCRIPT_STRANGE 15 - -#define IGUANA_MAXSCRIPTSIZE 10001 int32_t bitcoin_validaddress(struct iguana_info *coin,char *coinaddr); int32_t bitcoin_cltvscript(uint8_t p2shtype,char *ps2h_coinaddr,uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,char *senderaddr,char *otheraddr,uint8_t secret160[20],uint32_t locktime); @@ -69,7 +53,7 @@ int32_t bitcoin_revealsecret160(uint8_t *script,int32_t n,uint8_t secret160[20]) int32_t bitcoin_standardspend(uint8_t *script,int32_t n,uint8_t rmd160[20]); int32_t bitcoin_pubkeylen(const uint8_t *pubkey); -int32_t bitcoin_scriptget(struct iguana_info *coin,int32_t *hashtypep,uint32_t *sigsizep,uint32_t *pubkeysizep,uint32_t *suffixp,struct vin_info *vp,uint8_t *scriptsig,int32_t len,int32_t spendtype); +int32_t bitcoin_scriptget(struct iguana_info *coin,int32_t *hashtypep,uint32_t *sigsizep,uint32_t *pubkeysizep,uint8_t **userdatap,uint32_t *userdatalenp,struct vin_info *vp,uint8_t *scriptsig,int32_t len,int32_t spendtype); int32_t iguana_expandscript(struct iguana_info *coin,char *asmstr,int32_t maxlen,uint8_t *script,int32_t scriptlen); int32_t bitcoin_scriptsig(struct iguana_info *coin,uint8_t *script,int32_t n,const struct vin_info *vp,struct iguana_msgtx *msgtx); char *iguana_scriptget(struct iguana_info *coin,char *scriptstr,char *asmstr,int32_t max,int32_t hdrsi,uint32_t unspentind,bits256 txid,int32_t vout,uint8_t *rmd160,int32_t type,uint8_t *pubkey33); diff --git a/iguana/exchanges777.h b/iguana/exchanges777.h index c0b042a4d..1b713c8df 100755 --- a/iguana/exchanges777.h +++ b/iguana/exchanges777.h @@ -22,26 +22,34 @@ #include #endif -#define INSTANTDEX_DECKSIZE 2000 +#define INSTANTDEX_DECKSIZE 1000 #define INSTANTDEX_HOPS 2 -#define INSTANTDEX_DURATION 60 +#define INSTANTDEX_DURATION 300 -#define INSTANTDEX_INSURANCERATE (1. / 777.) +#define INSTANTDEX_ORDERSTATE_IDLE 0 +#define INSTANTDEX_ORDERSTATE_HAVEOTHERFEE 1 +#define INSTANTDEX_ORDERSTATE_HAVEDEPOSIT 2 +#define INSTANTDEX_ORDERSTATE_HAVEPAYMENT 4 +#define INSTANTDEX_ORDERSTATE_HAVEALTPAYMENT 8 +#define INSTANTDEX_ORDERSTATE_ORDERIDMASK (~(uint64_t)15) + +#define INSTANTDEX_INSURANCEDIV 777 #define INSTANTDEX_PUBEY "03bc2c7ba671bae4a6fc835244c9762b41647b9827d4780a89a949b984a8ddcc06" #define INSTANTDEX_RMD160 "ca1e04745e8ca0c60d8c5881531d51bec470743f" #define TIERNOLAN_RMD160 "daedddd8dbe7a2439841ced40ba9c3d375f98146" #define INSTANTDEX_BTC "1KRhTPvoxyJmVALwHFXZdeeWFbcJSbkFPu" #define INSTANTDEX_BTCD "RThtXup6Zo7LZAi8kRWgjAyi1s4u6U9Cpf" -#define INSTANTDEX_MINPERC 50. +#define INSTANTDEX_MINPERC 50 -#define INSTANTDEX_OFFERDURATION 300 -#define INSTANTDEX_LOCKTIME 3600 +#define INSTANTDEX_OFFERDURATION 600 +//#define INSTANTDEX_LOCKTIME 3600 #define EXCHANGES777_MINPOLLGAP 1 #define EXCHANGES777_MAXDEPTH 200 #define EXCHANGES777_DEFAULT_TIMEOUT 30 typedef void CURL; struct exchange_info; +struct exchange_quote; struct exchange_funcs { @@ -64,10 +72,13 @@ struct exchange_info { struct exchange_funcs issue; char name[16],apikey[MAX_JSON_FIELD],apisecret[MAX_JSON_FIELD],tradepassword[MAX_JSON_FIELD],userid[MAX_JSON_FIELD]; - uint32_t exchangeid,pollgap,lastpoll; + uint32_t exchangeid,pollgap,lastpoll; portable_mutex_t mutex,mutexH,mutexS,mutexP,mutexR,mutexT; uint64_t lastnonce,exchangebits; double commission; void *privatedata; - CURL *cHandle; queue_t requestQ,pricesQ,statemachineQ,tradebotsQ,acceptableQ,historyQ; + struct tradebot_info *tradebots; + struct bitcoin_swapinfo *statemachines,*history; + struct instantdex_accept *offers; + CURL *cHandle; queue_t recvQ,pricesQ,requestQ; }; struct instantdex_msghdr @@ -108,56 +119,52 @@ struct exchange_request struct instantdex_offer { char base[24],rel[24]; - uint64_t price64,basevolume64,offer64; + int64_t price64,basevolume64; uint64_t account; uint32_t expiration,nonce; char myside,acceptdir,minperc,pad; }; struct instantdex_accept { - struct queueitem DL; + struct instantdex_accept *next,*prev; + uint8_t state,reported,minconfirms,peerhas[IGUANA_MAXPEERS/8]; uint64_t pendingvolume64,orderid; - uint32_t dead; int32_t didstate; + uint32_t dead; struct instantdex_offer offer; }; -struct bitcoin_statetx +struct instantdex_stateinfo { - bits256 txid; - uint64_t amount,change,inputsum; - double numconfirms; - char destaddr[64]; - char txbytes[]; + char name[24]; int16_t ind,initialstate; + cJSON *(*process)(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp); + cJSON *(*timeout)(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp); + int16_t timeoutind,errorind; + struct instantdex_event *events; int32_t numevents; }; +struct bitcoin_eventitem { struct queueitem DL; cJSON *argjson,*newjson; int32_t serdatalen; char cmd[16]; uint8_t serdata[]; }; + struct bitcoin_swapinfo { - struct queueitem DL; - struct instantdex_accept mine,other; - bits256 privkeys[INSTANTDEX_DECKSIZE+2],mypubs[2],otherpubs[2],privAm,pubAm,privBn,pubBn; - bits256 myorderhash,otherorderhash,mypubkey,othertrader; + struct bitcoin_swapinfo *next,*prev; portable_mutex_t mutex; + queue_t eventsQ; //struct bitcoin_eventitem *pollevent; + bits256 privkeys[INSTANTDEX_DECKSIZE],myprivs[2],mypubs[2],otherpubs[2],pubA0,pubB0,pubB1,privAm,pubAm,privBn,pubBn; + bits256 myorderhash,otherorderhash,mypubkey,othertrader,bothorderhash; uint64_t otherdeck[INSTANTDEX_DECKSIZE][2],deck[INSTANTDEX_DECKSIZE][2]; - uint64_t altsatoshis,BTCsatoshis,insurance,altpremium,matched64; - int32_t isinitiator,choosei,otherchoosei,cutverified,otherverifiedcut; + uint64_t altsatoshis,BTCsatoshis,insurance,altinsurance; + int32_t choosei,otherchoosei,cutverified,otherverifiedcut,numpubs,havestate,otherhavestate; struct bitcoin_statetx *deposit,*payment,*altpayment,*myfee,*otherfee; - char expectedcmdstr[16],status[16],waitfortx[16]; - struct instantdex_stateinfo *state; uint32_t expiration,dead,reftime; + char status[16],waitfortx[16]; + struct instantdex_stateinfo *state; struct instantdex_accept mine,other; + struct iguana_info *coinbtc,*altcoin; uint8_t secretAm[20],secretBn[20]; + uint32_t expiration,dead,reftime,btcconfirms,altconfirms,locktime; }; struct instantdex_event { char cmdstr[24],sendcmd[16]; int16_t nextstateind; }; -struct instantdex_stateinfo -{ - char name[24]; int16_t ind,initialstate; - cJSON *(*process)(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp); - cJSON *(*timeout)(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp); - int16_t timeoutind,errorind; - struct instantdex_event *events; int32_t numevents; -}; - #define instantdex_isbob(swap) (swap)->mine.offer.myside -struct instantdex_accept *instantdex_offerfind(struct supernet_info *myinfo,struct exchange_info *exchange,cJSON *bids,cJSON *asks,uint64_t orderid,char *base,char *rel,int32_t requeue); +struct instantdex_accept *instantdex_offerfind(struct supernet_info *myinfo,struct exchange_info *exchange,cJSON *bids,cJSON *asks,uint64_t orderid,char *base,char *rel,int32_t report); cJSON *instantdex_acceptjson(struct instantdex_accept *ap); cJSON *instantdex_historyjson(struct bitcoin_swapinfo *swap); struct bitcoin_swapinfo *instantdex_historyfind(struct supernet_info *myinfo,struct exchange_info *exchange,uint64_t orderid); @@ -178,11 +185,15 @@ double truefx_price(struct exchange_info *exchange,char *base,char *rel,struct e double fxcm_price(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *bidasks,int32_t maxdepth,double commission,cJSON *argjson,int32_t invert); double instaforex_price(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *bidasks,int32_t maxdepth,double commission,cJSON *argjson,int32_t invert); -char *instantdex_createaccept(struct supernet_info *myinfo,struct instantdex_accept **aptrp,struct exchange_info *exchange,char *base,char *rel,double price,double basevolume,int32_t acceptdir,char *mysidestr,int32_t duration,uint64_t offerer,int32_t queueflag,uint8_t minperc); -void instantdex_update(struct supernet_info *myinfo); -char *instantdex_sendcmd(struct supernet_info *myinfo,struct instantdex_offer *offer,cJSON *argjson,char *cmdstr,bits256 desthash,int32_t hops,void *extra,int32_t extralen); +char *instantdex_createaccept(struct supernet_info *myinfo,struct instantdex_accept **aptrp,struct exchange_info *exchange,char *base,char *rel,double price,double basevolume,int32_t acceptdir,char *mysidestr,int32_t duration,uint64_t offerer,uint8_t minperc); +char *instantdex_sendcmd(struct supernet_info *myinfo,struct instantdex_offer *offer,cJSON *argjson,char *cmdstr,bits256 desthash,int32_t hops,void *extra,int32_t extralen,struct iguana_peer *addr,struct bitcoin_swapinfo *swap); char *instantdex_sendoffer(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *argjson); // Bob sending to network (Alice) -struct bitcoin_swapinfo *instantdex_statemachinefind(struct supernet_info *myinfo,struct exchange_info *exchange,uint64_t orderid,int32_t requeueflag); -char *instantdex_checkoffer(struct supernet_info *myinfo,uint64_t *txidp,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *json); +struct bitcoin_swapinfo *instantdex_statemachinefind(struct supernet_info *myinfo,struct exchange_info *exchange,uint64_t orderid); +char *instantdex_checkoffer(struct supernet_info *myinfo,int32_t *addedp,uint64_t *txidp,struct exchange_info *exchange,struct instantdex_accept *ap,cJSON *json); +void tradebot_timeslices(struct exchange_info *exchange); +struct instantdex_stateinfo *BTC_initFSM(int32_t *n); +struct bitcoin_statetx *instantdex_feetx(struct supernet_info *myinfo,struct instantdex_accept *A,struct bitcoin_swapinfo *swap,struct iguana_info *coin); +void instantdex_statemachine_iter(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap); +void instantdex_historyadd(struct exchange_info *exchange,struct bitcoin_swapinfo *swap); #endif diff --git a/iguana/fastgenbtc b/iguana/fastgenbtc new file mode 100755 index 000000000..f6cf5fb2e --- /dev/null +++ b/iguana/fastgenbtc @@ -0,0 +1,6 @@ +while true +do +../agents/iguana coins/genbtcfast.json +sleep 3 +done + diff --git a/iguana/genbtc b/iguana/genbtc deleted file mode 100755 index 5c6c61ec2..000000000 --- a/iguana/genbtc +++ /dev/null @@ -1 +0,0 @@ -curl --url "http://127.0.0.1:7778" --data "{\"prefetchlag\":5,\"poll\":1,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"BTC\",\"startpend\":8,\"endpend\":1,\"services\":0,\"maxpeers\":64}" diff --git a/iguana/genbtcloop b/iguana/genbtcloop new file mode 100755 index 000000000..1b8e2d987 --- /dev/null +++ b/iguana/genbtcloop @@ -0,0 +1,6 @@ +while true +do +../agents/iguana coins/genbtc.json +sleep 3 +done + diff --git a/iguana/help/.tmpmarker b/iguana/help/.tmpmarker deleted file mode 100644 index e69de29bb..000000000 diff --git a/iguana/iguana.sources b/iguana/iguana.sources index 68a2d7a9e..0c258c886 100755 --- a/iguana/iguana.sources +++ b/iguana/iguana.sources @@ -1,2 +1,2 @@ -SOURCES := SuperNET.c iguana_bundles.c iguana_interpreter.c mini-gmp.c main.c iguana_payments.c iguana_spendvectors.c iguana_sign.c iguana_txidfind.c iguana_realtime.c iguana_volatiles.c peggy_price.c SuperNET_category.c iguana_chains.c iguana_ramchain.c iguana_secp.c pangea_api.c peggy_ramkv.c SuperNET_hexmsg.c iguana_exchanges.c iguana_recv.c pangea_bets.c peggy_serdes.c SuperNET_keys.c iguana_rpc.c pangea_hand.c peggy_tx.c cards777.c iguana_init.c iguana_scripts.c pangea_json.c peggy_txind.c iguana777.c iguana_instantdex.c iguana_tradebots.c pangea_summary.c peggy_update.c iguana_accept.c iguana_json.c iguana_tx.c peggy.c poker.c iguana_bitmap.c iguana_msg.c iguana_unspents.c peggy_accts.c ramchain_api.c iguana_blocks.c iguana_peers.c iguana_wallet.c peggy_consensus.c databases/iguana_DB.c secp256k1/src/secp256k1.c \ No newline at end of file +SOURCES := iguana_bundles.c iguana_mofn.c iguana_stake.c iguana_interpreter.c mini-gmp.c main.c iguana_payments.c iguana_spendvectors.c iguana_sign.c iguana_txidfind.c iguana_realtime.c iguana_volatiles.c peggy_price.c iguana_chains.c iguana_ramchain.c iguana_secp.c pangea_api.c peggy_ramkv.c iguana_exchanges.c iguana_recv.c pangea_bets.c peggy_serdes.c SuperNET_keys.c iguana_rpc.c pangea_hand.c peggy_tx.c cards777.c iguana_init.c iguana_scripts.c pangea_json.c peggy_txind.c iguana777.c iguana_tradebots.c pangea_summary.c peggy_update.c iguana_accept.c iguana_json.c iguana_tx.c peggy.c poker.c iguana_bitmap.c iguana_msg.c iguana_unspents.c peggy_accts.c ramchain_api.c iguana_blocks.c iguana_peers.c iguana_wallet.c peggy_consensus.c ../gecko/gecko.c ../basilisk/basilisk.c ../datachain/datachain.c secp256k1/src/secp256k1.c \ No newline at end of file diff --git a/iguana/iguana777.c b/iguana/iguana777.c index 41bd0ce19..1ed4b4101 100755 --- a/iguana/iguana777.c +++ b/iguana/iguana777.c @@ -15,93 +15,89 @@ #include "iguana777.h" +#include "exchanges777.h" #include "secp256k1/include/secp256k1.h" +#include "secp256k1/include/secp256k1_schnorr.h" +#include "secp256k1/include/secp256k1_rangeproof.h" const char *Hardcoded_coins[][3] = { { "BTC", "bitcoin", "0" }, { "BTCD", "BitcoinDark", "129" }, { "VPN", "VPNcoin", "129" }, { "LTC", "litecoin", "129" } , { "endmarker", "", "" } }; -struct iguana_info *iguana_coinfind(const char *symbol) +struct iguana_info *iguana_coinfind(char *symbol) { - int32_t i; - for (i=0; iallcoins_being_added != 0 ) { - if ( Coins[i] != 0 && strcmp(Coins[i]->symbol,symbol) == 0 ) - return(Coins[i]); + printf("wait for coinadd to complete, OK if rare\n"); + sleep(1); } - return(0); + symbolcrc = calc_crc32(0,symbol,(int32_t)strlen(symbol)); + //portable_mutex_lock(&myinfo->allcoins_mutex); + HASH_FIND(hh,myinfo->allcoins,&symbolcrc,sizeof(coin->symbolcrc),coin); + //portable_mutex_unlock(&myinfo->allcoins_mutex); + return(coin); } -struct iguana_info *iguana_coinadd(const char *symbol,cJSON *argjson) +struct iguana_info *iguana_coinadd(char *symbol,char *name,cJSON *argjson,int32_t virtcoin) { - struct iguana_info *coin; int32_t i = 0; - if ( symbol == 0 ) + struct iguana_info *coin; uint32_t symbolcrc; char *privatechain; int32_t j; struct supernet_info *myinfo = SuperNET_MYINFO(0); + if ( (coin= iguana_coinfind(symbol)) == 0 ) { - for (i=0; iallcoins_being_added = 1; + coin = mycalloc('C',1,sizeof(*coin)); + coin->blockspacesize = IGUANA_MAXPACKETSIZE + 8192; + coin->blockspace = calloc(1,coin->blockspacesize); + if ( virtcoin != 0 || ((privatechain= jstr(argjson,"geckochain")) != 0 && privatechain[0] != 0) ) { - Coins[i] = mycalloc('C',1,sizeof(*Coins[i])); - printf("iguana_coin.(new) -> %p\n",Coins[i]); - return(Coins[i]); - } return(0); - printf("i.%d (%s) vs name.(%s)\n",i,Coins[i]->name,symbol); - } - } - else - { - for (i=0; i= sizeof(Hardcoded_coins)/sizeof(*Hardcoded_coins) ) - break; - //printf("Hardcoded_coins[i][0] %s vs.(%s)\n",Hardcoded_coins[i][0],symbol); - //if ( symbol[0] == 0 ) - // getchar(); - if ( strcmp("endmarker",Hardcoded_coins[i][0]) == 0 || strcmp(symbol,Hardcoded_coins[i][0]) == 0 ) + myinfo->allcoins_numvirts++; + coin->virtualchain = 1; + } + else { - if ( Coins[i] == 0 ) - Coins[i] = mycalloc('C',1,sizeof(*Coins[i])); - coin = Coins[i]; - if ( coin->chain == 0 ) + coin->chain = iguana_chainfind((char *)symbol,argjson,1); + coin->peers = calloc(1,sizeof(*coin->peers)); + for (j=0; jname,Hardcoded_coins[i][1]); - else if (argjson != 0 ) - { - if ( jstr(argjson,"name") != 0 ) - safecopy(coin->name,jstr(argjson,"name"),sizeof(coin->name)); - else strcpy(coin->name,symbol); - } - coin->chain = iguana_chainfind((char *)symbol,argjson,1); - coin->ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); - strcpy(coin->symbol,symbol); - iguana_initcoin(coin,argjson); + coin->peers->active[j].usock = -1; + strcpy(coin->peers->active[j].coinname,name); + strcpy(coin->peers->active[j].symbol,symbol); } - return(coin); } + if ( (coin->protocol= juint(argjson,"protocol")) == 0 ) + coin->protocol = IGUANA_PROTOCOL_BITCOIN; + coin->ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); + secp256k1_pedersen_context_initialize(coin->ctx); + secp256k1_rangeproof_context_initialize(coin->ctx); + strcpy(coin->name,name); + strcpy(coin->symbol,symbol); + iguana_initcoin(coin,argjson); + basilisk_functions(coin,coin->protocol); + printf("ADD ALLCOINS.(%s) name.(%s) size %ld numvirts.%d\n",symbol,name,sizeof(*coin),myinfo->allcoins_numvirts); + coin->symbolcrc = symbolcrc = calc_crc32(0,symbol,(int32_t)strlen(symbol)); + //portable_mutex_lock(&myinfo->allcoins_mutex); + HASH_ADD(hh,myinfo->allcoins,symbolcrc,sizeof(coin->symbolcrc),coin); + //portable_mutex_unlock(&myinfo->allcoins_mutex); + struct iguana_info *virt,*tmp; + HASH_ITER(hh,myinfo->allcoins,virt,tmp) + { + printf("%s ",virt->symbol); + } + printf("allcoins\n"); + myinfo->allcoins_being_added = 0; } + if ( (coin= iguana_coinfind(symbol)) == 0 ) + printf("error finding justadded.(%s)\n",symbol); } - return(0); -} - -struct iguana_info *iguana_coinselect() -{ - int32_t i; - for (i=0; isymbol[0] != 0 && Coins[i]->bundlescount > 0 ) - return(Coins[i]); - } - return(0); + return(coin); } void iguana_recvalloc(struct iguana_info *coin,int32_t numitems) { //coin->blocks.ptrs = myrealloc('W',coin->blocks.ptrs,coin->blocks.ptrs==0?0:coin->blocks.maxbits * sizeof(*coin->blocks.ptrs),numitems * sizeof(*coin->blocks.ptrs)); - coin->blocks.RO = myrealloc('W',coin->blocks.RO,coin->blocks.RO==0?0:coin->blocks.maxbits * sizeof(*coin->blocks.RO),numitems * sizeof(*coin->blocks.RO)); + //coin->blocks.RO = myrealloc('W',coin->blocks.RO,coin->blocks.RO==0?0:coin->blocks.maxbits * sizeof(*coin->blocks.RO),numitems * sizeof(*coin->blocks.RO)); //printf("realloc waitingbits.%d -> %d\n",coin->blocks.maxbits,numitems); - coin->blocks.maxbits = numitems; + //coin->blocks.maxbits = numitems; } static int _decreasing_double(const void *a,const void *b) @@ -137,21 +133,22 @@ double iguana_metric(struct iguana_peer *addr,uint32_t now,double decay) return(metric); } -int32_t iguana_peermetrics(struct iguana_info *coin) +int32_t iguana_peermetrics(struct supernet_info *myinfo,struct iguana_info *coin) { int32_t i,ind,n; double *sortbuf,sum; uint32_t now; struct iguana_peer *addr,*slowest = 0; //printf("peermetrics\n"); sortbuf = mycalloc('s',coin->MAXPEERS,sizeof(double)*2); - coin->peers.mostreceived = 0; + coin->peers->mostreceived = 0; now = (uint32_t)time(NULL); for (i=n=0; iMAXPEERS; i++) { - addr = &coin->peers.active[i]; - if ( addr->usock < 0 || addr->dead != 0 || addr->ready == 0 ) + addr = &coin->peers->active[i]; + if ( addr->usock < 0 || addr->dead != 0 || addr->ready == 0 || addr->ipbits == 0 ) continue; - addr->pendblocks = 0; - if ( addr->recvblocks > coin->peers.mostreceived ) - coin->peers.mostreceived = addr->recvblocks; + addr->pendblocks >>= 1; + addr->pendhdrs >>= 1; + if ( addr->recvblocks > coin->peers->mostreceived ) + coin->peers->mostreceived = addr->recvblocks; //printf("[%.0f %.0f] ",addr->recvblocks,addr->recvtotal); sortbuf[n*2 + 0] = iguana_metric(addr,now,.995); sortbuf[n*2 + 1] = i; @@ -165,31 +162,31 @@ int32_t iguana_peermetrics(struct iguana_info *coin) { if ( i < coin->MAXPEERS ) { - coin->peers.topmetrics[i] = sortbuf[i*2]; + coin->peers->topmetrics[i] = sortbuf[i*2]; ind = (int32_t)sortbuf[i*2 +1]; - coin->peers.ranked[i] = &coin->peers.active[ind]; + coin->peers->ranked[i] = &coin->peers->active[ind]; if ( sortbuf[i*2] > SMALLVAL && (double)i/n > .8 && (time(NULL) - addr->ready) > 77 ) - slowest = coin->peers.ranked[i]; - //printf("(%.5f %s) ",sortbuf[i*2],coin->peers.ranked[i]->ipaddr); - coin->peers.ranked[i]->rank = i + 1; - sum += coin->peers.topmetrics[i]; + slowest = coin->peers->ranked[i]; + //printf("(%.5f %s) ",sortbuf[i*2],coin->peers->ranked[i]->ipaddr); + coin->peers->ranked[i]->rank = i + 1; + sum += coin->peers->topmetrics[i]; } } - coin->peers.numranked = n; + coin->peers->numranked = n; portable_mutex_unlock(&coin->peers_mutex); //printf("NUMRANKED.%d\n",n); if ( i > 0 ) { - coin->peers.avemetric = (sum / i); + coin->peers->avemetric = (sum / i); if ( i >= 7*(coin->MAXPEERS/8) && slowest != 0 ) { - printf("prune slowest peer.(%s) numranked.%d MAXPEERS.%d\n",slowest->ipaddr,n,coin->MAXPEERS); + printf("prune slowest peer.(%s) numranked.%d MAXpeers->%d\n",slowest->ipaddr,n,coin->MAXPEERS); slowest->dead = 1; } } } myfree(sortbuf,coin->MAXPEERS * sizeof(double) * 2); - return(coin->peers.mostreceived); + return(coin->peers->mostreceived); } void *iguana_kviAddriterator(struct iguana_info *coin,struct iguanakv *kv,struct iguana_kvitem *item,uint64_t args,void *key,void *value,int32_t valuesize) @@ -197,10 +194,10 @@ void *iguana_kviAddriterator(struct iguana_info *coin,struct iguanakv *kv,struct char ipaddr[64]; int32_t i; FILE *fp = (FILE *)(long)args; struct iguana_peer *addr; struct iguana_iAddr *iA = value; if ( fp != 0 && iA != 0 && iA->numconnects > 0 && iA->lastconnect > time(NULL)-IGUANA_RECENTPEER ) { - for (i=0; ipeers.numranked; i++) - if ( (addr= coin->peers.ranked[i]) != 0 && addr->ipbits == iA->ipbits ) + for (i=0; ipeers->numranked; i++) + if ( (addr= coin->peers->ranked[i]) != 0 && addr->ipbits == iA->ipbits ) break; - if ( i == coin->peers.numranked ) + if ( i == coin->peers->numranked ) { expand_ipbits(ipaddr,iA->ipbits); fprintf(fp,"%s\n",ipaddr); @@ -209,28 +206,33 @@ void *iguana_kviAddriterator(struct iguana_info *coin,struct iguanakv *kv,struct return(0); } -uint32_t iguana_updatemetrics(struct iguana_info *coin) +uint32_t iguana_updatemetrics(struct supernet_info *myinfo,struct iguana_info *coin) { char fname[512],tmpfname[512],oldfname[512],ipaddr[64]; int32_t i,j; struct iguana_peer *addr,*tmpaddr; FILE *fp; - iguana_peermetrics(coin); + iguana_peermetrics(myinfo,coin); sprintf(fname,"%s/%s_peers.txt",GLOBAL_CONFSDIR,coin->symbol), OS_compatible_path(fname); sprintf(oldfname,"%s/%s_oldpeers.txt",GLOBAL_CONFSDIR,coin->symbol), OS_compatible_path(oldfname); sprintf(tmpfname,"%s/%s/peers.txt",GLOBAL_TMPDIR,coin->symbol), OS_compatible_path(tmpfname); if ( (fp= fopen(tmpfname,"w")) != 0 ) { - for (i=0; ipeers.numranked; i++) + for (i=0; ipeers->numranked; i++) { - if ( (addr= coin->peers.ranked[i]) != 0 && addr->relayflag != 0 && strcmp(addr->ipaddr,"127.0.0.1") != 0 ) + if ( (addr= coin->peers->ranked[i]) != 0 && addr->relayflag != 0 && strcmp(addr->ipaddr,"127.0.0.1") != 0 ) { - for (j=0; jpeers.numranked; j++) + for (j=0; jpeers->numranked; j++) { - if ( i != j && (tmpaddr= coin->peers.ranked[j]) != 0 && (uint32_t)addr->ipbits == (uint32_t)tmpaddr->ipbits ) + if ( i != j && (tmpaddr= coin->peers->ranked[j]) != 0 && (uint32_t)addr->ipbits == (uint32_t)tmpaddr->ipbits ) break; } - if ( j == coin->peers.numranked ) + if ( j == coin->peers->numranked ) { expand_ipbits(ipaddr,(uint32_t)addr->ipbits); fprintf(fp,"%s\n",ipaddr); + if ( 0 && addr->msgcounts.verack == 0 ) + { + printf("iguana_sendblockreq (%s) addrind.%d hasn't verack'ed yet\n",addr->ipaddr,addr->addrind); + iguana_send_version(coin,addr,coin->myservices); + } } } } @@ -266,10 +268,10 @@ void iguana_emitQ(struct iguana_info *coin,struct iguana_bundle *bp) void iguana_bundleQ(struct iguana_info *coin,struct iguana_bundle *bp,int32_t timelimit) { struct iguana_helper *ptr; - if ( bp->queued == 0 && bp->emitfinish <= 1 && iguana_bundleready(coin,bp,0) == bp->n ) + if ( 0 && bp->queued == 0 && bp->emitfinish <= 1 && iguana_bundleready(coin,bp,0) == bp->n ) printf("bundle.[%d] is ready\n",bp->hdrsi); bp->queued = (uint32_t)time(NULL); - ptr = mycalloc('i',1,sizeof(*ptr)); + ptr = mycalloc('q',1,sizeof(*ptr)); ptr->allocsize = sizeof(*ptr); ptr->coin = coin; ptr->bp = bp, ptr->hdrsi = bp->hdrsi; @@ -360,7 +362,7 @@ int32_t iguana_validated(struct iguana_info *coin) return(n); } -int32_t iguana_helperA(struct iguana_info *coin,struct iguana_bundle *bp,int32_t convertflag) +int32_t iguana_helperA(struct supernet_info *myinfo,struct iguana_info *coin,int32_t helperid,struct iguana_bundle *bp,int32_t convertflag) { int32_t retval,num = 0; if ( bp == 0 ) @@ -368,11 +370,11 @@ int32_t iguana_helperA(struct iguana_info *coin,struct iguana_bundle *bp,int32_t printf("iguana_helperA unexpected null bp\n"); return(-1); } - //printf("validate incr.%d and gen utxo.[%d] utxofinish.%u Xspends.%p\n",incr,hdrsi,bp->utxofinish,bp->ramchain.Xspendinds); + //printf("helperid.%d validate gen utxo.[%d] utxofinish.%u\n",helperid,bp->hdrsi,bp->utxofinish); if ( strcmp("BTC",coin->symbol) == 0 || iguana_bundlevalidate(coin,bp,0) == bp->n ) // { retval = 0; - if ( bp->utxofinish > 1 || (retval= iguana_spendvectors(coin,bp,&bp->ramchain,0,bp->n,convertflag,0)) >= 0 ) + if ( bp->utxofinish > 1 || (retval= iguana_spendvectors(myinfo,coin,bp,&bp->ramchain,0,bp->n,convertflag,0)) >= 0 ) { if ( retval > 0 ) { @@ -397,7 +399,7 @@ int32_t iguana_helperB(struct iguana_info *coin,int32_t helperid,struct iguana_b printf("iguana_helperB unexpected null bp\n"); return(-1); } - if ( bp != coin->current ) + //if ( bp != coin->current ) { iguana_ramchain_prefetch(coin,&bp->ramchain,7); if ( convertflag == 0 ) @@ -411,7 +413,62 @@ int32_t iguana_helperB(struct iguana_info *coin,int32_t helperid,struct iguana_b return(0); } -int32_t iguana_utxogen(struct iguana_info *coin,int32_t helperid,int32_t convertflag) +void iguana_update_balances(struct iguana_info *coin) +{ + int32_t i,hdrsi,max; struct iguana_bundle *bp; char fname[1024]; + if ( coin->RTheight > 0 ) + { + printf("Need to restart iguana to generate new balances files\n"); + printf("RT dataset can expand past bundle boundary, so no need to update balance files now\n"); + return; + } + max = coin->bundlescount; + if ( coin->bundles[max-1] == coin->current || coin->bundles[max-1] == 0 || (coin->bundles[max-1] != 0 && coin->bundles[max-1]->emitfinish <= 1) ) + max--; + //coin->spendvectorsaved = 0; + if ( iguana_balancefinished(coin) < max && iguana_spendvectorsaves(coin) == 0 ) // + { + if ( coin->origbalanceswritten <= 1 ) + hdrsi = 0; + else hdrsi = coin->origbalanceswritten; + for (i=0; ibundles[i]) != 0 && bp != coin->current ) + { + iguana_volatilespurge(coin,&bp->ramchain); + sprintf(fname,"%s/%s/accounts/debits.%d",GLOBAL_DBDIR,coin->symbol,bp->bundleheight); + OS_removefile(fname,0); + sprintf(fname,"%s/%s/accounts/lastspends.%d",GLOBAL_DBDIR,coin->symbol,bp->bundleheight); + OS_removefile(fname,0); + iguana_volatilesalloc(coin,&bp->ramchain,0);//i < hdrsi); + } + printf("accounts files purged\n"); + sleep(3); + for (hdrsi=0; hdrsibundles[hdrsi]) != 0 ) + { + if ( bp != coin->current ) + { + //iguana_ramchain_prefetch(coin,&bp->ramchain,3); + if ( iguana_balancegen(coin,0,bp,0,coin->chain->bundlesize-1,0) == 0 ) + { + fprintf(stderr,"%d ",hdrsi); + bp->balancefinish = (uint32_t)time(NULL); + } + else printf("balancegen error.[%d]\n",bp->hdrsi); + } + } else printf("null bp.[%d]\n",hdrsi); + } + //if ( max != coin->origbalanceswritten ) + { + coin->balanceflush = max+1; + while ( coin->balanceflush != 0 ) + sleep(3); + }// else printf("skip flush when max.%d and orig.%d\n",max,coin->origbalanceswritten); + } +} + +int32_t iguana_utxogen(struct supernet_info *myinfo,struct iguana_info *coin,int32_t helperid,int32_t convertflag) { int32_t hdrsi,n,i,max,incr,num = 0; struct iguana_bundle *bp; if ( coin->spendvectorsaved > 1 ) @@ -419,21 +476,21 @@ int32_t iguana_utxogen(struct iguana_info *coin,int32_t helperid,int32_t convert printf("skip utxogen as spendvectorsaved.%u\n",coin->spendvectorsaved); return(0); } - printf("helperid.%d start utxogen\n",helperid); - incr = 1;//IGUANA_NUMHELPERS; - //if ( 1 || coin->PREFETCHLAG > 0 ) // data issues on slow systems - // incr = 1; + //if ( (incr= IGUANA_NUMHELPERS) > 8 ) + // incr = 8; + incr = IGUANA_NUMHELPERS; max = coin->bundlescount; - if ( coin->bundles[max-1] != 0 && coin->bundles[max-1]->emitfinish <= 1 ) + if ( coin->bundles[max-1] == coin->current || coin->bundles[max-1] == 0 || (coin->bundles[max-1] != 0 && coin->bundles[max-1]->emitfinish <= 1) ) max--; + printf("helperid.%d start %s utxogen bundlescount.%d max.%d\n",helperid,coin->symbol,coin->bundlescount,max); if ( helperid < incr ) { for (hdrsi=helperid; hdrsibundles[hdrsi],convertflag); + num += iguana_helperA(myinfo,coin,helperid,coin->bundles[hdrsi],convertflag); } while ( (n= iguana_utxofinished(coin)) < max ) { - //printf("helperid.%d utxofinished.%d vs %d\n",helperid,n,max); + printf("helperid.%d utxofinished.%d vs %d\n",helperid,n,max); sleep(IGUANA_NUMHELPERS+3); } if ( helperid < incr ) @@ -448,82 +505,140 @@ int32_t iguana_utxogen(struct iguana_info *coin,int32_t helperid,int32_t convert } if ( helperid == 0 ) { - if ( iguana_balancefinished(coin) < max && iguana_spendvectorsaves(coin) == 0 ) - { - if ( 1 || coin->origbalanceswritten <= 1 ) - hdrsi = 0; - else hdrsi = coin->origbalanceswritten; - for (i=0; ibundles[i]) != 0 && bp != coin->current ) - iguana_volatilesalloc(coin,&bp->ramchain,i < hdrsi); - for (; hdrsibundles[hdrsi]) != 0 ) - { - //iguana_ramchain_prefetch(coin,&bp->ramchain,3); - if ( iguana_balancegen(coin,0,bp,0,coin->chain->bundlesize-1,0) == 0 ) - bp->balancefinish = (uint32_t)time(NULL); - } - } - if ( max != coin->origbalanceswritten ) - { - coin->balanceflush = max+1; - while ( coin->balanceflush != 0 ) - sleep(3); - } else printf("skip flush when max.%d and orig.%d\n",max,coin->origbalanceswritten); - } + printf("start iguana_update_balances\n"); + iguana_update_balances(coin); + printf("iguana_update_balances completed\n"); if ( 1 ) { for (i=0; ibundles[i]) != 0 ) { - //iguana_volatilespurge(coin,&bp->ramchain); + iguana_volatilespurge(coin,&bp->ramchain); iguana_volatilesmap(coin,&bp->ramchain); } } } while ( iguana_balancefinished(coin) < max || coin->balanceflush != 0 ) sleep(3); - //printf("helper.%d check validates\n",helperid); - incr = IGUANA_NUMHELPERS; if ( helperid < incr ) { for (hdrsi=helperid; hdrsibundles[hdrsi]) == 0 ) - break; + { + printf("unexpected null bp for [%d]\n",hdrsi); + continue; + } if ( iguana_bundlevalidate(coin,bp,0) != bp->n ) { printf("validate.[%d] error. refresh page or restart iguana and it should regenerate\n",bp->hdrsi); exit(-1); - } //else printf("helperid.%d validated.[%d]\n",helperid,hdrsi); + } // else printf("%s helperid.%d validated.[%d]\n",coin->symbol,helperid,hdrsi); } } - /*while ( iguana_validated(coin) < max || iguana_utxofinished(coin) < max || iguana_balancefinished(coin) < max ) + while ( iguana_validated(coin) < max || iguana_utxofinished(coin) < max ) { - printf("helperid.%d waiting for spendvectorsaved.%u v.%d u.%d b.%d vs max.%d\n",helperid,coin->spendvectorsaved,iguana_validated(coin),iguana_utxofinished(coin),iguana_balancefinished(coin),max); - sleep(IGUANA_NUMHELPERS+3); - }*/ + printf("%s helperid.%d waiting for spendvectorsaved.%u v.%d u.%d b.%d vs max.%d\n",coin->symbol,helperid,coin->spendvectorsaved,iguana_validated(coin),iguana_utxofinished(coin),iguana_balancefinished(coin),max); + sleep(2*IGUANA_NUMHELPERS+3); + } + //printf("helper.%d check validates\n",helperid); + //incr = IGUANA_NUMHELPERS; + //incr = 1; if ( helperid == 0 ) { coin->spendvectorsaved = (uint32_t)time(NULL); - //printf("UTXOGEN spendvectorsaved <- %u\n",coin->spendvectorsaved); + coin->spendvalidated = 0; + printf("%s UTXOGEN spendvectorsaved <- %u\n",coin->symbol,coin->spendvectorsaved); + if ( iguana_utxoaddr_gen(myinfo,coin,(coin->bundlescount - 1) * coin->chain->bundlesize) == 0 ) + { + printf("retry utxoaddr_gen\n"); + if ( iguana_utxoaddr_gen(myinfo,coin,(coin->bundlescount - 1) * coin->chain->bundlesize) == 0 ) + { + printf("restart iguana: fatal error generating ledger file for %s\n",coin->symbol); + exit(1); + } + } } else { while ( coin->spendvectorsaved <= 1 ) sleep(IGUANA_NUMHELPERS+3); } - //printf("helper.%d helperdone\n",helperid); + printf("%s helper.%d helperdone\n",coin->symbol,helperid); return(num); } +int32_t iguana_coin_mainiter(struct iguana_info *coin,int32_t *numpeersp) +{ + int32_t n,j,isRT = 0; struct iguana_bundle *bp; + if ( coin->RTheight == 0 && coin->firstRTheight == 0 && coin->current != 0 && coin->active != 0 && coin->started != 0 ) + { + isRT *= (coin->RTheight > 0); + if ( coin->peers != 0 ) + *numpeersp += coin->peers->numranked; + if ( 0 && (rand() % 10) == 0 ) + printf("%s main.%u vs %u, svs %u %d vs %d\n",coin->symbol,(uint32_t)time(NULL),coin->startutc+10,coin->spendvectorsaved ,coin->blocks.hwmchain.height/coin->chain->bundlesize,(coin->longestchain-coin->minconfirms)/coin->chain->bundlesize); + if ( time(NULL) > coin->startutc+60 && coin->blocks.hwmchain.height/coin->chain->bundlesize >= (coin->longestchain-coin->chain->bundlesize)/coin->chain->bundlesize ) + { + n = coin->bundlescount-1; + //printf("%s n.%d emitfinished.%d coin->spendvectorsaved %d\n",coin->symbol,n,iguana_emitfinished(coin,1),coin->spendvectorsaved); + if ( iguana_emitfinished(coin,1) >= n ) + { + if ( coin->PREFETCHLAG >= 0 && coin->fastfind == 0 ) + { + for (j=0; jbundles[j] != 0 ) + iguana_alloctxbits(coin,&coin->bundles[j]->ramchain); + sleep(3); + } + if ( iguana_validated(coin) < n || iguana_utxofinished(coin) < n || iguana_balancefinished(coin) < n ) + { + coin->spendvectorsaved = 1; + //printf("update volatile data, need.%d vs utxo.%d balances.%d validated.%d\n",n,iguana_utxofinished(coin),iguana_balancefinished(coin),iguana_validated(coin)); + } + else + { + coin->spendvectorsaved = (uint32_t)time(NULL); + //printf("already done UTXOGEN (%d %d) (%d %d)\n",iguana_utxofinished(coin),n,iguana_balancefinished(coin),n); + } + } //else printf("only emit.%d vs %d\n",iguana_emitfinished(coin),n); + } + if ( (bp= coin->current) != 0 && coin->stucktime != 0 && coin->isRT == 0 && coin->RTheight == 0 && (time(NULL) - coin->stucktime) > coin->MAXSTUCKTIME ) + { + if ( 0 ) + { + printf("%s is stuck too long, restarting due to %d\n",coin->symbol,bp->hdrsi); + if ( coin->started != 0 ) + { + iguana_coinpurge(coin); + sleep(3); + while ( coin->started == 0 ) + { + printf("wait for coin to reactivate\n"); + sleep(1); + } + sleep(3); + } + } + } + } + return(isRT); +} + void iguana_helper(void *arg) { - cJSON *argjson=0; int32_t iter,i,n,j,polltimeout,type,helperid=rand(),flag,allcurrent,idle=0; - struct iguana_helper *ptr; struct iguana_info *coin; struct OS_memspace MEM,*MEMB; struct iguana_bundle *bp; + static uint64_t helperidbits; + cJSON *argjson=0; int32_t iter,n,j,numpeers,polltimeout,type,helperid=rand(),flag,allcurrent,idle=0; + struct iguana_helper *ptr; struct iguana_info *coin,*tmp; struct OS_memspace MEM,*MEMB; struct iguana_bundle *bp; struct supernet_info *myinfo = SuperNET_MYINFO(0); + helperid %= 64; if ( arg != 0 && (argjson= cJSON_Parse(arg)) != 0 ) helperid = juint(argjson,"helperid"); + if ( ((1 << helperid) & helperidbits) != 0 ) + { + printf("SKIP duplicate helper.%d\n",helperid); + return; + } + helperidbits |= (1 << helperid); if ( IGUANA_NUMHELPERS < 2 ) type = 3; else type = (1 << (helperid % 2)); @@ -535,24 +650,32 @@ void iguana_helper(void *arg) sleep(2); while ( 1 ) { - //iguana_jsonQ(); cant do this here + //printf("helperid.%d top of loop\n",helperid); flag = 0; - allcurrent = 2; + allcurrent = 1; polltimeout = 100; - for (i=0; iallcoins_mutex); + numpeers = 0; + HASH_ITER(hh,myinfo->allcoins,coin,tmp) { - if ( (coin= Coins[i]) != 0 ) + if ( coin->firstRTheight == 0 ) { if ( coin->spendvectorsaved == 1 ) - iguana_utxogen(coin,helperid,0); - else if ( coin->spendvectorsaved > 1 ) + iguana_utxogen(myinfo,coin,helperid,0); + else if ( coin->spendvectorsaved > 1 && (coin->spendvalidated & (1 << helperid)) == 0 ) { + //printf("%s spendvectorsaved.%u helperid.%d validate\n",coin->symbol,coin->spendvectorsaved,helperid); for (j=helperid; jbundlescount-1; j+=IGUANA_NUMHELPERS) if ( (bp= coin->bundles[j]) != 0 ) iguana_bundlevalidate(coin,bp,0); + coin->spendvalidated |= (1 << helperid); + //printf("DONE %s spendvectorsaved.%u helperid.%d validate\n",coin->symbol,coin->spendvectorsaved,helperid); } } + if ( helperid == 0 ) + iguana_coin_mainiter(coin,&numpeers); } + //portable_mutex_unlock(&myinfo->allcoins_mutex); n = queue_size(&bundlesQ); for (iter=0; iterpolltimeout; if ( coin->current != 0 && coin->current->hdrsi != coin->bundlescount-1 ) allcurrent = 0; - //printf("[%d] bundleQ size.%d lag.%ld\n",bp->hdrsi,queue_size(&bundlesQ),time(NULL) - bp->nexttime); + //printf("h.%d [%d] bundleQ size.%d lag.%ld\n",helperid,bp->hdrsi,queue_size(&bundlesQ),time(NULL) - bp->nexttime); coin->numbundlesQ--; if ( coin->started != 0 && (bp->nexttime == 0 || time(NULL) > bp->nexttime) && coin->active != 0 ) { - flag += iguana_bundleiters(ptr->coin,&MEM,MEMB,bp,ptr->timelimit,IGUANA_DEFAULTLAG); + flag += iguana_bundleiters(myinfo,ptr->coin,&MEM,MEMB,bp,ptr->timelimit,IGUANA_DEFAULTLAG); } else { @@ -584,30 +707,6 @@ void iguana_helper(void *arg) myfree(ptr,ptr->allocsize); } else break; } - /*n = queue_size(&validateQ) / IGUANA_NUMHELPERS + 1; - printf("vQ is n.%d\n",n); - for (iter=0; iterbp) != 0 && (coin= ptr->coin) != 0 && coin->active != 0 ) - { - printf("helper.%d validate.[%d] %d vs %d\n",helperid,bp->hdrsi,coin->blocks.hwmchain.height/coin->chain->bundlesize,(coin->longestchain-1)/coin->chain->bundlesize); - if ( coin->blocks.hwmchain.height/coin->chain->bundlesize >= (coin->longestchain-1)/coin->chain->bundlesize ) - flag += iguana_bundlevalidate(coin,bp,0); - else - { - usleep(10000); - printf("requeue vQ.[%d]\n",bp->hdrsi); - iguana_validateQ(coin,bp); - } - } - else if ( coin->active != 0 ) - printf("helper validate missing param? %p %p\n",ptr->coin,ptr->bp); - myfree(ptr,ptr->allocsize); - flag++; - }*/ if ( queue_size(&bundlesQ) > 1 ) allcurrent = 0; if ( flag != 0 ) @@ -616,21 +715,50 @@ void iguana_helper(void *arg) { //printf("bundlesQ allcurrent\n"); usleep(polltimeout * 10000); - } - else usleep(polltimeout * 1000); + } else usleep(polltimeout * 10000); } } +void iguana_callcoinstart(struct supernet_info *myinfo,struct iguana_info *coin) +{ + struct iguana_bundle *bp; int32_t bundlei; bits256 zero; char dirname[512],*symbol; + iguana_rwiAddrind(coin,0,0,0); + //for (i=0; ichain); i++) + // printf("%02x",((uint8_t *)coin->chain)[i]); + char str[65]; printf(" netmagic.%08x init.(%s) maxpeers.%d maxrecvcache.%s services.%llx MAXMEM.%s polltimeout.%d cache.%d pend.(%d -> %d)\n",*(uint32_t *)coin->chain->netmagic,coin->symbol,coin->MAXPEERS,mbstr(str,coin->MAXRECVCACHE),(long long)coin->myservices,mbstr(str,coin->MAXMEM),coin->polltimeout,coin->enableCACHE,coin->startPEND,coin->endPEND); + symbol = coin->symbol; + sprintf(dirname,"%s/ro",GLOBAL_DBDIR), OS_ensure_directory(dirname); + sprintf(dirname,"%s/ro/%s",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname); + sprintf(dirname,"%s/%s",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname); + sprintf(dirname,"%s/purgeable/%s",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname); + sprintf(dirname,"%s/%s/validated",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname); + sprintf(dirname,"%s/%s/accounts",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname); + sprintf(dirname,"%s/%s/spends",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname); + sprintf(dirname,"%s/%s/vouts",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname); + if ( coin->VALIDATEDIR[0] != 0 ) + { + sprintf(dirname,"%s",coin->VALIDATEDIR), OS_ensure_directory(dirname); + sprintf(dirname,"%s/%s",coin->VALIDATEDIR,symbol), OS_ensure_directory(dirname); + } + sprintf(dirname,"%s/%s",GLOBAL_TMPDIR,symbol), OS_ensure_directory(dirname); + sprintf(dirname,"%s/%s/RT",GLOBAL_TMPDIR,coin->symbol), OS_ensure_directory(dirname); + iguana_coinstart(coin,coin->initialheight,coin->mapflags); + coin->chain->minconfirms = coin->minconfirms; + coin->started = coin; + coin->startutc = (uint32_t)time(NULL); + memset(zero.bytes,0,sizeof(zero)); + if ( (bp= iguana_bundlecreate(coin,&bundlei,0,*(bits256 *)coin->chain->genesis_hashdata,zero,1)) != 0 ) + bp->bundleheight = 0; +} + void iguana_coinloop(void *arg) { - struct iguana_info *coin,**coins = arg; - struct iguana_bundle *bp; int32_t flag,i,n,bundlei; bits256 zero; char str[2065]; - uint32_t now; + struct supernet_info *myinfo; int32_t flag,i,n; bits256 zero; uint32_t now; struct iguana_info *coin,**coins = arg; + myinfo = SuperNET_MYINFO(0); n = (int32_t)(long)coins[0]; coins++; - printf("begin coinloop[%d]\n",n); coin = coins[0]; - iguana_launchpeer(coin,"127.0.0.1"); + printf("begin coinloop[%d] %s\n",n,coin->symbol); memset(zero.bytes,0,sizeof(zero)); while ( 1 ) { @@ -639,82 +767,101 @@ void iguana_coinloop(void *arg) { if ( (coin= coins[i]) != 0 ) { - if ( coin->MAXPEERS > IGUANA_MAXPEERS ) - coin->MAXPEERS = IGUANA_MAXPEERS; - if ( coin->MAXPEERS < IGUANA_MINPEERS ) - coin->MAXPEERS = IGUANA_MAXPEERS; -#ifdef __PNACL__ - if ( strcmp(coin->symbol,"BTC") == 0 ) + if ( n > 1 && coin->RTheight > 0 && (rand() % 10) != 0 ) continue; - if ( coin->MAXPEERS > 64 ) - coin->MAXPEERS = 64; + if ( coin->peers == 0 ) + { + printf("FATAL lack of peers struct\n"); + exit(-1); + iguana_launchpeer(coin,"127.0.0.1",1); + } + if ( coin->virtualchain == 0 ) + { + if ( coin->MAXPEERS > IGUANA_MAXPEERS ) + coin->MAXPEERS = IGUANA_MAXPEERS; + if ( coin->MAXPEERS > 1 && coin->MAXPEERS < IGUANA_MINPEERS ) + coin->MAXPEERS = IGUANA_MAXPEERS; +#ifdef __PNACL__ + if ( coin->MAXPEERS > 64 ) + coin->MAXPEERS = 64; #endif + } if ( coin->started == 0 && coin->active != 0 ) { - iguana_rwiAddrind(coin,0,0,0); - iguana_coinstart(coin,coin->initialheight,coin->mapflags); - printf("init.(%s) maxpeers.%d maxrecvcache.%s services.%llx MAXMEM.%s polltimeout.%d cache.%d pend.(%d -> %d)\n",coin->symbol,coin->MAXPEERS,mbstr(str,coin->MAXRECVCACHE),(long long)coin->myservices,mbstr(str,coin->MAXMEM),coin->polltimeout,coin->enableCACHE,coin->startPEND,coin->endPEND); - coin->chain->minconfirms = coin->minconfirms; - coin->started = coin; - coin->startutc = (uint32_t)time(NULL); - if ( (bp= iguana_bundlecreate(coin,&bundlei,0,*(bits256 *)coin->chain->genesis_hashdata,zero,1)) != 0 ) - bp->bundleheight = 0; + iguana_callcoinstart(myinfo,coin); } now = (uint32_t)time(NULL); coin->idletime = 0; if ( coin->started != 0 && coin->active != 0 ) { - if ( coin->peers.numranked > 4 && coin->isRT == 0 && now > coin->startutc+77 && coin->numsaved >= (coin->longestchain/coin->chain->bundlesize)*coin->chain->bundlesize && coin->blocks.hwmchain.height >= coin->longestchain-30 ) + //printf("%s numranked.%d isRT.%d numsaved.%d M.%d L.%d numverified.%d hdrsi.%d\n",coin->symbol,coin->peers->numranked,coin->isRT,coin->numsaved,coin->blocks.hwmchain.height,coin->longestchain,coin->numverified,coin->current!=0?coin->current->hdrsi:-1); + if ( coin->peers->numranked > 4 && coin->isRT == 0 && now > coin->startutc+77 && coin->numsaved >= (coin->longestchain/coin->chain->bundlesize)*coin->chain->bundlesize && coin->blocks.hwmchain.height >= coin->longestchain-30 ) { - fprintf(stderr,">>>>>>> %s isRT blockrecv.%d vs longest.%d\n",coin->symbol,coin->blocksrecv,coin->longestchain); - coin->isRT = 1; + //fprintf(stderr,">>>>>>> %s isRT blockrecv.%d.%d\n",coin->symbol,coin->blocksrecv,coin->longestchain); + //coin->isRT = 1; if ( coin->polltimeout > 100 ) coin->polltimeout = 100; if ( coin->MAXPEERS > IGUANA_MINPEERS ) coin->MAXPEERS = IGUANA_MINPEERS; } - if ( coin->isRT != 0 && coin->current != 0 && coin->numverified >= coin->current->hdrsi ) + /*if ( coin->isRT != 0 && coin->current != 0 && coin->numverified >= coin->current->hdrsi ) { //static int32_t saved; //if ( saved++ == 0 ) // iguana_coinflush(coin,1); - } - if ( coin->bindsock >= 0 ) + }*/ + if ( RELAYID >= 0 ) { - if ( coin->peers.numranked < (7*coin->MAXPEERS/8) && now > coin->lastpossible ) + if ( coin->bindsock >= 0 ) { - //fprintf(stderr,"possible\n"); - if ( coin->peers.numranked > 0 && (now % 60) == 0 ) - iguana_send_ping(coin,coin->peers.ranked[rand() % coin->peers.numranked]); - coin->lastpossible = iguana_possible_peer(coin,0); // tries to connect to new peers + if ( coin->MAXPEERS > 1 && coin->peers->numranked < IGUANA_MAXPEERS/2 && now > coin->lastpossible+2 ) + { + //fprintf(stderr,"check possible\n"); + if ( coin->peers->numranked > 0 && (now % 60) == 0 ) + iguana_send_ping(myinfo,coin,coin->peers->ranked[rand() % coin->peers->numranked]); + coin->lastpossible = iguana_possible_peer(coin,0); // tries to connect to new peers + } } - } - else - { - if ( coin->peers.numranked < ((7*coin->MAXPEERS)>>3) && now > coin->lastpossible ) + else { - if ( coin->peers.numranked > 0 && (now % 60) == 0 ) - iguana_send_ping(coin,coin->peers.ranked[rand() % coin->peers.numranked]); - coin->lastpossible = iguana_possible_peer(coin,0); // tries to connect to new peers + if ( coin->MAXPEERS > 1 && coin->peers->numranked < ((7*coin->MAXPEERS)>>3) && now > coin->lastpossible+10 ) + { + if ( coin->peers->numranked > 0 && (now % 60) == 0 ) + iguana_send_ping(myinfo,coin,coin->peers->ranked[rand() % coin->peers->numranked]); + coin->lastpossible = iguana_possible_peer(coin,0); // tries to connect to new peers + } + } + if ( coin->MAXPEERS > 1 && now > coin->peers->lastmetrics+10 ) + { + coin->peers->lastmetrics = iguana_updatemetrics(myinfo,coin); // ranks peers } } - if ( now > coin->peers.lastmetrics+10 ) + if ( coin->FULLNODE != 0 || coin->VALIDATENODE != 0 || coin->MAXPEERS == 1 ) { - //fprintf(stderr,"metrics\n"); - coin->peers.lastmetrics = iguana_updatemetrics(coin); // ranks peers + portable_mutex_lock(&coin->allcoins_mutex); + flag += iguana_processrecv(myinfo,coin); + portable_mutex_unlock(&coin->allcoins_mutex); + if ( strcmp(coin->symbol,"BTCD") == 0 && coin->RTheight > 0 && coin->RTheight > coin->chain->bundlesize ) + { + int32_t hdrsi,nonz,errs; struct iguana_pkhash *refP; struct iguana_bundle *bp; + hdrsi = (coin->RTheight / coin->chain->bundlesize) - 1; + if ( 0 && (bp= coin->bundles[hdrsi]) != 0 && bp->weights == 0 ) + bp->weights = iguana_PoS_weights(myinfo,coin,&refP,&bp->supply,&bp->numweights,&nonz,&errs,bp->bundleheight); + } } - if ( coin->longestchain+10000 > coin->blocks.maxbits ) - iguana_recvalloc(coin,coin->longestchain + 100000); - flag += iguana_processrecv(coin); } coin->idletime = (uint32_t)time(NULL); } } - if ( flag == 0 && coin->isRT == 0 ) - usleep(coin->polltimeout*1000 + (coin->peers.numranked == 0)*1000000); + //iguana_jsonQ(); + //printf("%s flag.%d isRT.%d polltimeout.%d numranked.%d\n",coin->symbol,flag,coin->isRT,coin->polltimeout,coin->peers->numranked); + /*if ( flag == 0 && coin->isRT == 0 && coin->peers != 0 ) + usleep(coin->polltimeout*1000 + (coin->peers->numranked == 0)*1000000); else if ( coin->current != 0 && coin->current->hdrsi == coin->longestchain/coin->chain->bundlesize ) - usleep(coin->polltimeout*1000 + 90000 + (coin->peers.numranked == 0)*1000000); - else usleep(coin->polltimeout*1000); + usleep(coin->polltimeout*5000 + 90000 + (coin->peers->numranked == 0)*1000000); + else usleep(coin->polltimeout*1000);*/ + if ( flag == 0 ) + usleep(100000); } } @@ -731,66 +878,86 @@ void iguana_coinargs(char *symbol,int64_t *maxrecvcachep,int32_t *minconfirmsp,i *servicesp = j64bits(json,"services"); } -struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers,int64_t maxrecvcache,uint64_t services,int32_t initialheight,int32_t maphash,int32_t minconfirms,int32_t maxrequests,int32_t maxbundles,cJSON *json) +void iguana_nameset(char name[64],char *symbol,cJSON *json) +{ + if ( strcmp("BTC",symbol) == 0 ) + strcpy(name,"Bitcoin"); + else if ( strcmp("BTCD",symbol) == 0 ) + strcpy(name,"BitcoinDark"); + else + { + name[0] = 0; + if ( json != 0 ) + safecopy(name,jstr(json,"name"),64); + if ( name[0] == 0 ) + strcpy(name,symbol); + } +} + +struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers,int64_t maxrecvcache,uint64_t services,int32_t initialheight,int32_t maphash,int32_t minconfirms,int32_t maxrequests,int32_t maxbundles,cJSON *json,int32_t virtcoin) { struct iguana_chain *iguana_createchain(cJSON *json); - struct iguana_info *coin; int32_t j,m,mult,maxval,mapflags; char dirname[512]; cJSON *peers; + struct iguana_info *coin; int32_t j,m,mult,maxval,mapflags; char name[64]; cJSON *peers; mapflags = IGUANA_MAPRECVDATA | maphash*IGUANA_MAPTXIDITEMS | maphash*IGUANA_MAPPKITEMS | maphash*IGUANA_MAPBLOCKITEMS | maphash*IGUANA_MAPPEERITEMS; - coin = iguana_coinadd(symbol,json); - if ( (coin->MAXPEERS= maxpeers) <= 0 ) - coin->MAXPEERS = (strcmp(symbol,"BTC") == 0) ? 128 : 64; - if ( (coin->MAXRECVCACHE= maxrecvcache) == 0 ) - coin->MAXRECVCACHE = IGUANA_MAXRECVCACHE; - if ( (coin->MAXPENDINGREQUESTS= maxrequests) <= 0 ) - coin->MAXPENDINGREQUESTS = (strcmp(symbol,"BTC") == 0) ? IGUANA_MAXPENDINGREQUESTS : IGUANA_PENDINGREQUESTS; + iguana_nameset(name,symbol,json); + if ( (coin= iguana_coinfind(symbol)) == 0 ) + coin = iguana_coinadd(symbol,name,json,virtcoin); + //printf("ensure directories maxval.%d mult.%d start.%d end.%d\n",maxval,mult,coin->startPEND,coin->endPEND); + mult = (strcmp("BTC",coin->symbol) != 0) ? 32 : 512; + maxval = IGUANA_MAXPENDBUNDLES; + if ( coin->virtualchain == 0 ) + { + if ( (coin->MAXPEERS= maxpeers) <= 0 ) + coin->MAXPEERS = (strcmp(symbol,"BTC") == 0) ? 128 : 64; + if ( (coin->MAXRECVCACHE= maxrecvcache) == 0 ) + coin->MAXRECVCACHE = IGUANA_MAXRECVCACHE; + if ( (coin->MAXPENDINGREQUESTS= maxrequests) <= 0 ) + coin->MAXPENDINGREQUESTS = (strcmp(symbol,"BTC") == 0) ? IGUANA_MAXPENDINGREQUESTS : IGUANA_PENDINGREQUESTS; + if ( jobj(json,"prefetchlag") != 0 ) + coin->PREFETCHLAG = jint(json,"prefetchlag"); + else if ( strcmp("BTC",coin->symbol) == 0 ) + coin->PREFETCHLAG = 13; + else coin->PREFETCHLAG = -1; + if ( (coin->MAXSTUCKTIME= juint(json,"maxstuck")) == 0 ) + coin->MAXSTUCKTIME = _IGUANA_MAXSTUCKTIME; + if ( (coin->startPEND= juint(json,"startpend")) == 0 ) + { + if ( strcmp("BTCD",coin->symbol) == 0 ) + coin->startPEND = 500; + else coin->startPEND = IGUANA_MAXPENDBUNDLES*mult; + } + if ( coin->startPEND > maxval*mult ) + coin->startPEND = maxval*mult; + else if ( coin->startPEND < 2 ) + coin->startPEND = 2; + coin->MAXBUNDLES = coin->startPEND; + if ( (coin->endPEND= juint(json,"endpend")) == 0 ) + { + if ( strcmp("BTCD",coin->symbol) == 0 ) + coin->endPEND = 500; + else coin->endPEND = IGUANA_MINPENDBUNDLES*mult; + } + if ( coin->endPEND > maxval*mult ) + coin->endPEND = maxval*mult; + else if ( coin->endPEND < 2 ) + coin->endPEND = 2; +#ifdef __PNACL__ + coin->startPEND = coin->endPEND = 1; +#endif + } else coin->MAXPEERS = 0; coin->myservices = services; coin->initialheight = initialheight; coin->mapflags = mapflags; - mult = (strcmp("BTC",coin->symbol) != 0) ? 8 : 8; - maxval = IGUANA_MAXPENDBUNDLES; + coin->protocol = IGUANA_PROTOCOL_BITCOIN; + if ( (coin->txfee= jdouble(json,"txfee") * SATOSHIDEN) == 0 ) + coin->txfee = 10000; + if ( (coin->txfee_perkb= j64bits(json,"txfee_perkb")) < coin->txfee/8 ) + coin->txfee_perkb = coin->txfee / 8; coin->MAXMEM = juint(json,"RAM"); - if ( jobj(json,"prefetchlag") != 0 ) - coin->PREFETCHLAG = jint(json,"prefetchlag"); - else if ( strcmp("BTC",coin->symbol) == 0 ) - coin->PREFETCHLAG = 13; - else coin->PREFETCHLAG = -1; - if ( (coin->MAXSTUCKTIME= juint(json,"maxstuck")) == 0 ) - coin->MAXSTUCKTIME = _IGUANA_MAXSTUCKTIME; if ( coin->MAXMEM == 0 ) coin->MAXMEM = IGUANA_DEFAULTRAM; - //if ( strcmp("BTC",coin->symbol) == 0 && coin->MAXMEM < 4 ) - // maxval = (int32_t)coin->MAXMEM; coin->MAXMEM *= (1024L * 1024 * 1024); -#ifdef __PNACL__ - maxval = 1;// * (strcmp("BTC",coin->symbol) != 0) + 8; - //if ( mult > 1 ) - // mult /= 2; -#endif - if ( (coin->startPEND= juint(json,"startpend")) == 0 ) - { - if ( strcmp("BTCD",coin->symbol) == 0 ) - coin->startPEND = 500; - else coin->startPEND = IGUANA_MAXPENDBUNDLES*mult; - } - if ( coin->startPEND > maxval*mult ) - coin->startPEND = maxval*mult; - else if ( coin->startPEND < 2 ) - coin->startPEND = 2; - coin->MAXBUNDLES = coin->startPEND; - if ( (coin->endPEND= juint(json,"endpend")) == 0 ) - { - if ( strcmp("BTCD",coin->symbol) == 0 ) - coin->endPEND = 500; - else coin->endPEND = IGUANA_MINPENDBUNDLES*mult; - } - if ( coin->endPEND > maxval*mult ) - coin->endPEND = maxval*mult; - else if ( coin->endPEND < 2 ) - coin->endPEND = 2; -#ifdef __PNACL__ - //coin->startPEND = coin->endPEND = 1; -#endif - coin->enableCACHE = 0;//(strcmp("BTC",coin->symbol) != 0); + coin->enableCACHE = 0;//(strcmp("BTCD",coin->symbol) == 0); if ( jobj(json,"cache") != 0 ) coin->enableCACHE = juint(json,"cache"); if ( (coin->polltimeout= juint(json,"poll")) <= 0 ) @@ -798,33 +965,24 @@ struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers, coin->active = juint(json,"active"); if ( (coin->minconfirms = minconfirms) == 0 ) coin->minconfirms = (strcmp(symbol,"BTC") == 0) ? 3 : 10; - printf("ensure directories maxval.%d mult.%d start.%d end.%d\n",maxval,mult,coin->startPEND,coin->endPEND); - sprintf(dirname,"%s/ro",GLOBAL_DBDIR), OS_ensure_directory(dirname); - sprintf(dirname,"%s/ro/%s",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname); - sprintf(dirname,"%s/%s",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname); - sprintf(dirname,"%s/%s/validated",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname); - sprintf(dirname,"%s/%s/accounts",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname); - sprintf(dirname,"%s/%s/spends",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname); - sprintf(dirname,"%s/%s/vouts",GLOBAL_DBDIR,symbol), OS_ensure_directory(dirname); - if ( coin->VALIDATEDIR[0] != 0 ) - { - sprintf(dirname,"%s",coin->VALIDATEDIR), OS_ensure_directory(dirname); - sprintf(dirname,"%s/%s",coin->VALIDATEDIR,symbol), OS_ensure_directory(dirname); - } - sprintf(dirname,"%s/%s",GLOBAL_TMPDIR,symbol), OS_ensure_directory(dirname); if ( coin->chain == 0 && (coin->chain= iguana_createchain(json)) == 0 ) { printf("cant initialize chain.(%s)\n",jstr(json,0)); strcpy(coin->name,"illegalcoin"); coin->symbol[0] = 0; return(0); - } else iguana_chainparms(coin->chain,json); + } if ( jobj(json,"RELAY") != 0 ) - coin->RELAYNODE = juint(json,"RELAY"); - else coin->RELAYNODE = 1; + coin->FULLNODE = juint(json,"RELAY"); + else coin->FULLNODE = (strcmp(coin->symbol,"BTCD") == 0); if ( jobj(json,"VALIDATE") != 0 ) coin->VALIDATENODE = juint(json,"VALIDATE"); - else coin->VALIDATENODE = 1; + else coin->VALIDATENODE = (strcmp(coin->symbol,"BTCD") == 0); + if ( coin->VALIDATENODE != 0 || coin->FULLNODE != 0 ) + SuperNET_MYINFO(0)->IAMRELAY++; +#ifdef __PNACL + coin->VALIDATENODE = coin->FULLNODE = 0; +#endif if ( jobj(json,"validatedir") != 0 ) safecopy(coin->VALIDATEDIR,jstr(json,"validatedir"),sizeof(coin->VALIDATEDIR)); else strcpy(coin->VALIDATEDIR,GLOBAL_VALIDATEDIR); @@ -837,18 +995,22 @@ struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers, } printf("addnodes.%d\n",m); } - char str[65]; printf("pend.(%d -> %d) MAXMEM.%s enablecache.%d VALIDATEDIR.(%s)\n",coin->startPEND,coin->endPEND,mbstr(str,coin->MAXMEM),coin->enableCACHE,coin->VALIDATEDIR); + char str[65]; + if ( coin->virtualchain == 0 ) + printf("pend.(%d -> %d) MAXMEM.%s enablecache.%d VALIDATEDIR.(%s) VALIDATE.%d RELAY.%d\n",coin->startPEND,coin->endPEND,mbstr(str,coin->MAXMEM),coin->enableCACHE,coin->VALIDATEDIR,coin->VALIDATENODE,coin->FULLNODE); return(coin); } -int32_t iguana_launchcoin(struct supernet_info *myinfo,char *symbol,cJSON *json) +int32_t iguana_launchcoin(struct supernet_info *myinfo,char *symbol,cJSON *json,int32_t virtcoin) { - int32_t maxpeers,maphash,initialheight,minconfirms,maxrequests,maxbundles; - int64_t maxrecvcache; uint64_t services; struct iguana_info **coins,*coin; + int32_t maxpeers,maphash,initialheight,minconfirms,maxrequests,maxbundles; char name[64]; int64_t maxrecvcache; uint64_t services; struct iguana_info **coins,*coin; if ( symbol == 0 ) return(-1); - printf("launchcoin.%s\n",symbol); - if ( (coin= iguana_coinadd(symbol,json)) == 0 ) + if ( (coin= iguana_coinfind(symbol)) != 0 ) + return(0); + iguana_nameset(name,symbol,json); + printf("launchcoin.%s name.%s\n",symbol,name); + if ( (coin= iguana_coinadd(symbol,name,json,virtcoin)) == 0 ) return(-1); if ( myinfo->rpcsymbol[0] == 0 || iguana_coinfind(myinfo->rpcsymbol) == 0 ) strcpy(myinfo->rpcsymbol,symbol); @@ -859,13 +1021,14 @@ int32_t iguana_launchcoin(struct supernet_info *myinfo,char *symbol,cJSON *json) else maphash = 0; iguana_coinargs(symbol,&maxrecvcache,&minconfirms,&maxpeers,&initialheight,&services,&maxrequests,&maxbundles,json); coins = mycalloc('A',1+1,sizeof(*coins)); - if ( (coin= iguana_setcoin(symbol,coins,maxpeers,maxrecvcache,services,initialheight,maphash,minconfirms,maxrequests,maxbundles,json)) != 0 ) + if ( (coin= iguana_setcoin(symbol,coins,maxpeers,maxrecvcache,services,initialheight,maphash,minconfirms,maxrequests,maxbundles,json,virtcoin)) != 0 ) { coins[0] = (void *)((long)1); coins[1] = coin; - printf("launch coinloop for.%s services.%llx\n",coin->symbol,(long long)services); + printf("launch.%p coinloop for.%s services.%llx started.%p peers.%p\n",coin,coin->symbol,(long long)services,coin->started,coin->peers); coin->launched = iguana_launch(coin,"iguana_coinloop",iguana_coinloop,coins,IGUANA_PERMTHREAD); coin->active = 1; + coin->started = 0; return(1); } else @@ -882,7 +1045,8 @@ void iguana_coins(void *arg) { struct iguana_info **coins,*coin; char *jsonstr,*symbol; cJSON *array,*item,*json; int32_t i,n,maxpeers,maphash,initialheight,minconfirms,maxrequests,maxbundles; - int64_t maxrecvcache; uint64_t services; struct vin_info V; + int64_t maxrecvcache; uint64_t services; struct vin_info V; struct supernet_info *myinfo; + myinfo = SuperNET_MYINFO(0); memset(&V,0,sizeof(V)); if ( (jsonstr= arg) != 0 && (json= cJSON_Parse(jsonstr)) != 0 ) { @@ -891,7 +1055,7 @@ void iguana_coins(void *arg) if ( (symbol= jstr(json,"coin")) != 0 && strncmp(symbol,"BTC",3) == 0 ) { coins = mycalloc('A',1+1,sizeof(*coins)); - if ( (coins[1]= iguana_setcoin(symbol,coins,0,0,0,0,0,0,0,0,json)) != 0 ) + if ( (coins[1]= iguana_setcoin(symbol,coins,0,0,0,0,0,0,0,0,json,0)) != 0 ) { _iguana_calcrmd160(coins[1],&V); coins[0] = (void *)((long)1); @@ -919,7 +1083,7 @@ void iguana_coins(void *arg) continue; } iguana_coinargs(symbol,&maxrecvcache,&minconfirms,&maxpeers,&initialheight,&services,&maxrequests,&maxbundles,item); - coins[1 + i] = coin = iguana_setcoin(symbol,coins,maxpeers,maxrecvcache,services,initialheight,maphash,minconfirms,maxrequests,maxbundles,item); + coins[1 + i] = coin = iguana_setcoin(symbol,coins,maxpeers,maxrecvcache,services,initialheight,maphash,minconfirms,maxrequests,maxbundles,item,0); if ( coin == 0 ) { printf("iguana_coins: couldnt initialize.(%s)\n",symbol); diff --git a/iguana/iguana777.h b/iguana/iguana777.h index 9c8002e53..7768f23ef 100755 --- a/iguana/iguana777.h +++ b/iguana/iguana777.h @@ -15,951 +15,76 @@ #ifndef iguana777_net_h #define iguana777_net_h -#include "../crypto777/OS_portable.h" -#include "SuperNET.h" - -#define SPARSECOUNT(x) ((x) << 1) - -typedef int32_t (*blockhashfunc)(uint8_t *blockhashp,uint8_t *serialized,int32_t len); -#define IGUANA_MAXSCRIPTSIZE 10001 -#define IGUANA_SERIALIZE_SPENDVECTORGEN -//#define IGUANA_DISABLEPEERS -#define _IGUANA_MAXSTUCKTIME 10 -#ifdef __PNACL__ -#define IGUANA_MAXITERATIONS 77 +#if (defined(_WIN32) || defined(__WIN32__)) && \ +!defined(WIN32) && !defined(__SYMBIAN32__) +#define WIN32 #else -#define IGUANA_MAXITERATIONS 10000 +#ifndef __MINGW +#include #endif -#define IGUANA_DEFAULTLAG 30 - -#define IGUANA_MAXHEIGHT (1 << 30) -#define IGUANA_MAXCOINS 64 -#define IGUANA_MAXDELAY_MILLIS (3600 * 1000) -#define IGUANA_DEFAULT_POLLTIMEOUT 10 - -#define IGUANA_EXCHANGEIDLE 10 -#define IGUANS_JSMILLIS 100 - -#define IGUANA_WIDTH 1024 -#define IGUANA_HEIGHT 200 - -#define IGUANA_HEADPERCENTAGE 0. -#define IGUANA_TAILPERCENTAGE 1.0 -#define IGUANA_MAXPENDHDRS 1 -#define IGUANA_MAXPENDINGREQUESTS 8 -#define IGUANA_PENDINGREQUESTS 500 -#define IGUANA_MINPENDBUNDLES 4 -#define IGUANA_MAXPENDBUNDLES 64 -#ifdef __APPLE__ -#define IGUANA_RPCPORT 7778 -#else -#define IGUANA_RPCPORT 7778 #endif -#define IGUANA_MAXRAMCHAINSIZE ((uint64_t)1024L * 1024L * 1024L * 16) - -#define IGUANA_MAPHASHTABLES 1 -#define IGUANA_DEFAULTRAM 4 -#define IGUANA_MAXRECVCACHE ((int64_t)1024L * 1024 * 1024L) -#define IGUANA_MAXBUNDLES (50000000 / 500) - -#define IGUANA_MINPEERS 24 -#define IGUANA_LOG2MAXPEERS 10 -#define IGUANA_LOG2PACKETSIZE 21 -#define IGUANA_LOG2PEERFILESIZE 23 - -#define IGUANA_MAXPEERS (1 << IGUANA_LOG2MAXPEERS) -#define IGUANA_MAXPACKETSIZE (1 << IGUANA_LOG2PACKETSIZE) -#define IGUANA_PEERFILESIZE (1 << IGUANA_LOG2PEERFILESIZE) -struct iguana_txdatabits { uint64_t addrind:IGUANA_LOG2MAXPEERS,filecount:10,fpos:IGUANA_LOG2PEERFILESIZE,datalen:IGUANA_LOG2PACKETSIZE,isdir:1; }; - -#define IGUANA_MAXFILEITEMS 8192 -#define IGUANA_RECENTPEER (3600 * 24 * 7) - -#define IGUANA_PERMTHREAD 0 -#define IGUANA_CONNTHREAD 1 -#define IGUANA_SENDTHREAD 2 -#define IGUANA_RECVTHREAD 3 -#define IGUANA_HELPERTHREAD 4 -#define IGUANA_EXCHANGETHREAD 5 - -#define IGUANA_DEDICATED_THREADS -#ifdef IGUANA_DEDICATED_THREADS -#define IGUANA_MAXCONNTHREADS IGUANA_MINPEERS -#define IGUANA_MAXSENDTHREADS (IGUANA_MAXPEERS>>2) -#define IGUANA_MAXRECVTHREADS (IGUANA_MAXPEERS>>2) -#else -#define IGUANA_MAXCONNTHREADS 16 -#define IGUANA_MAXSENDTHREADS 16 -#define IGUANA_MAXRECVTHREADS 16 -#endif - -#define IGUANA_SUBDIRDIVISOR 28000 - -#ifdef __PNACL -void PNACL_message(const char* format, ...); -#endif - -extern int32_t IGUANA_NUMHELPERS; - -#ifdef __PNACL -#define printf PNACL_message -#define MS_ASYNC 1 /* Sync memory asynchronously. */ -#define MS_SYNC 4 /* Synchronous memory sync. */ -#else -#define PNACL_message printf -#endif - -#ifndef MSG_NOSIGNAL -#define MSG_NOSIGNAL 0x4000 // Do not generate SIGPIPE -#endif - -#define BIP0031_VERSION 60000 -#define CADDR_TIME_VERSION 31402 -#define MIN_PROTO_VERSION 209 -#define MAX_BLOCK_SIZE 1000000 -#define COINBASE_MATURITY 100 - -#define _IGUANA_HDRSCOUNT 2000 -#define _IGUANA_BLOCKHASHES 500 -#define IGUANA_MAXBUNDLESIZE _IGUANA_HDRSCOUNT - -#define NODE_NETWORK (1 << 0) -#define NODE_GETUTXO (1 << 1) -#define NODE_BLOOM (1 << 2) - -#define PROTOCOL_VERSION 70001 -#define INIT_PROTO_VERSION 209 // initial proto version, to be increased after version/verack negotiation -#define GETHEADERS_VERSION 31800 // In this version, 'getheaders' was introduced. -#define MIN_PEER_PROTO_VERSION GETHEADERS_VERSION // disconnect from peers older than this proto version -// nTime field added to CAddress, starting with this version, if possible, avoid requesting addresses nodes older than this -#define CADDR_TIME_VERSION 31402 -// only request blocks from nodes outside this range of versions -#define NOBLKS_VERSION_START 32000 -#define NOBLKS_VERSION_END 32400 - -#define BIP0031_VERSION 60000 // BIP 0031, pong message, is enabled for all versions AFTER this one -#define MEMPOOL_GD_VERSION 60002 // "mempool" command, enhanced "getdata" behavior starts with this version -#define NO_BLOOM_VERSION 70011 // "filter*" disabled without NODE_BLOOM after and including this version - -#define MSG_TX 1 -#define MSG_BLOCK 2 -#define MSG_FILTERED_BLOCK 3 -#define MSG_BUNDLE_HEADERS 255 -#define MSG_BUNDLE 254 - -#define IGUANA_MAXLOCATORS 64 -#define IGUANA_MAXINV 50000 - -#define IGUANA_VOLATILE 1 -#define IGUANA_ITEMIND_DATA 2 -#define IGUANA_MAPPED_ITEM 4 -#define IGUANA_SHA256 0x80 -#define IGUANA_ALLOC_MULT 1.1 -#define IGUANA_ALLOC_INCR 1000 - -#define IGUANA_JSONTIMEOUT 10000 - -#define IGUANA_MAPRECVDATA 1 -#define IGUANA_MAPTXIDITEMS 2 -#define IGUANA_MAPPKITEMS 4 -#define IGUANA_MAPBLOCKITEMS 8 -#define IGUANA_MAPPEERITEMS 16 - -#define IGUANA_PEER_ELIGIBLE 1 -#define IGUANA_PEER_CONNECTING 2 -#define IGUANA_PEER_READY 3 -#define IGUANA_PEER_KILLED 4 - -//#define CHAIN_BTCD 0 -//#define CHAIN_TESTNET3 1 -//#define CHAIN_BITCOIN 2 -//#define CHAIN_VPN 3 - -#define IGUANA_SEARCHBUNDLE 1 -#define IGUANA_SEARCHNOLAST (IGUANA_SEARCHBUNDLE | 2) -#define IGUANA_SEARCHPREV 4 -#define IGUANA_SEARCHNEXT 8 -#define IGUANA_SEARCHALL (IGUANA_SEARCHBUNDLE | IGUANA_SEARCHPREV | IGUANA_SEARCHNEXT) - - -typedef void (*iguana_func)(void *); -struct iguana_thread -{ - struct queueitem DL; - pthread_t handle; - struct iguana_info *coin; - char name[16]; - uint8_t type; - iguana_func funcp; - void *arg; -}; - -struct iguana_blockreq { struct queueitem DL; bits256 hash2,*blockhashes; struct iguana_bundle *bp; int32_t n,height,bundlei; }; - -struct iguana_peermsgrequest { struct queueitem DL; struct iguana_peer *addr; bits256 hash2; int32_t type; }; - -struct iguana_chain -{ - //const int32_t chain_id; - char name[32],symbol[8],messagemagic[64]; - uint8_t pubtype,p2shtype,wiftype,netmagic[4]; - char *genesis_hash,*genesis_hex; // hex string - uint16_t portp2p,rpcport; - uint8_t hastimestamp,unitval; - uint64_t rewards[512][2]; - uint8_t genesis_hashdata[32],minconfirms; - uint16_t ramchainport,bundlesize,hasheaders; - char gethdrsmsg[16]; - uint64_t txfee,minoutput,dust; - blockhashfunc hashalgo; - char userhome[512],serverport[128],userpass[1024]; - char use_addmultisig,do_opreturn; - int32_t estblocktime; -}; - -struct iguana_msgaddress { uint32_t nTime; uint64_t nServices; uint8_t ip[16]; uint16_t port; } __attribute__((packed)); - -struct iguana_msgversion -{ - uint32_t nVersion; - uint64_t nServices; - int64_t nTime; - struct iguana_msgaddress addrTo,addrFrom; - uint64_t nonce; - char strSubVer[80]; - uint32_t nStartingHeight; - uint8_t relayflag; -} __attribute__((packed)); - -struct iguana_VPNversion -{ - uint32_t nVersion; - uint64_t nServices; - int64_t nTime; - struct iguana_msgaddress addrTo,addrFrom; - uint64_t nonce; - char strSubVer[80]; - uint32_t nStartingHeight; - uint32_t iVer,v_Network_id; uint16_t wPort; uint8_t bIsGui; uint16_t wCtPort,wPrPort; -} __attribute__((packed)); - -struct iguana_msgblockhdr -{ - uint32_t version; - bits256 prev_block,merkle_root; - uint32_t timestamp,bits,nonce; -} __attribute__((packed)); - -struct iguana_msgblock -{ - struct iguana_msgblockhdr H; // double hashed for blockhash - uint32_t txn_count; -} __attribute__((packed)); - -struct iguana_msgvin { bits256 prev_hash; uint8_t *vinscript,*spendscript,*redeemscript; uint32_t prev_vout,sequence; uint16_t scriptlen,p2shlen,suffixlen,spendlen; } __attribute__((packed)); - -struct iguana_msgvout { uint64_t value; uint32_t pk_scriptlen; uint8_t *pk_script; } __attribute__((packed)); - -struct iguana_msgtx -{ - uint32_t version,tx_in,tx_out,lock_time; - struct iguana_msgvin *vins; - struct iguana_msgvout *vouts; - bits256 txid; - int32_t allocsize,timestamp; -} __attribute__((packed)); - -struct iguana_packet { struct queueitem DL; struct iguana_peer *addr; struct tai embargo; int32_t datalen,getdatablock; uint8_t serialized[]; }; - -struct msgcounts { uint32_t version,verack,getaddr,addr,inv,getdata,notfound,getblocks,getheaders,headers,tx,block,mempool,ping,pong,reject,filterload,filteradd,filterclear,merkleblock,alert; }; - -struct iguana_fileitem { bits256 hash2; struct iguana_txdatabits txdatabits; }; - -struct iguana_kvitem { UT_hash_handle hh; uint8_t keyvalue[]; };// __attribute__((packed)); - -struct iguana_iAddr -{ - UT_hash_handle hh; uint64_t ipbits; - uint32_t lastkilled,lastconnect; - int32_t status,height,numkilled,numconnects; -}; - -struct iguana_cacheptr { struct queueitem DL; int32_t allocsize,recvlen; uint8_t *data; }; - -// iguana blocks -struct iguana_blockRO -{ - bits256 hash2,prev_block,merkle_root; - uint32_t timestamp,nonce,bits,version; - uint32_t firsttxidind,firstvin,firstvout,firstpkind,firstexternalind,recvlen:24,tbd:8; - uint16_t txn_count,numvouts,numvins,extra; -}; - -struct iguana_block -{ - struct iguana_blockRO RO; - double PoW; // NOT consensus safe, for estimation purposes only - int32_t height,fpos; uint32_t fpipbits,issued,lag:20,peerid:12; - uint16_t hdrsi:15,mainchain:1,bundlei:11,valid:1,queued:1,txvalid:1,newtx:1,processed:1; - UT_hash_handle hh; struct iguana_bundlereq *req; //void *serdata; -} __attribute__((packed)); - - -#define IGUANA_LHASH_BLOCKS 0 -#define IGUANA_LHASH_TXIDS 1 // -#define IGUANA_LHASH_UNSPENTS 2 // -#define IGUANA_LHASH_SPENDS 3 // -#define IGUANA_LHASH_PKHASHES 4 // -#define IGUANA_LHASH_ACCOUNTS 5 // -#define IGUANA_LHASH_EXTERNALS 6 // -#define IGUANA_LHASH_KSPACE 7 // -#define IGUANA_LHASH_TXBITS 8 // -#define IGUANA_LHASH_PKBITS 9 // -#define IGUANA_NUMLHASHES (IGUANA_LHASH_PKBITS + 1) - -struct iguana_counts -{ - uint32_t firsttxidind,firstunspentind,firstspendind,firstpkind; - //bits256 lhashes[IGUANA_NUMAPPENDS],ledgerhash; struct sha256_vstate states[IGUANA_NUMAPPENDS]; - //bits256 blockhash,merkle_root; - uint64_t credits,debits; - //uint32_t timestamp,height; - //struct iguana_prevdep dep; - struct iguana_block block; -} __attribute__((packed)); - -struct iguana_blocks -{ - char coin[8]; - struct iguanakv *db; - struct iguana_block *hash; struct iguana_blockRO *RO; int32_t maxbits; - int32_t maxblocks,initblocks,hashblocks,issuedblocks,recvblocks,emitblocks,parsedblocks,dirty; - struct iguana_block hwmchain; -}; - -struct iguana_ledger -{ - struct iguana_counts snapshot; - //struct iguana_account accounts[]; -} __attribute__((packed)); -// ramchain temp file structures -struct iguana_unspent20 { uint64_t value; uint32_t scriptpos,txidind:28,type:4; uint16_t scriptlen,fileid; uint8_t rmd160[20]; } __attribute__((packed)); -struct iguana_spend256 { bits256 prevhash2; uint64_t scriptpos:48,vinscriptlen:16; uint32_t sequenceid; int16_t prevout; uint16_t spendind,fileid; } __attribute__((packed)); +//#define BTC2_VERSION +#define BTC2_HARDFORK_HEIGHT 444444 +#define BTC2_SIGHASH_FORKID 0xcf +#define BTC2_NETMAGIC 0xaabbccdd +#define BTC2_DEFAULT_PORT 8222 +#define BTC2_DIFF_WINDOW 60 -// permanent readonly structs -struct iguana_txid { bits256 txid; uint32_t txidind:29,firstvout:28,firstvin:28,bundlei:11,locktime,version,timestamp,extraoffset; uint16_t numvouts,numvins; } __attribute__((packed)); +struct supernet_info; +struct exchange_info; -struct iguana_unspent { uint64_t value; uint32_t txidind,pkind,prevunspentind,scriptpos; uint16_t scriptlen,hdrsi; uint16_t fileid:11,type:5; int16_t vout; } __attribute__((packed)); - -struct iguana_spend { uint64_t scriptpos:48,scriptlen:16; uint32_t spendtxidind,sequenceid; int16_t prevout; uint16_t fileid:15,external:1; } __attribute__((packed)); // numsigs:4,numpubkeys:4,p2sh:1,sighash:4 - -struct iguana_pkhash { uint8_t rmd160[20]; uint32_t pkind; } __attribute__((packed)); //firstunspentind,pubkeyoffset - -// dynamic -struct iguana_account { int64_t total; uint32_t lastunspentind; } __attribute__((packed)); -struct iguana_utxo { uint32_t fromheight:31,lockedflag:1,prevunspentind:31,spentflag:1; } __attribute__((packed)); -struct iguana_hhaccount { UT_hash_handle hh; uint64_t pval; struct iguana_account a; } __attribute__((packed)); -struct iguana_hhutxo { UT_hash_handle hh; uint64_t uval; struct iguana_utxo u; } __attribute__((packed)); - -// GLOBAL one zero to non-zero write (unless reorg) -struct iguana_spendvector { uint64_t value; uint32_t pkind,unspentind; int32_t fromheight; uint16_t hdrsi:15,tmpflag:1; } __attribute__((packed)); // unspentind -//struct iguana_pkextra { uint32_t firstspendind; } __attribute__((packed)); // pkind - -struct iguana_txblock -{ - uint32_t numtxids,numunspents,numspends,extralen,recvlen; - // following set during second pass (still in peer context) - uint32_t numpkinds,numexternaltxids,datalen,pkoffset; - uint8_t space[256]; // order: extra[], T, U, S, P, external txids - struct iguana_block block; -}; - -#define RAMCHAIN_PTR(rdata,offset) ((void *)(long)((long)(rdata) + (long)(rdata)->offset)) -struct iguana_ramchaindata -{ - bits256 sha256; - bits256 lhashes[IGUANA_NUMLHASHES],firsthash2,prevhash2; - int64_t allocsize,Boffset,Toffset,Uoffset,Soffset,Poffset,Aoffset,Xoffset,TXoffset,PKoffset,Koffset; - int32_t numblocks,height,firsti,hdrsi,txsparsebits,pksparsebits; - uint32_t numtxids,numunspents,numspends,numpkinds,numexternaltxids,numtxsparse,numpksparse,scriptspace,stackspace; - uint8_t rdata[]; -}; - -struct iguana_ramchain_hdr -{ - uint32_t txidind,unspentind,spendind,scriptoffset,stacksize; uint16_t hdrsi,bundlei:15,ROflag:1; - struct iguana_ramchaindata *data; -}; - -struct iguana_ramchain -{ - struct iguana_ramchain_hdr H; bits256 lasthash2; uint64_t datasize,allocatedA2,allocatedU2; - uint32_t numblocks:31,expanded:1,pkind,externalind,height,numXspends; - long sparseadds,sparsesearches,sparseadditers,sparsesearchiters,sparsehits,sparsemax; - struct iguana_kvitem *txids,*pkhashes; - struct OS_memspace *hashmem; long filesize,sigsfilesize,debitsfilesize,lastspendsfilesize; - void *fileptr,*sigsfileptr,*Xspendptr,*debitsfileptr,*lastspendsfileptr; - char from_ro,from_roX,from_roA,from_roU; - struct iguana_account *A,*A2,*creditsA; struct iguana_spendvector *Xspendinds; - struct iguana_utxo *Uextras; uint8_t *txbits; struct iguana_txid *cacheT; - //int16_t permutation[IGUANA_MAXBUNDLES]; -//struct iguana_Uextra *U2,*roU2; struct iguana_pkextra *P2,*roP2; -}; - -struct iguana_peer -{ - struct queueitem DL; - queue_t sendQ; - bits256 iphash,pubkey,sharedseed,persistent; uint32_t lastpersist; - struct iguana_msgaddress A; - char ipaddr[64],lastcommand[16],coinstr[16],symbol[16]; - uint64_t pingnonce,totalsent,totalrecv,ipbits; double pingtime,sendmillis,pingsum,getdatamillis; - uint32_t lastcontact,sendtime,ready,startsend,startrecv,pending,lastgotaddr,lastblockrecv,pendtime,lastflush,lastpoll,myipbits,persistent_peer,protover; - int32_t supernet,dead,addrind,usock,lastheight,relayflag,numpackets,numpings,ipv6,height,rank,pendhdrs,pendblocks,recvhdrs,lastlefti,validpub,othervalid,dirty[2],laggard; - double recvblocks,recvtotal; - int64_t allocated,freed; - bits256 RThashes[IGUANA_MAXBUNDLESIZE]; int32_t numRThashes; - struct msgcounts msgcounts; - struct OS_memspace RAWMEM,TXDATA,HASHMEM; - struct iguana_ramchain ramchain; - struct iguana_fileitem *filehash2; int32_t numfilehash2,maxfilehash2; - //struct iguana_bundle *bp; - FILE *voutsfp,*vinsfp; - uint8_t *blockspace;//[IGUANA_MAXPACKETSIZE + 8192]; -#ifdef IGUANA_PEERALLOC - struct OS_memspace *SEROUT[128]; -#endif -}; - -struct iguana_peers -{ - bits256 lastrequest; - struct iguana_peer active[IGUANA_MAXPEERS+1],*ranked[IGUANA_MAXPEERS+1],*localaddr; - struct iguana_thread *peersloop,*recvloop; pthread_t *acceptloop; - double topmetrics[IGUANA_MAXPEERS+1],avemetric; - long vinptrs[IGUANA_MAXPEERS+1][2],voutptrs[IGUANA_MAXPEERS+1][2]; - uint32_t numranked,mostreceived,shuttingdown,lastpeer,lastmetrics,numconnected; - int32_t numfiles; -}; - -struct iguana_bloom16 { uint8_t hash2bits[65536 / 8]; }; -struct iguana_bloominds { uint16_t inds[8]; }; - -struct iguana_bundle -{ - struct queueitem DL; struct iguana_info *coin; struct iguana_bundle *nextbp; - struct iguana_bloom16 bloom; int64_t totaldurations,duplicatedurations; int32_t durationscount,duplicatescount; - uint32_t issuetime,hdrtime,emitfinish,mergefinish,purgetime,queued,startutxo,utxofinish,balancefinish,validated,lastspeculative,dirty,nexttime,currenttime,lastprefetch,lastRT,missingstime,unsticktime,converted; - int32_t numhashes,numrecv,numsaved,numcached,generrs,currentflag,origmissings,numissued,Xvalid; - int32_t minrequests,n,hdrsi,bundleheight,numtxids,numspends,numunspents,numspec,isRT; - double avetime,threshold,metric; uint64_t datasize,estsize; - struct iguana_block *blocks[IGUANA_MAXBUNDLESIZE]; - uint8_t *speculativecache[IGUANA_MAXBUNDLESIZE],haveblock[IGUANA_MAXBUNDLESIZE/3+1]; - uint32_t issued[IGUANA_MAXBUNDLESIZE]; - bits256 prevbundlehash2,hashes[IGUANA_MAXBUNDLESIZE+1],nextbundlehash2,allhash,*speculative,validatehash; - struct iguana_ramchain ramchain; uint8_t red,green,blue; - struct iguana_spendvector *tmpspends; int32_t numtmpspends; -}; - -struct iguana_bundlereq -{ - struct queueitem DL; struct iguana_info *coin; int32_t type; - struct iguana_peer *addr; struct iguana_block *blocks,block; bits256 *hashes,txid; - struct iguana_txdatabits txdatabits; - struct iguana_msghdr H; - int32_t allocsize,datalen,n,recvlen,numtx; uint32_t ipbits; - uint8_t copyflag,serialized[]; -}; - -struct iguana_bitmap { int32_t width,height,amplitude; char name[52]; uint8_t data[IGUANA_WIDTH*IGUANA_HEIGHT*3]; }; - -struct iguana_waddress { UT_hash_handle hh; uint64_t balance,*unspents; uint32_t maxunspents,numunspents; uint16_t scriptlen; uint8_t rmd160[20],pubkey[33],wiftype,addrtype; bits256 privkey; char symbol[8],coinaddr[36],wifstr[54]; uint8_t redeemScript[]; }; -struct iguana_waccount { UT_hash_handle hh; char account[128]; struct iguana_waddress *waddr,*current; }; -struct iguana_wallet { UT_hash_handle hh; struct iguana_waccount *wacct; }; - -struct scriptinfo { UT_hash_handle hh; uint32_t fpos; uint16_t scriptlen; uint8_t script[]; }; -struct hhbits256 { UT_hash_handle hh; bits256 txid; int32_t height; uint16_t firstvout; }; - -struct iguana_info -{ - char name[64],symbol[8],statusstr[512],scriptsfname[2][512]; - struct iguana_peers peers; struct iguana_peer internaladdr; - uint32_t fastfind; FILE *fastfps[0x100]; uint8_t *fast[0x100]; int32_t *fasttables[0x100]; long fastsizes[0x100]; - uint64_t instance_nonce,myservices,totalsize,totalrecv,totalpackets,sleeptime; - int64_t mining,totalfees,TMPallocated,MAXRECVCACHE,MAXMEM,PREFETCHLAG,estsize,activebundles; - int32_t MAXPEERS,MAXPENDINGREQUESTS,MAXBUNDLES,MAXSTUCKTIME,active,closestbundle,numemitted,lastsweep,numemit,startutc,newramchain,numcached,cachefreed,helperdepth,startPEND,endPEND,enableCACHE,RELAYNODE,VALIDATENODE,origbalanceswritten,balanceswritten,RTheight,RTdatabad; - bits256 balancehash,allbundles; - uint32_t lastsync,parsetime,numiAddrs,lastpossible,bundlescount,savedblocks,backlog,spendvectorsaved,laststats; char VALIDATEDIR[512]; - int32_t longestchain,badlongestchain,longestchain_strange,RTramchain_busy,emitbusy,stuckiters; - struct tai starttime; double startmillis; - struct iguana_chain *chain; - struct iguana_iAddr *iAddrs; +#include "../crypto777/OS_portable.h" +#include "../datachain/datachain.h" + +#include "../includes/iguana_defines.h" +#include "../includes/iguana_types.h" +#include "../includes/iguana_structs.h" +#include "../includes/iguana_funcs.h" +#include "../includes/iguana_globals.h" +#include "../basilisk/basilisk.h" +#include "../gecko/gecko.h" + + +struct supernet_address +{ + bits256 pubkey,iphash,persistent; + uint32_t selfipbits,myipbits; int32_t confirmed,totalconfirmed; uint64_t nxt64bits; + char NXTADDR[32],BTC[64],BTCD[64]; +}; + +struct liquidity_info { char base[64],rel[64]; double profit,refprice; }; +struct message_info { int32_t msgcount; bits256 refhash,msghashes[64]; uint32_t timestamps[64]; }; + +struct supernet_info +{ + struct supernet_address myaddr; + bits256 persistent_priv,privkey; + uint8_t persistent_pubkey33[33]; + char ipaddr[64],NXTAPIURL[512],secret[4096],password[4096],rpcsymbol[64],handle[1024],permanentfile[1024]; + char *decryptstr; + int32_t maxdelay,IAMRELAY,IAMLP,publicRPC,basilisk_busy,genesisresults; + uint32_t expiration,dirty,DEXactive; + uint16_t argport,rpcport; + struct basilisk_info basilisks; + struct exchange_info *tradingexchanges[SUPERNET_MAXEXCHANGES]; int32_t numexchanges; + struct iguana_waccount *wallet; + struct iguana_info *allcoins; int32_t allcoins_being_added,allcoins_numvirts; + portable_mutex_t bu_mutex,allcoins_mutex,gecko_mutex,basilisk_mutex,DEX_mutex,DEX_reqmutex,DEX_swapmutex; + struct queueitem *DEX_quotes; + struct basilisk_swap *swaps[256]; int32_t numswaps; + struct basilisk_message *messagetable; portable_mutex_t messagemutex; queue_t msgQ; void *ctx; - struct iguana_bitmap screen; - //struct pollfd fds[IGUANA_MAXPEERS]; struct iguana_peer bindaddr; int32_t numsocks; - struct OS_memspace TXMEM,MEM,MEMB[IGUANA_MAXBUNDLESIZE]; - queue_t acceptQ,hdrsQ,blocksQ,priorityQ,possibleQ,cacheQ,recvQ,msgrequestQ; - double parsemillis,avetime; uint32_t Launched[8],Terminated[8]; - portable_mutex_t peers_mutex,blocks_mutex; - //portable_mutex_t scripts_mutex[2]; FILE *scriptsfp[2]; void *scriptsptr[2]; long scriptsfilesize[2]; - //struct scriptinfo *scriptstable[2]; - struct iguana_bundle *bundles[IGUANA_MAXBUNDLES],*current,*lastpending; - struct iguana_ramchain RTramchain; struct OS_memspace RTmem,RThashmem; bits256 RThash1; - int32_t numremain,numpendings,zcount,recvcount,bcount,pcount,lastbundle,numsaved,pendbalances,numverified,blockdepth; - uint32_t recvtime,hdrstime,backstoptime,lastbundletime,numreqsent,numbundlesQ,lastbundleitime,lastdisp,RTgenesis,RTstarti,idletime,stucktime,stuckmonitor,maxstuck,lastreqtime,RThdrstime; - double bandwidth,maxbandwidth,backstopmillis; bits256 backstophash2; int64_t spaceused; - int32_t initialheight,mapflags,minconfirms,numrecv,bindsock,isRT,backstop,blocksrecv,merging,polltimeout,numreqtxids,allhashes,balanceflush; bits256 reqtxids[64]; - void *launched,*started,*rpcloop; - uint64_t bloomsearches,bloomhits,bloomfalse,collisions,txfee_perkb; - uint8_t blockspace[IGUANA_MAXPACKETSIZE + 8192]; struct OS_memspace blockMEM; - struct iguana_blocks blocks; bits256 APIblockhash,APItxid; char *APIblockstr; - struct iguana_hhutxo *utxotable; struct iguana_hhaccount *accountstable; char lastdispstr[2048]; - double txidfind_totalmillis,txidfind_num,spendtxid_totalmillis,spendtxid_num; + uint8_t *pingbuf; + struct delayedPoW_info dPoW; + struct basilisk_spend *spends; int32_t numspends; + struct peggy_info *PEGS; + struct liquidity_info linfos[64]; + // compatibility + bits256 pangea_category,instantdex_category; + uint8_t logs[256],exps[510]; + struct message_info msgids[8192]; }; -struct vin_signer { bits256 privkey; char coinaddr[64]; uint8_t siglen,sig[80],rmd160[20],pubkey[66]; }; - -struct vin_info -{ - struct iguana_msgvin vin; uint64_t amount; cJSON *extras; bits256 sigtxid; - int32_t M,N,validmask,spendlen,type,p2shlen,suffixlen,numpubkeys,numsigs,height,hashtype; - uint32_t sequence,unspentind; struct vin_signer signers[16]; char coinaddr[65]; - uint8_t rmd160[20],spendscript[IGUANA_MAXSCRIPTSIZE],p2shscript[IGUANA_MAXSCRIPTSIZE]; -}; - -struct bitcoin_unspent -{ - bits256 txid,privkeys[16]; uint64_t value; int32_t vout,spendlen,p2shlen,numpubkeys; uint32_t sequence; - uint8_t addrtype,rmd160[20],pubkeys[16][65],spendscript[IGUANA_MAXSCRIPTSIZE],p2shscript[IGUANA_MAXSCRIPTSIZE]; -}; - -struct bitcoin_spend -{ - char changeaddr[64]; uint8_t change160[20]; - int32_t numinputs; - int64_t txfee,input_satoshis,satoshis,change; - struct bitcoin_unspent inputs[]; -}; - -// peers -int32_t iguana_verifypeer(struct iguana_info *coin,void *key,void *value,int32_t itemind,int32_t itemsize); -int32_t iguana_peermetrics(struct iguana_info *coin); -void iguana_peersloop(void *arg); -int32_t iguana_queue_send(struct iguana_info *coin,struct iguana_peer *addr,int32_t delay,uint8_t *serialized,char *cmd,int32_t len,int32_t getdatablock,int32_t forceflag); -uint32_t iguana_rwiAddrind(struct iguana_info *coin,int32_t rwflag,struct iguana_iAddr *iA,uint32_t ind); -void iguana_connections(void *arg); -uint32_t iguana_possible_peer(struct iguana_info *coin,char *ip_port); -//int32_t iguana_set_iAddrheight(struct iguana_info *coin,uint32_t ipbits,int32_t height); -//struct iguana_peer *iguana_choosepeer(struct iguana_info *coin); -void iguana_initpeer(struct iguana_info *coin,struct iguana_peer *addr,uint64_t ipbits); -void iguana_startconnection(void *arg); -void iguana_shutdownpeers(struct iguana_info *coin,int32_t forceflag); -void iguana_acceptloop(void *args); -void iguana_recvloop(void *args); -int32_t iguana_send(struct iguana_info *coin,struct iguana_peer *addr,uint8_t *serialized,int32_t len); -uint32_t iguana_updatemetrics(struct iguana_info *coin); -void *iguana_peeralloc(struct iguana_info *coin,struct iguana_peer *addr,int32_t datalen); -int64_t iguana_peerfree(struct iguana_info *coin,struct iguana_peer *addr,void *ptr,int32_t datalen); -int64_t iguana_peerallocated(struct iguana_info *coin,struct iguana_peer *addr); - -// serdes -int32_t iguana_rwmem(int32_t rwflag,uint8_t *serialized,int32_t len,void *endianedp); -int32_t iguana_rwnum(int32_t rwflag,uint8_t *serialized,int32_t len,void *endianedp); -int32_t iguana_rwvarint32(int32_t rwflag,uint8_t *serialized,uint32_t *int32p); -int32_t iguana_rwbignum(int32_t rwflag,uint8_t *serialized,int32_t len,uint8_t *endianedp); -int32_t iguana_rwblock(int32_t rwflag,bits256 *hash2p,uint8_t *serialized,struct iguana_msgblock *msg); -int32_t iguana_serialize_block(bits256 *hash2p,uint8_t serialized[sizeof(struct iguana_msgblock)],struct iguana_block *block); -void iguana_blockconv(struct iguana_block *dest,struct iguana_msgblock *msg,bits256 hash2,int32_t height); -//void iguana_freetx(struct iguana_msgtx *tx,int32_t n); -int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struct OS_memspace *rawmem,struct OS_memspace *txmem,struct OS_memspace *hashmem,struct iguana_msghdr *H,uint8_t *data,int32_t datalen); - -// send message -int32_t iguana_validatehdr(char *symbol,struct iguana_msghdr *H); -int32_t iguana_sethdr(struct iguana_msghdr *H,const uint8_t netmagic[4],char *command,uint8_t *data,int32_t datalen); -int32_t iguana_send_version(struct iguana_info *coin,struct iguana_peer *addr,uint64_t myservices); -int32_t iguana_gentxarray(struct iguana_info *coin,struct OS_memspace *mem,struct iguana_txblock *txblock,int32_t *lenp,uint8_t *data,int32_t datalen); -int32_t iguana_gethdrs(struct iguana_info *coin,uint8_t *serialized,char *cmd,char *hashstr); -int32_t iguana_getdata(struct iguana_info *coin,uint8_t *serialized,int32_t type,bits256 *hashes,int32_t n); -void iguana_blockunconv(struct iguana_msgblock *msg,struct iguana_block *src,int32_t cleartxn_count); -int32_t iguana_peerblockrequest(struct iguana_info *coin,uint8_t *blockspace,int32_t max,struct iguana_peer *addr,bits256 hash2,int32_t validatesigs); -int32_t iguana_validatesigs(struct iguana_info *coin,struct iguana_msgvin *vin); - -// ramchain -int64_t iguana_verifyaccount(struct iguana_info *coin,struct iguana_account *acct,uint32_t pkind); -int32_t iguana_initramchain(struct iguana_info *coin,int32_t initialheight,int32_t mapflags,int32_t fullverify); -void iguana_syncramchain(struct iguana_info *coin); -//int32_t iguana_validateramchain(struct iguana_info *coin,int64_t *netp,uint64_t *creditsp,uint64_t *debitsp,int32_t height,struct iguana_block *block,int32_t hwmheight,struct iguana_prevdep *lp); -int32_t iguana_calcrmd160(struct iguana_info *coin,char *asmstr,struct vin_info *vp,uint8_t *pk_script,int32_t pk_scriptlen,bits256 debugtxid,int32_t vout,uint32_t sequence); -uint32_t iguana_updatescript(struct iguana_info *coin,uint32_t blocknum,uint32_t txidind,uint32_t spendind,uint32_t unspentind,uint64_t value,uint8_t *script,int32_t scriptlen,uint32_t sequence); -void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_txblock *txdata,struct iguana_msgtx *txarray,struct iguana_msghdr *H,uint8_t *data,int32_t datalen); -int32_t iguana_parseblock(struct iguana_info *coin,struct iguana_block *block,struct iguana_msgtx *tx,int32_t numtx); -uint32_t iguana_txidind(struct iguana_info *coin,uint32_t *firstvoutp,uint32_t *firstvinp,bits256 txid); -bits256 iguana_txidstr(struct iguana_info *coin,uint32_t *firstvoutp,uint32_t *firstvinp,char *txidstr,uint32_t txidind); -int32_t iguana_updateramchain(struct iguana_info *coin); -//void iguana_emittxarray(struct iguana_info *coin,FILE *fp,struct iguana_bundle *bundle,struct iguana_block *block,struct iguana_msgtx *txarray,int32_t numtx); - -// blockchain -int32_t iguana_needhdrs(struct iguana_info *coin); -struct iguana_chain *iguana_chainfind(char *name,cJSON *argjson,int32_t createflag); -int32_t iguana_chainextend(struct iguana_info *coin,struct iguana_block *newblock); -uint64_t iguana_miningreward(struct iguana_info *coin,uint32_t blocknum); - -// tx -int32_t iguana_rwtx(int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized,struct iguana_msgtx *msg,int32_t maxsize,bits256 *txidp,int32_t hastimestamp,int32_t isvpncoin); -void iguana_gottxidsM(struct iguana_info *coin,struct iguana_peer *addr,bits256 *txids,int32_t n); -void iguana_gotunconfirmedM(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_msgtx *tx,uint8_t *data,int32_t datalen); -void iguana_gotblockhashesM(struct iguana_info *coin,struct iguana_peer *addr,bits256 *blockhashes,int32_t n); - -// blocks -bits256 iguana_blockhash(struct iguana_info *coin,int32_t height); -#define iguana_blockfind(str,coin,hash2) iguana_blockhashset(str,coin,-1,hash2,0) -struct iguana_block *iguana_blockhashset(char *debugstr,struct iguana_info *coin,int32_t height,bits256 hash2,int32_t createflag); - -uint32_t iguana_syncs(struct iguana_info *coin); -void iguana_gotdata(struct iguana_info *coin,struct iguana_peer *addr,int32_t height); -//int64_t iguana_getbalance(struct iguana_info *coin,uint64_t *creditsp,uint64_t *debitsp,int32_t *nump,uint32_t *unspents,long max,struct iguana_pkhash *P,uint32_t pkind); -int32_t iguana_queueblock(struct iguana_info *coin,int32_t height,bits256 hash2,int32_t priority); -int32_t iguana_updatewaiting(struct iguana_info *coin,int32_t starti,int32_t max); - -// recvbits -int32_t iguana_recvinit(struct iguana_info *coin,int32_t initialheight); -int32_t ramcoder_decompress(uint8_t *data,int32_t maxlen,uint8_t *bits,uint32_t numbits,bits256 seed); -int32_t ramcoder_compress(uint8_t *bits,int32_t maxlen,uint8_t *data,int32_t datalen,bits256 seed); -uint64_t hconv_bitlen(uint64_t bitlen); -struct iguana_block *iguana_blockptr(char *debugstr,struct iguana_info *coin,int32_t height); -int32_t iguana_processrecv(struct iguana_info *coin); // single threaded -void iguana_recvalloc(struct iguana_info *coin,int32_t numitems); -void iguana_coins(void *arg); -int32_t iguana_savehdrs(struct iguana_info *coin); - -// hdrs -struct iguana_bundle *iguana_bundlecreate(struct iguana_info *coin,int32_t *bundleip,int32_t bundleheight,bits256 bundlehash2,bits256 allhash,int32_t issueflag); -struct iguana_block *iguana_updatehdrs(struct iguana_info *coin,int32_t *newhwmp,struct iguana_block *block,bits256 prevhash2,bits256 hash2); -void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp); -void iguana_gotheadersM(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_block *blocks,int32_t n); -void iguana_emittxdata(struct iguana_info *coin,struct iguana_bundle *bp); -int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr); -int32_t iguana_avail(struct iguana_info *coin,int32_t height,int32_t n); -int32_t iguana_updatebundles(struct iguana_info *coin); -void iguana_bundlestats(struct iguana_info *coin,char *str,int32_t lag); - -// init -struct iguana_info *iguana_coinstart(struct iguana_info *coin,int32_t initialheight,int32_t mapflags); -void iguana_initcoin(struct iguana_info *coin,cJSON *argjson); -void iguana_coinloop(void *arg); - -// utils -double PoW_from_compact(uint32_t nBits,uint8_t unitval); -void calc_rmd160(char *hexstr,uint8_t buf[20],uint8_t *msg,int32_t len); -void calc_OP_HASH160(char *hexstr,uint8_t hash160[20],char *msg); -double dxblend(double *destp,double val,double decay); - -// json -int32_t iguana_processjsonQ(struct iguana_info *coin); // reentrant, can be called during any idletime -char *iguana_JSON(char *,uint16_t port); -char *SuperNET_p2p(struct iguana_info *coin,struct iguana_peer *addr,int32_t *delaymillisp,char *ipaddr,uint8_t *data,int32_t datalen,int32_t compressed); - -char *mbstr(char *str,double); -int init_hexbytes_noT(char *hexbytes,unsigned char *message,long len); -int32_t decode_hex(unsigned char *bytes,int32_t n,char *hex); -char hexbyte(int32_t c); -char *clonestr(char *str); -long _stripwhite(char *buf,int accept); -int32_t myatoi(char *str,int32_t range); -int32_t safecopy(char *dest,char *src,long len); -void escape_code(char *escaped,char *str); -int32_t is_zeroes(char *str); -int64_t conv_floatstr(char *numstr); -int32_t has_backslash(char *str); - -struct iguana_thread *iguana_launch(struct iguana_info *coin,char *name,iguana_func funcp,void *arg,uint8_t type); -int32_t iguana_numthreads(struct iguana_info *coin,int32_t mask); -void iguana_terminator(void *arg); - -int32_t is_hexstr(char *str,int32_t n); -void iguana_initQ(queue_t *Q,char *name); -void iguana_emitQ(struct iguana_info *coin,struct iguana_bundle *bp); -void iguana_txdataQ(struct iguana_info *coin,struct iguana_peer *addr,FILE *fp,long fpos,int32_t datalen); -void iguana_helper(void *arg); - -struct iguana_helper { struct queueitem DL; void *coin,*addr,*bp,*nextbp,*fp; long fpos; int32_t allocsize,type,hdrsi,bundlei,datalen,timelimit; uint32_t starttime; }; -int32_t iguana_helpertask(FILE *fp,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_helper *ptr); -void iguana_flushQ(struct iguana_info *coin,struct iguana_peer *addr); -//struct iguana_txdatabits iguana_peerfilePT(struct iguana_info *coin,struct iguana_peer *addr,bits256 hash2,struct iguana_txdatabits txdatabits,int32_t recvlen); -struct iguana_txdatabits iguana_calctxidbits(uint32_t addrind,uint32_t filecount,uint32_t fpos,uint32_t datalen); -int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_bundle *bp,uint32_t starttime); // helper thread -int32_t iguana_bundlemergeHT(char *fname,struct iguana_info *coin,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_bundle *bp,struct iguana_bundle *nextbp,uint32_t starttime); // helper thread - -void iguana_peerfilename(struct iguana_info *coin,char *fname,uint32_t addrind,uint32_t filecount); - -struct iguana_txblock *iguana_ramchainptrs(struct iguana_txid **Tptrp,struct iguana_unspent20 **Uptrp,struct iguana_spend256 **Sptrp,struct iguana_pkhash **Pptrp,bits256 **externalTptrp,struct OS_memspace *mem,struct iguana_txblock *origtxdata); - -int32_t iguana_ramchainsave(struct iguana_info *coin,struct iguana_ramchain *ramchain); -int32_t iguana_ramchainfree(struct iguana_info *coin,struct OS_memspace *mem,struct iguana_ramchain *ramchain); -struct iguana_ramchain *iguana_ramchainmergeHT(struct iguana_info *coin,struct OS_memspace *mem,struct iguana_ramchain *ramchains[],int32_t n,struct iguana_bundle *bp); -void iguana_ramchainmerge(struct iguana_info *coin); - -int32_t iguana_blockQ(char *argstr,struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,int32_t priority); -void iguana_blockcopy(struct iguana_info *coin,struct iguana_block *block,struct iguana_block *origblock); -int32_t iguana_rpctest(struct iguana_info *coin); -extern queue_t helperQ; -extern const char *Hardcoded_coins[][3]; -void iguana_main(void *arg); -extern struct iguana_info *Coins[64]; -int32_t iguana_peerfname(struct iguana_info *coin,int32_t *hdrsip,char *dirname,char *fname,uint32_t ipbits,bits256 hash2,bits256 prevhash2,int32_t numblocks,int32_t dispflag); -struct iguana_txblock *iguana_peertxdata(struct iguana_info *coin,int32_t *bundleip,char *fname,struct OS_memspace *mem,uint32_t ipbits,bits256 hash2); -int32_t iguana_peerfile_exists(struct iguana_info *coin,struct iguana_peer *addr,char *dirname,char *fname,bits256 hash2,bits256 prevhash2,int32_t numblocks); -struct iguana_ramchain *iguana_ramchainset(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct iguana_txblock *txdata); -void *iguana_iAddriterator(struct iguana_info *coin,struct iguana_iAddr *iA); -long iguana_ramchain_data(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_txblock *origtxdata,struct iguana_msgtx *txarray,int32_t txn_count,uint8_t *data,int32_t recvlen); -int32_t iguana_bundlehash2add(struct iguana_info *coin,struct iguana_block **blockp,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2); -struct iguana_block *iguana_bundleblockadd(struct iguana_info *coin,struct iguana_bundle **bpp,int32_t *bundleip,struct iguana_block *origblock); -int32_t iguana_chainextend(struct iguana_info *coin,struct iguana_block *newblock); -int32_t iguana_blockvalidate(struct iguana_info *coin,int32_t *validp,struct iguana_block *block,int32_t dispflag); -char *iguana_bundledisp(struct iguana_info *coin,struct iguana_bundle *prevbp,struct iguana_bundle *bp,struct iguana_bundle *nextbp,int32_t m); -struct iguana_bundle *iguana_bundlefind(struct iguana_info *coin,struct iguana_bundle **bpp,int32_t *bundleip,bits256 hash2); -//int32_t iguana_chainheight(struct iguana_info *coin,struct iguana_block *origblock); -bits256 *iguana_blockhashptr(struct iguana_info *coin,int32_t height); -int32_t iguana_hash2set(struct iguana_info *coin,char *debugstr,struct iguana_bundle *bp,int32_t bundlei,bits256 newhash2); -struct iguana_block *_iguana_chainlink(struct iguana_info *coin,struct iguana_block *newblock); -int32_t iguana_hashfree(struct iguana_kvitem *hashtable,int32_t freeitem); -int32_t iguana_processbundlesQ(struct iguana_info *coin,int32_t *newhwmp); // single threaded -int32_t iguana_ramchainverifyPT(struct iguana_info *coin,struct iguana_ramchain *ramchain); -void *map_file(char *fname,long *filesizep,int32_t enablewrite); -void iguana_rpcloop(void *args); -int32_t iguana_socket(int32_t bindflag,char *hostname,uint16_t port); -void iguana_mergeQ(struct iguana_info *coin,struct iguana_bundle *bp,struct iguana_bundle *nextbp); - -#define bits256_nonz(a) (((a).ulongs[0] | (a).ulongs[1] | (a).ulongs[2] | (a).ulongs[3]) != 0) -//int32_t btc_addr2univ(uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr); - -struct iguana_agent -{ - char name[32],hostname[64]; void *methods; uint16_t port; int32_t sock,nummethods; - bits256 pubkey,privkey; - char *(*parsefunc)(struct iguana_agent *agent,char *method,void *json,char *remoteaddr); -}; - -int32_t iguana_txbytes(struct iguana_info *coin,uint8_t *serialized,int32_t maxlen,bits256 *txidp,struct iguana_txid *tx,int32_t height,struct iguana_msgvin *vins,struct iguana_msgvout *vouts); -int32_t iguana_vinset(struct iguana_info *coin,uint8_t *scriptspace,int32_t height,struct iguana_msgvin *vin,struct iguana_txid *tx,int32_t i); -int32_t iguana_voutset(struct iguana_info *coin,uint8_t *scriptspace,char *asmstr,int32_t height,struct iguana_msgvout *vout,struct iguana_txid *tx,int32_t i); -//int32_t btc_convrmd160(char *coinaddr,uint8_t addrtype,uint8_t rmd160[20]); -struct iguana_txid *iguana_bundletx(struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei,struct iguana_txid *tx,int32_t txidind); -int32_t iguana_txidreq(struct iguana_info *coin,char **retstrp,bits256 txid); -void iguana_bundleiclear(struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei); -int32_t hcalc_bitsize(uint64_t x); -struct iguana_txid *iguana_txidfind(struct iguana_info *coin,int32_t *heightp,struct iguana_txid *tx,bits256 txid,int32_t lasthdrsi); -int32_t iguana_scriptgen(struct iguana_info *coin,int32_t *Mp,int32_t *nump,char *coinaddr,uint8_t *script,char *asmstr,uint8_t rmd160[20],uint8_t type,const struct vin_info *vp,int32_t txi); -int32_t iguana_ramchain_spendtxid(struct iguana_info *coin,uint32_t *unspentindp,bits256 *txidp,struct iguana_txid *T,int32_t numtxids,bits256 *X,int32_t numexternaltxids,struct iguana_spend *s); -struct iguana_info *iguana_coinselect(); -void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr); -struct iguana_peer *iguana_peerslot(struct iguana_info *coin,uint64_t ipbits,int32_t forceflag); -void iguana_dedicatedglue(void *arg); -void SuperNET_remotepeer(struct supernet_info *myinfo,struct iguana_info *coin,char *symbol,char *ipaddr,int32_t supernetflag); -void SuperNET_yourip(struct supernet_info *myinfo,char *yourip); -void iguana_peerkill(struct iguana_info *coin); - -char *busdata_sync(uint32_t *noncep,char *jsonstr,char *broadcastmode,char *destNXTaddr); -void peggy(); -int32_t opreturns_init(uint32_t blocknum,uint32_t blocktimestamp,char *path); -struct iguana_info *iguana_coinfind(const char *symbol); -struct iguana_info *iguana_coinadd(const char *symbol,cJSON *json); -struct iguana_ramchain *iguana_bundleload(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct iguana_bundle *bp,int32_t extraflag); -int32_t iguana_sendblockreq(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,int32_t iamthreadsafe); -int32_t iguana_send_supernet(struct iguana_info *coin,struct iguana_peer *addr,char *jsonstr,int32_t delay); - -struct iguana_waccount *iguana_waccountfind(struct supernet_info *myinfo,struct iguana_info *coin,char *account); -struct iguana_waddress *iguana_waccountadd(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waccount **wacctp,char *walletaccount,char *coinaddr); -struct iguana_waddress *iguana_waccountswitch(struct supernet_info *myinfo,struct iguana_info *coin,char *account,char *coinaddr,char *redeemScript); -struct iguana_waddress *iguana_waddresscalc(struct supernet_info *myinfo,uint8_t pubval,uint8_t wiftype,struct iguana_waddress *addr,bits256 privkey); -struct iguana_waddress *iguana_waddressfind(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waccount *wacct,char *coinaddr); -char *iguana_coinjson(struct iguana_info *coin,char *method,cJSON *json); -cJSON *iguana_peersjson(struct iguana_info *coin,int32_t addronly); -//int32_t btc_priv2wif(char *wifstr,uint8_t privkey[32],uint8_t addrtype); -//int32_t btc_pub2rmd(uint8_t rmd160[20],uint8_t pubkey[33]); -int32_t iguana_launchcoin(struct supernet_info *myinfo,char *symbol,cJSON *json); -int32_t iguana_bundleinitmap(struct iguana_info *coin,struct iguana_bundle *bp,int32_t height,bits256 hash2,bits256 hash1); -int32_t iguana_jsonQ(); -int32_t is_bitcoinrpc(struct supernet_info *myinfo,char *method,char *remoteaddr); -char *iguana_bitcoinRPC(struct supernet_info *myinfo,char *method,cJSON *json,char *remoteaddr,uint16_t port); -cJSON *iguana_pubkeyjson(struct iguana_info *coin,char *pubkeystr); -void iguana_bundleQ(struct iguana_info *coin,struct iguana_bundle *bp,int32_t timelimit); -int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_bundle *bp,int32_t timelimit,int32_t lag); -void ramcoder_test(void *data,int64_t len); -void iguana_exit(); -int32_t iguana_pendingaccept(struct iguana_info *coin); -char *iguana_blockingjsonstr(struct supernet_info *myinfo,char *jsonstr,uint64_t tag,int32_t maxmillis,char *remoteaddr,uint16_t port); -void iguana_iAkill(struct iguana_info *coin,struct iguana_peer *addr,int32_t markflag); -cJSON *SuperNET_bits2json(uint8_t *serialized,int32_t datalen); -int32_t SuperNET_sendmsg(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,bits256 destpub,bits256 mypriv,bits256 mypub,uint8_t *msg,int32_t len,uint8_t *data,int32_t delaymillis); -int32_t category_peer(struct supernet_info *myinfo,struct iguana_peer *addr,bits256 category,bits256 subhash); -int32_t bitcoin_wif2priv(uint8_t *addrtypep,bits256 *privkeyp,char *wifstr); -int32_t bitcoin_priv2wif(char *wifstr,bits256 privkey,uint8_t addrtype); -bits256 iguana_chaingenesis(bits256 genesishash,char *genesisblock,char *hashalgostr,int32_t version,uint32_t timestamp,uint32_t bits,uint32_t nonce,bits256 merkle_root); -int32_t iguana_send_ConnectTo(struct iguana_info *coin,struct iguana_peer *addr); -cJSON *iguana_txjson(struct iguana_info *coin,struct iguana_txid *tx,int32_t height,struct vin_info *V); -char *iguana_txscan(struct iguana_info *coin,cJSON *json,uint8_t *data,int32_t recvlen,bits256 txid); -char *iguana_rawtxbytes(struct iguana_info *coin,cJSON *json,struct iguana_msgtx *msgtx); -int32_t iguana_send_VPNversion(struct iguana_info *coin,struct iguana_peer *addr,uint64_t myservices); -void exchanges777_init(struct supernet_info *myinfo,cJSON *exchanges,int32_t sleepflag); -int32_t iguana_rwvout(int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized,struct iguana_msgvout *msg); -int32_t iguana_rwvin(int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized,struct iguana_msgvin *msg); -int32_t iguana_rwmsgtx(struct iguana_info *coin,int32_t rwflag,cJSON *json,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,bits256 *txidp,char *vpnstr); -int32_t iguana_ramtxbytes(struct iguana_info *coin,uint8_t *serialized,int32_t maxlen,bits256 *txidp,struct iguana_txid *tx,int32_t height,struct iguana_msgvin *vins,struct iguana_msgvout *vouts,int32_t validatesigs); -cJSON *bitcoin_txtest(struct iguana_info *coin,char *rawtxstr,bits256 txid); -cJSON *iguana_blockjson(struct iguana_info *coin,struct iguana_block *block,int32_t txidsflag); -//int32_t iguana_sig(uint8_t *sig,int32_t maxsize,uint8_t *data,int32_t datalen,bits256 privkey); -//int32_t iguana_ver(uint8_t *sig,int32_t siglen,uint8_t *data,int32_t datalen,bits256 pubkey); -//int32_t iguana_ver(uint8_t *sig,int32_t siglen,uint8_t *data,int32_t datalen,uint8_t *pubkey); -void calc_rmd160_sha256(uint8_t rmd160[20],uint8_t *data,int32_t datalen); -int32_t bitcoin_checklocktimeverify(uint8_t *script,int32_t n,uint32_t locktime); -struct bitcoin_spend *iguana_spendset(struct supernet_info *myinfo,struct iguana_info *coin,int64_t satoshis,int64_t insurance,char *account); -cJSON *bitcoin_hex2json(struct iguana_info *coin,bits256 *txidp,struct iguana_msgtx *msgtx,char *txbytes); -cJSON *iguana_signtx(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,char **signedtxp,struct bitcoin_spend *spend,cJSON *txobj,cJSON *vins); -void iguana_addscript(struct iguana_info *coin,cJSON *dest,uint8_t *script,int32_t scriptlen,char *fieldname); - -cJSON *bitcoin_txcreate(struct iguana_info *coin,int64_t locktime); -cJSON *bitcoin_txoutput(struct iguana_info *coin,cJSON *txobj,uint8_t *paymentscript,int32_t len,uint64_t satoshis); -cJSON *bitcoin_txinput(struct iguana_info *coin,cJSON *txobj,bits256 txid,int32_t vout,uint32_t sequenceid,uint8_t *spendscript,int32_t spendlen,uint8_t *redeemscript,int32_t p2shlen,uint8_t *pubkeys[],int32_t numpubkeys); - -int32_t bitcoin_changescript(struct iguana_info *coin,uint8_t *changescript,int32_t n,uint64_t *changep,char *changeaddr,uint64_t inputsatoshis,uint64_t satoshis,uint64_t txfee); -//cJSON *bitcoin_addinput(struct iguana_info *coin,cJSON *txobj,bits256 txid,int32_t vout,uint32_t sequenceid,uint8_t *spendscript,int32_t spendlen,uint8_t *redeemscript,int32_t p2shlen,uint8_t *pubkeys[],int32_t numpubkeys); -int32_t bitcoin_verifytx(struct iguana_info *coin,bits256 *signedtxidp,char **signedtx,char *rawtxstr,struct vin_info *V,int32_t numinputs); -int32_t bitcoin_verify(void *ctx,uint8_t *sig,int32_t siglen,bits256 txhash2,uint8_t *pubkey,int32_t plen); -char *bitcoin_json2hex(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,cJSON *txjson,struct vin_info *V); -int32_t bitcoin_addr2rmd160(uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr); -char *issue_startForging(struct supernet_info *myinfo,char *secret); -struct bitcoin_unspent *iguana_unspentsget(struct supernet_info *myinfo,struct iguana_info *coin,char **retstrp,double *balancep,int32_t *numunspentsp,double minconfirms,char *account); -void iguana_chainparms(struct iguana_chain *chain,cJSON *argjson); -int32_t iguana_pkhasharray(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *array,int32_t minconf,int32_t maxconf,int64_t *totalp,struct iguana_pkhash *P,int32_t max,uint8_t rmd160[20],char *coinaddr,uint8_t *pubkey33,int32_t lastheight,uint64_t *unspents,int32_t *numunspentsp,int32_t maxunspents); -long iguana_spentsfile(struct iguana_info *coin,int32_t n); -uint8_t *iguana_rmdarray(struct iguana_info *coin,int32_t *numrmdsp,cJSON *array,int32_t firsti); -int64_t iguana_unspents(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *array,int32_t minconf,int32_t maxconf,uint8_t *rmdarray,int32_t numrmds,int32_t lastheight,uint64_t *unspents,int32_t *numunspentsp); -uint8_t *iguana_walletrmds(struct supernet_info *myinfo,struct iguana_info *coin,int32_t *numrmdsp); -char *iguana_bundleaddrs(struct iguana_info *coin,int32_t hdrsi); -uint32_t iguana_sparseaddpk(uint8_t *bits,int32_t width,uint32_t tablesize,uint8_t rmd160[20],struct iguana_pkhash *P,uint32_t pkind,struct iguana_ramchain *ramchain); -int32_t iguana_vinscriptparse(struct iguana_info *coin,struct vin_info *vp,uint32_t *sigsizep,uint32_t *pubkeysizep,uint32_t *p2shsizep,uint32_t *suffixp,uint8_t *vinscript,int32_t scriptlen); -void iguana_parsebuf(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_msghdr *H,uint8_t *buf,int32_t len); -int32_t _iguana_calcrmd160(struct iguana_info *coin,struct vin_info *vp); -int32_t iguana_spendvectors(struct iguana_info *coin,struct iguana_bundle *bp,struct iguana_ramchain *ramchain,int32_t starti,int32_t numblocks,int32_t convertflag,int32_t iterate); -int32_t iguana_balancegen(struct iguana_info *coin,int32_t incremental,struct iguana_bundle *bp,int32_t startheight,int32_t endheight,int32_t startemit); -int32_t iguana_bundlevalidate(struct iguana_info *coin,struct iguana_bundle *bp,int32_t forceflag); -void iguana_validateQ(struct iguana_info *coin,struct iguana_bundle *bp); -struct iguana_bloominds iguana_calcbloom(bits256 hash2); -int32_t iguana_bloomfind(struct iguana_info *coin,struct iguana_bloom16 *bloom,int32_t incr,struct iguana_bloominds bit); -struct iguana_bloominds iguana_bloomset(struct iguana_info *coin,struct iguana_bloom16 *bloom,int32_t incr,struct iguana_bloominds bit); -int32_t iguana_Xspendmap(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct iguana_bundle *bp); -//void iguana_balancesQ(struct iguana_info *coin,struct iguana_bundle *bp); -int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi); -int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int32_t starti,int32_t max); -int32_t iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp,int32_t startheight,int32_t endheight); -int32_t iguana_sendblockreqPT(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,int32_t iamthreadsafe); -int32_t iguana_blockreq(struct iguana_info *coin,int32_t height,int32_t priority); -int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp,int32_t lag); -int32_t iguana_ramchain_prefetch(struct iguana_info *coin,struct iguana_ramchain *ramchain,int32_t txonly); -int32_t iguana_realtime_update(struct iguana_info *coin); -int32_t iguana_volatilesmap(struct iguana_info *coin,struct iguana_ramchain *ramchain); -void iguana_volatilespurge(struct iguana_info *coin,struct iguana_ramchain *ramchain); -int32_t iguana_volatilesinit(struct iguana_info *coin); -void iguana_initfinal(struct iguana_info *coin,bits256 lastbundle); -int64_t iguana_ramchainopen(char *fname,struct iguana_info *coin,struct iguana_ramchain *ramchain,struct OS_memspace *mem,struct OS_memspace *hashmem,int32_t bundleheight,bits256 hash2); -int32_t iguana_ramchain_free(struct iguana_info *coin,struct iguana_ramchain *ramchain,int32_t deleteflag); -void iguana_blocksetcounters(struct iguana_info *coin,struct iguana_block *block,struct iguana_ramchain * ramchain); -int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain *dest,struct iguana_ramchain *ramchain,struct iguana_bundle *bp,int16_t bundlei); -void *iguana_bundlefile(struct iguana_info *coin,char *fname,long *filesizep,struct iguana_bundle *bp,int32_t bundlei); -int32_t iguana_mapchaininit(char *fname,struct iguana_info *coin,struct iguana_ramchain *mapchain,struct iguana_bundle *bp,int32_t bundlei,struct iguana_block *block,void *ptr,long filesize); -void iguana_autoextend(struct iguana_info *coin,struct iguana_bundle *bp); -void iguana_RTramchainfree(struct iguana_info *coin,struct iguana_bundle *bp); -void iguana_coinpurge(struct iguana_info *coin); -int32_t iguana_setmaxbundles(struct iguana_info *coin); -void iguana_bundlepurgefiles(struct iguana_info *coin,struct iguana_bundle *bp); -uint32_t iguana_sparseaddtx(uint8_t *bits,int32_t width,uint32_t tablesize,bits256 txid,struct iguana_txid *T,uint32_t txidind,struct iguana_ramchain *ramchain); -void iguana_launchpeer(struct iguana_info *coin,char *ipaddr); -//void iguana_spendvectorsQ(struct iguana_info *coin,struct iguana_bundle *bp); -int8_t iguana_blockstatus(struct iguana_info *coin,struct iguana_block *block); -int32_t iguana_peerslotinit(struct iguana_info *coin,struct iguana_peer *addr,int32_t slotid,uint64_t ipbits); -void iguana_blockunmark(struct iguana_info *coin,struct iguana_block *block,struct iguana_bundle *bp,int32_t i,int32_t deletefile); -int32_t iguana_reqblocks(struct iguana_info *coin); -void iguana_walletlock(struct supernet_info *myinfo,struct iguana_info *coin); -int32_t _SuperNET_encryptjson(char *destfname,char *passphrase,int32_t passsize,char *fname2fa,int32_t fnamesize,cJSON *argjson); -int32_t bitcoin_pubkeylen(const uint8_t *pubkey); -struct iguana_block *iguana_bundleblock(struct iguana_info *coin,bits256 *hash2p,struct iguana_bundle *bp,int32_t i); -void *iguana_ramchainfile(struct iguana_info *coin,struct iguana_ramchain *dest,struct iguana_ramchain *R,struct iguana_bundle *bp,int32_t bundlei,struct iguana_block *block); -int32_t iguana_bundlehashadd(struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei,struct iguana_block *block); -int32_t iguana_convert(struct iguana_info *coin,int32_t helperid,struct iguana_bundle *bp,int32_t RTflag,int32_t starti); -int32_t iguana_bundleissuemissing(struct iguana_info *coin,struct iguana_bundle *bp,int32_t priority,double mult); -FILE *myfopen(char *fname,char *mode); -int32_t myfclose(FILE *fp); -int32_t iguana_walkchain(struct iguana_info *coin,int32_t skipflag); -struct iguana_block *iguana_fastlink(struct iguana_info *coin,int32_t hwmheight); -int32_t iguana_balancenormal(struct iguana_info *coin,struct iguana_bundle *bp,int32_t startheight,int32_t endheight); -int32_t iguana_spendvectorsaves(struct iguana_info *coin); -int32_t iguana_convertfinished(struct iguana_info *coin); -int32_t iguana_emitfinished(struct iguana_info *coin,int32_t queueincomplete); -int32_t iguana_utxofinished(struct iguana_info *coin); -int32_t iguana_balancefinished(struct iguana_info *coin); -int32_t iguana_alloctxbits(struct iguana_info *coin,struct iguana_ramchain *ramchain); -void iguana_allocvolatile(struct iguana_info *coin,struct iguana_ramchain *ramchain); -int32_t iguana_rwaddr(int32_t rwflag,uint8_t *serialized,struct iguana_msgaddress *addr,int32_t protover); -struct iguana_waddress *iguana_waddresscreate(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waccount *wacct,char *coinaddr,char *redeemScript); - -int32_t iguana_peerhdrrequest(struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_peer *addr,bits256 hash2); -int32_t iguana_peeraddrrequest(struct iguana_info *coin,struct iguana_peer *addr,uint8_t *space,int32_t max); -int32_t iguana_peerdatarequest(struct iguana_info *coin,struct iguana_peer *addr,uint8_t *space,int32_t max); -int32_t iguana_peergetrequest(struct iguana_info *coin,struct iguana_peer *addr,uint8_t *data,int32_t recvlen,int32_t getblock); -int32_t iguana_bundlefname(struct iguana_info *coin,struct iguana_bundle *bp,char *fname); -int32_t iguana_bundleremove(struct iguana_info *coin,int32_t hdrsi,int32_t tmpfiles); -int32_t iguana_voutsfname(struct iguana_info *coin,int32_t roflag,char *fname,int32_t slotid); -int32_t iguana_vinsfname(struct iguana_info *coin,int32_t roflag,char *fname,int32_t slotid); -bits256 iguana_merkle(struct iguana_info *coin,bits256 *tree,int32_t txn_count); -int32_t iguana_bundleready(struct iguana_info *coin,struct iguana_bundle *bp,int32_t requiredflag); -int32_t iguana_blast(struct iguana_info *coin,struct iguana_peer *addr); -int32_t iguana_validated(struct iguana_info *coin); -void iguana_volatilesalloc(struct iguana_info *coin,struct iguana_ramchain *ramchain,int32_t copyflag); -int32_t iguana_send_ping(struct iguana_info *coin,struct iguana_peer *addr); -int32_t iguana_process_msgrequestQ(struct iguana_info *coin); -uint32_t iguana_fastfindinit(struct iguana_info *coin); -int32_t iguana_unspentindfind(struct iguana_info *coin,char *coinaddr,uint8_t *spendscript,int32_t *scriptlenp,uint64_t *valuep,int32_t *heightp,bits256 txid,int32_t vout,int32_t lasthdrsi); -int32_t iguana_addressvalidate(struct iguana_info *coin,uint8_t *addrtypep,uint8_t rmd160[20],char *address); -int32_t bitcoin_sign(void *ctx,char *symbol,uint8_t *sig,bits256 txhash2,bits256 privkey,int32_t recoverflag); -bits256 iguana_str2priv(struct supernet_info *myinfo,struct iguana_info *coin,char *str); -int32_t iguana_spentflag(struct iguana_info *coin,int64_t *RTspendp,int32_t *spentheightp,struct iguana_ramchain *ramchain,int16_t spent_hdrsi,uint32_t spent_unspentind,int32_t height,int32_t minconf,int32_t maxconf,uint64_t amount); -int32_t iguana_voutscript(struct iguana_info *coin,struct iguana_bundle *bp,uint8_t *scriptspace,char *asmstr,struct iguana_unspent *u,struct iguana_pkhash *p,int32_t txi); -cJSON *iguana_unspentjson(struct supernet_info *myinfo,struct iguana_info *coin,int32_t hdrsi,uint32_t unspentind,struct iguana_txid *T,struct iguana_unspent *up,uint8_t rmd160[20],char *coinaddr,uint8_t *pubkey33); -int32_t bitcoin_standardspend(uint8_t *script,int32_t n,uint8_t rmd160[20]); -struct iguana_waddress *iguana_waddresssearch(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waccount **wacctp,char *coinaddr); -int64_t iguana_addressreceived(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *json,char *remoteaddr,cJSON *txids,cJSON *vouts,char *coinaddr,int32_t minconf); -cJSON *iguana_walletjson(struct supernet_info *myinfo); -int32_t iguana_payloadupdate(struct supernet_info *myinfo,struct iguana_info *coin,char *retstr,struct iguana_waddress *waddr,char *account); -int32_t bitcoin_MofNspendscript(uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,const struct vin_info *vp); -cJSON *iguana_p2shjson(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *retjson,struct iguana_waddress *waddr); -char *setaccount(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waddress **waddrp,char *account,char *coinaddr,char *redeemScript); -char *iguana_APIrequest(struct iguana_info *coin,bits256 blockhash,bits256 txid,int32_t seconds); -int32_t bitcoin_verifyvins(struct iguana_info *coin,bits256 *signedtxidp,char **signedtx,struct iguana_msgtx *msgtx,uint8_t *serialized,int32_t maxsize,struct vin_info *V,int32_t sighash); -int64_t iguana_fastfindcreate(struct iguana_info *coin); -int32_t bitcoin_validaddress(struct iguana_info *coin,char *coinaddr); -int32_t iguana_volatileupdate(struct iguana_info *coin,int32_t incremental,struct iguana_ramchain *spentchain,int16_t spent_hdrsi,uint32_t spent_unspentind,uint32_t spent_pkind,uint64_t spent_value,uint32_t spendind,uint32_t fromheight); -int32_t iguana_utxoupdate(struct iguana_info *coin,int16_t spent_hdrsi,uint32_t spent_unspentind,uint32_t spent_pkind,uint64_t spent_value,uint32_t spendind,uint32_t fromheight); -int32_t iguana_unspentslists(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waddress **waddrs,int32_t maxwaddrs,int64_t required,int32_t minconf,char *account); -int64_t iguana_unspentset(struct supernet_info *myinfo,struct iguana_info *coin); -int32_t iguana_txidfastfind(struct iguana_info *coin,int32_t *heightp,bits256 txid,int32_t lasthdrsi); -uint8_t iguana_addrtype(struct iguana_info *coin,uint8_t script_type); -struct iguana_waddress *iguana_waddressadd(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waccount *wacct,struct iguana_waddress *addwaddr,char *redeemScript); -cJSON *iguana_createvins(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *txobj,cJSON *vins); -bits256 bitcoin_pubkey33(void *ctx,uint8_t *data,bits256 privkey); -bits256 bitcoin_randkey(void *ctx); -int32_t bitcoin_recoververify(void *ctx,char *symbol,uint8_t *sig64,bits256 messagehash2,uint8_t *pubkey); -int32_t bitcoin_assembler(struct iguana_info *coin,uint8_t script[IGUANA_MAXSCRIPTSIZE],cJSON *scriptobj,int32_t interpret,int64_t nLockTime,struct vin_info *V); -cJSON *iguana_spendasm(struct iguana_info *coin,uint8_t *spendscript,int32_t spendlen); - -extern int32_t HDRnet,netBLOCKS; - -extern queue_t bundlesQ,emitQ,TerminateQ; -extern char GLOBAL_TMPDIR[],GLOBAL_VALIDATEDIR[],GLOBAL_HELPDIR[],GLOBAL_DBDIR[],GLOBAL_CONFSDIR[]; - - -#include "../includes/iguana_api.h" - #endif diff --git a/iguana/iguana_accept.c b/iguana/iguana_accept.c index 6a5f15ea8..6e2895a33 100755 --- a/iguana/iguana_accept.c +++ b/iguana/iguana_accept.c @@ -14,6 +14,7 @@ ******************************************************************************/ #include "iguana777.h" +#include "exchanges777.h" struct iguana_accept { struct queueitem DL; char ipaddr[64]; uint32_t ipbits; int32_t sock; uint16_t port; }; @@ -64,16 +65,18 @@ void iguana_acceptloop(void *args) { struct iguana_peer *addr; struct iguana_info *coin = args; struct pollfd pfd; int32_t sock; struct iguana_accept *ptr; uint16_t port = coin->chain->portp2p; - socklen_t clilen; struct sockaddr_in cli_addr; char ipaddr[64]; uint32_t i,ipbits; + socklen_t clilen; struct sockaddr_in cli_addr; char ipaddr[64]; uint32_t i,ipbits,flag; + if ( coin->peers == 0 ) + return; while ( (coin->bindsock= iguana_socket(1,"0.0.0.0",port)) < 0 ) { - if ( coin->peers.localaddr != 0 ) + if ( coin->peers->localaddr != 0 ) { printf("another daemon running, no need to have iguana accept connections\n"); return; } - if ( port != IGUANA_RPCPORT ) - return; + //if ( port != IGUANA_RPCPORT ) + // return; sleep(5); } printf(">>>>>>>>>>>>>>>> iguana_bindloop 127.0.0.1:%d bind sock.%d\n",port,coin->bindsock); @@ -95,40 +98,47 @@ void iguana_acceptloop(void *args) } memcpy(&ipbits,&cli_addr.sin_addr.s_addr,sizeof(ipbits)); expand_ipbits(ipaddr,ipbits); - for (i=0; ipeers.active[i].ipbits == (uint32_t)ipbits && coin->peers.active[i].usock >= 0 ) + if ( coin->peers->active[i].ipbits == (uint32_t)ipbits && coin->peers->active[i].usock >= 0 ) { printf("found existing peer.(%s) in slot[%d]\n",ipaddr,i); - close(sock); - sock = -1; - //iguana_iAkill(coin,&coin->peers.active[i],0); + close(coin->peers->active[i].usock); + coin->peers->active[i].dead = 0; + coin->peers->active[i].usock = sock; + coin->peers->active[i].A.port = cli_addr.sin_port; + coin->peers->active[i].ready = (uint32_t)time(NULL); + flag = 1; + //instantdex_peerhas_clear(coin,&coin->peers->active[i]); + //iguana_iAkill(coin,&coin->peers->active[i],0); //sleep(1); break; } } - if ( sock < 0 ) + if ( flag != 0 ) continue; printf("NEWSOCK.%d for %x (%s)\n",sock,ipbits,ipaddr); /*if ( (uint32_t)ipbits == myinfo->myaddr.myipbits ) { }*/ - if ( (addr= iguana_peerslot(coin,ipbits,0)) == 0 ) + if ( (addr= iguana_peerslot(coin,ipbits,1)) == 0 ) { ptr = mycalloc('a',1,sizeof(*ptr)); strcpy(ptr->ipaddr,ipaddr); ptr->ipbits = ipbits; ptr->sock = sock; - ptr->port = coin->chain->portp2p; + ptr->port = cli_addr.sin_port; printf("queue PENDING ACCEPTS\n"); queue_enqueue("acceptQ",&coin->acceptQ,&ptr->DL,0); } else { - printf("LAUNCH DEDICATED THREAD for %s\n",ipaddr); + printf("LAUNCH DEDICATED THREAD for %s:%u\n",ipaddr,cli_addr.sin_port); addr->usock = sock; addr->dead = 0; + addr->A.port = cli_addr.sin_port; strcpy(addr->symbol,coin->symbol); iguana_launch(coin,"accept",iguana_dedicatedglue,addr,IGUANA_CONNTHREAD); //iguana_dedicatedloop(coin,addr); @@ -175,36 +185,37 @@ void iguana_msgrequestQ(struct iguana_info *coin,struct iguana_peer *addr,int32_ queue_enqueue("msgrequest",&coin->msgrequestQ,&msg->DL,0); } -int32_t iguana_process_msgrequestQ(struct iguana_info *coin) +int32_t iguana_process_msgrequestQ(struct supernet_info *myinfo,struct iguana_info *coin) { - struct iguana_peermsgrequest *msg; int32_t height,len,flag = 0; bits256 checktxid; struct iguana_txid *tx,T; + struct iguana_peermsgrequest *msg; int32_t height,len,flag = 0; bits256 checktxid; struct iguana_txid *tx,T; struct iguana_peer *addr; if ( (msg= queue_dequeue(&coin->msgrequestQ,0)) != 0 ) { flag = 1; if ( msg->addr != 0 ) { - char str[65]; printf("send type.%d %s -> (%s)\n",msg->type,bits256_str(str,msg->hash2),msg->addr->ipaddr); + //char str[65]; printf("send type.%d %s -> (%s)\n",msg->type,bits256_str(str,msg->hash2),msg->addr->ipaddr); if ( msg->type == MSG_BLOCK ) { - if ( coin->RELAYNODE != 0 || coin->VALIDATENODE ) + if ( coin->FULLNODE != 0 || coin->VALIDATENODE != 0 ) { - if ( (len= iguana_peerblockrequest(coin,&coin->blockspace[sizeof(struct iguana_msghdr)],sizeof(coin->blockspace),0,msg->hash2,0)) > 0 ) + if ( (addr= msg->addr) != 0 && (len= iguana_peerblockrequest(coin,coin->blockspace,(int32_t)(coin->blockspacesize - sizeof(struct iguana_msghdr)),0,msg->hash2,0)) > 0 ) { - iguana_queue_send(coin,msg->addr,0,coin->blockspace,"block",len,0,0); + //char str[65]; printf("msg Sendlen.%d block %s to %s\n",len,bits256_str(str,msg->hash2),addr->ipaddr); + iguana_queue_send(addr,0,coin->blockspace,"block",len); } } } else if ( msg->type == MSG_TX ) { - if ( coin->RELAYNODE != 0 || coin->VALIDATENODE ) + if ( coin->FULLNODE != 0 || coin->VALIDATENODE ) { if ( (tx= iguana_txidfind(coin,&height,&T,msg->hash2,coin->bundlescount-1)) != 0 ) { - if ( (len= iguana_ramtxbytes(coin,&coin->blockspace[sizeof(struct iguana_msghdr)],sizeof(coin->blockspace),&checktxid,tx,height,0,0,0)) > 0 ) + if ( (len= iguana_ramtxbytes(coin,&coin->blockspace[sizeof(struct iguana_msghdr)],coin->blockspacesize,&checktxid,tx,height,0,0,0)) > 0 ) { char str[65],str2[65]; if ( bits256_cmp(msg->hash2,checktxid) == 0 ) - iguana_queue_send(coin,msg->addr,0,coin->blockspace,"block",len,0,0); + iguana_queue_send(msg->addr,0,coin->blockspace,"block",len); else printf("checktxid mismatch (%s) != (%s)\n",bits256_str(str,msg->hash2),bits256_str(str2,checktxid)); } } @@ -222,6 +233,15 @@ int32_t iguana_process_msgrequestQ(struct iguana_info *coin) { } + /*else if ( msg->type == MSG_QUOTE ) + { + if ( (len= instantdex_quoterequest(myinfo,coin,&coin->blockspace[sizeof(struct iguana_msghdr)],coin->blockspacesize,msg->addr,msg->hash2)) > 0 ) + { + //iguana_sethdr((void *)coin->blockspace,coin->chain->netmagic,"quote",&coin->blockspace[sizeof(struct iguana_msghdr)],len); + //iguana_msgparser(coin,msg->addr,0,0,0,(void *)coin->blockspace,&coin->blockspace[sizeof(struct iguana_msghdr)],len); + iguana_queue_send(msg->addr,0,coin->blockspace,"quote",len); + } + }*/ } free(msg); } @@ -247,10 +267,46 @@ int32_t iguana_peerdatarequest(struct iguana_info *coin,struct iguana_peer *addr return(len); } -int32_t iguana_peerhdrrequest(struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_peer *addr,bits256 hash2) +int32_t iguana_inv2packet(uint8_t *serialized,int32_t maxsize,int32_t type,bits256 *hashes,int32_t n) { - int32_t len=0,i,height,hdrsi,bundlei,bundlesize,firstvout,retval=-1; struct iguana_block *block; struct iguana_msgblock msgB; bits256 checkhash2; struct iguana_bundle *bp; - if ( (firstvout= iguana_unspentindfind(coin,0,0,0,0,&height,hash2,0,coin->bundlescount-1)) != 0 ) + int32_t i,len = sizeof(struct iguana_msghdr); uint64_t x = n; + memset(serialized,0,len); + len += iguana_rwvarint(1,&serialized[len],&x); + //for (i=0; i<10; i++) + // printf("%02x ",data[i]); + //printf("x.%d recvlen.%d\n",(int32_t)x,recvlen); + if ( x < IGUANA_MAXINV ) + { + for (i=0; i maxsize ) + return(-1); + return(len - sizeof(struct iguana_msghdr)); +} + +int32_t iguana_headerget(struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_block *block) +{ + bits256 checkhash2; struct iguana_msgblock msgB; int32_t len = 0; + iguana_blockunconv(coin->chain->zcash,coin->chain->auxpow,&msgB,block,1); + if ( (len= iguana_rwblock(coin->symbol,coin->chain->zcash,coin->chain->auxpow,coin->chain->hashalgo,1,&checkhash2,&serialized[sizeof(struct iguana_msghdr)],&msgB,(int32_t)(maxsize-sizeof(struct iguana_msghdr)))) < 0 ) + return(-1); + if ( bits256_cmp(checkhash2,block->RO.hash2) != 0 ) + { + char str[65],str2[65]; + printf("iguana_peerhdrrequest blockhash.%d error (%s) vs (%s)\n",block->height,bits256_str(str,checkhash2),bits256_str(str2,block->RO.hash2)); + return(-1); + } + return(len); +} + +int32_t iguana_peerhdrrequest(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_peer *addr,bits256 hash2) +{ + int32_t len=0,i,flag=0,height,n,hdrsi,bundlei,bundlesize,firstvout,retval=-1; struct iguana_block *block; struct iguana_bundle *bp; + if ( coin->RTheight > 0 && (firstvout= iguana_RTunspentindfind(myinfo,coin,0,0,0,0,&height,hash2,0,coin->bundlescount-1,0)) != 0 ) { bundlesize = coin->chain->bundlesize; hdrsi = (height / bundlesize); @@ -261,26 +317,27 @@ int32_t iguana_peerhdrrequest(struct iguana_info *coin,uint8_t *serialized,int32 { if ( (block= bp->blocks[i]) != 0 ) { - iguana_blockunconv(&msgB,block,1); - len += iguana_rwblock(1,&checkhash2,&serialized[sizeof(struct iguana_msghdr) + len],&msgB); - if ( bits256_cmp(checkhash2,block->RO.hash2) != 0 ) + if ( (n= iguana_headerget(coin,&serialized[len],maxsize-len,block)) < 0 ) { - char str[65],str2[65]; - printf("iguana_peerhdrrequest blockhash.%d error (%s) vs (%s)\n",height+i,bits256_str(str,checkhash2),bits256_str(str2,block->RO.hash2)); - return(-1); + printf("%s error getting header ht.%d\n",coin->symbol,block->height); + continue; } + len += n; } else printf("cant find block at ht.%d\n",height+i); } } - retval = iguana_queue_send(coin,addr,0,serialized,"headers",len,0,0); - printf("hdrs request retval.%d len.%d\n",retval,len); + if ( 0 && flag != 0 && strcmp("BTCD",coin->symbol) != 0 ) + retval = iguana_queue_send(addr,0,serialized,"headers",len); + //printf("hdrs request retval.%d len.%d\n",retval,len); } //else printf("couldnt find header\n"); return(retval); } -int32_t iguana_peergetrequest(struct iguana_info *coin,struct iguana_peer *addr,uint8_t *data,int32_t recvlen,int32_t getblock) +int32_t iguana_peergetrequest(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,uint8_t *data,int32_t recvlen,int32_t getblock) { int32_t i,reqvers,len,n,flag = 0; bits256 hash2; + if ( coin->RTheight <= 0 ) + return(0); if ( getblock != 0 ) addr->msgcounts.getblocks++; else addr->msgcounts.getheaders++; @@ -293,9 +350,9 @@ int32_t iguana_peergetrequest(struct iguana_info *coin,struct iguana_peer *addr, break; if ( flag == 0 ) { - if ( getblock != 0 && iguana_peerblockrequest(coin,addr->blockspace,sizeof(addr->blockspace),addr,hash2,0) > 0 ) + if ( getblock != 0 && iguana_peerblockrequest(coin,addr->blockspace,IGUANA_MAXPACKETSIZE,addr,hash2,0) > 0 ) flag = 1; - else if ( getblock == 0 && iguana_peerhdrrequest(coin,addr->blockspace,sizeof(addr->blockspace),addr,hash2) > 0 ) + else if ( getblock == 0 && iguana_peerhdrrequest(myinfo,coin,addr->blockspace,IGUANA_MAXPACKETSIZE,addr,hash2) > 0 ) flag = 1; } } @@ -308,27 +365,41 @@ int32_t iguana_peergetrequest(struct iguana_info *coin,struct iguana_peer *addr, int32_t iguana_peeraddrrequest(struct iguana_info *coin,struct iguana_peer *addr,uint8_t *space,int32_t spacesize) { - int32_t i,iter,n,max,sendlen; uint64_t x; struct iguana_msghdr H; struct iguana_peer *tmpaddr; + int32_t i,iter,n,max,sendlen; uint64_t x; struct iguana_peer *tmpaddr,tmp; char ipaddr[65]; + if ( coin->peers == 0 ) + return(0); sendlen = 0; max = (IGUANA_MINPEERS + IGUANA_MAXPEERS) / 2; - if ( max > coin->peers.numranked ) - max = coin->peers.numranked; + if ( max > coin->peers->numranked ) + max = coin->peers->numranked; x = 0; - sendlen = iguana_rwvarint(1,&space[sizeof(H)],&x); + sendlen = iguana_rwvarint(1,&space[sendlen],&x); for (iter=0; iter<2; iter++) { for (i=n=0; ipeers.ranked[i]) != 0 && ((iter == 0 && tmpaddr->supernet != 0) || (iter == 1 && tmpaddr->supernet == 0)) && tmpaddr->ipaddr[0] != 0 ) + if ( (tmpaddr= coin->peers->ranked[i]) != 0 && ((iter == 0 && tmpaddr->supernet != 0) || (iter == 1 && tmpaddr->supernet == 0)) && tmpaddr->ipbits != 0 ) { - sendlen += iguana_rwaddr(1,&space[sizeof(H) + sendlen],&tmpaddr->A,(int32_t)tmpaddr->protover); - printf("(%s) ",tmpaddr->ipaddr); + tmp = *tmpaddr; + iguana_rwnum(1,&tmp.A.ip[12],sizeof(uint32_t),&tmp.ipbits); + expand_ipbits(ipaddr,tmp.ipbits); + if ( tmp.A.port == 0 ) + { + ((uint8_t *)&tmp.A.port)[0] = ((uint8_t *)&coin->chain->portp2p)[1]; + ((uint8_t *)&tmp.A.port)[1] = ((uint8_t *)&coin->chain->portp2p)[0]; + } + //printf("(%s:%02x%02x).%04x ",ipaddr,((uint8_t *)&tmp.A.port)[0],((uint8_t *)&tmp.A.port)[1],(int32_t)tmp.protover); + sendlen += iguana_rwaddr(1,&space[sendlen],&tmp.A,CADDR_TIME_VERSION); x++; + if ( x == 0xf8 ) + break; } } } - iguana_rwvarint(1,&space[sizeof(H)],&x); - printf("addrrequest: sendlen.%d x.%d\n",sendlen,(int32_t)x); + iguana_rwvarint(1,space,&x); + //for (i=0; iscreen != 0 ) { - strcpy(coin->screen.name,coin->symbol); - coin->screen.amplitude = 255; - coin->screen.width = IGUANA_WIDTH; - coin->screen.height = IGUANA_HEIGHT; - memset(coin->screen.data,0xff,sizeof(coin->screen.data)); + strcpy(coin->screen->name,coin->symbol); + coin->screen->amplitude = 255; + coin->screen->width = IGUANA_WIDTH; + coin->screen->height = IGUANA_HEIGHT; + memset(coin->screen->data,0xff,sizeof(coin->screen->data)); if ( coin->bundlescount > 0 ) { n = 100; @@ -1109,11 +1109,11 @@ struct iguana_bitmap *iguana_bitmapfind(char *name) { if ( hdrsi >= coin->bundlescount ) break; - iguana_bitmapbundle(coin,&coin->screen.data[3*(y*coin->screen.width*n + x*n)],coin->screen.width,n,n,coin->bundles[hdrsi]); + iguana_bitmapbundle(coin,&coin->screen->data[3*(y*coin->screen->width*n + x*n)],coin->screen->width,n,n,coin->bundles[hdrsi]); } } } - return(&coin->screen); + return(coin->screen); } return(0); } diff --git a/iguana/iguana_blocks.c b/iguana/iguana_blocks.c index 18e1fdb56..511303f6f 100755 --- a/iguana/iguana_blocks.c +++ b/iguana/iguana_blocks.c @@ -15,7 +15,101 @@ #include "iguana777.h" -bits256 iguana_merkle(struct iguana_info *coin,bits256 *tree,int32_t txn_count) +#define iguana_blockfind(str,coin,hash2) iguana_blockhashset(str,coin,-1,hash2,0) + +void iguana_blockconv(uint8_t zcash,uint8_t auxpow,struct iguana_block *dest,struct iguana_msgblock *msg,bits256 hash2,int32_t height) //uint32_t numtxids,uint32_t numunspents,uint32_t numspends,double PoW) +{ + int32_t i; + memset(dest,0,sizeof(*dest)); + dest->RO.version = msg->H.version; + dest->RO.prev_block = msg->H.prev_block; + dest->RO.merkle_root = msg->H.merkle_root; + dest->RO.timestamp = msg->H.timestamp; + dest->RO.bits = msg->H.bits; + dest->RO.txn_count = msg->txn_count; + dest->height = height; + dest->RO.hash2 = hash2; + if ( zcash == 0 ) + dest->RO.nonce = msg->H.nonce; + else + { + dest->RO.allocsize = (int32_t)(sizeof(*dest) + sizeof(*dest->zRO)); + dest->zRO[0].bignonce = msg->zH.bignonce; + for (i=0; izRO[0].solution[i] = msg->zH.solution[i]; + } +} + +void iguana_blockunconv(uint8_t zcash,uint8_t auxpow,struct iguana_msgblock *msg,struct iguana_block *src,int32_t cleartxn_count) +{ + int32_t i; + memset(msg,0,sizeof(*msg)); + msg->H.version = src->RO.version; + msg->H.prev_block = src->RO.prev_block; + msg->H.merkle_root = src->RO.merkle_root; + msg->H.timestamp = src->RO.timestamp; + msg->H.bits = src->RO.bits; + if ( zcash == 0 ) + msg->H.nonce = src->RO.nonce; + else + { + msg->zH.bignonce = src->zRO[0].bignonce; + msg->zH.numelements = ZCASH_SOLUTION_ELEMENTS; + for (i=0; izH.solution[i] = src->zRO[0].solution[i]; + } + if ( cleartxn_count == 0 ) + msg->txn_count = src->RO.txn_count; +} + +void iguana_blockcopy(uint8_t zcash,uint8_t auxpow,struct iguana_info *coin,struct iguana_block *block,struct iguana_block *origblock) +{ + int32_t i; + block->RO.hash2 = origblock->RO.hash2; + block->RO.merkle_root = origblock->RO.merkle_root; + if ( bits256_nonz(block->RO.prev_block) == 0 ) + block->RO.prev_block = origblock->RO.prev_block; + if ( block->mainchain == 0 ) + block->mainchain = origblock->mainchain; + if ( block->fpos < 0 ) + block->fpos = origblock->fpos; + if ( block->fpipbits == 0 ) + block->fpipbits = origblock->fpipbits; + if ( block->RO.timestamp == 0 ) + block->RO.timestamp = origblock->RO.timestamp; + if ( block->RO.bits == 0 ) + block->RO.bits = origblock->RO.bits; + if ( block->RO.txn_count == 0 ) + block->RO.txn_count = origblock->RO.txn_count; + if ( block->RO.version == 0 ) + block->RO.version = origblock->RO.version; + if ( block->mainchain == 0 ) + block->mainchain = origblock->mainchain; + if ( block->valid == 0 ) + block->valid = origblock->valid; + if ( block->RO.recvlen == 0 ) + block->RO.recvlen = origblock->RO.recvlen; + if ( zcash == 0 ) + { + if ( block->RO.nonce == 0 ) + block->RO.nonce = origblock->RO.nonce; + } + else + { + iguana_blocksizecheck("blockcopy dest",coin->chain->zcash,block); + iguana_blocksizecheck("blockcopy src",coin->chain->zcash,origblock); + if ( block->RO.allocsize != origblock->RO.allocsize ) + printf("missing space for zcash block.%d origblock.%d\n",block->RO.allocsize,origblock->RO.allocsize); + else + { + block->zRO[0].bignonce = origblock->zRO[0].bignonce; + for (i=0; izRO[0].solution[i] = origblock->zRO[0].solution[i]; + } + } +} + +bits256 iguana_merkle(bits256 *tree,int32_t txn_count) { int32_t i,n=0,prev; uint8_t serialized[sizeof(bits256) * 2]; if ( txn_count == 1 ) @@ -38,7 +132,17 @@ bits256 iguana_merkle(struct iguana_info *coin,bits256 *tree,int32_t txn_count) return(tree[n]); } -#define iguana_blockfind(str,coin,hash2) iguana_blockhashset(str,coin,-1,hash2,0) +struct iguana_block *iguana_prevblock(struct iguana_info *coin,struct iguana_block *block,int32_t PoSflag) +{ + int32_t hdrsi,bundlei,height; struct iguana_bundle *bp; + if ( (height= block->height - 1) < 0 ) + return(0); + hdrsi = (height / coin->chain->bundlesize); + bundlei = (height % coin->chain->bundlesize); + if ( hdrsi < coin->bundlescount && (bp= coin->bundles[hdrsi]) != 0 ) + return(bp->blocks[bundlei]); + else return(0); +} void _iguana_blocklink(struct iguana_info *coin,struct iguana_block *prev,struct iguana_block *block) { @@ -70,17 +174,18 @@ void _iguana_blocklink(struct iguana_info *coin,struct iguana_block *prev,struct struct iguana_block *iguana_blockhashset(char *debugstr,struct iguana_info *coin,int32_t height,bits256 hash2,int32_t createflag) { - struct iguana_block *block,*prev; - if ( height > 0 && height > coin->blocks.maxbits ) + struct iguana_block *block,*prev; int32_t size; + /*if ( height > 0 && height > coin->blocks.maxbits ) { printf("%s: illegal height.%d when max.%d, or nonz depth.%d\n",debugstr,height,coin->blocks.maxbits,coin->blockdepth); //getchar(); return(0); - } + }*/ while ( coin->blockdepth > 0 ) { - sleep(1); - printf("%s >>>>>>>>>> OK only if rare %s blockhashset.%d depth.%d\n",coin->symbol,debugstr,height,coin->blockdepth); + usleep(100000); + if ( coin->blockdepth > 0 ) + printf("A %s >>>>>>>>>> OK only if rare %s blockhashset.%d depth.%d\n",coin->symbol,debugstr,height,coin->blockdepth); //fprintf(stderr,">>>>>>>>>> OK only if rare %s blockhashset.%d depth.%d\n",debugstr,height,depth); //printf("%d\n",1/(1 - depth/depth)); } @@ -92,8 +197,9 @@ struct iguana_block *iguana_blockhashset(char *debugstr,struct iguana_info *coin coin->blockdepth--; while ( coin->blockdepth > 0 ) { - sleep(1); - printf(" %s >>>>>>>>>> OK only if rare %s match blockhashset.%d depth.%d\n",coin->symbol,debugstr,height,coin->blockdepth); + usleep(100000); + if ( coin->blockdepth > 0 ) + printf("B %s >>>>>>>>>> OK only if rare %s match blockhashset.%d depth.%d\n",coin->symbol,debugstr,height,coin->blockdepth); //fprintf(stderr,">>>>>>>>>> OK only if rare%s match blockhashset.%d depth.%d\n",debugstr,height,depth); //printf("%d\n",1/(1 - depth/depth)); } @@ -102,8 +208,11 @@ struct iguana_block *iguana_blockhashset(char *debugstr,struct iguana_info *coin if ( createflag > 0 ) { portable_mutex_lock(&coin->blocks_mutex); - block = calloc(1,sizeof(*block)); + size = (int32_t)((coin->chain->zcash != 0) ? sizeof(struct iguana_zblock) : sizeof(struct iguana_block)); + block = calloc(1,size); block->RO.hash2 = hash2; + block->RO.allocsize = size; + iguana_blocksizecheck("blockhashset",coin->chain->zcash,block); block->hh.itemind = height, block->height = -1; HASH_ADD(hh,coin->blocks.hash,RO.hash2,sizeof(hash2),block); block->hh.next = block->hh.prev = 0; @@ -113,9 +222,10 @@ struct iguana_block *iguana_blockhashset(char *debugstr,struct iguana_info *coin if ( prev != 0 ) _iguana_blocklink(coin,prev,block); } - //char str[65]; printf("added.(%s) height.%d (%p %p)\n",bits256_str(str,hash2),height,block->hh.prev,block->hh.next); - if ( 0 ) + //char str[65]; + if ( coin->virtualchain != 0 ) { + //printf("%s added.(%s) height.%d (%p %p)\n",coin->symbol,bits256_str(str,hash2),height,block->hh.prev,block->hh.next); struct iguana_block *tmp; HASH_FIND(hh,coin->blocks.hash,&hash2,sizeof(hash2),tmp); char str[65]; @@ -129,8 +239,9 @@ struct iguana_block *iguana_blockhashset(char *debugstr,struct iguana_info *coin coin->blockdepth--; while ( coin->blockdepth > 0 ) { - sleep(1); - printf("%s >>>>>>>>>> OK only if rare %s create blockhashset.%d depth.%d\n",coin->symbol,debugstr,height,coin->blockdepth); + usleep(100000); + if ( coin->blockdepth > 0 ) + printf("C %s >>>>>>>>>> OK only if rare %s create blockhashset.%d depth.%d\n",coin->symbol,debugstr,height,coin->blockdepth); //fprintf(stderr,">>>>>>>>>> OK only if rare%s create blockhashset.%d depth.%d\n",debugstr,height,depth); //printf("%d\n",1/(1 - depth/depth)); } @@ -144,22 +255,12 @@ bits256 *iguana_blockhashptr(struct iguana_info *coin,int32_t height) { hdrsi = (height / bundlesize); bundlei = height - (hdrsi * bundlesize); - if ( hdrsi >= 0 && hdrsi < bundlesize && bundlei >= 0 && bundlei < bundlesize && (bp= coin->bundles[hdrsi]) != 0 ) + if ( hdrsi >= 0 && hdrsi < coin->bundlescount && bundlei >= 0 && bundlei < bundlesize ) { - return(&bp->hashes[bundlei]); + if ( (bp= coin->bundles[hdrsi]) != 0 ) + return(&bp->hashes[bundlei]); + else return(0); } - /*for (i=0; ibundlescount; i++) - { - if ( (bp= coin->bundles[i]) != 0 ) - { - if ( height >= bp->bundleheight && height < bp->bundleheight+bp->n ) - { - hashptr = &bp->hashes[height - bp->bundleheight]; - //printf("i.%d hashptr.%p height.%d vs (%d %d)\n",i,hashptr,height,bp->bundleheight,bp->bundleheight+bp->n); - return(hashptr); - } - } - }*/ } return(0); } @@ -180,19 +281,66 @@ struct iguana_block *iguana_blockptr(char *debugstr,struct iguana_info *coin,int return(0); } +int32_t iguana_blocksizecheck(char *debugstr,uint8_t zcash,struct iguana_block *block) +{ + int32_t bsize = zcash != 0 ? sizeof(struct iguana_zblock) : sizeof(struct iguana_block); + if ( block->RO.allocsize != bsize ) + { + if ( block->RO.allocsize == 0 || block->RO.allocsize < bsize ) + { + //printf("%s block validate warning: mismatched size %d vs %d\n",debugstr,block->RO.allocsize,bsize); + block->RO.allocsize = bsize; + } else return(-1); + return(bsize); + } + return(0); +} + +int32_t iguana_blockROsize(uint8_t zcash) +{ + return((int32_t)(sizeof(struct iguana_blockRO) + zcash*sizeof(struct iguana_msgblockhdr_zcash))); +} + +void *iguana_blockzcopyRO(uint8_t zcash,struct iguana_blockRO *dest,int32_t desti,struct iguana_blockRO *src,int32_t srci) +{ + int32_t bROsize = iguana_blockROsize(zcash); + dest = (void *)((long)dest + desti*bROsize); + src = (void *)((long)src + srci*bROsize); + memcpy(dest,src,bROsize); + return(src); +} + +void iguana_blockzcopy(uint8_t zcash,struct iguana_block *dest,struct iguana_block *src) +{ + iguana_blocksizecheck("blockcopy dest",zcash,dest); + iguana_blocksizecheck("blockcopy src",zcash,src); + if ( zcash == 0 ) + *dest = *src; + else + { + if ( src->RO.allocsize != sizeof(struct iguana_zblock) ) + printf("warning: iguana_blockcopy src size %d vs %d\n",src->RO.allocsize,(int32_t)sizeof(struct iguana_zblock)); + *(struct iguana_zblock *)dest = *(struct iguana_zblock *)src; + dest->RO.allocsize = sizeof(struct iguana_zblock); + } +} + int32_t iguana_blockvalidate(struct iguana_info *coin,int32_t *validp,struct iguana_block *block,int32_t dispflag) { bits256 hash2; uint8_t serialized[sizeof(struct iguana_msgblock) + 4096]; *validp = 0; - iguana_serialize_block(&hash2,serialized,block); + iguana_serialize_block(coin->chain,&hash2,serialized,block); *validp = (memcmp(hash2.bytes,block->RO.hash2.bytes,sizeof(hash2)) == 0); block->valid = *validp; + iguana_blocksizecheck("blockvalidate",coin->chain->zcash,block); char str[65]; char str2[65]; if ( *validp == 0 ) { if ( dispflag != 0 ) { - printf("iguana_blockvalidate: miscompare (%s) vs (%s)\n",bits256_str(str,hash2),bits256_str(str2,block->RO.hash2)); + static uint32_t counter; + if ( (counter++ % 10000) == 9999 ) + printf("iguana_blockvalidate: %s miscompare.%d (%s) vs (%s)\n",coin->symbol,counter,bits256_str(str,hash2),bits256_str(str2,block->RO.hash2)); //getchar(); } return(-1); @@ -227,87 +375,30 @@ void iguana_blockmerge(struct iguana_block *dest,struct iguana_prevdep *destlp,s iguana_mergeprevdep(destlp,srclp); }*/ -void iguana_blockconv(struct iguana_block *dest,struct iguana_msgblock *msg,bits256 hash2,int32_t height) //uint32_t numtxids,uint32_t numunspents,uint32_t numspends,double PoW) -{ - memset(dest,0,sizeof(*dest)); - dest->RO.version = msg->H.version; - dest->RO.prev_block = msg->H.prev_block; - dest->RO.merkle_root = msg->H.merkle_root; - dest->RO.timestamp = msg->H.timestamp; - dest->RO.bits = msg->H.bits; - dest->RO.nonce = msg->H.nonce; - dest->RO.txn_count = msg->txn_count; - dest->height = height; - dest->RO.hash2 = hash2; -} - -void iguana_blockunconv(struct iguana_msgblock *msg,struct iguana_block *src,int32_t cleartxn_count) -{ - memset(msg,0,sizeof(*msg)); - msg->H.version = src->RO.version; - msg->H.prev_block = src->RO.prev_block; - msg->H.merkle_root = src->RO.merkle_root; - msg->H.timestamp = src->RO.timestamp; - msg->H.bits = src->RO.bits; - msg->H.nonce = src->RO.nonce; - if ( cleartxn_count == 0 ) - msg->txn_count = src->RO.txn_count; -} - -void iguana_blockcopy(struct iguana_info *coin,struct iguana_block *block,struct iguana_block *origblock) -{ - block->RO.hash2 = origblock->RO.hash2; - block->RO.merkle_root = origblock->RO.merkle_root; - if ( bits256_nonz(block->RO.prev_block) == 0 ) - block->RO.prev_block = origblock->RO.prev_block; - if ( block->mainchain == 0 ) - block->mainchain = origblock->mainchain; - if ( block->fpos < 0 ) - block->fpos = origblock->fpos; - if ( block->fpipbits == 0 ) - block->fpipbits = origblock->fpipbits; - if ( block->RO.timestamp == 0 ) - block->RO.timestamp = origblock->RO.timestamp; - if ( block->RO.nonce == 0 ) - block->RO.nonce = origblock->RO.nonce; - if ( block->RO.bits == 0 ) - block->RO.bits = origblock->RO.bits; - if ( block->RO.txn_count == 0 ) - block->RO.txn_count = origblock->RO.txn_count; - if ( block->RO.version == 0 ) - block->RO.version = origblock->RO.version; - if ( block->mainchain == 0 ) - block->mainchain = origblock->mainchain; - if ( block->valid == 0 ) - block->valid = origblock->valid; - if ( block->RO.recvlen == 0 ) - block->RO.recvlen = origblock->RO.recvlen; -} - double PoW_from_compact(uint32_t nBits,uint8_t unitval) // NOT consensus safe, but most of the time will be correct { uint32_t nbytes,nbits,i,n; double PoW; uint64_t mult; nbytes = (nBits >> 24) & 0xFF; nbits = (8 * (nbytes - 3)); PoW = (nBits & 0xFFFFFF); - if ( nbytes > unitval ) + if ( 0 && nbytes > unitval ) { - printf("illegal nBits.%x\n",nBits); + printf("illegal nBits.%x unitval.%02x\n",nBits,unitval); return(0.); } - if ( (n= ((8* (unitval-3)) - nbits)) != 0 ) // 0x1d00ffff is genesis nBits so we map that to 1. + if ( (n= ((8 * (unitval-3)) - nbits)) != 0 ) // 0x1d00ffff is genesis nBits so we map that to 1. { //printf("nbits.%d -> n.%d\n",nbits,n); if ( n < 64 ) PoW /= (1LL << n); - else // very rare case efficiency not issue + else // rare case efficiency not issue { for (i=0; i %.15f diff %.15f | n.%d unitval.%d nbytes.%d\n",nBits,PoW,1./PoW,n,unitval,nbytes); @@ -345,6 +436,7 @@ int32_t iguana_walkchain(struct iguana_info *coin,int32_t skipflag) } else if ( block->height >= 0 && block->height != height ) printf("walkchain height mismatch %d vs %d\n",block->height,height); + iguana_blocksizecheck("walkchain",coin->chain->zcash,block); if ( bits256_nonz(iguana_blockhash(coin,height)) != 0 && bits256_cmp(iguana_blockhash(coin,height),block->RO.hash2) != 0 ) { printf("walk error blockhash error at %d %s\n",height,bits256_str(str,iguana_blockhash(coin,height))); @@ -409,10 +501,10 @@ struct iguana_block *iguana_fastlink(struct iguana_info *coin,int32_t hwmheight) coin->blocks.maxblocks = (block->height + 1); if ( coin->blocks.maxblocks > coin->longestchain ) coin->longestchain = coin->blocks.maxblocks; - coin->blocks.hwmchain = *block; block->valid = block->mainchain = 1; block->hdrsi = hdrsi, block->bundlei = bundlei; block->height = height; + //printf("set height.%d for bundlei.%d\n",height,bundlei); block->PoW = PoW_from_compact(block->RO.bits,coin->chain->unitval) + prevPoW; block->hh.prev = prev; if ( prev != 0 ) @@ -439,49 +531,60 @@ void iguana_setchain(void *chainparms) printf("RETURN iguana_setchain chainparms.%p\n",chainparms); } -struct iguana_block *_iguana_chainlink(struct iguana_info *coin,struct iguana_block *newblock) +struct iguana_block *_iguana_chainlink(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_block *newblock) { - int32_t valid,bundlei,height=-1; struct iguana_block *hwmchain,*block = 0,*prev=0,*next; - bits256 *hash2p=0; double prevPoW = 0.; struct iguana_bundle *bp; - if ( newblock == 0 ) - return(0); - hwmchain = &coin->blocks.hwmchain; - if ( 0 && hwmchain->height > 0 && ((bp= coin->current) == 0 || hwmchain->height/coin->chain->bundlesize > bp->hdrsi+0*bp->isRT) ) + int32_t valid,bundlei,height=-1; struct iguana_block *hwmchain,*block = 0,*prev=0; + bits256 *hash2p=0; double prevPoW = 0.; + if ( newblock == 0 || newblock->RO.timestamp == 0 || bits256_nonz(newblock->RO.prev_block) == 0 ) return(0); + iguana_blocksizecheck("chainlink new",coin->chain->zcash,newblock); + hwmchain = (struct iguana_block *)&coin->blocks.hwmchain; if ( (block= iguana_blockfind("chainlink",coin,newblock->RO.hash2)) != 0 ) { + iguana_blockcopy(coin->chain->zcash,coin->chain->auxpow,coin,block,newblock); + if ( block->RO.timestamp == 0 ) + block->mainchain = block->valid = block->txvalid = 0; + iguana_blocksizecheck("chainlink",coin->chain->zcash,block); if ( memcmp(coin->chain->genesis_hashdata,block->RO.hash2.bytes,sizeof(bits256)) == 0 ) + { block->PoW = PoW_from_compact(block->RO.bits,coin->chain->unitval), height = 0; + if ( isnan(block->PoW) != 0 ) + block->PoW = 0.; + } else if ( (prev= iguana_blockfind("chainprev",coin,block->RO.prev_block)) != 0 ) { - if ( memcmp(prev->RO.hash2.bytes,coin->blocks.hwmchain.RO.hash2.bytes,sizeof(bits256)) == 0 ) - prev->mainchain = 1; + //if ( memcmp(prev->RO.hash2.bytes,coin->blocks.hwmchain.RO.hash2.bytes,sizeof(bits256)) == 0 ) + // prev->mainchain = 1; + if ( bits256_nonz(prev->RO.hash2) == 0 || (prev->valid == 0 && iguana_blockvalidate(coin,&valid,prev,0) < 0) ) + { + char str[65]; + if ( 0 && bits256_nonz(prev->RO.hash2) != 0 ) + printf("(%s) notready v.%d m.%d h.%d\n",bits256_str(str,prev->RO.hash2),prev->valid,prev->mainchain,prev->height); + return(0); + } else prev->valid = 1; if ( prev->valid != 0 && prev->mainchain != 0 && prev->height >= 0 ) { prevPoW = prev->PoW; block->PoW = PoW_from_compact(block->RO.bits,coin->chain->unitval) + prevPoW; - if ( (next= prev->hh.next) != 0 ) + /*if ( (next= prev->hh.next) != 0 ) { if ( next->mainchain != 0 && block->PoW < next->PoW ) return(0); + //printf("block->PoW %f next %f\n",block->PoW,next->PoW); hwmchain = next; - } + }*/ height = prev->height + 1; } - else - { - //char str[65]; printf("(%s) notready v.%d m.%d h.%d\n",bits256_str(str,prev->RO.hash2),prev->valid,prev->mainchain,prev->height); - return(0); - } } else { - char str[65]; - if ( 0 && bits256_nonz(block->RO.prev_block) != 0 ) - printf("chainlink error: cant find prev.(%s)\n",bits256_str(str,block->RO.prev_block)); - iguana_blockunmark(coin,block,0,-1,0); - //memset(&block->RO.prev_block.bytes,0,sizeof(block->RO.prev_block)); - //getchar(); + if ( bits256_nonz(block->RO.prev_block) != 0 ) + { + //printf("chainlink error: cant find prev.(%s)\n",bits256_str(str,block->RO.prev_block)); + iguana_blockunmark(coin,block,0,-1,0); + //memset(&block->RO.prev_block.bytes,0,sizeof(block->RO.prev_block)); + //getchar(); + } return(0); } //char str[65]; printf("extend? %s.h%d: %.15f vs %.15f ht.%d vs %d\n",bits256_str(str,block->RO.hash2),height,block->PoW,coin->blocks.hwmchain.PoW,height,coin->blocks.hwmchain.height); @@ -498,11 +601,10 @@ struct iguana_block *_iguana_chainlink(struct iguana_info *coin,struct iguana_bl // iguana_blockunmain(coin,prev->hh.next); prev->hh.next = block; } - if ( coin->isRT != 0 || block->height == hwmchain->height ) + if ( coin->isRT != 0 || block->height >= hwmchain->height ) { coin->blocks.maxblocks = (block->height + 1); - coin->blocks.hwmchain = *block; - //printf("[%s] <- ht.%d\n",bits256_str(str,block->hash2),coin->blocks.hwmheight); + //printf("[%s] <- ht.%d %f\n",bits256_str(str,block->RO.hash2),coin->blocks.hwmchain.height,coin->blocks.hwmchain.PoW); char str[65],str2[65]; bits256 zero; memset(&zero,0,sizeof(zero)); bits256_str(str,newblock->RO.hash2); @@ -511,9 +613,9 @@ struct iguana_block *_iguana_chainlink(struct iguana_info *coin,struct iguana_bl else str2[0] = 0; if ( coin->blocks.maxblocks > coin->longestchain ) coin->longestchain = coin->blocks.maxblocks; - if ( 1 && (block->height % 1000) == 0 ) + if ( 0 && (block->height % coin->chain->bundlesize) == 0 ) { - //printf("EXTENDMAIN %s %d <- (%s) n.%u max.%u PoW %f numtx.%d valid.%d\n",str,block->height,str2,hwmchain->height+1,coin->blocks.maxblocks,block->PoW,block->RO.txn_count,block->valid); + printf("EXTENDMAIN %s %d <- (%s) n.%u max.%u PoW %f numtx.%d valid.%d\n",str,block->height,str2,hwmchain->height+1,coin->blocks.maxblocks,block->PoW,block->RO.txn_count,block->valid); //iguana_walkchain(coin); } struct iguana_bundle *bp; int32_t hdrsi; @@ -542,18 +644,23 @@ struct iguana_block *_iguana_chainlink(struct iguana_info *coin,struct iguana_bl { if ( bits256_nonz(bp->hashes[block->height % coin->chain->bundlesize]) != 0 ) { - char str[65],str2[65]; - printf("ERROR: need to fix up bundle for height.%d (%p %p) (%s %s)\n",block->height,block,bp->blocks[block->height % coin->chain->bundlesize],bits256_str(str,block->RO.hash2),bits256_str(str2,bp->hashes[block->height % coin->chain->bundlesize])); - if ( bp == coin->current && coin->RTheight > 0 ) - coin->RTdatabad = 1; - //iguana_bundleremove(coin,bp->hdrsi,0); - //exit(-1); - //getchar(); + if ( bp->blocks[block->height % coin->chain->bundlesize] == 0 && block != 0 ) + bp->blocks[block->height % coin->chain->bundlesize] = block; + else + { + char str[65],str2[65]; + printf("ERROR: need to fix up bundle for height.%d (%p %p) (%s %s)\n",block->height,block,bp->blocks[block->height % coin->chain->bundlesize],bits256_str(str,block->RO.hash2),bits256_str(str2,bp->hashes[block->height % coin->chain->bundlesize])); + //if ( bp == coin->current && coin->RTheight > 0 ) + // coin->RTdatabad = 1; + //iguana_bundleremove(coin,bp->hdrsi,0); + //exit(-1); + //getchar(); + } } iguana_blockunmark(coin,block,bp,block->height % coin->chain->bundlesize,0); iguana_bundlehash2add(coin,0,bp,block->height % coin->chain->bundlesize,block->RO.hash2); } - if ( coin->started != 0 && (block->height % coin->chain->bundlesize) == coin->minconfirms )//&& (block->height > coin->longestchain-coin->chain->bundlesize*2 || ((block->height / coin->chain->bundlesize) % 10) == 9) ) + if ( coin->started != 0 && (block->height % coin->chain->bundlesize) == coin->minconfirms && (block->height > coin->longestchain-coin->chain->bundlesize*2 || ((block->height / coin->chain->bundlesize) % 100) == 9) ) { //printf("savehdrs.[%d] ht.%d\n",bp->hdrsi,block->height); iguana_savehdrs(coin); @@ -562,19 +669,28 @@ struct iguana_block *_iguana_chainlink(struct iguana_info *coin,struct iguana_bl } } block->mainchain = 1; + if ( coin->blocks.pending > 0 ) + coin->blocks.pending--; /*if ( block->serdata != 0 ) { printf(" call process_iguanablock2.%p ht.%d nbits.%08x\n",block->serdata,block->height,*(uint32_t *)&block->serdata[72]); process_iguanablock(block->serdata,CHAINPARMS); }*/ + iguana_blockzcopy(coin->chain->zcash,(void *)&coin->blocks.hwmchain,block); + iguana_RTnewblock(myinfo,coin,block); return(block); } } - } else printf("chainlink error from block.%p\n",block); + } + else + { + char str[65]; + printf("chainlink error from block.%p %s\n",block,bits256_str(str,newblock->RO.hash2)); + } return(0); } -void iguana_blocksetheights(struct iguana_info *coin,struct iguana_block *block) +/*void iguana_blocksetheights(struct iguana_info *coin,struct iguana_block *block) { int32_t height; if ( (height= block->height) < 0 ) @@ -585,9 +701,9 @@ void iguana_blocksetheights(struct iguana_info *coin,struct iguana_block *block) iguana_bundlehash2add(coin,0,coin->bundles[height/coin->chain->bundlesize],height % coin->chain->bundlesize,block->RO.hash2); block = block->hh.next, height++; } -} +}*/ -int32_t iguana_chainextend(struct iguana_info *coin,struct iguana_block *newblock) +int32_t iguana_chainextend(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_block *newblock) { struct iguana_block *block,*prev; int32_t valid,oldhwm; char str[65]; if ( iguana_blockvalidate(coin,&valid,newblock,0) < 0 || valid == 0 ) @@ -599,7 +715,7 @@ int32_t iguana_chainextend(struct iguana_info *coin,struct iguana_block *newbloc { block = iguana_blockhashset("chainextend",coin,-1,newblock->RO.hash2,1); if ( block != newblock ) - iguana_blockcopy(coin,block,newblock); + iguana_blockcopy(coin->chain->zcash,coin->chain->auxpow,coin,block,newblock); block->valid = 1; if ( block->hh.prev == 0 && (prev= iguana_blockfind("extendprev",coin,block->RO.prev_block)) != 0 ) { @@ -622,7 +738,7 @@ int32_t iguana_chainextend(struct iguana_info *coin,struct iguana_block *newbloc { oldhwm = coin->blocks.hwmchain.height; //printf("link.%s\n",bits256_str(str,block->hash2)); - while ( block != 0 && memcmp(block->RO.hash2.bytes,coin->blocks.hwmchain.RO.hash2.bytes,sizeof(bits256)) != 0 && _iguana_chainlink(coin,block) == block && coin->blocks.hwmchain.height != oldhwm ) + while ( block != 0 && memcmp(block->RO.hash2.bytes,coin->blocks.hwmchain.RO.hash2.bytes,sizeof(bits256)) != 0 && _iguana_chainlink(myinfo,coin,block) == block && coin->blocks.hwmchain.height != oldhwm ) { oldhwm = coin->blocks.hwmchain.height; block = block->hh.next; diff --git a/iguana/iguana_bundles.c b/iguana/iguana_bundles.c index faf31f72c..f84969741 100755 --- a/iguana/iguana_bundles.c +++ b/iguana/iguana_bundles.c @@ -143,8 +143,9 @@ int32_t iguana_hash2set(struct iguana_info *coin,char *debugstr,struct iguana_bu { char str2[65],str3[65]; bits256_str(str2,*orighash2p), bits256_str(str3,newhash2); - printf("WARNING iguana_hash2set overwrite [%s] %s with %s [%d:%d]\n",debugstr,str2,str3,bp->hdrsi,bundlei); - *orighash2p = newhash2; + printf("WARNING iguana_hash2set overwrite avoided [%s] %s with %s [%d:%d]\n",debugstr,str2,str3,bp->hdrsi,bundlei); + return(-1); + //*orighash2p = newhash2; // getchar(); // return(-1); } @@ -180,7 +181,7 @@ int32_t iguana_hash2set(struct iguana_info *coin,char *debugstr,struct iguana_bu retval = 0; } else retval = (bundlei >= 0 && bundlei < coin->chain->bundlesize) ? 0 : 1; //printf("set [%d] <- %s\n",bundlei,bits256_str(str,newhash2)); - if ( bits256_cmp(*orighash2p,newhash2) != 0 ) + /*if ( bits256_cmp(*orighash2p,newhash2) != 0 ) { if ( bits256_nonz(*orighash2p) != 0 && bp->bundleheight+bundlei <= coin->blocks.hwmchain.height ) { @@ -191,7 +192,7 @@ int32_t iguana_hash2set(struct iguana_info *coin,char *debugstr,struct iguana_bu } } *orighash2p = newhash2; - } + }*/ return(retval); } @@ -202,25 +203,51 @@ int32_t iguana_bundlehash2add(struct iguana_info *coin,struct iguana_block **blo if ( blockp != 0 ) *blockp = 0; if ( bp == 0 || bits256_nonz(hash2) == 0 ) + { + printf("iguana_bundlehash2add null hash2\n"); return(-1111); + } if ( bits256_nonz(hash2) != 0 && (block= iguana_blockhashset("bundlehash2add",coin,-1,hash2,1)) != 0 ) { if ( bp->blocks[bundlei] != 0 && bp->blocks[bundlei] != block ) { - //printf("bp.[%d]->blocks[%d] mismatch %p != %p\n",bp->hdrsi,bundlei,bp->blocks[bundlei],block); - iguana_blockunmark(coin,block,bp,bundlei,1); - bp->blocks[bundlei] = 0; - return(-1); + if ( block->mainchain != 0 && (block->height % coin->chain->bundlesize) == bundlei && (block->height / coin->chain->bundlesize) == bp->hdrsi ) + { + printf("would have bundle block override [%d:%d]\n",bp->hdrsi,bundlei); + //bp->blocks[bundlei] = block; + //bp->hashes[bundlei] = block->RO.hash2; + } + else if ( block->mainchain == 0 ) + { + /*if ( coin->RTheight > 0 && bp->bundleheight+bundlei > coin->firstRTheight ) + { + if ( bundlei > 1 ) + bundlei -= 2; + if ( bp->bundleheight+bundlei > coin->blocks.hwmchain.height && (block= iguana_blockfind("reset",coin,bp->hashes[0])) != 0 ) + { + iguana_blockzcopy(coin->chain->zcash,(void *)&coin->blocks.hwmchain,block); + printf("RESET HWM to %d ht.%d\n",bp->bundleheight+bundlei,block->height); + return(-1); + } //else printf("couldnt find block at %d\n",bp->bundleheight+bundlei); + } + //else if ( bundlei > 0 ) + if ( bp->blocks[bundlei] != 0 ) + { + printf("bp.[%d]->blocks[%d] mismatch %p != %p\n",bp->hdrsi,bundlei,bp->blocks[bundlei],block); + bp->blocks[bundlei] = 0; + }*/ + iguana_blockunmark(coin,block,bp,bundlei,1); + return(-1); + } } - if ( bits256_nonz(bp->hashes[bundlei]) != 0 && bits256_cmp(bp->hashes[bundlei],block->RO.hash2) != 0 ) + if ( 0 && bits256_nonz(bp->hashes[bundlei]) != 0 && bits256_cmp(bp->hashes[bundlei],block->RO.hash2) != 0 ) { //char str[65],str2[65]; - //printf("bp.[%d]->hashes[%d] mismatch %s != %s%s\n",bp->hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei]),bits256_str(str2,block->RO.hash2),block->mainchain?".main":""); + //printf("B bp.[%d]->hashes[%d] mismatch %s != %s%s\n",bp->hdrsi,bundlei,bits256_str(str,bp->hashes[bundlei]),bits256_str(str2,block->RO.hash2),block->mainchain?".main":""); iguana_blockunmark(coin,block,bp,bundlei,1); bp->blocks[bundlei] = 0; //if ( block->mainchain != 0 ) - // bp->hashes[bundlei] = block->RO.hash2; - + // bp->hashes[bundlei] = block->RO.hash2; return(-1); } /*if ( (block->hdrsi != bp->hdrsi || block->bundlei != bundlei) && (block->hdrsi != 0 || block->bundlei != 0) ) @@ -239,8 +266,8 @@ int32_t iguana_bundlehash2add(struct iguana_info *coin,struct iguana_block **blo { if ( (block->hdrsi != bp->hdrsi || block->bundlei != bundlei) && (block->hdrsi != 0 || block->bundlei != 0) ) { - char str[65]; printf("blockadd warning: %d[%d] main.%d <- %d[%d] %s\n",block->hdrsi,block->bundlei,block->mainchain,bp->hdrsi,bundlei,bits256_str(str,hash2)); - iguana_blockunmark(coin,block,bp,bundlei,block->mainchain != 0); + char str[65]; printf("blockadd warning: %d[%d] main.%d prevent <- %d[%d] %s\n",block->hdrsi,block->bundlei,block->mainchain,bp->hdrsi,bundlei,bits256_str(str,hash2)); + //iguana_blockunmark(coin,block,bp,bundlei,block->mainchain != 0); err |= 2; return(-1); //exit(-1); @@ -295,11 +322,10 @@ int32_t iguana_bundlehash2add(struct iguana_info *coin,struct iguana_block **blo } else err |= 128; if ( err != 0 ) { - printf("bundlehash2add err.%d\n",err); - return(0); - //while ( 1 ) - // sleep(1); - //exit(-1); + static uint32_t counter; + if ( counter++ < 100 ) + printf("bundlehash2add err.%d\n",err); + //return(0); } return(-err); } @@ -387,13 +413,15 @@ struct iguana_txid *iguana_bundletx(struct iguana_info *coin,struct iguana_bundl { static const bits256 zero; int32_t hdrsi,iter; struct iguana_txid *T; int64_t Toffset; char fname[1024]; FILE *fp; struct iguana_ramchaindata rdata,*rptr; - if ( (rptr= bp->ramchain.H.data) != 0 ) + portable_mutex_lock(&coin->special_mutex); + if ( (rptr= bp->ramchain.H.data) != 0 )//|| (bp == coin->current && (rptr= coin->RTramchain.H.data) != 0) ) { - //T = (void *)(long)((long)rptr + (long)rptr->Toffset); T = RAMCHAIN_PTR(rptr,Toffset); *tx = T[txidind]; + portable_mutex_unlock(&coin->special_mutex); return(tx); } + portable_mutex_unlock(&coin->special_mutex); printf("bundletx without ramchain\n"); for (iter=0; iter<2; iter++) { @@ -419,7 +447,7 @@ struct iguana_txid *iguana_bundletx(struct iguana_info *coin,struct iguana_bundl char *iguana_bundleaddrs(struct iguana_info *coin,int32_t hdrsi) { - uint8_t *PKbits; struct iguana_pkhash *P; uint32_t pkind,numpkinds; struct iguana_bundle *bp; struct iguana_ramchain *ramchain; cJSON *retjson; char rmdstr[41]; + uint8_t *PKbits; struct iguana_pkhash *P; uint32_t pkind,numpkinds; struct iguana_bundle *bp; struct iguana_ramchain *ramchain; struct iguana_ramchaindata *rdata; cJSON *retjson; char rmdstr[41]; if ( (bp= coin->bundles[hdrsi]) != 0 ) { if ( 0 && coin->RTramchain_busy != 0 ) @@ -428,14 +456,12 @@ char *iguana_bundleaddrs(struct iguana_info *coin,int32_t hdrsi) return(0); } ramchain = &bp->ramchain;//(bp->isRT != 0) ? &bp->ramchain : &coin->RTramchain; - if ( ramchain->H.data != 0 ) + if ( (rdata= ramchain->H.data) != 0 ) { - numpkinds = ramchain->H.data->numpkinds;//(bp->isRT != 0) ? ramchain->H.data->numpkinds : ramchain->pkind; + numpkinds = rdata->numpkinds;//(bp->isRT != 0) ? rdata->numpkinds : ramchain->pkind; retjson = cJSON_CreateArray(); - PKbits = RAMCHAIN_PTR(ramchain->H.data,PKoffset); - P = RAMCHAIN_PTR(ramchain->H.data,Poffset); - //PKbits = (void *)(long)((long)ramchain->H.data + ramchain->H.data->PKoffset); - //P = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Poffset); + PKbits = RAMCHAIN_PTR(rdata,PKoffset); + P = RAMCHAIN_PTR(rdata,Poffset); for (pkind=0; pkindrmd160,20); @@ -451,22 +477,30 @@ char *iguana_bundleaddrs(struct iguana_info *coin,int32_t hdrsi) void iguana_bundlepurgefiles(struct iguana_info *coin,struct iguana_bundle *bp) { static const bits256 zero; - char fname[1024]; FILE *fp; int32_t subdir,hdrsi,j,lasti,i,m = 0; uint32_t ipbits = 0; + char fname[1024]; FILE *fp; int32_t recvlen,numtx,subdir,hdrsi,j,lasti,i,m = 0; uint32_t ipbits = 0; if ( coin->current != 0 ) lasti = coin->current->hdrsi; else lasti = 0; - if ( bp->purgetime == 0 && time(NULL) > bp->emitfinish+600 && bp->hdrsi < lasti-2 ) + if ( coin->virtualchain != 0 || (bp->purgetime == 0 && time(NULL) > bp->emitfinish+600 && bp->hdrsi < lasti-2) ) { for (j=m=0; jn; j++) { + portable_mutex_lock(&coin->RTmutex); + recvlen = -1; + iguana_RTrawdata(coin,bp->hashes[j],0,&recvlen,&numtx,0); // delete file + portable_mutex_unlock(&coin->RTmutex); if ( iguana_peerfname(coin,&hdrsi,GLOBAL_TMPDIR,fname,ipbits,bp->hashes[j],zero,1,1) >= 0 ) { if ( (fp= fopen(fname,"rb")) != 0 ) { - printf("purge.(%s)\n",fname); + //printf("purge.(%s)\n",fname); fclose(fp); if ( OS_removefile(fname,0) > 0 ) - coin->peers.numfiles--, m++; + { + if ( coin->peers != 0 ) + coin->peers->numfiles--; + m++; + } } } else printf("error removing.(%s)\n",fname); @@ -493,10 +527,13 @@ void iguana_bundlepurgefiles(struct iguana_info *coin,struct iguana_bundle *bp) uint8_t iguana_recentpeers(struct iguana_info *coin,int32_t *capacityp,struct iguana_peer *peers[]) { - struct iguana_peer *addr; uint8_t m; int32_t capacity,i,n = coin->peers.numranked; + struct iguana_peer *addr; uint8_t m; int32_t capacity,i,n; + if ( coin->peers == 0 ) + return(0); + n = coin->peers->numranked; for (i=m=capacity=0; ipeers.ranked[i]) != 0 && addr->dead == 0 && addr->usock >= 0 && addr->msgcounts.verack != 0 && addr->pendblocks < coin->MAXPENDINGREQUESTS ) + if ( (addr= coin->peers->ranked[i]) != 0 && addr->dead == 0 && addr->usock >= 0 && addr->msgcounts.verack != 0 && addr->pendblocks < coin->MAXPENDINGREQUESTS ) { if ( peers != 0 ) peers[m] = addr; @@ -577,6 +614,8 @@ struct iguana_block *iguana_bundleblock(struct iguana_info *coin,bits256 *hash2p int32_t iguana_bundleissuemissing(struct iguana_info *coin,struct iguana_bundle *bp,int32_t priority,double mult) { int32_t i,max,nonz,starti,lasti,firsti,lag,num,n=0; uint32_t now; bits256 hash2; double aveduration; struct iguana_peer *addr; + if ( coin->peers == 0 ) + return(0); starti = coin->current == 0 ? 0 : coin->current->hdrsi; lasti = coin->lastpending == 0 ? starti+coin->MAXBUNDLES : coin->lastpending->hdrsi; if ( bp->hdrsi < starti || bp->hdrsi > lasti || bp->emitfinish != 0 || ((priority > 0 || bp == coin->current) && time(NULL) < bp->missingstime+3) || time(NULL) < bp->missingstime+30 ) @@ -603,7 +642,7 @@ int32_t iguana_bundleissuemissing(struct iguana_info *coin,struct iguana_bundle else if ( lag < 60 ) lag = 60; } - if ( (num= coin->peers.numranked) != 0 ) + if ( (num= coin->peers->numranked) != 0 ) { if ( num > 64 ) max = log2(num * num) + 1; @@ -627,13 +666,13 @@ int32_t iguana_bundleissuemissing(struct iguana_info *coin,struct iguana_bundle iguana_bundleblock(coin,&hash2,bp,i); if ( bits256_nonz(hash2) != 0 ) { - if ( (addr= coin->peers.ranked[rand() % max]) != 0 && addr->usock >= 0 && addr->dead == 0 ) + if ( (addr= coin->peers->ranked[rand() % max]) != 0 && addr->usock >= 0 && addr->dead == 0 ) { struct iguana_blockreq *req = 0; - //if ( bp == coin->current ) - // printf("iguana_bundleissuemissing.[%d:%d]\n",bp->hdrsi,i); + if ( 0 && bp == coin->current ) + printf("iguana_bundleissuemissing.[%d:%d]\n",bp->hdrsi,i); if ( priority > 2 || bp->numsaved > bp->n-10 ) - iguana_sendblockreqPT(coin,addr,bp,i,hash2,0); + iguana_sendblockreqPT(coin,0,bp,i,hash2,0); else { req = mycalloc('y',1,sizeof(*req)); @@ -655,12 +694,12 @@ int32_t iguana_bundleissuemissing(struct iguana_info *coin,struct iguana_bundle iguana_bundleblock(coin,&hash2,bp,firsti); if ( bits256_nonz(hash2) != 0 ) { - if ( (addr= coin->peers.ranked[rand() % max]) != 0 && addr->usock >= 0 && addr->dead == 0 ) + if ( (addr= coin->peers->ranked[rand() % max]) != 0 && addr->usock >= 0 && addr->dead == 0 ) { //if ( bp == coin->current ) // printf("iguana_bundleissuemissing.[%d:%d]\n",bp->hdrsi,i); n++; - iguana_sendblockreqPT(coin,addr,bp,firsti,hash2,0); + iguana_sendblockreqPT(coin,0,bp,firsti,hash2,0); } } } @@ -772,9 +811,11 @@ int32_t iguana_bundleready(struct iguana_info *coin,struct iguana_bundle *bp,int //printf("(%x:%x) ",(uint32_t)block->RO.hash2.ulongs[3],(uint32_t)bp->hashes[i].ulongs[3]); if ( block->txvalid == 0 || block->fpipbits == 0 || block->fpos < 0 || (bp->bundleheight+i > 0 && bits256_nonz(block->RO.prev_block) == 0) || iguana_blockvalidate(coin,&valid,block,1) < 0 ) { + char str[65]; if ( requiredflag != 0 ) printf(">>>>>>> block contents error at ht.%d [%d:%d]\n",bp->bundleheight+i,bp->hdrsi,i); - //char str[65]; patch.(%s) and reissue %s checki.%d vs %d\n",block->fpipbits,bp->bundleheight+i,bits256_str(str,block->RO.prev_block),fname,checki,i); + if ( 0 && bits256_nonz(block->RO.hash2) != 0 ) + printf("patch.%d and reissue prev.%s %d\n",bp->bundleheight+i,bits256_str(str,block->RO.prev_block),i); iguana_blockunmark(coin,block,bp,i,1); } else @@ -793,23 +834,28 @@ int32_t iguana_bundleready(struct iguana_info *coin,struct iguana_bundle *bp,int } fclose(fp); } - else + else if ( 0 ) //#endif { iguana_blockunmark(coin,block,bp,i,1); if ( 0 && requiredflag != 0 ) printf("not ready altpath.(%d %d %d %d %d) [%d:%d]\n",block->txvalid == 0,block->fpipbits == 0 ,block->fpos < 0,(bp->bundleheight+i > 0 && bits256_nonz(block->RO.prev_block) == 0),iguana_blockvalidate(coin,&valid,block,1) < 0,bp->hdrsi,i); } + else + { + iguana_blockunmark(coin,block,bp,i,0); + //printf("cant find (%s)\n",fname); + } } } else { if ( requiredflag != 0 ) printf("no block at [%d:%d]\n",bp->hdrsi,i); - iguana_blockunmark(coin,block,bp,i,0); + iguana_blockunmark(coin,block,bp,i,bp->queued != 0); if ( bp->queued != 0 ) { - printf("error getting block (%d:%d) %p\n",bp->hdrsi,i,block); + //printf("error getting block (%d:%d) %p\n",bp->hdrsi,i,block); return(-1); } } @@ -838,7 +884,7 @@ int32_t iguana_bundlehdr(struct iguana_info *coin,struct iguana_bundle *bp,int32 for (i=0; in; i++) if ( GETBIT(bp->haveblock,i) == 0 ) bp->issued[i] = 0; - //queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); + queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); } iguana_bundleissuemissing(coin,bp,3,1.); /*if ( bp == coin->current ) @@ -896,7 +942,7 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp,int datasize = numhashes = numsaved = numrecv = numcached = minrequests = 0; for (bundlei=0; bundlein; bundlei++) { - if ( bits256_nonz(bp->hashes[bundlei]) > 0 ) + if ( bits256_nonz(bp->hashes[bundlei]) != 0 ) { numhashes++; if ( bp->speculativecache[bundlei] != 0 ) @@ -917,7 +963,23 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp,int numrecv++; datasize += block->RO.recvlen; } - } else printf("hash mismatch [%d:%d]\n",bp->hdrsi,bundlei); + } + else if ( 0 && bits256_nonz(block->RO.hash2) != 0 && bits256_nonz(bp->hashes[bundlei]) != 0 ) + { + printf("hash mismatch [%d:%d]\n",bp->hdrsi,bundlei); + iguana_blockunmark(coin,block,bp,bundlei,1); + if ( bundlei < coin->chain->bundlesize-1 ) + { + if ( (block= iguana_blockfind("mismatch",coin,bp->hashes[bundlei+1])) != 0 ) + { + if ( block->mainchain != 0 ) + { + bp->hashes[bundlei] = block->RO.prev_block; + printf("patch [%d:%d] from next block\n",bp->hdrsi,bundlei); + } + } + } + } } //else printf("[null %d:%d] ",bp->hdrsi,bundlei); } } @@ -963,10 +1025,10 @@ int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp,int return(0); }*/ -int32_t iguana_bundlefinalize(struct iguana_info *coin,struct iguana_bundle *bp,struct OS_memspace *mem,struct OS_memspace *memB) +int32_t iguana_bundlefinalize(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_bundle *bp,struct OS_memspace *mem,struct OS_memspace *memB) { int32_t i; struct iguana_bundle *tmpbp; - if ( iguana_bundleready(coin,bp,0) == bp->n ) + if ( coin->firstRTheight == 0 && iguana_bundleready(coin,bp,0) == bp->n ) { printf(">>>>>>>>>>>>>> EMIT.[%3d] %s | 1st.%-3d h.%-3d c.%-3d s.[%3d] maxB.%d NET.(h%d b%d) %ld:%02ld\n",bp->hdrsi,coin->symbol,coin->current!=0?coin->current->hdrsi:-1,coin->current!=0?coin->current->numhashes:-1,coin->current!=0?coin->current->numcached:-1,coin->current!=0?coin->current->numsaved:-1,coin->MAXBUNDLES,HDRnet,netBLOCKS,(time(NULL)-coin->startutc)/60,(time(NULL)-coin->startutc)%60); if ( bp->emitfinish != 0 ) @@ -975,12 +1037,12 @@ int32_t iguana_bundlefinalize(struct iguana_info *coin,struct iguana_bundle *bp, return(0); } bp->emitfinish = 1; - sleep(1); // make sure new incoming packet didnt overwrite + usleep(100000); // make sure new incoming packet didnt overwrite if ( iguana_bundleready(coin,bp,1) == bp->n ) { - sleep(1); // make sure new incoming packet didnt overwrite + usleep(100000); // make sure new incoming packet didnt overwrite coin->emitbusy++; - if ( iguana_bundlesaveHT(coin,mem,memB,bp,(uint32_t)time(NULL)) == 0 ) + if ( iguana_bundlesaveHT(myinfo,coin,mem,memB,bp,(uint32_t)time(NULL)) == 0 ) { //fprintf(stderr,"emitQ done coin.%p bp.[%d] ht.%d\n",coin,bp->hdrsi,bp->bundleheight); bp->emitfinish = (uint32_t)time(NULL) + 1; @@ -988,7 +1050,7 @@ int32_t iguana_bundlefinalize(struct iguana_info *coin,struct iguana_bundle *bp, coin->numemitted++; for (i=0; in; i++) iguana_hash2set(coin,"bundlefinalize",bp,i,bp->hashes[i]); - /*if ( bp->hdrsi == 0 && iguana_peerblockrequest(coin,coin->blockspace,sizeof(coin->blockspace),0,bp->hashes[0],1) > 0 ) + /*if ( bp->hdrsi == 0 && iguana_peerblockrequest(coin,coin->blockspace,coin->blockspacesize,0,bp->hashes[0],1) > 0 ) printf("GENESIS block validated\n"); else printf("GENESIS didnt validate bp.%p\n",bp);*/ //if ( strcmp("BTC",coin->symbol) != 0 ) @@ -1002,8 +1064,10 @@ int32_t iguana_bundlefinalize(struct iguana_info *coin,struct iguana_bundle *bp, } else { - //fprintf(stderr,"emitQ done coin.%p bp.[%d] ht.%d error\n",coin,bp->hdrsi,bp->bundleheight); + fprintf(stderr,"emitQ done coin.%p bp.[%d] ht.%d error\n",coin,bp->hdrsi,bp->bundleheight); bp->emitfinish = 0; + coin->emitbusy--; + return(0); } coin->emitbusy--; } @@ -1022,13 +1086,13 @@ int32_t iguana_bundlefinalize(struct iguana_info *coin,struct iguana_bundle *bp, return(0); } -int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_bundle *bp,int32_t timelimit,int32_t lag) +int32_t iguana_bundleiters(struct supernet_info *myinfo,struct iguana_info *coin,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_bundle *bp,int32_t timelimit,int32_t lag) { int32_t range,starti,lasti,retval=0,max,counter = 0; struct iguana_bundle *currentbp,*lastbp; if ( coin->started == 0 || coin->active == 0 ) { printf("%s not ready yet\n",coin->symbol); - bp->nexttime = (uint32_t)time(NULL) + 3; + bp->nexttime = (uint32_t)time(NULL) + 1; iguana_bundleQ(coin,bp,1000); return(retval); } @@ -1039,19 +1103,22 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru lastbp = coin->lastpending; starti = currentbp == 0 ? 0 : currentbp->hdrsi; lasti = lastbp == 0 ? coin->bundlescount-1 : lastbp->hdrsi; + range = lasti - starti + 1; iguana_bundlecalcs(coin,bp,lag); - if ( bp->hdrsi == coin->bundlescount-1 ) + if ( coin->blockdepth == 0 && coin->blockdepth == 0 && bp->hdrsi == coin->bundlescount-1 ) iguana_autoextend(coin,bp); if ( 0 && bp->hdrsi == 0 ) printf("ITER utxo.%u now.%u spec.%-4d bundle.%-4d h.%-4d r.%-4d s.%-4d F.%d T.%d issued.%d mb.%d/%d\n",bp->utxofinish,(uint32_t)time(NULL),bp->numspec,bp->bundleheight/coin->chain->bundlesize,bp->numhashes,bp->numrecv,bp->numsaved,bp->emitfinish,timelimit,counter,coin->MAXBUNDLES,coin->bundlescount); - bp->nexttime = (uint32_t)time(NULL) + ((bp->hdrsi > starti) ? cbrt(bp->hdrsi - starti)/10 : 0); + bp->nexttime = (uint32_t)time(NULL) + ((bp->hdrsi > starti) ? 0 : -2); if ( bp->hdrsi == coin->bundlescount-1 || (bp->numhashes < bp->n && bp->bundleheight < coin->longestchain-coin->chain->bundlesize) ) iguana_bundlehdr(coin,bp,starti); else if ( bp->emitfinish == 0 && bp->numsaved >= bp->n ) { - if ( iguana_bundlefinalize(coin,bp,mem,memB) > 0 ) + if ( coin->virtualchain != 0 || iguana_bundlefinalize(myinfo,coin,bp,mem,memB) > 0 ) + { + //printf("bundlefinalized done.[%d]\n",bp->hdrsi); return(0); - //else printf("bundlefinalize not done.[%d]\n",bp->hdrsi); + } retval = 1; } else if ( bp->hdrsi == starti || (bp->hdrsi >= starti && bp->hdrsi <= starti+range) ) @@ -1059,11 +1126,15 @@ int32_t iguana_bundleiters(struct iguana_info *coin,struct OS_memspace *mem,stru max = bp->n; counter = iguana_bundleissuemissing(coin,bp,1,3.); if ( 0 && counter > 0 ) - printf("ITER.rt%d now.%u spec.%-4d bundle.%-4d h.%-4d r.%-4d s.%-4d F.%d T.%d issued.%d mb.%d/%d\n",bp->isRT,(uint32_t)time(NULL),bp->numspec,bp->bundleheight/coin->chain->bundlesize,bp->numhashes,bp->numrecv,bp->numsaved,bp->emitfinish,timelimit,counter,coin->MAXBUNDLES,coin->bundlescount); - } else bp->nexttime += 3; + printf("starti.%d range.%d now.%u spec.%-4d bundle.%-4d h.%-4d r.%-4d s.%-4d F.%d T.%d issued.%d mb.%d/%d\n",starti,range,(uint32_t)time(NULL),bp->numspec,bp->bundleheight/coin->chain->bundlesize,bp->numhashes,bp->numrecv,bp->numsaved,bp->emitfinish,timelimit,counter,coin->MAXBUNDLES,coin->bundlescount); + } else bp->nexttime++; if ( bp->emitfinish <= 1 ) iguana_bundleQ(coin,bp,1000); - else bp->queued = 0; + else + { + //printf("[%d] not queued\n",bp->hdrsi); + bp->queued = 0; + } return(retval); } @@ -1105,7 +1176,7 @@ int32_t iguana_cacheprocess(struct iguana_info *coin,struct iguana_bundle *bp,in iguana_meminit(&coin->internaladdr.TXDATA,"txdata",0,IGUANA_MAXPACKETSIZE*1.5,0); if ( coin->internaladdr.HASHMEM.ptr == 0 ) iguana_meminit(&coin->internaladdr.HASHMEM,"HASHPTRS",0,256,0); - if ( iguana_msgparser(coin,&coin->internaladdr,&coin->internaladdr.RAWMEM,&coin->internaladdr.TXDATA,&coin->internaladdr.HASHMEM,&H,&data[sizeof(recvlen)],recvlen) < 0 ) + if ( iguana_msgparser(coin,&coin->internaladdr,&coin->internaladdr.RAWMEM,&coin->internaladdr.TXDATA,&coin->internaladdr.HASHMEM,&H,&data[sizeof(recvlen)],recvlen,1) < 0 ) printf("error parsing speculativecache.[%d:%d]\n",bp->hdrsi,bundlei); } free(data); @@ -1117,10 +1188,12 @@ int32_t iguana_cacheprocess(struct iguana_info *coin,struct iguana_bundle *bp,in void iguana_unstickhdr(struct iguana_info *coin,struct iguana_bundle *bp,int32_t lag) { int32_t datalen,m,i; uint8_t serialized[512]; char str[65]; struct iguana_peer *addr; - if ( (m= coin->peers.numranked) > 0 && bp->numhashes < bp->n && bp->hdrsi < coin->longestchain/coin->chain->bundlesize && time(NULL) > bp->unsticktime+lag ) + if ( coin->peers == 0 ) + return; + if ( (m= coin->peers->numranked) > 0 && bp->numhashes < bp->n && bp->hdrsi < coin->longestchain/coin->chain->bundlesize && time(NULL) > bp->unsticktime+lag ) { for (i=0; i<10; i++) - if ( (addr= coin->peers.ranked[rand() % m]) != 0 && addr->usock >= 0 && addr->dead == 0 && (datalen= iguana_gethdrs(coin,serialized,coin->chain->gethdrsmsg,bits256_str(str,bp->hashes[0]))) > 0 ) + if ( (addr= coin->peers->ranked[rand() % m]) != 0 && addr->usock >= 0 && addr->dead == 0 && (datalen= iguana_gethdrs(coin,serialized,coin->chain->gethdrsmsg,bits256_str(str,bp->hashes[0]))) > 0 ) { //printf("UNSTICK HDR.[%d]\n",bp->hdrsi); iguana_send(coin,addr,serialized,datalen); @@ -1176,11 +1249,54 @@ void iguana_bundlemissings(struct iguana_info *coin,struct iguana_bundle *bp,uin } } } - -void iguana_bundlestats(struct iguana_info *coin,char *str,int32_t lag) + +int32_t iguana_bundlehash2_check(struct iguana_info *coin,bits256 hash2) +{ + struct iguana_bundle *bp; int32_t j,flag=0; struct iguana_block *block; + if ( bits256_nonz(hash2) == 0 ) + return(-1); + if ( (bp= coin->current) != 0 ) + { + for (j=0; jn; j++) + { + if ( j < bp->numspec && bp->speculative != 0 && bits256_cmp(bp->speculative[j],hash2) == 0 ) + { + flag = 1; + if ( (block= iguana_blockfind("hashspec",coin,hash2)) != 0 ) + { + if ( block->mainchain != 0 && block->txvalid != 0 && block->hdrsi != bp->hdrsi ) + { + printf("found [%d:%d] in [%d:%d]'s place\n",block->hdrsi,block->bundlei,bp->hdrsi,j); + memset(&bp->speculative[j],0,sizeof(bp->speculative[j])); + } + } + break; + } + if ( bits256_cmp(bp->hashes[j],hash2) == 0 ) + { + flag = 1; + if ( (block= iguana_blockfind("hashspec",coin,hash2)) != 0 ) + { + if ( block->mainchain != 0 && block->txvalid != 0 && block->hdrsi != bp->hdrsi ) + { + printf("found [%d:%d] in [%d:%d]'s place\n",block->hdrsi,block->bundlei,bp->hdrsi,j); + memset(&bp->hashes[j],0,sizeof(bp->hashes[j])); + bp->blocks[j] = 0; + } + } + break; + } + } + } + return(flag); +} + +void iguana_bundlestats(struct supernet_info *myinfo,struct iguana_info *coin,char *str,int32_t lag) { int32_t i,n,m,j,numv,numconverted,count,starti,lasti,pending,capacity,displag,numutxo,numbalances,numrecv,done,numhashes,numcached,numsaved,numemit; struct iguana_block *block; bits256 hash2; - int64_t spaceused=0,estsize = 0; struct iguana_bundle *currentbp,*lastbp,*bp,*lastpending = 0,*firstgap = 0; uint32_t now; + int64_t spaceused=0,estsize = 0; struct iguana_bundle *currentbp,*lastbp,*bp,*lastpending = 0,*firstgap = 0; uint32_t now; + if ( coin->bundlescount <= 0 ) + return; now = (uint32_t)time(NULL); displag = (now - coin->lastdisp); numrecv = numhashes = numcached = numconverted = numsaved = numemit = done = numutxo = numbalances = 0; @@ -1203,7 +1319,7 @@ void iguana_bundlestats(struct iguana_info *coin,char *str,int32_t lag) { if ( (block= iguana_bundleblock(coin,&hash2,bp,j)) == 0 && bits256_nonz(hash2) != 0 ) block = iguana_blockfind("bundlestats",coin,hash2); - if ( block == 0 || bits256_nonz(block->RO.prev_block) == 0 || _iguana_chainlink(coin,block) == 0 ) + if ( block == 0 || bits256_nonz(block->RO.prev_block) == 0 || _iguana_chainlink(myinfo,coin,block) == 0 ) break; } } @@ -1306,21 +1422,26 @@ void iguana_bundlestats(struct iguana_info *coin,char *str,int32_t lag) coin->numremain = n; coin->blocksrecv = numrecv; uint64_t tmp; int32_t diff,p = 0; struct tai difft,t = tai_now(); - for (i=0; ipeers.active[i].usock >= 0 ) - p++; + if ( coin->peers != 0 ) + { + for (i=0; ipeers->active[i].usock > 0 ) + p++; + } diff = (int32_t)time(NULL) - coin->startutc; difft.x = (t.x - coin->starttime.x), difft.millis = (t.millis - coin->starttime.millis); tmp = (difft.millis * 1000000); tmp %= 1000000000; difft.millis = ((double)tmp / 1000000.); - if ( (bp= firstgap) != coin->current && bp != 0 )//&& coin->PREFETCHLAG < 0 ) + if ( (bp= firstgap) != 0 )//&& coin->PREFETCHLAG < 0 ) { - printf("new 1st.%d\n",bp->hdrsi); + if ( bp != coin->current ) + printf("new 1st.%d\n",bp->hdrsi); + //else printf("issue 1st.%d\n",bp->hdrsi); for (i=0; in; i++) if ( GETBIT(bp->haveblock,i) == 0 ) bp->issued[i] = 0; - iguana_bundleissuemissing(coin,bp,3,1.); + iguana_bundleissuemissing(coin,bp,1 + (rand() % 3),1.); } if ( (coin->current= firstgap) == 0 ) { @@ -1383,7 +1504,9 @@ void iguana_bundlestats(struct iguana_info *coin,char *str,int32_t lag) coin->stucktime = coin->stuckiters = 0; if ( coin->stucktime != 0 && time(NULL)-coin->stucktime > coin->maxstuck ) coin->maxstuck = (uint32_t)time(NULL) - coin->stucktime; - sprintf(str,"%s.RT%d u.%d+c.%d b.%d v.%d (%d+%d/%d 1st.%d).s%d to %d N[%d] h.%d r.%d c.%d s.%d d.%d E.%d maxB.%d peers.%d/%d Q.(%d %d) (L.%d %d:%d) M.%d %s",coin->symbol,coin->RTheight,numutxo,numconverted,numbalances,iguana_validated(coin),firstgap!=0?firstgap->numcached:-1,firstgap!=0?firstgap->numsaved:-1,firstgap!=0?firstgap->numhashes:-1,firstgap!=0?firstgap->hdrsi:-1,firstgap!=0?firstgap->numspec:-1,coin->lastpending!=0?coin->lastpending->hdrsi:0,count,numhashes,coin->blocksrecv,numcached,numsaved,done,numemit,coin->MAXBUNDLES,p,coin->MAXPEERS,queue_size(&coin->priorityQ),queue_size(&coin->blocksQ),coin->longestchain,coin->longestchain/coin->chain->bundlesize,coin->longestchain%coin->chain->bundlesize,coin->blocks.hwmchain.height,bits256_str(str5,coin->blocks.hwmchain.RO.hash2)); + sprintf(str,"%s.RT%d u.%d+c.%d b.%d v.%d (%d+%d/%d 1st.%d).s%d to %d N[%d] h.%d r.%d c.%d s.%d d.%d E.%d maxB.%d peers.%d/%d Q.(%d %d) (L.%d %d:%d) M.%d %s ledger.%08llx supply %.8f",coin->symbol,coin->RTheight,numutxo,numconverted,numbalances,iguana_validated(coin),firstgap!=0?firstgap->numcached:-1,firstgap!=0?firstgap->numsaved:-1,firstgap!=0?firstgap->numhashes:-1,firstgap!=0?firstgap->hdrsi:-1,firstgap!=0?firstgap->numspec:-1,coin->lastpending!=0?coin->lastpending->hdrsi:0,count,numhashes,coin->blocksrecv,numcached,numsaved,done,numemit,coin->MAXBUNDLES,p,coin->MAXPEERS,queue_size(&coin->priorityQ),queue_size(&coin->blocksQ),coin->longestchain,coin->longestchain/coin->chain->bundlesize,coin->longestchain%coin->chain->bundlesize,coin->blocks.hwmchain.height,bits256_str(str5,coin->blocks.hwmchain.RO.hash2),(long long)coin->utxoaddrhash.txid,dstr(coin->histbalance)+dstr(coin->RTcredits)-dstr(coin->RTdebits)); +//if( strcmp("BTC",coin->symbol) == 0 ) +// printf("%s\n",str); if ( coin->current != 0 && coin->current->hdrsi == coin->longestchain/coin->chain->bundlesize && numemit == coin->current->hdrsi && numutxo == coin->bundlescount-1 ) { //printf("have all utxo, generate balances\n"); @@ -1403,14 +1526,31 @@ void iguana_bundlestats(struct iguana_info *coin,char *str,int32_t lag) } } //sprintf(str+strlen(str),"%s.%-2d %s time %.2f files.%d Q.%d %d\n",coin->symbol,flag,str,(double)(time(NULL)-coin->starttime)/60.,coin->peers.numfiles,queue_size(&coin->priorityQ),queue_size(&coin->blocksQ)); - if ( time(NULL) > coin->lastdisp+7 && (strcmp(str,coin->lastdispstr) != 0 || time(NULL) > coin->lastdisp+60) ) + if ( time(NULL) > coin->lastdisp+30 && (strcmp(str,coin->lastdispstr) != 0 || time(NULL) > coin->lastdisp+60) ) { - printf("%s bQ.%d %d:%02d:%02d stuck.%d max.%d\n",str,queue_size(&bundlesQ),(int32_t)difft.x/3600,(int32_t)(difft.x/60)%60,(int32_t)difft.x%60,coin->stucktime!=0?(uint32_t)time(NULL) - coin->stucktime:0,coin->maxstuck); + static FILE *logfp; + if ( logfp == 0 ) + logfp = fopen("debug.log","wb"); + if ( logfp != 0 ) + { + fprintf(logfp,"%s bQ.%d %d:%02d:%02d stuck.%d max.%d\n",str,queue_size(&bundlesQ),(int32_t)difft.x/3600,(int32_t)(difft.x/60)%60,(int32_t)difft.x%60,coin->stucktime!=0?(uint32_t)time(NULL) - coin->stucktime:0,coin->maxstuck); + fflush(logfp); + } + //printf("%s bQ.%d %d:%02d:%02d stuck.%d max.%d\n",str,queue_size(&bundlesQ),(int32_t)difft.x/3600,(int32_t)(difft.x/60)%60,(int32_t)difft.x%60,coin->stucktime!=0?(uint32_t)time(NULL) - coin->stucktime:0,coin->maxstuck); strcpy(coin->lastdispstr,str); if ( (rand() % 100) == 0 ) myallocated(0,0); coin->lastdisp = (uint32_t)time(NULL); } + if ( 0 && (bp= coin->current) != 0 && coin->RTheight >= bp->bundleheight && coin->RTheight < bp->bundleheight+bp->n ) + { + for (i=coin->RTheight-bp->bundleheight; in; i++) + { + iguana_bundlehash2_check(coin,bp->hashes[i]); + if ( bp->speculative != 0 ) + iguana_bundlehash2_check(coin,bp->speculative[i]); + } + } iguana_setmaxbundles(coin); strcpy(coin->statusstr,str); coin->estsize = estsize; diff --git a/iguana/iguana_chains.c b/iguana/iguana_chains.c index 38d63d499..d2c05b78f 100755 --- a/iguana/iguana_chains.c +++ b/iguana/iguana_chains.c @@ -26,7 +26,7 @@ static struct iguana_chain Chains[] = { - //[CHAIN_TESTNET3] = + /*//[CHAIN_TESTNET3] = { //CHAIN_TESTNET3, "testnet3", "tBTC", "Bitcoin Signed Message:\n", // strMessageMagic @@ -35,23 +35,24 @@ static struct iguana_chain Chains[] = "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943", "0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5494dffff001d1aa4ae180101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000", 18333,18334,0, - }, + },*/ + // curl --data '{"jsonrpc": "2.0", "method": "get_order_book", "params": [], "id": 1}' http://127.0.0.1:8090/rpc //[CHAIN_BITCOIN] = { //CHAIN_BITCOIN, - "bitcoin", "BTC", "Bitcoin Signed Message:\n", // strMessageMagic + "Bitcoin", "BTC", "Bitcoin Signed Message:\n", // strMessageMagic 0, 5, 0x80, "\xf9\xbe\xb4\xd9", "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f", "0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49ffff001d1dac2b7c0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000", - 8333,8334,0,0x1d, + 8333,8332,0,0x1d, { { 210000, (50 * SATOSHIDEN) }, { 420000, (50 * SATOSHIDEN) / 2 }, { 630000, (50 * SATOSHIDEN) / 4 },{ 840000, (50 * SATOSHIDEN) / 8 }, } }, //[CHAIN_BTCD] = { //CHAIN_BTCD, - "btcd", "BTCD", "BitcoinDark Signed Message:\n", // strMessageMagic + "BitcoinDark", "BTCD", "BitcoinDark Signed Message:\n", // strMessageMagic PUBKEY_ADDRESS_BTCD, SCRIPT_ADDRESS_BTCD, PRIVKEY_ADDRESS_BTCD, "\xe4\xc2\xd8\xe6", "0000044966f40703b516c5af180582d53f783bfd319bb045e2dc3e05ea695d46", @@ -60,9 +61,13 @@ static struct iguana_chain Chains[] = 14631,14632,1,0x1e, { { 12000, (80 * SATOSHIDEN) }, } }, - //[CHAIN_VPN] = + //curl --url "http://127.0.0.1:7778" --data "{\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"poll\":10,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":8,\"endpend\":8,\"services\":129,\"maxpeers\":256,\"newcoin\":\"VPN\",\"name\":\"VPNcoin\",\"hasheaders\":1,\"useaddmultisig\":0,\"txhastimestamp\":1,\"minoutput\":10000,\"minconfirms\":2,\"txfee_satoshis\":\"10000\",\"genesishash\":\"00000ac7d764e7119da60d3c832b1d4458da9bc9ef9d5dd0d91a15f690a46d99\",\"genesis\":{\"version\":1,\"timestamp\":1409839200,\"nBits\":\"1e0fffff\",\"nonce\":64881664,\"merkle_root\":\"698a93a1cacd495a7a4fb3864ad8d06ed4421dedbc57f9aaad733ea53b1b5828\"},\"protover\":70002,\"netmagic\":\"fbc0b6db\",\"p2p\":1920,\"rpc\":1921,\"pubval\":71,\"p2shval\":5,\"wifval\":199}" + + //iguana_chaingenesis("VPN",0,bits256_conv("00000ac7d764e7119da60d3c832b1d4458da9bc9ef9d5dd0d91a15f690a46d99"),genesisblock,"scrypt",1,1409839200,0x1e0fffff,64881664,bits256_conv("698a93a1cacd495a7a4fb3864ad8d06ed4421dedbc57f9aaad733ea53b1b5828")); // VPN + + /*//[CHAIN_VPN] = { - "vpncoin", "VPN", "VPNcoin Signed Message:\n", // strMessageMagic + "VPNcoin", "VPN", "VPNcoin Signed Message:\n", // strMessageMagic 71, 5, 199, // PUBKEY_ADDRESS + SCRIPT_ADDRESS addrman.h, use wif2priv API on any valid wif "\xfb\xc0\xb6\xdb", // pchMessageStart main.cpp //"aaea16b9b820180153d9cd069dbfd54764f07cb49c71987163132a72d568cb14", @@ -70,16 +75,18 @@ static struct iguana_chain Chains[] = "01000000000000000000000000000000000000000000000000000000000000000000000028581b3ba53e73adaaf957bced1d42d46ed0d84a86b34f7a5a49cdcaa1938a6940540854ffff0f1e78b20100010100000040540854010000000000000000000000000000000000000000000000000000000000000000ffffffff2404ffff001d01041c5468752c20342053657020323031342031323a30303a303020474d54ffffffff01000000000000000000000000000000", 1920,1921,1,0x1e // port and rpcport vpncoin.conf }, - //[CHAIN_LTC] = + + //[CHAIN_LTC] = { - "litecoin", "LTC", "Litecoin Signed Message:\n", + "Litecoin", "LTC", "Litecoin Signed Message:\n", 0, 5, 176, // PUBKEY_ADDRESS + SCRIPT_ADDRESS addrman.h, use wif2priv API on any valid wif "\xfb\xc0\xb6\xdb", // pchMessageStart main.cpp //"12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2", "12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2", - "010000000000000000000000000000000000000000000000000000000000000000000000d9ced4ed1130f7b7faad9be25323ffafa33232a17c3edf6cfd97bee6bafbdd97b9aa8e4ef0ff0f1ecd513f7c0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4804ffff001d0104404e592054696d65732030352f4f63742f32303131205374657665204a6f62732c204170706c65e280997320566973696f6e6172792c2044696573206174203536ffffffff0100f2052a010000004341040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9ac00000000", + //010000000000000000000000000000000000000000000000000000000000000000000000d9ced4ed1130f7b7faad9be25323ffafa33232a17c3edf6cfd97bee6bafbdd97b9aa8e4ef0ff0f1ecd513f7c + "010000000000000000000000000000000000000000000000000000000000000000000000d9ced4ed1130f7b7faad9be25323ffafa33232a17c3edf6cfd97bee6bafbdd97b9aa8e4ef0ff0f1ecd513f7c0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4804ffff001d0104404e592054696d65732030352f4f63742f32303131205374657665204a6f62732c204170706c65e280997320566973696f6e6172792c2044696573206174203536ffffffff0100f2052a010000004341040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9ac00000000", 9333,9334,0,0x1e // port and rpcport litecoin.conf - }, + },*/ }; /* @@ -105,15 +112,20 @@ int32_t blockhash_sha256(uint8_t *blockhashp,uint8_t *serialized,int32_t len) int32_t blockhash_scrypt(uint8_t *blockhashp,uint8_t *serialized,int32_t len) { - bits256 hash; - vcalc_sha256(0,hash.bytes,serialized,len); - printf("need to implement scrypt hash here\n"); - exit(-1); + if ( len == 80 ) + { + calc_scrypthash((uint32_t *)blockhashp,serialized); + //*(bits256 *)blockhashp = scrypt_blockhash(serialized); + //int32_t i; for (i=0; i<32; i++) + // printf("%02x",blockhashp[i]); + //printf(" scrypt\n"); + } else memset(blockhashp,0,sizeof(*blockhashp)); return(sizeof(bits256)); } blockhashfunc iguana_hashalgo(char *hashalgostr) { + return(blockhash_sha256); // all coins seem to use this for the actual blockchain data if ( hashalgostr == 0 || hashalgostr[0] == 0 || strcmp(hashalgostr,"sha256") == 0 ) return(blockhash_sha256); else if ( strcmp(hashalgostr,"scrypt") == 0 ) @@ -122,29 +134,55 @@ blockhashfunc iguana_hashalgo(char *hashalgostr) return(0); } -bits256 iguana_chaingenesis(bits256 genesishash,char *genesisblock,char *hashalgostr,int32_t version,uint32_t timestamp,uint32_t nBits,uint32_t nonce,bits256 merkle_root) +bits256 iguana_calcblockhash(char *symbol,int32_t (*hashalgo)(uint8_t *blockhashp,uint8_t *serialized,int32_t len),uint8_t *serialized,int32_t len) +{ + bits256 tmp,hash2; int32_t i; + memset(&hash2,0,sizeof(hash2)); + if ( (*hashalgo)(tmp.bytes,serialized,len) != sizeof(bits256) ) + memset(tmp.bytes,0,sizeof(hash2)); + else if ( hashalgo == blockhash_sha256 ) + { + for (i=0; i<32; i++) + hash2.bytes[i] = tmp.bytes[31 - i]; + } else return(tmp); + /*if ( hashalgo == blockhash_scrypt ) + { + char str[65]; bits256 checkhash2; struct iguana_msgblock msg; struct iguana_block *block; struct iguana_info *coin; + if ( (coin= iguana_coinfind(symbol)) != 0 ) + { + iguana_rwblock(symbol,hashalgo,0,&checkhash2,serialized,&msg); + if ( (block= iguana_blockfind("hashalgo",coin,msg.H.prev_block)) != 0 ) + { + hash2 = iguana_blockhash(coin,block->height+1); + printf("sethash2.(%s)\n",bits256_str(str,hash2)); + } + } + }*/ + return(hash2); +} + +bits256 iguana_chaingenesis(char *symbol,uint8_t zcash,uint8_t auxpow,int32_t (*hashalgo)(uint8_t *blockhashp,uint8_t *serialized,int32_t len),bits256 genesishash,char *genesisblock,char *hashalgostr,int32_t version,uint32_t timestamp,uint32_t nBits,uint32_t nonce,bits256 merkle_root) { - struct iguana_msgblock msg; int32_t len,blockhashlen; bits256 hash2; - char blockhashstr[256],str3[65]; uint8_t serialized[1024],blockhash[256]; - int32_t (*hashalgo)(uint8_t *blockhashp,uint8_t *serialized,int32_t len); + struct iguana_msgblock msg; int32_t len; bits256 hash2; char blockhashstr[256]; uint8_t serialized[8192]; memset(&msg,0,sizeof(msg)); msg.H.version = version; msg.H.merkle_root = merkle_root; msg.H.timestamp = timestamp; msg.H.bits = nBits; msg.H.nonce = nonce; - len = iguana_rwblock(1,&hash2,serialized,&msg); + if ( zcash != 0 ) + printf("need to handle zcash genesis\n"); + if ( hashalgostr != 0 && strcmp(hashalgostr,"sha256") != 0 ) + hashalgo = iguana_hashalgo(hashalgostr); + else hashalgo = blockhash_sha256; + len = iguana_rwblock(symbol,zcash,auxpow,hashalgo,1,&hash2,serialized,&msg,sizeof(1024)); blockhashstr[0] = 0; - if ( hashalgostr != 0 && strcmp(hashalgostr,"sha256") != 0 && (hashalgo= iguana_hashalgo(hashalgostr)) != 0 ) - { - if ( (blockhashlen= (*hashalgo)(blockhash,serialized,len)) > 0 ) - init_hexbytes_noT(blockhashstr,blockhash,blockhashlen); - } else init_hexbytes_noT(blockhashstr,hash2.bytes,sizeof(hash2)); + init_hexbytes_noT(blockhashstr,hash2.bytes,sizeof(hash2)); char str[65],str2[65]; if ( bits256_cmp(genesishash,hash2) != 0 ) - printf("WARNING: genesishash.(%s) mismatch vs calc.(%s)\n",bits256_str(str,genesishash),bits256_str(str2,genesishash)); + printf("WARNING: genesishash.(%s) mismatch vs calc.(%s)\n",bits256_str(str,genesishash),bits256_str(str2,hash2)); init_hexbytes_noT(genesisblock,serialized,len); - printf("v.%d t.%u %s nBits.%08x nonce.%u merkle.(%s) genesis.(%s) hash2.(%s) blockhash.(%s) size.%d\n",version,timestamp,utc_str(str3,timestamp),nBits,nonce,bits256_str(str2,merkle_root),genesisblock,bits256_str(str,hash2),blockhashstr,(int32_t)strlen(genesisblock)/2); + //printf("v.%d t.%u %s nBits.%08x nonce.%u merkle.(%s) genesis.(%s) hash2.(%s) blockhash.(%s) size.%d\n",version,timestamp,utc_str(str3,timestamp),nBits,nonce,bits256_str(str2,merkle_root),genesisblock,bits256_str(str,hash2),blockhashstr,(int32_t)strlen(genesisblock)/2); return(hash2); } @@ -185,8 +223,9 @@ char *default_coindir(char *confname,char *coinstr) void set_coinconfname(char *fname,char *coinstr,char *userhome,char *coindir,char *confname) { char buf[64]; - if ( coindir == 0 || coindir[0] == 0 ) + if ( coindir == 0 || coindir[0] == 0 || confname == 0 || confname[0] == 0 ) coindir = default_coindir(buf,coinstr); + else buf[0] = 0; if ( confname == 0 || confname[0] == 0 ) { confname = buf; @@ -200,11 +239,11 @@ uint16_t extract_userpass(char *serverport,char *userpass,char *coinstr,char *us { FILE *fp; uint16_t port = 0; char fname[2048],line[1024],*rpcuser,*rpcpassword,*rpcport,*str; - if ( strcmp(coinstr,"NXT") == 0 ) + if ( strcmp(coinstr,"NXT") == 0 || coindir == 0 || confname == 0 || coindir[0] == 0 || confname[0] == 0 ) return(0); serverport[0] = userpass[0] = 0; set_coinconfname(fname,coinstr,userhome,coindir,confname); - printf("set_coinconfname.(%s)\n",fname); + printf("set_coinconfname.(%s) <- (%s)\n",fname,confname); if ( (fp= fopen(OS_compatible_path(fname),"r")) != 0 ) { if ( Debuglevel > 1 ) @@ -248,56 +287,110 @@ uint16_t extract_userpass(char *serverport,char *userpass,char *coinstr,char *us void iguana_chainparms(struct iguana_chain *chain,cJSON *argjson) { extern char Userhome[]; - char *path,*conf,*hexstr,genesisblock[1024]; bits256 hash; uint16_t port; cJSON *rpair,*genesis,*rewards,*item; int32_t i,n,m; uint32_t nBits; uint8_t tmp[4]; + char *path,conf[512],*hexstr,genesisblock[1024]; uint16_t port; cJSON *rpair,*genesis,*rewards,*item; int32_t i,n,m; uint32_t nBits; uint8_t tmp[4]; + //printf("chainparams.(%s)\n",jprint(argjson,0)); if ( strcmp(chain->symbol,"NXT") != 0 ) { - if ( strcmp(chain->symbol,"BTC") != 0 ) - { - if ( strcmp(chain->symbol,"LTC") == 0 ) - chain->pubtype = 48, chain->p2shtype = 5, chain->minconfirms = 1, chain->txfee = 100000; - else if ( strcmp(chain->symbol,"BTCD") == 0 ) - chain->pubtype = 60, chain->p2shtype = 85; - else if ( strcmp(chain->symbol,"DOGE") == 0 ) - chain->pubtype = 30, chain->p2shtype = 35, chain->txfee = SATOSHIDEN; - else if ( strcmp(chain->symbol,"VRC") == 0 ) - chain->pubtype = 70, chain->p2shtype = 85; - else if ( strcmp(chain->symbol,"OPAL") == 0 ) - chain->pubtype = 115, chain->p2shtype = 28; - else if ( strcmp(chain->symbol,"BITS") == 0 ) - chain->pubtype = 25, chain->p2shtype = 8; - } - chain->minoutput = j64bits(argjson,"minoutput"); + if ( strcmp(chain->symbol,"BTCD") == 0 ) + chain->pubtype = 60, chain->p2shtype = 85, chain->portp2p = 14631, chain->rpcport = 14632; + else if ( strcmp(chain->symbol,"BTC") == 0 ) + chain->pubtype = 0, chain->p2shtype = 5, chain->portp2p = 8333, chain->rpcport = 8332; + else chain->do_opreturn = juint(argjson,"do_opreturn"); + if ( (chain->minoutput= j64bits(argjson,"minoutput")) == 0 ) + chain->minoutput = 10000; chain->minconfirms = juint(argjson,"minconfirms"); - chain->estblocktime = juint(argjson,"estblocktime"); + if ( (chain->estblocktime= juint(argjson,"estblocktime")) == 0 ) + chain->estblocktime = juint(argjson,"blocktime"); + if ( chain->estblocktime == 0 ) + chain->estblocktime = 60; + if ( chain->havecltv == 0 ) + chain->havecltv = juint(argjson,"havecltv"); path = jstr(argjson,"path"); - conf = jstr(argjson,"conf"); - chain->dust = j64bits(argjson,"dust"); + if ( jobj(argjson,"conf") == 0 ) + conf[0] = 0; + else safecopy(conf,jstr(argjson,"conf"),sizeof(conf)); + if ( conf[0] != 0 ) + printf("CONF.(%s)\n",conf); + safecopy(chain->name,jstr(argjson,"name"),sizeof(chain->name)); + //chain->dust = j64bits(argjson,"dust"); if ( jobj(argjson,"txfee_satoshis") != 0 ) chain->txfee = j64bits(argjson,"txfee_satoshis"); if ( chain->txfee == 0 ) chain->txfee = (uint64_t)(SATOSHIDEN * jdouble(argjson,"txfee")); chain->use_addmultisig = juint(argjson,"useaddmultisig"); - chain->do_opreturn = juint(argjson,"do_opreturn"); - if ( jobj(argjson,"hastimestamp") != 0 ) - chain->hastimestamp = juint(argjson,"hastimestamp"); - else if ( jobj(argjson,"oldtx_format") != 0 ) - chain->hastimestamp = !juint(argjson,"oldtx_format"); + if ( juint(argjson,"p2p") != 0 ) + chain->portp2p = juint(argjson,"p2p"); + else chain->portp2p = juint(argjson,"portp2p"); + if ( (chain->rpcport= juint(argjson,"rpc")) == 0 ) + { + if ( chain->portp2p != 0 ) + chain->rpcport = chain->portp2p-1; + } + if ( chain->portp2p == 0 ) + { + if ( strcmp("BTC",chain->symbol) == 0 ) + chain->portp2p = 8333; + else if ( strcmp("BTCD",chain->symbol) == 0 ) + chain->portp2p = 14631; + } + if ( chain->rpcport == 0 ) + { + if ( strcmp("BTC",chain->symbol) == 0 ) + chain->rpcport = 8332; + else if ( strcmp("BTCD",chain->symbol) == 0 ) + chain->rpcport = 14632; + } + chain->zcash = juint(argjson,"zcash"); + if ( (chain->normal_txversion= juint(argjson,"normal_txversion")) == 0 ) + chain->normal_txversion = IGUANA_NORMAL_TXVERSION; + if ( (chain->locktime_txversion= juint(argjson,"locktime_txversion")) == 0 ) + chain->locktime_txversion = IGUANA_LOCKTIME_TXVERSION; + if ( jobj(argjson,"isPoS") != 0 ) + chain->isPoS = juint(argjson,"isPoS"); if ( jstr(argjson,"userhome") != 0 ) strcpy(chain->userhome,jstr(argjson,"userhome")); else strcpy(chain->userhome,Userhome); + if ( (chain->protover= juint(argjson,"protover")) == 0 ) + chain->protover = PROTOCOL_VERSION; + chain->auxpow = juint(argjson,"auxpow"); + if ( (chain->targetspacing= jint(argjson,"targetspacing")) == 0 ) + chain->targetspacing = NTARGETSPACING; + if ( (chain->targettimespan= jint(argjson,"targettimespan")) == 0 ) + chain->targettimespan = NTARGETSPACING * 60; if ( (port= extract_userpass(chain->serverport,chain->userpass,chain->symbol,chain->userhome,path,conf)) != 0 ) chain->rpcport = port; - printf("COIN.%s serverport.(%s) userpass.(%s) port.%u\n",chain->symbol,chain->serverport,chain->userpass,chain->rpcport); - if ( (hexstr= jstr(argjson,"pubval")) != 0 && strlen(hexstr) == 2 ) - decode_hex((uint8_t *)&chain->pubtype,1,hexstr); - if ( (hexstr= jstr(argjson,"scriptval")) != 0 && strlen(hexstr) == 2 ) - decode_hex((uint8_t *)&chain->p2shtype,1,hexstr); - if ( (hexstr= jstr(argjson,"wiftype")) != 0 && strlen(hexstr) == 2 ) - decode_hex((uint8_t *)&chain->wiftype,1,hexstr); + if ( jobj(argjson,"halving") != 0 ) + chain->halvingduration = juint(argjson,"halving"); + else chain->halvingduration = 210000; + if ( jobj(argjson,"reward") != 0 ) + chain->initialreward = jdouble(argjson,"reward") * SATOSHIDEN; + else chain->initialreward = 50 * SATOSHIDEN; + if ( chain->serverport[0] == 0 ) + sprintf(chain->serverport,"127.0.0.1:%u",chain->rpcport); + if ( strcmp(chain->symbol,"BTC") != 0 && strcmp(chain->symbol,"BTCD") != 0 ) + { + chain->pubtype = juint(argjson,"pubval"); + chain->p2shtype = juint(argjson,"p2shval"); + chain->wiftype = juint(argjson,"wifval"); + if ( chain->pubtype == 0 && chain->p2shtype == 0 && chain->wiftype == 0 ) + { + if ( (hexstr= jstr(argjson,"pubval")) != 0 && strlen(hexstr) == 2 ) + decode_hex((uint8_t *)&chain->pubtype,1,hexstr); + if ( (hexstr= jstr(argjson,"scriptval")) != 0 && strlen(hexstr) == 2 ) + decode_hex((uint8_t *)&chain->p2shtype,1,hexstr); + else if ( (hexstr= jstr(argjson,"p2shval")) != 0 && strlen(hexstr) == 2 ) + decode_hex((uint8_t *)&chain->p2shtype,1,hexstr); + if ( (hexstr= jstr(argjson,"wifval")) != 0 && strlen(hexstr) == 2 ) + decode_hex((uint8_t *)&chain->wiftype,1,hexstr); + } + } + printf("addrtypes.(%02x %02x %02x) (%d %d %d)\n",chain->pubtype,chain->p2shtype,chain->wiftype,chain->pubtype,chain->p2shtype,chain->wiftype); if ( (hexstr= jstr(argjson,"netmagic")) != 0 && strlen(hexstr) == 8 ) - decode_hex((uint8_t *)chain->netmagic,1,hexstr); + decode_hex((uint8_t *)chain->netmagic,4,hexstr); if ( (hexstr= jstr(argjson,"unitval")) != 0 && strlen(hexstr) == 2 ) decode_hex((uint8_t *)&chain->unitval,1,hexstr); + if ( (hexstr= jstr(argjson,"alertpubkey")) != 0 && (strlen(hexstr)>>1) <= sizeof(chain->alertpubkey) ) + decode_hex((uint8_t *)chain->alertpubkey,(int32_t)strlen(hexstr)>>1,hexstr); if ( (hexstr= jstr(argjson,"genesishash")) != 0 ) { chain->genesis_hash = mycalloc('G',1,strlen(hexstr)+1); @@ -306,7 +399,7 @@ void iguana_chainparms(struct iguana_chain *chain,cJSON *argjson) if ( (genesis= jobj(argjson,"genesis")) != 0 ) { chain->hashalgo = iguana_hashalgo(jstr(genesis,"hashalgo")); - decode_hex(hash.bytes,sizeof(hash),chain->genesis_hash); + decode_hex(chain->genesishash2.bytes,sizeof(chain->genesishash2),chain->genesis_hash); if ( jstr(genesis,"nBits") != 0 ) { decode_hex((void *)&tmp,sizeof(tmp),jstr(genesis,"nBits")); @@ -314,26 +407,42 @@ void iguana_chainparms(struct iguana_chain *chain,cJSON *argjson) ((uint8_t *)&nBits)[1] = tmp[2]; ((uint8_t *)&nBits)[2] = tmp[1]; ((uint8_t *)&nBits)[3] = tmp[0]; - } - else nBits = 0x1e00ffff; - hash = iguana_chaingenesis(hash,genesisblock,jstr(genesis,"hashalgo"),juint(genesis,"version"),juint(genesis,"timestamp"),nBits,juint(genesis,"nonce"),jbits256(genesis,"merkle_root")); - //chain->genesis_hash = clonestr(bits256_str(str,hash)); + } else nBits = 0x1e00ffff; + chain->nBits = nBits; + chain->unitval = (nBits >> 24); + printf("NETMAGIC %08x unitval.%02x nBits.%08x\n",*(uint32_t *)chain->netmagic,chain->unitval,chain->nBits); + chain->genesishash2 = iguana_chaingenesis(chain->symbol,chain->zcash,chain->auxpow,chain->hashalgo,chain->genesishash2,genesisblock,jstr(genesis,"hashalgo"),juint(genesis,"version"),juint(genesis,"timestamp"),nBits,juint(genesis,"nonce"),jbits256(genesis,"merkle_root")); + memcpy(chain->genesis_hashdata,chain->genesishash2.bytes,32); + char str[65]; init_hexbytes_noT(str,chain->genesis_hashdata,32); + chain->genesis_hash = clonestr(str); chain->genesis_hex = clonestr(genesisblock); } else { + if ( jstr(argjson,"nBits") != 0 ) + { + decode_hex((void *)&tmp,sizeof(tmp),jstr(argjson,"nBits")); + ((uint8_t *)&nBits)[0] = tmp[3]; + ((uint8_t *)&nBits)[1] = tmp[2]; + ((uint8_t *)&nBits)[2] = tmp[1]; + ((uint8_t *)&nBits)[3] = tmp[0]; + } else nBits = 0x1e00ffff; + chain->nBits = nBits; + chain->unitval = (nBits >> 24); + printf("NETMAGIC -> %08x unitval.%02x (%s) -> tmp.%08x nBits.%08x\n",*(uint32_t *)chain->netmagic,chain->unitval,jstr(argjson,"nBits"),*(uint32_t *)tmp,chain->nBits); if ( (hexstr= jstr(argjson,"genesisblock")) != 0 ) { - chain->genesis_hex = mycalloc('G',1,strlen(hexstr)+1); - strcpy(chain->genesis_hex,hexstr); + uint8_t hexbuf[1024],*ptr,*data; int32_t datalen,hdrsize; + hdrsize = chain->zcash != 0 ? sizeof(struct iguana_msgblockhdr_zcash) : sizeof(struct iguana_msgblockhdr); + chain->genesis_hex = clonestr(hexstr); + data = get_dataptr(BASILISK_HDROFFSET,&ptr,&datalen,hexbuf,sizeof(hexbuf),hexstr); + chain->genesishash2 = iguana_calcblockhash(chain->symbol,chain->hashalgo,data,hdrsize); + memcpy(chain->genesis_hashdata,chain->genesishash2.bytes,32); + //char str[65]; printf("%s -> calculated %s from %d datalen\n",hexstr,bits256_str(str,chain->genesishash2),hdrsize); + if ( ptr != 0 ) + free(ptr); } } - if ( juint(argjson,"p2p") != 0 ) - chain->portp2p = juint(argjson,"p2p"); - if ( (chain->ramchainport= juint(argjson,"ramchain")) == 0 ) - chain->ramchainport = chain->portp2p - 1; - if ( (chain->rpcport= juint(argjson,"rpc")) == 0 ) - chain->rpcport = chain->portp2p + 1; if ( (rewards= jarray(&n,argjson,"rewards")) != 0 ) { for (i=0; imessagemagic,"%s Signed Message:\n",chain->name); + printf("COIN.%s serverport.(%s) userpass.(%s) RPCport.%u P2P.%u magic.%08x\n",chain->symbol,chain->serverport,chain->userpass,chain->rpcport,chain->portp2p,*(uint32_t *)chain->netmagic); } } void iguana_chaininit(struct iguana_chain *chain,int32_t hasheaders,cJSON *argjson) { + int32_t i; + if ( chain->hashalgo != 0 ) + return; + if ( strcmp(chain->symbol,"BTCD") == 0 ) + { + chain->numPoStargets = 1; + chain->PoSheights[0] = 0; + memset(&chain->PoStargets[0],0xff,sizeof(bits256)); + for (i=0; i<20; i++) + chain->PoStargets[0] = bits256_rshift(chain->PoStargets[0]); + chain->PoWtarget = bits256_from_compact(0x1e0fffff); + } chain->hasheaders = hasheaders; - chain->minoutput = 10000; - chain->hashalgo = blockhash_sha256; + chain->hashalgo = blockhash_sha256; // most all coins seem to use this for blockchain if ( strcmp(chain->symbol,"BTC") == 0 ) { chain->unitval = 0x1d; chain->txfee = 10000; + chain->havecltv = 1; } else chain->txfee = 1000000; if ( chain->unitval == 0 ) @@ -374,9 +497,9 @@ void iguana_chaininit(struct iguana_chain *chain,int32_t hasheaders,cJSON *argjs strcpy(chain->gethdrsmsg,"getblocks"); chain->bundlesize = _IGUANA_BLOCKHASHES; } + if ( strcmp(chain->symbol,"BTC") == 0 ) + chain->bundlesize = 100; decode_hex((uint8_t *)chain->genesis_hashdata,32,(char *)chain->genesis_hash); - if ( chain->ramchainport == 0 ) - chain->ramchainport = chain->portp2p - 1; if ( chain->rpcport == 0 ) chain->rpcport = chain->portp2p + 1; } @@ -387,23 +510,25 @@ struct iguana_chain *iguana_chainfind(char *name,cJSON *argjson,int32_t createfl for (i=0; igenesis_hash,chain->name,name,strcmp(name,chain->name)); + //printf("chain.(%s).%s vs %s.%d\n",chain->genesis_hash,chain->name,name,strcmp(name,chain->name)); if ( chain->name[0] == 0 || chain->genesis_hash == 0 ) { if ( createflag != 0 && argjson != 0 ) { - iguana_chaininit(chain,strcmp(chain->symbol,"BTC") == 0,argjson); + iguana_chaininit(chain,strcmp(chain->symbol,"BTCD") != 0,argjson); return(chain); } continue; } if ( strcmp(name,chain->symbol) == 0 ) { - iguana_chaininit(chain,strcmp(chain->symbol,"BTC") == 0,argjson); + iguana_chaininit(chain,strcmp(chain->symbol,"BTCD") != 0,argjson); return(chain); } } - return NULL; + chain = calloc(1,sizeof(*chain)); + iguana_chaininit(chain,1,argjson); + return(chain); } struct iguana_chain *iguana_findmagic(uint8_t netmagic[4]) diff --git a/iguana/iguana_exchanges.c b/iguana/iguana_exchanges.c index c9484f9a9..c7839bebb 100755 --- a/iguana/iguana_exchanges.c +++ b/iguana/iguana_exchanges.c @@ -22,6 +22,131 @@ //char *Exchange_names[] = { "poloniex", "bittrex", "btc38", "huobi", "bitstamp", "bitfinex", "btce", "coinbase", "okcoin", "lakebtc", "quadriga", "truefx", "ecb", "instaforex", "fxcm", "yahoo" }; +int32_t instantdex_updatesources(struct exchange_info *exchange,struct exchange_quote *sortbuf,int32_t n,int32_t max,int32_t ind,int32_t dir,struct exchange_quote *quotes,int32_t numquotes) +{ + int32_t i; struct exchange_quote *quote; + //printf("instantdex_updatesources.%s update dir.%d numquotes.%d\n",exchange->name,dir,numquotes); + for (i=0; iprice,quote->volume); + if ( quote->price > SMALLVAL ) + { + sortbuf[n] = *quote; + sortbuf[n].val = ind; + sortbuf[n].exchangebits = exchange->exchangebits; + //printf("sortbuf[%d] <-\n",n*2); + if ( ++n >= max ) + break; + } + } + return(n); +} + +double instantdex_aveprice(struct supernet_info *myinfo,struct exchange_quote *sortbuf,int32_t max,double *totalvolp,char *base,char *rel,double basevolume,cJSON *argjson) +{ + char *str; double totalvol,pricesum; uint32_t timestamp; + struct exchange_quote quote; int32_t i,n,dir,num,depth = 100; + struct exchange_info *exchange; struct exchange_request *req,*active[64]; + if ( myinfo == 0 ) + myinfo = SuperNET_MYINFO(0); + timestamp = (uint32_t)time(NULL); + if ( basevolume < 0. ) + basevolume = -basevolume, dir = -1; + else dir = 1; +#ifdef INCLUDE_PAX + if ( rel == 0 || rel[0] == 0 ) + { + *totalvolp = 1.; + return(PAX_aveprice(myinfo,base)); + } +#endif + memset(sortbuf,0,sizeof(*sortbuf) * max); + if ( base != 0 && rel != 0 && basevolume > SMALLVAL ) + { + for (i=num=0; inumexchanges && num < sizeof(active)/sizeof(*active); i++) + { + if ( (exchange= myinfo->tradingexchanges[i]) != 0 ) + { + if ( (req= exchanges777_baserelfind(exchange,base,rel,'M')) == 0 ) + { + if ( (str= exchanges777_Qprices(exchange,base,rel,30,1,depth,argjson,1,exchange->commission)) != 0 ) + free(str); + req = exchanges777_baserelfind(exchange,base,rel,'M'); + } + if ( req == 0 ) + { + if ( (*exchange->issue.supports)(exchange,base,rel,argjson) != 0 ) + printf("unexpected null req.(%s %s) %s\n",base,rel,exchange->name); + } + else + { + //printf("active.%s\n",exchange->name); + active[num++] = req; + } + } + } + for (i=n=0; inumbids > 0 ) + n = instantdex_updatesources(active[i]->exchange,sortbuf,n,max,i,1,active[i]->bidasks,active[i]->numbids); + else if ( dir > 0 && active[i]->numasks > 0 ) + n = instantdex_updatesources(active[i]->exchange,sortbuf,n,max,i,-1,&active[i]->bidasks[1],active[i]->numasks); + } + //printf("numexchanges.%d dir.%d %s/%s numX.%d n.%d\n",myinfo->numexchanges,dir,base,rel,num,n); + if ( dir < 0 ) + revsort64s(&sortbuf[0].satoshis,n,sizeof(*sortbuf)); + else sort64s(&sortbuf[0].satoshis,n,sizeof(*sortbuf)); + for (totalvol=pricesum=i=0; iexchange->name,pricesum/totalvol,totalvol); + } + } + if ( totalvol > 0. ) + { + *totalvolp = totalvol; + return(pricesum / totalvol); + } + } + *totalvolp = 0; + return(0); +} + +double instantdex_avehbla(struct supernet_info *myinfo,double retvals[4],char *_base,char *_rel,double basevolume) +{ + double avebid,aveask,bidvol,askvol; struct exchange_quote sortbuf[2560]; cJSON *argjson; char base[64],rel[64]; + if ( retvals == 0 ) + return(0); + strcpy(base,_base); + if ( _rel == 0 ) + strcpy(rel,""); + else strcpy(rel,_rel); + if ( myinfo == 0 ) + myinfo = SuperNET_MYINFO(0); + argjson = cJSON_CreateObject(); + aveask = instantdex_aveprice(myinfo,sortbuf,sizeof(sortbuf)/(4*sizeof(*sortbuf)),&askvol,base,rel,basevolume,argjson); + avebid = instantdex_aveprice(myinfo,sortbuf,sizeof(sortbuf)/(4*sizeof(*sortbuf)),&bidvol,base,rel,-basevolume,argjson); + free_json(argjson); + retvals[0] = avebid, retvals[1] = bidvol, retvals[2] = aveask, retvals[3] = askvol; +#ifdef INCLUDE_PAX + int32_t basenum,relnum; double baseval,relval; + if ( (basenum= PAX_basenum(base)) >= 0 && (relnum= PAX_basenum(rel)) >= 0 ) + { + if ( myinfo->PEGS != 0 && (baseval= myinfo->PEGS->data.RTmatrix[basenum][basenum]) != 0. && (relval= myinfo->PEGS->data.RTmatrix[relnum][relnum]) != 0. ) + return(baseval / relval); + } +#endif + if ( avebid > SMALLVAL && aveask > SMALLVAL ) + return((avebid + aveask) * .5); + else return(0); +} + void prices777_processprice(struct exchange_info *exchange,char *base,char *rel,struct exchange_quote *bidasks,int32_t maxdepth) { @@ -56,10 +181,10 @@ cJSON *exchanges777_quotejson(struct exchange_quote *quote,int32_t allflag,doubl jaddnum(json,"cumulative",totalvol); if ( quote->timestamp != 0 ) jaddstr(json,"time",utc_str(str,quote->timestamp)); - if ( quote->orderid > 0 ) + if ( quote->orderid != 0 ) jadd64bits(json,"orderid",quote->orderid); //if ( quote->offerNXT != 0 ) - jadd64bits(json,"offerer",quote->offerNXT); + jadd64bits(json,"account",quote->offerNXT); return(json); } else return(cJSON_CreateNumber(quote->price)); } @@ -227,7 +352,7 @@ void exchanges777_json_quotes(struct exchange_info *exchange,double commission,c //if ( strcmp(prices->exchange,"bter") == 0 && dir < 0 ) // slot = ((bidask==0?n:m) - 1) - i; //else - slot = i; + slot = i; timestamp = 0; item = jitem(bidask==0?bids:asks,slot); if ( pricefield != 0 && volfield != 0 ) @@ -245,7 +370,7 @@ void exchanges777_json_quotes(struct exchange_info *exchange,double commission,c volume = jdouble(item,"volume"); timestamp = juint(item,"timestamp"); orderid = j64bits(item,"orderid"); - offerNXT = j64bits(item,"offerer"); + offerNXT = j64bits(item,"account"); } if ( price == 0. || volume == 0. ) continue; @@ -537,10 +662,10 @@ char *exchanges777_process(struct exchange_info *exchange,int32_t *retvalp,struc req->orderid = orderid; retstr = (*exchange->issue.orderstatus)(exchange,req->orderid,req->argjson); /*retjson = cJSON_CreateObject(); - if ( orderid != 0 ) - jadd64bits(retjson,"result",orderid); - else jaddstr(retjson,"error","no return value from trade call"); - retstr = jprint(retjson,1);*/ + if ( orderid != 0 ) + jadd64bits(retjson,"result",orderid); + else jaddstr(retjson,"error","no return value from trade call"); + retstr = jprint(retjson,1);*/ } } break; @@ -583,25 +708,53 @@ char *exchanges777_process(struct exchange_info *exchange,int32_t *retvalp,struc return(retstr); } +/*void iguana_statemachineupdate(struct supernet_info *myinfo,struct exchange_info *exchange) +{ + int32_t timemod,modwidth = 10; struct iguana_info *coin; struct bitcoin_swapinfo *swap,*tmp; struct iguana_bundlereq *req; + timemod = time(NULL) % modwidth; + coin = iguana_coinfind("BTCD"); + portable_mutex_lock(&exchange->mutexS); + DL_FOREACH_SAFE(exchange->statemachines,swap,tmp) + { + if ( swap->dead != 0 || swap->mine.dead != 0 || swap->other.dead != 0 ) + DL_DELETE(exchange->statemachines,swap); + else if ( (swap->mine.orderid % modwidth) == timemod ) + instantdex_statemachine_iter(myinfo,exchange,swap); + } + portable_mutex_unlock(&exchange->mutexS); + while ( (req= queue_dequeue(&exchange->recvQ,0)) != 0 ) + { + if ( instantdex_recvquotes(coin,req,req->hashes,req->n) != 0 ) + myfree(req->hashes,(req->n+1) * sizeof(*req->hashes)), req->hashes = 0; + } + //iguana_inv2poll(myinfo,coin); +}*/ + void exchanges777_loop(void *ptr) { - struct peggy_info *PEGS; struct exchange_info *exchange = ptr; - int32_t flag,retval,i,peggyflag = 0; struct exchange_request *req; char *retstr; void *bot; + struct supernet_info *myinfo; struct exchange_info *exchange = ptr; + int32_t flag,retval,i; struct exchange_request *req; char *retstr; + myinfo = SuperNET_MYINFO(0); +#ifdef INCLUDE_PAX + struct peggy_info *PEGS=0; int32_t peggyflag = 0; if ( strcmp(exchange->name,"PAX") == 0 ) { - PEGS = calloc(1,sizeof(*PEGS)); - PAX_init(PEGS); - exchange->privatedata = PEGS; - peggyflag = 1; - _crypto_update(PEGS,PEGS->cryptovols,&PEGS->data,1,peggyflag); - PEGS->lastupdate = (uint32_t)time(NULL); + if ( (PEGS= myinfo->PEGS) != 0 ) + { + exchange->privatedata = PEGS; + peggyflag = 1; + _crypto_update(PEGS,PEGS->cryptovols,&PEGS->data,1,peggyflag); + PEGS->lastupdate = (uint32_t)time(NULL); + } } - printf("exchanges loop.(%s) %p\n",exchange->name,&exchange->requestQ); +#endif + printf("exchanges loop.(%s)\n",exchange->name); while ( 1 ) { - if ( peggyflag != 0 ) +#ifdef INCLUDE_PAX + if ( peggyflag != 0 && PEGS != 0 ) { - printf("nonz peggy\n"); + //printf("nonz peggy\n"); PAX_idle(PEGS,peggyflag,3); if ( time(NULL) > PEGS->lastupdate+100 ) { @@ -609,6 +762,7 @@ void exchanges777_loop(void *ptr) PEGS->lastupdate = (uint32_t)time(NULL); } } +#endif flag = retval = 0; retstr = 0; if ( (req= queue_dequeue(&exchange->requestQ,0)) != 0 ) @@ -638,7 +792,7 @@ void exchanges777_loop(void *ptr) //if ( retval == EXCHANGE777_ISPENDING ) // queue_enqueue("Xpending",&exchange->pendingQ,&req->DL,0), flag++; //else - if ( retval == EXCHANGE777_REQUEUE ) + if ( retval == EXCHANGE777_REQUEUE ) queue_enqueue("requeue",&exchange->requestQ,&req->DL,0); else { @@ -654,15 +808,14 @@ void exchanges777_loop(void *ptr) free(req); } } - if ( (bot= queue_dequeue(&exchange->tradebotsQ,0)) != 0 ) - tradebot_timeslice(exchange,bot); + tradebot_timeslices(exchange); if ( time(NULL) > exchange->lastpoll+exchange->pollgap ) { - if ( strcmp(exchange->name,"bitcoin") == 0 ) + /*if ( strcmp(exchange->name,"bitcoin") == 0 ) { - instantdex_update(SuperNET_MYINFO(0)); + iguana_statemachineupdate(myinfo,exchange); //printf("InstantDEX call update\n"); - } + }*/ if ( (req= queue_dequeue(&exchange->pricesQ,0)) != 0 ) { //printf("check %s pricesQ (%s %s)\n",exchange->name,req->base,req->rel); @@ -751,7 +904,7 @@ char *exchanges777_submit(struct exchange_info *exchange,struct exchange_request char *exchanges777_Qtrade(struct exchange_info *exchange,char *base,char *rel,int32_t maxseconds,int32_t dotrade,int32_t dir,double price,double volume,cJSON *argjson) { - struct exchange_request *req; int32_t polarity; + struct exchange_request *req; int32_t polarity; if ( exchange->issue.supports == 0 ) return(clonestr("{\"error\":\"no supports function\"}")); if ( base[0] == 0 || rel[0] == 0 || (polarity= (*exchange->issue.supports)(exchange,base,rel,argjson)) <= 0 || price < SMALLVAL || volume < SMALLVAL ) @@ -769,9 +922,15 @@ char *exchanges777_Qprices(struct exchange_info *exchange,char *base,char *rel,i { struct exchange_request *req; int32_t polarity; if ( exchange->issue.supports == 0 ) + { + printf("%s doesnt have supports func\n",exchange->name); return(clonestr("{\"error\":\"no supports function\"}")); + } if ( base[0] == 0 || rel[0] == 0 || (polarity= (*exchange->issue.supports)(exchange,base,rel,argjson)) == 0 ) + { + //printf("%s invalid (%s) or (%s)\n",exchange->name,base,rel); return(clonestr("{\"error\":\"invalid base or rel\"}")); + } if ( depth <= 0 ) depth = 1; req = calloc(1,sizeof(*req) + sizeof(*req->bidasks)*depth*2); @@ -791,11 +950,14 @@ char *exchanges777_Qprices(struct exchange_info *exchange,char *base,char *rel,i if ( (req->commission= commission) == 0. ) req->commission = exchange->commission; if ( monitor == 0 ) + { + printf("%s submit (%s) (%s)\n",exchange->name,base,rel); return(exchanges777_submit(exchange,req,'Q',maxseconds)); + } else { req->func = 'M'; - printf("Monitor.%s (%s %s) invert.%d\n",exchange->name,base,rel,req->invert); + //printf("Monitor.%s (%s %s) invert.%d\n",exchange->name,base,rel,req->invert); queue_enqueue("pricesQ",&exchange->pricesQ,&req->DL,0); return(clonestr("{\"result\":\"start monitoring\"}")); } @@ -818,13 +980,16 @@ char *exchanges777_Qrequest(struct exchange_info *exchange,int32_t func,char *ba int32_t exchanges777_id(char *exchangestr) { int32_t i; - for (i=0; iname); - if ( strcmp(exchangestr,Exchange_funcs[i]->name) == 0 ) - return(i); + for (i=0; iname); + if ( strcmp(exchangestr,Exchange_funcs[i]->name) == 0 ) + return(i); + } + //printf("cant find (%s)\n",exchangestr); } - //printf("cant find (%s)\n",exchangestr); return(-1); } @@ -849,6 +1014,15 @@ struct exchange_info *exchanges777_find(char *exchangestr) return(0); } +void iguana_gotquotesM(struct iguana_info *coin,struct iguana_peer *addr,bits256 *quotes,int32_t n) +{ + struct iguana_bundlereq *req; struct exchange_info *exchange = exchanges777_find("bitcoin"); + //printf("got %d quotes from %s\n",n,addr->ipaddr); + req = iguana_bundlereq(coin,addr,'Q',0,0); + req->hashes = quotes, req->n = n; + queue_enqueue("recvQ",&exchange->recvQ,&req->DL,0); +} + struct exchange_info *exchange_create(char *exchangestr,cJSON *argjson) { static int didinit; @@ -885,13 +1059,16 @@ struct exchange_info *exchange_create(char *exchangestr,cJSON *argjson) return(0); } exchange = calloc(1,sizeof(*exchange)); + portable_mutex_init(&exchange->mutex); + portable_mutex_init(&exchange->mutexS); + portable_mutex_init(&exchange->mutexH); + portable_mutex_init(&exchange->mutexP); + portable_mutex_init(&exchange->mutexR); + portable_mutex_init(&exchange->mutexT); exchange->issue = *Exchange_funcs[i]; - iguana_initQ(&exchange->pricesQ,"prices"); - iguana_initQ(&exchange->requestQ,"request"); - iguana_initQ(&exchange->acceptableQ,"acceptable"); - iguana_initQ(&exchange->tradebotsQ,"tradebots"); - iguana_initQ(&exchange->historyQ,"history"); - iguana_initQ(&exchange->statemachineQ,"statemachineQ"); + iguana_initQ(&exchange->recvQ,"recvQ"); + iguana_initQ(&exchange->pricesQ,"pricesQ"); + iguana_initQ(&exchange->requestQ,"requestQ"); exchange->exchangeid = exchangeid; safecopy(exchange->name,exchangestr,sizeof(exchange->name)); exchange->exchangebits = stringbits(exchange->name); @@ -909,6 +1086,7 @@ struct exchange_info *exchange_create(char *exchangestr,cJSON *argjson) exchange->commission *= .01; printf("ADDEXCHANGE.(%s) [%s, %s, %s] commission %.3f%% -> exchangeid.%d\n",exchangestr,exchange->apikey,exchange->userid,exchange->apisecret,exchange->commission * 100.,exchangeid); Exchanges[exchangeid] = exchange; + //instantdex_FSMinit(); iguana_launch(0,"exchangeloop",(void *)exchanges777_loop,exchange,IGUANA_EXCHANGETHREAD); return(exchange); } @@ -933,10 +1111,10 @@ struct exchange_info *exchanges777_info(char *exchangestr,int32_t sleepflag,cJSO void exchanges777_init(struct supernet_info *myinfo,cJSON *exchanges,int32_t sleepflag) { - int32_t i,n; cJSON *argjson,*item; bits256 instantdexhash; struct exchange_info *exchange; + int32_t i,n; cJSON *argjson,*item; struct exchange_info *exchange; if ( (exchange= exchanges777_find("bitcoin")) == 0 && (exchange= exchange_create("bitcoin",0)) != 0 ) myinfo->tradingexchanges[myinfo->numexchanges++] = exchange; - if ( 0 && exchanges != 0 ) + if ( exchanges != 0 ) { n = cJSON_GetArraySize(exchanges); for (i=0; itradingexchanges[myinfo->numexchanges++] = exchange; } } - if ( 0 ) + if ( 1 ) { argjson = cJSON_CreateObject(); for (i=0; iname,"PAX") == 0 || strcmp(Exchange_funcs[i]->name,"truefx") == 0 || strcmp(Exchange_funcs[i]->name,"fxcm") == 0 || strcmp(Exchange_funcs[i]->name,"instaforx") == 0 ) continue; - if ( (exchange= exchanges777_info(Exchange_funcs[i]->name,sleepflag,argjson,0)) != 0 ) + if ( ((exchange= exchanges777_find(Exchange_funcs[i]->name)) == 0 && (exchange= exchange_create(Exchange_funcs[i]->name,item)) != 0) || (exchange= exchanges777_info(Exchange_funcs[i]->name,sleepflag,argjson,0)) != 0 ) myinfo->tradingexchanges[myinfo->numexchanges++] = exchange; } free_json(argjson); } - instantdexhash = calc_categoryhashes(0,"InstantDEX",0); - printf("InstantDEX:\n"); - category_subscribe(myinfo,instantdexhash,GENESIS_PUBKEY); - category_processfunc(instantdexhash,GENESIS_PUBKEY,InstantDEX_hexmsg); - category_processfunc(instantdexhash,myinfo->myaddr.persistent,InstantDEX_hexmsg); +} + +cJSON *iguana_pricesarray(struct supernet_info *myinfo,char *exchange,char *base,char *rel,int32_t period,uint32_t start,uint32_t end) +{ + cJSON *array = cJSON_CreateArray(); + return(array); } #include "../includes/iguana_apidefs.h" @@ -973,9 +1152,12 @@ THREE_STRINGS_AND_THREE_INTS(InstantDEX,orderbook,exchange,base,rel,depth,allfie struct exchange_info *ptr; if ( remoteaddr == 0 ) { - if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) - return(exchanges777_Qprices(ptr,base,rel,juint(json,"maxseconds"),allfields,depth,json,0,ptr->commission)); - else return(clonestr("{\"error\":\"cant find or create exchange\"}")); + if ( exchange != 0 && exchange[0] != 0 ) + { + if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) + return(exchanges777_Qprices(ptr,base,rel,juint(json,"maxseconds"),allfields,depth,json,0,ptr->commission)); + else return(clonestr("{\"error\":\"cant find or create exchange\"}")); + } else return(clonestr("{\"error\":\"no exchange specified\"}")); } else return(clonestr("{\"error\":\"no remote for this API\"}")); } @@ -984,6 +1166,8 @@ THREE_STRINGS_AND_THREE_DOUBLES(InstantDEX,buy,exchange,base,rel,price,volume,do struct exchange_info *ptr; if ( remoteaddr == 0 ) { + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) return(exchanges777_Qtrade(ptr,base,rel,juint(json,"maxseconds"),dotrade,1,price,volume,json)); else return(clonestr("{\"error\":\"cant find or create exchange\"}")); @@ -995,6 +1179,8 @@ THREE_STRINGS_AND_THREE_DOUBLES(InstantDEX,sell,exchange,base,rel,price,volume,d struct exchange_info *ptr; if ( remoteaddr == 0 ) { + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) return(exchanges777_Qtrade(ptr,base,rel,juint(json,"maxseconds"),dotrade,-1,price,volume,json)); else return(clonestr("{\"error\":\"cant find or create exchange\"}")); @@ -1006,6 +1192,8 @@ THREE_STRINGS_AND_DOUBLE(InstantDEX,withdraw,exchange,base,destaddr,amount) struct exchange_info *ptr; if ( remoteaddr == 0 ) { + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) return(exchanges777_Qrequest(ptr,'W',base,0,juint(json,"maxseconds"),0,destaddr,amount,json)); else return(clonestr("{\"error\":\"cant find or create exchange\"}")); @@ -1017,6 +1205,8 @@ TWO_STRINGS(InstantDEX,balance,exchange,base) struct exchange_info *ptr; if ( remoteaddr == 0 ) { + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) return(exchanges777_Qrequest(ptr,'B',base,0,juint(json,"maxseconds"),0,0,0,json)); else return(clonestr("{\"error\":\"cant find or create exchange\"}")); @@ -1028,6 +1218,8 @@ TWO_STRINGS(InstantDEX,orderstatus,exchange,orderid) struct exchange_info *ptr; if ( remoteaddr == 0 ) { + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) return(exchanges777_Qrequest(ptr,'P',0,0,juint(json,"maxseconds"),calc_nxt64bits(orderid),0,0,json)); else return(clonestr("{\"error\":\"cant find or create exchange\"}")); @@ -1039,6 +1231,8 @@ TWO_STRINGS(InstantDEX,cancelorder,exchange,orderid) struct exchange_info *ptr; if ( remoteaddr == 0 ) { + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) return(exchanges777_Qrequest(ptr,'C',0,0,juint(json,"maxseconds"),calc_nxt64bits(orderid),0,0,json)); else return(clonestr("{\"error\":\"cant find or create exchange\"}")); @@ -1050,6 +1244,8 @@ STRING_ARG(InstantDEX,openorders,exchange) struct exchange_info *ptr; if ( remoteaddr == 0 ) { + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) return(exchanges777_Qrequest(ptr,'O',0,0,juint(json,"maxseconds"),0,0,0,json)); else return(clonestr("{\"error\":\"cant find or create exchange\"}")); @@ -1061,6 +1257,8 @@ STRING_ARG(InstantDEX,tradehistory,exchange) struct exchange_info *ptr; if ( remoteaddr == 0 ) { + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) return(exchanges777_Qrequest(ptr,'H',0,0,juint(json,"maxseconds"),0,0,0,json)); else return(clonestr("{\"error\":\"cant find or create exchange\"}")); @@ -1072,6 +1270,8 @@ THREE_STRINGS(InstantDEX,apikeypair,exchange,apikey,apisecret) struct exchange_info *ptr; if ( remoteaddr == 0 ) { + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) { if ( apikey != 0 && apikey[0] != 0 && apisecret != 0 && apisecret[0] != 0 ) @@ -1089,6 +1289,8 @@ THREE_STRINGS(InstantDEX,setuserid,exchange,userid,tradepassword) struct exchange_info *ptr; if ( remoteaddr == 0 ) { + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) { safecopy(ptr->userid,userid,sizeof(ptr->userid)); @@ -1103,6 +1305,8 @@ STRING_AND_INT(InstantDEX,pollgap,exchange,pollgap) struct exchange_info *ptr; if ( remoteaddr == 0 ) { + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); if ( (ptr= exchanges777_info(exchange,1,json,remoteaddr)) != 0 ) { ptr->pollgap = pollgap; @@ -1136,4 +1340,135 @@ STRING_ARG(InstantDEX,allpairs,exchange) return((*ptr->issue.allpairs)(ptr,json)); else return(clonestr("{\"error\":\"cant find or create exchange\"}")); } + +TWO_STRINGS(iguana,rate,base,rel) +{ + cJSON *retjson,*tmpjson; char *retstr,baserel[128],_base[64],_rel[64]; double aveprice = 0.; + safecopy(_base,base,sizeof(_base)); + safecopy(_rel,rel,sizeof(_rel)); + if ( (retstr= tradebot_aveprice(myinfo,coin,json,remoteaddr,"",_base,_rel,1)) != 0 ) + { + if ( (tmpjson= cJSON_Parse(retstr)) != 0 ) + { + aveprice = jdouble(tmpjson,"aveprice"); + retjson = cJSON_CreateObject(); + sprintf(baserel,"%s/%s",_base,_rel); + jaddnum(retjson,baserel,aveprice); + jaddstr(retjson,"result","success"); + free_json(tmpjson); + return(jprint(retjson,1)); + } else return(clonestr("{\"error\":\"error parsing return from aveprice\"}")); + } else return(clonestr("{\"error\":\"null return from aveprice\"}")); +} + +THREE_STRINGS_AND_THREE_INTS(iguana,prices,exchange,base,rel,period,start,end) +{ + cJSON *retjson = cJSON_CreateObject(); + if ( period <= 0 ) + period = 60; + if ( end <= 0 ) + end = (uint32_t)time(NULL); + if ( start <= 0 || start >= end ) + start = end - 1024*period; + jaddstr(retjson,"base",base); + jaddstr(retjson,"rel",rel); + jaddstr(retjson,"exchange",exchange[0] != 0 ? exchange : "all"); + jaddstr(retjson,"result","success"); + jaddnum(retjson,"start",start); + jaddnum(retjson,"end",end); + jaddnum(retjson,"period",period); + jadd(retjson,"prices",iguana_pricesarray(myinfo,exchange,base,rel,period,start,end)); + return(jprint(retjson,1)); +} + +INT_AND_ARRAY(iguana,rates,unused,quotes) +{ + int32_t i,n,len,j,haveslash; char *retstr,*quote,base[64][64],rel[64][64],field[64]; double aveprice; cJSON *tmpjson,*item,*array=0,*retjson = cJSON_CreateObject(); +#ifdef INCLUDE_PAX + char *str; int32_t nonz; + if ( myinfo->PEGS != 0 && (str= peggy_emitprices(&nonz,myinfo->PEGS,(uint32_t)time(NULL),PEGGY_MAXLOCKDAYS)) != 0 ) + free(str); +#endif + if ( is_cJSON_Array(quotes) != 0 && (n= cJSON_GetArraySize(quotes)) > 0 ) + { + if ( n > 64 ) + { + jaddstr(retjson,"error","only 16 quotes at a time"); + return(jprint(retjson,1)); + } + memset(base,0,sizeof(base)); + memset(rel,0,sizeof(rel)); + for (i=0; i= 64 ) + { + if ( array != 0 ) + free_json(array); + jaddstr(retjson,"error","quote too long"); + return(jprint(retjson,1)); + } + for (j=haveslash=0; j 0 && j < len-1 ) + { + memcpy(base[i],quote,j); + base[i][j] = 0; + j++; + strcpy(rel[i],"e[j]); + break; + } + else + { + if ( array != 0 ) + free_json(array); + jaddstr(retjson,"error","no base error in quote item"); + return(jprint(retjson,1)); + } + } + } + if ( j < len || haveslash == 0 ) + { + if ( haveslash == 0 ) + strcpy(base[i],quote); + aveprice = 0.; + if ( (retstr= tradebot_aveprice(myinfo,coin,json,remoteaddr,"",base[i],rel[i],1)) != 0 ) + { + if ( (tmpjson= cJSON_Parse(retstr)) != 0 ) + { + aveprice = jdouble(tmpjson,"aveprice"); + //printf("(%s) ",jprint(tmpjson,0)); + free_json(tmpjson); + } else printf("error parsing.(%s)\n",retstr); + if ( haveslash == 0 ) + strcpy(field,base[i]); + else sprintf(field,"%s/%s",base[i],rel[i]); + item = cJSON_CreateObject(); + jaddnum(item,field,aveprice); + if ( array == 0 ) + array = cJSON_CreateArray(); + jaddi(array,item); + free(retstr); + //printf(" <- aveprice %f\n",aveprice); + } else printf("no return from aveprice\n"); + } + else + { + if ( array != 0 ) + free_json(array); + jaddstr(retjson,"error","syntax error in quote item"); + return(jprint(retjson,1)); + } + } else printf("i.%d of %d null quote\n",i,n); + } + jaddstr(retjson,"result","success"); + jadd(retjson,"rates",array); + } else jaddstr(retjson,"error","no quotes array"); + return(jprint(retjson,1)); +} #include "../includes/iguana_apiundefs.h" diff --git a/iguana/iguana_init.c b/iguana/iguana_init.c index a5b177909..c9e2bfa04 100755 --- a/iguana/iguana_init.c +++ b/iguana/iguana_init.c @@ -36,8 +36,11 @@ void iguana_initQs(struct iguana_info *coin) iguana_initQ(&coin->msgrequestQ,"msgrequestQ"); iguana_initQ(&coin->cacheQ,"cacheQ"); iguana_initQ(&coin->recvQ,"recvQ"); - for (i=0; ipeers.active[i].sendQ,"addrsendQ"); + if ( coin->MAXPEERS > 0 && coin->peers != 0 ) + { + for (i=0; ipeers->active[i].sendQ,"addrsendQ"); + } } void iguana_initpeer(struct iguana_info *coin,struct iguana_peer *addr,uint64_t ipbits) @@ -48,35 +51,51 @@ void iguana_initpeer(struct iguana_info *coin,struct iguana_peer *addr,uint64_t expand_ipbits(addr->ipaddr,(uint32_t)addr->ipbits); //addr->pending = (uint32_t)time(NULL); strcpy(addr->symbol,coin->symbol); - strcpy(addr->coinstr,coin->name); + strcpy(addr->coinname,coin->name); iguana_initQ(&addr->sendQ,"addrsendQ"); } void iguana_initcoin(struct iguana_info *coin,cJSON *argjson) { int32_t i; char dirname[1024]; - sprintf(dirname,"%s/%s",GLOBAL_TMPDIR,coin->symbol), OS_portable_path(dirname); - portable_mutex_init(&coin->peers_mutex); - portable_mutex_init(&coin->blocks_mutex); - iguana_meminit(&coin->blockMEM,"blockMEM",coin->blockspace,sizeof(coin->blockspace),0); - iguana_initQs(coin); - coin->bindsock = -1; - OS_randombytes((unsigned char *)&coin->instance_nonce,sizeof(coin->instance_nonce)); - coin->startutc = (uint32_t)time(NULL); - while ( time(NULL) == coin->startutc ) - usleep(1); - coin->startutc++; - printf("start.%u\n",coin->startutc); - coin->startmillis = OS_milliseconds(), coin->starttime = tai_now(); - coin->avetime = 1 * 100; - //coin->R.maxrecvbundles = IGUANA_INITIALBUNDLES; - for (i=0; ipeers.active[i].usock = -1; + if ( coin->instance_nonce == 0 ) + { + sprintf(dirname,"%s/%s",GLOBAL_TMPDIR,coin->symbol), OS_portable_path(dirname); + portable_mutex_init(&coin->RTmutex); + portable_mutex_init(&coin->peers_mutex); + portable_mutex_init(&coin->blocks_mutex); + portable_mutex_init(&coin->special_mutex); + portable_mutex_init(&coin->allcoins_mutex); + coin->txfee = 10000; + iguana_meminit(&coin->blockMEM,"blockMEM",coin->blockspace,coin->blockspacesize,0); + iguana_initQs(coin); + coin->bindsock = -1; + OS_randombytes((unsigned char *)&coin->instance_nonce,sizeof(coin->instance_nonce)); + coin->startutc = (uint32_t)time(NULL); + while ( time(NULL) == coin->startutc ) + usleep(1); + coin->startutc++; + printf("start.%u\n",coin->startutc); + coin->startmillis = OS_milliseconds(), coin->starttime = tai_now(); + coin->avetime = 1 * 100; + //coin->R.maxrecvbundles = IGUANA_INITIALBUNDLES; + if ( coin->MAXPEERS > 0 && coin->peers != 0 ) + { + for (i=0; ipeers->active[i].usock = -1; + } + } } -bits256 iguana_genesis(struct iguana_info *coin,struct iguana_chain *chain) +bits256 iguana_genesis(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_chain *chain) { - struct iguana_block block,*ptr; struct iguana_msgblock msg; bits256 hash2; char str[65],str2[65]; uint8_t buf[1024]; int32_t height; + struct iguana_block *block,*ptr; struct iguana_msgblock msg; bits256 hash2; char str[65],str2[65]; uint8_t buf[8192],blockspace[sizeof(*block)+sizeof(*block->zRO)]; int32_t height,auxback; + if ( coin == 0 || chain == 0 ) + return(GENESIS_PUBKEY); + block = (void *)blockspace; + memset(block,0,sizeof(blockspace)); + block->RO.allocsize = chain->zcash != 0 ? sizeof(struct iguana_zblock) : sizeof(struct iguana_block); + iguana_blocksizecheck("genesis",chain->zcash,block); if ( chain->genesis_hex == 0 ) { printf("no genesis_hex for %s\n",coin->symbol); @@ -84,45 +103,41 @@ bits256 iguana_genesis(struct iguana_info *coin,struct iguana_chain *chain) return(hash2); } decode_hex(buf,(int32_t)strlen(chain->genesis_hex)/2,(char *)chain->genesis_hex); - hash2 = bits256_doublesha256(0,buf,sizeof(struct iguana_msgblockhdr)); - iguana_rwblock(0,&hash2,buf,&msg); - if ( memcmp(hash2.bytes,chain->genesis_hashdata,sizeof(hash2)) != 0 ) + hash2 = iguana_calcblockhash(coin->symbol,coin->chain->hashalgo,buf,sizeof(struct iguana_msgblockhdr)); + auxback = coin->chain->auxpow, coin->chain->auxpow = 0; + iguana_rwblock(coin->symbol,coin->chain->zcash,coin->chain->auxpow,coin->chain->hashalgo,0,&hash2,buf,&msg,sizeof(buf)); + coin->chain->auxpow = auxback; + if ( coin->virtualchain == 0 && coin->MAXPEERS > 1 ) { - bits256_str(str,hash2); - printf("genesis mismatch? calculated %s vs %s\n",str,bits256_str(str2,*(bits256 *)chain->genesis_hashdata)); - //hash2 = bits256_conv("00000ac7d764e7119da60d3c832b1d4458da9bc9ef9d5dd0d91a15f690a46d99"); - - //memset(hash2.bytes,0,sizeof(hash2)); - //return(hash2); - } + if ( memcmp(hash2.bytes,chain->genesis_hashdata,sizeof(hash2)) != 0 ) + { + bits256_str(str,hash2); + printf("genesis mismatch? zcash.%d calculated %s vs %s\n",coin->chain->zcash,str,bits256_str(str2,*(bits256 *)chain->genesis_hashdata)); + memcpy(hash2.bytes,chain->genesis_hashdata,sizeof(hash2)); + } + } else memcpy(hash2.bytes,chain->genesis_hashdata,sizeof(hash2)); bits256_str(str,hash2); - printf("genesis.(%s) len.%d hash.%s\n",chain->genesis_hex,(int32_t)sizeof(msg.H),str); - iguana_blockconv(&block,&msg,hash2,0); - block.RO.txn_count = 1; - block.RO.numvouts = 1; + printf("genesis.(%s) zcash.%d len.%d hash.%s\n",chain->genesis_hex,coin->chain->zcash,(int32_t)sizeof(msg.H),str); + iguana_blockconv(coin->chain->zcash,coin->chain->auxpow,block,&msg,hash2,0); + block->RO.txn_count = 1; + block->RO.numvouts = 1; + block->RO.allocsize = (int32_t)(sizeof(*block) + coin->chain->zcash*sizeof(*block->zRO)); iguana_gotdata(coin,0,0); if ( (ptr= iguana_blockhashset("genesis0",coin,0,hash2,1)) != 0 ) { - iguana_blockcopy(coin,ptr,&block); + iguana_blockcopy(coin->chain->zcash,coin->chain->auxpow,coin,ptr,block); + iguana_blocksizecheck("genesis ptr",coin->chain->zcash,ptr); ptr->mainchain = 1; ptr->height = 0; - coin->blocks.RO[0] = block.RO; - if ( (height= iguana_chainextend(coin,ptr)) == 0 ) + //coin->blocks.RO[0] = block.RO; + if ( coin->virtualchain != 0 || (height= iguana_chainextend(myinfo,coin,ptr)) == 0 ) { - block = *ptr; + iguana_blockzcopy(coin->chain->zcash,block,ptr); + iguana_blockzcopy(coin->chain->zcash,(void *)&coin->blocks.hwmchain,ptr); + printf("size.%d genesis block PoW %f ptr %f\n",block->RO.allocsize,block->PoW,ptr->PoW); coin->blocks.recvblocks = coin->blocks.issuedblocks = 1; - } - else printf("genesis block doesnt validate for %s ht.%d\n",coin->symbol,height); + } else printf("genesis block doesnt validate for %s ht.%d\n",coin->symbol,height); } else printf("couldnt hashset genesis\n"); - if ( coin->blocks.hwmchain.height != 0 || fabs(coin->blocks.hwmchain.PoW - block.PoW) > SMALLVAL || memcmp(coin->blocks.hwmchain.RO.hash2.bytes,hash2.bytes,sizeof(hash2)) != 0 ) - { - printf("%s genesis values mismatch hwmheight.%d %.15f %.15f %s\n",coin->name,coin->blocks.hwmchain.height,coin->blocks.hwmchain.PoW,block.PoW,bits256_str(str,coin->blocks.hwmchain.RO.hash2)); - getchar(); - } - int32_t bundlei = -2; - static const bits256 zero; - iguana_bundlecreate(coin,&bundlei,0,hash2,zero,1); - _iguana_chainlink(coin,iguana_blockfind("genesis",coin,hash2)); return(hash2); } @@ -213,7 +228,7 @@ int32_t iguana_bundleinitmap(struct iguana_info *coin,struct iguana_bundle *bp,i if ( coin->current != 0 && coin->current->hdrsi+1 == bp->hdrsi ) coin->current = bp; bp->emitfinish = (uint32_t)time(NULL) + 1; - //printf("[%d %u] ",bp->hdrsi,bp->emitfinish); + //printf("[%d].%p ",bp->hdrsi,bp->ramchain.H.data); return(0); } else @@ -229,14 +244,17 @@ int32_t iguana_bundleinitmap(struct iguana_info *coin,struct iguana_bundle *bp,i } } -void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) +void iguana_parseline(struct supernet_info *myinfo,struct iguana_info *coin,int32_t iter,FILE *fp) { int32_t j,k,m,c,flag,bundlei,lastheight,height = -1; char checkstr[1024],line[1024]; struct iguana_peer *addr; struct iguana_bundle *bp; bits256 allhash,hash2,hash1,zero,lastbundle; + if ( coin->FULLNODE == 0 && coin->VALIDATENODE == 0 && iter > 0 ) + return; memset(&zero,0,sizeof(zero)); lastbundle = zero; if ( coin->MAXPEERS > IGUANA_MAXPEERS ) coin->MAXPEERS = IGUANA_MAXPEERS; +#ifdef oldway if ( iter == 1 && 0 ) { int32_t i; FILE *fp; char fname[512]; struct iguana_blockRO blockRO; @@ -258,6 +276,9 @@ void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) printf("validate.%d blocks that were read in\n",i); } } +#endif + OS_randombytes((void *)&m,sizeof(m)); + srand(m); m = flag = 0; allhash = zero; memset(line,0,sizeof(line)); @@ -268,17 +289,17 @@ void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) //printf("parse line.(%s) maxpeers.%d\n",line,coin->MAXPEERS); if ( iter == 0 ) { - if ( m < coin->MAXPEERS-3 )//&& m < 77.7 ) + if ( m < 32 || (m < coin->MAXPEERS/2 && strcmp("BTCD",coin->symbol) != 0) )//&& m < 77.7 ) { if ( 0 && m == 0 ) { - addr = &coin->peers.active[m++]; + addr = &coin->peers->active[m++]; iguana_initpeer(coin,addr,(uint32_t)calc_ipbits("127.0.0.1")); //printf("call initpeer.(%s)\n",addr->ipaddr); iguana_launch(coin,"connection",iguana_startconnection,addr,IGUANA_CONNTHREAD); } #ifndef IGUANA_DISABLEPEERS - addr = &coin->peers.active[m++]; + addr = &coin->peers->active[m++]; iguana_initpeer(coin,addr,(uint32_t)calc_ipbits(line)); //printf("call initpeer.(%s)\n",addr->ipaddr); iguana_launch(coin,"connection",iguana_startconnection,addr,IGUANA_CONNTHREAD); @@ -301,19 +322,22 @@ void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) if ( line[k] == ' ' ) { decode_hex(hash2.bytes,sizeof(hash2),line+k+1); - //printf("line.(%s) k.%d (%c)(%c)(%d)\n",line,k,line[k+63],line[k+64],line[k+65]); + if ( coin->virtualchain != 0 ) + printf("%s line.(%s) k.%d (%c)(%c)(%d)\n",coin->symbol,line,k,line[k+63],line[k+64],line[k+65]); if ( height >= 0 && bits256_nonz(hash2) != 0 ) { if ( (bp= iguana_bundlecreate(coin,&bundlei,height,hash2,zero,0)) != 0 ) { //printf("created bundle.%d\n",bp->hdrsi); + memset(hash1.bytes,0,sizeof(hash1)); + iguana_bundleinitmap(coin,bp,height,hash2,hash1); lastbundle = hash2; } } - if ( line[k + 65] != 0 && line[k+65] != '\n' && line[k+65] != '\r' ) + if ( line[k + 65] != 0 && line[k+65] != '\n' && line[k+65] != '\r' ) { - if ( height > (coin->blocks.maxbits - 1000) ) - iguana_recvalloc(coin,height + 100000); + //if ( height > (coin->blocks.maxbits - 1000) ) + // iguana_recvalloc(coin,height + 100000); decode_hex(allhash.bytes,sizeof(allhash),line+k+1 + 64 + 1); init_hexbytes_noT(checkstr,allhash.bytes,sizeof(allhash)); //printf("parseline: k.%d %d height.%d m.%d bundlesize.%d (%s) check.(%s)\n",k,line[k],height,m,coin->chain->bundlesize,&line[k+1+65],checkstr);// + strlen(line+k+1)]); @@ -323,7 +347,9 @@ void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) if ( strlen(line+k+1 + 2*64 + 2) == sizeof(hash1)*2 ) decode_hex(hash1.bytes,sizeof(hash1),line+k+1 + 2*64 + 2); else memset(hash1.bytes,0,sizeof(hash1)); - //char str[65],str2[65]; printf(">>>> bundle.%d got (%s)/(%s) allhash.(%s)\n",height,bits256_str(str,hash1),checkstr,bits256_str(str2,allhash)); + if ( coin->virtualchain != 0 ) + memset(hash1.bytes,0,sizeof(hash1)); + //char str[65],str2[65]; printf(">>>> %s bundle.%d last.%d got (%s)/(%s) allhash.(%s)\n",coin->symbol,height,lastheight,bits256_str(str,hash1),checkstr,bits256_str(str2,allhash)); if ( (bp= iguana_bundlecreate(coin,&bundlei,height,hash2,allhash,0)) != 0 ) { if ( bits256_cmp(allhash,bp->allhash) != 0 ) @@ -345,11 +371,25 @@ void iguana_parseline(struct iguana_info *coin,int32_t iter,FILE *fp) } if ( iter == 1 && bits256_nonz(lastbundle) != 0 ) { - printf("parseline ht.%d\n",lastheight); - iguana_initfinal(coin,lastbundle); + printf("%s parseline ht.%d\n",coin->symbol,lastheight); + iguana_initfinal(myinfo,coin,lastbundle); } } +long iguana_bundlesload(struct supernet_info *myinfo,struct iguana_info *coin) +{ + char fname[1024]; int32_t iter = 1; FILE *fp; long fpos = -1; + sprintf(fname,"%s/%s_%s.txt",GLOBAL_CONFSDIR,coin->symbol,(iter == 0) ? "peers" : "hdrs"), OS_compatible_path(fname); + if ( (fp= fopen(fname,"r")) != 0 ) + { + iguana_parseline(myinfo,coin,iter,fp); + printf("done parsefile.%d (%s) size.%ld\n",iter,fname,fpos); + fpos = ftell(fp); + fclose(fp); + } + return(fpos); +} + void iguana_ramchainpurge(struct iguana_info *coin,struct iguana_bundle *bp,struct iguana_ramchain *ramchain) { iguana_ramchain_free(coin,ramchain,1); @@ -398,12 +438,14 @@ void iguana_blockspurge(struct iguana_info *coin) } coin->blocks.hash = 0; } - if ( coin->blocks.RO != 0 ) + /*if ( coin->blocks.RO != 0 ) { + printf("deprecated coin->blocks.RO used??\n"); myfree(coin->blocks.RO,coin->blocks.maxbits * sizeof(*coin->blocks.RO)); coin->blocks.RO = 0; } - coin->blocks.maxbits = coin->blocks.maxblocks = coin->blocks.initblocks = coin->blocks.hashblocks = coin->blocks.issuedblocks = coin->blocks.recvblocks = coin->blocks.emitblocks = coin->blocks.parsedblocks = coin->blocks.dirty = 0; + coin->blocks.maxbits = */coin->blocks.maxblocks = coin->blocks.initblocks = coin->blocks.hashblocks = coin->blocks.issuedblocks = coin->blocks.recvblocks = coin->blocks.emitblocks = coin->blocks.parsedblocks = coin->blocks.dirty = 0; + printf("clear hwmchain\n"); memset(&coin->blocks.hwmchain,0,sizeof(coin->blocks.hwmchain)); } @@ -439,7 +481,8 @@ void iguana_coinpurge(struct iguana_info *coin) myfree(req,req->allocsize); } } - iguana_RTramchainfree(coin,coin->current); + //iguana_RTramchainfree(coin,coin->current); + iguana_RTdataset_free(coin); coin->bundlescount = 0; for (i=0; ibundlescount; i++) if ( (bp= coin->bundles[i]) != 0 ) @@ -453,115 +496,116 @@ void iguana_coinpurge(struct iguana_info *coin) struct iguana_info *iguana_coinstart(struct iguana_info *coin,int32_t initialheight,int32_t mapflags) { FILE *fp; char fname[512],*symbol; int32_t iter; long fpos; bits256 lastbundle; struct supernet_info *myinfo = SuperNET_MYINFO(0); + /*if ( coin->peers == 0 ) + { + printf("cant start privatechain directly\n"); + return(0); + }*/ coin->sleeptime = 10000; symbol = coin->symbol; - if ( iguana_peerslotinit(coin,&coin->internaladdr,IGUANA_MAXPEERS,calc_ipbits("127.0.0.1:7777")) < 0 ) + if ( coin->peers != 0 && iguana_peerslotinit(coin,&coin->internaladdr,IGUANA_MAXPEERS,calc_ipbits("127.0.0.1:7777")) < 0 ) { printf("iguana_coinstart: error creating peerslot\n"); return(0); } if ( initialheight < coin->chain->bundlesize*10 ) initialheight = coin->chain->bundlesize*10; - iguana_recvalloc(coin,initialheight); if ( coin->longestchain == 0 ) coin->longestchain = 1; memset(&coin->blocks.hwmchain,0,sizeof(coin->blocks.hwmchain)); coin->blocks.hwmchain.height = 0; + coin->blocks.hwmchain.RO.allocsize = coin->chain->zcash != 0 ? sizeof(struct iguana_zblock) : sizeof(struct iguana_block); printf("%s MYSERVICES.%llx\n",coin->symbol,(long long)coin->myservices); - if ( (coin->myservices & NODE_NETWORK) != 0 ) + if ( coin->virtualchain == 0 && coin->peers != 0 ) { - if ( coin->peers.acceptloop == 0 && coin->peers.localaddr == 0 ) + if ( (coin->myservices & NODE_NETWORK) != 0 || (coin->FULLNODE != 0 || coin->VALIDATENODE != 0) ) { - coin->peers.acceptloop = malloc(sizeof(pthread_t)); - if ( OS_thread_create(coin->peers.acceptloop,NULL,(void *)iguana_acceptloop,(void *)coin) != 0 ) + if ( coin->peers->acceptloop == 0 && coin->peers->localaddr == 0 ) { - free(coin->peers.acceptloop); - coin->peers.acceptloop = 0; - printf("error launching accept thread for port.%u\n",coin->chain->portp2p); + coin->peers->acceptloop = malloc(sizeof(pthread_t)); + if ( OS_thread_create(coin->peers->acceptloop,NULL,(void *)iguana_acceptloop,(void *)coin) != 0 ) + { + free(coin->peers->acceptloop); + coin->peers->acceptloop = 0; + printf("error launching accept thread for port.%u\n",coin->chain->portp2p); + } + } + } + if ( coin->FULLNODE != 0 && coin->rpcloop == 0 ) + { + myinfo->argport = coin->chain->rpcport; + coin->rpcloop = malloc(sizeof(pthread_t)); + if ( OS_thread_create(coin->rpcloop,NULL,(void *)iguana_rpcloop,(void *)myinfo) != 0 ) + { + free(coin->rpcloop); + coin->rpcloop = 0; + printf("error launching rpcloop for %s port.%u\n",coin->symbol,coin->chain->rpcport); } } } - if ( (coin->myservices & 0x80) == 0x80 && coin->rpcloop == 0 ) + //coin->firstblock = coin->blocks.parsedblocks + 1; + iguana_genesis(myinfo,coin,coin->chain); + int32_t bundlei = -2; + static const bits256 zero; + iguana_bundlecreate(coin,&bundlei,0,*(bits256 *)coin->chain->genesis_hashdata,zero,1); + if ( coin->virtualchain == 0 ) { - myinfo->argport = coin->chain->rpcport; - coin->rpcloop = malloc(sizeof(pthread_t)); - if ( OS_thread_create(coin->rpcloop,NULL,(void *)iguana_rpcloop,(void *)myinfo) != 0 ) + _iguana_chainlink(myinfo,coin,iguana_blockfind("genesis",coin,*(bits256 *)coin->chain->genesis_hashdata)); + if ( coin->blocks.hwmchain.height != 0 || memcmp(coin->blocks.hwmchain.RO.hash2.bytes,coin->chain->genesis_hashdata,sizeof(coin->chain->genesis_hashdata)) != 0 ) { - free(coin->rpcloop); - coin->rpcloop = 0; - printf("error launching rpcloop for %s port.%u\n",coin->symbol,coin->chain->rpcport); + char str[65]; printf("%s genesis values mismatch hwmheight.%d %.15f %.15f %s\n",coin->name,coin->blocks.hwmchain.height,coin->blocks.hwmchain.PoW,coin->blocks.hwmchain.PoW,bits256_str(str,coin->blocks.hwmchain.RO.hash2)); + getchar(); } } - //coin->firstblock = coin->blocks.parsedblocks + 1; - iguana_genesis(coin,coin->chain); memset(&lastbundle,0,sizeof(lastbundle)); - for (iter=coin->peers.numranked>8; iter<2; iter++) + if ( coin->peers == 0 ) + iter = 2; + else iter = (coin->peers->numranked > 8); + for (; iter<2; iter++) { #ifdef __PNACL__ if ( iter == 0 ) { char **ipaddrs = 0; int32_t j,num; - char *BTC_ipaddrs[] = { "5.9.102.210", "130.211.146.81", "1176.9.29.76", "108.58.252.82", "148.251.151.48", "74.207.233.193" }; + char *BTC_ipaddrs[] = { "5.9.102.210", "130.211.146.81", "176.9.29.76", "108.58.252.82", "148.251.151.48", "74.207.233.193" }; char *BTCD_ipaddrs[] = { "5.9.102.210", "89.248.160.236", "89.248.160.237", "89.248.160.238", "89.248.160.239", "89.248.160.240", "89.248.160.241", "89.248.160.242", "89.248.160.243", "89.248.160.244", "89.248.160.245", "78.47.58.62", "67.212.70.88", "94.102.50.69", "50.179.58.158", "194.135.94.30", "109.236.85.42", "104.236.127.154", "68.45.147.145", "37.59.14.7", "78.47.115.250", "188.40.138.8", "62.75.143.120", "82.241.71.230", "217.23.6.2", "73.28.172.128", "45.55.149.34", "192.0.242.54", "81.181.155.53", "91.66.185.97", "85.25.217.233", "144.76.239.66", "95.80.9.112", "80.162.193.118", "173.65.129.85", "2.26.173.58", "78.14.250.69", "188.226.253.77", "58.107.67.39", "124.191.37.212", "176.226.137.238", "69.145.25.85", "24.168.14.28", "73.201.180.47", "76.188.171.53", "63.247.147.166", "121.108.241.247", "36.74.36.125", "106.186.119.171", "188.166.91.37", "223.134.228.208", "89.248.160.244", "178.33.209.212", "71.53.156.38", "88.198.10.165", "24.117.221.0", "74.14.104.57", "158.69.27.82", "110.174.129.213", "75.130.163.51" }; if ( strcmp(coin->symbol,"BTCD") == 0 ) ipaddrs = BTCD_ipaddrs, num = (int32_t)(sizeof(BTCD_ipaddrs)/sizeof(*BTCD_ipaddrs)); else if ( strcmp(coin->symbol,"BTC") == 0 ) ipaddrs = BTC_ipaddrs, num = (int32_t)(sizeof(BTC_ipaddrs)/sizeof(*BTC_ipaddrs)); - if ( ipaddrs != 0 ) + if ( ipaddrs != 0 && coin->virtualchain == 0 ) { for (j=0; jsymbol,"BTCD") == 0 ) - { - bits256 hash2,allhash,hash1; int32_t bundlei,i,nonz,height; struct iguana_bundle *bp; - for (i=nonz=0; i (coin->blocks.maxbits - 1000) ) - iguana_recvalloc(coin,height + 100000); - hash2 = bits256_conv(BTCD_hdrs[i][1]); - if ( BTCD_hdrs[i][2][0] != 0 ) - allhash = bits256_conv(BTCD_hdrs[i][2]); - if ( BTCD_hdrs[i][3][0] != 0 ) - hash1 = bits256_conv(BTCD_hdrs[i][3]); - if ( (bp= iguana_bundlecreate(coin,&bundlei,height,hash2,allhash,0)) != 0 ) - { - if ( iguana_bundleinitmap(coin,bp,height,hash2,hash1) == 0 ) - lastbundle = hash2, nonz++; - } - } - printf("H file.[%d] nonz.%d\n",i,nonz); - //if ( bits256_nonz(lastbundle) != 0 ) - // iguana_initfinal(coin,lastbundle); - //break; - } } #endif sprintf(fname,"%s/%s_%s.txt",GLOBAL_CONFSDIR,coin->symbol,(iter == 0) ? "peers" : "hdrs"), OS_compatible_path(fname); //sprintf(fname,"confs/%s_%s.txt",coin->symbol,(iter == 0) ? "peers" : "hdrs"); //sprintf(fname,"tmp/%s/%s.txt",coin->symbol,(iter == 0) ? "peers" : "hdrs"); OS_compatible_path(fname); - printf("parsefile.%d %s\n",iter,fname); if ( (fp= fopen(fname,"r")) != 0 ) { - iguana_parseline(coin,iter,fp); + if ( coin->virtualchain == 0 || iter > 0 ) + { + printf("parsefile.%d %s\n",iter,fname); + iguana_parseline(myinfo,coin,iter,fp); + printf("done parsefile.%d (%s) size.%ld\n",iter,fname,fpos); + } fpos = ftell(fp); fclose(fp); } else fpos = -1; - printf("done parsefile.%d (%s) size.%ld\n",iter,fname,fpos); } #ifndef IGUANA_DEDICATED_THREADS - coin->peers.peersloop = iguana_launch("peersloop",iguana_peersloop,coin,IGUANA_PERMTHREAD); + coin->peers->peersloop = iguana_launch("peersloop",iguana_peersloop,coin,IGUANA_PERMTHREAD); #endif printf("started.%s %p active.%d\n",coin->symbol,coin->started,coin->active); return(coin); diff --git a/iguana/iguana_instantdex.c b/iguana/iguana_instantdex.c deleted file mode 100755 index d1a579cf8..000000000 --- a/iguana/iguana_instantdex.c +++ /dev/null @@ -1,1266 +0,0 @@ -/****************************************************************************** - * Copyright © 2014-2016 The SuperNET Developers. * - * * - * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * - * the top-level directory of this distribution for the individual copyright * - * holder information and the developer policies on copyright and licensing. * - * * - * Unless otherwise agreed in a custom licensing agreement, no part of the * - * SuperNET software, including this file may be copied, modified, propagated * - * or distributed except according to the terms contained in the LICENSE file * - * * - * Removal or modification of this copyright notice is prohibited. * - * * - ******************************************************************************/ - -// selftest supports against allpairs list - -#include "exchanges777.h" - -struct instantdex_stateinfo *BTC_states; int32_t BTC_numstates; - -int64_t instantdex_BTCsatoshis(int64_t price,int64_t volume) -{ - if ( volume > price ) - return(price * dstr(volume)); - else return(dstr(price) * volume); -} - -int64_t instantdex_insurance(struct iguana_info *coin,int64_t amount) -{ - return(amount * INSTANTDEX_INSURANCERATE + coin->chain->txfee); // insurance prevents attack -} - -void instantdex_swapfree(struct instantdex_accept *A,struct bitcoin_swapinfo *swap) -{ - if ( A != 0 ) - free(A); - if ( swap != 0 ) - { - if ( swap->deposit != 0 ) - free(swap->deposit); - if ( swap->payment != 0 ) - free(swap->payment); - if ( swap->altpayment != 0 ) - free(swap->altpayment); - if ( swap->myfee != 0 ) - free(swap->myfee); - if ( swap->otherfee != 0 ) - free(swap->otherfee); - } -} - -cJSON *instantdex_defaultprocess(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) -{ - uint8_t *serdata = *serdatap; int32_t serdatalen = *serdatalenp; - *serdatap = 0, *serdatalenp = 0; - if ( serdata != 0 && serdatalen > 0 ) - { - serdata[serdatalen-1] = 0; - } - return(newjson); -} - -cJSON *instantdex_defaulttimeout(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) -{ - uint8_t *serdata = *serdatap; int32_t serdatalen = *serdatalenp; - *serdatap = 0, *serdatalenp = 0; - if ( serdata != 0 && serdatalen > 0 ) - { - serdata[serdatalen-1] = 0; - } - return(newjson); -} - -struct instantdex_stateinfo instantdex_errorstate = { "error", 0,0, instantdex_defaultprocess, instantdex_defaulttimeout }; -struct instantdex_stateinfo instantdex_timeoutstate = { "timeout", 1,0, instantdex_defaultprocess, instantdex_defaulttimeout }; - -struct instantdex_stateinfo *instantdex_statefind(struct instantdex_stateinfo *states,int32_t numstates,char *statename) -{ - int32_t i; struct instantdex_stateinfo *state = 0; - if ( states != 0 && statename != 0 && numstates > 0 ) - { - for (i=0; iname,statename) == 0 ) - return(state); - } - } - return(0); -} - -void instantdex_stateinit(struct instantdex_stateinfo *states,int32_t numstates,struct instantdex_stateinfo *state,char *name,char *errorstr,char *timeoutstr,void *process_func,void *timeout_func) -{ - struct instantdex_stateinfo *timeoutstate,*errorstate; - memset(state,0,sizeof(*state)); - strcpy(state->name,name); - if ( (errorstate= instantdex_statefind(states,numstates,errorstr)) == 0 ) - errorstate = &instantdex_errorstate; - state->errorind = errorstate->ind; - if ( (timeoutstate= instantdex_statefind(states,numstates,timeoutstr)) == 0 ) - timeoutstate = &instantdex_timeoutstate; - else printf("TS.%s ",timeoutstr); - state->timeoutind = timeoutstate->ind; - if ( (state->process= process_func) == 0 ) - state->process = instantdex_defaultprocess; - if ( (state->timeout= timeout_func) == 0 ) - state->timeout = instantdex_defaulttimeout; -} - -struct instantdex_stateinfo *instantdex_statecreate(struct instantdex_stateinfo *states,int32_t *numstatesp,char *name,cJSON *(*process_func)(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp),cJSON *(*timeout_func)(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp),char *timeoutstr,char *errorstr,int32_t initialstate) -{ - struct instantdex_stateinfo S,*state = 0; - if ( (state= instantdex_statefind(states,*numstatesp,name)) == 0 ) - { - states = realloc(states,sizeof(*states) * (*numstatesp + 1)); - state = &states[*numstatesp]; - instantdex_stateinit(states,*numstatesp,state,name,errorstr,timeoutstr,process_func,timeout_func); - state->initialstate = initialstate; - printf("STATES[%d] %s %p %p %d %d\n",*numstatesp,state->name,state->process,state->timeout,state->timeoutind,state->errorind); - state->ind = (*numstatesp)++; - } - else - { - instantdex_stateinit(states,*numstatesp,&S,name,errorstr,timeoutstr,process_func,timeout_func); - S.ind = state->ind; - S.initialstate = initialstate; - if ( memcmp(&S,state,sizeof(S) - sizeof(void *) - sizeof(int)) != 0 ) - { - int32_t i; - for (i=0; iname,state->process,state->timeout,state->timeoutind,state->errorind,S.name,S.process,S.timeout,S.timeoutind,S.errorind); - printf("statecreate error!!! (%s) already exists\n",name); - } - } - return(states); -} - -struct instantdex_event *instantdex_addevent(struct instantdex_stateinfo *states,int32_t numstates,char *statename,char *cmdstr,char *sendcmd,char *nextstatename) -{ - struct instantdex_stateinfo *nextstate,*state; - if ( (state= instantdex_statefind(states,numstates,statename)) != 0 && (nextstate= instantdex_statefind(states,numstates,nextstatename)) != 0 ) - { - if ( (state->events= realloc(state->events,(state->numevents + 1) * sizeof(*state->events))) != 0 ) - { - memset(&state->events[state->numevents],0,sizeof(state->events[state->numevents])); - strcpy(state->events[state->numevents].cmdstr,cmdstr); - if ( sendcmd != 0 ) - strcpy(state->events[state->numevents].sendcmd,sendcmd); - state->events[state->numevents].nextstateind = nextstate->ind; - state->numevents++; - } - return(state->events); - } - else - { - int32_t i; - for (i=0; i %s) without existing state and nextstate\n",statename,nextstatename); - exit(-1); - return(0); - } -} - -double instantdex_FSMtest(struct instantdex_stateinfo *states,int32_t numstates,int32_t maxiters) -{ - int32_t i,most,r,r2,n,m=0,initials[100],nextstate=-1; - struct instantdex_stateinfo *state; struct instantdex_event *event; double sum = 0.; - if ( maxiters < 1 ) - maxiters = 1; - for (i=n=most=0; i 0 ) - { - printf("initialstate[%d] %d %s\n",i,states[i].initialstate,states[i].name); - initials[n++] = i; - } - if ( n > 0 && n < sizeof(initials)/sizeof(*initials) ) - { - for (i=0; iname[0] == 0 || state->ind >= numstates ) - { - printf("illegal state.(%s) %d? ind.%d >= numstates.%d\n",state->name,nextstate,state->ind,numstates); - break; - } - m = 0; - while ( m++ < 1000 && state->initialstate >= 0 && state->numevents != 0 ) - { - if ( (i % 1000000) == 0 ) - fprintf(stderr,"%s ",state->name); - r2 = rand() % state->numevents; - event = &state->events[r2]; - if ( (nextstate= event->nextstateind) < 0 ) - break; - if ( event->nextstateind >= numstates ) - { - printf("nextstateind overflow? %d vs %d\n",event->nextstateind,numstates); - break; - } - state = &states[event->nextstateind]; - } - if ( m > most ) - most = m; - sum += m; - if ( (i % 1000000) == 0 ) - fprintf(stderr,"reached %s m.%d events most.%d ave %.2f\n",state->name,m,most,sum/(i+1)); - } - } - fprintf(stderr," most.%d ave %.2f\n",most,sum/(i+1)); - return(sum / maxiters); -} - -cJSON *InstantDEX_argjson(char *reference,char *message,char *othercoinaddr,char *otherNXTaddr,int32_t iter,int32_t val,int32_t val2) -{ - cJSON *argjson = cJSON_CreateObject(); - if ( reference != 0 ) - jaddstr(argjson,"refstr",reference); - if ( message != 0 && message[0] != 0 ) - jaddstr(argjson,"message",message); - if ( othercoinaddr != 0 && othercoinaddr[0] != 0 ) - jaddstr(argjson,"othercoinaddr",othercoinaddr); - if ( otherNXTaddr != 0 && otherNXTaddr[0] != 0 ) - jaddstr(argjson,"otherNXTaddr",otherNXTaddr); - //jaddbits256(argjson,"basetxid",basetxid); - //jaddbits256(argjson,"reltxid",reltxid); - if ( iter != 3 ) - { - if ( val == 0 ) - val = INSTANTDEX_DURATION; - jaddnum(argjson,"duration",val); - jaddnum(argjson,"flags",val2); - } - else - { - if ( val > 0 ) - jaddnum(argjson,"baseheight",val); - if ( val2 > 0 ) - jaddnum(argjson,"relheight",val2); - } - return(argjson); -} - -struct instantdex_msghdr *instantdex_msgcreate(struct supernet_info *myinfo,struct instantdex_msghdr *msg,int32_t datalen) -{ - bits256 otherpubkey; uint64_t signerbits; uint32_t timestamp; uint8_t buf[sizeof(msg->sig)],*data; - memset(&msg->sig,0,sizeof(msg->sig)); - datalen += (int32_t)(sizeof(*msg) - sizeof(msg->sig)); - data = (void *)((long)msg + sizeof(msg->sig)); - otherpubkey = acct777_msgpubkey(data,datalen); - timestamp = (uint32_t)time(NULL); - acct777_sign(&msg->sig,myinfo->privkey,otherpubkey,timestamp,data,datalen); - //printf("signed datalen.%d allocsize.%d crc.%x\n",datalen,msg->sig.allocsize,calc_crc32(0,data,datalen)); - if ( (signerbits= acct777_validate(&msg->sig,acct777_msgprivkey(data,datalen),msg->sig.pubkey)) != 0 ) - { - //int32_t i; - //char str[65],str2[65]; - //for (i=0; i>>>>>>>>>>>>>>> validated [%ld] len.%d (%s + %s)\n",(long)data-(long)msg,datalen,bits256_str(str,acct777_msgprivkey(data,datalen)),bits256_str(str2,msg->sig.pubkey)); - memset(buf,0,sizeof(buf)); - acct777_rwsig(1,buf,&msg->sig); - memcpy(&msg->sig,buf,sizeof(buf)); - return(msg); - } else printf("error validating instantdex msg\n"); - return(0); -} - -bits256 instantdex_rwoffer(int32_t rwflag,int32_t *lenp,uint8_t *serialized,struct instantdex_offer *offer) -{ - bits256 orderhash; int32_t len = 0; - if ( rwflag == 1 ) - { - vcalc_sha256(0,orderhash.bytes,(void *)offer,sizeof(*offer)); - /*int32_t i; - for (i=0; ibase),offer->base); - len += iguana_rwstr(rwflag,&serialized[len],sizeof(offer->rel),offer->rel); - len += iguana_rwnum(rwflag,&serialized[len],sizeof(offer->price64),&offer->price64); - len += iguana_rwnum(rwflag,&serialized[len],sizeof(offer->basevolume64),&offer->basevolume64); - len += iguana_rwnum(rwflag,&serialized[len],sizeof(offer->offer64),&offer->offer64); - len += iguana_rwnum(rwflag,&serialized[len],sizeof(offer->expiration),&offer->expiration); - len += iguana_rwnum(rwflag,&serialized[len],sizeof(offer->nonce),&offer->nonce); - len += iguana_rwnum(rwflag,&serialized[len],sizeof(offer->myside),&offer->myside); - len += iguana_rwnum(rwflag,&serialized[len],sizeof(offer->acceptdir),&offer->acceptdir); - if ( rwflag == 0 ) - { - vcalc_sha256(0,orderhash.bytes,(void *)offer,sizeof(*offer)); - /*int32_t i; - for (i=0; ihandle); - jaddbits256(argjson,"categoryhash",instantdexhash); - jaddbits256(argjson,"traderpub",myinfo->myaddr.persistent); - orderhash = instantdex_rwoffer(1,&olen,serialized,offer); - if ( 1 ) - { - struct instantdex_offer checkoffer; bits256 checkhash; int32_t checklen; - checkhash = instantdex_rwoffer(0,&checklen,serialized,&checkoffer); - if ( checkhash.txid != orderhash.txid ) - { - for (i=0; imyaddr.persistent); - reqstr = jprint(argjson,0); - slen = (int32_t)(strlen(reqstr) + 1); - datalen = (int32_t)slen + extralen + olen; - msg = calloc(1,datalen + sizeof(*msg)); - for (i=0; icmd); i++) - if ( (msg->cmd[i]= cmdstr[i]) == 0 ) - break; - memcpy(msg->serialized,reqstr,slen); - memcpy(&msg->serialized[slen],serialized,olen); - //printf("extralen.%d datalen.%d slen.%d olen.%d\n",extralen,datalen,slen,olen); - if ( extralen > 0 ) - memcpy(&msg->serialized[slen + olen],extraser,extralen); - free(reqstr); - if ( instantdex_msgcreate(myinfo,msg,datalen) != 0 ) - { - printf(">>>>>>>>>>>> instantdex send.(%s) datalen.%d allocsize.%d crc.%x\n",cmdstr,datalen,msg->sig.allocsize,calc_crc32(0,(void *)((long)msg + 8),datalen-8)); - hexstr = malloc(msg->sig.allocsize*2 + 1); - init_hexbytes_noT(hexstr,(uint8_t *)msg,msg->sig.allocsize); - retstr = SuperNET_categorymulticast(myinfo,0,instantdexhash,desthash,hexstr,0,hops,1,argjson,0); - free_json(argjson), free(hexstr), free(msg); - return(retstr); - } - else - { - free_json(argjson), free(msg); - printf("cant msgcreate datalen.%d\n",datalen); - return(clonestr("{\"error\":\"couldnt create instantdex message\"}")); - } -} - -int32_t instantdex_updatesources(struct exchange_info *exchange,struct exchange_quote *sortbuf,int32_t n,int32_t max,int32_t ind,int32_t dir,struct exchange_quote *quotes,int32_t numquotes) -{ - int32_t i; struct exchange_quote *quote; - //printf("instantdex_updatesources update dir.%d numquotes.%d\n",dir,numquotes); - for (i=0; iprice,quote->volume); - if ( quote->price > SMALLVAL ) - { - sortbuf[n] = *quote; - sortbuf[n].val = ind; - sortbuf[n].exchangebits = exchange->exchangebits; - //printf("sortbuf[%d] <-\n",n*2); - if ( ++n >= max ) - break; - } - } - return(n); -} - -double instantdex_aveprice(struct supernet_info *myinfo,struct exchange_quote *sortbuf,int32_t max,double *totalvolp,char *base,char *rel,double basevolume,cJSON *argjson) -{ - char *str; double totalvol,pricesum; uint32_t timestamp; - struct exchange_quote quote; int32_t i,n,dir,num,depth = 100; - struct exchange_info *exchange; struct exchange_request *req,*active[64]; - timestamp = (uint32_t)time(NULL); - if ( basevolume < 0. ) - basevolume = -basevolume, dir = -1; - else dir = 1; - memset(sortbuf,0,sizeof(*sortbuf) * max); - if ( base != 0 && rel != 0 && basevolume > SMALLVAL ) - { - for (i=num=0; inumexchanges && num < sizeof(active)/sizeof(*active); i++) - { - if ( (exchange= myinfo->tradingexchanges[i]) != 0 ) - { - if ( (req= exchanges777_baserelfind(exchange,base,rel,'M')) == 0 ) - { - if ( (str= exchanges777_Qprices(exchange,base,rel,30,1,depth,argjson,1,exchange->commission)) != 0 ) - free(str); - req = exchanges777_baserelfind(exchange,base,rel,'M'); - } - if ( req == 0 ) - { - if ( (*exchange->issue.supports)(exchange,base,rel,argjson) != 0 ) - printf("unexpected null req.(%s %s) %s\n",base,rel,exchange->name); - } - else - { - //printf("active.%s\n",exchange->name); - active[num++] = req; - } - } - } - for (i=n=0; inumbids > 0 ) - n = instantdex_updatesources(active[i]->exchange,sortbuf,n,max,i,1,active[i]->bidasks,active[i]->numbids); - else if ( dir > 0 && active[i]->numasks > 0 ) - n = instantdex_updatesources(active[i]->exchange,sortbuf,n,max,i,-1,&active[i]->bidasks[1],active[i]->numasks); - } - //printf("dir.%d %s/%s numX.%d n.%d\n",dir,base,rel,num,n); - if ( dir < 0 ) - revsort64s(&sortbuf[0].satoshis,n,sizeof(*sortbuf)); - else sort64s(&sortbuf[0].satoshis,n,sizeof(*sortbuf)); - for (totalvol=pricesum=i=0; iexchange->name,pricesum/totalvol,totalvol); - } - } - if ( totalvol > 0. ) - { - *totalvolp = totalvol; - return(pricesum / totalvol); - } - } - *totalvolp = 0; - return(0); -} - -double instantdex_avehbla(struct supernet_info *myinfo,double retvals[4],char *base,char *rel,double basevolume) -{ - double avebid,aveask,bidvol,askvol; struct exchange_quote sortbuf[256]; cJSON *argjson; - argjson = cJSON_CreateObject(); - aveask = instantdex_aveprice(myinfo,sortbuf,sizeof(sortbuf)/sizeof(*sortbuf),&askvol,base,rel,basevolume,argjson); - avebid = instantdex_aveprice(myinfo,sortbuf,sizeof(sortbuf)/sizeof(*sortbuf),&bidvol,base,rel,-basevolume,argjson); - free_json(argjson); - retvals[0] = avebid, retvals[1] = bidvol, retvals[2] = aveask, retvals[3] = askvol; - if ( avebid > SMALLVAL && aveask > SMALLVAL ) - return((avebid + aveask) * .5); - else return(0); -} - -int32_t instantdex_bidaskdir(struct instantdex_offer *offer) -{ - if ( offer->myside == 0 && offer->acceptdir > 0 ) // base - return(-1); - else if ( offer->myside == 1 && offer->acceptdir < 0 ) // rel - return(1); - else return(0); -} - -cJSON *instantdex_offerjson(struct instantdex_offer *offer,uint64_t orderid) -{ - int32_t dir; cJSON *item = cJSON_CreateObject(); - jadd64bits(item,"orderid",orderid); - jadd64bits(item,"offerer",offer->offer64); - if ( (dir= instantdex_bidaskdir(offer)) > 0 ) - jaddstr(item,"type","bid"); - else if ( dir < 0 ) - jaddstr(item,"type","ask"); - else - { - jaddstr(item,"type","strange"); - jaddnum(item,"acceptdir",offer->acceptdir); - jaddnum(item,"myside",offer->myside); - } - jaddstr(item,"base",offer->base); - jaddstr(item,"rel",offer->rel); - jaddnum(item,"timestamp",offer->expiration); - jaddnum(item,"price",dstr(offer->price64)); - jaddnum(item,"volume",dstr(offer->basevolume64)); - jaddnum(item,"minperc",offer->minperc); - jaddnum(item,"nonce",offer->nonce); - jaddnum(item,"expiresin",offer->expiration - time(NULL)); - return(item); -} - -cJSON *instantdex_acceptjson(struct instantdex_accept *ap) -{ - cJSON *item = cJSON_CreateObject(); - jadd64bits(item,"orderid",ap->orderid); - jaddnum(item,"pendingvolume",dstr(ap->pendingvolume64)); - if ( ap->dead != 0 ) - jadd64bits(item,"dead",ap->dead); - jadd(item,"offer",instantdex_offerjson(&ap->offer,ap->orderid)); - return(item); -} - -void instantdex_statetxjson(cJSON *array,char *name,struct bitcoin_statetx *tx) -{ - cJSON *item; - if ( tx != 0 ) - { - item = cJSON_CreateObject(); - jaddbits256(item,"txid",tx->txid); - jaddnum(item,"inputsum",dstr(tx->inputsum)); - jaddnum(item,"amount",dstr(tx->amount)); - jaddnum(item,"change",dstr(tx->change)); - jaddnum(item,"txfee",dstr(tx->inputsum) - dstr(tx->amount) - dstr(tx->change)); - jaddnum(item,"confirms",dstr(tx->numconfirms)); - jaddstr(item,"destaddr",tx->destaddr); - jaddstr(item,"txbytes",tx->txbytes); - jadd(array,name,item); - } -} - -cJSON *instantdex_statemachinejson(struct bitcoin_swapinfo *swap) -{ - cJSON *retjson,*txs; int32_t isbob,mydir,otherdir; - retjson = cJSON_CreateObject(); - if ( swap != 0 ) - { - mydir = instantdex_bidaskdir(&swap->mine.offer); - otherdir = instantdex_bidaskdir(&swap->other.offer); - isbob = instantdex_isbob(swap); - jaddnum(retjson,"isbob",isbob); - jaddnum(retjson,"mydir",mydir); - jaddnum(retjson,"otherdir",otherdir); - jaddnum(retjson,"expiration",swap->expiration); - jaddnum(retjson,"insurance",dstr(swap->insurance)); - jaddnum(retjson,"baseamount",dstr(swap->altsatoshis)); - jaddnum(retjson,"BTCamount",dstr(swap->BTCsatoshis)); - jaddnum(retjson,"expiration",swap->expiration); - if ( swap->dead != 0 ) - jadd64bits(retjson,"dead",swap->dead); - jaddbits256(retjson,"privAm",swap->privAm); - jaddbits256(retjson,"pubAm",swap->pubAm); - jaddbits256(retjson,"privBn",swap->privBn); - jaddbits256(retjson,"pubBn",swap->pubBn); - - jaddbits256(retjson,"myorderhash",swap->myorderhash); - jaddnum(retjson,"choosei",swap->choosei); - jaddnum(retjson,"cutverified",swap->cutverified); - jaddbits256(retjson,"othertrader",swap->othertrader); - jaddbits256(retjson,"otherorderhash",swap->otherorderhash); - jaddnum(retjson,"otherchoosei",swap->otherchoosei); - jaddnum(retjson,"otherverifiedcut",swap->otherverifiedcut); - if ( isbob == 0 ) - { - jaddbits256(retjson,"pubA0",swap->mypubs[0]); - jaddbits256(retjson,"pubA1",swap->mypubs[1]); - jaddbits256(retjson,"pubB0",swap->otherpubs[0]); - jaddbits256(retjson,"pubB1",swap->otherpubs[1]); - } - else - { - jaddbits256(retjson,"pubB0",swap->mypubs[0]); - jaddbits256(retjson,"pubB1",swap->mypubs[1]); - jaddbits256(retjson,"pubA0",swap->otherpubs[0]); - jaddbits256(retjson,"pubA1",swap->otherpubs[1]); - } - if ( mydir > 0 && otherdir < 0 ) - { - jadd64bits(retjson,"bidid",swap->mine.orderid); - jadd64bits(retjson,"askid",swap->other.orderid); - } - else if ( mydir < 0 && otherdir > 0 ) - { - jadd64bits(retjson,"askid",swap->mine.orderid); - jadd64bits(retjson,"bidid",swap->other.orderid); - } - if ( swap->matched64 == swap->mine.orderid ) - { - jadd(retjson,"initiator",instantdex_acceptjson(&swap->other)); - jadd(retjson,"matched",instantdex_acceptjson(&swap->mine)); - } - else if ( swap->matched64 == swap->other.orderid ) - { - jadd(retjson,"initiator",instantdex_acceptjson(&swap->mine)); - jadd(retjson,"matched",instantdex_acceptjson(&swap->other)); - } - else jaddstr(retjson,"initiator","illegal initiator missing"); - if ( swap->state != 0 ) - jaddstr(retjson,"state",swap->state->name); - txs = cJSON_CreateObject(); - instantdex_statetxjson(txs,"deposit",swap->deposit); - instantdex_statetxjson(txs,"payment",swap->payment); - instantdex_statetxjson(txs,"altpayment",swap->altpayment); - instantdex_statetxjson(txs,"myfee",swap->myfee); - instantdex_statetxjson(txs,"otherfee",swap->otherfee); - jadd(retjson,"txs",txs); - jaddstr(retjson,"status",swap->status); - } - return(retjson); -} - -cJSON *instantdex_historyjson(struct bitcoin_swapinfo *swap) -{ - // need to make sure accepts are put onto history queue when they are completed or deaded - // also to make permanent copy (somewhere) - return(instantdex_statemachinejson(swap)); -} - -struct bitcoin_swapinfo *instantdex_historyfind(struct supernet_info *myinfo,struct exchange_info *exchange,uint64_t orderid) -{ - struct bitcoin_swapinfo PAD,*swap,*retswap = 0; uint32_t now; - now = (uint32_t)time(NULL); - memset(&PAD,0,sizeof(PAD)); - queue_enqueue("historyQ",&exchange->historyQ,&PAD.DL,0); - while ( (swap= queue_dequeue(&exchange->historyQ,0)) != 0 && swap != &PAD ) - { - if ( orderid == swap->mine.orderid ) - retswap = swap; - queue_enqueue("historyQ",&exchange->historyQ,&swap->DL,0); - } - return(retswap); -} - -struct bitcoin_swapinfo *instantdex_statemachinefind(struct supernet_info *myinfo,struct exchange_info *exchange,uint64_t orderid,int32_t requeueflag) -{ - struct bitcoin_swapinfo PAD,*swap,*retswap = 0; uint32_t now; - now = (uint32_t)time(NULL); - memset(&PAD,0,sizeof(PAD)); - queue_enqueue("statemachineQ",&exchange->statemachineQ,&PAD.DL,0); - while ( (swap= queue_dequeue(&exchange->statemachineQ,0)) != 0 && swap != &PAD ) - { - if ( now < swap->expiration && swap->mine.dead == 0 && swap->other.dead == 0 ) - { - if ( orderid == swap->mine.orderid || orderid == swap->other.orderid ) - { - if ( retswap != 0 && requeueflag == 0 ) - queue_enqueue("statemachineQ",&exchange->statemachineQ,&retswap->DL,0); - retswap = swap; - } - } - else - { - strcpy(swap->status,"expired"); - printf("expired pending, need to take action, send timeout event\n"); - queue_enqueue("historyQ",&exchange->historyQ,&swap->DL,0); - continue; - } - if ( swap != retswap || requeueflag != 0 ) - queue_enqueue("statemachineQ",&exchange->statemachineQ,&swap->DL,0); - } - //printf("found statemachine.%p\n",retswap); - return(retswap); -} - -struct instantdex_accept *instantdex_offerfind(struct supernet_info *myinfo,struct exchange_info *exchange,cJSON *bids,cJSON *asks,uint64_t orderid,char *base,char *rel,int32_t requeue) -{ - struct instantdex_accept PAD,*ap,*retap = 0; uint32_t now; cJSON *item,*offerobj; char *type; - now = (uint32_t)time(NULL); - memset(&PAD,0,sizeof(PAD)); - queue_enqueue("acceptableQ",&exchange->acceptableQ,&PAD.DL,0); - while ( (ap= queue_dequeue(&exchange->acceptableQ,0)) != 0 && ap != &PAD ) - { - if ( now < ap->offer.expiration && ap->dead == 0 ) - { - //printf("%d %d find cmps %d %d %d %d %d %d me.%llu vs %llu o.%llu | vs %llu\n",instantdex_bidaskdir(&ap->offer),ap->offer.expiration-now,strcmp(base,"*") == 0,strcmp(base,ap->offer.base) == 0,strcmp(rel,"*") == 0,strcmp(rel,ap->offer.rel) == 0,orderid == 0,orderid == ap->orderid,(long long)myinfo->myaddr.nxt64bits,(long long)ap->offer.offer64,(long long)ap->orderid,(long long)orderid); - if ( (strcmp(base,"*") == 0 || strcmp(base,ap->offer.base) == 0) && (strcmp(rel,"*") == 0 || strcmp(rel,ap->offer.rel) == 0) && (orderid == 0 || orderid == ap->orderid) ) - { - if ( requeue == 0 && retap != 0 ) - queue_enqueue("acceptableQ",&exchange->acceptableQ,&retap->DL,0); - retap = ap; - } - if ( (item= instantdex_acceptjson(ap)) != 0 ) - { - //printf("item.(%s)\n",jprint(item,0)); - if ( (offerobj= jobj(item,"offer")) != 0 && (type= jstr(offerobj,"type")) != 0 ) - { - if ( strcmp(type,"bid") == 0 && bids != 0 ) - jaddi(bids,jduplicate(offerobj)); - else if ( strcmp(type,"ask") == 0 && asks != 0 ) - jaddi(asks,jduplicate(offerobj)); - } - free_json(item); - } else printf("error generating acceptjson.%llu\n",(long long)ap->orderid); - if ( ap != retap || requeue != 0 ) - { - //printf("requeue.%p\n",ap); - queue_enqueue("acceptableQ",&exchange->acceptableQ,&ap->DL,0); - } - } else free(ap); - } - return(retap); -} - -struct instantdex_accept *instantdex_acceptable(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *A,double minperc) -{ - struct instantdex_accept PAD,*ap,*retap = 0; double aveprice;//,retvals[4]; - uint64_t minvol,bestprice64 = 0; uint32_t now; int32_t offerdir; - aveprice = 0;//instantdex_avehbla(myinfo,retvals,A->offer.base,A->offer.rel,dstr(A->offer.basevolume64)); - now = (uint32_t)time(NULL); - memset(&PAD,0,sizeof(PAD)); - queue_enqueue("acceptableQ",&exchange->acceptableQ,&PAD.DL,0); - offerdir = instantdex_bidaskdir(&A->offer); - minvol = (A->offer.basevolume64 * minperc * .01); - printf("offerdir.%d (%s/%s) minperc %.3f minvol %.8f vs %.8f\n",offerdir,A->offer.base,A->offer.rel,minperc,dstr(minvol),dstr(A->offer.basevolume64)); - while ( (ap= queue_dequeue(&exchange->acceptableQ,0)) != 0 && ap != &PAD ) - { - if ( now > ap->offer.expiration || ap->dead != 0 || A->offer.offer64 == ap->offer.offer64 ) - { - //printf("now.%u skip expired %u/dead.%u or my order orderid.%llu from %llu\n",now,ap->offer.expiration,ap->dead,(long long)ap->orderid,(long long)ap->offer.offer64); - } - else if ( strcmp(ap->offer.base,A->offer.base) != 0 || strcmp(ap->offer.rel,A->offer.rel) != 0 ) - { - //printf("skip mismatched.(%s/%s) orderid.%llu from %llu\n",ap->offer.base,ap->offer.rel,(long long)ap->orderid,(long long)ap->offer.offer64); - } - else if ( offerdir*instantdex_bidaskdir(&ap->offer) > 0 ) - { - //printf("skip same direction %d orderid.%llu from %llu\n",instantdex_bidaskdir(&ap->offer),(long long)ap->orderid,(long long)ap->offer.offer64); - } - else if ( minvol > ap->offer.basevolume64 - ap->pendingvolume64 ) - { - //printf("skip too small order %.8f vs %.8f orderid.%llu from %llu\n",dstr(minvol),dstr(ap->offer.basevolume64)-dstr(ap->pendingvolume64),(long long)ap->orderid,(long long)ap->offer.offer64); - } - else if ( (offerdir > 0 && ap->offer.price64 > A->offer.price64) || (offerdir < 0 && ap->offer.price64 < A->offer.price64) ) - { - //printf("skip out of band dir.%d offer %.8f vs %.8f orderid.%llu from %llu\n",offerdir,dstr(ap->offer.price64),dstr(A->offer.price64),(long long)ap->orderid,(long long)ap->offer.offer64); - } - else - { - if ( bestprice64 == 0 || (offerdir > 0 && ap->offer.price64 < bestprice64) || (offerdir < 0 && ap->offer.price64 > bestprice64) ) - { - printf(">>>> MATCHED better price dir.%d offer %.8f vs %.8f orderid.%llu from %llu\n",offerdir,dstr(ap->offer.price64),dstr(A->offer.price64),(long long)ap->orderid,(long long)ap->offer.offer64); - bestprice64 = ap->offer.price64; - if ( retap != 0 ) - queue_enqueue("acceptableQ",&exchange->acceptableQ,&retap->DL,0); - retap = ap; - } - } - if ( ap != retap ) - queue_enqueue("acceptableQ",&exchange->acceptableQ,&ap->DL,0); - else free(ap); - } - return(retap); -} - -// NXTrequest: -// sends NXT assetid, volume and desired -// request: -// other node sends (othercoin, othercoinaddr, otherNXT and reftx that expires well before phasedtx) -// proposal: -// NXT node submits phasedtx that refers to it, but it wont confirm -// approve: -// other node verifies unconfirmed has phasedtx and broadcasts cltv, also to NXT node, releases trigger -// confirm: -// NXT node verifies bitcoin txbytes has proper payment and cashes in with onetimepubkey -// BTC* node approves phased tx with onetimepubkey - -bits256 instantdex_acceptset(struct instantdex_accept *ap,char *base,char *rel,int32_t duration,int32_t myside,int32_t acceptdir,double price,double volume,uint64_t offerbits,uint32_t nonce,uint8_t minperc) -{ - bits256 hash; - memset(ap,0,sizeof(*ap)); - safecopy(ap->offer.base,base,sizeof(ap->offer.base)); - safecopy(ap->offer.rel,rel,sizeof(ap->offer.rel)); - if ( nonce == 0 ) - OS_randombytes((uint8_t *)&ap->offer.nonce,sizeof(ap->offer.nonce)); - else ap->offer.nonce = nonce; - if ( duration < 1000000000 ) - ap->offer.expiration = (uint32_t)time(NULL) + duration; - else ap->offer.expiration = duration; - ap->offer.offer64 = offerbits; - ap->offer.myside = myside; - ap->offer.acceptdir = acceptdir; - ap->offer.minperc = minperc; - ap->offer.price64 = price * SATOSHIDEN; - ap->offer.basevolume64 = volume * SATOSHIDEN; - vcalc_sha256(0,hash.bytes,(void *)&ap->offer,sizeof(ap->offer)); - ap->orderid = hash.txid; - //int32_t i; - //for (i=0; ioffer); i++) - // printf("%02x ",((uint8_t *)&ap->offer)[i]); - //printf("\n(%s/%s) %.8f %.8f acceptdir.%d myside.%d\n",base,rel,price,volume,acceptdir,myside); - return(hash); -} - -int32_t instantdex_acceptextract(struct instantdex_accept *ap,cJSON *argjson) -{ - char *base,*rel; bits256 hash,traderpub; double price,volume; int32_t baserel,acceptdir,minperc; - memset(ap,0,sizeof(*ap)); - if ( (base= jstr(argjson,"base")) != 0 ) - { - volume = jdouble(argjson,"volume"); - if ( (minperc= juint(argjson,"minperc")) < INSTANTDEX_MINPERC ) - minperc = INSTANTDEX_MINPERC; - else if ( minperc > 100 ) - minperc = 100; - if ( (rel= jstr(argjson,"rel")) != 0 ) - safecopy(ap->offer.rel,rel,sizeof(ap->offer.rel)); - if ( (price= jdouble(argjson,"maxprice")) > SMALLVAL ) - { - baserel = 1; - acceptdir = -1; - } - else if ( (price= jdouble(argjson,"minprice")) > SMALLVAL ) - { - baserel = 0; - acceptdir = 1; - } else return(-1); - //printf("price %f vol %f baserel.%d acceptdir.%d\n",price,volume,baserel,acceptdir); - traderpub = jbits256(argjson,"traderpub"); - hash = instantdex_acceptset(ap,base,rel,INSTANTDEX_LOCKTIME*2,baserel,acceptdir,price,volume,traderpub.txid,0,minperc); - } - else - { - if ( (base= jstr(argjson,"b")) != 0 ) - safecopy(ap->offer.base,base,sizeof(ap->offer.base)); - if ( (rel= jstr(argjson,"r")) != 0 ) - safecopy(ap->offer.rel,rel,sizeof(ap->offer.rel)); - ap->offer.nonce = juint(argjson,"n"); - ap->offer.expiration = juint(argjson,"e"); - ap->offer.myside = juint(argjson,"s"); - ap->offer.acceptdir = jint(argjson,"d"); - ap->offer.offer64 = j64bits(argjson,"o"); - ap->offer.price64 = j64bits(argjson,"p"); - ap->offer.basevolume64 = j64bits(argjson,"v"); - if ( (ap->offer.minperc= juint(argjson,"m")) < INSTANTDEX_MINPERC ) - ap->offer.minperc = INSTANTDEX_MINPERC; - vcalc_sha256(0,hash.bytes,(void *)&ap->offer,sizeof(ap->offer)); - ap->orderid = j64bits(argjson,"id"); - } - if ( hash.txid != ap->orderid ) - { - int32_t i; - for (i=0; iorderid); - return(-1); - } - return(0); -} - -#include "swaps/iguana_BTCswap.c" -#include "swaps/iguana_ALTswap.c" -#include "swaps/iguana_NXTswap.c" -#include "swaps/iguana_PAXswap.c" - -struct bitcoin_swapinfo *bitcoin_swapinit(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *myap,struct instantdex_accept *otherap,int32_t aminitiator,cJSON *argjson,char *statename) -{ - struct bitcoin_swapinfo *swap = 0; struct iguana_info *coinbtc,*altcoin; - swap = calloc(1,sizeof(struct bitcoin_swapinfo)); - swap->state = instantdex_statefind(BTC_states,BTC_numstates,statename); - swap->mine = *myap, swap->other = *otherap; - if ( (swap->isinitiator= aminitiator) != 0 ) - { - swap->matched64 = otherap->orderid; - swap->expiration = otherap->offer.expiration; - } - else - { - swap->matched64 = myap->orderid; - swap->expiration = myap->offer.expiration; - } - swap->choosei = swap->otherchoosei = -1; - strcpy(swap->status,"pending"); - vcalc_sha256(0,swap->myorderhash.bytes,(void *)&swap->mine.offer,sizeof(swap->mine.offer)); - vcalc_sha256(0,swap->otherorderhash.bytes,(void *)&swap->other.offer,sizeof(swap->other.offer)); - swap->mypubkey = myinfo->myaddr.persistent; - swap->othertrader = jbits256(argjson,"traderpub"); - swap->altsatoshis = myap->offer.basevolume64; - swap->BTCsatoshis = instantdex_BTCsatoshis(myap->offer.price64,myap->offer.basevolume64); - if ( (coinbtc= iguana_coinfind("BTC")) == 0 || (altcoin= iguana_coinfind(swap->mine.offer.base)) == 0 ) - { - printf("cant find BTC or %s\n",swap->mine.offer.base); - return(0); - } - swap->insurance = (swap->BTCsatoshis * INSTANTDEX_INSURANCERATE + coinbtc->chain->txfee); - swap->altpremium = (swap->altsatoshis * INSTANTDEX_INSURANCERATE + altcoin->chain->txfee); - if ( myap->offer.myside != instantdex_isbob(swap) || otherap->offer.myside == instantdex_isbob(swap) ) - { - printf("isbob error.(%d %d) %d\n",myap->offer.myside,otherap->offer.myside,instantdex_isbob(swap)); - return(0); - } - return(swap); -} - -char *instantdex_checkoffer(struct supernet_info *myinfo,uint64_t *txidp,struct exchange_info *exchange,struct instantdex_accept *myap,cJSON *argjson) -{ - char *retstr = 0; struct instantdex_accept *otherap; struct bitcoin_swapinfo *swap; cJSON *newjson; int32_t isbob = 0; - *txidp = myap->orderid; - if ( (otherap= instantdex_acceptable(myinfo,exchange,myap,myap->offer.minperc)) == 0 ) - { - printf("add.%llu to acceptableQ\n",(long long)myap->orderid); - if ( (retstr= instantdex_sendcmd(myinfo,&myap->offer,argjson,"BTCoffer",GENESIS_PUBKEY,INSTANTDEX_HOPS,0,0)) != 0 ) - free(retstr); - queue_enqueue("acceptableQ",&exchange->acceptableQ,&myap->DL,0); - return(jprint(instantdex_offerjson(&myap->offer,myap->orderid),1)); - } - else - { - isbob = myap->offer.myside; - swap = bitcoin_swapinit(myinfo,exchange,myap,otherap,1,argjson,isbob != 0 ? "BOB_sentoffer" : "ALICE_sentoffer"); - printf("STATEMACHINEQ.(%llu / %llu)\n",(long long)swap->mine.orderid,(long long)swap->other.orderid); - //queue_enqueue("acceptableQ",&exchange->acceptableQ,&swap->DL,0); - queue_enqueue("statemachineQ",&exchange->statemachineQ,&swap->DL,0); - if ( (newjson= instantdex_parseargjson(myinfo,exchange,swap,argjson,1)) == 0 ) - return(clonestr("{\"error\":\"instantdex_checkoffer null newjson\"}")); - return(instantdex_sendcmd(myinfo,&swap->mine.offer,newjson,"BTCoffer",GENESIS_PUBKEY,INSTANTDEX_HOPS,swap->deck,sizeof(swap->deck))); - } - return(retstr); -} - -char *instantdex_gotoffer(struct supernet_info *myinfo,struct exchange_info *exchange,struct instantdex_accept *myap,struct instantdex_accept *otherap,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,uint8_t *serdata,int32_t serdatalen) // receiving side -{ - struct bitcoin_swapinfo *swap = 0; bits256 traderpub; struct iguana_info *coinbtc,*altcoin; cJSON *newjson=0; char *retstr=0; int32_t isbob; - coinbtc = iguana_coinfind("BTC"); - traderpub = jbits256(argjson,"traderpub"); - if ( bits256_cmp(traderpub,myinfo->myaddr.persistent) == 0 ) - { - printf("got my own gotoffer packet orderid.%llu/%llu\n",(long long)myap->orderid,(long long)otherap->orderid); - return(clonestr("{\"result\":\"got my own packet\"}")); - } - if ( 0 ) - { - int32_t i; - for (i=0; ioffer); i++) - printf("%02x ",((uint8_t *)&otherap->offer)[i]); - printf("gotoffer.%llu\n",(long long)otherap->orderid); - } - printf(">>>>>>>>> GOTOFFER T.%d got (%s/%s) %.8f vol %.8f %llu offerside.%d offerdir.%d decksize.%d/datalen.%d\n",bits256_cmp(traderpub,myinfo->myaddr.persistent),myap->offer.base,myap->offer.rel,dstr(myap->offer.price64),dstr(myap->offer.basevolume64),(long long)myap->orderid,myap->offer.myside,myap->offer.acceptdir,(int32_t)sizeof(swap->deck),serdatalen); - if ( exchange == 0 ) - return(clonestr("{\"error\":\"instantdex_BTCswap null exchange ptr\"}")); - if ( (altcoin= iguana_coinfind(myap->offer.base)) == 0 || coinbtc == 0 ) - return(clonestr("{\"error\":\"instantdex_BTCswap cant find btc or other coin info\"}")); - if ( strcmp(myap->offer.rel,"BTC") != 0 ) - return(clonestr("{\"error\":\"instantdex_BTCswap offer non BTC rel\"}")); - if ( myap->offer.expiration < (time(NULL) + INSTANTDEX_DURATION) || otherap->offer.expiration < (time(NULL) + INSTANTDEX_DURATION) ) - return(clonestr("{\"error\":\"instantdex_BTCswap offer too close to expiration\"}")); - isbob = myap->offer.myside; - swap = bitcoin_swapinit(myinfo,exchange,myap,otherap,0,argjson,isbob != 0 ? "BOB_gotoffer" : "ALICE_gotoffer"); - if ( (newjson= instantdex_parseargjson(myinfo,exchange,swap,argjson,1)) == 0 ) - { - printf("error parsing argjson\n"); - return(clonestr("{\"error\":\"instantdex_BTCswap offer null newjson\"}")); - } - else //if ( (retstr= instantdex_addfeetx(myinfo,newjson,ap,swap,"BOB_gotoffer","ALICE_gotoffer")) == 0 ) - { - queue_enqueue("acceptableQ",&exchange->acceptableQ,&swap->DL,0); - queue_enqueue("statemachineQ",&exchange->statemachineQ,&swap->DL,0); - if ( (retstr= instantdex_choosei(swap,newjson,argjson,serdata,serdatalen)) != 0 ) - return(retstr); - else - { - return(instantdex_sendcmd(myinfo,&swap->mine.offer,newjson,"BTCdeckC",traderpub,INSTANTDEX_HOPS,swap->deck,sizeof(swap->deck))); - } - } - return(retstr); -} - -char *instantdex_parse(struct supernet_info *myinfo,struct instantdex_msghdr *msg,cJSON *argjson,char *remoteaddr,uint64_t signerbits,struct instantdex_offer *offer,bits256 orderhash,uint8_t *serdata,int32_t serdatalen) -{ - char cmdstr[16],*retstr; struct exchange_info *exchange; struct instantdex_accept A,*ap = 0; bits256 traderpub; cJSON *newjson; struct bitcoin_swapinfo *swap; - if ( BTC_states == 0 ) - BTC_states = BTC_initFSM(&BTC_numstates); - exchange = exchanges777_find("bitcoin"); - memset(cmdstr,0,sizeof(cmdstr)), memcpy(cmdstr,msg->cmd,sizeof(msg->cmd)); - if ( argjson != 0 ) - { - traderpub = jbits256(argjson,"traderpub"); - memset(&A,0,sizeof(A)); - if ( j64bits(argjson,"id") != orderhash.txid ) - { - printf("orderhash %llu mismatch id.%llu\n",(long long)orderhash.txid,(long long)j64bits(argjson,"id")); - return(clonestr("{\"error\":\"orderhash mismatch\"}")); - } - A.offer = *offer; - A.orderid = orderhash.txid; - printf("got.(%s) for %llu offer64.%llu\n",cmdstr,(long long)A.orderid,(long long)A.offer.offer64); - if ( (A.offer.minperc= jdouble(argjson,"p")) < INSTANTDEX_MINPERC ) - A.offer.minperc = INSTANTDEX_MINPERC; - else if ( A.offer.minperc > 100 ) - A.offer.minperc = 100; - if ( strcmp(cmdstr,"BTCoffer") == 0 ) // incoming - { - printf("BTCoffer state\n"); - if ( (ap= instantdex_acceptable(myinfo,exchange,&A,A.offer.minperc)) != 0 ) - { - if ( (retstr= instantdex_gotoffer(myinfo,exchange,ap,&A,msg,argjson,remoteaddr,signerbits,serdata,serdatalen)) != 0 ) // adds to statemachine if no error - { - printf("from GOTOFFER.(%s)\n",retstr); - return(retstr); - } else return(clonestr("{\"error\":\"gotoffer error\"}")); - } - else - { - printf("no matching trade for %s %llu -> InstantDEX_minaccept isbob.%d\n",cmdstr,(long long)A.orderid,A.offer.myside); - if ( instantdex_offerfind(myinfo,exchange,0,0,A.orderid,"*","*",1) == 0 ) - { - ap = calloc(1,sizeof(*ap)); - *ap = A; - printf("acceptableQ <- %llu\n",(long long)ap->orderid); - queue_enqueue("acceptableQ",&exchange->acceptableQ,&ap->DL,0); - return(clonestr("{\"result\":\"added new order to orderbook\"}")); - } else return(clonestr("{\"result\":\"order was already in orderbook\"}")); - } - } - else if ( (swap= instantdex_statemachinefind(myinfo,exchange,A.orderid,1)) != 0 ) - { - //printf("found existing state machine %llu\n",(long long)A.orderid); - newjson = instantdex_parseargjson(myinfo,exchange,swap,argjson,0); - if ( serdatalen == sizeof(swap->otherdeck) && swap->choosei < 0 && (retstr= instantdex_choosei(swap,newjson,argjson,serdata,serdatalen)) != 0 ) - { - printf("error choosei\n"); - return(retstr); - } - return(instantdex_statemachine(BTC_states,BTC_numstates,myinfo,exchange,swap,cmdstr,argjson,newjson,serdata,serdatalen)); - } - else - { - printf("cant find existing order.%llu that matches\n",(long long)A.orderid); - return(clonestr("{\"error\":\"cant find matching order\"}")); - } - } - return(clonestr("{\"error\":\"request needs argjson\"}")); -} - -char *InstantDEX_hexmsg(struct supernet_info *myinfo,struct category_info *cat,void *ptr,int32_t len,char *remoteaddr) -{ - struct instantdex_msghdr *msg = ptr; int32_t i,olen,slen,num,datalen,newlen,flag = 0; - uint8_t *serdata; struct supernet_info *myinfos[64]; struct instantdex_offer rawoffer; - uint64_t signerbits; uint8_t tmp[sizeof(msg->sig)]; char *retstr = 0; - bits256 orderhash,traderpub; cJSON *retjson,*item,*argjson = 0; - if ( BTC_states == 0 ) - BTC_states = BTC_initFSM(&BTC_numstates); - datalen = len - (int32_t)sizeof(msg->sig); - serdata = (void *)((long)msg + sizeof(msg->sig)); - //printf("a signed datalen.%d allocsize.%d crc.%x\n",datalen,msg->sig.allocsize,calc_crc32(0,serdata,datalen)); - acct777_rwsig(0,(void *)&msg->sig,(void *)tmp); - memcpy(&msg->sig,tmp,sizeof(msg->sig)); - // printf("b signed datalen.%d allocsize.%d crc.%x\n",datalen,msg->sig.allocsize,calc_crc32(0,serdata,datalen)); - if ( remoteaddr != 0 && remoteaddr[0] == 0 && strcmp("127.0.0.1",remoteaddr) == 0 && ((uint8_t *)msg)[len-1] == 0 && (argjson= cJSON_Parse((char *)msg)) != 0 ) - { - printf("string instantdex_hexmsg RESULT.(%s)\n",jprint(argjson,0)); - free_json(argjson); - return(clonestr("{\"error\":\"string base packets deprecated\"}")); - } - else if ( (signerbits= acct777_validate(&msg->sig,acct777_msgprivkey(serdata,datalen),msg->sig.pubkey)) != 0 )//|| 1 ) - { - flag++; - printf("InstantDEX_hexmsg <<<<<<<<<<<<< sigsize.%d VALIDATED [%ld] len.%d t%u allocsize.%d (%s) [%d]\n",(int32_t)sizeof(msg->sig),(long)serdata-(long)msg,datalen,msg->sig.timestamp,msg->sig.allocsize,(char *)msg->serialized,serdata[datalen-1]); - newlen = (int32_t)(msg->sig.allocsize - ((long)msg->serialized - (long)msg)); - serdata = msg->serialized; - //printf("newlen.%d diff.%ld alloc.%d datalen.%d\n",newlen,((long)msg->serialized - (long)msg),msg->sig.allocsize,datalen); - if ( (argjson= cJSON_Parse((char *)serdata)) != 0 ) - { - slen = (int32_t)strlen((char *)serdata) + 1; - serdata = &serdata[slen]; - newlen -= slen; - } - if ( newlen > 0 ) - { - orderhash = instantdex_rwoffer(0,&olen,serdata,&rawoffer); - newlen -= olen; - //newlen -= ((long)msg->serialized - (long)msg); - serdata = &serdata[olen]; - //printf("received orderhash.%llu olen.%d slen.%d newlen.%d\n",(long long)orderhash.txid,olen,slen,newlen); - } else olen = 0; - if ( newlen <= 0 ) - serdata = 0, newlen = 0; - if ( serdata != 0 || argjson != 0 ) - { - //printf("CALL instantdex_parse.(%s)\n",argjson!=0?jprint(argjson,0):""); - retjson = cJSON_CreateArray(); - if ( (num= SuperNET_MYINFOS(myinfos,sizeof(myinfos)/sizeof(*myinfos))) == 0 ) - { - myinfos[0] = myinfo; - num = 1; - } - for (i=0; imyaddr.persistent)); - traderpub = jbits256(argjson,"traderpub"); - if ( bits256_cmp(traderpub,myinfo->myaddr.persistent) == 0 ) - continue; - if ( (retstr= instantdex_parse(myinfo,msg,argjson,remoteaddr,signerbits,&rawoffer,orderhash,serdata,newlen)) != 0 ) - { - item = cJSON_CreateObject(); - jaddstr(item,"result",retstr); - if ( myinfo->handle[0] != 0 ) - jaddstr(item,"handle",myinfo->handle); - jaddbits256(item,"traderpub",myinfo->myaddr.persistent); - jaddi(retjson,item); - } - } - retstr = jprint(retjson,1); - } - } else printf("sig err datalen.%d\n",datalen); - if ( argjson != 0 ) - free_json(argjson); - return(retstr); -} - -char *instantdex_createaccept(struct supernet_info *myinfo,struct instantdex_accept **aptrp,struct exchange_info *exchange,char *base,char *rel,double price,double basevolume,int32_t acceptdir,char *mysidestr,int32_t duration,uint64_t offerer,int32_t queueflag,uint8_t minperc) -{ - struct instantdex_accept *ap; int32_t myside; char *retstr; - *aptrp = 0; - if ( exchange != 0 ) - { - *aptrp = ap = calloc(1,sizeof(*ap)); - if ( strcmp(mysidestr,base) == 0 ) - myside = 0; - else if ( strcmp(mysidestr,rel) == 0 ) - myside = 1; - else - { - myside = -1; - printf("myside.(%s) != base.%s or rel.%s\n",mysidestr,base,rel); - } - instantdex_acceptset(ap,base,rel,duration,myside,acceptdir,price,basevolume,offerer,0,minperc); - if ( queueflag != 0 ) - { - printf("acceptableQ <- %llu\n",(long long)ap->orderid); - queue_enqueue("acceptableQ",&exchange->acceptableQ,&ap->DL,0); - } - retstr = jprint(instantdex_acceptjson(ap),1); - //printf("acceptableQ %llu (%s)\n",(long long)ap->orderid,retstr); - return(retstr); - } else return(clonestr("{\"error\":\"invalid exchange\"}")); -} - -void instantdex_update(struct supernet_info *myinfo) -{ - struct instantdex_msghdr *pm; struct category_msg *m; bits256 instantdexhash; char *str,remote[64]; queue_t *Q; struct queueitem *item; struct category_info *cat; - instantdexhash = calc_categoryhashes(0,"InstantDEX",0); - //char str2[65]; printf("instantdexhash.(%s)\n",bits256_str(str2,instantdexhash)); - if ( (Q= category_Q(&cat,instantdexhash,myinfo->myaddr.persistent)) != 0 && queue_size(Q) > 0 && (item= Q->list) != 0 ) - { - m = (void *)item; - m = queue_dequeue(Q,0); - pm = (struct instantdex_msghdr *)m->msg; - //printf("loop cmd.(%s)\n",pm->cmd); - //if ( m->remoteipbits == 0 && (m= queue_dequeue(Q,0)) ) - { - //if ( (void *)m == (void *)item ) - { - pm = (struct instantdex_msghdr *)m->msg; - if ( m->remoteipbits != 0 ) - expand_ipbits(remote,m->remoteipbits); - else remote[0] = 0; - if ( (str= InstantDEX_hexmsg(myinfo,cat,pm,m->len,remote)) != 0 ) - free(str); - } //else printf("instantdex_update: unexpected m.%p changed item.%p\n",m,item); - free(m); - } - } -} - -#include "../includes/iguana_apidefs.h" - -TWO_STRINGS_AND_TWO_DOUBLES(InstantDEX,maxaccept,base,rel,maxprice,basevolume) -{ - struct instantdex_accept *ap; char *retstr; struct exchange_info *exchange; uint64_t txid; - myinfo = SuperNET_accountfind(json); - if ( remoteaddr == 0 && (exchange= exchanges777_find("bitcoin")) != 0 ) - { - retstr = instantdex_createaccept(myinfo,&ap,exchange,base,rel,maxprice,basevolume,-1,rel,INSTANTDEX_OFFERDURATION,myinfo->myaddr.nxt64bits,1,juint(json,"minperc")); - return(instantdex_checkoffer(myinfo,&txid,exchange,ap,json)); - - } else return(clonestr("{\"error\":\"InstantDEX API request only local usage!\"}")); -} - -TWO_STRINGS_AND_TWO_DOUBLES(InstantDEX,minaccept,base,rel,minprice,basevolume) -{ - struct instantdex_accept *ap; char *retstr; struct exchange_info *exchange; uint64_t txid; - myinfo = SuperNET_accountfind(json); - if ( remoteaddr == 0 && (exchange= exchanges777_find("bitcoin")) != 0 ) - { - retstr = instantdex_createaccept(myinfo,&ap,exchanges777_find("bitcoin"),base,rel,minprice,basevolume,1,base,INSTANTDEX_OFFERDURATION,myinfo->myaddr.nxt64bits,1,juint(json,"minperc")); - return(instantdex_checkoffer(myinfo,&txid,exchange,ap,json)); - } else return(clonestr("{\"error\":\"InstantDEX API request only local usage!\"}")); -} - -char *instantdex_statemachineget(struct supernet_info *myinfo,struct bitcoin_swapinfo **swapp,cJSON *argjson,char *remoteaddr) -{ - struct bitcoin_swapinfo *swap; uint64_t orderid,otherorderid; struct exchange_info *exchange; - *swapp = 0; - if ( remoteaddr == 0 && (exchange= exchanges777_find("bitcoin")) != 0 ) - { - orderid = j64bits(argjson,"myorderid"); - otherorderid = j64bits(argjson,"otherid"); - if ( (swap= instantdex_statemachinefind(myinfo,exchange,orderid,1)) != 0 ) - { - if ( swap->other.orderid != otherorderid ) - return(clonestr("{\"error\":\"statemachine otherid mismatch\"}")); - else - { - *swapp = swap; - return(0); - } - } else return(clonestr("{\"error\":\"statemachine not found\"}")); - } else return(clonestr("{\"error\":\"atomic API request only local usage!\"}")); -} - -THREE_STRINGS(atomic,approve,myorderid,otherid,txname) -{ - char *retstr,virtualevent[16]; cJSON *newjson; struct bitcoin_statetx *tx; struct bitcoin_swapinfo *swap = 0; - if ( (retstr= instantdex_statemachineget(myinfo,&swap,json,remoteaddr)) != 0 ) - return(retstr); - else if ( (tx= instantdex_getstatetx(swap,txname)) == 0 ) - return(clonestr("{\"error\":\"cant find txname\"}")); - else - { - strcpy(virtualevent,txname); - strcat(virtualevent,"found"); - newjson = cJSON_CreateObject(); - if ( (retstr= instantdex_sendcmd(myinfo,&swap->mine.offer,newjson,virtualevent,myinfo->myaddr.persistent,0,0,0)) != 0 ) - return(retstr); - else return(clonestr("{\"result\":\"statemachine sent found event\"}")); - } -} - -THREE_STRINGS(atomic,claim,myorderid,otherid,txname) -{ - char *retstr; struct bitcoin_statetx *tx; struct bitcoin_swapinfo *swap = 0; - if ( (retstr= instantdex_statemachineget(myinfo,&swap,json,remoteaddr)) != 0 ) - return(retstr); - else if ( (tx= instantdex_getstatetx(swap,txname)) == 0 ) - return(clonestr("{\"error\":\"cant find txname\"}")); - else - { - return(clonestr("{\"result\":\"statemachine should claim tx\"}")); - } -} - -THREE_STRINGS_AND_DOUBLE(tradebot,aveprice,comment,base,rel,basevolume) -{ - double retvals[4],aveprice; cJSON *retjson = cJSON_CreateObject(); - aveprice = instantdex_avehbla(myinfo,retvals,base,rel,basevolume); - jaddstr(retjson,"result","success"); - jaddnum(retjson,"aveprice",aveprice); - jaddnum(retjson,"avebid",retvals[0]); - jaddnum(retjson,"bidvol",retvals[1]); - jaddnum(retjson,"aveask",retvals[2]); - jaddnum(retjson,"askvol",retvals[3]); - return(jprint(retjson,1)); -} - -#include "../includes/iguana_apiundefs.h" - diff --git a/iguana/iguana_interpreter.c b/iguana/iguana_interpreter.c index 36dad141d..0ad66ed15 100755 --- a/iguana/iguana_interpreter.c +++ b/iguana/iguana_interpreter.c @@ -100,6 +100,14 @@ #define IGUANA_OP_CHECKSEQUENCEVERIFY 0xb2 #define IGUANA_OP_NOP10 0xb9 +#define IGUANA_OP_COMBINEPUBKEYS 0xc0 +#define IGUANA_OP_CHECKSCHNORR 0xc1 +#define IGUANA_OP_CHECKSCHNORRVERIFY 0xc2 + +// https://github.com/TierNolan/bips/blob/cpkv/bip-cprkv.mediawiki +#define IGUANA_OP_CHECKPRIVATEKEY 0xc3 +#define IGUANA_OP_CHECKPRIVATEKEYVERIFY 0xc4 + #define IGUANA_NOPFLAG 1 #define IGUANA_ALWAYSILLEGAL 2 #define IGUANA_EXECUTIONILLEGAL 4 @@ -243,6 +251,12 @@ enum opcodetype OP_NOP9 = 0xb8, OP_NOP10 = 0xb9, + OP_COMBINEPUBKEYS = 0xc0, + OP_CHECKSCHNORR = 0xc1, + OP_CHECKSCHNORRVERIFY = 0xc2, + OP_CHECKPRIVATEKEY = 0xc3, + OP_CHECKPRIVATEKEYVERIFY = 0xc4, + // template matching params //OP_SMALLINTEGER = 0xfa, //OP_PUBKEYS = 0xfb, @@ -371,6 +385,11 @@ const char *get_opname(uint8_t *stackitemsp,uint8_t *flagsp,int32_t *extralenp,e case OP_CHECKSIGVERIFY: *stackitemsp = 2; *flagsp = IGUANA_CRYPTOFLAG | IGUANA_POSTVERIFY; return "OP_CHECKSIGVERIFY"; case OP_CHECKMULTISIG: *flagsp = IGUANA_CRYPTOFLAG; return "OP_CHECKMULTISIG"; case OP_CHECKMULTISIGVERIFY: *flagsp = IGUANA_CRYPTOFLAG | IGUANA_POSTVERIFY; return "OP_CHECKMULTISIGVERIFY"; + case OP_COMBINEPUBKEYS: *flagsp = IGUANA_CRYPTOFLAG; return "OP_COMBINEPUBKEYS"; + case OP_CHECKSCHNORR: *stackitemsp = 3; *flagsp = IGUANA_CRYPTOFLAG; return "OP_CHECKSCHNORR"; + case OP_CHECKSCHNORRVERIFY: *stackitemsp = 3; *flagsp = IGUANA_CRYPTOFLAG | IGUANA_POSTVERIFY; return "OP_CHECKSCHNORRVERIFY"; + case OP_CHECKPRIVATEKEY: *stackitemsp = 2; *flagsp = IGUANA_CRYPTOFLAG; return "OP_CHECKPRIVATEKEY"; + case OP_CHECKPRIVATEKEYVERIFY: *stackitemsp = 2; *flagsp = IGUANA_CRYPTOFLAG | IGUANA_POSTVERIFY; return "OP_CHECKPRIVATEKEYVERIFY"; // expanson case OP_NOP1 : *flagsp = IGUANA_NOPFLAG; return "OP_NOP1"; @@ -465,19 +484,29 @@ static int32_t iguana_isnonz(struct iguana_stackdata Snum) return(0); } -static int32_t iguana_num(struct iguana_stackdata Snum) +static int64_t iguana_num(struct iguana_stackdata Snum) { if ( Snum.size == sizeof(int32_t) ) return(Snum.U.val); + else if ( Snum.size == sizeof(int64_t) ) + return(Snum.U.val64); else return(0); } static int32_t iguana_pushdata(struct iguana_interpreter *stacks,int64_t num64,uint8_t *numbuf,int32_t numlen) { - struct iguana_stackdata Snum; cJSON *item = 0; char str[256]; int32_t num = (int32_t)num64; + struct iguana_stackdata Snum; cJSON *item = 0; char tmpstr[2048]; int32_t num = (int32_t)num64; + if ( stacks->lastpath[stacks->ifdepth] < 0 ) + return(0); + printf("PUSH.(%lld %p %d)\n",(long long)num64,numbuf,numlen); if ( stacks->maxstackdepth > 0 ) { - printf("PUSHDATA.[%d]\n",numlen); + /*if ( numbuf != 0 ) + { + int32_t i; for (i=0; istackdepth < stacks->maxstackdepth ) { if ( stacks->logarray != 0 ) @@ -490,44 +519,21 @@ static int32_t iguana_pushdata(struct iguana_interpreter *stacks,int64_t num64,u iguana_rwnum(1,(void *)&num,numlen,numbuf); numlen = sizeof(num); Snum.U.val = num; - if ( item != 0 ) - jaddnum(item,"push",num); } else if ( numlen <= sizeof(int64_t) ) { iguana_rwnum(1,(void *)&num64,numlen,numbuf); numlen = sizeof(num64); Snum.U.val64 = num64; - if ( item != 0 ) - jadd64bits(item,"push",num64); } else if ( numlen == 20 ) - { memcpy(Snum.U.rmd160,numbuf,20); - if ( item != 0 ) - { - init_hexbytes_noT(str,Snum.U.rmd160,20); - jaddstr(item,"push",str); - } - } else if ( numlen == sizeof(bits256) ) - { iguana_rwbignum(1,Snum.U.hash2.bytes,sizeof(Snum.U.hash2),numbuf); - if ( item != 0 ) - jaddbits256(item,"push",Snum.U.hash2); - } else if ( numlen == 33 ) - { memcpy(Snum.U.pubkey,numbuf,numlen); - if ( item != 0 ) - jaddnum(item,"push",numlen); - } else if ( numlen < 74 ) - { memcpy(Snum.U.sig,numbuf,numlen); - if ( item != 0 ) - jaddnum(item,"push",numlen); - } else { Snum.data = malloc(numlen); @@ -536,10 +542,24 @@ static int32_t iguana_pushdata(struct iguana_interpreter *stacks,int64_t num64,u jaddnum(item,"push",numlen); } Snum.size = numlen; + if ( item != 0 ) + { + init_hexbytes_noT(tmpstr,numbuf,numlen); + jaddstr(item,"push",tmpstr); + } } else if ( num64 <= 0xffffffff ) // what about negative numbers? + { Snum.U.val = num, Snum.size = sizeof(num); - else Snum.U.val64 = num64, Snum.size = sizeof(num64); + if ( item != 0 ) + jaddnum(item,"push",Snum.U.val); + } + else + { + Snum.U.val64 = num64, Snum.size = sizeof(num64); + if ( item != 0 ) + jaddnum(item,"push",Snum.U.val64); + } if ( item != 0 ) { jaddnum(item,"depth",stacks->stackdepth); @@ -575,18 +595,18 @@ static int32_t iguana_cmp(struct iguana_stackdata *a,struct iguana_stackdata *b) if ( a->size == b->size ) { if ( a->size == 4 ) - return(a->U.val == b->U.val); + return(a->U.val != b->U.val); else if ( a->size == 8 ) - return(a->U.val64 == b->U.val64); + return(a->U.val64 != b->U.val64); else if ( a->size == 20 ) - return(memcmp(a->U.rmd160,b->U.rmd160,sizeof(a->U.rmd160)) == 0); + return(memcmp(a->U.rmd160,b->U.rmd160,sizeof(a->U.rmd160))); else if ( a->size == 32 ) - return(memcmp(a->U.hash2.bytes,b->U.hash2.bytes,sizeof(a->U.hash2)) == 0); + return(memcmp(a->U.hash2.bytes,b->U.hash2.bytes,sizeof(a->U.hash2))); else if ( a->size == 33 ) - return(memcmp(a->U.pubkey,b->U.pubkey,33) == 0); + return(memcmp(a->U.pubkey,b->U.pubkey,33)); else if ( a->size < 74 ) - return(memcmp(a->U.sig,b->U.sig,a->size) == 0); - else return(memcmp(a->data,b->data,sizeof(a->size)) == 0); + return(memcmp(a->U.sig,b->U.sig,a->size)); + else return(memcmp(a->data,b->data,sizeof(a->size))); } return(-1); } @@ -612,9 +632,9 @@ static int32_t iguana_dataparse(struct iguana_interpreter *stacks,uint8_t *scrip tmp[1] = c; tmp[2] = 0; decode_hex(&script[k],1,tmp), (*lenp) = 1; + iguana_pushdata(stacks,script[k],0,0); if ( script[k] != 0 ) script[k++] += (IGUANA_OP_1 - 1); - iguana_pushdata(stacks,c,0,0); return(k); } else if ( n == 2 && c == '1' && str[1] == '0' && is_delim(str[2]) != 0 ) @@ -709,53 +729,104 @@ int32_t iguana_checksig(struct iguana_info *coin,struct iguana_stackdata pubkeya uint8_t pubkey[MAX_SCRIPT_ELEMENT_SIZE],sig[MAX_SCRIPT_ELEMENT_SIZE]; int32_t plen,siglen; plen = iguana_databuf(pubkey,pubkeyarg); siglen = iguana_databuf(sig,sigarg); - /*int32_t i; for (i=0; i 0 && siglen > 0 && siglen < 74 ) return(bitcoin_verify(coin->ctx,sig,siglen-1,sigtxid,pubkey,plen) == 0); return(0); } +int32_t iguana_checkprivatekey(struct iguana_info *coin,struct iguana_stackdata pubkeyarg,struct iguana_stackdata privkeyarg) +{ + uint8_t pubkey[MAX_SCRIPT_ELEMENT_SIZE],privkey[MAX_SCRIPT_ELEMENT_SIZE],checkpub[33]; int32_t plen,privlen; + plen = iguana_databuf(pubkey,pubkeyarg); + privlen = iguana_databuf(privkey,privkeyarg); + if ( bitcoin_pubkeylen(pubkey) == plen && plen > 0 && privlen == 32 ) + { + bitcoin_pubkey33(coin->ctx,checkpub,*(bits256 *)privkey); + return(memcmp(checkpub,pubkey,33) == 0); + } + return(0); +} + +int32_t iguana_checkschnorrsig(struct iguana_info *coin,int64_t M,struct iguana_stackdata pubkeyarg,struct iguana_stackdata sigarg,bits256 sigtxid) +{ + uint8_t combined_pub[MAX_SCRIPT_ELEMENT_SIZE],sig[MAX_SCRIPT_ELEMENT_SIZE]; int32_t plen,siglen; + plen = iguana_databuf(combined_pub,pubkeyarg); + siglen = iguana_databuf(sig,sigarg); + if ( bitcoin_pubkeylen(combined_pub) == 33 && siglen == 64 ) + return(bitcoin_schnorr_verify(coin->ctx,sig,sigtxid,combined_pub,33) == 0); + return(0); +} + int32_t iguana_checkmultisig(struct iguana_info *coin,struct iguana_interpreter *stacks,int32_t M,int32_t N,bits256 txhash2) { - int32_t i,j=0,len,valid=0,numsigners = 0,siglens[MAX_PUBKEYS_PER_MULTISIG]; uint8_t pubkeys[MAX_PUBKEYS_PER_MULTISIG][MAX_SCRIPT_ELEMENT_SIZE],sigs[MAX_PUBKEYS_PER_MULTISIG][MAX_SCRIPT_ELEMENT_SIZE]; + int32_t i,j=0,len,n,m,valid=0,numsigners = 0,siglens[MAX_PUBKEYS_PER_MULTISIG]; uint8_t pubkeys[MAX_PUBKEYS_PER_MULTISIG][MAX_SCRIPT_ELEMENT_SIZE],sigs[MAX_PUBKEYS_PER_MULTISIG][MAX_SCRIPT_ELEMENT_SIZE]; if ( M <= N && N <= MAX_PUBKEYS_PER_MULTISIG ) { + if ( stacks->stackdepth <= 0 ) + return(0); + n = (int32_t)iguana_num(iguana_pop(stacks)); + if ( n != N ) + { + printf("iguana_checkmultisig n.%d != N.%d\n",n,N); + return(0); + } for (i=0; istackdepth <= 0 ) return(0); len = iguana_databuf(pubkeys[i],iguana_pop(stacks)); if ( len == bitcoin_pubkeylen(pubkeys[i]) ) + { numsigners++; + //for (j=0; j<33; j++) + // printf("%02x",pubkeys[i][j]); + //printf(" <- pubkey.[%d]\n",i); + } else { + printf("nonpubkey on stack\n"); + return(0); memcpy(sigs[0],pubkeys[i],len); siglens[0] = len; break; } } - for (i=1; istackdepth <= 0 ) + return(0); + m = (int32_t)iguana_num(iguana_pop(stacks)); + if ( m != M ) + { + printf("iguana_checkmultisig m.%d != M.%d\n",m,M); + return(0); + } + for (i=0; istackdepth <= 0 ) return(0); siglens[i] = iguana_databuf(sigs[i],iguana_pop(stacks)); - if ( siglens[i] > 0 && siglens[i] < 74 ) + if ( siglens[i] <= 0 || siglens[i] > 74 ) break; + //for (j=0; jstackdepth > 0 ) + iguana_pop(stacks); // for backward compatibility j = numsigners-1; for (i=numsigners-1; i>=0; i--) { for (; j>=0; j--) { - if ( bitcoin_verify(coin->ctx,sigs[i],siglens[i],txhash2,pubkeys[j],bitcoin_pubkeylen(pubkeys[j])) == 0 ) + if ( bitcoin_verify(coin->ctx,sigs[i],siglens[i]-1,txhash2,pubkeys[j],bitcoin_pubkeylen(pubkeys[j])) == 0 ) { if ( ++valid >= M ) return(1); @@ -770,10 +841,16 @@ int32_t iguana_checkmultisig(struct iguana_info *coin,struct iguana_interpreter return(0); } -int32_t iguana_checklocktimeverify(struct iguana_info *coin,int64_t nLockTime,uint32_t nSequence,struct iguana_stackdata Snum) +#define LOCKTIME_THRESHOLD 500000000 +int32_t iguana_checklocktimeverify(struct iguana_info *coin,int64_t tx_lockval,uint32_t nSequence,struct iguana_stackdata Snum) { - int32_t num = iguana_num(Snum); - if ( num < 0 || (num >= 500000000 && nLockTime < 500000000) || (num < 500000000 && nLockTime >= 500000000) || nSequence == 0xffffffff || num > nLockTime ) + int64_t nLockTime = iguana_num(Snum); + if ( nLockTime < 0 || tx_lockval < 0 ) + return(-1); + else if ( ((tx_lockval < LOCKTIME_THRESHOLD && nLockTime < LOCKTIME_THRESHOLD) || + (tx_lockval >= LOCKTIME_THRESHOLD && nLockTime >= LOCKTIME_THRESHOLD)) == 0 ) + return(-1); + else if ( nLockTime > tx_lockval ) return(-1); return(0); } @@ -859,9 +936,12 @@ int32_t iguana_expandscript(struct iguana_info *coin,char *asmstr,int32_t maxlen { n = script[i++]; n = (n << 8) | script[i++]; - for (j=0; jstack)*2*IGUANA_MAXSTACKITEMS); stacks->maxstackdepth = IGUANA_MAXSTACKITEMS; - if ( interpret > 1 ) - stacks->logarray = cJSON_CreateArray(); + if ( (stacks->logarray= logarray) != 0 ) + item = cJSON_CreateObject(); + else item = 0; if ( V->M == 0 && V->N == 0 ) V->N = V->M = 1; for (i=0; iN; i++) @@ -925,6 +1006,7 @@ int32_t bitcoin_assembler(struct iguana_info *coin,uint8_t script[IGUANA_MAXSCRI free(stacks); return(-1); } + //printf("pushdata siglen.%d depth.%d\n",V->signers[i].siglen,stacks->stackdepth); } } for (i=0; iN; i++) @@ -932,10 +1014,59 @@ int32_t bitcoin_assembler(struct iguana_info *coin,uint8_t script[IGUANA_MAXSCRI if ( V->signers[i].siglen != 0 ) { plen = bitcoin_pubkeylen(V->signers[i].pubkey); - if ( V->spendscript[0] != plen || V->spendscript[V->spendlen - 1] != IGUANA_OP_CHECKSIG || bitcoin_pubkeylen(&V->spendscript[1]) <= 0 ) + if ( V->suppress_pubkeys == 0 && (V->spendscript[0] != plen || V->spendscript[V->spendlen - 1] != IGUANA_OP_CHECKSIG || bitcoin_pubkeylen(&V->spendscript[1]) <= 0) ) + { iguana_pushdata(stacks,0,V->signers[i].pubkey,plen); + printf(">>>>>>>>> suppress.%d pushdata plen.%d depth.%d\n",V->suppress_pubkeys,plen,stacks->stackdepth); + } else printf("<<<<<<<<<< skip pubkey push %d script[0].%d spendlen.%d depth.%d\n",plen,V->spendscript[0],V->spendlen,stacks->stackdepth); + } + } + if ( V->userdatalen != 0 ) + { + len = 0; + while ( len < V->userdatalen ) + { + dlen = V->userdata[len++]; + if ( dlen > 0 && dlen < 76 ) + iguana_pushdata(stacks,0,&V->userdata[len],dlen), len += dlen; + else if ( dlen >= IGUANA_OP_1 && dlen <= IGUANA_OP_16 ) + { + dlen -= (IGUANA_OP_1 - 1); + iguana_pushdata(stacks,dlen,0,0); + } + else if ( dlen == IGUANA_OP_PUSHDATA1 ) + { + iguana_pushdata(stacks,V->userdata[len++],0,0); + } + else if ( dlen == IGUANA_OP_PUSHDATA2 ) + { + iguana_pushdata(stacks,V->userdata[len] + ((int32_t)V->userdata[len+1]<<8),0,0); + len += 2; + } + else if ( dlen == IGUANA_OP_0 ) + iguana_pushdata(stacks,0,0,0); + else if ( dlen == IGUANA_OP_1NEGATE ) + iguana_pushdata(stacks,-1,0,0); + else + { + printf("invalid data opcode %02x\n",dlen); + free(stacks); + return(-1); + } + printf("user data stackdepth.%d dlen.%d\n",stacks->stackdepth,dlen); + } + if ( len != V->userdatalen ) + { + printf("mismatched userdatalen %d vs %d\n",len,V->userdatalen); + free(stacks); + return(-1); } } + if ( item != 0 && stacks->logarray != 0 ) + { + jaddstr(item,"spendasm",asmstr); + jaddi(stacks->logarray,item); + } if ( V->extras != 0 ) { if ( (n= cJSON_GetArraySize(V->extras)) > 0 ) @@ -991,12 +1122,13 @@ int32_t bitcoin_assembler(struct iguana_info *coin,uint8_t script[IGUANA_MAXSCRI str--; if ( (n= iguana_dataparse(stacks,script,k,str,&len)) > 0 ) { - k += n; + k = n; str += len; continue; } else if ( n < 0 ) { + printf("dataparse negative n.%d\n",n); errs++; break; } @@ -1011,6 +1143,7 @@ int32_t bitcoin_assembler(struct iguana_info *coin,uint8_t script[IGUANA_MAXSCRI break; } HASH_FIND(hh,OPTABLE,str,j,op); + printf("{%s}\n",str); str += j; if ( op != 0 ) { @@ -1025,11 +1158,92 @@ int32_t bitcoin_assembler(struct iguana_info *coin,uint8_t script[IGUANA_MAXSCRI } memset(args,0,sizeof(args)); numargs = 0; + script[k++] = op->opcode; + if ( (op->flags & IGUANA_CONTROLFLAG) != 0 ) + { + //printf("control opcode depth.%d\n",stacks->stackdepth); + switch ( op->opcode ) + { + case IGUANA_OP_IF: case IGUANA_OP_NOTIF: + if ( stacks->ifdepth >= IGUANA_MAXSTACKDEPTH ) + { + printf("ifdepth.%d >= MAXSTACKDEPTH.%d\n",stacks->ifdepth,IGUANA_MAXSTACKDEPTH); + errs++; + } + else + { + if ( stacks->stackdepth <= 0 ) + { + printf("if invalid stackdepth %d\n",stacks->stackdepth); + errs++; + } + else + { + args[0] = iguana_pop(stacks); + if ( iguana_isnonz(args[0]) == (op->opcode == IGUANA_OP_IF) ) + { + val = 1; + //printf("OP_IF enabled depth.%d\n",stacks->stackdepth); + } + else + { + val = -1; + //printf("OP_IF disabled depth.%d\n",stacks->stackdepth); + } + stacks->lastpath[++stacks->ifdepth] = val; + } + } + break; + case IGUANA_OP_ELSE: + /*if ( stacks->stackdepth <= 0 ) + { + printf("else invalid stackdepth %d\n",stacks->stackdepth); + errs++; + } + else*/ + { + if ( stacks->ifdepth <= stacks->elsedepth ) + { + printf("unhandled opcode.%02x stacks->ifdepth %d <= %d stacks->elsedepth\n",op->opcode,stacks->ifdepth,stacks->elsedepth); + errs++; + } + stacks->lastpath[stacks->ifdepth] *= -1; + //printf("OP_ELSE status.%d depth.%d\n",stacks->lastpath[stacks->ifdepth],stacks->stackdepth); + } + break; + case IGUANA_OP_ENDIF: + if ( stacks->ifdepth <= 0 ) + { + printf("endif without if offset.%ld\n",(long)str-(long)asmstr); + errs++; + } + stacks->ifdepth--; + //printf("OP_ENDIF status.%d depth.%d\n",stacks->lastpath[stacks->ifdepth],stacks->stackdepth); + break; + case IGUANA_OP_VERIFY: + break; + case IGUANA_OP_RETURN: + iguana_pushdata(stacks,0,0,0); + errs++; + break; + } + if ( errs != 0 ) + break; + continue; + } + if ( stacks->lastpath[stacks->ifdepth] != 0 ) + { + if ( stacks->lastpath[stacks->ifdepth] < 0 ) + { + //printf("SKIP opcode.%02x depth.%d\n",op->opcode,stacks->stackdepth); + if ( stacks->logarray ) + jaddistr(stacks->logarray,"skip"); + continue; + } + //printf("conditional opcode.%02x stackdepth.%d\n",op->opcode,stacks->stackdepth); + } if ( op->opcode <= IGUANA_OP_16 || ++numops <= MAX_OPS_PER_SCRIPT ) { - script[k++] = op->opcode; - if ( stacks->logarray ) - jaddistr(stacks->logarray,(char *)op->hh.key); if ( (op->flags & IGUANA_ALWAYSILLEGAL) != 0 ) { printf("disabled opcode.%s at offset.%ld\n",str,(long)str-(long)asmstr); @@ -1056,6 +1270,8 @@ int32_t bitcoin_assembler(struct iguana_info *coin,uint8_t script[IGUANA_MAXSCRI } if ( interpret == 0 || V == 0 ) continue; + if ( (op->flags & IGUANA_NOPFLAG) != 0 ) + continue; if ( (numargs= op->stackitems) > 0 ) { if ( stacks->stackdepth < op->stackitems ) @@ -1067,59 +1283,22 @@ int32_t bitcoin_assembler(struct iguana_info *coin,uint8_t script[IGUANA_MAXSCRI for (i=0; iflags & IGUANA_NOPFLAG) != 0 ) - continue; - if ( (op->flags & IGUANA_CONTROLFLAG) != 0 ) + //printf("%02x: numargs.%d depth.%d\n",op->opcode,numargs,stacks->stackdepth); + if ( stacks->logarray != 0 ) { - switch ( op->opcode ) + char tmpstr[1096]; + item = cJSON_CreateObject(); + array = cJSON_CreateArray(); + for (i=0; iifdepth >= IGUANA_MAXSTACKDEPTH ) - { - printf("ifdepth.%d >= MAXSTACKDEPTH.%d\n",stacks->ifdepth,IGUANA_MAXSTACKDEPTH); - errs++; - } - else - { - if ( iguana_isnonz(args[0]) == (op->opcode == IGUANA_OP_IF) ) - val = 1; - else val = -1; - stacks->lastpath[++stacks->ifdepth] = val; - } - break; - case IGUANA_OP_ELSE: - if ( stacks->ifdepth <= stacks->elsedepth ) - { - printf("unhandled opcode.%02x stacks->ifdepth %d <= %d stacks->elsedepth\n",op->opcode,stacks->ifdepth,stacks->elsedepth); - errs++; - } - stacks->lastpath[stacks->ifdepth] *= -1; - break; - case IGUANA_OP_ENDIF: - if ( stacks->ifdepth <= 0 ) - { - printf("endif without if offset.%ld\n",(long)str-(long)asmstr); - errs++; - } - stacks->ifdepth--; - break; - case IGUANA_OP_VERIFY: break; - case IGUANA_OP_RETURN: - iguana_pushdata(stacks,0,0,0); - errs++; - break; + datalen = iguana_databuf(databuf,args[i]); + init_hexbytes_noT(tmpstr,databuf,datalen); + jaddistr(array,tmpstr); } - if ( errs != 0 ) - break; - continue; - } - if ( stacks->lastpath[stacks->ifdepth] < 0 ) - { - if ( stacks->logarray ) - jaddistr(stacks->logarray,"skip"); - continue; + jadd(item,(char *)op->hh.key,array); + jaddi(stacks->logarray,item); } - else if ( (op->flags & IGUANA_EXECUTIONILLEGAL) != 0 ) + if ( (op->flags & IGUANA_EXECUTIONILLEGAL) != 0 ) { printf("opcode not allowed to run.%s at %ld\n",(char *)op->hh.key,(long)str-(long)asmstr); errs++; @@ -1129,7 +1308,17 @@ int32_t bitcoin_assembler(struct iguana_info *coin,uint8_t script[IGUANA_MAXSCRI { if ( iguana_cmp(&args[0],&args[1]) == 0 ) iguana_pushdata(stacks,1,0,0); - else iguana_pushdata(stacks,0,0,0); + else + { + for (i=0; iflags & IGUANA_CRYPTOFLAG) != 0 ) { @@ -1163,6 +1352,12 @@ int32_t bitcoin_assembler(struct iguana_info *coin,uint8_t script[IGUANA_MAXSCRI case IGUANA_OP_CHECKMULTISIG: case IGUANA_OP_CHECKMULTISIGVERIFY: iguana_pushdata(stacks,iguana_checkmultisig(coin,stacks,V->M,V->N,V->sigtxid),0,0); break; + case IGUANA_OP_CHECKSCHNORR: case IGUANA_OP_CHECKSCHNORRVERIFY: + iguana_pushdata(stacks,iguana_checkschnorrsig(coin,iguana_num(args[2]),args[1],args[0],V->sigtxid),0,0); + break; + case IGUANA_OP_CHECKPRIVATEKEY: case IGUANA_OP_CHECKPRIVATEKEYVERIFY: + iguana_pushdata(stacks,iguana_checkprivatekey(coin,args[1],args[0]),0,0); + break; } } else if ( op->opcode == IGUANA_OP_CHECKLOCKTIMEVERIFY ) // former OP_NOP2 @@ -1193,7 +1388,7 @@ int32_t bitcoin_assembler(struct iguana_info *coin,uint8_t script[IGUANA_MAXSCRI { if ( interpret != 0 && stacks->stackdepth < (val= iguana_num(args[0])) ) { - printf("stack not deep enough %d < %d\n",stacks->stackdepth,iguana_num(args[0])); + printf("stack not deep enough %d < %lld\n",stacks->stackdepth,(long long)iguana_num(args[0])); errs++; break; } @@ -1205,7 +1400,7 @@ int32_t bitcoin_assembler(struct iguana_info *coin,uint8_t script[IGUANA_MAXSCRI else { args[1] = stacks->stack[stacks->stackdepth - 1 - val]; - for (i=stacks->stackdepth-1-val; istackdepth-1; i++) + for (i=(int32_t)(stacks->stackdepth-1-val); istackdepth-1; i++) stacks->stack[i] = stacks->stack[i+1]; stacks->stack[stacks->stackdepth - 1] = args[1]; } @@ -1256,7 +1451,7 @@ int32_t bitcoin_assembler(struct iguana_info *coin,uint8_t script[IGUANA_MAXSCRI } else if ( (op->flags & IGUANA_MATHFLAG) != 0 ) { - int32_t numA,numB,numC; + int64_t numA,numB,numC; for (i=0; istackitems; i++) { if ( args[i].size != sizeof(int32_t) ) @@ -1320,6 +1515,7 @@ int32_t bitcoin_assembler(struct iguana_info *coin,uint8_t script[IGUANA_MAXSCRI } if ( iguana_isnonz(stacks->stack[stacks->stackdepth-1]) == 0 ) break; + iguana_pop(stacks); } } else @@ -1344,15 +1540,23 @@ int32_t bitcoin_assembler(struct iguana_info *coin,uint8_t script[IGUANA_MAXSCRI { errs++; printf("empty stack error\n"); + jaddstr(interpreter,"error","empty stack"); jadd(interpreter,"result",jfalse()); } else if ( iguana_isnonz(stacks->stack[--stacks->stackdepth]) != 0 ) { - printf("Evaluate true, depth.%d errs.%d\n",stacks->stackdepth,errs); - jadd(interpreter,"result",jtrue()); + printf("Evaluate true, depth.%d errs.%d k.%d\n",stacks->stackdepth,errs,k); + if ( errs == 0 ) + jadd(interpreter,"result",jtrue()); + else jadd(interpreter,"result",jfalse()); } - if ( stacks->logarray != 0 ) - printf("LOG.(%s)\n",jprint(stacks->logarray,1)); + else + { + jadd(interpreter,"result",jfalse()); + printf("Evaluate FALSE, depth.%d errs.%d [0] size.%d num.%d\n",stacks->stackdepth,errs,stacks->stack[0].size,stacks->stack[0].U.val); + } + //if ( stacks->logarray != 0 ) + // printf("LOG.(%s)\n",jprint(stacks->logarray,0)); if ( numargs > 0 ) { for (i=0; i& stack) -{ - if (stack.empty()) - throw runtime_error("popstack(): stack empty"); - stack.pop_back(); -} - -bool static IsCompressedOrUncompressedPubKey(const valtype &vchPubKey) { - if (vchPubKey.size() < 33) { - // Non-canonical public key: too short - return false; - } - if (vchPubKey[0] == 0x04) { - if (vchPubKey.size() != 65) { - // Non-canonical public key: invalid length for uncompressed key - return false; - } - } else if (vchPubKey[0] == 0x02 || vchPubKey[0] == 0x03) { - if (vchPubKey.size() != 33) { - // Non-canonical public key: invalid length for compressed key - return false; - } - } else { - // Non-canonical public key: neither compressed nor uncompressed - return false; - } - return true; -} - -/** - * A canonical signature exists of: <30> <02> <02> - * Where R and S are not negative (their first byte has its highest bit not set), and not - * excessively padded (do not start with a 0 byte, unless an otherwise negative number follows, - * in which case a single 0 byte is necessary and even required). - * - * See https://bitcointalk.org/index.php?topic=8392.msg127623#msg127623 - * - * This function is consensus-critical since BIP66. - */ -bool static IsValidSignatureEncoding(const std::vector &sig) { - // Format: 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-length] [S] [sighash] - // * total-length: 1-byte length descriptor of everything that follows, - // excluding the sighash byte. - // * R-length: 1-byte length descriptor of the R value that follows. - // * R: arbitrary-length big-endian encoded R value. It must use the shortest - // possible encoding for a positive integers (which means no null bytes at - // the start, except a single one when the next byte has its highest bit set). - // * S-length: 1-byte length descriptor of the S value that follows. - // * S: arbitrary-length big-endian encoded S value. The same rules apply. - // * sighash: 1-byte value indicating what data is hashed (not part of the DER - // signature) - - // Minimum and maximum size constraints. - if (sig.size() < 9) return false; - if (sig.size() > 73) return false; - - // A signature is of type 0x30 (compound). - if (sig[0] != 0x30) return false; - - // Make sure the length covers the entire signature. - if (sig[1] != sig.size() - 3) return false; - - // Extract the length of the R element. - unsigned int lenR = sig[3]; - - // Make sure the length of the S element is still inside the signature. - if (5 + lenR >= sig.size()) return false; - - // Extract the length of the S element. - unsigned int lenS = sig[5 + lenR]; - - // Verify that the length of the signature matches the sum of the length - // of the elements. - if ((size_t)(lenR + lenS + 7) != sig.size()) return false; - - // Check whether the R element is an integer. - if (sig[2] != 0x02) return false; - - // Zero-length integers are not allowed for R. - if (lenR == 0) return false; - - // Negative numbers are not allowed for R. - if (sig[4] & 0x80) return false; - - // Null bytes at the start of R are not allowed, unless R would - // otherwise be interpreted as a negative number. - if (lenR > 1 && (sig[4] == 0x00) && !(sig[5] & 0x80)) return false; - - // Check whether the S element is an integer. - if (sig[lenR + 4] != 0x02) return false; - - // Zero-length integers are not allowed for S. - if (lenS == 0) return false; - - // Negative numbers are not allowed for S. - if (sig[lenR + 6] & 0x80) return false; - - // Null bytes at the start of S are not allowed, unless S would otherwise be - // interpreted as a negative number. - if (lenS > 1 && (sig[lenR + 6] == 0x00) && !(sig[lenR + 7] & 0x80)) return false; - - return true; -} - -bool static IsLowDERSignature(const valtype &vchSig, ScriptError* serror) { - if (!IsValidSignatureEncoding(vchSig)) { - return set_error(serror, SCRIPT_ERR_SIG_DER); - } - std::vector vchSigCopy(vchSig.begin(), vchSig.begin() + vchSig.size() - 1); - if (!CPubKey::CheckLowS(vchSigCopy)) { - return set_error(serror, SCRIPT_ERR_SIG_HIGH_S); - } - return true; -} - -bool static IsDefinedHashtypeSignature(const valtype &vchSig) { - if (vchSig.size() == 0) { - return false; - } - unsigned char nHashType = vchSig[vchSig.size() - 1] & (~(SIGHASH_ANYONECANPAY)); - if (nHashType < SIGHASH_ALL || nHashType > SIGHASH_SINGLE) - return false; - - return true; -} - -bool CheckSignatureEncoding(const vector &vchSig, unsigned int flags, ScriptError* serror) { - // Empty signature. Not strictly DER encoded, but allowed to provide a - // compact way to provide an invalid signature for use with CHECK(MULTI)SIG - if (vchSig.size() == 0) { - return true; - } - if ((flags & (SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_STRICTENC)) != 0 && !IsValidSignatureEncoding(vchSig)) { - return set_error(serror, SCRIPT_ERR_SIG_DER); - } else if ((flags & SCRIPT_VERIFY_LOW_S) != 0 && !IsLowDERSignature(vchSig, serror)) { - // serror is set - return false; - } else if ((flags & SCRIPT_VERIFY_STRICTENC) != 0 && !IsDefinedHashtypeSignature(vchSig)) { - return set_error(serror, SCRIPT_ERR_SIG_HASHTYPE); - } - return true; -} - -bool static CheckPubKeyEncoding(const valtype &vchSig, unsigned int flags, ScriptError* serror) { - if ((flags & SCRIPT_VERIFY_STRICTENC) != 0 && !IsCompressedOrUncompressedPubKey(vchSig)) { - return set_error(serror, SCRIPT_ERR_PUBKEYTYPE); - } - return true; -} - -bool static CheckMinimalPush(const valtype& data, opcodetype opcode) { - if (data.size() == 0) { - // Could have used OP_0. - return opcode == OP_0; - } else if (data.size() == 1 && data[0] >= 1 && data[0] <= 16) { - // Could have used OP_1 .. OP_16. - return opcode == OP_1 + (data[0] - 1); - } else if (data.size() == 1 && data[0] == 0x81) { - // Could have used OP_1NEGATE. - return opcode == OP_1NEGATE; - } else if (data.size() <= 75) { - // Could have used a direct push (opcode indicating number of bytes pushed + those bytes). - return opcode == data.size(); - } else if (data.size() <= 255) { - // Could have used OP_PUSHDATA. - return opcode == OP_PUSHDATA1; - } else if (data.size() <= 65535) { - // Could have used OP_PUSHDATA2. - return opcode == OP_PUSHDATA2; - } - return true; -} - -bool EvalScript(vector >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror) -{ - static const CScriptNum bnZero(0); - static const CScriptNum bnOne(1); - static const CScriptNum bnFalse(0); - static const CScriptNum bnTrue(1); - static const valtype vchFalse(0); - static const valtype vchZero(0); - static const valtype vchTrue(1, 1); - - CScript::const_iterator pc = script.begin(); - CScript::const_iterator pend = script.end(); - CScript::const_iterator pbegincodehash = script.begin(); - opcodetype opcode; - valtype vchPushValue; - vector vfExec; - vector altstack; - set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR); - if (script.size() > 10000) - return set_error(serror, SCRIPT_ERR_SCRIPT_SIZE); - int nOpCount = 0; - bool fRequireMinimal = (flags & SCRIPT_VERIFY_MINIMALDATA) != 0; - - try - { - while (pc < pend) - { - bool fExec = !count(vfExec.begin(), vfExec.end(), false); - - // - // Read instruction - // - if (!script.GetOp(pc, opcode, vchPushValue)) - return set_error(serror, SCRIPT_ERR_BAD_OPCODE); - if (vchPushValue.size() > MAX_SCRIPT_ELEMENT_SIZE) - return set_error(serror, SCRIPT_ERR_PUSH_SIZE); - - // Note how OP_RESERVED does not count towards the opcode limit. - if (opcode > OP_16 && ++nOpCount > MAX_OPS_PER_SCRIPT) - return set_error(serror, SCRIPT_ERR_OP_COUNT); - - if (opcode == OP_CAT || - opcode == OP_SUBSTR || - opcode == OP_LEFT || - opcode == OP_RIGHT || - opcode == OP_INVERT || - opcode == OP_AND || - opcode == OP_OR || - opcode == OP_XOR || - opcode == OP_2MUL || - opcode == OP_2DIV || - opcode == OP_MUL || - opcode == OP_DIV || - opcode == OP_MOD || - opcode == OP_LSHIFT || - opcode == OP_RSHIFT) - return set_error(serror, SCRIPT_ERR_DISABLED_OPCODE); // Disabled opcodes. - - if (fExec && 0 <= opcode && opcode <= OP_PUSHDATA4) { - if (fRequireMinimal && !CheckMinimalPush(vchPushValue, opcode)) { - return set_error(serror, SCRIPT_ERR_MINIMALDATA); - } - stack.push_back(vchPushValue); - } else if (fExec || (OP_IF <= opcode && opcode <= OP_ENDIF)) - switch (opcode) - { - // - // Push value - // - case OP_1NEGATE: - case OP_1: - case OP_2: - case OP_3: - case OP_4: - case OP_5: - case OP_6: - case OP_7: - case OP_8: - case OP_9: - case OP_10: - case OP_11: - case OP_12: - case OP_13: - case OP_14: - case OP_15: - case OP_16: - { - // ( -- value) - CScriptNum bn((int)opcode - (int)(OP_1 - 1)); - stack.push_back(bn.getvch()); - // The result of these opcodes should always be the minimal way to push the data - // they push, so no need for a CheckMinimalPush here. - } - break; - - - // - // Control - // - case OP_NOP: - break; - - case OP_CHECKLOCKTIMEVERIFY: - { - if (!(flags & SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY)) { - // not enabled; treat as a NOP2 - if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) { - return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS); - } - break; - } - - if (stack.size() < 1) - return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - - // Note that elsewhere numeric opcodes are limited to - // operands in the range -2**31+1 to 2**31-1, however it is - // legal for opcodes to produce results exceeding that - // range. This limitation is implemented by CScriptNum's - // default 4-byte limit. - // - // If we kept to that limit we'd have a year 2038 problem, - // even though the nLockTime field in transactions - // themselves is uint32 which only becomes meaningless - // after the year 2106. - // - // Thus as a special case we tell CScriptNum to accept up - // to 5-byte bignums, which are good until 2**39-1, well - // beyond the 2**32-1 limit of the nLockTime field itself. - const CScriptNum nLockTime(stacktop(-1), fRequireMinimal, 5); - - // In the rare event that the argument may be < 0 due to - // some arithmetic being done first, you can always use - // 0 MAX CHECKLOCKTIMEVERIFY. - if (nLockTime < 0) - return set_error(serror, SCRIPT_ERR_NEGATIVE_LOCKTIME); - - // Actually compare the specified lock time with the transaction. - if (!checker.CheckLockTime(nLockTime)) - return set_error(serror, SCRIPT_ERR_UNSATISFIED_LOCKTIME); - - break; - } - - case OP_NOP1: case OP_NOP3: case OP_NOP4: case OP_NOP5: - case OP_NOP6: case OP_NOP7: case OP_NOP8: case OP_NOP9: case OP_NOP10: - { - if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) - return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS); - } - break; - - case OP_IF: - case OP_NOTIF: - { - // if [statements] [else [statements]] endif - bool fValue = false; - if (fExec) - { - if (stack.size() < 1) - return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL); - valtype& vch = stacktop(-1); - fValue = CastToBool(vch); - if (opcode == OP_NOTIF) - fValue = !fValue; - popstack(stack); - } - vfExec.push_back(fValue); - } - break; - - case OP_ELSE: - { - if (vfExec.empty()) - return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL); - vfExec.back() = !vfExec.back(); - } - break; - - case OP_ENDIF: - { - if (vfExec.empty()) - return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL); - vfExec.pop_back(); - } - break; - - case OP_VERIFY: - { - // (true -- ) or - // (false -- false) and return - if (stack.size() < 1) - return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - bool fValue = CastToBool(stacktop(-1)); - if (fValue) - popstack(stack); - else - return set_error(serror, SCRIPT_ERR_VERIFY); - } - break; - - case OP_RETURN: - { - return set_error(serror, SCRIPT_ERR_OP_RETURN); - } - break; - - - // - // Stack ops - // - case OP_TOALTSTACK: - { - if (stack.size() < 1) - return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - altstack.push_back(stacktop(-1)); - popstack(stack); - } - break; - - case OP_FROMALTSTACK: - { - if (altstack.size() < 1) - return set_error(serror, SCRIPT_ERR_INVALID_ALTSTACK_OPERATION); - stack.push_back(altstacktop(-1)); - popstack(altstack); - } - break; - - case OP_2DROP: - { - // (x1 x2 -- ) - if (stack.size() < 2) - return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - popstack(stack); - popstack(stack); - } - break; - - case OP_2DUP: - { - // (x1 x2 -- x1 x2 x1 x2) - if (stack.size() < 2) - return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - valtype vch1 = stacktop(-2); - valtype vch2 = stacktop(-1); - stack.push_back(vch1); - stack.push_back(vch2); - } - break; - - case OP_3DUP: - { - // (x1 x2 x3 -- x1 x2 x3 x1 x2 x3) - if (stack.size() < 3) - return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - valtype vch1 = stacktop(-3); - valtype vch2 = stacktop(-2); - valtype vch3 = stacktop(-1); - stack.push_back(vch1); - stack.push_back(vch2); - stack.push_back(vch3); - } - break; - - case OP_2OVER: - { - // (x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2) - if (stack.size() < 4) - return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - valtype vch1 = stacktop(-4); - valtype vch2 = stacktop(-3); - stack.push_back(vch1); - stack.push_back(vch2); - } - break; - - case OP_2ROT: - { - // (x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2) - if (stack.size() < 6) - return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - valtype vch1 = stacktop(-6); - valtype vch2 = stacktop(-5); - stack.erase(stack.end()-6, stack.end()-4); - stack.push_back(vch1); - stack.push_back(vch2); - } - break; - - case OP_2SWAP: - { - // (x1 x2 x3 x4 -- x3 x4 x1 x2) - if (stack.size() < 4) - return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - swap(stacktop(-4), stacktop(-2)); - swap(stacktop(-3), stacktop(-1)); - } - break; - - case OP_IFDUP: - { - // (x - 0 | x x) - if (stack.size() < 1) - return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - valtype vch = stacktop(-1); - if (CastToBool(vch)) - stack.push_back(vch); - } - break; - - case OP_DEPTH: - { - // -- stacksize - CScriptNum bn(stack.size()); - stack.push_back(bn.getvch()); - } - break; - - case OP_DROP: - { - // (x -- ) - if (stack.size() < 1) - return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - popstack(stack); - } - break; - - case OP_DUP: - { - // (x -- x x) - if (stack.size() < 1) - return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - valtype vch = stacktop(-1); - stack.push_back(vch); - } - break; - - case OP_NIP: - { - // (x1 x2 -- x2) - if (stack.size() < 2) - return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - stack.erase(stack.end() - 2); - } - break; - - case OP_OVER: - { - // (x1 x2 -- x1 x2 x1) - if (stack.size() < 2) - return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - valtype vch = stacktop(-2); - stack.push_back(vch); - } - break; - - case OP_PICK: - case OP_ROLL: - { - // (xn ... x2 x1 x0 n - xn ... x2 x1 x0 xn) - // (xn ... x2 x1 x0 n - ... x2 x1 x0 xn) - if (stack.size() < 2) - return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - int n = CScriptNum(stacktop(-1), fRequireMinimal).getint(); - popstack(stack); - if (n < 0 || n >= (int)stack.size()) - return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - valtype vch = stacktop(-n-1); - if (opcode == OP_ROLL) - stack.erase(stack.end()-n-1); - stack.push_back(vch); - } - break; - - case OP_ROT: - { - // (x1 x2 x3 -- x2 x3 x1) - // x2 x1 x3 after first swap - // x2 x3 x1 after second swap - if (stack.size() < 3) - return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - swap(stacktop(-3), stacktop(-2)); - swap(stacktop(-2), stacktop(-1)); - } - break; - - case OP_SWAP: - { - // (x1 x2 -- x2 x1) - if (stack.size() < 2) - return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - swap(stacktop(-2), stacktop(-1)); - } - break; - - case OP_TUCK: - { - // (x1 x2 -- x2 x1 x2) - if (stack.size() < 2) - return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - valtype vch = stacktop(-1); - stack.insert(stack.end()-2, vch); - } - break; - - - case OP_SIZE: - { - // (in -- in size) - if (stack.size() < 1) - return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - CScriptNum bn(stacktop(-1).size()); - stack.push_back(bn.getvch()); - } - break; - - - // - // Bitwise logic - // - case OP_EQUAL: - case OP_EQUALVERIFY: - //case OP_NOTEQUAL: // use OP_NUMNOTEQUAL - { - // (x1 x2 - bool) - if (stack.size() < 2) - return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - valtype& vch1 = stacktop(-2); - valtype& vch2 = stacktop(-1); - bool fEqual = (vch1 == vch2); - // OP_NOTEQUAL is disabled because it would be too easy to say - // something like n != 1 and have some wiseguy pass in 1 with extra - // zero bytes after it (numerically, 0x01 == 0x0001 == 0x000001) - //if (opcode == OP_NOTEQUAL) - // fEqual = !fEqual; - popstack(stack); - popstack(stack); - stack.push_back(fEqual ? vchTrue : vchFalse); - if (opcode == OP_EQUALVERIFY) - { - if (fEqual) - popstack(stack); - else - return set_error(serror, SCRIPT_ERR_EQUALVERIFY); - } - } - break; - - - // - // Numeric - // - case OP_1ADD: - case OP_1SUB: - case OP_NEGATE: - case OP_ABS: - case OP_NOT: - case OP_0NOTEQUAL: - { - // (in -- out) - if (stack.size() < 1) - return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - CScriptNum bn(stacktop(-1), fRequireMinimal); - switch (opcode) - { - case OP_1ADD: bn += bnOne; break; - case OP_1SUB: bn -= bnOne; break; - case OP_NEGATE: bn = -bn; break; - case OP_ABS: if (bn < bnZero) bn = -bn; break; - case OP_NOT: bn = (bn == bnZero); break; - case OP_0NOTEQUAL: bn = (bn != bnZero); break; - default: assert(!"invalid opcode"); break; - } - popstack(stack); - stack.push_back(bn.getvch()); - } - break; - - case OP_ADD: - case OP_SUB: - case OP_BOOLAND: - case OP_BOOLOR: - case OP_NUMEQUAL: - case OP_NUMEQUALVERIFY: - case OP_NUMNOTEQUAL: - case OP_LESSTHAN: - case OP_GREATERTHAN: - case OP_LESSTHANOREQUAL: - case OP_GREATERTHANOREQUAL: - case OP_MIN: - case OP_MAX: - { - // (x1 x2 -- out) - if (stack.size() < 2) - return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - CScriptNum bn1(stacktop(-2), fRequireMinimal); - CScriptNum bn2(stacktop(-1), fRequireMinimal); - CScriptNum bn(0); - switch (opcode) - { - case OP_ADD: - bn = bn1 + bn2; - break; - - case OP_SUB: - bn = bn1 - bn2; - break; - - case OP_BOOLAND: bn = (bn1 != bnZero && bn2 != bnZero); break; - case OP_BOOLOR: bn = (bn1 != bnZero || bn2 != bnZero); break; - case OP_NUMEQUAL: bn = (bn1 == bn2); break; - case OP_NUMEQUALVERIFY: bn = (bn1 == bn2); break; - case OP_NUMNOTEQUAL: bn = (bn1 != bn2); break; - case OP_LESSTHAN: bn = (bn1 < bn2); break; - case OP_GREATERTHAN: bn = (bn1 > bn2); break; - case OP_LESSTHANOREQUAL: bn = (bn1 <= bn2); break; - case OP_GREATERTHANOREQUAL: bn = (bn1 >= bn2); break; - case OP_MIN: bn = (bn1 < bn2 ? bn1 : bn2); break; - case OP_MAX: bn = (bn1 > bn2 ? bn1 : bn2); break; - default: assert(!"invalid opcode"); break; - } - popstack(stack); - popstack(stack); - stack.push_back(bn.getvch()); - - if (opcode == OP_NUMEQUALVERIFY) - { - if (CastToBool(stacktop(-1))) - popstack(stack); - else - return set_error(serror, SCRIPT_ERR_NUMEQUALVERIFY); - } - } - break; - - case OP_WITHIN: - { - // (x min max -- out) - if (stack.size() < 3) - return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - CScriptNum bn1(stacktop(-3), fRequireMinimal); - CScriptNum bn2(stacktop(-2), fRequireMinimal); - CScriptNum bn3(stacktop(-1), fRequireMinimal); - bool fValue = (bn2 <= bn1 && bn1 < bn3); - popstack(stack); - popstack(stack); - popstack(stack); - stack.push_back(fValue ? vchTrue : vchFalse); - } - break; - - - // - // Crypto - // - case OP_RIPEMD160: - case OP_SHA1: - case OP_SHA256: - case OP_HASH160: - case OP_HASH256: - { - // (in -- hash) - if (stack.size() < 1) - return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - valtype& vch = stacktop(-1); - valtype vchHash((opcode == OP_RIPEMD160 || opcode == OP_SHA1 || opcode == OP_HASH160) ? 20 : 32); - if (opcode == OP_RIPEMD160) - CRIPEMD160().Write(begin_ptr(vch), vch.size()).Finalize(begin_ptr(vchHash)); - else if (opcode == OP_SHA1) - CSHA1().Write(begin_ptr(vch), vch.size()).Finalize(begin_ptr(vchHash)); - else if (opcode == OP_SHA256) - CSHA256().Write(begin_ptr(vch), vch.size()).Finalize(begin_ptr(vchHash)); - else if (opcode == OP_HASH160) - CHash160().Write(begin_ptr(vch), vch.size()).Finalize(begin_ptr(vchHash)); - else if (opcode == OP_HASH256) - CHash256().Write(begin_ptr(vch), vch.size()).Finalize(begin_ptr(vchHash)); - popstack(stack); - stack.push_back(vchHash); - } - break; - - case OP_CODESEPARATOR: - { - // Hash starts after the code separator - pbegincodehash = pc; - } - break; - - case OP_CHECKSIG: - case OP_CHECKSIGVERIFY: - { - // (sig pubkey -- bool) - if (stack.size() < 2) - return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - - valtype& vchSig = stacktop(-2); - valtype& vchPubKey = stacktop(-1); - - // Subset of script starting at the most recent codeseparator - CScript scriptCode(pbegincodehash, pend); - - // Drop the signature, since there's no way for a signature to sign itself - scriptCode.FindAndDelete(CScript(vchSig)); - - if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, serror)) { - //serror is set - return false; - } - bool fSuccess = checker.CheckSig(vchSig, vchPubKey, scriptCode); - - popstack(stack); - popstack(stack); - stack.push_back(fSuccess ? vchTrue : vchFalse); - if (opcode == OP_CHECKSIGVERIFY) - { - if (fSuccess) - popstack(stack); - else - return set_error(serror, SCRIPT_ERR_CHECKSIGVERIFY); - } - } - break; - - case OP_CHECKMULTISIG: - case OP_CHECKMULTISIGVERIFY: - { - // ([sig ...] num_of_signatures [pubkey ...] num_of_pubkeys -- bool) - - int i = 1; - if ((int)stack.size() < i) - return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - - int nKeysCount = CScriptNum(stacktop(-i), fRequireMinimal).getint(); - if (nKeysCount < 0 || nKeysCount > MAX_PUBKEYS_PER_MULTISIG) - return set_error(serror, SCRIPT_ERR_PUBKEY_COUNT); - nOpCount += nKeysCount; - if (nOpCount > MAX_OPS_PER_SCRIPT) - return set_error(serror, SCRIPT_ERR_OP_COUNT); - int ikey = ++i; - i += nKeysCount; - if ((int)stack.size() < i) - return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - - int nSigsCount = CScriptNum(stacktop(-i), fRequireMinimal).getint(); - if (nSigsCount < 0 || nSigsCount > nKeysCount) - return set_error(serror, SCRIPT_ERR_SIG_COUNT); - int isig = ++i; - i += nSigsCount; - if ((int)stack.size() < i) - return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - - // Subset of script starting at the most recent codeseparator - CScript scriptCode(pbegincodehash, pend); - - // Drop the signatures, since there's no way for a signature to sign itself - for (int k = 0; k < nSigsCount; k++) - { - valtype& vchSig = stacktop(-isig-k); - scriptCode.FindAndDelete(CScript(vchSig)); - } - - bool fSuccess = true; - while (fSuccess && nSigsCount > 0) - { - valtype& vchSig = stacktop(-isig); - valtype& vchPubKey = stacktop(-ikey); - - // Note how this makes the exact order of pubkey/signature evaluation - // distinguishable by CHECKMULTISIG NOT if the STRICTENC flag is set. - // See the script_(in)valid tests for details. - if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, serror)) { - // serror is set - return false; - } - - // Check signature - bool fOk = checker.CheckSig(vchSig, vchPubKey, scriptCode); - - if (fOk) { - isig++; - nSigsCount--; - } - ikey++; - nKeysCount--; - - // If there are more signatures left than keys left, - // then too many signatures have failed. Exit early, - // without checking any further signatures. - if (nSigsCount > nKeysCount) - fSuccess = false; - } - - // Clean up stack of actual arguments - while (i-- > 1) - popstack(stack); - - // A bug causes CHECKMULTISIG to consume one extra argument - // whose contents were not checked in any way. - // - // Unfortunately this is a potential source of mutability, - // so optionally verify it is exactly equal to zero prior - // to removing it from the stack. - if (stack.size() < 1) - return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - if ((flags & SCRIPT_VERIFY_NULLDUMMY) && stacktop(-1).size()) - return set_error(serror, SCRIPT_ERR_SIG_NULLDUMMY); - popstack(stack); - - stack.push_back(fSuccess ? vchTrue : vchFalse); - - if (opcode == OP_CHECKMULTISIGVERIFY) - { - if (fSuccess) - popstack(stack); - else - return set_error(serror, SCRIPT_ERR_CHECKMULTISIGVERIFY); - } - } - break; - - default: - return set_error(serror, SCRIPT_ERR_BAD_OPCODE); - } - - // Size limits - if (stack.size() + altstack.size() > 1000) - return set_error(serror, SCRIPT_ERR_STACK_SIZE); - } - } - catch (...) - { - return set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR); - } - - if (!vfExec.empty()) - return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL); - - return set_success(serror); -} - -namespace { - - /** - * Wrapper that serializes like CTransaction, but with the modifications - * required for the signature hash done in-place - */ - class CTransactionSignatureSerializer { - private: - const CTransaction &txTo; //! reference to the spending transaction (the one being serialized) - const CScript &scriptCode; //! output script being consumed - const unsigned int nIn; //! input index of txTo being signed - const bool fAnyoneCanPay; //! whether the hashtype has the SIGHASH_ANYONECANPAY flag set - const bool fHashSingle; //! whether the hashtype is SIGHASH_SINGLE - const bool fHashNone; //! whether the hashtype is SIGHASH_NONE - - public: - CTransactionSignatureSerializer(const CTransaction &txToIn, const CScript &scriptCodeIn, unsigned int nInIn, int nHashTypeIn) : - txTo(txToIn), scriptCode(scriptCodeIn), nIn(nInIn), - fAnyoneCanPay(!!(nHashTypeIn & SIGHASH_ANYONECANPAY)), - fHashSingle((nHashTypeIn & 0x1f) == SIGHASH_SINGLE), - fHashNone((nHashTypeIn & 0x1f) == SIGHASH_NONE) {} - - /** Serialize the passed scriptCode, skipping OP_CODESEPARATORs */ - template - void SerializeScriptCode(S &s, int nType, int nVersion) const { - CScript::const_iterator it = scriptCode.begin(); - CScript::const_iterator itBegin = it; - opcodetype opcode; - unsigned int nCodeSeparators = 0; - while (scriptCode.GetOp(it, opcode)) { - if (opcode == OP_CODESEPARATOR) - nCodeSeparators++; - } - ::WriteCompactSize(s, scriptCode.size() - nCodeSeparators); - it = itBegin; - while (scriptCode.GetOp(it, opcode)) { - if (opcode == OP_CODESEPARATOR) { - s.write((char*)&itBegin[0], it-itBegin-1); - itBegin = it; - } - } - if (itBegin != scriptCode.end()) - s.write((char*)&itBegin[0], it-itBegin); - } - - /** Serialize an input of txTo */ - template - void SerializeInput(S &s, unsigned int nInput, int nType, int nVersion) const { - // In case of SIGHASH_ANYONECANPAY, only the input being signed is serialized - if (fAnyoneCanPay) - nInput = nIn; - // Serialize the prevout - ::Serialize(s, txTo.vin[nInput].prevout, nType, nVersion); - // Serialize the script - if (nInput != nIn) - // Blank out other inputs' signatures - ::Serialize(s, CScriptBase(), nType, nVersion); - else - SerializeScriptCode(s, nType, nVersion); - // Serialize the nSequence - if (nInput != nIn && (fHashSingle || fHashNone)) - // let the others update at will - ::Serialize(s, (int)0, nType, nVersion); - else - ::Serialize(s, txTo.vin[nInput].nSequence, nType, nVersion); - } - - /** Serialize an output of txTo */ - template - void SerializeOutput(S &s, unsigned int nOutput, int nType, int nVersion) const { - if (fHashSingle && nOutput != nIn) - // Do not lock-in the txout payee at other indices as txin - ::Serialize(s, CTxOut(), nType, nVersion); - else - ::Serialize(s, txTo.vout[nOutput], nType, nVersion); - } - - /** Serialize txTo */ - template - void Serialize(S &s, int nType, int nVersion) const { - // Serialize nVersion - ::Serialize(s, txTo.nVersion, nType, nVersion); - // Serialize vin - unsigned int nInputs = fAnyoneCanPay ? 1 : txTo.vin.size(); - ::WriteCompactSize(s, nInputs); - for (unsigned int nInput = 0; nInput < nInputs; nInput++) - SerializeInput(s, nInput, nType, nVersion); - // Serialize vout - unsigned int nOutputs = fHashNone ? 0 : (fHashSingle ? nIn+1 : txTo.vout.size()); - ::WriteCompactSize(s, nOutputs); - for (unsigned int nOutput = 0; nOutput < nOutputs; nOutput++) - SerializeOutput(s, nOutput, nType, nVersion); - // Serialize nLockTime - ::Serialize(s, txTo.nLockTime, nType, nVersion); - } - }; - -} // anon namespace - -uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, size_t* nHashedOut) -{ - static const uint256 one(uint256S("0000000000000000000000000000000000000000000000000000000000000001")); - if (nIn >= txTo.vin.size()) { - // nIn out of range - return one; - } - - // Check for invalid use of SIGHASH_SINGLE - if ((nHashType & 0x1f) == SIGHASH_SINGLE) { - if (nIn >= txTo.vout.size()) { - // nOut out of range - return one; - } - } - - // Wrapper to serialize only the necessary parts of the transaction being signed - CTransactionSignatureSerializer txTmp(txTo, scriptCode, nIn, nHashType); - - // Serialize and hash - CHashWriter ss(SER_GETHASH, 0); - ss << txTmp << nHashType; - if (nHashedOut != NULL) - *nHashedOut = ss.GetNumBytesHashed(); - return ss.GetHash(); -} - -bool TransactionSignatureChecker::VerifySignature(const std::vector& vchSig, const CPubKey& pubkey, const uint256& sighash) const -{ - return pubkey.Verify(sighash, vchSig); -} - -bool TransactionSignatureChecker::CheckSig(const vector& vchSigIn, const vector& vchPubKey, - const CScript& scriptCode) const -{ - CPubKey pubkey(vchPubKey); - if (!pubkey.IsValid()) - return false; - - // Hash type is one byte tacked on to the end of the signature - vector vchSig(vchSigIn); - if (vchSig.empty()) - return false; - int nHashType = vchSig.back(); - vchSig.pop_back(); - - size_t nHashed = 0; - uint256 sighash = SignatureHash(scriptCode, *txTo, nIn, nHashType, &nHashed); - nBytesHashed += nHashed; - ++nSigops; - - if (!VerifySignature(vchSig, pubkey, sighash)) - return false; - - return true; -} - -bool TransactionSignatureChecker::CheckLockTime(const CScriptNum& nLockTime) const -{ - // There are two kinds of nLockTime: lock-by-blockheight - // and lock-by-blocktime, distinguished by whether - // nLockTime < LOCKTIME_THRESHOLD. - // - // We want to compare apples to apples, so fail the script - // unless the type of nLockTime being tested is the same as - // the nLockTime in the transaction. - if (!( - (txTo->nLockTime < LOCKTIME_THRESHOLD && nLockTime < LOCKTIME_THRESHOLD) || - (txTo->nLockTime >= LOCKTIME_THRESHOLD && nLockTime >= LOCKTIME_THRESHOLD) - )) - return false; - - // Now that we know we're comparing apples-to-apples, the - // comparison is a simple numeric one. - if (nLockTime > (int64_t)txTo->nLockTime) - return false; - - // Finally the nLockTime feature can be disabled and thus - // CHECKLOCKTIMEVERIFY bypassed if every txin has been - // finalized by setting nSequence to maxint. The - // transaction would be allowed into the blockchain, making - // the opcode ineffective. - // - // Testing if this vin is not final is sufficient to - // prevent this condition. Alternatively we could test all - // inputs, but testing just this input minimizes the data - // required to prove correct CHECKLOCKTIMEVERIFY execution. - if (txTo->vin[nIn].IsFinal()) - return false; - - return true; -} - - -bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror) -{ - set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR); - - if ((flags & SCRIPT_VERIFY_SIGPUSHONLY) != 0 && !scriptSig.IsPushOnly()) { - return set_error(serror, SCRIPT_ERR_SIG_PUSHONLY); - } - - vector > stack, stackCopy; - if (!EvalScript(stack, scriptSig, flags, checker, serror)) - // serror is set - return false; - if (flags & SCRIPT_VERIFY_P2SH) - stackCopy = stack; - if (!EvalScript(stack, scriptPubKey, flags, checker, serror)) - // serror is set - return false; - if (stack.empty()) - return set_error(serror, SCRIPT_ERR_EVAL_FALSE); - if (CastToBool(stack.back()) == false) - return set_error(serror, SCRIPT_ERR_EVAL_FALSE); - - // Additional validation for spend-to-script-hash transactions: - if ((flags & SCRIPT_VERIFY_P2SH) && scriptPubKey.IsPayToScriptHash()) - { - // scriptSig must be literals-only or validation fails - if (!scriptSig.IsPushOnly()) - return set_error(serror, SCRIPT_ERR_SIG_PUSHONLY); - - // Restore stack. - swap(stack, stackCopy); - - // stack cannot be empty here, because if it was the - // P2SH HASH <> EQUAL scriptPubKey would be evaluated with - // an empty stack and the EvalScript above would return false. - assert(!stack.empty()); - - const valtype& pubKeySerialized = stack.back(); - CScript pubKey2(pubKeySerialized.begin(), pubKeySerialized.end()); - popstack(stack); - - if (!EvalScript(stack, pubKey2, flags, checker, serror)) - // serror is set - return false; - if (stack.empty()) - return set_error(serror, SCRIPT_ERR_EVAL_FALSE); - if (!CastToBool(stack.back())) - return set_error(serror, SCRIPT_ERR_EVAL_FALSE); - } - - // The CLEANSTACK check is only performed after potential P2SH evaluation, - // as the non-P2SH evaluation of a P2SH script will obviously not result in - // a clean stack (the P2SH inputs remain). - if ((flags & SCRIPT_VERIFY_CLEANSTACK) != 0) { - // Disallow CLEANSTACK without P2SH, as otherwise a switch CLEANSTACK->P2SH+CLEANSTACK - // would be possible, which is not a softfork (and P2SH should be one). - assert((flags & SCRIPT_VERIFY_P2SH) != 0); - if (stack.size() != 1) { - return set_error(serror, SCRIPT_ERR_CLEANSTACK); - } - } - - return set_success(serror); -} -#endif - diff --git a/iguana/iguana_json.c b/iguana/iguana_json.c index 2b74906c8..610012727 100755 --- a/iguana/iguana_json.c +++ b/iguana/iguana_json.c @@ -14,7 +14,7 @@ ******************************************************************************/ #include "iguana777.h" -#include "SuperNET.h" +//#include "SuperNET.h" cJSON *helpjson(cJSON *json,cJSON *array,cJSON *agents,char *agentstr,char *method,cJSON *methodargs) { @@ -112,6 +112,7 @@ cJSON *SuperNET_helpjson() #define IGUANA_HELP_I(agent,name,val) array = helpjson(IGUANA_ARGS,#agent,#name,helparray(cJSON_CreateArray(),helpitem(#val,"int"))) #define IGUANA_HELP_II(agent,name,val,val2) array = helpjson(IGUANA_ARGS,#agent,#name,helparray2(cJSON_CreateArray(),helpitem(#val,"int"),helpitem(#val2,"int"))) +#define IGUANA_HELP_ID(agent,name,val,val2) array = helpjson(IGUANA_ARGS,#agent,#name,helparray2(cJSON_CreateArray(),helpitem(#val,"int"),helpitem(#val2,"float"))) #define IGUANA_HELP_IA(agent,name,val,obj) array = helpjson(IGUANA_ARGS,#agent,#name,helparray2(cJSON_CreateArray(),helpitem(#val,"int"),helpitem(#obj,"array"))) #define IGUANA_HELP_IIA(agent,name,val,val2,obj) array = helpjson(IGUANA_ARGS,#agent,#name,helparray3(cJSON_CreateArray(),helpitem(#val,"int"),helpitem(#val2,"int"),helpitem(#obj,"array"))) #define IGUANA_HELP_III(agent,name,val,val2,val3) array = helpjson(IGUANA_ARGS,#agent,#name,helparray3(cJSON_CreateArray(),helpitem(#val,"int"),helpitem(#val2,"int"),helpitem(#val3,"int"))) @@ -142,6 +143,7 @@ cJSON *SuperNET_helpjson() // API functions #define ZERO_ARGS IGUANA_HELP0 #define INT_ARG IGUANA_HELP_I +#define INT_AND_DOUBLE IGUANA_HELP_ID #define TWO_INTS IGUANA_HELP_II #define STRING_ARG IGUANA_HELP_S #define TWO_STRINGS IGUANA_HELP_SS @@ -371,6 +373,7 @@ cJSON *update_docjson(cJSON *docjson,char *agent,char *method) { sprintf(stubstr,"{\"agent\":\"%s\",\"method\":\"%s\",\"field0\":\"put in helpful info field0\",\"field1\":\"put in helpful info for field1\",\"help\":\"put helpful info here\",\"teststatus\":[{\"tester\":\"bob\",\"result\":\"put result here\",\"notes\":\"put useful notes here\",\"automated\":\"notyet\",\"sourcefile\":\"%s_%s_test.py\"}]}",agent,method,agent,method); sprintf(fname,"%s/%s_%s.json",GLOBAL_HELPDIR,agent,method); + OS_portable_path(fname); if ( (docstr= OS_filestr(&allocsize,fname)) != 0 ) { if ( (item= cJSON_Parse(docstr)) == 0 ) @@ -475,35 +478,13 @@ int32_t pretty_forms(char *fname,char *agentstr,char *suffix) char *SuperNET_htmlstr(char *fname,char *htmlstr,int32_t maxsize,char *agentstr) { - int32_t i,n,len,size = 0; long filesize; cJSON *helpjson,*item,*array; char *str; FILE *fp = 0; + //int32_t i,n,len,size = 0; cJSON *helpjson,*item,*array; char *str; FILE *fp = 0; + long filesize; htmlstr[0] = 0; pretty_forms(fname,agentstr,"html"); - printf("autocreate %s\n","_API.md"); - pretty_forms("_API.md",0,"md"); -return(OS_filestr(&filesize,"index7778.html")); - sprintf(htmlstr," SuperUGLY GUI> "); - size = (int32_t)strlen(htmlstr); - if ( (helpjson= SuperNET_helpjson()) != 0 ) - { - if ( (array= jarray(&n,helpjson,"API")) != 0 ) - { - for (i=0; i


"); - printf("



\n"); - return(htmlstr); + //printf("autocreate %s\n","autoAPI.md"); + pretty_forms("autoAPI.md",0,"md"); + return(OS_filestr(&filesize,"index7778.html")); } cJSON *iguana_peerjson(struct iguana_info *coin,struct iguana_peer *addr) @@ -555,12 +536,12 @@ cJSON *iguana_peerjson(struct iguana_info *coin,struct iguana_peer *addr) cJSON *iguana_peersjson(struct iguana_info *coin,int32_t addronly) { cJSON *retjson,*array; int32_t i; struct iguana_peer *addr; - if ( coin == 0 ) + if ( coin == 0 || coin->peers == 0 ) return(0); array = cJSON_CreateArray(); for (i=0; iMAXPEERS; i++) { - addr = &coin->peers.active[i]; + addr = &coin->peers->active[i]; if ( addr->usock >= 0 && addr->ipbits != 0 && addr->ipaddr[0] != 0 ) { if ( addronly != 0 ) @@ -591,16 +572,26 @@ STRING_ARG(iguana,peers,activecoin) STRING_ARG(iguana,getconnectioncount,activecoin) { int32_t i,num = 0; char buf[512]; - if ( coin != 0 ) + if ( coin != 0 && coin->peers != 0 ) { - for (i=0; ipeers.active)/sizeof(*coin->peers.active); i++) - if ( coin->peers.active[i].usock >= 0 ) + for (i=0; ipeers->active)/sizeof(*coin->peers->active); i++) + if ( coin->peers->active[i].usock >= 0 ) num++; sprintf(buf,"{\"result\":\"%d\"}",num); return(clonestr(buf)); } else return(clonestr("{\"error\":\"getconnectioncount needs coin\"}")); } +ZERO_ARGS(bitcoinrpc,getdifficulty) +{ + char buf[512]; + if ( coin != 0 ) + { + sprintf(buf,"{\"result\":\"success\",\"proof-of-work\":\"%.8f\",\"search-interval\": 0}",PoW_from_compact(coin->blocks.hwmchain.RO.bits,coin->chain->unitval)); + return(clonestr(buf)); + } else return(clonestr("{\"error\":\"getdifficulty needs coin\"}")); +} + STRING_ARG(iguana,addcoin,newcoin) { char *symbol; int32_t retval; @@ -613,7 +604,7 @@ STRING_ARG(iguana,addcoin,newcoin) // if ( strcmp(symbol,"BTC") == 0 ) // return(clonestr("{\"result\":\"BTC for chrome app is not yet\"}")); #endif - if ( (retval= iguana_launchcoin(myinfo,symbol,json)) > 0 ) + if ( (retval= iguana_launchcoin(myinfo,symbol,json,0)) > 0 ) { if ( myinfo->rpcsymbol[0] == 0 ) safecopy(myinfo->rpcsymbol,symbol,sizeof(myinfo->rpcsymbol)); @@ -636,10 +627,12 @@ STRING_ARG(iguana,startcoin,activecoin) STRING_ARG(iguana,stopcoin,activecoin) { + if ( activecoin[0] != 0 ) + coin = iguana_coinfind(activecoin); if ( coin != 0 ) { coin->active = 0; - iguana_coinpurge(coin); + //iguana_coinpurge(coin); return(clonestr("{\"result\":\"coin stopped\"}")); } else return(clonestr("{\"error\":\"stopcoin needs coin\"}")); } @@ -655,15 +648,38 @@ STRING_ARG(iguana,pausecoin,activecoin) TWO_STRINGS(iguana,addnode,activecoin,ipaddr) { - struct iguana_peer *addr; + struct iguana_peer *addr; int32_t i,n; if ( coin == 0 ) coin = iguana_coinfind(activecoin); printf("coin.%p.[%s] addnode.%s -> %s\n",coin,coin!=0?coin->symbol:"",activecoin,ipaddr); - if ( coin != 0 && ipaddr != 0 && is_ipaddr(ipaddr) != 0 ) + if ( coin != 0 && coin->peers != 0 && ipaddr != 0 && is_ipaddr(ipaddr) != 0 ) { //iguana_possible_peer(coin,ipaddr); - if ( (addr= iguana_peerslot(coin,(uint32_t)calc_ipbits(ipaddr),0)) != 0 ) + if ( (addr= iguana_peerslot(coin,(uint32_t)calc_ipbits(ipaddr),1)) != 0 ) { + addr->supernet = 1; + if ( addr->usock >= 0 ) + { + if ( (n= coin->peers->numranked) != 0 ) + { + for (i=0; ipeers->ranked[i] ) + break; + } + if ( i == n ) + { + if ( i == IGUANA_MAXPEERS ) + i--; + else coin->peers->numranked = n+1; + coin->peers->ranked[i] = addr; + addr->recvblocks = coin->peers->ranked[0]->recvblocks + 100; + addr->recvtotal = coin->peers->ranked[0]->recvtotal*1.1 + 100; + printf("set (%s) -> slot.%d numranked.%d\n",ipaddr,i,coin->peers->numranked); + } else printf("(%s) is already peer.%d\n",ipaddr,i); + } + return(clonestr("{\"result\":\"peer was already connected\"}")); + } if ( addr->pending == 0 ) { addr->pending = (uint32_t)time(NULL); @@ -680,13 +696,13 @@ TWO_STRINGS(iguana,addnode,activecoin,ipaddr) TWO_STRINGS(iguana,persistent,activecoin,ipaddr) { int32_t i; - if ( coin != 0 && ipaddr != 0 ) + if ( coin != 0 && coin->peers != 0 && ipaddr != 0 ) { for (i=0; ipeers.active[i].ipaddr,ipaddr) == 0 ) + if ( strcmp(coin->peers->active[i].ipaddr,ipaddr) == 0 ) { - coin->peers.active[i].persistent_peer = juint(json,"interval")+3; + coin->peers->active[i].persistent_peer = juint(json,"interval")+3; return(clonestr("{\"result\":\"node marked as persistent\"}")); } } @@ -697,14 +713,14 @@ TWO_STRINGS(iguana,persistent,activecoin,ipaddr) TWO_STRINGS(iguana,removenode,activecoin,ipaddr) { int32_t i; - if ( coin != 0 && ipaddr != 0 ) + if ( coin != 0 && coin->peers != 0 && ipaddr != 0 ) { for (i=0; ipeers.active[i].ipaddr,ipaddr) == 0 ) + if ( strcmp(coin->peers->active[i].ipaddr,ipaddr) == 0 ) { - coin->peers.active[i].rank = 0; - coin->peers.active[i].dead = (uint32_t)time(NULL); + coin->peers->active[i].rank = 0; + coin->peers->active[i].dead = (uint32_t)time(NULL); return(clonestr("{\"result\":\"node marked as dead\"}")); } } @@ -724,11 +740,11 @@ TWO_STRINGS(iguana,oneshot,activecoin,ipaddr) TWO_STRINGS(iguana,nodestatus,activecoin,ipaddr) { int32_t i; struct iguana_peer *addr; - if ( coin != 0 && ipaddr != 0 ) + if ( coin != 0 && coin->peers != 0 && ipaddr != 0 ) { for (i=0; iMAXPEERS; i++) { - addr = &coin->peers.active[i]; + addr = &coin->peers->active[i]; if ( strcmp(addr->ipaddr,ipaddr) == 0 ) return(jprint(iguana_peerjson(coin,addr),1)); } @@ -739,7 +755,7 @@ TWO_STRINGS(iguana,nodestatus,activecoin,ipaddr) STRING_AND_INT(iguana,maxpeers,activecoin,max) { cJSON *retjson; int32_t i; struct iguana_peer *addr; - if ( coin != 0 ) + if ( coin != 0 && coin->peers != 0 ) { retjson = cJSON_CreateObject(); if ( max > IGUANA_MAXPEERS ) @@ -747,7 +763,7 @@ STRING_AND_INT(iguana,maxpeers,activecoin,max) if ( max > coin->MAXPEERS ) { for (i=max; iMAXPEERS; i++) - if ( (addr= coin->peers.ranked[i]) != 0 ) + if ( (addr= coin->peers->ranked[i]) != 0 ) addr->dead = 1; } coin->MAXPEERS = max; @@ -774,7 +790,7 @@ char *hmac_dispatch(char *(*hmacfunc)(char *dest,char *key,int32_t key_size,char char *hash_dispatch(void (*hashfunc)(char *hexstr,uint8_t *buf,uint8_t *msg,int32_t len),char *name,char *message) { - char hexstr[16384]; uint8_t databuf[8192]; cJSON *json; + char hexstr[65537]; uint8_t databuf[32768]; cJSON *json; if ( message != 0 && message[0] != 0 ) { memset(hexstr,0,sizeof(hexstr)); @@ -841,7 +857,7 @@ STRING_ARG(SuperNET,bitcoinrpc,setcoin) strcpy(myinfo->rpcsymbol,setcoin); touppercase(myinfo->rpcsymbol); printf("bitcoinrpc.%s\n",myinfo->rpcsymbol); - if ( iguana_launchcoin(myinfo,myinfo->rpcsymbol,json) < 0 ) + if ( iguana_launchcoin(myinfo,myinfo->rpcsymbol,json,0) < 0 ) return(clonestr("{\"error\":\"error creating coin\"}")); else { @@ -897,6 +913,7 @@ char *SuperNET_parser(struct supernet_info *myinfo,char *agentstr,char *method,c #define IGUANA_DISPATCH0(agent,name) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS)) #define IGUANA_DISPATCH_S(agent,name,str) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jstr(json,#str))) #define IGUANA_DISPATCH_SS(agent,name,str,str2) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jstr(json,#str),jstr(json,#str2))) +#define IGUANA_DISPATCH_ID(agent,name,dval,val) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jdouble(json,#dval),jdouble(json,#val))) #define IGUANA_DISPATCH_SD(agent,name,str,val) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jstr(json,#str),jdouble(json,#val))) #define IGUANA_DISPATCH_SSS(agent,name,str,str2,str3) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jstr(json,#str),jstr(json,#str2),jstr(json,#str3))) #define IGUANA_DISPATCH_SSSS(agent,name,str,str2,str3,str4) else if ( strcmp(#agent,agentstr) == 0 && strcmp(method,#name) == 0 ) return(agent ## _ ## name(IGUANA_ARGS,jstr(json,#str),jstr(json,#str2),jstr(json,#str3),jstr(json,#str4))) @@ -950,6 +967,7 @@ char *SuperNET_parser(struct supernet_info *myinfo,char *agentstr,char *method,c // API functions #define ZERO_ARGS IGUANA_DISPATCH0 #define INT_ARG IGUANA_DISPATCH_I +#define INT_AND_DOUBLE IGUANA_DISPATCH_ID #define TWO_INTS IGUANA_DISPATCH_II #define STRING_ARG IGUANA_DISPATCH_S #define TWO_STRINGS IGUANA_DISPATCH_SS diff --git a/iguana/iguana_mofn.c b/iguana/iguana_mofn.c new file mode 100755 index 000000000..51c82eee4 --- /dev/null +++ b/iguana/iguana_mofn.c @@ -0,0 +1,787 @@ + +/* + * This file is Copyright Daniel Silverstone 2006,2015 + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#include "iguana777.h" +#include "secp256k1/include/secp256k1.h" +#include "secp256k1/include/secp256k1_schnorr.h" +#include "secp256k1/include/secp256k1_rangeproof.h" + +// ------------------------------------------------------[ Preparation ]---- + +static gfshare_ctx *_gfshare_ctx_init_core(uint8_t *sharenrs,uint32_t sharecount,uint8_t threshold,uint32_t size,void *space,int32_t spacesize) +{ + gfshare_ctx *ctx; int32_t allocsize; + allocsize = (int32_t)(sizeof(struct _gfshare_ctx) + threshold * size); + if ( allocsize > spacesize ) + { + printf("malloc allocsize %d vs spacesize.%d\n",allocsize,spacesize); + ctx = malloc(allocsize); + if( ctx == NULL ) + return NULL; // errno should still be set from XMALLOC() + ctx->allocsize = allocsize; + } else ctx = space; + memset(ctx,0,allocsize); + ctx->sharecount = sharecount; + ctx->threshold = threshold; + ctx->size = size; + memcpy(ctx->sharenrs,sharenrs,sharecount); + ctx->buffersize = threshold * size; + return(ctx); +} + +// Initialise a gfshare context for producing shares +gfshare_ctx *gfshare_ctx_initenc(uint8_t *sharenrs,uint32_t sharecount,uint8_t threshold,uint32_t size,void *space,int32_t spacesize) +{ + uint32_t i; + for (i=0; ithreshold = 0; + return(ctx); +} + +// Free a share context's memory +void gfshare_ctx_free(gfshare_ctx *ctx) +{ + OS_randombytes(ctx->buffer,ctx->buffersize); + OS_randombytes(ctx->sharenrs,ctx->sharecount); + if ( ctx->allocsize != 0 ) + { + OS_randombytes((uint8_t *)ctx,sizeof(struct _gfshare_ctx)); + free(ctx); + } + OS_randombytes((uint8_t *)ctx,sizeof(struct _gfshare_ctx)); +} + +// --------------------------------------------------------[ Splitting ]---- + +// Provide a secret to the encoder. (this re-scrambles the coefficients) +void gfshare_ctx_enc_setsecret(gfshare_ctx *ctx,uint8_t *secret) +{ + memcpy(ctx->buffer + ((ctx->threshold-1) * ctx->size),secret,ctx->size); + OS_randombytes(ctx->buffer,(ctx->threshold-1) * ctx->size); +} + +// Extract a share from the context. 'share' must be preallocated and at least 'size' bytes long. 'sharenr' is the index into the 'sharenrs' array of the share you want. +void gfshare_ctx_encgetshare(uint8_t *_logs,uint8_t *_exps,gfshare_ctx *ctx,uint8_t sharenr,uint8_t *share) +{ + uint32_t pos,coefficient,ilog = _logs[ctx->sharenrs[sharenr]]; + uint8_t *share_ptr,*coefficient_ptr = ctx->buffer; + for (pos=0; possize; pos++) + share[pos] = *(coefficient_ptr++); + for (coefficient=1; coefficientthreshold; coefficient++) + { + share_ptr = share; + for (pos=0; possize; pos++) + { + uint8_t share_byte = *share_ptr; + if ( share_byte != 0 ) + share_byte = _exps[ilog + _logs[share_byte]]; + *share_ptr++ = share_byte ^ *coefficient_ptr++; + } + } +} + +// ----------------------------------------------------[ Recombination ]---- + +// Inform a recombination context of a change in share indexes +void gfshare_ctx_dec_newshares(gfshare_ctx *ctx,uint8_t *sharenrs) +{ + memcpy(ctx->sharenrs,sharenrs,ctx->sharecount); +} + +// Provide a share context with one of the shares. The 'sharenr' is the index into the 'sharenrs' array +void gfshare_ctx_dec_giveshare(gfshare_ctx *ctx,uint8_t sharenr,uint8_t *share) +{ + memcpy(ctx->buffer + (sharenr * ctx->size),share,ctx->size); +} + +// Extract the secret by interpolating the shares. secretbuf must be allocated and at least 'size' bytes +void gfshare_ctx_decextract(uint8_t *_logs,uint8_t *_exps,gfshare_ctx *ctx,uint8_t *secretbuf) +{ + uint32_t i,j; uint8_t *secret_ptr,*share_ptr,sharei,sharej; + for (i=0; isize; i++) + secretbuf[i] = 0; + for (i=0; isharecount; i++) + { + // Compute L(i) as per Lagrange Interpolation + unsigned Li_top = 0, Li_bottom = 0; + if ( (sharei= ctx->sharenrs[i]) != 0 ) + { + for (j=0; jsharecount; j++) + { + if ( i != j && sharei != (sharej= ctx->sharenrs[j]) ) + { + if ( sharej == 0 ) + continue; // skip empty share + Li_top += _logs[sharej]; + if ( Li_top >= 0xff ) + Li_top -= 0xff; + Li_bottom += _logs[sharei ^ sharej]; + if ( Li_bottom >= 0xff ) + Li_bottom -= 0xff; + } + } + if ( Li_bottom > Li_top ) + Li_top += 0xff; + Li_top -= Li_bottom; // Li_top is now log(L(i)) + secret_ptr = secretbuf, share_ptr = ctx->buffer + (ctx->size * i); + for (j=0; jsize; j++) + { + if ( *share_ptr != 0 ) + *secret_ptr ^= _exps[Li_top + _logs[*share_ptr]]; + share_ptr++, secret_ptr++; + } + } + } +} + +int32_t gfshare_test(struct supernet_info *myinfo,int32_t M,int32_t N,int32_t datasize) +{ + int ok = 1, i,k; + uint8_t * secret = malloc(datasize); + uint8_t *shares[255]; + uint8_t *recomb = malloc(datasize); + uint8_t space[8192],sharenrs[255],newsharenrs[255];// = (uint8_t *)strdup("0124z89abehtr"); + gfshare_ctx *G; + for (i=0; i> 8; + /* Stage 2, split it N ways with a threshold of M */ + G = gfshare_ctx_initenc( sharenrs, N, M, datasize,space,sizeof(space) ); + gfshare_ctx_enc_setsecret( G, secret ); + for (i=0; ilogs,myinfo->exps, G, i, shares[i] ); + gfshare_ctx_free( G ); + /* Prep the decode shape */ + uint8_t save[255]; + memcpy(save,sharenrs,sizeof(sharenrs)); + G = gfshare_ctx_initdec( sharenrs, N, datasize,space,sizeof(space) ); + for (k=0; k<10; k++) + { + memcpy(sharenrs,save,sizeof(sharenrs)); + memset(newsharenrs,0,N); + int32_t j,r,m; + m = M + (rand() % (N-M+1)); + for (i=0; ilogs,myinfo->exps, G, recomb ); + for (i=0; ictx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); + secp256k1_pedersen_context_initialize(myinfo->ctx); + secp256k1_rangeproof_context_initialize(myinfo->ctx); + for (i=0; i<255; i++) + { + _exps[i] = x; + _logs[x] = i; + x <<= 1; + if ( x & 0x100 ) + x ^= 0x11d; // Unset the 8th bit and mix in 0x1d + } + for (i=255; i<510; i++) + _exps[i] = _exps[i % 255]; + _logs[0] = 0; // can't log(0) so just set it neatly to 0 + if ( 0 ) + { + void test_mofn(struct supernet_info *myinfo); + gfshare_test(myinfo,6,11,32); + test_mofn(myinfo); + getchar(); + } +} + +// Construct and write out the tables for the gfshare code +int maingen(int argc,char **argv) +{ + uint8_t logs[256],exps[255]; uint32_t i; + libgfshare_init(0,logs,exps); + // The above generation algorithm clearly demonstrates that + // logs[exps[i]] == i for 0 <= i <= 254 + // exps[logs[i]] == i for 1 <= i <= 255 + // Spew out the tables + fprintf(stdout, "\ + /*\n\ + * This file is autogenerated by gfshare_maketable.\n\ + */\n\ + \n\ + static uint8_t logs[256] = {\n "); + for ( i = 0; i < 256; ++i ) + { + fprintf(stdout, "0x%02x", logs[i]); + if( i == 255 ) + fprintf(stdout, " };\n"); + else if( (i % 8) == 7 ) + fprintf(stdout, ",\n "); + else + fprintf(stdout, ", "); + } + // The exp table we output from 0 to 509 because that way when we + // do the lagrange interpolation we don't have to be quite so strict + // with staying inside the field which makes it quicker + fprintf(stdout, "\ + \n\ + static uint8_t exps[510] = {\n "); + for ( i = 0; i < 510; ++i ) + { + fprintf(stdout, "0x%02x", exps[i % 255]); /* exps[255]==exps[0] */ + if ( i == 509 ) + fprintf(stdout, " };\n"); + else if( (i % 8) == 7) + fprintf(stdout, ",\n "); + else + fprintf(stdout, ", "); + } + return 0; +} + +/****************************************************************************** + * Copyright © 2014-2016 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +int32_t init_sharenrs(uint8_t sharenrs[255],uint8_t *orig,int32_t m,int32_t n) +{ + uint8_t *randvals,valid[255]; + int32_t i,j,r,remains,orign; + if ( m > n || n >= 0xff ) // reserve 255 for illegal sharei + { + printf("illegal M.%d of N.%d\n",m,n); + return(-1); + } + randvals = calloc(1,65536); + OS_randombytes(randvals,65536); + if ( orig == 0 && n == m ) + { + memset(sharenrs,0,n); + for (i=0; i<255; i++) + valid[i] = (i + 1); + remains = orign = 255; + for (i=0; i= M ) + { + G = gfshare_ctx_initdec(recovernrs,N,datasize,space,sizeof(space)); + for (i=0; ilogs,myinfo->exps,G,recover); + gfshare_ctx_free(G); + return(recover); + } else return(0); +} + +void calc_share(struct supernet_info *myinfo,uint8_t *buffer,int32_t size,int32_t M,uint32_t ilog,uint8_t *share) +{ + uint32_t pos,coefficient; uint8_t *share_ptr,share_byte; + for (pos=0; posexps[ilog + myinfo->logs[share_byte]]; + *share_ptr++ = (share_byte ^ *buffer++); + } + } +} + +void calc_shares(struct supernet_info *myinfo,uint8_t *shares,uint8_t *secret,int32_t size,int32_t width,int32_t M,int32_t N,uint8_t *sharenrs,uint8_t *space,int32_t spacesize) +{ + int32_t i; uint8_t *buffer; + if ( M*width > spacesize ) + { + buffer = calloc(M,width); + printf("calloc M.%d width.%d\n",M,width); + } else buffer = space; + memset(shares,0,N * width); + memcpy(buffer + ((M - 1) * size),secret,size); + OS_randombytes(buffer,(M - 1) * size); + for (i=0; ilogs[sharenrs[i]],&shares[i * width]); + //printf("(%03d %08x) ",sharenrs[i],calc_crc32(0,&shares[i * width],size)); + } + if ( buffer != space ) + free(buffer); +} + +int32_t calc_sharenrs(uint8_t *sharenrs,int32_t N,uint8_t *data,int32_t datasize) +{ + bits256 hash,hash2; uint8_t r; int32_t i,j,n = sizeof(hash); + vcalc_sha256(0,hash.bytes,data,datasize); + vcalc_sha256(0,hash2.bytes,hash.bytes,sizeof(hash)); + for (i=0; i= sizeof(hash) ) + { + vcalc_sha256(0,hash.bytes,hash2.bytes,sizeof(hash2)); + vcalc_sha256(0,hash2.bytes,hash.bytes,sizeof(hash)); + n = 0; + } + r = hash2.bytes[n++]; + if ( (sharenrs[i]= r) == 0 || sharenrs[i] == 0xff ) + continue; + for (j=0; j N || N == 0 || N == 0xff ) + return(0); + allocsize = mofn256_size(M,N); + if ( allocsize > spacesize ) + { + mofn = calloc(1,allocsize); + mofn->allocsize = allocsize; + } + else + { + mofn = (void *)space; + memset(mofn,0,allocsize); + } + mofn->M = M; + mofn->N = N; + mofn->sharenrs = (void *)&mofn->allshares[N]; + if ( calcflag != 0 ) + { + mofn->secret = secret; + calcmofn(myinfo,mofn->allshares[0].bytes,mofn->sharenrs,M,secret.bytes,sizeof(secret),N); + } + return(mofn); +} + +bits256 mofn256_recover(struct supernet_info *myinfo,struct mofn256_info *mofn) +{ + uint8_t *shares[255]; bits256 recover; int32_t i; + for (i=0; iN; i++) + { + if ( bits256_nonz(mofn->allshares[i]) != 0 ) + shares[i] = mofn->allshares[i].bytes; + else shares[i] = 0; + } + if ( recoverdata(myinfo,shares,mofn->sharenrs,mofn->M,recover.bytes,sizeof(recover),mofn->N) == 0 ) + memset(recover.bytes,0,sizeof(recover)); + return(recover); +} + +int32_t test_mofn256(struct supernet_info *myinfo,int32_t M,int32_t N) +{ + uint8_t space[8192]; char str[65],str2[65]; struct mofn256_info *mofn,*cmp; bits256 secret,recover; int32_t i,allocsize,retval,m = 0; + allocsize = mofn256_size(M,N); + cmp = mofn256_init(myinfo,GENESIS_PUBKEY,M,N,0,space,sizeof(space)); + secret = rand256(0); + mofn = mofn256_init(myinfo,secret,M,N,1,&space[allocsize],sizeof(space) - allocsize); + memcpy(cmp->sharenrs,mofn->sharenrs,mofn->N); + for (i=0; iallshares[i] = mofn->allshares[i], m++; + recover = mofn256_recover(myinfo,cmp); + retval = -1 * (bits256_cmp(recover,mofn->secret) != 0); + if ( bits256_cmp(recover,mofn->secret) != 0 ) + { + if ( m >= M ) + printf("%s %s error m.%d vs M.%d N.%d\n",bits256_str(str,secret),bits256_str(str2,recover),m,mofn->M,mofn->N); + } + if ( ((long)mofn - (long)space) >= sizeof(space) || ((long)mofn - (long)space) < 0 ) + free(mofn); + if ( ((long)cmp - (long)space) >= sizeof(space) || ((long)cmp - (long)space) < 0 ) + free(cmp); + return(retval); +} + +#define N 11 +#define M 6 +void test_mofn(struct supernet_info *myinfo) +{ + bits256 allshares[N],secret,recover; uint8_t *shares[N],sharenrs[N]; int32_t i,j,m; + secret = rand256(0); + srand(secret.uints[0]); + calcmofn(myinfo,allshares[0].bytes,sharenrs,M,secret.bytes,sizeof(secret),N); + for (i=0; i<10000; i++) + { + memset(shares,0,sizeof(shares)); + for (j=m=0; jbytes,pubkey33+1,32); + break; + } + } + if ( j == maxj ) + { + printf("couldnt generate even noncepair\n"); + exit(-1); + } + return(privnonce); +} + +struct schnorr_info +{ + bits256 msg256,privkey,pubkey,privnonce,pubnonce,serhash2; + int32_t M,N; uint32_t msgid; + uint8_t sig64[64],combinedsig64[64],allpub[33],combined_allpub[33]; + uint16_t ind,nonz; + bits256 *pubkeys,*pubnonces; + uint8_t serialized[65 + sizeof(uint16_t) + sizeof(uint32_t) + sizeof(bits256)*4]; + uint8_t sigs[]; +}; + +int32_t schnorr_rwinitdata(int32_t rwflag,uint8_t *serialized,uint16_t *indp,uint32_t *msgidp,bits256 hashes[4]) +{ + int32_t i,j,len = 0; + len += iguana_rwnum(rwflag,&serialized[len],sizeof(*indp),indp); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(*msgidp),msgidp); + for (j=0; j<4; j++) + for (i=0; i<32; i++) + iguana_rwnum(rwflag,&serialized[len++],1,&hashes[j].bytes[i]); + return(len); +} + +struct schnorr_info *schnorr_init(struct supernet_info *myinfo,uint32_t msgid,uint16_t ind,int32_t M,int32_t N,void *space,int32_t spacesize,bits256 msg256) +{ + uint8_t *serialized; bits256 hashes[4]; int32_t len,odd_even = 0; struct schnorr_info *si = space; + si->pubnonces = (void *)&si->sigs[N * 64]; + si->pubkeys = &si->pubnonces[N]; + si->M = M; + si->N = N; + si->ind = ind; + si->msgid = msgid; + si->msg256 = msg256; + si->pubkey = bitcoin_pub256(myinfo->ctx,&si->privkey,odd_even); + si->privnonce = iguana_schnorr_noncepair(myinfo->ctx,&si->pubnonce,odd_even,msg256,si->privkey,100); + len = 0; + serialized = &si->serialized[65]; + hashes[0] = myinfo->myaddr.persistent; + hashes[1] = si->pubkey; + hashes[2] = si->pubnonce; + hashes[3] = msg256; + len = schnorr_rwinitdata(1,serialized,&ind,&msgid,hashes); + blockhash_sha256(si->serhash2.bytes,serialized,len); + if ( bitcoin_sign(myinfo->ctx,"SCHNORR",si->serialized,si->serhash2,myinfo->persistent_priv,1) != 65 ) + printf("error signing schnorr initdata\n"); + return(si); +} + +int32_t schnorr_update(struct supernet_info *myinfo,struct schnorr_info *si,uint8_t *serialized,int32_t recvlen) +{ + int32_t len; uint16_t ind; uint32_t msgid; bits256 hashes[4]; + // verify compact sig + len = schnorr_rwinitdata(0,&serialized[65],&ind,&msgid,hashes); + // verify persistent pubkey matches ind + if ( bits256_cmp(hashes[3],si->msg256) == 0 && msgid == si->msgid && bits256_nonz(si->pubkeys[ind]) == 0 && bits256_nonz(si->pubnonces[ind]) == 0 ) + { + si->pubkeys[ind] = hashes[1]; + si->pubnonces[ind] = hashes[2]; + if ( ++si->nonz >= si->M ) + { + iguana_schnorr_peersign(myinfo->ctx,si->allpub,si->sig64,si->ind,si->privkey,si->privnonce,si->pubnonces,si->M,si->msg256); + // broadcast si->sig64 + ind + msgid + } + } + return(si->M); +} + +/*{ + if ( bitcoin_schnorr_combine(myinfo->ctx,si->combinedsig64,si->combined_allpub,si->sigs,si->M,si->msg256) < 0 ) + printf("error combining k.%d sig64 iter.%d\n",k,iter); + if ( bitcoin_schnorr_verify(myinfo->ctx,si->combinedsig64,si->msg256,si->combined_allpub,33) < 0 ) + printf("allpub2 error verifying combined sig k.%d\n",k); +}*/ + +void iguana_schnorr(struct supernet_info *myinfo) +{ + uint8_t allpubs[256][33],allpub[33],allpub2[33],sig64s[256][64],sig64[64],*sigs[256]; bits256 msg256,privnonces[256],signers,privkeys[256],pubkeys[256],pubkeysB[256],nonces[256]; int32_t i,iter,n,k,maxj = 100; + OS_randombytes((void *)&n,sizeof(n)); + srand(n); + n = 1 + (rand() % 255); + // generate onetime keypairs + for (i=0; ictx,&privkeys[i],0); + msg256 = rand256(0); + for (i=0; ictx,&nonces[i],0,msg256,privkeys[i],maxj); + for (i=0; ictx,allpubs[i],sig64s[i],i,privkeys[i],privnonces[i],nonces,n,msg256); + for (iter=0; iter<1; iter++) + { + memset(signers.bytes,0,sizeof(signers)); + for (i=k=0; ictx,sig64,allpub2,sigs,k,msg256) < 0 ) + printf("error combining k.%d sig64 iter.%d\n",k,iter); + else if ( bitcoin_schnorr_verify(myinfo->ctx,sig64,msg256,allpub2,33) < 0 ) + printf("allpub2 error verifying combined sig k.%d\n",k); + else if ( 0 ) // doesnt replicate with subsets + { + if ( bitcoin_pubkey_combine(myinfo->ctx,allpub,0,pubkeys,n,0,0) == 0 ) + { + if ( memcmp(allpub,allpubs[0],33) != 0 ) + { + printf("\n"); + for (k=0; k<33; k++) + printf("%02x",allpubs[0][k]); + printf(" combined\n"); + for (k=0; k<33; k++) + printf("%02x",allpub[k]); + printf(" allpub, "); + printf("allpub mismatch iter.%d i.%d n.%d\n",iter,i,n); + } else printf("validated iter.%d k.%d %llx\n",iter,k,(long long)signers.txid); + } //else printf("error combining\n"); + } else printf("passed n.%d\n",n); + } +} diff --git a/iguana/iguana_msg.c b/iguana/iguana_msg.c index e21f5e8ff..8db7a25b9 100755 --- a/iguana/iguana_msg.c +++ b/iguana/iguana_msg.c @@ -41,7 +41,7 @@ int32_t iguana_rwversion(int32_t rwflag,uint8_t *serialized,struct iguana_msgver len += iguana_rwaddr(rwflag,&serialized[len],&msg->addrTo,MIN_PROTO_VERSION); len += iguana_rwaddr(rwflag,&serialized[len],&msg->addrFrom,MIN_PROTO_VERSION); len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->nonce),&msg->nonce); - len += iguana_rwstr(rwflag,&serialized[len],sizeof(msg->strSubVer),msg->strSubVer); + len += iguana_rwvarstr(rwflag,&serialized[len],sizeof(msg->strSubVer),msg->strSubVer); len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->nStartingHeight),&msg->nStartingHeight); if ( readsize == 117 ) { @@ -53,43 +53,144 @@ int32_t iguana_rwversion(int32_t rwflag,uint8_t *serialized,struct iguana_msgver len += iguana_rwnum(rwflag,&serialized[len],sizeof(wCtPort),&wCtPort); len += iguana_rwnum(rwflag,&serialized[len],sizeof(wPrPort),&wPrPort); /*int iVer = BitNet_Version; - unsigned short wPort = GetListenPort(); - unsigned char bIsGui = 0; // 2014.12.18 add - unsigned short wCtPort = 0; - unsigned short wPrPort = 0; - vRecv >> iVer; - pfrom->vBitNet.v_iVersion = iVer; - vRecv >> pfrom->vBitNet.; - if (!vRecv.empty()){ vRecv >> pfrom->vBitNet.v_ListenPort; } - if (!vRecv.empty()){ vRecv >> pfrom->vBitNet.v_IsGuiNode; } //-- 2014.12.18 add - if (!vRecv.empty()){ vRecv >> pfrom->vBitNet.v_iVpnServiceCtrlPort; } //-- 2014.12.28 add - if (!vRecv.empty()){ vRecv >> pfrom->vBitNet.v_P2P_proxy_port; } //-- 2014.12.28 add - */ + unsigned short wPort = GetListenPort(); + unsigned char bIsGui = 0; // 2014.12.18 add + unsigned short wCtPort = 0; + unsigned short wPrPort = 0; + vRecv >> iVer; + pfrom->vBitNet.v_iVersion = iVer; + vRecv >> pfrom->vBitNet.; + if (!vRecv.empty()){ vRecv >> pfrom->vBitNet.v_ListenPort; } + if (!vRecv.empty()){ vRecv >> pfrom->vBitNet.v_IsGuiNode; } //-- 2014.12.18 add + if (!vRecv.empty()){ vRecv >> pfrom->vBitNet.v_iVpnServiceCtrlPort; } //-- 2014.12.28 add + if (!vRecv.empty()){ vRecv >> pfrom->vBitNet.v_P2P_proxy_port; } //-- 2014.12.28 add + */ printf("iVer.%d v_Network_id.%d wPort.%u bIsGui.%d wCtPort.%u wPrPort.%u\n",iVer,v_Network_id,wPort,bIsGui,wCtPort,wPrPort); len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->relayflag),&msg->relayflag); } - else if ( msg->nVersion > 70000 ) + else if ( msg->nVersion > 70002 ) len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->relayflag),&msg->relayflag); //if ( rwflag == 0 ) //printf("readsize.%d %-15s v.%llu srv.%llx %u ht.%llu [%s].R%d nonce.%llx\n",readsize,ipaddr,(long long)msg->nVersion,(long long)msg->nServices,(uint32_t)msg->nTime,(long long)msg->nStartingHeight,msg->strSubVer,msg->relayflag,(long long)msg->nonce); - // 6e ea 00 00 01 00 00 00 00 00 00 00 86 5f a8 56 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff ff b5 2f b7 bc c6 83 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff ff 67 e5 7e c2 07 80 00 00 00 00 00 00 00 00 10 2f 42 69 74 4e 65 74 3a 31 2e 31 2e 33 2e 32 2f 92 d0 09 00 6c 04 00 00 01 00 00 00 80 07 01 9a 03 9b 03 01 return(len); } -// 06000000996da490f6151ad9d05d9defc99bda58441d2b833c0da69d11e764d7c70a00003378a650b506a66b41097a0b513f2fee899788711bc6643ff976ce6dbb0b620c5f800854ffff0f1e0004de0301010000005e800854010000000000000000000000000000000000000000000000000000000000000000ffffffff03510102ffffffff0100008a5d784563011976a9145166e6e52de58dfacb18670c0030aedcf295233988ac000000000000 +int32_t iguana_rwmerklebranch(int32_t rwflag,uint8_t *serialized,struct iguana_msgmerkle *msg) +{ + int32_t i,len = 0; + len += iguana_rwvarint32(rwflag,&serialized[len],&msg->branch_length); + if ( msg->branch_length < sizeof(msg->branch_hash)/sizeof(*msg->branch_hash) ) + { + for (i=0; ibranch_length; i++) + { + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->branch_hash[i]),msg->branch_hash[i].bytes); + } + } else return(1000000); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->branch_side_mask),&msg->branch_side_mask); + //printf("branch_length.%d side_mask.%x\n",msg->branch_length,msg->branch_side_mask); + return(len); +} -int32_t iguana_rwblock(int32_t rwflag,bits256 *hash2p,uint8_t *serialized,struct iguana_msgblock *msg) +int32_t iguana_rwzsolution(int32_t rwflag,uint8_t *serialized,uint32_t *solution,int32_t n) { - int32_t len = 0; char blockhash[65]; uint64_t x; + int32_t i,len = 0; + for (i=0; iH.version),&msg->H.version); len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->H.prev_block),msg->H.prev_block.bytes); len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->H.merkle_root),msg->H.merkle_root.bytes); len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->H.timestamp),&msg->H.timestamp); len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->H.bits),&msg->H.bits); - len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->H.nonce),&msg->H.nonce); - *hash2p = bits256_doublesha256(blockhash,serialized,len); - // char str[65]; printf("len.%d: block version.%d timestamp.%u bits.%x nonce.%u prev.(%s) %llx blockhash.(%s) %llx\n",len,msg->H.version,msg->H.timestamp,msg->H.bits,msg->H.nonce,bits256_str(str,msg->H.prev_block),(long long)msg->H.merkle_root.txid,blockhash,(long long)hash2p->txid); - if ( rwflag != 0 ) + if ( zcash == 0 ) + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->H.nonce),&msg->H.nonce); + else + { + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->zH.bignonce),msg->zH.bignonce.bytes); + //char str[65]; printf("prev.(%s) len.%d [%d %d %d]\n",bits256_str(str,msg->H.prev_block),len,serialized[len],serialized[len+1],serialized[len+2]); + if ( rwflag != 0 ) + tmp = msg->zH.numelements; + len += iguana_rwvarint32(rwflag,&serialized[len],(uint32_t *)&tmp); + if ( rwflag == 0 ) + msg->zH.numelements = tmp; + if ( msg->zH.numelements != ZCASH_SOLUTION_ELEMENTS ) + { + int32_t i; for (i=0; i<157; i++) + printf("%02x",serialized[i]); + printf(" unexpected ZCASH_SOLUTION_ELEMENTS, got %d vs %d len.%d\n",msg->zH.numelements,ZCASH_SOLUTION_ELEMENTS,len); + return(-1); + } + len += iguana_rwzsolution(rwflag,&serialized[len],msg->zH.solution,ZCASH_SOLUTION_ELEMENTS); + } + return(len); +} + +int32_t iguana_eatauxpow(int32_t rwflag,char *symbol,uint8_t zcash,uint8_t *serialized,int32_t maxlen) +{ + int32_t len = 0; void *ptr; struct iguana_msgtx msg; struct OS_memspace MEM; bits256 auxhash2,coinbasetxid; struct iguana_msgmerkle *coinbase_branch,*blockchain_branch; struct iguana_msgblock parentblock; struct iguana_info *coin; + if ( rwflag == 0 && (coin= iguana_coinfind(symbol)) != 0 && coin->chain->auxpow != 0 ) + { + memset(&msg,0,sizeof(msg)); + coinbase_branch = calloc(1,sizeof(*coinbase_branch)); + blockchain_branch = calloc(1,sizeof(*blockchain_branch)); + memset(&parentblock,0,sizeof(parentblock)); + memset(&MEM,0,sizeof(MEM)); + ptr = calloc(1,1000000); + iguana_meminit(&MEM,"auxpow",ptr,1000000,0); + len += iguana_rwtx(coin->chain->zcash,rwflag,&MEM,&serialized[len],&msg,(int32_t)MEM.totalsize,&coinbasetxid,coin->chain->isPoS,0); + if ( len > maxlen ) + return(-1); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(auxhash2),auxhash2.bytes); + if ( len > maxlen ) + return(-1); + len += iguana_rwmerklebranch(rwflag,&serialized[len],coinbase_branch); + if ( len > maxlen ) + return(-1); + len += iguana_rwmerklebranch(rwflag,&serialized[len],blockchain_branch); + if ( len > maxlen ) + return(-1); + len += iguana_rwblockhdr(rwflag,zcash,&serialized[len],&parentblock); + if ( len > maxlen ) + return(-1); + free(ptr); + free(coinbase_branch); + free(blockchain_branch); + } + return(len); +} + +int32_t iguana_blockhdrsize(char *symbol,uint8_t zcash,uint8_t auxpow)//,uint8_t *serialized,int32_t maxlen) +{ + int32_t len = 0; + if ( zcash == 0 ) + { + if ( auxpow == 0 ) + return(sizeof(struct iguana_msgblockhdr)); + //if ( (len= iguana_eatauxpow(0,symbol,&serialized[sizeof(struct iguana_msgblockhdr)],(int32_t)(maxlen-sizeof(struct iguana_msgblockhdr)))) > 0 ) + return(sizeof(struct iguana_msgblockhdr) + len); + //else + return(-1); + } else return((int32_t)(sizeof(struct iguana_msgblockhdr) - sizeof(uint32_t) + sizeof(struct iguana_msgblockhdr_zcash) + auxpow*sizeof(bits256))); +} + +int32_t iguana_rwblock(char *symbol,uint8_t zcash,uint8_t auxpow,int32_t (*hashalgo)(uint8_t *blockhashp,uint8_t *serialized,int32_t len),int32_t rwflag,bits256 *hash2p,uint8_t *serialized,struct iguana_msgblock *msg,int32_t maxlen) +{ + int32_t len = 0; uint64_t x; + if ( (len= iguana_rwblockhdr(rwflag,zcash,serialized,msg)) < 0 ) + { + printf("error rw.%d blockhdr zcash.%d\n",rwflag,zcash); + return(-1); + } + *hash2p = iguana_calcblockhash(symbol,hashalgo,serialized,len); + //char str[65],str2[65]; printf("zcash.%d len.%d: block version.%d timestamp.%u bits.%x nonce.%u prev.(%s) %llx hash2.%s\n",zcash,len,msg->H.version,msg->H.timestamp,msg->H.bits,msg->H.nonce,bits256_str(str,msg->H.prev_block),(long long)msg->H.merkle_root.txid,bits256_str(str2,*hash2p)); + if ( auxpow != 0 && (msg->H.version & 0x100) != 0 ) + len += iguana_eatauxpow(rwflag,symbol,zcash,&serialized[len],maxlen-len); + if ( rwflag == 1 ) x = msg->txn_count; len += iguana_rwvarint(rwflag,&serialized[len],&x); if ( rwflag == 0 ) @@ -104,18 +205,30 @@ int32_t iguana_rwblock(int32_t rwflag,bits256 *hash2p,uint8_t *serialized,struct return(len); } -int32_t iguana_serialize_block(bits256 *hash2p,uint8_t serialized[sizeof(struct iguana_msgblock)],struct iguana_block *block) +int32_t iguana_serialize_block(struct iguana_chain *chain,bits256 *hash2p,uint8_t serialized[sizeof(struct iguana_msgblock)],struct iguana_block *block) { - struct iguana_msgblock msg; + struct iguana_msgblock msg; int32_t i,len; memset(&msg,0,sizeof(msg)); msg.H.version = block->RO.version; msg.H.prev_block = block->RO.prev_block; msg.H.merkle_root = block->RO.merkle_root; msg.H.timestamp = block->RO.timestamp; msg.H.bits = block->RO.bits; - msg.H.nonce = block->RO.nonce; + if ( chain->zcash == 0 ) + msg.H.nonce = block->RO.nonce; + else + { + if ( block->RO.allocsize == sizeof(struct iguana_zblock) ) + { + msg.zH.bignonce = block->zRO[0].bignonce; + msg.zH.numelements = ZCASH_SOLUTION_ELEMENTS; + for (i=0; izRO[0].solution[i]; + } else printf("iguana_serialize_block has missing zRO\n"); + } msg.txn_count = block->RO.txn_count; - return(iguana_rwblock(1,hash2p,serialized,&msg)); + len = iguana_rwblock(chain->symbol,chain->zcash,chain->auxpow,chain->hashalgo,1,hash2p,serialized,&msg,IGUANA_MAXPACKETSIZE); + return(len); } int32_t iguana_rwblockhash(int32_t rwflag,uint8_t *serialized,uint32_t *nVersionp,uint32_t *varintp,bits256 *hashes,bits256 *stophash) @@ -135,67 +248,121 @@ int32_t iguana_rwblockhash(int32_t rwflag,uint8_t *serialized,uint32_t *nVersion return(len); } -/*int32_t iguana_request_data(struct iguana_info *coin,struct iguana_peer *addr,bits256 *hashes,int32_t n,uint32_t type,int32_t forceflag) +int32_t iguana_rwmsgalert(struct iguana_info *coin,int32_t rwflag,uint8_t *serialized,struct iguana_msgalert *msg) { - uint32_t len,i; uint8_t serialized[sizeof(struct iguana_msghdr) + (sizeof(uint32_t) + sizeof(bits256))*32 + sizeof(uint64_t)]; - if ( addr == 0 ) - return(-1); - len = iguana_rwvarint32(1,&serialized[sizeof(struct iguana_msghdr)],(uint32_t *)&n); - for (i=0; iversion),&msg->version); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->relayuntil),&msg->relayuntil); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->expiration),&msg->expiration); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->ID),&msg->ID); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->cancel),&msg->cancel); + len += iguana_rwvarint32(rwflag,&serialized[len],&msg->numcancellist); + if ( msg->numcancellist != 0 ) { - len += iguana_rwnum(1,&serialized[sizeof(struct iguana_msghdr) + len],sizeof(uint32_t),&type); - len += iguana_rwbignum(1,&serialized[sizeof(struct iguana_msghdr) + len],sizeof(bits256),hashes[i].bytes); + for (i=0; inumcancellist; i++) + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->version),&msg->list[i]); } - //printf("iguana_request_data.%d %s ht.%d\n",n,bits256_str(hashes[0]),iguana_height(coin,hashes[0])); - addr->getdatamillis = milliseconds(); - len = iguana_queue_send(coin,addr,0,serialized,"getdata",len,iguana_height(coin,hashes[n-1]),forceflag); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->minver),&msg->minver); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->maxver),&msg->maxver); + len += iguana_rwvarint32(rwflag,&serialized[len],&msg->setsubvervar); + len += iguana_rwvarstr(rwflag,&serialized[len],sizeof(msg->subver),msg->subver); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->priority),&msg->priority); + len += iguana_rwvarstr(rwflag,&serialized[len],sizeof(msg->comment),msg->comment); + len += iguana_rwvarstr(rwflag,&serialized[len],sizeof(msg->statusbar),msg->statusbar); + len += iguana_rwvarstr(rwflag,&serialized[len],sizeof(msg->reserved),msg->reserved); + alerthash2 = bits256_doublesha256(0,serialized,len); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->siglen),&msg->siglen); + if ( msg->siglen >= 70 && msg->siglen < 74 ) + { + if ( rwflag == 0 ) + memcpy(msg->sig,&serialized[len],msg->siglen); + else memcpy(&serialized[len],msg->sig,msg->siglen); + len += msg->siglen; + plen = bitcoin_pubkeylen(coin->chain->alertpubkey); + isvalid = (bitcoin_verify(coin->ctx,msg->sig,msg->siglen,alerthash2,coin->chain->alertpubkey,plen) == 0); + for (i=0; isiglen; i++) + printf("%02x",msg->sig[i]); + printf(" %s\n",isvalid != 0 ? "VALIDSIG" : "SIGERROR"); + for (i=0; ichain->alertpubkey[i]); + char str[65]; printf(" alertpubkey.%d, alerthash2.%s\n",plen,bits256_str(str,alerthash2)); + } else msg->siglen = 0; + printf(" ALERT v.%d relay.%lld expires.%lld ID.%d cancel.%d numlist.%d minver.%d maxver.%d subver.(%s) priority.%d comment.(%s) STATUS.(%s) reserved.(%s)\n",msg->version,(long long)msg->relayuntil,(long long)msg->expiration,msg->ID,msg->cancel,msg->numcancellist,msg->minver,msg->maxver,msg->subver,msg->priority,msg->comment,msg->statusbar,msg->reserved); return(len); -}*/ +} + +/*int32_t iguana_request_data(struct iguana_info *coin,struct iguana_peer *addr,bits256 *hashes,int32_t n,uint32_t type,int32_t forceflag) + { + uint32_t len,i; uint8_t serialized[sizeof(struct iguana_msghdr) + (sizeof(uint32_t) + sizeof(bits256))*32 + sizeof(uint64_t)]; + if ( addr == 0 ) + return(-1); + len = iguana_rwvarint32(1,&serialized[sizeof(struct iguana_msghdr)],(uint32_t *)&n); + for (i=0; igetdatamillis = milliseconds(); + len = iguana_queue_send(addr,0,serialized,"getdata",len,iguana_height(coin,hashes[n-1]),forceflag); + return(len); + }*/ -void iguana_gotversion(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_msgversion *vers) +void iguana_gotversion(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,struct iguana_msgversion *vers) { - uint8_t serialized[sizeof(struct iguana_msghdr)]; - //printf("gotversion from %s: starting height.%d services.%llx proto.%d\n",addr->ipaddr,vers->nStartingHeight,(long long)vers->nServices,vers->nVersion); - if ( (vers->nServices & NODE_NETWORK) != 0 )//&& vers->nonce != coin->instance_nonce ) + uint8_t serialized[sizeof(struct iguana_msghdr)]; char *retstr; + //printf("gotversion from %s: starting height.%d services.%llx proto.%d (%s)\n",addr->ipaddr,vers->nStartingHeight,(long long)vers->nServices,vers->nVersion,vers->strSubVer); + if ( 0 && strncmp(vers->strSubVer,"/iguana",strlen("/iguana")) == 0 ) + { + addr->supernet = 1, addr->basilisk = 0; + if ( (retstr= basilisk_addrelay_info(myinfo,0,(uint32_t)addr->ipbits,GENESIS_PUBKEY)) != 0 ) + free(retstr); + } + else if ( strncmp(vers->strSubVer,"/basilisk",strlen("/basilisk")) == 0 ) + addr->basilisk = 1, addr->supernet = 0; + if ( (vers->nServices & NODE_NETWORK) != 0 ) { addr->protover = (vers->nVersion < PROTOCOL_VERSION) ? vers->nVersion : PROTOCOL_VERSION; + //printf("(%s) proto.%d -> %d\n",addr->ipaddr,vers->nVersion,addr->protover); addr->relayflag = vers->relayflag; addr->height = vers->nStartingHeight; addr->relayflag = 1; iguana_gotdata(coin,addr,addr->height); - iguana_queue_send(coin,addr,0,serialized,"verack",0,0,0); + iguana_queue_send(addr,0,serialized,"verack",0); //iguana_send_ping(coin,addr); } - else if ( (vers->nServices & (1<<7)) == 0 ) + else if ( 0 && addr->supernet == 0 && addr->basilisk == 0 )//|| (addr->basilisk != 0 && myinfo->IAMRELAY == 0) ) addr->dead = (uint32_t)time(NULL); - if ( (vers->nServices & (1<<7)) == (1<<7) ) - addr->supernet = 1; - if ( addr->supernet != 0 ) - printf("height.%d nServices.%lld nonce.%llu %srelay node.(%s) supernet.%d\n",vers->nStartingHeight,(long long)vers->nServices,(long long)vers->nonce,addr->relayflag==0?"non-":"",addr->ipaddr,addr->supernet); + if ( addr->supernet != 0 || addr->basilisk != 0 ) + printf("height.%d nServices.%lld nonce.%llu %srelay node.(%s) supernet.%d basilisk.%d longest.%u\n",vers->nStartingHeight,(long long)vers->nServices,(long long)vers->nonce,addr->relayflag==0?"non-":"",addr->ipaddr,addr->supernet,addr->basilisk,vers->nStartingHeight); if ( (int32_t)vers->nStartingHeight > coin->longestchain ) { if ( coin->badlongestchain != 0 && (int32_t)vers->nStartingHeight >= coin->badlongestchain ) { printf("peer.(%s) gives badlongestchain.%d\n",addr->ipaddr,vers->nStartingHeight); addr->dead = 1; - } else coin->longestchain = vers->nStartingHeight; + } //else coin->longestchain = vers->nStartingHeight; } - iguana_queue_send(coin,addr,0,serialized,"getaddr",0,0,0); + iguana_queue_send(addr,0,serialized,"getaddr",0); } int32_t iguana_send_version(struct iguana_info *coin,struct iguana_peer *addr,uint64_t myservices) { int32_t len; struct iguana_msgversion msg; uint8_t serialized[sizeof(struct iguana_msghdr)+sizeof(msg)]; memset(&msg,0,sizeof(msg)); - msg.nVersion = PROTOCOL_VERSION; - msg.nServices = myservices; + msg.nVersion = coin->chain->protover;//PROTOCOL_VERSION; + msg.nServices = (myservices & NODE_NETWORK); msg.nTime = (int64_t)time(NULL); msg.nonce = coin->instance_nonce; - sprintf(msg.strSubVer,"/Satoshi:0.10.0/"); + if ( coin->FULLNODE != 0 || coin->VALIDATENODE != 0 ) + sprintf(msg.strSubVer,"/iguana 0.00/"); + else sprintf(msg.strSubVer,"/basilisk 0.00/"); + //printf("SEND.(%s) -> (%s)\n",msg.strSubVer,addr->ipaddr); + //sprintf(msg.strSubVer,"/Satoshi:0.10.0/"); msg.nStartingHeight = coin->blocks.hwmchain.height; iguana_gotdata(coin,addr,msg.nStartingHeight); len = iguana_rwversion(1,&serialized[sizeof(struct iguana_msghdr)],&msg,addr->ipaddr,0); - return(iguana_queue_send(coin,addr,0,serialized,"version",len,0,1)); + return(iguana_queue_send(addr,0,serialized,"version",len)); } int32_t iguana_send_VPNversion(struct iguana_info *coin,struct iguana_peer *addr,uint64_t myservices) @@ -203,28 +370,38 @@ int32_t iguana_send_VPNversion(struct iguana_info *coin,struct iguana_peer *addr int32_t len; struct iguana_VPNversion msg; uint8_t serialized[sizeof(struct iguana_msghdr)+sizeof(msg)]; memset(&msg,0,sizeof(msg)); msg.nVersion = PROTOCOL_VERSION; - msg.nServices = myservices; + msg.nServices = (myservices & NODE_NETWORK); msg.nTime = (int64_t)time(NULL); msg.nonce = 0;//coin->instance_nonce; - sprintf(msg.strSubVer,"/Satoshi:0.11.99/"); + if ( coin->FULLNODE != 0 || coin->VALIDATENODE != 0 ) + sprintf(msg.strSubVer,"/iguana 0.00/"); + else sprintf(msg.strSubVer,"/basilisk 0.00/"); msg.nStartingHeight = coin->blocks.hwmchain.height; len = iguana_rwversion(1,&serialized[sizeof(struct iguana_msghdr)],(void *)&msg,addr->ipaddr,117); - return(iguana_queue_send(coin,addr,0,serialized,"version",len,0,1)); + return(iguana_queue_send(addr,0,serialized,"version",len)); } -void iguana_gotverack(struct iguana_info *coin,struct iguana_peer *addr) +void iguana_supernet_ping(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr) +{ + if ( addr->supernet != 0 || addr->basilisk != 0 ) + { + //if ( coin->FULLNODE != 0 ) + // basilisk_relays_send(myinfo,addr); + //printf("send getpeers to %s\n",addr->ipaddr); + //printf("maybe send basilisk ping here?\n"); + //iguana_send_supernet(addr,SUPERNET_GETPEERSTR,0); + } +} + +void iguana_gotverack(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr) { uint8_t serialized[sizeof(struct iguana_msghdr)]; if ( addr != 0 ) { //printf("gotverack from %s\n",addr->ipaddr); addr->A.nTime = (uint32_t)time(NULL); - iguana_queue_send(coin,addr,0,serialized,"getaddr",0,0,0); - if ( addr->supernet != 0 ) - { - printf("send getpeers to %s\n",addr->ipaddr); - iguana_send_supernet(coin,addr,SUPERNET_GETPEERSTR,0); - } + iguana_queue_send(addr,0,serialized,"getaddr",0); + iguana_supernet_ping(myinfo,coin,addr); } } @@ -244,26 +421,23 @@ void iguana_gotaddr(struct iguana_info *coin,struct iguana_peer *addr,struct igu printf("0x%02x%s",A->ip[i],i<15?",":""); printf("}, 14631},\n"); } - iguana_possible_peer(coin,ipport); - //printf("gotaddr.(%s:%d) from (%s)\n",ipaddr,port,addr->ipaddr); + if ( strcmp(coin->symbol,"BTC") != 0 || (rand() % 10) == 0 ) + iguana_possible_peer(coin,ipport); + if ( 0 && strncmp("BTC",coin->symbol,3) != 0 ) + printf("%s\n",ipaddr); } -void iguana_gotping(struct iguana_info *coin,struct iguana_peer *addr,uint64_t nonce,uint8_t *data) +void iguana_gotping(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,uint64_t nonce,uint8_t *data) { - int32_t len; char myipaddr[64]; uint8_t serialized[sizeof(struct iguana_msghdr) + sizeof(nonce)]; + int32_t len; uint8_t serialized[sizeof(struct iguana_msghdr) + sizeof(nonce)]; len = iguana_rwnum(1,&serialized[sizeof(struct iguana_msghdr)],sizeof(uint64_t),&nonce); if ( memcmp(data,&serialized[sizeof(struct iguana_msghdr)],sizeof(nonce)) != 0 ) printf("ping ser error %llx != %llx\n",(long long)nonce,*(long long *)data); - iguana_queue_send(coin,addr,0,serialized,"pong",len,0,0); - if ( addr->supernet != 0 ) - { - expand_ipbits(myipaddr,(uint32_t)nonce); - printf("send getpeers to %s, myipaddr.(%s)\n",addr->ipaddr,myipaddr); - iguana_send_supernet(coin,addr,SUPERNET_GETPEERSTR,0); - } + iguana_queue_send(addr,0,serialized,"pong",len); + iguana_supernet_ping(myinfo,coin,addr); } -int32_t iguana_send_ping(struct iguana_info *coin,struct iguana_peer *addr) +int32_t iguana_send_ping(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr) { int32_t len; uint64_t nonce; uint8_t serialized[sizeof(struct iguana_msghdr) + sizeof(nonce)]; if ( (nonce= addr->pingnonce) == 0 ) @@ -273,11 +447,12 @@ int32_t iguana_send_ping(struct iguana_info *coin,struct iguana_peer *addr) addr->pingtime = (uint32_t)time(NULL); } //printf("pingnonce.%llx from (%s)\n",(long long)nonce,addr->ipaddr); - iguana_queue_send(coin,addr,0,serialized,"getaddr",0,0,0); + iguana_queue_send(addr,0,serialized,"getaddr",0); len = iguana_rwnum(1,&serialized[sizeof(struct iguana_msghdr)],sizeof(uint64_t),&nonce); - if ( addr->supernet != 0 ) - iguana_send_supernet(coin,addr,SUPERNET_GETPEERSTR,0); - return(iguana_queue_send(coin,addr,0,serialized,"ping",len,0,0)); + iguana_supernet_ping(myinfo,coin,addr); + //if ( myinfo->IAMRELAY != 0 ) + // basilisk_relays_send(myinfo,addr); + return(iguana_queue_send(addr,0,serialized,"ping",len)); } int32_t iguana_send_ConnectTo(struct iguana_info *coin,struct iguana_peer *addr) @@ -286,7 +461,7 @@ int32_t iguana_send_ConnectTo(struct iguana_info *coin,struct iguana_peer *addr) r = rand(); len = iguana_rwnum(1,&serialized[sizeof(struct iguana_msghdr)],sizeof(uint32_t),&r); len += iguana_rwnum(1,&serialized[sizeof(struct iguana_msghdr)+len],sizeof(port),&port); - return(iguana_queue_send(coin,addr,0,serialized,"ConnectTo",len,0,0)); + return(iguana_queue_send(addr,0,serialized,"ConnectTo",len)); } void iguana_gotpong(struct iguana_info *coin,struct iguana_peer *addr,uint64_t nonce) @@ -295,7 +470,7 @@ void iguana_gotpong(struct iguana_info *coin,struct iguana_peer *addr,uint64_t n { addr->pingtime = (OS_milliseconds() - addr->sendmillis) + 1; addr->pingsum += addr->pingtime, addr->numpings++; - printf("%s pingtime %.0f numpings.%d [%.3f] ",addr->ipaddr,addr->pingtime,addr->numpings,addr->pingsum/addr->numpings); + //printf("%s pingtime %.0f numpings.%d [%.3f] ",addr->ipaddr,addr->pingtime,addr->numpings,addr->pingsum/addr->numpings); } if ( nonce != addr->pingnonce ) { @@ -331,6 +506,7 @@ int32_t iguana_getdata(struct iguana_info *coin,uint8_t *serialized,int32_t type return(iguana_sethdr((void *)serialized,coin->chain->netmagic,"getdata",&serialized[sizeof(struct iguana_msghdr)],len)); } +int32_t debugtest; int32_t iguana_rwvin(int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized,struct iguana_msgvin *msg) { int32_t len = 0; uint32_t tmp; @@ -346,19 +522,23 @@ int32_t iguana_rwvin(int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized, } len += iguana_rwmem(rwflag,&serialized[len],msg->scriptlen,msg->vinscript); len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->sequence),&msg->sequence); - //char str[65]; printf("MSGvin.(%s/v%d) script[%d]\n",bits256_str(str,msg->prev_hash),msg->prev_vout,msg->scriptlen); - //int i; for (i=0; iscriptlen; i++) - // printf("%02x ",msg->script[i]); - //printf(" inscriptlen.%d, prevhash.%llx prev_vout.%d | ",msg->scriptlen,(long long)msg->prev_hash.txid,msg->prev_vout); + if ( debugtest != 0 ) + { + char str[65]; printf("MSGvin.(%s/v%d) script[%d]\n",bits256_str(str,msg->prev_hash),msg->prev_vout,msg->scriptlen); + int i; for (i=0; iscriptlen; i++) + printf("%02x ",msg->vinscript[i]); + printf(" vinscriptlen.%d, prevhash.%llx prev_vout.%d | ",msg->scriptlen,(long long)msg->prev_hash.txid,msg->prev_vout); + } return(len); } -int32_t debugtest; int32_t iguana_rwvout(int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized,struct iguana_msgvout *msg) { int32_t len = 0; len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->value),&msg->value); len += iguana_rwvarint32(rwflag,&serialized[len],&msg->pk_scriptlen); + if ( msg->pk_scriptlen > IGUANA_MAXSCRIPTSIZE ) + return(-1); if ( rwflag == 0 ) msg->pk_script = iguana_memalloc(mem,msg->pk_scriptlen,1); len += iguana_rwmem(rwflag,&serialized[len],msg->pk_scriptlen,msg->pk_script); @@ -372,34 +552,80 @@ int32_t iguana_rwvout(int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized return(len); } -int32_t iguana_rwtx(int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized,struct iguana_msgtx *msg,int32_t maxsize,bits256 *txidp,int32_t hastimestamp,int32_t isvpncoin) +int32_t iguana_rwjoinsplit(int32_t rwflag,uint8_t *serialized,struct iguana_msgjoinsplit *msg) { - int32_t i,len = 0; uint8_t *txstart = serialized; char txidstr[65]; + int32_t len = 0; + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->vpub_old),&msg->vpub_old); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->vpub_new),&msg->vpub_new); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->anchor),msg->anchor.bytes); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->nullifiers[0]),msg->nullifiers[0].bytes); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->nullifiers[1]),msg->nullifiers[1].bytes); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->commitments[0]),msg->commitments[0].bytes); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->commitments[1]),msg->commitments[1].bytes); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->ephemeralkey),msg->ephemeralkey.bytes); + if ( rwflag == 1 ) + memcpy(&serialized[len],msg->ciphertexts,sizeof(msg->ciphertexts)); + else memcpy(msg->ciphertexts,&serialized[len],sizeof(msg->ciphertexts)); + len += sizeof(msg->ciphertexts); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->randomseed),msg->randomseed.bytes); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->vmacs[0]),msg->vmacs[0].bytes); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(msg->vmacs[1]),msg->vmacs[1].bytes); + if ( rwflag == 1 ) + memcpy(&serialized[len],msg->zkproof,sizeof(msg->zkproof)); + else memcpy(msg->zkproof,&serialized[len],sizeof(msg->zkproof)); + len += sizeof(msg->zkproof); + return(len); +} + +int32_t iguana_rwtx(uint8_t zcash,int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized,struct iguana_msgtx *msg,int32_t maxsize,bits256 *txidp,int32_t hastimestamp,int32_t isvpncoin) +{ + int32_t i,n,len = 0; uint8_t *txstart = serialized; char txidstr[65]; + if ( maxsize < sizeof(msg->version) ) + return(-1); + msg->serialized = serialized; len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->version),&msg->version); if ( hastimestamp != 0 ) + { + if ( maxsize-len < sizeof(msg->timestamp) ) + return(-1); len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->timestamp),&msg->timestamp); + } len += iguana_rwvarint32(rwflag,&serialized[len],&msg->tx_in); - //printf("version.%d ",msg->version); if ( rwflag == 0 ) msg->vins = iguana_memalloc(mem,msg->tx_in * sizeof(*msg->vins),1); + if ( maxsize-len <= 0 ) + return(-1); for (i=0; itx_in; i++) { - len += iguana_rwvin(rwflag,mem,&serialized[len],&msg->vins[i]); - if ( len > maxsize ) + if ( len+sizeof(bits256)+sizeof(int32_t) > maxsize ) + { + { + printf("invalid tx_in.%d len.%d vs maxsize.%d before\n",msg->tx_in,len,maxsize); + return(-1); + } + } + if ( (n= iguana_rwvin(rwflag,mem,&serialized[len],&msg->vins[i])) >= 0 ) + len += n; + if ( n < 0 || len+sizeof(int32_t) > maxsize ) { printf("invalid tx_in.%d len.%d vs maxsize.%d\n",msg->tx_in,len,maxsize); return(-1); } } - //printf("numvins.%d\n",msg->tx_in); len += iguana_rwvarint32(rwflag,&serialized[len],&msg->tx_out); - //printf("numvouts.%d ",msg->tx_out); + if ( len + msg->tx_out*8 > maxsize ) + { + printf("invalid tx_out.%d len.%d vs maxsize.%d\n",msg->tx_out,len,maxsize); + return(-1); + } + //printf("numvouts.%d ",msg->tx_out); if ( rwflag == 0 ) msg->vouts = iguana_memalloc(mem,msg->tx_out * sizeof(*msg->vouts),1); for (i=0; itx_out; i++) { - len += iguana_rwvout(rwflag,mem,&serialized[len],&msg->vouts[i]); - if ( len > maxsize ) + if ( (n= iguana_rwvout(rwflag,mem,&serialized[len],&msg->vouts[i])) >= 0 ) + len += n; + if ( n < 0 || len > maxsize ) { printf("invalid tx_out.%d len.%d vs maxsize.%d\n",msg->tx_out,len,maxsize); return(-1); @@ -413,6 +639,28 @@ int32_t iguana_rwtx(int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized,s for (; serialized[len]!=0&&lenversion == 2 ) + { + uint32_t numjoinsplits; struct iguana_msgjoinsplit joinsplit; uint8_t joinsplitpubkey[33],joinsplitsig[64]; + len += iguana_rwvarint32(rwflag,&serialized[len],&numjoinsplits); + char str[65]; + printf("numjoinsplits.%d version.%d numvins.%d numvouts.%d locktime.%u %s\n",numjoinsplits,msg->version,msg->tx_in,msg->tx_out,msg->lock_time,bits256_str(str,*txidp)); + if ( numjoinsplits > 0 ) + { + for (i=0; iallocsize = len; return(len); @@ -420,23 +668,26 @@ int32_t iguana_rwtx(int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized,s char *iguana_txscan(struct iguana_info *coin,cJSON *json,uint8_t *data,int32_t recvlen,bits256 txid) { - struct iguana_msgtx tx; bits256 hash2; struct iguana_block block; struct iguana_msgblock msg; - int32_t i,n,len; char *txbytes,vpnstr[64]; + struct iguana_msgtx tx; bits256 hash2; struct iguana_block *block; struct iguana_msgblock msg; + int32_t i,n,len,extralen = 65356; char *txbytes,vpnstr[64]; uint8_t *extraspace,blockspace[sizeof(*block)+sizeof(*block->zRO)]; + block = (void *)blockspace; memset(&msg,0,sizeof(msg)); vpnstr[0] = 0; - len = iguana_rwblock(0,&hash2,data,&msg); - iguana_blockconv(&block,&msg,hash2,-1); + extraspace = calloc(1,extralen); + len = iguana_rwblock(coin->symbol,coin->chain->zcash,coin->chain->auxpow,coin->chain->hashalgo,0,&hash2,data,&msg,recvlen); + iguana_blockconv(coin->chain->zcash,coin->chain->auxpow,block,&msg,hash2,-1); for (i=0; iblocks.hwmchain.height,0,0,&data[len],recvlen - len,&tx,&tx.txid,vpnstr,extraspace,extralen,0,0)) < 0 ) break; - //char str[65]; printf("%d of %d: %s\n",i,msg.txn_count,bits256_str(str,tx.txid)); + char str[65]; printf("%d of %d: %s len.%d\n",i,msg.txn_count,bits256_str(str,tx.txid),len); if ( bits256_cmp(txid,tx.txid) == 0 ) { - if ( (n= iguana_rwmsgtx(coin,0,json,&data[len],recvlen - len,&tx,&tx.txid,vpnstr)) > 0 ) + if ( (n= iguana_rwmsgtx(coin,coin->blocks.hwmchain.height,0,json,&data[len],recvlen - len,&tx,&tx.txid,vpnstr,extraspace,extralen,0,0)) > 0 ) { txbytes = malloc(n*2+1); init_hexbytes_noT(txbytes,&data[len],n); + free(extraspace); return(txbytes); } } @@ -447,38 +698,48 @@ char *iguana_txscan(struct iguana_info *coin,cJSON *json,uint8_t *data,int32_t r int32_t iguana_gentxarray(struct iguana_info *coin,struct OS_memspace *mem,struct iguana_txblock *txdata,int32_t *lenp,uint8_t *data,int32_t recvlen) { - struct iguana_msgtx *tx; bits256 hash2; struct iguana_msgblock msg; int32_t i,n,len,numvouts,numvins; + struct iguana_msgtx *tx; bits256 hash2; struct iguana_msgblock msg; int32_t i,n,hdrlen,len,numvouts,numvins; char str[65]; memset(&msg,0,sizeof(msg)); - len = iguana_rwblock(0,&hash2,data,&msg); - iguana_blockconv(&txdata->block,&msg,hash2,-1); - tx = iguana_memalloc(mem,msg.txn_count*sizeof(*tx),1); - for (i=numvins=numvouts=0; isymbol,coin->chain->zcash,coin->chain->auxpow,coin->chain->hashalgo,0,&hash2,data,&msg,recvlen); + hdrlen = len; + if ( len > recvlen ) { - if ( (n= iguana_rwtx(0,mem,&data[len],&tx[i],recvlen - len,&tx[i].txid,coin->chain->hastimestamp,strcmp(coin->symbol,"VPN")==0)) < 0 ) - break; - if ( 0 && bits256_cmp(tx[i].txid,bits256_conv("091c99b7b7f9b83ad2385c45b342ed5dd57035d15ff812262a3ceb3f1b291a5a")) == 0 ) - { - int32_t j; for (j=0; len+jchain->hastimestamp,strcmp(coin->symbol,"VPN")==0)) < 0 ) - { - + printf("gentxarray error len.%d > recvlen.%d\n",len,recvlen); + return(-1); + } + iguana_blockconv(coin->chain->zcash,coin->chain->auxpow,(struct iguana_block *)&txdata->zblock,&msg,hash2,-1); + numvins = numvouts = 0; + if ( msg.txn_count > 0 ) + { + tx = iguana_memalloc(mem,msg.txn_count*sizeof(*tx),1); + for (i=0; i recvlen ) + { + printf("gentxarrayB error len.%d > recvlen.%d\n",len,recvlen); + return(-1); } - debugtest = 0;*/ + if ( (n= iguana_rwtx(coin->chain->zcash,0,mem,&data[len],&tx[i],recvlen - len,&tx[i].txid,coin->chain->isPoS,strcmp(coin->symbol,"VPN")==0)) < 0 ) + { + //for (i=0; i recvlen.%d, n.%d hdrlen.%d\n",i,len,recvlen,n,hdrlen); + return(-1); + } + numvouts += tx[i].tx_out; + numvins += tx[i].tx_in; + len += n; } - numvouts += tx[i].tx_out; - numvins += tx[i].tx_in; - len += n; + if ( coin->chain->isPoS != 0 && len != recvlen && data[len] == (recvlen - len - 1) ) + { + //printf("\n>>>>>>>>>>> len.%d vs recvlen.%d [%d]\n",len,recvlen,data[len]); + memcpy(txdata->space,&data[len],recvlen-len); + len += (recvlen-len); + txdata->extralen = (recvlen - len); + } else txdata->extralen = 0; } - if ( coin->chain->hastimestamp != 0 && len != recvlen && data[len] == (recvlen - len - 1) ) - { - //printf("\n>>>>>>>>>>> len.%d vs recvlen.%d [%d]\n",len,recvlen,data[len]); - memcpy(txdata->space,&data[len],recvlen-len); - len += (recvlen-len); - txdata->extralen = (recvlen - len); - } else txdata->extralen = 0; + if ( coin->chain->auxpow != 0 && len != recvlen ) + printf("numtx.%d %s hdrlen.%d len.%d vs recvlen.%d v.%08x\n",msg.txn_count,bits256_str(str,hash2),hdrlen,len,recvlen,txdata->zblock.RO.version); txdata->recvlen = len; txdata->numtxids = msg.txn_count; txdata->numunspents = numvouts; @@ -496,16 +757,16 @@ int32_t iguana_send_hashes(struct iguana_info *coin,char *command,struct iguana_ nVersion = 0; len = iguana_rwblockhash(1,&serialized[sizeof(struct iguana_msghdr)],&nVersion,&varint,hashes,&stophash); //printf("%s send_hashes.%d %s height.%d\n",addr->ipaddr,n,bits256_str(hashes[0]),iguana_height(coin,hashes[0])); - retval = iguana_queue_send(coin,addr,0,serialized,command,len,0,0); + retval = iguana_queue_send(addr,0,serialized,command,len); myfree(serialized,size); } else printf("iguana_send_hashes: unexpected n.%d\n",n); return(retval); } -int32_t iguana_intvectors(struct iguana_info *coin,struct iguana_peer *addr,int32_t processflag,uint8_t *data,int32_t datalen) +int32_t iguana_intvectors(struct iguana_info *coin,struct iguana_peer *addr,int32_t processflag,uint8_t *data,int32_t datalen) // other side needs to be a bit smart about what hashes are sents in { - uint32_t type; bits256 *txids=0,*blockhashes=0,hash; int32_t i,n,m,len; uint64_t x; - len = n = m = 0; + uint32_t type; bits256 *txids=0,*quotes=0,*blockhashes=0,hash; int32_t i,n,q,m,len; uint64_t x; + len = n = m = q = 0; len += iguana_rwvarint(0,&data[len],&x); for (i=0; i 0 ) + { + if ( q != x ) + quotes = myrealloc('q',quotes,(int32_t)((x+1)*sizeof(*quotes)),(q+1)*sizeof(*quotes)); + if ( processflag != 0 ) + iguana_gotquotesM(coin,addr,quotes,q), quotes = 0; + } if ( txids != 0 ) myfree(txids,sizeof(*txids) * (x+1)); if ( blockhashes != 0 ) @@ -557,228 +834,328 @@ int32_t iguana_intvectors(struct iguana_info *coin,struct iguana_peer *addr,int3 //printf("intvectors.%c recvlen.%d\n",intvectors,recvlen); } -int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struct OS_memspace *rawmem,struct OS_memspace *txmem,struct OS_memspace *hashmem,struct iguana_msghdr *H,uint8_t *data,int32_t recvlen) +int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struct OS_memspace *rawmem,struct OS_memspace *txmem,struct OS_memspace *hashmem,struct iguana_msghdr *H,uint8_t *data,int32_t recvlen,int32_t fromcache) { - uint8_t serialized[16384]; char *retstr; - int32_t i,retval,ishost,delay,srvmsg,bloom,sendlen=0,intvectors,len= -100; uint64_t nonce,x; bits256 hash2; + uint8_t serialized[16384]; char *ipaddr; struct supernet_info *myinfo = SuperNET_MYINFO(0); + int32_t i,n=0,retval=-1,ishost,srvmsg,bloom,sendlen=0,intvectors,len= -100; uint64_t nonce,x; bits256 hash2; bloom = intvectors = srvmsg = -1; - if ( addr != 0 ) + if ( strncmp(H->command+1,"uperNET",strlen("uperNET")) == 0 || strncmp(H->command,"uperNet",strlen("uperNet")) == 0 ) { - addr->lastcontact = (uint32_t)time(NULL); - strcpy(addr->lastcommand,H->command); - } - retval = 0; - //printf("iguana_msgparser from (%s) parse.(%s) len.%d\n",addr->ipaddr,H->command,recvlen); - if ( strncmp(H->command,"SuperNET",strlen("SuperNET")) == 0 ) - { - addr->supernet = 1; - addr->msgcounts.verack++; - len = recvlen; - if ( (retstr= SuperNET_p2p(coin,addr,&delay,addr->ipaddr,data,recvlen,H->command[strlen("SuperNET")]=='b')) != 0 ) + if ( addr != 0 ) { - iguana_send_supernet(coin,addr,retstr,delay); - free(retstr); - } - //printf("GOT.(%s) [%s] len.%d from %s -> (%s)\n",H->command,data,recvlen,addr->ipaddr,retstr==0?"null":retstr); + if ( H->command[0] == 'S' ) + addr->supernet = 1, addr->basilisk = 0; + else if ( H->command[0] == 's' ) + addr->basilisk = 1, addr->supernet = 0; + ipaddr = addr->ipaddr; + } else ipaddr = 0; + len = recvlen; + //printf("GOT.(%s) len.%d from %s\n",H->command,recvlen,addr->ipaddr); + basilisk_p2p(myinfo,addr,ipaddr,data,recvlen,&H->command[strlen("SuperNET")],H->command[6] == 'e' && H->command[7] == 't'); + return(0); } - else if ( (ishost= (strcmp(H->command,"getblocks") == 0)) || strcmp(H->command,"block") == 0 ) + if ( addr != 0 ) { - if ( addr != 0 ) + if ( 0 && strcmp("DOGE",coin->symbol) == 0 ) + printf("iguana_msgparser from (%s) parse.(%s) len.%d\n",addr->ipaddr,H->command,recvlen); + //iguana_peerblockrequest(coin,addr->blockspace,IGUANA_MAXPACKETSIZE,addr,iguana_blockhash(coin,100),0); + addr->lastcontact = (uint32_t)time(NULL); + strcpy(addr->lastcommand,H->command); + retval = 0; + if ( (ishost= (strcmp(H->command,"getblocks") == 0)) || strcmp(H->command,"block") == 0 ) { - if ( ishost == 0 ) + if ( addr != 0 && rawmem->ptr != 0 ) { struct iguana_txblock txdata; - addr->msgcounts.block++; iguana_memreset(rawmem), iguana_memreset(txmem); memset(&txdata,0,sizeof(txdata)); - if ( (len= iguana_gentxarray(coin,rawmem,&txdata,&len,data,recvlen)) == recvlen ) - iguana_gotblockM(coin,addr,&txdata,rawmem->ptr,H,data,recvlen); - else printf("parse error block txn_count.%d, len.%d vs recvlen.%d from.(%s)\n",txdata.block.RO.txn_count,len,recvlen,addr->ipaddr); - } else len = iguana_peergetrequest(coin,addr,data,recvlen,1); + if ( ishost == 0 ) + { + if ( 0 && coin->chain->auxpow != 0 ) + { + int32_t i; for (i=0; imsgcounts.block++; + if ( (n= iguana_gentxarray(coin,rawmem,&txdata,&len,data,recvlen)) == recvlen || n == recvlen-1 ) + { + len = n; + iguana_gotblockM(coin,addr,&txdata,rawmem->ptr,H,data,recvlen,fromcache); + } + else + { + //for (i=0; iipaddr); + } + } + else + { + len = iguana_peergetrequest(myinfo,coin,addr,data,recvlen,1); + //printf("peergetrequest len.%d\n",len); + } + } else printf("command.(%s) addr.%p rawmemptr.%p\n",H->command,addr,rawmem->ptr); } - } - else if ( (ishost= (strcmp(H->command,"getdata") == 0)) || strcmp(H->command,"inv") == 0 ) - { - if ( addr != 0 ) + else if ( (ishost= (strncmp(H->command,"inv",3) == 0)) || strncmp(H->command,"getdata",7) == 0 ) { - if ( ishost != 0 ) - { - addr->msgcounts.getdata++; - len = iguana_peerdatarequest(coin,addr,data,recvlen); - } - else + if ( addr != 0 ) { - intvectors = 'I', addr->msgcounts.inv++; - len = iguana_intvectors(coin,addr,1,data,recvlen); + if ( ishost == 0 ) + { + addr->msgcounts.getdata++; + len = iguana_peerdatarequest(coin,addr,data,recvlen); + } + else + { + intvectors = 'I', addr->msgcounts.inv++; + if ( 0 && strcmp(H->command,"inv2") == 0 ) + printf("GOT INV2.%d\n",recvlen); + len = iguana_intvectors(coin,addr,1,data,recvlen); // indirectly issues getdata + } } } - } - else if ( (ishost= (strcmp(H->command,"getheaders") == 0)) || strcmp(H->command,"headers") == 0 ) - { - struct iguana_msgblock msg; struct iguana_block *blocks; uint32_t n=0; - len = 0; - if ( ishost == 0 ) + else if ( (ishost= (strcmp(H->command,"getheaders") == 0)) || strcmp(H->command,"headers") == 0 ) { - len = iguana_rwvarint32(0,data,&n); - if ( n <= IGUANA_MAXINV ) + struct iguana_msgblock msg; struct iguana_zblock *zblocks; uint32_t tmp,n=0; + len = 0; + if ( addr != 0 && recvlen >= sizeof(bits256) && strcmp("BTCD",coin->symbol) != 0 ) { - blocks = mycalloc('i',1,sizeof(*blocks) * n); - for (i=0; itotalsize == 0 ) + iguana_meminit(rawmem,"bighdrs",0,IGUANA_MAXPACKETSIZE * 2,0); + memset(prevhash2.bytes,0,sizeof(prevhash2)); + zblocks = mycalloc('z',1,(int32_t)(sizeof(struct iguana_zblock) * n)); + //printf("%s got %d headers len.%d\n",coin->symbol,n,recvlen); + for (i=0; ichain->auxpow != 0 ) + { + tmp = iguana_rwblockhdr(0,coin->chain->zcash,&data[len],&msg); + hash2 = iguana_calcblockhash(coin->symbol,coin->chain->hashalgo,&data[len],tmp); + len += tmp; + if ( (msg.H.version & 0x100) != 0 ) + { + iguana_memreset(rawmem); + tx = iguana_memalloc(rawmem,sizeof(*tx),1); + len += iguana_rwtx(coin->chain->zcash,0,rawmem,&data[len],tx,recvlen-len,&tx->txid,coin->chain->isPoS,strcmp(coin->symbol,"VPN")==0); + len += iguana_rwbignum(0,&data[len],sizeof(auxhash2),auxhash2.bytes); + len += iguana_rwmerklebranch(0,&data[len],coinbase_branch); + len += iguana_rwmerklebranch(0,&data[len],blockchain_branch); + len += iguana_rwblockhdr(0,coin->chain->zcash,&data[len],&parentblock); + } + len += iguana_rwvarint32(0,&data[len],&tmp); + char str[65],str2[65]; + if ( 0 && coin->chain->auxpow != 0 ) + printf("%d %d of %d: %s %s v.%08x numtx.%d cmp.%d\n",len,i,n,bits256_str(str,hash2),bits256_str(str2,msg.H.prev_block),msg.H.version,tmp,bits256_cmp(prevhash2,msg.H.prev_block)); + } else len += iguana_rwblock(coin->chain->symbol,coin->chain->zcash,coin->chain->auxpow,coin->chain->hashalgo,0,&hash2,&data[len],&msg,recvlen); + iguana_blockconv(coin->chain->zcash,coin->chain->auxpow,(struct iguana_block *)&zblocks[i],&msg,hash2,-1); + prevhash2 = hash2; + } + free(coinbase_branch); + free(blockchain_branch); + if ( iguana_gotheadersM(coin,addr,zblocks,n) < 0 ) + myfree(zblocks,(int32_t)(sizeof(struct iguana_zblock) * n)); + //myfree(blocks,sizeof(*blocks) * n); + if ( len == recvlen && addr != 0 ) + addr->msgcounts.headers++; + } else printf("got unexpected n.%d for headers\n",n); + } + else if ( addr->headerserror == 0 ) + { + len = iguana_peergetrequest(myinfo,coin,addr,data,recvlen,0); } - iguana_gotheadersM(coin,addr,blocks,n); - //myfree(blocks,sizeof(*blocks) * n); - if ( len == recvlen && addr != 0 ) - addr->msgcounts.headers++; - } else printf("got unexpected n.%d for headers\n",n); - } else len = iguana_peergetrequest(coin,addr,data,recvlen,0); - } - else if ( (ishost= (strcmp(H->command,"version") == 0)) || strcmp(H->command,"verack") == 0 ) - { - if ( addr != 0 ) - { - if ( ishost != 0 ) - { - struct iguana_msgversion recvmv; - len = iguana_rwversion(0,data,&recvmv,addr->ipaddr,recvlen); - if ( len <= recvlen ) - iguana_gotversion(coin,addr,&recvmv); - addr->msgcounts.version++; - } - else - { - iguana_gotverack(coin,addr); - addr->msgcounts.verack++; - len = 0; } } - } - else if ( (ishost= (strcmp(H->command,"ping") == 0)) || strcmp(H->command,"pong") == 0 ) - { - len = 0; - if ( recvlen == sizeof(uint64_t) && addr != 0 ) + else if ( (ishost= (strcmp(H->command,"version") == 0)) || strcmp(H->command,"verack") == 0 ) { - len = iguana_rwnum(0,data,sizeof(uint64_t),&nonce); if ( addr != 0 ) { - //printf("%u got nonce.%llx from %s\n",(uint32_t)time(NULL),(long long)nonce,addr->ipaddr); if ( ishost != 0 ) { - iguana_gotping(coin,addr,nonce,data); - addr->msgcounts.ping++; + struct iguana_msgversion recvmv; + len = iguana_rwversion(0,data,&recvmv,addr->ipaddr,recvlen); + if ( len <= recvlen ) + iguana_gotversion(myinfo,coin,addr,&recvmv); + addr->msgcounts.version++; } else { - iguana_gotpong(coin,addr,nonce); - addr->msgcounts.pong++; + iguana_gotverack(myinfo,coin,addr); + addr->msgcounts.verack++; + len = 0; } - iguana_queue_send(coin,addr,0,serialized,"getaddr",0,0,0); } } - } - else if ( (ishost= (strcmp(H->command,"getaddr") == 0)) || strcmp(H->command,"addr") == 0 ) - { - struct iguana_msgaddress A; - if ( addr != 0 ) + else if ( (ishost= (strcmp(H->command,"ping") == 0)) || strcmp(H->command,"pong") == 0 ) { - if ( ishost == 0 ) + len = 0; + if ( recvlen == sizeof(uint64_t) && addr != 0 ) { - len = iguana_rwvarint(0,data,&x); - for (i=0; iprotover); - iguana_gotaddr(coin,addr,&A); + //printf("%u got nonce.%llx from %s\n",(uint32_t)time(NULL),(long long)nonce,addr->ipaddr); + if ( ishost != 0 ) + { + iguana_gotping(myinfo,coin,addr,nonce,data); + addr->msgcounts.ping++; + } + else + { + iguana_gotpong(coin,addr,nonce); + addr->msgcounts.pong++; + } + iguana_queue_send(addr,0,serialized,"getaddr",0); } - if ( len == recvlen && addr != 0 ) + } + } + else if ( (ishost= (strcmp(H->command,"getaddr") == 0)) || strcmp(H->command,"addr") == 0 ) + { + struct iguana_msgaddress A; + //printf("iguana_msgparser from (%s) parse.(%s) len.%d\n",addr->ipaddr,H->command,recvlen); + if ( addr != 0 ) + { + if ( ishost == 0 ) { - addr->lastgotaddr = (uint32_t)time(NULL); - addr->msgcounts.addr++; + //for (i=0; iprotover); + iguana_gotaddr(coin,addr,&A); + } + if ( len == recvlen ) + { + addr->lastgotaddr = (uint32_t)time(NULL); + addr->msgcounts.addr++; + } + } + else + { + len = 0; + if ( (sendlen= iguana_peeraddrrequest(coin,addr,&addr->blockspace[sizeof(H)],IGUANA_MAXPACKETSIZE)) > 0 ) + { + if ( 0 ) + { + int32_t checklen; uint32_t checkbits; char checkaddr[64]; + checklen = iguana_rwvarint(0,&addr->blockspace[sizeof(H)],&x); + printf("\nSENDING:\n"); + for (i=0; iblockspace[sizeof(H)+i]); + printf(" %p addr sendlen.%d N.%d\n",&addr->blockspace[sizeof(H)],sendlen,(int32_t)x); + for (i=0; iblockspace[sizeof(H) + checklen],&A,CADDR_TIME_VERSION); + iguana_rwnum(0,&A.ip[12],sizeof(uint32_t),&checkbits); + expand_ipbits(checkaddr,checkbits); + printf("checkaddr.(%s:%02x%02x) ",checkaddr,((uint8_t *)&A.port)[1],((uint8_t *)&A.port)[0]); + } + printf("x.%d\n",(int32_t)x); + } + retval = iguana_queue_send(addr,0,addr->blockspace,"addr",sendlen); + } + addr->msgcounts.getaddr++; } } - else + //printf("%s -> addr recvlen.%d num.%d\n",addr->ipaddr,recvlen,(int32_t)x); + } + else if ( strcmp(H->command,"notfound") == 0 ) + { + if ( addr != 0 ) { - len = 0; - if ( (sendlen= iguana_peeraddrrequest(coin,addr,addr->blockspace,sizeof(addr->blockspace))) > 0 ) - retval = iguana_queue_send(coin,addr,0,addr->blockspace,"addr",sendlen,0,0); - addr->msgcounts.getaddr++; + printf("%s SERVER notfound\n",addr->ipaddr); + intvectors = 'N', addr->msgcounts.notfound++; + len = iguana_intvectors(coin,addr,1,data,recvlen); } } - //printf("%s -> addr recvlen.%d num.%d\n",addr->ipaddr,recvlen,(int32_t)x); - } - else if ( strcmp(H->command,"notfound") == 0 ) - { - printf("%s SERVER notfound\n",addr->ipaddr); - intvectors = 'N', addr->msgcounts.notfound++; - len = iguana_intvectors(coin,addr,1,data,recvlen); - } - else if ( strcmp(H->command,"mempool") == 0 ) - { - printf("%s SERVER mempool\n",addr->ipaddr); - srvmsg = 'M', addr->msgcounts.mempool++; - } - else if ( strcmp(H->command,"tx") == 0 ) - { - struct iguana_msgtx *tx; - iguana_memreset(rawmem); - tx = iguana_memalloc(rawmem,sizeof(*tx),1);//mycalloc('u',1,sizeof(*tx)); - len = iguana_rwtx(0,rawmem,data,tx,recvlen,&tx->txid,coin->chain->hastimestamp,strcmp(coin->symbol,"VPN")==0); - iguana_gotunconfirmedM(coin,addr,tx,data,recvlen); - printf("tx recvlen.%d vs len.%d\n",recvlen,len); - addr->msgcounts.tx++; - } - else if ( strcmp(H->command,"ConnectTo") == 0 ) - { - iguana_queue_send(coin,addr,0,serialized,"getaddr",0,0,0); - len = 6; - } - else if ( strcmp(H->command,"reject") == 0 ) - { - for (i=0; imsgcounts.reject++; - } - else if ( strcmp(H->command,"alert") == 0 ) - { - for (i=0; imsgcounts.alert++; - } - else if ( addr != 0 ) - { - if ( strcmp(H->command,"filterload") == 0 ) // for bloom - bloom = 'L', addr->msgcounts.filterload++; - else if ( strcmp(H->command,"filteradd") == 0 ) // for bloom - bloom = 'A', addr->msgcounts.filteradd++; - else if ( strcmp(H->command,"filterclear") == 0 ) // for bloom - bloom = 'C', addr->msgcounts.filterclear++; - else if ( strcmp(H->command,"merkleblock") == 0 ) // for bloom - bloom = 'M', addr->msgcounts.merkleblock++; - } - if ( bloom >= 0 || srvmsg >= 0 ) - len = recvlen; // just mark as valid - if ( len != recvlen && len != recvlen-1 && len != recvlen-2 ) - { - //printf("error.(%s) (%s): len.%d != recvlen.%d\n",H->command,addr->ipaddr,len,recvlen); - //for (i=0; icommand,"addr") != 0 ) - printf("%s.%s len mismatch %d != %d\n",addr!=0?addr->ipaddr:"local",H->command,len,recvlen); - } - else if ( len != recvlen ) - { - printf("%s extra byte.[%02x] command.%s len.%d recvlen.%d\n",addr->ipaddr,data[recvlen-1],H->command,len,recvlen); - //retval = -1; + else if ( strcmp(H->command,"mempool") == 0 ) + { + if ( addr != 0 ) + { + printf("%s SERVER mempool\n",addr->ipaddr); + srvmsg = 'M', addr->msgcounts.mempool++; + } + } + else if ( strcmp(H->command,"tx") == 0 ) + { + struct iguana_msgtx *tx; + iguana_memreset(rawmem); + tx = iguana_memalloc(rawmem,sizeof(*tx),1);//mycalloc('u',1,sizeof(*tx)); + len = iguana_rwtx(coin->chain->zcash,0,rawmem,data,tx,recvlen,&tx->txid,coin->chain->isPoS,strcmp(coin->symbol,"VPN")==0); + if ( addr != 0 ) + { + iguana_gotunconfirmedM(coin,addr,tx,data,recvlen); + printf("tx recvlen.%d vs len.%d\n",recvlen,len); + addr->msgcounts.tx++; + } + } + else if ( addr != 0 && strcmp(H->command,"ConnectTo") == 0 ) + { + iguana_queue_send(addr,0,serialized,"getaddr",0); + len = 6; + } + else if ( strcmp(H->command,"reject") == 0 ) + { + if ( addr != 0 ) + { + if ( strncmp((char *)data+1,"headers",7) == 0 ) + addr->headerserror++; + else + { + for (i=0; iipaddr,addr->protover); + addr->msgcounts.reject++; + } + } + len = recvlen; + } + else if ( strcmp(H->command,"alert") == 0 ) + { + struct iguana_msgalert alert; + memset(&alert,0,sizeof(alert)); + len = iguana_rwmsgalert(coin,0,data,&alert); + if ( len == recvlen && addr != 0 ) + addr->msgcounts.alert++; + } + else if ( addr != 0 ) + { + if ( strcmp(H->command,"filterload") == 0 ) // for bloom + bloom = 'L', addr->msgcounts.filterload++; + else if ( strcmp(H->command,"filteradd") == 0 ) // for bloom + bloom = 'A', addr->msgcounts.filteradd++; + else if ( strcmp(H->command,"filterclear") == 0 ) // for bloom + bloom = 'C', addr->msgcounts.filterclear++; + else if ( strcmp(H->command,"merkleblock") == 0 ) // for bloom + bloom = 'M', addr->msgcounts.merkleblock++; + } + if ( bloom >= 0 || srvmsg >= 0 ) + len = recvlen; // just mark as valid + if ( len != recvlen && len != recvlen-1 && len != recvlen-2 ) + { + //printf("error.(%s) (%s): len.%d != recvlen.%d\n",H->command,addr->ipaddr,len,recvlen); + //for (i=0; icommand,"addr") != 0 && (coin->chain->auxpow == 0 || strcmp(H->command,"headers") != 0) ) + printf("%s %s.%s len mismatch %d != %d\n",coin->symbol,addr!=0?addr->ipaddr:"local",H->command,len,recvlen); + } + else if ( len != recvlen && recvlen > 1 ) + { + //printf("%s extra byte.[%02x] command.%s len.%d recvlen.%d\n",addr->ipaddr,data[recvlen-1],H->command,len,recvlen); + //retval = -1; + } } return(retval); -} - +} \ No newline at end of file diff --git a/iguana/iguana_passport.c b/iguana/iguana_passport.c index 40c568684..36e8dfcfc 100755 --- a/iguana/iguana_passport.c +++ b/iguana/iguana_passport.c @@ -28,8 +28,10 @@ While it is not expected that there will be more than 256 such blockchains, by u 'b' -> bitcoin/BitcoinDark (BTC) 'c' -> colored coins 'e' -> ethereum (ETH) + 'h' -> HEAT 'n' -> NXT 'o' -> open assets + 's' -> BURST 'w' -> WAVES 'x' -> counterparty (XCP) '?' -> please contact jl777 to have a new code for asset supporting blockchain added. diff --git a/iguana/iguana_payments.c b/iguana/iguana_payments.c index 746950e34..79f58a38c 100755 --- a/iguana/iguana_payments.c +++ b/iguana/iguana_payments.c @@ -13,6 +13,8 @@ * * ******************************************************************************/ +// compare multiple rawtx returns + #include "iguana777.h" char *iguana_APIrequest(struct iguana_info *coin,bits256 blockhash,bits256 txid,int32_t seconds) @@ -52,7 +54,7 @@ bits256 iguana_str2priv(struct supernet_info *myinfo,struct iguana_info *coin,ch decode_hex(privkey.bytes,sizeof(privkey),str); else if ( bitcoin_wif2priv(&addrtype,&privkey,str) != sizeof(bits256) ) { - if ( (waddr= iguana_waddresssearch(myinfo,coin,&wacct,str)) != 0 ) + if ( (waddr= iguana_waddresssearch(myinfo,&wacct,str)) != 0 ) privkey = waddr->privkey; else memset(privkey.bytes,0,sizeof(privkey)); } @@ -66,7 +68,7 @@ int32_t iguana_pubkeyget(struct supernet_info *myinfo,struct iguana_info *coin,u len = (int32_t)strlen(str); if ( is_hexstr(str,len) == 0 ) { - if ( (waddr= iguana_waddresssearch(myinfo,coin,&wacct,str)) != 0 ) + if ( (waddr= iguana_waddresssearch(myinfo,&wacct,str)) != 0 ) { if ( (plen= bitcoin_pubkeylen(waddr->pubkey)) > 0 ) memcpy(pubkeydata,waddr->pubkey,plen); @@ -109,7 +111,7 @@ cJSON *iguana_p2shjson(struct supernet_info *myinfo,struct iguana_info *coin,cJS addresses = cJSON_CreateArray(); for (i=0; iwifstr[0] != 0 ) + if ( V.signers[i].coinaddr[0] != 0 && (waddr= iguana_waddresssearch(myinfo,&wacct,V.signers[i].coinaddr)) != 0 && waddr->wifstr[0] != 0 ) jaddistr(privkeys,waddr->wifstr); else jaddistr(privkeys,""); if ( (plen= bitcoin_pubkeylen(V.signers[i].pubkey)) > 0 ) @@ -150,38 +152,366 @@ cJSON *iguana_scriptobj(struct iguana_info *coin,uint8_t rmd160[20],char *coinad for (i=0; ichain->p2shtype,script,scriptlen); + jaddstr(scriptobj,"p2sh",coinaddr); + } memcpy(rmd160,V.rmd160,20); } return(scriptobj); } -char *sendtoaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr,uint64_t satoshis,char *comment,char *comment2,int32_t minconf,char *account) +int32_t iguana_RTbestunspent(struct supernet_info *myinfo,struct iguana_info *coin,int32_t *aboveip,int64_t *abovep,int32_t *belowip,int64_t *belowp,struct iguana_outpoint *unspents,int32_t numunspents,uint64_t value) +{ + int32_t i,abovei,belowi; int64_t above,below,gap,atx_value; + abovei = belowi = -1; + for (above=below=i=0; i value ) + { + gap = (atx_value - value); + if ( above == 0 || gap < above ) + { + above = gap; + abovei = i; + } + } else gap = (value - atx_value); + if ( below == 0 || gap < below ) + { + below = gap; + belowi = i; + } + } + *aboveip = abovei; + *abovep = above; + *belowip = belowi; + *belowp = below; + return(abovei >= 0 ? abovei : belowi); +} + +cJSON *iguana_inputjson(bits256 txid,int32_t vout,uint8_t *spendscript,int32_t spendlen) +{ + char hexstr[IGUANA_MAXSCRIPTSIZE*2 + 1]; cJSON *sobj,*item = cJSON_CreateObject(); + jaddbits256(item,"txid",txid); + jaddnum(item,"vout",vout); + sobj = cJSON_CreateObject(); + init_hexbytes_noT(hexstr,spendscript,spendlen); + jaddstr(sobj,"hex",hexstr); + jadd(item,"scriptPubKey",sobj); + return(item); +} + +cJSON *iguana_RTinputsjson(struct supernet_info *myinfo,struct iguana_info *coin,uint64_t *totalp,uint64_t amount,struct iguana_outpoint *unspents,int32_t num) +{ + cJSON *vins; uint8_t spendscript[IGUANA_MAXSCRIPTSIZE]; struct iguana_txid *T; struct iguana_unspent *U,*u; struct iguana_bundle *bp; struct iguana_ramchain *ramchain; char coinaddr[64]; int32_t vout,height,abovei,belowi,i,spendlen,ind; uint32_t txidind; struct iguana_ramchaindata *rdata; bits256 txid; int64_t above,below,total = 0; struct iguana_outpoint outpt; int64_t remains = amount; + *totalp = 0; + vins = cJSON_CreateArray(); + for (i=0; i= 0) ) + ind = abovei; + else ind = belowi; + outpt = unspents[ind]; + memset(&unspents[ind],0,sizeof(unspents[ind])); + if ( coin->FULLNODE == 0 && coin->VALIDATENODE == 0 ) + { + if ( (spendlen= basilisk_unspentfind(myinfo,coin,&txid,&vout,spendscript,outpt,outpt.value)) > 0 ) + { + jaddi(vins,iguana_inputjson(txid,vout,spendscript,spendlen)); + total += outpt.value; + remains -= outpt.value; + //printf("%s value %.8f -> remains %.8f\n",coinaddr,dstr(value),dstr(remains)); + if ( remains <= 0 ) + break; + } + continue; + } + if ( (spendlen= _iguana_RTunspentfind(myinfo,coin,&txid,&vout,spendscript,outpt,outpt.value)) > 0 ) + { + jaddi(vins,iguana_inputjson(txid,vout,spendscript,spendlen)); + total += outpt.value; + remains -= outpt.value; + //printf("%s value %.8f -> remains %.8f\n",coinaddr,dstr(value),dstr(remains)); + if ( remains <= 0 ) + break; + continue; + } + if ( (bp= coin->bundles[outpt.hdrsi]) == 0 ) + { + printf("no bundle.[%d]\n",outpt.hdrsi); + free_json(vins); + return(0); + } + ramchain = &bp->ramchain; + if ( (rdata= ramchain->H.data) == 0 ) + continue; + U = RAMCHAIN_PTR(rdata,Uoffset); + T = RAMCHAIN_PTR(rdata,Toffset); + if ( outpt.unspentind > 0 && outpt.unspentind < rdata->numunspents ) + { + u = &U[outpt.unspentind]; + if ( (txidind= u->txidind) > 0 && txidind < rdata->numtxids ) + { + if ( iguana_unspentindfind(myinfo,coin,coinaddr,spendscript,&spendlen,&amount,&height,T[txidind].txid,u->vout,coin->bundlescount-1,0) == outpt.unspentind && spendlen > 0 ) + { + jaddi(vins,iguana_inputjson(T[txidind].txid,u->vout,spendscript,spendlen)); + total += outpt.value; + remains -= outpt.value; + //printf("%s value %.8f -> remains %.8f\n",coinaddr,dstr(value),dstr(remains)); + if ( remains <= 0 ) + break; + } + else + { + char str[65];printf("couldnt get script for %s.%d\n",bits256_str(str,T[txidind].txid),u->vout); + free_json(vins); + return(0); + } + } + else + { + printf("illegal txidind.%d [%d]\n",txidind,outpt.hdrsi); + free_json(vins); + return(0); + } + } + else + { + printf("%s illegal unspentind.u%d [%d]\n",coin->symbol,outpt.unspentind,outpt.hdrsi); + free_json(vins); + return(0); + } + } + *totalp = total; + return(vins); +} + +char *iguana_signrawtx(struct supernet_info *myinfo,struct iguana_info *coin,int32_t height,bits256 *signedtxidp,int32_t *completedp,cJSON *vins,char *rawtx,cJSON *privkeys,struct vin_info *V) { - uint8_t addrtype,rmd160[20]; int32_t i,j,numwaddrs,numunspents=0; struct iguana_waddress **waddrs,*waddr; uint64_t *unspents; + char *signedtx = 0; struct iguana_msgtx msgtx; int32_t numinputs,flagV = 0,flag = 0; + *completedp = 0; + if ( privkeys == 0 ) + privkeys = iguana_privkeysjson(myinfo,coin,vins), flag = 1; + if ( (numinputs= cJSON_GetArraySize(vins)) > 0 && privkeys != 0 ) + { + memset(&msgtx,0,sizeof(msgtx)); + if ( V == 0 ) + V = calloc(numinputs,sizeof(*V)), flagV = 1; + //printf("SIGN.(%s) priv.(%s) %llx %llx\n",jprint(vins,0),jprint(privkeys,0),(long long)V->signers[0].privkey.txid,(long long)V->signers[1].privkey.txid); + if ( V != 0 ) + { + if ( iguana_signrawtransaction(myinfo,coin,height,&msgtx,&signedtx,signedtxidp,V,numinputs,rawtx,vins,privkeys) > 0 ) + *completedp = 1; + else printf("signrawtransaction incomplete\n"); + if ( flagV != 0 ) + free(V); + } + if ( flag != 0 ) + free_json(privkeys); + } + printf("signed.(%s)\n",signedtx!=0?signedtx:""); + return(signedtx); +} + +bits256 iguana_sendrawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,char *signedtx) +{ + bits256 txid; uint8_t *serialized; int32_t i,len,n; struct iguana_peer *addr; cJSON *vals; char *str; + len = (int32_t)strlen(signedtx) >> 1; + serialized = calloc(1,sizeof(struct iguana_msghdr) + len); + decode_hex(&serialized[sizeof(struct iguana_msghdr)],len,signedtx); + txid = bits256_doublesha256(0,&serialized[sizeof(struct iguana_msghdr)],len); + if ( coin->peers != 0 && (n= coin->peers->numranked) > 0 ) + { + for (i=0; i<8 && ipeers->ranked[i]) != 0 && addr->dead == 0 && addr->usock >= 0 ) + iguana_queue_send(addr,0,serialized,"tx",len); + } + } + else + { + vals = cJSON_CreateObject(); + jaddstr(vals,"symbol",coin->symbol); + if ( (str= gecko_sendrawtransaction(myinfo,coin->symbol,serialized,len,txid,vals,signedtx)) != 0 ) + free(str); + free_json(vals); + } + free(serialized); + return(txid); +} + +char *iguana_calcrawtx(struct supernet_info *myinfo,struct iguana_info *coin,cJSON **vinsp,cJSON *txobj,int64_t satoshis,char *changeaddr,int64_t txfee,cJSON *addresses,int32_t minconf,uint8_t *opreturn,int32_t oplen,int64_t burnamount,char *remoteaddr) +{ + uint8_t addrtype,rmd160[20],spendscript[IGUANA_MAXSCRIPTSIZE]; int32_t max,num,spendlen; char *rawtx=0; bits256 txid; cJSON *vins=0; uint64_t avail,total,change; struct iguana_outpoint *unspents = 0; struct vin_info *V=0; + *vinsp = 0; + max = 10000; + satoshis += burnamount; + unspents = calloc(max,sizeof(*unspents)); + if ( (num= iguana_RTunspentslists(myinfo,coin,&avail,unspents,max,satoshis+txfee,minconf,addresses,remoteaddr)) <= 0 ) + { + free(unspents); + return(0); + } + if ( txobj != 0 && avail >= satoshis+txfee ) + { + if ( (vins= iguana_RTinputsjson(myinfo,coin,&total,satoshis + txfee,unspents,num)) != 0 ) + { + if ( total < (satoshis + txfee) ) + { + free_json(vins); + free(unspents); + printf("insufficient total %.8f vs (%.8f + %.8f)\n",dstr(total),dstr(satoshis),dstr(txfee)); + return(0); + } + if ( (change= (total - (satoshis + txfee))) > 0 && (changeaddr == 0 || changeaddr[0] == 0) ) + { + printf("no changeaddr for %.8f\n",dstr(change)); + free_json(vins); + free(unspents); + return(0); + } + iguana_createvins(myinfo,coin,txobj,vins); + if ( change > 0 ) + { + if ( iguana_addressvalidate(coin,&addrtype,changeaddr) < 0 ) + { + free_json(vins); + free(unspents); + printf("illegal destination address.(%s)\n",changeaddr); + return(0); + } + bitcoin_addr2rmd160(&addrtype,rmd160,changeaddr); + spendlen = bitcoin_standardspend(spendscript,0,rmd160); + bitcoin_txoutput(txobj,spendscript,spendlen,change); + int32_t i; for (i=0; iMAXPEERS == 1 || coin->FULLNODE != 0 || coin->VALIDATENODE != 0 ) + { + num = cJSON_GetArraySize(vins); + for (i=0; i [comment] [comment-to] is a real and is rounded to 8 decimal places. Returns the transaction ID if successful. Y + if ( account == 0 || account[0] == 0 ) + account = "*"; + addresses = iguana_getaddressesbyaccount(myinfo,coin,account); + if ( coin->changeaddr[0] == 0 ) + { + //if ( (waddr= iguana_getaccountaddress(myinfo,coin,0,0,coin->changeaddr,"change")) == 0 ) + // return(clonestr("{\"error\":\"no change address specified\"}")); + bitcoin_address(coin->changeaddr,coin->chain->pubtype,myinfo->persistent_pubkey33,33); + printf("%s change %s\n",coin->symbol,coin->changeaddr); + } if ( coinaddr != 0 && coinaddr[0] != 0 && satoshis != 0 ) { - if ( iguana_addressvalidate(coin,&addrtype,rmd160,coinaddr) < 0 ) + if ( iguana_addressvalidate(coin,&addrtype,coinaddr) < 0 ) return(clonestr("{\"error\":\"invalid coin address\"}")); - waddrs = (struct iguana_waddress **)coin->blockspace; - numwaddrs = iguana_unspentslists(myinfo,coin,waddrs,(int32_t)(sizeof(coin->blockspace)/sizeof(*waddrs)),satoshis,minconf,0); - if ( numwaddrs > 0 ) + bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr); + spendlen = bitcoin_standardspend(spendscript,0,rmd160); + init_hexbytes_noT(spendscriptstr,spendscript,spendlen); + basilisktag = (uint32_t)rand(); + valsobj = cJSON_CreateObject(); + jadd(valsobj,"addresses",addresses); + jaddstr(valsobj,"coin",coin->symbol); + jaddstr(valsobj,"changeaddr",coin->changeaddr); + jaddstr(valsobj,"spendscript",spendscriptstr); + jadd64bits(valsobj,"satoshis",satoshis); + jadd64bits(valsobj,"txfee",txfee); + jaddnum(valsobj,"minconf",minconf); + jaddnum(valsobj,"basilisktag",basilisktag); + jaddnum(valsobj,"locktime",locktime); + jaddnum(valsobj,"timeout",30000); + if ( 0 && comment != 0 && is_hexstr(comment,0) > 0 ) + jaddstr(valsobj,"opreturn",comment); + if ( (retstr= basilisk_bitcoinrawtx(myinfo,coin,remoteaddr,basilisktag,jint(valsobj,"timeout"),valsobj)) != 0 ) { - unspents = (uint64_t *)((long)coin->blockspace + sizeof(*waddrs)*numwaddrs); - for (i=0; inumunspents > 0 ) + if ( (rawtx= jstr(retjson,"rawtx")) != 0 && (vins= jobj(retjson,"vins")) != 0 ) { - for (j=0; jnumunspents; j++) - printf("([%d].u%u) ",(uint32_t)(unspents[i]>>32),(uint32_t)unspents[i]); - printf("(%s %.8f)\n",waddr->coinaddr,dstr(waddr->balance)); + if ( (signedtx= iguana_signrawtx(myinfo,coin,coin->blocks.hwmchain.height,&signedtxid,&completed,vins,rawtx,0,0)) != 0 ) + { + iguana_RTunspentslock(myinfo,coin,vins); + retjson = cJSON_CreateObject(); + jaddbits256(retjson,"result",signedtxid); + jaddstr(retjson,"signedtx",signedtx); + jadd(retjson,"complete",completed != 0 ? jtrue() : jfalse()); + if ( completed != 0 ) + { + senttxid = iguana_sendrawtransaction(myinfo,coin,signedtx); + if ( bits256_cmp(senttxid,signedtxid) == 0 ) + jaddstr(retjson,"sendrawtransaction","success"); + else jaddbits256(retjson,"senderror",senttxid); + } + free_json(vins); + free(signedtx); + return(jprint(retjson,1)); + } + else + { + free_json(vins); + return(clonestr("{\"error\":\"couldnt sign rawtx\"}")); + } } + free_json(retjson); } - } - printf("need to generate send %.8f to %s [%s] [%s] using numaddrs.%d numunspents.%d\n",dstr(satoshis),coinaddr,comment!=0?comment:"",comment2!=0?comment2:"",numwaddrs,numunspents); + free(retstr); + return(clonestr("{\"error\":\"couldnt create rawtx\"}")); + } else return(clonestr("{\"error\":\"couldnt create rawtx\"}")); } return(clonestr("{\"error\":\"need address and amount\"}")); } @@ -191,22 +521,11 @@ char *sendtoaddress(struct supernet_info *myinfo,struct iguana_info *coin,char * STRING_AND_INT(bitcoinrpc,sendrawtransaction,rawtx,allowhighfees) { - cJSON *retjson = cJSON_CreateObject(); char txidstr[65]; bits256 txid; uint8_t *serialized; struct iguana_peer *addr; int32_t i,len = (int32_t)strlen(rawtx) >> 1; + cJSON *retjson = cJSON_CreateObject(); bits256 txid; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); - if ( coin->peers.numranked >= 8 ) - { - serialized = calloc(1,sizeof(struct iguana_msghdr) + len); - decode_hex(&serialized[sizeof(struct iguana_msghdr)],len,rawtx); - for (i=0; i<8; i++) - { - if ( (addr= coin->peers.ranked[i]) != 0 && addr->dead == 0 && addr->usock >= 0 ) - iguana_queue_send(coin,addr,0,serialized,"tx",len,0,0); - } - free(serialized); - txid = bits256_doublesha256(txidstr,&serialized[sizeof(struct iguana_msghdr)],len); - jaddstr(retjson,"result",txidstr); - } else jaddstr(retjson,"error","no peers"); + txid = iguana_sendrawtransaction(myinfo,coin,rawtx); + jaddbits256(retjson,"result",txid); return(jprint(retjson,1)); } @@ -219,7 +538,7 @@ STRING_ARG(bitcoinrpc,submitblock,rawbytes) return(jprint(retjson,1)); } -ZERO_ARGS(bitcoinrpc,makekeypair) +ZERO_ARGS(iguana,makekeypair) { if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); @@ -227,13 +546,13 @@ ZERO_ARGS(bitcoinrpc,makekeypair) privkey = rand256(1); jaddstr(retjson,"result","success"); jaddstr(retjson,"privkey",bits256_str(str,privkey)); - jadd(retjson,"rosetta",SuperNET_rosettajson(privkey,1)); + jadd(retjson,"rosetta",SuperNET_rosettajson(myinfo,privkey,1)); return(jprint(retjson,1)); } STRING_ARG(bitcoinrpc,validatepubkey,pubkeystr) { - uint8_t rmd160[20],pubkey[65],addrtype = 0; int32_t plen; char coinaddr[128],*str; cJSON *retjson; + uint8_t pubkey[65],addrtype = 0; int32_t plen; char coinaddr[128],*str; cJSON *retjson; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); plen = (int32_t)strlen(pubkeystr) >> 1; @@ -243,7 +562,7 @@ STRING_ARG(bitcoinrpc,validatepubkey,pubkeystr) decode_hex(pubkey,plen,pubkeystr); if ( (str= bitcoin_address(coinaddr,addrtype,pubkey,plen)) != 0 ) { - if ( iguana_addressvalidate(coin,&addrtype,rmd160,coinaddr) < 0 ) + if ( iguana_addressvalidate(coin,&addrtype,coinaddr) < 0 ) return(clonestr("{\"error\":\"invalid coin address\"}")); retjson = cJSON_CreateObject(); jaddstr(retjson,"result","success"); @@ -359,27 +678,42 @@ INT_ARRAY_STRING(bitcoinrpc,addmultisigaddress,M,pubkeys,account) // HASH_AND_TWOINTS(bitcoinrpc,gettxout,txid,vout,mempool) { - uint8_t script[IGUANA_MAXSCRIPTSIZE],rmd160[20],pubkey33[33]; char coinaddr[128],asmstr[IGUANA_MAXSCRIPTSIZE*2+1]; struct iguana_bundle *bp; int32_t minconf,scriptlen,unspentind,height,spentheight; int64_t RTspend; struct iguana_ramchaindata *rdata; struct iguana_pkhash *P; struct iguana_txid *T; struct iguana_unspent *U; struct iguana_ramchain *ramchain; cJSON *scriptobj,*retjson = cJSON_CreateObject(); + uint8_t script[IGUANA_MAXSCRIPTSIZE],rmd160[20],pubkey33[33]; char coinaddr[128],asmstr[IGUANA_MAXSCRIPTSIZE*2+1]; struct iguana_bundle *bp; int32_t minconf,scriptlen,unspentind,height,spentheight; int64_t RTspend; int64_t value; struct iguana_ramchaindata *rdata; struct iguana_pkhash *P; struct iguana_txid *T; struct iguana_unspent *U; struct iguana_outpoint outpt; struct iguana_ramchain *ramchain; cJSON *scriptobj,*retjson = cJSON_CreateObject(); if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); if ( coin != 0 ) { + if ( (value= _RTgettxout(coin,&height,&scriptlen,script,rmd160,coinaddr,txid,vout,mempool)) > 0 ) + { + jaddbits256(retjson,"bestblock",coin->blocks.hwmchain.RO.hash2); + jaddnum(retjson,"bestheight",coin->blocks.hwmchain.height); + jaddnum(retjson,"height",height); + jaddnum(retjson,"confirmations",coin->blocks.hwmchain.height - height + 1); + jaddnum(retjson,"value",dstr(value)); + if ( (height % coin->chain->bundlesize) == 0 && vout == 0 ) + jadd(retjson,"coinbase",jtrue()); + else jadd(retjson,"coinbase",jfalse()); + asmstr[0] = 0; + if ( (scriptobj= iguana_scriptobj(coin,rmd160,coinaddr,asmstr,script,scriptlen)) != 0 ) + jadd(retjson,"scriptPubKey",scriptobj); + return(jprint(retjson,1)); + } minconf = (mempool != 0) ? 0 : 1; - if ( (unspentind= iguana_unspentindfind(coin,0,0,0,0,&height,txid,vout,coin->bundlescount-1)) != 0 ) + if ( (unspentind= iguana_RTunspentindfind(myinfo,coin,0,0,0,0,&height,txid,vout,coin->bundlescount-1,0)) != 0 ) { if ( height >= 0 && height < coin->longestchain && (bp= coin->bundles[height / coin->chain->bundlesize]) != 0 ) { - ramchain = (bp == coin->current) ? &coin->RTramchain : &bp->ramchain; + ramchain = &bp->ramchain; if ( (rdata= ramchain->H.data) != 0 ) { U = RAMCHAIN_PTR(rdata,Uoffset); P = RAMCHAIN_PTR(rdata,Poffset); T = RAMCHAIN_PTR(rdata,Toffset); - //U = (void *)(long)((long)rdata + rdata->Uoffset); - //P = (void *)(long)((long)rdata + rdata->Poffset); - //T = (void *)(long)((long)rdata + rdata->Toffset); RTspend = 0; - if ( iguana_spentflag(coin,&RTspend,&spentheight,ramchain,bp->hdrsi,unspentind,height,minconf,coin->longestchain,U[unspentind].value) == 0 ) + memset(&outpt,0,sizeof(outpt)); + outpt.hdrsi = bp->hdrsi; + outpt.unspentind = unspentind; + if ( iguana_RTspentflag(myinfo,coin,&RTspend,&spentheight,ramchain,outpt,height,minconf,coin->longestchain,U[unspentind].value) == 0 ) { jaddbits256(retjson,"bestblock",coin->blocks.hwmchain.RO.hash2); jaddnum(retjson,"bestheight",coin->blocks.hwmchain.height); @@ -394,7 +728,7 @@ HASH_AND_TWOINTS(bitcoinrpc,gettxout,txid,vout,mempool) if ( (scriptobj= iguana_scriptobj(coin,rmd160,coinaddr,asmstr,script,scriptlen)) != 0 ) jadd(retjson,"scriptPubKey",scriptobj); } - jadd(retjson,"iguana",iguana_unspentjson(myinfo,coin,bp->hdrsi,unspentind,T,&U[unspentind],rmd160,coinaddr,pubkey33)); + jadd(retjson,"iguana",iguana_RTunspentjson(myinfo,coin,outpt,T[U[unspentind].txidind].txid,unspentind-T[U[unspentind].txidind].firstvout,U[unspentind].value,&U[unspentind],rmd160,coinaddr,pubkey33,spentheight,remoteaddr)); if ( (height % coin->chain->bundlesize) == 0 && vout == 0 ) jadd(retjson,"coinbase",jtrue()); else jadd(retjson,"coinbase",jfalse()); @@ -499,68 +833,213 @@ THREE_STRINGS(bitcoinrpc,verifymessage,address,sig,message) HASH_AND_INT(bitcoinrpc,getrawtransaction,txid,verbose) { - struct iguana_txid *tx,T; char *txbytes; bits256 checktxid; int32_t len,height; cJSON *retjson,*txobj; + struct iguana_txid *tx,T; char *txbytes; bits256 checktxid; int32_t len=0,height,extralen=65536; cJSON *retjson,*txobj; uint8_t *extraspace; struct iguana_block *block; bits256 hash2; struct iguana_RTtxid *RTptr; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); - if ( (tx= iguana_txidfind(coin,&height,&T,txid,coin->bundlescount-1)) != 0 ) + HASH_FIND(hh,coin->RTdataset,txid.bytes,sizeof(txid),RTptr); + if ( RTptr != 0 && RTptr->rawtxbytes != 0 && RTptr->txlen > 0 ) { - retjson = cJSON_CreateObject(); - if ( (len= iguana_ramtxbytes(coin,coin->blockspace,sizeof(coin->blockspace),&checktxid,tx,height,0,0,0)) > 0 ) + checktxid = RTptr->txid; + height = RTptr->height; + len = RTptr->txlen; + memcpy(coin->blockspace,RTptr->rawtxbytes,len); + } + else if ( (tx= iguana_txidfind(coin,&height,&T,txid,coin->bundlescount-1)) != 0 ) + { + len = iguana_ramtxbytes(coin,coin->blockspace,coin->blockspacesize,&checktxid,tx,height,0,0,0); + } + retjson = cJSON_CreateObject(); + if ( len > 0 ) + { + txbytes = calloc(1,len*2+1); + init_hexbytes_noT(txbytes,coin->blockspace,len); + if ( verbose != 0 ) { - txbytes = calloc(1,len*2+1); - init_hexbytes_noT(txbytes,coin->blockspace,len); - if ( verbose != 0 ) + extraspace = calloc(1,extralen); + txobj = bitcoin_hex2json(coin,coin->blocks.hwmchain.height,&checktxid,0,txbytes,extraspace,extralen,0,0,0); + free(extraspace); + free(txbytes); + if ( txobj != 0 ) { - txobj = bitcoin_hex2json(coin,&checktxid,0,txbytes); - free(txbytes); - if ( txobj != 0 ) - return(jprint(txobj,1)); + hash2 = iguana_blockhash(coin,height); + jaddbits256(txobj,"blockhash",hash2); + if ( (block= iguana_blockfind("rawtx",coin,hash2)) != 0 ) + jaddnum(txobj,"blocktime",block->RO.timestamp); + jaddnum(txobj,"height",height); + jaddnum(txobj,"confirmations",coin->blocks.hwmchain.height - height); + return(jprint(txobj,1)); } - jaddstr(retjson,"result",txbytes); - printf("txbytes.(%s) len.%d (%s)\n",txbytes,len,jprint(retjson,0)); - free(txbytes); + } + jaddstr(retjson,"result",txbytes); + char str[65]; printf("txbytes.(%s) len.%d (%s) %s\n",txbytes,len,jprint(retjson,0),bits256_str(str,checktxid)); + free(txbytes); + return(jprint(retjson,1)); + } + else if ( height >= 0 ) + { + if ( coin->APIblockstr != 0 ) + jaddstr(retjson,"error","already have pending request"); + else + { + int32_t datalen; uint8_t *data; char *blockstr; bits256 blockhash; + blockhash = iguana_blockhash(coin,height); + if ( (blockstr= iguana_APIrequest(coin,blockhash,txid,2)) != 0 ) + { + datalen = (int32_t)(strlen(blockstr) >> 1); + data = malloc(datalen); + decode_hex(data,datalen,blockstr); + if ( (txbytes= iguana_txscan(coin,verbose != 0 ? retjson : 0,data,datalen,txid)) != 0 ) + { + jaddstr(retjson,"result",txbytes); + jaddbits256(retjson,"blockhash",blockhash); + jaddnum(retjson,"height",height); + free(txbytes); + } else jaddstr(retjson,"error","cant find txid in block"); + free(blockstr); + free(data); + } else jaddstr(retjson,"error","cant find blockhash"); return(jprint(retjson,1)); } - else if ( height >= 0 ) + } + return(clonestr("{\"error\":\"cant find txid\"}")); +} + +int64_t iguana_lockval(int32_t finalized,int64_t locktime) +{ + int64_t lockval = -1; + if ( finalized == 0 ) + return(locktime); + return(lockval); +} + +char *iguana_validaterawtx(struct supernet_info *myinfo,struct iguana_info *coin,int32_t height,struct iguana_msgtx *msgtx,uint8_t *extraspace,int32_t extralen,char *rawtx,int32_t mempool,int32_t suppress_pubkeys) +{ + bits256 signedtxid,txid; struct iguana_msgvin vin; cJSON *log,*vins,*vouts,*txobj,*retjson; char *checkstr,*signedtx; int32_t finalized = 1,i,len,maxsize,numinputs,numoutputs,complete; struct vin_info *V; uint8_t *serialized,*serialized2; uint32_t sigsize,pubkeysize,p2shsize,suffixlen; int64_t inputsum,outputsum,lockval; + retjson = cJSON_CreateObject(); + inputsum = outputsum = numinputs = numoutputs = 0; + if ( rawtx != 0 && rawtx[0] != 0 && coin != 0 ) + { + if ( (strlen(rawtx) & 1) != 0 ) + return(clonestr("{\"error\":\"rawtx hex has odd length\"}")); + memset(msgtx,0,sizeof(*msgtx)); + if ( (txobj= bitcoin_hex2json(coin,coin->blocks.hwmchain.height,&msgtx->txid,msgtx,rawtx,extraspace,extralen,0,0,suppress_pubkeys)) != 0 ) { - if ( coin->APIblockstr != 0 ) - jaddstr(retjson,"error","already have pending request"); - else + //printf("txobj.(%s)\n",jprint(txobj,0)); + if ( (checkstr= bitcoin_json2hex(myinfo,coin,&txid,txobj,0)) != 0 ) { - int32_t datalen; uint8_t *data; char *blockstr; bits256 blockhash; - blockhash = iguana_blockhash(coin,height); - if ( (blockstr= iguana_APIrequest(coin,blockhash,txid,2)) != 0 ) + if ( strcmp(rawtx,checkstr) != 0 ) { - datalen = (int32_t)(strlen(blockstr) >> 1); - data = malloc(datalen); - decode_hex(data,datalen,blockstr); - if ( (txbytes= iguana_txscan(coin,verbose != 0 ? retjson : 0,data,datalen,txid)) != 0 ) + jaddstr(retjson,"error","converting from hex2json and json2hex mismatch"); + jaddstr(retjson,"original",rawtx); + jaddstr(retjson,"checkstr",checkstr); + for (i=0; rawtx[i]!=0 && checkstr[i]!=0; i++) + if ( rawtx[i] != checkstr[i] ) + break; + jaddnum(retjson,"mismatch position",i); + jadd(retjson,"origtx",txobj); + if ( (txobj= bitcoin_hex2json(coin,coin->blocks.hwmchain.height,&txid,msgtx,checkstr,extraspace,extralen,0,0,suppress_pubkeys)) != 0 ) + jadd(retjson,"checktx",txobj); + free(checkstr); + return(jprint(retjson,1)); + } + free(checkstr); + } + if ( (vouts= jarray(&numoutputs,txobj,"vout")) > 0 ) + { + struct iguana_msgvout vout; uint8_t voutdata[IGUANA_MAXSCRIPTSIZE]; + for (i=0; i 0 ) + outputsum += vout.value; + } + } + if ( (vins= jarray(&numinputs,txobj,"vin")) > 0 ) + { + maxsize = (int32_t)strlen(rawtx); + serialized = malloc(maxsize); + serialized2 = malloc(maxsize); + len = 0; + V = calloc(numinputs,sizeof(*V)); + for (i=0; ivins[i].prev_hash,msgtx->vins[i].prev_vout,coin->bundlescount-1,mempool)) > 0 ) { - jaddstr(retjson,"result",txbytes); - jaddbits256(retjson,"blockhash",blockhash); - jaddnum(retjson,"height",height); - free(txbytes); - } else jaddstr(retjson,"error","cant find txid in block"); - free(blockstr); - free(data); - } else jaddstr(retjson,"error","cant find blockhash"); - return(jprint(retjson,1)); + inputsum += V[i].amount; + msgtx->vins[i].spendscript = V[i].spendscript; + msgtx->vins[i].spendlen = V[i].spendlen; + V[i].hashtype = iguana_vinscriptparse(coin,&V[i],&sigsize,&pubkeysize,&p2shsize,&suffixlen,msgtx->vins[i].vinscript,msgtx->vins[i].scriptlen); + V[i].userdatalen = suffixlen; + memcpy(V[i].spendscript,msgtx->vins[i].spendscript,msgtx->vins[i].spendlen); + V[i].spendlen = msgtx->vins[i].spendlen; + if ( msgtx->vins[i].sequence < IGUANA_SEQUENCEID_FINAL ) + finalized = 0; + //printf("V %.8f (%s) spendscript.[%d] scriptlen.%d\n",dstr(V[i].amount),V[i].coinaddr,V[i].spendlen,V[i].spendlen); + } + } + V[0].suppress_pubkeys = suppress_pubkeys; + if ( (complete= bitcoin_verifyvins(coin,height,&signedtxid,&signedtx,msgtx,serialized2,maxsize,V,1,0,suppress_pubkeys)) > 0 && signedtx != 0 ) + { + msgtx->txid = signedtxid; + log = cJSON_CreateArray(); + lockval = iguana_lockval(finalized,jint(txobj,"locktime")); + if ( iguana_interpreter(coin,log,lockval,V,numinputs) < 0 ) + { + jaddstr(retjson,"error","interpreter rejects tx"); + } + jadd(retjson,"interpreter",log); + } + jaddnum(retjson,"complete",complete); + free(serialized), free(serialized2); } - } else printf("height.%d\n",height); + } + //char str[65]; printf("got txid.(%s)\n",bits256_str(str,txid)); } - return(clonestr("{\"error\":\"cant find txid\"}")); + msgtx->inputsum = inputsum; + msgtx->numinputs = numinputs; + msgtx->outputsum = outputsum; + msgtx->numoutputs = numoutputs; + msgtx->txfee = (inputsum - outputsum); + return(jprint(retjson,1)); +} + +STRING_AND_INT(bitcoinrpc,validaterawtransaction,rawtx,suppress) +{ + uint8_t *extraspace; int32_t extralen=65536;// char *retstr; struct iguana_msgtx msgtx; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + + //cJSON *txobj; char *teststr= "{\"version\":1,\"locktime\":0,\"vin\":[{\"userdata\":\"20fe936da3707c8c4cc7eb0352160ec3f50b9454d46425df6347b2fbc5b2ec87ea00\",\"txid\":\"ee12e50b629d5d45438570fff841d1a2ba7d27f356de4aa06900c9a5e38cf141\",\"vout\":0,\"scriptPubKey\":{\"hex\":\"a9145cc47cc123e3f9b7dce0230009b9d3013a9e0c9687\"},\"suppress\":1,\"redeemScript\":\"6304165daa57b1752102a9669e63ef1ab04913615c2f3887ea3584f81e5f08feee9535b19ab3739d8afdac67a9143805600256ed8498ca1ec426759212e5835e8dc2882103a7b696908f77d69ec89887f8c4a0423b9e80b5974dc43301bd7d8abad07e1211ac68\"}],\"vout\":[{\"satoshis\":\"21821\",\"scriptPubkey\":{\"hex\":\"76a9143ef4734c1141725c095342095f6e0e7748b6c16588ac\"}}]}"; + + cJSON *txobj; char *teststr= "{\"version\":1,\"locktime\":0,\"vin\":[{\"userdata\":\"206efad760ee54b9b2e2a038a821ef9f950eb0e248545ac202c3e2074cd14f92cb00\",\"txid\":\"3f4759381a62154f2f0eefed1e4433342548ad7b269f912820383b715a39273c\",\"vout\":0,\"scriptPubKey\":{\"hex\":\"a91446dcccef39c1d8c6da2ccc35dce2bfa7ec0d168887\"},\"suppress\":1,\"redeemScript\":\"63041c60aa57b1752103175cf93574c31637b8c2d8acd5319e3cd23761b5e418d32c6bcb194972ba9273ac67a9142d75daf71325feaa593b8f30989e462892189914882102a9669e63ef1ab04913615c2f3887ea3584f81e5f08feee9535b19ab3739d8afdac68\"}],\"vout\":[{\"satoshis\":\"18625\",\"scriptPubkey\":{\"hex\":\"76a914b7128d2ee837cf03e30a2c0e3e0181f7b9669bb688ac\"}}]}"; + // 01000000013c27395a713b382028919f267bad48253433441eedef0e2f4f15621a3859473f00000000d147304402207ecd423b55c1aa45a994c4eb4337ff0891692fbb69954a9ba024745a99c5272d02207cea696425feb5388153ab7f2608d66a66e4c95cfda2d44e98bc56e25994d3f701206efad760ee54b9b2e2a038a821ef9f950eb0e248545ac202c3e2074cd14f92cb004c6763041c60aa57b1752103175cf93574c31637b8c2d8acd5319e3cd23761b5e418d32c6bcb194972ba9273ac67a9142d75daf71325feaa593b8f30989e462892189914882102a9669e63ef1ab04913615c2f3887ea3584f81e5f08feee9535b19ab3739d8afdac68ffffffff01c1480000000000001976a914b7128d2ee837cf03e30a2c0e3e0181f7b9669bb688ac00000000 + // 01000000013c27395a713b382028919f267bad48253433441eedef0e2f4f15621a3859473f00000000fd8b00206efad760ee54b9b2e2a038a821ef9f950eb0e248545ac202c3e2074cd14f92cb004c6763041c60aa57b1752103175cf93574c31637b8c2d8acd5319e3cd23761b5e418d32c6bcb194972ba9273ac67a9142d75daf71325feaa593b8f30989e462892189914882102a9669e63ef1ab04913615c2f3887ea3584f81e5f08feee9535b19ab3739d8afdac68ffffffff01c1480000000000001976a914b7128d2ee837cf03e30a2c0e3e0181f7b9669bb688ac00000000 + //cJSON *txobj; char *teststr= "{\"version\":1,\"locktime\":0,\"vin\":[{\"userdata\":\"20ae439d344513eab8e718d8214fe6ae8133b8b5b594afd64da21d0e40b9c37cdd00\",\"txid\":\"2c1320315f4fb519cbf2b4d7b67855013b9a09a85e515df43b41d407a0083b09\",\"vout\":0,\"scriptPubKey\":{\"hex\":\"a9142e7674400d04217f770f2222126dc7fee44b06b487\"},\"suppress\":1,\"redeemScript\":\"63041686a657b1752102a9669e63ef1ab04913615c2f3887ea3584f81e5f08feee9535b19ab3739d8afdac67a914ed74c61c27656abc6c20687c3a9212ffdc6f34cd88210398a4cb9f6ea7c52a4e27455028a95e2e4e397a110fb75f072c2c58a8bdcbf4baac68\"}],\"vout\":[{\"satoshis\":\"16733\",\"scriptPubkey\":{\"hex\":\"76a91454a752f0d71b89d7c014ed0be29ca231c9546f9f88ac\"}}]}"; + extraspace = calloc(1,extralen); + if ( (txobj= cJSON_Parse(teststr)) != 0 ) + { + bits256 txid; + rawtx = bitcoin_json2hex(myinfo,coin,&txid,txobj,0); + txobj = bitcoin_hex2json(coin,coin->blocks.hwmchain.height,&txid,0,rawtx,extraspace,extralen,0,0,suppress); + printf("RAWTX.(%s) -> (%s)\n",rawtx,jprint(txobj,0)); + } + //retstr = iguana_validaterawtx(myinfo,coin,coin->blocks.hwmchain.height,&msgtx,extraspace,extralen,rawtx,0,suppress); + free(extraspace); + return(rawtx); } -STRING_ARG(bitcoinrpc,decoderawtransaction,rawtx) +STRING_AND_INT(bitcoinrpc,decoderawtransaction,rawtx,suppress) { - cJSON *txobj = 0; bits256 txid; + cJSON *txobj = 0; bits256 txid; uint8_t *extraspace; int32_t extralen = 65536; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); if ( rawtx != 0 && rawtx[0] != 0 ) { if ( (strlen(rawtx) & 1) != 0 ) return(clonestr("{\"error\":\"rawtx hex has odd length\"}")); - txobj = bitcoin_hex2json(coin,&txid,0,rawtx); + extraspace = calloc(1,extralen); + txobj = bitcoin_hex2json(coin,coin->blocks.hwmchain.height,&txid,0,rawtx,extraspace,extralen,0,0,suppress); + free(extraspace); //char str[65]; printf("got txid.(%s)\n",bits256_str(str,txid)); } if ( txobj == 0 ) @@ -601,10 +1080,10 @@ cJSON *iguana_createvins(struct supernet_info *myinfo,struct iguana_info *coin,c spendlen = (int32_t)strlen(hexstr) >> 1; decode_hex(spendscript,spendlen,hexstr); } - if ( (unspentind= iguana_unspentindfind(coin,coinaddr,spendscript,&spendlen,&satoshis,&height,txid,vout,coin->bundlescount-1)) > 0 ) + if ( (unspentind= iguana_RTunspentindfind(myinfo,coin,coinaddr,spendscript,&spendlen,&satoshis,&height,txid,vout,coin->bundlescount-1,0)) > 0 ) { - printf("[%d] unspentind.%d (%s) spendlen.%d %.8f\n",height/coin->chain->bundlesize,unspentind,coinaddr,spendlen,dstr(satoshis)); - if ( coinaddr[0] != 0 && (waddr= iguana_waddresssearch(myinfo,coin,&wacct,coinaddr)) != 0 ) + //printf("[%d] unspentind.%d (%s) spendlen.%d %.8f\n",height/coin->chain->bundlesize,unspentind,coinaddr,spendlen,dstr(satoshis)); + if ( coinaddr[0] != 0 && (waddr= iguana_waddresssearch(myinfo,&wacct,coinaddr)) != 0 ) { init_hexbytes_noT(pubkeystr,waddr->pubkey,bitcoin_pubkeylen(waddr->pubkey)); jaddistr(pubkeys,pubkeystr); @@ -622,9 +1101,14 @@ cJSON *iguana_createvins(struct supernet_info *myinfo,struct iguana_info *coin,c init_hexbytes_noT(scriptstr,redeemscript,p2shlen); jaddstr(newvin,"redeemScript",scriptstr); } - if ( jobj(item,"sequence") != 0 ) - sequenceid = juint(item,"sequence"); - else sequenceid = 0xffffffff; + if ( jint(txobj,"locktime") > 0 ) + sequenceid = (uint32_t)time(NULL); // any value < 0xfffffffe should be fine + else + { + if ( jobj(item,"sequence") != 0 ) + sequenceid = juint(item,"sequence"); + else sequenceid = 0xffffffff; + } jaddnum(newvin,"sequence",sequenceid); bitcoin_txinput(coin,txobj,txid,vout,sequenceid,spendscript,spendlen,redeemscript,p2shlen,0,0); jadd(newvin,"pubkeys",pubkeys); @@ -639,20 +1123,21 @@ ARRAY_OBJ_INT(bitcoinrpc,createrawtransaction,vins,vouts,locktime) bits256 txid; int32_t offset,spendlen=0,n; uint8_t addrtype,rmd160[20],spendscript[IGUANA_MAXSCRIPTSIZE]; uint64_t satoshis; char *hexstr,*field,*txstr; cJSON *txobj,*item,*obj,*retjson = cJSON_CreateObject(); if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); - if ( coin != 0 && (txobj= bitcoin_txcreate(coin,locktime)) != 0 ) + if ( coin != 0 && (txobj= bitcoin_txcreate(coin->chain->isPoS,locktime,locktime==0?coin->chain->normal_txversion:coin->chain->locktime_txversion)) != 0 ) { iguana_createvins(myinfo,coin,txobj,vins); if ( (n= cJSON_GetArraySize(vouts)) > 0 ) { - if ( (item= vouts->child) != 0 && n == 1 ) + if ( is_cJSON_Array(vouts) != 0 && n == 1 && (item= jitem(vouts,0)) != 0 ) item = item->child; + else item = vouts->child; while ( item != 0 ) { if ( (field= jfieldname(item)) != 0 ) { if ( strcmp(field,"data") == 0 ) { - if ( (hexstr= jstr(item,"data")) != 0 ) + if ( (hexstr= jstr(item,0)) != 0 ) { spendlen = (int32_t)strlen(hexstr) >> 1; offset = 0; @@ -689,7 +1174,7 @@ ARRAY_OBJ_INT(bitcoinrpc,createrawtransaction,vins,vouts,locktime) if ( (obj= jobj(item,"amount")) != 0 ) satoshis = jdouble(obj,0) * SATOSHIDEN; else satoshis = 0; - bitcoin_txoutput(coin,txobj,spendscript+offset,spendlen,satoshis); + bitcoin_txoutput(txobj,spendscript+offset,spendlen,satoshis); } } break; @@ -700,7 +1185,7 @@ ARRAY_OBJ_INT(bitcoinrpc,createrawtransaction,vins,vouts,locktime) { spendlen = bitcoin_standardspend(spendscript,0,rmd160); satoshis = jdouble(item,0) * SATOSHIDEN; - bitcoin_txoutput(coin,txobj,spendscript,spendlen,satoshis); + bitcoin_txoutput(txobj,spendscript,spendlen,satoshis); } } } @@ -718,33 +1203,82 @@ ARRAY_OBJ_INT(bitcoinrpc,createrawtransaction,vins,vouts,locktime) TWOINTS_AND_ARRAY(bitcoinrpc,listunspent,minconf,maxconf,array) { - int32_t numrmds,numunspents=0; uint8_t *rmdarray; cJSON *retjson = cJSON_CreateArray(); + //int32_t numrmds,numunspents=0; uint8_t *rmdarray; cJSON *retjson = cJSON_CreateArray(); + cJSON *argarray,*retjson; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); if ( minconf == 0 ) minconf = 1; if ( maxconf == 0 ) - maxconf = 9999999; - rmdarray = iguana_rmdarray(coin,&numrmds,array,0); - iguana_unspents(myinfo,coin,retjson,minconf,maxconf,rmdarray,numrmds,0,0,&numunspents); - if ( rmdarray != 0 ) - free(rmdarray); + maxconf = (1 << 30); + if ( (argarray= array) == 0 || cJSON_GetArraySize(array) == 0 ) + argarray = iguana_getaddressesbyaccount(myinfo,coin,"*"); + retjson = iguana_RTlistunspent(myinfo,coin,argarray,minconf,maxconf,remoteaddr); + if ( argarray != array ) + free_json(argarray); return(jprint(retjson,1)); } -INT_AND_ARRAY(bitcoinrpc,lockunspent,flag,array) +ZERO_ARGS(bitcoinrpc,getrawchangeaddress) { if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); cJSON *retjson = cJSON_CreateObject(); + jaddstr(retjson,"result",coin->changeaddr); + return(jprint(retjson,1)); +} + +INT_AND_ARRAY(bitcoinrpc,lockunspent,flag,array) +{ + struct iguana_outpoint outpt; int32_t RTspendflag,vout,i,n,height,spentheight,lockedflag; cJSON *item,*retjson; bits256 txid; uint32_t unspentind; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + retjson = cJSON_CreateObject(); + if ( array != 0 && (n= cJSON_GetArraySize(array)) > 0 ) + { + for (i=0; ibundlescount-1,0)) != 0 ) + { + memset(&outpt,0,sizeof(outpt)); + outpt.hdrsi = height / coin->chain->bundlesize; + outpt.unspentind = unspentind; + iguana_RTutxofunc(coin,&spentheight,&lockedflag,outpt,&RTspendflag,!flag,0); + } + } + } + } return(jprint(retjson,1)); } ZERO_ARGS(bitcoinrpc,listlockunspent) { + cJSON *array,*retjson; //int32_t vout; //struct iguana_outpoint outpt; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); - cJSON *retjson = cJSON_CreateObject(); + array = cJSON_CreateArray(); + retjson = cJSON_CreateObject(); + printf("need to port listlockunspent to new RT method\n"); + jaddstr(retjson,"error","need to port listlockunspent to new RT method"); + /*if ( coin->utxotable != 0 ) + { + HASH_ITER(hh,coin->utxotable,hhutxo,tmputxo) + { + item = cJSON_CreateObject(); + //if ( (vout= iguana_RTuvaltxid(myinfo,&txid,coin,hhutxo->outpt)) >= 0 ) + { + jaddbits256(item,"txid",txid); + jaddnum(item,"vout",vout); + jaddi(array,item); + } + } + }*/ + jadd(retjson,"result",array); return(jprint(retjson,1)); } @@ -769,8 +1303,8 @@ S_D_SS(bitcoinrpc,sendtoaddress,address,amount,comment,comment2) if ( myinfo->expiration == 0 ) return(clonestr("{\"error\":\"need to unlock wallet\"}")); myinfo->expiration++; - iguana_unspentset(myinfo,coin); - return(sendtoaddress(myinfo,coin,address,amount * SATOSHIDEN,comment,comment2,coin->minconfirms,0)); + //iguana_unspentset(myinfo,coin); + return(sendtoaddress(myinfo,coin,remoteaddr,address,amount * SATOSHIDEN,coin->txfee,comment,comment2,coin->minconfirms,0)); } SS_D_I_SS(bitcoinrpc,sendfrom,fromaccount,toaddress,amount,minconf,comment,comment2) @@ -780,8 +1314,8 @@ SS_D_I_SS(bitcoinrpc,sendfrom,fromaccount,toaddress,amount,minconf,comment,comme if ( myinfo->expiration == 0 ) return(clonestr("{\"error\":\"need to unlock wallet\"}")); myinfo->expiration++; - iguana_unspentset(myinfo,coin); - return(sendtoaddress(myinfo,coin,toaddress,amount * SATOSHIDEN,comment,comment2,minconf,fromaccount)); + //iguana_unspentset(myinfo,coin); + return(sendtoaddress(myinfo,coin,remoteaddr,toaddress,amount * SATOSHIDEN,coin->txfee,comment,comment2,minconf,fromaccount)); } S_A_I_S(bitcoinrpc,sendmany,fromaccount,payments,minconf,comment) @@ -792,7 +1326,7 @@ S_A_I_S(bitcoinrpc,sendmany,fromaccount,payments,minconf,comment) if ( myinfo->expiration == 0 ) return(clonestr("{\"error\":\"need to unlock wallet\"}")); myinfo->expiration++; - iguana_unspentset(myinfo,coin); + //iguana_unspentset(myinfo,coin); n = cJSON_GetArraySize(payments); item = payments->child; for (required=i=0; itxfee,comment,"",minconf,fromaccount)) != 0 ) { free(str); } diff --git a/iguana/iguana_peers.c b/iguana/iguana_peers.c index 74243e12f..068dd8c49 100755 --- a/iguana/iguana_peers.c +++ b/iguana/iguana_peers.c @@ -20,25 +20,62 @@ struct iguana_iAddr *iguana_iAddrhashfind(struct iguana_info *coin,uint64_t ipbi int32_t iguana_validatehdr(char *symbol,struct iguana_msghdr *H) { - int32_t i = 0,len = -1; - if ( strcmp(symbol,"VPN") != 0 ) + int32_t i = 0,valid=0,len = -1; char cmdstr[16]; + memcpy(cmdstr,H->command,sizeof(H->command)); + cmdstr[0] = toupper((int32_t)cmdstr[0]); + cmdstr[5] = toupper((int32_t)cmdstr[5]); + cmdstr[6] = toupper((int32_t)cmdstr[6]); + cmdstr[7] = toupper((int32_t)cmdstr[7]); + if ( strcmp(symbol,"VPN") == 0 || strncmp("SuperNET",cmdstr,strlen("SuperNET")) == 0 ) + valid = 1; + else { for (i=0; Iguana_validcommands[i]!=0&&Iguana_validcommands[i][0]!=0; i++) if ( strcmp(H->command,Iguana_validcommands[i]) == 0 ) + { + valid = 1; break; + } } - if ( Iguana_validcommands[i][0] != 0 ) + if ( valid != 0 ) { iguana_rwnum(0,H->serdatalen,sizeof(H->serdatalen),(uint32_t *)&len); if ( len > IGUANA_MAXPACKETSIZE ) return(-1); - } + } else return(-1); return(len); } +struct iguana_peer *iguana_peeralive(struct iguana_peer *addr,int32_t needalive) +{ + if ( needalive == 0 || (addr->usock >= 0 && addr->dead == 0) ) + return(addr); + else return(0); +} + +struct iguana_peer *iguana_peerfindipaddr(struct iguana_info *coin,char *ipaddr,int32_t needalive) +{ + int32_t i; + for (i=0; ipeers->active[i].ipaddr) == 0 ) + return(iguana_peeralive(&coin->peers->active[i],needalive)); + return(0); +} + +struct iguana_peer *iguana_peerfindipbits(struct iguana_info *coin,uint32_t ipbits,int32_t needalive) +{ + int32_t i; + for (i=0; ipeers->active[i].ipbits ) + return(iguana_peeralive(&coin->peers->active[i],needalive)); + return(0); +} + struct iguana_iAddr *_iguana_hashset(struct iguana_info *coin,uint32_t ipbits,int32_t itemind) { struct iguana_iAddr *ptr = 0; int32_t allocsize; char str[65]; struct OS_memspace *mem = 0; + if ( coin->virtualchain != 0 ) + return(0); expand_ipbits(str,ipbits); HASH_FIND(hh,coin->iAddrs,&ipbits,sizeof(ipbits),ptr); //printf("%p hashset.(%s) -> ptr.%p itemind.%d keylen.%ld %x\n",coin->iAddrs,str,ptr,itemind,sizeof(ipbits),ipbits); @@ -72,6 +109,8 @@ struct iguana_iAddr *_iguana_hashset(struct iguana_info *coin,uint32_t ipbits,in struct iguana_iAddr *iguana_iAddrhashset(struct iguana_info *coin,struct iguana_iAddr *iA,int32_t ind) { struct iguana_iAddr *tmp,*item; + if ( coin->virtualchain != 0 ) + return(0); if ( iA == 0 || iA->ipbits == 0 ) { printf("null iA.%p or ipbits.%llx ind.%d status.%d\n",iA,iA!=0?(long long)iA->ipbits:0,iA!=0?iA->hh.itemind:0,iA!=0?iA->status:0); @@ -81,7 +120,7 @@ struct iguana_iAddr *iguana_iAddrhashset(struct iguana_info *coin,struct iguana_ portable_mutex_lock(&coin->peers_mutex); if ( (item= _iguana_hashfind(coin,(uint32_t)iA->ipbits)) == 0 ) { - tmp = mycalloc('i',1,sizeof(*iA)); + tmp = mycalloc('p',1,sizeof(*iA)); *tmp = *iA; iA = tmp; if ( ind <= 0 ) @@ -108,6 +147,8 @@ struct iguana_iAddr *iguana_iAddrhashset(struct iguana_info *coin,struct iguana_ struct iguana_iAddr *iguana_iAddrhashfind(struct iguana_info *coin,uint64_t ipbits,int32_t createflag) { int32_t ind; struct iguana_iAddr *item = 0; + if ( coin->virtualchain != 0 ) + return(0); portable_mutex_lock(&coin->peers_mutex); if ( ipbits != 0 ) { @@ -126,6 +167,8 @@ struct iguana_iAddr *iguana_iAddrhashfind(struct iguana_info *coin,uint64_t ipbi uint32_t iguana_rwiAddrind(struct iguana_info *coin,int32_t rwflag,struct iguana_iAddr *iA,uint32_t ind) { FILE *fp; char fname[512],hexstr[65],ipaddr[64]; uint32_t ipbits; int32_t i,n,m,retval = 0; struct iguana_iAddr tmp,*ptr; + if ( coin->virtualchain != 0 ) + return(0); sprintf(fname,"%s/%s_peers.dat",GLOBAL_DBDIR,coin->symbol), OS_compatible_path(fname); if ( rwflag < 0 || iA == 0 ) { @@ -251,6 +294,8 @@ uint32_t iguana_rwiAddrind(struct iguana_info *coin,int32_t rwflag,struct iguana void iguana_iAconnected(struct iguana_info *coin,struct iguana_peer *addr) { struct iguana_iAddr *iA; + if ( coin->virtualchain != 0 ) + return; if ( (iA= iguana_iAddrhashfind(coin,addr->ipbits,1)) != 0 ) { iA->status = IGUANA_PEER_READY; @@ -267,6 +312,8 @@ void iguana_iAconnected(struct iguana_info *coin,struct iguana_peer *addr) void iguana_iAkill(struct iguana_info *coin,struct iguana_peer *addr,int32_t markflag) { struct iguana_iAddr *iA; int32_t rank; char ipaddr[64]; + if ( coin->virtualchain != 0 ) + return; if ( addr->ipbits == 0 ) { printf("cant iAkill null ipbits\n"); @@ -276,8 +323,8 @@ void iguana_iAkill(struct iguana_info *coin,struct iguana_peer *addr,int32_t mar strcpy(ipaddr,addr->ipaddr); if ( addr->usock >= 0 ) closesocket(addr->usock), addr->usock = -1; - if ( addr == coin->peers.localaddr ) - coin->peers.localaddr = 0; + if ( coin->peers != 0 && addr == coin->peers->localaddr ) + coin->peers->localaddr = 0; //printf("iAkill.(%s)\n",addr->ipaddr); if ( (iA= iguana_iAddrhashfind(coin,addr->ipbits,1)) != 0 ) { @@ -374,7 +421,7 @@ int32_t iguana_socket(int32_t bindflag,char *hostname,uint16_t port) } sleep(13); //continue; - } + } if ( errno != ECONNRESET && errno != ENOTCONN && errno != ECONNREFUSED && errno != ETIMEDOUT && errno != EHOSTUNREACH ) { printf("%s(%s) port.%d failed: %s sock.%d. errno.%d\n",bindflag!=0?"bind":"connect",hostname,port,strerror(errno),sock,errno); @@ -395,13 +442,13 @@ int32_t iguana_socket(int32_t bindflag,char *hostname,uint16_t port) int32_t iguana_send(struct iguana_info *coin,struct iguana_peer *addr,uint8_t *serialized,int32_t len) { - int32_t numsent,remains,usock,r,i; - if ( addr == 0 ) + int32_t numsent,remains,usock,r,i; char *cmdstr = (char *)&serialized[4]; + if ( addr == 0 && coin->peers != 0 ) { r = rand(); for (i=0; ipeers.active[(i + r) % IGUANA_MAXPEERS]; + addr = &coin->peers->active[(i + r) % IGUANA_MAXPEERS]; if ( addr->usock >= 0 && addr->msgcounts.verack > 0 ) break; } @@ -414,24 +461,30 @@ int32_t iguana_send(struct iguana_info *coin,struct iguana_peer *addr,uint8_t *s return(-1); } remains = len; - if ( strncmp((char *)&serialized[4],"SuperNET",strlen("SuperNET")) == 0 ) + if ( strncmp(cmdstr+1,"uperNET",strlen("uperNET")) == 0 || strncmp(cmdstr+1,"uperNet",strlen("uperNet")) == 0 ) { - //printf(" >>>>>>> send.(%s) %d bytes to %s supernet.%d\n",(char *)&serialized[4],len,addr->ipaddr,addr->supernet); + //for (i=0; i>>>>>> send.(%s) crc.%x %d bytes to %s:%u supernet.%d\n",cmdstr,calc_crc32(0,serialized,len),len,addr->ipaddr,addr->A.port,addr->supernet); } - else if ( addr->msgcounts.verack == 0 && (strcmp((char *)&serialized[4],"version") != 0 && strcmp((char *)&serialized[4],"ConnectTo") != 0 && strcmp((char *)&serialized[4],"verack") != 0) != 0 ) + else if ( addr->msgcounts.verack == 0 && (strcmp(cmdstr,"version") != 0 && strcmp(cmdstr,"ConnectTo") != 0 && strcmp(cmdstr,"verack") != 0) != 0 ) { - //printf("skip.(%s) since no verack yet\n",(char *)&serialized[4]); + //printf("skip.(%s) since no verack yet\n",cmdstr); return(-1); } - if ( strcmp((char *)&serialized[4],"ping") == 0 ) + if ( strcmp(cmdstr,"ping") == 0 ) addr->sendmillis = OS_milliseconds(); if ( len > IGUANA_MAXPACKETSIZE ) printf("sending too big! %d\n",len); while ( remains > 0 ) { - if ( coin->peers.shuttingdown != 0 ) + if ( coin->peers != 0 && coin->peers->shuttingdown != 0 ) return(-1); +#ifdef _WIN32 + if ( (numsent= (int32_t)send(usock,serialized,remains,0)) < 0 ) +#else if ( (numsent= (int32_t)send(usock,serialized,remains,MSG_NOSIGNAL)) < 0 ) +#endif { printf("send errno.%d %s\n",errno,strerror(errno)); if ( errno != EAGAIN && errno != EWOULDBLOCK ) @@ -447,15 +500,15 @@ int32_t iguana_send(struct iguana_info *coin,struct iguana_peer *addr,uint8_t *s remains -= numsent; serialized += numsent; if ( remains > 0 ) - printf("iguana sent.%d remains.%d of len.%d\n",numsent,remains,len); + printf("%s iguana sent.%d remains.%d of len.%d\n",addr->ipaddr,numsent,remains,len); } } addr->totalsent += len; - //printf(" %s sent.%d bytes to %s\n",(char *)&serialized[4],len,addr->ipaddr);// getchar(); + //printf(" (%s) sent.%d bytes to %s\n",cmdstr,len,addr->ipaddr);// getchar(); return(len); } -int32_t iguana_queue_send(struct iguana_info *coin,struct iguana_peer *addr,int32_t delay,uint8_t *serialized,char *cmd,int32_t len,int32_t getdatablock,int32_t forceflag) +int32_t iguana_queue_send(struct iguana_peer *addr,int32_t delay,uint8_t *serialized,char *cmd,int32_t len) { struct iguana_packet *packet; int32_t datalen; if ( addr == 0 ) @@ -464,12 +517,10 @@ int32_t iguana_queue_send(struct iguana_info *coin,struct iguana_peer *addr,int3 exit(-1); return(-1); } - if ( (datalen= iguana_sethdr((void *)serialized,coin->chain->netmagic,cmd,&serialized[sizeof(struct iguana_msghdr)],len)) < 0 ) + if ( (datalen= iguana_sethdr((void *)serialized,addr->netmagic,cmd,&serialized[sizeof(struct iguana_msghdr)],len)) < 0 ) return(-1); if ( strcmp("getaddr",cmd) == 0 && time(NULL) < addr->lastgotaddr+300 ) return(0); - //if ( strcmp("version",cmd) == 0 ) - // return(iguana_send(coin,addr,serialized,datalen)); packet = mycalloc('S',1,sizeof(struct iguana_packet) + datalen); packet->datalen = datalen; packet->addr = addr; @@ -495,7 +546,7 @@ int32_t iguana_recv(char *ipaddr,int32_t usock,uint8_t *recvbuf,int32_t len) { if ( errno == EAGAIN ) { - //printf("%s recv errno.%d %s\n",ipaddr,errno,strerror(errno)); + //printf("%s recv errno.%d %s len.%d remains.%d\n",ipaddr,errno,strerror(errno),len,remains); //printf("EAGAIN for len %d, remains.%d\n",len,remains); sleep(1); } else return(-errno); @@ -505,22 +556,23 @@ int32_t iguana_recv(char *ipaddr,int32_t usock,uint8_t *recvbuf,int32_t len) if ( recvlen > 0 ) { remains -= recvlen; + //int32_t i; for (i=0; i 0 ) - printf("got %d remains.%d of total.%d\n",recvlen,remains,len); } } return(len); } -void iguana_parsebuf(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_msghdr *H,uint8_t *buf,int32_t len) +void iguana_parsebuf(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_msghdr *H,uint8_t *buf,int32_t len,int32_t fromcache) { struct iguana_msghdr checkH; memset(&checkH,0,sizeof(checkH)); if ( iguana_sethdr(&checkH,coin->chain->netmagic,H->command,buf,len) > 0 && memcmp(&checkH,H,sizeof(checkH)) == 0 ) { - if ( strcmp(H->command,"block") == 0 || strcmp(H->command,"tx") == 0 ) + if ( strcmp(H->command,"block") == 0 || strcmp(H->command,"getblocks") == 0 || strcmp(H->command,"tx") == 0 ) { if ( addr->RAWMEM.ptr == 0 ) iguana_meminit(&addr->RAWMEM,addr->ipaddr,0,IGUANA_MAXPACKETSIZE * 2,0); @@ -530,7 +582,7 @@ void iguana_parsebuf(struct iguana_info *coin,struct iguana_peer *addr,struct ig iguana_meminit(&addr->HASHMEM,"HASHPTRS",0,256,0);//IGUANA_MAXPACKETSIZE*16,0); //printf("Init %s memory %p %p %p\n",addr->ipaddr,addr->RAWMEM.ptr,addr->TXDATA.ptr,addr->HASHMEM.ptr); } - if ( iguana_msgparser(coin,addr,&addr->RAWMEM,&addr->TXDATA,&addr->HASHMEM,H,buf,len) < 0 || addr->dead != 0 ) + if ( iguana_msgparser(coin,addr,&addr->RAWMEM,&addr->TXDATA,&addr->HASHMEM,H,buf,len,fromcache) < 0 || addr->dead != 0 ) { printf("%p addr->dead.%d or parser break at %u\n",&addr->dead,addr->dead,(uint32_t)time(NULL)); addr->dead = (uint32_t)time(NULL); @@ -542,18 +594,25 @@ void iguana_parsebuf(struct iguana_info *coin,struct iguana_peer *addr,struct ig coin->totalrecv += len, coin->totalpackets++; //printf("next iter.(%s) numreferrals.%d numpings.%d\n",addr->ipaddr,addr->numreferrals,addr->numpings); } - } else printf("header error from %s\n",addr->ipaddr); + } + else + { + int z; + for (z=0; zipaddr,len,calc_crc32(0,buf,len)); + } } void _iguana_processmsg(struct iguana_info *coin,int32_t usock,struct iguana_peer *addr,uint8_t *_buf,int32_t maxlen) { int32_t len,recvlen; void *buf = _buf; struct iguana_msghdr H; - if ( coin->peers.shuttingdown != 0 || addr->dead != 0 ) + if ( (coin->peers != 0 && coin->peers->shuttingdown != 0) || addr->dead != 0 ) return; memset(&H,0,sizeof(H)); if ( (recvlen= (int32_t)iguana_recv(addr->ipaddr,usock,(uint8_t *)&H,sizeof(H))) == sizeof(H) ) { - if ( coin->peers.shuttingdown != 0 || addr->dead != 0 ) + if ( (coin->peers != 0 && coin->peers->shuttingdown != 0) || addr->dead != 0 ) return; { iguana_rwnum(0,H.serdatalen,sizeof(H.serdatalen),(uint32_t *)&len); @@ -572,24 +631,26 @@ void _iguana_processmsg(struct iguana_info *coin,int32_t usock,struct iguana_pee buf = mycalloc('p',1,len); if ( (recvlen= iguana_recv(addr->ipaddr,usock,buf,len)) < 0 ) { - printf("recv error on (%s) len.%d errno.%d (%s)\n",H.command,len,-recvlen,strerror(-recvlen)); + printf("%s recv error on (%s) len.%d errno.%d (%s)\n",addr->ipaddr,H.command,len,-recvlen,strerror(-recvlen)); if ( buf != _buf ) myfree(buf,len); - addr->dead = (uint32_t)time(NULL); + //addr->dead = (uint32_t)time(NULL); return; } } - // 79 22 e3 b4 80 07 - //int32_t i; for (i=0; iipaddr); - addr->dead = 1; + static uint32_t counter; + if ( counter++ < 10 ) + { + int32_t i; for (i=0; isymbol,H.command,addr->ipaddr,len); + } + //addr->dead = 1; } // printf("%s recv error on hdr errno.%d (%s) -> zombify\n",addr->ipaddr,-recvlen,strerror(-recvlen)); #ifndef IGUANA_DEDICATED_THREADS @@ -614,6 +675,8 @@ void iguana_gotdata(struct iguana_info *coin,struct iguana_peer *addr,int32_t he int32_t iguana_iAddrheight(struct iguana_info *coin,uint64_t ipbits) { struct iguana_iAddr *iA; + if ( coin->virtualchain != 0 ) + return(0); if ( (iA= iguana_iAddrhashfind(coin,ipbits,0)) != 0 ) return(iA->height); return(0); @@ -624,21 +687,29 @@ void iguana_startconnection(void *arg) int32_t i,n; uint16_t port; char ipaddr[64]; struct iguana_peer *addr = arg; struct iguana_info *coin = 0; if ( addr == 0 || (coin= iguana_coinfind(addr->symbol)) == 0 ) { - printf("iguana_startconnection nullptrs addr.%p coin.%p\n",addr,coin); + printf("iguana_startconnection nullptrs addr.%p (%s) coin.%p\n",addr,addr!=0?addr->symbol:"",coin); return; } - addr->addrind = (int32_t)(((long)addr - (long)&coin->peers.active[0]) / sizeof(*addr)); + if ( coin->virtualchain != 0 || coin->peers == 0 ) + return; + addr->addrind = (int32_t)(((long)addr - (long)&coin->peers->active[0]) / sizeof(*addr)); if ( addr->usock >= 0 ) { printf("%s usock.%d skip connection\n",addr->ipaddr,addr->usock); return; } - if ( strcmp(coin->name,addr->coinstr) != 0 ) + if ( strcmp(coin->name,addr->coinname) != 0 ) { - printf("iguana_startconnection.%s mismatched coin.%p (%s) vs (%s)\n",addr->ipaddr,coin,coin->symbol,addr->coinstr); + printf("iguana_startconnection.%s:%04x mismatched coin.%p (%s) vs (%s)\n",addr->ipaddr,coin->chain->portp2p,coin,coin->symbol,addr->coinname); return; } - //printf("MYSERVICES.%llx\n",(long long)coin->myservices); + if ( strcmp("85.25.217.233",addr->ipaddr) == 0 ) + { + printf("temp blacklist %s\n",addr->ipaddr); + iguana_iAkill(coin,addr,1); + return; + } + //printf("%s iguana_startconnection.%s:%04x\n",coin->symbol,addr->ipaddr,coin->chain->portp2p); if ( strcmp("127.0.0.1",addr->ipaddr) == 0 )//&& (coin->myservices & NODE_NETWORK) != 0 ) { iguana_iAkill(coin,addr,0); @@ -651,10 +722,10 @@ void iguana_startconnection(void *arg) port = coin->chain->portp2p; if ( addr->usock < 0 ) addr->usock = iguana_socket(0,addr->ipaddr,port); - if ( addr->usock < 0 || coin->peers.shuttingdown != 0 ) + if ( addr->usock < 0 || (coin->peers != 0 && coin->peers->shuttingdown != 0) ) { strcpy(ipaddr,addr->ipaddr); - //printf("refused PEER KILLED. slot.%d for %s:%d usock.%d\n",addr->addrind,ipaddr,coin->chain->portp2p,addr->usock); + //printf("%s refused PEER KILLED. slot.%d for %s:%d usock.%d\n",coin->symbol,addr->addrind,ipaddr,coin->chain->portp2p,addr->usock); iguana_iAkill(coin,addr,1); } else @@ -665,21 +736,24 @@ void iguana_startconnection(void *arg) addr->pending = 0; addr->height = iguana_iAddrheight(coin,addr->ipbits); strcpy(addr->symbol,coin->symbol); - strcpy(addr->coinstr,coin->name); - coin->peers.lastpeer = (uint32_t)time(NULL); - for (i=n=0; iMAXPEERS; i++) - if ( coin->peers.active[i].usock > 0 ) - n++; + strcpy(addr->coinname,coin->name); + if ( coin->peers != 0 ) + { + coin->peers->lastpeer = (uint32_t)time(NULL); + for (i=n=0; ipeers->active[i].usock > 0 ) + n++; + coin->peers->numconnected++; + if ( strcmp("127.0.0.1",addr->ipaddr) == 0 ) + coin->peers->localaddr = addr; + else if ( coin->peers->numranked == 0 ) + coin->peers->ranked[0] = addr; + } else n = 0; iguana_iAconnected(coin,addr); - coin->peers.numconnected++; - printf("%s.PEER CONNECTED.%d:%d of max.%d! %s:%d usock.%d\n",coin->symbol,coin->peers.numconnected,n,coin->MAXPEERS,addr->ipaddr,coin->chain->portp2p,addr->usock); - if ( strcmp("127.0.0.1",addr->ipaddr) == 0 ) - coin->peers.localaddr = addr; - else if ( coin->peers.numranked == 0 ) - coin->peers.ranked[0] = addr; + printf("%s.PEER CONNECTED.%d:%d of max.%d! %s:%d usock.%d\n",coin->symbol,coin->peers->numconnected,n,coin->MAXPEERS,addr->ipaddr,coin->chain->portp2p,addr->usock); #ifdef IGUANA_DEDICATED_THREADS //iguana_launch("recv",iguana_dedicatedrecv,addr,IGUANA_RECVTHREAD); - iguana_dedicatedloop(coin,addr); + iguana_dedicatedloop(SuperNET_MYINFO(0),coin,addr); #endif } } @@ -687,9 +761,11 @@ void iguana_startconnection(void *arg) void iguana_peerkill(struct iguana_info *coin) { struct iguana_peer *addr; - if ( coin->peers.numranked > 0 && (addr= coin->peers.ranked[coin->peers.numranked-1]) != 0 ) + if ( coin->virtualchain != 0 || coin->peers == 0 ) + return; + if ( coin->peers->numranked > 0 && (addr= coin->peers->ranked[coin->peers->numranked-1]) != 0 ) { - printf("mark rank.%d as dead.(%s)\n",coin->peers.numranked,addr->ipaddr); + printf("mark rank.%d as dead.(%s)\n",coin->peers->numranked,addr->ipaddr); addr->dead = (uint32_t)time(NULL); } } @@ -697,9 +773,11 @@ void iguana_peerkill(struct iguana_info *coin) struct iguana_peer *iguana_peerslot(struct iguana_info *coin,uint64_t ipbits,int32_t forceflag) { int32_t i; struct iguana_peer *addr; char ipaddr[64]; + if ( coin->virtualchain != 0 || coin->peers == 0 ) + return(0); for (i=0; ipeers.active[i].ipbits ) - return(forceflag!=0 ? &coin->peers.active[i] : 0); + if ( (uint32_t)ipbits == (uint32_t)coin->peers->active[i].ipbits ) + return(forceflag!=0 ? &coin->peers->active[i] : 0); expand_ipbits(ipaddr,ipbits); #ifdef IGUANA_DISABLEPEERS if ( strcmp("127.0.0.1",ipaddr) != 0 ) @@ -710,11 +788,11 @@ struct iguana_peer *iguana_peerslot(struct iguana_info *coin,uint64_t ipbits,int { if ( i < coin->MAXPEERS || forceflag != 0 ) { - addr = &coin->peers.active[i]; + addr = &coin->peers->active[i]; addr->addrind = i; if ( addr->usock >= 0 || addr->pending != 0 || addr->ipbits == ipbits || strcmp(ipaddr,addr->ipaddr) == 0 ) { - //printf("skip.(%s) usock.%d pending.%d ipbits.%x vs %x lag.%ld\n",addr->ipaddr,addr->usock,addr->pending,addr->ipbits,iA->ipbits,time(NULL)-addr->pending); + //printf("%s i.%d skip.(%s) usock.%d pending.%d ipbits.%llx lag.%ld\n",coin->symbol,i,addr->ipaddr,addr->usock,addr->pending,(long long)addr->ipbits,time(NULL)-addr->pending); continue; } portable_mutex_lock(&coin->peers_mutex); @@ -731,22 +809,33 @@ struct iguana_peer *iguana_peerslot(struct iguana_info *coin,uint64_t ipbits,int return(0); } -void iguana_launchpeer(struct iguana_info *coin,char *ipaddr) +void iguana_launchpeer(struct iguana_info *coin,char *ipaddr,int32_t forceflag) { struct iguana_peer *addr; uint32_t ipbits = (uint32_t)calc_ipbits(ipaddr); - if ( (addr= iguana_peerslot(coin,ipbits,0)) != 0 ) + if ( coin == 0 ) + { + printf("iguana_launchpeer: null coin?\n"); + return; + } + if ( coin->virtualchain != 0 ) + return; + if ( (addr= iguana_peerslot(coin,ipbits,forceflag)) != 0 ) iguana_launch(coin,"connection",iguana_startconnection,addr,IGUANA_CONNTHREAD); + else printf("iguana_launchpeer skip %s\n",ipaddr); } void *iguana_iAddriterator(struct iguana_info *coin,struct iguana_iAddr *iA) { struct iguana_peer *addr = 0; + if ( coin->virtualchain != 0 ) + return(0); if ( iA != 0 && iA->ipbits != 0 && iguana_numthreads(coin,1 << IGUANA_CONNTHREAD) < IGUANA_MAXCONNTHREADS && iA->status == IGUANA_PEER_ELIGIBLE ) { //printf("%x\n",iA->ipbits); //portable_mutex_unlock(&coin->peers_mutex); if ( (addr= iguana_peerslot(coin,iA->ipbits,0)) != 0 ) { + addr->ipbits = iA->ipbits; //printf("pend.%d status.%d possible peer.(%s).%x threads %d %d %d %d\n",addr->pending,iA->status,addr->ipaddr,(uint32_t)addr->ipbits,iguana_numthreads(coin,0),iguana_numthreads(coin,1),iguana_numthreads(coin,2),iguana_numthreads(coin,3)); if ( addr->pending == 0 && iA->status != IGUANA_PEER_CONNECTING && (iA->status != IGUANA_PEER_KILLED || time(NULL) > iA->lastkilled+600) ) { @@ -764,7 +853,7 @@ void *iguana_iAddriterator(struct iguana_info *coin,struct iguana_iAddr *iA) printf("error rwiAddrind.%d\n",iA->hh.itemind); } } - } else printf("no open peer slots left\n"); + } else printf("%s no open peer slots left\n",coin->symbol); } //else if ( iA != 0 ) // printf("iA->ipbits %d, %d iguana_numthreads(coin,1 << IGUANA_CONNTHREAD) status.%d\n",iA->ipbits,iguana_numthreads(coin,1 << IGUANA_CONNTHREAD),iA->status); @@ -775,14 +864,19 @@ void *iguana_iAddriterator(struct iguana_info *coin,struct iguana_iAddr *iA) uint32_t iguana_possible_peer(struct iguana_info *coin,char *ipaddr) { char checkaddr[64]; uint64_t ipbits; uint32_t now = (uint32_t)time(NULL); int32_t i,n; struct iguana_iAddr *iA; - if ( ipaddr != 0 && ipaddr[0] != 0 ) + if ( coin->virtualchain != 0 || coin->peers == 0 ) + return(0); + if ( ipaddr != 0 && ipaddr[0] != 0 && coin->peers != 0 ) { - for (i=n=0; iMAXPEERS; i++) - if ( strcmp(ipaddr,coin->peers.active[i].ipaddr) == 0 ) + if ( strcmp(ipaddr,"0.0.0.0") == 0 || strcmp(ipaddr,"127.0.0.1") == 0 ) + return(0); + for (i=n=0; ipeers->active[i].ipaddr) == 0 ) { - printf("%s possible peer.(%s) %x already there\n",coin->symbol,ipaddr,(uint32_t)coin->peers.active[i].ipbits); + printf("%s possible peer.(%s) %x already there\n",coin->symbol,ipaddr,(uint32_t)coin->peers->active[i].ipbits); return(0); } + //printf("%s Q possible.(%s)\n",coin->symbol,ipaddr); queue_enqueue("possibleQ",&coin->possibleQ,queueitem(ipaddr),1); return((uint32_t)time(NULL)); } @@ -797,28 +891,37 @@ uint32_t iguana_possible_peer(struct iguana_info *coin,char *ipaddr) return((uint32_t)time(NULL)); } #endif - //printf("check possible peer.(%s)\n",ipaddr); - for (i=n=0; iMAXPEERS; i++) + ipbits = (uint32_t)calc_ipbits(ipaddr); + //printf("%s check possible peer.(%s)\n",coin->symbol,ipaddr); + if ( iguana_peerslot(coin,(uint32_t)ipbits,0) != 0 ) + return((uint32_t)time(NULL)); + for (i=n=0; ipeers.active[i].ipaddr) == 0 ) + if ( strcmp(ipaddr,coin->peers->active[i].ipaddr) == 0 ) { //printf("(%s) already active\n",ipaddr); free_queueitem(ipaddr); return((uint32_t)time(NULL)); } - else if ( coin->peers.active[i].ipaddr[0] != 0 ) + else if ( coin->peers->active[i].ipaddr[0] != 0 ) n++; } - if ( n >= coin->MAXPEERS-(coin->MAXPEERS>>3)-1 || coin->peers.numranked >= coin->MAXPEERS ) + if ( n >= coin->MAXPEERS-(coin->MAXPEERS>>3)-1 || coin->peers->numranked >= coin->MAXPEERS ) return((uint32_t)time(NULL)); if ( strncmp("0.0.0",ipaddr,5) != 0 && strcmp("0.0.255.255",ipaddr) != 0 && strcmp("1.0.0.0",ipaddr) != 0 ) { + for (i=0; ipaddr[i]!=0; i++) + if ( ipaddr[i] == ':' ) + { + ipaddr[i] = 0; + break; + } if ( (ipbits= calc_ipbits(ipaddr)) != 0 ) { expand_ipbits(checkaddr,ipbits); if ( strcmp(checkaddr,ipaddr) == 0 ) { - //printf("valid ipaddr.(%s) MAXPEERS.%d\n",ipaddr,coin->MAXPEERS); + //printf("%s valid ipaddr.(%s) MAXPEERS.%d\n",coin->symbol,ipaddr,coin->MAXPEERS); if ( (iA= iguana_iAddrhashfind(coin,ipbits,1)) != 0 ) { if ( iA->status != IGUANA_PEER_CONNECTING && iA->status != IGUANA_PEER_READY && iA->status != IGUANA_PEER_ELIGIBLE ) @@ -830,9 +933,9 @@ uint32_t iguana_possible_peer(struct iguana_info *coin,char *ipaddr) printf("error updating status for (%s) ind.%d\n",ipaddr,iA->hh.itemind); iguana_iAddriterator(coin,iA); } else printf("ignore.(%s) lastconnect.%u lastkilled.%u numconnects.%d\n",ipaddr,iA->lastconnect,iA->lastkilled,iA->numconnects); - } //else printf("skip.(%s) ind.%d status.%d\n",ipaddr,iA->hh.itemind,iA->status); + } else printf("skip.(%s) ind.%d status.%d\n",ipaddr,iA->hh.itemind,iA->status); } else printf("cant find (%s) which should have been created\n",ipaddr); - } else printf("reject ipaddr.(%s) vs checkaddr.(%s)\n",ipaddr,checkaddr); + } else printf("%s reject ipaddr.(%s) vs checkaddr.(%s)\n",coin->symbol,ipaddr,checkaddr); } } free_queueitem(ipaddr); @@ -882,7 +985,7 @@ int32_t iguana_pollrecv(struct iguana_info *coin,struct iguana_peer *addr,uint8_ { #ifndef IGUANA_DEDICATED_THREADS strcpy(addr->symbol,coin->symbol); - if ( addr != coin->peers.localaddr ) + if ( coin->peers != 0 && addr != coin->peers->localaddr ) { addr->startrecv = (uint32_t)time(NULL); iguana_launch("processmsg",iguana_processmsg,addr,IGUANA_RECVTHREAD); @@ -982,6 +1085,7 @@ int64_t iguana_peerfree(struct iguana_info *coin,struct iguana_peer *addr,void * return(-1); } #else + void *iguana_peeralloc(struct iguana_info *coin,struct iguana_peer *addr,int32_t datalen) { addr->allocated += datalen; @@ -1018,6 +1122,7 @@ int32_t iguana_vinsfname(struct iguana_info *coin,int32_t roflag,char *fname,int int32_t iguana_peerslotinit(struct iguana_info *coin,struct iguana_peer *addr,int32_t slotid,uint64_t ipbits) { char fname[1024]; + memcpy(addr->netmagic,coin->chain->netmagic,4); addr->ipbits = ipbits; addr->addrind = slotid; iguana_voutsfname(coin,0,fname,addr->addrind); @@ -1025,33 +1130,36 @@ int32_t iguana_peerslotinit(struct iguana_info *coin,struct iguana_peer *addr,in fseek(addr->voutsfp,0,SEEK_END); else if ( (addr->voutsfp= fopen(fname,"wb+")) == 0 ) { - printf("cant create.(%s)\n",fname); + printf("iguana_peerslotinit cant create.(%s)\n",fname); return(-1); } - if ( coin->VALIDATENODE != 0 || coin->RELAYNODE != 0 ) + if ( coin->MAXPEERS == 1 || coin->VALIDATENODE != 0 || coin->FULLNODE != 0 ) { iguana_vinsfname(coin,0,fname,addr->addrind); if ( (addr->vinsfp= fopen(fname,"rb+")) != 0 ) fseek(addr->vinsfp,0,SEEK_END); else if ( (addr->vinsfp= fopen(fname,"wb+")) == 0 ) { - printf("cant create.(%s)\n",fname); + printf("iguana_peerslotinit cant create.(%s)\n",fname); return(-1); } } return(0); } -void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) +void iguana_dedicatedloop(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr) { - static uint32_t lastping; + //static uint32_t lastping; struct pollfd fds; struct iguana_bundlereq *req; uint8_t *buf; uint32_t ipbits; int32_t bufsize,flag,run,timeout = coin->polltimeout == 0 ? 10 : coin->polltimeout; - if ( iguana_peerslotinit(coin,addr,(int32_t)(((long)addr - (long)&coin->peers.active[0]) / sizeof(*addr)),calc_ipbits(addr->ipaddr)) < 0 ) + if ( coin->virtualchain != 0 || coin->peers == 0 ) + return; + if ( iguana_peerslotinit(coin,addr,(int32_t)(((long)addr - (long)&coin->peers->active[0]) / sizeof(*addr)),calc_ipbits(addr->ipaddr)) < 0 ) { printf("error creating peer's files\n"); return; } + //instantdex_peerhas_clear(coin,addr); #ifdef IGUANA_PEERALLOC int32_t i; int64_t remaining; struct OS_memspace *mem[sizeof(addr->SEROUT)/sizeof(*addr->SEROUT)]; for (i=0; iSEROUT)/sizeof(*addr->SEROUT); i++) @@ -1086,16 +1194,15 @@ void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) //printf("send version myservices.%llu to (%s)\n",(long long)coin->myservices,addr->ipaddr); } //sleep(1+(rand()%5)); - //iguana_queue_send(coin,addr,0,serialized,"getaddr",0,0,0); run = 0; - while ( addr->usock >= 0 && addr->dead == 0 && coin->peers.shuttingdown == 0 ) + while ( addr->usock >= 0 && addr->dead == 0 && coin->peers->shuttingdown == 0 ) { - if ( 0 && (req= queue_dequeue(&coin->cacheQ,0)) != 0 ) + if ( (req= queue_dequeue(&coin->cacheQ,0)) != 0 ) { if ( req->datalen != 0 ) { - //char str[65]; printf("CACHE.%p parse[%d] %s %s\n",req,req->recvlen,req->H.command,bits256_str(str,req->block.RO.hash2)); - iguana_parsebuf(coin,addr,&req->H,req->serialized,req->recvlen); + //char str[65]; printf("CACHE.%p parse[%d] %s %s\n",req,req->recvlen,req->H.command,bits256_str(str,req->zblock.RO.hash2)); + iguana_parsebuf(coin,addr,&req->H,req->serializeddata,req->recvlen,1); } else printf("CACHE error no datalen\n"); coin->cachefreed++; myfree(req,req->allocsize); @@ -1155,14 +1262,13 @@ void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) } if ( flag != 0 ) run = 0; - else if ( addr->supernet != 0 && time(NULL) > lastping+SUPERNET_PINGGAP ) + /*else if ( 0 && addr->supernet != 0 && time(NULL) > lastping+SUPERNET_PINGGAP ) { - iguana_send_supernet(coin,addr,SUPERNET_GETPEERSTR,0); + iguana_send_supernet(addr,SUPERNET_GETPEERSTR,0); lastping = (uint32_t)time(NULL); - } + }*/ if ( addr->persistent_peer != 0 ) { - uint16_t port; if ( addr->usock < 0 || addr->dead != 0 ) { if ( addr->usock >= 0 ) @@ -1172,9 +1278,9 @@ void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) { printf("persistent peer.(%s) disconnected... reconnect\n",addr->ipaddr); sleep(addr->persistent_peer); - if ( (port= (uint16_t)(addr->ipbits >> 32)) == 0 ) - port = coin->chain->portp2p; - addr->usock = iguana_socket(0,addr->ipaddr,port); + if ( (addr->A.port= (uint16_t)(addr->ipbits >> 32)) == 0 ) + addr->A.port = coin->chain->portp2p; + addr->usock = iguana_socket(0,addr->ipaddr,addr->A.port); } } } @@ -1185,17 +1291,23 @@ void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) } } //printf(">>>>>>>>>>>>>> finish %s dedicatedloop.%s\n",coin->symbol,addr->ipaddr); - if ( addr->vinsfp != 0 ) - fclose(addr->vinsfp); - if ( addr->voutsfp != 0 ) - fclose(addr->voutsfp); + if ( 0 ) + { + if ( addr->vinsfp != 0 ) + fclose(addr->vinsfp), addr->vinsfp = 0; + if ( addr->voutsfp != 0 ) + fclose(addr->voutsfp), addr->voutsfp = 0; + } iguana_iAkill(coin,addr,addr->dead != 0); myfree(buf,bufsize); if ( addr->filehash2 != 0 ) - myfree(addr->filehash2,addr->maxfilehash2*sizeof(*addr->filehash2)); - iguana_mempurge(&addr->RAWMEM); - iguana_mempurge(&addr->TXDATA); - iguana_mempurge(&addr->HASHMEM); + myfree(addr->filehash2,addr->maxfilehash2*sizeof(*addr->filehash2)), addr->filehash2 = 0; + if ( 0 ) + { + iguana_mempurge(&addr->RAWMEM); + iguana_mempurge(&addr->TXDATA); + iguana_mempurge(&addr->HASHMEM); + } #ifdef IGUANA_PEERALLOC while ( (remaining= iguana_peerallocated(coin,addr)) > 0 ) { @@ -1213,7 +1325,7 @@ void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr) } } #endif - coin->peers.numconnected--; + coin->peers->numconnected--; } void iguana_dedicatedglue(void *arg) @@ -1224,7 +1336,7 @@ void iguana_dedicatedglue(void *arg) printf("iguana_dedicatedglue nullptrs addr.%p coin.%p\n",addr,coin); return; } - iguana_dedicatedloop(coin,addr); + iguana_dedicatedloop(SuperNET_MYINFO(0),coin,addr); } void iguana_peersloop(void *ptr) @@ -1236,9 +1348,9 @@ void iguana_peersloop(void *ptr) memset(fds,0,sizeof(fds)); memset(bufs,0,sizeof(bufs)); memset(bufsizes,0,sizeof(bufsizes)); - while ( 1 ) + while ( coin->peers != 0 ) { - while ( coin->peers.shuttingdown != 0 ) + while ( coin->peers->shuttingdown != 0 ) { printf("peers shuttingdown\n"); sleep(3); @@ -1248,7 +1360,7 @@ void iguana_peersloop(void *ptr) for (j=n=nonz=0; jMAXPEERS; j++) { i = (j + r) % coin->MAXPEERS; - addr = &coin->peers.active[i]; + addr = &coin->peers->active[i]; fds[i].fd = -1; if ( addr->usock >= 0 && addr->dead == 0 && addr->ready != 0 && (addr->startrecv+addr->startsend) != 0 ) { @@ -1262,7 +1374,7 @@ void iguana_peersloop(void *ptr) for (j=0; jMAXPEERS; j++) { i = (j + r) % coin->MAXPEERS; - addr = &coin->peers.active[i]; + addr = &coin->peers->active[i]; if ( addr->usock < 0 || addr->dead != 0 || addr->ready == 0 ) continue; if ( addr->startrecv == 0 && (fds[i].revents & POLLIN) != 0 && iguana_numthreads(1 << IGUANA_RECVTHREAD) < IGUANA_MAXRECVTHREADS ) @@ -1281,7 +1393,7 @@ void iguana_peersloop(void *ptr) } if ( flag == 0 ) { - if ( time(NULL) > lastping+1 ) + if ( 0 && time(NULL) > lastping+1 && addr->supernet != 0 ) iguana_send_supernet(coin,addr,SUPERNET_GETPEERSTR,0); usleep(1000); } diff --git a/iguana/iguana_ramchain.c b/iguana/iguana_ramchain.c index d0eb9b27f..19e9817f1 100755 --- a/iguana/iguana_ramchain.c +++ b/iguana/iguana_ramchain.c @@ -81,6 +81,8 @@ struct iguana_kvitem *iguana_hashsetPT(struct iguana_ramchain *ramchain,int32_t void iguana_blocksetcounters(struct iguana_info *coin,struct iguana_block *block,struct iguana_ramchain * ramchain) { + if ( 0 && coin->virtualchain != 0 ) + printf("iguana_blocksetcounters.%s 1st txidind.%u <- ht.%d\n",coin->symbol,ramchain->H.txidind,block->height); block->RO.firsttxidind = ramchain->H.txidind; block->RO.firstvout = ramchain->H.unspentind; block->RO.firstvin = ramchain->H.spendind; @@ -102,7 +104,7 @@ int32_t iguana_peerfname(struct iguana_info *coin,int32_t *hdrsip,char *dirname, if ( bits256_nonz(prevhash2) == 0 || (bp= iguana_bundlefind(coin,&bp,&bundlei,prevhash2)) == 0 || bundlei >= coin->chain->bundlesize-1 ) { if ( 0 && dispflag != 0 ) - printf("iguana_peerfname error finding.(%s) spec.%p bp.%p\n",bits256_str(str,hash2),bp!=0?bp->speculative:0,bp); + printf("iguana_peerfname %s error finding.(%s) spec.%p bp.%p\n",coin->symbol,bits256_str(str,hash2),bp!=0?bp->speculative:0,bp); return(-2); } else bundlei++; @@ -164,9 +166,11 @@ int32_t iguana_peerfile_exists(struct iguana_info *coin,struct iguana_peer *addr uint32_t iguana_ramchain_addtxid(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 txid,int32_t numvouts,int32_t numvins,uint32_t locktime,uint32_t version,uint32_t timestamp,int16_t bundlei) { - uint32_t txidind; struct iguana_txid *t; struct iguana_kvitem *ptr; + uint32_t txidind; struct iguana_txid *t; struct iguana_kvitem *ptr; struct iguana_ramchaindata *rdata; +#ifndef WIN32 if ( sizeof(*t) != 64 ) printf("sizeof iguana_txid.%d != 64?\n",(int32_t)sizeof(*t)); +#endif txidind = ramchain->H.txidind; t = &T[txidind]; if ( ramchain->H.ROflag != 0 ) @@ -191,8 +195,8 @@ uint32_t iguana_ramchain_addtxid(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 printf("addtxid error: t->txidind %u != %u txidind || t->firstvout %u != %u ramchain->H.unspentind || t->firstvin %u != %u ramchain->H.spendind || t->bundlei %u != %u bundlei\n",t->txidind,txidind,t->firstvout,ramchain->H.unspentind,t->firstvin,ramchain->H.spendind,t->bundlei,bundlei); return(0); } - if ( ramchain->expanded != 0 ) - iguana_sparseaddtx(TXbits,ramchain->H.data->txsparsebits,ramchain->H.data->numtxsparse,txid,T,txidind,ramchain); + if ( ramchain->expanded != 0 && (rdata= ramchain->H.data) != 0 ) + iguana_sparseaddtx(TXbits,rdata->txsparsebits,rdata->numtxsparse,txid,T,txidind,ramchain); //if ( txidind <= 2 ) // printf("%p TXID.[%d] firstvout.%d/%d firstvin.%d/%d\n",t,txidind,ramchain->unspentind,numvouts,ramchain->spendind,numvins); } @@ -205,7 +209,7 @@ uint32_t iguana_ramchain_addtxid(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 } if ( ptr->hh.itemind != txidind ) { - printf("iguana_ramchain_addtxid warning: adding txidind.%u vs %u\n",txidind,ptr->hh.itemind); + printf("iguana_ramchain_addtxid %d warning: adding txidind.%u vs %u\n",ramchain->height,txidind,ptr->hh.itemind); } } return(txidind); @@ -213,8 +217,8 @@ uint32_t iguana_ramchain_addtxid(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 uint32_t iguana_ramchain_addpkhash(struct iguana_info *coin,RAMCHAIN_FUNC,uint8_t *rmd160,int32_t pubkeyind,uint32_t unspentind,uint32_t pkind) { - struct iguana_kvitem *ptr; uint32_t i; - if ( ramchain->expanded != 0 && (ptr= iguana_hashfind(ramchain,'P',rmd160)) == 0 ) + struct iguana_kvitem *ptr; uint32_t i; struct iguana_ramchaindata *rdata; + if ( ramchain->expanded != 0 && (ptr= iguana_hashfind(ramchain,'P',rmd160)) == 0 && (rdata= ramchain->H.data) != 0 ) { if ( ramchain->H.ROflag != 0 ) { @@ -252,7 +256,7 @@ uint32_t iguana_ramchain_addpkhash(struct iguana_info *coin,RAMCHAIN_FUNC,uint8_ // printf("%02x",rmd160[i]); //printf(" -> rmd160 pkind.%d \n",pkind); if ( ramchain->expanded != 0 ) - iguana_sparseaddpk(PKbits,ramchain->H.data->pksparsebits,ramchain->H.data->numpksparse,rmd160,P,pkind,ramchain); + iguana_sparseaddpk(PKbits,rdata->pksparsebits,rdata->numpksparse,rmd160,P,pkind,ramchain); } if ( (ptr= iguana_hashsetPT(ramchain,'P',&P[pkind],pkind)) == 0 ) { @@ -319,8 +323,8 @@ uint32_t iguana_ramchain_addunspent20(struct iguana_info *coin,struct iguana_pee if ( addr != 0 && addr->voutsfp != 0 ) { #ifdef __PNACL__ - static portable_mutex_t mutex; - portable_mutex_lock(&mutex); + //static portable_mutex_t mutex; + //portable_mutex_lock(&mutex); #endif u->fileid = (uint32_t)addr->addrind; scriptpos = ftell(addr->voutsfp); @@ -330,9 +334,10 @@ uint32_t iguana_ramchain_addunspent20(struct iguana_info *coin,struct iguana_pee printf("error writing vout scriptlen.%d errno.%d or scriptpos.%lld != %u\n",scriptlen,errno,(long long)scriptpos,u->scriptpos); else addr->dirty[0]++; #ifdef __PNACL__ - portable_mutex_unlock(&mutex); + //portable_mutex_unlock(&mutex); #endif - } else printf("addr.%p unspent error fp.%p\n",addr,addr!=0?addr->voutsfp:0); + } + else printf("addr.%p unspent error fp.%p\n",addr,addr!=0?addr->voutsfp:0); } } u->txidind = ramchain->H.txidind; @@ -370,10 +375,6 @@ uint32_t iguana_ramchain_addunspent(struct iguana_info *coin,RAMCHAIN_FUNC,uint6 printf("addunspent error getting pkind\n"); return(0); } - if ( 0 ) - { - printf(" ROflag.%d pkind.%d unspentind.%d vout.%d %.8f script[%d] uoffset.%d %d:%d type.%d A.%p\n",ramchain->H.ROflag,pkind,unspentind,vout,dstr(value),scriptlen,u->scriptpos,ramchain->H.scriptoffset,ramchain->H.data->scriptspace,type,A); - } if ( ramchain->H.ROflag != 0 ) { /*if ( Kspace != 0 && ((u->scriptoffset != 0 && scriptlen > 0) || type == IGUANA_SCRIPT_76AC) ) @@ -413,17 +414,17 @@ uint32_t iguana_ramchain_addunspent(struct iguana_info *coin,RAMCHAIN_FUNC,uint6 int32_t iguana_ramchain_txid(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 *txidp,struct iguana_spend *s) { - uint32_t ind,external; + uint32_t ind,external; struct iguana_ramchaindata *rdata; memset(txidp,0,sizeof(*txidp)); //printf("s.%p ramchaintxid vout.%x spendtxidind.%d numexternals.%d isext.%d numspendinds.%d\n",s,s->vout,s->spendtxidind,ramchain->numexternaltxids,s->external,ramchain->numspends); - if ( s->prevout < 0 ) + if ( s->prevout < 0 || (rdata= ramchain->H.data) == 0 ) return(-1); ind = s->spendtxidind; external = (ind >> 31) & 1; ind &= ~(1 << 31); - if ( s->external != 0 && s->external == external && ind < ramchain->H.data->numexternaltxids ) + if ( s->external != 0 && s->external == external && ind < rdata->numexternaltxids ) { - //printf("ind.%d externalind.%d X[%d]\n",ind,ramchain->externalind,ramchain->H.data->numexternaltxids); + //printf("ind.%d externalind.%d X[%d]\n",ind,ramchain->externalind,rdata->numexternaltxids); *txidp = X[ind]; return(s->prevout); } @@ -437,14 +438,14 @@ int32_t iguana_ramchain_txid(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 *txi uint32_t iguana_ramchain_addspend(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 prev_hash,int32_t prev_vout,uint32_t sequence,int32_t hdrsi,uint16_t fileid,uint64_t scriptpos,int32_t vinscriptlen) { - struct iguana_spend *s; struct iguana_kvitem *ptr = 0; bits256 txid; - uint32_t spendind,unspentind,txidind=0,pkind,external=0; uint64_t value = 0; - // uint8_t _script[IGUANA_MAXSCRIPTSIZE]; int32_t metalen,i,checklen; + struct iguana_spend *s; struct iguana_kvitem *ptr = 0; bits256 txid; uint32_t spendind,unspentind,txidind=0,pkind,external=0; uint64_t value = 0; struct iguana_ramchaindata *rdata; + if ( (rdata= ramchain->H.data) == 0 ) + return(0); spendind = ramchain->H.spendind++; s = &Sx[spendind]; pkind = unspentind = 0; ptr = iguana_hashfind(ramchain,'T',prev_hash.bytes); - if ( prev_vout >= 0 && ptr == 0 ) + if ( (bits256_nonz(prev_hash) != 0 || prev_vout >= 0) && ptr == 0 ) { external = 1; txidind = ramchain->externalind++; @@ -454,7 +455,7 @@ uint32_t iguana_ramchain_addspend(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 { if ( memcmp(X[txidind].bytes,prev_hash.bytes,sizeof(prev_hash)) != 0 ) { - char str[65],str2[65]; printf("iguana_ramchain_addspend X[%d] of %d cmperror %s vs %s\n",txidind,ramchain->H.data->numexternaltxids,bits256_str(str,X[txidind]),bits256_str(str2,prev_hash)); + char str[65],str2[65]; printf("iguana_ramchain_addspend X[%d] of %d cmperror %s vs %s\n",txidind,rdata->numexternaltxids,bits256_str(str,X[txidind]),bits256_str(str2,prev_hash)); return(0); } } else X[txidind] = prev_hash; @@ -471,18 +472,18 @@ uint32_t iguana_ramchain_addspend(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 printf("unexpected addspend case: null ptr prev.%d [%d] s%u\n",prev_vout,hdrsi,spendind); if ( prev_vout >= 0 && (external= ((txidind >> 31) & 1)) == 0 ) { - if ( txidind > 0 && txidind < ramchain->H.data->numtxids ) + if ( txidind > 0 && txidind < rdata->numtxids ) { - if ( (unspentind= T[txidind].firstvout + prev_vout) > 0 && unspentind < ramchain->H.data->numunspents ) + if ( (unspentind= T[txidind].firstvout + prev_vout) > 0 && unspentind < rdata->numunspents ) { value = Ux[unspentind].value; - if ( (pkind= Ux[unspentind].pkind) == 0 || pkind >= ramchain->H.data->numpkinds ) + if ( (pkind= Ux[unspentind].pkind) == 0 || pkind >= rdata->numpkinds ) { printf("spendind.%d -> unspendind.%d %.8f -> pkind.0x%x\n",spendind,unspentind,dstr(value),pkind); return(0); } - } else printf("addspend illegal unspentind.%d vs %d\n",unspentind,ramchain->H.data->numunspents); - } else printf("addspend illegal txidind.%d vs %d\n",txidind,ramchain->H.data->numtxids), exit(-1); + } else printf("addspend illegal unspentind.%d vs %d\n",unspentind,rdata->numunspents); + } else printf("addspend illegal txidind.%d vs %d\n",txidind,rdata->numtxids), exit(-1); } if ( ramchain->H.ROflag != 0 ) { @@ -492,7 +493,7 @@ uint32_t iguana_ramchain_addspend(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 char str[65],str2[65]; printf("ramchain_addspend RO value mismatch diffseq.%x v %x (%d) vs (%d) %s vs %s\n",s->sequenceid,sequence,s->prevout,prev_vout,bits256_str(str,txid),bits256_str(str2,prev_hash)); return(0); } - /*if ( (checklen= iguana_vinscriptdecode(coin,ramchain,&metalen,_script,&Kspace[ramchain->H.data->scriptspace],Kspace,s)) != vinscriptlen || (vinscript != 0 && memcmp(_script,vinscript,vinscriptlen) != 0) ) + /*if ( (checklen= iguana_vinscriptdecode(coin,ramchain,&metalen,_script,&Kspace[rdata->scriptspace],Kspace,s)) != vinscriptlen || (vinscript != 0 && memcmp(_script,vinscript,vinscriptlen) != 0) ) { static uint64_t counter; if ( counter++ < 100 ) @@ -510,11 +511,6 @@ uint32_t iguana_ramchain_addspend(struct iguana_info *coin,RAMCHAIN_FUNC,bits256 } else { - //for (i=0; isequenceid = sequence; s->external = external, s->spendtxidind = txidind, s->prevout = prev_vout; @@ -586,8 +582,8 @@ uint32_t iguana_ramchain_addspend256(struct iguana_info *coin,struct iguana_peer if ( (s->vinscriptlen= vinscriptlen) > 0 && vinscript != 0 && addr != 0 && addr->vinsfp != 0 && vinscriptlen < IGUANA_MAXSCRIPTSIZE) { #ifdef __PNACL__ - static portable_mutex_t mutex; - portable_mutex_lock(&mutex); + //static portable_mutex_t mutex; + //portable_mutex_lock(&mutex); #endif s->fileid = (uint32_t)addr->addrind; if ( (s->scriptpos= ftell(addr->vinsfp)) == 0 ) @@ -596,11 +592,13 @@ uint32_t iguana_ramchain_addspend256(struct iguana_info *coin,struct iguana_peer printf("error.%d writing vinscriptlen.%d errno.%d addrind.%d\n",err,vinscriptlen,errno,addr->addrind); else addr->dirty[1]++; #ifdef __PNACL__ - portable_mutex_unlock(&mutex); + //portable_mutex_unlock(&mutex); #endif } else s->scriptpos = 0; //else printf("spend256 scriptfpos.%d\n",s->scriptfpos); - //char str[65]; printf("W.%p s.%d vout.%d/%d [%d] %s fpos.%u slen.%d\n",s,spendind,s->prevout,prev_vout,bp->hdrsi,bits256_str(str,prev_hash),s->scriptfpos,s->vinscriptlen); + char str[65]; + if ( 0 && coin->virtualchain != 0 ) + printf("W.%p s.%d vout.%d/%d [%d] %s fpos.%u slen.%d\n",s,spendind,s->prevout,prev_vout,bp->hdrsi,bits256_str(str,prev_hash),(uint32_t)s->scriptpos,s->vinscriptlen); } return(spendind); } @@ -608,7 +606,7 @@ uint32_t iguana_ramchain_addspend256(struct iguana_info *coin,struct iguana_peer int64_t iguana_hashmemsize(int64_t numtxids,int64_t numunspents,int64_t numspends,int64_t numpkinds,int64_t numexternaltxids,int64_t scriptspace) { int64_t allocsize = 0; - allocsize += (scriptspace + IGUANA_MAXSCRIPTSIZE + ((numtxids + numpkinds) * (sizeof(UT_hash_handle)*2)) + (((sizeof(struct iguana_account)) * 2 * numpkinds)) + (2 * numunspents * sizeof(struct iguana_spendvector))); + allocsize += 2 * (scriptspace + IGUANA_MAXSCRIPTSIZE + ((numtxids + numpkinds) * (sizeof(UT_hash_handle)*2)) + (((sizeof(struct iguana_account)) * 2 * numpkinds)) + (2 * numunspents * sizeof(struct iguana_spendvector))); if ( allocsize >= (1LL << 32) ) { printf("REALLY big hashmemsize %llu, truncate and hope for best\n",(long long)allocsize); @@ -686,13 +684,13 @@ void *iguana_ramchain_offset(char *fname,void *dest,uint8_t *lhash,FILE *fp,uint else if ( fp != 0 && len > 0 ) { #ifdef __PNACL__ - static portable_mutex_t mutex; - portable_mutex_lock(&mutex); + //static portable_mutex_t mutex; + //portable_mutex_lock(&mutex); #endif startfpos = ftell(fp); err = fwrite(srcptr,1,len,fp); #ifdef __PNACL__ - portable_mutex_unlock(&mutex); + //portable_mutex_unlock(&mutex); #endif if ( err != len ) { @@ -702,19 +700,6 @@ void *iguana_ramchain_offset(char *fname,void *dest,uint8_t *lhash,FILE *fp,uint fprintf(stderr,"probably out of disk space. please free up space\n"); fpos = len = 0; } -#ifdef __PNACL__ - if ( 0 && len > 0 ) - { - int32_t i,c; - fseek(fp,startfpos,SEEK_SET); - for (i=0; iH.data != 0 ) + if ( (rdata= ramchain->H.data) != 0 ) { + //printf("start PREFETCH.[%d] flag.%d -> nonz.%d\n",rdata->height,flag,nonz); if ( flag == 0 ) { ptr = ramchain->fileptr; @@ -738,15 +724,12 @@ int32_t iguana_ramchain_prefetch(struct iguana_info *coin,struct iguana_ramchain else if ( (flag & 1) != 0 ) { //printf("nonz.%d of %d\n",nonz,(int32_t)ramchain->filesize); - X = RAMCHAIN_PTR(ramchain->H.data,Xoffset); - T = RAMCHAIN_PTR(ramchain->H.data,Toffset); - TXbits = RAMCHAIN_PTR(ramchain->H.data,TXoffset); - //X = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Xoffset); - //T = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Toffset); - //TXbits = (void *)(long)((long)ramchain->H.data + ramchain->H.data->TXoffset); - numtxids = ramchain->H.data->numtxids; - numexternal = ramchain->H.data->numexternaltxids; - tlen = (ramchain->H.data->numtxsparse * ramchain->H.data->txsparsebits) >> 3; + X = RAMCHAIN_PTR(rdata,Xoffset); + T = RAMCHAIN_PTR(rdata,Toffset); + TXbits = RAMCHAIN_PTR(rdata,TXoffset); + numtxids = rdata->numtxids; + numexternal = rdata->numexternaltxids; + tlen = (rdata->numtxsparse * rdata->txsparsebits) >> 3; for (i=0; iH.data,Uoffset); - //U = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Uoffset); - numunspents = ramchain->H.data->numunspents; + U = RAMCHAIN_PTR(rdata,Uoffset); + numunspents = rdata->numunspents; for (i=0; iH.data,Poffset); - PKbits = RAMCHAIN_PTR(ramchain->H.data,PKoffset); - //P = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Poffset); - //PKbits = (void *)(long)((long)ramchain->H.data + ramchain->H.data->PKoffset); - numpkinds = ramchain->H.data->numpkinds; - plen = (ramchain->H.data->numpksparse * ramchain->H.data->pksparsebits) >> 3; + P = RAMCHAIN_PTR(rdata,Poffset); + PKbits = RAMCHAIN_PTR(rdata,PKoffset); + numpkinds = rdata->numpkinds; + plen = (rdata->numpksparse * rdata->pksparsebits) >> 3; for (i=0; i nonz.%d\n",rdata->height,flag,nonz); } - //printf("PREFETCH.[%d] flag.%d -> nonz.%d\n",ramchain->H.data->height,flag,nonz); return(nonz); } -int64_t _iguana_rdata_action(char *fname,FILE *fp,bits256 lhashes[IGUANA_NUMLHASHES],void *destptr,uint64_t fpos,uint32_t expanded,uint32_t numtxids,uint32_t numunspents,uint32_t numspends,uint32_t numpkinds,uint32_t numexternaltxids,uint32_t scriptspace,uint32_t txsparsebits,uint64_t numtxsparse,uint32_t pksparsebits,uint64_t numpksparse,uint64_t srcsize,RAMCHAIN_FUNC,int32_t numblocks) +int64_t _iguana_rdata_action(char *fname,FILE *fp,bits256 lhashes[IGUANA_NUMLHASHES],void *destptr,uint64_t fpos,uint32_t expanded,uint32_t numtxids,uint32_t numunspents,uint32_t numspends,uint32_t numpkinds,uint32_t numexternaltxids,uint32_t scriptspace,uint32_t txsparsebits,uint64_t numtxsparse,uint32_t pksparsebits,uint64_t numpksparse,uint64_t srcsize,RAMCHAIN_FUNC,int32_t numblocks,uint8_t zcash) { #define RAMCHAIN_LARG(ind) ((lhashes == 0) ? 0 : lhashes[ind].bytes) FILE *fparg = 0; int32_t iter; uint64_t txbits,pkbits,offset = 0; struct iguana_ramchaindata *rdata = destptr; @@ -836,16 +816,8 @@ int64_t _iguana_rdata_action(char *fname,FILE *fp,bits256 lhashes[IGUANA_NUMLHAS continue; } offset = sizeof(struct iguana_ramchaindata); - char str[65]; - //if ( fparg != 0 && numblocks > 1 ) - // printf("%p B[0] %s -> ",B,bits256_str(str,B[0].hash2)); - B = iguana_ramchain_offset(fname,rdata,RAMCHAIN_LARG(IGUANA_LHASH_BLOCKS),fparg,fpos,B,&offset,(sizeof(struct iguana_blockRO) * numblocks),srcsize); - if ( 0 && fparg != 0 && numblocks > 1 ) - { - printf("%s %p\n",bits256_str(str,B[0].hash2),B); - //if ( bits256_nonz(B[0].hash2) == 0 ) - // getchar(); - } + //printf("bROsize.%d\n",bROsize); + B = iguana_ramchain_offset(fname,rdata,RAMCHAIN_LARG(IGUANA_LHASH_BLOCKS),fparg,fpos,B,&offset,(iguana_blockROsize(zcash) * numblocks),srcsize); T = iguana_ramchain_offset(fname,rdata,RAMCHAIN_LARG(IGUANA_LHASH_TXIDS),fparg,fpos,T,&offset,(sizeof(struct iguana_txid) * numtxids),srcsize); if ( expanded != 0 ) { @@ -913,71 +885,77 @@ int64_t _iguana_rdata_action(char *fname,FILE *fp,bits256 lhashes[IGUANA_NUMLHAS #undef SPARSECOUNT } -int64_t iguana_ramchain_action(char *fname,RAMCHAIN_FUNC,FILE *fp,bits256 lhashes[IGUANA_NUMLHASHES],struct iguana_ramchaindata *destdata,uint64_t fpos,struct iguana_ramchaindata *srcdata,int32_t numblocks,int32_t scriptspace) +int64_t iguana_ramchain_action(char *fname,RAMCHAIN_FUNC,FILE *fp,bits256 lhashes[IGUANA_NUMLHASHES],struct iguana_ramchaindata *destdata,uint64_t fpos,struct iguana_ramchaindata *srcdata,int32_t numblocks,int32_t scriptspace,uint8_t zcash) { if ( 0 && ramchain->expanded == 0 ) printf("action.%p (%p %p %p) %ld allocated.%ld [%d:%d %d:%d]\n",srcdata,fp,lhashes,destdata,(long)fpos,(long)srcdata->allocsize,srcdata->txsparsebits,srcdata->numtxsparse,srcdata->pksparsebits,srcdata->numpksparse); - return(_iguana_rdata_action(fname,fp,lhashes,destdata,fpos,ramchain->expanded,srcdata->numtxids,srcdata->numunspents,srcdata->numspends,srcdata->numpkinds,srcdata->numexternaltxids,scriptspace,srcdata->txsparsebits,srcdata->numtxsparse,srcdata->pksparsebits,srcdata->numpksparse,srcdata->allocsize,RAMCHAIN_ARG,numblocks)); + return(_iguana_rdata_action(fname,fp,lhashes,destdata,fpos,ramchain->expanded,srcdata->numtxids,srcdata->numunspents,srcdata->numspends,srcdata->numpkinds,srcdata->numexternaltxids,scriptspace,srcdata->txsparsebits,srcdata->numtxsparse,srcdata->pksparsebits,srcdata->numpksparse,srcdata->allocsize,RAMCHAIN_ARG,numblocks,zcash)); } -int64_t iguana_ramchain_size(char *fname,RAMCHAIN_FUNC,int32_t numblocks,int32_t scriptspace) +int64_t iguana_ramchain_size(char *fname,RAMCHAIN_FUNC,int32_t numblocks,int32_t scriptspace,uint8_t zcash) { - int64_t allocsize; - allocsize = iguana_ramchain_action(fname,RAMCHAIN_ARG,0,0,0,0,ramchain->H.data,numblocks,scriptspace); - if ( 0 && ramchain->expanded != 0 ) - printf("%p iguana_ramchain_size.expanded.%d %u: Koffset.%u scriptoffset.%u stacksize.%u stackspace.%u [%u]\n",ramchain,ramchain->expanded,(int32_t)allocsize,(int32_t)ramchain->H.data->Koffset,(int32_t)ramchain->H.scriptoffset,(int32_t)ramchain->H.stacksize,(int32_t)ramchain->H.data->stackspace,scriptspace); + int64_t allocsize = -1; struct iguana_ramchaindata *rdata; + if ( (rdata= ramchain->H.data) != 0 ) + { + allocsize = iguana_ramchain_action(fname,RAMCHAIN_ARG,0,0,0,0,rdata,numblocks,scriptspace,zcash); + if ( 0 && ramchain->expanded != 0 ) + printf("%p iguana_ramchain_size.expanded.%d %u: Koffset.%u scriptoffset.%u stacksize.%u stackspace.%u [%u]\n",ramchain,ramchain->expanded,(int32_t)allocsize,(int32_t)rdata->Koffset,(int32_t)ramchain->H.scriptoffset,(int32_t)ramchain->H.stacksize,(int32_t)rdata->stackspace,scriptspace); + } return(allocsize); } -long iguana_ramchain_setsize(char *fname,struct iguana_ramchain *ramchain,struct iguana_ramchaindata *srcdata,int32_t numblocks) +long iguana_ramchain_setsize(char *fname,struct iguana_ramchain *ramchain,struct iguana_ramchaindata *srcdata,int32_t numblocks,uint8_t zcash) { RAMCHAIN_DECLARE; RAMCHAIN_ZEROES; struct iguana_ramchaindata *rdata = ramchain->H.data; //B = 0, Ux = 0, Sx = 0, P = 0, A = 0, X = 0, Kspace = TXbits = PKbits = 0, U = 0, S = 0, T = 0; //U2 = 0, P2 = 0, - rdata->numtxids = ramchain->H.txidind; - rdata->numunspents = ramchain->H.unspentind; - rdata->numspends = ramchain->H.spendind; - rdata->numpkinds = ramchain->pkind; - rdata->numexternaltxids = ramchain->externalind; - rdata->scriptspace = ramchain->H.scriptoffset; - rdata->stackspace = ramchain->H.stacksize; - rdata->allocsize = iguana_ramchain_size(fname,RAMCHAIN_ARG,numblocks,rdata->scriptspace); - if ( 0 && rdata->scriptspace != 0 ) - printf("iguana_ramchain_setsize: Koffset.%d scriptspace.%d stackspace.%d (scriptoffset.%d stacksize.%d) allocsize.%d\n",(int32_t)rdata->Koffset,(int32_t)rdata->scriptspace,(int32_t)rdata->stackspace,(int32_t)ramchain->H.scriptoffset,(int32_t)ramchain->H.stacksize,(int32_t)rdata->allocsize); - ramchain->datasize = rdata->allocsize; - return((long)rdata->allocsize); + if ( rdata != 0 ) + { + rdata->numtxids = ramchain->H.txidind; + rdata->numunspents = ramchain->H.unspentind; + rdata->numspends = ramchain->H.spendind; + rdata->numpkinds = ramchain->pkind; + rdata->numexternaltxids = ramchain->externalind; + rdata->scriptspace = ramchain->H.scriptoffset; + rdata->stackspace = ramchain->H.stacksize; + rdata->allocsize = iguana_ramchain_size(fname,RAMCHAIN_ARG,numblocks,rdata->scriptspace,zcash); + if ( 0 && rdata->scriptspace != 0 ) + printf("iguana_ramchain_setsize: Koffset.%d scriptspace.%d stackspace.%d (scriptoffset.%d stacksize.%d) allocsize.%d\n",(int32_t)rdata->Koffset,(int32_t)rdata->scriptspace,(int32_t)rdata->stackspace,(int32_t)ramchain->H.scriptoffset,(int32_t)ramchain->H.stacksize,(int32_t)rdata->allocsize); + ramchain->datasize = rdata->allocsize; + return((long)rdata->allocsize); + } else return(-1); } -int64_t iguana_ramchain_compact(char *fname,RAMCHAIN_FUNC,struct iguana_ramchaindata *destdata,struct iguana_ramchaindata *srcdata,int32_t numblocks) +int64_t iguana_ramchain_compact(char *fname,RAMCHAIN_FUNC,struct iguana_ramchaindata *destdata,struct iguana_ramchaindata *srcdata,int32_t numblocks,uint8_t zcash) { //iguana_ramchain_setsize(ramchain,srcdata); - return(iguana_ramchain_action(fname,RAMCHAIN_ARG,0,0,destdata,0,srcdata,numblocks,ramchain->H.scriptoffset)); + return(iguana_ramchain_action(fname,RAMCHAIN_ARG,0,0,destdata,0,srcdata,numblocks,ramchain->H.scriptoffset,zcash)); } -bits256 iguana_ramchain_lhashes(char *fname,RAMCHAIN_FUNC,struct iguana_ramchaindata *destdata,struct iguana_ramchaindata *srcdata,int32_t numblocks,int32_t scriptspace) +bits256 iguana_ramchain_lhashes(char *fname,RAMCHAIN_FUNC,struct iguana_ramchaindata *destdata,struct iguana_ramchaindata *srcdata,int32_t numblocks,int32_t scriptspace,uint8_t zcash) { - iguana_ramchain_action(fname,RAMCHAIN_ARG,0,destdata->lhashes,0,0,srcdata,numblocks,scriptspace); + iguana_ramchain_action(fname,RAMCHAIN_ARG,0,destdata->lhashes,0,0,srcdata,numblocks,scriptspace,zcash); memset(&destdata->sha256,0,sizeof(destdata->sha256)); vcalc_sha256(0,destdata->sha256.bytes,(void *)destdata,sizeof(*destdata)); return(destdata->sha256); } -int64_t iguana_ramchain_saveaction(char *fname,RAMCHAIN_FUNC,FILE *fp,struct iguana_ramchaindata *rdata,int32_t numblocks,int32_t scriptspace) +int64_t iguana_ramchain_saveaction(char *fname,RAMCHAIN_FUNC,FILE *fp,struct iguana_ramchaindata *rdata,int32_t numblocks,int32_t scriptspace,uint8_t zcash) { long before,after; before = ftell(fp); - iguana_ramchain_action(fname,RAMCHAIN_ARG,fp,0,rdata,0,rdata,numblocks,scriptspace); + iguana_ramchain_action(fname,RAMCHAIN_ARG,fp,0,rdata,0,rdata,numblocks,scriptspace,zcash); after = ftell(fp); if ( 0 && ramchain->expanded == 0 ) { int32_t i; for (i=0; i size.%ld %ld vs %ld %u\n",(int32_t)rdata->Koffset,(long)Kspace-(long)rdata,(int32_t)sizeof(*rdata),rdata->numtxids,rdata->numunspents,rdata->numspends,rdata->numpkinds,rdata->numexternaltxids,(long)rdata->allocsize,(long)iguana_ramchain_size(fname,RAMCHAIN_ARG,numblocks,scriptspace),after-before+sizeof(*rdata),scriptspace); + printf(" SAVEACTION: K.%d:%ld rdata.%d DEST T.%d U.%d S.%d P.%d X.%d -> size.%ld %ld vs %ld %u\n",(int32_t)rdata->Koffset,(long)Kspace-(long)rdata,(int32_t)sizeof(*rdata),rdata->numtxids,rdata->numunspents,rdata->numspends,rdata->numpkinds,rdata->numexternaltxids,(long)rdata->allocsize,(long)iguana_ramchain_size(fname,RAMCHAIN_ARG,numblocks,scriptspace,zcash),after-before+sizeof(*rdata),scriptspace); } - //printf("before.%ld after.%ld allocsize.%ld [%ld] %ld expanded.%d\n",before,after,(long)srcdata->allocsize,(long)ramchain->H.data->allocsize,(long)iguana_ramchain_size(ramchain),ramchain->expanded); + //printf("before.%ld after.%ld allocsize.%ld [%ld] %ld expanded.%d\n",before,after,(long)srcdata->allocsize,(long)rdata->allocsize,(long)iguana_ramchain_size(ramchain),ramchain->expanded); return(after - before); } -int64_t iguana_ramchain_init(char *fname,struct iguana_ramchain *ramchain,struct OS_memspace *mem,struct OS_memspace *hashmem,int32_t firsti,int32_t numtxids,int32_t numunspents,int32_t numspends,int32_t numpkinds,int32_t numexternaltxids,int32_t scriptspace,int32_t expanded,int32_t numblocks) +int64_t iguana_ramchain_init(char *fname,struct iguana_ramchain *ramchain,struct OS_memspace *mem,struct OS_memspace *hashmem,int32_t firsti,int32_t numtxids,int32_t numunspents,int32_t numspends,int32_t numpkinds,int32_t numexternaltxids,int32_t scriptspace,int32_t expanded,int32_t numblocks,uint8_t zcash) { RAMCHAIN_DECLARE; RAMCHAIN_ZEROES; int64_t offset = 0; struct iguana_ramchaindata *rdata; //B = 0, Ux = 0, Sx = 0, P = 0, A = 0, X = 0, Kspace = TXbits = PKbits = 0, U = 0, S = 0, T = 0; @@ -988,6 +966,8 @@ int64_t iguana_ramchain_init(char *fname,struct iguana_ramchain *ramchain,struct if ( (ramchain->hashmem= hashmem) != 0 ) iguana_memreset(hashmem); rdata = ramchain->H.data = mem->ptr;//, offset += sizeof(struct iguana_ramchaindata); + if ( rdata == 0 ) + return(0); if ( (rdata->firsti= firsti) != 0 ) { numtxids++, numunspents++, numspends++; @@ -998,13 +978,13 @@ int64_t iguana_ramchain_init(char *fname,struct iguana_ramchain *ramchain,struct numexternaltxids = numspends; if ( numpkinds == 0 ) numpkinds = numunspents; - _iguana_rdata_action(fname,0,0,rdata,0,expanded,numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace,0,0,0,0,0,RAMCHAIN_ARG,numblocks); + _iguana_rdata_action(fname,0,0,rdata,0,expanded,numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace,0,0,0,0,0,RAMCHAIN_ARG,numblocks,zcash); offset += rdata->allocsize; if ( 0 && expanded != 0 ) printf("init T.%d U.%d S.%d P.%d X.%d -> %ld\n",numtxids,numunspents,numspends,numpkinds,numexternaltxids,(long)offset); - if ( rdata->allocsize != iguana_ramchain_size(fname,RAMCHAIN_ARG,numblocks,scriptspace) ) + if ( rdata->allocsize != iguana_ramchain_size(fname,RAMCHAIN_ARG,numblocks,scriptspace,zcash) ) { - printf("offset.%ld scriptspace.%d allocsize.%ld vs memsize.%ld\n",(long)offset,scriptspace,(long)rdata->allocsize,(long)iguana_ramchain_size(fname,RAMCHAIN_ARG,numblocks,scriptspace)); + printf("offset.%ld scriptspace.%d allocsize.%ld vs memsize.%ld\n",(long)offset,scriptspace,(long)rdata->allocsize,(long)iguana_ramchain_size(fname,RAMCHAIN_ARG,numblocks,scriptspace,zcash)); exit(-1); } if ( offset <= mem->totalsize ) @@ -1012,7 +992,7 @@ int64_t iguana_ramchain_init(char *fname,struct iguana_ramchain *ramchain,struct else { printf("offset.%ld vs memsize.%ld\n",(long)offset,(long)mem->totalsize); - printf("NEED %ld realloc for totalsize %ld\n",(long)offset,(long)iguana_ramchain_size(fname,RAMCHAIN_ARG,numblocks,scriptspace)); + printf("NEED %ld realloc for totalsize %ld\n",(long)offset,(long)iguana_ramchain_size(fname,RAMCHAIN_ARG,numblocks,scriptspace,zcash)); getchar(); //exit(-1); iguana_mempurge(mem); @@ -1026,13 +1006,13 @@ int64_t iguana_ramchain_init(char *fname,struct iguana_ramchain *ramchain,struct return(offset); } -int32_t iguana_ramchain_alloc(char *fname,struct iguana_info *coin,struct iguana_ramchain *ramchain,struct OS_memspace *mem,struct OS_memspace *hashmem,uint32_t numtxids,uint32_t numunspents,uint32_t numspends,uint32_t numpkinds,uint32_t numexternaltxids,uint32_t scriptspace,int32_t height,int32_t numblocks) +int32_t iguana_ramchain_alloc(char *fname,struct iguana_info *coin,struct iguana_ramchain *ramchain,struct OS_memspace *mem,struct OS_memspace *hashmem,uint32_t numtxids,uint32_t numunspents,uint32_t numspends,uint32_t numpkinds,uint32_t numexternaltxids,uint32_t scriptspace,int32_t height,int32_t numblocks,uint8_t zcash) { RAMCHAIN_DECLARE; RAMCHAIN_ZEROES; int64_t hashsize,allocsize,x; //B = 0, Ux = 0, Sx = 0, P = 0, A = 0, X = 0, Kspace = TXbits = PKbits = 0, U = 0, S = 0, T = 0; memset(ramchain,0,sizeof(*ramchain)); ramchain->height = height; - allocsize = _iguana_rdata_action(fname,0,0,0,0,1,numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace,0,0,0,0,0,RAMCHAIN_ARG,numblocks); + allocsize = _iguana_rdata_action(fname,0,0,0,0,1,numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace,0,0,0,0,0,RAMCHAIN_ARG,numblocks,zcash); if ( 0 && ramchain->expanded != 0 ) printf("T.%d U.%d S.%d P.%d X.%d -> %ld\n",numtxids,numunspents,numspends,numpkinds,numexternaltxids,(long)allocsize); memset(mem,0,sizeof(*mem)); @@ -1043,16 +1023,16 @@ int32_t iguana_ramchain_alloc(char *fname,struct iguana_info *coin,struct iguana char str[65],str2[65]; fprintf(stderr,"ht.%d wait for allocated %s < MAXMEM %s | elapsed %.2f minutes hashsize.%ld allocsize.%ld\n",height,mbstr(str,myallocated(0,-1)+hashsize+allocsize),mbstr(str2,coin->MAXMEM),(double)(time(NULL)-coin->startutc)/60.,(long)hashsize,(long)allocsize); sleep(13); } - iguana_meminit(hashmem,"ramhashmem",0,hashsize,0); + iguana_meminit(hashmem,"ramhashmem",0,hashsize + 65536,0); iguana_meminit(mem,"ramchain",0,allocsize + 65536,0); mem->alignflag = sizeof(uint32_t); hashmem->alignflag = sizeof(uint32_t); - if ( iguana_ramchain_init(fname,ramchain,mem,hashmem,1,numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace,1,numblocks) == 0 ) + if ( iguana_ramchain_init(fname,ramchain,mem,hashmem,1,numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace,1,numblocks,zcash) == 0 ) return(-1); return(0); } -long iguana_ramchain_save(struct iguana_info *coin,RAMCHAIN_FUNC,uint32_t ipbits,bits256 hash2,bits256 prevhash2,int32_t bundlei,struct iguana_bundle *bp) +long iguana_ramchain_save(struct iguana_info *coin,RAMCHAIN_FUNC,uint32_t ipbits,bits256 hash2,bits256 prevhash2,int32_t bundlei,struct iguana_bundle *bp,uint8_t zcash) { struct iguana_ramchaindata *rdata,tmp; char fname[1024]; long fpos = -1; int32_t hdrsi,checki; FILE *fp; if ( (rdata= ramchain->H.data) == 0 ) @@ -1066,55 +1046,33 @@ long iguana_ramchain_save(struct iguana_info *coin,RAMCHAIN_FUNC,uint32_t ipbits return(-1); } OS_compatible_path(fname); - /*if ( (fp= fopen(fname,"rb+")) == 0 ) - { - if ( (fp= fopen(fname,"wb")) != 0 ) - coin->peers.numfiles++; - else - { - printf("iguana_ramchain_save: couldnt create.(%s)\n",fname); - return(-1); - } - } - else if ( ipbits != 0 ) - { - //fseek(fp,0,SEEK_END); - } - else - { - fclose(fp); - if ( (fp= fopen(fname,"wb")) == 0 ) - { - printf("iguana_ramchain_save b: couldnt create.(%s)\n",fname); - return(-1); - } - }*/ #ifdef __PNACL__ - static portable_mutex_t mutex; - portable_mutex_lock(&mutex); + //static portable_mutex_t mutex; + //portable_mutex_lock(&mutex); #endif if ( (fp= fopen(fname,"wb")) == 0 ) printf("iguana_ramchain_save: couldnt create.(%s) errno.%d\n",fname,errno); - else coin->peers.numfiles++; + else if ( coin->peers != 0 ) + coin->peers->numfiles++; if ( fp != 0 ) { fpos = ftell(fp); if ( ramchain->expanded != 0 ) - iguana_ramchain_lhashes(fname,RAMCHAIN_ARG,rdata,rdata,bp!=0?bp->n:1,ramchain->H.scriptoffset); + iguana_ramchain_lhashes(fname,RAMCHAIN_ARG,rdata,rdata,bp!=0?bp->n:1,ramchain->H.scriptoffset,zcash); tmp = *rdata; - iguana_ramchain_compact(fname,RAMCHAIN_ARG,&tmp,rdata,bp!=0?bp->n:1); + iguana_ramchain_compact(fname,RAMCHAIN_ARG,&tmp,rdata,bp!=0?bp->n:1,zcash); if ( 0 && ramchain->expanded != 0 ) - printf("compact.%s: Koffset.%d scriptoffset.%d stacksize.%d allocsize.%d\n",fname,(int32_t)ramchain->H.data->Koffset,ramchain->H.scriptoffset,ramchain->H.stacksize,(int32_t)ramchain->H.data->allocsize); + printf("compact.%s: Koffset.%d scriptoffset.%d stacksize.%d allocsize.%d\n",fname,(int32_t)rdata->Koffset,ramchain->H.scriptoffset,ramchain->H.stacksize,(int32_t)rdata->allocsize); if ( fwrite(&tmp,1,sizeof(tmp),fp) != sizeof(tmp) ) { printf("ramchain_save error writing header.%s\n",fname); fpos = -1; - } else iguana_ramchain_saveaction(fname,RAMCHAIN_ARG,fp,rdata,bp!=0?bp->n:1,ramchain->H.scriptoffset); + } else iguana_ramchain_saveaction(fname,RAMCHAIN_ARG,fp,rdata,bp!=0?bp->n:1,ramchain->H.scriptoffset,zcash); *rdata = tmp; fclose(fp); } #ifdef __PNACL__ - portable_mutex_unlock(&mutex); + //portable_mutex_unlock(&mutex); #endif return(fpos); } @@ -1163,13 +1121,13 @@ int32_t iguana_ramchain_verify(struct iguana_info *coin,struct iguana_ramchain * printf("BIP 0 detected\n"); else { - char str[65]; printf("error -3: %s itemind.%d vs txidind.%d | num.%d\n",bits256_str(str,t->txid),ptr->hh.itemind,ramchain->H.txidind,ramchain->H.data->numtxids); + char str[65]; printf("error -3: %s itemind.%d vs txidind.%d | num.%d\n",bits256_str(str,t->txid),ptr->hh.itemind,ramchain->H.txidind,rdata->numtxids); return(-3); } } else { - char str[65]; printf("error -3: %s itemind.%d vs txidind.%d | num.%d\n",bits256_str(str,t->txid),ptr->hh.itemind,ramchain->H.txidind,ramchain->H.data->numtxids); + char str[65]; printf("error -3: %s itemind.%d vs txidind.%d | num.%d\n",bits256_str(str,t->txid),ptr->hh.itemind,ramchain->H.txidind,rdata->numtxids); //exit(-1); return(-3); } @@ -1261,19 +1219,21 @@ int32_t iguana_ramchain_verify(struct iguana_info *coin,struct iguana_ramchain * int32_t iguana_ramchain_free(struct iguana_info *coin,struct iguana_ramchain *ramchain,int32_t deleteflag) { - struct iguana_kvitem *item,*tmp; + struct iguana_kvitem *item,*tmp; struct iguana_ramchaindata *rdata; + if ( (rdata= ramchain->H.data) == 0 ) + return(-1); if ( ramchain->H.ROflag != 0 && ramchain->hashmem == 0 ) { if ( ramchain->A != ramchain->creditsA ) { - //printf("hashmem.%p Free A %p %p, numpkinds.%d %ld\n",ramchain->hashmem,ramchain->A,ramchain->creditsA,ramchain->H.data->numpkinds,sizeof(*ramchain->A) * ramchain->H.data->numpkinds); + //printf("hashmem.%p Free A %p %p, numpkinds.%d %ld\n",ramchain->hashmem,ramchain->A,ramchain->creditsA,rdata->numpkinds,sizeof(*ramchain->A) * rdata->numpkinds); if ( deleteflag != 0 ) - myfree(ramchain->A,sizeof(*ramchain->A) * ramchain->H.data->numpkinds), ramchain->A = 0; + myfree(ramchain->A,sizeof(*ramchain->A) * rdata->numpkinds), ramchain->A = 0; } //if ( ramchain->U2 != ramchain->roU2 ) - // myfree(ramchain->U2,sizeof(*ramchain->U2) * ramchain->H.data->numunspents), ramchain->U2 = 0; + // myfree(ramchain->U2,sizeof(*ramchain->U2) * rdata->numunspents), ramchain->U2 = 0; //if ( ramchain->P2 != ramchain->roP2 ) - // myfree(ramchain->P2,sizeof(*ramchain->P2) * ramchain->H.data->numpkinds), ramchain->P2 = 0; + // myfree(ramchain->P2,sizeof(*ramchain->P2) * rdata->numpkinds), ramchain->P2 = 0; } if ( deleteflag != 0 ) { @@ -1355,17 +1315,17 @@ int32_t iguana_bundleremove(struct iguana_info *coin,int32_t hdrsi,int32_t tmpfi int32_t iguana_ramchain_extras(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct OS_memspace *hashmem,int32_t extraflag) { - RAMCHAIN_DECLARE; int32_t err=0; - if ( ramchain->expanded != 0 ) + RAMCHAIN_DECLARE; int32_t err=0; struct iguana_ramchaindata *rdata; + if ( ramchain->expanded != 0 && (rdata= ramchain->H.data) != 0 ) { - _iguana_ramchain_setptrs(RAMCHAIN_PTRS,ramchain->H.data); - if ( extraflag == 0 && ramchain->H.data != 0 ) + _iguana_ramchain_setptrs(RAMCHAIN_PTRS,rdata); + if ( extraflag == 0 ) { if ( (ramchain->hashmem= hashmem) != 0 ) iguana_memreset(hashmem); - else printf("alloc ramchain->A %d\n",(int32_t)(sizeof(struct iguana_account) * ramchain->H.data->numpkinds)); - ramchain->A = (hashmem != 0 && hashmem->ptr != 0) ? iguana_memalloc(hashmem,sizeof(struct iguana_account) * ramchain->H.data->numpkinds,1) : mycalloc('p',ramchain->H.data->numpkinds,sizeof(struct iguana_account)); - ramchain->Uextras = (hashmem != 0 && hashmem->ptr != 0) ? iguana_memalloc(hashmem,sizeof(*ramchain->Uextras) * ramchain->H.data->numunspents,1) : mycalloc('p',ramchain->H.data->numunspents,sizeof(*ramchain->Uextras)); + else printf("alloc ramchain->A %d\n",(int32_t)(sizeof(struct iguana_account) * rdata->numpkinds)); + ramchain->A = (hashmem != 0 && hashmem->ptr != 0) ? iguana_memalloc(hashmem,sizeof(struct iguana_account) * rdata->numpkinds,1) : mycalloc('p',rdata->numpkinds,sizeof(struct iguana_account)); + ramchain->Uextras = (hashmem != 0 && hashmem->ptr != 0) ? iguana_memalloc(hashmem,sizeof(*ramchain->Uextras) * rdata->numunspents,1) : mycalloc('p',rdata->numunspents,sizeof(*ramchain->Uextras)); } else err = iguana_volatilesmap(coin,ramchain); } return(err); @@ -1390,7 +1350,8 @@ int32_t iguana_Xspendmap(struct iguana_info *coin,struct iguana_ramchain *ramcha bp->startutxo = bp->utxofinish = (uint32_t)time(NULL); if ( bp->Xvalid == 0 ) { - printf("[%d] filesize %ld Xspendptr.%p %p num.%d\n",bp->hdrsi,filesize,ramchain->Xspendptr,ramchain->Xspendinds,ramchain->numXspends); + if ( (rand() % 10) == 0 ) + printf("[%d] filesize %ld Xspendptr.%p %p num.%d\n",bp->hdrsi,filesize,ramchain->Xspendptr,ramchain->Xspendinds,ramchain->numXspends); bp->Xvalid = 1; } return(ramchain->numXspends); @@ -1405,14 +1366,15 @@ int32_t iguana_Xspendmap(struct iguana_info *coin,struct iguana_ramchain *ramcha ramchain->Xspendinds = 0; } } + else if ( 0 && iter == 1 ) + printf("couldnt map.(%s)\n",fname); } return(ramchain->numXspends); } -struct iguana_ramchain *_iguana_ramchain_map(struct iguana_info *coin,char *fname,struct iguana_bundle *bp,int32_t numblocks,struct iguana_ramchain *ramchain,struct OS_memspace *hashmem,uint32_t ipbits,bits256 hash2,bits256 prevhash2,int32_t bundlei,long fpos,int32_t allocextras,int32_t expanded) +struct iguana_ramchain *_iguana_ramchain_map(struct iguana_info *coin,char *fname,struct iguana_bundle *bp,int32_t numblocks,struct iguana_ramchain *ramchain,struct OS_memspace *hashmem,uint32_t ipbits,bits256 hash2,bits256 prevhash2,int32_t bundlei,long fpos,int32_t allocextras,int32_t expanded,uint8_t zcash) { - RAMCHAIN_DECLARE; int32_t valid,iter,i,checki,hdrsi; - char str[65],str2[65],dirstr[64]; long filesize; void *ptr; struct iguana_block *block; + RAMCHAIN_DECLARE; int32_t valid,iter,i,checki,hdrsi; long filesize; void *ptr; char str[65],str2[65],dirstr[64]; struct iguana_block *block; struct iguana_zblockRO zRO; struct iguana_ramchaindata *rdata; /*if ( ramchain->expanded != 0 && (ramchain->sigsfileptr == 0 || ramchain->sigsfilesize == 0) ) { sprintf(sigsfname,"sigs/%s/%s",coin->symbol,bits256_str(str,hash2)); @@ -1450,14 +1412,14 @@ struct iguana_ramchain *_iguana_ramchain_map(struct iguana_info *coin,char *fnam if ( ramchain->fileptr != 0 && ramchain->filesize > 0 ) { // verify hashes - ramchain->H.data = (void *)(long)((long)ramchain->fileptr + fpos); + ramchain->H.data = rdata = (void *)(long)((long)ramchain->fileptr + fpos); ramchain->H.ROflag = 1; ramchain->expanded = expanded; ramchain->numblocks = (bp == 0) ? 1 : bp->n; - //printf("ptr.%p exp.%d extra.%d %p mapped P[%d] fpos.%d + %ld -> %ld vs %ld offset.%u:%u stack.%u:%u\n",ptr,expanded,allocextras,ramchain->H.data,(int32_t)ramchain->H.data->Poffset,(int32_t)fpos,(long)ramchain->H.data->allocsize,(long)(fpos + ramchain->H.data->allocsize),ramchain->filesize,ramchain->H.scriptoffset,ramchain->H.data->scriptspace,ramchain->H.stacksize,ramchain->H.data->stackspace); + //printf("ptr.%p exp.%d extra.%d %p mapped P[%d] fpos.%d + %ld -> %ld vs %ld offset.%u:%u stack.%u:%u\n",ptr,expanded,allocextras,rdata,(int32_t)rdata->Poffset,(int32_t)fpos,(long)rdata->allocsize,(long)(fpos + rdata->allocsize),ramchain->filesize,rscriptoffset,rdata->scriptspace,rstacksize,rdata->stackspace); if ( 0 && bp != 0 ) { - /*blocksRO = (struct iguana_blockRO *)ramchain->H.data; + /*blocksRO = (struct iguana_blockRO *)rdata; for (i=0; in; i++) { printf("%p ",&blocksRO[i]); @@ -1469,7 +1431,7 @@ struct iguana_ramchain *_iguana_ramchain_map(struct iguana_info *coin,char *fnam } bp->blocks[i]->RO = blocksRO[i]; } - ramchain->H.data = (void *)&blocksRO[bp->n];*/ + rdata = (void *)&blocksRO[bp->n];*/ for (valid=0,i=bp->n-1; i>=0; i--) { if ( (block= bp->blocks[i]) != 0 ) @@ -1487,18 +1449,18 @@ struct iguana_ramchain *_iguana_ramchain_map(struct iguana_info *coin,char *fnam return(0); } } - _iguana_ramchain_setptrs(RAMCHAIN_PTRS,ramchain->H.data); - if ( iguana_ramchain_size(fname,RAMCHAIN_ARG,ramchain->numblocks,ramchain->H.data->scriptspace) != ramchain->H.data->allocsize || fpos+ramchain->H.data->allocsize > filesize ) + _iguana_ramchain_setptrs(RAMCHAIN_PTRS,rdata); + if ( iguana_ramchain_size(fname,RAMCHAIN_ARG,ramchain->numblocks,rdata->scriptspace,zcash) != rdata->allocsize || fpos+rdata->allocsize > filesize ) { - printf("iguana_ramchain_map.(%s) size mismatch %ld vs %ld vs filesize.%ld numblocks.%d expanded.%d fpos.%d sum %ld\n",fname,(long)iguana_ramchain_size(fname,RAMCHAIN_ARG,ramchain->numblocks,ramchain->H.data->scriptspace),(long)ramchain->H.data->allocsize,(long)filesize,ramchain->numblocks,expanded,(int32_t)fpos,(long)(fpos+ramchain->H.data->allocsize)); + printf("iguana_ramchain_map.(%s) size mismatch %ld vs %ld vs filesize.%ld numblocks.%d expanded.%d fpos.%d sum %ld\n",fname,(long)iguana_ramchain_size(fname,RAMCHAIN_ARG,ramchain->numblocks,rdata->scriptspace,zcash),(long)rdata->allocsize,(long)filesize,ramchain->numblocks,expanded,(int32_t)fpos,(long)(fpos+rdata->allocsize)); //exit(-1); munmap(ramchain->fileptr,ramchain->filesize); OS_removefile(fname,0); return(0); } - else if ( memcmp(hash2.bytes,ramchain->H.data->firsthash2.bytes,sizeof(bits256)) != 0 ) + else if ( memcmp(hash2.bytes,rdata->firsthash2.bytes,sizeof(bits256)) != 0 ) { - printf("iguana_ramchain_map.(%s) hash2 mismatch %s vs %s\n",fname,bits256_str(str,hash2),bits256_str(str2,ramchain->H.data->firsthash2)); + printf("iguana_ramchain_map.(%s) hash2 mismatch %s vs %s\n",fname,bits256_str(str,hash2),bits256_str(str2,rdata->firsthash2)); //munmap(ramchain->fileptr,ramchain->filesize); return(0); } @@ -1506,7 +1468,7 @@ struct iguana_ramchain *_iguana_ramchain_map(struct iguana_info *coin,char *fnam { if ( allocextras > 0 ) { - ramchain->height = ramchain->H.data->height; + ramchain->height = rdata->height; if ( iguana_ramchain_extras(coin,ramchain,ramchain->hashmem,allocextras) == 0 && bp != 0 ) { bp->balancefinish = (uint32_t)time(NULL); @@ -1518,17 +1480,27 @@ struct iguana_ramchain *_iguana_ramchain_map(struct iguana_info *coin,char *fnam { for (i=0; in; i++) { - if ( bp->blocks[i] == 0 && (bp->blocks[i]= iguana_blockhashset("mapchain",coin,-1,B[i].hash2,1)) == 0 ) + iguana_blockzcopyRO(zcash,(void *)&zRO,0,B,i); + if ( bp->blocks[i] == 0 && (bp->blocks[i]= iguana_blockhashset("mapchain",coin,-1,zRO.RO.hash2,1)) == 0 ) { printf("Error getting blockptr\n"); return(0); } - bp->blocks[i]->RO = B[i];//coin->blocks.RO[bp->bundleheight + i]; - coin->blocks.RO[bp->bundleheight+i] = B[i]; - bp->hashes[i] = B[i].hash2; + else + { + bp->hashes[i] = zRO.RO.hash2; + //bp->blocks[i]->RO = zRO.RO; + iguana_blockzcopyRO(zcash,&bp->blocks[i]->RO,0,(void *)&zRO,0); + } + /* if ( (bRO= iguana_blockzcopyRO(zcash,&bp->blocks[i]->RO,0,B,i)) != 0 ) + { + //memcpy(&bp->blocks[i]->RO,bRO,bROsize);//coin->blocks.RO[bp->bundleheight + i]; + //coin->blocks.RO[bp->bundleheight+i] = B[i]; + bp->hashes[i] = bRO->hash2; + }*/ } } - //printf("iguana_ramchain_map.(%s) size %ld vs %ld vs filesize.%ld numblocks.%d expanded.%d fpos.%d sum %ld\n",fname,(long)iguana_ramchain_size(RAMCHAIN_ARG,ramchain->numblocks,ramchain->H.data->scriptspace),(long)ramchain->H.data->allocsize,(long)filesize,ramchain->numblocks,expanded,(int32_t)fpos,(long)(fpos+ramchain->H.data->allocsize)); + //printf("iguana_ramchain_map.(%s) size %ld vs %ld vs filesize.%ld numblocks.%d expanded.%d fpos.%d sum %ld\n",fname,(long)iguana_ramchain_size(RAMCHAIN_ARG,ramchain->numblocks,rdata->scriptspace),(long)rdata->allocsize,(long)filesize,ramchain->numblocks,expanded,(int32_t)fpos,(long)(fpos+rdata->allocsize)); bp->Xvalid = 1; iguana_Xspendmap(coin,ramchain,bp); return(ramchain); @@ -1540,34 +1512,38 @@ struct iguana_ramchain *iguana_ramchain_map(struct iguana_info *coin,char *fname { struct iguana_ramchain *retptr; #ifdef __PNACL__ - static portable_mutex_t mutex; - portable_mutex_lock(&mutex); + //static portable_mutex_t mutex; + //portable_mutex_lock(&mutex); #endif ramchain->height = bp->bundleheight; - retptr = _iguana_ramchain_map(coin,fname,bp,numblocks,ramchain,hashmem,ipbits,hash2,prevhash2,bundlei,fpos,allocextras,expanded); + retptr = _iguana_ramchain_map(coin,fname,bp,numblocks,ramchain,hashmem,ipbits,hash2,prevhash2,bundlei,fpos,allocextras,expanded,coin->chain->zcash); #ifdef __PNACL__ - portable_mutex_unlock(&mutex); + //portable_mutex_unlock(&mutex); #endif return(retptr); } void iguana_ramchain_link(struct iguana_ramchain *ramchain,bits256 firsthash2,int32_t hdrsi,int32_t height,int32_t bundlei,int32_t numblocks,int32_t firsti,int32_t ROflag) { - if ( ROflag == 0 ) + struct iguana_ramchaindata *rdata; + if ( (rdata= ramchain->H.data) != 0 ) { - ramchain->H.data->firsthash2 = firsthash2; - //ramchain->H.data->lasthash2 = lasthash2; - ramchain->H.data->hdrsi = hdrsi; - ramchain->H.data->height = height; - ramchain->H.data->numblocks = numblocks; + if ( ROflag == 0 ) + { + rdata->firsthash2 = firsthash2; + //rdata->lasthash2 = lasthash2; + rdata->hdrsi = hdrsi; + rdata->height = height; + rdata->numblocks = numblocks; + } + ramchain->H.hdrsi = hdrsi; + ramchain->H.bundlei = bundlei; + ramchain->height = height; + ramchain->numblocks = numblocks; + //ramchain->lasthash2 = lasthash2; + ramchain->H.txidind = ramchain->H.unspentind = ramchain->H.spendind = ramchain->pkind = firsti; + ramchain->externalind = 0;//ramchain->H.scriptoffset = ramchain->H.stacksize = 0; } - ramchain->H.hdrsi = hdrsi; - ramchain->H.bundlei = bundlei; - ramchain->height = height; - ramchain->numblocks = numblocks; - //ramchain->lasthash2 = lasthash2; - ramchain->H.txidind = ramchain->H.unspentind = ramchain->H.spendind = ramchain->pkind = firsti; - ramchain->externalind = 0;//ramchain->H.scriptoffset = ramchain->H.stacksize = 0; } int32_t iguana_ramchain_cmp(struct iguana_ramchain *A,struct iguana_ramchain *B,int32_t deepflag) @@ -1652,23 +1628,26 @@ int32_t iguana_ramchain_cmp(struct iguana_ramchain *A,struct iguana_ramchain *B, return(-1); } -int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain *dest,struct iguana_ramchain *ramchain,struct iguana_bundle *bp,int16_t bundlei) +int32_t iguana_ramchain_iterate(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_ramchain *dest,struct iguana_ramchain *ramchain,struct iguana_bundle *bp,int16_t bundlei) { RAMCHAIN_DECLARE; RAMCHAIN_DESTDECLARE; - int32_t j,hdrsi,prevout,scriptlen; uint32_t sequenceid,destspendind=0,desttxidind=0; uint16_t fileid; uint64_t scriptpos; + int32_t j,hdrsi,prevout,scriptlen; uint32_t timestamp=0,unspentind,sequenceid,destspendind=0,desttxidind=0; uint16_t fileid; uint64_t scriptpos; int64_t crypto777_payment = 0; bits256 prevhash; uint64_t value; uint8_t type; struct iguana_unspent *u; struct iguana_txid *tx; struct iguana_ramchaindata *rdata; uint8_t rmd160[20]; //if ( dest != 0 ) - // printf("iterate ramchain.%p rdata.%p dest.%p ht.%d/%d txids.%p destoffset.%d\n",ramchain,ramchain->H.data,dest,bp->bundleheight,bp->n,ramchain->txids,dest->H.scriptoffset); + // printf("iterate ramchain.%p rdata.%p dest.%p ht.%d/%d txids.%p destoffset.%d\n",ramchain,rdata,dest,bp->bundleheight,bp->n,ramchain->txids,dest->H.scriptoffset); if ( (rdata= ramchain->H.data) == 0 ) { printf("iguana_ramchain_iterate cant iterate without data\n"); return(-1); } if ( dest != 0 ) + { + // required to do one block at a time, all vins/vouts the same height are assumed to happen simultaneously with vouts before vins _iguana_ramchain_setptrs(RAMCHAIN_DESTPTRS,dest->H.data); + } //fprintf(stderr,"iterate %d/%d dest.%p ramchain.%p rdata.%p\n",bp->bundleheight,bp->n,dest,ramchain,rdata); - _iguana_ramchain_setptrs(RAMCHAIN_PTRS,ramchain->H.data); + _iguana_ramchain_setptrs(RAMCHAIN_PTRS,rdata); ramchain->H.ROflag = 1; ramchain->H.unspentind = ramchain->H.spendind = ramchain->pkind = rdata->firsti; ramchain->externalind = ramchain->H.stacksize = 0; @@ -1683,19 +1662,22 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain if ( coin->active == 0 ) return(-1);; if ( 0 && ramchain->expanded == 0 && dest != 0 ) - printf("ITER [%d] TXID.%d -> dest.%p desttxid.%d dest->hashmem.%p numtxids.%d\n",ramchain->H.data->height,ramchain->H.txidind,dest,dest!=0?dest->H.txidind:0,dest!=0?dest->hashmem:0,rdata->numtxids); + printf("ITER [%d] TXID.%d -> dest.%p desttxid.%d dest->hashmem.%p numtxids.%d\n",rdata->height,ramchain->H.txidind,dest,dest!=0?dest->H.txidind:0,dest!=0?dest->hashmem:0,rdata->numtxids); tx = &T[ramchain->H.txidind]; if ( iguana_ramchain_addtxid(coin,RAMCHAIN_ARG,tx->txid,tx->numvouts,tx->numvins,tx->locktime,tx->version,tx->timestamp,bundlei) == 0 ) return(-1); //printf("txidind.%u firstvout.%u firstvin.%u bundlei.%d n.%d\n",tx->txidind,tx->firstvout,tx->firstvin,bundlei,bp->n); if ( dest != 0 ) { + if ( dest->expanded != 0 ) + iguana_opreturn(myinfo,1,coin,tx->timestamp,bp,0,bp->bundleheight + bundlei,(((uint64_t)bp->hdrsi << 32) | dest->H.unspentind),0,0,0,0); //char str[65]; if ( 0 && ramchain->expanded == 0 ) - printf("ITER [%d] TXID.%d -> dest.%p desttxid.%d dest->hashmem.%p numtxids.%d\n",ramchain->H.data->height,ramchain->H.txidind,dest,dest!=0?dest->H.txidind:0,dest!=0?dest->hashmem:0,rdata->numtxids); + printf("ITER [%d] TXID.%d -> dest.%p desttxid.%d dest->hashmem.%p numtxids.%d\n",rdata->height,ramchain->H.txidind,dest,dest!=0?dest->H.txidind:0,dest!=0?dest->hashmem:0,rdata->numtxids); if ( iguana_ramchain_addtxid(coin,RAMCHAIN_DESTARG,tx->txid,tx->numvouts,tx->numvins,tx->locktime,tx->version,tx->timestamp,bundlei) == 0 ) return(-2); } + crypto777_payment = 0; for (j=0; jnumvouts; j++) { if ( coin->active == 0 ) @@ -1725,7 +1707,7 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain scriptdata = iguana_ramchain_scriptdecode(&metalen,&scriptlen,Kspace,type,_script,u->scriptoffset,P[u->pkind].pubkeyoffset < ramchain->H.scriptoffset ? P[u->pkind].pubkeyoffset : 0); }*/ //fprintf(stderr,"iter add %p[%d] type.%d\n",scriptdata,scriptlen,type); - if ( iguana_ramchain_addunspent(coin,RAMCHAIN_ARG,value,hdrsi,rmd160,j,type,fileid,(uint32_t)scriptpos,scriptlen,ramchain->H.txidind-rdata->firsti) == 0 ) + if ( (unspentind= iguana_ramchain_addunspent(coin,RAMCHAIN_ARG,value,hdrsi,rmd160,j,type,fileid,(uint32_t)scriptpos,scriptlen,ramchain->H.txidind-rdata->firsti)) == 0 ) return(-3); } } @@ -1750,7 +1732,7 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain printf("%02x",scriptdata[i]); fprintf(stderr," raw unspent script type.%d U%d offset.%d\n",type,ramchain->H.unspentind,U[ramchain->H.unspentind].scriptoffset); } //else printf("no script\n");*/ - if ( iguana_ramchain_addunspent20(coin,0,RAMCHAIN_ARG,value,0,scriptlen,tx->txid,j,type,bp,rmd160) == 0 ) + if ( (unspentind= iguana_ramchain_addunspent20(coin,0,RAMCHAIN_ARG,value,0,scriptlen,tx->txid,j,type,bp,rmd160)) == 0 ) return(-4); if ( 0 ) { @@ -1761,6 +1743,7 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain } if ( dest != 0 ) { + crypto777_payment = datachain_update(myinfo,1,coin,timestamp,bp,rmd160,crypto777_payment,type,bp->bundleheight + bundlei,(((uint64_t)bp->hdrsi << 32) | unspentind),value,fileid,scriptpos,scriptlen,tx->txid,j); if ( iguana_ramchain_addunspent(coin,RAMCHAIN_DESTARG,value,hdrsi,rmd160,j,type,fileid,(uint32_t)scriptpos,scriptlen,ramchain->H.txidind-rdata->firsti) == 0 ) return(-5); } //else printf("addunspent20 done\n"); @@ -1771,7 +1754,7 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain { dest->H.txidind++; dest->H.spendind += tx->numvins; - } //else printf("iter scriptoffset.%u/%u stacksize.%u/%u\n",ramchain->H.scriptoffset,ramchain->H.data->scriptspace,ramchain->H.stacksize,ramchain->H.data->stackspace); + } //else printf("iter scriptoffset.%u/%u stacksize.%u/%u\n",ramchain->H.scriptoffset,rdata->scriptspace,ramchain->H.stacksize,rdata->stackspace); } if ( dest != 0 ) { @@ -1782,6 +1765,7 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain for (ramchain->H.txidind=rdata->firsti; ramchain->H.txidindnumtxids; ramchain->H.txidind++) { tx = &T[ramchain->H.txidind]; + timestamp = tx->timestamp; for (j=0; jnumvins; j++) { if ( coin->active == 0 ) @@ -1794,7 +1778,7 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain fileid = Sx[ramchain->H.spendind].fileid; scriptpos = Sx[ramchain->H.spendind].scriptpos; scriptlen = Sx[ramchain->H.spendind].scriptlen; - //scriptlen = iguana_vinscriptdecode(coin,ramchain,&metalen,_script,&Kspace[ramchain->H.data->scriptspace],Kspace,&Sx[ramchain->H.spendind]); + //scriptlen = iguana_vinscriptdecode(coin,ramchain,&metalen,_script,&Kspace[rdata->scriptspace],Kspace,&Sx[ramchain->H.spendind]); //scriptdata = _script; prevout = iguana_ramchain_txid(coin,RAMCHAIN_ARG,&prevhash,&Sx[ramchain->H.spendind]); //fprintf(stderr,"from expanded iter\n"); @@ -1802,7 +1786,7 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain { char str[65]; printf("hdrsi.%d txidind.%d spendind.%d spendtxid.%x %d vin.%d %s vout.%d\n",bp->bundleheight,ramchain->H.txidind,ramchain->H.spendind,Sx[ramchain->H.spendind].spendtxidind,Sx[ramchain->H.spendind].spendtxidind&0xfffffff,j,bits256_str(str,prevhash),prevout); - //for (i=0; iH.data->numexternaltxids; i++) + //for (i=0; inumexternaltxids; i++) // printf("%p X[%d] %s\n",X,i,bits256_str(str,X[i])); //exit(-1); iguana_ramchain_txid(coin,RAMCHAIN_ARG,&prevhash,&Sx[ramchain->H.spendind]); @@ -1834,6 +1818,7 @@ int32_t iguana_ramchain_iterate(struct iguana_info *coin,struct iguana_ramchain } if ( dest != 0 ) { + datachain_update_spend(myinfo,1,coin,timestamp,bp,bp->bundleheight + bundlei,tx->txid,j,0,-1); if ( iguana_ramchain_addspend(coin,RAMCHAIN_DESTARG,prevhash,prevout,sequenceid,bp->hdrsi,fileid,scriptpos,scriptlen) == 0 ) return(-9); //printf("from dest iter scriptspace.%d\n",dest->H.stacksize); @@ -1849,25 +1834,25 @@ long iguana_ramchain_data(struct iguana_info *coin,struct iguana_peer *addr,stru { static uint64_t totalrecv; int32_t verifyflag = 0; - RAMCHAIN_DECLARE; uint32_t addr_ipbits; struct iguana_ramchain R,*mapchain,*ramchain = &addr->ramchain; - struct iguana_msgtx *tx; char fname[1024]; uint8_t rmd160[20]; // long fsize; void *ptr; - int32_t i,j,fpos,pubkeysize,msize,sigsize,subdir,firsti=1,err,flag,bundlei = -2; bits256 merkle_root; - struct iguana_bundle *bp = 0; struct iguana_block *block; uint32_t scriptspace,stackspace; + RAMCHAIN_DECLARE; uint32_t addr_ipbits; struct iguana_ramchain R,*mapchain,*ramchain = &addr->ramchain; struct iguana_msgtx *tx; char fname[1024]; uint8_t rmd160[20]; struct iguana_ramchaindata *rdata; int32_t i,j,fpos,pubkeysize,msize,sigsize,subdir,firsti=1,err,flag,bundlei = -2; bits256 merkle_root; struct iguana_bundle *bp = 0; struct iguana_block *block; uint32_t scriptspace,stackspace; totalrecv += recvlen; #ifdef __PNACL__ //verifyflag = 1; #endif - if ( (addr_ipbits= (uint32_t)addr->ipbits) == 0 ) + if ( addr == 0 || (addr_ipbits= (uint32_t)addr->ipbits) == 0 ) addr_ipbits = 1; - if ( bits256_nonz(origtxdata->block.RO.merkle_root) == 0 ) + if ( bits256_nonz(origtxdata->zblock.RO.merkle_root) == 0 ) { - memset(&origtxdata->block.RO.prev_block,0,sizeof(bits256)); - origtxdata->block.RO.recvlen = 0; - origtxdata->block.issued = 0; + memset(&origtxdata->zblock.RO.prev_block,0,sizeof(bits256)); + origtxdata->zblock.RO.recvlen = 0; + origtxdata->zblock.issued = 0; return(-1); } - for (i=0; idirty)/sizeof(*addr->dirty); i++) - addr->dirty[i] = 0; + if ( addr != 0 ) + { + for (i=0; idirty)/sizeof(*addr->dirty); i++) + addr->dirty[i] = 0; + } msize = (int32_t)sizeof(bits256) * (txn_count+1) * 2; if ( msize <= addr->TXDATA.totalsize ) { @@ -1875,41 +1860,41 @@ long iguana_ramchain_data(struct iguana_info *coin,struct iguana_peer *addr,stru iguana_memreset(&addr->TXDATA); for (i=0; iblock.RO.merkle_root) != 0 ) + merkle_root = iguana_merkle(tree,txn_count); + if ( bits256_cmp(merkle_root,origtxdata->zblock.RO.merkle_root) != 0 ) { char str[65],str2[65]; - printf(">>>>>>>>>> merkle mismatch.[%d] calc.(%s) vs (%s)\n",txn_count,bits256_str(str,merkle_root),bits256_str(str2,origtxdata->block.RO.merkle_root)); - origtxdata->block.RO.recvlen = 0; - origtxdata->block.issued = 0; + printf(">>>>>>>>>> %s %s merkle mismatch.[%d] calc.(%s) vs (%s)\n",addr->ipaddr,coin->symbol,txn_count,bits256_str(str,merkle_root),bits256_str(str2,origtxdata->zblock.RO.merkle_root)); + origtxdata->zblock.RO.recvlen = 0; + origtxdata->zblock.issued = 0; return(-1); } //else printf("matched merkle.%d\n",txn_count); } else printf("not enough memory for merkle verify %d vs %lu\n",(int32_t)(sizeof(bits256)*(txn_count+1)),(long)addr->TXDATA.totalsize); bp = 0, bundlei = -2; - if ( iguana_bundlefind(coin,&bp,&bundlei,origtxdata->block.RO.hash2) == 0 ) + if ( iguana_bundlefind(coin,&bp,&bundlei,origtxdata->zblock.RO.hash2) == 0 ) { bp = 0, bundlei = -2; - if ( iguana_bundlefind(coin,&bp,&bundlei,origtxdata->block.RO.prev_block) == 0 ) + if ( iguana_bundlefind(coin,&bp,&bundlei,origtxdata->zblock.RO.prev_block) == 0 ) { - origtxdata->block.RO.recvlen = 0; - origtxdata->block.issued = 0; + origtxdata->zblock.RO.recvlen = 0; + origtxdata->zblock.issued = 0; return(-1); } else if ( bundlei < coin->chain->bundlesize-1 ) bundlei++; else { - origtxdata->block.issued = 0; - origtxdata->block.RO.recvlen = 0; - char str[65]; printf("ramchain data: error finding block %s\n",bits256_str(str,origtxdata->block.RO.hash2)); + origtxdata->zblock.issued = 0; + origtxdata->zblock.RO.recvlen = 0; + char str[65]; printf("ramchain data: error finding block %s\n",bits256_str(str,origtxdata->zblock.RO.hash2)); return(-1); } } - if ( (block= bp->blocks[bundlei]) == 0 || bits256_cmp(block->RO.hash2,origtxdata->block.RO.hash2) != 0 || bits256_cmp(bp->hashes[bundlei],origtxdata->block.RO.hash2) != 0 ) + if ( (block= bp->blocks[bundlei]) == 0 || bits256_cmp(block->RO.hash2,origtxdata->zblock.RO.hash2) != 0 || bits256_cmp(bp->hashes[bundlei],origtxdata->zblock.RO.hash2) != 0 ) { char str[65]; if ( 0 && block != 0 ) - printf("%d:%d has no block ptr.%p %s or wrong hash\n",bp->hdrsi,bundlei,block,bits256_str(str,origtxdata->block.RO.hash2)); + printf("%d:%d has no block ptr.%p %s or wrong hash\n",bp->hdrsi,bundlei,block,bits256_str(str,origtxdata->zblock.RO.hash2)); return(-1); } block->txvalid = 1; @@ -1927,7 +1912,7 @@ long iguana_ramchain_data(struct iguana_info *coin,struct iguana_peer *addr,stru } sigsize = pubkeysize = 0; scriptspace = 1;//iguana_scriptspaceraw(coin,&scriptsize,&sigsize,&pubkeysize,txarray,txn_count); - if ( iguana_ramchain_init(fname,ramchain,&addr->TXDATA,&addr->HASHMEM,1,txn_count,origtxdata->numunspents,origtxdata->numspends,0,0,(scriptspace+sigsize+pubkeysize)*1.1,0,1) == 0 ) + if ( iguana_ramchain_init(fname,ramchain,&addr->TXDATA,&addr->HASHMEM,1,txn_count,origtxdata->numunspents,origtxdata->numspends,0,0,(scriptspace+sigsize+pubkeysize)*1.1,0,1,coin->chain->zcash) == 0 ) { if ( block->fpipbits == 0 ) block->issued = block->RO.recvlen = 0, block->fpos = -1; @@ -1935,134 +1920,100 @@ long iguana_ramchain_data(struct iguana_info *coin,struct iguana_peer *addr,stru } block->fpos = fpos = -1; iguana_ramchain_link(ramchain,block->RO.hash2,bp->hdrsi,bp->bundleheight+bundlei,bundlei,1,firsti,0); - _iguana_ramchain_setptrs(RAMCHAIN_PTRS,ramchain->H.data); - subdir = bp->bundleheight / IGUANA_SUBDIRDIVISOR; - char dirname[1024]; sprintf(dirname,"%s/%s/%d",GLOBAL_TMPDIR,coin->symbol,subdir), OS_ensure_directory(dirname); - sprintf(dirname,"%s/%s/%d/%d",GLOBAL_TMPDIR,coin->symbol,subdir,bp->bundleheight), OS_ensure_directory(dirname); - //printf("Kspace.%p bp.[%d:%d] <- scriptspace.%d expanded.%d\n",Kspace,bp->hdrsi,bundlei,scriptspace,ramchain->expanded); - if ( T == 0 || U == 0 || S == 0 || B == 0 ) - { - block->issued = 0; - block->RO.recvlen = 0; - printf("fatal error getting txdataptrs %p %p %p %p\n",T,U,S,B); - return(-1); - } - block->fpipbits = 1; - for (i=0; iH.txidind++) - { - tx = &txarray[i]; - iguana_ramchain_addtxid(coin,RAMCHAIN_ARG,tx->txid,tx->tx_out,tx->tx_in,tx->lock_time,tx->version,tx->timestamp,bundlei); - for (j=0; jtx_out; j++) + if ( (rdata= ramchain->H.data) != 0 ) + { + _iguana_ramchain_setptrs(RAMCHAIN_PTRS,rdata); + subdir = bp->bundleheight / IGUANA_SUBDIRDIVISOR; + char dirname[1024]; sprintf(dirname,"%s/%s/%d",GLOBAL_TMPDIR,coin->symbol,subdir), OS_ensure_directory(dirname); + sprintf(dirname,"%s/%s/%d/%d",GLOBAL_TMPDIR,coin->symbol,subdir,bp->bundleheight), OS_ensure_directory(dirname); + //printf("Kspace.%p bp.[%d:%d] <- scriptspace.%d expanded.%d\n",Kspace,bp->hdrsi,bundlei,scriptspace,ramchain->expanded); + if ( T == 0 || U == 0 || S == 0 || B == 0 ) + { + block->issued = 0; + block->RO.recvlen = 0; + printf("fatal error getting txdataptrs %p %p %p %p\n",T,U,S,B); + return(-1); + } + block->fpipbits = 1; + for (i=0; iH.txidind++) { - memset(rmd160,0,sizeof(rmd160)); - //printf("i.%d j.%d pkscriptlen.%d\n",i,j,tx->vouts[j].pk_scriptlen); - iguana_ramchain_addunspent20(coin,addr,RAMCHAIN_ARG,tx->vouts[j].value,tx->vouts[j].pk_script,tx->vouts[j].pk_scriptlen,tx->txid,j,-1,bp,rmd160); + tx = &txarray[i]; + iguana_ramchain_addtxid(coin,RAMCHAIN_ARG,tx->txid,tx->tx_out,tx->tx_in,tx->lock_time,tx->version,tx->timestamp,bundlei); + for (j=0; jtx_out; j++) + { + memset(rmd160,0,sizeof(rmd160)); + //printf("i.%d j.%d pkscriptlen.%d\n",i,j,tx->vouts[j].pk_scriptlen); + iguana_ramchain_addunspent20(coin,addr,RAMCHAIN_ARG,tx->vouts[j].value,tx->vouts[j].pk_script,tx->vouts[j].pk_scriptlen,tx->txid,j,-1,bp,rmd160); + } + ramchain->H.spendind += tx->tx_in; } - ramchain->H.spendind += tx->tx_in; - } - //printf("scriptoffset.%d after %d txids\n",ramchain->H.scriptoffset,txn_count); - ramchain->H.txidind = ramchain->H.spendind = ramchain->H.data->firsti; - for (i=0; iH.txidind++) - { - tx = &txarray[i]; - for (j=0; jtx_in; j++) + //printf("scriptoffset.%d after %d txids\n",ramchain->H.scriptoffset,txn_count); + ramchain->H.txidind = ramchain->H.spendind = rdata->firsti; + for (i=0; iH.txidind++) { - iguana_ramchain_addspend256(coin,addr,RAMCHAIN_ARG,tx->vins[j].prev_hash,tx->vins[j].prev_vout,tx->vins[j].vinscript,tx->vins[j].scriptlen,tx->vins[j].sequence,bp);//,bp->hdrsi,bundlei); + tx = &txarray[i]; + for (j=0; jtx_in; j++) + { + iguana_ramchain_addspend256(coin,addr,RAMCHAIN_ARG,tx->vins[j].prev_hash,tx->vins[j].prev_vout,tx->vins[j].vinscript,tx->vins[j].scriptlen,tx->vins[j].sequence,bp);//,bp->hdrsi,bundlei); + } } - } - ramchain->H.data->prevhash2 = block->RO.prev_block; - ramchain->H.data->scriptspace = scriptspace = ramchain->H.scriptoffset; - ramchain->H.data->stackspace = stackspace = ramchain->H.stacksize; - iguana_ramchain_setsize(fname,ramchain,ramchain->H.data,1); - flag = 0; - if ( ramchain->H.txidind != ramchain->H.data->numtxids || ramchain->H.unspentind != ramchain->H.data->numunspents || ramchain->H.spendind != ramchain->H.data->numspends ) - { - printf("error creating PT ramchain.[%d:%d] ramchain->txidind %d != %d ramchain->data->numtxids || ramchain->unspentind %d != %d ramchain->data->numunspents || ramchain->spendind %d != %d ramchain->data->numspends space.(%d v %d)\n",bp->hdrsi,bp->bundleheight,ramchain->H.txidind,ramchain->H.data->numtxids,ramchain->H.unspentind,ramchain->H.data->numunspents,ramchain->H.spendind,ramchain->H.data->numspends,ramchain->H.scriptoffset,ramchain->H.data->scriptspace); - block->fpipbits = 0; - block->issued = 0; - block->RO.recvlen = 0; - } - else - { - if ( (err= iguana_ramchain_verify(coin,ramchain)) == 0 ) + rdata->prevhash2 = block->RO.prev_block; + rdata->scriptspace = scriptspace = ramchain->H.scriptoffset; + rdata->stackspace = stackspace = ramchain->H.stacksize; + iguana_ramchain_setsize(fname,ramchain,rdata,1,coin->chain->zcash); + flag = 0; + if ( ramchain->H.txidind != rdata->numtxids || ramchain->H.unspentind != rdata->numunspents || ramchain->H.spendind != rdata->numspends ) + { + printf("error creating PT ramchain.[%d:%d] ramchain->txidind %d != %d ramchain->data->numtxids || ramchain->unspentind %d != %d ramchain->data->numunspents || ramchain->spendind %d != %d ramchain->data->numspends space.(%d v %d)\n",bp->hdrsi,bp->bundleheight,ramchain->H.txidind,rdata->numtxids,ramchain->H.unspentind,rdata->numunspents,ramchain->H.spendind,rdata->numspends,ramchain->H.scriptoffset,rdata->scriptspace); + block->fpipbits = 0; + block->issued = 0; + block->RO.recvlen = 0; + } + else { - B[0] = block->RO; - ramchain->H.data->scriptspace = ramchain->H.scriptoffset = scriptspace; - ramchain->H.data->stackspace = ramchain->H.stacksize = stackspace; - if ( (fpos= (int32_t)iguana_ramchain_save(coin,RAMCHAIN_ARG,addr_ipbits,block->RO.hash2,block->RO.prev_block,bundlei,0)) >= 0 ) + if ( (err= iguana_ramchain_verify(coin,ramchain)) == 0 ) { - //char str[65]; printf("saved.%s [%d:%d]\n",bits256_str(str,block->RO.hash2),bp->hdrsi,bundlei); - origtxdata->datalen = (int32_t)ramchain->H.data->allocsize; - ramchain->H.ROflag = 0; - flag = 1; - if ( addr->dirty[0] != 0 && addr->voutsfp != 0 ) - fflush(addr->voutsfp); - if ( addr->dirty[1] != 0 && addr->vinsfp != 0 ) - fflush(addr->vinsfp); - memset(&R,0,sizeof(R)); - if ( verifyflag != 0 && (mapchain= iguana_ramchain_map(coin,fname,0,1,&R,0,addr_ipbits,block->RO.hash2,block->RO.prev_block,bundlei,fpos,1,0)) == 0 ) + iguana_blockzcopyRO(coin->chain->zcash,B,0,&block->RO,0); + rdata->scriptspace = ramchain->H.scriptoffset = scriptspace; + rdata->stackspace = ramchain->H.stacksize = stackspace; + if ( (fpos= (int32_t)iguana_ramchain_save(coin,RAMCHAIN_ARG,addr_ipbits,block->RO.hash2,block->RO.prev_block,bundlei,0,coin->chain->zcash)) >= 0 ) { - printf("delete unverified [%d:%d]\n",bp->hdrsi,bundlei); - iguana_ramchain_free(coin,&R,1); - fpos = -1; - //printf("mapped Soffset.%ld\n",(long)mapchain->data->Soffset); - /*iguana_ramchain_link(&R,block->RO.hash2,bp->hdrsi,bp->bundleheight+bundlei,bundlei,1,firsti,1); - if ( 1 ) // unix issues? - { - if ( (err= iguana_ramchain_cmp(ramchain,mapchain,0)) != 0 ) - fpos = -1, printf("error.%d comparing ramchains\n",err); - else - { - ptr = mapchain->fileptr; fsize = mapchain->filesize; - mapchain->fileptr = 0, mapchain->filesize = 0; - iguana_ramchain_free(coin,mapchain,1); - memset(&R,0,sizeof(R)); - R.H.data = (void *)(long)((long)ptr + fpos), R.filesize = fsize; - iguana_ramchain_link(&R,block->RO.hash2,bp->hdrsi,bp->bundleheight+bundlei,bundlei,1,firsti,1); - } - } - if ( (err= iguana_ramchain_cmp(ramchain,&R,0)) != 0 ) + origtxdata->datalen = (int32_t)rdata->allocsize; + //char str[65]; printf("saved.%s [%d:%d] fpos.%d datalen.%d\n",bits256_str(str,block->RO.hash2),bp->hdrsi,bundlei,fpos,origtxdata->datalen); + ramchain->H.ROflag = 0; + flag = 1; + if ( addr->dirty[0] != 0 && addr->voutsfp != 0 ) + fflush(addr->voutsfp); + if ( addr->dirty[1] != 0 && addr->vinsfp != 0 ) + fflush(addr->vinsfp); + memset(&R,0,sizeof(R)); + if ( verifyflag != 0 && (mapchain= iguana_ramchain_map(coin,fname,0,1,&R,0,addr_ipbits,block->RO.hash2,block->RO.prev_block,bundlei,fpos,1,0)) == 0 ) { + printf("delete unverified [%d:%d]\n",bp->hdrsi,bundlei); + iguana_ramchain_free(coin,&R,1); fpos = -1; - block->issued = 0; - block->RO.recvlen = 0; - printf("error.%d comparing REMAP ramchains\n",err); } else { - iguana_ramchain_extras(coin,&R,0,0); - if ( (err= iguana_ramchain_iterate(coin,0,&R,bp,bundlei)) != 0 ) - printf("err.%d iterate ",err); - //printf("SUCCESS REMAP\n"); - bp->numtxids += ramchain->H.data->numtxids; - bp->numunspents += ramchain->H.data->numunspents; - bp->numspends += ramchain->H.data->numspends; - //bp->rawscriptspace += ramchain->H.data->scriptspace; + bp->numtxids += rdata->numtxids; + bp->numunspents += rdata->numunspents; + bp->numspends += rdata->numspends; + //bp->rawscriptspace += rdata->scriptspace; } - iguana_ramchain_free(coin,&R,1); - if ( err != 0 ) - iguana_blockunmark(coin,block,bp,bundlei,1);*/ - } - else - { - bp->numtxids += ramchain->H.data->numtxids; - bp->numunspents += ramchain->H.data->numunspents; - bp->numspends += ramchain->H.data->numspends; - //bp->rawscriptspace += ramchain->H.data->scriptspace; - } - if ( fpos >= 0 ) - block->fpos = fpos, block->fpipbits = addr_ipbits; + if ( fpos >= 0 ) + block->fpos = fpos, block->fpipbits = addr_ipbits; + } else printf("save error\n"); + } + else + { + printf("ramchain verification error.%d hdrsi.%d bundlei.%d n.%d\n",err,bp->hdrsi,bundlei,bp->n); + fpos = -1; } - } - else - { - printf("ramchain verification error.%d hdrsi.%d bundlei.%d n.%d\n",err,bp->hdrsi,bundlei,bp->n); - fpos = -1; } } if ( fpos < 0 ) iguana_blockunmark(coin,block,bp,bundlei,1); - //fprintf(stderr,"finished with hdrsi.%d ht.%d scripts.%u:%u\n",bp->hdrsi,bp->bundleheight,ramchain->H.scriptoffset,ramchain->H.data->scriptspace); + //fprintf(stderr,"finished with hdrsi.%d ht.%d scripts.%u:%u\n",bp->hdrsi,bp->bundleheight,ramchain->H.scriptoffset,rdata->scriptspace); ramchain->H.ROflag = 0; iguana_ramchain_free(coin,ramchain,0); return(fpos); @@ -2072,12 +2023,12 @@ long iguana_ramchain_data(struct iguana_info *coin,struct iguana_peer *addr,stru void iguana_ramchain_disp(struct iguana_ramchain *ramchain) { - RAMCHAIN_DECLARE; int32_t j; uint32_t txidind,unspentind,spendind; struct iguana_txid *tx; char str[65]; - _iguana_ramchain_setptrs(RAMCHAIN_PTRS,ramchain->H.data); - if ( ramchain->H.data != 0 ) + RAMCHAIN_DECLARE; int32_t j; uint32_t txidind,unspentind,spendind; struct iguana_txid *tx; char str[65]; struct iguana_ramchaindata *rdata; + if ( (rdata= ramchain->H.data) != 0 ) { - unspentind = spendind = ramchain->H.data->firsti; - for (txidind=ramchain->H.data->firsti; txidindH.data->numtxids; txidind++) + _iguana_ramchain_setptrs(RAMCHAIN_PTRS,rdata); + unspentind = spendind = rdata->firsti; + for (txidind=rdata->firsti; txidindnumtxids; txidind++) { tx = &T[txidind]; for (j=0; jnumvins; j++, spendind++) @@ -2237,62 +2188,62 @@ void iguana_bundlemapfree(struct iguana_info *coin,struct OS_memspace *mem,struc iguana_mempurge(hashmem); } -int32_t iguana_ramchain_expandedsave(struct iguana_info *coin,RAMCHAIN_FUNC,struct iguana_ramchain *newchain,struct OS_memspace *hashmem,int32_t cmpflag,struct iguana_bundle *bp) +int32_t iguana_ramchain_expandedsave(struct supernet_info *myinfo,struct iguana_info *coin,RAMCHAIN_FUNC,struct iguana_ramchain *newchain,struct OS_memspace *hashmem,int32_t cmpflag,struct iguana_bundle *bp) { static const bits256 zero; - bits256 firsthash2; int32_t err,bundlei,hdrsi,numblocks,firsti,height,retval= -1; - struct iguana_ramchain checkR,*mapchain; char fname[1024]; struct iguana_block *block; - uint32_t scriptspace,scriptoffset,stacksize; uint8_t *destoffset,*srcoffset; - firsthash2 = ramchain->H.data->firsthash2;//, lasthash2 = ramchain->H.data->lasthash2; - height = ramchain->height, firsti = ramchain->H.data->firsti, hdrsi = ramchain->H.hdrsi, numblocks = ramchain->numblocks; + bits256 firsthash2; int32_t err,bundlei,hdrsi,numblocks,firsti,height,retval= -1; struct iguana_ramchain checkR,*mapchain; char fname[1024]; struct iguana_block *block; uint32_t scriptspace,scriptoffset,stacksize; uint8_t *destoffset,*srcoffset; struct iguana_ramchaindata *rdata; + if ( (rdata= ramchain->H.data) == 0 ) + return(-1); + firsthash2 = rdata->firsthash2;//, lasthash2 = rdata->lasthash2; + height = ramchain->height, firsti = rdata->firsti, hdrsi = ramchain->H.hdrsi, numblocks = ramchain->numblocks; destoffset = &Kspace[ramchain->H.scriptoffset]; - srcoffset = &Kspace[ramchain->H.data->scriptspace - ramchain->H.stacksize]; + srcoffset = &Kspace[rdata->scriptspace - ramchain->H.stacksize]; if ( ramchain->expanded != 0 ) { if ( (long)destoffset > (long)srcoffset ) printf("smashed stack? dest.%ld vs src %ld offset.%u stacksize.%u space.%u\n",(long)destoffset,(long)srcoffset,(uint32_t)ramchain->H.scriptoffset,(uint32_t)ramchain->H.stacksize,(uint32_t)ramchain->H.scriptoffset); } - //printf("%d SAVE: Koffset.%d scriptoffset.%d stacksize.%d allocsize.%d gap.%ld RO.%d\n",bp->bundleheight,(int32_t)ramchain->H.data->Koffset,ramchain->H.scriptoffset,ramchain->H.stacksize,(int32_t)ramchain->H.data->allocsize,(long)destoffset - (long)srcoffset,ramchain->H.ROflag); - scriptspace = ramchain->H.data->scriptspace; + //printf("%d SAVE: Koffset.%d scriptoffset.%d stacksize.%d allocsize.%d gap.%ld RO.%d\n",bp->bundleheight,(int32_t)rdata->Koffset,ramchain->H.scriptoffset,ramchain->H.stacksize,(int32_t)rdata->allocsize,(long)destoffset - (long)srcoffset,ramchain->H.ROflag); + scriptspace = rdata->scriptspace; scriptoffset = ramchain->H.scriptoffset; stacksize = ramchain->H.stacksize; //ramchain->H.scriptoffset = scriptoffset; if ( (block= bp->blocks[0]) != 0 ) - ramchain->H.data->prevhash2 = block->RO.prev_block; - ramchain->H.data->scriptspace = scriptoffset; - ramchain->H.stacksize = ramchain->H.data->stackspace = stacksize; - iguana_ramchain_setsize(fname,ramchain,ramchain->H.data,bp->n); - //printf("Apresave T.%d U.%d S.%d P.%d X.%d -> size.%ld firsti.%d scriptoffset.%d stacksize.%d\n",ramchain->H.data->numtxids,ramchain->H.data->numunspents,ramchain->H.data->numspends,ramchain->H.data->numpkinds,ramchain->H.data->numexternaltxids,(long)ramchain->H.data->allocsize,firsti,ramchain->H.scriptoffset,ramchain->H.stacksize); + rdata->prevhash2 = block->RO.prev_block; + rdata->scriptspace = scriptoffset; + ramchain->H.stacksize = rdata->stackspace = stacksize; + iguana_ramchain_setsize(fname,ramchain,rdata,bp->n,coin->chain->zcash); + //printf("Apresave T.%d U.%d S.%d P.%d X.%d -> size.%ld firsti.%d scriptoffset.%d stacksize.%d\n",rdata->numtxids,rdata->numunspents,rdata->numspends,rdata->numpkinds,rdata->numexternaltxids,(long)rdata->allocsize,firsti,ramchain->H.scriptoffset,ramchain->H.stacksize); *newchain = *ramchain; - //memcpy(ramchain->roU2,ramchain->U2,sizeof(*ramchain->U2) * ramchain->H.data->numunspents); - //memcpy(ramchain->roP2,ramchain->P2,sizeof(*ramchain->P2) * ramchain->H.data->numpkinds); - memcpy(ramchain->creditsA,ramchain->A,sizeof(*ramchain->A) * ramchain->H.data->numpkinds); - memset(ramchain->A,0,sizeof(*ramchain->A) * ramchain->H.data->numpkinds); - //printf("presave T.%d U.%d S.%d P.%d X.%d -> size.%ld firsti.%d\n",ramchain->H.data->numtxids,ramchain->H.data->numunspents,ramchain->H.data->numspends,ramchain->H.data->numpkinds,ramchain->H.data->numexternaltxids,(long)ramchain->H.data->allocsize,firsti); - //printf("0 preSAVE: Koffset.%d scriptoffset.%d stacksize.%d allocsize.%d\n",(int32_t)ramchain->H.data->Koffset,ramchain->H.scriptoffset,ramchain->H.stacksize,(int32_t)ramchain->H.data->allocsize); - if ( (err= iguana_ramchain_iterate(coin,0,ramchain,bp,-1)) != 0 ) + //memcpy(ramchain->roU2,ramchain->U2,sizeof(*ramchain->U2) * rdata->numunspents); + //memcpy(ramchain->roP2,ramchain->P2,sizeof(*ramchain->P2) * rdata->numpkinds); + memcpy(ramchain->creditsA,ramchain->A,sizeof(*ramchain->A) * rdata->numpkinds); + memset(ramchain->A,0,sizeof(*ramchain->A) * rdata->numpkinds); + //printf("presave T.%d U.%d S.%d P.%d X.%d -> size.%ld firsti.%d\n",rdata->numtxids,rdata->numunspents,rdata->numspends,rdata->numpkinds,rdata->numexternaltxids,(long)rdata->allocsize,firsti); + //printf("0 preSAVE: Koffset.%d scriptoffset.%d stacksize.%d allocsize.%d\n",(int32_t)rdata->Koffset,ramchain->H.scriptoffset,ramchain->H.stacksize,(int32_t)rdata->allocsize); + if ( (err= iguana_ramchain_iterate(myinfo,coin,0,ramchain,bp,-1)) != 0 ) printf("ERROR.%d iterating presave ramchain hdrsi.%d\n",err,hdrsi); else { - //printf("postiterate0.%d T.%d U.%d S.%d P.%d X.%d -> size.%ld firsti.%d scripts.%d:%d stack.%d:%d\n",bp->bundleheight,ramchain->H.data->numtxids,ramchain->H.data->numunspents,ramchain->H.data->numspends,ramchain->H.data->numpkinds,ramchain->H.data->numexternaltxids,(long)ramchain->H.data->allocsize,firsti,(int32_t)ramchain->H.scriptoffset,scriptoffset,(int32_t)ramchain->H.stacksize,stacksize); + //printf("postiterate0.%d T.%d U.%d S.%d P.%d X.%d -> size.%ld firsti.%d scripts.%d:%d stack.%d:%d\n",bp->bundleheight,rdata->numtxids,rdata->numunspents,rdata->numspends,rdata->numpkinds,rdata->numexternaltxids,(long)rdata->allocsize,firsti,(int32_t)ramchain->H.scriptoffset,scriptoffset,(int32_t)ramchain->H.stacksize,stacksize); if ( ramchain->H.scriptoffset > scriptoffset || ramchain->H.stacksize > stacksize ) printf("MEMORY OVERFLOW\n"); if ( (err= iguana_ramchain_verify(coin,ramchain)) != 0 ) printf("ERROR.%d verifying presave ramchain hdrsi.%d\n",err,hdrsi); else retval = 0; } - //printf("postiterateA.%d T.%d U.%d S.%d P.%d X.%d -> size.%ld firsti.%d scripts.%d:%d stack.%d:%d\n",bp->bundleheight,ramchain->H.data->numtxids,ramchain->H.data->numunspents,ramchain->H.data->numspends,ramchain->H.data->numpkinds,ramchain->H.data->numexternaltxids,(long)ramchain->H.data->allocsize,firsti,(int32_t)ramchain->H.scriptoffset,scriptoffset,(int32_t)ramchain->H.stacksize,stacksize); + //printf("postiterateA.%d T.%d U.%d S.%d P.%d X.%d -> size.%ld firsti.%d scripts.%d:%d stack.%d:%d\n",bp->bundleheight,rdata->numtxids,rdata->numunspents,rdata->numspends,rdata->numpkinds,rdata->numexternaltxids,(long)rdata->allocsize,firsti,(int32_t)ramchain->H.scriptoffset,scriptoffset,(int32_t)ramchain->H.stacksize,stacksize); ramchain->H.scriptoffset = scriptoffset; - ramchain->H.data->scriptspace = scriptoffset; - ramchain->H.stacksize = ramchain->H.data->stackspace = stacksize; - if ( iguana_ramchain_save(coin,RAMCHAIN_ARG,0,firsthash2,zero,0,bp) < 0 ) + rdata->scriptspace = scriptoffset; + ramchain->H.stacksize = rdata->stackspace = stacksize; + if ( iguana_ramchain_save(coin,RAMCHAIN_ARG,0,firsthash2,zero,0,bp,coin->chain->zcash) < 0 ) { printf("ERROR saving ramchain hdrsi.%d, deleting and will regenerate\n",hdrsi); iguana_mempurge(hashmem); } else { - //printf("DEST T.%d U.%d S.%d P.%d X.%d -> size.%ld Xoffset.%d\n",ramchain->H.data->numtxids,ramchain->H.data->numunspents,ramchain->H.data->numspends,ramchain->H.data->numpkinds,ramchain->H.data->numexternaltxids,(long)ramchain->H.data->allocsize,(int32_t)ramchain->H.data->Xoffset); + //printf("DEST T.%d U.%d S.%d P.%d X.%d -> size.%ld Xoffset.%d\n",rdata->numtxids,rdata->numunspents,rdata->numspends,rdata->numpkinds,rdata->numexternaltxids,(long)rdata->allocsize,(int32_t)rdata->Xoffset); //printf("free dest hdrs.%d retval.%d\n",bp->hdrsi,retval); memset(&checkR,0,sizeof(checkR)); checkR.sigsfileptr = ramchain->sigsfileptr; @@ -2305,7 +2256,7 @@ int32_t iguana_ramchain_expandedsave(struct iguana_info *coin,RAMCHAIN_FUNC,stru iguana_ramchain_link(mapchain,firsthash2,hdrsi,height,0,numblocks,firsti,1); iguana_ramchain_extras(coin,mapchain,hashmem,0); //printf("expSAVE: Koffset.%d scriptoffset.%d stacksize.%d allocsize.%d\n",(int32_t)mapchain->H.data->Koffset,mapchain->H.scriptoffset,mapchain->H.stacksize,(int32_t)mapchain->H.data->allocsize); - if ( (err= iguana_ramchain_iterate(coin,0,mapchain,bp,bundlei)) != 0 ) + if ( (err= iguana_ramchain_iterate(myinfo,coin,0,mapchain,bp,bundlei)) != 0 ) printf("err.%d iterate mapped dest\n",err); else if ( cmpflag != 0 ) { @@ -2334,36 +2285,53 @@ struct iguana_ramchain *iguana_bundleload(struct iguana_info *coin,struct iguana { static const bits256 zero; struct iguana_blockRO *B; struct iguana_txid *T; int32_t i,firsti = 1; char fname[512]; - struct iguana_block *block; struct iguana_ramchain *mapchain; + struct iguana_block *block,*prev,*prev2; struct iguana_ramchain *mapchain; struct iguana_ramchaindata *rdata; memset(ramchain,0,sizeof(*ramchain)); if ( (mapchain= iguana_ramchain_map(coin,fname,bp,bp->n,ramchain,0,0,bp->hashes[0],zero,0,0,extraflag,1)) != 0 ) { iguana_ramchain_link(mapchain,bp->hashes[0],bp->hdrsi,bp->bundleheight,0,bp->n,firsti,1); - //char str[65]; printf("bp.%d: T.%d U.%d S.%d P%d X.%d MAPPED %s %p\n",bp->hdrsi,mapchain->H.data->numtxids,mapchain->H.data->numunspents,mapchain->H.data->numspends,mapchain->H.data->numpkinds,mapchain->H.data->numexternaltxids,mbstr(str,mapchain->H.data->allocsize),mapchain->H.data); + //char str[65]; printf("%s bp.%d: T.%d U.%d S.%d P%d X.%d MAPPED %s %p\n",coin->symbol,bp->hdrsi,mapchain->H.data->numtxids,mapchain->H.data->numunspents,mapchain->H.data->numspends,mapchain->H.data->numpkinds,mapchain->H.data->numexternaltxids,mbstr(str,mapchain->H.data->allocsize),mapchain->H.data); //ramcoder_test(mapchain->H.data,mapchain->H.data->allocsize); - B = RAMCHAIN_PTR(ramchain->H.data,Boffset); - T = RAMCHAIN_PTR(ramchain->H.data,Toffset); - //B = (void *)(long)((long)mapchain->H.data + mapchain->H.data->Boffset); - //T = (void *)(long)((long)mapchain->H.data + mapchain->H.data->Toffset); - for (i=0; in; i++) + if ( (rdata= ramchain->H.data) != 0 ) { - if ( (block= bp->blocks[i]) != 0 || (block= iguana_blockhashset("bundleload",coin,bp->bundleheight+i,bp->hashes[i],1)) != 0 ) + B = RAMCHAIN_PTR(rdata,Boffset); + T = RAMCHAIN_PTR(rdata,Toffset); + prev = prev2 = 0; + for (i=0; in; i++) { - block->queued = 1; - block->txvalid = 1; - block->height = bp->bundleheight + i; - block->hdrsi = bp->hdrsi; - block->bundlei = i; - block->fpipbits = (uint32_t)calc_ipbits("127.0.0.1"); - block->RO = B[i]; - //printf("%x ",(int32_t)B[i].hash2.ulongs[3]); - iguana_hash2set(coin,"bundleload",bp,i,block->RO.hash2); - //if ( bits256_nonz(bp->hashes[i]) == 0 ) - // bp->hashes[i] = B[i].hash2; - if ( bp->bundleheight+i == coin->blocks.hwmchain.height+1 ) + if ( (block= bp->blocks[i]) != 0 || (block= iguana_blockhashset("bundleload",coin,bp->bundleheight+i,bp->hashes[i],1)) != 0 ) { - //printf("try extend.%d\n",bp->bundleheight+i); - //_iguana_chainlink(coin,block); wrong context + if ( bits256_to_compact(bits256_from_compact(block->RO.bits)) != block->RO.bits ) + { + char str[65]; + printf("nbits calc error %x -> %s -> %x\n",block->RO.bits,bits256_str(str,bits256_from_compact(block->RO.bits)),bits256_to_compact(bits256_from_compact(block->RO.bits))); + } + block->queued = 1; + block->txvalid = 1; + block->height = bp->bundleheight + i; + //printf("bundleload bundlei.%d < height %d %d\n",i,block->height,i); + block->hdrsi = bp->hdrsi; + block->bundlei = i; + block->fpipbits = (uint32_t)calc_ipbits("127.0.0.1"); + iguana_blockzcopyRO(coin->chain->zcash,&block->RO,0,B,i); + //printf("%x ",(int32_t)B[i].hash2.ulongs[3]); + iguana_hash2set(coin,"bundleload",bp,i,block->RO.hash2); + bp->blocks[i] = block; + if ( (prev= block->hh.prev) != 0 ) + { + prev2 = prev->hh.prev; + prev->hh.next = block; + } + if ( prev2 != 0 && prev != 0 && strcmp(coin->symbol,"BTCD") == 0 && bp->bundleheight > 20000 && prev != 0 && iguana_targetbits(coin,block,prev,prev2,1,coin->chain->targetspacing,coin->chain->targettimespan) != block->RO.bits ) + { + printf("nbits target error %x != %x ht.%d\n",iguana_targetbits(coin,block,prev,prev2,1,coin->chain->targetspacing,coin->chain->targettimespan),block->RO.bits,block->height); + } //else printf(">>>>>>>>>> matched nbits %x ht.%d\n",block->RO.bits,block->height); + if ( bp->bundleheight+i == coin->blocks.hwmchain.height+1 ) + { + //printf("try extend.%d\n",bp->bundleheight+i); + //_iguana_chainlink(coin,block); //wrong context + } + prev2 = prev, prev = block; } } } @@ -2414,7 +2382,7 @@ int64_t iguana_ramchainopen(char *fname,struct iguana_info *coin,struct iguana_r #endif if ( mem->ptr == 0 ) { - while ( (allocsize= _iguana_rdata_action(fname,0,0,0,0,1,numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace,0,0,0,0,0,RAMCHAIN_ARG,numblocks)) > 2*1024LL*1024L*1024L ) + while ( (allocsize= _iguana_rdata_action(fname,0,0,0,0,1,numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace,0,0,0,0,0,RAMCHAIN_ARG,numblocks,coin->chain->zcash)) > 2*1024LL*1024L*1024L ) { numtxids *= .9; numunspents *= .9; @@ -2423,19 +2391,22 @@ int64_t iguana_ramchainopen(char *fname,struct iguana_info *coin,struct iguana_r numexternaltxids *= .9; } iguana_meminit(mem,coin->symbol,0,allocsize + 65536*3,0); + printf("%s meminit %lld\n",coin->symbol,(long long)mem->totalsize); } if ( hashmem->ptr == 0 ) { hashsize = iguana_hashmemsize(numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace); iguana_meminit(hashmem,coin->symbol,0,hashsize + 65536*3,0); + printf("%s hash meminit %lld\n",coin->symbol,(long long)hashmem->totalsize); } - if ( iguana_ramchain_init(fname,ramchain,mem,hashmem,1,numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace,1,numblocks) > 0 ) + if ( iguana_ramchain_init(fname,ramchain,mem,hashmem,1,numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace,1,numblocks,coin->chain->zcash) > 0 ) { iguana_ramchain_link(ramchain,hash2,bundleheight/coin->chain->bundlesize,bundleheight,0,0,1,0); ramchain->expanded = 1; ramchain->H.scriptoffset = 1; _iguana_ramchain_setptrs(RAMCHAIN_PTRS,ramchain->H.data); iguana_ramchain_extras(coin,ramchain,hashmem,0); + printf("%s ramchaininit %p ramchain.%p\n",coin->symbol,ramchain->H.data,ramchain); } if ( rdata != 0 ) return(rdata->allocsize); @@ -2456,9 +2427,9 @@ int32_t iguana_mapchaininit(char *fname,struct iguana_info *coin,struct iguana_r return(-1); } _iguana_ramchain_setptrs(MAPCHAIN_PTRS,mapchain->H.data); - if ( block->fpos+mapchain->H.data->allocsize > filesize || iguana_ramchain_size(fname,MAPCHAIN_ARG,1,mapchain->H.data->scriptspace) != mapchain->H.data->allocsize ) + if ( block->fpos+mapchain->H.data->allocsize > filesize || iguana_ramchain_size(fname,MAPCHAIN_ARG,1,mapchain->H.data->scriptspace,coin->chain->zcash) != mapchain->H.data->allocsize ) { - printf("iguana_mapchaininit.%d ipbits.%x size mismatch %ld vs %ld vs filesize.%ld fpos.%ld bundlei.%d expanded.%d soff.%d\n",bp->bundleheight,block->fpipbits,(long)iguana_ramchain_size(fname,MAPCHAIN_ARG,1,mapchain->H.data->scriptspace),(long)mapchain->H.data->allocsize,(long)filesize,(long)block->fpos,bundlei,mapchain->expanded,mapchain->H.data->scriptspace); + printf("iguana_mapchaininit.%d ipbits.%x size mismatch %ld vs %ld vs filesize.%ld fpos.%ld bundlei.%d expanded.%d soff.%d\n",bp->bundleheight,block->fpipbits,(long)iguana_ramchain_size(fname,MAPCHAIN_ARG,1,mapchain->H.data->scriptspace,coin->chain->zcash),(long)mapchain->H.data->allocsize,(long)filesize,(long)block->fpos,bundlei,mapchain->expanded,mapchain->H.data->scriptspace); //getchar(); return(-1); } @@ -2474,7 +2445,7 @@ int32_t iguana_mapchaininit(char *fname,struct iguana_info *coin,struct iguana_r } // helper threads: NUM_HELPERS -int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_bundle *bp,uint32_t starttime) // helper thread +int32_t iguana_bundlesaveHT(struct supernet_info *myinfo,struct iguana_info *coin,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_bundle *bp,uint32_t starttime) // helper thread { static int depth; static const bits256 zero; RAMCHAIN_DESTDECLARE; RAMCHAIN_DECLARE; RAMCHAIN_ZEROES; @@ -2512,7 +2483,6 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str } if ( (block= bp->blocks[bundlei]) == 0 || bits256_nonz(block->RO.hash2) == 0 || memcmp(block->RO.hash2.bytes,bp->hashes[bundlei].bytes,sizeof(bits256)) != 0 || bits256_cmp(block->RO.prev_block,prevhash2) != 0 ) // block != iguana_blockfind("bundlesave",coin,block->RO.hash2) { - printf("block.%p error vs %p\n",block,iguana_blockfind("bundlesaveerr",coin,block->RO.hash2)); break; } fpipbits = block->fpipbits, fpos = block->fpos; @@ -2523,7 +2493,7 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str { iguana_bundlemapfree(coin,0,0,ipbits,ptrs,filesizes,num,R,starti,endi); iguana_blockunmark(coin,bp->blocks[bundlei],bp,bundlei,1); - printf("error mapping hdrsi.%d bundlei.%d\n",bp->hdrsi,bundlei); + printf("saveHT error mapping hdrsi.%d bundlei.%d\n",bp->hdrsi,bundlei); return(-1); } //printf("done mapchain.[%d:%d]\n",bp->hdrsi,bundlei); @@ -2550,7 +2520,7 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str { iguana_bundlemapfree(coin,0,0,ipbits,ptrs,filesizes,num,R,starti,endi); iguana_blockunmark(coin,bp->blocks[bundlei],bp,bundlei,1); - printf("error mapping hdrsi.%d bundlei.%d\n",bp->hdrsi,bundlei); + printf("B error mapping hdrsi.%d bundlei.%d\n",bp->hdrsi,bundlei); return(-1); } dest = &bp->ramchain; @@ -2560,7 +2530,7 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str numexternaltxids = numspends; //printf("E.%d depth.%d start bundle ramchain %d at %u started.%u lag.%d\n",coin->numemitted,depth,bp->bundleheight,now,starttime,now-starttime); depth++; - if ( iguana_ramchain_alloc(fname,coin,dest,mem,&HASHMEM,numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace+sigspace,bp->bundleheight+starti,bp_n) < 0 ) + if ( iguana_ramchain_alloc(fname,coin,dest,mem,&HASHMEM,numtxids,numunspents,numspends,numpkinds,numexternaltxids,scriptspace+sigspace,bp->bundleheight+starti,bp_n,coin->chain->zcash) < 0 ) { printf("error iguana_ramchain_alloc for bundleheight.%d\n",bp->bundleheight); iguana_bundlemapfree(coin,mem,&HASHMEM,ipbits,ptrs,filesizes,num,R,starti,endi); @@ -2589,8 +2559,9 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str iguana_blockunmark(coin,block,bp,i,1); return(-1); } - destB[i] = block->RO; - } else printf("error getting block (%d:%d) %p vs %p\n",bp->hdrsi,i,block,bp->blocks[i]); + iguana_blockzcopyRO(coin->chain->zcash,destB,i,&block->RO,0); + //destB[i] = block->RO; + } else printf("bundlesave error getting block (%d:%d) %p vs %p\n",bp->hdrsi,i,block,bp->blocks[i]); } dest->H.txidind = dest->H.unspentind = dest->H.spendind = dest->pkind = dest->H.data->firsti; dest->externalind = dest->H.stacksize = 0; @@ -2602,10 +2573,11 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str if ( (block= bp->blocks[bundlei]) != 0 ) { iguana_blocksetcounters(coin,block,dest); - coin->blocks.RO[bp->bundleheight+bundlei] = block->RO; - destB[bundlei] = block->RO; + //coin->blocks.RO[bp->bundleheight+bundlei] = block->RO; + iguana_blockzcopyRO(coin->chain->zcash,destB,bundlei,&block->RO,0); + //destB[bundlei] = block->RO; //fprintf(stderr,"(%d %d).%d ",R[bundlei].H.data->numtxids,dest->H.txidind,bundlei); - if ( (err= iguana_ramchain_iterate(coin,dest,&R[bundlei],bp,bundlei)) != 0 ) + if ( (err= iguana_ramchain_iterate(myinfo,coin,dest,&R[bundlei],bp,bundlei)) != 0 ) { if ( (block= bp->blocks[bundlei]) != 0 ) { @@ -2632,7 +2604,7 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str //printf(" about to save dest scriptoffset.%d stacksize.%d data scriptspace.%d\n",dest->H.scriptoffset,dest->H.stacksize,dest->H.data->scriptspace); depth--; memset(&newchain,0,sizeof(newchain)); - if ( bundlei == endi+1 && iguana_ramchain_expandedsave(coin,RAMCHAIN_DESTARG,&newchain,&HASHMEM,0,bp) == 0 ) + if ( bundlei == endi+1 && iguana_ramchain_expandedsave(myinfo,coin,RAMCHAIN_DESTARG,&newchain,&HASHMEM,0,bp) == 0 ) { //char str[65]; printf("d.%d ht.%d %s saved lag.%d elapsed.%ld\n",depth,dest->height,mbstr(str,dest->H.data->allocsize),now-starttime,time(NULL)-now); retval = 0; @@ -2641,15 +2613,15 @@ int32_t iguana_bundlesaveHT(struct iguana_info *coin,struct OS_memspace *mem,str if ( retval == 0 ) { //char dirname[1024]; - printf("delete %d files hdrs.[%d] retval.%d bp_n.%d\n",num,bp->hdrsi,retval,bp_n); + //printf("delete %d files hdrs.[%d] retval.%d bp_n.%d\n",num,bp->hdrsi,retval,bp_n); if ( iguana_bundleload(coin,&newchain,bp,0) == 0 ) retval = -1; else if ( bp_n == bp->n && bp->n == coin->chain->bundlesize && bp->hdrsi < coin->bundlescount-3 ) { for (j=starti; j<=endi; j++) { - if ( iguana_peerfname(coin,&hdrsi,GLOBAL_TMPDIR,fname,0,bp->hashes[j],zero,1,1) >= 0 ) - coin->peers.numfiles -= OS_removefile(fname,0); + if ( iguana_peerfname(coin,&hdrsi,GLOBAL_TMPDIR,fname,0,bp->hashes[j],zero,1,1) >= 0 && coin->peers != 0 ) + coin->peers->numfiles -= OS_removefile(fname,0); else printf("error removing.(%s)\n",fname); } //sprintf(dirname,"%s/%s/%d",GLOBAL_TMPDIR,coin->symbol,bp->bundleheight), OS_portable_rmdir(dirname,1); @@ -2680,7 +2652,7 @@ void iguana_mergefree(struct iguana_info *coin,struct OS_memspace *mem,struct ig iguana_mempurge(hashmemB); } -int32_t iguana_bundlemergeHT(char *fname,struct iguana_info *coin,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_bundle *bp,struct iguana_bundle *nextbp,uint32_t starttime) +int32_t iguana_bundlemergeHT(struct supernet_info *myinfo,char *fname,struct iguana_info *coin,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_bundle *bp,struct iguana_bundle *nextbp,uint32_t starttime) { static int32_t depth; static const bits256 zero; RAMCHAIN_DESTDECLARE; struct OS_memspace HASHMEM,HASHMEMA,HASHMEMB; @@ -2709,7 +2681,7 @@ int32_t iguana_bundlemergeHT(char *fname,struct iguana_info *coin,struct OS_mems } if ( A->H.data != 0 && B->H.data != 0 && B->height == A->height+A->numblocks ) { - if ( iguana_ramchain_alloc(fname,coin,dest,mem,&HASHMEM,(A->H.data->numtxids+B->H.data->numtxids),(A->H.data->numunspents+B->H.data->numunspents),(A->H.data->numspends+B->H.data->numspends),(A->H.data->numpkinds+B->H.data->numpkinds),(A->H.data->numexternaltxids+B->H.data->numexternaltxids),A->H.data->scriptspace,A->height,A->numblocks + B->numblocks) < 0 ) + if ( iguana_ramchain_alloc(fname,coin,dest,mem,&HASHMEM,(A->H.data->numtxids+B->H.data->numtxids),(A->H.data->numunspents+B->H.data->numunspents),(A->H.data->numspends+B->H.data->numspends),(A->H.data->numpkinds+B->H.data->numpkinds),(A->H.data->numexternaltxids+B->H.data->numexternaltxids),A->H.data->scriptspace,A->height,A->numblocks + B->numblocks,coin->chain->zcash) < 0 ) { printf("depth.%d ht.%d fsize.%s ERROR alloc lag.%d elapsed.%ld\n",depth,dest->height,mbstr(str,dest->H.data->allocsize),now-starttime,time(NULL)-now); iguana_mergefree(coin,mem,A,B,&HASHMEM,&HASHMEMA,&HASHMEMB); @@ -2721,11 +2693,11 @@ int32_t iguana_bundlemergeHT(char *fname,struct iguana_info *coin,struct OS_mems iguana_ramchain_extras(coin,dest,&HASHMEM,0); dest->H.txidind = dest->H.unspentind = dest->H.spendind = dest->pkind = dest->H.data->firsti; dest->externalind = 0; - if ( (err= iguana_ramchain_iterate(coin,dest,A,bp,-1)) != 0 ) + if ( (err= iguana_ramchain_iterate(myinfo,coin,dest,A,bp,-1)) != 0 ) printf("error.%d ramchain_iterate A.%d\n",err,A->height); - else if ( (err= iguana_ramchain_iterate(coin,dest,B,nextbp,-1)) != 0 ) + else if ( (err= iguana_ramchain_iterate(myinfo,coin,dest,B,nextbp,-1)) != 0 ) printf("error.%d ramchain_iterate B.%d\n",err,B->height); - else if ( iguana_ramchain_expandedsave(coin,RAMCHAIN_DESTARG,&newchain,&HASHMEM,0,0) == 0 ) + else if ( iguana_ramchain_expandedsave(myinfo,coin,RAMCHAIN_DESTARG,&newchain,&HASHMEM,0,0) == 0 ) { printf("merging isnt setup to save the blockROs\n"); printf("depth.%d ht.%d fsize.%s MERGED %d[%d] and %d[%d] lag.%d elapsed.%ld bp.%d -> %d\n",depth,dest->height,mbstr(str,dest->H.data->allocsize),A->height,A->numblocks,B->height,B->numblocks,now-starttime,time(NULL)-now,bp->bundleheight,nextbp->bundleheight); @@ -2794,3 +2766,94 @@ void iguana_ramchainmerge(struct iguana_info *coin) // jl777: verify prev/next h } } #endif + +void iguana_RTvout(struct iguana_info *coin,int64_t polarity,struct iguana_RTtxid *RTptr,struct iguana_block *block,bits256 txid,int32_t j,struct iguana_msgvout *vout) +{ + int32_t scriptlen,type,k; uint8_t *script; struct vin_info V; char coinaddr[64]; + script = vout->pk_script; + scriptlen = vout->pk_scriptlen; + type = iguana_calcrmd160(coin,0,&V,script,scriptlen,txid,j,0xffffffff); + if ( (type == 12 && scriptlen == 0) || (type == 1 && bitcoin_pubkeylen(script+1) <= 0) ) + { + for (k=0; kchain->pubtype,V.rmd160,sizeof(V.rmd160)); + iguana_RTunspent(coin,RTptr,block,polarity,coinaddr,V.rmd160,type,script,scriptlen,txid,j,vout->value); +} + +int32_t iguana_RTramchaindata(struct supernet_info *myinfo,struct iguana_info *coin,struct OS_memspace *TXDATA,struct OS_memspace *HASHMEM,int64_t polarity,struct iguana_block *block,struct iguana_msgtx *txarray,int32_t txn_count) +{ + RAMCHAIN_DECLARE; struct iguana_ramchain R,*ramchain = &R; struct iguana_msgtx *tx; char fname[1024]; struct iguana_ramchaindata *rdata; struct iguana_RTtxid *RTptr; int32_t iter,hdrsi,bundlei,i,j,firsti = 1; + if ( block->RO.txn_count != txn_count ) + { + printf("txn_count mismatch ht.%d %d != %d\n",block->height,block->RO.txn_count,txn_count); + return(-1); + } + hdrsi = (block->height / coin->chain->bundlesize); + bundlei = (block->height % coin->chain->bundlesize); + if ( iguana_ramchain_init(fname,ramchain,TXDATA,HASHMEM,1,block->RO.txn_count,block->RO.numvouts,block->RO.numvins,0,0,1,0,1,coin->chain->zcash) == 0 ) + { + printf("error iguana_ramchain_init\n"); + return(-1); + } + iguana_ramchain_link(ramchain,block->RO.hash2,hdrsi,block->height,bundlei,1,firsti,0); + if ( (rdata= ramchain->H.data) != 0 ) + { + _iguana_ramchain_setptrs(RAMCHAIN_PTRS,rdata); + if ( T == 0 || U == 0 || S == 0 || B == 0 ) + { + printf("fatal error getting txdataptrs %p %p %p %p\n",T,U,S,B); + return(-1); + } + for (iter=0; iter<2; iter++) + { + ramchain->H.txidind = ramchain->H.spendind = ramchain->H.unspentind = rdata->firsti; + for (i=0; iH.txidind++) + { + tx = &txarray[i]; + RTptr = iguana_RTtxid_create(coin,block,polarity,i,txn_count,tx->txid,tx->tx_out,tx->tx_in,tx->lock_time,tx->version,tx->timestamp,tx->serialized,tx->allocsize); + if ( polarity > 0 ) + { + if ( iter == 0 ) + { + for (j=0; jtx_out; j++) + iguana_RTvout(coin,polarity,RTptr,block,tx->txid,j,&tx->vouts[j]); + ramchain->H.spendind += tx->tx_in; + } + else + { + for (j=0; jtx_in; j++) + { + iguana_RTspend(myinfo,coin,RTptr,block,polarity,tx->vins[j].vinscript,tx->vins[j].scriptlen,tx->txid,j,tx->vins[j].prev_hash,tx->vins[j].prev_vout); + } + ramchain->H.unspentind += tx->tx_out; + } + } + else + { + if ( iter == 0 ) + { + for (j=tx->tx_in-1; j>=0; j--) + { + iguana_RTspend(myinfo,coin,RTptr,block,polarity,tx->vins[j].vinscript,tx->vins[j].scriptlen,tx->txid,j,tx->vins[j].prev_hash,tx->vins[j].prev_vout); + } + ramchain->H.unspentind += tx->tx_out; + } + else + { + for (j=tx->tx_out-1; j>=0; j--) + iguana_RTvout(coin,polarity,RTptr,block,tx->txid,j,&tx->vouts[j]); + ramchain->H.spendind += tx->tx_in; + } + } + } + } + //printf("scriptoffset.%d after %d txids\n",ramchain->H.scriptoffset,txn_count); + iguana_ramchain_free(coin,ramchain,0); + return(0); + } + iguana_ramchain_free(coin,ramchain,0); + return(-1); +} diff --git a/iguana/iguana_realtime.c b/iguana/iguana_realtime.c index 0780d59b0..36b558747 100755 --- a/iguana/iguana_realtime.c +++ b/iguana/iguana_realtime.c @@ -13,23 +13,30 @@ * * ******************************************************************************/ +// verify undo cases for hhutxo, and all 4 permutations of setting + #include "iguana777.h" +//#define ENABLE_RAMCHAIN +#ifdef oldway void iguana_RTramchainfree(struct iguana_info *coin,struct iguana_bundle *bp) { + //return; +#ifdef ENABLE_RAMCHAIN int32_t hdrsi; + //portable_mutex_lock(&coin->RTmutex); if ( coin->utxotable != 0 ) { printf("free RTramchain\n"); - iguana_utxoupdate(coin,-1,0,0,0,0,-1); // free hashtables - coin->RTheight = coin->balanceswritten * coin->chain->bundlesize; + //iguana_utxoupdate(coin,-1,0,0,0,0,-1,0); // free hashtables + coin->lastRTheight = coin->RTheight = 0;//(coin->bundlescount-1) * coin->chain->bundlesize; coin->RTgenesis = 0; + iguana_utxoaddrs_purge(coin); iguana_ramchain_free(coin,&coin->RTramchain,1); if ( bp != 0 ) bp->ramchain = coin->RTramchain; iguana_mempurge(&coin->RTmem); iguana_mempurge(&coin->RThashmem); - coin->RTdatabad = 0; for (hdrsi=coin->bundlescount-1; hdrsi>0; hdrsi--) if ( (bp= coin->bundles[hdrsi]) == 0 && bp != coin->current ) { @@ -37,19 +44,24 @@ void iguana_RTramchainfree(struct iguana_info *coin,struct iguana_bundle *bp) if ( iguana_volatilesmap(coin,&bp->ramchain) != 0 ) printf("error mapping bundle.[%d]\n",hdrsi); } + coin->RTdatabad = 0; printf("done RTramchain\n"); } + //portable_mutex_unlock(&coin->RTmutex); +#endif } -void *iguana_ramchainfile(struct iguana_info *coin,struct iguana_ramchain *dest,struct iguana_ramchain *R,struct iguana_bundle *bp,int32_t bundlei,struct iguana_block *block) +void *iguana_ramchainfile(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_ramchain *dest,struct iguana_ramchain *R,struct iguana_bundle *bp,int32_t bundlei,struct iguana_block *block) { + //return(0); +#ifdef ENABLE_RAMCHAIN char fname[1024]; long filesize; int32_t err; void *ptr=0; if ( block == bp->blocks[bundlei] && (ptr= iguana_bundlefile(coin,fname,&filesize,bp,bundlei)) != 0 ) { if ( iguana_mapchaininit(fname,coin,R,bp,bundlei,block,ptr,filesize) >= 0 ) { if ( dest != 0 && dest->H.data != 0 ) - err = iguana_ramchain_iterate(coin,dest,R,bp,bundlei); + err = iguana_ramchain_iterate(myinfo,coin,dest,R,bp,bundlei); else err = 0; if ( err != 0 || dest->H.data == 0 || bits256_cmp(R->H.data->firsthash2,block->RO.hash2) != 0 ) { @@ -61,40 +73,43 @@ void *iguana_ramchainfile(struct iguana_info *coin,struct iguana_ramchain *dest, iguana_blockunmark(coin,block,bp,bundlei,1); iguana_ramchain_free(coin,R,1); } //else printf("ramchainfile ptr.%p block.%p\n",ptr,block); +#endif return(0); } void iguana_RTramchainalloc(char *fname,struct iguana_info *coin,struct iguana_bundle *bp) { + //return; +#ifdef ENABLE_RAMCHAIN uint32_t i,changed = 0; struct iguana_ramchaindata *rdata; struct iguana_ramchain *dest = &coin->RTramchain; struct iguana_blockRO *B; struct iguana_bundle *tmpbp; + //portable_mutex_lock(&coin->RTmutex); if ( (rdata= dest->H.data) != 0 ) { i = 0; - if ( coin->RTheight != bp->bundleheight + rdata->numblocks ) + if ( coin->RTheight != coin->lastRTheight ) changed++; else { B = RAMCHAIN_PTR(rdata,Boffset); - //B = (void *)(long)((long)rdata + rdata->Boffset); for (i=0; inumblocks; i++) if ( bits256_cmp(B[i].hash2,bp->hashes[i]) != 0 ) { char str[65],str2[65]; printf("mismatched hash2 at %d %s vs %s\n",bp->bundleheight+i,bits256_str(str,B[i].hash2),bits256_str(str2,bp->hashes[i])); changed++; + iguana_blockunmark(coin,bp->blocks[i],bp,i,1); break; } } if ( changed != 0 ) { printf("RTramchain changed %d bundlei.%d | coin->RTheight %d != %d bp->bundleheight + %d coin->RTramchain.H.data->numblocks\n",coin->RTheight,i,coin->RTheight,bp->bundleheight,rdata->numblocks); - //coin->RTheight = coin->balanceswritten * coin->chain->bundlesize; iguana_RTramchainfree(coin,bp); } } if ( coin->RTramchain.H.data == 0 ) { - printf("ALLOC RTramchain\n"); iguana_ramchainopen(fname,coin,dest,&coin->RTmem,&coin->RThashmem,bp->bundleheight,bp->hashes[0]); + printf("ALLOC RTramchain.(%s) RTrdata %p rdata.%p\n",fname,coin->RTramchain.H.data,bp->ramchain.H.data); dest->H.txidind = dest->H.unspentind = dest->H.spendind = dest->pkind = dest->H.data->firsti; dest->externalind = dest->H.stacksize = 0; dest->H.scriptoffset = 1; @@ -103,16 +118,20 @@ void iguana_RTramchainalloc(char *fname,struct iguana_info *coin,struct iguana_b for (i=0; ihdrsi; i++) if ( (tmpbp= coin->bundles[i]) != 0 ) { - //iguana_volatilespurge(coin,&tmpbp->ramchain); + iguana_volatilespurge(coin,&tmpbp->ramchain); iguana_volatilesmap(coin,&tmpbp->ramchain); } sleep(1); } } + //portable_mutex_unlock(&coin->RTmutex); +#endif } void iguana_rdataset(struct iguana_ramchain *dest,struct iguana_ramchaindata *rdest,struct iguana_ramchain *src) { + //return; +#ifdef ENABLE_RAMCHAIN *dest = *src; dest->H.data = rdest; *rdest = *src->H.data; @@ -122,10 +141,13 @@ void iguana_rdataset(struct iguana_ramchain *dest,struct iguana_ramchaindata *rd rdest->numunspents = src->H.unspentind; rdest->numspends = src->H.spendind; //printf("RT set numtxids.%u numspends.%u\n",rdest->numtxids,rdest->numspends); +#endif } void iguana_rdatarestore(struct iguana_ramchain *dest,struct iguana_ramchaindata *rdest,struct iguana_ramchain *src) { + //return; +#ifdef ENABLE_RAMCHAIN *src = *dest; *src->H.data = *rdest; src->pkind = rdest->numpkinds; @@ -134,38 +156,46 @@ void iguana_rdatarestore(struct iguana_ramchain *dest,struct iguana_ramchaindata src->H.unspentind = rdest->numunspents; src->H.spendind = rdest->numspends; printf("RT restore numtxids.%u numspends.%u\n",rdest->numtxids,rdest->numspends); +#endif } void iguana_RThdrs(struct iguana_info *coin,struct iguana_bundle *bp,int32_t numaddrs) { + //return; +#ifdef ENABLE_RAMCHAIN int32_t datalen,i; uint8_t serialized[512]; char str[65]; struct iguana_peer *addr; - for (i=0; ipeers.numranked; i++) + if ( coin->peers == 0 ) + return; + datalen = iguana_gethdrs(coin,serialized,coin->chain->gethdrsmsg,bits256_str(str,bp->hashes[0])); + for (i=0; ipeers->numranked; i++) { queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,bp->hashes[0])),1); - if ( (addr= coin->peers.ranked[i]) != 0 && addr->usock >= 0 && addr->dead == 0 && (datalen= iguana_gethdrs(coin,serialized,coin->chain->gethdrsmsg,bits256_str(str,bp->hashes[0]))) > 0 ) + if ( coin->chain->hasheaders == 0 ) + queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(bits256_str(str,coin->blocks.hwmchain.RO.hash2)),1); + if ( (addr= coin->peers->ranked[i]) != 0 && addr->usock >= 0 && addr->dead == 0 && datalen > 0 ) { iguana_send(coin,addr,serialized,datalen); - addr->pendhdrs++; + //addr->pendhdrs++; } } +#endif } -void iguana_RTspendvectors(struct iguana_info *coin,struct iguana_bundle *bp) +void iguana_RTspendvectors(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_bundle *bp) { + //return; +#ifdef ENABLE_RAMCHAIN int32_t iterate,lasti,num,hdrsi,orignumemit; struct iguana_ramchain R; struct iguana_ramchaindata RDATA; if ( bp->hdrsi <= 0 ) return; + printf("RTspendvectors [%d]\n",bp->hdrsi); bp->ramchain = coin->RTramchain; iguana_rdataset(&R,&RDATA,&coin->RTramchain); if ( (lasti= (coin->RTheight - ((coin->RTheight/bp->n)*bp->n))) >= bp->n-1 ) lasti = bp->n - 1; orignumemit = bp->numtmpspends; -#ifdef __APPLE__ - iterate = 0*(coin->bundlescount-1); -#else iterate = 0; -#endif - if ( iguana_spendvectors(coin,bp,&coin->RTramchain,coin->RTstarti,lasti,0,iterate) < 0 ) + if ( iguana_spendvectors(myinfo,coin,bp,&coin->RTramchain,coin->RTstarti%coin->chain->bundlesize,lasti,0,iterate) < 0 ) { printf("RTutxo error -> RTramchainfree\n"); coin->RTdatabad = 1; @@ -173,7 +203,7 @@ void iguana_RTspendvectors(struct iguana_info *coin,struct iguana_bundle *bp) } else { - printf("RTspendvectors calculated to %d [%d]\n",coin->RTheight,bp->hdrsi); + //printf("RTspendvectors calculated to %d [%d]\n",coin->RTheight,bp->hdrsi); bp->converted = 1; for (hdrsi=num=0; hdrsihdrsi; hdrsi++) { @@ -186,57 +216,102 @@ void iguana_RTspendvectors(struct iguana_info *coin,struct iguana_bundle *bp) #endif num += iguana_convert(coin,IGUANA_NUMHELPERS,coin->bundles[hdrsi],1,orignumemit); } - printf("RTspendvectors converted.%d to %d\n",num,coin->RTheight); + //printf("RTspendvectors converted.%d to %d\n",num,coin->RTheight); + //iguana_rdatarestore(&R,&RDATA,&bp->ramchain); bp->converted = (uint32_t)time(NULL); - if ( iguana_balancegen(coin,1,bp,coin->RTstarti,coin->RTheight > 0 ? coin->RTheight-1 : bp->n-1,orignumemit) < 0 ) + if ( iguana_balancegen(coin,1,bp,coin->RTstarti,coin->RTheight > 0 ? coin->RTheight-1 : bp->bundleheight+bp->n-1,orignumemit) < 0 ) + { + printf("balancegen error\n"); coin->RTdatabad = 1; - else if ( coin->RTgenesis == 0 ) - printf(">>>>>> IGUANA %s READY FOR REALTIME RPC <<<<<<\n",coin->symbol); + } + else if ( coin->RTgenesis == 0 && coin->firstRTgenesis == 0 ) + coin->firstRTgenesis++, printf(">>>>>> IGUANA %s READY FOR REALTIME RPC <<<<<<\n",coin->symbol); //printf("iguana_balancegen [%d] (%d to %d)\n",bp->hdrsi,coin->RTstarti,(coin->RTheight-1)%bp->n); - coin->RTstarti = (coin->RTheight % bp->n); + coin->RTstarti = coin->RTheight; } +#endif } -int32_t iguana_realtime_update(struct iguana_info *coin) +int32_t iguana_realtime_update(struct supernet_info *myinfo,struct iguana_info *coin) { + int32_t flag = 0; + //return(0); +#ifdef ENABLE_RAMCHAIN double startmillis0; static double totalmillis0; static int32_t num0; - struct iguana_bundle *bp; struct iguana_ramchaindata *rdata; int32_t bundlei,i,n,flag=0; bits256 hash2,*ptr; struct iguana_peer *addr; + struct iguana_bundle *bp; struct iguana_ramchaindata *rdata; int32_t offset,bundlei,i,n; bits256 hash2,*ptr; struct iguana_peer *addr; struct iguana_block *block=0; struct iguana_blockRO *B; struct iguana_ramchain *dest=0,blockR; + if ( coin->peers == 0 && coin->virtualchain == 0 ) + return(0); + offset = 0;//(strcmp("BTC",coin->symbol) != 0); + if ( coin->RTheight >= (coin->current->hdrsi+1)*coin->chain->bundlesize ) + { + printf("inversion RT %d >= %d\n",coin->RTheight,(coin->current->hdrsi+1)*coin->chain->bundlesize); + coin->lastRTheight = coin->RTheight = coin->current->hdrsi*coin->chain->bundlesize; + iguana_utxoaddrs_purge(coin); + } if ( coin->current != 0 && (coin->blocks.hwmchain.height % coin->chain->bundlesize) == coin->chain->bundlesize-1 && coin->blocks.hwmchain.height/coin->chain->bundlesize == coin->longestchain/coin->chain->bundlesize ) { block = coin->current->blocks[coin->current->n - 1]; if ( _iguana_chainlink(coin,block) <= 0 ) { - //printf("RT edge case couldnt link\n"); + printf("RT edge case couldnt link\n"); + } + else + { + printf("RT edge case.%d\n",block->height); + if ( (bp= coin->bundles[coin->RTheight / coin->chain->bundlesize]) != 0 ) + iguana_spendvectors(myinfo,coin,bp,&bp->ramchain,0,bp->n,0,0); + iguana_update_balances(coin); } - else printf("RT edge case.%d\n",block->height); } if ( coin->spendvectorsaved <= 1 ) + { + //printf("%s spendvectorsaved not yet\n",coin->symbol); + usleep(100000); return(0); + } + //portable_mutex_lock(&coin->RTmutex); for (i=0; ibundlescount-1; i++) { - if ( (bp= coin->bundles[i]) != 0 && (i > 0 && bp->utxofinish == 0) ) + if ( (bp= coin->bundles[i]) != 0 && (i > 0 && bp->utxofinish == 0) && bp != coin->current ) { - if ( iguana_spendvectors(coin,bp,&bp->ramchain,0,bp->n,0,0) < 0 ) + if ( iguana_spendvectors(myinfo,coin,bp,&bp->ramchain,0,bp->n,0,0) < 0 ) { - printf("error generating spendvectors.[%d], exiting. just restart iguana\n",i); - exit(-1); + //portable_mutex_unlock(&coin->RTmutex); + printf("error generating spendvectors.[%d], skipping\n",i); + return(0); } // else printf("generated UTXO.[%d]\n",i); coin->spendvectorsaved = 1; } } + //portable_mutex_unlock(&coin->RTmutex); bp = coin->current; - if ( bp == 0 || iguana_validated(coin) < bp->hdrsi ) + if ( bp == 0 )//|| iguana_validated(coin) < bp->hdrsi ) + { + //printf("bp.%p validated.%d vs hdrsi.%d\n",bp,iguana_validated(coin),bp->hdrsi); return(0); - if ( 1 && coin->RTheight > 0 && coin->spendvectorsaved != 1 && coin->bundlescount-1 != coin->balanceswritten ) + } + if ( 0 && coin->RTheight > 0 && coin->spendvectorsaved != 1 && coin->bundlescount-1 != coin->balanceswritten ) { printf("RT mismatch %d != %d\n",coin->bundlescount-1,coin->balanceswritten); - coin->spendvectorsaved = 0; iguana_RTramchainfree(coin,coin->current); + coin->spendvectorsaved = 0; + coin->lastRTheight = coin->RTheight = 0; + iguana_utxoaddrs_purge(coin); + /*while ( coin->spendvectorsaved <= 1 ) + { + fprintf(stderr,"wait for spendvectorsaved\n"); + sleep(3); + }*/ return(0); } - if ( coin->RTdatabad == 0 && bp->hdrsi == coin->longestchain/coin->chain->bundlesize && bp->hdrsi >= coin->balanceswritten && coin->RTheight >= bp->bundleheight && coin->RTheight < bp->bundleheight+bp->n && ((coin->RTheight < coin->blocks.hwmchain.height && time(NULL) > bp->lastRT) || time(NULL) > bp->lastRT+10) ) + if ( coin->RTdatabad == 0 && bp->hdrsi >= (coin->longestchain/coin->chain->bundlesize)-1 && bp->hdrsi >= coin->balanceswritten-2 && ((coin->RTheight < coin->blocks.hwmchain.height-offset && time(NULL) > bp->lastRT) || time(NULL) > bp->lastRT+1) ) //coin->RTheight >= bp->bundleheight && coin->RTheight < bp->bundleheight+bp->n && { + if ( coin->RTheight < bp->hdrsi*coin->chain->bundlesize ) + { + coin->lastRTheight = coin->RTheight = bp->hdrsi*coin->chain->bundlesize; + iguana_utxoaddrs_purge(coin); + } if ( (block= bp->blocks[0]) == 0 || block->txvalid == 0 || block->mainchain == 0 ) { if ( block != 0 ) @@ -247,48 +322,50 @@ int32_t iguana_realtime_update(struct iguana_info *coin) bp->issued[0] = 0; hash2 = bp->hashes[0]; //char str[65]; printf("RT[0] [%d:%d] %s %p\n",bp->hdrsi,0,bits256_str(str,hash2),block); - addr = coin->peers.ranked[rand() % 8]; - if ( addr != 0 && addr->usock >= 0 && addr->dead == 0 ) - iguana_sendblockreqPT(coin,addr,bp,0,hash2,0); + if ( coin->peers != 0 ) + { + addr = coin->peers->ranked[rand() % 8]; + if ( addr != 0 && addr->usock >= 0 && addr->dead == 0 ) + iguana_sendblockreqPT(coin,addr,bp,0,hash2,0); + } } } } //char str[65]; printf("check longest.%d RTheight.%d hwm.%d %s %p\n",coin->longestchain,coin->RTheight,coin->blocks.hwmchain.height,bits256_str(str,bp->hashes[0]),block); if ( bits256_cmp(coin->RThash1,bp->hashes[1]) != 0 ) coin->RThash1 = bp->hashes[1]; - bp->lastRT = (uint32_t)time(NULL); - if ( coin->RTheight < coin->longestchain && coin->peers.numranked > 0 && time(NULL) > coin->RThdrstime+10 ) + //bp->lastRT = (uint32_t)time(NULL); + if ( coin->peers != 0 && coin->RTheight <= coin->longestchain-offset && coin->peers->numranked > 0 && time(NULL) > coin->RThdrstime+16 ) { - iguana_RThdrs(coin,bp,coin->peers.numranked); - coin->RThdrstime = bp->lastRT; - for (i=0; ipeers.numranked; i++) - { - if ( (addr= coin->peers.ranked[i]) != 0 && addr->usock >= 0 && addr->dead == 0 ) - { - //printf("%d ",addr->numRThashes); - } - } - //printf("RTheaders %s\n",coin->symbol); + iguana_RThdrs(coin,bp,coin->peers->numranked); + coin->RThdrstime = (uint32_t)time(NULL); } bp->lastRT = (uint32_t)time(NULL); iguana_RTramchainalloc("RTbundle",coin,bp); bp->isRT = 1; - while ( (rdata= coin->RTramchain.H.data) != 0 && coin->RTheight <= coin->blocks.hwmchain.height ) + //printf("%s rdata.%p RTheight.%d hwm.%d RTdatabad.%d\n",coin->symbol,coin->RTramchain.H.data,coin->RTheight,coin->blocks.hwmchain.height,coin->RTdatabad); + while ( (rdata= coin->RTramchain.H.data) != 0 && coin->RTheight <= coin->blocks.hwmchain.height-offset && coin->RTdatabad == 0 ) { - if ( coin->RTdatabad != 0 ) - break; dest = &coin->RTramchain; B = RAMCHAIN_PTR(rdata,Boffset); - //B = (void *)(long)((long)rdata + rdata->Boffset); bundlei = (coin->RTheight % coin->chain->bundlesize); if ( (block= iguana_bundleblock(coin,&hash2,bp,bundlei)) != 0 ) + { iguana_bundlehashadd(coin,bp,bundlei,block); - //printf("RT.%d vs hwm.%d starti.%d bp->n %d block.%p/%p ramchain.%p\n",coin->RTheight,coin->blocks.hwmchain.height,coin->RTstarti,bp->n,block,bp->blocks[bundlei],dest->H.data); - if ( coin->RTdatabad == 0 && block != 0 && bits256_nonz(block->RO.prev_block) != 0 ) + //printf("RT.%d vs hwm.%d starti.%d bp->n %d block.%p/%p ramchain.%p databad.%d prevnonz.%d\n",coin->RTheight,coin->blocks.hwmchain.height,coin->RTstarti,bp->n,block,bp->blocks[bundlei],dest->H.data,coin->RTdatabad,bits256_nonz(block->RO.prev_block)); + } + else { + //printf("cant find bundleblock [%d:%d]\n",bp->hdrsi,bundlei); + iguana_blockQ("RTmissing",coin,bp,bundlei,hash2,1); + break; + } + if ( coin->RTdatabad == 0 && block != 0 && (block->height == 0 || bits256_nonz(block->RO.prev_block) != 0) ) + { + //printf("bundlei.%d blockht.%d RTheight.%d\n",bundlei,block->height,coin->RTheight); iguana_blocksetcounters(coin,block,dest); startmillis0 = OS_milliseconds(); - if ( coin->RTdatabad == 0 && iguana_ramchainfile(coin,dest,&blockR,bp,bundlei,block) == 0 ) + if ( iguana_ramchainfile(myinfo,coin,dest,&blockR,bp,bundlei,block) == 0 ) { for (i=0; in; i++) if ( GETBIT(bp->haveblock,i) == 0 ) @@ -302,14 +379,17 @@ int32_t iguana_realtime_update(struct iguana_info *coin) { uint8_t serialized[512]; int32_t len; struct iguana_peer *addr; //char str[65]; printf("RT error [%d:%d] %s %p\n",bp->hdrsi,i,bits256_str(str,hash2),block); - addr = coin->peers.ranked[rand() % 8]; - if ( addr != 0 && addr->usock >= 0 && addr->dead == 0 && (len= iguana_getdata(coin,serialized,MSG_BLOCK,&hash2,1)) > 0 ) - iguana_send(coin,addr,serialized,len); + if ( coin->peers != 0 ) + { + addr = coin->peers->ranked[rand() % 8]; + if ( addr != 0 && addr->usock >= 0 && addr->dead == 0 && (len= iguana_getdata(coin,serialized,MSG_BLOCK,&hash2,1)) > 0 ) + iguana_send(coin,addr,serialized,len); + } coin->RTgenesis = 0; } if ( bits256_nonz(hash2) != 0 ) iguana_blockQ("RTerr",coin,bp,i,hash2,1); - break; + //break; } return(-1); } else iguana_ramchain_free(coin,&blockR,1); @@ -317,31 +397,59 @@ int32_t iguana_realtime_update(struct iguana_info *coin) totalmillis0 += (OS_milliseconds() - startmillis0); num0++; flag++; - coin->blocks.RO[bp->bundleheight+bundlei] = block->RO; + //coin->blocks.RO[bp->bundleheight+bundlei] = block->RO; coin->RTheight++; - printf(">>>> RT.%d hwm.%d L.%d T.%d U.%d S.%d P.%d X.%d -> size.%ld\n",coin->RTheight,coin->blocks.hwmchain.height,coin->longestchain,dest->H.txidind,dest->H.unspentind,dest->H.spendind,dest->pkind,dest->externalind,(long)dest->H.data->allocsize); + coin->lastRTheight = coin->RTheight; + //printf(">>>> RT.%d hwm.%d L.%d T.%d U.%d S.%d P.%d X.%d -> size.%ld\n",coin->RTheight,coin->blocks.hwmchain.height,coin->longestchain,dest->H.txidind,dest->H.unspentind,dest->H.spendind,dest->pkind,dest->externalind,(long)dest->H.data->allocsize); if ( coin->RTramchain.H.data != 0 ) coin->RTramchain.H.data->numblocks = bundlei + 1; else break; } else break; } } + else + { + if ( coin->virtualchain == 0 ) + { + //printf("%s skip RT.(%d %d %d %d %d %d %d %u)\n",coin->symbol,coin->RTdatabad,bp->hdrsi,coin->longestchain/coin->chain->bundlesize,coin->balanceswritten,coin->RTheight,bp->bundleheight,coin->blocks.hwmchain.height,bp->lastRT); + //sleep(1); + } + } n = 0; - if ( coin->RTdatabad == 0 && dest != 0 && flag != 0 && coin->RTheight >= coin->longestchain ) + if ( coin->RTdatabad == 0 && dest != 0 && flag != 0 && coin->RTheight >= coin->blocks.hwmchain.height-offset ) { - //printf("ramchainiterate.[%d] ave %.2f micros, total %.2f seconds starti.%d num.%d\n",num0,(totalmillis0*1000.)/num0,totalmillis0/1000.,coin->RTstarti,coin->RTheight%bp->n); - if ( (n= iguana_walkchain(coin,1)) == coin->RTheight-1 ) + printf("ramchainiterate.[%d] ave %.2f micros, total %.2f seconds starti.%d num.%d\n",num0,(totalmillis0*1000.)/num0,totalmillis0/1000.,coin->RTstarti,coin->RTheight%bp->n); + if ( (n= iguana_walkchain(coin,1)) == coin->RTheight-1+offset ) { //printf("RTgenesis verified\n"); - iguana_RTspendvectors(coin,bp); - coin->RTgenesis = (uint32_t)time(NULL); - } else coin->RTdatabad = 1; + if ( (coin->RTheight % coin->chain->bundlesize) > 3 ) + { + //portable_mutex_lock(&coin->RTmutex); + iguana_RTspendvectors(myinfo,coin,bp); + //portable_mutex_unlock(&coin->RTmutex); + coin->RTgenesis = (uint32_t)time(NULL); + } + } + else + { + printf("walkchain error n.%d != %d\n",n,coin->RTheight-1+offset); + coin->RTdatabad = 1; + } } if ( dest != 0 && flag != 0 ) - printf("<<<< flag.%d RT.%d:%d hwm.%d L.%d T.%d U.%d S.%d P.%d X.%d -> size.%ld\n",flag,coin->RTheight,n,coin->blocks.hwmchain.height,coin->longestchain,dest->H.txidind,dest->H.unspentind,dest->H.spendind,dest->pkind,dest->externalind,dest->H.data!=0?(long)dest->H.data->allocsize:-1); + printf("<<<< flag.%d RT.%d:%d hwm.%d L.%d T.%d U.%d S.%d P.%d X.%d -> size.%ld balance %.8f + %.8f - %.8f = supply %.8f\n",flag,coin->RTheight,n,coin->blocks.hwmchain.height,coin->longestchain,dest->H.txidind,dest->H.unspentind,dest->H.spendind,dest->pkind,dest->externalind,dest->H.data!=0?(long)dest->H.data->allocsize:-1,dstr(coin->histbalance),dstr(coin->RTcredits),dstr(coin->RTdebits),dstr(coin->histbalance + coin->RTcredits - coin->RTdebits)); if ( coin->RTdatabad != 0 ) { + bits256 lastbundle; + //portable_mutex_lock(&coin->RTmutex); + printf("START DATABAD fixing\n"); iguana_RTramchainfree(coin,bp); + if ( coin->RTdatabad < 0 ) + { + memset(lastbundle.bytes,0,sizeof(lastbundle)); + iguana_initfinal(myinfo,coin,lastbundle); + } + coin->RTdatabad = 0; //memset(bp->hashes,0,sizeof(bp->hashes)); memset(bp->blocks,0,sizeof(bp->blocks)); if ( 0 && bp->speculative != 0 ) @@ -352,6 +460,647 @@ int32_t iguana_realtime_update(struct iguana_info *coin) myfree(ptr,(bp->n+1)*sizeof(*bp->speculative)); } iguana_RTramchainalloc("RTbundle",coin,bp); + printf("DONE DATABAD fixing\n"); + //portable_mutex_unlock(&coin->RTmutex); } +#endif return(flag); } +#endif + +//#define FAST_UTHASH +#ifdef FAST_UTHASH +#undef uthash_malloc +#undef uthash_free +#define uthash_malloc(size) ((coin->RTHASHMEM.ptr == 0) ? mycalloc('u',1,size) : iguana_memalloc(&coin->RTHASHMEM,size,1)) +#define uthash_free(mem,size) ((coin->RTHASHMEM.ptr == 0) ? myfree(mem,size) : 0) +#endif + +void iguana_RTtxid_free(struct iguana_RTtxid *RTptr) +{ + int32_t i; + for (i=0; inumvouts; i++) + if ( RTptr->unspents[i] != 0 ) + free(RTptr->unspents[i]); + for (i=0; inumvins; i++) + if ( RTptr->spends[i] != 0 ) + free(RTptr->spends[i]); + if ( RTptr->rawtxbytes != 0 ) + free(RTptr->rawtxbytes); + free(RTptr); +} + +void iguana_RTdataset_free(struct iguana_info *coin) +{ + struct iguana_RTtxid *RTptr,*tmp; struct iguana_RTaddr *RTaddr,*tmp2; + HASH_ITER(hh,coin->RTdataset,RTptr,tmp) + { + HASH_DELETE(hh,coin->RTdataset,RTptr); + iguana_RTtxid_free(RTptr); + } + HASH_ITER(hh,coin->RTaddrs,RTaddr,tmp2) + { + HASH_DELETE(hh,coin->RTaddrs,RTaddr); + free(RTaddr); + } + iguana_hhutxo_purge(coin); + iguana_memreset(&coin->RTHASHMEM); +} + +void iguana_RTreset(struct iguana_info *coin) +{ + iguana_utxoaddrs_purge(coin); + //iguana_utxoupdate(coin,-1,0,0,0,0,-1,0); // free hashtables + coin->lastRTheight = 0; + iguana_RTdataset_free(coin); +#ifdef FAST_UTHASH + if ( coin->RTHASHMEM.ptr == 0 ) + iguana_meminit(&coin->RTHASHMEM,"RTHASHMEM",0,1024*1024*1024,0); + iguana_memreset(&coin->RTHASHMEM); +#endif + printf("%s RTreset %d\n",coin->symbol,coin->RTheight); + coin->RTheight = coin->firstRTheight; +} + +struct iguana_RTaddr *iguana_RTaddrfind(struct iguana_info *coin,uint8_t *rmd160,char *coinaddr) +{ + struct iguana_RTaddr *RTaddr; int32_t len; char _coinaddr[64]; + if ( coinaddr == 0 ) + { + coinaddr = _coinaddr; + bitcoin_address(coinaddr,coin->chain->pubtype,rmd160,20); + } + len = (int32_t)strlen(coinaddr); + HASH_FIND(hh,coin->RTaddrs,coinaddr,len,RTaddr); + return(RTaddr); +} + +int64_t iguana_RTbalance(struct iguana_info *coin,char *coinaddr) +{ + struct iguana_RTaddr *RTaddr; uint8_t addrtype,rmd160[20]; int32_t len; + len = (int32_t)strlen(coinaddr); + HASH_FIND(hh,coin->RTaddrs,coinaddr,len,RTaddr); + if ( RTaddr != 0 ) + return(RTaddr->credits - RTaddr->debits + RTaddr->histbalance); + else + { + bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr); + return(iguana_utxoaddrtablefind(coin,-1,-1,rmd160)); + } +} + +void iguana_RTcoinaddr(struct iguana_info *coin,struct iguana_RTtxid *RTptr,struct iguana_block *block,int64_t polarity,char *coinaddr,uint8_t *rmd160,int32_t spendflag,int64_t value,struct iguana_RTunspent *unspent) +{ + struct iguana_RTaddr *RTaddr; int32_t len = (int32_t)strlen(coinaddr); + HASH_FIND(hh,coin->RTaddrs,coinaddr,len,RTaddr); + if ( RTaddr == 0 ) + { + RTaddr = calloc(1,sizeof(*RTaddr)); + strncpy(RTaddr->coinaddr,coinaddr,len); + RTaddr->histbalance = iguana_utxoaddrtablefind(coin,-1,-1,rmd160); + HASH_ADD_KEYPTR(hh,coin->RTaddrs,RTaddr->coinaddr,len,RTaddr); + } + if ( spendflag != 0 ) + { + RTaddr->debits += polarity * value; + coin->RTdebits += polarity * value; + } + else + { + RTaddr->credits += polarity * value; + coin->RTcredits += polarity * value; + if ( polarity > 0 ) + { + //printf("unspent[%d] <- %p\n",RTaddr->numunspents,unspent); + RTaddr->numunspents++; + unspent->prevunspent = RTaddr->lastunspent; + RTaddr->lastunspent = unspent; + } + else if ( polarity < 0 ) + { + if ( RTaddr->lastunspent == unspent ) + { + RTaddr->lastunspent = unspent->prevunspent; + free(unspent); + } else printf("lastunspent.%p != %p\n",RTaddr->lastunspent,unspent); + //RTaddr->unspents[i] = RTaddr->unspents[--RTaddr->numunspents]; + } + } + if ( 0 && strcmp("BTC",coin->symbol) != 0 && strcmp("LTC",coin->symbol) != 0 && strcmp("DOGE",coin->symbol) != 0 ) + printf("%lld %s %.8f h %.8f, cr %.8f deb %.8f [%.8f] numunspents.%d %p\n",(long long)polarity,coinaddr,dstr(value),dstr(RTaddr->histbalance),dstr(RTaddr->credits),dstr(RTaddr->debits),dstr(RTaddr->credits)-dstr(RTaddr->debits)+dstr(RTaddr->histbalance),RTaddr->numunspents,unspent); +} + +struct iguana_RTunspent *iguana_RTunspent_create(uint8_t *rmd160,int64_t value,uint8_t *script,int32_t scriptlen,struct iguana_RTtxid *parent,int32_t vout) +{ + struct iguana_RTunspent *unspent; + unspent = calloc(1,sizeof(*unspent) + scriptlen); + unspent->value = value; + if ( (unspent->parent= parent) != 0 ) + unspent->height = parent->height; + else unspent->height = -1; + unspent->vout = vout; + unspent->scriptlen = scriptlen; + memcpy(unspent->rmd160,rmd160,sizeof(unspent->rmd160)); + memcpy(unspent->script,script,scriptlen); + return(unspent); +} + +void iguana_RTunspent(struct iguana_info *coin,struct iguana_RTtxid *RTptr,struct iguana_block *block,int64_t polarity,char *coinaddr,uint8_t *rmd160,int32_t type,uint8_t *script,int32_t scriptlen,bits256 txid,int32_t vout,int64_t value) +{ + int32_t i; struct iguana_RTunspent *unspent; char str[65]; + //printf("iguana_RTunspent.%lld %s vout.%d %.8f\n",(long long)polarity,coinaddr,vout,dstr(value)); + //fprintf(stderr,"+"); + if ( RTptr != 0 ) + { + if ( bits256_cmp(RTptr->txid,txid) == 0 ) + { + if ( (unspent= RTptr->unspents[vout]) == 0 ) + { + if ( polarity > 0 ) + { + unspent = iguana_RTunspent_create(rmd160,value,script,scriptlen>0?scriptlen:0,RTptr,vout); + RTptr->unspents[vout] = unspent; + } else printf("iguana_RTunspent missing vout.%d ptr\n",vout); + } + else + { + if ( memcmp(rmd160,unspent->rmd160,sizeof(unspent->rmd160)) != 0 || value != unspent->value || scriptlen != unspent->scriptlen || memcmp(unspent->script,script,scriptlen) != 0 ) + { + printf("iguana_RTunspent.%d of %d mismatch %s\n",vout,RTptr->numvouts,bits256_str(str,RTptr->txid)); + return; + } + } + if ( (unspent->spend == 0 && polarity < 0) || (unspent->spend != 0 && polarity > 0) ) + printf("unspent spend.%p opposite when polarity.%lld\n",unspent->spend,(long long)polarity); + iguana_RTcoinaddr(coin,RTptr,block,polarity,coinaddr,unspent->rmd160,0,value,unspent); + if ( polarity < 0 ) + RTptr->unspents[vout] = 0; + } else printf("iguana_RTunspent txid mismatch %llx != %llx\n",(long long)RTptr->txid.txid,(long long)txid.txid); + } + else + { + for (i=0; i<20; i++) + printf("%02x",rmd160[i]); + printf(" %s vout.%d %.8f %lld\n",coinaddr,vout,dstr(value),(long long)polarity); + } + //fprintf(stderr,","); +} + +void iguana_RTspend(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_RTtxid *RTptr,struct iguana_block *block,int64_t polarity,uint8_t *script,int32_t scriptlen,bits256 txid,int32_t vini,bits256 prev_hash,int32_t prev_vout) +{ + struct iguana_RTspend *spend; struct iguana_RTtxid *spentRTptr; struct iguana_RTunspent *unspent=0; char str[65],str2[65],coinaddr[64]; uint8_t addrtype,rmd160[20],spendscript[IGUANA_MAXSCRIPTSIZE]; uint32_t unspentind; int32_t spendlen,height; uint64_t value; struct iguana_outpoint spentpt; + //printf("RTspend %s vini.%d spend.(%s/v%d) %lld\n",bits256_str(str,txid),vini,bits256_str(str2,prev_hash),prev_vout,(long long)polarity); + if ( vini == 0 && bits256_nonz(prev_hash) == 0 && prev_vout < 0 ) + return; + //fprintf(stderr,"-"); + if ( RTptr != 0 ) + { + if ( bits256_cmp(RTptr->txid,txid) == 0 ) + { + if ( (spend= RTptr->spends[vini]) == 0 ) + { + if ( polarity > 0 ) + { + spend = calloc(1,sizeof(*spend) + scriptlen); + spend->prev_hash = prev_hash; + spend->prev_vout = prev_vout; + spend->scriptlen = scriptlen; + memcpy(spend->vinscript,script,scriptlen); + RTptr->spends[vini] = spend; + } else printf("iguana_RTspend missing vini.%d ptr\n",vini); + } + else + { + if ( bits256_cmp(prev_hash,spend->prev_hash) != 0 || prev_vout != spend->prev_vout || scriptlen != spend->scriptlen || memcmp(spend->vinscript,script,scriptlen) != 0 ) + { + printf("RTspend.%d of %d mismatch %s\n",vini,RTptr->numvins,bits256_str(str,RTptr->txid)); + return; + } + } + if ( bits256_nonz(prev_hash) != 0 && prev_vout >= 0 ) + { + HASH_FIND(hh,coin->RTdataset,prev_hash.bytes,sizeof(prev_hash),spentRTptr); + if ( spentRTptr != 0 ) + { + if ( (unspent= spentRTptr->unspents[prev_vout]) == 0 ) + { + printf("iguana_RTspend null unspent.(%s).%d\n",bits256_str(str,prev_hash),prev_vout); + } + } + else + { + if ( (unspentind= iguana_unspentindfind(myinfo,coin,coinaddr,spendscript,&spendlen,&value,&height,prev_hash,prev_vout,coin->bundlescount,0)) == 0 ) + printf("iguana_RTspend cant find spentRTptr.(%s) search history\n",bits256_str(str,prev_hash)); + else + { + int32_t spentheight,lockedflag,RTspentflag; + bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr); + //printf("found unspentind (%s %.8f).%d spendlen.%d\n",coinaddr,dstr(value),addrtype,spendlen); + unspent = iguana_RTunspent_create(rmd160,value,spendscript,spendlen>0?spendlen:0,0,prev_vout); + memset(&spentpt,0,sizeof(spentpt)); + spentpt.unspentind = unspentind; + spentpt.hdrsi = height / coin->chain->bundlesize; + iguana_RTutxofunc(coin,&spentheight,&lockedflag,spentpt,&RTspentflag,0,RTptr->height); + } + } + if ( unspent != 0 ) + { + bitcoin_address(coinaddr,coin->chain->pubtype,unspent->rmd160,sizeof(unspent->rmd160)); + iguana_RTcoinaddr(coin,RTptr,block,polarity,coinaddr,unspent->rmd160,1,unspent->value,unspent); + if ( polarity < 0 ) + unspent->spend = 0; + else unspent->spend = spend; + } + } + } else printf("iguana_RTspend txid mismatch %llx != %llx\n",(long long)RTptr->txid.txid,(long long)txid.txid); + } else printf("null rtptr? %s vini.%d spend.(%s/v%d) %lld\n",bits256_str(str,txid),vini,bits256_str(str2,prev_hash),prev_vout,(long long)polarity); + //fprintf(stderr,","); +} + +struct iguana_RTtxid *iguana_RTtxid_create(struct iguana_info *coin,struct iguana_block *block,int64_t polarity,int32_t txi,int32_t txn_count,bits256 txid,int32_t numvouts,int32_t numvins,uint32_t locktime,uint32_t version,uint32_t timestamp,uint8_t *serialized,int32_t txlen) +{ + struct iguana_RTtxid *RTptr; char str[65]; + if ( block == 0 || block->height < coin->firstRTheight || block->height >= coin->firstRTheight+sizeof(coin->RTblocks)/sizeof(*coin->RTblocks) ) + { + printf("iguana_RTtxid_create: illegal block height.%d\n",block!=0?block->height:-1); + return(0); + } + //fprintf(stderr,"t"); + HASH_FIND(hh,coin->RTdataset,txid.bytes,sizeof(txid),RTptr); + if ( RTptr == 0 ) + { + RTptr = calloc(1,sizeof(*RTptr) + sizeof(void *)*numvins + sizeof(void *)*numvouts); + RTptr->txi = txi, RTptr->txn_count = txn_count; + RTptr->coin = coin; + RTptr->block = block; + RTptr->height = block->height; + RTptr->txid = txid; + RTptr->txn_count = txn_count; + RTptr->numvouts = numvouts; + RTptr->numvins = numvins; + RTptr->locktime = locktime; + RTptr->version = version; + RTptr->timestamp = timestamp; + RTptr->unspents = (void *)&RTptr->spends[numvins]; + if ( txlen > 0 ) + { + RTptr->rawtxbytes = malloc(txlen); + RTptr->txlen = txlen; + memcpy(RTptr->rawtxbytes,serialized,txlen); + } + HASH_ADD_KEYPTR(hh,coin->RTdataset,RTptr->txid.bytes,sizeof(RTptr->txid),RTptr); + if ( 0 && strcmp("BTC",coin->symbol) != 0 ) + printf("%s txid.(%s) vouts.%d vins.%d version.%d lock.%u t.%u %lld\n",coin->symbol,bits256_str(str,txid),numvouts,numvins,version,locktime,timestamp,(long long)polarity); + } + else if ( RTptr->txn_count != txn_count || RTptr->numvouts != numvouts || RTptr->numvins != numvins ) + { + printf("%s inconsistent counts.(%d %d %d) vs (%d %d %d)\n",bits256_str(str,txid),RTptr->txn_count,RTptr->numvouts,RTptr->numvins,txn_count,numvouts,numvins); + return(0); + } + //fprintf(stderr," %d ",txi); + //if ( txi == txn_count-1 ) + // fprintf(stderr," ht.%d\n",block->height); + return(RTptr); +} + +int64_t _RTgettxout(struct iguana_info *coin,int32_t *height,int32_t *scriptlen,uint8_t *script,uint8_t *rmd160,char *coinaddr,bits256 txid,int32_t vout,int32_t mempool) +{ + int64_t value = 0; struct iguana_RTtxid *RTptr; struct iguana_RTunspent *unspent = 0; + HASH_FIND(hh,coin->RTdataset,txid.bytes,sizeof(txid),RTptr); + if ( RTptr != 0 && (RTptr->height <= coin->blocks.hwmchain.height || mempool != 0) ) + { + if ( vout >= 0 && vout < RTptr->txn_count && (unspent= RTptr->unspents[vout]) != 0 ) + { + *height = RTptr->height; + if ( (*scriptlen= unspent->scriptlen) > 0 ) + memcpy(script,unspent->script,*scriptlen); + memcpy(rmd160,unspent->rmd160,sizeof(unspent->rmd160)); + bitcoin_address(coinaddr,coin->chain->pubtype,rmd160,sizeof(unspent->rmd160)); + value = unspent->value; + } else printf("vout.%d error %p\n",vout,unspent); + } + return(value); +} + +int32_t iguana_RTunspentindfind(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr,uint8_t *spendscript,int32_t *spendlenp,uint64_t *valuep,int32_t *heightp,bits256 txid,int32_t vout,int32_t lasthdrsi,int32_t mempool) +{ + char _coinaddr[64]; uint8_t rmd160[20]; int64_t value; + if ( coinaddr == 0 ) + coinaddr = _coinaddr; + if ( (value= _RTgettxout(coin,heightp,spendlenp,spendscript,rmd160,coinaddr,txid,vout,mempool)) > 0 ) + { + if ( valuep != 0 ) + *valuep = value; + return(0); + } + else return(iguana_unspentindfind(myinfo,coin,coinaddr,spendscript,spendlenp,valuep,heightp,txid,vout,lasthdrsi,mempool)); +} + +int32_t _iguana_RTunspentfind(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,int32_t *voutp,uint8_t *spendscript,struct iguana_outpoint outpt,int64_t value) +{ + int32_t spendlen = 0; struct iguana_RTunspent *unspent; struct iguana_RTtxid *parent; + if ( outpt.isptr != 0 && (unspent= outpt.ptr) != 0 && (parent= unspent->parent) != 0 ) + { + if ( value != unspent->value ) + printf("_iguana_RTunspentfind: mismatched value %.8f != %.8f\n",dstr(value),dstr(unspent->value)); + if ( (spendlen= unspent->scriptlen) > 0 ) + memcpy(spendscript,unspent->script,spendlen); + *txidp = parent->txid; + *voutp = unspent->vout; + } + return(spendlen); +} + +void iguana_RTunmap(uint8_t *ptr,uint32_t len) +{ + OS_releasemap(&ptr[-2*sizeof(len)],len+2*sizeof(len)); +} + +void *iguana_RTrawdata(struct iguana_info *coin,bits256 hash2,uint8_t *data,int32_t *recvlenp,int32_t *numtxp,int32_t checkonly) +{ + FILE *fp; char fname[1024],str[65]; long filesize; int32_t len; uint8_t *ptr; uint32_t i,nonz,checknumtx,checklen; + sprintf(fname,"%s/%s/RT/%s.raw",GLOBAL_TMPDIR,coin->symbol,bits256_str(str,hash2)); + OS_compatible_path(fname); + if ( *recvlenp == -1 ) + OS_removefile(fname,0); + else + { + if ( (checkonly != 0 || *recvlenp > 0) && (fp= fopen(fname,"rb")) != 0 ) + { + fseek(fp,0,SEEK_END); + filesize = ftell(fp); + rewind(fp); + if ( fread(&len,1,sizeof(len),fp) == sizeof(len) && len == filesize-sizeof(int32_t)*2 ) + { + fclose(fp); + //printf("already have %s\n",bits256_str(str,hash2)); + *recvlenp = 0; + if ( checkonly != 0 ) + return((void *)"already have rawdata"); + return(0); + } + //printf("len.%d filesize.%ld\n",len,filesize); + fclose(fp); + OS_removefile(fname,0); + } + else if ( checkonly == 0 ) + { + if ( *recvlenp > 0 ) + { + if ( coin->RTheight == 0 && coin->blocks.hwmchain.height < coin->longestchain-coin->chain->bundlesize && iguana_utxofinished(coin) < coin->bundlescount-3 ) + { + //printf("skip %s\n",bits256_str(str,hash2)); + return(0); + } + if ( (fp= fopen(fname,"wb")) != 0 ) + { + if ( fwrite(recvlenp,1,sizeof(*recvlenp),fp) != sizeof(*recvlenp) || fwrite(numtxp,1,sizeof(*numtxp),fp) != sizeof(*numtxp) || fwrite(data,1,*recvlenp,fp) != *recvlenp ) + printf("error writing %s len.%d numtx.%d\n",bits256_str(str,hash2),*recvlenp,*numtxp); + fclose(fp); + //printf("numtx.%d len.%d %s hwm.%d L.%d\n",*numtxp,*recvlenp,fname,coin->blocks.hwmchain.height,coin->longestchain); + } else printf("couldnt create %s\n",fname); + } + else if ( (ptr= OS_mapfile(fname,&filesize,0)) != 0 ) + { + memcpy(&checklen,ptr,sizeof(checklen)); + memcpy(&checknumtx,&ptr[sizeof(checklen)],sizeof(checknumtx)); + *numtxp = checknumtx; + if ( checklen == (int32_t)(filesize - sizeof(checklen) - sizeof(checknumtx)) )//&& checknumtx == *numtxp ) + { + for (i=nonz=0; ichain->bundlesize); + bundlei = (height % coin->chain->bundlesize); + if ( (bp= coin->bundles[hdrsi]) != 0 && bits256_nonz(bp->hashes[bundlei]) != 0 ) + iguana_RTrawdata(coin,bp->hashes[bundlei],0,&recvlen,&numtx,0); // delete file + } + printf("end %s RTpurge.%d\n",coin->symbol,lastheight); +} + +int32_t iguana_RTiterate(struct supernet_info *myinfo,struct iguana_info *coin,int32_t offset,struct iguana_block *block,int64_t polarity) +{ + struct iguana_txblock txdata; uint8_t *serialized; struct iguana_bundle *bp; int32_t hdrsi,bundlei,height,i,n,errs=0,numtx,num,len; int32_t recvlen = 0; + if ( (numtx= coin->RTnumtx[offset]) == 0 || (serialized= coin->RTrawdata[offset]) == 0 || (recvlen= coin->RTrecvlens[offset]) == 0 ) + { + char str[65]; + //printf("errs.%d cant load %s ht.%d polarity.%lld numtx.%d %p recvlen.%d\n",errs,bits256_str(str,block->RO.hash2),block->height,(long long)polarity,coin->RTnumtx[offset],coin->RTrawdata[offset],coin->RTrecvlens[offset]); + coin->RTrecvlens[offset] = 0; + coin->RTrawdata[offset] = iguana_RTrawdata(coin,block->RO.hash2,0,&coin->RTrecvlens[offset],&coin->RTnumtx[offset],0); + if ( (numtx= coin->RTnumtx[offset]) == 0 || (serialized= coin->RTrawdata[offset]) == 0 || (recvlen= coin->RTrecvlens[offset]) == 0 ) + { + printf("%s errs.%d cant load %s ht.%d polarity.%lld numtx.%d %p recvlen.%d\n",coin->symbol,errs,bits256_str(str,block->RO.hash2),block->height,(long long)polarity,coin->RTnumtx[offset],coin->RTrawdata[offset],coin->RTrecvlens[offset]); + struct iguana_peer *addr; + iguana_blockQ("RTiterate",coin,0,-1,block->RO.hash2,1); + if ( coin->peers != 0 && coin->peers->numranked > 0 ) + { + for (i=0; ipeers->numranked&&i<8; i++) + if ( (addr= coin->peers->ranked[i]) != 0 ) + iguana_sendblockreqPT(coin,addr,0,-1,block->RO.hash2,1); + } + num = 0; + for (height=block->height+1; height<=coin->blocks.hwmchain.height; height++) + { + hdrsi = (height / coin->chain->bundlesize); + bundlei = (height % coin->chain->bundlesize); + if ( (bp= coin->bundles[hdrsi]) != 0 && (block= bp->blocks[bundlei]) != 0 ) + { + recvlen = 0; + if ( iguana_RTrawdata(coin,block->RO.hash2,0,&recvlen,&numtx,0) == 0 ) + { + num++; + iguana_blockQ("RTiterate",coin,0,-1,block->RO.hash2,1); + if ( coin->peers != 0 && (n= coin->peers->numranked) > 0 ) + { + if ( (addr= coin->peers->ranked[rand() % n]) != 0 ) + iguana_sendblockreqPT(coin,addr,0,-1,block->RO.hash2,1); + } + } + } + } + printf("issue missing %d to ht.%d\n",num,height); + return(-1); + } + } + printf("%s RTiterate.%lld offset.%d numtx.%d len.%d\n",coin->symbol,(long long)polarity,offset,coin->RTnumtx[offset],coin->RTrecvlens[offset]); + if ( coin->RTrawmem.ptr == 0 ) + iguana_meminit(&coin->RTrawmem,"RTrawmem",0,IGUANA_MAXPACKETSIZE * 2,0); + if ( coin->RTmem.ptr == 0 ) + iguana_meminit(&coin->RTmem,"RTmem",0,IGUANA_MAXPACKETSIZE * 2,0); + if ( coin->RThashmem.ptr == 0 ) + iguana_meminit(&coin->RThashmem,"RThashmem",0,IGUANA_MAXPACKETSIZE * 2,0); + iguana_memreset(&coin->RTrawmem), iguana_memreset(&coin->RTmem), iguana_memreset(&coin->RThashmem); + memset(&txdata,0,sizeof(txdata)); + //extern int32_t debugtest; + //debugtest = 1; + //fprintf(stderr,"T"); + if ( (n= iguana_gentxarray(coin,&coin->RTrawmem,&txdata,&len,serialized,recvlen)) > 0 ) + { + //fprintf(stderr,"R"); + iguana_RTramchaindata(myinfo,coin,&coin->RTmem,&coin->RThashmem,polarity,block,coin->RTrawmem.ptr,numtx); + return(0); + } else printf("gentxarray n.%d RO.txn_count.%d recvlen.%d\n",n,numtx,recvlen); + //debugtest = 0; + iguana_RTreset(coin); + return(-1); +} + +struct iguana_block *iguana_RTblock(struct iguana_info *coin,int32_t height) +{ + int32_t offset; struct iguana_block *block; + offset = height - coin->firstRTheight; + //printf("%s iguana_RTblock.%d offset.%d\n",coin->symbol,height,offset); + if ( offset < sizeof(coin->RTblocks)/sizeof(*coin->RTblocks) ) + { + if ( (block= coin->RTblocks[offset]) != 0 ) + { + if ( block->height != coin->firstRTheight+offset ) + { + printf("block height mismatch patch %d != %d\n",block->height,coin->firstRTheight+offset); + block->height = coin->firstRTheight+offset; + } + return(block); + } + } + else printf("RTblock offset.%d too big\n",offset); + return(0); +} + +int32_t iguana_RTblockadd(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_block *block) +{ + int32_t offset; + if ( block != 0 ) + { + offset = block->height - coin->firstRTheight; + if ( coin->RTrawdata[offset] == 0 ) + coin->RTrawdata[offset] = iguana_RTrawdata(coin,block->RO.hash2,0,&coin->RTrecvlens[offset],&coin->RTnumtx[offset],0); + //printf("%s RTblockadd.%d offset.%d numtx.%d len.%d\n",coin->symbol,block->height,offset,coin->RTnumtx[offset],coin->RTrecvlens[offset]); + block->RO.txn_count = coin->RTnumtx[offset]; + coin->RTblocks[offset] = block; + if ( iguana_RTiterate(myinfo,coin,offset,block,1) < 0 ) + return(-1); + } + return(0); +} + +int32_t iguana_RTblocksub(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_block *block) +{ + int32_t offset; + if ( block != 0 ) + { + offset = block->height - coin->firstRTheight; + block->RO.txn_count = coin->RTnumtx[offset]; + printf("%s RTblocksub.%d offset.%d\n",coin->symbol,block->height,offset); + if ( iguana_RTiterate(myinfo,coin,offset,block,-1) < 0 ) + return(-1); + if ( coin->RTrawdata[offset] != 0 && coin->RTrecvlens[offset] != 0 ) + iguana_RTunmap(coin->RTrawdata[offset],coin->RTrecvlens[offset]); + coin->RTrawdata[offset] = 0; + coin->RTrecvlens[offset] = 0; + coin->RTnumtx[offset] = 0; + coin->RTblocks[offset] = 0; + } + return(0); +} + +void iguana_RTnewblock(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_block *block) +{ + int32_t i,n,height,hdrsi,bundlei; struct iguana_block *addblock,*subblock; struct iguana_bundle *bp; + if ( block->height < coin->firstRTheight || block->height >= coin->firstRTheight+sizeof(coin->RTblocks)/sizeof(*coin->RTblocks) ) + { + if ( coin->firstRTheight > 0 ) + printf("iguana_RTnewblock illegal blockheight.%d\n",block->height); + return; + } + if ( block != 0 && coin->RTheight > 0 && coin->RTheight <= coin->blocks.hwmchain.height ) + { + portable_mutex_lock(&coin->RTmutex); + if ( block->height > coin->lastRTheight ) + { + n = (block->height - coin->RTheight) + 1; + for (i=0; iRTheight + i); + hdrsi = (height / coin->chain->bundlesize); + bundlei = (height % coin->chain->bundlesize); + if ( (bp= coin->bundles[hdrsi]) != 0 && (addblock= bp->blocks[bundlei]) != 0 && addblock->height == coin->RTheight+i ) + { + if ( iguana_RTblockadd(myinfo,coin,addblock) < 0 ) + break; + coin->lastRTheight = addblock->height; + } + else + { + printf("missing RTaddblock at i.%d RTheight.%d vs %p %d\n",i,coin->RTheight,addblock,addblock!=0?addblock->height:-1); + break; + } + } + coin->RTheight += i; + //printf("%s >= RTnewblock RTheight %d prev %d\n",coin->symbol,coin->RTheight,coin->lastRTheight); + } + else if ( block->height == coin->lastRTheight ) + { + if ( (subblock= iguana_RTblock(coin,block->height)) != 0 && subblock != block ) + { + if ( iguana_RTblocksub(myinfo,coin,subblock) < 0 || iguana_RTblockadd(myinfo,coin,block) < 0 ) + { + portable_mutex_unlock(&coin->RTmutex); + return; + } + printf("%s == RTnewblock RTheight %d prev %d\n",coin->symbol,coin->RTheight,coin->lastRTheight); + } + } + else + { + if ( block->height < coin->firstRTheight ) + { + if ( coin->lastRTheight > 0 ) + printf("%s ht.%d reorg past firstRTheight.%d\n",coin->symbol,block->height,coin->firstRTheight); + iguana_RTreset(coin); + } + else + { + while ( coin->lastRTheight >= block->height ) + { + if ( iguana_RTblocksub(myinfo,coin,iguana_RTblock(coin,coin->lastRTheight--)) < 0 ) + { + coin->RTheight = coin->lastRTheight+1; + portable_mutex_unlock(&coin->RTmutex); + return; + } + } + coin->RTheight = coin->lastRTheight+1; + if ( iguana_RTblockadd(myinfo,coin,block) < 0 ) + { + portable_mutex_unlock(&coin->RTmutex); + return; + } + coin->lastRTheight = block->height; + coin->RTheight = coin->lastRTheight+1; + } + } + portable_mutex_unlock(&coin->RTmutex); + //block = iguana_blockfind("next",coin,iguana_blockhash(coin,block->height+1)); + } +} + +// infinite loops at bundle boundary? +// >= RTnewblock RTheight 1254001 prev 1254000 +// B errs.0 cant load 15102564820405cd16506d2731567453c437af07cdd5954bc21b32304e39b1d4 ht.1254001 polarity.1 numtx.0 (nil) recvlen.0 diff --git a/iguana/iguana_recv.c b/iguana/iguana_recv.c index b3dc5a749..6bd9d4e66 100755 --- a/iguana/iguana_recv.c +++ b/iguana/iguana_recv.c @@ -20,9 +20,11 @@ static int32_t numDuplicates,numAfteremit; static int64_t sizeDuplicates,sizeAfteremit; -struct iguana_bundlereq *iguana_bundlereq(struct iguana_info *coin,struct iguana_peer *addr,int32_t type,int32_t datalen) +struct iguana_bundlereq *iguana_bundlereq(struct iguana_info *coin,struct iguana_peer *addr,int32_t type,uint8_t *data,int32_t datalen) { struct iguana_bundlereq *req; int32_t allocsize; + if ( data == 0 ) + datalen = 0; allocsize = (uint32_t)sizeof(*req) + datalen; req = mycalloc(type,1,allocsize); req->allocsize = allocsize; @@ -30,6 +32,8 @@ struct iguana_bundlereq *iguana_bundlereq(struct iguana_info *coin,struct iguana req->addr = addr; req->coin = coin; req->type = type; + if ( data != 0 && datalen > 0 ) + memcpy(req->serializeddata,data,datalen); return(req); } @@ -59,35 +63,54 @@ int32_t iguana_speculativesearch(struct iguana_info *coin,struct iguana_block ** int32_t iguana_sendblockreqPT(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,int32_t iamthreadsafe) { static bits256 lastreq,lastreq2; - int32_t len,j; struct iguana_bundle *checkbp; uint8_t serialized[sizeof(struct iguana_msghdr) + sizeof(uint32_t)*32 + sizeof(bits256)]; struct iguana_block *block=0; + int32_t len,j,n,recvlen,numtx; struct iguana_bundle *checkbp; uint8_t serialized[sizeof(struct iguana_msghdr) + sizeof(uint32_t)*32 + sizeof(bits256)]; struct iguana_block *block=0; char hexstr[65]; init_hexbytes_noT(hexstr,hash2.bytes,sizeof(hash2)); - if ( addr == 0 || memcmp(lastreq.bytes,hash2.bytes,sizeof(hash2)) == 0 || memcmp(lastreq2.bytes,hash2.bytes,sizeof(hash2)) == 0 ) + if ( addr == 0 && coin->peers != 0 && (n= coin->peers->numranked) > 0 ) + addr = coin->peers->ranked[rand() % n]; + if ( addr == 0 || addr->pendblocks > coin->MAXPENDINGREQUESTS ) + return(0); + if ( memcmp(lastreq.bytes,hash2.bytes,sizeof(hash2)) == 0 || memcmp(lastreq2.bytes,hash2.bytes,sizeof(hash2)) == 0 ) { //printf("duplicate req %s or null addr.%p\n",bits256_str(hexstr,hash2),addr); - // if ( (rand() % 10 ) != 0 ) + if ( iamthreadsafe == 0 && (rand() % 10 ) != 0 ) return(0); } + if ( addr->usock < 0 ) + return(0); checkbp = 0, j = -2; if ( (checkbp= iguana_bundlefind(coin,&checkbp,&j,hash2)) != 0 && j >= 0 && j < checkbp->n ) { - if ( checkbp->emitfinish != 0 || ((block= checkbp->blocks[j]) != 0 && block->txvalid != 0) ) + if ( checkbp->emitfinish != 0 || ((block= checkbp->blocks[j]) != 0 && block->txvalid != 0 && block->mainchain != 0 && block->valid != 0) ) { - //printf("found valid [%d:%d] in blockreqPT\n",checkbp->hdrsi,j); - return(0); + //char str[65]; + recvlen = numtx = 0; + if ( iguana_RTrawdata(coin,hash2,0,&recvlen,&numtx,1) != 0 ) + { + //printf("found valid [%d:%d] in blockreqPT\n",checkbp->hdrsi,j); + return(0); + } //else printf("no RTrawdata for %s\n",bits256_str(str,hash2)); } } - if ( 1 && coin->enableCACHE != 0 && iguana_speculativesearch(coin,&block,hash2) != 0 ) + if ( 0 && coin->enableCACHE != 0 && iguana_speculativesearch(coin,&block,hash2) != 0 ) { if ( block != 0 && block->hdrsi != 0 && block->bundlei != 0 ) { //printf("found valid [%d:%d] in blockreqPT txvalid.%d\n",block!=0?block->hdrsi:-1,block!=0?block->bundlei:-1,block->txvalid); - if ( block->txvalid != 0 ) + if ( block->mainchain != 0 && block->valid != 0 && block->txvalid != 0 ) + { + /*if ( (bp= coin->bundles[block->bundlei]) != 0 ) + { + bp->hashes[block->bundlei] = block->RO.hash2; + bp->blocks[block->bundlei] = block; + }*/ return(0); + } } } if ( addr->msgcounts.verack == 0 ) { - //printf("iguana_sendblockreq (%s) addrind.%d hasn't verack'ed yet\n",addr->ipaddr,addr->addrind); + if ( (rand() % 100) == 0 ) + printf("iguana_sendblockreq (%s) addrind.%d hasn't verack'ed yet\n",addr->ipaddr,addr->addrind); //iguana_send_version(coin,addr,coin->myservices); return(-1); } @@ -104,7 +127,7 @@ int32_t iguana_sendblockreqPT(struct iguana_info *coin,struct iguana_peer *addr, if ( block != 0 ) block->issued = addr->pendtime; if ( 0 && coin->current == bp ) - printf("REQ.%s bundlei.%d hdrsi.%d\n",bits256_str(hexstr,hash2),bundlei,bp!=0?bp->hdrsi:-1); + printf("REQ.(%s) [%d:%d] %s n.%d\n",bits256_str(hexstr,hash2),bundlei,bp!=0?bp->hdrsi:-1,addr->ipaddr,addr->pendblocks); } else printf("MSG_BLOCK null datalen.%d\n",len); return(len); } @@ -115,14 +138,14 @@ int32_t iguana_sendtxidreq(struct iguana_info *coin,struct iguana_peer *addr,bit int32_t len,i,r,j; //char hexstr[65]; init_hexbytes_noT(hexstr,hash2.bytes,sizeof(hash2)); if ( (len= iguana_getdata(coin,serialized,MSG_TX,&hash2,1)) > 0 ) { - if ( addr == 0 ) + if ( addr == 0 && coin->peers != 0 ) { r = rand(); for (i=0; iMAXPEERS; i++) { j = (i + r) % coin->MAXPEERS; - addr = &coin->peers.active[j]; - if ( coin->peers.active[j].usock >= 0 && coin->peers.active[j].dead == 0 ) + addr = &coin->peers->active[j]; + if ( coin->peers->active[j].usock >= 0 && coin->peers->active[j].dead == 0 ) { iguana_send(coin,addr,serialized,len); break; @@ -144,9 +167,12 @@ int32_t iguana_txidreq(struct iguana_info *coin,char **retstrp,bits256 txid) } char str[65]; printf("txidreq.%s\n",bits256_str(str,txid)); coin->reqtxids[coin->numreqtxids++] = txid; - for (i=0; iMAXPEERS; i++) - if ( coin->peers.active[i].usock >= 0 ) - iguana_sendtxidreq(coin,coin->peers.ranked[i],txid); + if ( coin->peers != 0 ) + { + for (i=0; ipeers->active[i].usock >= 0 ) + iguana_sendtxidreq(coin,coin->peers->ranked[i],txid); + } return(0); } @@ -154,10 +180,10 @@ void iguana_gotunconfirmedM(struct iguana_info *coin,struct iguana_peer *addr,st { struct iguana_bundlereq *req; char str[65]; printf("%s unconfirmed.%s\n",addr->ipaddr,bits256_str(str,tx->txid)); - req = iguana_bundlereq(coin,addr,'U',datalen); + req = iguana_bundlereq(coin,addr,'U',data,datalen); req->datalen = datalen; req->txid = tx->txid; - memcpy(req->serialized,data,datalen); + memcpy(req->serializeddata,data,datalen); queue_enqueue("recvQ",&coin->recvQ,&req->DL,0); } @@ -207,8 +233,8 @@ struct iguana_txblock *iguana_peertxdata(struct iguana_info *coin,int32_t *bundl int32_t iguana_speculativefind(struct iguana_info *coin,struct iguana_bundle *bp,struct iguana_block *block,uint8_t *data,int32_t recvlen) { - int32_t i,j,numcached,cachelen; uint8_t *tmp; char str[65]; - if ( coin->enableCACHE == 0 ) + int32_t i,j,numcached,cachelen=0; uint8_t *tmp; char str[65]; + if ( coin->enableCACHE == 0 || recvlen < 0 ) return(-1); if ( recvlen < 0 || recvlen > IGUANA_MAXPACKETSIZE ) { @@ -221,7 +247,7 @@ int32_t iguana_speculativefind(struct iguana_info *coin,struct iguana_bundle *bp { if ( (tmp= bp->speculativecache[i]) != 0 ) { - memcmp(&cachelen,tmp,sizeof(cachelen)); + memcpy(&cachelen,tmp,sizeof(cachelen)); if ( cachelen < 0 || cachelen > IGUANA_MAXPACKETSIZE ) { printf("illegal cachelen.%d %s [%d:%d] %p\n",cachelen,coin->symbol,bp->hdrsi,i,tmp); @@ -229,7 +255,9 @@ int32_t iguana_speculativefind(struct iguana_info *coin,struct iguana_bundle *bp continue; } if ( memcmp(&recvlen,tmp,sizeof(recvlen)) != 0 || memcmp(&tmp[sizeof(recvlen)],data,recvlen) != 0 ) - printf("cachedata ERROR [%d:%d] already has recvlen.%d vs %d for %s\n",bp->hdrsi,i,recvlen,cachelen,bits256_str(str,block->RO.hash2)); + { + //printf("cachedata ERROR [%d:%d] already has recvlen.%d vs %d for %s\n",bp->hdrsi,i,recvlen,cachelen,bits256_str(str,block->RO.hash2)); + } return(0); } bp->speculativecache[i] = calloc(1,recvlen + sizeof(recvlen)); @@ -290,9 +318,9 @@ void iguana_bundletime(struct iguana_info *coin,struct iguana_bundle *bp,int32_t } } -void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_txblock *origtxdata,struct iguana_msgtx *txarray,struct iguana_msghdr *H,uint8_t *data,int32_t recvlen) +void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_txblock *origtxdata,struct iguana_msgtx *txarray,struct iguana_msghdr *H,uint8_t *data,int32_t recvlen,int32_t fromcache) { - struct iguana_bundlereq *req; struct iguana_txblock *txdata = 0; int32_t valid,speculative=0,i,j,bundlei,copyflag; struct iguana_block *block; struct iguana_bundle *bp; uint32_t now; char str[65]; + struct iguana_bundlereq *req; struct iguana_txblock *txdata = 0; int32_t valid,speculative=0,i,j,bundlei,copyflag,numtx; struct iguana_block *block; struct iguana_bundle *bp; uint32_t now; char str[65]; if ( recvlen < 0 || recvlen > IGUANA_MAXPACKETSIZE ) { printf("iguana_getblockM: illegal recvlen.%d\n",recvlen); @@ -312,7 +340,7 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i } if ( coin->numreqtxids > 0 ) { - for (i=0; iblock.RO.txn_count; i++) + for (i=0; izblock.RO.txn_count; i++) { for (j=0; jnumreqtxids; j++) { @@ -323,21 +351,21 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i } } } - if ( iguana_blockvalidate(coin,&valid,&origtxdata->block,1) < 0 ) + origtxdata->zblock.RO.allocsize = sizeof(origtxdata->zblock); + if ( iguana_blockvalidate(coin,&valid,(struct iguana_block *)&origtxdata->zblock,1) < 0 ) { - printf("got block that doesnt validate? %s\n",bits256_str(str,origtxdata->block.RO.hash2)); + printf("got block that doesnt validate? %s\n",bits256_str(str,origtxdata->zblock.RO.hash2)); return; - } - else if ( 0 && coin->enableCACHE != 0 ) - printf("cache.%d validated.(%s)\n",coin->enableCACHE,bits256_str(str,origtxdata->block.RO.hash2)); - origtxdata->block.txvalid = 1; - if ( addr != 0 && addr != &coin->internaladdr ) + } else if ( 0 && coin->enableCACHE != 0 ) + printf("c.%d v.(%s) %s n%d\n",coin->enableCACHE,bits256_str(str,origtxdata->zblock.RO.hash2),addr->ipaddr,addr->pendblocks); + origtxdata->zblock.txvalid = 1; + if ( fromcache == 0 && coin->virtualchain == 0 && addr != 0 && addr != &coin->internaladdr ) { static uint64_t received[IGUANA_MAXPEERS],count[IGUANA_MAXPEERS],lastcount,lastreceived,last; received[addr->addrind] += recvlen; count[addr->addrind]++; now = (uint32_t)time(NULL); - if ( ((rand() % 100) == 0 && now > last+10) || now > last+60 ) + if ( ((rand() % 10000) == 0 && now > last+60) || now > last+600 ) { int64_t sum2 = 0,sum = 0,diffr,diff; double bw = 0.; for (i=0; ienableCACHE != 0) && (strcmp(coin->symbol,"BTC") != 0); + copyflag = (coin->enableCACHE != 0) && (strcmp(coin->symbol,"BTC") != 0); bp = 0, bundlei = -2; - bp = iguana_bundlefind(coin,&bp,&bundlei,origtxdata->block.RO.hash2); + bp = iguana_bundlefind(coin,&bp,&bundlei,origtxdata->zblock.RO.hash2); if ( bp != 0 && bundlei >= 0 && bundlei < bp->n ) { block = bp->blocks[bundlei]; @@ -379,17 +407,24 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i bp->dirty++; if ( bundlei >= 0 && block != 0 ) { - if ( iguana_blockstatus(coin,block) != 0 && block->txvalid != 0 ) + if ( block->fpipbits != 0 && block->txvalid != 0 ) { numDuplicates++; sizeDuplicates += recvlen; - iguana_bundletime(coin,bp,bundlei,block,1); //printf("duplicate [%d:%d] %s\n",bp->hdrsi,bundlei,bits256_str(str,block->RO.hash2)); - if ( bits256_cmp(origtxdata->block.RO.hash2,block->RO.hash2) == 0 ) - return; - else printf("mismatched tx received? mainchain.%d\n",block->mainchain); - if ( block->mainchain != 0 ) + if ( bits256_cmp(origtxdata->zblock.RO.hash2,block->RO.hash2) != 0 ) + { + //printf("mismatched tx %s received? mainchain.%d\n",bits256_str(str,block->RO.hash2),block->mainchain); return; + } + else + { + iguana_bundletime(coin,bp,bundlei,block,1); + iguana_blockzcopyRO(coin->chain->zcash,&block->RO,0,&origtxdata->zblock.RO,0); + block->txvalid = 1; + } + //if ( block->mainchain != 0 ) + // return; } else { @@ -397,14 +432,6 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i if ( 0 && bp == coin->current ) printf("recv [%d:%d] %s\n",bp->hdrsi,bundlei,bits256_str(str,block->RO.hash2)); } - block->RO = origtxdata->block.RO; - block->txvalid = 1; - /*if ( block->serdata == 0 ) - { - block->serdata = malloc(recvlen); - memcpy(block->serdata,data,recvlen); - }*/ - //printf("update prev for [%d:%d]\n",bp->hdrsi,bundlei); } } else @@ -415,7 +442,7 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i { if ( (bp= coin->bundles[i]) != 0 && bp->emitfinish == 0 && bp->speculative != 0 && bp->numhashes < bp->n ) { - if ( (j= iguana_speculativefind(coin,bp,&origtxdata->block,data,recvlen)) >= 0 ) + if ( (j= iguana_speculativefind(coin,bp,(struct iguana_block *)&origtxdata->zblock,data,recvlen)) >= 0 ) { copyflag = 0; speculative = 1; @@ -427,21 +454,28 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i } } } - if ( copyflag != 0 && recvlen != 0 && (bp == 0 || bundlei < 0 || ((block= bp->blocks[bundlei]) != 0 && iguana_blockstatus(coin,block) == 0)) ) + block = 0; + if ( copyflag != 0 && recvlen != 0 && (bp == 0 || bundlei < 0 || ((block= bp->blocks[bundlei]) != 0 && block->fpipbits == 0 && block->req == 0)) ) { - req = iguana_bundlereq(coin,addr,'B',copyflag * recvlen); + struct iguana_msghdr checkH; + req = iguana_bundlereq(coin,addr,'B',data,copyflag * recvlen); req->copyflag = 1; - //printf("copy %p serialized[%d]\n",req,req->recvlen); - memcpy(req->serialized,data,recvlen); + req->H = *H; + if ( 0 && iguana_sethdr(&checkH,coin->chain->netmagic,H->command,req->serializeddata,recvlen) > 0 && memcmp(&checkH,H,sizeof(checkH)) != 0 ) + { + int z; + for (z=0; zH datalen.%d crc.%08x error\n",recvlen,calc_crc32(0,data,recvlen)); + } } else { copyflag = 0; - req = iguana_bundlereq(coin,addr,'B',0); + req = iguana_bundlereq(coin,addr,'B',0,0); } req->recvlen = recvlen; - req->H = *H; - if ( bits256_cmp(origtxdata->block.RO.hash2,coin->APIblockhash) == 0 ) + if ( bits256_cmp(origtxdata->zblock.RO.hash2,coin->APIblockhash) == 0 ) { printf("MATCHED APIblockhash\n"); coin->APIblockstr = calloc(1,recvlen*2+1); @@ -450,18 +484,21 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i txdata = origtxdata; if ( addr != 0 ) { - if ( addr->pendblocks > 0 ) - addr->pendblocks--; - addr->lastblockrecv = (uint32_t)time(NULL); - addr->recvblocks += 1.; - addr->recvtotal += recvlen; - if ( speculative == 0 && iguana_ramchain_data(coin,addr,origtxdata,txarray,origtxdata->block.RO.txn_count,data,recvlen) > 0 ) + if ( fromcache == 0 ) + { + if ( addr->pendblocks > 0 ) + addr->pendblocks--; + addr->lastblockrecv = (uint32_t)time(NULL); + addr->recvblocks += 1.; + addr->recvtotal += recvlen; + } + if ( speculative == 0 && iguana_ramchain_data(coin,addr,origtxdata,txarray,origtxdata->zblock.RO.txn_count,data,recvlen) >= 0 ) { - txdata->block.fpipbits = (uint32_t)addr->ipbits; - txdata->block.RO.recvlen = recvlen; - txdata->block.fpos = 0; + txdata->zblock.fpipbits = (uint32_t)addr->ipbits; + txdata->zblock.RO.recvlen = recvlen; + txdata->zblock.fpos = 0; req->datalen = txdata->datalen; - req->ipbits = txdata->block.fpipbits; + req->ipbits = txdata->zblock.fpipbits; /*if ( 0 ) { struct iguana_txblock *checktxdata; struct OS_memspace checkmem; int32_t checkbundlei; @@ -473,28 +510,48 @@ void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct i } iguana_mempurge(&checkmem); }*/ - } + } //else printf("cant save block\n"); } - req->block = txdata->block; - //printf("recvlen.%d ipbits.%x prev.(%s)\n",req->block.RO.recvlen,req->block.fpipbits,bits256_str(str,txdata->block.RO.prev_block)); - req->block.RO.txn_count = req->numtx = txdata->block.RO.txn_count; - coin->recvcount++; - coin->recvtime = (uint32_t)time(NULL); - req->addr = addr; - netBLOCKS++; - queue_enqueue("recvQ",&coin->recvQ,&req->DL,0); + if ( txdata->zblock.fpos == 0 ) + { + numtx = origtxdata->zblock.RO.txn_count; + for (i=0; ibundlescount; i++) + if ( (bp= coin->bundles[i]) != 0 && bp->utxofinish <= 1 ) + break; + if ( (i > coin->bundlescount-2 && coin->blocks.hwmchain.height > coin->longestchain-coin->chain->bundlesize*2) || coin->RTheight > 0 ) + { + portable_mutex_lock(&coin->RTmutex); + iguana_RTrawdata(coin,txdata->zblock.RO.hash2,data,&recvlen,&numtx,0); + portable_mutex_unlock(&coin->RTmutex); + } + req->zblock = txdata->zblock; + if ( coin->virtualchain != 0 ) + printf("%s recvlen.%d ipbits.%x prev.(%s)\n",coin->symbol,req->zblock.RO.recvlen,req->zblock.fpipbits,bits256_str(str,txdata->zblock.RO.prev_block)); + req->zblock.RO.txn_count = req->numtx = txdata->zblock.RO.txn_count; + if ( fromcache == 0 ) + { + coin->recvcount++; + coin->recvtime = (uint32_t)time(NULL); + netBLOCKS++; + } + req->addr = addr; + //if ( (bits256_cmp(origtxdata->zblock.RO.hash2,coin->blocks.hwmchain.RO.hash2) == 0 || req->zblock.mainchain == 0 || req->zblock.valid == 0 || req->zblock.txvalid == 0) && iguana_RTrawdata(coin,origtxdata->zblock.RO.hash2,0,&len,&numtx,1) == 0 ) + queue_enqueue("recvQ",&coin->recvQ,&req->DL,0); + if ( 0 && strcmp("BTCD",coin->symbol) == 0 ) + printf("%s Q.(%s)\n",coin->symbol,bits256_str(str,origtxdata->zblock.RO.hash2)); + } else printf("nonz fpos.%d %s\n",txdata->zblock.fpos,bits256_str(str,origtxdata->zblock.RO.hash2)); } void iguana_gottxidsM(struct iguana_info *coin,struct iguana_peer *addr,bits256 *txids,int32_t n) { struct iguana_bundlereq *req; //printf("got %d txids from %s\n",n,addr->ipaddr); - req = iguana_bundlereq(coin,addr,'T',0); + req = iguana_bundlereq(coin,addr,'T',0,0); req->hashes = txids, req->n = n; queue_enqueue("recvQ",&coin->recvQ,&req->DL,0); } -void iguana_gotheadersM(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_block *blocks,int32_t n) +int32_t iguana_gotheadersM(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_zblock *zblocks,int32_t n) { struct iguana_bundlereq *req; int32_t i,num; if ( addr != 0 ) @@ -513,24 +570,24 @@ void iguana_gotheadersM(struct iguana_info *coin,struct iguana_peer *addr,struct if ( addr->pendhdrs > 0 ) addr->pendhdrs--; //printf("%s blocks[%d] ht.%d gotheaders pend.%d %.0f\n",addr->ipaddr,n,blocks[0].height,addr->pendhdrs,milliseconds()); - if ( bits256_cmp(blocks[1].RO.hash2,coin->RThash1) == 0 ) + if ( bits256_cmp(zblocks[1].RO.hash2,coin->RThash1) == 0 ) { num = (n < coin->chain->bundlesize ? n : coin->chain->bundlesize); for (i=0; iRThashes[i] = blocks[i].RO.hash2; + addr->RThashes[i] = zblocks[i].RO.hash2; addr->numRThashes = num; } } - req = iguana_bundlereq(coin,addr,'H',0); - req->blocks = blocks, req->n = n; + req = iguana_bundlereq(coin,addr,'H',0,0); + req->blocks = zblocks, req->n = n; HDRnet++; - //char str[65]; printf("PTblockhdrs.%s net.%d blocks.%d\n",bits256_str(str,blocks[0].RO.hash2),HDRnet,netBLOCKS); queue_enqueue("recvQ",&coin->recvQ,&req->DL,0); + return(0); } void iguana_gotblockhashesM(struct iguana_info *coin,struct iguana_peer *addr,bits256 *blockhashes,int32_t n) { - struct iguana_bundlereq *req; int32_t num; + struct iguana_bundlereq *req; int32_t i,num; //struct iguana_bundle *bp; if ( addr != 0 ) { addr->recvhdrs++; @@ -543,14 +600,22 @@ void iguana_gotblockhashesM(struct iguana_info *coin,struct iguana_peer *addr,bi addr->numRThashes = num; } } - req = iguana_bundlereq(coin,addr,'S',0); + req = iguana_bundlereq(coin,addr,'S',0,0); req->hashes = blockhashes, req->n = n; char str[65]; if ( 0 && n > 2 && addr != 0 ) printf("addr.%d %s [%d]\n",addr->rank,bits256_str(str,blockhashes[1]),n); queue_enqueue("recvQ",&coin->recvQ,&req->DL,0); - if ( strcmp("BTC",coin->symbol) != 0 && n > coin->chain->bundlesize ) - iguana_sendblockreqPT(coin,addr,0,-1,blockhashes[1],0); + if ( strcmp("BTC",coin->symbol) != 0 ) + { + if ( n > coin->chain->bundlesize ) + iguana_sendblockreqPT(coin,addr,0,-1,blockhashes[1],0); + if ( 0 && coin->RTheight > 0 ) + { + for (i=1; i 0 ) block->RO.prev_block = blockhashes[i-1]; block->height = bp->bundleheight + i; + //printf("allhashcmp ht.%d for %d\n",block->height,i); block->mainchain = 1; if ( prev != 0 ) { @@ -654,12 +720,12 @@ int32_t iguana_bundlehashadd(struct iguana_info *coin,struct iguana_bundle *bp,i if ( firstflag != 0 && bp->emitfinish == 0 ) { //block->fpos = -1; - if ( 0 && iguana_ramchainfile(coin,0,&blockR,bp,bundlei,block) == 0 ) + if ( 0 && iguana_ramchainfile(SuperNET_MYINFO(0),coin,0,&blockR,bp,bundlei,block) == 0 ) { size = sizeof(blockR); iguana_ramchain_free(coin,&blockR,1); } - else if ( bp->hdrsi == coin->longestchain/bp->n ) + else if ( bp->hdrsi > 0 && bp->hdrsi == coin->longestchain/bp->n ) { checki = iguana_peerfname(coin,&hdrsi,GLOBAL_TMPDIR,fname,0,block->RO.hash2,zero,1,0); if ( (fp= fopen(fname,"rb")) != 0 ) @@ -683,10 +749,92 @@ int32_t iguana_bundlehashadd(struct iguana_info *coin,struct iguana_bundle *bp,i return(retval); } +void iguana_bundle_set(struct iguana_info *coin,struct iguana_block *block,int32_t height) +{ + int32_t hdrsi,bundlei; struct iguana_bundle *bp; + if ( block->height < 0 || block->height == height ) + { + hdrsi = (height / coin->chain->bundlesize); + bundlei = (height % coin->chain->bundlesize); + if ( hdrsi < coin->bundlescount && (bp= coin->bundles[hdrsi]) != 0 ) + { + bp->blocks[bundlei] = block; + bp->hashes[bundlei] = block->RO.hash2; + if ( bp->speculative != 0 ) + bp->speculative[bundlei] = block->RO.hash2; + //char str[65]; printf("SET %s ht.%d in [%d:%d]\n",bits256_str(str,block->RO.hash2),height,hdrsi,bundlei); + } //else printf("iguana_bundle_set: no bundle at [%d]\n",hdrsi); + } else printf("iguana_bundle_set: mismatch ht.%d vs %d\n",block->height,height); +} + +void iguana_hwmchain_set(struct iguana_info *coin,struct iguana_block *block,int32_t height) +{ + if ( coin->RTheight > 0 ) + { + if ( block->height == height ) + { + iguana_blockcopy(coin->chain->zcash,coin->chain->auxpow,coin,(struct iguana_block *)&coin->blocks.hwmchain,block); + char str[65]; printf("SET HWM.%s ht.%d\n",bits256_str(str,block->RO.hash2),height); + } else printf("iguana_hwmchain_set: mismatched ht.%d vs %d\n",block->height,height); + } +} + +void iguana_mainchain_clear(struct iguana_info *coin,struct iguana_block *mainchain,struct iguana_block *oldhwm,int32_t n) +{ + int32_t i,height; char str[65]; struct iguana_block *tmp = oldhwm; + if ( mainchain != oldhwm ) + { + height = oldhwm->height; + for (i=0; iRO.hash2); + if ( tmp->mainchain == 0 ) + printf("%s iguana_mainchain_clear: unexpected non-main ht.%d %s\n",coin->symbol,tmp->height,str); + else if ( tmp->height != height ) + printf("iguana_mainchain_clear: unexpected ht.%d vs %d %s\n",tmp->height,height,str); + else + { + tmp->mainchain = 0; + printf("CLEAR mainchain.%d %s\n",height,str); + } + if ( (tmp= iguana_blockfind("clear",coin,tmp->RO.prev_block)) == 0 ) + { + printf("iguana_mainchain_clear: got null tmp i.%d of %d %s\n",i,n,str); + return; + } + } + if ( tmp != mainchain && coin->RTheight > 0 ) + printf("iguana_mainchain_clear: unexpected mismatch ht.%d vs %d %s\n",tmp->height,mainchain->height,bits256_str(str,tmp->RO.hash2)); + } +} + +int32_t iguana_height_estimate(struct iguana_info *coin,struct iguana_block **mainchainp,struct iguana_block *block) +{ + int32_t i,n; struct iguana_block *tmp = block; + *mainchainp = 0; + for (i=n=0; ichain->bundlesize; i++) + { + if ( tmp != 0 && (tmp= iguana_blockfind("estimate",coin,tmp->RO.hash2)) != 0 ) + { + if ( tmp->mainchain != 0 && tmp->height >= 0 ) + { + char str[65]; + if ( 0 && n > 0 && coin->RTheight > 0 ) + printf("%s M.%d dist.%d -> %d\n",bits256_str(str,block->RO.hash2),tmp->height,n,tmp->height+n); + *mainchainp = tmp; + return(tmp->height + n); + } + n++; + tmp = iguana_blockfind("prevestimate",coin,tmp->RO.prev_block); + } else return(0); + } + return(0); +} + // main context, ie single threaded -struct iguana_bundle *iguana_bundleset(struct iguana_info *coin,struct iguana_block **blockp,int32_t *bundleip,struct iguana_block *origblock) +struct iguana_bundle *iguana_bundleset(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_block **blockp,int32_t *bundleip,struct iguana_block *origblock) { - struct iguana_block *block,*prevblock; bits256 zero,hash2,prevhash2; struct iguana_bundle *prevbp,*bp = 0; int32_t prevbundlei,bundlei = -2; // struct iguana_ramchain blockR; + struct iguana_block *block,*prevblock,*tmp,*mainchain,*hwmblock; bits256 zero,hash2,prevhash2; struct iguana_bundle *prevbp,*bp = 0; int32_t i,newheight,prevbundlei,bundlei = -2; // struct iguana_ramchain blockR; *bundleip = -2; *blockp = 0; if ( origblock == 0 ) return(0); @@ -697,10 +845,31 @@ struct iguana_bundle *iguana_bundleset(struct iguana_info *coin,struct iguana_bl prevhash2 = origblock->RO.prev_block; if ( block != origblock ) { - iguana_blockcopy(coin,block,origblock); + iguana_blockcopy(coin->chain->zcash,coin->chain->auxpow,coin,block,origblock); //fprintf(stderr,"bundleset block.%p vs origblock.%p prev.%d bits.%x fpos.%ld\n",block,origblock,bits256_nonz(prevhash2),block->fpipbits,block->fpos); } *blockp = block; + if ( coin->blocks.hwmchain.height > 0 && (hwmblock= iguana_blockfind("hwm",coin,coin->blocks.hwmchain.RO.hash2)) != 0 ) + { + if ( (newheight= iguana_height_estimate(coin,&mainchain,block)) >= coin->blocks.hwmchain.height ) + { + iguana_mainchain_clear(coin,mainchain,hwmblock,coin->blocks.hwmchain.height-mainchain->height); + tmp = block; + for (i=0; iheight; i++) + { + iguana_bundle_set(coin,tmp,newheight-i); + if ( (tmp= iguana_blockfind("hwmprev",coin,tmp->RO.prev_block)) == 0 ) + break; + iguana_RTnewblock(myinfo,coin,tmp); + } + if ( mainchain != hwmblock ) + iguana_hwmchain_set(coin,mainchain,mainchain->height); // trigger reprocess + } + else if ( coin->RTheight > 0 && newheight == coin->RTheight ) + { + //printf("newheight.%d is RTheight\n",newheight); + } + } //if ( 0 && bits256_nonz(prevhash2) > 0 ) // iguana_patch(coin,block); bp = 0, bundlei = -2; @@ -734,7 +903,7 @@ struct iguana_bundle *iguana_bundleset(struct iguana_info *coin,struct iguana_bl { if ( prevbp->hdrsi+1 == coin->bundlescount && prevbundlei == coin->chain->bundlesize-1 ) { - printf("AUTOCREATE.%d\n",prevbp->bundleheight + coin->chain->bundlesize); + printf("%s AUTOCREATE.%d\n",coin->symbol,prevbp->bundleheight + coin->chain->bundlesize); if ( (bp= iguana_bundlecreate(coin,bundleip,prevbp->bundleheight + coin->chain->bundlesize,hash2,zero,0)) != 0 ) { if ( bp->queued == 0 ) @@ -758,72 +927,92 @@ struct iguana_bundle *iguana_bundleset(struct iguana_info *coin,struct iguana_bl void iguana_checklongestchain(struct iguana_info *coin,struct iguana_bundle *bp,int32_t num) { int32_t i; struct iguana_peer *addr; - if ( num > 3 && num < bp->n ) + if ( coin->RTheight > 0 && num > 30 && num < bp->n ) { if ( coin->longestchain > bp->bundleheight+num+10*coin->chain->minconfirms ) { printf("strange.%d suspicious longestchain.%d vs [%d:%d] %d bp->n %d\n",coin->longestchain_strange,coin->longestchain,bp->hdrsi,num,bp->bundleheight+num,bp->n); - if ( coin->longestchain_strange++ > 10 ) + if ( coin->longestchain_strange++ > 100 ) { coin->badlongestchain = coin->longestchain; coin->longestchain = bp->bundleheight+num; coin->longestchain_strange = 0; - for (i=0; ipeers.numranked; i++) - if ( (addr= coin->peers.ranked[i]) != 0 && addr->height >= coin->badlongestchain ) - { - printf("blacklist addr.(%s) height %d\n",addr->ipaddr,addr->height); - addr->dead = 1; - addr->rank = 0; - } + if ( coin->peers != 0 ) + { + for (i=0; ipeers->numranked; i++) + if ( (addr= coin->peers->ranked[i]) != 0 && addr->height >= coin->badlongestchain ) + { + printf("blacklist addr.(%s) height %d\n",addr->ipaddr,addr->height); + addr->dead = 1; + addr->rank = 0; + } + } } } else if ( coin->longestchain_strange > 0 ) { - //printf("not strange.%d suspicious longestchain.%d vs [%d:%d] %d bp->n %d\n",coin->longestchain_strange,coin->longestchain,bp->hdrsi,num,bp->bundleheight+num,bp->n); + printf("not strange.%d suspicious longestchain.%d vs [%d:%d] %d bp->n %d\n",coin->longestchain_strange,coin->longestchain,bp->hdrsi,num,bp->bundleheight+num,bp->n); coin->longestchain_strange--; } } } -struct iguana_bundlereq *iguana_recvblockhdrs(struct iguana_info *coin,struct iguana_bundlereq *req,struct iguana_block *blocks,int32_t n,int32_t *newhwmp) +struct iguana_bundlereq *iguana_recvblockhdrs(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_bundlereq *req,struct iguana_zblock *zblocks,int32_t n,int32_t *newhwmp) { - int32_t i,bundlei,match; struct iguana_block *block; struct iguana_peer *addr; struct iguana_bundle *bp,*firstbp = 0; - if ( blocks == 0 ) + int32_t i,bundlei,match; struct iguana_block *block; bits256 prevhash2; uint8_t serialized[sizeof(struct iguana_msgblock) + sizeof(struct iguana_msgblockhdr_zcash)]; struct iguana_peer *addr; struct iguana_bundle *bp,*firstbp = 0; + if ( zblocks == 0 ) { printf("iguana_recvblockhdrs null blocks?\n"); return(req); } - if ( blocks != 0 && n > 0 ) + if ( zblocks != 0 && n > 0 ) { + memset(prevhash2.bytes,0,sizeof(prevhash2)); for (i=match=0; iblocks.hwmchain.RO.hash2) == 0 ) { - bp->dirty++; - if ( 0 && bp->issued[bundlei] == 0 && bp->hdrsi < coin->MAXBUNDLES ) - iguana_blockQ("recvhdr",coin,bp,bundlei,blocks[i].RO.hash2,1); - //printf("{%d:%d} ",bp->hdrsi,bundlei); - if ( i == 0 ) + bp = 0, bundlei = -2; + if ( (bp= iguana_bundleset(myinfo,coin,&block,&bundlei,(struct iguana_block *)&zblocks[i])) != 0 ) { - firstbp = bp; - iguana_checklongestchain(coin,bp,n); + if ( block->height >= 0 && block->height+1 > coin->longestchain ) + coin->longestchain = block->height+1; + _iguana_chainlink(myinfo,coin,block); } - if ( bundlei == i+1 && bp == firstbp ) - match++; - else + //char str[65]; printf("HWM in hdr's prev[%d] bp.%p bundlei.%d block.%p %s\n",i,bp,bundlei,block,bp!=0?bits256_str(str,bp->hashes[bundlei]):"()"); + } + if ( i > 0 && bits256_cmp(prevhash2,zblocks[i].RO.prev_block) == 0 ) + { + bp = 0, bundlei = -2; + if ( (bp= iguana_bundleset(myinfo,coin,&block,&bundlei,(struct iguana_block *)&zblocks[i])) != 0 ) { - if ( bp != coin->current && i != n-1 ) - fprintf(stderr,"recvhdr: ht.%d[%d] vs i.%d\n",bp->bundleheight,bundlei,i); + bp->dirty++; + if ( 0 && bp->issued[bundlei] == 0 && bp->hdrsi < coin->MAXBUNDLES ) + iguana_blockQ("recvhdr",coin,bp,bundlei,block->RO.hash2,1); + //printf("{%d:%d} ",bp->hdrsi,bundlei); + if ( i == 0 ) + { + firstbp = bp; + iguana_checklongestchain(coin,bp,n); + } + if ( bundlei == i+1 && bp == firstbp ) + match++; + else + { + if ( 0 && bp != coin->current && i != n-1 ) + fprintf(stderr,"recvhdr: ht.%d[%d] vs i.%d\n",bp->bundleheight,bundlei,i); + } } } + prevhash2 = zblocks[i].RO.hash2; + //printf("%d bp.%p [%d] bundlei.%d %s prev.%s\n",i,bp,bp!=0?bp->hdrsi:-1,bundlei,bits256_str(str,zblocks[i].RO.hash2),bits256_str(str2,zblocks[i].RO.prev_block)); //else if ( bp != firstbp ) // printf("blockhash[%d] cant be found n.%d\n",i,n); } char str[65]; if ( 0 && bp == coin->current ) - printf("i.%d n.%d match.%d blockhdrs.%s hdrsi.%d\n",i,n,match,bits256_str(str,blocks[0].RO.hash2),firstbp!=0?firstbp->hdrsi:-1); + printf("i.%d n.%d match.%d blockhdrs.%s hdrsi.%d\n",i,n,match,bits256_str(str,zblocks[0].RO.hash2),firstbp!=0?firstbp->hdrsi:-1); if ( firstbp != 0 && match == coin->chain->bundlesize-1 && n == firstbp->n ) { if ( firstbp->queued == 0 ) @@ -836,7 +1025,9 @@ struct iguana_bundlereq *iguana_recvblockhdrs(struct iguana_info *coin,struct ig { addr->RThashes[i] = firstbp->hashes[0]; for (i=1; iRThashes[i] = blocks[i].RO.hash2; + { + iguana_serialize_block(coin->chain,&addr->RThashes[i],serialized,(struct iguana_block *)&zblocks[i]); + } //memcpy(addr->RThashes,blockhashes,bp->numspec * sizeof(*addr->RThashes)); addr->numRThashes = n; } @@ -855,7 +1046,7 @@ void iguana_autoextend(struct iguana_info *coin,struct iguana_bundle *bp) { if ( newbp->bundleheight != bp->bundleheight+bp->n ) { - printf("found spurious extra hash for [%d:%d]\n",bp->hdrsi,bp->n); + printf("%d vs %d found spurious extra hash for [%d:%d]\n",newbp->bundleheight,bp->bundleheight,bp->hdrsi,bp->n); memset(&bp->nextbundlehash2,0,sizeof(bp->nextbundlehash2)); return; } @@ -874,14 +1065,27 @@ void iguana_autoextend(struct iguana_info *coin,struct iguana_bundle *bp) struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct iguana_bundlereq *req,bits256 *blockhashes,int32_t num) { - int32_t bundlei,i,starti; struct iguana_bundle *bp; bits256 allhash,zero; struct iguana_peer *addr; struct iguana_block *block; char str[65],str2[65]; // uint8_t serialized[512]; + int32_t bundlei,i,starti; struct iguana_block *block; struct iguana_bundle *bp; bits256 allhash,zero; struct iguana_peer *addr; char str[65],str2[65]; // uint8_t serialized[512]; memset(zero.bytes,0,sizeof(zero)); bp = 0, bundlei = -2; iguana_bundlefind(coin,&bp,&bundlei,blockhashes[1]); - if ( 0 && num >= coin->chain->bundlesize ) + if ( 0 && strcmp("BTCD",coin->symbol) == 0 )//0 && num >= coin->chain->bundlesize ) printf("blockhashes[%d] %d of %d %s bp.%d[%d]\n",num,bp==0?-1:bp->hdrsi,coin->bundlescount,bits256_str(str,blockhashes[1]),bp==0?-1:bp->bundleheight,bundlei); if ( num < 2 ) return(req); + else + { + for (i=1; iheight+1 > coin->longestchain ) + { + coin->longestchain = block->height+1; + if ( bp != 0 && bp->speculative != 0 && i < bp->n ) + bp->speculative[i] = blockhashes[i]; + } + iguana_blockQ("recvhash",coin,0,-1,blockhashes[i],1); + } + } if ( bp != 0 ) { bp->dirty++; @@ -903,7 +1107,17 @@ struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct //printf("done allhashes\n"); } else if ( bp->hdrsi == coin->bundlescount-1 ) + { iguana_checklongestchain(coin,bp,num); + if ( bp->speculative != 0 && bp->numspec < num ) + { + for (i=bp->numspec; ispeculative[i]) == 0 ) + bp->speculative[i] = blockhashes[i]; + } + } + } if ( strcmp("BTC",coin->symbol) != 0 && (bp->speculative == 0 || num > bp->numspec) && bp->emitfinish == 0 ) { //printf("FOUND speculative.%s BLOCKHASHES[%d] ht.%d\n",bits256_str(str,blockhashes[1]),num,bp->bundleheight); @@ -925,7 +1139,7 @@ struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct //printf("speculate new issue [%d:%d]\n",bp->hdrsi,i); } bp->speculative[0] = bp->hashes[0]; - bp->numspec = num <= bp->n+1 ? num : bp->n+1; + bp->numspec = (num <= bp->n+1) ? num : bp->n+1; if ( bp == coin->current && (addr= req->addr) != 0 ) { memcpy(addr->RThashes,blockhashes,bp->numspec * sizeof(*addr->RThashes)); @@ -970,7 +1184,7 @@ struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct //block->blockhashes = blockhashes, req->hashes = 0; //printf("set block->blockhashes[%d]\n",num); } - /*if ( (addr= coin->peers.ranked[0]) != 0 ) + /*if ( (addr= coin->peers->ranked[0]) != 0 ) { if ( (len= iguana_getdata(coin,serialized,MSG_BLOCK,&blockhashes[1],1)) > 0 ) { @@ -996,30 +1210,55 @@ struct iguana_bundlereq *iguana_recvblockhashes(struct iguana_info *coin,struct { iguana_blockQ("recvhash7",coin,0,-7,blockhashes[1],1); iguana_blockQ("recvhash7",coin,0,-7,blockhashes[num-1],1); + //if ( 1 && coin->RTheight > 0 ) + { + for (i=1; isymbol) == 0 ) + printf("%s received.(%s) %s\n",coin->symbol,bits256_str(str,origblock->RO.hash2),addr->ipaddr); + if ( (block= iguana_blockfind("recv",coin,origblock->RO.hash2)) != 0 ) + iguana_blockcopy(coin->chain->zcash,coin->chain->auxpow,coin,block,(struct iguana_block *)origblock); + else if ( (block= iguana_blockhashset("recvblock",coin,-1,origblock->RO.hash2,1)) == 0 ) + { + printf("error adding %s\n",bits256_str(str,origblock->RO.hash2)); + return(req); + } if ( bits256_nonz(origblock->RO.prev_block) != 0 ) - iguana_blockQ("prev",coin,0,-1,origblock->RO.prev_block,1); - if ( (bp= iguana_bundleset(coin,&block,&bundlei,origblock)) != 0 && bp == coin->current && block != 0 && bp->speculative != 0 && bundlei >= 0 ) + { + if ( (prevblock= iguana_blockfind("prev",coin,origblock->RO.prev_block)) != 0 && prevblock->height+1 > coin->longestchain ) + coin->longestchain = prevblock->height+1; + else iguana_blockQ("prev",coin,0,-1,origblock->RO.prev_block,1); + } + if ( (bp= iguana_bundleset(myinfo,coin,&block,&bundlei,(struct iguana_block *)origblock)) != 0 && bp == coin->current && block != 0 && bp->speculative != 0 && bundlei >= 0 ) { if ( bp->speculative != 0 && bp->numspec <= bundlei ) { bp->speculative[bundlei] = block->RO.hash2; bp->numspec = bundlei+1; } - while ( bundlei < bp->n && block != 0 && bp->bundleheight+bundlei == coin->blocks.hwmchain.height+1 && _iguana_chainlink(coin,block) != 0 ) + while ( bundlei < bp->n && block != 0 && bp->bundleheight+bundlei == coin->blocks.hwmchain.height+1 && _iguana_chainlink(myinfo,coin,block) != 0 ) { //printf("MAIN.%d ",bp->bundleheight+bundlei); bundlei++; block = iguana_bundleblock(coin,&hash2,bp,bundlei); } //printf("autoadd [%d:%d]\n",bp->hdrsi,bundlei); - } + } // else printf("couldnt find.(%s)\n",bits256_str(str,block->RO.hash2)); if ( bp != 0 ) { bp->dirty++; @@ -1031,6 +1270,23 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana } } } + else if ( req->copyflag != 0 ) + { + if ( bp == 0 && (block == 0 || block->queued == 0) ) + { + //fprintf(stderr,"req.%p copyflag.%d data %d %d\n",req,req->copyflag,req->recvlen,recvlen); + coin->numcached++; + if ( block != 0 ) + block->queued = 1; + queue_enqueue("cacheQ",&coin->cacheQ,&req->DL,0); + return(0); + } + else if ( block != 0 && block->req == 0 ) + { + block->req = req; + req = 0; + } //else printf("already have cache entry.(%s)\n",bits256_str(str,origblock->RO.hash2)); + } if ( block != 0 )//&& bp != 0 && bp->hdrsi == coin->bundlescount-1 ) { int32_t i,numsaved = 0; struct iguana_block *tmpblock; static int32_t numrecv; @@ -1041,17 +1297,17 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana if ( (tmpblock= bp->blocks[i]) != 0 && tmpblock->fpipbits != 0 && tmpblock->fpos >= 0 && ((bp->hdrsi == 0 && i == 0) || bits256_nonz(tmpblock->RO.prev_block) != 0) ) numsaved++; } - //fprintf(stderr,"%s [%d:%d] block.%x | s.%d r.%d copy.%d mainchain.%d\n",bits256_str(str,origblock->RO.hash2),bp!=0?bp->hdrsi:-1,bundlei,block!=0?block->fpipbits:0,numsaved,numrecv,req->copyflag,block->mainchain); - if ( _iguana_chainlink(coin,block) == 0 ) + // fprintf(stderr,"%s [%d:%d] block.%x | s.%d r.%d copy.%d mainchain.%d\n",bits256_str(str,origblock->RO.hash2),bp!=0?bp->hdrsi:-1,bundlei,block!=0?block->fpipbits:0,numsaved,numrecv,req!=0?req->copyflag:-1,block->mainchain); + if ( _iguana_chainlink(myinfo,coin,block) == 0 ) { next = block; - for (i=n=0; ichain->bundlesize && n == 0; i++) + for (i=n=0; ichain->bundlesize && n < 60; i++) { if ( (block= iguana_blockfind("recvblock",coin,block->RO.prev_block)) == 0 ) break; - if ( block->mainchain != 0 || _iguana_chainlink(coin,block) != 0 ) + if ( block->mainchain != 0 || _iguana_chainlink(myinfo,coin,block) != 0 ) { - _iguana_chainlink(coin,next); + _iguana_chainlink(myinfo,coin,next); n++; break; } @@ -1066,26 +1322,10 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana } if ( (block= iguana_blockhashset("recvblock",coin,-1,origblock->RO.hash2,1)) != 0 ) { - if ( block != origblock ) - iguana_blockcopy(coin,block,origblock); + if ( block != (struct iguana_block *)origblock ) + iguana_blockcopy(coin->chain->zcash,coin->chain->auxpow,coin,block,(struct iguana_block *)origblock); if ( block->lag != 0 && block->issued != 0 ) block->lag = (uint32_t)time(NULL) - block->issued; - if ( req->copyflag != 0 ) - { - if ( block->queued == 0 && bp != 0 ) - { - char str[65]; fprintf(stderr,"req.%p %s copyflag.%d %d data %d %d\n",req,bits256_str(str,block->RO.hash2),req->copyflag,block->height,req->recvlen,recvlen); - coin->numcached++; - block->queued = 1; - queue_enqueue("cacheQ",&coin->cacheQ,&req->DL,0); - return(0); - } - else if ( block->req == 0 ) - { - block->req = req; - req = 0; - } //else printf("already have cache entry.(%s)\n",bits256_str(str,origblock->RO.hash2)); - } //printf("datalen.%d ipbits.%x\n",datalen,req->ipbits); } else printf("cant create origblock.%p block.%p bp.%p bundlei.%d\n",origblock,block,bp,bundlei); return(req); @@ -1093,9 +1333,12 @@ struct iguana_bundlereq *iguana_recvblock(struct iguana_info *coin,struct iguana struct iguana_bundlereq *iguana_recvtxids(struct iguana_info *coin,struct iguana_bundlereq *req,bits256 *txids,int32_t n) { - char str[65]; + int32_t i; if ( n > 0 ) - printf("got txids[%d] %s\n",n,bits256_str(str,txids[0])); + { + for (i=0; iaddr); + } return(req); } @@ -1126,21 +1369,40 @@ int32_t iguana_blockreq(struct iguana_info *coin,int32_t height,int32_t priority return(-1); } -int32_t iguana_reqblocks(struct iguana_info *coin) +int32_t iguana_reqblocks(struct supernet_info *myinfo,struct iguana_info *coin) { - int32_t hdrsi,hdrsi0,bundlei0,lflag,bundlei,iters=0,flag = 0; bits256 hash2; struct iguana_block *next,*block; struct iguana_bundle *bp; + int32_t hdrsi,lflag,bundlei,iters=0,flag = 0; bits256 hash2; struct iguana_block *next,*block; struct iguana_bundle *bp; + if ( (block= iguana_blockfind("hwmcheck",coin,coin->blocks.hwmchain.RO.hash2)) == 0 || block->mainchain == 0 || block->height != coin->blocks.hwmchain.height ) + { + printf("HWM mismatch ht.%d vs %d or not mainchain.%d\n",block->height,coin->blocks.hwmchain.height,block->mainchain); + if ( coin->blocks.hwmchain.height > 0 ) + { + if ( (block= iguana_blockfind("hwmcheckb",coin,coin->blocks.hwmchain.RO.prev_block)) != 0 ) + { + printf("decrement HWM\n"); + iguana_blockzcopy(coin->chain->zcash,(struct iguana_block *)&coin->blocks.hwmchain,block); + return(0); + } + } + } if ( time(NULL) < coin->lastreqtime+2 ) return(0); coin->lastreqtime = (uint32_t)time(NULL); //printf("reqblocks %u\n",coin->lastreqtime); - hdrsi = (coin->blocks.hwmchain.height+1) / coin->chain->bundlesize; + hdrsi = (coin->blocks.hwmchain.height + 1) / coin->chain->bundlesize; if ( (bp= coin->bundles[hdrsi]) != 0 ) { + /*for (bundlei=0; bundleichain->bundlesize; bundlei++) + if ( (block= bp->blocks[bundlei]) != 0 && bits256_cmp(block->RO.hash2,bp->hashes[bundlei]) != 0 && bits256_nonz(bp->hashes[bundlei]) != 0 ) + { + char str[65]; printf("%s [%d] bundlei.%d ht.%d vs expected %d\n",bits256_str(str,bp->hashes[bundlei]),hdrsi,bundlei,block->height,bp->bundleheight+bundlei); + bp->blocks[bundlei] = iguana_blockfind("fixit",coin,bp->hashes[bundlei]); + }*/ bundlei = (coin->blocks.hwmchain.height+1) % coin->chain->bundlesize; if ( (next= bp->blocks[bundlei]) != 0 || (next= iguana_blockfind("reqblocks",coin,bp->hashes[bundlei])) != 0 ) { if ( bits256_nonz(next->RO.prev_block) > 0 ) - _iguana_chainlink(coin,next); + _iguana_chainlink(myinfo,coin,next); else if ( next->queued == 0 && next->fpipbits == 0 && (rand() % 100) == 0 ) { //printf("HWM next %d\n",coin->blocks.hwmchain.height+1); @@ -1157,6 +1419,7 @@ int32_t iguana_reqblocks(struct iguana_info *coin) bundlei = (coin->blocks.hwmchain.height+1) % coin->chain->bundlesize; if ( 1 ) { + int32_t hdrsi0,bundlei0; if ( (next= iguana_bundleblock(coin,&hash2,coin->bundles[hdrsi],bundlei)) == 0 ) { hdrsi0 = (coin->blocks.hwmchain.height) / coin->chain->bundlesize; @@ -1180,12 +1443,13 @@ int32_t iguana_reqblocks(struct iguana_info *coin) next = 0; } } - if ( next != 0 ) + if ( next != 0 )//&& time(NULL) > coin->nextchecked+10 ) { //printf("have next %d\n",coin->blocks.hwmchain.height); if ( memcmp(next->RO.prev_block.bytes,coin->blocks.hwmchain.RO.hash2.bytes,sizeof(bits256)) == 0 ) { - if ( _iguana_chainlink(coin,next) != 0 ) + coin->nextchecked = (uint32_t)time(NULL); + if ( _iguana_chainlink(myinfo,coin,next) != 0 ) lflag++, flag++; //else printf("chainlink error for %d\n",coin->blocks.hwmchain.height+1); } @@ -1222,7 +1486,7 @@ int32_t iguana_reqblocks(struct iguana_info *coin) if ( (block= iguana_blockfind("reqblocks",coin,hash2)) != 0 && bits256_cmp(block->RO.prev_block,coin->blocks.hwmchain.RO.hash2) == 0 ) { //printf("speculative is next at %d\n",coin->backstop); - if ( _iguana_chainlink(coin,block) != 0 ) + if ( _iguana_chainlink(myinfo,coin,block) != 0 ) lflag++, flag++;//, printf("NEWHWM.%d\n",coin->backstop); } } @@ -1261,26 +1525,26 @@ int32_t iguana_reqblocks(struct iguana_info *coin) return(flag); } -int32_t iguana_processrecvQ(struct iguana_info *coin,int32_t *newhwmp) // single threaded +int32_t iguana_processrecvQ(struct supernet_info *myinfo,struct iguana_info *coin,int32_t *newhwmp) // single threaded { int32_t flag = 0; struct iguana_bundlereq *req; *newhwmp = 0; while ( flag < IGUANA_MAXITERATIONS && coin->active != 0 && (req= queue_dequeue(&coin->recvQ,0)) != 0 ) { flag++; - //fprintf(stderr,"flag.%d %s recvQ.%p type.%c n.%d\n",flag,req->addr != 0 ? req->addr->ipaddr : "0",req,req->type,req->n); + //fprintf(stderr,"%s flag.%d %s recvQ.%p type.%c n.%d\n",coin->symbol,flag,req->addr != 0 ? req->addr->ipaddr : "0",req,req->type,req->n); if ( req->type == 'B' ) // one block with all txdata { netBLOCKS--; - req = iguana_recvblock(coin,req->addr,req,&req->block,req->numtx,req->datalen,req->recvlen,newhwmp); + req = iguana_recvblock(myinfo,coin,req->addr,req,&req->zblock,req->numtx,req->datalen,req->recvlen,newhwmp); } else if ( req->type == 'H' ) // blockhdrs (doesnt have txn_count!) { HDRnet--; - if ( (req= iguana_recvblockhdrs(coin,req,req->blocks,req->n,newhwmp)) != 0 ) + if ( (req= iguana_recvblockhdrs(myinfo,coin,req,req->blocks,req->n,newhwmp)) != 0 ) { if ( req->blocks != 0 ) - myfree(req->blocks,sizeof(*req->blocks) * req->n), req->blocks = 0; + myfree(req->blocks,sizeof(struct iguana_zblock) * req->n), req->blocks = 0; } } else if ( req->type == 'S' ) // blockhashes @@ -1289,12 +1553,17 @@ int32_t iguana_processrecvQ(struct iguana_info *coin,int32_t *newhwmp) // single myfree(req->hashes,sizeof(*req->hashes) * req->n), req->hashes = 0; } else if ( req->type == 'U' ) // unconfirmed tx - req = iguana_recvunconfirmed(coin,req,req->serialized,req->datalen); + req = iguana_recvunconfirmed(coin,req,req->serializeddata,req->datalen); else if ( req->type == 'T' ) // txids from inv { if ( (req= iguana_recvtxids(coin,req,req->hashes,req->n)) != 0 ) myfree(req->hashes,(req->n+1) * sizeof(*req->hashes)), req->hashes = 0; } + /*else if ( req->type == 'Q' ) // quotes from inv + { + if ( (req= instantdex_recvquotes(coin,req,req->hashes,req->n)) != 0 ) + myfree(req->hashes,(req->n+1) * sizeof(*req->hashes)), req->hashes = 0; + }*/ else printf("iguana_updatebundles unknown type.%c\n",req->type);//, getchar(); //fprintf(stderr,"finished coin->recvQ\n"); if ( req != 0 ) @@ -1313,17 +1582,17 @@ int32_t iguana_needhdrs(struct iguana_info *coin) int32_t iguana_reqhdrs(struct iguana_info *coin) { int32_t i,lag,n = 0; struct iguana_bundle *bp; char hashstr[65]; - if ( queue_size(&coin->hdrsQ) == 0 ) + //if ( queue_size(&coin->hdrsQ) == 0 ) { if ( coin->active != 0 ) { for (i=0; ibundlescount; i++) { - if ( (bp= coin->bundles[i]) != 0 && (bp == coin->current || bp->hdrsi == coin->longestchain/coin->chain->bundlesize || i == coin->bundlescount-1 || (bp->numhashes < bp->n && bp->speculative == 0)) ) + if ( (bp= coin->bundles[i]) != 0 && (bp == coin->current || bp->hdrsi == coin->blocks.hwmchain.height/coin->chain->bundlesize || i == coin->bundlescount-1 || bp->numhashes < bp->n) ) { if ( bp == coin->current ) - lag = 7; - else lag = 13; + lag = 13; + else lag = 17; if ( time(NULL) > bp->issuetime+lag ) { if ( 0 && bp == coin->current ) @@ -1332,6 +1601,16 @@ int32_t iguana_reqhdrs(struct iguana_info *coin) coin->numpendings++; init_hexbytes_noT(hashstr,bp->hashes[0].bytes,sizeof(bits256)); queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr),1); + if ( bp == coin->current && coin->blocks.hwmchain.height > 100 ) + { + init_hexbytes_noT(hashstr,bp->hashes[0].bytes,sizeof(bits256)); + queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr),1); + //printf("%s issue HWM HDRS [%d] %s\n",coin->symbol,bp->hdrsi,hashstr); + bits256 hash2 = iguana_blockhash(coin,coin->blocks.hwmchain.height-10); + init_hexbytes_noT(hashstr,hash2.bytes,sizeof(bits256)); + //printf("%s issue HWM HDRS %d-10 %s\n",coin->symbol,coin->blocks.hwmchain.height,hashstr); + queue_enqueue("hdrsQ",&coin->hdrsQ,queueitem(hashstr),1); + } //printf("hdrsi.%d reqHDR.(%s) numhashes.%d\n",bp->hdrsi,hashstr,bp->numhashes); if ( 1 ) { @@ -1357,7 +1636,7 @@ int32_t iguana_blockQ(char *argstr,struct iguana_info *coin,struct iguana_bundle queue_t *Q; char *str; uint32_t now; int32_t n,height = -1; struct iguana_blockreq *req,*ptr; struct iguana_block *block = 0; if ( bits256_nonz(hash2) == 0 ) { - printf("%s.cant queue zerohash bundlei.%d\n",argstr,bundlei); + //printf("%s.cant queue zerohash bundlei.%d\n",argstr,bundlei); //getchar(); return(-1); } @@ -1425,14 +1704,14 @@ int32_t iguana_blockQ(char *argstr,struct iguana_info *coin,struct iguana_bundle height = bp->bundleheight + bundlei; bp->issued[bundlei] = 1; } - req->height = height; - req->bundlei = bundlei; + req->height = -1; //height; + req->bundlei = -1; //bundlei; char str2[65]; - //printf("%s %s %s [%d:%d] %d %s %d numranked.%d qsize.%d\n",coin->symbol,argstr,str,bp!=0?bp->hdrsi:-1,bundlei,req->height,bits256_str(str2,hash2),coin->blocks.recvblocks,coin->peers.numranked,queue_size(Q)); + //printf("%s %s %s [%d:%d] %d %s %d numranked.%d qsize.%d\n",coin->symbol,argstr,str,bp!=0?bp->hdrsi:-1,bundlei,req->height,bits256_str(str2,hash2),coin->blocks.recvblocks,coin->peers->numranked,queue_size(Q)); if ( (n= queue_size(Q)) > 100000 ) { if ( 1 && n > 200000 ) - printf("%s %s %s [%d:%d] %d %s %d numranked.%d qsize.%d\n",coin->symbol,argstr,str,bp!=0?bp->hdrsi:-1,bundlei,req->height,bits256_str(str2,hash2),coin->blocks.recvblocks,coin->peers.numranked,queue_size(Q)); + printf("%s %s %s [%d:%d] %d %s %d numranked.%d qsize.%d\n",coin->symbol,argstr,str,bp!=0?bp->hdrsi:-1,bundlei,req->height,bits256_str(str2,hash2),coin->blocks.recvblocks,coin->peers != 0 ? coin->peers->numranked : -1,queue_size(Q)); while ( (ptr= queue_dequeue(Q,0)) != 0 ) myfree(ptr,sizeof(*ptr)); coin->backlog = n*10 + 1000000; @@ -1512,14 +1791,18 @@ int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) return(0); } priority = 1; + pend = 0; req = queue_dequeue(&coin->priorityQ,0); if ( flag == 0 && req == 0 && addr->pendblocks < limit ) { priority = 0; - for (i=m=pend=0; ipeers.numranked; i++) + if ( coin->peers != 0 ) { - if ( (ptr= coin->peers.ranked[i]) != 0 && ptr->msgcounts.verack > 0 ) - pend += ptr->pendblocks, m++; + for (i=m=pend=0; ipeers->numranked; i++) + { + if ( (ptr= coin->peers->ranked[i]) != 0 && ptr->msgcounts.verack > 0 ) + pend += ptr->pendblocks, m++; + } } if ( pend < coin->MAXPENDINGREQUESTS*m ) req = queue_dequeue(&coin->blocksQ,0); @@ -1554,48 +1837,46 @@ int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr) return(flag); } -int32_t iguana_processrecv(struct iguana_info *coin) // single threaded +int32_t iguana_processrecv(struct supernet_info *myinfo,struct iguana_info *coin) // single threaded { - int32_t i,newhwm = 0,hwmheight,flag = 0; char str[2000]; + int32_t newhwm = 0,hwmheight,flag = 0; char str[2000]; hwmheight = coin->blocks.hwmchain.height; coin->RTramchain_busy = 1; if ( coin->balanceflush != 0 ) { - if ( iguana_balanceflush(coin,coin->balanceflush) > 0 ) + fprintf(stderr,"%s call balanceflush\n",coin->symbol); + //portable_mutex_lock(&coin->RTmutex); + coin->disableUTXO = 1; + //iguana_utxoupdate(coin,-1,0,0,0,0,-1,0); // free hashtables + if ( iguana_balanceflush(myinfo,coin,coin->balanceflush) > 0 ) printf("balanceswritten.%d flushed coin->balanceflush %d vs %d coin->longestchain/coin->chain->bundlesize\n",coin->balanceswritten,coin->balanceflush,coin->longestchain/coin->chain->bundlesize); + //portable_mutex_unlock(&coin->RTmutex); + coin->disableUTXO = 0; + fprintf(stderr,"%s back balanceflush\n",coin->symbol); coin->balanceflush = 0; + //iguana_utxoaddr_gen(myinfo,coin,(coin->balanceswritten - 1) * coin->chain->bundlesize); } - //printf("recvQ\n"); - flag += iguana_processrecvQ(coin,&newhwm); - //printf("reqhdrs\n"); - flag += iguana_reqhdrs(coin); - if ( coin->spendvectorsaved > 1 ) + if ( (rand() % 10) == 0 ) { - if ( time(NULL) > coin->laststats+5 ) + if ( coin->utxoaddrtable != 0 && coin->RTheight > 0 && coin->RTheight <= coin->blocks.hwmchain.height ) { - //printf("reqblocks\n"); - flag += iguana_reqblocks(coin); - //printf("bundlestats\n"); - iguana_bundlestats(coin,str,IGUANA_DEFAULTLAG); - coin->laststats = (uint32_t)time(NULL); + struct iguana_block *block; + if ( (block= iguana_blockfind("utxogen",coin,coin->blocks.hwmchain.RO.hash2)) != 0 ) + iguana_RTnewblock(myinfo,coin,block); } } - else - { - flag += iguana_reqblocks(coin); - iguana_bundlestats(coin,str,IGUANA_DEFAULTLAG); - } - if ( time(NULL) > coin->spendvectorsaved ) + flag += iguana_processrecvQ(myinfo,coin,&newhwm); + if ( coin->RTheight == 0 || (rand() % 30) == 0 ) + flag += iguana_reqblocks(myinfo,coin); + if ( time(NULL) > coin->laststats+30 ) { - for (i=0; ichain->bundlesize; i++) - { - if ( coin->RTdatabad != 0 || iguana_realtime_update(coin) <= 0 ) - break; - } + flag += iguana_reqhdrs(coin); + iguana_bundlestats(myinfo,coin,str,IGUANA_DEFAULTLAG); + coin->laststats = (uint32_t)time(NULL); } - coin->RTramchain_busy = 0;//(coin->RTgenesis == 0); - flag += iguana_process_msgrequestQ(coin); - iguana_jsonQ(); + //iguana_realtime_update(myinfo,coin); + coin->RTramchain_busy = 0; + flag += iguana_process_msgrequestQ(myinfo,coin); if ( hwmheight != coin->blocks.hwmchain.height ) flag = 1; return(flag); diff --git a/iguana/iguana_rpc.c b/iguana/iguana_rpc.c index e4dc0bfc7..32dd36668 100755 --- a/iguana/iguana_rpc.c +++ b/iguana/iguana_rpc.c @@ -14,7 +14,7 @@ ******************************************************************************/ #include "iguana777.h" -#include "SuperNET.h" +//#include "SuperNET.h" #define RPCARGS struct supernet_info *myinfo,uint16_t port,struct iguana_info *coin,cJSON *params[],int32_t n,cJSON *json,char *remoteaddr,cJSON *array #define GLUEARGS cJSON *json,struct supernet_info *myinfo,uint16_t port,struct iguana_info *coin,char *remoteaddr,cJSON *params[] @@ -23,13 +23,15 @@ char *sglue(GLUEARGS,char *agent,char *method) { - char *retstr,*rpcretstr,*walletstr; cJSON *retjson,*tmpjson,*result,*error,*wallet; int32_t i,j,len; + char *retstr,*rpcretstr,*walletstr,checkstr[64],dcheckstr[64]; cJSON *retjson,*tmpjson,*result,*error,*wallet; int32_t i,j,len; int64_t val; double dval; if ( json == 0 ) json = cJSON_CreateObject(); //printf("sglue.(%s)\n",jprint(json,0)); jaddstr(json,"agent",agent); jaddstr(json,"method",method); jaddstr(json,"coin",coin->symbol); + if ( myinfo->expiration != 0 && time(NULL) > myinfo->expiration ) + iguana_walletlock(myinfo,0); if ( (retstr= SuperNET_JSON(myinfo,json,remoteaddr,port)) != 0 ) { if ( (retjson= cJSON_Parse(retstr)) != 0 ) @@ -73,11 +75,25 @@ char *sglue(GLUEARGS,char *agent,char *method) { for (i=1,j=0; itype&0xff) != cJSON_NULL || (result->type&0xff) != cJSON_NULL ) @@ -253,6 +269,11 @@ static char *getblockcount(RPCARGS) return(sglue(0,CALLGLUE,"bitcoinrpc","getblockcount")); } +static char *getdifficulty(RPCARGS) +{ + return(sglue(0,CALLGLUE,"bitcoinrpc","getdifficulty")); +} + static char *getblock(RPCARGS) { cJSON *obj; @@ -368,7 +389,7 @@ static char *dumpprivkey(RPCARGS) static char *importprivkey(RPCARGS) { - return(sglue1(0,CALLGLUE,"bitcoinrpc","importprivkey","wif",params[0])); + return(sglue3(0,CALLGLUE,"bitcoinrpc","importprivkey","wif",params[0],"account",params[1],"rescan",params[2])); } static char *dumpwallet(RPCARGS) @@ -383,12 +404,18 @@ static char *importwallet(RPCARGS) static char *walletpassphrase(RPCARGS) { + /*cJSON *a,*b,*c; + a = jduplicate(params[0]); + b = jduplicate(params[2]); + c = jduplicate(params[1]); + sglue3(0,CALLGLUE,"bitcoinrpc","walletpassphrase","password",a,"permanentfile",b,"timeout",c); + */ return(sglue3(0,CALLGLUE,"bitcoinrpc","walletpassphrase","password",params[0],"permanentfile",params[2],"timeout",params[1])); } static char *walletpassphrasechange(RPCARGS) { - return(sglue4(0,CALLGLUE,"bitcoinrpc","walletpassphrasechange","oldpassphrase",params[0],"newpassphrase",params[1],"oldpermanentfile",params[2],"oldpermanentfile",params[3])); +return(sglue4(0,CALLGLUE,"bitcoinrpc","walletpassphrasechange","oldpassphrase",params[0],"newpassphrase",params[1],"oldpermanentfile",params[2],"oldpermanentfile",params[3])); } static char *walletlock(RPCARGS) @@ -492,7 +519,12 @@ static char *createrawtransaction(RPCARGS) static char *decoderawtransaction(RPCARGS) { - return(sglue1(0,CALLGLUE,"bitcoinrpc","decoderawtransaction","rawtx",params[0])); + return(sglue2(0,CALLGLUE,"bitcoinrpc","decoderawtransaction","rawtx",params[0],"suppress",params[1])); +} + +static char *validaterawtransaction(RPCARGS) +{ + return(sglue2(0,CALLGLUE,"bitcoinrpc","validaterawtransaction","rawtx",params[0],"suppress",params[1])); } static char *decodescript(RPCARGS) @@ -530,6 +562,7 @@ struct RPC_info { char *name; char *(*rpcfunc)(RPCARGS); int32_t flag0,remotefla { "stop", &stop, true, true }, { "getbestblockhash", &getbestblockhash, true, true }, { "getblockcount", &getblockcount, true, true }, + { "getdifficulty", &getdifficulty, true, true }, { "getconnectioncount", &getconnectioncount, true, true }, { "getpeerinfo", &getpeerinfo, true, true }, { "getinfo", &getinfo, true, true }, @@ -570,6 +603,7 @@ struct RPC_info { char *name; char *(*rpcfunc)(RPCARGS); int32_t flag0,remotefla { "importprivkey", &importprivkey, false, false }, { "getrawtransaction", &getrawtransaction, false, false }, { "createrawtransaction", &createrawtransaction, false, false }, + { "validaterawtransaction", &validaterawtransaction, false, true }, { "decoderawtransaction", &decoderawtransaction, false, true }, { "decodescript", &decodescript, false, true }, { "signrawtransaction", &signrawtransaction, false, false }, @@ -638,9 +672,10 @@ char *iguana_bitcoinrpc(struct supernet_info *myinfo,uint16_t port,struct iguana char *iguana_bitcoinRPC(struct supernet_info *myinfo,char *method,cJSON *json,char *remoteaddr,uint16_t port) { - cJSON *params[16],*array; struct iguana_info *coin = 0; char symbol[16]; int32_t i,c,n; char *retstr = 0; + cJSON *params[16],*array; struct iguana_info *tmp,*coin = 0; char symbol[16]; int32_t i,c,n; char *retstr = 0; symbol[0] = 0; memset(params,0,sizeof(params)); + //printf("bitcoinRPC\n"); if ( json != 0 ) { if ( port == myinfo->rpcport ) @@ -654,26 +689,36 @@ char *iguana_bitcoinRPC(struct supernet_info *myinfo,char *method,cJSON *json,ch sprintf(symbol,"%c%c%c%c",c,'T',c+1,c+2); } } - else safecopy(symbol,jstr(json,"coin"),sizeof(symbol)); + else + { + safecopy(symbol,jstr(json,"coin"),sizeof(symbol)); + for (i=0; symbol[i]!=0; i++) + symbol[i] = toupper((int32_t)symbol[i]); + } if ( myinfo->rpcsymbol[0] == 0 ) strcpy(myinfo->rpcsymbol,symbol); } else { - for (i=0; ichain->rpcport == port ) + //portable_mutex_lock(&myinfo->allcoins_mutex); + HASH_ITER(hh,myinfo->allcoins,coin,tmp) + { + if ( coin->chain->rpcport == port ) break; - if ( i == IGUANA_MAXCOINS ) - coin = 0; + else coin = 0; + } + //portable_mutex_unlock(&myinfo->allcoins_mutex); } if ( coin == 0 && symbol[0] != 0 ) coin = iguana_coinfind(symbol); + if ( coin != 0 ) + safecopy(symbol,coin->symbol,sizeof(symbol)); //printf("method.(%s) (%s) remote.(%s) symbol.(%s)\n",method,jprint(json,0),remoteaddr,symbol); if ( method != 0 && symbol[0] != 0 && (coin != 0 || (coin= iguana_coinfind(symbol)) != 0) ) { if ( (array= jarray(&n,json,"params")) == 0 ) { - i= 0, n = 0; + i = 0, n = 0; } else if ( n > 0 ) { @@ -772,7 +817,7 @@ cJSON *SuperNET_urlconv(char *value,int32_t bufsize,char *urlstr) { data = &urlstr[totallen - datalen]; data[-1] = 0; - printf("post.(%s) (%c)\n",data,data[0]); + //printf("post.(%s) (%c)\n",data,data[0]); jaddstr(json,"POST",data); } } else break; @@ -784,8 +829,8 @@ cJSON *SuperNET_urlconv(char *value,int32_t bufsize,char *urlstr) char *SuperNET_rpcparse(struct supernet_info *myinfo,char *retbuf,int32_t bufsize,int32_t *jsonflagp,int32_t *postflagp,char *urlstr,char *remoteaddr,char *filetype,uint16_t port) { - cJSON *tokens,*argjson,*json = 0; long filesize; - char symbol[16],buf[4096],urlmethod[16],*data,url[1024],*retstr,*filestr,*token = 0; int32_t i,j,n,num=0; + cJSON *tokens,*argjson,*origargjson,*json = 0; long filesize; + char symbol[16],buf[4096],urlmethod[16],*data,url[1024],furl[1024],*retstr,*filestr,*token = 0; int32_t i,j,n,num=0; //printf("rpcparse.(%s)\n",urlstr); for (i=0; i0; i--) @@ -970,15 +1020,26 @@ char *SuperNET_rpcparse(struct supernet_info *myinfo,char *retbuf,int32_t bufsiz } } } - //printf("after urlconv.(%s) argjson.(%s)\n",jprint(json,0),jprint(argjson,0)); - if ( jstr(argjson,"method") == 0 ) + if ( is_cJSON_Array(argjson) != 0 && (n= cJSON_GetArraySize(argjson)) > 0 ) { - free_json(argjson); - return(0); + cJSON *retitem,*retarray = cJSON_CreateArray(); + origargjson = argjson; + for (i=0; i (%s) postflag.%d (%s)\n",urlstr,jprint(argjson,0),cJSON_Print(json),*postflagp,retstr); + } + free_json(origargjson); + retstr = jprint(retarray,1); } - retstr = SuperNET_JSON(myinfo,argjson,remoteaddr,port); - //printf("(%s) {%s} -> (%s) postflag.%d (%s)\n",urlstr,jprint(argjson,0),cJSON_Print(json),*postflagp,retstr); - free_json(argjson); + else retstr = SuperNET_JSON(myinfo,argjson,remoteaddr,port); return(retstr); } *jsonflagp = 1; @@ -1020,6 +1081,8 @@ void iguana_rpcloop(void *args) jsonbuf = calloc(1,IGUANA_MAXPACKETSIZE); while ( (bindsock= iguana_socket(1,"127.0.0.1",port)) < 0 ) { + //if ( coin->MAXPEERS == 1 ) + // break; //exit(-1); sleep(3); } @@ -1117,13 +1180,15 @@ void iguana_rpcloop(void *args) if ( retstr != 0 ) { char *response,hdrs[1024]; + //printf("RETURN.(%s)\n",retstr); if ( jsonflag != 0 || postflag != 0 ) { - response = malloc(strlen(retstr)+1024+1); + response = malloc(strlen(retstr)+1024+1+1); sprintf(hdrs,"HTTP/1.1 200 OK\r\nAccess-Control-Allow-Origin: *\r\nAccess-Control-Allow-Credentials: true\r\nAccess-Control-Allow-Methods: GET, POST\r\nCache-Control : no-cache, no-store, must-revalidate\r\n%sContent-Length : %8d\r\n\r\n",content_type,(int32_t)strlen(retstr)); response[0] = '\0'; strcat(response,hdrs); strcat(response,retstr); + strcat(response,"\n"); if ( retstr != space ) free(retstr); retstr = response; diff --git a/iguana/iguana_scripts.c b/iguana/iguana_scripts.c index a816322ed..1e6ad9a67 100755 --- a/iguana/iguana_scripts.c +++ b/iguana/iguana_scripts.c @@ -42,6 +42,7 @@ int32_t bitcoin_revealsecret160(uint8_t *script,int32_t n,uint8_t secret160[20]) return(n); } +// OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG int32_t bitcoin_standardspend(uint8_t *script,int32_t n,uint8_t rmd160[20]) { script[n++] = SCRIPT_OP_DUP; @@ -54,7 +55,11 @@ int32_t bitcoin_standardspend(uint8_t *script,int32_t n,uint8_t rmd160[20]) int32_t bitcoin_checklocktimeverify(uint8_t *script,int32_t n,uint32_t locktime) { - script[n++] = (locktime >> 24), script[n++] = (locktime >> 16), script[n++] = (locktime >> 8), script[n++] = locktime; + script[n++] = 4; + script[n++] = locktime & 0xff, locktime >>= 8; + script[n++] = locktime & 0xff, locktime >>= 8; + script[n++] = locktime & 0xff, locktime >>= 8; + script[n++] = locktime & 0xff; script[n++] = SCRIPT_OP_CHECKLOCKTIMEVERIFY; script[n++] = SCRIPT_OP_DROP; return(n); @@ -444,11 +449,12 @@ int32_t iguana_calcrmd160(struct iguana_info *coin,char *asmstr,struct vin_info //error memalloc mem.0x7f6fc6e4a2a8 94.242.229.158 alloc 1 used 2162688 totalsize.2162688 -> 94.242.229.158 (nil) -int32_t bitcoin_scriptget(struct iguana_info *coin,int32_t *hashtypep,uint32_t *sigsizep,uint32_t *pubkeysizep,uint32_t *suffixp,struct vin_info *vp,uint8_t *scriptsig,int32_t len,int32_t spendtype) +int32_t bitcoin_scriptget(struct iguana_info *coin,int32_t *hashtypep,uint32_t *sigsizep,uint32_t *pubkeysizep,uint8_t **userdatap,uint32_t *userdatalenp,struct vin_info *vp,uint8_t *scriptsig,int32_t len,int32_t spendtype) { - char asmstr[IGUANA_MAXSCRIPTSIZE*3]; int32_t j,n,siglen,plen; + char asmstr[IGUANA_MAXSCRIPTSIZE*3]; int32_t j,n,siglen,plen; uint8_t *p2shscript; j = n = 0; - *suffixp = *pubkeysizep = 0; + *userdatap = 0; + *userdatalenp = *pubkeysizep = 0; *hashtypep = SIGHASH_ALL; while ( (siglen= scriptsig[n]) >= 70 && siglen <= 73 && n+siglen < len && j < 16 ) { @@ -472,7 +478,7 @@ int32_t bitcoin_scriptget(struct iguana_info *coin,int32_t *hashtypep,uint32_t * vp->type = spendtype; if ( j == 0 ) { - *suffixp = len; + //*userdatalenp = len; vp->spendlen = len; return(vp->spendlen); } @@ -488,21 +494,28 @@ int32_t bitcoin_scriptget(struct iguana_info *coin,int32_t *hashtypep,uint32_t * j++; } vp->numpubkeys = j; - if ( n+2 < len && (scriptsig[n] == 0x4c || scriptsig[n] == 0x4d) ) + *userdatap = &scriptsig[n]; + *userdatalenp = (len - n); + p2shscript = 0; + while ( n < len ) { - if ( scriptsig[n] == 0x4c ) - vp->p2shlen = scriptsig[n+1], n += 2; - else vp->p2shlen = ((uint32_t)scriptsig[n+1] + ((uint32_t)scriptsig[n+2] << 8)), n += 3; - //printf("p2sh opcode.%02x %02x %02x scriptlen.%d\n",scriptsig[n],scriptsig[n+1],scriptsig[n+2],vp->p2shlen); - if ( vp->p2shlen < IGUANA_MAXSCRIPTSIZE && n+vp->p2shlen <= len ) + if ( n+2 < len && (scriptsig[n] == 0x4c || scriptsig[n] == 0x4d) ) { - memcpy(vp->p2shscript,&scriptsig[n],vp->p2shlen); - n += vp->p2shlen; - vp->type = IGUANA_SCRIPT_P2SH; - } else vp->p2shlen = 0; + if ( scriptsig[n] == 0x4c ) + vp->p2shlen = scriptsig[n+1], n += 2; + else vp->p2shlen = ((uint32_t)scriptsig[n+1] + ((uint32_t)scriptsig[n+2] << 8)), n += 3; + //printf("p2sh opcode.%02x %02x %02x scriptlen.%d\n",scriptsig[n],scriptsig[n+1],scriptsig[n+2],vp->p2shlen); + if ( vp->p2shlen < IGUANA_MAXSCRIPTSIZE && n+vp->p2shlen <= len ) + { + p2shscript = &scriptsig[n]; + memcpy(vp->p2shscript,&scriptsig[n],vp->p2shlen); + n += vp->p2shlen; + vp->type = IGUANA_SCRIPT_P2SH; + } else vp->p2shlen = 0; + } } - if ( n < len ) - *suffixp = (len - n); + if ( *userdatap == p2shscript ) + *userdatap = 0; /*if ( len == 0 ) { // txid.(eccf7e3034189b851985d871f91384b8ee357cd47c3024736e5676eb2debb3f2).v1 @@ -514,15 +527,17 @@ int32_t bitcoin_scriptget(struct iguana_info *coin,int32_t *hashtypep,uint32_t * return(vp->spendlen); } -int32_t iguana_vinscriptparse(struct iguana_info *coin,struct vin_info *vp,uint32_t *sigsizep,uint32_t *pubkeysizep,uint32_t *p2shsizep,uint32_t *suffixp,uint8_t *vinscript,int32_t scriptlen) +int32_t iguana_vinscriptparse(struct iguana_info *coin,struct vin_info *vp,uint32_t *sigsizep,uint32_t *pubkeysizep,uint32_t *p2shsizep,uint32_t *userdatalenp,uint8_t *vinscript,int32_t scriptlen) { - int32_t hashtype; - *sigsizep = *pubkeysizep = *p2shsizep = *suffixp = 0; - if ( bitcoin_scriptget(coin,&hashtype,sigsizep,pubkeysizep,suffixp,vp,vinscript,scriptlen,0) < 0 ) + int32_t hashtype; uint8_t *userdata = 0; + *sigsizep = *pubkeysizep = *p2shsizep = *userdatalenp = 0; + if ( bitcoin_scriptget(coin,&hashtype,sigsizep,pubkeysizep,&userdata,userdatalenp,vp,vinscript,scriptlen,0) < 0 ) { printf("iguana_vinscriptparse: error parsing vinscript?\n"); return(-1); } + if ( userdata != 0 && *userdatalenp > 0 ) + memcpy(vp->userdata,userdata,*userdatalenp); if ( vp->type == IGUANA_SCRIPT_P2SH ) { *p2shsizep = vp->p2shlen + 1 + (vp->p2shlen >= 0xfd)*2; @@ -632,9 +647,9 @@ int32_t iguana_vinscriptdecode(struct iguana_info *coin,struct iguana_ramchain * for (i=0; inumpubkeys; i++) { len += iguana_rwvarint32(0,&metascript[len],(void *)&poffset); - if ( poffset > ramchain->H.data->scriptspace-33 ) + if ( poffset > rdata->scriptspace-33 ) { - printf("illegal poffset.%d/%d\n",poffset,ramchain->H.data->scriptspace); + printf("illegal poffset.%d/%d\n",poffset,rdata->scriptspace); return(-1); } //printf("poffset[%d] of %d poffset %x\n",i,s->numpubkeys,poffset); @@ -790,7 +805,7 @@ int32_t iguana_metascript(struct iguana_info *coin,RAMCHAIN_FUNC,struct iguana_s { ramchain->H.stacksize += sigslen; s->scriptoffset = ramchain->H.scriptoffset; - len = iguana_vinscriptencode(coin,&metalen,&Kspace[ramchain->H.data->scriptspace],ramchain->H.stacksize,Kspace,ramchain->H.scriptoffset,s,sigsbuf,sigslen,poffsets,V.p2shscript,V.p2shlen,suffix,suffixlen); + len = iguana_vinscriptencode(coin,&metalen,&Kspace[rdata->scriptspace],ramchain->H.stacksize,Kspace,ramchain->H.scriptoffset,s,sigsbuf,sigslen,poffsets,V.p2shscript,V.p2shlen,suffix,suffixlen); } else printf("sigslen.%d numsigs.%d numpubs.%d suffixlen.%d\n",sigslen,V.numsigs,V.numpubkeys,suffixlen); } else @@ -810,7 +825,7 @@ int32_t iguana_metascript(struct iguana_info *coin,RAMCHAIN_FUNC,struct iguana_s } } //printf("checklen.%d scriptoffset.%d\n",checklen,ramchain->H.scriptoffset); - if ( (decodelen= iguana_vinscriptdecode(coin,ramchain,&checkmetalen,_script,&Kspace[ramchain->H.data->scriptspace],Kspace,s)) != vinscriptlen || (vinscript != 0 && memcmp(_script,vinscript,vinscriptlen) != 0) || checkmetalen != metalen ) + if ( (decodelen= iguana_vinscriptdecode(coin,ramchain,&checkmetalen,_script,&Kspace[rdata->scriptspace],Kspace,s)) != vinscriptlen || (vinscript != 0 && memcmp(_script,vinscript,vinscriptlen) != 0) || checkmetalen != metalen ) { //static uint64_t counter; //if ( counter++ < 100 ) @@ -877,7 +892,7 @@ int32_t iguana_ramchain_scriptspace(struct iguana_info *coin,int32_t *sigspacep, int32_t j,scriptlen; struct vin_info V; uint32_t sequence,p2shspace,altspace,sigspace,pubkeyspace,spendind,unspentind,p2shsize,pubkeysize,sigsize,scriptspace,suffixlen; struct iguana_txid *tx; struct iguana_ramchaindata *rdata; uint8_t *scriptdata; - _iguana_ramchain_setptrs(RAMCHAIN_PTRS,ramchain->H.data); + _iguana_ramchain_setptrs(RAMCHAIN_PTRS,rdata); *sigspacep = *pubkeyspacep = altspace = 0; return(1); if ( (rdata= ramchain->H.data) == 0 || ramchain->expanded != 0 ) @@ -902,7 +917,7 @@ int32_t iguana_ramchain_scriptspace(struct iguana_info *coin,int32_t *sigspacep, { sequence = S[spendind].sequenceid; scriptlen = S[spendind].vinscriptlen; - if ( S[spendind].scriptoffset != 0 && S[spendind].scriptoffset+scriptlen < ramchain->H.data->scriptspace ) + if ( S[spendind].scriptoffset != 0 && S[spendind].scriptoffset+scriptlen < rdata->scriptspace ) { scriptdata = &Kspace[S[spendind].scriptoffset]; altspace += scriptlen; @@ -1000,14 +1015,14 @@ uint8_t *iguana_ramchain_scriptdecode(int32_t *metalenp,int32_t *scriptlenp,uint /*origoffset = ramchain->H.scriptoffset; if ( type != IGUANA_SCRIPT_STRANGE && type != IGUANA_SCRIPT_DATA && type != IGUANA_SCRIPT_OPRETURN && scriptlen > 0 && script != 0 ) { - if ( Kspace != 0 && ramchain->H.scriptoffset+scriptlen+3 <= ramchain->H.data->scriptspace-ramchain->H.stacksize ) + if ( Kspace != 0 && ramchain->H.scriptoffset+scriptlen+3 <= rdata->scriptspace-ramchain->H.stacksize ) { if ( (u->scriptoffset= iguana_ramchain_scriptencode(coin,Kspace,&ramchain->H.scriptoffset,type,script,scriptlen,&pubkeyoffset)) > 0 || type == IGUANA_SCRIPT_76AC ) { fprintf(stderr,"new offset.%d from scriptlen.%d pubkeyoffset.%d\n",ramchain->H.scriptoffset,scriptlen,pubkeyoffset); } //printf("[%d] u%d offset.%u len.%d\n",hdrsi,unspentind,u->scriptoffset,scriptlen); - } else printf("[%d] u%d Kspace.%p scriptspace overflow! %d + %d vs space.%d - stack.%d\n",hdrsi,unspentind,Kspace,ramchain->H.scriptoffset,scriptlen,ramchain->H.data->scriptspace,ramchain->H.stacksize); + } else printf("[%d] u%d Kspace.%p scriptspace overflow! %d + %d vs space.%d - stack.%d\n",hdrsi,unspentind,Kspace,ramchain->H.scriptoffset,scriptlen,rdata->scriptspace,ramchain->H.stacksize); checkscript = iguana_ramchain_scriptdecode(&metalen,&checklen,Kspace,u->type,_script,u->scriptoffset,P[pkind].pubkeyoffset < ramchain->H.scriptoffset ? P[pkind].pubkeyoffset : 0); if ( checklen != scriptlen || (script != 0 && checkscript != 0 && memcmp(checkscript,script,scriptlen) != 0) ) { diff --git a/iguana/iguana_secp.c b/iguana/iguana_secp.c index 29d563527..2e25b0ecc 100755 --- a/iguana/iguana_secp.c +++ b/iguana/iguana_secp.c @@ -19,30 +19,42 @@ #include #include "../includes/curve25519.h" #include "secp256k1/include/secp256k1.h" +#include "secp256k1/include/secp256k1_ecdh.h" +#include "secp256k1/include/secp256k1_schnorr.h" +#include "secp256k1/include/secp256k1_rangeproof.h" #include "secp256k1/include/secp256k1_recovery.h" -//#include "../../secp256k1-zkp/include/secp256k1.h" -//#include "../../secp256k1-zkp/include/secp256k1_recovery.h" +SECP256K1_API extern const secp256k1_nonce_function secp256k1_nonce_function_rfc6979; + +#define bits256_nonz(a) (((a).ulongs[0] | (a).ulongs[1] | (a).ulongs[2] | (a).ulongs[3]) != 0) + +#define SECP_ENSURE_CTX int32_t flag = 0; if ( ctx == 0 ) { ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); secp256k1_pedersen_context_initialize(ctx); secp256k1_rangeproof_context_initialize(ctx); flag++; } else flag = 0; if ( ctx != 0 ) +#define ENDSECP_ENSURE_CTX if ( flag != 0 ) secp256k1_context_destroy(ctx); + +int32_t bitcoin_pubkeylen(const uint8_t *pubkey) +{ + if ( pubkey[0] == 2 || pubkey[0] == 3 ) + return(33); + else if ( pubkey[0] == 4 ) + return(65); + else return(-1); +} bits256 bitcoin_randkey(secp256k1_context *ctx) { - int32_t i,flag = 0; bits256 privkey; - if ( ctx == 0 ) - ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY), flag++; - if ( ctx != 0 ) + int32_t i; bits256 privkey; + SECP_ENSURE_CTX { for (i=0; i<100; i++) { privkey = rand256(0); - if ( secp256k1_ec_seckey_verify(ctx,privkey.bytes) > 0 ) + if ( secp256k1_ec_seckey_verify(ctx,privkey.bytes) != 0 ) { - if ( flag != 0 ) - secp256k1_context_destroy(ctx); + ENDSECP_ENSURE_CTX return(privkey); } } - if ( flag != 0 ) - secp256k1_context_destroy(ctx); + ENDSECP_ENSURE_CTX } fprintf(stderr,"couldnt generate valid bitcoin privkey. something is REALLY wrong. exiting\n"); exit(-1); @@ -50,56 +62,66 @@ bits256 bitcoin_randkey(secp256k1_context *ctx) bits256 bitcoin_pubkey33(secp256k1_context *ctx,uint8_t *data,bits256 privkey) { - int32_t flag=0; size_t plen; bits256 pubkey; secp256k1_pubkey secppub; + size_t plen; bits256 pubkey; secp256k1_pubkey secppub; memset(pubkey.bytes,0,sizeof(pubkey)); - if ( ctx == 0 ) - ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY), flag++; - if ( ctx != 0 ) + SECP_ENSURE_CTX { if ( secp256k1_ec_seckey_verify(ctx,privkey.bytes) == 0 ) { printf("bitcoin_sign illegal privkey\n"); return(pubkey); } - if ( secp256k1_ec_pubkey_create(ctx,&secppub,privkey.bytes) > 0 ) + if ( secp256k1_ec_pubkey_create(ctx,&secppub,privkey.bytes) != 0 ) { plen = 33; secp256k1_ec_pubkey_serialize(ctx,data,&plen,&secppub,SECP256K1_EC_COMPRESSED); if ( plen == 33 ) memcpy(pubkey.bytes,data+1,sizeof(pubkey)); } - if ( flag != 0 ) - secp256k1_context_destroy(ctx); + ENDSECP_ENSURE_CTX } return(pubkey); } +bits256 bitcoin_pub256(void *ctx,bits256 *privkeyp,uint8_t odd_even) +{ + bits256 pub256; uint8_t pubkey[33]; int32_t i; + for (i=0; i<100; i++) + { + *privkeyp = rand256(0); + pub256 = bitcoin_pubkey33(ctx,pubkey,*privkeyp); + if ( pubkey[0] == odd_even+2 ) + return(pub256); + } + printf("bitcoin_pub256 couldnt generate pubkey.%d\n",odd_even+2); + memset(pub256.bytes,0,sizeof(pub256)); + return(pub256); +} + int32_t bitcoin_sign(void *ctx,char *symbol,uint8_t *sig,bits256 txhash2,bits256 privkey,int32_t recoverflag) { int32_t fCompressed = 1; - secp256k1_ecdsa_signature SIG; secp256k1_ecdsa_recoverable_signature rSIG; bits256 extra_entropy,seed; int32_t flag = 0,recid,retval = -1; size_t siglen = 72; secp256k1_pubkey SECPUB,CHECKPUB; + secp256k1_ecdsa_signature SIG; secp256k1_ecdsa_recoverable_signature rSIG; bits256 extra_entropy,seed; int32_t recid,retval = -1; size_t siglen = 72; secp256k1_pubkey SECPUB,CHECKPUB; seed = rand256(0); extra_entropy = rand256(0); - if ( ctx == 0 ) - ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY), flag++; - if ( ctx != 0 ) + SECP_ENSURE_CTX { if ( secp256k1_ec_seckey_verify(ctx,privkey.bytes) == 0 ) { printf("bitcoin_sign illegal privkey\n"); return(-1); } - if ( secp256k1_context_randomize(ctx,seed.bytes) > 0 ) + if ( secp256k1_context_randomize(ctx,seed.bytes) != 0 ) { if ( recoverflag != 0 ) { - if ( secp256k1_ecdsa_sign_recoverable(ctx,&rSIG,txhash2.bytes,privkey.bytes,secp256k1_nonce_function_rfc6979,extra_entropy.bytes) > 0 ) + if ( secp256k1_ecdsa_sign_recoverable(ctx,&rSIG,txhash2.bytes,privkey.bytes,secp256k1_nonce_function_rfc6979,extra_entropy.bytes) != 0 ) { recid = -1; secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx,sig+1,&recid,&rSIG); - if ( secp256k1_ecdsa_recover(ctx,&SECPUB,&rSIG,txhash2.bytes) > 0 ) + if ( secp256k1_ecdsa_recover(ctx,&SECPUB,&rSIG,txhash2.bytes) != 0 ) { - if ( secp256k1_ec_pubkey_create(ctx,&CHECKPUB,privkey.bytes) > 0 ) + if ( secp256k1_ec_pubkey_create(ctx,&CHECKPUB,privkey.bytes) != 0 ) { if ( memcmp(&SECPUB,&CHECKPUB,sizeof(SECPUB)) == 0 ) { @@ -113,349 +135,630 @@ int32_t bitcoin_sign(void *ctx,char *symbol,uint8_t *sig,bits256 txhash2,bits256 } else { - if ( secp256k1_ecdsa_sign(ctx,&SIG,txhash2.bytes,privkey.bytes,secp256k1_nonce_function_rfc6979,extra_entropy.bytes) > 0 ) + if ( secp256k1_ecdsa_sign(ctx,&SIG,txhash2.bytes,privkey.bytes,secp256k1_nonce_function_rfc6979,extra_entropy.bytes) != 0 ) { - if ( secp256k1_ecdsa_signature_serialize_der(ctx,sig,&siglen,&SIG) > 0 ) + if ( secp256k1_ecdsa_signature_serialize_der(ctx,sig,&siglen,&SIG) != 0 ) retval = (int32_t)siglen; } } } - if ( flag != 0 ) - secp256k1_context_destroy(ctx); + ENDSECP_ENSURE_CTX } return(retval); } int32_t bitcoin_recoververify(void *ctx,char *symbol,uint8_t *sig65,bits256 messagehash2,uint8_t *pubkey) { - size_t plen; int32_t retval = -1,flag = 0; secp256k1_pubkey PUB; secp256k1_ecdsa_signature SIG; secp256k1_ecdsa_recoverable_signature rSIG; + int32_t retval = -1; size_t plen; secp256k1_pubkey PUB; secp256k1_ecdsa_signature SIG; secp256k1_ecdsa_recoverable_signature rSIG; pubkey[0] = 0; - if ( ctx == 0 ) - ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY), flag++; - if ( ctx != 0 ) + SECP_ENSURE_CTX { plen = (sig65[0] <= 31) ? 65 : 33; secp256k1_ecdsa_recoverable_signature_parse_compact(ctx,&rSIG,sig65 + 1,0); secp256k1_ecdsa_recoverable_signature_convert(ctx,&SIG,&rSIG); - if ( secp256k1_ecdsa_recover(ctx,&PUB,&rSIG,messagehash2.bytes) > 0 ) + if ( secp256k1_ecdsa_recover(ctx,&PUB,&rSIG,messagehash2.bytes) != 0 ) { - secp256k1_ec_pubkey_serialize(ctx,pubkey,&plen,&PUB,plen == 65 ? SECP256K1_EC_UNCOMPRESSED : SECP256K1_EC_COMPRESSED); - if ( secp256k1_ecdsa_verify(ctx,&SIG,messagehash2.bytes,&PUB) > 0 ) + plen = 33; + secp256k1_ec_pubkey_serialize(ctx,pubkey,&plen,&PUB,SECP256K1_EC_COMPRESSED);//plen == 65 ? SECP256K1_EC_UNCOMPRESSED : SECP256K1_EC_COMPRESSED); + if ( secp256k1_ecdsa_verify(ctx,&SIG,messagehash2.bytes,&PUB) != 0 ) + { retval = 0; + /*if ( pubkey[0] == 4 ) // experimentally looks like 04 is set + pubkey[0] = 2; + else if ( pubkey[0] != 2 ) + pubkey[0] = 3;*/ + } else printf("secp256k1_ecdsa_verify error\n"); } else printf("secp256k1_ecdsa_recover error\n"); - if ( flag != 0 ) - secp256k1_context_destroy(ctx); + ENDSECP_ENSURE_CTX } return(retval); } int32_t bitcoin_verify(void *ctx,uint8_t *sig,int32_t siglen,bits256 txhash2,uint8_t *pubkey,int32_t plen) { - int32_t flag=0,retval = -1; secp256k1_pubkey PUB; secp256k1_ecdsa_signature SIG; - if ( ctx == 0 ) - ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY), flag++; - if ( ctx != 0 ) + int32_t retval = -1; secp256k1_pubkey PUB; secp256k1_ecdsa_signature SIG; + SECP_ENSURE_CTX { - if ( secp256k1_ec_pubkey_parse(ctx,&PUB,pubkey,plen) > 0 ) + if ( secp256k1_ec_pubkey_parse(ctx,&PUB,pubkey,plen) != 0 ) { secp256k1_ecdsa_signature_parse_der(ctx,&SIG,sig,siglen); - if ( secp256k1_ecdsa_verify(ctx,&SIG,txhash2.bytes,&PUB) > 0 ) + if ( secp256k1_ecdsa_verify(ctx,&SIG,txhash2.bytes,&PUB) != 0 ) retval = 0; } - if ( flag != 0 ) - secp256k1_context_destroy(ctx); + ENDSECP_ENSURE_CTX } return(retval); } -#ifdef oldway -#include "../includes/openssl/ec.h" -#include "../includes/openssl/ecdsa.h" -#include "../includes/openssl/obj_mac.h" +bits256 bitcoin_sharedsecret(void *ctx,bits256 privkey,uint8_t *pubkey,int32_t plen) +{ + int32_t retval = -1; bits256 shared; secp256k1_pubkey PUB; + memset(shared.bytes,0,sizeof(shared)); + SECP_ENSURE_CTX + { + if ( secp256k1_ec_pubkey_parse(ctx,&PUB,pubkey,plen) != 0 ) + { + if ( secp256k1_ecdh(ctx,shared.bytes,&PUB,privkey.bytes) != 0 ) + retval = 0; + else memset(shared.bytes,0,sizeof(shared)); + } + ENDSECP_ENSURE_CTX + } + return(shared); +} -static const char base58_chars[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; +int32_t bitcoin_schnorr_sign(void *ctx,uint8_t *sig64,bits256 txhash2,bits256 privkey) +{ + int32_t retval = -1; bits256 seed; + SECP_ENSURE_CTX + { + seed = rand256(0); + if ( secp256k1_schnorr_sign(ctx,sig64,txhash2.bytes,privkey.bytes,secp256k1_nonce_function_rfc6979,seed.bytes) != 0 ) + retval = 0; + ENDSECP_ENSURE_CTX + } + return(retval); +} -struct bp_key { EC_KEY *k; }; +int32_t bitcoin_schnorr_verify(void *ctx,uint8_t *sig64,bits256 txhash2,uint8_t *pubkey,int32_t plen) +{ + int32_t retval = -1; secp256k1_pubkey PUB; + SECP_ENSURE_CTX + { + if ( secp256k1_ec_pubkey_parse(ctx,&PUB,pubkey,plen) != 0 ) + { + if ( secp256k1_schnorr_verify(ctx,sig64,txhash2.bytes,&PUB) != 0 ) + retval = 0; + } + ENDSECP_ENSURE_CTX + } + return(retval); +} -EC_KEY *oldbitcoin_privkeyset(uint8_t *oddevenp,bits256 *pubkeyp,bits256 privkey) +int32_t bitcoin_schnorr_recover(void *ctx,uint8_t *pubkey,uint8_t *sig64,bits256 txhash2) { - BIGNUM *bn; BN_CTX *ctx = NULL; uint8_t *ptr,tmp[33]; EC_POINT *pub_key = NULL; const EC_GROUP *group; - EC_KEY *KEY = EC_KEY_new_by_curve_name(NID_secp256k1); - *oddevenp = 0; - EC_KEY_set_conv_form(KEY,POINT_CONVERSION_COMPRESSED); + int32_t retval = -1; secp256k1_pubkey PUB; size_t plen; + SECP_ENSURE_CTX { - if ( (group= EC_KEY_get0_group(KEY)) != 0 && (ctx= BN_CTX_new()) != 0 ) + if ( secp256k1_schnorr_recover(ctx,&PUB,sig64,txhash2.bytes) != 0 ) { - if ( (pub_key= EC_POINT_new(group)) != 0 ) - { - if ( (bn= BN_bin2bn(privkey.bytes,sizeof(privkey),BN_new())) != 0 ) - { - if ( EC_POINT_mul(group,pub_key,bn,NULL,NULL,ctx) > 0 ) - { - EC_KEY_set_private_key(KEY,bn); - EC_KEY_set_public_key(KEY,pub_key); - ptr = tmp; - i2o_ECPublicKey(KEY,&ptr); - *oddevenp = tmp[0]; - memcpy(pubkeyp->bytes,&tmp[1],sizeof(*pubkeyp)); - } - BN_clear_free(bn); - } - EC_POINT_free(pub_key); - } - BN_CTX_free(ctx); + plen = 33; + secp256k1_ec_pubkey_serialize(ctx,pubkey,&plen,&PUB,SECP256K1_EC_COMPRESSED); + retval = 0; } + ENDSECP_ENSURE_CTX } - return(KEY); + return(retval); } -int32_t oldbitcoin_verify(uint8_t *sig,int32_t siglen,uint8_t *data,int32_t datalen,uint8_t *pubkey,int32_t len) +bits256 bitcoin_schnorr_noncepair(void *ctx,uint8_t *pubnonce,bits256 txhash2,bits256 privkey) //exchange { - ECDSA_SIG *esig; int32_t retval = -1; uint8_t tmp[33],*ptr,*sigptr = sig; EC_KEY *KEY = 0; - if ( len < 0 ) - return(-1); - if ( (esig= ECDSA_SIG_new()) != 0 ) + int32_t retval = -1; size_t plen; secp256k1_pubkey PUB; bits256 privnonce,seed; + memset(privnonce.bytes,0,sizeof(privnonce)); + pubnonce[0] = 0; + SECP_ENSURE_CTX + { + seed = rand256(0); + if ( secp256k1_schnorr_generate_nonce_pair(ctx,&PUB,privnonce.bytes,txhash2.bytes,privkey.bytes,secp256k1_nonce_function_rfc6979,seed.bytes) != 0 ) + { + plen = 33; + secp256k1_ec_pubkey_serialize(ctx,pubnonce,&plen,&PUB,SECP256K1_EC_COMPRESSED); + retval = 0; + } + ENDSECP_ENSURE_CTX + } + return(privnonce); +} + +int32_t bitcoin_pubkey_combine(void *ctx,uint8_t *combined_pub,uint8_t *skipkey,bits256 *evenkeys,int32_t n,bits256 *oddkeys,int32_t m) +{ + int32_t i,num,iter,max,retval = -1; uint8_t pubkey[33]; size_t plen; secp256k1_pubkey PUBall,*PUBptrs[256],PUBkeys[256]; + SECP_ENSURE_CTX { - if ( d2i_ECDSA_SIG(&esig,(const uint8_t **)&sigptr,siglen) != 0 ) + if ( n+m > 0 && n+m < sizeof(PUBptrs)/sizeof(*PUBptrs) ) { - if ( (KEY= EC_KEY_new_by_curve_name(NID_secp256k1)) != 0 ) + for (iter=num=0; iter<2; iter++) { - EC_KEY_set_conv_form(KEY,POINT_CONVERSION_COMPRESSED); - if ( len == 32 ) + if ( (max= (iter == 0) ? n : m) != 0 ) { - memcpy(tmp+1,pubkey,len); - for (tmp[0]=2; tmp[0]<=3; tmp[0]++) + for (i=0; i 0 ) + PUBptrs[num] = &PUBkeys[num]; + pubkey[0] = 2 + iter; + memcpy(pubkey+1,((iter == 0) ? evenkeys : oddkeys)[i].bytes,32); + if ( skipkey != 0 && memcmp(pubkey,skipkey,33) == 0 ) { - retval = 0; + //printf("skipkey.%d\n",i); + continue; + } + if ( secp256k1_ec_pubkey_parse(ctx,PUBptrs[num],pubkey,33) == 0 ) + { + int32_t j; for (j=0; j<33; j++) + printf("%02x",pubkey[j]); + printf(" error parsing pubkey iter.%d num.%d i.%d\n",iter,num,i); break; } + num++; } } - else - { - ptr = pubkey; - o2i_ECPublicKey(&KEY,(const uint8_t **)&ptr,len); - if ( ECDSA_do_verify(data,datalen,esig,KEY) > 0 ) - retval = 0; - } - EC_KEY_free(KEY); + } + if ( secp256k1_ec_pubkey_combine(ctx,&PUBall,(void *)PUBptrs,num) != 0 ) + { + plen = 33; + secp256k1_ec_pubkey_serialize(ctx,combined_pub,&plen,&PUBall,SECP256K1_EC_COMPRESSED); + retval = 0; } } - ECDSA_SIG_free(esig); + ENDSECP_ENSURE_CTX } return(retval); } -int32_t oldbitcoin_sign(uint8_t *sig,int32_t maxlen,uint8_t *data,int32_t datalen,bits256 privkey) +int32_t bitcoin_schnorr_partialsign(void *ctx,uint8_t *sig64,uint8_t *combined_pub,bits256 txhash2,bits256 privkey,bits256 privnonce,uint8_t *pubptrs[],int32_t n) // generate and exchange { - EC_KEY *KEY; uint8_t oddeven; bits256 pubkey; uint8_t *ptr; int32_t siglen,retval = -1; - ECDSA_SIG *SIG; BN_CTX *ctx; const EC_GROUP *group; BIGNUM *order,*halforder; - if ( (KEY= oldbitcoin_privkeyset(&oddeven,&pubkey,privkey)) != 0 ) + int32_t bitcoin_pubkeylen(const uint8_t *pubkey); + int32_t i,retval = -1; secp256k1_pubkey PUBall,**PUBptrs; size_t plen; + SECP_ENSURE_CTX { - if ( (SIG= ECDSA_do_sign(data,datalen,KEY)) != 0 ) + PUBptrs = calloc(n,sizeof(*PUBptrs)); + for (i=0; is,halforder) > 0 ) - { - // enforce low S values, by negating the value (modulo the order) if above order/2. - BN_sub(SIG->s,order,SIG->s); - } - ptr = 0; - siglen = i2d_ECDSA_SIG(SIG,&ptr); - if ( ptr != 0 ) + PUBptrs[i] = calloc(1,sizeof(secp256k1_pubkey)); + if ( secp256k1_ec_pubkey_parse(ctx,PUBptrs[i],pubptrs[i],bitcoin_pubkeylen(pubptrs[i])) != 0 ) + break; + } + if ( n > 0 && secp256k1_ec_pubkey_combine(ctx,&PUBall,(void *)PUBptrs,n) != 0 ) + { + plen = 33; + if ( secp256k1_schnorr_partial_sign(ctx,sig64,txhash2.bytes,privkey.bytes,&PUBall,privnonce.bytes) != 0 ) { - if ( siglen > 0 ) - { - memcpy(sig,ptr,siglen); - retval = siglen; - } - free(ptr); + secp256k1_ec_pubkey_serialize(ctx,combined_pub,&plen,&PUBall,SECP256K1_EC_COMPRESSED); + retval = 0; } - BN_CTX_end(ctx); - BN_CTX_free(ctx); - ECDSA_SIG_free(SIG); } - //if ( ECDSA_sign(0,data,datalen,sig,&siglen,KEY) > 0 && siglen <= maxlen ) - // retval = siglen; - EC_KEY_free(KEY); + free(PUBptrs); + ENDSECP_ENSURE_CTX } return(retval); } -bits256 oldbitcoin_pubkey33(void *_ctx,uint8_t *data,bits256 privkey) +int32_t bitcoin_schnorr_combine(void *ctx,uint8_t *sig64,uint8_t *allpub,uint8_t **sigs,int32_t n,bits256 txhash2) { - uint8_t oddeven,data2[65]; size_t plen; bits256 pubkey; secp256k1_pubkey secppub; secp256k1_context *ctx; - EC_KEY *KEY; - if ( (KEY= oldbitcoin_privkeyset(&oddeven,&pubkey,privkey)) != 0 ) - { - data[0] = oddeven; - memcpy(data+1,pubkey.bytes,sizeof(pubkey)); - EC_KEY_free(KEY); - if ( (ctx= secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY)) != 0 ) + int32_t rc,retval = -1; + SECP_ENSURE_CTX + { + if ( (rc= secp256k1_schnorr_partial_combine(ctx,sig64,(void *)sigs,n)) != 0 ) { - if ( secp256k1_ec_pubkey_create(ctx,&secppub,privkey.bytes) > 0 ) + if ( bitcoin_schnorr_recover(ctx,allpub,sig64,txhash2) == 0 ) { - secp256k1_ec_pubkey_serialize(ctx,data2,&plen,&secppub,1); - if ( memcmp(data2,data,plen) != 0 ) - printf("pubkey compare error plen.%d\n",(int32_t)plen); - else printf("pubkey verified\n"); - } //else printf("error secp256k1_ec_pubkey_create\n"); - secp256k1_context_destroy(ctx); + if ( bitcoin_schnorr_verify(ctx,sig64,txhash2,allpub,33) == 0 ) + retval = 0; + } } - } else memset(pubkey.bytes,0,sizeof(pubkey)); - return(pubkey); + ENDSECP_ENSURE_CTX + } + return(retval); +} + +int32_t bitcoin_pederson_commit(void *ctx,uint8_t *commit,bits256 blind,uint64_t value) +{ + int32_t retval = -1; + SECP_ENSURE_CTX + { + if ( secp256k1_pedersen_commit(ctx,commit,blind.bytes,value) != 0 ) + retval = 0; + ENDSECP_ENSURE_CTX + } + return(retval); +} + +bits256 bitcoin_pederson_blindsum(void *ctx,bits256 **blindptrs,int32_t n,int32_t numpos) +{ + bits256 blind_out; + memset(blind_out.bytes,0,sizeof(blind_out)); + SECP_ENSURE_CTX + { + if ( secp256k1_pedersen_blind_sum(ctx,blind_out.bytes,(void *)blindptrs,n,numpos) == 0 ) + memset(blind_out.bytes,0,sizeof(blind_out)); + ENDSECP_ENSURE_CTX + } + return(blind_out); +} + +int32_t bitcoin_pederson_tally(void *ctx,uint8_t **commits,int32_t n,int32_t numpos,int64_t excess) +{ + int32_t retval = -1; + SECP_ENSURE_CTX + { + printf("bitcoin_pederson_tally: n.%d numpos.%d excess %lld\n",n,numpos,(long long)excess); + if ( secp256k1_pedersen_verify_tally(ctx,(void *)commits,numpos,(void *)&commits[numpos],n - numpos,excess) != 0 ) + retval = 0; + ENDSECP_ENSURE_CTX + } + return(retval); +} + +int32_t bitcoin_rangeproof_message(void *ctx,uint8_t *blind_out,uint8_t *message,uint64_t *valuep,bits256 nonce,uint64_t *min_valuep,uint64_t *max_valuep,uint8_t *commit,uint8_t *proof,int32_t prooflen) +{ + int32_t outlen = 0,retval = -1; + SECP_ENSURE_CTX + { + if ( secp256k1_rangeproof_rewind(ctx,blind_out,valuep,message,&outlen,nonce.bytes,min_valuep,max_valuep,commit,proof,prooflen) != 0 ) + retval = outlen; + ENDSECP_ENSURE_CTX + } + return(retval); } -void bn_mpi2bn(BIGNUM *vo,uint8_t *data,int32_t datalen) +uint64_t bitcoin_rangeverify(void *ctx,int32_t *exponentp,int32_t *mantissap,uint64_t *min_valuep,uint8_t *commit,uint8_t *proof,int32_t prooflen) { - uint8_t vch2[64 + 4]; uint32_t i,vch2_len = (int32_t)datalen + 4; - if ( datalen < sizeof(vch2) ) + uint64_t max_value,retval = 0; + max_value = *min_valuep = *exponentp = *mantissap = 0; + if ( secp256k1_rangeproof_info(ctx,exponentp,mantissap,min_valuep,&max_value,proof,prooflen) != 0 ) { - vch2[0] = (datalen >> 24) & 0xff; - vch2[1] = (datalen >> 16) & 0xff; - vch2[2] = (datalen >> 8) & 0xff; - vch2[3] = (datalen >> 0) & 0xff; - for (i=0; i= 4 && sz < sizeof(s_be) ) // get MPI format size + int32_t prooflen=0 ,retval = -1; + SECP_ENSURE_CTX { - BN_bn2mpi(v,s_be); - // copy-swap MPI to little endian, sans 32-bit size prefix - sz -= 4; - for (i=0; i= 2 && revdata[len - 1] == 0 && revdata[len - 2] >= 0x80 ) - len--; - zeroes = 0; - for (p=coinaddr; *p==base58_chars[0]; p++) - zeroes++; - be_sz = (uint32_t)len + (uint32_t)zeroes; - memset(data,0,be_sz); - for (i=0; i 0 ) { - for (i=0; i> 1) ) - { - ctx = BN_CTX_new(); - BN_init(&bn58), BN_init(&bn0), BN_init(&bn), BN_init(&dv), BN_init(&rem); - BN_set_word(&bn58,58); - BN_set_word(&bn0,0); - for (i=0; i 0 ) + bits256 privnonces[100],privkeys[100],txhash2; uint8_t *sigs[100],allpub[100][33],sig64[100][64],allsig64[100][64],combined_pub[100][33],pubnonces[100][33],*pubptrs[100]; int32_t i,j,N,n,errs = 0; + iguana_pederson_test(ctx); + SECP_ENSURE_CTX + { + N = 100; + txhash2 = rand256(0); + for (i=0; i 1 ) { - if ( data[i] == 0 ) - rs[n++] = base58_chars[0]; - else break; + if ( bitcoin_schnorr_partialsign(ctx,sig64[i],combined_pub[i],txhash2,privkeys[i],privnonces[i],pubptrs,N-1) < 0 ) + errs++; + } + else + { + if ( bitcoin_schnorr_sign(ctx,sig64[0],txhash2,privkeys[0]) < 0 ) + errs++; } - for (i=0; iprev_hash),msg->prev_hash.bytes); len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->prev_vout),&msg->prev_vout); if ( rwflag == 1 ) - tmp = msg->scriptlen; + { + tmp = msg->scriptlen + msg->userdatalen + msg->p2shlen; + if ( msg->p2shlen != 0 ) + { + if ( msg->p2shlen < 76 ) + tmp++; + else if ( msg->p2shlen < 0x100 ) + tmp += 2; + else tmp += 3; + } + } len += iguana_rwvarint32(rwflag,&serialized[len],&tmp); if ( rwflag == 0 ) + { + if ( msg->p2shlen != 0 ) + { + if ( msg->p2shlen < 76 ) + tmp++; + else if ( msg->p2shlen < 0x100 ) + tmp += 2; + else tmp += 3; + } msg->scriptlen = tmp; + } if ( msg->scriptlen > IGUANA_MAXSCRIPTSIZE ) { printf("iguana_vinparse illegal scriptlen.%d\n",msg->scriptlen); return(-1); } + //printf("len.%d scriptlen.%d user.%d p2sh.%d\n",len,msg->scriptlen,msg->userdatalen,msg->p2shlen); if ( rwflag == 0 ) { msg->vinscript = &serialized[len]; len += msg->scriptlen; } - else if ( msg->vinscript != 0 && msg->scriptlen > 0 ) + else { + if ( msg->vinscript != 0 && msg->scriptlen > 0 ) memcpy(&serialized[len],msg->vinscript,msg->scriptlen), len += msg->scriptlen; // pubkeys here + if ( msg->userdatalen > 0 && msg->userdata != 0 ) + { + //printf("userdata.%d scriptlen.%d\n",msg->userdatalen,msg->scriptlen); + memcpy(&serialized[len],msg->userdata,msg->userdatalen); + len += msg->userdatalen; + } if ( (p2shlen= msg->p2shlen) > 0 && msg->redeemscript != 0 ) { - if ( p2shlen > msg->suffixlen ) + //printf("p2shlen.%d %x\n",p2shlen,p2shlen); + if ( p2shlen < 76 ) + serialized[len++] = p2shlen; + else if ( p2shlen <= 0xff ) { - p2shlen -= msg->suffixlen; - if ( p2shlen < 76 ) - serialized[len++] = p2shlen; - else if ( p2shlen <= 0xff ) - { - serialized[len++] = 0x4c; - serialized[len++] = p2shlen; - } - else if ( p2shlen <= 0xffff ) - { - serialized[len++] = 0x4d; - serialized[len++] = (p2shlen & 0xff); - serialized[len++] = ((p2shlen >> 8) & 0xff); - } else return(-1); - memcpy(&serialized[len],msg->redeemscript,p2shlen), len += p2shlen; + serialized[len++] = 0x4c; + serialized[len++] = p2shlen; } - if ( msg->suffixlen > 0 ) - memcpy(&serialized[len],&msg->redeemscript[msg->scriptlen - msg->suffixlen],msg->suffixlen), len += msg->suffixlen; + else if ( p2shlen <= 0xffff ) + { + serialized[len++] = 0x4d; + serialized[len++] = (p2shlen & 0xff); + serialized[len++] = ((p2shlen >> 8) & 0xff); + } else return(-1); + memcpy(&serialized[len],msg->redeemscript,p2shlen), len += p2shlen; } } len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->sequence),&msg->sequence); if ( 0 ) { int32_t i; char str[65]; - for (i=0; iscriptlen; i++) - printf("%02x",msg->vinscript[i]); - printf(" prev_hash.(%s) vout.%d [%p] scriptlen.%d rwflag.%d\n",bits256_str(str,msg->prev_hash),msg->prev_vout,msg->vinscript,msg->scriptlen,rwflag); + for (i=0; isequence,bits256_str(str,msg->prev_hash),msg->prev_vout,msg->vinscript,msg->scriptlen,rwflag); } return(len); } @@ -100,7 +123,7 @@ int32_t iguana_voutparse(int32_t rwflag,uint8_t *serialized,struct iguana_msgvou return(len); } -cJSON *iguana_vinjson(struct iguana_info *coin,struct iguana_msgvin *vin) +cJSON *iguana_vinjson(struct iguana_info *coin,struct iguana_msgvin *vin,bits256 sigtxid) { char str[65]; int32_t vout; cJSON *json = cJSON_CreateObject(); vout = vin->prev_vout; @@ -111,23 +134,49 @@ cJSON *iguana_vinjson(struct iguana_info *coin,struct iguana_msgvin *vin) { jaddstr(json,"txid",bits256_str(str,vin->prev_hash)); jaddnum(json,"vout",vout); - if ( vin->scriptlen > 0 ) + if ( bits256_nonz(sigtxid) != 0 ) + jaddbits256(json,"sigtxid",sigtxid); + if ( vin->scriptlen > 0 ) // sigs iguana_addscript(coin,json,vin->vinscript,vin->scriptlen,"scriptSig"); - if ( vin->spendlen > 0 ) - iguana_addscript(coin,json,vin->spendscript,vin->spendlen,"scriptPubKey"); + if ( vin->userdatalen > 0 && vin->userdata != 0 ) + iguana_addscript(coin,json,vin->userdata,vin->userdatalen,"userdata"); if ( vin->p2shlen > 0 ) iguana_addscript(coin,json,vin->redeemscript,vin->p2shlen,"redeemScript"); + if ( vin->spendlen > 0 ) + iguana_addscript(coin,json,vin->spendscript,vin->spendlen,"scriptPubKey"); } return(json); } +int32_t iguana_parsehexstr(uint8_t **destp,uint16_t *lenp,uint8_t *dest2,int32_t *len2p,uint8_t *serialized,char *hexstr) +{ + int32_t n; + n = (int32_t)strlen(hexstr) >> 1; + //printf("addhex.(%s) %d\n",hexstr,n); + if ( serialized == 0 ) + serialized = *destp; + if ( serialized != 0 ) + { + decode_hex(serialized,n,hexstr); + *destp = serialized; + *lenp = n; + if ( dest2 != 0 && len2p != 0 ) + { + *len2p = n; + memcpy(dest2,serialized,n); + } + } + return(n); +} + int32_t iguana_parsevinobj(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_msgvin *vin,cJSON *vinobj,struct vin_info *V) { - struct iguana_waddress *waddr; struct iguana_waccount *wacct; int32_t i,n,plen,len = 0; char *suffixstr,*pubkeystr,*hexstr = 0,*redeemstr = 0,*spendstr = 0; cJSON *scriptjson = 0,*obj,*pubkeysjson = 0; - //printf("PARSEVIN.(%s)\n",jprint(vinobj,0)); + struct iguana_waddress *waddr; struct iguana_waccount *wacct; uint8_t lastbyte; uint32_t tmp=0; int32_t i,n,starti,suppress_pubkeys,siglen,plen,m,rwflag=1,need_op0=0,len = 0; char *userdata,*pubkeystr,*hexstr = 0,*redeemstr = 0,*spendstr = 0; cJSON *scriptjson = 0,*obj,*pubkeysjson = 0; + //printf("PARSEVIN.(%s) vin.%p\n",jprint(vinobj,0),vin); if ( V == 0 ) memset(vin,0,sizeof(*vin)); vin->prev_vout = -1; + suppress_pubkeys = juint(vinobj,"suppress"); if ( jobj(vinobj,"sequence") != 0 ) vin->sequence = juint(vinobj,"sequence"); else vin->sequence = 0xffffffff; @@ -140,104 +189,162 @@ int32_t iguana_parsevinobj(struct supernet_info *myinfo,struct iguana_info *coin if ( ((spendstr= jstr(vinobj,"scriptPub")) == 0 && (spendstr= jstr(vinobj,"scriptPubkey")) == 0) || is_hexstr(spendstr,(int32_t)strlen(spendstr)) <= 0 ) { if ( (obj= jobj(vinobj,"scriptPub")) != 0 || (obj= jobj(vinobj,"scriptPubkey")) != 0 ) + { spendstr = jstr(obj,"hex"); + lastbyte = _decode_hex(&spendstr[strlen(spendstr)-2]); + if ( lastbyte == SCRIPT_OP_CHECKMULTISIG ) + need_op0 = 1; + } } if ( (redeemstr= jstr(vinobj,"redeemScript")) == 0 || is_hexstr(redeemstr,(int32_t)strlen(redeemstr)) <= 0 ) { if ( (obj= jobj(vinobj,"redeemScript")) != 0 ) + { redeemstr = jstr(obj,"hex"); + lastbyte = _decode_hex(&redeemstr[strlen(redeemstr)-2]); + if ( lastbyte == SCRIPT_OP_CHECKMULTISIG ) + need_op0 = 1; + } + } + if ( (userdata= jstr(vinobj,"userdata")) == 0 || is_hexstr(userdata,(int32_t)strlen(userdata)) <= 0 ) + { + if ( (obj= jobj(vinobj,"userdata")) != 0 ) + userdata = jstr(obj,"hex"); } } - if ( hexstr != 0 ) - { - n = (int32_t)strlen(hexstr) >> 1; - decode_hex(serialized,n,hexstr); - vin->vinscript = serialized; - vin->scriptlen = n; - } //else printf("iguana_parsevinobj: hex script missing (%s)\n",jprint(vinobj,0)); + len += iguana_rwbignum(rwflag,&serialized[len],sizeof(vin->prev_hash),vin->prev_hash.bytes); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(vin->prev_vout),&vin->prev_vout); if ( V != 0 ) { if ( vin->vinscript == 0 ) { - if ( (V->unspentind= iguana_unspentindfind(coin,V->coinaddr,V->spendscript,&V->spendlen,&V->amount,&V->height,vin->prev_hash,vin->prev_vout,coin->bundlescount-1)) > 0 ) + if ( (V->unspentind= iguana_RTunspentindfind(myinfo,coin,V->coinaddr,V->spendscript,&V->spendlen,&V->amount,&V->height,vin->prev_hash,vin->prev_vout,coin->bundlescount-1,0)) > 0 ) { - if ( V->coinaddr[0] != 0 && (waddr= iguana_waddresssearch(myinfo,coin,&wacct,V->coinaddr)) != 0 ) + if ( V->coinaddr[0] != 0 && (waddr= iguana_waddresssearch(myinfo,&wacct,V->coinaddr)) != 0 ) { memcpy(V->signers[0].pubkey,waddr->pubkey,bitcoin_pubkeylen(waddr->pubkey)); } - printf("V %.8f (%s) spendscript.[%d]\n",dstr(V->amount),V->coinaddr,V->spendlen); + //printf("V %.8f (%s) spendscript.[%d]\n",dstr(V->amount),V->coinaddr,V->spendlen); } } - if ( (pubkeysjson= jarray(&n,vinobj,"pubkeys")) != 0 ) + } + tmp = IGUANA_MAXSCRIPTSIZE; + len += iguana_rwvarint32(rwflag,&serialized[len],&tmp); + starti = len; + if ( need_op0 != 0 ) + serialized[len++] = 0; // hack for bug for bug backward compatibility + if ( hexstr != 0 ) + { + n = (int32_t)strlen(hexstr) >> 1; + printf("add.(%s) offset.%d\n",hexstr,len); + vin->vinscript = &serialized[len]; + decode_hex(&serialized[len],n,hexstr); + vin->scriptlen = n + need_op0; + if ( V != 0 ) { - if ( vin->vinscript == 0 ) + i = m = 0; + while ( m < n ) { - vin->vinscript = serialized; - vin->vinscript[0] = 0; - vin->scriptlen = 1; + siglen = serialized[len + m++]; + if ( i == 0 && m == 1 && siglen == 0 ) // multisig backward compatible + continue; + memcpy(V->signers[i].sig,&serialized[len + m],siglen); + m += siglen; + i++; } - for (i=0; ivinscript == 0 ) + { + printf("null vinscript case\n"); + vin->vinscript = serialized; + vin->vinscript[0] = 0; + vin->scriptlen = 1; + } + for (i=0; i> 1) > 0 ) { - if ( (pubkeystr= jstr(jitem(pubkeysjson,i),0)) != 0 && (plen= (int32_t)strlen(pubkeystr) >> 1) > 0 ) + if ( V != 0 ) + memcpy(V->signers[i].pubkey,&vin->vinscript[vin->scriptlen],plen); + if ( suppress_pubkeys == 0 ) { + printf("addpub.(%s)\n",pubkeystr); vin->vinscript[vin->scriptlen++] = plen; decode_hex(&vin->vinscript[vin->scriptlen],plen,pubkeystr); - memcpy(V->signers[i].pubkey,&vin->vinscript[vin->scriptlen],plen); vin->scriptlen += plen; + serialized[len++] = plen; + memcpy(&serialized[len],&vin->vinscript[vin->scriptlen],plen), len += plen; } } } - if ( vin->vinscript != 0 ) - serialized = &vin->vinscript[vin->scriptlen]; - len = vin->scriptlen; - if ( redeemstr != 0 ) - { - n = (int32_t)strlen(redeemstr) >> 1; - decode_hex(serialized,n,redeemstr); - vin->redeemscript = serialized; - V->p2shlen = vin->p2shlen = n; - memcpy(V->p2shscript,serialized,n); - } - if ( (suffixstr= jstr(vinobj,"suffix")) != 0 && is_hexstr(suffixstr,(int32_t)strlen(suffixstr)) > 0 ) + } + //printf("len.%d: ",len); + if ( userdata != 0 ) + { + n = iguana_parsehexstr(&vin->userdata,&vin->userdatalen,V!=0?V->userdata:0,V!=0?&V->userdatalen:0,&serialized[len],userdata); + printf("parsed userdata.%d\n",n); + len += n; + } + //printf("len.%d: ",len); + if ( redeemstr != 0 ) + { + n = (int32_t)strlen(redeemstr) >> 1; + if ( n < 76 ) + serialized[len++] = n; + else if ( n <= 0xff ) { - if ( vin->redeemscript == 0 ) - { - vin->redeemscript = serialized; - vin->redeemscript[0] = 0; - } - n = (int32_t)strlen(suffixstr) >> 1; - decode_hex(&vin->redeemscript[vin->p2shlen],n,suffixstr); - vin->p2shlen += n; + serialized[len++] = 0x4c; + serialized[len++] = n; } - len += vin->p2shlen; - serialized = vin->redeemscript != 0 ? &vin->redeemscript[vin->p2shlen] : &serialized[len]; - if ( spendstr != 0 ) + else { - n = (int32_t)strlen(spendstr) >> 1; - decode_hex(serialized,n,spendstr); - vin->spendscript = serialized; - vin->spendlen = n; + serialized[len++] = 0x4d; + serialized[len++] = n & 0xff; + serialized[len++] = (n >> 8) & 0xff; } - len += vin->spendlen; + n = iguana_parsehexstr(&vin->redeemscript,&vin->p2shlen,V!=0?V->p2shscript:0,V!=0?&V->p2shlen:0,&serialized[len],redeemstr); + len += n; + } + tmp = (len - starti); + for (i=0; i> 8) & 0xff); + //printf("output sequence.[%d] <- %x\n",len,vin->sequence); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(vin->sequence),&vin->sequence); + if ( spendstr != 0 ) + { + n = iguana_parsehexstr(&vin->spendscript,&vin->spendlen,V!=0?V->spendscript:0,V!=0?&V->spendlen:0,0,spendstr); } return(len); } int32_t iguana_parsevoutobj(struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_msgvout *vout,cJSON *voutobj) { - int32_t len = 0; cJSON *skey; char *hexstr; + int32_t n,len = 0,rwflag = 1; cJSON *skey; char *hexstr; memset(vout,0,sizeof(*vout)); if ( jobj(voutobj,"satoshis") != 0 ) vout->value = j64bits(voutobj,"satoshis"); else vout->value = jdouble(voutobj,"value") * SATOSHIDEN; + len += iguana_rwnum(rwflag,&serialized[len],sizeof(vout->value),&vout->value); if ( (skey= jobj(voutobj,"scriptPubKey")) != 0 ) { if ( (hexstr= jstr(skey,"hex")) != 0 ) { - len = (int32_t)strlen(hexstr) >> 1; - decode_hex(serialized,len,hexstr); - vout->pk_script = serialized; - vout->pk_scriptlen = len; + n = (int32_t)strlen(hexstr) >> 1; + vout->pk_scriptlen = n; + len += iguana_rwvarint32(rwflag,&serialized[len],&vout->pk_scriptlen); + decode_hex(&serialized[len],n,hexstr); + vout->pk_script = &serialized[len]; + len += n; } } return(len); @@ -250,6 +357,7 @@ cJSON *iguana_voutjson(struct iguana_info *coin,struct iguana_msgvout *vout,int3 uint8_t space[8192]; cJSON *addrs,*skey,*json = cJSON_CreateObject(); vp = calloc(1,sizeof(*vp)); jadd64bits(json,"satoshis",vout->value); + jaddnum(json,"value",dstr(vout->value)); jaddnum(json,"n",txi); //"scriptPubKey":{"asm":"OP_DUP OP_HASH160 5f69cb73016264270dae9f65c51f60d0e4d6fd44 OP_EQUALVERIFY OP_CHECKSIG","reqSigs":1,"type":"pubkeyhash","addresses":["RHyh1V9syARTf2pyxibz7v27D5paBeWza5"]} if ( vout->pk_script != 0 && vout->pk_scriptlen*2+1 < sizeof(scriptstr) ) @@ -291,40 +399,85 @@ cJSON *iguana_voutjson(struct iguana_info *coin,struct iguana_msgvout *vout,int3 return(json); } -int32_t iguana_rwmsgtx(struct iguana_info *coin,int32_t rwflag,cJSON *json,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,bits256 *txidp,char *vpnstr) +bits256 bitcoin_sigtxid(struct iguana_info *coin,int32_t height,uint8_t *serialized,int32_t maxlen,struct iguana_msgtx *msgtx,int32_t vini,uint8_t *spendscript,int32_t spendlen,int32_t hashtype,char *vpnstr,int32_t suppress_pubkeys) { - int32_t i,n,len = 0; uint8_t *txstart = serialized; char txidstr[65]; cJSON *array=0; + int32_t i,len; bits256 sigtxid,txid,revsigtxid; struct iguana_msgtx dest; + dest = *msgtx; + memset(sigtxid.bytes,0,sizeof(sigtxid)); + if ( hashtype != SIGHASH_ALL ) + { + printf("currently only SIGHASH_ALL supported, not %d\n",hashtype); + return(sigtxid); + } + for (i=0; itx_in; i++) + { + if ( i == vini ) + { + dest.vins[i].vinscript = spendscript; + dest.vins[i].scriptlen = spendlen; + } + else + { + dest.vins[i].vinscript = (uint8_t *)""; + dest.vins[i].scriptlen = 0; + } + dest.vins[i].p2shlen = 0; + dest.vins[i].redeemscript = 0; + } + len = iguana_rwmsgtx(coin,height,1,0,serialized,maxlen,&dest,&txid,vpnstr,0,0,0,suppress_pubkeys); + if ( len > 0 ) + { +#ifdef BTC2_VERSION + if ( height >= BTC2_HARDFORK_HEIGHT ) + hashtype |= (0x777 << 20); +#endif + len += iguana_rwnum(1,&serialized[len],sizeof(hashtype),&hashtype); + revsigtxid = bits256_doublesha256(0,serialized,len); + for (i=0; iversion),&msg->version); if ( json != 0 ) { jaddnum(json,"version",msg->version); array = cJSON_CreateArray(); + if ( rwflag == 0 ) + sigser = calloc(1,maxsize*2); + //printf("json.%p array.%p sigser.%p\n",json,array,sigser); } //printf("version.%d\n",msg->version); - if ( coin->chain->hastimestamp != 0 ) + if ( coin->chain->isPoS != 0 ) { len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->timestamp),&msg->timestamp); //char str[65]; printf("version.%d timestamp.%08x %u %s\n",msg->version,msg->timestamp,msg->timestamp,utc_str(str,msg->timestamp)); if ( json != 0 ) jaddnum(json,"timestamp",msg->timestamp); } - //for (i=len; itx_in); - //printf(" tx_in.%08x\n",msg->tx_in); if ( rwflag == 0 ) { - if ( len + sizeof(struct iguana_msgvin)*msg->tx_in > maxsize ) + if ( msg->vins == 0 ) { - printf("len.%d + tx_in.%d > maxsize.%d\n",len,msg->tx_in,maxsize); - return(-1); - } - maxsize -= (sizeof(struct iguana_msgvin) * msg->tx_in); - msg->vins = (struct iguana_msgvin *)&serialized[maxsize]; + if ( sizeof(struct iguana_msgvin)*msg->tx_in > extralen ) + { + printf("(size.%d * tx_in.%d) > extralen.%d\n",(int32_t)sizeof(struct iguana_msgvin),msg->tx_in,extralen); + return(-1); + } + msg->vins = (struct iguana_msgvin *)extraspace; + extraused += (sizeof(struct iguana_msgvin) * msg->tx_in); + } else printf("unexpected non-null msg->vins.%p\n",msg->vins); memset(msg->vins,0,sizeof(struct iguana_msgvin) * msg->tx_in); } for (i=0; itx_in; i++) { + //printf("vin.%d starts offset.%d\n",i,len); if ( (n= iguana_vinparse(coin,rwflag,&serialized[len],&msg->vins[i])) < 0 ) return(-1); //printf("vin.%d n.%d len.%d\n",i,n,len); @@ -335,37 +488,50 @@ int32_t iguana_rwmsgtx(struct iguana_info *coin,int32_t rwflag,cJSON *json,uint8 return(-1); } if ( array != 0 ) - jaddi(array,iguana_vinjson(coin,&msg->vins[i])); + { + if ( sigser != 0 && vins != 0 ) + { + //set spendscript here + printf("vini.%d spendscript.%p spendlen.%d (%s)\n",i,msg->vins[i].spendscript,msg->vins[i].spendlen,jprint(jitem(vins,i),0)); + sigtxid = bitcoin_sigtxid(coin,height,sigser,maxsize*2,msg,i,msg->vins[i].spendscript,msg->vins[i].spendlen,SIGHASH_ALL,vpnstr,suppress_pubkeys); + } else memset(sigtxid.bytes,0,sizeof(sigtxid)); + jaddi(array,iguana_vinjson(coin,&msg->vins[i],sigtxid)); + } } if ( array != 0 ) { + if ( sigser != 0 ) + free(sigser); jadd(json,"vin",array); jaddnum(json,"numvins",msg->tx_in); array = cJSON_CreateArray(); } - //for (i=len; itx_out); - //printf(" txout.%d\n",msg->tx_out); if ( rwflag == 0 ) { - if ( len + sizeof(struct iguana_msgvout)*msg->tx_out > maxsize ) + if ( msg->vouts == 0 ) { - printf("len.%d + tx_in.%d > maxsize.%d\n",len,msg->tx_in,maxsize); - return(-1); - } - maxsize -= (sizeof(struct iguana_msgvout) * msg->tx_out); - msg->vouts = (struct iguana_msgvout *)&serialized[maxsize]; + if ( (extraused & 0xf) != 0 ) + extraused += 0xf - (extraused & 0xf); + if ( extraused + sizeof(struct iguana_msgvout)*msg->tx_out > extralen ) + { + printf("extraused.%d + tx_out.%d > extralen.%d\n",extraused,msg->tx_out,extralen); + return(-1); + } + msg->vouts = (struct iguana_msgvout *)&extraspace[extraused]; + extraused += (sizeof(struct iguana_msgvout) * msg->tx_out); + } else printf("unexpected non-null msg->vouts %p\n",msg->vouts); memset(msg->vouts,0,sizeof(struct iguana_msgvout) * msg->tx_out); } for (i=0; itx_out; i++) { + //printf("vout.%d starts %d\n",i,len); if ( (n= iguana_voutparse(rwflag,&serialized[len],&msg->vouts[i])) < 0 ) return(-1); len += n; if ( len > maxsize ) { - printf("invalid tx_out.%d len.%d vs maxsize.%d\n",msg->tx_out,len,maxsize); + printf("invalid tx_out.%d len.%d vs maxsize.%d n.%d\n",msg->tx_out,len,maxsize,n); return(-1); } if ( array != 0 ) @@ -401,7 +567,7 @@ int32_t iguana_rwmsgtx(struct iguana_info *coin,int32_t rwflag,cJSON *json,uint8 *txidp = bits256_doublesha256(txidstr,txstart,len); if ( json != 0 ) { - jadd64bits(json,"locktime",msg->lock_time); + jaddnum(json,"locktime",msg->lock_time); jaddnum(json,"size",len); jaddbits256(json,"txid",*txidp); //printf("TX.(%s) %p\n",jprint(json,0),json); @@ -410,67 +576,85 @@ int32_t iguana_rwmsgtx(struct iguana_info *coin,int32_t rwflag,cJSON *json,uint8 return(len); } -bits256 iguana_parsetxobj(struct supernet_info *myinfo,struct iguana_info *coin,int32_t *txstartp,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,cJSON *txobj,struct vin_info *V) // json -> serialized + (msg,V) +bits256 iguana_parsetxobj(struct supernet_info *myinfo,struct iguana_info *coin,int32_t *txstartp,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,cJSON *txobj,struct vin_info *V) { - int32_t i,numvins,numvouts,len = 0; cJSON *array=0; bits256 txid; char vpnstr[64]; + int32_t i,numvins,numvouts,len = 0,rwflag=1; cJSON *array=0; bits256 txid; char vpnstr[64]; memset(&txid,0,sizeof(txid)); + memset(msg,0,sizeof(*msg)); + *txstartp = 0; if ( txobj == 0 ) return(txid); - memset(msg,0,sizeof(*msg)); vpnstr[0] = 0; if ( (msg->version= juint(txobj,"version")) == 0 ) msg->version = 1; - if ( coin->chain->hastimestamp != 0 ) + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->version),&msg->version); + if ( coin->chain->isPoS != 0 ) { if ( (msg->timestamp= juint(txobj,"timestamp")) == 0 ) msg->timestamp = (uint32_t)time(NULL); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->timestamp),&msg->timestamp); } if ( (array= jarray(&numvins,txobj,"vin")) != 0 ) { msg->tx_in = numvins; + len += iguana_rwvarint32(rwflag,&serialized[len],&msg->tx_in); if ( len + sizeof(struct iguana_msgvin)*msg->tx_in > maxsize ) - return(msg->txid); + return(txid); maxsize -= (sizeof(struct iguana_msgvin) * msg->tx_in); msg->vins = (struct iguana_msgvin *)&serialized[maxsize]; if ( msg->tx_in > 0 && msg->tx_in*sizeof(struct iguana_msgvin) < maxsize ) { for (i=0; itx_in; i++) + { + //printf("vinobj.%d starts offset.%d\n",i,len); len += iguana_parsevinobj(myinfo,coin,&serialized[len],maxsize,&msg->vins[i],jitem(array,i),V!=0?&V[i]:0); + } } } if ( (array= jarray(&numvouts,txobj,"vout")) != 0 ) { msg->tx_out = numvouts; + len += iguana_rwvarint32(rwflag,&serialized[len],&msg->tx_out); if ( len + sizeof(struct iguana_msgvout)*msg->tx_out > maxsize ) - return(msg->txid); + return(txid); maxsize -= (sizeof(struct iguana_msgvout) * msg->tx_out); msg->vouts = (struct iguana_msgvout *)&serialized[maxsize]; if ( msg->tx_out > 0 && msg->tx_out*sizeof(struct iguana_msgvout) < maxsize ) { for (i=0; itx_out; i++) + { + //printf("parsevout.%d starts %d\n",i,len); len += iguana_parsevoutobj(coin,&serialized[len],maxsize,&msg->vouts[i],jitem(array,i)); + } } } - msg->lock_time = (int32_t)j64bits(txobj,"locktime"); - msg->txid = jbits256(txobj,"txid"); - *txstartp = len; - if ( (msg->allocsize= iguana_rwmsgtx(coin,1,0,&serialized[len],maxsize-len,msg,&txid,vpnstr)) < 0 ) + msg->lock_time = jint(txobj,"locktime"); + len += iguana_rwnum(rwflag,&serialized[len],sizeof(msg->lock_time),&msg->lock_time); + //msg->txid = jbits256(txobj,"txid"); + *txstartp = 0; + msg->allocsize = len; + msg->txid = txid = bits256_doublesha256(0,serialized,len); + //for (i=0; isuppress_pubkeys:0)) != msg->allocsize ) { - memset(txid.bytes,0,sizeof(txid)); - printf("error parsing txobj\n"); - msg->allocsize = 0; + //memset(txid.bytes,0,sizeof(txid)); + printf("error parsing txobj: expected %d got %d\n",msg->allocsize,len); + //msg->allocsize = 0; } + msg->txid = txid;*/ //char str[65]; printf("json -> %s\n",bits256_str(str,txid)); return(txid); } -char *iguana_rawtxbytes(struct iguana_info *coin,cJSON *json,struct iguana_msgtx *msgtx) +char *iguana_rawtxbytes(struct iguana_info *coin,int32_t height,cJSON *json,struct iguana_msgtx *msgtx,int32_t suppress_pubkeys) { int32_t n; char *txbytes = 0,vpnstr[64]; uint8_t *serialized; serialized = malloc(IGUANA_MAXPACKETSIZE); vpnstr[0] = 0; //char str[65]; printf("%d of %d: %s\n",i,msg.txn_count,bits256_str(str,tx.txid)); - if ( (n= iguana_rwmsgtx(coin,1,json,serialized,IGUANA_MAXPACKETSIZE,msgtx,&msgtx->txid,vpnstr)) > 0 ) + if ( (n= iguana_rwmsgtx(coin,height,1,json,serialized,IGUANA_MAXPACKETSIZE,msgtx,&msgtx->txid,vpnstr,0,0,0,suppress_pubkeys)) > 0 ) { txbytes = malloc(n*2+1); init_hexbytes_noT(txbytes,serialized,n); @@ -498,75 +682,77 @@ char *bitcoin_json2hex(struct supernet_info *myinfo,struct iguana_info *coin,bit return(txbytes); } -cJSON *bitcoin_hex2json(struct iguana_info *coin,bits256 *txidp,struct iguana_msgtx *msgtx,char *txbytes) +cJSON *bitcoin_data2json(struct iguana_info *coin,int32_t height,bits256 *txidp,struct iguana_msgtx *msgtx,uint8_t *extraspace,int32_t extralen,uint8_t *serialized,int32_t len,cJSON *vins,int32_t suppress_pubkeys) { - int32_t n,len; char vpnstr[64]; struct iguana_msgtx M; uint8_t *serialized; cJSON *txobj; + int32_t n; char vpnstr[64]; struct iguana_msgtx M; cJSON *txobj; + if ( coin == 0 || serialized == 0 ) + return(0); txobj = cJSON_CreateObject(); if ( msgtx == 0 ) - { msgtx = &M; - memset(msgtx,0,sizeof(M)); - } - len = (int32_t)strlen(txbytes) >> 1; - serialized = malloc(len + 32768); - decode_hex(serialized,len,txbytes); + memset(msgtx,0,sizeof(M)); vpnstr[0] = 0; memset(txidp,0,sizeof(*txidp)); - if ( (n= iguana_rwmsgtx(coin,0,txobj,serialized,len + 32768,msgtx,txidp,vpnstr)) <= 0 ) + if ( (n= iguana_rwmsgtx(coin,height,0,txobj,serialized,len,msgtx,txidp,vpnstr,extraspace,extralen,vins,suppress_pubkeys)) <= 0 ) { - printf("error from rwmsgtx\n"); + printf("errortxobj.(%s)\n",jprint(txobj,0)); free_json(txobj); - txobj = 0; + txobj = cJSON_CreateObject(); + jaddstr(txobj,"error","couldnt decode transaction"); + jaddstr(txobj,"coin",coin->symbol); } - free(serialized); return(txobj); } -bits256 bitcoin_sigtxid(struct iguana_info *coin,uint8_t *serialized,int32_t maxlen,struct iguana_msgtx *msgtx,int32_t vini,uint8_t *spendscript,int32_t spendlen,int32_t hashtype,char *vpnstr) +cJSON *bitcoin_hex2json(struct iguana_info *coin,int32_t height,bits256 *txidp,struct iguana_msgtx *msgtx,char *txbytes,uint8_t *extraspace,int32_t extralen,uint8_t *origserialized,cJSON *vins,int32_t suppress_pubkeys) { - int32_t i,len; bits256 sigtxid,txid,revsigtxid; struct iguana_msgtx dest; - dest = *msgtx; - memset(sigtxid.bytes,0,sizeof(sigtxid)); - if ( hashtype != SIGHASH_ALL ) - { - printf("currently only SIGHASH_ALL supported, not %d\n",hashtype); - return(sigtxid); - } - for (i=0; itx_in; i++) - { - if ( i == vini ) - { - dest.vins[i].vinscript = spendscript; - dest.vins[i].scriptlen = spendlen; - } - else - { - dest.vins[i].vinscript = (uint8_t *)""; - dest.vins[i].scriptlen = 0; - } - dest.vins[i].p2shlen = 0; - dest.vins[i].redeemscript = 0; - } - len = iguana_rwmsgtx(coin,1,0,serialized,maxlen,&dest,&txid,vpnstr); - if ( len > 0 ) - { - len += iguana_rwnum(1,&serialized[len],sizeof(hashtype),&hashtype); - revsigtxid = bits256_doublesha256(0,serialized,len); - for (i=0; i> 1; + if ( (serialized= origserialized) == 0 ) + serialized = calloc(1,len); + decode_hex(serialized,len,txbytes); + txobj = bitcoin_data2json(coin,height,txidp,msgtx,extraspace,extralen,serialized,len,vins,suppress_pubkeys); + if ( serialized != origserialized ) + free(serialized); + return(txobj); } int32_t iguana_msgtx_Vset(struct iguana_info *coin,uint8_t *serialized,int32_t maxlen,struct iguana_msgtx *msgtx,struct vin_info *V) { - int32_t vini,j,scriptlen,p2shlen,siglen,plen,len = 0; uint8_t *script; struct vin_info *vp; + int32_t vini,j,scriptlen,p2shlen,userdatalen,need_op0=0,siglen,plen,len = 0; uint8_t *script,*redeemscript=0,*userdata=0; struct vin_info *vp; for (vini=0; vinitx_in; vini++) { vp = &V[vini]; + if ( (userdatalen= vp->userdatalen) == 0 ) + { + userdatalen = vp->userdatalen = msgtx->vins[vini].userdatalen; + userdata = msgtx->vins[vini].userdata; + } else userdata = vp->userdata; + if ( (p2shlen= vp->p2shlen) == 0 ) + { + p2shlen = vp->p2shlen = msgtx->vins[vini].p2shlen; + redeemscript = msgtx->vins[vini].redeemscript; + } + else + { + redeemscript = vp->p2shscript; + msgtx->vins[vini].redeemscript = redeemscript; + } + if ( msgtx->vins[vini].spendlen > 33 && msgtx->vins[vini].spendscript[msgtx->vins[vini].spendlen - 1] == SCRIPT_OP_CHECKMULTISIG ) + { + need_op0 = 1; + printf("found multisig spendscript\n"); + } + if ( redeemscript != 0 && p2shlen > 33 && redeemscript[p2shlen - 1] == SCRIPT_OP_CHECKMULTISIG ) + { + need_op0 = 1; + printf("found multisig redeemscript\n"); + } msgtx->vins[vini].vinscript = script = &serialized[len]; msgtx->vins[vini].vinscript[0] = 0; - scriptlen = 0; + scriptlen = need_op0; for (j=0; jN; j++) { if ( (siglen= vp->signers[j].siglen) > 0 ) @@ -576,7 +762,8 @@ int32_t iguana_msgtx_Vset(struct iguana_info *coin,uint8_t *serialized,int32_t m scriptlen += siglen; } } - if ( vp->N > 1 || bitcoin_pubkeylen(&vp->spendscript[1]) != vp->spendscript[0] || vp->spendscript[vp->spendlen-1] != 0xac ) + msgtx->vins[vini].scriptlen = scriptlen; + if ( vp->suppress_pubkeys == 0 && (vp->N > 1 || bitcoin_pubkeylen(&vp->spendscript[1]) != vp->spendscript[0] || vp->spendscript[vp->spendlen-1] != 0xac) ) { for (j=0; jN; j++) { @@ -587,11 +774,18 @@ int32_t iguana_msgtx_Vset(struct iguana_info *coin,uint8_t *serialized,int32_t m scriptlen += plen; } } + msgtx->vins[vini].scriptlen = scriptlen; } - msgtx->vins[vini].scriptlen = scriptlen; - if ( (p2shlen= vp->p2shlen) > 0 ) + if ( userdatalen != 0 ) + { + memcpy(&script[scriptlen],userdata,userdatalen); + msgtx->vins[vini].userdata = &script[scriptlen]; + msgtx->vins[vini].userdatalen = userdatalen; + scriptlen += userdatalen; + } + printf("USERDATALEN.%d scriptlen.%d redeemlen.%d\n",userdatalen,scriptlen,p2shlen); + if ( p2shlen != 0 ) { - msgtx->vins[vini].redeemscript = &script[scriptlen]; if ( p2shlen < 76 ) script[scriptlen++] = p2shlen; else if ( p2shlen <= 0xff ) @@ -605,19 +799,22 @@ int32_t iguana_msgtx_Vset(struct iguana_info *coin,uint8_t *serialized,int32_t m script[scriptlen++] = (p2shlen & 0xff); script[scriptlen++] = ((p2shlen >> 8) & 0xff); } else return(-1); - memcpy(&script[scriptlen],vp->p2shscript,p2shlen), scriptlen += p2shlen; - if ( (msgtx->vins[vini].suffixlen= vp->suffixlen) > 0 ) - { - memcpy(&script[scriptlen],&vp->p2shscript[vp->p2shlen - vp->suffixlen],vp->suffixlen); - scriptlen += vp->suffixlen; - } + msgtx->vins[vini].p2shlen = p2shlen; + memcpy(&script[scriptlen],redeemscript,p2shlen); + scriptlen += p2shlen; } len += scriptlen; } + if ( 0 ) + { + int32_t i; for (i=0; itx_out; @@ -626,7 +823,7 @@ int32_t bitcoin_verifyvins(struct iguana_info *coin,bits256 *signedtxidp,char ** memset(signedtxidp,0,sizeof(*signedtxidp)); for (vini=0; vinitx_in; vini++) { - sigtxid = bitcoin_sigtxid(coin,serialized,maxlen,msgtx,vini,msgtx->vins[vini].spendscript,msgtx->vins[vini].spendlen,sighash,vpnstr); + sigtxid = bitcoin_sigtxid(coin,height,serialized,maxlen,msgtx,vini,msgtx->vins[vini].spendscript,msgtx->vins[vini].spendlen,sighash,vpnstr,suppress_pubkeys); if ( bits256_nonz(sigtxid) != 0 ) { vp = &V[vini]; @@ -635,7 +832,7 @@ int32_t bitcoin_verifyvins(struct iguana_info *coin,bits256 *signedtxidp,char ** { sig = vp->signers[j].sig; siglen = vp->signers[j].siglen; - if ( bits256_nonz(vp->signers[j].privkey) != 0 ) + if ( signtx != 0 && bits256_nonz(vp->signers[j].privkey) != 0 ) { siglen = bitcoin_sign(coin->ctx,coin->symbol,sig,sigtxid,vp->signers[j].privkey,0); if ( (plen= bitcoin_pubkeylen(vp->signers[j].pubkey)) <= 0 ) @@ -643,12 +840,12 @@ int32_t bitcoin_verifyvins(struct iguana_info *coin,bits256 *signedtxidp,char ** sig[siglen++] = sighash; vp->signers[j].siglen = siglen; /*for (i=0; isigners[j].pubkey[i]);*/ + printf("%02x",sig[i]); + printf(" sig, "); + for (i=0; isigners[j].pubkey[i]);*/ // s2 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1; - char str[65]; printf(" SIGNEDTX.[%02x] siglen.%d sigtxid.%s\n",sig[siglen-1],siglen,bits256_str(str,sigtxid)); + //char str[65]; printf(" SIGNEDTX.[%02x] siglen.%d sigtxid.%s\n",sig[siglen-1],siglen,bits256_str(str,sigtxid)); } if ( sig == 0 || siglen == 0 ) { @@ -662,145 +859,32 @@ int32_t bitcoin_verifyvins(struct iguana_info *coin,bits256 *signedtxidp,char ** } else { - printf("SIG.%d.%d VERIFIED \n",vini,j);//%s (%s)\n",vini,*signedtx,jprint(txobj,1)); flag++; numsigs++; + /*int32_t z; + for (z=0; zsigners[j].pubkey[z]); + printf(" <- pub, SIG.%d.%d VERIFIED numsigs.%d vs M.%d\n",vini,j,numsigs,vp->M);*/ } } if ( numsigs >= vp->M ) complete = 1; } - } + } //0398a4cb9f6ea7c52a4e27455028a95e2e4e397a110fb75f072c2c58a8bdcb iguana_msgtx_Vset(coin,serialized,maxlen,msgtx,V); cJSON *txobj = cJSON_CreateObject(); - *signedtx = iguana_rawtxbytes(coin,txobj,msgtx); - //printf("SIGNEDTX.(%s)\n",jprint(txobj,1)); + *signedtx = iguana_rawtxbytes(coin,height,txobj,msgtx,suppress_pubkeys); + printf("SIGNEDTX.(%s)\n",jprint(txobj,1)); *signedtxidp = msgtx->txid; return(complete); } -int32_t bitcoin_verifytx(struct iguana_info *coin,bits256 *signedtxidp,char **signedtx,char *rawtxstr,struct vin_info *V,int32_t numinputs) -{ - int32_t len,maxsize,retval = -1; uint8_t *serialized,*serialized2; - struct iguana_msgtx msgtx; bits256 txid; char vpnstr[64]; - len = (int32_t)strlen(rawtxstr); - maxsize = len + 32768; - serialized = calloc(1,maxsize), serialized2 = calloc(1,maxsize); - len >>= 1; - vpnstr[0] = 0; - decode_hex(serialized,len,rawtxstr); - memset(&msgtx,0,sizeof(msgtx)); - if ( iguana_rwmsgtx(coin,0,0,serialized,maxsize,&msgtx,&txid,vpnstr) > 0 && numinputs == msgtx.tx_in ) - { - if ( bitcoin_verifyvins(coin,signedtxidp,signedtx,&msgtx,serialized2,maxsize,V,SIGHASH_ALL) == 0 ) - retval = 0; - else printf("bitcoin_verifytx: bitcoin_verifyvins error\n"); - } else printf("bitcoin_verifytx: error iguana_rwmsgtx\n"); - free(serialized), free(serialized2); - return(retval); -} - -cJSON *iguana_signtx(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,char **signedtxp,struct bitcoin_spend *spend,cJSON *txobj,cJSON *vins) -{ - int32_t i,j,m,n,plen; char *rawtxstr,*pubkeystr,*spendstr; struct vin_info *V,*vp; bits256 txid; struct iguana_waccount *wacct; struct iguana_waddress *waddr; cJSON *vitem,*vinsobj,*pubkeys; - V = calloc(spend->numinputs,sizeof(*V)); - if ( *signedtxp != 0 ) - { - if ( txobj != 0 ) - free_json(txobj); - txobj = bitcoin_hex2json(coin,&txid,0,*signedtxp); - if ( vins != 0 ) - { - if ( jobj(txobj,"vin") != 0 ) - jdelete(txobj,"vin"); - jadd(txobj,"vin",iguana_createvins(myinfo,coin,txobj,vins)); - } - //printf("bitcoin_hex2json (%s)\n",jprint(txobj,0)); - free(*signedtxp); - } - vinsobj = jarray(&n,txobj,"vin"); - for (i=0; inuminputs; i++) // N times less efficient, but for small number of inputs ok - { - vp = &V[i]; - if ( i < n ) - { - if ( (vitem= jitem(vinsobj,i)) != 0 && ((spendstr= jstr(vitem,"scriptPub")) != 0 || (spendstr= jstr(vitem,"scriptPubKey")) != 0) ) - { - vp->spendlen = (int32_t)strlen(spendstr) >> 1; - decode_hex(vp->spendscript,vp->spendlen,spendstr); - } else spendstr = 0; - } - else vitem = 0; - vp->N = vp->M = 1; - if ( (rawtxstr= bitcoin_json2hex(myinfo,coin,&txid,txobj,0)) != 0 ) - { - for (j=0; jinputs[i].privkeys)/sizeof(*spend->inputs[i].privkeys); j++) - { - if ( bits256_nonz(spend->inputs[i].privkeys[j]) != 0 ) - { - vp->signers[j].privkey = spend->inputs[i].privkeys[j]; - bitcoin_pubkey33(coin->ctx,vp->signers[j].pubkey,vp->signers[j].privkey); - } - else - { - vp->signers[j].pubkey[0] = 0; - break; - } - } - if ( vitem != 0 && (pubkeys= jarray(&m,vitem,"pubkeys")) != 0 )//spend->inputs[i].numpubkeys > 0 ) - { - for (j=0; jinputs[i].privkeys)/sizeof(*spend->inputs[i].privkeys); j++) - { - if ( j < m && (pubkeystr= jstr(jitem(pubkeys,j),0)) != 0 && is_hexstr(pubkeystr,(int32_t)strlen(pubkeystr)) > 0 ) - decode_hex(vp->signers[j].pubkey,(int32_t)strlen(pubkeystr)>>1,pubkeystr); - else if ( (plen= bitcoin_pubkeylen(spend->inputs[i].pubkeys[j])) > 0 ) - memcpy(vp->signers[j].pubkey,spend->inputs[i].pubkeys[j],plen); - } - } - /*if ( spend->inputs[i].spendlen > 0 ) - { - memcpy(vp->spendscript,spend->inputs[i].spendscript,spend->inputs[i].spendlen); - vp->spendlen = spend->inputs[i].spendlen; - }*/ - if ( spend->inputs[i].p2shlen > 0 ) - { - memcpy(vp->p2shscript,spend->inputs[i].p2shscript,spend->inputs[i].p2shlen); - vp->p2shlen = spend->inputs[i].p2shlen; - } - for (j=0; jinputs[i].privkeys)/sizeof(*spend->inputs[i].privkeys); j++) - { - if ( vp->signers[j].coinaddr[0] == 0 && (plen= bitcoin_pubkeylen(spend->inputs[i].pubkeys[j])) > 0 ) - { - bitcoin_address(vp->signers[j].coinaddr,coin->chain->pubtype,spend->inputs[i].pubkeys[j],plen); - } - } - if ( myinfo->expiration != 0 ) - { - for (j=0; jinputs[i].privkeys)/sizeof(*spend->inputs[i].privkeys); j++) - { - if ( bits256_nonz(vp->signers[j].privkey) == 0 && vp->signers[j].coinaddr[0] != 0 ) - { - if ( (waddr= iguana_waddresssearch(myinfo,coin,&wacct,vp->signers[j].coinaddr)) != 0 ) - vp->signers[j].privkey = waddr->privkey; - } - } - } - vp->sequence = spend->inputs[i].sequence; - //printf("json2hex.(%s)\n",rawtxstr); - } - } - bitcoin_verifytx(coin,txidp,signedtxp,rawtxstr,V,spend->numinputs); - //printf("json2hex.(%s)\n",rawtxstr); - free(rawtxstr); - if ( *signedtxp != 0 && i != spend->numinputs ) - free(*signedtxp), *signedtxp = 0; - free(V); - return(txobj); -} - int32_t iguana_vininfo_create(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msgtx,cJSON *vins,int32_t numinputs,struct vin_info *V) { - int32_t i,plen,len = 0; struct vin_info *vp; struct iguana_waccount *wacct; struct iguana_waddress *waddr; uint32_t sigsize,pubkeysize,p2shsize,suffixlen; + int32_t i,plen,finalized = 1,len = 0; struct vin_info *vp; struct iguana_waccount *wacct; struct iguana_waddress *waddr; uint32_t sigsize,pubkeysize,p2shsize,userdatalen; msgtx->tx_in = numinputs; maxsize -= (sizeof(struct iguana_msgvin) * msgtx->tx_in); msgtx->vins = (struct iguana_msgvin *)&serialized[maxsize]; @@ -811,15 +895,17 @@ int32_t iguana_vininfo_create(struct supernet_info *myinfo,struct iguana_info *c { vp = &V[i]; len += iguana_parsevinobj(myinfo,coin,&serialized[len],maxsize,&msgtx->vins[i],jitem(vins,i),vp); + if ( msgtx->vins[i].sequence < IGUANA_SEQUENCEID_FINAL ) + finalized = 0; if ( msgtx->vins[i].spendscript == 0 ) { - if ( (vp->unspentind= iguana_unspentindfind(coin,vp->coinaddr,vp->spendscript,&vp->spendlen,&vp->amount,&vp->height,msgtx->vins[i].prev_hash,msgtx->vins[i].prev_vout,coin->bundlescount-1)) > 0 ) + if ( (vp->unspentind= iguana_RTunspentindfind(myinfo,coin,vp->coinaddr,vp->spendscript,&vp->spendlen,&vp->amount,&vp->height,msgtx->vins[i].prev_hash,msgtx->vins[i].prev_vout,coin->bundlescount-1,0)) > 0 ) { msgtx->vins[i].spendscript = vp->spendscript; msgtx->vins[i].spendlen = vp->spendlen; - vp->hashtype = iguana_vinscriptparse(coin,V,&sigsize,&pubkeysize,&p2shsize,&suffixlen,vp->spendscript,vp->spendlen); - vp->suffixlen = suffixlen; - printf("V %.8f (%s) spendscript.[%d]\n",dstr(vp->amount),vp->coinaddr,vp->spendlen); + vp->hashtype = iguana_vinscriptparse(coin,vp,&sigsize,&pubkeysize,&p2shsize,&userdatalen,vp->spendscript,vp->spendlen); + vp->userdatalen = userdatalen; + printf("V %.8f (%s) spendscript.[%d] userdatalen.%d\n",dstr(vp->amount),vp->coinaddr,vp->spendlen,userdatalen); } } else @@ -830,7 +916,9 @@ int32_t iguana_vininfo_create(struct supernet_info *myinfo,struct iguana_info *c if ( (plen= bitcoin_pubkeylen(vp->signers[0].pubkey)) > 0 ) bitcoin_address(vp->coinaddr,coin->chain->pubtype,vp->signers[0].pubkey,plen); } - if ( vp->coinaddr[i] != 0 && (waddr= iguana_waddresssearch(myinfo,coin,&wacct,vp->coinaddr)) != 0 ) + if ( vp->M == 0 && vp->N == 0 ) + vp->M = vp->N = 1; + if ( vp->coinaddr[i] != 0 && (waddr= iguana_waddresssearch(myinfo,&wacct,vp->coinaddr)) != 0 ) { vp->signers[0].privkey = waddr->privkey; if ( (plen= bitcoin_pubkeylen(waddr->pubkey)) != vp->spendscript[1] || vp->spendscript[vp->spendlen-1] != 0xac ) @@ -839,20 +927,18 @@ int32_t iguana_vininfo_create(struct supernet_info *myinfo,struct iguana_info *c memcpy(vp->signers[0].pubkey,waddr->pubkey,plen); } } - if ( vp->M == 0 && vp->N == 0 ) - vp->M = vp->N = 1; } } /*for (i=0; itx_out; i++) - { - if ( msgtx->vouts[i].pk_script != 0 ) - { - for (j=0; jvouts[i].pk_scriptlen; j++) - printf("%02x",msgtx->vouts[i].pk_script[j]); - printf(" pk_script[%d]\n",i); - } - }*/ - return(len); + { + if ( msgtx->vouts[i].pk_script != 0 ) + { + for (j=0; jvouts[i].pk_scriptlen; j++) + printf("%02x",msgtx->vouts[i].pk_script[j]); + printf(" pk_script[%d]\n",i); + } + }*/ + return(finalized); } void iguana_ensure_privkey(struct supernet_info *myinfo,struct iguana_info *coin,bits256 privkey) @@ -861,13 +947,13 @@ void iguana_ensure_privkey(struct supernet_info *myinfo,struct iguana_info *coin bitcoin_pubkey33(myinfo->ctx,pubkey33,privkey); bitcoin_address(coinaddr,coin->chain->pubtype,pubkey33,33); //printf("privkey for (%s)\n",coinaddr); - if ( myinfo->expiration != 0 && ((waddr= iguana_waddresssearch(myinfo,coin,&wacct,coinaddr)) == 0 || bits256_nonz(waddr->privkey) == 0) ) + if ( myinfo->expiration != 0 && ((waddr= iguana_waddresssearch(myinfo,&wacct,coinaddr)) == 0 || bits256_nonz(waddr->privkey) == 0) ) { if ( waddr == 0 ) { memset(&addr,0,sizeof(addr)); iguana_waddresscalc(myinfo,coin->chain->pubtype,coin->chain->wiftype,&addr,privkey); - if ( (wacct= iguana_waccountfind(myinfo,coin,"default")) != 0 ) + if ( (wacct= iguana_waccountfind(myinfo,"default")) != 0 ) waddr = iguana_waddressadd(myinfo,coin,wacct,&addr,0); } if ( waddr != 0 ) @@ -875,10 +961,10 @@ void iguana_ensure_privkey(struct supernet_info *myinfo,struct iguana_info *coin waddr->privkey = privkey; if ( bitcoin_priv2wif(waddr->wifstr,waddr->privkey,coin->chain->wiftype) > 0 ) { - if ( waddr->wiftype != coin->chain->wiftype ) + if ( 0 && waddr->wiftype != coin->chain->wiftype ) printf("ensurepriv warning: mismatched wiftype %02x != %02x\n",waddr->wiftype,coin->chain->wiftype); - if ( waddr->addrtype != coin->chain->pubtype ) - printf("ensurepriv warning: mismatched wiftype %02x != %02x\n",waddr->addrtype,coin->chain->pubtype); + if ( 0 && waddr->addrtype != coin->chain->pubtype ) + printf("ensurepriv warning: mismatched addrtype %02x != %02x\n",waddr->addrtype,coin->chain->pubtype); } } } @@ -901,7 +987,7 @@ int32_t bitcoin_txaddspend(struct iguana_info *coin,cJSON *txobj,char *destaddre { bitcoin_addr2rmd160(&addrtype,rmd160,destaddress); scriptlen = bitcoin_standardspend(outputscript,0,rmd160); - bitcoin_txoutput(coin,txobj,outputscript,scriptlen,satoshis); + bitcoin_txoutput(txobj,outputscript,scriptlen,satoshis); return(0); } else return(-1); } @@ -944,12 +1030,12 @@ cJSON *iguana_scriptpubkeys(struct iguana_info *coin,uint8_t *script,int32_t scr void iguana_addscript(struct iguana_info *coin,cJSON *dest,uint8_t *script,int32_t scriptlen,char *fieldname) { char *scriptstr,scriptbuf[8192+256]; int32_t maxlen; cJSON *scriptobj; - if ( scriptlen < 0 ) + if ( scriptlen < 0 || scriptlen > IGUANA_MAXSCRIPTSIZE || scriptlen > sizeof(scriptbuf) ) return; - if ( scriptlen > sizeof(scriptbuf) ) - maxlen = (scriptlen << 1) + 2048, scriptstr = malloc(maxlen); - else scriptstr = scriptbuf, maxlen = sizeof(scriptbuf); + scriptstr = scriptbuf, maxlen = sizeof(scriptbuf); init_hexbytes_noT(scriptstr,script,scriptlen); + if ( strcmp(fieldname,"userdata") == 0 ) + printf("SCRIPT_USERDATA.(%s)\n",scriptstr); if ( strcmp(fieldname,"coinbase") == 0 ) jaddstr(dest,"coinbase",scriptstr); else @@ -1008,27 +1094,19 @@ cJSON *bitcoin_txinput(struct iguana_info *coin,cJSON *txobj,bits256 txid,int32_ return(txobj); } -cJSON *bitcoin_txcreate(struct iguana_info *coin,int64_t locktime) +cJSON *bitcoin_txcreate(int32_t isPoS,int64_t locktime,uint32_t txversion) { cJSON *json = cJSON_CreateObject(); - if ( locktime == 0 ) - { - jaddnum(json,"version",1); - jadd64bits(json,"locktime",0); - } - else - { - jaddnum(json,"version",4); - jadd64bits(json,"locktime",locktime); - } - if ( coin->chain->hastimestamp != 0 ) + jaddnum(json,"version",txversion); + jaddnum(json,"locktime",locktime); + if ( isPoS != 0 ) jaddnum(json,"timestamp",time(NULL)); jadd(json,"vin",cJSON_CreateArray()); jadd(json,"vout",cJSON_CreateArray()); return(json); } -cJSON *bitcoin_txoutput(struct iguana_info *coin,cJSON *txobj,uint8_t *paymentscript,int32_t len,uint64_t satoshis) +cJSON *bitcoin_txoutput(cJSON *txobj,uint8_t *paymentscript,int32_t len,uint64_t satoshis) { char *hexstr; cJSON *item,*skey,*vouts = jduplicate(jobj(txobj,"vout")); jdelete(txobj,"vout"); @@ -1046,24 +1124,51 @@ cJSON *bitcoin_txoutput(struct iguana_info *coin,cJSON *txobj,uint8_t *paymentsc return(txobj); } -int32_t iguana_interpreter(struct iguana_info *coin,int64_t nLockTime,struct vin_info *V,int32_t numvins) +int32_t iguana_interpreter(struct iguana_info *coin,cJSON *logarray,int64_t nLockTime,struct vin_info *V,int32_t numvins) { - uint8_t script[IGUANA_MAXSCRIPTSIZE]; int32_t vini,scriptlen,errs = 0; cJSON *spendscript; + uint8_t script[IGUANA_MAXSCRIPTSIZE],*activescript; char str[IGUANA_MAXSCRIPTSIZE*2+1]; int32_t vini,scriptlen,activescriptlen,errs = 0; cJSON *spendscript,*item; for (vini=0; vini 0 ) + { + activescript = V[vini].p2shscript; + activescriptlen = V[vini].p2shlen; + } + else + { + activescript = V[vini].spendscript; + activescriptlen = V[vini].spendlen; + } + spendscript = iguana_spendasm(coin,activescript,activescriptlen); + //printf("interpreter.(%s)\n",jprint(spendscript,0)); + if ( (scriptlen= bitcoin_assembler(coin,logarray,script,spendscript,1,nLockTime,&V[vini])) < 0 ) { errs++; } - else if ( scriptlen != V[vini].spendlen || memcmp(script,V[vini].spendscript,scriptlen) != 0 ) + else if ( scriptlen != activescriptlen || memcmp(script,activescript,scriptlen) != 0 ) { + if ( logarray != 0 ) + { + item = cJSON_CreateObject(); + jaddstr(item,"error","script reconstruction failed"); + init_hexbytes_noT(str,activescript,activescriptlen); + jaddstr(item,"original",str); + init_hexbytes_noT(str,script,scriptlen); + jaddstr(item,"reconstructed",str); + jaddi(logarray,item); + } else printf("scriptlen mismatch.%d vs %d or miscompare\n",scriptlen,V[vini].spendlen); errs++; } } if ( errs != 0 ) return(-errs); - else return(0); + if ( logarray != 0 ) + { + item = cJSON_CreateObject(); + jaddstr(item,"result","success"); + jaddi(logarray,item); + } + return(0); } #include "../includes/iguana_apidefs.h" @@ -1072,7 +1177,7 @@ int32_t iguana_interpreter(struct iguana_info *coin,int64_t nLockTime,struct vin P2SH_SPENDAPI(iguana,spendmsig,activecoin,vintxid,vinvout,destaddress,destamount,destaddress2,destamount2,M,N,pubA,wifA,pubB,wifB,pubC,wifC) { - struct vin_info V; uint8_t p2sh_rmd160[20],serialized[2096],spendscript[32],pubkeys[3][65],*pubkeyptrs[3]; int32_t spendlen; + struct vin_info V; uint8_t p2sh_rmd160[20],serialized[2096],spendscript[32],pubkeys[3][65],*pubkeyptrs[3]; int32_t spendlen,height = 0; char msigaddr[64],*retstr; cJSON *retjson,*txobj; struct iguana_info *active; bits256 signedtxid; char *signedtx; struct iguana_msgtx msgtx; @@ -1085,7 +1190,7 @@ P2SH_SPENDAPI(iguana,spendmsig,activecoin,vintxid,vinvout,destaddress,destamount if ( M > N || N > 3 ) return(clonestr("{\"error\":\"illegal M or N\"}")); memset(&V,0,sizeof(V)); - txobj = bitcoin_txcreate(active,0); + txobj = bitcoin_txcreate(active->chain->isPoS,0,coin->chain->normal_txversion); if ( destaddress[0] != 0 && destamount > 0. ) bitcoin_txaddspend(active,txobj,destaddress,destamount * SATOSHIDEN); if ( destaddress2[0] != 0 && destamount2 > 0. ) @@ -1117,7 +1222,7 @@ P2SH_SPENDAPI(iguana,spendmsig,activecoin,vintxid,vinvout,destaddress,destamount bitcoin_txinput(active,txobj,vintxid,vinvout,0xffffffff,spendscript,spendlen,V.p2shscript,V.p2shlen,pubkeyptrs,N); bitcoin_address(msigaddr,active->chain->p2shtype,V.p2shscript,V.p2shlen); retjson = cJSON_CreateObject(); - if ( bitcoin_verifyvins(active,&signedtxid,&signedtx,&msgtx,serialized,sizeof(serialized),&V,SIGHASH_ALL) == 0 ) + if ( bitcoin_verifyvins(active,height,&signedtxid,&signedtx,&msgtx,serialized,sizeof(serialized),&V,SIGHASH_ALL,1,V.suppress_pubkeys) == 0 ) { jaddstr(retjson,"result","msigtx"); if ( signedtx != 0 ) @@ -1128,29 +1233,37 @@ P2SH_SPENDAPI(iguana,spendmsig,activecoin,vintxid,vinvout,destaddress,destamount return(jprint(retjson,1)); } -int32_t iguana_signrawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_msgtx *msgtx,char **signedtxp,bits256 *signedtxidp,struct vin_info *V,int32_t numinputs,char *rawtx,cJSON *vins,cJSON *privkeys) +int32_t iguana_signrawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,int32_t height,struct iguana_msgtx *msgtx,char **signedtxp,bits256 *signedtxidp,struct vin_info *V,int32_t numinputs,char *rawtx,cJSON *vins,cJSON *privkeys) { - uint8_t *serialized,*serialized2,*serialized3; int32_t i,len,n,maxsize,complete = 0; char *checkstr,*privkeystr,*signedtx = 0; bits256 privkey,txid; cJSON *item; cJSON *txobj = 0; + uint8_t *serialized,*serialized2,*serialized3,*serialized4,*extraspace; int32_t finalized,i,len,n,maxsize,complete = 0,extralen = 65536; char *checkstr,*privkeystr,*signedtx = 0; bits256 privkey,txid; cJSON *item; cJSON *txobj = 0; maxsize = 1000000; if ( rawtx != 0 && rawtx[0] != 0 && (len= (int32_t)strlen(rawtx)>>1) < maxsize ) { serialized = malloc(maxsize); serialized2 = malloc(maxsize); serialized3 = malloc(maxsize); + serialized4 = malloc(maxsize); + extraspace = malloc(extralen); memset(msgtx,0,sizeof(*msgtx)); decode_hex(serialized,len,rawtx); - if ( (txobj= bitcoin_hex2json(coin,&txid,msgtx,rawtx)) != 0 ) + if ( (txobj= bitcoin_hex2json(coin,height,&txid,msgtx,rawtx,extraspace,extralen,serialized4,vins,V->suppress_pubkeys)) != 0 ) { - //printf("txobj.(%s)\n",jprint(txobj,0)); - if ( (checkstr= bitcoin_json2hex(myinfo,coin,&txid,txobj,0)) != 0 ) + //if ( vins != 0 ) + // printf("vins.(%s)\n",jprint(vins,0)); + if ( jobj(txobj,"error") != 0 ) + { + printf("txobj.(%s)\n",jprint(txobj,0)); + } + if ( 0 && (checkstr= bitcoin_json2hex(myinfo,coin,&txid,txobj,V)) != 0 ) { if ( strcmp(rawtx,checkstr) != 0 ) { printf("RAW.(%s) ->\nNEW.(%s)\n",rawtx,checkstr); - free_json(txobj); - free(checkstr); - free(serialized), free(serialized2), free(serialized3); - return(-2); + //free_json(txobj); + //free(checkstr); + //free(serialized), free(serialized2), free(serialized3), free(serialized4); + //free(extraspace); + //return(-2); } free(checkstr); } @@ -1158,7 +1271,7 @@ int32_t iguana_signrawtransaction(struct supernet_info *myinfo,struct iguana_inf if ( (numinputs= cJSON_GetArraySize(vins)) > 0 ) { memset(msgtx,0,sizeof(*msgtx)); - if ( iguana_rwmsgtx(coin,0,0,serialized,maxsize,msgtx,&txid,"") > 0 && numinputs == msgtx->tx_in ) + if ( iguana_rwmsgtx(coin,height,0,0,serialized,maxsize,msgtx,&txid,"",extraspace,65536,vins,V->suppress_pubkeys) > 0 && numinputs == msgtx->tx_in ) { if ( (n= cJSON_GetArraySize(privkeys)) > 0 ) { @@ -1167,17 +1280,25 @@ int32_t iguana_signrawtransaction(struct supernet_info *myinfo,struct iguana_inf item = jitem(privkeys,i); privkeystr = jstr(item,0); privkey = iguana_str2priv(myinfo,coin,privkeystr); + V->signers[i].privkey = privkey; if ( bits256_nonz(privkey) != 0 ) iguana_ensure_privkey(myinfo,coin,privkey); } } - iguana_vininfo_create(myinfo,coin,serialized2,maxsize,msgtx,vins,numinputs,V); - if ( (complete= bitcoin_verifyvins(coin,signedtxidp,&signedtx,msgtx,serialized3,maxsize,V,SIGHASH_ALL)) > 0 ) + finalized = iguana_vininfo_create(myinfo,coin,serialized2,maxsize,msgtx,vins,numinputs,V); + if ( (complete= bitcoin_verifyvins(coin,height,signedtxidp,&signedtx,msgtx,serialized3,maxsize,V,SIGHASH_ALL,1,V->suppress_pubkeys)) > 0 && signedtx != 0 ) { - iguana_interpreter(coin,j64bits(txobj,"locktime"),V,numinputs); + int32_t tmp; + if ( (tmp= iguana_interpreter(coin,0,iguana_lockval(finalized,jint(txobj,"locktime")),V,numinputs)) < 0 ) + { + printf("iguana_interpreter %d error.(%s)\n",tmp,signedtx); + complete = 0; + } } } } + free(extraspace); + free(serialized), free(serialized2), free(serialized3), free(serialized4); } else return(-1); if ( txobj != 0 ) free_json(txobj); @@ -1202,7 +1323,7 @@ STRING_ARRAY_OBJ_STRING(bitcoinrpc,signrawtransaction,rawtx,vins,privkeys,sighas { V = calloc(numinputs,sizeof(*V)); memset(&msgtx,0,sizeof(msgtx)); - if ( (complete= iguana_signrawtransaction(myinfo,coin,&msgtx,&signedtx,&signedtxid,V,numinputs,rawtx,vins,privkeys)) >= 0 ) + if ( (complete= iguana_signrawtransaction(myinfo,coin,coin->blocks.hwmchain.height,&msgtx,&signedtx,&signedtxid,V,numinputs,rawtx,vins,privkeys)) >= 0 ) { if ( signedtx != 0 ) { diff --git a/iguana/iguana_spendvectors.c b/iguana/iguana_spendvectors.c index f63a71c1c..3c11f0d8f 100755 --- a/iguana/iguana_spendvectors.c +++ b/iguana/iguana_spendvectors.c @@ -56,7 +56,7 @@ int32_t iguana_spendvectorsave(struct iguana_info *coin,struct iguana_bundle *bp int32_t i,retval = -1; FILE *fp; char fname[1024],str[65]; long fsize; bits256 zero,sha256; if ( ptr == 0 || (bp->hdrsi != 0 && ptr == bp->ramchain.Xspendinds) ) { - //printf("iguana_spendvectorsave.[%d] ptr.%p Xspendinds\n",bp->hdrsi,ptr); + printf("iguana_spendvectorsave.[%d] ptr.%p Xspendinds\n",bp->hdrsi,ptr); return(0); } memset(zero.bytes,0,sizeof(zero)); @@ -72,7 +72,7 @@ int32_t iguana_spendvectorsave(struct iguana_info *coin,struct iguana_bundle *bp { if ( fwrite(sha256.bytes,1,sizeof(sha256),fp) != sizeof(sha256) ) printf("error writing hash for %d -> (%s)\n",(int32_t)(sizeof(*ptr) * emit),fname); - else if ( fwrite(ptr,sizeof(*ptr),emit,fp) != emit ) + else if ( emit != 0 && fwrite(ptr,sizeof(*ptr),emit,fp) != emit ) printf("error writing %d of %d -> (%s)\n",emit,n,fname); else { @@ -93,98 +93,96 @@ int32_t iguana_spendvectorsave(struct iguana_info *coin,struct iguana_bundle *bp //int32_t i; for (i=0; inumXspends; i++) // printf("(%d u%d) ",ramchain->Xspendinds[i].hdrsi,ramchain->Xspendinds[i].ind); //printf("filesize %ld Xspendptr.%p %p num.%d\n",fsize,ramchain->Xspendptr,ramchain->Xspendinds,ramchain->numXspends); - } - else printf("iguana_spendvectors: Error creating.(%s)\n",fname); + } else printf("iguana_spendvectors: Error creating.(%s)\n",fname); return(retval); } struct iguana_bundle *iguana_externalspent(struct iguana_info *coin,bits256 *prevhashp,uint32_t *unspentindp,struct iguana_ramchain *ramchain,int32_t spent_hdrsi,struct iguana_spend *s,int32_t prefetchflag) { - int32_t prev_vout,height,hdrsi; uint32_t sequenceid,unspentind; char str[65]; - struct iguana_bundle *spentbp=0; struct iguana_txid *T,TX,*tp; bits256 *X; bits256 prev_hash; - X = RAMCHAIN_PTR(ramchain->H.data,Xoffset); - T = RAMCHAIN_PTR(ramchain->H.data,Toffset); - //X = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Xoffset); - //T = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Toffset); - //printf("external X.%p %ld num.%d\n",X,(long)ramchain->H.data->Xoffset,(int32_t)ramchain->H.data->numexternaltxids); - sequenceid = s->sequenceid; - hdrsi = spent_hdrsi; - *unspentindp = 0; - memset(prevhashp,0,sizeof(*prevhashp)); - if ( s->prevout < 0 ) + int32_t prev_vout,height,hdrsi; uint32_t sequenceid,unspentind; char str[65]; struct iguana_bundle *spentbp=0; struct iguana_txid *T,TX,*tp; bits256 *X; bits256 prev_hash; struct iguana_ramchaindata *rdata; + if ( (rdata= ramchain->H.data) != 0 ) { - //printf("n.%d coinbase at spendind.%d firstvin.%d -> firstvout.%d -> unspentind\n",m,spendind,nextT->firstvin,nextT->firstvout); - //nextT++; - //m++; - return(0); - } - else - { - prev_vout = s->prevout; - iguana_ramchain_spendtxid(coin,&unspentind,&prev_hash,T,ramchain->H.data->numtxids,X,ramchain->H.data->numexternaltxids,s); - *prevhashp = prev_hash; - *unspentindp = unspentind; - if ( unspentind == 0 ) + X = RAMCHAIN_PTR(rdata,Xoffset); + T = RAMCHAIN_PTR(rdata,Toffset); + sequenceid = s->sequenceid; + hdrsi = spent_hdrsi; + *unspentindp = 0; + memset(prevhashp,0,sizeof(*prevhashp)); + if ( s->prevout < 0 ) + { + //printf("n.%d coinbase at spendind.%d firstvin.%d -> firstvout.%d -> unspentind\n",m,spendind,nextT->firstvin,nextT->firstvout); + //nextT++; + //m++; + return(0); + } + else { - //double duration,startmillis = OS_milliseconds(); - if ( (tp= iguana_txidfind(coin,&height,&TX,prev_hash,spent_hdrsi-1)) != 0 ) + prev_vout = s->prevout; + iguana_ramchain_spendtxid(coin,&unspentind,&prev_hash,T,rdata->numtxids,X,rdata->numexternaltxids,s); + *prevhashp = prev_hash; + *unspentindp = unspentind; + if ( unspentind == 0 ) { - *unspentindp = unspentind = TX.firstvout + ((prev_vout > 0) ? prev_vout : 0); - hdrsi = height / coin->chain->bundlesize; - if ( hdrsi >= 0 && hdrsi < coin->bundlescount && (spentbp= coin->bundles[hdrsi]) != 0 ) + //double duration,startmillis = OS_milliseconds(); + if ( (tp= iguana_txidfind(coin,&height,&TX,prev_hash,spent_hdrsi-1)) != 0 ) { - //printf("%s height.%d firstvout.%d prev.%d ->U%d\n",bits256_str(str,prev_hash),height,TX.firstvout,prev_vout,unspentind); - /*now = (uint32_t)time(NULL); - duration = (OS_milliseconds() - startmillis); - if ( 0 && ((uint64_t)coin->txidfind_num % 1000000) == 1 ) - printf("%p iguana_txidfind.[%.0f] ave %.2f micros, total %.2f seconds | duration %.3f millis\n",spentbp->ramchain.txbits,coin->txidfind_num,(coin->txidfind_totalmillis*1000.)/coin->txidfind_num,coin->txidfind_totalmillis/1000.,duration); - coin->txidfind_totalmillis += duration; - coin->txidfind_num += 1.;*/ - if ( 1 && coin->PREFETCHLAG > 0 ) + *unspentindp = unspentind = TX.firstvout + ((prev_vout > 0) ? prev_vout : 0); + hdrsi = height / coin->chain->bundlesize; + if ( hdrsi >= 0 && hdrsi < coin->bundlescount && (spentbp= coin->bundles[hdrsi]) != 0 ) { - if ( spentbp->lastprefetch == 0 ) + //printf("%s height.%d firstvout.%d prev.%d ->U%d\n",bits256_str(str,prev_hash),height,TX.firstvout,prev_vout,unspentind); + /*now = (uint32_t)time(NULL); + duration = (OS_milliseconds() - startmillis); + if ( 0 && ((uint64_t)coin->txidfind_num % 1000000) == 1 ) + printf("%p iguana_txidfind.[%.0f] ave %.2f micros, total %.2f seconds | duration %.3f millis\n",spentbp->ramchain.txbits,coin->txidfind_num,(coin->txidfind_totalmillis*1000.)/coin->txidfind_num,coin->txidfind_totalmillis/1000.,duration); + coin->txidfind_totalmillis += duration; + coin->txidfind_num += 1.;*/ + if ( 1 && coin->PREFETCHLAG > 0 ) { - iguana_ramchain_prefetch(coin,&spentbp->ramchain,prefetchflag); - spentbp->lastprefetch = (uint32_t)time(NULL); + if ( spentbp->lastprefetch == 0 ) + { + iguana_ramchain_prefetch(coin,&spentbp->ramchain,prefetchflag); + spentbp->lastprefetch = (uint32_t)time(NULL); + } + /*else if ( 0 && (rand() % IGUANA_NUMHELPERS) == 0 && (duration > 10 || duration > (10 * coin->txidfind_totalmillis)/coin->txidfind_num) ) + { + printf("slow txidfind %.2f vs %.2f prefetch[%d] from.[%d] lag.%ld last.%u\n",duration,coin->txidfind_totalmillis/coin->txidfind_num,spentbp->hdrsi,ramchain->height/coin->chain->bundlesize,time(NULL) - spentbp->lastprefetch,spentbp->lastprefetch); + iguana_ramchain_prefetch(coin,ramchain,1); + //spentbp->lastprefetch = now; + }*/ } - /*else if ( 0 && (rand() % IGUANA_NUMHELPERS) == 0 && (duration > 10 || duration > (10 * coin->txidfind_totalmillis)/coin->txidfind_num) ) - { - printf("slow txidfind %.2f vs %.2f prefetch[%d] from.[%d] lag.%ld last.%u\n",duration,coin->txidfind_totalmillis/coin->txidfind_num,spentbp->hdrsi,ramchain->height/coin->chain->bundlesize,time(NULL) - spentbp->lastprefetch,spentbp->lastprefetch); - iguana_ramchain_prefetch(coin,ramchain,1); - //spentbp->lastprefetch = now; - }*/ + } + else + { + printf("illegal hdrsi.%d prev_hash.(%s) for bp.[%d]\n",hdrsi,bits256_str(str,prev_hash),spent_hdrsi); + exit(-1); } } else { - printf("illegal hdrsi.%d prev_hash.(%s) for bp.[%d]\n",hdrsi,bits256_str(str,prev_hash),spent_hdrsi); - exit(-1); - } - } - else - { - printf("cant find prev_hash.(%s) for bp.[%d]\n",bits256_str(str,prev_hash),spent_hdrsi); - if ( spent_hdrsi < coin->current->hdrsi ) - { - iguana_bundleremove(coin,spent_hdrsi,1); - exit(-1); + printf("cant find prev_hash.(%s) for bp.[%d]\n",bits256_str(str,prev_hash),spent_hdrsi); + if ( spent_hdrsi < coin->current->hdrsi ) + { + iguana_bundleremove(coin,spent_hdrsi,1); + exit(-1); + } + coin->RTdatabad = 1; + return(0); } - coin->RTdatabad = 1; - return(0); - } - } else printf("external spent unexpected nonz unspentind [%d]\n",spent_hdrsi); + } else printf("external spent unexpected nonz unspentind [%d]\n",spent_hdrsi); + } + if ( (spentbp= coin->bundles[hdrsi]) == 0 || hdrsi > spent_hdrsi ) + printf("%s illegal hdrsi.%d when [%d] spentbp.%p\n",coin->symbol,hdrsi,spent_hdrsi,spentbp); + else if ( unspentind == 0 || unspentind >= spentbp->ramchain.H.data->numunspents ) + printf("%s illegal unspentind.%d vs max.%d spentbp.%p[%d]\n",coin->symbol,unspentind,spentbp->ramchain.H.data->numunspents,spentbp,hdrsi); + else return(spentbp); + iguana_bundleremove(coin,spent_hdrsi,1); } - if ( (spentbp= coin->bundles[hdrsi]) == 0 || hdrsi > spent_hdrsi ) - printf("illegal hdrsi.%d when [%d] spentbp.%p\n",hdrsi,spent_hdrsi,spentbp); - else if ( unspentind == 0 || unspentind >= spentbp->ramchain.H.data->numunspents ) - printf("illegal unspentind.%d vs max.%d spentbp.%p[%d]\n",unspentind,spentbp->ramchain.H.data->numunspents,spentbp,hdrsi); - else return(spentbp); - iguana_bundleremove(coin,spent_hdrsi,1); - exit(-1); + //exit(-1); return(0); } -struct iguana_bundle *iguana_fastexternalspent(struct iguana_info *coin,bits256 *prevhashp,uint32_t *unspentindp,struct iguana_ramchain *ramchain,int32_t spent_hdrsi,struct iguana_spend *s) +struct iguana_bundle *iguana_fastexternalspent(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *prevhashp,uint32_t *unspentindp,struct iguana_ramchain *ramchain,int32_t spent_hdrsi,struct iguana_spend *s) { int32_t prev_vout,height,hdrsi,unspentind; uint32_t ind; struct iguana_txid *T; bits256 *X; bits256 prev_hash; struct iguana_ramchaindata *rdata; @@ -204,7 +202,7 @@ struct iguana_bundle *iguana_fastexternalspent(struct iguana_info *coin,bits256 X = RAMCHAIN_PTR(rdata,Xoffset); //X = (void *)(long)((long)rdata + rdata->Xoffset); *prevhashp = prev_hash = X[ind]; - if ( (unspentind= iguana_unspentindfind(coin,0,0,0,0,&height,prev_hash,prev_vout,spent_hdrsi-1)) != 0 ) + if ( (unspentind= iguana_unspentindfind(myinfo,coin,0,0,0,0,&height,prev_hash,prev_vout,spent_hdrsi-1,0)) != 0 ) //if ( (firstvout= iguana_txidfastfind(coin,&height,prev_hash,spent_hdrsi-1)) >= 0 ) { /*duration = (OS_milliseconds() - startmillis); @@ -235,7 +233,7 @@ struct iguana_bundle *iguana_fastexternalspent(struct iguana_info *coin,bits256 return(0); } -int32_t iguana_spendvectors(struct iguana_info *coin,struct iguana_bundle *bp,struct iguana_ramchain *ramchain,int32_t starti,int32_t numblocks,int32_t convertflag,int32_t iterate) +int32_t iguana_spendvectors(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_bundle *bp,struct iguana_ramchain *ramchain,int32_t starti,int32_t numblocks,int32_t convertflag,int32_t iterate) { static uint64_t total,emitted; int32_t iter,spendind,n=0,txidind,errs=0,emit=0,i,j,k; double startmillis; bits256 prevhash; @@ -243,15 +241,20 @@ int32_t iguana_spendvectors(struct iguana_info *coin,struct iguana_bundle *bp,st struct iguana_bundle *spentbp; struct iguana_blockRO *B; struct iguana_spendvector *ptr; struct iguana_unspent *u,*spentU; struct iguana_txid *T; char str[65]; struct iguana_spend *S,*s; //void *fastfind = 0; - //printf("iguana_spendvectors.[%d] gen.%d ramchain data.%p txbits.%p\n",bp->hdrsi,bp->bundleheight,ramchain->H.data,ramchain->txbits); + //printf("iguana_spendvectors.[%d] gen.%d ramchain data.%p txbits.%p\n",bp->hdrsi,bp->bundleheight,rdata,ramchain->txbits); + if ( ramchain->H.data == 0 ) + { + printf("AUTO volatilesalloc [%d]\n",bp->hdrsi); + iguana_volatilesalloc(coin,ramchain,0); + } if ( (rdata= ramchain->H.data) == 0 || (n= rdata->numspends) < 1 ) { printf("iguana_spendvectors.[%d]: no rdata.%p %d\n",bp->hdrsi,rdata,n); return(0); } - B = (void *)(long)((long)rdata + rdata->Boffset); - S = (void *)(long)((long)rdata + rdata->Soffset); - T = (void *)(long)((long)rdata + rdata->Toffset); + B = RAMCHAIN_PTR(rdata,Boffset); + S = RAMCHAIN_PTR(rdata,Soffset); + T = RAMCHAIN_PTR(rdata,Toffset); if ( ramchain->Xspendinds != 0 ) { bp->tmpspends = ramchain->Xspendinds; @@ -308,7 +311,7 @@ int32_t iguana_spendvectors(struct iguana_info *coin,struct iguana_bundle *bp,st { if ( coin->fastfind != 0 ) { - spentbp = iguana_fastexternalspent(coin,&prevhash,&spent_unspentind,ramchain,bp->hdrsi,s); + spentbp = iguana_fastexternalspent(myinfo,coin,&prevhash,&spent_unspentind,ramchain,bp->hdrsi,s); } else if ( spentbp == 0 ) { @@ -396,14 +399,14 @@ int32_t iguana_spendvectors(struct iguana_info *coin,struct iguana_bundle *bp,st free(coin->fast[iter]); coin->fast[iter] = fastfind; }*/ - if ( txidind != ramchain->H.data->numtxids && txidind != ramchain->H.txidind ) + if ( txidind != rdata->numtxids && txidind != ramchain->H.txidind ) { - printf("spendvectors: numtxid.%d != bp numtxids %d/%d\n",txidind,ramchain->H.txidind,ramchain->H.data->numtxids); + printf("spendvectors: numtxid.%d != bp numtxids %d/%d\n",txidind,ramchain->H.txidind,rdata->numtxids); errs++; } - if ( spendind != ramchain->H.data->numspends && spendind != ramchain->H.spendind ) + if ( spendind != rdata->numspends && spendind != ramchain->H.spendind ) { - printf("spendvectors: spendind.%d != bp numspends %d/%d\n",spendind,ramchain->H.spendind,ramchain->H.data->numspends); + printf("spendvectors: spendind.%d != bp numspends %d/%d\n",spendind,ramchain->H.spendind,rdata->numspends); errs++; } } @@ -442,17 +445,25 @@ int32_t iguana_spendvectors(struct iguana_info *coin,struct iguana_bundle *bp,st int32_t iguana_balancegen(struct iguana_info *coin,int32_t incremental,struct iguana_bundle *bp,int32_t starti,int32_t endheight,int32_t startemit) { - uint32_t spent_unspentind,spent_pkind,txidind,h,i,j,endi,k,now; uint64_t spent_value; + uint32_t spent_unspentind,spent_pkind,unspentind,txidind,h,i,j,endi,k,now; uint64_t spent_value; struct iguana_ramchain *ramchain; struct iguana_ramchaindata *rdata; - struct iguana_spendvector *spend; struct iguana_unspent *spentU,*u; struct iguana_spendvector *Xspendinds; - struct iguana_txid *T; struct iguana_blockRO *B; struct iguana_bundle *spentbp; + struct iguana_spendvector *spend; struct iguana_unspent *spentU,*u,*U; struct iguana_spendvector *Xspendinds; + struct iguana_txid *T; struct iguana_blockRO *B; struct iguana_bundle *spentbp; struct iguana_pkhash *P; //struct iguana_utxoaddr *utxoaddr; int32_t spent_hdrsi,spendind,n,numXspends,errs=0,emit=0; struct iguana_spend *S,*s; - ramchain = &bp->ramchain; //(bp == coin->current) ? &coin->RTramchain : &bp->ramchain; - if ( (rdata= ramchain->H.data) == 0 || (n= ramchain->H.data->numspends) < 1 ) + /*if ( (starti % coin->chain->bundlesize) != 0 || (endheight % coin->chain->bundlesize) != coin->chain->bundlesize-1 ) + ramchain = &coin->RTramchain; + else*/ ramchain = &bp->ramchain; + starti %= coin->chain->bundlesize; + if ( (rdata= ramchain->H.data) == 0 || (n= rdata->numspends) < 1 ) return(-1); - S = (void *)(long)((long)rdata + rdata->Soffset); - B = (void *)(long)((long)rdata + rdata->Boffset); - T = (void *)(long)((long)rdata + rdata->Toffset); + S = RAMCHAIN_PTR(rdata,Soffset); + B = RAMCHAIN_PTR(rdata,Boffset); + T = RAMCHAIN_PTR(rdata,Toffset); + U = RAMCHAIN_PTR(rdata,Uoffset); + P = RAMCHAIN_PTR(rdata,Poffset); + //S = (void *)(long)((long)rdata + rdata->Soffset); + //B = (void *)(long)((long)rdata + rdata->Boffset); + //T = (void *)(long)((long)rdata + rdata->Toffset); numXspends = ramchain->numXspends; if ( (Xspendinds= ramchain->Xspendinds) == 0 ) { @@ -463,32 +474,47 @@ int32_t iguana_balancegen(struct iguana_info *coin,int32_t incremental,struct ig //return(-1); } } - endi = (endheight % bp->n); + endi = (endheight % coin->chain->bundlesize); txidind = B[starti].firsttxidind; spendind = B[starti].firstvin; + unspentind = B[starti].firstvout; emit = startemit; - if ( coin->RTheight == 0 || bp->bundleheight+bp->n < coin->RTheight ) + if ( 0 && (coin->RTheight == 0 || bp->bundleheight+bp->n < coin->RTheight) ) fprintf(stderr,"BALANCEGEN.[%d] %p[%d] starti.%d s%d <-> endi.%d s%d startemit.%d\n",bp->hdrsi,Xspendinds,numXspends,starti,spendind,endi,B[endi].firstvin+B[endi].numvins,startemit); for (i=starti; i<=endi; i++) { now = (uint32_t)time(NULL); if ( 0 && bp == coin->current ) printf("hdrs.[%d] B[%d] 1st txidind.%d txn_count.%d firstvin.%d firstvout.%d\n",bp->hdrsi,i,B[i].firsttxidind,B[i].txn_count,B[i].firstvin,B[i].firstvout); - if ( txidind != B[i].firsttxidind || spendind != B[i].firstvin ) + if ( txidind != B[i].firsttxidind || spendind != B[i].firstvin || unspentind != B[i].firstvout ) { - printf("balancegen: txidind %u != %u B[%d].firsttxidind || spendind %u != %u B[%d].firstvin errs.%d\n",txidind,B[i].firsttxidind,i,spendind,B[i].firstvin,i,errs); + printf("balancegen: txidind %u != %u B[%d].firsttxidind || spendind %u != %u B[%d].firstvin errs.%d (%u != %u)\n",txidind,B[i].firsttxidind,i,spendind,B[i].firstvin,i,errs,unspentind,B[i].firstvout); return(-1); } for (j=0; jcurrent ) printf("starti.%d txidind.%d txi.%d numvins.%d spendind.%d\n",i,txidind,j,T[txidind].numvins,spendind); + /*if ( bp == coin->current )//ramchain == &coin->RTramchain ) + { + for (k=0; khdrsi,u->pkind,P[u->pkind].rmd160,&coin->RTprev)) != 0 ) + { + utxoaddr->RTcredits += u->value; + coin->RTcredits += u->value; + //printf("[%d] u%u += %.8f\n",bp->hdrsi,u->pkind,dstr(u->value)); + } else printf("cant find utxoaddr\n"); + } + } else */ + unspentind += T[txidind].numvouts; for (k=0; kspendtxidind].firstvout + s->prevout; spentU = RAMCHAIN_PTR(rdata,Uoffset); - //spentU = (void *)(long)((long)rdata + rdata->Uoffset); u = &spentU[spent_unspentind]; if ( (spent_pkind= u->pkind) != 0 && spent_pkind < rdata->numpkinds ) spent_value = u->value; - /*found spend d9151... txidind.1083097 [202] s3163977 - //found spend d9151... txidind.1083097 [202] s4033628 - if ( spent_hdrsi == 202 && (spendind == 3163977 || spendind == 4033628) ) - printf("internal spend.%d spendtxidind.%d 1st.%d U.(prevout.%d u%u pkind.%u %.8f)\n",spendind,txidind,T[s->spendtxidind].firstvout,s->prevout,spent_unspentind,u->pkind,dstr(u->value));*/ + // printf("internal spend.%d spendtxidind.%d 1st.%d U.(prevout.%d u%u pkind.%u %.8f)\n",spendind,txidind,T[s->spendtxidind].firstvout,s->prevout,spent_unspentind,u->pkind,dstr(u->value));*/ } else //if ( i > 0 || j > 0 || k > 0 ) { @@ -540,7 +562,7 @@ int32_t iguana_balancegen(struct iguana_info *coin,int32_t incremental,struct ig { if ( 0 && bp == coin->current ) printf("[%d] spendind.%u -> [%d] u%d\n",bp->hdrsi,spendind,spent_hdrsi,spent_unspentind); - if ( iguana_volatileupdate(coin,incremental,spentbp == coin->current ? &coin->RTramchain : &spentbp->ramchain,spent_hdrsi,spent_unspentind,spent_pkind,spent_value,spendind,h) < 0 ) + if ( iguana_volatileupdate(coin,incremental,&spentbp->ramchain,spent_hdrsi,spent_unspentind,spent_pkind,spent_value,spendind,h) < 0 ) //(spentbp == coin->current) ? &coin->RTramchain : errs++; } else //if ( Xspendinds != 0 ) @@ -551,14 +573,14 @@ int32_t iguana_balancegen(struct iguana_info *coin,int32_t incremental,struct ig } } } - if ( txidind != bp->ramchain.H.data->numtxids && (bp != coin->current || txidind != ramchain->H.txidind) ) + if ( txidind != ramchain->H.data->numtxids && (bp != coin->current || txidind != ramchain->H.txidind) ) { - printf("numtxid.%d != bp numtxids %d/%d\n",txidind,bp->ramchain.H.txidind,bp->ramchain.H.data->numtxids); + printf("numtxid.%d != bp numtxids %d/%d\n",txidind,ramchain->H.txidind,ramchain->H.data->numtxids); errs++; } - if ( spendind != ramchain->H.data->numspends && (bp != coin->current || spendind != ramchain->H.spendind) ) + if ( spendind != rdata->numspends && (bp != coin->current || spendind != ramchain->H.spendind) ) { - printf("spendind.%d != bp numspends %d/%d\n",spendind,bp->ramchain.H.spendind,bp->ramchain.H.data->numspends); + printf("spendind.%d != bp numspends %d/%d\n",spendind,ramchain->H.spendind,ramchain->H.data->numspends); errs++; } if ( emit != numXspends ) @@ -587,20 +609,20 @@ void iguana_truncatebalances(struct iguana_info *coin) coin->balanceswritten = 0; } -int32_t iguana_volatilesinit(struct iguana_info *coin) +int32_t iguana_volatilesinit(struct supernet_info *myinfo,struct iguana_info *coin) { bits256 balancehash,allbundles; struct iguana_utxo *Uptr; struct iguana_account *Aptr; struct sha256_vstate vstate,bstate; int32_t i,from_ro,numpkinds,numunspents; struct iguana_bundle *bp; struct iguana_block *block; uint32_t crc,filecrc; FILE *fp; char crcfname[512],str[65],str2[65],buf[2048]; from_ro = 1; - for (i=0; ibalanceswritten; i++) + for (i=0; ibundlescount; i++)//balanceswritten; i++) { if ( (bp= coin->bundles[i]) == 0 ) - break; + continue; if ( bp->emitfinish <= 1 || (i > 0 && bp->utxofinish <= 1) ) { - printf("hdrsi.[%d] emitfinish.%u utxofinish.%u\n",i,bp->emitfinish,bp->utxofinish); - break; + //printf("hdrsi.[%d] emitfinish.%u utxofinish.%u\n",i,bp->emitfinish,bp->utxofinish); + continue; } iguana_volatilesmap(coin,&bp->ramchain); if ( from_ro != 0 && (bp->ramchain.from_ro == 0 || (bp->hdrsi > 0 && bp->ramchain.from_roX == 0) || bp->ramchain.from_roA == 0 || bp->ramchain.from_roU == 0) ) @@ -609,12 +631,12 @@ int32_t iguana_volatilesinit(struct iguana_info *coin) from_ro = 0; } } - if ( i < coin->balanceswritten-1 ) + /*if ( i < coin->balanceswritten-1 ) { printf("TRUNCATE balances written.%d -> %d\n",coin->balanceswritten,i); iguana_truncatebalances(coin); } - else + else*/ { coin->balanceswritten = i; //printf("verify crc and sha256 hash for %d of %d\n",i,coin->balanceswritten); @@ -688,25 +710,36 @@ int32_t iguana_volatilesinit(struct iguana_info *coin) } } } - if ( (coin->RTheight= coin->balanceswritten * coin->chain->bundlesize) > coin->longestchain ) - coin->longestchain = coin->RTheight; - iguana_bundlestats(coin,buf,IGUANA_DEFAULTLAG); - if ( (bp= coin->bundles[coin->balanceswritten-1]) != 0 && (block= bp->blocks[bp->n-1]) != 0 ) + //if ( (coin->RTheight= (coin->balanceswritten-1) * coin->chain->bundlesize) > coin->longestchain ) + // coin->longestchain = coin->RTheight; + iguana_bundlestats(myinfo,coin,buf,IGUANA_DEFAULTLAG); + if ( (bp= coin->bundles[coin->bundlescount-1]) != 0 && (block= bp->blocks[bp->n-1]) != 0 ) { - //char str[65]; - //printf("set hwmchain.%d <- %s %p\n",bp->bundleheight+bp->n-1,bits256_str(str,bp->hashes[bp->n-1]),block); if ( block->height > coin->blocks.hwmchain.height ) - coin->blocks.hwmchain = *block; + { + char str[65]; + printf("set hwmchain.%d <- %s %p\n",block->height,bits256_str(str,bp->hashes[bp->n-1]),block); + iguana_blockzcopy(coin->chain->zcash,(void *)&coin->blocks.hwmchain,block); + } } //printf("end volatilesinit\n"); if ( iguana_fastfindinit(coin) == 0 )//&& coin->PREFETCHLAG >= 0 ) iguana_fastfindcreate(coin); - return(coin->balanceswritten); + /*for (j=0; jbundlescount; j++) + if ( (bp= coin->bundles[j]) != 0 ) + { + iguana_volatilesalloc(coin,&bp->ramchain,1); + iguana_volatilesmap(coin,&bp->ramchain); + } + iguana_update_balances(coin);*/ + iguana_datachain_scan(myinfo,coin,CRYPTO777_RMD160); + //iguana_utxoaddr_gen(myinfo,coin,(coin->bundlescount - 1) * coin->chain->bundlesize);*/ + return(coin->bundlescount); } -void iguana_initfinal(struct iguana_info *coin,bits256 lastbundle) +void iguana_initfinal(struct supernet_info *myinfo,struct iguana_info *coin,bits256 lastbundle) { - int32_t i; struct iguana_bundle *bp; bits256 hash2; struct iguana_block *block; char hashstr[65]; + int32_t i,hdrsi,bundlei,height; struct iguana_bundle *bp; bits256 hash2; struct iguana_block *block; char hashstr[65]; if ( bits256_nonz(lastbundle) > 0 ) { init_hexbytes_noT(hashstr,lastbundle.bytes,sizeof(bits256)); @@ -742,10 +775,11 @@ void iguana_initfinal(struct iguana_info *coin,bits256 lastbundle) } printf("i.%d bundlescount.%d\n",i,coin->bundlescount); if ( coin->balanceswritten > 1 ) - coin->balanceswritten = iguana_volatilesinit(coin); + coin->balanceswritten = iguana_volatilesinit(myinfo,coin); if ( coin->balanceswritten > 1 ) { - for (i=0; ibalanceswritten; i++) + //for (i=0; ibalanceswritten; i++) + for (i=0; ibundlescount; i++) { //printf("%d ",i); iguana_validateQ(coin,coin->bundles[i]); @@ -754,7 +788,7 @@ void iguana_initfinal(struct iguana_info *coin,bits256 lastbundle) printf("i.%d balanceswritten.%d\n",i,coin->balanceswritten); if ( coin->balanceswritten < coin->bundlescount ) { - for (i=coin->balanceswritten; ibundlescount; i++) + for (i=0*coin->balanceswritten; ibundlescount; i++) { if ( (bp= coin->bundles[i]) != 0 && bp->queued == 0 ) { @@ -765,16 +799,29 @@ void iguana_initfinal(struct iguana_info *coin,bits256 lastbundle) printf("iguana_bundlesQ %d to %d\n",coin->balanceswritten,coin->bundlescount); } if ( (coin->origbalanceswritten= coin->balanceswritten) > 0 ) - iguana_volatilesinit(coin); + iguana_volatilesinit(myinfo,coin); iguana_savehdrs(coin); iguana_fastlink(coin,coin->balanceswritten * coin->chain->bundlesize - 1); iguana_walkchain(coin,0); hash2 = iguana_blockhash(coin,coin->balanceswritten * coin->chain->bundlesize); if ( bits256_nonz(hash2) != 0 && (block= iguana_blockfind("initfinal",coin,hash2)) != 0 ) - _iguana_chainlink(coin,block); + { + for (height=0; heightbundlescount*coin->chain->bundlesize; height++) + { + if ( _iguana_chainlink(myinfo,coin,block) == 0 ) + break; + if ( coin->virtualchain == 0 ) + break; + bundlei = (height % coin->chain->bundlesize); + hdrsi = (height / coin->chain->bundlesize); + if ( (bp= coin->bundles[hdrsi]) == 0 || (block= bp->blocks[bundlei]) == 0 ) + break; + } + printf("%s height.%d hwm.%d\n",coin->symbol,height,coin->blocks.hwmchain.height); + } } -int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi) +int32_t iguana_balanceflush(struct supernet_info *myinfo,struct iguana_info *coin,int32_t refhdrsi) { int32_t hdrsi,numpkinds,iter,numhdrsi,i,numunspents,err; struct iguana_bundle *bp; char fname[1024],fname2[1024],destfname[1024]; bits256 balancehash,allbundles; FILE *fp,*fp2; @@ -812,7 +859,8 @@ int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi) if ( fwrite(Uptr,sizeof(*Uptr),numunspents,fp2) == numunspents ) { err = 0; - printf("[%d] of %d saved (%s) and (%s)\n",hdrsi,numhdrsi,fname,fname2); + if ( (hdrsi % 100) == 0 ) + printf("[%d] of %d saved (%s) and (%s)\n",hdrsi,numhdrsi,fname,fname2); } } } @@ -846,7 +894,8 @@ int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi) printf("balances error copying (%s) -> (%s)\n",fname2,destfname); return(-1); } - printf("%s -> %s\n",fname,destfname); + if ( (hdrsi % 100) == 0 ) + printf("%s -> %s\n",fname,destfname); OS_removefile(fname,0); OS_removefile(fname2,0); } @@ -856,9 +905,9 @@ int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi) break; } } - else if ( hdrsi > 0 && (coin->current == 0 || hdrsi != coin->current->hdrsi) ) + else if ( hdrsi > 0 && hdrsi != coin->bundlescount && (coin->current == 0 || hdrsi != coin->current->hdrsi ) ) { - printf("balanceflush iter.%d error loading [%d] Aptr.%p Uptr.%p numpkinds.%u numunspents.%u\n",iter,hdrsi,Aptr,Uptr,numpkinds,numunspents); + printf("balanceflush num.%d iter.%d error loading [%d] Aptr.%p Uptr.%p numpkinds.%u numunspents.%u\n",coin->bundlescount,iter,hdrsi,Aptr,Uptr,numpkinds,numunspents); return(-1); } } @@ -868,7 +917,7 @@ int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi) coin->balanceswritten = numhdrsi; if ( 1 ) { - for (hdrsi=0; hdrsibundles[hdrsi]) == 0 && bp != coin->current ) { iguana_volatilespurge(coin,&bp->ramchain); @@ -877,12 +926,14 @@ int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi) } } char str[65]; printf("BALANCES WRITTEN for %d orig.%d bundles %s\n",coin->balanceswritten,coin->origbalanceswritten,bits256_str(str,coin->balancehash)); + //iguana_utxoaddr_gen(myinfo,coin,(coin->balanceswritten - 1) * coin->chain->bundlesize); if ( 0 && coin->balanceswritten > coin->origbalanceswritten+10 ) // strcmp(coin->symbol,"BTC") == 0 && { coin->active = 0; coin->started = 0; - for (i=0; ipeers.active[i].dead = (uint32_t)time(NULL); + if ( coin->peers != 0 ) + for (i=0; ipeers->active[i].dead = (uint32_t)time(NULL); #ifdef __linux__ char cmd[1024]; sprintf(cmd,"mksquashfs %s/%s %s.%d -comp xz",GLOBAL_DBDIR,coin->symbol,coin->symbol,coin->balanceswritten); @@ -908,15 +959,16 @@ int32_t iguana_balanceflush(struct iguana_info *coin,int32_t refhdrsi) } exit(-1); } - coin->balanceswritten = iguana_volatilesinit(coin); + coin->balanceswritten = iguana_volatilesinit(myinfo,coin); //printf("flush free\n"); - iguana_RTramchainfree(coin,bp); + iguana_RTdataset_free(coin); + //iguana_RTramchainfree(coin,bp); return(coin->balanceswritten); } int32_t iguana_spendvectorsaves(struct iguana_info *coin) { - int32_t i,j,n,iter; struct iguana_bundle *bp; + int32_t i,j,n,iter; struct iguana_bundle *bp; struct iguana_ramchaindata *rdata; if ( coin->spendvectorsaved > 1 ) return(0); coin->spendvectorsaved = 1; @@ -940,7 +992,7 @@ int32_t iguana_spendvectorsaves(struct iguana_info *coin) } } } - else if ( iguana_spendvectorsave(coin,bp,&bp->ramchain,bp->tmpspends,bp->numtmpspends,bp->ramchain.H.data->numspends) == 0 ) + else if ( (rdata= bp->ramchain.H.data) != 0 && iguana_spendvectorsave(coin,bp,&bp->ramchain,bp->tmpspends,bp->numtmpspends,rdata->numspends) == 0 ) { if ( bp->tmpspends != 0 && bp->numtmpspends > 0 && bp->tmpspends != bp->ramchain.Xspendinds ) myfree(bp->tmpspends,sizeof(*bp->tmpspends) * bp->numtmpspends); @@ -951,6 +1003,7 @@ int32_t iguana_spendvectorsaves(struct iguana_info *coin) } } coin->spendvectorsaved = (uint32_t)time(NULL); + coin->spendvalidated = 0; return(0); } @@ -1031,7 +1084,7 @@ int32_t iguana_convert(struct iguana_info *coin,int32_t helperid,struct iguana_b total[helperid % max] += converted; for (i=sum=0; icurrent ) printf("[%4d] millis %7.3f converted.%-7d balance calc.%-4d of %4d | total.%llu of %llu depth.%d\n",bp->hdrsi,OS_milliseconds()-startmillis,converted,m,n,(long long)sum,(long long)total_tmpspends,(int32_t)depth); } depth--; @@ -1041,16 +1094,16 @@ int32_t iguana_convert(struct iguana_info *coin,int32_t helperid,struct iguana_b int32_t iguana_bundlevalidate(struct iguana_info *coin,struct iguana_bundle *bp,int32_t forceflag) { static int32_t totalerrs,totalvalidated; - FILE *fp; char fname[1024]; uint8_t *blockspace; uint32_t now = (uint32_t)time(NULL); + FILE *fp; char fname[1024]; uint8_t *blockspace; //uint32_t now = (uint32_t)time(NULL); int32_t i,max,len,errs = 0; struct sha256_vstate vstate; bits256 validatehash; int64_t total = 0; - if ( (coin->VALIDATENODE == 0 && coin->RELAYNODE == 0) || bp->ramchain.from_ro != 0 || bp == coin->current ) + if ( (coin->MAXPEERS > 1 && coin->VALIDATENODE == 0 && coin->FULLNODE == 0) || bp->ramchain.from_ro != 0 || bp == coin->current ) { bp->validated = (uint32_t)time(NULL); return(bp->n); } if ( bp->validated <= 1 || forceflag != 0 ) { - //printf("validate.[%d]\n",bp->hdrsi); + //printf("validate.[%d] forceflag.%d\n",bp->hdrsi,forceflag); vupdate_sha256(validatehash.bytes,&vstate,0,0); sprintf(fname,"%s/%s/validated/%d",GLOBAL_DBDIR,coin->symbol,bp->bundleheight); //printf("validatefname.(%s)\n",fname); @@ -1068,7 +1121,7 @@ int32_t iguana_bundlevalidate(struct iguana_info *coin,struct iguana_bundle *bp, } if ( forceflag != 0 || bp->validated <= 1 ) { - max = sizeof(coin->blockspace); + max = coin->blockspacesize; blockspace = calloc(1,max); iguana_volatilesmap(coin,&bp->ramchain); for (i=0; in; i++) @@ -1087,7 +1140,10 @@ int32_t iguana_bundlevalidate(struct iguana_info *coin,struct iguana_bundle *bp, } free(blockspace); bp->validated = (uint32_t)time(NULL); - printf("VALIDATED.[%d] ht.%d duration.%d errs.%d total.%lld %u | total errs.%d validated.%d %llx\n",bp->hdrsi,bp->bundleheight,bp->validated - now,errs,(long long)total,bp->validated,totalerrs,totalvalidated,(long long)validatehash.txid); + // printf("VALIDATED.[%d] ht.%d duration.%d errs.%d total.%lld %u | total errs.%d validated.%d %llx\n",bp->hdrsi,bp->bundleheight,bp->validated - now,errs,(long long)total,bp->validated,totalerrs,totalvalidated,(long long)validatehash.txid); + //iguana_volatilesmap(coin,&bp->ramchain); + //if ( bp == coin->current ) + // coin->RTdatabad = -1; } if ( errs == 0 && fp == 0 ) { diff --git a/iguana/iguana_stake.c b/iguana/iguana_stake.c index 5eedb3a84..fe36b9429 100644 --- a/iguana/iguana_stake.c +++ b/iguana/iguana_stake.c @@ -1,25 +1,104 @@ -#ifdef reference // modify time.1462237906 modifier.baed58b98a00e41d +#include "iguana777.h" + +#define CENT (SATOSHIDEN / 100) +#define COIN_YEAR_REWARD ((int64_t)5 * CENT) // 5% per year +#define NCOINBASEMATURITY 100 +#define STAKE_TIMESTAMP_MASK 15 + +#define NTARGETSPACING 60 // BitcoinDark - 1 minute +#define NTARGETTIMESPAN (60 * NTARGETSPACING) // BitcoinDark - every 1 hour +#define NINTERVAL_MSPACING (((NTARGETTIMESPAN / NTARGETSPACING) - 1) * NTARGETSPACING) +#define NINTERVAL_PSPACING (((NTARGETTIMESPAN / NTARGETSPACING) + 1) * NTARGETSPACING) -static const int64_t COIN_YEAR_REWARD = 5 * CENT; // 5% per year -int nCoinbaseMaturity = 100; -static const int STAKE_TIMESTAMP_MASK = 15; +#define NSTAKESPLITAGE (1 * 24 * NTARGETTIMESPAN) +#define NSTAKE_MINAGE (8 * NTARGETTIMESPAN) // BitcoinDark - 8 hours +#define NSTAKEMAXAGE ((int64_t)-1) +#define NMAXSTAKESEARCHINTERVAL 60 +#define NSTAKECOMBINETHRESHOLD (1000 * COIN) -// MODIFIER_INTERVAL_RATIO: // ratio of group interval length between the last group and the first group -static const int MODIFIER_INTERVAL_RATIO = 3; +#define MODIFIER_INTERVAL_RATIO 3 +#define NMODIFIERINTERVAL (10 * NTARGETSPACING) // BitcoinDark - time to elapse before new modifier is -CBigNum bnProofOfStakeLimit(~uint256(0) >> 20); -CBigNum bnProofOfStakeLimitV2(~uint256(0) >> 48); +// miner's coin stake reward based on coin age spent (coin-days) +int64_t iguana_POSreward(int64_t nCoinAge, int64_t nFees) +{ + int64_t nSubsidy = (nCoinAge * COIN_YEAR_REWARD * 33) / (365 * 33 + 8); + return(nSubsidy + nFees); +} -unsigned int nTargetSpacing = 1 * 60; // BitcoinDark - 1 minute -static const int64_t nTargetTimespan = 60 * 60; // BitcoinDark - every 1 hour -unsigned int nStakeMinAge = 8 * 60 * 60; // BitcoinDark - 8 hours -unsigned int nStakeMaxAge = -1; -unsigned int nModifierInterval = 10 * 60; // BitcoinDark - time to elapse before new modifier is +// maximum nBits value could possible be required nTime after +uint32_t iguana_maxbits(bits256 targetval,uint32_t nBits,int64_t nTime) +{ + bits256 bitsval; + bitsval = bits256_from_compact(nBits); + bitsval = bits256_lshift(bitsval); + while ( nTime > 0 && bits256_cmp(bitsval,targetval) < 0 ) + { + bitsval = bits256_rshift(bitsval); // Maximum 200% adjustment per day... + nTime -= 24 * 60 * 60; + } + if ( bits256_cmp(bitsval,targetval) > 0 ) + bitsval = targetval; + return(bits256_to_compact(bitsval)); +} -unsigned int nStakeSplitAge = 1 * 24 * 60 * 60; -int64_t nStakeCombineThreshold = 1000 * COIN; +bits256 iguana_targetval(struct iguana_info *coin,int32_t height,int32_t PoSflag) +{ + int32_t i; bits256 targetval; + if ( PoSflag == 0 ) + return(coin->chain->PoWtarget); + else + { + targetval = coin->chain->PoStargets[0]; + for (i=0; ichain->numPoStargets; i++) + { + if ( height < coin->chain->PoSheights[i] ) + break; + targetval = coin->chain->PoStargets[i]; + } + } + return(targetval); +} + +// minimum amount of stake that could possibly be required nTime after +// minimum proof-of-stake required was nBase +uint32_t iguana_minstake(struct iguana_info *coin,int32_t height,uint32_t nBits,int64_t nTime,uint32_t nBlockTime) +{ + return(iguana_maxbits(iguana_targetval(coin,height,1),nBits,nTime)); +} + +uint32_t iguana_targetbits(struct iguana_info *coin,struct iguana_block *hwmchain,struct iguana_block *prev,struct iguana_block *prev2,int32_t PoSflag,int32_t targetspacing,int32_t targettimespan) +{ + // targetspacing NTARGETSPACING, mspacing NINTERVAL_MSPACING, pspacing NINTERVAL_PSPACING + bits256 mpz_muldivcmp(bits256 oldval,int32_t mulval,int32_t divval,bits256 cmpval); + bits256 targetval; int32_t gap,mspacing,pspacing; + if ( hwmchain->height <= 2 || hwmchain->height <= 0 ) + return(hwmchain->RO.bits); + mspacing = (((targettimespan / targetspacing) - 1) * targetspacing); + pspacing = (((targettimespan / targetspacing) + 1) * targetspacing); + targetval = iguana_targetval(coin,hwmchain->height,PoSflag); + if ( prev != 0 ) + { + if ( prev2 != 0 && prev->RO.timestamp != 0 && prev2->RO.timestamp != 0 ) + { + //if ( prev->RO.timestamp != 0 && prev2->RO.timestamp != 0 ) skip check for compatiblity + { + if ( (gap= prev->RO.timestamp - prev2->RO.timestamp) < 0 ) + gap = targetspacing; + //printf("nBits.%08x gap.%d (%u - %u)\n",prev->RO.bits,gap,prev->RO.timestamp,prev2->RO.timestamp); + targetval = mpz_muldivcmp(bits256_from_compact(prev->RO.bits),mspacing + (gap << 1),pspacing,targetval); + } + } + } + return(bits256_to_compact(targetval)); +} + +#ifdef reference + +CBigNum bnProofOfStakeLimit(~uint256(0) >> 20); +CBigNum bnProofOfStakeLimitV2(~uint256(0) >> 48); enum { @@ -29,26 +108,24 @@ enum }; uint64_t nStakeModifier; // hash modifier for proof-of-stake -unsigned int nStakeModifierChecksum; // checksum of index; in-memeory only +uint32_t nStakeModifierChecksum; // checksum of index; in-memory only uint256 CBlockIndex::GetBlockTrust() const { CBigNum bnTarget; bnTarget.SetCompact(nBits); - if (bnTarget <= 0) return 0; - return ((CBigNum(1)<<256) / (bnTarget+1)).getuint256(); } -unsigned int GetStakeEntropyBit() const +uint32_t GetStakeEntropyBit() const { return ((nFlags & BLOCK_STAKE_ENTROPY) >> 1); } -bool SetStakeEntropyBit(unsigned int nEntropyBit) +bool SetStakeEntropyBit(uint32_t nEntropyBit) { if (nEntropyBit > 1) return false; @@ -68,80 +145,6 @@ void SetStakeModifier(uint64_t nModifier, bool fGeneratedStakeModifier) nFlags |= BLOCK_STAKE_MODIFIER; } -// miner's coin stake reward based on coin age spent (coin-days) -int64_t GetProofOfStakeReward(int64_t nCoinAge, int64_t nFees) -{ - int64_t nSubsidy = nCoinAge * COIN_YEAR_REWARD * 33 / (365 * 33 + 8); - return(nSubsidy + nFees); -} - -// -// maximum nBits value could possible be required nTime after -// -unsigned int ComputeMaxBits(CBigNum bnTargetLimit, unsigned int nBase, int64_t nTime) -{ - CBigNum bnResult; - bnResult.SetCompact(nBase); - bnResult *= 2; - while (nTime > 0 && bnResult < bnTargetLimit) - { - // Maximum 200% adjustment per day... - bnResult *= 2; - nTime -= 24 * 60 * 60; - } - if (bnResult > bnTargetLimit) - bnResult = bnTargetLimit; - return bnResult.GetCompact(); -} - -// -// minimum amount of stake that could possibly be required nTime after -// minimum proof-of-stake required was nBase -// -unsigned int ComputeMinStake(unsigned int nBase, int64_t nTime, unsigned int nBlockTime) -{ - return ComputeMaxBits(bnProofOfStakeLimit, nBase, nTime); -} - -static CBigNum GetProofOfStakeLimit(int nHeight) -{ - if(IsPoSV2(nHeight)) - return bnProofOfStakeLimitV2; - else - return bnProofOfStakeLimit; -} - -unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfStake) -{ - CBigNum bnTargetLimit = fProofOfStake ? GetProofOfStakeLimit(pindexLast->nHeight) : bnProofOfWorkLimit; - - if (pindexLast == NULL) - return bnTargetLimit.GetCompact(); // genesis block - const CBlockIndex* pindexPrev = GetLastBlockIndex(pindexLast, fProofOfStake); - if (pindexPrev->pprev == NULL) - return bnTargetLimit.GetCompact(); // first block - const CBlockIndex* pindexPrevPrev = GetLastBlockIndex(pindexPrev->pprev, fProofOfStake); - if (pindexPrevPrev->pprev == NULL) - return bnTargetLimit.GetCompact(); // second block - - int64_t nActualSpacing = pindexPrev->GetBlockTime() - pindexPrevPrev->GetBlockTime(); - if (nActualSpacing < 0) - nActualSpacing = nTargetSpacing; - - // ppcoin: target change every block - // ppcoin: retarget with exponential moving toward target spacing - CBigNum bnNew; - bnNew.SetCompact(pindexPrev->nBits); - int64_t nInterval = nTargetTimespan / nTargetSpacing; - bnNew *= ((nInterval - 1) * nTargetSpacing + nActualSpacing + nActualSpacing); - bnNew /= ((nInterval + 1) * nTargetSpacing); - - if (bnNew <= 0 || bnNew > bnTargetLimit) - bnNew = bnTargetLimit; - - return bnNew.GetCompact(); -} - // ppcoin: total coin age spent in transaction, in the unit of coin-days. // Only those coins meeting minimum age requirement counts. As those // transactions not in main chain are not currently indexed so we @@ -168,7 +171,7 @@ bool CTransaction::GetCoinAge(CTxDB& txdb, uint64_t& nCoinAge) const CBlock block; if (!block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false)) return false; // unable to read block of previous transaction - if (block.GetBlockTime() + nStakeMinAge > nTime) + if (block.GetBlockTime() + NSTAKE_MINAGE > nTime) continue; // only count coins meeting min age requirement int64_t nValueIn = txPrev.vout[txin.prevout.n].nValue; @@ -206,13 +209,12 @@ bool CBlock::GetCoinAge(uint64_t& nCoinAge) const } // Get time weight -int64_t GetWeight(int64_t nIntervalBeginning, int64_t nIntervalEnd) +int64_t GetWeight(int64_t nIntervalBeginning,int64_t nIntervalEnd) { // Kernel hash weight starts from 0 at the min age // this change increases active coins participating the hash and helps // to secure the network when proof-of-stake difficulty is low - - return min(nIntervalEnd - nIntervalBeginning - nStakeMinAge, (int64_t)nStakeMaxAge); + return min(nIntervalEnd - nIntervalBeginning - NSTAKE_MINAGE,NSTAKEMAXAGE); } // Get the last stake modifier and its generation time from a given block @@ -230,50 +232,44 @@ static bool GetLastStakeModifier(const CBlockIndex* pindex, uint64_t& nStakeModi } // Get selection interval section (in seconds) -static int64_t GetStakeModifierSelectionIntervalSection(int nSection) +static int64_t GetStakeModifierSelectionIntervalSection(int32_t nSection) { assert (nSection >= 0 && nSection < 64); - return (nModifierInterval * 63 / (63 + ((63 - nSection) * (MODIFIER_INTERVAL_RATIO - 1)))); + return (NMODIFIERINTERVAL * 63 / (63 + ((63 - nSection) * (MODIFIER_INTERVAL_RATIO - 1)))); } // Get stake modifier selection interval (in seconds) static int64_t GetStakeModifierSelectionInterval() { int64_t nSelectionInterval = 0; - for (int nSection=0; nSection<64; nSection++) + for (int32_t nSection=0; nSection<64; nSection++) nSelectionInterval += GetStakeModifierSelectionIntervalSection(nSection); return nSelectionInterval; } // select a block from the candidate blocks in vSortedByTimestamp, excluding -// already selected blocks in vSelectedBlocks, and with timestamp up to -// nSelectionIntervalStop. -static bool SelectBlockFromCandidates(vector >& vSortedByTimestamp, map& mapSelectedBlocks, - int64_t nSelectionIntervalStop, uint64_t nStakeModifierPrev, const CBlockIndex** pindexSelected) +// already selected blocks in vSelectedBlocks, and with timestamp up to nSelectionIntervalStop. +static bool SelectBlockFromCandidates(vector >& vSortedByTimestamp, map& mapSelectedBlocks,int64_t nSelectionIntervalStop, uint64_t nStakeModifierPrev, const CBlockIndex **pindexSelected) { - bool fSelected = false; - uint256 hashBest = 0; + bool fSelected = false; uint256 hashBest = 0; *pindexSelected = (const CBlockIndex*) 0; - BOOST_FOREACH(const PAIRTYPE(int64_t, uint256)& item, vSortedByTimestamp) + BOOST_FOREACH(const PAIRTYPE(int64_t, uint256)&item, vSortedByTimestamp) { if (!mapBlockIndex.count(item.second)) return error("SelectBlockFromCandidates: failed to find block index for candidate block %s", item.second.ToString().c_str()); - const CBlockIndex* pindex = mapBlockIndex[item.second]; - if (fSelected && pindex->GetBlockTime() > nSelectionIntervalStop) + const CBlockIndex *pindex = mapBlockIndex[item.second]; + if ( fSelected && pindex->GetBlockTime() > nSelectionIntervalStop ) break; if (mapSelectedBlocks.count(pindex->GetBlockHash()) > 0) continue; - // compute the selection hash by hashing its proof-hash and the - // previous proof-of-stake modifier + // compute the selection hash by hashing its proof-hash and the previous proof-of-stake modifier CDataStream ss(SER_GETHASH, 0); ss << pindex->hashProof << nStakeModifierPrev; uint256 hashSelection = Hash(ss.begin(), ss.end()); - // the selection hash is divided by 2**32 so that proof-of-stake block - // is always favored over proof-of-work block. this is to preserve - // the energy efficiency property - if (pindex->IsProofOfStake()) + // the selection hash is divided by 2**32 so that proof-of-stake block is always favored over proof-of-work block. this is to preserve the energy efficiency property + if ( pindex->IsProofOfStake() ) hashSelection >>= 32; - if (fSelected && hashSelection < hashBest) + if ( fSelected && hashSelection < hashBest ) { hashBest = hashSelection; *pindexSelected = (const CBlockIndex*) pindex; @@ -321,21 +317,21 @@ bool ComputeNextStakeModifier(const CBlockIndex* pindexPrev, uint64_t& nStakeMod { printf("ComputeNextStakeModifier: prev modifier=0x%016"PRIx64" time=%s\n", nStakeModifier, DateTimeStrFormat(nModifierTime).c_str()); } - if (nModifierTime / nModifierInterval >= pindexPrev->GetBlockTime() / nModifierInterval) + if (nModifierTime / NMODIFIERINTERVAL >= pindexPrev->GetBlockTime() / NMODIFIERINTERVAL) return true; // Sort candidate blocks by timestamp vector > vSortedByTimestamp; - vSortedByTimestamp.reserve(64 * nModifierInterval / nTargetSpacing); + vSortedByTimestamp.reserve(64 * (NMODIFIERINTERVAL / NTARGETSPACING)); int64_t nSelectionInterval = GetStakeModifierSelectionInterval(); - int64_t nSelectionIntervalStart = (pindexPrev->GetBlockTime() / nModifierInterval) * nModifierInterval - nSelectionInterval; + int64_t nSelectionIntervalStart = (pindexPrev->GetBlockTime() / NMODIFIERINTERVAL) * NMODIFIERINTERVAL - nSelectionInterval; const CBlockIndex* pindex = pindexPrev; while (pindex && pindex->GetBlockTime() >= nSelectionIntervalStart) { vSortedByTimestamp.push_back(make_pair(pindex->GetBlockTime(), pindex->GetBlockHash())); pindex = pindex->pprev; } - int nHeightFirstCandidate = pindex ? (pindex->nHeight + 1) : 0; + int32_t nHeightFirstCandidate = pindex ? (pindex->nHeight + 1) : 0; reverse(vSortedByTimestamp.begin(), vSortedByTimestamp.end()); sort(vSortedByTimestamp.begin(), vSortedByTimestamp.end()); @@ -343,7 +339,7 @@ bool ComputeNextStakeModifier(const CBlockIndex* pindexPrev, uint64_t& nStakeMod uint64_t nStakeModifierNew = 0; int64_t nSelectionIntervalStop = nSelectionIntervalStart; map mapSelectedBlocks; - for (int nRound=0; nRoundpnext) { // reached best block; may happen if node is behind on block chain - if (fPrintProofOfStake || (pindex->GetBlockTime() + nStakeMinAge - nStakeModifierSelectionInterval > GetAdjustedTime())) - return error("GetKernelStakeModifier() : reached best block %s at height %d from block %s", - pindex->GetBlockHash().ToString().c_str(), pindex->nHeight, hashBlockFrom.ToString().c_str()); - else - return false; + if (fPrintProofOfStake || (pindex->GetBlockTime() + NSTAKE_MINAGE - nStakeModifierSelectionInterval > GetAdjustedTime())) + return error("GetKernelStakeModifier() : reached best block %s at height %d from block %s",pindex->GetBlockHash().ToString().c_str(), pindex->nHeight, hashBlockFrom.ToString().c_str()); + else return false; } pindex = pindex->pnext; if (pindex->GeneratedStakeModifier()) @@ -445,13 +439,13 @@ static bool GetKernelStakeModifier(uint256 hashBlockFrom, uint64_t& nStakeModifi // quantities so as to generate blocks faster, degrading the system back into // a proof-of-work situation. // -bool CheckStakeKernelHashV1(unsigned int nBits, const CBlock& blockFrom, unsigned int nTxPrevOffset, const CTransaction& txPrev, const COutPoint& prevout, unsigned int nTimeTx, uint256& hashProofOfStake, uint256& targetProofOfStake, bool fPrintProofOfStake) +bool CheckStakeKernelHashV1(uint32_t nBits, const CBlock& blockFrom,uint32_t nTxPrevOffset, const CTransaction& txPrev, const COutPoint& prevout,uint32_t nTimeTx, uint256& hashProofOfStake, uint256& targetProofOfStake, bool fPrintProofOfStake) { if (nTimeTx < txPrev.nTime) // Transaction timestamp violation return error("CheckStakeKernelHash() : nTime violation"); - unsigned int nTimeBlockFrom = blockFrom.GetBlockTime(); - if (nTimeBlockFrom + nStakeMinAge > nTimeTx) // Min age requirement + uint32_t nTimeBlockFrom = blockFrom.GetBlockTime(); + if (nTimeBlockFrom + NSTAKE_MINAGE > nTimeTx) // Min age requirement return error("CheckStakeKernelHash() : min age violation"); CBigNum bnTargetPerCoinDay; @@ -466,7 +460,7 @@ bool CheckStakeKernelHashV1(unsigned int nBits, const CBlock& blockFrom, unsigne // Calculate hash CDataStream ss(SER_GETHASH, 0); uint64_t nStakeModifier = 0; - int nStakeModifierHeight = 0; + int32_t nStakeModifierHeight = 0; int64_t nStakeModifierTime = 0; if ( !GetKernelStakeModifier(hashBlockFrom, nStakeModifier, nStakeModifierHeight, nStakeModifierTime, fPrintProofOfStake) ) @@ -504,7 +498,7 @@ bool CheckStakeKernelHashV1(unsigned int nBits, const CBlock& blockFrom, unsigne return true; } -bool CheckStakeKernelHash(CBlockIndex* pindexPrev, unsigned int nBits, const CBlock& blockFrom, unsigned int nTxPrevOffset, const CTransaction& txPrev, const COutPoint& prevout, unsigned int nTimeTx, uint256& hashProofOfStake, uint256& targetProofOfStake, bool fPrintProofOfStake) +bool CheckStakeKernelHash(CBlockIndex* pindexPrev, uint32_t nBits, const CBlock& blockFrom, uint32_t nTxPrevOffset, const CTransaction& txPrev, const COutPoint& prevout, uint32_t nTimeTx, uint256& hashProofOfStake, uint256& targetProofOfStake, bool fPrintProofOfStake) { if (IsPoSV2(pindexPrev->nHeight+1)) return CheckStakeKernelHashV2(pindexPrev, nBits, blockFrom.GetBlockTime(), txPrev, prevout, nTimeTx, hashProofOfStake, targetProofOfStake, fPrintProofOfStake); @@ -512,10 +506,9 @@ bool CheckStakeKernelHash(CBlockIndex* pindexPrev, unsigned int nBits, const CBl return CheckStakeKernelHashV1(nBits, blockFrom, nTxPrevOffset, txPrev, prevout, nTimeTx, hashProofOfStake, targetProofOfStake, fPrintProofOfStake); } -bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int64_t nSearchInterval, int64_t nFees, CTransaction& txNew, CKey& key) +bool CWallet::CreateCoinStake(const CKeyStore& keystore, uint32_t nBits, int64_t nSearchInterval, int64_t nFees, CTransaction& txNew, CKey& key) { - CBlockIndex* pindexPrev = pindexBest; - CBigNum bnTargetPerCoinDay; + CBigNum bnTargetPerCoinDay; CBlockIndex *pindexPrev = pindexBest; bnTargetPerCoinDay.SetCompact(nBits); txNew.vin.clear(); @@ -528,12 +521,10 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int // Choose coins to use int64_t nBalance = GetBalance(); - if (nBalance <= nReserveBalance) return false; vector vwtxPrev; - set > setCoins; int64_t nValueIn = 0; @@ -564,15 +555,14 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int continue; } - static int nMaxStakeSearchInterval = 60; - if (block.GetBlockTime() + nStakeMinAge > txNew.nTime - nMaxStakeSearchInterval) + if (block.GetBlockTime() + NSTAKE_MINAGE > txNew.nTime - NMAXSTAKESEARCHINTERVAL) continue; // only count coins meeting min age requirement bool fKernelFound = false; - for (unsigned int n=0; nGetHash(), pcoin.second); if (CheckStakeKernelHash(pindexPrev, nBits, block, txindex.pos.nTxPos - txindex.pos.nBlockPos, *pcoin.first, prevoutStake, txNew.nTime - n, hashProofOfStake, targetProofOfStake)) @@ -653,29 +643,26 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins) { - // Attempt to add more inputs - // Only add coins of the same key/address as kernel + // Attempt to add more inputs: Only add coins of the same key/address as kernel if (txNew.vout.size() == 2 && ((pcoin.first->vout[pcoin.second].scriptPubKey == scriptPubKeyKernel || pcoin.first->vout[pcoin.second].scriptPubKey == txNew.vout[1].scriptPubKey)) && pcoin.first->GetHash() != txNew.vin[0].prevout.hash) { int64_t nTimeWeight = GetWeight((int64_t)pcoin.first->nTime, (int64_t)txNew.nTime); - // Stop adding more inputs if already too many inputs if (txNew.vin.size() >= 100) break; // Stop adding more inputs if value is already pretty significant - if (nCredit >= nStakeCombineThreshold) + if (nCredit >= NSTAKECOMBINETHRESHOLD) break; // Stop adding inputs if reached reserve limit if (nCredit + pcoin.first->vout[pcoin.second].nValue > nBalance - nReserveBalance) break; // Do not add additional significant input - if (pcoin.first->vout[pcoin.second].nValue >= nStakeCombineThreshold) + if (pcoin.first->vout[pcoin.second].nValue >= NSTAKECOMBINETHRESHOLD) continue; // Do not add input that is still too young - if (nTimeWeight < nStakeMinAge) + if (nTimeWeight < NSTAKE_MINAGE) continue; - txNew.vin.push_back(CTxIn(pcoin.first->GetHash(), pcoin.second)); nCredit += pcoin.first->vout[pcoin.second].nValue; vwtxPrev.push_back(pcoin.first); @@ -689,7 +676,7 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int if (!txNew.GetCoinAge(txdb, nCoinAge)) return error("CreateCoinStake : failed to calculate coin age"); - int64_t nReward = GetProofOfStakeReward(nCoinAge, nFees); + int64_t nReward = iguana_POSreward(nCoinAge, nFees); if (nReward <= 0) return false; @@ -701,12 +688,10 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int { txNew.vout[1].nValue = (nCredit / 2 / CENT) * CENT; txNew.vout[2].nValue = nCredit - txNew.vout[1].nValue; - } - else - txNew.vout[1].nValue = nCredit; + } else txNew.vout[1].nValue = nCredit; // Sign - int nIn = 0; + int32_t nIn = 0; BOOST_FOREACH(const CWalletTx* pcoin, vwtxPrev) { if (!SignSignature(*this, *pcoin, txNew, nIn++)) @@ -714,7 +699,7 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int } // Limit size - unsigned int nBytes = ::GetSerializeSize(txNew, SER_NETWORK, PROTOCOL_VERSION); + uint32_t nBytes = ::GetSerializeSize(txNew, SER_NETWORK, PROTOCOL_VERSION); if (nBytes >= MAX_BLOCK_SIZE_GEN/5) return error("CreateCoinStake : exceeded coinstake size limit"); @@ -723,7 +708,7 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int } // Check kernel hash target and coinstake signature -bool CheckProofOfStake(CBlockIndex* pindexPrev, const CTransaction& tx, unsigned int nBits, uint256& hashProofOfStake, uint256& targetProofOfStake) +bool CheckProofOfStake(CBlockIndex* pindexPrev, const CTransaction& tx, uint32_t nBits, uint256& hashProofOfStake, uint256& targetProofOfStake) { if (!tx.IsCoinStake()) return error("CheckProofOfStake() : called on non-coinstake %s", tx.GetHash().ToString().c_str()); @@ -761,7 +746,7 @@ bool CheckCoinStakeTimestamp(int64_t nTimeBlock, int64_t nTimeTx) } // Get stake modifier checksum -unsigned int GetStakeModifierChecksum(const CBlockIndex* pindex) +uint32_t GetStakeModifierChecksum(const CBlockIndex* pindex) { //assert (pindex->pprev || pindex->GetBlockHash() == (!fTestNet ? hashGenesisBlock : hashGenesisBlockTestNet)); // Hash previous checksum with flags, hashProofOfStake and nStakeModifier @@ -775,7 +760,7 @@ unsigned int GetStakeModifierChecksum(const CBlockIndex* pindex) } // Check stake modifier hard checkpoints -bool CheckStakeModifierCheckpoints(int nHeight, unsigned int nStakeModifierChecksum) +bool CheckStakeModifierCheckpoints(int32_t nHeight, uint32_t nStakeModifierChecksum) { MapModifierCheckpoints& checkpoints = (fTestNet ? mapStakeModifierCheckpointsTestNet : mapStakeModifierCheckpoints); @@ -783,47 +768,36 @@ bool CheckStakeModifierCheckpoints(int nHeight, unsigned int nStakeModifierCheck return nStakeModifierChecksum == checkpoints[nHeight]; return true; } + // novacoin: attempt to generate suitable proof-of-stake bool CBlock::SignBlock(CWallet& wallet, int64_t nFees) { - // if we are trying to sign - // something except proof-of-stake block template + // if we are trying to sign something except proof-of-stake block template if (!vtx[0].vout[0].IsEmpty()) return false; - - // if we are trying to sign - // a complete proof-of-stake block + // if we are trying to sign a complete proof-of-stake block if (IsProofOfStake()) return true; - static int64_t nLastCoinStakeSearchTime = GetAdjustedTime(); // startup timestamp - - CKey key; - CTransaction txCoinStake; - int64_t nSearchTime = txCoinStake.nTime; // search to current time - + CKey key; CTransaction txCoinStake; int64_t nSearchTime = txCoinStake.nTime; // search to current time if (nSearchTime > nLastCoinStakeSearchTime) { if (wallet.CreateCoinStake(wallet, nBits, nSearchTime-nLastCoinStakeSearchTime, nFees, txCoinStake, key)) { - if (txCoinStake.nTime >= max(pindexBest->GetPastTimeLimit()+1, PastDrift(pindexBest->GetBlockTime()))) - { - // make sure coinstake would meet timestamp protocol - // as it would be the same as the block timestamp - vtx[0].nTime = nTime = txCoinStake.nTime; - nTime = max(pindexBest->GetPastTimeLimit()+1, GetMaxTransactionTime()); - nTime = max(GetBlockTime(), PastDrift(pindexBest->GetBlockTime())); - // we have to make sure that we have no future timestamps in - // our transactions set - for (vector::iterator it = vtx.begin(); it != vtx.end();) - if (it->nTime > nTime) { it = vtx.erase(it); } else { ++it; } - - vtx.insert(vtx.begin() + 1, txCoinStake); - hashMerkleRoot = BuildMerkleTree(); - - // append a signature to our block - return key.Sign(GetHash(), vchBlockSig); - } + if (txCoinStake.nTime >= max(pindexBest->GetPastTimeLimit()+1, PastDrift(pindexBest->GetBlockTime()))) + { + // make sure coinstake would meet timestamp protocol as it would be the same as the block timestamp + vtx[0].nTime = nTime = txCoinStake.nTime; + nTime = max(pindexBest->GetPastTimeLimit()+1, GetMaxTransactionTime()); + nTime = max(GetBlockTime(), PastDrift(pindexBest->GetBlockTime())); + // we have to make sure that we have no future timestamps in our transactions set + for (vector::iterator it = vtx.begin(); it != vtx.end();) + if (it->nTime > nTime) { it = vtx.erase(it); } else { ++it; } + vtx.insert(vtx.begin() + 1, txCoinStake); + hashMerkleRoot = BuildMerkleTree(); + // append a signature to our block + return key.Sign(GetHash(), vchBlockSig); + } } nLastCoinStakeSearchInterval = nSearchTime - nLastCoinStakeSearchTime; nLastCoinStakeSearchTime = nSearchTime; @@ -836,15 +810,11 @@ bool CBlock::CheckBlockSignature() const { if (IsProofOfWork()) return vchBlockSig.empty(); - vector vSolutions; txnouttype whichType; - const CTxOut& txout = vtx[1].vout[1]; - if (!Solver(txout.scriptPubKey, whichType, vSolutions)) return false; - if (whichType == TX_PUBKEY) { valtype& vchPubKey = vSolutions[0]; @@ -855,7 +825,6 @@ bool CBlock::CheckBlockSignature() const return false; return key.Verify(GetHash(), vchBlockSig); } - return false; } diff --git a/iguana/iguana_tradebots.c b/iguana/iguana_tradebots.c index 36ce9df09..275592554 100755 --- a/iguana/iguana_tradebots.c +++ b/iguana/iguana_tradebots.c @@ -27,7 +27,7 @@ struct tradebot_trade struct tradebot_info { - struct queueitem DL; + struct tradebot_info *next,*prev; struct supernet_info *myinfo; char name[128],exchangestr[32],base[32],rel[32]; int32_t dir,numtrades,estimatedtrades; @@ -88,10 +88,9 @@ cJSON *tradebot_json(struct supernet_info *myinfo,struct exchange_info *exchange struct tradebot_info *tradebot_find(struct supernet_info *myinfo,struct exchange_info *exchange,char *botname,cJSON *array,char *base,char *rel) { - struct tradebot_info PAD,*bot,*retbot = 0; - memset(&PAD,0,sizeof(PAD)); - queue_enqueue("tradebotsQ",&exchange->tradebotsQ,&PAD.DL,0); - while ( (bot= queue_dequeue(&exchange->tradebotsQ,0)) != 0 && bot != &PAD ) + struct tradebot_info *tmp,*bot,*retbot = 0; + portable_mutex_lock(&exchange->mutexT); + DL_FOREACH_SAFE(exchange->tradebots,bot,tmp) { if ( botname != 0 && strcmp(botname,bot->name) == 0 ) retbot = bot; @@ -99,11 +98,18 @@ struct tradebot_info *tradebot_find(struct supernet_info *myinfo,struct exchange jaddi(array,tradebot_json(myinfo,exchange,bot)); if ( base != 0 && rel != 0 && strcmp(base,bot->base) == 0 && strcmp(rel,bot->rel) == 0 ) retbot = bot; - queue_enqueue("tradebotsQ",&exchange->tradebotsQ,&bot->DL,0); } + portable_mutex_unlock(&exchange->mutexT); return(retbot); } +void tradebot_add(struct exchange_info *exchange,struct tradebot_info *bot) +{ + portable_mutex_lock(&exchange->mutexT); + DL_APPEND(exchange->tradebots,bot); + portable_mutex_unlock(&exchange->mutexT); +} + struct tradebot_info *tradebot_create(struct supernet_info *myinfo,struct exchange_info *exchange,char *base,char *rel,int32_t dir,double price,double volume,int32_t duration) { struct tradebot_info *bot; @@ -120,7 +126,7 @@ struct tradebot_info *tradebot_create(struct supernet_info *myinfo,struct exchan bot->expiration = bot->started + duration; bot->estimatedtrades = (duration / TRADEBOTS_GAPTIME) + 1; sprintf(bot->name,"%s_%s_%s.%d",exchange->name,base,rel,bot->started); - queue_enqueue("tradebotsQ",&exchange->tradebotsQ,&bot->DL,0); + tradebot_add(exchange,bot); } return(bot); } @@ -156,8 +162,23 @@ void tradebot_timeslice(struct exchange_info *exchange,void *_bot) } } } - queue_enqueue("tradebotsQ",&exchange->tradebotsQ,&bot->DL,0); - } else free(bot); + } + else + { + DL_DELETE(exchange->tradebots,bot); + free(bot); + } +} + +void tradebot_timeslices(struct exchange_info *exchange) +{ + struct tradebot_info *bot,*tmp; + portable_mutex_lock(&exchange->mutexT); + DL_FOREACH_SAFE(exchange->tradebots,bot,tmp) + { + tradebot_timeslice(exchange,bot); + } + portable_mutex_unlock(&exchange->mutexT); } char *tradebot_launch(struct supernet_info *myinfo,char *exchangestr,char *base,char *rel,int32_t dir,double price,double volume,int32_t duration,char *remoteaddr,cJSON *json) @@ -200,6 +221,24 @@ char *tradebot_control(struct supernet_info *myinfo,char *exchangestr,char *boti #include "../includes/iguana_apidefs.h" +HASH_ARRAY_STRING(tradebot,liquidity,hash,vals,targetcoin) +{ + tradebot_liquidity_command(myinfo,targetcoin,hash,vals); + return(clonestr("{\"result\":\"targetcoin updated\"}")); +} + +ZERO_ARGS(tradebot,amlp) +{ + myinfo->IAMLP = 1; + return(clonestr("{\"result\":\"liquidity provider active\"}")); +} + +ZERO_ARGS(tradebot,notlp) +{ + myinfo->IAMLP = 0; + return(clonestr("{\"result\":\"not liquidity provider\"}")); +} + THREE_STRINGS_AND_DOUBLE(tradebot,monitor,exchange,base,rel,commission) { int32_t allfields = 1,depth = 50; struct exchange_info *ptr; diff --git a/iguana/iguana_tx.c b/iguana/iguana_tx.c index bf426d26e..36df86655 100755 --- a/iguana/iguana_tx.c +++ b/iguana/iguana_tx.c @@ -14,7 +14,7 @@ ******************************************************************************/ #include "iguana777.h" -#include "SuperNET.h" +//#include "SuperNET.h" //struct iguana_txid { bits256 txid; uint32_t txidind,firstvout,firstvin,locktime,version,timestamp; uint16_t numvouts,numvins; } __attribute__((packed)); @@ -68,30 +68,34 @@ int32_t iguana_scriptdata(struct iguana_info *coin,uint8_t *scriptspace,long fil int32_t iguana_vinset(struct iguana_info *coin,uint8_t *scriptspace,int32_t height,struct iguana_msgvin *vin,struct iguana_txid *tx,int32_t i) { struct iguana_spend *s,*S; uint32_t spendind,unspentind; bits256 *X; struct iguana_bundle *bp; - struct iguana_ramchaindata *rdata; struct iguana_txid *T; char fname[1024]; int32_t scriptlen,err = 0; + struct iguana_ramchaindata *rdata=0; struct iguana_txid *T; char fname[1024]; int32_t scriptlen,err = 0; struct iguana_ramchain *ramchain; memset(vin,0,sizeof(*vin)); - if ( height >= 0 && height < coin->chain->bundlesize*coin->bundlescount && (bp= coin->bundles[height / coin->chain->bundlesize]) != 0 && (rdata= bp->ramchain.H.data) != 0 ) + if ( height >= 0 && height < coin->chain->bundlesize*coin->bundlescount && (bp= coin->bundles[height / coin->chain->bundlesize]) != 0 ) { - S = RAMCHAIN_PTR(rdata,Soffset); - X = RAMCHAIN_PTR(rdata,Xoffset); - T = RAMCHAIN_PTR(rdata,Toffset); - //S = (void *)(long)((long)rdata + rdata->Soffset); - //X = (void *)(long)((long)rdata + rdata->Xoffset); - //T = (void *)(long)((long)rdata + rdata->Toffset); - spendind = (tx->firstvin + i); - s = &S[spendind]; - vin->sequence = s->sequenceid; - vin->prev_vout = s->prevout; - if ( s->scriptpos != 0 && s->scriptlen > 0 ) + ramchain = &bp->ramchain;//(bp == coin->current) ? &coin->RTramchain : &bp->ramchain; + if ( ((rdata= ramchain->H.data) != 0 || ((bp == coin->current && (rdata= ramchain->H.data) != 0))) && i < tx->numvins ) + //if ( (rdata= ramchain->H.data) != 0 && i < rdata->numspends ) { - iguana_vinsfname(coin,bp->ramchain.from_ro,fname,s->fileid); - if ( (scriptlen= iguana_scriptdata(coin,scriptspace,coin->peers.vinptrs[s->fileid],fname,s->scriptpos,s->scriptlen)) != s->scriptlen ) - printf("err.%d getting %d bytes from fileid.%llu[%d] %s for s%d\n",err,s->scriptlen,(long long)s->scriptpos,s->fileid,fname,spendind); - } - vin->scriptlen = s->scriptlen; - vin->vinscript = scriptspace; - iguana_ramchain_spendtxid(coin,&unspentind,&vin->prev_hash,T,rdata->numtxids,X,rdata->numexternaltxids,s); - } + S = RAMCHAIN_PTR(rdata,Soffset); + X = RAMCHAIN_PTR(rdata,Xoffset); + T = RAMCHAIN_PTR(rdata,Toffset); + spendind = (tx->firstvin + i); + s = &S[spendind]; + vin->sequence = s->sequenceid; + vin->prev_vout = s->prevout; + if ( s->prevout < 0 ) + ; + if ( s->scriptpos != 0 && s->scriptlen > 0 ) + { + iguana_vinsfname(coin,bp->ramchain.from_ro,fname,s->fileid); + if ( (scriptlen= iguana_scriptdata(coin,scriptspace,coin->vinptrs[s->fileid],fname,s->scriptpos,s->scriptlen)) != s->scriptlen ) + printf("err.%d getting %d bytes from fileid.%llu[%d] %s for s%d\n",err,s->scriptlen,(long long)s->scriptpos,s->fileid,fname,spendind); + } + vin->scriptlen = s->scriptlen; + vin->vinscript = scriptspace; + iguana_ramchain_spendtxid(coin,&unspentind,&vin->prev_hash,T,rdata->numtxids,X,rdata->numexternaltxids,s); + } else printf("null rdata.%p error height.%d i.%d\n",rdata,height,i); + } else printf("error getting rdata.%p height.%d\n",rdata,height); if ( err != 0 ) return(-err); else return(vin->scriptlen); @@ -103,7 +107,7 @@ int32_t iguana_voutscript(struct iguana_info *coin,struct iguana_bundle *bp,uint if ( u->scriptpos > 0 && u->scriptlen > 0 ) { iguana_voutsfname(coin,bp->ramchain.from_ro,fname,u->fileid); - if ( (scriptlen= iguana_scriptdata(coin,scriptspace,coin->peers.voutptrs[u->fileid],fname,u->scriptpos,u->scriptlen)) != u->scriptlen ) + if ( (scriptlen= iguana_scriptdata(coin,scriptspace,coin->voutptrs[u->fileid],fname,u->scriptpos,u->scriptlen)) != u->scriptlen ) printf("%d bytes from fileid.%d[%d] %s for type.%d\n",u->scriptlen,u->fileid,u->scriptpos,fname,u->type); } else @@ -116,23 +120,27 @@ int32_t iguana_voutscript(struct iguana_info *coin,struct iguana_bundle *bp,uint int32_t iguana_voutset(struct iguana_info *coin,uint8_t *scriptspace,char *asmstr,int32_t height,struct iguana_msgvout *vout,struct iguana_txid *tx,int32_t i) { - struct iguana_ramchaindata *rdata; uint32_t unspentind,scriptlen = 0; struct iguana_bundle *bp; - struct iguana_unspent *u,*U; struct iguana_pkhash *P; int32_t err = 0; + struct iguana_ramchaindata *rdata=0; uint32_t unspentind,scriptlen = 0; struct iguana_bundle *bp; + struct iguana_unspent *u,*U; struct iguana_pkhash *P; struct iguana_ramchain *ramchain=0; int32_t err = 0; memset(vout,0,sizeof(*vout)); - if ( height >= 0 && height < coin->chain->bundlesize*coin->bundlescount && (bp= coin->bundles[height / coin->chain->bundlesize]) != 0 && (rdata= bp->ramchain.H.data) != 0 && i < tx->numvouts ) + if ( height >= 0 && height < coin->chain->bundlesize*coin->bundlescount && (bp= coin->bundles[height / coin->chain->bundlesize]) != 0 ) { - U = RAMCHAIN_PTR(rdata,Uoffset); - P = RAMCHAIN_PTR(rdata,Poffset); - //U = (void *)(long)((long)rdata + rdata->Uoffset); - //P = (void *)(long)((long)rdata + rdata->Poffset); - unspentind = (tx->firstvout + i); - u = &U[unspentind]; - if ( u->txidind != tx->txidind || u->vout != i || u->hdrsi != height / coin->chain->bundlesize ) - printf("iguana_voutset: txidind mismatch %d vs %d || %d vs %d || (%d vs %d)\n",u->txidind,u->txidind,u->vout,i,u->hdrsi,height / coin->chain->bundlesize); - vout->value = u->value; - vout->pk_script = scriptspace; - scriptlen = iguana_voutscript(coin,bp,scriptspace,asmstr,u,&P[u->pkind],i); - } else printf("iguana_voutset unexpected path\n"); + ramchain = &bp->ramchain;//(bp == coin->current) ? &coin->RTramchain : &bp->ramchain; + if ( ((rdata= ramchain->H.data) != 0 || ((bp == coin->current && (rdata= ramchain->H.data) != 0))) && i < tx->numvouts ) + { + U = RAMCHAIN_PTR(rdata,Uoffset); + P = RAMCHAIN_PTR(rdata,Poffset); + //U = (void *)(long)((long)rdata + rdata->Uoffset); + //P = (void *)(long)((long)rdata + rdata->Poffset); + unspentind = (tx->firstvout + i); + u = &U[unspentind]; + if ( u->txidind != tx->txidind || u->vout != i || u->hdrsi != height / coin->chain->bundlesize ) + printf("iguana_voutset: txidind mismatch %d vs %d || %d vs %d || (%d vs %d)\n",u->txidind,u->txidind,u->vout,i,u->hdrsi,height / coin->chain->bundlesize); + vout->value = u->value; + vout->pk_script = scriptspace; + scriptlen = iguana_voutscript(coin,bp,scriptspace,asmstr,u,&P[u->pkind],i); + } else printf("iguana_voutset unexpected path [%d] rdata.%p i.%d %d\n",bp->hdrsi,rdata,i,tx->numvouts); + } else printf("vout error getting rdata.%p height.%d\n",rdata,height); vout->pk_scriptlen = scriptlen; if ( err != 0 ) return(-err); @@ -154,7 +162,7 @@ struct iguana_txid *iguana_blocktx(struct iguana_info *coin,struct iguana_txid * return(tx); printf("error getting txidind.%d + i.%d from hdrsi.%d\n",txidind,i,block->hdrsi); return(0); - } // else printf("iguana_blocktx null txidind [%d:%d] i.%d\n",block->hdrsi,block->bundlei,i); + } else printf("iguana_blocktx null txidind [%d:%d] i.%d\n",block->hdrsi,block->bundlei,i); } else printf("iguana_blocktx no bp.[%d]\n",block->hdrsi); } else printf("blocktx illegal height.%d\n",block->height); } else printf("i.%d vs txn_count.%d\n",i,block->RO.txn_count); @@ -164,10 +172,21 @@ struct iguana_txid *iguana_blocktx(struct iguana_info *coin,struct iguana_txid * int32_t iguana_ramtxbytes(struct iguana_info *coin,uint8_t *serialized,int32_t maxlen,bits256 *txidp,struct iguana_txid *tx,int32_t height,struct iguana_msgvin *vins,struct iguana_msgvout *vouts,int32_t validatesigs) { int32_t i,rwflag=1,len = 0; char asmstr[512],txidstr[65]; - uint32_t numvins,numvouts; struct iguana_msgvin vin; struct iguana_msgvout vout; uint8_t space[IGUANA_MAXSCRIPTSIZE]; - len += iguana_rwnum(rwflag,&serialized[len],sizeof(tx->version),&tx->version); - if ( coin->chain->hastimestamp != 0 ) - len += iguana_rwnum(rwflag,&serialized[len],sizeof(tx->timestamp),&tx->timestamp); + uint32_t numvins,numvouts,version,locktime,timestamp=0; struct iguana_msgvin vin; struct iguana_msgvout vout; uint8_t space[IGUANA_MAXSCRIPTSIZE]; + if ( rwflag != 0 ) + { + version = tx->version; + locktime = tx->locktime; + timestamp = tx->timestamp; + } + len += iguana_rwnum(rwflag,&serialized[len],sizeof(version),&version); + if ( coin->chain->isPoS != 0 ) + len += iguana_rwnum(rwflag,&serialized[len],sizeof(timestamp),×tamp); + if ( rwflag == 0 ) + { + tx->version = version; + tx->timestamp = timestamp; + } numvins = tx->numvins, numvouts = tx->numvouts; len += iguana_rwvarint32(rwflag,&serialized[len],&numvins); memset(&vin,0,sizeof(vin)); @@ -184,7 +203,10 @@ int32_t iguana_ramtxbytes(struct iguana_info *coin,uint8_t *serialized,int32_t m len += iguana_rwvin(rwflag,0,&serialized[len],&vin); } if ( len > maxlen ) + { + printf("len.%d > maxlen.%d\n",len,maxlen); return(0); + } len += iguana_rwvarint32(rwflag,&serialized[len],&numvouts); for (i=0; i maxlen ) + { + printf("len.%d > maxlenB.%d\n",len,maxlen); return(0); - len += iguana_rwnum(rwflag,&serialized[len],sizeof(tx->locktime),&tx->locktime); + } + len += iguana_rwnum(rwflag,&serialized[len],sizeof(locktime),&locktime); + if ( rwflag == 0 ) + tx->locktime = locktime; *txidp = bits256_doublesha256(txidstr,serialized,len); if ( memcmp(txidp,tx->txid.bytes,sizeof(*txidp)) != 0 ) { - //for (i=0; itxid)); + for (i=0; itxid)); return(-1); } return(len); @@ -209,16 +236,25 @@ int32_t iguana_ramtxbytes(struct iguana_info *coin,uint8_t *serialized,int32_t m int32_t iguana_peerblockrequest(struct iguana_info *coin,uint8_t *blockspace,int32_t max,struct iguana_peer *addr,bits256 hash2,int32_t validatesigs) { - struct iguana_txid *tx,T; bits256 checktxid; int32_t i,len,total,bundlei=-2; struct iguana_block *block; struct iguana_msgblock msgB; bits256 *tree,checkhash2,merkle_root; struct iguana_bundle *bp=0; long tmp; char str[65]; + struct iguana_txid *tx,T; bits256 checktxid; int32_t i,len,total,bundlei=-2; struct iguana_block *block; struct iguana_msgblock msgB; bits256 *tree,checkhash2,merkle_root; struct iguana_bundle *bp=0; long tmp; char str[65]; struct iguana_ramchaindata *rdata; if ( (bp= iguana_bundlefind(coin,&bp,&bundlei,hash2)) != 0 && bundlei >= 0 && bundlei < bp->n ) { - if ( (block= bp->blocks[bundlei]) != 0 ) + if ( (rdata= bp->ramchain.H.data) == 0 )//&& bp == coin->current ) { - iguana_blockunconv(&msgB,block,1); - total = iguana_rwblock(1,&checkhash2,&blockspace[sizeof(struct iguana_msghdr) + 0],&msgB); + //printf("iguana_peerblockrequest no ramchain data [%d] use RTcache\n",bp->hdrsi); + //rdata = coin->RTramchain.H.data; + return(-1); + } + if ( (block= bp->blocks[bundlei]) != 0 && rdata != 0 ) + { + iguana_blockunconv(coin->chain->zcash,coin->chain->auxpow,&msgB,block,0); + msgB.txn_count = block->RO.txn_count; + total = iguana_rwblock(coin->symbol,coin->chain->zcash,coin->chain->auxpow,coin->chain->hashalgo,1,&checkhash2,&blockspace[sizeof(struct iguana_msghdr) + 0],&msgB,max); if ( bits256_cmp(checkhash2,block->RO.hash2) != 0 ) { - printf("iguana_peerblockrequest: blockhash mismatch ht.%d\n",bp->bundleheight+bundlei); + //static int counter; + //if ( counter++ < 100 ) + printf("iguana_peerblockrequest: blockhash mismatch ht.%d\n",bp->bundleheight+bundlei); return(-1); } for (i=0; iRO.txn_count; i++) @@ -229,14 +265,20 @@ int32_t iguana_peerblockrequest(struct iguana_info *coin,uint8_t *blockspace,int total += len; else { + //static int counter; char str[65],str2[65]; - printf("error getting txi.%d [%d:%d] cmp.%s %s\n",i,bp->hdrsi,bundlei,bits256_str(str,checktxid),bits256_str(str2,T.txid)); + //if ( counter++ < 100 ) + { + for (i=0; ihdrsi,bundlei,bits256_str(str,checktxid),bits256_str(str2,T.txid)); + } break; } } else { - //printf("null tx error getting txi.%d [%d:%d]\n",i,bp->hdrsi,bundlei); + printf("null tx error getting txi.%d [%d:%d]\n",i,bp->hdrsi,bundlei); break; } } @@ -253,13 +295,35 @@ int32_t iguana_peerblockrequest(struct iguana_info *coin,uint8_t *blockspace,int } if ( i == block->RO.txn_count ) { - merkle_root = iguana_merkle(coin,tree,block->RO.txn_count); + merkle_root = iguana_merkle(tree,block->RO.txn_count); if ( bits256_cmp(merkle_root,block->RO.merkle_root) == 0 ) { - if ( addr != 0 ) + if ( addr != 0 && addr->lastsent != block->height ) { - printf("Send block.%d to %s\n",total,addr->ipaddr); - return(iguana_queue_send(coin,addr,0,blockspace,"block",total,0,0)); + addr->lastsent = block->height; + printf("Sendlen.%d block.%d %s to %s\n",total,block->height,bits256_str(str,block->RO.hash2),addr->ipaddr); + if ( 0 ) + { + struct iguana_txblock txdata; int32_t checklen; static struct OS_memspace RAWMEM; + if ( RAWMEM.ptr == 0 ) + iguana_meminit(&RAWMEM,addr->ipaddr,0,IGUANA_MAXPACKETSIZE * 2,0); + else iguana_memreset(&RAWMEM); + memset(&txdata,0,sizeof(txdata)); + int32_t i; + for (i=0; ibundleheight+bundlei); } else printf("iguana_peerblockrequest: error merkle verify tx.[%d] for ht.%d\n",i,bp->bundleheight+bundlei); - } //else printf("iguana_peerblockrequest: error getting tx.[%d] for ht.%d block.%p main.%d ht.%d\n",i,bp->bundleheight+bundlei,block,block!=0?block->mainchain:-1,block!=0?block->height:-1); + } else printf("iguana_peerblockrequest: error getting tx.[%d] for ht.%d block.%p main.%d ht.%d\n",i,bp->bundleheight+bundlei,block,block!=0?block->mainchain:-1,block!=0?block->height:-1); } else { - if ( block != 0 ) - printf("iguana_peerblockrequest: block.%p ht.%d mainchain.%d [%d:%d]\n",block,block->height,block->mainchain,bp->hdrsi,bundlei); - else printf("iguana_peerblockrequest: block.%p [%d:%d]\n",block,bp->hdrsi,bundlei); + if ( coin->virtualchain != 0 ) + ; + /*if ( block != 0 ) + printf("iguana_peerblockrequest: block.%p ht.%d mainchain.%d [%d:%d] from %s bp.%p rdata.%p\n",block,block->height,block->mainchain,bp->hdrsi,bundlei,addr!=0?addr->ipaddr:"local",bp,bp!=0?rdata:0); + else printf("iguana_peerblockrequest: block.%p [%d:%d]\n",block,bp->hdrsi,bundlei);*/ } - } else printf("iguana_peerblockrequest: cant find %s\n",bits256_str(str,hash2)); + } //else printf("iguana_peerblockrequest: cant find %s\n",bits256_str(str,hash2)); return(-1); } @@ -285,7 +351,7 @@ cJSON *iguana_blockjson(struct iguana_info *coin,struct iguana_block *block,int3 char str[65],hexstr[1024]; int32_t i,len,size; struct iguana_txid *tx,T; struct iguana_msgblock msg; bits256 hash2,nexthash2; uint8_t serialized[1024]; cJSON *array,*json = cJSON_CreateObject(); jaddstr(json,"result","success"); - jaddstr(json,"blockhash",bits256_str(str,block->RO.hash2)); + jaddstr(json,"hash",bits256_str(str,block->RO.hash2)); jaddnum(json,"height",block->height); //jaddnum(json,"ipbits",block->fpipbits); jaddstr(json,"merkleroot",bits256_str(str,block->RO.merkle_root)); @@ -304,13 +370,13 @@ cJSON *iguana_blockjson(struct iguana_info *coin,struct iguana_block *block,int3 jaddnum(json,"numvins",block->RO.numvins); jaddnum(json,"recvlen",block->RO.recvlen); jaddnum(json,"hdrsi",block->hdrsi); - jaddnum(json,"PoW",block->PoW); + jaddnum(json,"difficulty",PoW_from_compact(block->RO.bits,coin->chain->unitval)); jaddnum(json,"bundlei",block->bundlei); jaddnum(json,"mainchain",block->mainchain); jaddnum(json,"valid",block->valid); jaddnum(json,"txn_count",block->RO.txn_count); - jaddnum(json,"bits",block->RO.bits); + jaddnum(json,"nBits",block->RO.bits); serialized[0] = ((uint8_t *)&block->RO.bits)[3]; serialized[1] = ((uint8_t *)&block->RO.bits)[2]; serialized[2] = ((uint8_t *)&block->RO.bits)[1]; @@ -322,9 +388,15 @@ cJSON *iguana_blockjson(struct iguana_info *coin,struct iguana_block *block,int3 msg.H.merkle_root = block->RO.merkle_root; msg.H.timestamp = block->RO.timestamp; msg.H.bits = block->RO.bits; - msg.H.nonce = block->RO.nonce; + if ( block->RO.allocsize == sizeof(struct iguana_zblock) ) + { + msg.zH.bignonce = block->zRO[0].bignonce; + msg.zH.numelements = ZCASH_SOLUTION_ELEMENTS; + for (i=0; izRO[0].solution[i]; + } else msg.H.nonce = block->RO.nonce; msg.txn_count = 0;//block->RO.txn_count; - len = iguana_rwblock(1,&hash2,serialized,&msg); + len = iguana_rwblock(coin->symbol,coin->chain->zcash,coin->chain->auxpow,coin->chain->hashalgo,1,&hash2,serialized,&msg,IGUANA_MAXPACKETSIZE*2); init_hexbytes_noT(hexstr,serialized,len); jaddstr(json,"blockheader",hexstr); if ( txidsflag != 0 ) @@ -338,7 +410,7 @@ cJSON *iguana_blockjson(struct iguana_info *coin,struct iguana_block *block,int3 jadd(json,"tx",array); //printf("add txids[%d]\n",block->txn_count); } - if ( (size= iguana_peerblockrequest(coin,coin->blockspace,sizeof(coin->blockspace),0,block->RO.hash2,0)) < 0 ) + if ( (size= iguana_peerblockrequest(coin,coin->blockspace,coin->blockspacesize,0,block->RO.hash2,0)) < 0 ) jaddstr(json,"error","couldnt generate raw bytes for block"); else jaddnum(json,"size",size); return(json); diff --git a/iguana/iguana_txidfind.c b/iguana/iguana_txidfind.c index 0415f3bed..9805c2ba6 100755 --- a/iguana/iguana_txidfind.c +++ b/iguana/iguana_txidfind.c @@ -17,17 +17,17 @@ int32_t iguana_alloctxbits(struct iguana_info *coin,struct iguana_ramchain *ramchain) { - static int64_t total; - if ( ramchain->txbits == 0 ) + static int64_t total; struct iguana_ramchaindata *rdata; + if ( 0 && ramchain->txbits == 0 && (rdata= ramchain->H.data) != 0 ) { int32_t tlen; uint8_t *TXbits; - TXbits = RAMCHAIN_PTR(ramchain->H.data,TXoffset); - //TXbits = (uint8_t *)((long)ramchain->H.data + ramchain->H.data->TXoffset); - tlen = (int32_t)hconv_bitlen(ramchain->H.data->numtxsparse * ramchain->H.data->txsparsebits); + TXbits = RAMCHAIN_PTR(rdata,TXoffset); + //TXbits = (uint8_t *)((long)rdata + rdata->TXoffset); + tlen = (int32_t)hconv_bitlen(rdata->numtxsparse * rdata->txsparsebits); ramchain->txbits = calloc(1,tlen); memcpy(ramchain->txbits,TXbits,tlen); total += tlen; - char str[65]; printf("alloc.[%d] txbits.%p[%d] total %s\n",ramchain->H.data->height/coin->chain->bundlesize,ramchain->txbits,tlen,mbstr(str,total)); + char str[65]; printf("%s alloc.[%d] txbits.%p[%d] total %s\n",coin->symbol,rdata->height/coin->chain->bundlesize,ramchain->txbits,tlen,mbstr(str,total)); return(tlen); } return(-1); @@ -35,21 +35,21 @@ int32_t iguana_alloctxbits(struct iguana_info *coin,struct iguana_ramchain *ramc int32_t iguana_alloccacheT(struct iguana_info *coin,struct iguana_ramchain *ramchain) { - static int64_t total; - if ( ramchain->cacheT == 0 ) + static int64_t total; struct iguana_ramchaindata *rdata; + if ( ramchain->cacheT == 0 && (rdata= ramchain->H.data) != 0 ) { int32_t i,tlen; struct iguana_txid *T; - T = RAMCHAIN_PTR(ramchain->H.data,Toffset); - //T = (void *)((long)ramchain->H.data + ramchain->H.data->Toffset); - tlen = sizeof(*T) * ramchain->H.data->numtxids; + T = RAMCHAIN_PTR(rdata,Toffset); + //T = (void *)((long)rdata + rdata->Toffset); + tlen = sizeof(*T) * rdata->numtxids; if ( (ramchain->cacheT= calloc(1,tlen)) != 0 ) { //memcpy(ramchain->cacheT,T,tlen); - for (i=0; iH.data->numtxids; i++) + for (i=0; inumtxids; i++) ramchain->cacheT[i] = T[i]; } else ramchain->cacheT = T; total += tlen; - char str[65]; printf("alloc.[%d] cacheT.%p[%d] total %s\n",ramchain->H.data->height/coin->chain->bundlesize,ramchain->cacheT,tlen,mbstr(str,total)); + char str[65]; printf("alloc.[%d] cacheT.%p[%d] total %s\n",rdata->height/coin->chain->bundlesize,ramchain->cacheT,tlen,mbstr(str,total)); return(tlen); } return(-1); @@ -58,6 +58,7 @@ int32_t iguana_alloccacheT(struct iguana_info *coin,struct iguana_ramchain *ramc uint32_t iguana_sparseadd(uint8_t *bits,uint32_t ind,int32_t width,uint32_t tablesize,uint8_t *key,int32_t keylen,uint32_t setind,void *refdata,int32_t refsize,struct iguana_ramchain *ramchain,uint32_t maxitems) { static uint8_t masks[8] = { 1, 2, 4, 8, 16, 32, 64, 128 }; + struct iguana_ramchaindata *rdata; int32_t i,j,x,n,modval; int64_t bitoffset; uint8_t *ptr; uint32_t *table,retval = 0; if ( tablesize == 0 ) { @@ -87,8 +88,8 @@ uint32_t iguana_sparseadd(uint8_t *bits,uint32_t ind,int32_t width,uint32_t tabl //if ( setind == 0 ) // ramchain->sparsesearches++; //else ramchain->sparseadds++; - if ( 0 && (ramchain->sparsesearches % 1000000) == 0 ) - printf("[%3d] %7d.[%-2d %8d] %5.3f adds.(%-10ld %10ld) search.(hits.%-10ld %10ld) %5.2f%% max.%ld\n",ramchain->height/ramchain->H.data->numblocks,ramchain->height,width,tablesize,(double)(ramchain->sparseadditers + ramchain->sparsesearchiters)/(1+ramchain->sparsesearches+ramchain->sparseadds),ramchain->sparseadds,ramchain->sparseadditers,ramchain->sparsehits,ramchain->sparsesearches,100.*(double)ramchain->sparsehits/(1+ramchain->sparsesearches),ramchain->sparsemax+1); + if ( 0 && (rdata= ramchain->H.data) != 0 && (ramchain->sparsesearches % 1000000) == 0 ) + printf("[%3d] %7d.[%-2d %8d] %5.3f adds.(%-10ld %10ld) search.(hits.%-10ld %10ld) %5.2f%% max.%ld\n",ramchain->height/rdata->numblocks,ramchain->height,width,tablesize,(double)(ramchain->sparseadditers + ramchain->sparsesearchiters)/(1+ramchain->sparsesearches+ramchain->sparseadds),ramchain->sparseadds,ramchain->sparseadditers,ramchain->sparsehits,ramchain->sparsesearches,100.*(double)ramchain->sparsehits/(1+ramchain->sparsesearches),ramchain->sparsemax+1); if ( width == 32 ) { table = (uint32_t *)bits; @@ -209,30 +210,36 @@ uint32_t iguana_sparseadd(uint8_t *bits,uint32_t ind,int32_t width,uint32_t tabl uint32_t iguana_sparseaddtx(uint8_t *bits,int32_t width,uint32_t tablesize,bits256 txid,struct iguana_txid *T,uint32_t txidind,struct iguana_ramchain *ramchain) { - uint32_t ind,retval; - //char str[65]; printf("sparseaddtx %s txidind.%d bits.%p\n",bits256_str(str,txid),txidind,bits); - ind = (txid.ulongs[0] ^ txid.ulongs[1] ^ txid.ulongs[2] ^ txid.ulongs[3]) % tablesize; - if ( (retval= iguana_sparseadd(bits,ind,width,tablesize,txid.bytes,sizeof(txid),txidind,T,sizeof(*T),ramchain,ramchain->H.data->numtxids)) != 0 ) + uint32_t ind,retval=0; struct iguana_ramchaindata *rdata = ramchain->H.data; + if ( tablesize > 0 ) { - char str[65]; - if ( txidind != 0 && retval != txidind ) - printf("sparse tx collision %s %u vs %u\n",bits256_str(str,txid),retval,txidind); - return(retval); + //char str[65]; printf("sparseaddtx %s txidind.%d bits.%p\n",bits256_str(str,txid),txidind,bits); + ind = (txid.ulongs[0] ^ txid.ulongs[1] ^ txid.ulongs[2] ^ txid.ulongs[3]) % tablesize; + if ( rdata != 0 && (retval= iguana_sparseadd(bits,ind,width,tablesize,txid.bytes,sizeof(txid),txidind,T,sizeof(*T),ramchain,rdata->numtxids)) != 0 ) + { + char str[65]; + if ( txidind != 0 && retval != txidind ) + printf("sparse tx collision %s %u vs %u\n",bits256_str(str,txid),retval,txidind); + return(retval); + } } return(retval); } uint32_t iguana_sparseaddpk(uint8_t *bits,int32_t width,uint32_t tablesize,uint8_t rmd160[20],struct iguana_pkhash *P,uint32_t pkind,struct iguana_ramchain *ramchain) { - uint32_t ind,key2; uint64_t key0,key1; - //int32_t i; for (i=0; i<20; i++) - // printf("%02x",rmd160[i]); - //char str[65]; printf(" sparseaddpk pkind.%d bits.%p\n",pkind,bits); - memcpy(&key0,rmd160,sizeof(key0)); - memcpy(&key1,&rmd160[sizeof(key0)],sizeof(key1)); - memcpy(&key2,&rmd160[sizeof(key0) + sizeof(key1)],sizeof(key2)); - ind = (key0 ^ key1 ^ key2) % tablesize; - return(iguana_sparseadd(bits,ind,width,tablesize,rmd160,20,pkind,P,sizeof(*P),ramchain,ramchain->H.data->numpkinds)); + uint32_t ind,key2; uint64_t key0,key1; struct iguana_ramchaindata *rdata; + if ( (rdata= ramchain->H.data) != 0 && tablesize > 0 ) + { + //int32_t i; for (i=0; i<20; i++) + // printf("%02x",rmd160[i]); + //printf(" sparseaddpk pkind.%d bits.%p\n",pkind,bits); + memcpy(&key0,rmd160,sizeof(key0)); + memcpy(&key1,&rmd160[sizeof(key0)],sizeof(key1)); + memcpy(&key2,&rmd160[sizeof(key0) + sizeof(key1)],sizeof(key2)); + ind = (key0 ^ key1 ^ key2) % tablesize; + return(iguana_sparseadd(bits,ind,width,tablesize,rmd160,20,pkind,P,sizeof(*P),ramchain,rdata->numpkinds)); + } else return(0); } int32_t iguana_ramchain_spendtxid(struct iguana_info *coin,uint32_t *unspentindp,bits256 *txidp,struct iguana_txid *T,int32_t numtxids,bits256 *X,int32_t numexternaltxids,struct iguana_spend *s) @@ -264,16 +271,17 @@ int32_t iguana_ramchain_spendtxid(struct iguana_info *coin,uint32_t *unspentindp struct iguana_txid *iguana_txidfind(struct iguana_info *coin,int32_t *heightp,struct iguana_txid *tx,bits256 txid,int32_t lasthdrsi) { uint8_t *TXbits; struct iguana_txid *T; uint32_t txidind; int32_t i; - struct iguana_bundle *bp; struct iguana_ramchain *ramchain; //struct iguana_block *block; + struct iguana_bundle *bp; struct iguana_ramchain *ramchain; struct iguana_ramchaindata *rdata; //struct iguana_block *block; *heightp = -1; + memset(tx,0,sizeof(*tx)); if ( lasthdrsi < 0 ) return(0); for (i=lasthdrsi; i>=0; i--) { if ( (bp= coin->bundles[i]) != 0 && (bp == coin->current || bp->emitfinish > 1) ) { - ramchain = (bp == coin->current) ? &coin->RTramchain : &bp->ramchain; - if ( ramchain->H.data != 0 ) + ramchain = &bp->ramchain;//(bp == coin->current) ? &coin->RTramchain : &bp->ramchain; + if ( (rdata= ramchain->H.data) != 0 ) { if ( (TXbits= ramchain->txbits) == 0 ) { @@ -281,9 +289,9 @@ struct iguana_txid *iguana_txidfind(struct iguana_info *coin,int32_t *heightp,st iguana_alloctxbits(coin,ramchain); if ( (TXbits= ramchain->txbits) == 0 ) { - //printf("use memory mapped.[%d]\n",ramchain->H.data->height/coin->chain->bundlesize); - TXbits = RAMCHAIN_PTR(ramchain->H.data,TXoffset); - //TXbits = (void *)(long)((long)ramchain->H.data + ramchain->H.data->TXoffset); + //printf("use memory mapped.[%d]\n",rdata->height/coin->chain->bundlesize); + TXbits = RAMCHAIN_PTR(rdata,TXoffset); + //TXbits = (void *)(long)((long)rdata + rdata->TXoffset); } } if ( (T= ramchain->cacheT) == 0 ) @@ -291,10 +299,10 @@ struct iguana_txid *iguana_txidfind(struct iguana_info *coin,int32_t *heightp,st //if ( coin->fastfind == 0 ) // iguana_alloccacheT(coin,ramchain); //if ( (T= ramchain->cacheT) == 0 ) - T = RAMCHAIN_PTR(ramchain->H.data,Toffset); - //T = (void *)(long)((long)ramchain->H.data + ramchain->H.data->Toffset); + T = RAMCHAIN_PTR(rdata,Toffset); + //T = (void *)(long)((long)rdata + rdata->Toffset); } - if ( (txidind= iguana_sparseaddtx(TXbits,ramchain->H.data->txsparsebits,ramchain->H.data->numtxsparse,txid,T,0,ramchain)) > 0 ) + if ( (txidind= iguana_sparseaddtx(TXbits,rdata->txsparsebits,rdata->numtxsparse,txid,T,0,ramchain)) > 0 ) { //printf("found txidind.%d\n",txidind); if ( bits256_cmp(txid,T[txidind].txid) == 0 ) @@ -323,6 +331,7 @@ struct iguana_txid *iguana_txidfind(struct iguana_info *coin,int32_t *heightp,st *heightp = bp->bundleheight + T[txidind].bundlei; //printf("found height.%d\n",*heightp); *tx = T[txidind]; + //printf("[%d] txidind.%d 1st.(%d %d)\n",bp->hdrsi,txidind,tx->firstvout,tx->firstvin); return(tx); } } @@ -530,7 +539,7 @@ int64_t iguana_fastfindcreate(struct iguana_info *coin) } for (i=errs=0; i<0x100; i++) { - fclose(coin->fastfps[i]); + fclose(coin->fastfps[i]), coin->fastfps[i] = 0; sprintf(fname,"DB/%s/fastfind/%02x",coin->symbol,i), OS_compatible_path(fname); //printf("%s\n",fname); if ( (sortbuf= OS_filestr(&allocsize,fname)) != 0 ) @@ -576,8 +585,7 @@ int64_t iguana_fastfindcreate(struct iguana_info *coin) } if ( fwrite(hashtable,sizeof(*hashtable),tablesize,coin->fastfps[i]) == tablesize ) { - fclose(coin->fastfps[i]); - coin->fastfps[i] = 0; + fclose(coin->fastfps[i]), coin->fastfps[i] = 0; if ( (coin->fast[i]= OS_mapfile(fname,&coin->fastsizes[i],0)) != 0 ) { } else errs++; @@ -587,8 +595,7 @@ int64_t iguana_fastfindcreate(struct iguana_info *coin) { printf("error saving (%s)\n",fname); OS_removefile(fname,0); - fclose(coin->fastfps[i]); - coin->fastfps[i] = 0; + fclose(coin->fastfps[i]), coin->fastfps[i] = 0; } free(hashtable); } else printf("couldnt overwrite (%s)\n",fname); @@ -602,3 +609,67 @@ int64_t iguana_fastfindcreate(struct iguana_info *coin) } return(total); } + +struct iguana_monitorinfo *iguana_monitorfind(struct iguana_info *coin,bits256 txid) +{ + int32_t i; + for (i=0; imonitoring)/sizeof(*coin->monitoring); i++) + if ( bits256_cmp(coin->monitoring[i].txid,txid) == 0 ) + return(&coin->monitoring[i]); + return(0); +} + +struct iguana_monitorinfo *iguana_txidreport(struct iguana_info *coin,bits256 txid,struct iguana_peer *addr) +{ + struct iguana_monitorinfo *ptr; char str[65]; + if ( (ptr= iguana_monitorfind(coin,txid)) != 0 ) + { + if ( GETBIT(ptr->peerbits,addr->addrind) == 0 ) + { + char str[65]; printf("%s reports %s\n",addr->ipaddr,bits256_str(str,txid)); + SETBIT(ptr->peerbits,addr->addrind); + ptr->numreported++; + } + } else printf("txid.%s not being monitored\n",bits256_str(str,txid)); + return(0); +} + +struct iguana_monitorinfo *iguana_txidmonitor(struct iguana_info *coin,bits256 txid) +{ + int32_t i; struct iguana_monitorinfo *ptr; + if ( (ptr= iguana_monitorfind(coin,txid)) == 0 ) + { + for (i=0; imonitoring)/sizeof(*coin->monitoring); i++) + if ( bits256_nonz(coin->monitoring[i].txid) == 0 ) + { + memset(&coin->monitoring[i],0,sizeof(coin->monitoring[i])); + coin->monitoring[i].txid = txid; + return(ptr); + } + } + printf("no monitoring slots left\n"); + return(0); +} + +double iguana_txidstatus(struct supernet_info *myinfo,struct iguana_info *coin,bits256 txid) +{ + int32_t height,firstvout,numranked; struct iguana_monitorinfo *ptr; char str[65]; + if ( coin != 0 && coin->peers != 0 && (numranked= coin->peers->numranked) > 0 ) + { + if ( (firstvout= iguana_RTunspentindfind(myinfo,coin,0,0,0,0,&height,txid,0,coin->bundlescount-1,0)) != 0 ) + { + if ( (ptr= iguana_monitorfind(coin,txid)) != 0 ) + memset(ptr,0,sizeof(*ptr)); + return((double)coin->longestchain - height); + } + if ( (ptr= iguana_monitorfind(coin,txid)) != 0 ) + return((double)ptr->numreported / numranked); + else + { + printf("iguana_txidstatus: unexpected missing %s %s\n",coin->symbol,bits256_str(str,txid)); + iguana_txidmonitor(coin,txid); + } + } + return(0.); +} + diff --git a/iguana/iguana_unspents.c b/iguana/iguana_unspents.c index 861f6434a..46cdeb34b 100755 --- a/iguana/iguana_unspents.c +++ b/iguana/iguana_unspents.c @@ -20,9 +20,96 @@ #include "iguana777.h" #include "exchanges/bitcoin.h" -int32_t iguana_unspentindfind(struct iguana_info *coin,char *coinaddr,uint8_t *spendscript,int32_t *spendlenp,uint64_t *valuep,int32_t *heightp,bits256 txid,int32_t vout,int32_t lasthdrsi) +int32_t iguana_RTunspentind2txid(struct supernet_info *myinfo,struct iguana_info *coin,int32_t *spentheightp,bits256 *txidp,int32_t *voutp,struct iguana_outpoint outpt) { - struct iguana_txid *tp,TX; struct iguana_pkhash *P; struct iguana_unspent *U; struct iguana_bundle *bp; struct iguana_ramchaindata *rdata; int64_t RTspend; int32_t pkind,hdrsi,firstvout,spentheight,unspentind = -1; + struct iguana_ramchaindata *rdata=0; struct iguana_bundle *bp=0; struct iguana_unspent *U,*u; struct iguana_txid *T,*t; struct iguana_RTunspent *unspent; struct iguana_RTtxid *parent; + *voutp = *spentheightp = -1; + memset(txidp,0,sizeof(*txidp)); + if ( outpt.isptr != 0 && (unspent= outpt.ptr) != 0 ) + { + if ( (parent= unspent->parent) != 0 ) + { + *txidp = parent->txid; + *spentheightp = parent->height; + } + *voutp = unspent->vout; + return(0); + } + memset(txidp,0,sizeof(*txidp)); + //if ( hdrsi == coin->bundlescount-1 ) + // rdata = coin->RTramchain.H.data; + //else if ( (bp= coin->bundles[hdrsi]) != 0 ) + bp = coin->bundles[outpt.hdrsi]; + rdata = bp->ramchain.H.data; + while ( rdata != 0 && outpt.unspentind > 0 && outpt.unspentind < rdata->numunspents ) + { + U = RAMCHAIN_PTR(rdata,Uoffset); + u = &U[outpt.unspentind]; + if ( u->txidind > 0 && u->txidind < rdata->numtxids ) + { + T = RAMCHAIN_PTR(rdata,Toffset); + t = &T[u->txidind]; + if ( outpt.unspentind >= t->firstvout ) + { + *txidp = t->txid; + *spentheightp = (outpt.hdrsi * coin->chain->bundlesize) + t->bundlei; + *voutp = outpt.unspentind - t->firstvout; + return(0); + } + } + else if ( bp == 0 && (bp= coin->bundles[outpt.hdrsi]) != 0 ) + rdata = bp->ramchain.H.data; + else break; + } + return(-1); + //{"txid":"e34686afc17ec37a8438f0c9a7e48f98d0c625c7917a59c2d7fa22b53d570115","vout":1,"address":"16jsjc1YvzDXqKf7PorMhTyK8ym3ra3uxm","scriptPubKey":"76a9143ef4734c1141725c095342095f6e0e7748b6c16588ac","amount":0.01000000,"timestamp":0,"height":419261,"confirmations":1729,"checkind":4497018,"account":"default","spendable":true,"spent":{"hdrsi":209,"pkind":2459804,"unspentind":4497018,"prevunspentind":0,"satoshis":"1000000","txidind":1726947,"vout":1,"type":2,"fileid":0,"scriptpos":0,"scriptlen":25},"spentheight":419713,"dest":{"spentfrom":"22651e62f248fe2e72053d650f177e4b246ee016605102a40419e603b2bbeac8","vin":0,"timestamp":0,"vouts":[{"1KRhTPvoxyJmVALwHFXZdeeWFbcJSbkFPu":0.00010000}, {"1GQHQ7vwVpGeir2kKrYATsLtrkUQSc7FGY":0.00980000}],"total":0.00990000,"ratio":1}} + /* cJSON *retarray,*item,*uitem,*sitem; char *retstr; int32_t i,n,retval = -1; + *voutp = *spentheightp = -1; + memset(txidp,0,sizeof(*txidp)); + if ( (retstr= bitcoinrpc_listunspent(myinfo,coin,0,0,0,0,0)) != 0 ) + { + if ( (retarray= cJSON_Parse(retstr)) != 0 ) + { + if ( (n= cJSON_GetArraySize(retarray)) > 0 ) + { + for (i=0; iRTmutex); if ( valuep != 0 ) *valuep = 0; if ( coinaddr != 0 ) @@ -33,15 +120,23 @@ int32_t iguana_unspentindfind(struct iguana_info *coin,char *coinaddr,uint8_t *s unspentind = (tp->firstvout + vout); if ( coinaddr != 0 && unspentind > 0 && (hdrsi= *heightp/coin->chain->bundlesize) >= 0 && hdrsi < coin->bundlescount && (bp= coin->bundles[hdrsi]) != 0 && (rdata= bp->ramchain.H.data) != 0 && unspentind < rdata->numunspents ) { + if ( time(NULL) > bp->lastprefetch+777 ) + { + //fprintf(stderr,"pf.[%d] ",bp->hdrsi); + iguana_ramchain_prefetch(coin,&bp->ramchain,0); + bp->lastprefetch = (uint32_t)time(NULL); + } U = RAMCHAIN_PTR(rdata,Uoffset); P = RAMCHAIN_PTR(rdata,Poffset); - //U = (void *)(long)((long)rdata + rdata->Uoffset); - //P = (void *)(long)((long)rdata + rdata->Poffset); pkind = U[unspentind].pkind; if ( pkind > 0 && pkind < rdata->numpkinds ) { RTspend = 0; - if ( iguana_spentflag(coin,&RTspend,&spentheight,bp == coin->current ? &coin->RTramchain : &bp->ramchain,bp->hdrsi,unspentind,0,1,coin->longestchain,U[unspentind].value) == 0 ) + flag++; + memset(&spentpt,0,sizeof(spentpt)); + spentpt.hdrsi = bp->hdrsi; + spentpt.unspentind = unspentind; + if ( iguana_RTspentflag(myinfo,coin,&RTspend,&spentheight,&bp->ramchain,spentpt,0,1,coin->longestchain,U[unspentind].value) == 0 ) //bp == coin->current ? &coin->RTramchain : { if ( valuep != 0 ) *valuep = U[unspentind].value; @@ -51,9 +146,53 @@ int32_t iguana_unspentindfind(struct iguana_info *coin,char *coinaddr,uint8_t *s } } } + if ( flag == 0 && mempool != 0 ) + { + if ( (memtx= gecko_unspentfind(0,coin,txid)) != 0 && vout < memtx->numoutputs ) + { + memcpy(&value,gecko_valueptr(memtx,vout),sizeof(value)); + if ( value > 0 ) + { + *valuep = value; + if ( spendlenp != 0 ) + { + *spendlenp = 1; + spendscript = 0; + printf("mempool unspentind doesnt support scriptlenp yet\n"); + } + } + } + } + //portable_mutex_unlock(&coin->RTmutex); return(unspentind); } +char *iguana_RTinputaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr,struct iguana_outpoint *spentp,cJSON *vinobj) +{ + bits256 txid; int32_t vout,checkind,height; + memset(spentp,0,sizeof(*spentp)); + spentp->hdrsi = -1; + if ( jobj(vinobj,"txid") != 0 && jobj(vinobj,"vout") != 0 ) + { + txid = jbits256(vinobj,"txid"); + vout = jint(vinobj,"vout"); + height = jint(vinobj,"height"); + checkind = jint(vinobj,"checkind"); + if ( (height != 0 && checkind != 0) || (checkind= iguana_RTunspentindfind(myinfo,coin,coinaddr,0,0,0,&height,txid,vout,coin->bundlescount-1,0)) > 0 ) + { + spentp->hdrsi = (height / coin->chain->bundlesize); + spentp->unspentind = checkind; + return(coinaddr); + } + else + { + char str[65]; + printf("error finding (%s/%d) height.%d checkind.%d\n",bits256_str(str,txid),vout,height,checkind); + } + } + return(0); +} + cJSON *ramchain_unspentjson(struct iguana_unspent *up,uint32_t unspentind) { cJSON *item = cJSON_CreateObject(); @@ -71,7 +210,68 @@ cJSON *ramchain_unspentjson(struct iguana_unspent *up,uint32_t unspentind) return(item); } -cJSON *iguana_unspentjson(struct supernet_info *myinfo,struct iguana_info *coin,int32_t hdrsi,uint32_t unspentind,struct iguana_txid *T,struct iguana_unspent *up,uint8_t rmd160[20],char *coinaddr,uint8_t *pubkey33) +cJSON *ramchain_spentjson(struct iguana_info *coin,int32_t spentheight,bits256 txid,int32_t vout,int64_t uvalue) +{ + char coinaddr[64]; bits256 hash2,*X; struct iguana_txid T,*tx,*spentT,*spent_tx; struct iguana_bundle *bp; int32_t j,i,ind; struct iguana_block *block; int64_t total = 0; struct iguana_unspent *U,*u; struct iguana_pkhash *P; struct iguana_spend *S,*s; struct iguana_ramchaindata *rdata; cJSON *addrs,*item,*voutobj; + item = cJSON_CreateObject(); + hash2 = iguana_blockhash(coin,spentheight); + if ( (block= iguana_blockfind("spent",coin,hash2)) != 0 && (bp= coin->bundles[spentheight/coin->chain->bundlesize]) != 0 && (rdata= bp->ramchain.H.data) != 0 ) + { + X = RAMCHAIN_PTR(rdata,Xoffset); + S = RAMCHAIN_PTR(rdata,Soffset); + U = RAMCHAIN_PTR(rdata,Uoffset); + P = RAMCHAIN_PTR(rdata,Poffset); + spentT = RAMCHAIN_PTR(rdata,Toffset); + for (i=0; iRO.txn_count; i++) + { + if ( (tx= iguana_blocktx(coin,&T,block,i)) != 0 ) + { + // struct iguana_txid { bits256 txid; uint32_t txidind:29,firstvout:28,firstvin:28,bundlei:11,locktime,version,timestamp,extraoffset; uint16_t numvouts,numvins; } __attribute__((packed)); + // struct iguana_spend { uint64_t scriptpos:48,scriptlen:16; uint32_t spendtxidind,sequenceid; int16_t prevout; uint16_t fileid:15,external:1; } __attribute__((packed)); // numsigs:4,numpubkeys:4,p2sh:1,sighash:4 + s = &S[tx->firstvin]; + for (j=0; jnumvins; j++,s++) + { + if ( s->prevout == vout ) + { + if ( s->external != 0 ) + { + ind = s->spendtxidind & 0xfffffff; + if ( bits256_cmp(X[ind],txid) != 0 ) + continue; + } + else + { + spent_tx = &spentT[s->spendtxidind]; + if ( bits256_cmp(spent_tx->txid,txid) != 0 ) + continue; + } + jaddbits256(item,"spentfrom",tx->txid); + jaddnum(item,"vin",j); + jaddnum(item,"timestamp",tx->timestamp); + u = &U[tx->firstvout]; + addrs = cJSON_CreateArray(); + for (j=0; jnumvouts; j++,u++) + { + voutobj = cJSON_CreateObject(); + bitcoin_address(coinaddr,iguana_addrtype(coin,u->type),P[u->pkind].rmd160,sizeof(P[u->pkind].rmd160)); + jaddnum(voutobj,coinaddr,dstr(u->value)); + jaddi(addrs,voutobj); + total += u->value; + } + jadd(item,"vouts",addrs); + jaddnum(item,"total",dstr(total)); + jaddnum(item,"ratio",dstr(uvalue) / dstr(total+coin->txfee)); + return(item); + } + } + } + } + } + jaddstr(item,"error","couldnt find spent info"); + return(item); +} + +cJSON *iguana_RTunspentjson(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_outpoint outpt,bits256 txid,int32_t vout,int64_t value,struct iguana_unspent *up,uint8_t rmd160[20],char *coinaddr,uint8_t *pubkey33,int32_t spentheight,char *remoteaddr) { /*{ "txid" : "d54994ece1d11b19785c7248868696250ab195605b469632b7bd68130e880c9a", @@ -84,34 +284,72 @@ cJSON *iguana_unspentjson(struct supernet_info *myinfo,struct iguana_info *coin, "spendable" : true },*/ //struct iguana_unspent { uint64_t value; uint32_t txidind,pkind,prevunspentind; uint16_t hdrsi:12,type:4,vout; } __attribute__((packed)); - struct iguana_waccount *wacct; struct iguana_waddress *waddr; int32_t height; char scriptstr[8192],asmstr[sizeof(scriptstr)+1024]; cJSON *item; uint32_t checkind; + struct iguana_waccount *wacct; struct iguana_waddress *waddr; int32_t height; char scriptstr[8192],asmstr[sizeof(scriptstr)+1024]; cJSON *item; uint32_t checkind; struct iguana_RTunspent *unspent; item = cJSON_CreateObject(); - jaddbits256(item,"txid",T[up->txidind].txid); - jaddnum(item,"vout",up->vout); + jaddbits256(item,"txid",txid); + jaddnum(item,"vout",vout); jaddstr(item,"address",coinaddr); - if ( iguana_scriptget(coin,scriptstr,asmstr,sizeof(scriptstr),hdrsi,unspentind,T[up->txidind].txid,up->vout,rmd160,up->type,pubkey33) != 0 ) - jaddstr(item,"scriptPubKey",scriptstr); - jaddnum(item,"amount",dstr(up->value)); - if ( (checkind= iguana_unspentindfind(coin,0,0,0,0,&height,T[up->txidind].txid,up->vout,coin->bundlescount-1)) != 0 ) + if ( outpt.isptr != 0 && (unspent= outpt.ptr) != 0 ) + { + if ( unspent->scriptlen > 0 ) + { + init_hexbytes_noT(scriptstr,unspent->script,unspent->scriptlen); + jaddstr(item,"scriptPubKey",scriptstr); + } + } + else + { + if ( iguana_scriptget(coin,scriptstr,asmstr,sizeof(scriptstr),outpt.hdrsi,outpt.unspentind,txid,vout,rmd160,up!=0?up->type:2,pubkey33) != 0 ) + jaddstr(item,"scriptPubKey",scriptstr); + } + jaddnum(item,"amount",dstr(value)); + //jaddnum(item,"timestamp",T[up->txidind].timestamp); + if ( (checkind= iguana_RTunspentindfind(myinfo,coin,0,0,0,0,&height,txid,vout,coin->bundlescount-1,0)) != 0 ) { + jaddnum(item,"height",height); jaddnum(item,"confirmations",coin->blocks.hwmchain.height - height + 1); jaddnum(item,"checkind",checkind); } - if ( (waddr= iguana_waddresssearch(myinfo,coin,&wacct,coinaddr)) != 0 ) + if ( remoteaddr == 0 || remoteaddr[0] == 0 ) { - jaddstr(item,"account",wacct->account); - jadd(item,"spendable",jtrue()); - } else jadd(item,"spendable",jfalse()); - jadd(item,"unspent",ramchain_unspentjson(up,unspentind)); + if ( (waddr= iguana_waddresssearch(myinfo,&wacct,coinaddr)) != 0 ) + { + jaddstr(item,"account",wacct->account); + if ( spentheight == 0 ) + jadd(item,"spendable",jtrue()); + else jadd(item,"spendable",jfalse()); + } else jadd(item,"spendable",jfalse()); + } + if ( spentheight > 0 ) + { + if ( up != 0 ) + jadd(item,"spent",ramchain_unspentjson(up,outpt.unspentind)); + jaddnum(item,"spentheight",spentheight); + jadd(item,"dest",ramchain_spentjson(coin,spentheight,txid,vout,value)); + } + else if ( up != 0 ) + jadd(item,"unspent",ramchain_unspentjson(up,outpt.unspentind)); return(item); } -struct iguana_pkhash *iguana_pkhashfind(struct iguana_info *coin,struct iguana_ramchain **ramchainp,int64_t *depositsp,uint32_t *lastunspentindp,struct iguana_pkhash *p,uint8_t rmd160[20],int32_t firsti,int32_t endi) +struct iguana_pkhash *iguana_pkhashfind(struct iguana_info *coin,struct iguana_ramchain **ramchainp,int64_t *depositsp,struct iguana_outpoint *lastptp,struct iguana_pkhash *p,uint8_t rmd160[20],int32_t firsti,int32_t endi) { - uint8_t *PKbits; struct iguana_pkhash *P; uint32_t pkind,numpkinds,i; struct iguana_bundle *bp; struct iguana_ramchain *ramchain; struct iguana_ramchaindata *rdata; struct iguana_account *ACCTS; + uint8_t *PKbits; struct iguana_pkhash *P; uint32_t pkind,numpkinds,i; struct iguana_bundle *bp; struct iguana_ramchain *ramchain; struct iguana_ramchaindata *rdata; struct iguana_account *ACCTS; struct iguana_RTaddr *RTaddr; *depositsp = 0; *ramchainp = 0; - *lastunspentindp = 0; + memset(lastptp,0,sizeof(*lastptp)); + if ( firsti == coin->bundlescount && endi == firsti ) + { + if ( (RTaddr= iguana_RTaddrfind(coin,rmd160,0)) != 0 ) + { + *depositsp = RTaddr->credits; + if ( (lastptp->ptr= RTaddr->lastunspent) != 0 ) + lastptp->isptr = 1; + memcpy(p->rmd160,rmd160,sizeof(p->rmd160)); + p->pkind = 0; + return(p); + } else return(0); + } for (i=firsti; ibundlescount&&i<=endi; i++) { if ( (bp= coin->bundles[i]) != 0 ) @@ -121,30 +359,30 @@ struct iguana_pkhash *iguana_pkhashfind(struct iguana_info *coin,struct iguana_r printf("iguana_pkhashfind: unexpected access when RTramchain_busy\n"); return(0); } - ramchain = (bp != coin->current) ? &bp->ramchain : &coin->RTramchain; - if ( (rdata= ramchain->H.data) != 0 ) + ramchain = &bp->ramchain;//(bp != coin->current) ? &bp->ramchain : &coin->RTramchain; + // prevent remote query access before RTmode + if ( (rdata= ramchain->H.data) != 0 && time(NULL) > bp->emitfinish+10 ) { numpkinds = rdata->numpkinds; PKbits = RAMCHAIN_PTR(rdata,PKoffset); P = RAMCHAIN_PTR(rdata,Poffset); - //PKbits = (void *)(long)((long)rdata + rdata->PKoffset); - //P = (void *)(long)((long)rdata + rdata->Poffset); if ( bp == coin->current ) ACCTS = ramchain->A; - else ACCTS = RAMCHAIN_PTR(rdata,Aoffset); //ACCTS = (void *)(long)((long)rdata + rdata->Aoffset); + else ACCTS = RAMCHAIN_PTR(rdata,Aoffset); if ( (pkind= iguana_sparseaddpk(PKbits,rdata->pksparsebits,rdata->numpksparse,rmd160,P,0,ramchain)) > 0 && pkind < numpkinds ) { *ramchainp = ramchain; *depositsp = ACCTS[pkind].total; - *lastunspentindp = ACCTS[pkind].lastunspentind; - printf("[%d] return pkind.%u of %u P.%p %.8f last.%u ACCTS.%p %p\n",i,pkind,numpkinds,P,dstr(*depositsp),*lastunspentindp,ACCTS,ramchain->A); + lastptp->hdrsi = bp->hdrsi; + lastptp->unspentind = ACCTS[pkind].lastunspentind; + //printf("[%d] return pkind.%u of %u P.%p %.8f last.%u ACCTS.%p %p\n",i,pkind,numpkinds,P,dstr(*depositsp),*lastunspentindp,ACCTS,ramchain->A); if ( P != 0 ) *p = P[pkind]; return(p); - } - else if ( pkind != 0 ) + } else if ( pkind != 0 ) printf("[%d] not found pkind.%d vs num.%d RT.%d rdata.%p\n",i,pkind,rdata->numpkinds,bp->isRT,rdata); - } else printf("%s.[%d] error null rdata isRT.%d\n",coin->symbol,i,bp->isRT); + } else if ( coin->spendvectorsaved > 1 && bp != coin->current && bp->bundleheight < coin->firstRTheight ) + printf("%s.[%d] skip null rdata isRT.%d [%d]\n",coin->symbol,i,bp->isRT,coin->current!=0?coin->current->hdrsi:-1); } } return(0); @@ -157,9 +395,77 @@ int32_t iguana_uheight(struct iguana_info *coin,int32_t bundleheight,struct igua else return(bundleheight); } -int64_t iguana_pkhashbalance(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *array,int64_t *spentp,uint64_t *unspents,int32_t *nump,struct iguana_ramchain *ramchain,struct iguana_pkhash *p,uint32_t lastunspentind,uint8_t rmd160[20],char *coinaddr,uint8_t *pubkey33,int32_t hdrsi,int32_t lastheight,int32_t minconf,int32_t maxconf) +int32_t iguana_datachain_scan(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t rmd160[20]) +{ + int64_t deposits,crypto777_payment; struct iguana_outpoint lastpt; uint32_t unspentind; int32_t i,j,num,uheight; struct iguana_bundle *bp; struct iguana_ramchain *ramchain; struct iguana_ramchaindata *rdata; struct iguana_pkhash *P,p; struct iguana_unspent *U,*u; struct iguana_txid *T,*tx; + for (i=num=0; ibundlescount&&i*coin->chain->bundlesizefirstRTheight; i++) + { + if ( (bp= coin->bundles[i]) != 0 ) + { + ramchain = 0; + memset(&lastpt,0,sizeof(lastpt)); + if ( iguana_pkhashfind(coin,&ramchain,&deposits,&lastpt,&p,rmd160,i,i) != 0 ) + { + if ( ramchain != 0 && (rdata= ramchain->H.data) != 0 ) + { + unspentind = lastpt.unspentind; + U = RAMCHAIN_PTR(rdata,Uoffset); + T = RAMCHAIN_PTR(rdata,Toffset); + P = RAMCHAIN_PTR(rdata,Poffset); + while ( unspentind > 0 ) + { + tx = &T[U[unspentind].txidind]; + u = &U[tx->firstvout]; + uheight = iguana_uheight(coin,ramchain->height,T,rdata->numtxids,u); + for (crypto777_payment=j=0; jnumvouts; j++,u++) + { + crypto777_payment = datachain_update(myinfo,0,coin,tx->timestamp,bp,P[u->pkind].rmd160,crypto777_payment,u->type,uheight,(((uint64_t)bp->hdrsi << 32) | unspentind),u->value,u->fileid,u->scriptpos,u->scriptlen,tx->txid,j); + } + num++; + unspentind = U[unspentind].prevunspentind; + } + } + } + } + } + // do a RT scan here + return(num); +} + +int32_t iguana_RTscanunspents(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,cJSON *array,int64_t *spentp,int64_t *depositsp,struct iguana_outpoint *unspents,int32_t max,uint8_t *rmd160,char *coinaddr,uint8_t *pubkey33,struct iguana_outpoint lastpt,int32_t lastheight) +{ + int32_t spentheight,n = 0; struct iguana_outpoint outpt; bits256 txid; struct iguana_RTtxid *parent; struct iguana_RTunspent *unspent = lastpt.ptr; + while ( unspent != 0 ) + { + if ( lastheight <= 0 || unspent->height < lastheight ) + { + if ( unspent->spend == 0 ) + { + spentheight = unspent->height; + memset(&outpt,0,sizeof(outpt)); + memset(&txid,0,sizeof(txid)); + if ( (parent= unspent->parent) != 0 ) + txid = parent->txid; + else printf("unspent has no parent?\n"); + outpt.isptr = 1; + outpt.ptr = unspent; + outpt.hdrsi = unspent->height / coin->chain->bundlesize; + if ( array != 0 ) + jaddi(array,iguana_RTunspentjson(myinfo,coin,outpt,txid,unspent->vout,unspent->value,0,rmd160,coinaddr,pubkey33,spentheight,remoteaddr)); + *depositsp += unspent->value; + if ( unspents != 0 ) + unspents[n] = outpt; + n++; + } else *spentp += unspent->value; + } + unspent = unspent->prevunspent; + } + return(n); +} + +int64_t iguana_RTpkhashbalance(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *array,int64_t *spentp,struct iguana_outpoint *unspents,int32_t *nump,struct iguana_ramchain *ramchain,struct iguana_pkhash *p,struct iguana_outpoint lastpt,uint8_t rmd160[20],char *coinaddr,uint8_t *pubkey33,int32_t lastheight,int32_t minconf,int32_t maxconf,char *remoteaddr,int32_t includespent) { - struct iguana_unspent *U; struct iguana_utxo *U2; struct iguana_spend *S; int32_t max,uheight,spentheight; uint32_t pkind=0,unspentind; int64_t spent = 0,checkval,deposits = 0; struct iguana_txid *T; struct iguana_account *A2; struct iguana_ramchaindata *rdata = 0; int64_t RTspend = 0; + struct iguana_unspent *U; struct iguana_utxo *U2; int32_t spentflag,max,uheight,spentheight; uint32_t pkind=0,unspentind; int64_t spent = 0,checkval,deposits = 0; struct iguana_txid *T; struct iguana_account *A2; struct iguana_outpoint outpt; struct iguana_ramchaindata *rdata = 0; int64_t RTspend = 0; //struct iguana_spend *S; max = *nump; *spentp = *nump = 0; if ( 0 && coin->RTramchain_busy != 0 ) @@ -167,43 +473,65 @@ int64_t iguana_pkhashbalance(struct supernet_info *myinfo,struct iguana_info *co printf("iguana_pkhashbalance: unexpected access when RTramchain_busy\n"); return(0); } + if ( ramchain == 0 ) // RT search + { + if ( lastpt.isptr != 0 ) + { + *nump = iguana_RTscanunspents(myinfo,coin,remoteaddr,array,spentp,&deposits,unspents,max,rmd160,coinaddr,pubkey33,lastpt,lastheight); + } else printf("iguana_pkhashbalance: unexpected non-ptr lastpt\n"); + return(deposits - *spentp); + } if ( ramchain->Uextras == 0 || (rdata= ramchain->H.data) == 0 ) { - printf("iguana_pkhashbalance: unexpected null spents.%p or rdata.%p\n",ramchain->Uextras,rdata); + if ( ramchain->height < (coin->bundlescount-1)*coin->chain->bundlesize ) + { + //printf("iguana_pkhashbalance.[%d] %d: unexpected null spents.%p or rdata.%p\n",ramchain->height,(coin->bundlescount-1)*coin->chain->bundlesize,ramchain->Uextras,rdata); + } else iguana_volatilesalloc(coin,ramchain,0); return(0); } - unspentind = lastunspentind; + unspentind = lastpt.unspentind; U = RAMCHAIN_PTR(rdata,Uoffset); T = RAMCHAIN_PTR(rdata,Toffset); - //U = (void *)(long)((long)rdata + rdata->Uoffset); - //T = (void *)(long)((long)rdata + rdata->Toffset); RTspend = 0; if ( lastheight == 0 ) lastheight = IGUANA_MAXHEIGHT; while ( unspentind > 0 ) { uheight = iguana_uheight(coin,ramchain->height,T,rdata->numtxids,&U[unspentind]); - if ( uheight < lastheight ) + if ( lastheight <= 0 || uheight < lastheight ) { deposits += U[unspentind].value; - if ( lastheight < 0 || iguana_spentflag(coin,&RTspend,&spentheight,ramchain,hdrsi,unspentind,lastheight,minconf,maxconf,U[unspentind].value) == 0 ) + memset(&outpt,0,sizeof(outpt)); + outpt.hdrsi = lastpt.hdrsi; + outpt.isptr = 0; + outpt.unspentind = unspentind; + outpt.value = U[unspentind].value; + RTspend = 0; + if ( iguana_RTspentflag(myinfo,coin,&RTspend,&spentheight,ramchain,outpt,lastheight,minconf,maxconf,U[unspentind].value) == 0 ) { if ( *nump < max && unspents != 0 ) - unspents[*nump] = ((uint64_t)hdrsi << 32) | unspentind; + unspents[*nump] = outpt; + //printf("+%.8f ",dstr(U[unspentind].value)); (*nump)++; - if ( array != 0 ) - jaddi(array,iguana_unspentjson(myinfo,coin,hdrsi,unspentind,T,&U[unspentind],rmd160,coinaddr,pubkey33)); - } else spent += U[unspentind].value; + spentflag = 0; + } + else + { + //printf("-%.8f ",dstr(U[unspentind].value)); + spent += U[unspentind].value; + spentflag = 1; + } + if ( array != 0 && (spentflag == 0 || includespent != 0) ) + jaddi(array,iguana_RTunspentjson(myinfo,coin,outpt,T[U[unspentind].txidind].txid,U[unspentind].vout,U[unspentind].value,&U[unspentind],rmd160,coinaddr,pubkey33,spentheight,remoteaddr)); if ( p->pkind != U[unspentind].pkind ) - printf("warning: [%d] p->pkind.%u vs U->pkind.%u for u%d\n",hdrsi,p->pkind,U[unspentind].pkind,unspentind); - } + printf("warning: [%d] p->pkind.%u vs U->pkind.%u for u%d\n",lastpt.hdrsi,p->pkind,U[unspentind].pkind,unspentind); + } // else printf("skip uheight.%d lastheight.%d\n",uheight,lastheight); pkind = p->pkind; unspentind = U[unspentind].prevunspentind; } if ( lastheight > 0 && (A2= ramchain->A2) != 0 && (U2= ramchain->Uextras) != 0 ) { - S = RAMCHAIN_PTR(rdata,Soffset); - //S = (void *)(long)((long)rdata + rdata->Soffset); + //S = RAMCHAIN_PTR(rdata,Soffset); unspentind = A2[pkind].lastunspentind; checkval = 0; while ( unspentind > 0 ) @@ -216,69 +544,90 @@ int64_t iguana_pkhashbalance(struct supernet_info *myinfo,struct iguana_info *co } unspentind = U2[unspentind].prevunspentind; } - if ( llabs(spent - checkval - RTspend) > SMALLVAL ) - printf("spend %s: [%d] deposits %.8f spent %.8f check %.8f (%.8f) vs A2[%u] %.8f\n",lastheight==IGUANA_MAXHEIGHT?"checkerr":"",hdrsi,dstr(deposits),dstr(spent),dstr(checkval)+dstr(RTspend),dstr(*spentp),pkind,dstr(A2[pkind].total)); + if ( 0 && llabs(spent - checkval - RTspend) > SMALLVAL ) + printf("spend %s: [%d] deposits %.8f spent %.8f check %.8f (%.8f) vs A2[%u] %.8f\n",lastheight==IGUANA_MAXHEIGHT?"checkerr":"",lastpt.hdrsi,dstr(deposits),dstr(spent),dstr(checkval)+dstr(RTspend),dstr(*spentp),pkind,dstr(A2[pkind].total)); } (*spentp) = spent; - //printf("spent %.8f, RTspent %.8f deposits %.8f\n",dstr(spent),dstr(RTspend),dstr(deposits)); + //printf("(%s) spent %.8f, RTspent %.8f deposits %.8f\n",coinaddr,dstr(spent),dstr(RTspend),dstr(deposits)); return(deposits - spent); } -int32_t iguana_pkhasharray(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *array,int32_t minconf,int32_t maxconf,int64_t *totalp,struct iguana_pkhash *P,int32_t max,uint8_t rmd160[20],char *coinaddr,uint8_t *pubkey33,int32_t lastheight,uint64_t *unspents,int32_t *numunspentsp,int32_t maxunspents) +int32_t iguana_RTpkhasharray(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *array,int32_t minconf,int32_t maxconf,uint64_t *totalp,struct iguana_pkhash *P,int32_t max,uint8_t rmd160[20],char *coinaddr,uint8_t *pubkey33,int32_t lastheight,struct iguana_outpoint *unspents,int32_t *numunspentsp,int32_t maxunspents,char *remoteaddr,int32_t includespent) { - int32_t i,n,m,numunspents = *numunspentsp; int64_t spent,deposits,netbalance,total; uint32_t lastunspentind; struct iguana_pkhash *p,_p; struct iguana_ramchain *ramchain; struct iguana_bundle *bp; + int32_t i,n,m,numunspents; int64_t spent,deposits,netbalance,total; struct iguana_outpoint lastpt; struct iguana_pkhash *p,_p; struct iguana_ramchain *ramchain; struct iguana_bundle *bp; if ( 0 && coin->RTramchain_busy != 0 ) { printf("iguana_pkhasharray: unexpected access when RTramchain_busy\n"); return(-1); } + numunspents = numunspentsp != 0 ? *numunspentsp : 0; if ( lastheight == 0 ) lastheight = IGUANA_MAXHEIGHT; if ( max > coin->bundlescount ) max = coin->bundlescount; - for (total=n=0,i=max-1; i>=0; i--) + //printf("minconf.%d maxconf.%d max.%d addr.%s last.%d maxunspents.%d\n",minconf,maxconf,max,coinaddr,lastheight,maxunspents); + for (total=n=i=0; i=coin->RTheight); i++) { - if ( (bp= coin->bundles[i]) == 0 ) + if ( i != max && (bp= coin->bundles[i]) == 0 ) continue; - if ( lastheight > 0 && bp->bundleheight > lastheight ) - break; - if ( (coin->blocks.hwmchain.height - (bp->bundleheight + bp->n - 1)) > maxconf ) - continue; - if ( (coin->blocks.hwmchain.height - bp->bundleheight) < minconf ) - break; - if ( iguana_pkhashfind(coin,&ramchain,&deposits,&lastunspentind,P != 0 ? &P[n] : &_p,rmd160,i,i) != 0 ) + else bp = 0; + if ( 0 && bp != 0 ) + { + if ( lastheight > 0 && bp->bundleheight > lastheight ) + { + //printf("lastheight.%d less than %d\n",lastheight,bp->bundleheight+bp->n); + break; + } + if ( (coin->blocks.hwmchain.height - (bp->bundleheight + bp->n - 1)) > maxconf ) + { + //printf("%d more than minconf.%d\n",(coin->blocks.hwmchain.height - (bp->bundleheight + bp->n - 1)),maxconf); + continue; + } + if ( (coin->blocks.hwmchain.height - bp->bundleheight) < minconf ) + { + //printf("%d less than minconf.%d\n",(coin->blocks.hwmchain.height - bp->bundleheight),minconf); + break; + } + } + if ( iguana_pkhashfind(coin,&ramchain,&deposits,&lastpt,P != 0 ? &P[n] : &_p,rmd160,i,i) != 0 ) { m = maxunspents; p = (P == 0) ? &_p : &P[n]; - if ( (netbalance= iguana_pkhashbalance(myinfo,coin,array,&spent,unspents != 0 ? &unspents[numunspents] : 0,&m,ramchain,p,lastunspentind,rmd160,coinaddr,pubkey33,i,lastheight,minconf,maxconf)) != deposits-spent && lastheight == IGUANA_MAXHEIGHT && minconf == 1 && maxconf > coin->blocks.hwmchain.height ) + if ( (netbalance= iguana_RTpkhashbalance(myinfo,coin,array,&spent,unspents != 0 ? &unspents[numunspents] : 0,&m,ramchain,p,lastpt,rmd160,coinaddr,pubkey33,lastheight,minconf,maxconf,remoteaddr,includespent)) != deposits-spent && lastheight == IGUANA_MAXHEIGHT && minconf == 1 && maxconf > coin->blocks.hwmchain.height ) { printf("pkhash balance mismatch from m.%d check %.8f vs %.8f spent %.8f [%.8f]\n",m,dstr(netbalance),dstr(deposits),dstr(spent),dstr(deposits)-dstr(spent)); } else { - //printf("pkhash balance.[%d] from m.%d check %.8f vs %.8f spent %.8f [%.8f]\n",i,m,dstr(netbalance),dstr(deposits),dstr(spent),dstr(deposits)-dstr(spent)); + //printf("%s pkhash balance.[%d] from m.%d check %.8f vs %.8f spent %.8f [%.8f]\n",coinaddr,i,m,dstr(netbalance),dstr(deposits),dstr(spent),dstr(deposits)-dstr(spent)); total += netbalance; n++; } - maxunspents -= m; + if ( maxunspents > 0 ) + { + maxunspents -= m; + if ( maxunspents <= 0 ) + break; + } numunspents += m; - printf("%d: balance %.8f, lastunspent.%u m.%d num.%d max.%d\n",i,dstr(total),lastunspentind,m,numunspents,maxunspents); + //printf("%d: balance %.8f, lastunspent.%u m.%d num.%d max.%d\n",i,dstr(total),lastunspentind,m,numunspents,maxunspents); } } if ( numunspentsp != 0 ) *numunspentsp = numunspents; - printf("numunspents.%d [%d] max.%d\n",numunspents,*numunspentsp,maxunspents); + //printf("numunspents.%d max.%d\n",numunspents,maxunspents); *totalp += total; return(n); } -int64_t iguana_unspents(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *array,int32_t minconf,int32_t maxconf,uint8_t *rmdarray,int32_t numrmds,int32_t lastheight,uint64_t *unspents,int32_t *numunspentsp) +int64_t iguana_RTunspents(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *array,int32_t minconf,int32_t maxconf,uint8_t *rmdarray,int32_t numrmds,int32_t lastheight,struct iguana_outpoint *unspents,int32_t *numunspentsp,char *remoteaddr,int32_t includespent) { - int64_t total=0,sum=0; struct iguana_pkhash *P; uint8_t *addrtypes,*pubkeys; int32_t i,numunspents,maxunspents,flag = 0; char coinaddr[64]; - if ( 0 && coin->RTramchain_busy != 0 ) + uint64_t total=0,sum=0; struct iguana_pkhash *P; uint8_t *addrtypes,*pubkeys; int32_t i,numunspents,maxunspents,flag = 0; char coinaddr[64]; + //portable_mutex_lock(&coin->RTmutex); + while ( 0 && coin->RTramchain_busy != 0 ) { - printf("iguana_pkhasharray: unexpected access when RTramchain_busy\n"); - return(sum); + fprintf(stderr,"iguana_pkhasharray: %s unexpected access when RTramchain_busy\n",coin->symbol); + sleep(1); } numunspents = 0; maxunspents = *numunspentsp; @@ -292,25 +641,28 @@ int64_t iguana_unspents(struct supernet_info *myinfo,struct iguana_info *coin,cJ { bitcoin_address(coinaddr,addrtypes[i],&rmdarray[i * 20],20); *numunspentsp = 0; - iguana_pkhasharray(myinfo,coin,array,minconf,maxconf,&total,P,coin->bundlescount,&rmdarray[i * 20],coinaddr,&pubkeys[33*i],lastheight,&unspents[numunspents],numunspentsp,maxunspents); - printf("iguana_unspents: i.%d of %d: %s %.8f numunspents.%d\n",i,numrmds,coinaddr,dstr(total),*numunspentsp); + iguana_RTpkhasharray(myinfo,coin,array,minconf,maxconf,&total,P,coin->bundlescount,&rmdarray[i * 20],coinaddr,&pubkeys[33*i],lastheight,&unspents[numunspents],numunspentsp,maxunspents,remoteaddr,includespent); + //printf("iguana_unspents: i.%d of %d: %s %.8f numunspents.%d\n",i,numrmds,coinaddr,dstr(total),*numunspentsp); maxunspents -= *numunspentsp; numunspents += *numunspentsp; sum += total; } - printf("sum %.8f\n",dstr(sum)); + //printf("sum %.8f\n",dstr(sum)); free(P); } *numunspentsp = numunspents; if ( flag != 0 && rmdarray != 0 ) free(rmdarray); + //portable_mutex_unlock(&coin->RTmutex); return(sum); } -uint8_t *iguana_rmdarray(struct iguana_info *coin,int32_t *numrmdsp,cJSON *array,int32_t firsti) +uint8_t *iguana_rmdarray(struct supernet_info *myinfo,struct iguana_info *coin,int32_t *numrmdsp,cJSON *array,int32_t firsti) { - int32_t i,n,j=0; char *coinaddr,rmdstr[41]; uint8_t *addrtypes,*rmdarray = 0; + int32_t i,n,flag=0,j=0; char *coinaddr,rmdstr[41]; uint8_t *addrtypes,*rmdarray = 0; *numrmdsp = 0; + if ( array == 0 || cJSON_GetArraySize(array) == 0 ) + array = iguana_getaddressesbyaccount(myinfo,coin,"*"); if ( array != 0 && (n= cJSON_GetArraySize(array)) > 0 ) { *numrmdsp = n - firsti; @@ -322,69 +674,765 @@ uint8_t *iguana_rmdarray(struct iguana_info *coin,int32_t *numrmdsp,cJSON *array { bitcoin_addr2rmd160(&addrtypes[j],&rmdarray[20 * j],coinaddr); init_hexbytes_noT(rmdstr,&rmdarray[20 * j],20); - printf("(%s %s) ",coinaddr,rmdstr); + //printf("(%s %s) ",coinaddr,rmdstr); j++; } } - printf("rmdarray[%d]\n",n); + //printf("rmdarray[%d]\n",n); } + if ( flag != 0 ) + free_json(array); return(rmdarray); } -int64_t iguana_unspentset(struct supernet_info *myinfo,struct iguana_info *coin) +int64_t *iguana_PoS_weights(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_pkhash **Ptrp,int64_t *supplyp,int32_t *numacctsp,int32_t *nonzp,int32_t *errsp,int32_t lastheight) { - int64_t sum = 0,total; struct iguana_waccount *wacct,*tmp; struct iguana_waddress *waddr,*tmp2; int32_t n,numunspents = 0; - HASH_ITER(hh,myinfo->wallet,wacct,tmp) + int64_t balance,total,supply,*weights=0; uint32_t pkind; int32_t numrmds,minconf,neg,numunspents,nonz,num=0; struct iguana_bundle *bp; struct iguana_ramchaindata *rdata; struct iguana_pkhash *refP; uint8_t rmd160[20],*rmdarray; cJSON *array; char coinaddr[64]; //struct iguana_account *A2; struct iguana_utxo *U2; + *supplyp = 0; + *numacctsp = *nonzp = 0; + *errsp = 1; + (*Ptrp) = 0; + if ( (bp= coin->bundles[lastheight / coin->chain->bundlesize]) == 0 || bp == coin->current ) + return(0); + if ( (rdata= bp->ramchain.H.data) == 0 ) + return(0); + (*Ptrp) = refP = RAMCHAIN_PTR(rdata,Poffset); + if ( (num= rdata->numpkinds) > 0 ) { - HASH_ITER(hh,wacct->waddr,waddr,tmp2) + weights = calloc(num,sizeof(*weights)); + minconf = coin->blocks.hwmchain.height - lastheight; + for (pkind=1; pkindaddrtype != coin->chain->pubtype || (bits256_nonz(waddr->privkey) == 0 && waddr->scriptlen == 0) ) - continue; total = 0; - n = 0; - iguana_pkhasharray(myinfo,coin,0,coin->minconfirms,coin->longestchain,&total,0,coin->bundlescount,waddr->rmd160,waddr->coinaddr,waddr->pubkey,coin->blocks.hwmchain.height - coin->minconfirms,(uint64_t *)coin->blockspace,&n,(int32_t)(sizeof(coin->blockspace)/sizeof(*waddr->unspents))); - if ( n > 0 ) + memcpy(rmd160,refP[pkind].rmd160,sizeof(rmd160)); + array = cJSON_CreateArray(); + bitcoin_address(coinaddr,coin->chain->pubtype,rmd160,sizeof(rmd160)); + jaddistr(array,coinaddr); + //bitcoin_address(coinaddr,coin->chain->p2shtype,rmd160,sizeof(rmd160)); + //jaddistr(array,coinaddr); + if ( (rmdarray= iguana_rmdarray(myinfo,coin,&numrmds,array,0)) != 0 ) { - if ( waddr->unspents == 0 || waddr->maxunspents < n ) + numunspents = 0; + balance = iguana_RTunspents(myinfo,coin,0,minconf,(1 << 30),rmdarray,numrmds,lastheight,0,&numunspents,0,0); + free(rmdarray); + weights[pkind] += balance; + if ( weights[pkind] != balance ) + printf("PKIND.%d %s %.8f += %.8f\n",pkind,coinaddr,dstr(weights[pkind]),dstr(balance)); + } + free_json(array); + } + } + nonz = neg = 0; + supply = 0; + for (pkind=1; pkindchain->bundlesize,num,nonz,neg,dstr(supply)); + return(weights); +} + +bits256 iguana_staker_hash2(bits256 refhash2,uint8_t *refrmd160,uint8_t *rmd160,int64_t weight) +{ + bits256 hash2; + vcalc_sha256cat(hash2.bytes,refhash2.bytes,sizeof(refhash2),rmd160,20); + return(mpz_div64(hash2,weight)); +} + +int _cmp_hashes(const void *a,const void *b) +{ +#define hasha (*(bits256 *)a) +#define hashb (*(bits256 *)b) + return(bits256_cmp(hasha,hashb)); +#undef hasha +#undef hashb +} + +int32_t iguana_staker_sort(struct iguana_info *coin,bits256 *hash2p,uint8_t *refrmd160,struct iguana_pkhash *refP,int64_t *weights,int32_t numweights,bits256 *sortbuf) +{ + int32_t i,j,n = 0; bits256 ind,refhash2 = *hash2p; + memset(sortbuf,0,sizeof(*sortbuf) * 2 * numweights); + for (i=0; i 0 ) + { + memset(&ind,0,sizeof(ind)); + for (j=0; j<20; j++) + ind.bytes[j] = refP[i].rmd160[j]; + ind.ulongs[3] = weights[i]; + ind.uints[5] = i; + sortbuf[n << 1] = iguana_staker_hash2(refhash2,refrmd160,ind.bytes,weights[i]); + sortbuf[(n << 1) + 1] = ind; + n++; + } + } + if ( n > 0 ) + qsort(sortbuf,n,sizeof(*sortbuf)*2,_cmp_hashes); + vcalc_sha256cat(hash2p->bytes,refhash2.bytes,sizeof(refhash2),sortbuf[1].bytes,20); + memcpy(refrmd160,sortbuf[1].bytes,20); + { + char str[65],coinaddr[64]; + bitcoin_address(coinaddr,coin->chain->pubtype,refrmd160,20); + printf("winner.%s %.8f: %s\n",coinaddr,dstr(sortbuf[1].ulongs[3]),bits256_str(str,sortbuf[0])); + } + return((int32_t)sortbuf[1].uints[5]); +} + +int32_t iguana_RTunspent_check(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_outpoint outpt) +{ + bits256 txid; int32_t vout,spentheight; + memset(&txid,0,sizeof(txid)); + if ( iguana_RTunspentind2txid(myinfo,coin,&spentheight,&txid,&vout,outpt) == 0 ) + { + //char str[65]; printf("verify %s/v%d is not already used\n",bits256_str(str,txid),vout); + if ( basilisk_addspend(myinfo,coin->symbol,txid,vout,0) != 0 ) + { + char str[65]; printf("iguana_unspent_check found unspentind (%u %d) %s\n",outpt.hdrsi,outpt.unspentind,bits256_str(str,txid)); + return(1); + } else return(0); + } + printf("iguana_unspent_check: couldnt find (%d %d)\n",outpt.hdrsi,outpt.unspentind); + return(-1); +} + +int32_t iguana_RTaddr_unspents(struct supernet_info *myinfo,struct iguana_info *coin,uint64_t *sump,struct iguana_outpoint *unspents,int32_t max,char *coinaddr,char *remoteaddr,int32_t lastheight,int32_t includespent) +{ + int32_t n,k,numunspents,minconf = 0; uint64_t total; uint8_t rmd160[20],pubkey[65],addrtype; + total = 0; + n = numunspents = 0; + bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr); + iguana_RTpkhasharray(myinfo,coin,0,minconf,coin->longestchain,&total,0,coin->bundlescount,rmd160,coinaddr,pubkey,lastheight,unspents,&n,max-1000,remoteaddr,includespent); + numunspents = n; + for (k=0; ktxfee; + for (i=numunspents=0; ilongestchain,coin->blocks.hwmchain.height - minconf); + if ( coin->FULLNODE != 0 || coin->VALIDATENODE != 0 ) + { + numunspents += iguana_RTaddr_unspents(myinfo,coin,&sum,&unspents[numunspents],max-numunspents,coinaddr,remoteaddr,coin->blocks.hwmchain.height - minconf,0); + } + else + { + if ( (waddr= iguana_waddresssearch(myinfo,&wacct,coinaddr)) != 0 && waddr->numunspents > 0 ) { - waddr->unspents = realloc(waddr->unspents,sizeof(*waddr->unspents) * n); - waddr->maxunspents = n; + r = (rand() % waddr->numunspents); + for (j=0; jnumunspents; j++) + { + i = ((j + r) % waddr->numunspents); + bu = &waddr->unspents[i]; + if ( basilisk_addspend(myinfo,coin->symbol,bu->txid,bu->vout,0) == 0 ) + { + for (k=0; khdrsi; + outpt.isptr = 0; + outpt.unspentind = bu->unspentind; + outpt.value = bu->value; + *unspents = outpt; + sum += bu->value; + printf("ADD unspent, mark spent\n"); + basilisk_addspend(myinfo,coin->symbol,bu->txid,bu->vout,1); + unspents++; + numunspents++; + } else printf("skip pending txid.%s/v%d\n",bits256_str(str,bu->txid),bu->vout); + } } - memcpy(waddr->unspents,coin->blockspace,sizeof(*waddr->unspents) * n); - waddr->numunspents = n; - waddr->balance = total; - sum += total; - numunspents += n; } + if ( numunspents > max || sum > required ) + break; + //printf("n.%d max.%d total %.8f\n",n,max,dstr(total)); } } - printf("available %.8f\n",dstr(sum)); - return(sum); + *totalp = sum; + return(numunspents); } -int32_t iguana_unspentslists(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waddress **waddrs,int32_t maxwaddrs,int64_t required,int32_t minconf,char *account) +int32_t iguana_RTuvaltxid(struct supernet_info *myinfo,bits256 *txidp,struct iguana_info *coin,struct iguana_outpoint outpt) { - int64_t remains; int32_t num = 0; struct iguana_waccount *wacct,*tmp; struct iguana_waddress *waddr,*tmp2; - remains = required * 1.1; - HASH_ITER(hh,myinfo->wallet,wacct,tmp) + struct iguana_bundle *bp; struct iguana_unspent *U,*u; struct iguana_txid *T; struct iguana_ramchain *ramchain; struct iguana_ramchaindata *rdata; struct iguana_RTunspent *unspent; struct iguana_RTtxid *parent; + if ( outpt.isptr != 0 && (unspent= outpt.ptr) != 0 && (parent= unspent->parent) != 0 ) { - if ( account != 0 && strcmp(account,wacct->account) != 0 ) - continue; - HASH_ITER(hh,wacct->waddr,waddr,tmp2) + *txidp = parent->txid; + return(unspent->vout); + } + if ( (bp= coin->bundles[outpt.hdrsi]) == 0 ) + return(-1); + ramchain = &bp->ramchain;//(bp == coin->current) ? &coin->RTramchain : &bp->ramchain; + if ( (rdata= ramchain->H.data) != 0 ) + { + U = RAMCHAIN_PTR(rdata,Uoffset); + T = RAMCHAIN_PTR(rdata,Toffset); + if ( outpt.unspentind > 0 && outpt.unspentind < rdata->numunspents ) { - if ( waddr->addrtype != coin->chain->pubtype || (bits256_nonz(waddr->privkey) == 0 && waddr->scriptlen == 0) ) - continue; - if ( waddr->balance > 0 ) + u = &U[outpt.unspentind]; + if ( u->txidind > 0 && u->txidind < rdata->numtxids ) { - remains -= waddr->balance; - waddrs[num++] = waddr; - if ( num >= maxwaddrs || remains <= 0 ) - break; + *txidp = T[u->txidind].txid; + return(outpt.unspentind - T[u->txidind].firstvout); + } + } + } + return(-1); +} + +uint64_t iguana_unspentavail(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_outpoint outpt,int32_t minconf,int32_t maxconf) +{ + struct iguana_ramchain *ramchain; struct iguana_bundle *bp; int64_t RTspend=0; int32_t spentheight,spentflag; struct iguana_unspent *U,*u; struct iguana_ramchaindata *rdata; + if ( (bp= coin->bundles[outpt.hdrsi]) == 0 ) + return(-1); + ramchain = &bp->ramchain;//(bp == coin->current) ? &coin->RTramchain : &bp->ramchain; + if ( (rdata= ramchain->H.data) == 0 ) + return(0); + if ( (spentflag= iguana_RTspentflag(myinfo,coin,&RTspend,&spentheight,ramchain,outpt,0,minconf,maxconf,0)) > 0 ) + { + printf("[%d].u%d was already spent ht.%d\n",outpt.hdrsi,outpt.unspentind,spentheight); + return(-1); + } + else if ( spentflag == 0 ) + { + U = RAMCHAIN_PTR(rdata,Uoffset); + if ( outpt.unspentind > 0 && outpt.unspentind < rdata->numunspents ) + { + u = &U[outpt.unspentind]; + return(u->value); + } + else + { + printf("%s illegal unspentind.%u vs %u [%d]\n",coin->symbol,outpt.unspentind,rdata->numunspents,bp->hdrsi); + return(-2); + } + } + else return(0); +} + +cJSON *iguana_RTlistunspent(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *argarray,int32_t minconf,int32_t maxconf,char *remoteaddr) +{ + int32_t numrmds,numunspents=0; uint8_t *rmdarray; cJSON *retjson = cJSON_CreateArray(); + rmdarray = iguana_rmdarray(myinfo,coin,&numrmds,argarray,0); + iguana_RTunspents(myinfo,coin,retjson,minconf,maxconf,rmdarray,numrmds,(1 << 30),0,&numunspents,remoteaddr,0); + if ( rmdarray != 0 ) + free(rmdarray); + /*{ + "txid" : "d54994ece1d11b19785c7248868696250ab195605b469632b7bd68130e880c9a", + "vout" : 1, + "address" : "mgnucj8nYqdrPFh2JfZSB1NmUThUGnmsqe", + "account" : "test label", + "scriptPubKey" : "76a9140dfc8bafc8419853b34d5e072ad37d1a5159f58488ac", + "amount" : 0.00010000, + "confirmations" : 6210, + "spendable" : true + },*/ + + return(retjson); +} + +#define UTXOADDR_ITEMSIZE 32 +#define iguana_utxotable_numinds(ind) (((ind) == 0xffff) ? coin->utxoaddrlastcount : (coin->utxoaddroffsets[(ind) + 1] - coin->utxoaddroffsets[ind])) + +int32_t iguana_rwutxoaddr(int32_t rwflag,uint16_t ind,uint8_t *serialized,struct iguana_utxoaddr *utxoaddr) +{ + uint32_t pkind=0; int32_t len = 0; + len += iguana_rwnum(rwflag,&serialized[0],sizeof(utxoaddr->hdrsi),&utxoaddr->hdrsi); + if ( rwflag == 0 ) + { + utxoaddr->rmd160[0] = (ind & 0xff); + utxoaddr->rmd160[1] = ((ind >> 8) & 0xff); + memcpy(&utxoaddr->rmd160[2],&serialized[2],18); + } else memcpy(&serialized[2],&utxoaddr->rmd160[2],18); + len += 18; + if ( rwflag != 0 ) + pkind = utxoaddr->pkind; + len += iguana_rwnum(rwflag,&serialized[20],sizeof(pkind),&pkind); + if ( rwflag == 0 ) + utxoaddr->pkind = pkind; + len += iguana_rwnum(rwflag,&serialized[24],sizeof(utxoaddr->histbalance),&utxoaddr->histbalance); + return(len); +} + +uint64_t iguana_utxoaddrtablefind(struct iguana_info *coin,int16_t search_hdrsi,uint32_t search_pkind,uint8_t rmd160[20]) +{ + struct iguana_utxoaddr UA; int32_t ind,num,i; uint8_t *ptr; + memset(&UA,0,sizeof(UA)); + ind = rmd160[0] + ((uint32_t)rmd160[1] << 8); + if ( coin->utxoaddroffsets != 0 && (num= iguana_utxotable_numinds(ind)) > 0 ) + { + for (i=0; iutxoaddrtable[(coin->utxoaddroffsets[ind] + i) * UTXOADDR_ITEMSIZE]; + iguana_rwutxoaddr(0,ind,ptr,&UA); + if ( (UA.pkind == search_pkind && UA.hdrsi == search_hdrsi) || memcmp(UA.rmd160,rmd160,20) == 0 ) + return(UA.histbalance); + } + //printf("ind.%04x no [%d] p%u after num.%d\n",ind,search_hdrsi,search_pkind,num); + } + return(0); +} + +struct iguana_utxoaddr *iguana_utxoaddrfind(int32_t createflag,struct iguana_info *coin,int16_t hdrsi,uint32_t pkind,uint8_t rmd160[20],struct iguana_utxoaddr **prevp) +{ + struct iguana_utxoaddr *utxoaddr; char coinaddr[64]; + HASH_FIND(hh,coin->utxoaddrs,rmd160,sizeof(utxoaddr->rmd160),utxoaddr); + if ( utxoaddr == 0 && createflag != 0 ) + { + utxoaddr = calloc(1,sizeof(*utxoaddr)); + ++coin->utxoaddrind; + utxoaddr->hdrsi = hdrsi; + utxoaddr->pkind = pkind; + if ( coin->utxoaddrtable != 0 && coin->utxoaddroffsets != 0 ) + { + utxoaddr->searchedhist = 1; + utxoaddr->histbalance = iguana_utxoaddrtablefind(coin,hdrsi,pkind,rmd160); + } + memcpy(utxoaddr->rmd160,rmd160,sizeof(utxoaddr->rmd160)); + HASH_ADD_KEYPTR(hh,coin->utxoaddrs,utxoaddr->rmd160,sizeof(utxoaddr->rmd160),utxoaddr); + if ( prevp != 0 ) + { + utxoaddr->hh.prev = *prevp; + if ( *prevp != 0 ) + (*prevp)->hh.next = utxoaddr; + *prevp = utxoaddr; + } + HASH_FIND(hh,coin->utxoaddrs,rmd160,sizeof(utxoaddr->rmd160),utxoaddr); + if ( utxoaddr == 0 ) + { + int32_t i; for (i=0; i<20; i++) + printf("%02x",utxoaddr->rmd160[i]); + bitcoin_address(coinaddr,coin->chain->pubtype,utxoaddr->rmd160,sizeof(utxoaddr->rmd160)); + printf(" %d of %d: %s %.8f\n",coin->utxoaddrind,coin->utxodatasize,coinaddr,dstr(utxoaddr->histbalance)); + printf("failed to find just added %d of %d\n",coin->utxoaddrind,coin->utxodatasize); + } + } + return(utxoaddr); +} + +uint64_t iguana_bundle_unspents(struct iguana_info *coin,struct iguana_bundle *bp,struct iguana_utxoaddr **prevp) +{ + struct iguana_utxoaddr *utxoaddr; uint32_t unspentind,pkind; struct iguana_ramchaindata *rdata=0; struct iguana_pkhash *P; struct iguana_unspent *U; struct iguana_utxo *U2=0; uint64_t value,balance = 0; + if ( bp == 0 || (rdata= bp->ramchain.H.data) == 0 || (U2= bp->ramchain.Uextras) == 0 ) + { + printf("missing ptr bp.%p rdata.%p U2.%p\n",bp,rdata,U2); + return(0); + } + U = RAMCHAIN_PTR(rdata,Uoffset); + P = RAMCHAIN_PTR(rdata,Poffset); + for (unspentind=1; unspentindnumunspents; unspentind++) + { + value = U[unspentind].value; + //printf("[%d] u%d: (p%u %.8f) from.%d lock.%d prev.%u spent.%d\n",bp->hdrsi,unspentind,U[unspentind].pkind,dstr(value),U2[unspentind].fromheight,U2[unspentind].lockedflag,U2[unspentind].prevunspentind,U2[unspentind].spentflag); + if ( U2[unspentind].fromheight == 0 && U2[unspentind].lockedflag == 0 && U2[unspentind].prevunspentind == 0 && U2[unspentind].spentflag == 0 && value != 0 ) + { + if ( value <= 0 ) + printf("[%d] u%u negative value %.8f??\n",bp->hdrsi,unspentind,dstr(value)); + else + { + balance += value; + if ( (pkind= U[unspentind].pkind) < rdata->numpkinds && pkind > 0 ) + { + if ( (utxoaddr= iguana_utxoaddrfind(1,coin,bp->hdrsi,pkind,P[pkind].rmd160,prevp)) != 0 ) + { + //printf("%.8f ",dstr(value)); + utxoaddr->histbalance += value; + } else printf("cant find pkind.%u for unspentind.%u hdrsi.%d\n",pkind,unspentind,bp->hdrsi); + } else printf("illegal pkind.%u for unspentind.%u hdrsi.%d\n",pkind,unspentind,bp->hdrsi); + } + } // else printf("[%d] u%u spent %.8f\n",bp->hdrsi,unspentind,dstr(value)); + } + printf("[%d %.8f] ",bp->hdrsi,dstr(balance)); + return(balance); +} + +static int _utxoaddr_cmp(const void *a,const void *b) +{ +#define item_a ((uint8_t *)a) +#define item_b ((uint8_t *)b) + uint16_t hdrsi_a,hdrsi_b; uint32_t pkind_a,pkind_b; + iguana_rwnum(0,&item_a[0],sizeof(hdrsi_a),&hdrsi_a); + iguana_rwnum(0,&item_a[20],sizeof(pkind_a),&pkind_a); + iguana_rwnum(0,&item_b[0],sizeof(hdrsi_b),&hdrsi_b); + iguana_rwnum(0,&item_b[20],sizeof(pkind_b),&pkind_b); + if ( hdrsi_b > hdrsi_a ) + return(1); + else if ( hdrsi_b < hdrsi_a ) + return(-1); + else + { + if ( pkind_b > pkind_a ) + return(1); + else if ( pkind_b < pkind_a ) + return(-1); + else return(0); + } +#undef item_a +#undef item_b +} + +int32_t iguana_utxoaddr_save(struct iguana_info *coin,char *fname,uint64_t balance,uint32_t *counts,uint32_t *offsets,uint8_t *table) +{ + FILE *fp; bits256 hash; int32_t retval = -1; + if ( (fp= fopen(fname,"wb")) != 0 ) + { + fwrite(&balance,1,sizeof(balance),fp); + fwrite(&counts[0xffff],1,sizeof(counts[0xffff]),fp); + fwrite(&coin->utxoaddrind,1,sizeof(coin->utxoaddrind),fp); + vcalc_sha256cat(hash.bytes,(void *)offsets,(int32_t)(0x10000 * sizeof(*offsets)),table,(int32_t)((coin->utxoaddrind+1) * UTXOADDR_ITEMSIZE)); + if ( fwrite(hash.bytes,1,sizeof(hash),fp) == sizeof(hash) ) + { + if ( fwrite(offsets,1,0x10000 * sizeof(*offsets),fp) == 0x10000 * sizeof(*offsets) ) + { + if ( fwrite(table,1,(coin->utxoaddrind+1) * UTXOADDR_ITEMSIZE,fp) != (coin->utxoaddrind+1) * UTXOADDR_ITEMSIZE ) + printf("error writing %s table\n",fname); + else retval = 0; + } else printf("error writing %s offsets\n",fname); + } else printf("error writing %s hash\n",fname); + fclose(fp); + } else printf("error creating %s\n",fname); + return(retval); +} + +int32_t iguana_utxoaddr_map(struct iguana_info *coin,char *fname) +{ + uint32_t ind,total=0,offset,size=0,last=0,lastcount=0,count,prevoffset=0; + if ( (coin->utxoaddrfileptr= OS_mapfile(fname,&coin->utxoaddrfilesize,0)) != 0 && coin->utxoaddrfilesize > sizeof(bits256)+0x10000*sizeof(*coin->utxoaddroffsets) ) + { + memcpy(&coin->histbalance,coin->utxoaddrfileptr,sizeof(coin->histbalance)); + memcpy(&last,(void *)((long)coin->utxoaddrfileptr+sizeof(uint64_t)),sizeof(last)); + memcpy(&coin->utxoaddrind,(void *)((long)coin->utxoaddrfileptr+sizeof(uint64_t)+sizeof(uint32_t)),sizeof(coin->utxoaddrind)); + memcpy(&coin->utxoaddrhash.bytes,(void *)((long)coin->utxoaddrfileptr+sizeof(uint64_t)+2*sizeof(uint32_t)),sizeof(coin->utxoaddrhash)); + coin->utxoaddroffsets = (void *)((long)coin->utxoaddrfileptr + sizeof(uint64_t) + 2*sizeof(uint32_t) + sizeof(bits256)); + for (ind=total=count=0; ind<0x10000; ind++) + { + if ( (offset= coin->utxoaddroffsets[ind]) != 0 ) + { + count = offset - prevoffset; + prevoffset = offset; + total += count; + } + } + size = (uint32_t)((total+1)*UTXOADDR_ITEMSIZE); + size += sizeof(uint64_t) + 2*sizeof(uint32_t) + sizeof(bits256); + size += 0x10000 * sizeof(*coin->utxoaddroffsets); + if ( size <= coin->utxoaddrfilesize ) + { + lastcount = (uint32_t)(coin->utxoaddrfilesize - size); + if ( (lastcount % UTXOADDR_ITEMSIZE) == 0 ) + { + lastcount /= UTXOADDR_ITEMSIZE; + coin->utxoaddrlastcount = lastcount; + coin->utxoaddrtable = (void *)&coin->utxoaddroffsets[0x10000]; + //iguana_utxoaddr_purge(coin); } } - if ( num >= maxwaddrs || remains <= 0 ) + printf("%.8f LASTCOUNT %d vs total %d, last %d vs lastcount %d, size.%d %ld\n",dstr(coin->histbalance),coin->utxoaddrlastcount,total,last,lastcount,size,coin->utxoaddrfilesize); + return(total + 1 + lastcount); + } + return(0); +} + +void iguana_utxoaddr_purge(struct iguana_info *coin) +{ + struct iguana_utxoaddr *utxoaddr,*tmp; + if ( coin->utxoaddrs != 0 ) + { + printf("free %s utxoaddrs\n",coin->symbol); + HASH_ITER(hh,coin->utxoaddrs,utxoaddr,tmp) + { + if ( utxoaddr != 0 ) + { + HASH_DELETE(hh,coin->utxoaddrs,utxoaddr); + free(utxoaddr); + } + } + coin->utxoaddrs = 0; + } + if ( coin->utxoaddrfileptr != 0 ) + { + OS_releasemap(coin->utxoaddrfileptr,coin->utxoaddrfilesize); + coin->utxoaddrfileptr = 0; + coin->utxoaddrtable = 0; + coin->utxoaddroffsets = 0; + } + memset(coin->utxoaddrhash.bytes,0,sizeof(coin->utxoaddrhash)); + coin->histbalance = 0; + coin->utxoaddrlastcount = 0; + coin->utxoaddrind = 0; + coin->utxoaddrfilesize = 0; +} + +int32_t iguana_utxoaddr_check(struct supernet_info *myinfo,struct iguana_info *coin,int32_t lastheight,struct iguana_outpoint *unspents,int32_t max,struct iguana_utxoaddr *utxoaddr) +{ + static int32_t good,bad; + char coinaddr[64]; uint64_t sum,checkbalance; int32_t iter,i,numunspents = 0; + sum = 0; + for (iter=0; iter<2; iter++) + { + bitcoin_address(coinaddr,iter == 0 ? coin->chain->pubtype : coin->chain->p2shtype,utxoaddr->rmd160,sizeof(utxoaddr->rmd160)); + numunspents += iguana_RTaddr_unspents(myinfo,coin,&sum,&unspents[numunspents],max-numunspents,coinaddr,0,lastheight,0); + if ( sum == utxoaddr->histbalance ) + { + checkbalance = iguana_utxoaddrtablefind(coin,0,0,utxoaddr->rmd160); + if ( checkbalance != sum ) + printf("%s checkbalance %.8f vs sum %.8f\n",coinaddr,dstr(checkbalance),dstr(sum)); break; + } } - return(num); + if ( sum != utxoaddr->histbalance || checkbalance != sum ) + { + bad++; + for (i=0; irmd160[i]); + bitcoin_address(coinaddr,coin->chain->pubtype,utxoaddr->rmd160,sizeof(utxoaddr->rmd160)); + printf(" %s: sum %.8f != %.8f numunspents.%d diff %.8f\n",coinaddr,dstr(sum),dstr(utxoaddr->histbalance),numunspents,dstr(utxoaddr->histbalance)-dstr(sum)); + return(-1); + } + good++; + if ( ((good + bad) % 1000) == 0 ) + printf("%s total %d utxoaddr validate good.%d bad.%d%s\n",coin->symbol,coin->utxoaddrind,good,bad,strcmp(coin->symbol,"BTC") == 0 ? " | (if this is taking too long, just exit and restart iguana)" : ""); + return(0); +} + +int32_t iguana_utxoaddr_validate(struct supernet_info *myinfo,struct iguana_info *coin,int32_t lastheight) +{ + struct iguana_outpoint *unspents; uint8_t *item; struct iguana_bundle *bp; struct iguana_utxoaddr UA; int32_t i,num,max,ind,total,errs=0; + if ( coin->utxoaddrtable == 0 ) + { + printf("no utxoaddrtable to validate?\n"); + return(-1); + } + for (i=0; ibundlescount; i++) + if ( (bp= coin->bundles[i]) != 0 && bp != coin->current ) + { + iguana_volatilespurge(coin,&bp->ramchain); + /*sprintf(fname,"%s/%s/accounts/debits.%d",GLOBAL_DBDIR,coin->symbol,bp->bundleheight); + OS_removefile(fname,0); + sprintf(fname,"%s/%s/accounts/lastspends.%d",GLOBAL_DBDIR,coin->symbol,bp->bundleheight); + OS_removefile(fname,0);*/ + iguana_volatilesmap(coin,&bp->ramchain); + } + total = 0; + max = 1024 * 1024 * 1024; + unspents = calloc(1,max); + max /= sizeof(*unspents); + memset(&UA,0,sizeof(UA)); + for (ind=0; ind<0x10000; ind++) + { + if ( (num= iguana_utxotable_numinds(ind)) > 0 ) + { + for (i=0; iutxoaddrtable[(coin->utxoaddroffsets[ind] + i) * UTXOADDR_ITEMSIZE]; + iguana_rwutxoaddr(0,ind,item,&UA); + errs += iguana_utxoaddr_check(myinfo,coin,lastheight,unspents,max,&UA); + total++; + } + } + } + free(unspents); + printf("validate errs.%d\n",errs); + return(errs); } +uint64_t iguana_RTstart(struct supernet_info *myinfo,struct iguana_info *coin,int32_t height) +{ + //struct iguana_block *block; + coin->firstRTheight = height; + iguana_RTreset(coin); + iguana_RTpurge(coin,coin->firstRTheight); + basilisk_unspents_update(myinfo,coin); + return(coin->histbalance); +} + +uint64_t iguana_utxoaddr_gen(struct supernet_info *myinfo,struct iguana_info *coin,int32_t maxheight) +{ + char fname[1024],fname2[1024],coinaddr[64],str[65],checkaddr[64]; struct iguana_utxoaddr *utxoaddr,UA,*tmp,*last=0; uint16_t hdrsi; uint8_t *table,item[UTXOADDR_ITEMSIZE]; uint32_t *counts,*offsets,offset,n; int32_t total,errs=0,height=0,j,k,ind,tablesize=0; struct iguana_bundle *bp; struct iguana_ramchaindata *rdata=0; uint64_t checkbalance=0,balance = 0; + for (hdrsi=0; hdrsibundlescount-1; hdrsi++) + { + if ( (bp= coin->bundles[hdrsi]) != 0 && bp->bundleheight < maxheight ) + height = bp->bundleheight + bp->n; + } + sprintf(fname2,"%s/%s/utxoaddrs.%d",GLOBAL_DBDIR,coin->symbol,height), OS_portable_path(fname2); + if ( iguana_utxoaddr_map(coin,fname2) != 0 ) + { + if ( 0 && strcmp("BTC",coin->symbol) != 0 ) + errs = iguana_utxoaddr_validate(myinfo,coin,height); + printf("nogen %s HIST BALANCE %s %.8f errs %d\n",fname2,bits256_str(str,coin->utxoaddrhash),dstr(coin->histbalance),errs); + if ( errs == 0 && coin->histbalance > 0 && height > 0 ) + return(iguana_RTstart(myinfo,coin,height)); + } + printf("utxoaddr_gen.%d\n",maxheight); + iguana_utxoaddr_purge(coin); + HASH_ITER(hh,coin->utxoaddrs,utxoaddr,tmp) + { + checkbalance += utxoaddr->histbalance; + } + printf("balance after purge %.8f\n",dstr(checkbalance)); + for (hdrsi=0; hdrsibundlescount-1; hdrsi++) + if ( (bp= coin->bundles[hdrsi]) != 0 && bp->bundleheight < maxheight && (rdata= bp->ramchain.H.data) != 0 ) + { + tablesize += rdata->numpkinds; + } + printf("allocate UTXOADDRS[%d]\n",tablesize); + coin->utxodatasize = tablesize; + coin->utxoaddrind = 0; + for (hdrsi=0; hdrsibundlescount-1; hdrsi++) + { + if ( (bp= coin->bundles[hdrsi]) != 0 && bp->bundleheight < maxheight ) + { + balance += iguana_bundle_unspents(coin,bp,&last); + fprintf(stderr,"(%d %.8f) ",hdrsi,dstr(balance)); + height = bp->bundleheight + bp->n; + } + } + sprintf(fname,"%s/%s/utxoaddrs",GLOBAL_DBDIR,coin->symbol), OS_portable_path(fname); + fprintf(stderr,"%d bundles for iguana_utxoaddr_gen.[%d] max.%d ht.%d\n",hdrsi,coin->utxoaddrind,coin->utxodatasize,maxheight); + counts = calloc(0x10000,sizeof(*counts)); + checkbalance = 0; + HASH_ITER(hh,coin->utxoaddrs,utxoaddr,tmp) + { + if ( utxoaddr->histbalance > 0 ) + { + checkbalance += utxoaddr->histbalance; + ind = utxoaddr->rmd160[0] + ((uint32_t)utxoaddr->rmd160[1] << 8); + counts[ind]++; + } else printf("error neg or zero balance %.8f\n",dstr(utxoaddr->histbalance)); + } + for (ind=total=0; ind<0x10000; ind++) + total += counts[ind]; + printf("checkbalance %.8f vs %.8f, total %d\n",dstr(checkbalance),dstr(balance),total); + if ( checkbalance == balance ) + { + table = calloc(coin->utxoaddrind+1,UTXOADDR_ITEMSIZE); + offsets = calloc(0x10000,sizeof(*offsets)); + offset = 0; + for (ind=0; ind<0x10000; ind++) + { + n = counts[ind]; + offsets[ind] = offset; + counts[ind] = 0; + offset += n; + } + printf("total %d offset %d\n",total,offset); + total = 0; + HASH_ITER(hh,coin->utxoaddrs,utxoaddr,tmp) + { + if ( utxoaddr->histbalance > 0 ) + { + bitcoin_address(coinaddr,coin->chain->pubtype,utxoaddr->rmd160,sizeof(utxoaddr->rmd160)); + memset(item,0,UTXOADDR_ITEMSIZE); + ind = utxoaddr->rmd160[0] + ((uint32_t)utxoaddr->rmd160[1] << 8); + iguana_rwutxoaddr(1,ind,item,utxoaddr); + memcpy(&table[(offsets[ind] + counts[ind]) * UTXOADDR_ITEMSIZE],item,UTXOADDR_ITEMSIZE); + iguana_rwutxoaddr(0,ind,&table[(offsets[ind] + counts[ind]) * UTXOADDR_ITEMSIZE],&UA); + iguana_rwutxoaddr(1,ind,item,&UA); + bitcoin_address(checkaddr,coin->chain->pubtype,UA.rmd160,sizeof(UA.rmd160)); + if ( strcmp(checkaddr,coinaddr) != 0 ) + printf("rw coinaddr error %s != %s\n",coinaddr,checkaddr); + //else printf("%d: ind.%04x %s %.8f %.8f %d\n",total,ind,coinaddr,dstr(UA.histbalance),dstr(utxoaddr->histbalance),counts[ind]); + total++; + if ( memcmp(&table[(offsets[ind] + counts[ind]) * UTXOADDR_ITEMSIZE],item,UTXOADDR_ITEMSIZE) != 0 ) + printf("rwutxoaddr cmp error\n"); + counts[ind]++; + } else printf("error neg or zero balance %.8f\n",dstr(utxoaddr->histbalance)); + } + offset = 1; + for (ind=0; ind<0x10000; ind++) + offset += counts[ind]; + if ( offset == coin->utxoaddrind+1 ) + { + for (ind=0; ind<0x10000; ind++) + { + if ( counts[ind] > 0 ) + { + qsort(&table[offsets[ind] * UTXOADDR_ITEMSIZE],counts[ind],UTXOADDR_ITEMSIZE,_utxoaddr_cmp); +continue; + for (j=0; jchain->pubtype,UA.rmd160,sizeof(UA.rmd160)); + //printf(" [%4d] p%-5d %12.8f ind.%04x %d %s\n",UA.hdrsi,UA.pkind,dstr(UA.histbalance),ind,j,coinaddr); + } + } + } + if ( iguana_utxoaddr_save(coin,fname,balance,counts,offsets,table) == 0 ) + { + if ( OS_copyfile(fname,fname2,1) < 0 ) + printf("error copying file %s to %s\n",fname,fname2); + else + { + for (hdrsi=0; hdrsibundlescount-1; hdrsi++) + { + if ( (bp= coin->bundles[hdrsi]) != 0 && bp->bundleheight < maxheight ) + bp->balancefinish = (uint32_t)time(NULL); + } + } + } else printf("error saving %s\n",fname); + } else printf("table has %d vs %d\n",offset,coin->utxoaddrind+1); + free(offsets); + free(table); + iguana_utxoaddr_purge(coin); + if ( iguana_utxoaddr_map(coin,fname) != 0 ) + { + printf("validating %s HIST BALANCE %s %.8f errs %d\n",fname2,bits256_str(str,coin->utxoaddrhash),dstr(coin->histbalance),errs); + errs = 0;//iguana_utxoaddr_validate(myinfo,coin,height); + printf("gen %s HIST BALANCE %s %.8f errs %d\n",fname2,bits256_str(str,coin->utxoaddrhash),dstr(coin->histbalance),errs); + if ( errs != 0 || height == 0 ) + { + printf("delete bad utxoaddr files\n"); + OS_removefile(fname,0); + OS_removefile(fname2,0); + } else return(iguana_RTstart(myinfo,coin,height)); + } + } + free(counts); + sprintf(fname,"%s/%s/balancecrc.%d",GLOBAL_DBDIR,coin->symbol,height/coin->chain->bundlesize - 1); + OS_removefile(fname,0); + sprintf(fname,"%s/%s/balancecrc.%d",GLOBAL_DBDIR,coin->symbol,height/coin->chain->bundlesize - 2); + OS_removefile(fname,0); + printf("return neg one remove %s\n",fname); + return(0); +} + +void iguana_utxoaddrs_purge(struct iguana_info *coin) +{ + struct iguana_utxoaddr *utxoaddr,*tmp; + coin->RTdebits = coin->RTdebits = 0; + HASH_ITER(hh,coin->utxoaddrs,utxoaddr,tmp) + { + if ( utxoaddr != 0 ) + { + utxoaddr->histbalance = 0; + // utxoaddr->RTcredits = utxoaddr->RTdebits = 0; + } + } +} diff --git a/iguana/iguana_volatiles.c b/iguana/iguana_volatiles.c index 5d616d7aa..d03e592e6 100755 --- a/iguana/iguana_volatiles.c +++ b/iguana/iguana_volatiles.c @@ -15,12 +15,7 @@ #include "iguana777.h" -struct iguana_hhutxo *iguana_hhutxofind(struct iguana_info *coin,uint64_t uval) -{ - struct iguana_hhutxo *hhutxo; - HASH_FIND(hh,coin->utxotable,&uval,sizeof(uval),hhutxo); - return(hhutxo); -} +#ifdef DEPRECATED_HHUTXO struct iguana_hhaccount *iguana_hhaccountfind(struct iguana_info *coin,uint64_t pval) { @@ -29,129 +24,234 @@ struct iguana_hhaccount *iguana_hhaccountfind(struct iguana_info *coin,uint64_t return(hhacct); } -int32_t iguana_utxoupdate(struct iguana_info *coin,int16_t spent_hdrsi,uint32_t spent_unspentind,uint32_t spent_pkind,uint64_t spent_value,uint32_t spendind,uint32_t fromheight) +int32_t iguana_utxoupdate(struct iguana_info *coin,int16_t spent_hdrsi,uint32_t spent_unspentind,uint32_t spent_pkind,uint64_t spent_value,uint32_t spendind,uint32_t fromheight,uint8_t *rmd160) { - //static struct iguana_hhutxo *HHUTXO; static struct iguana_hhaccount *HHACCT; static uint32_t numHHUTXO,maxHHUTXO,numHHACCT,maxHHACCT; struct iguana_hhutxo *hhutxo,*tmputxo; struct iguana_hhaccount *hhacct,*tmpacct; uint64_t uval,pval; if ( spent_hdrsi < 0 ) { - printf(">>>>>>>>>>> RESET UTXO HASH <<<<<<<<<\n"); + printf(">>>>>>>>>> RESET UTXO HASH <<<<<<<<<\n"); if ( coin->utxotable != 0 ) { HASH_ITER(hh,coin->utxotable,hhutxo,tmputxo) { - //HASH_DEL(coin->utxotable,hhutxo); + hhutxo->u.lockedflag = 0; hhutxo->u.spentflag = 0; hhutxo->u.fromheight = 0; hhutxo->u.prevunspentind = 0; //free(hhutxo); } - //coin->utxotable = 0; } if ( coin->accountstable != 0 ) { HASH_ITER(hh,coin->accountstable,hhacct,tmpacct) { - //HASH_DEL(coin->accountstable,hhacct); hhacct->a.lastunspentind = 0; hhacct->a.total = 0; //free(hhacct); } - //coin->accountstable = 0; } - /*if ( HHUTXO != 0 ) - { - free(HHUTXO); - maxHHUTXO = numHHUTXO = 0; - HHUTXO = 0; - } - if ( HHACCT != 0 ) - { - free(HHACCT); - maxHHACCT = numHHACCT = 0; - HHACCT = 0; - }*/ + return(0); + } + if ( coin->disableUTXO != 0 ) + { + printf("skip utxoupdate when disabled\n"); return(0); } uval = ((uint64_t)spent_hdrsi << 32) | spent_unspentind; pval = ((uint64_t)spent_hdrsi << 32) | spent_pkind; - if ( (hhutxo= iguana_hhutxofind(coin,uval)) != 0 && hhutxo->u.spentflag != 0 ) + if ( (hhutxo= iguana_hhutxofind(coin,uval)) != 0 ) { - printf("hhutxo.%p spentflag.%d\n",hhutxo,hhutxo->u.spentflag); - return(-1); + if ( hhutxo->u.spentflag != 0 ) + { + printf("hhutxo.%p spentflag.%d\n",hhutxo,hhutxo->u.spentflag); + return(-1); + } + else if ( spendind == hhutxo->u.spendind && fromheight == hhutxo->u.fromheight ) + { + printf("redundant hhutxo ht.%d s%u\n",fromheight,spendind); + return(0); + } } - /*if ( 0 && numHHUTXO+1 >= maxHHUTXO ) - { - maxHHUTXO += 1; - HHUTXO = realloc(HHUTXO,sizeof(*HHUTXO) * maxHHUTXO); - }*/ - hhutxo = calloc(1,sizeof(*hhutxo));//&HHUTXO[numHHUTXO++], memset(hhutxo,0,sizeof(*hhutxo)); + hhutxo = calloc(1,sizeof(*hhutxo)); hhutxo->uval = uval; HASH_ADD_KEYPTR(hh,coin->utxotable,&hhutxo->uval,sizeof(hhutxo->uval),hhutxo); if ( (hhacct= iguana_hhaccountfind(coin,pval)) == 0 ) { - /*if ( 0 && numHHACCT+1 >= maxHHACCT ) - { - maxHHACCT += 1; - HHACCT = realloc(HHACCT,sizeof(*HHACCT) * maxHHACCT); - }*/ - hhacct = calloc(1,sizeof(*hhacct)); // &HHACCT[numHHACCT++], memset(hhacct,0,sizeof(*hhacct)); + hhacct = calloc(1,sizeof(*hhacct)); hhacct->pval = pval; HASH_ADD_KEYPTR(hh,coin->accountstable,&hhacct->pval,sizeof(hhacct->pval),hhacct); } //printf("create hhutxo.%p hhacct.%p from.%d\n",hhutxo,hhacct,fromheight); hhutxo->u.spentflag = 1; + hhutxo->u.lockedflag = 0; hhutxo->u.fromheight = fromheight; + hhutxo->u.spendind = spendind; hhutxo->u.prevunspentind = hhacct->a.lastunspentind; hhacct->a.lastunspentind = spent_unspentind; hhacct->a.total += spent_value; - /*if ( iguana_hhutxofind(coin,uval) == 0 || iguana_hhaccountfind(coin,pval) == 0 ) - { - printf("null hh find.(%ld %ld) %p %p\n",(long)uval,(long)pval,iguana_hhutxofind(coin,uval),iguana_hhaccountfind(coin,pval)); - }*/ + /*struct iguana_utxoaddr *utxoaddr; + if ( (utxoaddr= iguana_utxoaddrfind(1,coin,spent_hdrsi,spent_pkind,rmd160,&coin->RTprev)) != 0 ) + { + utxoaddr->RTdebits += spent_value; + coin->RTdebits += spent_value; + //printf("from.%d [%d] u%u -= %.8f\n",fromheight,spent_hdrsi,spent_pkind,dstr(spent_value)); + }*/ return(0); } +#endif + +void iguana_hhutxo_purge(struct iguana_info *coin) +{ + struct iguana_hhutxo *hhutxo,*tmp; + HASH_ITER(hh,coin->utxotable,hhutxo,tmp) + { + HASH_DELETE(hh,coin->utxotable,hhutxo); + free(hhutxo); + } +} -int32_t iguana_spentflag(struct iguana_info *coin,int64_t *RTspendp,int32_t *spentheightp,struct iguana_ramchain *ramchain,int16_t spent_hdrsi,uint32_t spent_unspentind,int32_t height,int32_t minconf,int32_t maxconf,uint64_t amount) +struct iguana_hhutxo *iguana_hhutxofind(struct iguana_info *coin,uint64_t uval) { - uint32_t numunspents; struct iguana_hhutxo *hhutxo; struct iguana_utxo utxo; uint64_t confs,val,RTspend = 0; - *spentheightp = 0; - numunspents = ramchain->H.data->numunspents; + struct iguana_hhutxo *hhutxo; + HASH_FIND(hh,coin->utxotable,&uval,sizeof(uval),hhutxo); + return(hhutxo); +} + +int32_t iguana_RTutxofunc(struct iguana_info *coin,int32_t *fromheightp,int32_t *lockedflagp,struct iguana_outpoint spentpt,int32_t *RTspendflagp,int32_t lockflag,int32_t fromheight) +{ + uint64_t val; struct iguana_hhutxo *hhutxo; struct iguana_utxo utxo; struct iguana_ramchain *ramchain; struct iguana_bundle *bp; struct iguana_ramchaindata *rdata; struct iguana_RTunspent *unspent; int32_t spentflag = 0; + *RTspendflagp = *lockedflagp = *fromheightp = 0; memset(&utxo,0,sizeof(utxo)); - val = ((uint64_t)spent_hdrsi << 32) | spent_unspentind; - if ( spent_unspentind != 0 && spent_unspentind < numunspents ) + if ( coin->disableUTXO != 0 ) { - if ( ramchain->Uextras != 0 ) - utxo = ramchain->Uextras[spent_unspentind]; - if ( ramchain->Uextras == 0 || utxo.spentflag == 0 ) + printf("skip utxofind when disabled\n"); + return(1); + } + if ( spentpt.isptr != 0 ) + { + if ( (unspent= spentpt.ptr) != 0 ) { - //printf("check hhutxo [%d] u%u %p\n",spent_hdrsi,spent_unspentind,iguana_hhutxofind(coin,((uint64_t)202<<32)|3909240)); - if ( (hhutxo= iguana_hhutxofind(coin,val)) != 0 ) + if ( lockflag == 0 && fromheight == 0 ) { - utxo = hhutxo->u; - if ( utxo.spentflag != 0 ) - RTspend = amount; + if ( unspent->spend != 0 ) + spentflag = 1; + if ( unspent->locked != 0 ) + *lockedflagp = 1; + *fromheightp = unspent->fromheight; } + else if ( fromheight != 0 ) + { + unspent->fromheight = fromheight; + if ( unspent->spend == 0 ) + printf("unexpected null spend when fromheight.%d\n",fromheight); + } + else if ( lockflag != 0 ) + unspent->locked = 1; + } + else + { + printf("missing spentpt ptr when isptr?\n"); + return(1); } } else { - printf("illegal unspentind.%u vs %u hdrs.%d\n",spent_unspentind,numunspents,spent_hdrsi); - return(-1); + if ( (bp= coin->bundles[spentpt.hdrsi]) == 0 ) + return(1); + ramchain = &bp->ramchain;//(bp == coin->current) ? &coin->RTramchain : &bp->ramchain; + if ( (rdata= ramchain->H.data) == 0 ) + return(1); + val = ((uint64_t)spentpt.hdrsi << 32) | spentpt.unspentind; + if ( (utxo.fromheight= fromheight) != 0 ) + utxo.spentflag = 1; + if ( spentpt.unspentind > 0 && spentpt.unspentind < rdata->numunspents ) + { + if ( ramchain->Uextras != 0 ) + { + utxo = ramchain->Uextras[spentpt.unspentind]; + if ( lockflag != 0 ) + { + if ( (hhutxo= iguana_hhutxofind(coin,val)) == 0 ) + { + hhutxo = calloc(1,sizeof(*hhutxo)); + hhutxo->uval = val; + hhutxo->u = utxo; + HASH_ADD_KEYPTR(hh,coin->utxotable,&hhutxo->uval,sizeof(hhutxo->uval),hhutxo); + } + printf("iguana_utxofind: need to change to new RT lock method\n"); + } + } + if ( ramchain->Uextras == 0 || utxo.spentflag == 0 ) + { + if ( (hhutxo= iguana_hhutxofind(coin,val)) != 0 ) + utxo = hhutxo->u; + //printf("iguana_utxofind: need to change to new RT method\n"); + } + } + else + { + printf("%s illegal unspentind.%u vs %u hdrs.%d\n",coin->symbol,spentpt.unspentind,rdata->numunspents,spentpt.hdrsi); + } } - if ( utxo.spentflag != 0 && utxo.fromheight == 0 ) + if ( lockflag != 0 ) { - printf("illegal unspentind.%u vs %u hdrs.%d zero fromheight?\n",spent_unspentind,numunspents,spent_hdrsi); - return(-1); + if ( utxo.lockedflag == 0 ) + utxo.lockedflag = 1; + else printf("iguana_hhutxofind warning: locking already locked [%d].%u\n",spentpt.hdrsi,spentpt.unspentind); + } else utxo.lockedflag = 0; + if ( utxo.spentflag != 0 || utxo.lockedflag != 0 ) + *RTspendflagp = 1; + *fromheightp = utxo.fromheight; + return(utxo.spentflag); +} + +int32_t iguana_RTspentflag(struct supernet_info *myinfo,struct iguana_info *coin,int64_t *RTspendp,int32_t *spentheightp,struct iguana_ramchain *ramchain,struct iguana_outpoint spentpt,int32_t height,int32_t minconf,int32_t maxconf,uint64_t amount) +{ + uint32_t numunspents; int32_t RTspentflag,spentflag,lockedflag,fromheight; uint64_t confs;//,RTspend = 0; + struct iguana_ramchaindata *rdata; struct iguana_RTunspent *unspent; + *spentheightp = -1; + if ( coin->disableUTXO != 0 ) + { + //printf("skip spentflag when disabled\n"); + return(0); + } + if ( spentpt.isptr != 0 ) + { + if ( (unspent= spentpt.ptr) != 0 ) + { + if ( unspent->spend != 0 ) + { + *RTspendp += (amount == 0) ? coin->txfee : amount; + return(1); + } + else if ( unspent->locked != 0 ) + return(-1); + } else printf("missing spentpt ptr when isptr?\n"); + return(0); } - //printf("[%d] u%u %.8f, spentheight.%d vs height.%d spentflag.%d\n",spent_hdrsi,spent_unspentind,dstr(amount),utxo.fromheight,height,utxo.spentflag); - *spentheightp = utxo.fromheight; - if ( (confs= coin->blocks.hwmchain.height - utxo.fromheight) >= minconf && confs < maxconf && (height == 0 || utxo.fromheight < height) ) + if ( (rdata= ramchain->H.data) == 0 ) + return(0); + numunspents = rdata->numunspents; + spentflag = iguana_RTutxofunc(coin,&fromheight,&lockedflag,spentpt,&RTspentflag,0,0); + if ( spentflag != 0 && fromheight == 0 ) { - (*RTspendp) += RTspend; - if ( utxo.spentflag != 0 ) + if ( height == 0 ) + { + //printf("%s illegal unspentind.%u vs %u hdrs.%d zero fromheight.%d?\n",coin->symbol,spentpt.unspentind,numunspents,spentpt.hdrsi,fromheight); + height = spentpt.hdrsi*coin->chain->bundlesize + 1; + } + fromheight = height; + } + if ( RTspentflag != 0 ) + *RTspendp += (amount == 0) ? coin->txfee : amount; + //printf("[%d] u%u %.8f, spentheight.%d vs height.%d spentflag.%d\n",spent_hdrsi,spent_unspentind,dstr(amount),fromheight,height,spentflag); + *spentheightp = fromheight; + if ( (confs= coin->blocks.hwmchain.height - fromheight) >= minconf && confs < maxconf && (height <= 0 || fromheight < height) ) + { + //(*RTspendp) += RTspend; + if ( spentflag != 0 ) return(1); - else if ( utxo.lockedflag != 0 ) + else if ( lockedflag != 0 ) return(-1); else return(0); } @@ -160,13 +260,19 @@ int32_t iguana_spentflag(struct iguana_info *coin,int64_t *RTspendp,int32_t *spe int32_t iguana_volatileupdate(struct iguana_info *coin,int32_t incremental,struct iguana_ramchain *spentchain,int16_t spent_hdrsi,uint32_t spent_unspentind,uint32_t spent_pkind,uint64_t spent_value,uint32_t spendind,uint32_t fromheight) { - struct iguana_account *A2; struct iguana_ramchaindata *rdata; struct iguana_utxo *utxo; + struct iguana_ramchaindata *rdata; struct iguana_utxo *utxo; struct iguana_account *A2; // struct iguana_unspent *spentU; struct iguana_pkhash *spentP; + if ( coin->disableUTXO != 0 ) + { + printf("skip volatileupdate when disabled\n"); + return(0); + } if ( (rdata= spentchain->H.data) != 0 ) { + //portable_mutex_lock(&coin->RTmutex); if ( incremental == 0 ) { if ( spentchain->Uextras == 0 || spentchain->A2 == 0 ) - iguana_volatilesmap(coin,spentchain); + iguana_volatilesalloc(coin,spentchain,1); if ( spentchain->Uextras != 0 && (A2= spentchain->A2) != 0 ) { utxo = &spentchain->Uextras[spent_unspentind]; @@ -175,40 +281,76 @@ int32_t iguana_volatileupdate(struct iguana_info *coin,int32_t incremental,struc if ( 0 && fromheight/coin->chain->bundlesize >= coin->current->hdrsi ) printf("iguana_volatileupdate.%d: [%d] spent.(u%u %.8f pkind.%d) fromht.%d [%d] spendind.%d\n",incremental,spent_hdrsi,spent_unspentind,dstr(spent_value),spent_pkind,fromheight,fromheight/coin->chain->bundlesize,spendind); utxo->prevunspentind = A2[spent_pkind].lastunspentind; + utxo->spendind = spendind; utxo->spentflag = 1; utxo->fromheight = fromheight; A2[spent_pkind].total += spent_value; A2[spent_pkind].lastunspentind = spent_unspentind; + //portable_mutex_unlock(&coin->RTmutex); return(0); } else { - printf("from.%d spent_unspentind[%d] in hdrs.[%d] is spent fromht.%d %.8f\n",fromheight,spent_unspentind,spent_hdrsi,utxo->fromheight,dstr(spent_value)); + if ( spendind != utxo->spendind || fromheight != utxo->fromheight ) + printf("from.%d spent_unspentind[%d] in hdrs.[%d] is spent fromht.%d %.8f\n",fromheight,spent_unspentind,spent_hdrsi,utxo->fromheight,dstr(spent_value)); + else + { + //portable_mutex_unlock(&coin->RTmutex); + return(0); + } } } else printf("null ptrs.[%d] u.%u p.%u %.8f from ht.%d s.%u\n",spent_hdrsi,spent_unspentind,spent_pkind,dstr(spent_value),fromheight,spendind); } else // do the equivalent of historical, ie mark as spent, linked list, balance { //double startmillis = OS_milliseconds(); static double totalmillis; static int32_t utxon; - if ( iguana_utxoupdate(coin,spent_hdrsi,spent_unspentind,spent_pkind,spent_value,spendind,fromheight) == 0 ) + printf("hhutxo deprecated\n"); + exit(-1); + /*spentP = RAMCHAIN_PTR(rdata,Poffset); + spentU = RAMCHAIN_PTR(rdata,Uoffset); + if ( iguana_utxoupdate(coin,spent_hdrsi,spent_unspentind,spent_pkind,spent_value,spendind,fromheight,spentP[spent_pkind].rmd160) == 0 ) { - /*totalmillis += (OS_milliseconds() - startmillis); - if ( (++utxon % 100000) == 0 ) - printf("ave utxo[%d] %.2f micros total %.2f seconds\n",utxon,(1000. * totalmillis)/utxon,totalmillis/1000.);*/ + //totalmillis += (OS_milliseconds() - startmillis); + // if ( (++utxon % 100000) == 0 ) + // printf("ave utxo[%d] %.2f micros total %.2f seconds\n",utxon,(1000. * totalmillis)/utxon,totalmillis/1000.); + //portable_mutex_unlock(&coin->RTmutex); return(0); - } + }*/ } - printf("iguana_volatileupdate.%d: [%d] spent.(u%u %.8f pkind.%d) double spend? at ht.%d [%d] spendind.%d (%p %p)\n",incremental,spent_hdrsi,spent_unspentind,dstr(spent_value),spent_pkind,fromheight,fromheight/coin->chain->bundlesize,spendind,spentchain->Uextras,spentchain->A2); - if ( coin->current != 0 && fromheight >= coin->current->bundleheight ) + //portable_mutex_unlock(&coin->RTmutex); + printf("end iguana_volatileupdate.%d: [%d] spent.(u%u %.8f pkind.%d) double spend? at ht.%d [%d] spendind.%d (%p %p)\n",incremental,spent_hdrsi,spent_unspentind,dstr(spent_value),spent_pkind,fromheight,fromheight/coin->chain->bundlesize,spendind,spentchain->Uextras,spentchain->A2); + /*if ( coin->current != 0 && fromheight >= coin->current->bundleheight ) coin->RTdatabad = 1; else { printf("from.%d vs current.%d\n",fromheight,coin->current->bundleheight); - iguana_bundleremove(coin,spent_hdrsi,0); iguana_bundleremove(coin,fromheight/coin->chain->bundlesize,0); } - exit(-1); - } else printf("volatileupdate error null rdata [%d]\n",spentchain->height/coin->current->bundleheight); + coin->spendvectorsaved = 0; + coin->started = 0; + coin->active = 0;*/ + coin->RTdatabad = 1; + if ( coin->current != 0 && spent_hdrsi != coin->current->hdrsi && spent_hdrsi != fromheight/coin->chain->bundlesize ) + { + printf("restart iguana\n"); + struct iguana_bundle *bp; + portable_mutex_lock(&coin->special_mutex); + if ( (bp= coin->bundles[spent_hdrsi]) != 0 ) + { + iguana_bundleremove(coin,spent_hdrsi,0); + bp->ramchain.H.data = 0; + } + if ( (bp= coin->bundles[fromheight/coin->chain->bundlesize]) != 0 ) + { + iguana_bundleremove(coin,fromheight/coin->chain->bundlesize,0); + bp->ramchain.H.data = 0; + } + portable_mutex_unlock(&coin->special_mutex); + exit(-1); + } + } + else if ( coin->spendvectorsaved > 1 ) + printf("volatileupdate skip null rdata [%d]\n",spentchain->height/coin->current->bundleheight); return(-1); } @@ -296,11 +438,14 @@ int32_t iguana_volatilesmap(struct iguana_info *coin,struct iguana_ramchain *ram return(-1); } if ( ramchain->debitsfileptr != 0 && ramchain->lastspendsfileptr != 0 ) + { + //printf("volatilesmap.[%d] already mapped %p %p\n",ramchain->height,ramchain->debitsfileptr,ramchain->lastspendsfileptr); return(0); + } for (iter=0; iter<2; iter++) { sprintf(fname,"%s/%s%s/accounts/debits.%d",GLOBAL_DBDIR,iter==0?"ro/":"",coin->symbol,ramchain->height); - if ( (ramchain->debitsfileptr= OS_mapfile(fname,&ramchain->debitsfilesize,0)) != 0 && ramchain->debitsfilesize == sizeof(int32_t) + 2*sizeof(bits256) + sizeof(*ramchain->A2) * ramchain->H.data->numpkinds ) + if ( (ramchain->debitsfileptr= OS_mapfile(fname,&ramchain->debitsfilesize,0)) != 0 && ramchain->debitsfilesize == sizeof(int32_t) + 2*sizeof(bits256) + sizeof(*ramchain->A2) * rdata->numpkinds ) { ramchain->from_roA = (iter == 0); numhdrsi = *(int32_t *)ramchain->debitsfileptr; @@ -312,27 +457,42 @@ int32_t iguana_volatilesmap(struct iguana_info *coin,struct iguana_ramchain *ram coin->balancehash = balancehash; coin->allbundles = allbundles; } - if ( numhdrsi == coin->balanceswritten && memcmp(balancehash.bytes,coin->balancehash.bytes,sizeof(balancehash)) == 0 && memcmp(allbundles.bytes,coin->allbundles.bytes,sizeof(allbundles)) == 0 ) + if ( numhdrsi >= coin->balanceswritten-1 && memcmp(balancehash.bytes,coin->balancehash.bytes,sizeof(balancehash)) == 0 && memcmp(allbundles.bytes,coin->allbundles.bytes,sizeof(allbundles)) == 0 ) { ramchain->A2 = (void *)((long)ramchain->debitsfileptr + sizeof(numhdrsi) + 2*sizeof(bits256)); sprintf(fname,"%s/%s%s/accounts/lastspends.%d",GLOBAL_DBDIR,iter==0?"ro/":"",coin->symbol,ramchain->height); - if ( (ramchain->lastspendsfileptr= OS_mapfile(fname,&ramchain->lastspendsfilesize,0)) != 0 && ramchain->lastspendsfilesize == sizeof(int32_t) + 2*sizeof(bits256) + sizeof(*ramchain->Uextras) * ramchain->H.data->numunspents ) + if ( (ramchain->lastspendsfileptr= OS_mapfile(fname,&ramchain->lastspendsfilesize,0)) != 0 && ramchain->lastspendsfilesize == sizeof(int32_t) + 2*sizeof(bits256) + sizeof(*ramchain->Uextras) * rdata->numunspents ) { numhdrsi = *(int32_t *)ramchain->lastspendsfileptr; memcpy(balancehash.bytes,(void *)((long)ramchain->lastspendsfileptr + sizeof(numhdrsi)),sizeof(balancehash)); memcpy(allbundles.bytes,(void *)((long)ramchain->lastspendsfileptr + sizeof(numhdrsi) + sizeof(balancehash)),sizeof(allbundles)); - if ( numhdrsi == coin->balanceswritten && memcmp(balancehash.bytes,coin->balancehash.bytes,sizeof(balancehash)) == 0 && memcmp(allbundles.bytes,coin->allbundles.bytes,sizeof(allbundles)) == 0 ) + if ( numhdrsi >= coin->balanceswritten-1 && memcmp(balancehash.bytes,coin->balancehash.bytes,sizeof(balancehash)) == 0 && memcmp(allbundles.bytes,coin->allbundles.bytes,sizeof(allbundles)) == 0 ) { ramchain->Uextras = (void *)((long)ramchain->lastspendsfileptr + sizeof(numhdrsi) + 2*sizeof(bits256)); ramchain->from_roU = (iter == 0); - //printf("volatilesmap.[%d] %p %p\n",ramchain->height/coin->chain->bundlesize,ramchain->debitsfileptr,ramchain->lastspendsfileptr); + uint32_t unspentind,nonz=0; struct iguana_unspent *U; struct iguana_utxo *U2; + if ( iter == 1 && (ramchain->height % 100000) == 0 ) + { + U2 = ramchain->Uextras; + U = RAMCHAIN_PTR(ramchain->H.data,Uoffset); + for (unspentind=1; unspentindH.data->numunspents; unspentind++) + { + if ( U2[unspentind].spentflag != 0 ) + nonz++; + //printf("[%d] u%d: (p%u %.8f) from.%d lock.%d prev.%u spent.%d\n",ramchain->height/coin->chain->bundlesize,unspentind,U[unspentind].pkind,dstr(U[unspentind].value),U2[unspentind].fromheight,U2[unspentind].lockedflag,U2[unspentind].prevunspentind,U2[unspentind].spentflag); + } + //printf("iter.%d nonz.%d %s volatilesmap.[%d] %p %p\n",iter,nonz,fname,ramchain->height/coin->chain->bundlesize,ramchain->debitsfileptr,ramchain->lastspendsfileptr); + } err = 0; + struct iguana_bundle *bp; + if ( (bp= coin->bundles[ramchain->height / coin->chain->bundlesize]) != 0 ) + bp->balancefinish = (uint32_t)time(NULL); } else printf("ramchain map error2 balanceswritten %d vs %d hashes %x %x\n",coin->balanceswritten,numhdrsi,coin->balancehash.uints[0],balancehash.uints[0]); } else printf("ramchain map error3 %s\n",fname); } else { - printf("ramchain.[%d] map error balanceswritten %d vs %d hashes %x %x\n",ramchain->H.data->height,coin->balanceswritten,numhdrsi,coin->balancehash.uints[0],balancehash.uints[0]); + printf("ramchain.[%d] map error balanceswritten %d vs %d hashes %x %x\n",rdata->height,coin->balanceswritten,numhdrsi,coin->balancehash.uints[0],balancehash.uints[0]); err++; OS_removefile(fname,0); } diff --git a/iguana/iguana_wallet.c b/iguana/iguana_wallet.c index b2e67e629..a7912a569 100755 --- a/iguana/iguana_wallet.c +++ b/iguana/iguana_wallet.c @@ -29,12 +29,14 @@ void scrubfree(char *sensitivestr) } } -struct iguana_waddress *iguana_waddressfind(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waccount *wacct,char *coinaddr) +struct iguana_waddress *iguana_waddressfind(struct supernet_info *myinfo,struct iguana_waccount *wacct,char *coinaddr) { - struct iguana_waddress *waddr; int32_t len = (int32_t)strlen(coinaddr)+1; - HASH_FIND(hh,wacct->waddr,coinaddr,len,waddr); - if ( waddr != 0 && coin != 0 && strcmp(coin->symbol,waddr->symbol) != 0 ) - return(0); + struct iguana_waddress *waddr; uint8_t addrtype,rmd160[20]; + bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr); + //calc_rmd160_sha256(rmd160,pubkey33,33); + HASH_FIND(hh,wacct->waddr,rmd160,sizeof(rmd160),waddr); + //if ( waddr != 0 && coin != 0 && strcmp(coin->symbol,waddr->symbol) != 0 ) + // return(0); //printf("%s (%s).%d in (%s)\n",waddr==0?"couldnt find":"found",coinaddr,len,wacct->account); return(waddr); } @@ -46,74 +48,88 @@ struct iguana_waddress *iguana_waddressalloc(uint8_t addrtype,char *symbol,char waddr = mycalloc('w',1,sizeof(*waddr) + scriptlen); waddr->addrtype = addrtype; strcpy(waddr->coinaddr,coinaddr); + bitcoin_addr2rmd160(&addrtype,waddr->rmd160,coinaddr); strcpy(waddr->symbol,symbol); if ( (waddr->scriptlen= scriptlen) != 0 ) decode_hex(waddr->redeemScript,scriptlen,redeemScript); return(waddr); } -struct iguana_waccount *iguana_waccountfind(struct supernet_info *myinfo,struct iguana_info *coin,char *account) +struct iguana_waccount *iguana_waccountfind(struct supernet_info *myinfo,char *account) { - struct iguana_waccount *wacct; - HASH_FIND(hh,myinfo->wallet,account,strlen(account)+1,wacct); + struct iguana_waccount *wacct = 0; + if ( account != 0 ) + HASH_FIND(hh,myinfo->wallet,account,strlen(account)+1,wacct); //printf("waccountfind.(%s) -> wacct.%p\n",account,wacct); return(wacct); } -struct iguana_waccount *iguana_waccountcreate(struct supernet_info *myinfo,struct iguana_info *coin,char *account) +struct iguana_waccount *iguana_waccountcreate(struct supernet_info *myinfo,char *account) { - struct iguana_waccount *wacct,*ptr; int32_t len = (int32_t)strlen(account)+1; - HASH_FIND(hh,myinfo->wallet,account,len,wacct); - if ( wacct == 0 ) + struct iguana_waccount *wacct=0,*ptr; int32_t len; + if ( account != 0 ) { - wacct = mycalloc('w',1,sizeof(*wacct)); - strcpy(wacct->account,account); - HASH_ADD_KEYPTR(hh,myinfo->wallet,wacct->account,len,wacct); - //printf("waccountcreate.(%s) -> wacct.%p\n",account,wacct); - myinfo->dirty = (uint32_t)time(NULL); - if ( (ptr= iguana_waccountfind(myinfo,coin,account)) != wacct ) - printf("iguana_waccountcreate verify error %p vs %p\n",ptr,wacct); + if ( account[0] == 0 ) + account = "default"; + len = (int32_t)strlen(account)+1; + HASH_FIND(hh,myinfo->wallet,account,len,wacct); + if ( wacct == 0 ) + { + wacct = mycalloc('w',1,sizeof(*wacct) + len); + strcpy(wacct->account,account); + HASH_ADD_KEYPTR(hh,myinfo->wallet,wacct->account,len,wacct); + printf("waccountcreate.(%s) -> wacct.%p\n",account,wacct); + if ( (ptr= iguana_waccountfind(myinfo,account)) != wacct ) + { + printf("ERROR: iguana_waccountcreate verify error %p vs %p\n",ptr,wacct); + HASH_FIND(hh,myinfo->wallet,account,len,wacct); + printf("HASH_FIND.%p\n",wacct); + getchar(); + } + myinfo->dirty = (uint32_t)time(NULL); + } } return(wacct); } struct iguana_waddress *iguana_waddresscreate(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waccount *wacct,char *coinaddr,char *redeemScript) { - struct iguana_waddress *waddr,*ptr; int32_t len = (int32_t)strlen(coinaddr)+1; + struct iguana_waddress *waddr,*ptr; uint8_t rmd160[20],addrtype; + bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr); if ( wacct == 0 ) - wacct = iguana_waccountcreate(myinfo,coin,""); - HASH_FIND(hh,wacct->waddr,coinaddr,len,waddr); + wacct = iguana_waccountcreate(myinfo,""); + HASH_FIND(hh,wacct->waddr,rmd160,sizeof(rmd160),waddr); if ( waddr == 0 ) { if ( (waddr= iguana_waddressalloc(redeemScript==0?coin->chain->pubtype : coin->chain->p2shtype,coin->symbol,coinaddr,redeemScript)) != 0 ) { - HASH_ADD_KEYPTR(hh,wacct->waddr,waddr->coinaddr,len,waddr); + HASH_ADD_KEYPTR(hh,wacct->waddr,waddr->rmd160,sizeof(waddr->rmd160),waddr); myinfo->dirty = (uint32_t)time(NULL); - printf("create (%s).%d scriptlen.%d -> (%s)\n",coinaddr,len,waddr->scriptlen,wacct->account); + printf("create (%s)scriptlen.%d -> (%s)\n",coinaddr,waddr->scriptlen,wacct->account); } else printf("error iguana_waddressalloc null waddr\n"); } //else printf("have (%s) in (%s)\n",coinaddr,wacct->account); - if ( (ptr= iguana_waddressfind(myinfo,coin,wacct,coinaddr)) != waddr ) + if ( (ptr= iguana_waddressfind(myinfo,wacct,coinaddr)) != waddr ) printf("iguana_waddresscreate verify error %p vs %p\n",ptr,waddr); return(waddr); } struct iguana_waddress *iguana_waddressadd(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waccount *wacct,struct iguana_waddress *addwaddr,char *redeemScript) { - struct iguana_waddress *waddr,*ptr; int32_t len = (int32_t)strlen(addwaddr->coinaddr)+1; - HASH_FIND(hh,wacct->waddr,addwaddr->coinaddr,len,waddr); + struct iguana_waddress *waddr,*ptr; uint8_t rmd160[20],addrtype; + printf("search for (%s)\n",addwaddr->coinaddr); + bitcoin_addr2rmd160(&addrtype,rmd160,addwaddr->coinaddr); + HASH_FIND(hh,wacct->waddr,rmd160,sizeof(rmd160),waddr); if ( waddr == 0 ) { - if ( (waddr= iguana_waddressalloc(redeemScript==0?coin->chain->pubtype : coin->chain->p2shtype,coin->symbol,addwaddr->coinaddr,redeemScript)) != 0 ) + if ( (waddr= iguana_waddressalloc(addrtype,coin->symbol,addwaddr->coinaddr,redeemScript)) == 0 ) { - HASH_ADD_KEYPTR(hh,wacct->waddr,waddr->coinaddr,len,waddr); - myinfo->dirty = (uint32_t)time(NULL); - printf("add (%s).%d scriptlen.%d -> (%s) wif.(%s)\n",waddr->coinaddr,len,waddr->scriptlen,wacct->account,waddr->wifstr); - } else printf("error iguana_waddressalloc null waddr\n"); + printf("error iguana_waddressalloc null waddr\n"); + return(0); + } } //else printf("have (%s) in (%s)\n",waddr->coinaddr,wacct->account); - if ( (ptr= iguana_waddressfind(myinfo,coin,wacct,waddr->coinaddr)) != waddr ) - printf("iguana_waddressadd verify error %p vs %p\n",ptr,waddr); if ( waddr != 0 && waddr != addwaddr ) { + myinfo->dirty = (uint32_t)time(NULL); waddr->wiftype = coin->chain->wiftype; if ( redeemScript != 0 && (addwaddr->scriptlen= (int32_t)strlen(redeemScript) >> 1) != 0 ) { @@ -126,23 +142,39 @@ struct iguana_waddress *iguana_waddressadd(struct supernet_info *myinfo,struct i waddr->scriptlen = addwaddr->scriptlen; decode_hex(waddr->redeemScript,waddr->scriptlen,redeemScript); } - waddr->addrtype = coin->chain->p2shtype; + waddr->addrtype = addrtype;//coin->chain->p2shtype; memset(&waddr->privkey,0,sizeof(waddr->privkey)); memset(waddr->pubkey,0,sizeof(waddr->pubkey)); + calc_rmd160_sha256(waddr->rmd160,waddr->redeemScript,waddr->scriptlen); } else { - waddr->addrtype = coin->chain->pubtype; + waddr->addrtype = addrtype;//coin->chain->pubtype; waddr->wiftype = addwaddr->wiftype; if ( bits256_nonz(waddr->privkey) == 0 ) waddr->privkey = addwaddr->privkey; if ( addwaddr->wifstr[0] != 0 ) strcpy(waddr->wifstr,addwaddr->wifstr); - memcpy(waddr->pubkey,addwaddr->pubkey,sizeof(waddr->pubkey)); + memcpy(waddr->rmd160,rmd160,sizeof(waddr->rmd160)); + calc_rmd160_sha256(rmd160,addwaddr->pubkey,bitcoin_pubkeylen(addwaddr->pubkey)); + if ( memcmp(rmd160,waddr->rmd160,sizeof(waddr->rmd160)) == 0 ) + memcpy(waddr->pubkey,addwaddr->pubkey,sizeof(waddr->pubkey)); } - memcpy(waddr->rmd160,addwaddr->rmd160,sizeof(waddr->rmd160)); - strcpy(waddr->coinaddr,addwaddr->coinaddr); + bitcoin_address(waddr->coinaddr,waddr->addrtype,waddr->rmd160,sizeof(waddr->rmd160)); + myinfo->dirty = (uint32_t)time(NULL); + } + if ( (ptr= iguana_waddressfind(myinfo,wacct,waddr->coinaddr)) == 0 ) + { + HASH_ADD_KEYPTR(hh,wacct->waddr,waddr->rmd160,sizeof(waddr->rmd160),waddr); myinfo->dirty = (uint32_t)time(NULL); + int32_t i; for (i=0; i<20; i++) + printf("%02x",waddr->rmd160[i]); + printf(" add (%s) scriptlen.%d -> (%s) wif.(%s)\n",waddr->coinaddr,waddr->scriptlen,wacct->account,waddr->wifstr); + } + else + { + waddr = ptr; + printf("(%s) already in account.(%s)\n",waddr->coinaddr,wacct->account); } if ( waddr != 0 && waddr->symbol[0] == 0 ) strcpy(waddr->symbol,coin->symbol); @@ -151,8 +183,9 @@ struct iguana_waddress *iguana_waddressadd(struct supernet_info *myinfo,struct i struct iguana_waddress *iguana_waddressdelete(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waccount *wacct,char *coinaddr) { - struct iguana_waddress *waddr = 0; int32_t len = (int32_t)strlen(coinaddr)+1; - HASH_FIND(hh,wacct->waddr,coinaddr,len,waddr); + struct iguana_waddress *waddr = 0; uint8_t rmd160[20],addrtype; + bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr); + HASH_FIND(hh,wacct->waddr,rmd160,sizeof(rmd160),waddr); if ( waddr != 0 ) { HASH_DELETE(hh,wacct->waddr,waddr); @@ -161,52 +194,51 @@ struct iguana_waddress *iguana_waddressdelete(struct supernet_info *myinfo,struc return(waddr); } -struct iguana_waddress *iguana_waddresssearch(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waccount **wacctp,char *coinaddr) +struct iguana_waddress *iguana_waddresssearch(struct supernet_info *myinfo,struct iguana_waccount **wacctp,char *coinaddr) { struct iguana_waccount *wacct,*tmp; struct iguana_waddress *waddr; HASH_ITER(hh,myinfo->wallet,wacct,tmp) { - if ( (waddr= iguana_waddressfind(myinfo,coin,wacct,coinaddr)) != 0 ) + if ( (waddr= iguana_waddressfind(myinfo,wacct,coinaddr)) != 0 ) { - if ( waddr != 0 && bits256_nonz(waddr->privkey) != 0 ) + if ( waddr != 0 && bits256_nonz(waddr->privkey) != 0 && waddr->wifstr[0] == 0 ) { - if ( bitcoin_priv2wif(waddr->wifstr,waddr->privkey,coin->chain->wiftype) > 0 ) - { - if ( waddr->wiftype != coin->chain->wiftype ) - printf("waddresssearch warning: mismatched wiftype %02x != %02x\n",waddr->wiftype,coin->chain->wiftype); - if ( waddr->addrtype != coin->chain->pubtype ) - printf("waddresssearch warning: mismatched wiftype %02x != %02x\n",waddr->addrtype,coin->chain->pubtype); - } + printf("coinaddr.(%s) no wifstr\n",coinaddr); + //if ( bitcoin_priv2wif(waddr->wifstr,waddr->privkey,coin->chain->wiftype) > 0 ) + //{ + //} } (*wacctp) = wacct; return(waddr); - } + } //else printf("not in (%s)\n",wacct->account); } + (*wacctp) = 0; return(0); } -struct iguana_waddress *iguana_waddresscalc(struct supernet_info *myinfo,uint8_t pubtype,uint8_t wiftype,struct iguana_waddress *addr,bits256 privkey) +struct iguana_waddress *iguana_waddresscalc(struct supernet_info *myinfo,uint8_t pubtype,uint8_t wiftype,struct iguana_waddress *waddr,bits256 privkey) { - addr->privkey = privkey; - bitcoin_pubkey33(myinfo->ctx,addr->pubkey,addr->privkey); - calc_rmd160_sha256(addr->rmd160,addr->pubkey,33); - bitcoin_address(addr->coinaddr,pubtype,addr->rmd160,sizeof(addr->rmd160)); + waddr->privkey = privkey; + bitcoin_pubkey33(myinfo->ctx,waddr->pubkey,waddr->privkey); + calc_rmd160_sha256(waddr->rmd160,waddr->pubkey,33); + bitcoin_address(waddr->coinaddr,pubtype,waddr->rmd160,sizeof(waddr->rmd160)); if ( bits256_nonz(privkey) != 0 ) { - if ( bitcoin_priv2wif(addr->wifstr,addr->privkey,wiftype) > 0 ) + myinfo->dirty = (uint32_t)time(NULL); + if ( bitcoin_priv2wif(waddr->wifstr,waddr->privkey,wiftype) > 0 ) { - addr->wiftype = wiftype; - addr->addrtype = pubtype; - return(addr); + waddr->wiftype = wiftype; + waddr->addrtype = pubtype; + return(waddr); } - } else printf("waddress_calc null privkey\n"); + } else printf("waddress_calc.(%s) null privkey\n",waddr->coinaddr); return(0); } struct iguana_waddress *iguana_waccountswitch(struct supernet_info *myinfo,struct iguana_info *coin,char *account,char *coinaddr,char *redeemScript) { struct iguana_waccount *wacct = 0; struct iguana_waddress addr,*waddr = 0; int32_t flag = 0; - if ( (waddr= iguana_waddresssearch(myinfo,coin,&wacct,coinaddr)) != 0 ) + if ( (waddr= iguana_waddresssearch(myinfo,&wacct,coinaddr)) != 0 && wacct != 0 ) { if ( strcmp(wacct->account,account) != 0 ) { @@ -215,12 +247,18 @@ struct iguana_waddress *iguana_waccountswitch(struct supernet_info *myinfo,struc iguana_waddressdelete(myinfo,coin,wacct,coinaddr); } } - if ( waddr == 0 && (wacct= iguana_waccountcreate(myinfo,coin,account)) != 0 ) + if ( (wacct= iguana_waccountcreate(myinfo,account)) != 0 ) { waddr = iguana_waddresscreate(myinfo,coin,wacct,coinaddr,redeemScript); - if ( flag != 0 && redeemScript == 0 ) - iguana_waddresscalc(myinfo,coin->chain->pubtype,coin->chain->wiftype,waddr,addr.privkey); + if ( waddr != 0 ) + { + if ( redeemScript == 0 ) + iguana_waddresscalc(myinfo,coin->chain->pubtype,coin->chain->wiftype,waddr,addr.privkey); + strcpy(waddr->coinaddr,coinaddr); + waddr = iguana_waddressadd(myinfo,coin,wacct,waddr,redeemScript); + } else waddr = 0; } + myinfo->dirty = (uint32_t)time(NULL); return(waddr); } @@ -254,44 +292,77 @@ uint8_t *iguana_walletrmds(struct supernet_info *myinfo,struct iguana_info *coin return(rmdarray); } -cJSON *getaddressesbyaccount(struct supernet_info *myinfo,struct iguana_info *coin,char *account) +cJSON *iguana_getaddressesbyaccount(struct supernet_info *myinfo,struct iguana_info *coin,char *account) { - struct iguana_waccount *subset; struct iguana_waddress *waddr,*tmp; cJSON *retjson,*array; + struct iguana_waccount *subset,*tmp; char refaddr[64],coinaddr[64]; struct iguana_waddress *waddr,*tmp2; cJSON *retjson,*array; retjson = cJSON_CreateObject(); array = cJSON_CreateArray(); - if ( (subset= iguana_waccountfind(myinfo,coin,account)) != 0 ) + if ( account == 0 || account[0] == 0 ) + account = "*"; + if ( strcmp("*",account) != 0 ) { - HASH_ITER(hh,subset->waddr,waddr,tmp) + if ( (subset= iguana_waccountfind(myinfo,account)) != 0 ) { - jaddistr(array,waddr->coinaddr); + HASH_ITER(hh,subset->waddr,waddr,tmp2) + { + bitcoin_address(coinaddr,coin->chain->pubtype,waddr->rmd160,20); + printf("%s ",coinaddr); + jaddistr(array,coinaddr); + } + } else jaddstr(retjson,"result","cant find account"); + } + else + { + bitcoin_address(refaddr,coin->chain->pubtype,myinfo->persistent_pubkey33,33); + HASH_ITER(hh,myinfo->wallet,subset,tmp) + { + HASH_ITER(hh,subset->waddr,waddr,tmp2) + { + bitcoin_address(coinaddr,coin->chain->pubtype,waddr->rmd160,20); + jaddistr(array,coinaddr); + if ( strcmp(coinaddr,refaddr) == 0 ) + refaddr[0] = 0; + } } - } else jaddstr(retjson,"result","cant find account"); + if ( refaddr[0] != 0 ) + jaddistr(array,refaddr); + } return(array); } -struct iguana_waddress *iguana_ismine(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t addrtype,uint8_t pubkey[65],uint8_t rmd160[20]) +struct iguana_waddress *iguana_ismine(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr,uint8_t addrtype,uint8_t pubkey[65],uint8_t rmd160[20]) { - char coinaddr[65]; struct iguana_waccount *wacct; struct iguana_waddress *waddr = 0; + struct iguana_waccount *wacct; struct iguana_waddress *waddr = 0; if ( bitcoin_address(coinaddr,addrtype,rmd160,20) > 0 ) - waddr = iguana_waddresssearch(myinfo,coin,&wacct,coinaddr); + waddr = iguana_waddresssearch(myinfo,&wacct,coinaddr); return(waddr); } -int32_t iguana_addressvalidate(struct iguana_info *coin,uint8_t *addrtypep,uint8_t rmd160[20],char *address) +int32_t iguana_addressvalidate(struct iguana_info *coin,uint8_t *addrtypep,char *address) { - char checkaddr[64]; + char checkaddr[64]; uint8_t rmd160[20]; + *addrtypep = 0; + memset(rmd160,0,sizeof(rmd160)); bitcoin_addr2rmd160(addrtypep,rmd160,address); + //int32_t i; for (i=0; i<20; i++) + // printf("%02x",rmd160[i]); // 764692cd5473f62ffa8a93e55d876f567623de07 + //printf(" rmd160 addrtype.%02x\n",*addrtypep); if ( bitcoin_address(checkaddr,*addrtypep,rmd160,20) == checkaddr && strcmp(address,checkaddr) == 0 && (*addrtypep == coin->chain->pubtype || *addrtypep == coin->chain->p2shtype) ) return(0); - else return(-1); + else + { + //printf(" checkaddr.(%s) address.(%s) type.%02x vs (%02x %02x)\n",checkaddr,address,*addrtypep,coin->chain->pubtype,coin->chain->p2shtype); + return(-1); + } } -cJSON *iguana_waddressjson(cJSON *item,struct iguana_waddress *waddr) +cJSON *iguana_waddressjson(struct iguana_info *coin,cJSON *item,struct iguana_waddress *waddr) { - char str[256],redeemScript[4096]; + char str[256],redeemScript[4096],coinaddr[64]; if ( item == 0 ) item = cJSON_CreateObject(); - jaddstr(item,"address",waddr->coinaddr); + bitcoin_address(coinaddr,coin->chain->pubtype,waddr->rmd160,20); + jaddstr(item,"address",coinaddr); //jaddstr(item,"privkey",bits256_str(str,waddr->privkey)); //jaddstr(item,"wif",waddr->wifstr); init_hexbytes_noT(str,waddr->rmd160,20); @@ -312,34 +383,35 @@ cJSON *iguana_waddressjson(cJSON *item,struct iguana_waddress *waddr) char *setaccount(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waddress **waddrp,char *account,char *coinaddr,char *redeemScript) { - uint8_t addrtype,rmd160[20]; struct iguana_waddress *waddr=0; + uint8_t addrtype; struct iguana_waddress *waddr=0; if ( waddrp != 0 ) *waddrp = 0; if ( coinaddr != 0 && coinaddr[0] != 0 && account != 0 && account[0] != 0 ) { - if ( iguana_addressvalidate(coin,&addrtype,rmd160,coinaddr) < 0 ) + if ( iguana_addressvalidate(coin,&addrtype,coinaddr) < 0 ) return(clonestr("{\"error\":\"invalid coin address\"}")); if ( (waddr= iguana_waccountswitch(myinfo,coin,account,coinaddr,redeemScript)) != 0 ) { if ( waddrp != 0 ) *waddrp = waddr; return(clonestr("{\"result\":\"success\"}")); - } - else return(clonestr("{\"error\":\"couldnt set account\"}")); + } else return(clonestr("{\"error\":\"couldnt set account\"}")); } return(clonestr("{\"error\":\"need address and account\"}")); } char *getaccount(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr) { - struct iguana_waccount *wacct; struct iguana_waddress *waddr; uint8_t addrtype,rmd160[20]; cJSON *retjson; - if ( iguana_addressvalidate(coin,&addrtype,rmd160,coinaddr) < 0 ) + struct iguana_waccount *wacct; struct iguana_waddress *waddr; uint8_t addrtype; cJSON *retjson; + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"wallet must be unlocked to see accounts\"}")); + if ( iguana_addressvalidate(coin,&addrtype,coinaddr) < 0 ) return(clonestr("{\"error\":\"invalid coin address\"}")); - if ( (waddr= iguana_waddresssearch(myinfo,coin,&wacct,coinaddr)) == 0 ) + if ( (waddr= iguana_waddresssearch(myinfo,&wacct,coinaddr)) == 0 ) return(clonestr("{\"result\":\"no account for address\"}")); if ( wacct != 0 ) { - retjson = iguana_waddressjson(0,waddr); + retjson = iguana_waddressjson(coin,0,waddr); jaddstr(retjson,"account",wacct->account); jaddstr(retjson,"result","success"); return(jprint(retjson,1)); @@ -349,6 +421,7 @@ char *getaccount(struct supernet_info *myinfo,struct iguana_info *coin,char *coi char *jsuccess() { cJSON *retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); return(jprint(retjson,1)); } @@ -366,7 +439,7 @@ int32_t iguana_loginsave(struct supernet_info *myinfo,struct iguana_info *coin,c { if ( (passphrase= jstr(loginjson,"passphrase")) != 0 ) { - _SuperNET_encryptjson(destfname,passphrase,0,myinfo->permanentfile,0,loginjson); + _SuperNET_encryptjson(myinfo,destfname,passphrase,0,myinfo->permanentfile,0,loginjson); //printf("loginsave.(%s) <= (%s)\n",destfname,newstr); //iguana_walletlock(myinfo); } @@ -375,9 +448,17 @@ int32_t iguana_loginsave(struct supernet_info *myinfo,struct iguana_info *coin,c } return(-1); } +char *iguana_walletvalue(char *buf,struct iguana_waddress *waddr) +{ + if ( waddr->scriptlen > 0 ) + init_hexbytes_noT(buf,waddr->redeemScript,waddr->scriptlen); + else init_hexbytes_noT(buf,waddr->privkey.bytes,sizeof(waddr->privkey)); + return(buf); +} + int32_t iguana_payloadupdate(struct supernet_info *myinfo,struct iguana_info *coin,char *retstr,struct iguana_waddress *waddr,char *account) { - cJSON *retjson,*accountobj,*payload,*obj; char *newstr; int32_t retval = -1; + cJSON *retjson,*accountobj,*payload; char rmdstr[41],*newstr,*valuestr,valuebuf[IGUANA_MAXSCRIPTSIZE*2+1]; int32_t retval = -1; if ( (retjson= cJSON_Parse(retstr)) != 0 ) { if ( account == 0 || account[0] == 0 ) @@ -385,9 +466,10 @@ int32_t iguana_payloadupdate(struct supernet_info *myinfo,struct iguana_info *co payload = cJSON_DetachItemFromObject(retjson,"wallet"); if ( payload == 0 ) payload = cJSON_CreateObject(); - if ( waddr != 0 ) + if ( waddr != 0 && (valuestr= iguana_walletvalue(valuebuf,waddr)) != 0 ) { - if ( (accountobj= jobj(payload,account)) != 0 && (obj= jobj(accountobj,waddr->coinaddr)) != 0 ) + init_hexbytes_noT(rmdstr,waddr->rmd160,20); + if ( (accountobj= jobj(payload,account)) != 0 && jobj(accountobj,rmdstr) != 0 ) { free_json(retjson); free_json(payload); @@ -396,9 +478,9 @@ int32_t iguana_payloadupdate(struct supernet_info *myinfo,struct iguana_info *co if ( accountobj == 0 ) { accountobj = cJSON_CreateObject(); - jaddbits256(accountobj,waddr->coinaddr,waddr->privkey); jadd(payload,account,accountobj); - } else jaddbits256(accountobj,waddr->coinaddr,waddr->privkey); + } + jaddstr(accountobj,rmdstr,valuestr); } jadd(retjson,"wallet",payload); newstr = jprint(retjson,1); @@ -425,8 +507,8 @@ cJSON *iguana_payloadmerge(cJSON *loginjson,cJSON *importjson) if ( (obj= jobj(retjson,field)) == 0 ) { if ( strlen(field) == 20*2 ) - jaddstr(retjson,field,jstr(item,0)); - else jaddbits256(retjson,field,jbits256(item,0)); + jadd(retjson,field,item); + else jadd(retjson,field,item); } } item = item->next; @@ -437,11 +519,11 @@ cJSON *iguana_payloadmerge(cJSON *loginjson,cJSON *importjson) cJSON *iguana_walletadd(struct supernet_info *myinfo,struct iguana_waddress **waddrp,struct iguana_info *coin,char *retstr,char *account,struct iguana_waddress *refwaddr,int32_t setcurrent,char *redeemScript) { cJSON *retjson=0; struct iguana_waccount *wacct; struct iguana_waddress *waddr; - if ( (wacct= iguana_waccountfind(myinfo,coin,account)) == 0 ) - wacct = iguana_waccountcreate(myinfo,coin,account); + if ( (wacct= iguana_waccountfind(myinfo,account)) == 0 ) + wacct = iguana_waccountcreate(myinfo,account); if ( wacct != 0 ) { - //waddr = iguana_waddressfind(myinfo,coin,wacct,refwaddr->coinaddr); + //waddr = iguana_waddressfind(myinfo,wacct,refwaddr->coinaddr); waddr = iguana_waddressadd(myinfo,coin,wacct,refwaddr,redeemScript); if ( setcurrent != 0 ) wacct->current = waddr; @@ -452,7 +534,7 @@ cJSON *iguana_walletadd(struct supernet_info *myinfo,struct iguana_waddress **wa } else { - retjson = iguana_waddressjson(retjson,waddr); + retjson = iguana_waddressjson(coin,retjson,waddr); jaddstr(retjson,"account",account); jaddstr(retjson,"result","success"); } @@ -464,7 +546,7 @@ cJSON *iguana_walletadd(struct supernet_info *myinfo,struct iguana_waddress **wa cJSON *iguana_walletjson(struct supernet_info *myinfo) { - struct iguana_waccount *wacct,*tmp; struct iguana_waddress *waddr,*tmp2; cJSON *wallet,*account; char scriptstr[4096]; + struct iguana_waccount *wacct,*tmp; struct iguana_waddress *waddr,*tmp2; cJSON *wallet,*account; char valuebuf[IGUANA_MAXSCRIPTSIZE*2+1],rmdstr[128]; wallet = cJSON_CreateObject(); HASH_ITER(hh,myinfo->wallet,wacct,tmp) { @@ -473,25 +555,51 @@ cJSON *iguana_walletjson(struct supernet_info *myinfo) { if ( bits256_nonz(waddr->privkey) == 0 && waddr->scriptlen == 0 ) { - free_json(account); - free_json(wallet); - printf("found a null privkey in wallet, abort saving\n"); - return(0); + //free_json(account); + //free_json(wallet); + //printf("found a null privkey in wallet, abort saving\n"); + //return(0); } - if ( waddr->scriptlen != 0 ) - { - init_hexbytes_noT(scriptstr,waddr->redeemScript,waddr->scriptlen); - jaddstr(account,waddr->coinaddr,scriptstr); - } else jaddbits256(account,waddr->coinaddr,waddr->privkey); + init_hexbytes_noT(rmdstr,waddr->rmd160,sizeof(waddr->rmd160)); + jaddstr(account,rmdstr,iguana_walletvalue(valuebuf,waddr)); } jadd(wallet,wacct->account,account); } return(wallet); } +char *iguana_walletfields(struct iguana_info *coin,int32_t *p2shflagp,char *wifstr,char *address,char *fieldstr,char *valuestr) +{ + uint8_t rmd160[20],addrtype,script[IGUANA_MAXSCRIPTSIZE]; int32_t len; bits256 privkey; + *p2shflagp = 0; + if ( fieldstr != 0 && valuestr != 0 ) + { + len = is_hexstr(fieldstr,0); + if ( len > 0 ) + { + if ( len == 20*2 ) + decode_hex(rmd160,sizeof(rmd160),fieldstr); + else + { + len >>= 1; + decode_hex(script,len,valuestr); + calc_rmd160_sha256(rmd160,script,len); + bitcoin_address(address,coin->chain->p2shtype,rmd160,20); + *p2shflagp = 1; + return(valuestr); + } + } else bitcoin_addr2rmd160(&addrtype,rmd160,fieldstr); + privkey = bits256_conv(valuestr); + bitcoin_priv2wif(wifstr,privkey,coin->chain->wiftype); + bitcoin_address(address,coin->chain->pubtype,rmd160,20); + return(wifstr); + } + return(0); +} + int32_t iguana_walletemit(struct supernet_info *myinfo,char *fname,struct iguana_info *coin,cJSON *array) { - cJSON *item,*child; uint8_t addrtype,wiftype,rmd160[20]; char p2shaddr[128],str[64],wifstr[128],*account,*coinaddr,*privkeystr; int32_t i,j,n; FILE *fp; bits256 privkey; + cJSON *item,*child; char str[64],wifstr[128],*account,coinaddr[64],*privstr; int32_t i,n,p2shflag; FILE *fp; if ( (fp= fopen(fname,"wb")) == 0 ) return(-1); n = cJSON_GetArraySize(array); @@ -503,34 +611,8 @@ int32_t iguana_walletemit(struct supernet_info *myinfo,char *fname,struct iguana child = item->child; while ( child != 0 ) { - coinaddr = child->string; - privkeystr = child->valuestring; - if ( coinaddr != 0 && privkeystr != 0 ) - { - bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr); - wiftype = 188; - for (j=0; jchain != 0 ) - { - if ( addrtype == coin->chain->pubtype ) - { - wiftype = coin->chain->wiftype; - privkey = bits256_conv(privkeystr); - if ( bits256_nonz(privkey) != 0 && bitcoin_priv2wif(wifstr,privkey,wiftype) > 0 ) - { - fprintf(fp,"%s %s %32s=%d # addr=%s\n",wifstr,utc_str(str,(uint32_t)time(NULL)),account,i+1,coinaddr); - } - break; - } - else if ( addrtype == coin->chain->p2shtype ) - { - fprintf(fp,"%s %s %32s=%d # addr=%s # p2sh\n",privkeystr,utc_str(str,(uint32_t)time(NULL)),account,i+1,p2shaddr); - break; - } - } - } - } + if ( (privstr= iguana_walletfields(coin,&p2shflag,wifstr,coinaddr,child->string,child->valuestring)) != 0 ) + fprintf(fp,"%s %s %32s=%d # addr=%s\n",privstr,utc_str(str,(uint32_t)time(NULL)),account,i+1,coinaddr); child = child->next; } //printf("account.(%s)\n",account); @@ -542,16 +624,17 @@ int32_t iguana_walletemit(struct supernet_info *myinfo,char *fname,struct iguana } char *walleterrstr[] = { "P2SH_withpriv", "P2SH_withpub", "rmd160_mismatch", "pubkey_mismatch", "missing_pubkey", "account_mismatch" }; + uint8_t iguana_waddrvalidate(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waccount *wacct,struct iguana_waddress *waddr,int32_t repairflag,int32_t *errors) { - struct iguana_waccount *checkwacct; struct iguana_waddress *checkwaddr; uint8_t checkpub[33],rmd160[20],addrtype,checktype,plen,flag=0; + struct iguana_waccount *checkwacct; struct iguana_waddress *checkwaddr; uint8_t checkpub[33],rmd160[20],addrtype,checktype,plen,flag=0; int32_t i; if ( waddr != 0 ) { - if ( (checkwaddr= iguana_waddresssearch(myinfo,coin,&checkwacct,waddr->coinaddr)) != waddr || checkwacct != wacct ) + if ( (checkwaddr= iguana_waddresssearch(myinfo,&checkwacct,waddr->coinaddr)) != waddr || checkwacct != wacct ) { - errors[5]++; - flag |= (5 << 0); - if ( repairflag > 0 ) + //errors[5]++; + //flag |= (5 << 0); + //if ( repairflag > 0 ) { printf("waddrvalidate: need to manually setaccount to fix mismatch (%s:%s) <- (%s:%s)\n",checkwacct != 0 ? checkwacct->account : "",checkwaddr != 0 ? checkwaddr->coinaddr : "",wacct != 0 ? wacct->account : "",waddr->coinaddr); } @@ -564,14 +647,20 @@ uint8_t iguana_waddrvalidate(struct supernet_info *myinfo,struct iguana_info *co errors[0]++; flag |= (1 << 0); if ( repairflag > 0 ) + { + myinfo->dirty = (uint32_t)time(NULL); memset(&waddr->privkey,0,sizeof(waddr->privkey)); + } } if ( bitcoin_pubkeylen(waddr->pubkey) > 0 ) { errors[1]++; flag |= (1 << 1); if ( repairflag > 0 ) + { + myinfo->dirty = (uint32_t)time(NULL); memset(waddr->pubkey,0,sizeof(waddr->pubkey)); + } } } else checktype = coin->chain->pubtype; @@ -581,6 +670,7 @@ uint8_t iguana_waddrvalidate(struct supernet_info *myinfo,struct iguana_info *co flag |= (1 << 2); if ( repairflag > 0 ) { + myinfo->dirty = (uint32_t)time(NULL); waddr->addrtype = checktype; memcpy(waddr->rmd160,rmd160,sizeof(rmd160)); } @@ -595,7 +685,10 @@ uint8_t iguana_waddrvalidate(struct supernet_info *myinfo,struct iguana_info *co errors[3]++; flag |= (1 << 3); if ( repairflag > 0 ) + { + myinfo->dirty = (uint32_t)time(NULL); memcpy(waddr->pubkey,checkpub,sizeof(checkpub)); + } } } if ( (plen= bitcoin_pubkeylen(waddr->pubkey)) > 0 ) @@ -603,11 +696,23 @@ uint8_t iguana_waddrvalidate(struct supernet_info *myinfo,struct iguana_info *co calc_rmd160_sha256(rmd160,waddr->pubkey,plen); if ( memcmp(rmd160,waddr->rmd160,sizeof(rmd160)) != 0 ) { - errors[4]++; - flag |= (1 << 4); - if ( repairflag > 0 ) + for (i=0; i<20; i++) + if ( waddr->rmd160[i] != 0 ) + break; + if ( i != 20 ) { - printf("waddrvalidate unrecoverable error: cant determine pubkey from rmd160\n"); + errors[4]++; + flag |= (1 << 4); + if ( repairflag > 0 ) + { + printf("waddrvalidate unrecoverable error: cant determine pubkey from rmd160\n"); + } + } + else + { + memcpy(waddr->rmd160,rmd160,20); + bitcoin_address(waddr->coinaddr,coin->chain->pubtype,rmd160,sizeof(rmd160)); + myinfo->dirty = (uint32_t)time(NULL); } } } @@ -618,9 +723,13 @@ uint8_t iguana_waddrvalidate(struct supernet_info *myinfo,struct iguana_info *co cJSON *iguana_walletiterate(struct supernet_info *myinfo,struct iguana_info *coin,int32_t flag,cJSON *array,int32_t *goodp,int32_t *badp,int32_t *errors) { - struct iguana_waccount *wacct,*tmp; struct iguana_waddress *waddr=0,*tmp2; uint8_t errorflags; int32_t i,good=0,bad=0,_errors[8]; cJSON *item; + struct iguana_waccount *wacct,*tmp,*checkwacct; struct iguana_waddress *checkwaddr,*waddr=0,*tmp2; uint8_t persistent_rmd160[20],errorflags; int32_t i,persistent_flag=0,good=0,bad=0,_errors[8]; cJSON *item; char coinaddr[64],*retstr; if ( errors == 0 ) errors = _errors; + if ( myinfo->expiration != 0 ) + calc_rmd160_sha256(persistent_rmd160,myinfo->persistent_pubkey33,33); + else memset(persistent_rmd160,0,sizeof(persistent_rmd160)); + portable_mutex_lock(&myinfo->bu_mutex); HASH_ITER(hh,myinfo->wallet,wacct,tmp) { HASH_ITER(hh,wacct->waddr,waddr,tmp2) @@ -638,7 +747,7 @@ cJSON *iguana_walletiterate(struct supernet_info *myinfo,struct iguana_info *coi HASH_DELETE(hh,wacct->waddr,waddr); if ( waddr->unspents != 0 ) free(waddr->unspents); - printf("%p free %s\n",waddr,waddr->coinaddr); + //printf("walletiterate: %p free %s\n",waddr,waddr->coinaddr); myfree(waddr,sizeof(*waddr) + waddr->scriptlen); } } @@ -650,22 +759,58 @@ cJSON *iguana_walletiterate(struct supernet_info *myinfo,struct iguana_info *coi bad++; if ( array != 0 && (item= cJSON_CreateObject()) != 0 ) { - jaddnum(item,waddr->coinaddr,errorflags); + bitcoin_address(coinaddr,coin->chain->pubtype,waddr->rmd160,20); + jaddnum(item,coinaddr,errorflags); jaddi(array,item); } } else good++; + if ( myinfo->expiration != 0 && persistent_flag == 0 && memcmp(waddr->rmd160,persistent_rmd160,20) == 0 ) + { + persistent_flag = 1; + bitcoin_address(coinaddr,coin->chain->pubtype,waddr->rmd160,20); + printf("FOUND PERSISTENT.%s in %s\n",coinaddr,wacct->account); + } } } if ( flag < -1 ) { HASH_DELETE(hh,myinfo->wallet,wacct); - myfree(wacct,sizeof(*wacct)); + myfree(wacct,(int32_t)(sizeof(*wacct) + strlen(wacct->account) + 1)); + } + } + if ( myinfo->expiration != 0 ) + { + if ( flag >= 0 && persistent_flag == 0 ) + { + bitcoin_address(coinaddr,coin->chain->pubtype,persistent_rmd160,20); + if ( (retstr= setaccount(myinfo,coin,0,"default",coinaddr,0)) != 0 ) + { + free(retstr); + if ( (waddr= iguana_waddresssearch(myinfo,&wacct,coinaddr)) != 0 ) + { + memcpy(waddr->rmd160,persistent_rmd160,20); + memcpy(waddr->pubkey,myinfo->persistent_pubkey33,33); + waddr->privkey = myinfo->persistent_priv; + strcpy(waddr->coinaddr,coinaddr); + if ( (checkwaddr= iguana_waddresssearch(myinfo,&checkwacct,waddr->coinaddr)) != waddr || checkwacct != wacct ) + ; + } + } + printf("persistent address not found in wallet, autoadd.(%s)\n",coinaddr); } + else if ( persistent_flag != 0 ) + printf("found persistent address in wallet\n"); } + portable_mutex_unlock(&myinfo->bu_mutex); if ( goodp != 0 ) *goodp = good; if ( badp != 0 ) *badp = bad; + if ( iguana_waddresssearch(myinfo,&wacct,myinfo->myaddr.BTCD) != 0 ) + { + printf("found persistent address.(%s)\n",myinfo->myaddr.BTCD); + } + return(array); } @@ -689,9 +834,10 @@ char *iguana_walletscan(struct supernet_info *myinfo,struct iguana_info *coin,in void iguana_walletinitcheck(struct supernet_info *myinfo,struct iguana_info *coin) { // "wallet":{"test":{"R9S7zZzzvgb4CkiBH1i7gnFcwJuL1MYbxN":"18ab9c89ce83929db720cf26b663bf762532276146cd9d3e1f89086fcdf00053"}} - cJSON *payload,*item,*array,*child; char *account,*coinaddr,*privkeystr; int32_t i,j,n,len; struct iguana_waccount *wacct,*tmp; struct iguana_waddress waddr; bits256 privkey; uint8_t addrtype,rmd160[20]; + cJSON *payload,*item,*array,*child; char *account,coinaddr[128],*privstr,wifstr[128]; int32_t i,p2shflag,n; struct iguana_waccount *wacct; struct iguana_waddress waddr; bits256 privkey; if ( myinfo->wallet == 0 && myinfo->decryptstr != 0 && (payload= cJSON_Parse(myinfo->decryptstr)) != 0 ) { + //printf("WALLET.(%s)\n",myinfo->decryptstr); if ( (array= jobj(payload,"wallet")) != 0 ) { n = cJSON_GetArraySize(array); @@ -704,58 +850,57 @@ void iguana_walletinitcheck(struct supernet_info *myinfo,struct iguana_info *coi child = item->child; while ( child != 0 ) { - coinaddr = child->string; - privkeystr = child->valuestring; - if ( coinaddr != 0 && privkeystr != 0 ) + if ( (wacct= iguana_waccountcreate(myinfo,account)) != 0 ) { - if ( (wacct= iguana_waccountcreate(myinfo,coin,account)) != 0 ) + if ( (privstr= iguana_walletfields(coin,&p2shflag,wifstr,coinaddr,child->string,child->valuestring)) != 0 ) { - if ( iguana_waddresssearch(myinfo,coin,&tmp,coinaddr) == 0 ) + memset(&waddr,0,sizeof(waddr)); + strcpy(waddr.coinaddr,coinaddr); + if ( p2shflag != 0 ) + iguana_waddressadd(myinfo,coin,wacct,&waddr,child->valuestring); + else { - memset(&waddr,0,sizeof(waddr)); - strcpy(waddr.coinaddr,coinaddr); - waddr.addrtype = coin->chain->p2shtype; - if ( bitcoin_addr2rmd160(&addrtype,rmd160,coinaddr) == sizeof(rmd160) && addrtype == coin->chain->p2shtype ) - iguana_waddressadd(myinfo,coin,wacct,&waddr,privkeystr); - else - { - waddr.addrtype = coin->chain->pubtype; - privkey = bits256_conv(privkeystr); - if ( iguana_waddresscalc(myinfo,coin->chain->pubtype,coin->chain->wiftype,&waddr,privkey) != 0 ) - iguana_waddressadd(myinfo,coin,wacct,&waddr,0); - } - } else printf("dup.(%s) ",coinaddr); - len = (int32_t)strlen(privkeystr); - for (j=0; jvaluestring); + if ( iguana_waddresscalc(myinfo,coin->chain->pubtype,coin->chain->wiftype,&waddr,privkey) != 0 ) + iguana_waddressadd(myinfo,coin,wacct,&waddr,0); + else printf("walletinitcheck: error waddresscalc\n"); + } } } child = child->next; } - printf("account.(%s)\n",account); + //printf("account.(%s)\n",account); } item = item->next; } } free_json(payload); - myinfo->decryptstr = 0; scrubfree(myinfo->decryptstr); + myinfo->decryptstr = 0; myinfo->dirty = 0; } + printf("call walletiterate from initcheck.%p\n",myinfo->decryptstr); iguana_walletiterate(myinfo,coin,1,0,0,0,0); } void iguana_walletlock(struct supernet_info *myinfo,struct iguana_info *coin) { + if ( coin != 0 ) + memset(coin->changeaddr,0,sizeof(coin->changeaddr)); memset(&myinfo->persistent_priv,0,sizeof(myinfo->persistent_priv)); + memset(&myinfo->persistent_pubkey33,0,sizeof(myinfo->persistent_pubkey33)); memset(myinfo->secret,0,sizeof(myinfo->secret)); memset(myinfo->permanentfile,0,sizeof(myinfo->permanentfile)); if ( myinfo->decryptstr != 0 ) scrubfree(myinfo->decryptstr), myinfo->decryptstr = 0; + memset(myinfo->handle,0,sizeof(myinfo->handle)); + memset(myinfo->myaddr.NXTADDR,0,sizeof(myinfo->myaddr.NXTADDR)); + myinfo->myaddr.nxt64bits = 0; myinfo->expiration = 0; + portable_mutex_lock(&myinfo->bu_mutex); + if ( myinfo->spends != 0 ) + free(myinfo->spends), myinfo->numspends = 0; + portable_mutex_unlock(&myinfo->bu_mutex); iguana_walletiterate(myinfo,coin,-2,0,0,0,0); } @@ -764,34 +909,86 @@ int64_t iguana_waccountbalance(struct supernet_info *myinfo,struct iguana_info * int64_t balance; int32_t numrmds=0,numunspents = 0; uint8_t *rmdarray=0; if ( minconf == 0 ) minconf = 1; - rmdarray = iguana_rmdarray(coin,&numrmds,getaddressesbyaccount(myinfo,coin,wacct->account),0); - balance = iguana_unspents(myinfo,coin,0,minconf,(1 << 30),rmdarray,numrmds,lastheight,0,&numunspents); + rmdarray = iguana_rmdarray(myinfo,coin,&numrmds,iguana_getaddressesbyaccount(myinfo,coin,wacct->account),0); + balance = iguana_RTunspents(myinfo,coin,0,minconf,(1 << 30),rmdarray,numrmds,lastheight,0,&numunspents,0,0); if ( rmdarray != 0 ) free(rmdarray); return(balance); } +int64_t oldiguana_waccountbalance(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waccount *wacct,int32_t minconf,int32_t lastheight) +{ + int64_t balance=0; int32_t i,n; cJSON *addrs=0; + if ( minconf == 0 ) + minconf = 1; + if ( (addrs= iguana_getaddressesbyaccount(myinfo,coin,wacct->account)) != 0 ) + { + if ( (n= cJSON_GetArraySize(addrs)) > 0 ) + { + for (i=0; i 0 ) + { + addresses = calloc(numinputs,64); + for (i=n=0; iwifstr); + } + free(addresses); + } + return(privkeys); +} + #include "../includes/iguana_apidefs.h" #include "../includes/iguana_apideclares.h" -int64_t iguana_addressreceived(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *json,char *remoteaddr,cJSON *txids,cJSON *vouts,char *coinaddr,int32_t minconf) +int64_t iguana_addressreceived(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *json,char *remoteaddr,cJSON *txids,cJSON *vouts,cJSON *unspents,cJSON *spends,char *coinaddr,int32_t minconf,int32_t firstheight) { int64_t balance = 0; cJSON *unspentsjson,*balancejson,*item; int32_t i,n; char *balancestr; if ( (balancestr= iguana_balance(IGUANA_CALLARGS,coin->symbol,coinaddr,-1,minconf)) != 0 ) { - printf("balancestr.(%s) (%s)\n",balancestr,coinaddr); + //printf("balancestr.(%s) (%s)\n",balancestr,coinaddr); if ( (balancejson= cJSON_Parse(balancestr)) != 0 ) { balance = jdouble(balancejson,"balance") * SATOSHIDEN; - if ( (txids != 0 || vouts != 0) && (unspentsjson= jarray(&n,balancejson,"unspents")) != 0 ) + if ( (txids != 0 || vouts != 0 || unspents != 0 || spends != 0) && (unspentsjson= jarray(&n,balancejson,"unspents")) != 0 ) { for (i=0; i= firstheight ) + { + if ( txids != 0 ) + jaddibits256(txids,jbits256(item,"txid")); + if ( vouts != 0 ) + jaddinum(vouts,jint(item,"vout")); + if ( unspents != 0 && jobj(item,"unspent") != 0 ) + jaddi(unspents,jduplicate(item)); + if ( spends != 0 && jobj(item,"spent") != 0 ) + jaddi(spends,jduplicate(item)); + } } } free_json(balancejson); @@ -801,7 +998,6 @@ int64_t iguana_addressreceived(struct supernet_info *myinfo,struct iguana_info * return(balance); } - char *getnewaddress(struct supernet_info *myinfo,struct iguana_waddress **waddrp,struct iguana_info *coin,char *account,char *retstr) { struct iguana_waddress addr; cJSON *retjson; @@ -814,17 +1010,18 @@ char *getnewaddress(struct supernet_info *myinfo,struct iguana_waddress **waddrp if ( iguana_waddresscalc(myinfo,coin->chain->pubtype,coin->chain->wiftype,&addr,bitcoin_randkey(myinfo->ctx)) != 0 ) retjson = iguana_walletadd(myinfo,waddrp,coin,retstr,account,&addr,1,0); else return(clonestr("{\"error\":\"couldnt calculate waddr\"}")); - } else return(clonestr("{\"error\":\"no wallet data\"}")); + } else return(clonestr("{\"error\":\"no wallet data, did you remember to do encryptwallet onetime?\"}")); return(jprint(retjson,1)); } STRING_ARG(bitcoinrpc,validateaddress,address) { - cJSON *retjson; int32_t i; uint8_t addrtype,rmd160[20],pubkey[65]; struct iguana_info *other; char str[256]; + cJSON *retjson; uint8_t addrtype,rmd160[20],pubkey[65]; char coinaddr[64],str[256]; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); - if ( iguana_addressvalidate(coin,&addrtype,rmd160,address) < 0 ) + if ( iguana_addressvalidate(coin,&addrtype,address) < 0 ) return(clonestr("{\"error\":\"invalid coin address\"}")); + bitcoin_addr2rmd160(&addrtype,rmd160,address); retjson = cJSON_CreateObject(); jaddstr(retjson,"result","success"); jaddnum(retjson,"addrtype",addrtype); @@ -834,21 +1031,23 @@ STRING_ARG(bitcoinrpc,validateaddress,address) strcat(str,"88ac"); jaddstr(retjson,"scriptPubKey",str); jadd(retjson,"isscript",(addrtype == coin->chain->p2shtype) ? jtrue() : jfalse()); - if ( iguana_ismine(myinfo,coin,addrtype,pubkey,rmd160) > 0 ) + if ( iguana_ismine(myinfo,coin,coinaddr,addrtype,pubkey,rmd160) > 0 ) { init_hexbytes_noT(str,pubkey,bitcoin_pubkeylen(pubkey)); jaddstr(retjson,"pubkey",str); cJSON_AddTrueToObject(retjson,"ismine"); - } - else cJSON_AddFalseToObject(retjson,"ismine"); - for (i=0; isymbol,coinaddr); + //portable_mutex_lock(&myinfo->allcoins_mutex); + /*HASH_ITER(hh,myinfo->allcoins,other,tmp) { - if ( (other= Coins[i]) != 0 && strcmp(other->symbol,coin->symbol) != 0 ) + if ( strcmp(other->symbol,coin->symbol) != 0 ) { iguana_addressconv(coin,str,other,addrtype == coin->chain->p2shtype,rmd160); jaddstr(retjson,other->symbol,str); } - } + }*/ + //portable_mutex_unlock(&myinfo->allcoins_mutex); return(jprint(retjson,1)); } @@ -863,10 +1062,21 @@ ZERO_ARGS(bitcoinrpc,getinfo) jaddstr(retjson,"result","success"); jaddnum(retjson,"protocolversion",PROTOCOL_VERSION); jaddnum(retjson,"kbfee",dstr(coin->txfee_perkb)); + jaddnum(retjson,"txfee",dstr(coin->txfee)); + if ( coin->bundlescount > 1 ) + { + jaddnum(retjson,"bundles",100. * (double)iguana_emitfinished(coin,0)/(coin->bundlescount-1)); + jaddnum(retjson,"utxo",100. * (double)iguana_utxofinished(coin)/(coin->bundlescount-1)); + jaddnum(retjson,"balances",100. * (double)iguana_balancefinished(coin)/(coin->bundlescount-1)); + jaddnum(retjson,"validated",100. * (double)iguana_validated(coin)/(coin->bundlescount-1)); + } + jaddnum(retjson,"firstRTheight",coin->firstRTheight); + jaddnum(retjson,"RTheight",coin->RTheight); jaddnum(retjson,"blocks",coin->blocks.hwmchain.height); jaddnum(retjson,"longestchain",coin->longestchain); jaddnum(retjson,"port",coin->chain->portp2p); - jaddnum(retjson,"connections",coin->peers.numranked); + if ( coin->peers != 0 ) + jaddnum(retjson,"connections",coin->peers->numranked); jaddnum(retjson,"difficulty",coin->blocks.hwmchain.PoW); jaddstr(retjson,"status",coin->statusstr); jaddstr(retjson,"coin",coin->symbol); @@ -899,7 +1109,7 @@ STRING_ARG(bitcoinrpc,getnewaddress,account) if ( myinfo->expiration == 0 ) return(clonestr("{\"error\":\"need to unlock wallet\"}")); myinfo->expiration++; - if ( (retstr= SuperNET_login(IGUANA_CALLARGS,myinfo->handle,myinfo->secret,myinfo->permanentfile,0)) != 0 ) + if ( (retstr= SuperNET_login(IGUANA_CALLARGS,myinfo->handle,myinfo->secret,myinfo->permanentfile,myinfo->password)) != 0 ) { free(retstr); retstr = myinfo->decryptstr, myinfo->decryptstr = 0; @@ -911,9 +1121,38 @@ STRING_ARG(bitcoinrpc,getnewaddress,account) else return(clonestr("{\"error\":\"no wallet payload\"}")); } +struct iguana_waddress *iguana_getaccountaddress(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *json,char *remoteaddr,char *coinaddr,char *account) +{ + char *newstr,*retstr; struct iguana_waccount *wacct; struct iguana_waddress *waddr=0; + coinaddr[0] = 0; + if ( (wacct= iguana_waccountfind(myinfo,account)) == 0 ) + wacct = iguana_waccountcreate(myinfo,account); + if ( wacct != 0 ) + { + if ( (waddr= wacct->current) == 0 || waddr->numunspents > 0 ) + { + if ( (retstr= SuperNET_login(IGUANA_CALLARGS,myinfo->handle,myinfo->secret,myinfo->permanentfile,myinfo->password)) != 0 ) + { + free(retstr); + retstr = myinfo->decryptstr, myinfo->decryptstr = 0; + newstr = getnewaddress(myinfo,&waddr,coin,account,retstr); + if ( retstr != 0 ) + scrubfree(retstr); + retstr = newstr; + } else return(0); + } + } + if ( waddr != 0 ) + { + bitcoin_address(coinaddr,coin->chain->pubtype,waddr->rmd160,20); + return(waddr); + } + return(0); +} + STRING_ARG(bitcoinrpc,getaccountaddress,account) { - char *retstr,*newstr; struct iguana_waccount *wacct; struct iguana_waddress *waddr=0; cJSON *retjson; + char coinaddr[64]; struct iguana_waddress *waddr=0; cJSON *retjson; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); if ( myinfo->expiration == 0 ) @@ -921,30 +1160,12 @@ STRING_ARG(bitcoinrpc,getaccountaddress,account) myinfo->expiration++; if ( account != 0 && account[0] != 0 ) { - if ( (wacct= iguana_waccountfind(myinfo,coin,account)) == 0 ) - wacct = iguana_waccountcreate(myinfo,coin,account); - if ( wacct != 0 ) - { - if ( (waddr= wacct->current) == 0 ) - { - if ( (retstr= SuperNET_login(IGUANA_CALLARGS,myinfo->handle,myinfo->secret,myinfo->permanentfile,0)) != 0 ) - { - free(retstr); - retstr = myinfo->decryptstr, myinfo->decryptstr = 0; - printf("loginstr.(%s)\n",retstr); - newstr = getnewaddress(myinfo,&waddr,coin,account,retstr); - if ( retstr != 0 ) - scrubfree(retstr); - retstr = newstr; - } else return(clonestr("{\"error\":\"no wallet payload\"}")); - } - if ( waddr != 0 ) - retjson = iguana_waddressjson(0,waddr); - else return(clonestr("{\"error\":\"couldnt create address\"}")); - jaddstr(retjson,"account",account); - jaddstr(retjson,"result","success"); - return(jprint(retjson,1)); - } else return(clonestr("{\"error\":\"cant find account\"}")); + if ( (waddr= iguana_getaccountaddress(myinfo,coin,json,remoteaddr,coinaddr,account)) != 0 ) + retjson = iguana_waddressjson(coin,0,waddr); + else return(clonestr("{\"error\":\"couldnt create address\"}")); + jaddstr(retjson,"account",account); + jaddstr(retjson,"result","success"); + return(jprint(retjson,1)); } return(clonestr("{\"error\":\"no account specified\"}")); } @@ -964,9 +1185,17 @@ TWOSTRINGS_AND_INT(bitcoinrpc,walletpassphrase,password,permanentfile,timeout) return(clonestr("{\"error\":\"no remote\"}")); if ( timeout <= 0 ) return(clonestr("{\"error\":\"timeout must be positive\"}")); + iguana_walletlock(myinfo,coin); + printf("timeout.%d\n",timeout); + myinfo->expiration = (uint32_t)time(NULL) + timeout; + strcpy(myinfo->secret,password); + strcpy(myinfo->password,password); + if ( permanentfile != 0 ) + strcpy(myinfo->permanentfile,permanentfile); + retstr = SuperNET_login(IGUANA_CALLARGS,myinfo->handle,myinfo->secret,myinfo->permanentfile,myinfo->password); myinfo->expiration = (uint32_t)time(NULL) + timeout; - retstr = SuperNET_login(IGUANA_CALLARGS,myinfo->handle,password,permanentfile,0); iguana_walletinitcheck(myinfo,coin); + //basilisk_unspents_update(myinfo,coin); return(retstr); } @@ -975,10 +1204,26 @@ THREE_STRINGS(bitcoinrpc,encryptwallet,passphrase,password,permanentfile) char *retstr; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); + iguana_walletlock(myinfo,coin); if ( password == 0 || password[0] == 0 ) password = passphrase; - retstr = SuperNET_login(IGUANA_CALLARGS,myinfo->handle,password,permanentfile,passphrase); - //iguana_walletlock(myinfo); + if ( passphrase == 0 || passphrase[0] == 0 ) + passphrase = password; + strcpy(myinfo->secret,passphrase); + strcpy(myinfo->password,password); + if ( permanentfile != 0 ) + strcpy(myinfo->permanentfile,permanentfile); + retstr = SuperNET_login(IGUANA_CALLARGS,myinfo->handle,myinfo->secret,myinfo->permanentfile,myinfo->password); + myinfo->expiration = (uint32_t)time(NULL) + 3600*24; + struct iguana_waddress waddr; struct iguana_waccount *wacct; + if ( (wacct= iguana_waccountcreate(myinfo,"default")) != 0 ) + { + if ( iguana_waddresscalc(myinfo,coin->chain->pubtype,coin->chain->wiftype,&waddr,myinfo->persistent_priv) != 0 ) + iguana_waddressadd(myinfo,coin,wacct,&waddr,0); + else printf("couldnt waddresscalc persistent\n"); + } else printf("coildnt create default account\n"); + iguana_walletinitcheck(myinfo,coin); + myinfo->dirty = (uint32_t)time(NULL); return(retstr); } @@ -987,21 +1232,22 @@ FOUR_STRINGS(bitcoinrpc,walletpassphrasechange,oldpassword,newpassword,oldperman char destfname[1024],*tmpstr,*loginstr,*passphrase,*retstr = 0; cJSON *tmpjson,*loginjson; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); - if ( (tmpstr= SuperNET_login(IGUANA_CALLARGS,myinfo->handle,oldpassword,oldpermanentfile,0)) != 0 ) + if ( (tmpstr= SuperNET_login(IGUANA_CALLARGS,myinfo->handle,oldpassword,oldpermanentfile,oldpassword)) != 0 ) { free(tmpstr); tmpstr = myinfo->decryptstr, myinfo->decryptstr = 0; if ( (tmpjson= cJSON_Parse(tmpstr)) != 0 ) { - if ( (loginstr= SuperNET_login(IGUANA_CALLARGS,myinfo->handle,newpassword,newpermanentfile,0)) != 0 ) + if ( (loginstr= SuperNET_login(IGUANA_CALLARGS,myinfo->handle,newpassword,newpermanentfile,newpassword)) != 0 ) { if ( myinfo->decryptstr != 0 && (loginjson= cJSON_Parse(myinfo->decryptstr)) != 0 ) { if ( (passphrase= jstr(loginjson,"passphrase")) != 0 ) { - _SuperNET_encryptjson(destfname,passphrase,0,newpermanentfile,0,loginjson); + _SuperNET_encryptjson(myinfo,destfname,passphrase,0,newpermanentfile,0,loginjson); //iguana_walletlock(myinfo); - retstr = SuperNET_login(IGUANA_CALLARGS,myinfo->handle,newpassword,newpermanentfile,0); + retstr = SuperNET_login(IGUANA_CALLARGS,myinfo->handle,newpassword,newpermanentfile,newpassword); + myinfo->dirty = (uint32_t)time(NULL); } free_json(loginjson); } @@ -1013,7 +1259,7 @@ FOUR_STRINGS(bitcoinrpc,walletpassphrasechange,oldpassword,newpassword,oldperman scrubfree(tmpstr); } if ( retstr == 0 ) - retstr = clonestr("{\"error\":\"error changing walletpassphrase\"}"); + retstr = clonestr("{\"error\":\"need to call walletpassphrasechange again\"}"); return(retstr); } @@ -1028,6 +1274,7 @@ TWOSTRINGS_AND_INT(bitcoinrpc,importprivkey,wif,account,rescan) if ( account == 0 || account[0] == 0 ) account = "default"; len = (int32_t)strlen(wif); + memset(debugtxid.bytes,0,sizeof(debugtxid)); if ( is_hexstr(wif,len) > 0 ) { len >>= 1; @@ -1046,7 +1293,7 @@ TWOSTRINGS_AND_INT(bitcoinrpc,importprivkey,wif,account,rescan) memset(&addr,0,sizeof(addr)); if ( iguana_waddresscalc(myinfo,coin->chain->pubtype,coin->chain->wiftype,&addr,privkey) != 0 ) { - if ( (waddr= iguana_waddresssearch(myinfo,coin,&wacct,addr.coinaddr)) != 0 ) + if ( (waddr= iguana_waddresssearch(myinfo,&wacct,addr.coinaddr)) != 0 ) { waddr = iguana_waccountswitch(myinfo,coin,account,addr.coinaddr,0); return(clonestr("{\"result\":\"privkey already in wallet\"}")); @@ -1054,25 +1301,26 @@ TWOSTRINGS_AND_INT(bitcoinrpc,importprivkey,wif,account,rescan) if ( myinfo->expiration == 0 ) return(clonestr("{\"error\":\"need to unlock wallet\"}")); myinfo->expiration++; - if ( (retstr= SuperNET_login(IGUANA_CALLARGS,myinfo->handle,myinfo->secret,myinfo->permanentfile,0)) != 0 ) + if ( (retstr= SuperNET_login(IGUANA_CALLARGS,myinfo->handle,myinfo->secret,myinfo->permanentfile,myinfo->password)) != 0 ) { free(retstr); retstr = myinfo->decryptstr, myinfo->decryptstr = 0; if ( waddr == 0 ) waddr = &addr; iguana_waddresscalc(myinfo,coin->chain->pubtype,coin->chain->wiftype,waddr,privkey); + iguana_waccountswitch(myinfo,coin,account,waddr->coinaddr,0); retjson = iguana_walletadd(myinfo,0,coin,retstr,account,waddr,0,0); if ( retstr != 0 ) scrubfree(retstr); return(jprint(retjson,1)); - } + } else printf("null return from SuperNET_login\n"); } return(clonestr("{\"error\":\"cant calculate waddress\"}")); } STRING_ARG(bitcoinrpc,dumpprivkey,address) { - cJSON *retjson; int32_t len,p2shflag=0; struct iguana_waddress *waddr; struct iguana_waccount *wacct; uint8_t addrtype,type,redeemScript[IGUANA_MAXSCRIPTSIZE],rmd160[20]; char *coinaddr; struct vin_info V; bits256 debugtxid; + cJSON *retjson; int32_t len,p2shflag=0; struct iguana_waddress *waddr; struct iguana_waccount *wacct; uint8_t addrtype,type,redeemScript[IGUANA_MAXSCRIPTSIZE]; char *coinaddr; struct vin_info V; bits256 debugtxid; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); if ( myinfo->expiration == 0 ) @@ -1080,6 +1328,7 @@ STRING_ARG(bitcoinrpc,dumpprivkey,address) myinfo->expiration++; len = (int32_t)strlen(address); coinaddr = address; + memset(debugtxid.bytes,0,sizeof(debugtxid)); if ( is_hexstr(address,len) > 0 ) { len >>= 1; @@ -1090,9 +1339,9 @@ STRING_ARG(bitcoinrpc,dumpprivkey,address) coinaddr = V.coinaddr; } } - if ( strlen(coinaddr) > sizeof(V.coinaddr) || iguana_addressvalidate(coin,&addrtype,rmd160,coinaddr) < 0 ) + if ( strlen(coinaddr) > sizeof(V.coinaddr) || iguana_addressvalidate(coin,&addrtype,coinaddr) < 0 ) return(clonestr(p2shflag == 0 ? "{\"error\":\"invalid address\"}" : "{\"error\":\"invalid P2SH address\"}")); - if ( (waddr= iguana_waddresssearch(myinfo,coin,&wacct,coinaddr)) != 0 ) + if ( (waddr= iguana_waddresssearch(myinfo,&wacct,coinaddr)) != 0 ) { if ( (waddr->wifstr[0] != 0 || waddr->scriptlen > 0) ) { @@ -1110,10 +1359,12 @@ STRING_ARG(bitcoinrpc,dumpwallet,filename) char *retstr,*walletstr; cJSON *retjson,*walletobj,*strobj; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); if ( myinfo->expiration != 0 ) { myinfo->expiration++; - if ( (retstr= SuperNET_login(IGUANA_CALLARGS,myinfo->handle,myinfo->secret,myinfo->permanentfile,0)) != 0 ) + if ( (retstr= SuperNET_login(IGUANA_CALLARGS,myinfo->handle,myinfo->secret,myinfo->permanentfile,myinfo->password)) != 0 ) { if ( (retjson= cJSON_Parse(retstr)) != 0 ) { @@ -1142,20 +1393,25 @@ STRING_ARG(bitcoinrpc,backupwallet,filename) char *loginstr,*retstr = 0; cJSON *retjson,*payload; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); if ( myinfo->expiration != 0 ) { myinfo->expiration++; - if ( (loginstr= SuperNET_login(IGUANA_CALLARGS,myinfo->handle,myinfo->secret,myinfo->permanentfile,0)) != 0 ) + if ( (loginstr= SuperNET_login(IGUANA_CALLARGS,myinfo->handle,myinfo->secret,myinfo->permanentfile,myinfo->password)) != 0 ) { retstr = clonestr("{\"error\":\"couldnt backup wallet\"}"); - free(loginstr); - loginstr = myinfo->decryptstr, myinfo->decryptstr = 0; + if ( myinfo->decryptstr != 0 ) + { + free(loginstr); + loginstr = myinfo->decryptstr, myinfo->decryptstr = 0; + } if ( (retjson= cJSON_Parse(loginstr)) != 0 ) { if ( (payload= jobj(retjson,"wallet")) != 0 && iguana_walletemit(myinfo,filename,coin,payload) == 0 ) retstr = clonestr("{\"result\":\"wallet backup saved\"}"); free_json(retjson); - } + } else printf("couldnt parse.(%s)\n",loginstr); if ( loginstr != 0 ) scrubfree(loginstr); return(retstr); @@ -1168,6 +1424,8 @@ STRING_ARG(bitcoinrpc,importwallet,filename) cJSON *retjson = 0,*importjson,*loginjson = 0; long filesize; char *importstr,*loginstr; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); + if ( myinfo->expiration == 0 ) + return(clonestr("{\"error\":\"need to unlock wallet\"}")); if ( myinfo->expiration != 0 ) { myinfo->expiration++; @@ -1175,7 +1433,7 @@ STRING_ARG(bitcoinrpc,importwallet,filename) { if ( (importjson= cJSON_Parse(importstr)) != 0 ) { - if ( (loginstr= SuperNET_login(IGUANA_CALLARGS,myinfo->handle,myinfo->secret,myinfo->permanentfile,0)) != 0 ) + if ( (loginstr= SuperNET_login(IGUANA_CALLARGS,myinfo->handle,myinfo->secret,myinfo->permanentfile,myinfo->password)) != 0 ) { free(loginstr); loginstr = myinfo->decryptstr, myinfo->decryptstr = 0; @@ -1229,13 +1487,13 @@ STRING_AND_THREEINTS(bitcoinrpc,getbalance,account,minconf,includeempty,lastheig if ( myinfo->expiration == 0 ) return(clonestr("{\"error\":\"need to unlock wallet\"}")); if ( account == 0 ) - account = ""; + account = "*"; if ( minconf == 0 ) minconf = 1; - if ( strcmp(account,"*") != 0 ) - rmdarray = iguana_rmdarray(coin,&numrmds,getaddressesbyaccount(myinfo,coin,account),0); + //if ( strcmp(account,"*") != 0 ) + rmdarray = iguana_rmdarray(myinfo,coin,&numrmds,iguana_getaddressesbyaccount(myinfo,coin,account),0); numunspents = 0; - balance = iguana_unspents(myinfo,coin,0,minconf,(1 << 30),rmdarray,numrmds,lastheight,0,&numunspents); + balance = iguana_RTunspents(myinfo,coin,0,minconf,(1 << 30),rmdarray,numrmds,lastheight,0,&numunspents,remoteaddr,0); if ( rmdarray != 0 ) free(rmdarray); retjson = cJSON_CreateObject(); @@ -1251,7 +1509,7 @@ STRING_ARG(bitcoinrpc,getaddressesbyaccount,account) if ( myinfo->expiration == 0 ) return(clonestr("{\"error\":\"need to unlock wallet\"}")); retjson = cJSON_CreateObject(); - jadd(retjson,"result",getaddressesbyaccount(myinfo,coin,account)); + jadd(retjson,"result",iguana_getaddressesbyaccount(myinfo,coin,account)); return(jprint(retjson,1)); } @@ -1263,7 +1521,7 @@ STRING_AND_INT(bitcoinrpc,getreceivedbyaccount,account,minconf) if ( myinfo->expiration == 0 ) return(clonestr("{\"error\":\"need to unlock wallet\"}")); retjson = cJSON_CreateObject(); - if ( (wacct= iguana_waccountfind(myinfo,coin,account)) != 0 ) + if ( (wacct= iguana_waccountfind(myinfo,account)) != 0 ) { balance = iguana_waccountbalance(myinfo,coin,wacct,minconf,0); jaddnum(retjson,"result",dstr(balance)); @@ -1280,9 +1538,9 @@ STRING_AND_THREEINTS(bitcoinrpc,listtransactions,account,count,skip,includewatch return(clonestr("{\"error\":\"need to unlock wallet\"}")); retjson = cJSON_CreateObject(); retarray = cJSON_CreateArray(); - if ( (wacct= iguana_waccountfind(myinfo,coin,account)) != 0 ) + if ( (wacct= iguana_waccountfind(myinfo,account)) != 0 ) { - if ( (array= getaddressesbyaccount(myinfo,coin,account)) != 0 ) + if ( (array= iguana_getaddressesbyaccount(myinfo,coin,account)) != 0 ) { if ( (n= cJSON_GetArraySize(array)) > 0 ) { @@ -1293,7 +1551,7 @@ STRING_AND_THREEINTS(bitcoinrpc,listtransactions,account,count,skip,includewatch { vouts = cJSON_CreateArray(); txids = cJSON_CreateArray(); - iguana_addressreceived(myinfo,coin,0,remoteaddr,txids,vouts,coinaddr,1); + iguana_addressreceived(myinfo,coin,0,remoteaddr,txids,vouts,0,0,coinaddr,1,0); if ( (m= cJSON_GetArraySize(txids)) > 0 ) { for (j=0; jaccount); jaddnum(item,"amount",dstr(balance)); - jaddnum(item,"confirmations",minconf); + //jaddnum(item,"confirmations",coin->blocks.hwmchain.height - wacct->mostrecent); jaddi(array,item); } retjson = cJSON_CreateObject(); @@ -1362,7 +1620,7 @@ THREE_INTS(bitcoinrpc,listreceivedbyaccount,minconf,includeempty,watchonly) THREE_INTS(bitcoinrpc,listreceivedbyaddress,minconf,includeempty,flag) { - cJSON *retjson,*item,*array,*txids,*vouts; struct iguana_waccount *wacct,*tmp; struct iguana_waddress *waddr,*tmp2; + cJSON *retjson,*item,*array,*txids,*vouts; struct iguana_waccount *wacct,*tmp; struct iguana_waddress *waddr,*tmp2; uint8_t addrtype; char coinaddr[64]; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); if ( myinfo->expiration == 0 ) @@ -1373,10 +1631,12 @@ THREE_INTS(bitcoinrpc,listreceivedbyaddress,minconf,includeempty,flag) HASH_ITER(hh,wacct->waddr,waddr,tmp2) { item = cJSON_CreateObject(); - jaddstr(item,"address",waddr->coinaddr); + addrtype = (waddr->scriptlen > 0) ? coin->chain->p2shtype : coin->chain->pubtype; + bitcoin_address(coinaddr,addrtype,waddr->rmd160,20); + jaddstr(item,"address",coinaddr); txids = cJSON_CreateArray(); vouts = cJSON_CreateArray(); - jaddnum(item,"amount",dstr(iguana_addressreceived(myinfo,coin,0,remoteaddr,txids,vouts,waddr->coinaddr,minconf))); + jaddnum(item,"amount",dstr(iguana_addressreceived(myinfo,coin,0,remoteaddr,txids,vouts,0,0,coinaddr,minconf,0))); jadd(item,"txids",txids); jadd(item,"vouts",vouts); jaddi(array,item); @@ -1392,13 +1652,13 @@ STRING_AND_INT(bitcoinrpc,getreceivedbyaddress,address,minconf) char *balancestr; cJSON *balancejson,*retjson = cJSON_CreateObject(); if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); - if ( myinfo->expiration == 0 ) - return(clonestr("{\"error\":\"need to unlock wallet\"}")); + //if ( myinfo->expiration == 0 ) + // return(clonestr("{\"error\":\"need to unlock wallet\"}")); if ( (balancestr= iguana_balance(IGUANA_CALLARGS,coin->symbol,address,-1,minconf)) != 0 ) { if ( (balancejson= cJSON_Parse(balancestr)) != 0 ) { - jaddnum(retjson,"result",dstr(jdouble(balancejson,"balance"))); + jaddnum(retjson,"result",jdouble(balancejson,"balance")); free_json(balancejson); } } diff --git a/iguana/index copy.html b/iguana/index copy.html new file mode 100755 index 000000000..28d3217f1 --- /dev/null +++ b/iguana/index copy.html @@ -0,0 +1,842 @@ + + + + + + + iguana + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + +
+
+
+
+
+
+
+ + + +
+
+
+

Json posting form

+
+ +
+
+
+
+
+
+ +
+
+ + +
+
+
+
+
+
+ +
JSON response
+ +
+
+
+
+

+ List of games + +

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

Coin Management

+
+
+ +
+ + + +
+ + + + + + + + + + + + +
SymbolDescriptionStatusAction
+ + + + +
+
+
+
+
+ +
+
+ + +
+
+
+
+
+
+ +
JSON response
+ +
+
+
+
+
+
+ + + + +
+
+
+
+

+ Peer Management +

+
+
+ + + + +
+ +
+ + + + + + + + + + + + + + +
IP AddressCoin TypeHeightRankBlockFavourite Actions
+
+
+
+
+ +
+
+
+
+

+ Tradebot +

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

Settings

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

+ Encrypt/decrypt JSON +

+
+
+
+
+
+
+ +
+ + +
+
+
+ +
+
+ + +
+
+
+
+ +
+ + +
+
+
+ + +
+ +
+
+
+ +
JSON response
+ + +
encrypted file content
+ + +
+
+ +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + +
+
+
+
+ +
+ +
+ +
+
+ +
+
+ + +
+
+ +
+

Block Explorer tab

+
+
+
+ +
+

Set Active coin

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

InstantDEX

+
+ + + + + + + + + + + + + + +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+
+ + +
+
+ +
+ +
+ + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iguana/index.html b/iguana/index.html index 50efa9c89..864a191e0 100755 --- a/iguana/index.html +++ b/iguana/index.html @@ -1,636 +1,752 @@ - - - - - - - iguana - - - - - - - - - - - - - - - -
- -
- - -
-
-
-
-
-
-
- - - -
-
-
-

Json posting form

-
- -
-
-
-
-
-
- -
-
- - -
-
-
-
-
-
- -
JSON response
- -
-
-
-
-

- List of games - -

-
-
- - - - -
- -
-
-
- -
-
-
-
-
- - - -
-
-
-

Coin Management

-
-
- -
- - - -
- - - - - - - - - - - - -
SymbolDescriptionStatusAction
- - - - -
-
-
-
-
- -
-
- - -
-
-
-
-
-
- -
JSON response
- -
-
-
-
-
-
- - - - -
-
-
-
-

- Peer Management -

-
-
- - - - -
- -
- - - - - - - - - - - - - - -
IP AddressCoin TypeHeightRankBlockFavourite Actions
-
-
-
-
- -
-
-
-
-

- Tradebot -

-
-
- - - - - - - - - - - - - - -
-
- - - - -
- - - -
-
-
-
-
- - -
-
-
-

Settings

-
-
-
-
-
-
-
-
-
- - -
-
-
-
-
- -
-
-
-
-
-
- - -
-
-
-

- Encrypt/decrypt JSON -

-
-
-
-
-
-
- -
- - -
-
-
- -
-
- - -
-
-
-
- -
- - -
-
-
- - -
- -
-
-
- -
JSON response
- - -
encrypted file content
- - -
-
- -
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - -
-
-
-
- -
- -
- -
-
- -
-
- - -
-
- -
-

Block Explorer tab

-
-
-
- -
-

Set Active coin

-
- -
-
-
-
-
- - - -
-
- - - - -
-
-
- -
- - -
-
- -
-

Instandex tab

-
-
- - - - - - - - - - - - - - - - - - - - -
- -
- -
-
-
- - -
-
-
- -
- - -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + iguana + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + +
+
+
+
+
+
+
+ + + +
+
+
+

Json posting form

+
+ +
+
+
+
+
+
+ +
+
+ + +
+
+
+
+
+
+ +
JSON response
+ +
+
+
+
+

+ List of games + +

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

Coin Management

+
+
+ +
+ + + +
+ + + + + + + + + + + + +
SymbolDescriptionStatusAction
+ + + + +
+
+
+
+
+ +
+
+ + +
+
+
+
+
+
+ +
JSON response
+ +
+
+
+
+
+
+ + + + +
+
+
+
+

+ Peer Management +

+
+
+ + + + +
+ +
+ + + + + + + + + + + + + + +
IP AddressCoin TypeHeightRankBlockFavourite Actions
+
+
+
+
+ +
+
+
+
+

+ Tradebot +

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

Settings

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

+ Encrypt/decrypt JSON +

+
+
+
+
+
+
+ +
+ + +
+
+
+ +
+
+ + +
+
+
+
+ +
+ + +
+
+
+ + +
+ +
+
+
+ +
JSON response
+ + +
encrypted file content
+ + +
+
+ +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + +
+
+
+
+ +
+ +
+ +
+
+ +
+
+ + +
+
+ +
+

Block Explorer tab

+
+
+
+ +
+

Set Active coin

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

Choose Which Coins to Exchange

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

InstantDEX

+
+ + + + + + + + + + + + + + +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+
+ + +
+
+ +
+ +
+ + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iguana/js/amcharts/amcharts.js b/iguana/js/amcharts/amcharts.js new file mode 100755 index 000000000..4f31a8408 --- /dev/null +++ b/iguana/js/amcharts/amcharts.js @@ -0,0 +1,391 @@ +(function(){var d;window.AmCharts?d=window.AmCharts:(d={},window.AmCharts=d,d.themes={},d.maps={},d.inheriting={},d.charts=[],d.onReadyArray=[],d.useUTC=!1,d.updateRate=60,d.uid=0,d.lang={},d.translations={},d.mapTranslations={},d.windows={},d.initHandlers=[],d.amString="am",d.pmString="pm");d.Class=function(a){var b=function(){arguments[0]!==d.inheriting&&(this.events={},this.construct.apply(this,arguments))};a.inherits?(b.prototype=new a.inherits(d.inheriting),b.base=a.inherits.prototype,delete a.inherits): +(b.prototype.createEvents=function(){for(var a=0;ad.IEversion&&0b)return a;h=-1;for(a=(k=a.split(/\r\n|\n|\r/)).length;++hb;k[h]+=d.trim(g.slice(0,f))+((g=g.slice(f)).length?c:""))f=2==e||(f=g.slice(0,b+1).match(/\S*(\s)?$/))[1]?b:f.input.length-f[0].length||1==e&&b||f.input.length+(f=g.slice(b).match(/^\S*/))[0].length;g=d.trim(g)}return k.join(c)};d.trim=function(a){return a.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")};d.wrappedText=function(a,b,c,e,h,f,g,k){var l=d.text(a,b,c,e,h,f,g);if(l){var m=l.getBBox();if(m.width>k){var n="\n";d.isModern||(n="
");k=Math.floor(k/(m.width/ +b.length));2c&&(a=c);return a};d.isDefined=function(a){return void 0===a?!1:!0};d.stripNumbers=function(a){return a.replace(/[0-9]+/g,"")};d.roundTo=function(a,b){if(0>b)return a;var c=Math.pow(10,b);return Math.round(a*c)/c};d.toFixed=function(a,b){var c=String(Math.round(a*Math.pow(10,b)));if(0=g[b].contains){var l=a-Math.floor(a/g[b].contains)*g[b].contains;"ss"==b?(l=d.formatNumber(l,f),1==l.split(k)[0].length&&(l="0"+l)):l=d.roundTo(l,f.precision);("mm"==b||"hh"==b)&&10>l&&(l="0"+l);c=l+""+e[b]+""+c;a=Math.floor(a/g[b].contains);b=g[b].nextInterval;return d.formatDuration(a,b,c,e,h,f)}"ss"==b&&(a=d.formatNumber(a, +f),1==a.split(k)[0].length&&(a="0"+a));("mm"==b||"hh"==b)&&10>a&&(a="0"+a);c=a+""+e[b]+""+c;if(g[h].count>g[b].count)for(a=g[b].count;aa?"-":"";a=Math.abs(a);var k=String(a),l=!1;-1!= +k.indexOf("e")&&(l=!0);0<=c&&!l&&(k=d.toFixed(a,c));var m="";if(l)m=k;else{var k=k.split("."),l=String(k[0]),n;for(n=l.length;0<=n;n-=3)m=n!=l.length?0!==n?l.substring(n-3,n)+b+m:l.substring(n-3,n)+m:l.substring(n-3,n);void 0!==k[1]&&(m=m+f+k[1]);void 0!==c&&0=c.x-5&&a<=c.x+c.width+5&&b>=c.y-5&&b<=c.y+c.height+5?!0:!1};d.isPercents=function(a){if(-1!=String(a).indexOf("%"))return!0};d.formatValue=function(a,b,c,e,h,f,g,k){if(b){void 0=== +h&&(h="");var l;for(l=0;la&&(g="-");a=Math.abs(a);if(1=b[k].number&&(l=a/b[k].number,m=Number(e.precision),1>m&&(m=1),c=d.roundTo(l,m),m=d.formatNumber(c,{precision:-1,decimalSeparator:e.decimalSeparator,thousandsSeparator:e.thousandsSeparator}),!h||l==c)){f=g+""+m+""+b[k].prefix;break}}else for(k=0;k"==a&&(a="easeOutSine");"<"==a&&(a="easeInSine");"elastic"==a&&(a="easeOutElastic");return a};d.getObjById=function(a,b){var c,e;for(e=0;e"));return a};d.fixBrakes=function(a){if(d.isModern){var b=RegExp("
","g");a&&(a=a.replace(b,"\n"))}else a=d.fixNewLines(a);return a};d.deleteObject=function(a,b){if(a){if(void 0===b||null===b)b=20;if(0!==b)if("[object Array]"===Object.prototype.toString.call(a))for(var c=0;cb)return e/2*b*b+c;b--;return-e/2*(b*(b-2)-1)+c};d.easeInSine=function(a,b,c,e,d){return-e*Math.cos(b/d*(Math.PI/2))+e+c};d.easeOutSine=function(a,b,c,e,d){return e*Math.sin(b/d*(Math.PI/2))+c};d.easeOutElastic=function(a,b,c,e,d){a=1.70158;var f=0,g=e;if(0=== +b)return c;if(1==(b/=d))return c+e;f||(f=.3*d);gb?Math.abs(b)-1:Math.abs(b);var d;for(d=0;db?Number("0."+c+String(a)):Number(String(a)+c)};d.setCN=function(a,b,c,e){if(a.addClassNames&&b&&(b= +b.node)&&c){var d=b.getAttribute("class");a=a.classNamePrefix+"-";e&&(a="");d?b.setAttribute("class",d+" "+a+c):b.setAttribute("class",a+c)}};d.parseDefs=function(a,b){for(var c in a){var e=typeof a[c];if(0a&&(a=3)):a=this.width/this.minHorizontalGap,this.gridCountR=Math.max(a,1)):this.gridCountR=this.gridCount;this.axisWidth=this.axisLine.axisWidth;this.addTitle()},setOrientation:function(a){this.orientation=a?"H":"V"},addTitle:function(){var a= +this.title;this.titleLabel=null;if(a){var b=this.chart,c=this.titleColor;void 0===c&&(c=b.color);var e=this.titleFontSize;isNaN(e)&&(e=b.fontSize+1);a=d.text(b.container,a,c,b.fontFamily,e,this.titleAlign,this.titleBold);d.setCN(b,a,this.bcn+"title");this.titleLabel=a}},positionTitle:function(){var a=this.titleLabel;if(a){var b,c,e=this.labelsSet,h={};0this.autoRotateCount&&!isNaN(this.autoRotateAngle)&&(this.labelRotationR=this.autoRotateAngle),a=k;a<=B;a++){p=q+z*(a+Math.floor((D-q)/z))-C;"DD"==A&&(p+=36E5);p=d.resetDateToMin(new Date(p),A,u,t).getTime();"MM"==A&&(h=(p-l)/z,1.5<=(p-l)/z&&(p=p-(h-1)*z+d.getPeriodDuration("DD",3),p=d.resetDateToMin(new Date(p), +A,1).getTime(),C+=z));h=(p-this.startTime)*this.stepWidth;if("radar"==b.type){if(h=this.axisWidth-h,0>h||h>this.axisWidth)continue}else this.rotate?"date"==this.type&&"middle"==this.gridPosition&&(J=-z*this.stepWidth/2):"date"==this.type&&(h=this.axisWidth-h);f=!1;this.nextPeriod[g]&&(f=this.checkPeriodChange(this.nextPeriod[g],1,p,l,g));l=!1;f&&this.markPeriodChange?(f=this.dateFormatsObject[this.nextPeriod[g]],this.twoLineMode&&(f=this.dateFormatsObject[g]+"\n"+f,f=d.fixBrakes(f)),l=!0):f=this.dateFormatsObject[g]; +r||(l=!1);this.currentDateFormat=f;f=d.formatDate(new Date(p),f,b);if(a==k&&!c||a==B&&!e)f=" ";this.labelFunction&&(f=this.labelFunction(f,new Date(p),this,A,u,m).toString());this.boldLabels&&(l=!0);m=new this.axisItemRenderer(this,h,f,!1,n,J,!1,l);this.pushAxisItem(m);m=l=p;if(!isNaN(w))for(h=1;hb||b>this.height)return;if(isNaN(b)){this.hideBalloon();return}b=this.adjustBalloonCoordinate(b,e);e=this.coordinateToValue(b)}else{if(0> +a||a>this.width)return;if(isNaN(a)){this.hideBalloon();return}a=this.adjustBalloonCoordinate(a,e);e=this.coordinateToValue(a)}var f;if(d=this.chart.chartCursor)f=d.index;if(this.balloon&&void 0!==e&&this.balloon.enabled){if(this.balloonTextFunction){if("date"==this.type||!0===this.parseDates)e=new Date(e);e=this.balloonTextFunction(e)}else this.balloonText?e=this.formatBalloonText(this.balloonText,f,c):isNaN(e)||(e=this.formatValue(e,c));if(a!=this.prevBX||b!=this.prevBY)this.balloon.setPosition(a, +b),this.prevBX=a,this.prevBY=b,e&&this.balloon.showBalloon(e)}},adjustBalloonCoordinate:function(a){return a},createBalloon:function(){var a=this.chart,b=a.chartCursor;b&&(b=b.cursorPosition,"mouse"!=b&&(this.stickBalloonToCategory=!0),"start"==b&&(this.stickBalloonToStart=!0),"ValueAxis"==this.cname&&(this.stickBalloonToCategory=!1));this.balloon&&(this.balloon.destroy&&this.balloon.destroy(),d.extend(this.balloon,a.balloon,!0))},setBalloonBounds:function(){var a=this.balloon;if(a){var b=this.chart; +a.cornerRadius=0;a.shadowAlpha=0;a.borderThickness=1;a.borderAlpha=1;a.adjustBorderColor=!1;a.showBullet=!1;this.balloon=a;a.chart=b;a.mainSet=b.plotBalloonsSet;a.pointerWidth=this.tickLength;if(this.parseDates||"date"==this.type)a.pointerWidth=0;a.className=this.id;b="V";"V"==this.orientation&&(b="H");this.stickBalloonToCategory||(a.animationDuration=0);var c,e,d,f,g=this.inside,k=this.width,l=this.height;switch(this.position){case "bottom":c=0;e=k;g?(d=0,f=l):(d=l,f=l+1E3);break;case "top":c=0; +e=k;g?(d=0,f=l):(d=-1E3,f=0);break;case "left":d=0;f=l;g?(c=0,e=k):(c=-1E3,e=0);break;case "right":d=0,f=l,g?(c=0,e=k):(c=k,e=k+1E3)}a.drop||(a.pointerOrientation=b);a.setBounds(c,d,e,f)}}})})();(function(){var d=window.AmCharts;d.ValueAxis=d.Class({inherits:d.AxisBase,construct:function(a){this.cname="ValueAxis";this.createEvents("axisChanged","logarithmicAxisFailed","axisZoomed","axisIntZoomed");d.ValueAxis.base.construct.call(this,a);this.dataChanged=!0;this.stackType="none";this.position="left";this.unitPosition="right";this.includeAllValues=this.recalculateToPercents=this.includeHidden=this.includeGuidesInMinMax=this.integersOnly=!1;this.durationUnits={DD:"d. ",hh:":",mm:":",ss:""}; +this.scrollbar=!1;this.baseValue=0;this.radarCategoriesEnabled=!0;this.axisFrequency=1;this.gridType="polygons";this.useScientificNotation=!1;this.axisTitleOffset=10;this.pointPosition="axis";this.minMaxMultiplier=1;this.logGridLimit=2;this.totalTextOffset=this.treatZeroAs=0;this.minPeriod="ss";this.relativeStart=0;this.relativeEnd=1;d.applyTheme(this,a,this.cname)},updateData:function(){0>=this.gridCountR&&(this.gridCountR=1);this.totals=[];this.data=this.chart.chartData;var a=this.chart;"xy"!=a.type&& +(this.stackGraphs("smoothedLine"),this.stackGraphs("line"),this.stackGraphs("column"),this.stackGraphs("step"));this.recalculateToPercents&&this.recalculate();this.synchronizationMultiplier&&this.synchronizeWith?(d.isString(this.synchronizeWith)&&(this.synchronizeWith=a.getValueAxisById(this.synchronizeWith)),this.synchronizeWith&&(this.synchronizeWithAxis(this.synchronizeWith),this.foundGraphs=!0)):(this.foundGraphs=!1,this.getMinMax(),0===this.start&&this.end==this.data.length-1&&isNaN(this.minZoom)&& +isNaN(this.maxZoom)&&(this.fullMin=this.min,this.fullMax=this.max,"date"!=this.type&&(isNaN(this.minimum)||(this.fullMin=this.minimum),isNaN(this.maximum)||(this.fullMax=this.maximum)),this.logarithmic&&(this.fullMin=this.logMin,0===this.fullMin&&(this.fullMin=this.treatZeroAs)),"date"==this.type&&(this.minimumDate||(this.fullMin=this.minRR),this.maximumDate||(this.fullMax=this.maxRR))))},draw:function(){d.ValueAxis.base.draw.call(this);var a=this.chart,b=this.set;this.labelRotationR=this.labelRotation; +d.setCN(a,this.set,"value-axis value-axis-"+this.id);d.setCN(a,this.labelsSet,"value-axis value-axis-"+this.id);d.setCN(a,this.axisLine.axisSet,"value-axis value-axis-"+this.id);var c=this.type;"duration"==c&&(this.duration="ss");!0===this.dataChanged&&(this.updateData(),this.dataChanged=!1);"date"==c&&(this.logarithmic=!1,this.min=this.minRR,this.max=this.maxRR,this.reversed=!1,this.getDateMinMax());if(this.logarithmic){var e=this.treatZeroAs,h=this.getExtremes(0,this.data.length-1).min;!isNaN(this.minimum)&& +this.minimum=h||0>=this.minimum){this.fire({type:"logarithmicAxisFailed",chart:a});return}}this.grid0=null;var f,g,k=a.dx,l=a.dy,e=!1,h=this.logarithmic;if(isNaN(this.min)||isNaN(this.max)||!this.foundGraphs||Infinity==this.min||-Infinity==this.max)e=!0;else{"date"==this.type&&this.min==this.max&&(this.max+=this.minDuration(),this.min-=this.minDuration());var m= +this.labelFrequency,n=this.showFirstLabel,q=this.showLastLabel,p=1,t=0;this.minCalc=this.min;this.maxCalc=this.max;this.strictMinMax&&(isNaN(this.minimum)||(this.min=this.minimum),isNaN(this.maximum)||(this.max=this.maximum));isNaN(this.minZoom)||(this.minReal=this.min=this.minZoom);isNaN(this.maxZoom)||(this.max=this.maxZoom);if(this.logarithmic){g=Math.log(this.fullMax)*Math.LOG10E-Math.log(this.fullMin)*Math.LOG10E;var r=Math.log(this.max)/Math.LN10-Math.log(this.fullMin)*Math.LOG10E;this.relativeStart= +(Math.log(this.minReal)/Math.LN10-Math.log(this.fullMin)*Math.LOG10E)/g;this.relativeEnd=r/g}else this.relativeStart=d.fitToBounds((this.min-this.fullMin)/(this.fullMax-this.fullMin),0,1),this.relativeEnd=d.fitToBounds((this.max-this.fullMin)/(this.fullMax-this.fullMin),0,1);var r=Math.round((this.maxCalc-this.minCalc)/this.step)+1,w;!0===h?(w=Math.log(this.max)*Math.LOG10E-Math.log(this.minReal)*Math.LOG10E,this.stepWidth=this.axisWidth/w,w>this.logGridLimit&&(r=Math.ceil(Math.log(this.max)*Math.LOG10E)+ +1,t=Math.round(Math.log(this.minReal)*Math.LOG10E),r>this.gridCountR&&(p=Math.ceil(r/this.gridCountR)))):this.stepWidth=this.axisWidth/(this.max-this.min);var x=0;1>this.step&&-1this.maxDecCount&&(x=this.maxDecCount);var y=this.precision;isNaN(y)||(x=y);isNaN(this.maxZoom)&&(this.max=d.roundTo(this.max,this.maxDecCount),this.min=d.roundTo(this.min,this.maxDecCount));g={};g.precision=x;g.decimalSeparator=a.nf.decimalSeparator;g.thousandsSeparator= +a.nf.thousandsSeparator;this.numberFormatter=g;var u;this.exponential=!1;for(g=t;g=this.autoRotateCount&&!isNaN(this.autoRotateAngle)&&(this.labelRotationR=this.autoRotateAngle),c=this.minCalc,h&&(r++,c=this.maxCalc-r*x),this.gridCountReal=r,g=this.startCount=t;gthis.logGridLimit)t=Math.pow(10,g);else if(0>=t&&(t=c+x*g+x/2,0>=t))continue;u=this.formatValue(t, +!1,g);Math.round(g/m)!=g/m&&(u=void 0);if(0===g&&!n||g==r-1&&!q)u=" ";f=this.getCoordinate(t);var B;this.rotate&&this.autoWrap&&(B=this.stepWidth*x-10);u=new this.axisItemRenderer(this,f,u,void 0,B,void 0,void 0,this.boldLabels);this.pushAxisItem(u);if(t==this.baseValue&&"radar"!=a.type){var D,C;u=this.width;var J=this.height;"H"==this.orientation?0<=f&&f<=u+1&&(D=[f,f,f+k],C=[J,0,l]):0<=f&&f<=J+1&&(D=[0,u,u+k],C=[f,f,f+l]);D&&(u=d.fitToBounds(2*this.gridAlpha,0,1),isNaN(this.zeroGridAlpha)||(u=this.zeroGridAlpha), +u=d.line(a.container,D,C,this.gridColor,u,1,this.dashLength),u.translate(this.x,this.y),this.grid0=u,a.axesSet.push(u),u.toBack(),d.setCN(a,u,this.bcn+"zero-grid-"+this.id),d.setCN(a,u,this.bcn+"zero-grid"))}if(!isNaN(z)&&0this.logGridLimit&&(z=Math.pow(10,g+p)),u=9,z=(z-t)/u);f=this.gridAlpha;this.gridAlpha=this.minorGridAlpha;for(J=1;Jl&&0>k||(k=new this.guideFillRenderer(this, +l,k,C),this.pushAxisItem(k,z),z=k.graphics(),C.graphics=z,C.balloonText&&this.addEventListeners(z,C));this.fillAlpha=D}g=this.baseValue;this.min>this.baseValue&&this.max>this.baseValue&&(g=this.min);this.minc&&(f.precision=Math.abs(c)),b&&1b&&c.shift();for(var e=Math.floor(Math.log(Math.abs(a))*Math.LOG10E),d=0;da){if(g=Math.pow(10,-g)*f,g==Math.round(g))return f}else if(f==Math.round(f))return f}},stackGraphs:function(a){var b=this.stackType;"stacked"==b&&(b="regular");"line"== +b&&(b="none");"100% stacked"==b&&(b="100%");this.stackType=b;var c=[],e=[],h=[],f=[],g,k=this.chart.graphs,l,m,n,q,p,t=this.baseValue,r=!1;if("line"==a||"step"==a||"smoothedLine"==a)r=!0;if(r&&("regular"==b||"100%"==b))for(q=0;qg?(m.values.close=g,isNaN(e[p])?m.values.open=t:(m.values.close+=e[p],m.values.open=e[p]),e[p]=m.values.close):(m.values.close=g,isNaN(h[p])?m.values.open=t:(m.values.close+=h[p],m.values.open=h[p]),h[p]=m.values.close)))}}for(p=this.start;p<=this.end;p++)for(q=0;qc?(m.values.close=d.fitToBounds(c+e[p],-100,100),m.values.open=e[p],e[p]=m.values.close):(m.values.close=d.fitToBounds(c+h[p],-100,100),m.values.open=h[p],h[p]=m.values.close)))))},recalculate:function(){var a= +this.chart,b=a.graphs,c;for(c=0;cq&&g++}if(m= +a.recalculateFromDate)m=d.getDate(m,a.dataDateFormat,"fff"),g=a.getClosestIndex(a.chartData,"time",m.getTime(),!0,0,a.chartData.length),k=a.chartData.length-1;for(m=g;m<=k&&(g=this.data[m].axes[this.id].graphs[e.id],f=g.values[h],e.recalculateValue&&(f=g.dataContext[e.valueField+e.recalculateValue]),isNaN(f));m++);this.recBaseValue=f;for(h=l;h<=k;h++){g=this.data[h].axes[this.id].graphs[e.id];g.percents={};var l=g.values,p;for(p in l)g.percents[p]="percents"!=p?l[p]/f*100-100:l[p]}}}},getMinMax:function(){var a= +!1,b=this.chart,c=b.graphs,e;for(e=0;ethis.max&&(this.max=c.toValue),c.value>this.max&&(this.max=c.value);isNaN(this.minimum)||(this.min=this.minimum);isNaN(this.maximum)||(this.max=this.maximum);"date"==this.type&&this.getDateMinMax();this.min>this.max&&(a=this.max,this.max=this.min,this.min=a);isNaN(this.minZoom)|| +(this.min=this.minZoom);isNaN(this.maxZoom)||(this.max=this.maxZoom);this.minCalc=this.min;this.maxCalc=this.max;this.minReal=this.min;this.maxReal=this.max;0===this.min&&0===this.max&&(this.max=9);this.min>this.max&&(this.min=this.max-1);a=this.min;b=this.max;c=this.max-this.min;e=0===c?Math.pow(10,Math.floor(Math.log(Math.abs(this.max))*Math.LOG10E))/10:Math.pow(10,Math.floor(Math.log(Math.abs(c))*Math.LOG10E))/10;isNaN(this.maximum)&&(this.max=Math.ceil(this.max/e)*e+e);isNaN(this.minimum)&&(this.min= +Math.floor(this.min/e)*e-e);0>this.min&&0<=a&&(this.min=0);0=b&&(this.max=0);"100%"==this.stackType&&(this.min=0>this.min?-100:0,this.max=0>this.max?0:100);c=this.max-this.min;e=Math.pow(10,Math.floor(Math.log(Math.abs(c))*Math.LOG10E))/10;this.step=Math.ceil(c/this.gridCountR/e)*e;c=Math.pow(10,Math.floor(Math.log(Math.abs(this.step))*Math.LOG10E));c=d.fixStepE(c);e=Math.ceil(this.step/c);5=e&&2c?(this.maxDecCount=Math.abs(Math.log(Math.abs(c))*Math.LOG10E),this.maxDecCount=Math.round(this.maxDecCount),this.step=d.roundTo(this.step,this.maxDecCount+1)):this.maxDecCount=0;this.min=this.step*Math.floor(this.min/this.step);this.max=this.step*Math.ceil(this.max/this.step);0>this.min&&0<=a&&(this.min=0);0=b&&(this.max=0);1e&&(e=l);else for(var m in k)k.hasOwnProperty(m)&& +"percents"!=m&&"total"!=m&&"error"!=m&&(l=k[m],le&&(e=l))}}}return{min:c,max:e}},zoomOut:function(){this.maxZoom=this.minZoom=NaN;this.zoomToRelativeValues(0,1)},zoomToRelativeValues:function(a,b,c){if(this.reversed){var e=a;a=1-b;b=1-e}var d=this.fullMax,e=this.fullMin,f=e+(d-e)*a,g=e+(d-e)*b;this.logarithmic&&(d=Math.log(d)*Math.LOG10E-Math.log(e)*Math.LOG10E,f=Math.pow(10,d*a+Math.log(e)*Math.LOG10E),g=Math.pow(10,d*b+Math.log(e)*Math.LOG10E));return this.zoomToValues(f,g,c)},zoomToValues:function(a, +b,c){if(bn?(v=X+ha*Math.sin(T)-B-3+2,G+=-ha*Math.cos(T)-Pa*Math.sin(T)-4):v-=B+r+3+3,v-=Z):(0n?(v=X+B+3-ha/2*Math.sin(T)+2,G+=ha/2*Math.cos(T)):v+=B+u+3+3,v+=Z)):(v+=ma+r/2-da,G+=va,I?(0za+2||0>f))ba.remove(),ba=null}else{0<=b&&b<=X+1&&(0X+1||vc&&"object"==typeof n&&(n=n.join(",").split(",").reverse());"V"==g?(g=d.rect(l,a.width,c,n,m),g.translate(h,b-k+f)):(g=d.rect(l, +c,a.height,n,m),g.translate(b-k+h,f));d.setCN(a.chart,g,"guide-fill");e.id&&d.setCN(a.chart,g,"guide-fill-"+e.id);this.set=l.set([g])},graphics:function(){return this.set},getLabel:function(){}})})();(function(){var d=window.AmCharts;d.AmChart=d.Class({construct:function(a){this.svgIcons=this.tapToActivate=!0;this.theme=a;this.classNamePrefix="amcharts";this.addClassNames=!1;this.version="3.20.4";d.addChart(this);this.createEvents("buildStarted","dataUpdated","init","rendered","drawn","failed","resized","animationFinished");this.height=this.width="100%";this.dataChanged=!0;this.chartCreated=!1;this.previousWidth=this.previousHeight=0;this.backgroundColor="#FFFFFF";this.borderAlpha=this.backgroundAlpha= +0;this.color=this.borderColor="#000000";this.fontFamily="Verdana";this.fontSize=11;this.usePrefixes=!1;this.autoResize=!0;this.autoDisplay=!1;this.addCodeCredits=this.accessible=!0;this.touchStartTime=this.touchClickDuration=0;this.precision=-1;this.percentPrecision=2;this.decimalSeparator=".";this.thousandsSeparator=",";this.labels=[];this.allLabels=[];this.titles=[];this.marginRight=this.marginLeft=this.autoMarginOffset=0;this.timeOuts=[];this.creditsPosition="top-left";var b=document.createElement("div"), +c=b.style;c.overflow="hidden";c.position="relative";c.textAlign="left";this.chartDiv=b;b=document.createElement("div");c=b.style;c.overflow="hidden";c.position="relative";c.textAlign="left";this.legendDiv=b;this.titleHeight=0;this.hideBalloonTime=150;this.handDrawScatter=2;this.cssScale=this.handDrawThickness=1;this.cssAngle=0;this.prefixesOfBigNumbers=[{number:1E3,prefix:"k"},{number:1E6,prefix:"M"},{number:1E9,prefix:"G"},{number:1E12,prefix:"T"},{number:1E15,prefix:"P"},{number:1E18,prefix:"E"}, +{number:1E21,prefix:"Z"},{number:1E24,prefix:"Y"}];this.prefixesOfSmallNumbers=[{number:1E-24,prefix:"y"},{number:1E-21,prefix:"z"},{number:1E-18,prefix:"a"},{number:1E-15,prefix:"f"},{number:1E-12,prefix:"p"},{number:1E-9,prefix:"n"},{number:1E-6,prefix:"\u03bc"},{number:.001,prefix:"m"}];this.panEventsEnabled=!0;this.product="amcharts";this.animations=[];this.balloon=new d.AmBalloon(this.theme);this.balloon.chart=this;this.processTimeout=0;this.processCount=1E3;this.animatable=[];d.applyTheme(this, +a,"AmChart")},drawChart:function(){0a||isNaN(a))a=0;this.chartDiv.style.height=a+"px"}}return a},updateWidth:function(){var a=this.divRealWidth,b=this.divRealHeight,c=this.legend;if(c){var e=this.legendDiv,d=e.offsetWidth;isNaN(c.width)||(d=c.width);c.ieW&&(d=c.ieW);var f=e.offsetHeight,e=e.style,g=this.chartDiv.style,c=c.position;if("right"==c||"left"==c){a-=d;if(0>a||isNaN(a))a=0;g.width=a+"px";this.balloon.setBounds(2,2,a-2,this.realHeight);"left"==c?(g.left=d+"px",e.left="0px"):(g.left="0px", +e.left=a+"px");b>f&&(e.top=(b-f)/2+"px")}}return a},getTitleHeight:function(){this.drawTitles(!0);return this.titleHeight},addTitle:function(a,b,c,e,d){isNaN(b)&&(b=this.fontSize+2);a={text:a,size:b,color:c,alpha:e,bold:d,enabled:!0};this.titles.push(a);return a},handleWheel:function(a){var b=0;a||(a=window.event);a.wheelDelta?b=a.wheelDelta/120:a.detail&&(b=-a.detail/3);b&&this.handleWheelReal(b,a.shiftKey);a.preventDefault&&a.preventDefault()},handleWheelReal:function(){},handleDocTouchStart:function(){this.hideBalloonReal(); +this.handleMouseMove();this.tmx=this.mouseX;this.tmy=this.mouseY;this.touchStartTime=(new Date).getTime()},handleDocTouchEnd:function(){-.5Math.abs(this.mouseX-this.tmx)&&4>Math.abs(this.mouseY-this.tmy)?(this.tapped=!0,this.panRequired&&this.panEventsEnabled&&this.chartDiv&&(this.chartDiv.style.msTouchAction="none",this.chartDiv.style.touchAction="none")):this.mouseIsOver||this.resetTouchStyle()): +(this.tapped=!1,this.resetTouchStyle())},resetTouchStyle:function(){this.panEventsEnabled&&this.chartDiv&&(this.chartDiv.style.msTouchAction="auto",this.chartDiv.style.touchAction="auto")},checkTouchDuration:function(a){var b=this,c=(new Date).getTime();if(a)if(a.touches)b.isTouchEvent=!0;else if(!b.isTouchEvent)return!0;if(c-b.touchStartTime>b.touchClickDuration)return!0;setTimeout(function(){b.resetTouchDuration()},300)},resetTouchDuration:function(){this.isTouchEvent=!1},checkTouchMoved:function(){if(4< +Math.abs(this.mouseX-this.tmx)||4a.valueAxis.minMaxMultiplier&&a.positiveClip(a.set));break;case "radar":a.createRadarGraph();break;case "xy":a.createXYGraph()}a.playedTO=setTimeout(function(){a.setAnimationPlayed.call(a)},500*a.chart.startDuration)}},setAnimationPlayed:function(){this.animationPlayed=!0},createXYGraph:function(){var a=[],b=[],c=this.xAxis, +e=this.yAxis;this.pmh=e.height;this.pmw=c.width;this.pmy=this.pmx=0;var d;for(d=this.start;d<=this.end;d++){var f=this.data[d].axes[c.id].graphs[this.id],g=f.values,k=g.x,l=g.y,g=c.getCoordinate(k,this.noRounding),m=e.getCoordinate(l,this.noRounding);if(!isNaN(k)&&!isNaN(l)&&(a.push(g),b.push(m),f.x=g,f.y=m,k=this.createBullet(f,g,m,d),l=this.labelText)){var l=this.createLabel(f,l),n=0;k&&(n=k.size);this.positionLabel(f,g,m,l,n)}}this.drawLineGraph(a,b);this.launchAnimation()},createRadarGraph:function(){var a= +this.valueAxis.stackType,b=[],c=[],e=[],d=[],f,g,k,l,m;for(m=this.start;m<=this.end;m++){var n=this.data[m].axes[this.valueAxis.id].graphs[this.id],q,p;"none"==a||"3d"==a?q=n.values.value:(q=n.values.close,p=n.values.open);if(isNaN(q))this.connect||(this.drawLineGraph(b,c,e,d),b=[],c=[],e=[],d=[]);else{var t=this.valueAxis.getCoordinate(q,this.noRounding)-this.height,t=t*this.valueAxis.rMultiplier,r=-360/(this.end-this.start+1)*m;"middle"==this.valueAxis.pointPosition&&(r-=180/(this.end-this.start+ +1));q=t*Math.sin(r/180*Math.PI);t*=Math.cos(r/180*Math.PI);b.push(q);c.push(t);if(!isNaN(p)){var w=this.valueAxis.getCoordinate(p,this.noRounding)-this.height,w=w*this.valueAxis.rMultiplier,x=w*Math.sin(r/180*Math.PI),r=w*Math.cos(r/180*Math.PI);e.push(x);d.push(r);isNaN(k)&&(k=x);isNaN(l)&&(l=r)}r=this.createBullet(n,q,t,m);n.x=q;n.y=t;if(x=this.labelText)x=this.createLabel(n,x),w=0,r&&(w=r.size),this.positionLabel(n,q,t,x,w);isNaN(f)&&(f=q);isNaN(g)&&(g=t)}}b.push(f);c.push(g);isNaN(k)||(e.push(k), +d.push(l));this.drawLineGraph(b,c,e,d);this.launchAnimation()},positionLabel:function(a,b,c,e,d){if(e){var f=this.chart,g=this.valueAxis,k="middle",l=!1,m=this.labelPosition,n=e.getBBox(),q=this.chart.rotate,p=a.isNegative,t=this.fontSize;void 0===t&&(t=this.chart.fontSize);c-=n.height/2-t/2-1;void 0!==a.labelIsNegative&&(p=a.labelIsNegative);switch(m){case "right":m=q?p?"left":"right":"right";break;case "top":m=q?"top":p?"bottom":"top";break;case "bottom":m=q?"bottom":p?"top":"bottom";break;case "left":m= +q?p?"right":"left":"left"}var t=a.columnGraphics,r=0,w=0;t&&(r=t.x,w=t.y);var x=this.labelOffset;switch(m){case "right":k="start";b+=d/2+x;break;case "top":c=g.reversed?c+(d/2+n.height/2+x):c-(d/2+n.height/2+x);break;case "bottom":c=g.reversed?c-(d/2+n.height/2+x):c+(d/2+n.height/2+x);break;case "left":k="end";b-=d/2+x;break;case "inside":"column"==this.type&&(l=!0,q?p?(k="end",b=r-3-x):(k="start",b=r+3+x):c=p?w+7+x:w-10-x);break;case "middle":"column"==this.type&&(l=!0,q?b-=(b-r)/2+x-3:c-=(c-w)/ +2+x-3)}"auto"!=this.labelAnchor&&(k=this.labelAnchor);e.attr({"text-anchor":k});this.labelRotation&&e.rotate(this.labelRotation);e.translate(b,c);!this.showAllValueLabels&&t&&l&&(n=e.getBBox(),n.height>a.columnHeight||n.width>a.columnWidth)&&(e.remove(),e=null);e&&"radar"!=f.type&&(0>b||b>this.width||0>c||c>this.height)&&(e.remove(),e=null);if(e&&("serial"==f.type||"gantt"==f.type))if(q){if(0>c||c>this.height)e.remove(),e=null}else if(0>b||b>this.width)e.remove(),e=null;e&&this.allBullets.push(e); +return e}},getGradRotation:function(){var a=270;"horizontal"==this.gradientOrientation&&(a=0);return this.gradientRotation=a},createSerialGraph:function(){this.dashLengthSwitched=this.fillColorsSwitched=this.lineColorSwitched=void 0;var a=this.chart,b=this.id,c=this.index,e=this.data,h=this.chart.container,f=this.valueAxis,g=this.type,k=this.columnWidthReal,l=this.showBulletsAt;isNaN(this.columnWidth)||(k=this.columnWidth);isNaN(k)&&(k=.8);var m=this.useNegativeColorIfDown,n=this.width,q=this.height, +p=this.y,t=this.rotate,r=this.columnCount,w=d.toCoordinate(this.cornerRadiusTop,k/2),x=this.connect,y=[],u=[],A,z,B,D,C=this.chart.graphs.length,J,H=this.dx/this.tcc,S=this.dy/this.tcc,O=f.stackType,Q=this.start,ia=this.end,I=this.scrollbar,Z="graph-column-";I&&(Z="scrollbar-graph-column-");var va=this.categoryAxis,ma=this.baseCoord,Oa=this.negativeBase,ea=this.columnIndex,ca=this.lineThickness,X=this.lineAlpha,za=this.lineColorR,da=this.dashLength,fa=this.set,Aa,ga=this.getGradRotation(),T=this.chart.columnSpacing, +Y=va.cellWidth,Da=(Y*k-r)/r;T>Da&&(T=Da);var G,v,na,ha=q,Pa=n,ba=0,tb=0,ub,vb,gb,hb,wb=this.fillColorsR,Qa=this.negativeFillColors,Ja=this.negativeLineColor,Ya=this.fillAlphas,Za=this.negativeFillAlphas;"object"==typeof Ya&&(Ya=Ya[0]);"object"==typeof Za&&(Za=Za[0]);var xb=this.noRounding;"step"==g&&(xb=!1);var ib=f.getCoordinate(f.min);f.logarithmic&&(ib=f.getCoordinate(f.minReal));this.minCoord=ib;this.resetBullet&&(this.bullet="none");if(!(I||"line"!=g&&"smoothedLine"!=g&&"step"!=g||(1==e.length&& +"step"!=g&&"none"==this.bullet&&(this.bullet="round",this.resetBullet=!0),!Qa&&void 0==Ja||m))){var Ua=Oa;Ua>f.max&&(Ua=f.max);Uak&&(k=1);var Mb=this.fixedColumnWidth;isNaN(Mb)||(k=Mb);var L;if("line"==g||"step"==g||"smoothedLine"==g){if(0W?!0:!1);if(!I)switch(this.showBalloonAt){case "close":v.y=F;break;case "open":v.y=M;break;case "high":v.y=sa;break;case "low":v.y=qa}var ja=G.x[va.id],Wa=this.periodSpan-1;"step"!=g||isNaN(G.cellWidth)||(Y=G.cellWidth);var ya=Math.floor(Y/2)+Math.floor(Wa*Y/2),Ga=ya,nb=0;"left"==this.stepDirection&&(nb=(2*Y+Wa*Y)/2,ja-=nb);"center"==this.stepDirection&&(nb=Y/2,ja-=nb);"start"== +this.pointPosition&&(ja-=Y/2+Math.floor(Wa*Y/2),ya=0,Ga=Math.floor(Y)+Math.floor(Wa*Y));"end"==this.pointPosition&&(ja+=Y/2+Math.floor(Wa*Y/2),ya=Math.floor(Y)+Math.floor(Wa*Y),Ga=0);if(Nb){var Cb=this.columnWidth;isNaN(Cb)||(ya*=Cb,Ga*=Cb)}I||(v.x=ja);-1E5>ja&&(ja=-1E5);ja>n+1E5&&(ja=n+1E5);t?(E=F,N=M,M=F=ja,isNaN(ta)&&!this.fillToGraph&&(N=ma),pa=qa,ra=sa):(N=E=ja,isNaN(ta)&&!this.fillToGraph&&(M=ma));if(!Bb&&WTa?(Sa&&($a=!0),Sa=!1):(Sa||($a=!0),Sa=!0):v.isNegative=W=lb||Math.abs(F-kb)>=lb)y.push(E),u.push(F),jb=E,kb=F;wa=E;Ea=F;ka=E;la=F;!Ra||isNaN(M)||isNaN(N)||(U.push(N),V.push(M));if($a||void 0!=v.lineColor&&v.lineColor!=this.lineColorSwitched||void 0!= +v.fillColors&&v.fillColors!=this.fillColorsSwitched||!isNaN(v.dashLength))this.drawLineGraph(y,u,U,V),y=[E],u=[F],U=[],V=[],!Ra||isNaN(M)||isNaN(N)||(U.push(N),V.push(M)),m?Sa?(this.lineColorSwitched=za,this.fillColorsSwitched=wb):(this.lineColorSwitched=Ja,this.fillColorsSwitched=Qa):(this.lineColorSwitched=v.lineColor,this.fillColorsSwitched=v.fillColors),this.dashLengthSwitched=v.dashLength;v.gap&&(this.drawLineGraph(y,u,U,V),y=[],u=[],U=[],V=[])}break;case "smoothedLine":if(isNaN(W))x||(this.drawSmoothedGraph(y, +u,U,V),y=[],u=[],U=[],V=[]);else{if(Math.abs(E-jb)>=lb||Math.abs(F-kb)>=lb)y.push(E),u.push(F),jb=E,kb=F;wa=E;Ea=F;ka=E;la=F;!Ra||isNaN(M)||isNaN(N)||(U.push(N),V.push(M));void 0==v.lineColor&&void 0==v.fillColors&&isNaN(v.dashLength)||(this.drawSmoothedGraph(y,u,U,V),y=[E],u=[F],U=[],V=[],!Ra||isNaN(M)||isNaN(N)||(U.push(N),V.push(M)),this.lineColorSwitched=v.lineColor,this.fillColorsSwitched=v.fillColors,this.dashLengthSwitched=v.dashLength);v.gap&&(this.drawSmoothedGraph(y,u,U,V),y=[],u=[],U=[], +V=[])}break;case "step":if(!isNaN(W)){t?(isNaN(A)||(y.push(A),u.push(F-ya)),u.push(F-ya),y.push(E),u.push(F+Ga),y.push(E),!Ra||isNaN(M)||isNaN(N)||(isNaN(B)||(U.push(B),V.push(M-ya)),U.push(N),V.push(M-ya),U.push(N),V.push(M+Ga))):(isNaN(z)||(u.push(z),y.push(E-ya)),y.push(E-ya),u.push(F),y.push(E+Ga),u.push(F),!Ra||isNaN(M)||isNaN(N)||(isNaN(D)||(U.push(N-ya),V.push(D)),U.push(N-ya),V.push(M),U.push(N+Ga),V.push(M)));A=E;z=F;B=N;D=M;wa=E;Ea=F;ka=E;la=F;if($a||void 0!=v.lineColor||void 0!=v.fillColors|| +!isNaN(v.dashLength)){var cc=y[y.length-2],dc=u[u.length-2];y.pop();u.pop();this.drawLineGraph(y,u,U,V);y=[cc];u=[dc];t?(u.push(F+Ga),y.push(E)):(y.push(E+Ga),u.push(F));U=[];V=[];this.lineColorSwitched=v.lineColor;this.fillColorsSwitched=v.fillColors;this.dashLengthSwitched=v.dashLength;m&&(Sa?(this.lineColorSwitched=za,this.fillColorsSwitched=wb):(this.lineColorSwitched=Ja,this.fillColorsSwitched=Qa))}if(Nb||v.gap)A=z=NaN,this.drawLineGraph(y,u,U,V),y=[],u=[],U=[],V=[]}else if(!x){if(1>=this.periodSpan|| +1ya+Ga)A=z=NaN;this.drawLineGraph(y,u,U,V);y=[];u=[];U=[];V=[]}break;case "column":Ba=Ha;void 0!=v.lineColor&&(Ba=v.lineColor);if(!isNaN(W)){m||(v.isNegative=WQb&&ob>Qb)){var Ca;if(t){"3d"==O?(P=F-(r/2-this.depthCount+1)*(k+T)+T/2+S*ea,R=N+H*ea,Ca=ea):(P=Math.floor(F-(r/2-ea)*(k+T)+T/2),R=N,Ca=0);K=k;wa=E;Ea=P+k/2;ka=E;la=P+k/2;P+K>q+Ca*S&&(K=q-P+Ca*S); +Paa?!0:!1;0===aa&&1/W===1/-0&&(v.labelIsNegative=!0);isNaN(G.percentWidthValue)||(K=this.height*G.percentWidthValue/100,P=ja-K/2,Ea=P+K/2);K=d.roundTo(K,2);aa=d.roundTo(aa,2);Pn+Ca*H&&(K=n-R+Ca*H);Rq&&(K=q-P);0>P&&(K+=P,P=0);if(Pta?(Db=[E,ra],Eb=[N,pa]):(Db=[N,ra],Eb=[E,pa]);!isNaN(ra)&&!isNaN(pa)&&Fn&&(K=n-R);0>R&&(K+=R,R=0);aa=F-M;if(R=ta&&(Va=0);var ua=new d.Cuboid(h,K,aa,H,S,Ma,Va,ca,Ba,X,ga,w,t,da,bb,mb,Z),Fb,Gb;W>ta?(Fb=[F, +sa],Gb=[M,qa]):(Fb=[M,sa],Gb=[F,qa]);!isNaN(sa)&&!isNaN(qa)&&EW?E-$b/2-2-fb-sb:E+$b/2+3+fb+sb):(db=wa,eb=0>W?F+ac/2+fb+sb:F-ac/2-3-fb-sb);Na.translate(db,eb);f.totals[L]=Na;t?(0>eb||eb>q)&&Na.remove():(0>db||db>n)&&Na.remove()}}}}}}}if("line"== +g||"step"==g||"smoothedLine"==g)"smoothedLine"==g?this.drawSmoothedGraph(y,u,U,V):this.drawLineGraph(y,u,U,V),I||this.launchAnimation();this.bulletsHidden&&this.hideBullets();this.customBulletsHidden&&this.hideCustomBullets()},animateColumns:function(a,b){var c=this,e=c.chart.startDuration;0h.height&&(z=h.height),0>z&&(z=0));q=d.line(l,a,b,t,q,p,y,!1,!0,f);d.setCN(k,q,h.bcn+"stroke");m.push(q);m.click(function(a){h.handleGraphEvent(a,"clickGraph")}).mouseover(function(a){h.handleGraphEvent(a,"rollOverGraph")}).mouseout(function(a){h.handleGraphEvent(a,"rollOutGraph")}).touchmove(function(a){h.chart.handleMouseMove(a)}).touchend(function(a){h.chart.handleTouchEnd(a)});void 0===x||h.useNegativeColorIfDown||(p=d.line(l, +a,b,x,r,p,y,!1,!0,f),d.setCN(k,p,h.bcn+"stroke"),d.setCN(k,p,h.bcn+"stroke-negative"),n.push(p));if(0a&&(a=this.fillAlphas),0===a&&(a=this.bulletAlpha), +0===a&&(a=1));return a},createBullet:function(a,b,c){if(!isNaN(b)&&!isNaN(c)&&("none"!=this.bullet||this.customBullet||a.bullet||a.customBullet)){var e=this.chart,h=this.container,f=this.bulletOffset,g=this.bulletSize;isNaN(a.bulletSize)||(g=a.bulletSize);var k=a.values.value,l=this.maxValue,m=this.minValue,n=this.maxBulletSize,q=this.minBulletSize;isNaN(l)||(isNaN(k)||(g=(k-m)/(l-m)*(n-q)+q),m==l&&(g=n));l=g;this.bulletAxis&&(g=a.values.error,isNaN(g)||(k=g),g=this.bulletAxis.stepWidth*k);gb||b>this.width||c<-g/2||c>this.height)p.remove(),p=null;p&&(this.bulletSet.push(p),p.translate(b,c),this.addListeners(p,a),this.allBullets.push(p));a.bx=b;a.by=c;d.setCN(e,p,this.bcn+"bullet"); +a.className&&d.setCN(e,p,a.className,!0)}if(p){p.size=g||0;if(e=this.bulletHitAreaSize)h=d.circle(h,e,"#FFFFFF",.001,0),h.translate(b,c),a.hitBullet=h,this.bulletSet.push(h),this.addListeners(h,a);a.bulletGraphics=p;void 0!==this.tabIndex&&p.setAttr("tabindex",this.tabIndex)}else p={size:0};p.graphDataItem=a;return p}},showBullets:function(){var a=this.allBullets,b;this.bulletsHidden=!1;for(b=0;ba+k||hq+l)?(g.showBalloon(m),g.hide(0)):(g.followCursor(c),g.showBalloon(m)))):(this.hideBalloonReal(), +this.resizeBullet(a,e,h))}else this.hideBalloonReal()},resizeBullet:function(a,b,c){this.fixBulletSize();if(a&&d.isModern&&(1!=b||!isNaN(c))){var e=a.bulletGraphics;e&&!e.doNotScale&&(e.translate(a.bx,a.by,b),isNaN(c)||(e.setAttr("fill-opacity",c),e.setAttr("stroke-opacity",c)),this.resizedDItem=a)}}})})();(function(){var d=window.AmCharts;d.ChartCursor=d.Class({construct:function(a){this.cname="ChartCursor";this.createEvents("changed","zoomed","onHideCursor","onShowCursor","draw","selected","moved","panning","zoomStarted");this.enabled=!0;this.cursorAlpha=1;this.selectionAlpha=.2;this.cursorColor="#CC0000";this.categoryBalloonAlpha=1;this.color="#FFFFFF";this.type="cursor";this.zoomed=!1;this.zoomable=!0;this.pan=!1;this.categoryBalloonDateFormat="MMM DD, YYYY";this.categoryBalloonText="[[category]]"; +this.categoryBalloonEnabled=this.valueBalloonsEnabled=!0;this.rolledOver=!1;this.cursorPosition="middle";this.bulletsEnabled=this.skipZoomDispatch=!1;this.bulletSize=8;this.selectWithoutZooming=this.oneBalloonOnly=!1;this.graphBulletSize=1.7;this.animationDuration=.3;this.zooming=!1;this.adjustment=0;this.avoidBalloonOverlapping=!0;this.leaveCursor=!1;this.leaveAfterTouch=!0;this.valueZoomable=!1;this.balloonPointerOrientation="horizontal";this.hLineEnabled=this.vLineEnabled=!0;this.vZoomEnabled= +this.hZoomEnabled=!1;d.applyTheme(this,a,this.cname)},draw:function(){this.destroy();var a=this.chart;a.panRequired=!0;var b=a.container;this.rotate=a.rotate;this.container=b;this.prevLineHeight=this.prevLineWidth=NaN;b=b.set();b.translate(this.x,this.y);this.set=b;a.cursorSet.push(b);this.createElements();d.isString(this.limitToGraph)&&(this.limitToGraph=d.getObjById(a.graphs,this.limitToGraph),this.fullWidth=!1,this.cursorPosition="middle");this.pointer=this.balloonPointerOrientation.substr(0,1).toUpperCase(); +this.isHidden=!1;this.hideLines();this.valueLineAxis||(this.valueLineAxis=a.valueAxes[0])},createElements:function(){var a=this,b=a.chart,c=b.dx,e=b.dy,h=a.width,f=a.height,g,k,l=a.cursorAlpha,m=a.valueLineAlpha;a.rotate?(g=m,k=l):(k=m,g=l);"xy"==b.type&&(k=l,void 0!==m&&(k=m),g=l);a.vvLine=d.line(a.container,[c,0,0],[e,0,f],a.cursorColor,g,1);d.setCN(b,a.vvLine,"cursor-line");d.setCN(b,a.vvLine,"cursor-line-vertical");a.hhLine=d.line(a.container,[0,h,h+c],[0,0,e],a.cursorColor,k,1);d.setCN(b,a.hhLine, +"cursor-line");d.setCN(b,a.hhLine,"cursor-line-horizontal");a.vLine=a.rotate?a.vvLine:a.hhLine;a.set.push(a.vvLine);a.set.push(a.hhLine);a.set.node.style.pointerEvents="none";a.fullLines=a.container.set();b=b.cursorLineSet;b.push(a.fullLines);b.translate(a.x,a.y);b.clipRect(0,0,h,f);void 0!==a.tabIndex&&(b.setAttr("tabindex",a.tabIndex),b.keyup(function(b){a.handleKeys(b)}).focus(function(b){a.showCursor()}).blur(function(b){a.hideCursor()}));a.set.clipRect(0,0,h,f)},handleKeys:function(a){var b= +this.prevIndex,c=this.chart;if(c){var e=c.chartData;e&&(isNaN(b)&&(b=e.length-1),37!=a.keyCode&&40!=a.keyCode||b--,39!=a.keyCode&&38!=a.keyCode||b++,b=d.fitToBounds(b,c.startIndex,c.endIndex),(a=this.chart.chartData[b])&&this.setPosition(a.x.categoryAxis),this.prevIndex=b)}},update:function(){var a=this.chart;if(a){var b=a.mouseX-this.x,c=a.mouseY-this.y;this.mouseX=b;this.mouseY=c;this.mouse2X=a.mouse2X-this.x;this.mouse2Y=a.mouse2Y-this.y;var e;if(a.chartData&&0document.documentMode&&(this.updateOnReleaseOnly=!0);this.dragIconHeight=this.dragIconWidth=35;this.dragIcon="dragIconRoundBig"; +this.dragCursorHover="cursor: cursor: grab; cursor:-moz-grab; cursor:-webkit-grab;";this.dragCursorDown="cursor: cursor: grab; cursor:-moz-grabbing; cursor:-webkit-grabbing;";this.enabled=!0;this.percentStart=this.offset=0;this.percentEnd=1;d.applyTheme(this,a,"SimpleChartScrollbar")},getPercents:function(){var a=this.getDBox(),b=a.x,c=a.y,e=a.width,a=a.height;this.rotate?(b=1-c/this.height,c=1-(c+a)/this.height):(c=b/this.width,b=(b+e)/this.width);this.percentStart=c;this.percentEnd=b},draw:function(){var a= +this;a.destroy();if(a.enabled){var b=a.chart.container,c=a.rotate,e=a.chart;e.panRequired=!0;var h=b.set();a.set=h;e.scrollbarsSet.push(h);var f,g;c?(f=a.scrollbarHeight,g=e.plotAreaHeight):(g=a.scrollbarHeight,f=e.plotAreaWidth);a.width=f;if((a.height=g)&&f){var k=d.rect(b,f,g,a.backgroundColor,a.backgroundAlpha,1,a.backgroundColor,a.backgroundAlpha);d.setCN(e,k,"scrollbar-bg");a.bg=k;h.push(k);k=d.rect(b,f,g,"#000",.005);h.push(k);a.invisibleBg=k;k.click(function(){a.handleBgClick()}).mouseover(function(){a.handleMouseOver()}).mouseout(function(){a.handleMouseOut()}).touchend(function(){a.handleBgClick()}); +k=d.rect(b,f,g,a.selectedBackgroundColor,a.selectedBackgroundAlpha);d.setCN(e,k,"scrollbar-bg-selected");a.selectedBG=k;h.push(k);f=d.rect(b,f,g,"#000",.005);a.dragger=f;h.push(f);f.mousedown(function(b){a.handleDragStart(b)}).mouseup(function(){a.handleDragStop()}).mouseover(function(){a.handleDraggerOver()}).mouseout(function(){a.handleMouseOut()}).touchstart(function(b){a.handleDragStart(b)}).touchend(function(){a.handleDragStop()});g=e.pathToImages;var l,k=a.dragIcon.replace(/\.[a-z]*$/i,""); +c?(l=g+k+"H"+e.extension,g=a.dragIconWidth,c=a.dragIconHeight):(l=g+k+e.extension,c=a.dragIconWidth,g=a.dragIconHeight);k=b.image(l,0,0,c,g);d.setCN(e,k,"scrollbar-grip-left");l=b.image(l,0,0,c,g);d.setCN(e,l,"scrollbar-grip-right");var m=10,n=20;e.panEventsEnabled&&(m=25,n=a.scrollbarHeight);var q=d.rect(b,m,n,"#000",.005),p=d.rect(b,m,n,"#000",.005);p.translate(-(m-c)/2,-(n-g)/2);q.translate(-(m-c)/2,-(n-g)/2);c=b.set([k,p]);b=b.set([l,q]);a.iconLeft=c;h.push(a.iconLeft);a.iconRight=b;h.push(b); +e.makeAccessible(c,a.accessibleLabel);e.makeAccessible(b,a.accessibleLabel);e.makeAccessible(f,a.accessibleLabel);c.setAttr("role","menuitem");b.setAttr("role","menuitem");f.setAttr("role","menuitem");void 0!==a.tabIndex&&(c.setAttr("tabindex",a.tabIndex),c.keyup(function(b){a.handleKeys(b,1,0)}));void 0!==a.tabIndex&&(f.setAttr("tabindex",a.tabIndex),f.keyup(function(b){a.handleKeys(b,1,1)}));void 0!==a.tabIndex&&(b.setAttr("tabindex",a.tabIndex),b.keyup(function(b){a.handleKeys(b,0,1)}));c.mousedown(function(){a.leftDragStart()}).mouseup(function(){a.leftDragStop()}).mouseover(function(){a.iconRollOver()}).mouseout(function(){a.iconRollOut()}).touchstart(function(){a.leftDragStart()}).touchend(function(){a.leftDragStop()}); +b.mousedown(function(){a.rightDragStart()}).mouseup(function(){a.rightDragStop()}).mouseover(function(){a.iconRollOver()}).mouseout(function(){a.iconRollOut()}).touchstart(function(){a.rightDragStart()}).touchend(function(){a.rightDragStop()});d.ifArray(e.chartData)?h.show():h.hide();a.hideDragIcons();a.clipDragger(!1)}h.translate(a.x,a.y);h.node.style.msTouchAction="none";h.node.style.touchAction="none"}},handleKeys:function(a,b,c){this.getPercents();var e=this.percentStart,d=this.percentEnd;if(this.rotate)var f= +d,d=e,e=f;if(37==a.keyCode||40==a.keyCode)e-=.02*b,d-=.02*c;if(39==a.keyCode||38==a.keyCode)e+=.02*b,d+=.02*c;this.rotate&&(a=d,d=e,e=a);isNaN(d)||isNaN(e)||this.percentZoom(e,d,!0)},updateScrollbarSize:function(a,b){if(!isNaN(a)&&!isNaN(b)){a=Math.round(a);b=Math.round(b);var c=this.dragger,e,d,f,g,k;this.rotate?(e=0,d=a,f=this.width+1,g=b-a,c.setAttr("height",b-a),c.setAttr("y",d)):(e=a,d=0,f=b-a,g=this.height+1,k=b-a,c.setAttr("x",e),c.setAttr("width",k));this.clipAndUpdate(e,d,f,g)}},update:function(){var a, +b=!1,c,e,d=this.x,f=this.y,g=this.dragger,k=this.getDBox();if(k){c=k.x+d;e=k.y+f;var l=k.width,k=k.height,m=this.rotate,n=this.chart,q=this.width,p=this.height,t=n.mouseX,r=n.mouseY;a=this.initialMouse;this.forceClip&&this.clipDragger(!0);if(n.mouseIsOver){this.dragging&&(n=this.initialCoord,m?(a=n+(r-a),0>a&&(a=0),n=p-k,a>n&&(a=n),g.setAttr("y",a)):(a=n+(t-a),0>a&&(a=0),n=q-l,a>n&&(a=n),g.setAttr("x",a)),this.clipDragger(!0));if(this.resizingRight){if(m)if(a=r-e,a+e>p+f&&(a=p-e+f),0>a)this.resizingRight= +!1,b=this.resizingLeft=!0;else{if(0===a||isNaN(a))a=.1;g.setAttr("height",a)}else if(a=t-c,a+c>q+d&&(a=q-c+d),0>a)this.resizingRight=!1,b=this.resizingLeft=!0;else{if(0===a||isNaN(a))a=.1;g.setAttr("width",a)}this.clipDragger(!0)}if(this.resizingLeft){if(m)if(c=e,e=r,ep+f&&(e=p+f),a=!0===b?c-e:k+c-e,0>a)this.resizingRight=!0,this.resizingLeft=!1,g.setAttr("y",c+k-f);else{if(0===a||isNaN(a))a=.1;g.setAttr("y",e-f);g.setAttr("height",a)}else if(e=t,eq+d&&(e=q+d),a=!0===b?c-e:l+c-e,0>a)this.resizingRight=!0,this.resizingLeft=!1,g.setAttr("x",c+l-d);else{if(0===a||isNaN(a))a=.1;g.setAttr("x",e-d);g.setAttr("width",a)}this.clipDragger(!0)}}}},stopForceClip:function(){this.animating=this.forceClip=!1},clipDragger:function(a){var b=this.getDBox();if(b){var c=b.x,e=b.y,d=b.width,b=b.height,f=!1;if(this.rotate){if(c=0,d=this.width+1,this.clipY!=e||this.clipH!=b)f=!0}else if(e=0,b=this.height+1,this.clipX!=c||this.clipW!=d)f=!0;f&&(this.clipAndUpdate(c, +e,d,b),a&&(this.updateOnReleaseOnly||this.dispatchScrollbarEvent()))}},maskGraphs:function(){},clipAndUpdate:function(a,b,c,e){this.clipX=a;this.clipY=b;this.clipW=c;this.clipH=e;this.selectedBG.setAttr("width",c);this.selectedBG.setAttr("height",e);this.selectedBG.translate(a,b);this.updateDragIconPositions();this.maskGraphs(a,b,c,e)},dispatchScrollbarEvent:function(){if(this.skipEvent)this.skipEvent=!1;else{var a=this.chart;a.hideBalloon();var b=this.getDBox(),c=b.x,e=b.y,d=b.width,b=b.height;this.getPercents(); +this.rotate?(c=e,d=this.height/b):d=this.width/d;this.fire({type:"zoomed",position:c,chart:a,target:this,multiplier:d,relativeStart:this.percentStart,relativeEnd:this.percentEnd})}},updateDragIconPositions:function(){var a=this.getDBox(),b=a.x,c=a.y,e=this.iconLeft,d=this.iconRight,f,g,k=this.scrollbarHeight;this.rotate?(f=this.dragIconWidth,g=this.dragIconHeight,e.translate((k-g)/2,c-f/2),d.translate((k-g)/2,c+a.height-f/2)):(f=this.dragIconHeight,g=this.dragIconWidth,e.translate(b-g/2,(k-f)/2), +d.translate(b-g/2+a.width,(k-f)/2))},showDragIcons:function(){this.resizeEnabled&&(this.iconLeft.show(),this.iconRight.show())},hideDragIcons:function(){if(!this.resizingLeft&&!this.resizingRight&&!this.dragging){if(this.hideResizeGrips||!this.resizeEnabled)this.iconLeft.hide(),this.iconRight.hide();this.removeCursors()}},removeCursors:function(){this.chart.setMouseCursor("auto")},fireZoomEvent:function(a){this.fire({type:a,chart:this.chart,target:this})},percentZoom:function(a,b,c){a=d.fitToBounds(a, +0,b);b=d.fitToBounds(b,a,1);if(this.dragger&&this.enabled){this.dragger.stop();isNaN(a)&&(a=0);isNaN(b)&&(b=1);var e,h;this.rotate?(e=this.height,b=e-e*b,h=e-e*a):(e=this.width,h=e*b,b=e*a);this.updateScrollbarSize(b,h);this.clipDragger(!1);this.getPercents();c&&this.dispatchScrollbarEvent()}},destroy:function(){this.clear();d.remove(this.set);d.remove(this.iconRight);d.remove(this.iconLeft)},clear:function(){},handleDragStart:function(){if(this.enabled){this.fireZoomEvent("zoomStarted");var a=this.chart; +this.dragger.stop();this.removeCursors();d.isModern&&this.dragger.node.setAttribute("style",this.dragCursorDown);this.dragging=!0;var b=this.getDBox();this.rotate?(this.initialCoord=b.y,this.initialMouse=a.mouseY):(this.initialCoord=b.x,this.initialMouse=a.mouseX)}},handleDragStop:function(){this.updateOnReleaseOnly&&(this.update(),this.skipEvent=!1,this.dispatchScrollbarEvent());this.dragging=!1;this.mouseIsOver&&this.removeCursors();d.isModern&&this.dragger.node.setAttribute("style",this.dragCursorHover); +this.update();this.fireZoomEvent("zoomEnded")},handleDraggerOver:function(){this.handleMouseOver();d.isModern&&this.dragger.node.setAttribute("style",this.dragCursorHover)},leftDragStart:function(){this.fireZoomEvent("zoomStarted");this.dragger.stop();this.resizingLeft=!0},leftDragStop:function(){this.resizingLeft=!1;this.mouseIsOver||this.removeCursors();this.updateOnRelease();this.fireZoomEvent("zoomEnded")},rightDragStart:function(){this.fireZoomEvent("zoomStarted");this.dragger.stop();this.resizingRight= +!0},rightDragStop:function(){this.resizingRight=!1;this.mouseIsOver||this.removeCursors();this.updateOnRelease();this.fireZoomEvent("zoomEnded")},iconRollOut:function(){this.removeCursors()},iconRollOver:function(){this.rotate?this.chart.setMouseCursor("ns-resize"):this.chart.setMouseCursor("ew-resize");this.handleMouseOver()},getDBox:function(){if(this.dragger)return this.dragger.getBBox()},handleBgClick:function(){var a=this;if(!a.resizingRight&&!a.resizingLeft){a.zooming=!0;var b,c,e=a.scrollDuration, +h=a.dragger;b=a.getDBox();var f=b.height,g=b.width;c=a.chart;var k=a.y,l=a.x,m=a.rotate;m?(b="y",c=c.mouseY-f/2-k,c=d.fitToBounds(c,0,a.height-f)):(b="x",c=c.mouseX-g/2-l,c=d.fitToBounds(c,0,a.width-g));a.updateOnReleaseOnly?(a.skipEvent=!1,h.setAttr(b,c),a.dispatchScrollbarEvent(),a.clipDragger()):(a.animating=!0,c=Math.round(c),m?h.animate({y:c},e,">"):h.animate({x:c},e,">"),a.forceClip=!0,clearTimeout(a.forceTO),a.forceTO=setTimeout(function(){a.stopForceClip.call(a)},5E3*e))}},updateOnRelease:function(){this.updateOnReleaseOnly&& +(this.update(),this.skipEvent=!1,this.dispatchScrollbarEvent())},handleReleaseOutside:function(){if(this.set){if(this.resizingLeft||this.resizingRight||this.dragging)this.updateOnRelease(),this.removeCursors();this.animating=this.mouseIsOver=this.dragging=this.resizingRight=this.resizingLeft=!1;this.hideDragIcons();this.update()}},handleMouseOver:function(){this.mouseIsOver=!0;this.showDragIcons()},handleMouseOut:function(){this.mouseIsOver=!1;this.hideDragIcons();this.removeCursors()}})})();(function(){var d=window.AmCharts;d.ChartScrollbar=d.Class({inherits:d.SimpleChartScrollbar,construct:function(a){this.cname="ChartScrollbar";d.ChartScrollbar.base.construct.call(this,a);this.graphLineColor="#BBBBBB";this.graphLineAlpha=0;this.graphFillColor="#BBBBBB";this.graphFillAlpha=1;this.selectedGraphLineColor="#888888";this.selectedGraphLineAlpha=0;this.selectedGraphFillColor="#888888";this.selectedGraphFillAlpha=1;this.gridCount=0;this.gridColor="#FFFFFF";this.gridAlpha=.7;this.skipEvent= +this.autoGridCount=!1;this.color="#FFFFFF";this.scrollbarCreated=!1;this.oppositeAxis=!0;this.accessibleLabel="Zoom chart using cursor arrows";d.applyTheme(this,a,this.cname)},init:function(){var a=this.categoryAxis,b=this.chart,c=this.gridAxis;a||("CategoryAxis"==this.gridAxis.cname?(this.catScrollbar=!0,a=new d.CategoryAxis,a.id="scrollbar"):(a=new d.ValueAxis,a.data=b.chartData,a.id=c.id,a.type=c.type,a.maximumDate=c.maximumDate,a.minimumDate=c.minimumDate,a.minPeriod=c.minPeriod),this.categoryAxis= +a);a.chart=b;var e=b.categoryAxis;e&&(a.firstDayOfWeek=e.firstDayOfWeek);a.dateFormats=c.dateFormats;a.markPeriodChange=c.markPeriodChange;a.boldPeriodBeginning=c.boldPeriodBeginning;a.labelFunction=c.labelFunction;a.axisItemRenderer=d.RecItem;a.axisRenderer=d.RecAxis;a.guideFillRenderer=d.RecFill;a.inside=!0;a.fontSize=this.fontSize;a.tickLength=0;a.axisAlpha=0;d.isString(this.graph)&&(this.graph=d.getObjById(b.graphs,this.graph));(a=this.graph)&&this.catScrollbar&&(c=this.valueAxis,c||(this.valueAxis= +c=new d.ValueAxis,c.visible=!1,c.scrollbar=!0,c.axisItemRenderer=d.RecItem,c.axisRenderer=d.RecAxis,c.guideFillRenderer=d.RecFill,c.labelsEnabled=!1,c.chart=b),b=this.unselectedGraph,b||(b=new d.AmGraph,b.scrollbar=!0,this.unselectedGraph=b,b.negativeBase=a.negativeBase,b.noStepRisers=a.noStepRisers),b=this.selectedGraph,b||(b=new d.AmGraph,b.scrollbar=!0,this.selectedGraph=b,b.negativeBase=a.negativeBase,b.noStepRisers=a.noStepRisers));this.scrollbarCreated=!0},draw:function(){var a=this;d.ChartScrollbar.base.draw.call(a); +if(a.enabled){a.scrollbarCreated||a.init();var b=a.chart,c=b.chartData,e=a.categoryAxis,h=a.rotate,f=a.x,g=a.y,k=a.width,l=a.height,m=a.gridAxis,n=a.set;e.setOrientation(!h);e.parseDates=m.parseDates;"ValueAxis"==a.categoryAxis.cname&&(e.rotate=!h);e.equalSpacing=m.equalSpacing;e.minPeriod=m.minPeriod;e.startOnAxis=m.startOnAxis;e.width=k-1;e.height=l;e.gridCount=a.gridCount;e.gridColor=a.gridColor;e.gridAlpha=a.gridAlpha;e.color=a.color;e.tickLength=0;e.axisAlpha=0;e.autoGridCount=a.autoGridCount; +e.parseDates&&!e.equalSpacing&&e.timeZoom(b.firstTime,b.lastTime);e.minimum=a.gridAxis.fullMin;e.maximum=a.gridAxis.fullMax;e.strictMinMax=!0;e.zoom(0,c.length-1);if((m=a.graph)&&a.catScrollbar){var q=a.valueAxis,p=m.valueAxis;q.id=p.id;q.rotate=h;q.setOrientation(h);q.width=k;q.height=l;q.dataProvider=c;q.reversed=p.reversed;q.logarithmic=p.logarithmic;q.gridAlpha=0;q.axisAlpha=0;n.push(q.set);h?(q.y=g,q.x=0):(q.x=f,q.y=0);var f=Infinity,g=-Infinity,t;for(t=0;tg&&(g=x)}}Infinity!=f&&(q.minimum=f);-Infinity!=g&&(q.maximum=g+.1*(g-f));f==g&&(--q.minimum,q.maximum+=1);void 0!==a.minimum&&(q.minimum=a.minimum);void 0!==a.maximum&&(q.maximum=a.maximum);q.zoom(0,c.length-1);w=a.unselectedGraph;w.id=m.id;w.bcn="scrollbar-graph-";w.rotate=h;w.chart=b;w.data=c;w.valueAxis=q;w.chart=m.chart;w.categoryAxis=a.categoryAxis;w.periodSpan=m.periodSpan;w.valueField=m.valueField;w.openField= +m.openField;w.closeField=m.closeField;w.highField=m.highField;w.lowField=m.lowField;w.lineAlpha=a.graphLineAlpha;w.lineColorR=a.graphLineColor;w.fillAlphas=a.graphFillAlpha;w.fillColorsR=a.graphFillColor;w.connect=m.connect;w.hidden=m.hidden;w.width=k;w.height=l;w.pointPosition=m.pointPosition;w.stepDirection=m.stepDirection;w.periodSpan=m.periodSpan;p=a.selectedGraph;p.id=m.id;p.bcn=w.bcn+"selected-";p.rotate=h;p.chart=b;p.data=c;p.valueAxis=q;p.chart=m.chart;p.categoryAxis=e;p.periodSpan=m.periodSpan; +p.valueField=m.valueField;p.openField=m.openField;p.closeField=m.closeField;p.highField=m.highField;p.lowField=m.lowField;p.lineAlpha=a.selectedGraphLineAlpha;p.lineColorR=a.selectedGraphLineColor;p.fillAlphas=a.selectedGraphFillAlpha;p.fillColorsR=a.selectedGraphFillColor;p.connect=m.connect;p.hidden=m.hidden;p.width=k;p.height=l;p.pointPosition=m.pointPosition;p.stepDirection=m.stepDirection;p.periodSpan=m.periodSpan;b=a.graphType;b||(b=m.type);w.type=b;p.type=b;c=c.length-1;w.zoom(0,c);p.zoom(0, +c);p.set.click(function(){a.handleBackgroundClick()}).mouseover(function(){a.handleMouseOver()}).mouseout(function(){a.handleMouseOut()});w.set.click(function(){a.handleBackgroundClick()}).mouseover(function(){a.handleMouseOver()}).mouseout(function(){a.handleMouseOut()});n.push(w.set);n.push(p.set)}n.push(e.set);n.push(e.labelsSet);a.bg.toBack();a.invisibleBg.toFront();a.dragger.toFront();a.iconLeft.toFront();a.iconRight.toFront()}},timeZoom:function(a,b,c){this.startTime=a;this.endTime=b;this.timeDifference= +b-a;this.skipEvent=!d.toBoolean(c);this.zoomScrollbar();this.dispatchScrollbarEvent()},zoom:function(a,b){this.start=a;this.end=b;this.skipEvent=!0;this.zoomScrollbar()},dispatchScrollbarEvent:function(){if(this.categoryAxis&&"ValueAxis"==this.categoryAxis.cname)d.ChartScrollbar.base.dispatchScrollbarEvent.call(this);else if(this.skipEvent)this.skipEvent=!1;else{var a=this.chart.chartData,b,c;b=this.dragger.getBBox();var e=b.x,h=b.y,f=b.width,g=b.height,k=this.chart;this.rotate?(b=h,c=g):(b=e,c=f); +f={type:"zoomed",target:this};f.chart=k;var l=this.categoryAxis,m=this.stepWidth,e=k.minSelectedTime,h=k.maxSelectedTime,g=!1;if(l.parseDates&&!l.equalSpacing){if(a=k.lastTime,k=k.firstTime,l=Math.round(b/m)+k,b=this.dragging?l+this.timeDifference:Math.round((b+c)/m)+k,l>b&&(l=b),0h&&(b=Math.round(l+(b-l)/2),g=Math.round(h/2),l=b-g,b+=g,g=!0),b>a&&(b=a),b-eb&&(b=l+e),l!=this.startTime||b!=this.endTime)this.startTime= +l,this.endTime=b,f.start=l,f.end=b,f.startDate=new Date(l),f.endDate=new Date(b),this.fire(f)}else{l.startOnAxis||(b+=m/2);c-=this.stepWidth/2;var n=l.xToIndex(b),q=l.xToIndex(b+c);if(n!=this.start||this.end!=q)l.startOnAxis&&(this.resizingRight&&n==q&&q++,this.resizingLeft&&n==q&&(0this.timeDifference&&(this.timeDifference=0)},handleBackgroundClick:function(){d.ChartScrollbar.base.handleBackgroundClick.call(this);this.dragging||(this.difference=this.end-this.start,this.timeDifference=this.endTime-this.startTime,0>this.timeDifference&& +(this.timeDifference=0))}})})();(function(){var d=window.AmCharts;d.AmBalloon=d.Class({construct:function(a){this.cname="AmBalloon";this.enabled=!0;this.fillColor="#FFFFFF";this.fillAlpha=.8;this.borderThickness=2;this.borderColor="#FFFFFF";this.borderAlpha=1;this.cornerRadius=0;this.maxWidth=220;this.horizontalPadding=8;this.verticalPadding=4;this.pointerWidth=6;this.pointerOrientation="V";this.color="#000000";this.adjustBorderColor=!0;this.show=this.follow=this.showBullet=!1;this.bulletSize=3;this.shadowAlpha=.4;this.shadowColor= +"#000000";this.fadeOutDuration=this.animationDuration=.3;this.fixedPosition=!0;this.offsetY=6;this.offsetX=1;this.textAlign="center";this.disableMouseEvents=!0;this.deltaSignX=this.deltaSignY=1;d.isModern||(this.offsetY*=1.5);this.sdy=this.sdx=0;d.applyTheme(this,a,this.cname)},draw:function(){var a=this.pointToX,b=this.pointToY;d.isModern||(this.drop=!1);var c=this.chart;d.VML&&(this.fadeOutDuration=0);this.xAnim&&c.stopAnim(this.xAnim);this.yAnim&&c.stopAnim(this.yAnim);this.sdy=this.sdx=0;if(!isNaN(a)){var e= +this.follow,h=c.container,f=this.set;d.remove(f);this.removeDiv();f=h.set();f.node.style.pointerEvents="none";this.set=f;this.mainSet?(this.mainSet.push(this.set),this.sdx=this.mainSet.x,this.sdy=this.mainSet.y):c.balloonsSet.push(f);if(this.show){var g=this.l,k=this.t,l=this.r,m=this.b,n=this.balloonColor,q=this.fillColor,p=this.borderColor,t=q;void 0!=n&&(this.adjustBorderColor?t=p=n:q=n);var r=this.horizontalPadding,w=this.verticalPadding,x=this.pointerWidth,y=this.pointerOrientation,u=this.cornerRadius, +A=c.fontFamily,z=this.fontSize;void 0==z&&(z=c.fontSize);var n=document.createElement("div"),B=c.classNamePrefix;n.className=B+"-balloon-div";this.className&&(n.className=n.className+" "+B+"-balloon-div-"+this.className);B=n.style;this.disableMouseEvents&&(B.pointerEvents="none");B.position="absolute";var D=this.minWidth,C="";isNaN(D)||(C="min-width:"+(D-2*r)+"px; ");n.innerHTML='
'+this.text+"
";c.chartDiv.appendChild(n);this.textDiv=n;var J=n.offsetWidth,H=n.offsetHeight;n.clientHeight&&(J=n.clientWidth,H=n.clientHeight);A=H+2*w;C=J+2*r;!isNaN(D)&&CA&&(x=A/2),z=b-A/2,a=m&&(z=m-A); +zl&&(D=l-C);var k=z+w,m=D+r,O=this.shadowAlpha,Q=this.shadowColor,r=this.borderThickness,ia=this.bulletSize,I,w=this.fillAlpha,Z=this.borderAlpha;this.showBullet&&(I=d.circle(h,ia,t,w),f.push(I));this.drop?(g=C/1.6,l=0,"V"==y&&(y="down"),"H"==y&&(y="left"),"down"==y&&(D=a+1,z=b-g-g/3),"up"==y&&(l=180,D=a+1,z=b+g+g/3),"left"==y&&(l=270,D=a+g+g/3+2,z=b),"right"==y&&(l=90,D=a-g-g/3+2,z=b),k=z-H/2+1,m=D-J/2-1,q=d.drop(h,g,l,q,w,r,p,Z)):0C-x&&(g=C-x),gA-x&&(y=A-x),ya?C:a-D,C,C,0,0,C]),0this.r-e.width&&(a=this.r-e.width);dthis.processCount&&(this.processCount=1);var b=a.length/this.processCount;this.parseCount=Math.ceil(b)-1;for(var c=0;ca.length&&(c=a.length);var h=this.graphs,f={},g=this.seriesIdField;g||(g=this.categoryField);var k=!1,l,m=this.categoryAxis,n,q,p;m&&(k=m.parseDates,n=m.forceShowField,p=m.classNameField,q=m.labelColorField,l=m.categoryFunction);var t,r,w={},x;k&&(t=d.extractPeriod(m.minPeriod), +r=t.period,t=t.count,x=d.getPeriodDuration(r,t));var y={};this.lookupTable=y;var u,A=this.dataDateFormat,z={};for(u=b;u=x*Q&&(z[O].gap=!0);this.processFields(b,I,Z);I.category=B.category;I.serialDataItem=B;I.graph=b;B.axes[H].graphs[O]= +I;w[O]=B.time;z[O]=I}}}this.chartData[u]=B}if(this.parseCount==e){for(a=0;ab?this.colors[b]:a.lineColorR?a.lineColorR:d.randomColor();a.lineColorR=c}a.fillColorsR=a.fillColors?a.fillColors:a.lineColorR;a.bulletBorderColorR=a.bulletBorderColor?a.bulletBorderColor:a.useLineColorForBulletBorder?a.lineColorR:a.bulletColor;a.bulletColorR=a.bulletColor?a.bulletColor:a.lineColorR;if(c=this.patterns)a.pattern=c[b]},handleLegendEvent:function(a){var b=a.type;a=a.dataItem;if(!this.legend.data&&a){var c=a.hidden,d=a.showBalloon;switch(b){case "clickMarker":this.textClickEnabled&& +(d?this.hideGraphsBalloon(a):this.showGraphsBalloon(a));break;case "clickLabel":d?this.hideGraphsBalloon(a):this.showGraphsBalloon(a);break;case "rollOverItem":c||this.highlightGraph(a);break;case "rollOutItem":c||this.unhighlightGraph();break;case "hideItem":this.hideGraph(a);break;case "showItem":this.showGraph(a)}}},highlightGraph:function(a){var b=this.graphs,c,d=.2;this.legend&&(d=this.legend.rollOverGraphAlpha);if(1!=d)for(c=0;c=b&&(b=.001);if(void 0==h||0===h)h=.01;void 0===f&&(f="#000000");void 0===g&&(g=0);e={fill:c,stroke:f,"fill-opacity":e,"stroke-width":h,"stroke-opacity":g};a=isNaN(l)?a.circle(0,0,b).attr(e):a.ellipse(0,0,b,l).attr(e);k&&a.gradient("radialGradient",[c,d.adjustLuminosity(c,-.6)]);return a};d.text=function(a,b,c,e,h,f,g,k){f||(f="middle");"right"==f&&(f="end");"left"==f&&(f="start");isNaN(k)&&(k=1);void 0!==b&&(b=String(b),d.isIE&& +!d.isModern&&(b=b.replace("&","&"),b=b.replace("&","&")));c={fill:c,"font-family":e,"font-size":h+"px",opacity:k};!0===g&&(c["font-weight"]="bold");c["text-anchor"]=f;return a.text(b,c)};d.polygon=function(a,b,c,e,h,f,g,k,l,m,n){isNaN(f)&&(f=.01);isNaN(k)&&(k=h);var q=e,p=!1;"object"==typeof q&&1b&&(b=Math.abs(b),t=-b);0>c&&(c=Math.abs(c),r=-c);t+=d.dx;r+=d.dy;h={fill:q,stroke:g,"fill-opacity":h,"stroke-opacity":k};void 0!==n&&0=y&&(h=y);var u=1/180*Math.PI,y=b+Math.sin(e*u)*k,A=c-Math.cos(e*u)*w,z=b+Math.sin(e*u)*f,B=c-Math.cos(e*u)*g,D=b+Math.sin((e+h)*u)*f,C=c-Math.cos((e+h)*u)*g,J=b+Math.sin((e+h)*u)*k,u=c-Math.cos((e+h)*u)*w,H={fill:d.adjustLuminosity(m.fill,-.2),"stroke-opacity":0,"fill-opacity":m["fill-opacity"]},S=0;180Math.abs(h)&&1>=Math.abs(D-z)&&1>=Math.abs(C-B)&&(O=!0));h="";var Q;q&&(H["fill-opacity"]=0,H["stroke-opacity"]=m["stroke-opacity"]/2,H.stroke=m.stroke);if(0a.length&&(a=String(a[0])+String(a[0])+String(a[1])+String(a[1])+String(a[2])+String(a[2]));b=b||0;var c="#",e,h;for(h=0;3>h;h++)e=parseInt(a.substr(2*h,2),16),e=Math.round(Math.min(Math.max(0,e+e*b),255)).toString(16),c+=("00"+ +e).substr(e.length);return c}})();(function(){var d=window.AmCharts;d.Bezier=d.Class({construct:function(a,b,c,e,h,f,g,k,l,m,n){var q,p;"object"==typeof g&&1c&&(k=c);b.push({x:l.x-k/h,y:l.y-e/f});b.push({x:l.x,y:l.y});b.push({x:l.x+ +k/h,y:l.y+e/f})}e=a[a.length-1].y-a[a.length-2].y;c=a[a.length-1].x-a[a.length-2].x;b.push({x:a[a.length-1].x-c/h,y:a[a.length-1].y-e/f});b.push({x:a[a.length-1].x,y:a[a.length-1].y});return b},drawBeziers:function(a){var b="",c;for(c=0;c<(a.length-1)/3;c++)b+=this.drawBezierMidpoint(a[3*c],a[3*c+1],a[3*c+2],a[3*c+3]);return b},drawBezierMidpoint:function(a,b,c,d){var h=Math.round,f=this.getPointOnSegment(a,b,.75),g=this.getPointOnSegment(d,c,.75),k=(d.x-a.x)/16,l=(d.y-a.y)/16,m=this.getPointOnSegment(a, +b,.375);a=this.getPointOnSegment(f,g,.375);a.x-=k;a.y-=l;b=this.getPointOnSegment(g,f,.375);b.x+=k;b.y+=l;c=this.getPointOnSegment(d,c,.375);k=this.getMiddle(m,a);f=this.getMiddle(f,g);g=this.getMiddle(b,c);m=" Q"+h(m.x)+","+h(m.y)+","+h(k.x)+","+h(k.y);m+=" Q"+h(a.x)+","+h(a.y)+","+h(f.x)+","+h(f.y);m+=" Q"+h(b.x)+","+h(b.y)+","+h(g.x)+","+h(g.y);return m+=" Q"+h(c.x)+","+h(c.y)+","+h(d.x)+","+h(d.y)},getMiddle:function(a,b){return{x:(a.x+b.x)/2,y:(a.y+b.y)/2}},getPointOnSegment:function(a,b,c){return{x:a.x+ +(b.x-a.x)*c,y:a.y+(b.y-a.y)*c}}})})();(function(){var d=window.AmCharts;d.AmDraw=d.Class({construct:function(a,b,c,e){d.SVG_NS="http://www.w3.org/2000/svg";d.SVG_XLINK="http://www.w3.org/1999/xlink";d.hasSVG=!!document.createElementNS&&!!document.createElementNS(d.SVG_NS,"svg").createSVGRect;1>b&&(b=10);1>c&&(c=10);this.div=a;this.width=b;this.height=c;this.rBin=document.createElement("div");d.hasSVG?(d.SVG=!0,b=this.createSvgElement("svg"),a.appendChild(b),this.container=b,this.addDefs(e),this.R=new d.SVGRenderer(this)):d.isIE&&d.VMLRenderer&& +(d.VML=!0,d.vmlStyleSheet||(document.namespaces.add("amvml","urn:schemas-microsoft-com:vml"),31>document.styleSheets.length?(b=document.createStyleSheet(),b.addRule(".amvml","behavior:url(#default#VML); display:inline-block; antialias:true"),d.vmlStyleSheet=b):document.styleSheets[0].addRule(".amvml","behavior:url(#default#VML); display:inline-block; antialias:true")),this.container=a,this.R=new d.VMLRenderer(this,e),this.R.disableSelection(a))},createSvgElement:function(a){return document.createElementNS(d.SVG_NS, +a)},circle:function(a,b,c,e){var h=new d.AmDObject("circle",this);h.attr({r:c,cx:a,cy:b});this.addToContainer(h.node,e);return h},ellipse:function(a,b,c,e,h){var f=new d.AmDObject("ellipse",this);f.attr({rx:c,ry:e,cx:a,cy:b});this.addToContainer(f.node,h);return f},setSize:function(a,b){0c&&(c=1);1>e&&(e=1);k.attr({x:a,y:b,width:c,height:e,rx:h,ry:h,"stroke-width":f});this.addToContainer(k.node,g);return k},image:function(a,b,c,e,h,f){var g=new d.AmDObject("image",this);g.attr({x:b,y:c,width:e,height:h});this.R.path(g,a);this.addToContainer(g.node,f);return g},addToContainer:function(a,b){b||(b=this.container);b.appendChild(a)},text:function(a,b,c){return this.R.text(a,b,c)},path:function(a,b,c,e){var h=new d.AmDObject("path",this);e||(e="100,100"); +h.attr({cs:e});c?h.attr({dd:a}):h.attr({d:a});this.addToContainer(h.node,b);return h},set:function(a){return this.R.set(a)},remove:function(a){if(a){var b=this.rBin;b.appendChild(a);b.innerHTML=""}},renderFix:function(){var a=this.container,b=a.style;b.top="0px";b.left="0px";try{var c=a.getBoundingClientRect(),d=c.left-Math.round(c.left),h=c.top-Math.round(c.top);d&&(b.left=d+"px");h&&(b.top=h+"px")}catch(f){}},update:function(){this.R.update()},addDefs:function(a){if(d.hasSVG){var b=this.createSvgElement("desc"), +c=this.container;c.setAttribute("version","1.1");c.style.position="absolute";this.setSize(this.width,this.height);if(a.accessibleTitle){var e=this.createSvgElement("title");e.appendChild(document.createTextNode(a.accessibleTitle));c.appendChild(e)}d.rtl&&(c.setAttribute("direction","rtl"),c.style.left="auto",c.style.right="0px");a&&(a.addCodeCredits&&b.appendChild(document.createTextNode("JavaScript chart by amCharts "+a.version)),c.appendChild(b),a.defs&&(b=this.createSvgElement("defs"),c.appendChild(b), +d.parseDefs(a.defs,b),this.defs=b))}}})})();(function(){var d=window.AmCharts;d.AmDObject=d.Class({construct:function(a,b){this.D=b;this.R=b.R;this.node=this.R.create(this,a);this.y=this.x=0;this.scale=1},attr:function(a){this.R.attr(this,a);return this},getAttr:function(a){return this.node.getAttribute(a)},setAttr:function(a,b){this.R.setAttr(this,a,b);return this},clipRect:function(a,b,c,d){this.R.clipRect(this,a,b,c,d)},translate:function(a,b,c,d){d||(a=Math.round(a),b=Math.round(b));this.R.move(this,a,b,c);this.x=a;this.y=b;this.scale= +c;this.angle&&this.rotate(this.angle)},rotate:function(a,b){this.R.rotate(this,a,b);this.angle=a},animate:function(a,b,c){for(var e in a)if(a.hasOwnProperty(e)){var h=e,f=a[e];c=d.getEffect(c);this.R.animate(this,h,f,b,c)}},push:function(a){if(a){var b=this.node;b.appendChild(a.node);var c=a.clipPath;c&&b.appendChild(c);(a=a.grad)&&b.appendChild(a)}},text:function(a){this.R.setText(this,a)},remove:function(){this.stop();this.R.remove(this)},clear:function(){var a=this.node;if(a.hasChildNodes())for(;1<= +a.childNodes.length;)a.removeChild(a.firstChild)},hide:function(){this.setAttr("visibility","hidden")},show:function(){this.setAttr("visibility","visible")},getBBox:function(){return this.R.getBBox(this)},toFront:function(){var a=this.node;if(a){this.prevNextNode=a.nextSibling;var b=a.parentNode;b&&b.appendChild(a)}},toPrevious:function(){var a=this.node;a&&this.prevNextNode&&(a=a.parentNode)&&a.insertBefore(this.prevNextNode,null)},toBack:function(){var a=this.node;if(a){this.prevNextNode=a.nextSibling; +var b=a.parentNode;if(b){var c=b.firstChild;c&&b.insertBefore(a,c)}}},mouseover:function(a){this.R.addListener(this,"mouseover",a);return this},mouseout:function(a){this.R.addListener(this,"mouseout",a);return this},click:function(a){this.R.addListener(this,"click",a);return this},dblclick:function(a){this.R.addListener(this,"dblclick",a);return this},mousedown:function(a){this.R.addListener(this,"mousedown",a);return this},mouseup:function(a){this.R.addListener(this,"mouseup",a);return this},touchmove:function(a){this.R.addListener(this, +"touchmove",a);return this},touchstart:function(a){this.R.addListener(this,"touchstart",a);return this},touchend:function(a){this.R.addListener(this,"touchend",a);return this},keyup:function(a){this.R.addListener(this,"keyup",a);return this},focus:function(a){this.R.addListener(this,"focus",a);return this},blur:function(a){this.R.addListener(this,"blur",a);return this},contextmenu:function(a){this.node.addEventListener?this.node.addEventListener("contextmenu",a,!0):this.R.addListener(this,"contextmenu", +a);return this},stop:function(){d.removeFromArray(this.R.animations,this.an_translate);d.removeFromArray(this.R.animations,this.an_y);d.removeFromArray(this.R.animations,this.an_x)},length:function(){return this.node.childNodes.length},gradient:function(a,b,c){this.R.gradient(this,a,b,c)},pattern:function(a,b,c){a&&this.R.pattern(this,a,b,c)}})})();(function(){var d=window.AmCharts;d.VMLRenderer=d.Class({construct:function(a,b){this.chart=b;this.D=a;this.cNames={circle:"oval",ellipse:"oval",rect:"roundrect",path:"shape"};this.styleMap={x:"left",y:"top",width:"width",height:"height","font-family":"fontFamily","font-size":"fontSize",visibility:"visibility"}},create:function(a,b){var c;if("group"==b)c=document.createElement("div"),a.type="div";else if("text"==b)c=document.createElement("div"),a.type="text";else if("image"==b)c=document.createElement("img"), +a.type="image";else{a.type="shape";a.shapeType=this.cNames[b];c=document.createElement("amvml:"+this.cNames[b]);var d=document.createElement("amvml:stroke");c.appendChild(d);a.stroke=d;var h=document.createElement("amvml:fill");c.appendChild(h);a.fill=h;h.className="amvml";d.className="amvml";c.className="amvml"}c.style.position="absolute";c.style.top=0;c.style.left=0;return c},path:function(a,b){a.node.setAttribute("src",b)},setAttr:function(a,b,c){if(void 0!==c){var e;8===document.documentMode&& +(e=!0);var h=a.node,f=a.type,g=h.style;"r"==b&&(g.width=2*c,g.height=2*c);"oval"==a.shapeType&&("rx"==b&&(g.width=2*c),"ry"==b&&(g.height=2*c));"roundrect"==a.shapeType&&("width"!=b&&"height"!=b||--c);"cursor"==b&&(g.cursor=c);"cx"==b&&(g.left=c-d.removePx(g.width)/2);"cy"==b&&(g.top=c-d.removePx(g.height)/2);var k=this.styleMap[b];"width"==k&&0>c&&(c=0);void 0!==k&&(g[k]=c);"text"==f&&("text-anchor"==b&&(a.anchor=c,k=h.clientWidth,"end"==c&&(g.marginLeft=-k+"px"),"middle"==c&&(g.marginLeft=-(k/2)+ +"px",g.textAlign="center"),"start"==c&&(g.marginLeft="0px")),"fill"==b&&(g.color=c),"font-weight"==b&&(g.fontWeight=c));if(g=a.children)for(k=0;kc&&(g="dot"),3<=c&&6>=c&&(g="dash"),6g&&(b+=g);0>k&&(c+=k)}return{x:b,y:c,width:d,height:h}},setText:function(a,b){var c=a.node;c&&(c.innerHTML=b);this.setAttr(a,"text-anchor",a.anchor)},addListener:function(a,b,c){a.node["on"+b]=c},move:function(a,b,c){var e=a.node,h=e.style;"text"==a.type&&(c-=d.removePx(h.fontSize)/2-1);"oval"==a.shapeType&&(b-=d.removePx(h.width)/2,c-=d.removePx(h.height)/2);a=a.bw;isNaN(a)||(b-=a,c-=a);isNaN(b)||isNaN(c)||(e.style.left=b+"px",e.style.top= +c+"px")},svgPathToVml:function(a){var b=a.split(" ");a="";var c,d=Math.round,h;for(h=0;hthis.fontSize&&(this.ly=h/2-1);0p&&(p=z);u=u.height;u>t&&(t=u)}var z=t=0,B=f,D=0,C=0;for(A=0;AC&&(C=u.height);H+u.width>q&&0=l&&(z=0,t++,D=D+C+m,B=f,C=0);x.push(J)}u=x.getBBox();l=u.height+2*m-1;"left"==a||"right"==a?(n=u.width+2*f,k=n+b+c,g.style.width=k+"px",this.ieW=k):n=k-b-c-1;c=d.polygon(this.container,[0,n,n,0],[0,0,l,l],this.backgroundColor,this.backgroundAlpha,1,this.borderColor,this.borderAlpha);d.setCN(this.chart,c,"legend-bg");w.push(c);w.translate(b, +e);c.toBack();b=f;if("top"==a||"bottom"==a||"absolute"==a||"outside"==a)"center"==this.align?b=f+(n-u.width)/2:"right"==this.align&&(b=f+n-u.width);x.translate(b,m+1);this.titleHeight>l&&(l=this.titleHeight);a=l+e+h+1;0>a&&(a=0);a>this.chart.divRealHeight&&(g.style.top="0px");g.style.height=Math.round(a)+"px";r.setSize(this.divWidth,a)},createEntry:function(a){if(!1!==a.visibleInLegend&&!a.hideFromLegend){var b=this,c=b.chart,e=a.markerType;a.legendEntryWidth=b.markerSize;e||(e=b.markerType);var h= +a.color,f=a.alpha;a.legendKeyColor&&(h=a.legendKeyColor());a.legendKeyAlpha&&(f=a.legendKeyAlpha());var g;!0===a.hidden&&(g=h=b.markerDisabledColor);var k=a.pattern,l=a.customMarker;l||(l=b.customMarker);var m=b.container,n=b.markerSize,q=0,p=0,t=n/2;if(b.useGraphSettings){e=a.type;b.switchType=void 0;if("line"==e||"step"==e||"smoothedLine"==e||"ohlc"==e)k=m.set(),a.hidden||(h=a.lineColorR,g=a.bulletBorderColorR),q=d.line(m,[0,2*n],[n/2,n/2],h,a.lineAlpha,a.lineThickness,a.dashLength),d.setCN(c,q, +"graph-stroke"),k.push(q),a.bullet&&(a.hidden||(h=a.bulletColorR),q=d.bullet(m,a.bullet,a.bulletSize,h,a.bulletAlpha,a.bulletBorderThickness,g,a.bulletBorderAlpha))&&(d.setCN(c,q,"graph-bullet"),q.translate(n+1,n/2),k.push(q)),t=0,q=n,p=n/3;else{var r;a.getGradRotation&&(r=a.getGradRotation(),0===r&&(r=180));q=a.fillColorsR;!0===a.hidden&&(q=h);if(k=b.createMarker("rectangle",q,a.fillAlphas,a.lineThickness,h,a.lineAlpha,r,k,a.dashLength))t=n,k.translate(t,n/2);q=n}d.setCN(c,k,"graph-"+e);d.setCN(c, +k,"graph-"+a.id)}else if(l)k=m.image(l,0,0,n,n);else{var w;isNaN(b.gradientRotation)||(w=180+b.gradientRotation);(k=b.createMarker(e,h,f,void 0,void 0,void 0,w,k))&&k.translate(n/2,n/2)}d.setCN(c,k,"legend-marker");b.addListeners(k,a);m=m.set([k]);b.switchable&&a.switchable&&m.setAttr("cursor","pointer");void 0!==a.id&&d.setCN(c,m,"legend-item-"+a.id);d.setCN(c,m,a.className,!0);g=b.switchType;var x;g&&"none"!=g&&0c&&(d="00"+c);10<=c&&100>c&&(d="0"+c);a=a.replace(/fff/g,d)}return a};d.extractPeriod=function(a){var b=d.stripNumbers(a),c=1;b!=a&&(c=Number(a.slice(0,a.indexOf(b))));return{period:b,count:c}};d.getDate=function(a,b,c){return a instanceof Date?d.newDate(a,c):b&&isNaN(a)?d.stringToDate(a,b):new Date(a)};d.daysInMonth=function(a){return(new Date(a.getYear(),a.getMonth()+ +1,0)).getDate()};d.newDate=function(a,b){return b&&-1==b.indexOf("fff")?new Date(a):new Date(a.getFullYear(),a.getMonth(),a.getDate(),a.getHours(),a.getMinutes(),a.getSeconds(),a.getMilliseconds())};d.resetDateToMin=function(a,b,c,e){void 0===e&&(e=1);var h,f,g,k,l,m,n;d.useUTC?(h=a.getUTCFullYear(),f=a.getUTCMonth(),g=a.getUTCDate(),k=a.getUTCHours(),l=a.getUTCMinutes(),m=a.getUTCSeconds(),n=a.getUTCMilliseconds(),a=a.getUTCDay()):(h=a.getFullYear(),f=a.getMonth(),g=a.getDate(),k=a.getHours(),l= +a.getMinutes(),m=a.getSeconds(),n=a.getMilliseconds(),a=a.getDay());switch(b){case "YYYY":h=Math.floor(h/c)*c;f=0;g=1;n=m=l=k=0;break;case "MM":f=Math.floor(f/c)*c;g=1;n=m=l=k=0;break;case "WW":g=a>=e?g-a+e:g-(7+a)+e;n=m=l=k=0;break;case "DD":n=m=l=k=0;break;case "hh":k=Math.floor(k/c)*c;n=m=l=0;break;case "mm":l=Math.floor(l/c)*c;n=m=0;break;case "ss":m=Math.floor(m/c)*c;n=0;break;case "fff":n=Math.floor(n/c)*c}d.useUTC?(a=new Date,a.setUTCFullYear(h,f,g),a.setUTCHours(k,l,m,n)):a=new Date(h,f,g, +k,l,m,n);return a};d.getPeriodDuration=function(a,b){void 0===b&&(b=1);var c;switch(a){case "YYYY":c=316224E5;break;case "MM":c=26784E5;break;case "WW":c=6048E5;break;case "DD":c=864E5;break;case "hh":c=36E5;break;case "mm":c=6E4;break;case "ss":c=1E3;break;case "fff":c=1}return c*b};d.intervals={s:{nextInterval:"ss",contains:1E3},ss:{nextInterval:"mm",contains:60,count:0},mm:{nextInterval:"hh",contains:60,count:1},hh:{nextInterval:"DD",contains:24,count:2},DD:{nextInterval:"",contains:Infinity,count:3}}; +d.getMaxInterval=function(a,b){var c=d.intervals;return a>=c[b].contains?(a=Math.round(a/c[b].contains),b=c[b].nextInterval,d.getMaxInterval(a,b)):"ss"==b?c[b].nextInterval:b};d.dayNames="Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" ");d.shortDayNames="Sun Mon Tue Wed Thu Fri Sat".split(" ");d.monthNames="January February March April May June July August September October November December".split(" ");d.shortMonthNames="Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "); +d.getWeekNumber=function(a){a=new Date(a);a.setHours(0,0,0);a.setDate(a.getDate()+4-(a.getDay()||7));var b=new Date(a.getFullYear(),0,1);return Math.ceil(((a-b)/864E5+1)/7)};d.stringToDate=function(a,b){var c={},e=[{pattern:"YYYY",period:"year"},{pattern:"YY",period:"year"},{pattern:"MM",period:"month"},{pattern:"M",period:"month"},{pattern:"DD",period:"date"},{pattern:"D",period:"date"},{pattern:"JJ",period:"hours"},{pattern:"J",period:"hours"},{pattern:"HH",period:"hours"},{pattern:"H",period:"hours"}, +{pattern:"KK",period:"hours"},{pattern:"K",period:"hours"},{pattern:"LL",period:"hours"},{pattern:"L",period:"hours"},{pattern:"NN",period:"minutes"},{pattern:"N",period:"minutes"},{pattern:"SS",period:"seconds"},{pattern:"S",period:"seconds"},{pattern:"QQQ",period:"milliseconds"},{pattern:"QQ",period:"milliseconds"},{pattern:"Q",period:"milliseconds"}],h=!0,f=b.indexOf("AA");-1!=f&&(a.substr(f,2),"pm"==a.toLowerCase&&(h=!1));var f=b,g,k,l;for(l=0;lr&&(r="0"+r);b=b.replace(/JJ/g,r);b=b.replace(/J/g,q);r=k;0===r&&(r=24,-1!=b.indexOf("H")&&(f--,0===f&&(e=new Date(a),e.setDate(e.getDate()-1),h=e.getMonth(),f=e.getDate(),e=e.getFullYear())));a=h+1;9>h&&(a="0"+a);q=f;10>f&&(q="0"+f);var w=r;10>w&&(w="0"+w);b=b.replace(/HH/g,w);b=b.replace(/H/g,r);r=k;11w&&(w="0"+w);b=b.replace(/KK/g,w);b=b.replace(/K/g,r);r=k;0===r&&(r=12);12w&&(w="0"+w);b=b.replace(/LL/g,w);b=b.replace(/L/g,r); +r=l;10>r&&(r="0"+r);b=b.replace(/NN/g,r);b=b.replace(/N/g,l);l=m;10>l&&(l="0"+l);b=b.replace(/SS/g,l);b=b.replace(/S/g,m);m=n;10>m?m="00"+m:100>m&&(m="0"+m);l=n;10>l&&(l="00"+l);b=b.replace(/A/g,"@A@");b=b.replace(/QQQ/g,m);b=b.replace(/QQ/g,l);b=b.replace(/Q/g,n);b=b.replace(/YYYY/g,"@IIII@");b=b.replace(/YY/g,"@II@");b=b.replace(/MMMM/g,"@XXXX@");b=b.replace(/MMM/g,"@XXX@");b=b.replace(/MM/g,"@XX@");b=b.replace(/M/g,"@X@");b=b.replace(/DD/g,"@RR@");b=b.replace(/D/g,"@R@");b=b.replace(/EEEE/g,"@PPPP@"); +b=b.replace(/EEE/g,"@PPP@");b=b.replace(/EE/g,"@PP@");b=b.replace(/E/g,"@P@");b=b.replace(/@IIII@/g,e);b=b.replace(/@II@/g,p);b=b.replace(/@XXXX@/g,c.monthNames[h]);b=b.replace(/@XXX@/g,c.shortMonthNames[h]);b=b.replace(/@XX@/g,a);b=b.replace(/@X@/g,h+1);b=b.replace(/@RR@/g,q);b=b.replace(/@R@/g,f);b=b.replace(/@PPPP@/g,c.dayNames[g]);b=b.replace(/@PPP@/g,c.shortDayNames[g]);b=b.replace(/@PP@/g,t);b=b.replace(/@P@/g,g);return b=12>k?b.replace(/@A@/g,c.amString):b.replace(/@A@/g,c.pmString)};d.changeDate= +function(a,b,c,e,h){if(d.useUTC)return d.changeUTCDate(a,b,c,e,h);var f=-1;void 0===e&&(e=!0);void 0===h&&(h=!1);!0===e&&(f=1);switch(b){case "YYYY":a.setFullYear(a.getFullYear()+c*f);e||h||a.setDate(a.getDate()+1);break;case "MM":b=a.getMonth();a.setMonth(a.getMonth()+c*f);a.getMonth()>b+c*f&&a.setDate(a.getDate()-1);e||h||a.setDate(a.getDate()+1);break;case "DD":a.setDate(a.getDate()+c*f);break;case "WW":a.setDate(a.getDate()+c*f*7);break;case "hh":a.setHours(a.getHours()+c*f);break;case "mm":a.setMinutes(a.getMinutes()+ +c*f);break;case "ss":a.setSeconds(a.getSeconds()+c*f);break;case "fff":a.setMilliseconds(a.getMilliseconds()+c*f)}return a};d.changeUTCDate=function(a,b,c,d,h){var f=-1;void 0===d&&(d=!0);void 0===h&&(h=!1);!0===d&&(f=1);switch(b){case "YYYY":a.setUTCFullYear(a.getUTCFullYear()+c*f);d||h||a.setUTCDate(a.getUTCDate()+1);break;case "MM":b=a.getUTCMonth();a.setUTCMonth(a.getUTCMonth()+c*f);a.getUTCMonth()>b+c*f&&a.setUTCDate(a.getUTCDate()-1);d||h||a.setUTCDate(a.getUTCDate()+1);break;case "DD":a.setUTCDate(a.getUTCDate()+ +c*f);break;case "WW":a.setUTCDate(a.getUTCDate()+c*f*7);break;case "hh":a.setUTCHours(a.getUTCHours()+c*f);break;case "mm":a.setUTCMinutes(a.getUTCMinutes()+c*f);break;case "ss":a.setUTCSeconds(a.getUTCSeconds()+c*f);break;case "fff":a.setUTCMilliseconds(a.getUTCMilliseconds()+c*f)}return a}})(); diff --git a/iguana/js/amcharts/amstock.js b/iguana/js/amcharts/amstock.js new file mode 100755 index 000000000..fadcfa3dc --- /dev/null +++ b/iguana/js/amcharts/amstock.js @@ -0,0 +1,104 @@ +(function(){var d=window.AmCharts;d.AmStockChart=d.Class({construct:function(a){this.type="stock";this.cname="AmStockChart";d.addChart(this);this.version="3.20.4";this.theme=a;this.createEvents("buildStarted","zoomed","rollOverStockEvent","rollOutStockEvent","clickStockEvent","panelRemoved","dataUpdated","init","rendered","drawn","resized");this.colors="#FF6600 #FCD202 #B0DE09 #0D8ECF #2A0CD0 #CD0D74 #CC0000 #00CC00 #0000CC #DDDDDD #999999 #333333 #990000".split(" ");this.firstDayOfWeek=1;this.glueToTheEnd= +!1;this.dataSetCounter=-1;this.zoomOutOnDataSetChange=!1;this.panels=[];this.dataSets=[];this.chartCursors=[];this.comparedDataSets=[];this.classNamePrefix="amcharts";this.categoryAxesSettings=new d.CategoryAxesSettings(a);this.valueAxesSettings=new d.ValueAxesSettings(a);this.panelsSettings=new d.PanelsSettings(a);this.chartScrollbarSettings=new d.ChartScrollbarSettings(a);this.chartCursorSettings=new d.ChartCursorSettings(a);this.stockEventsSettings=new d.StockEventsSettings(a);this.legendSettings= +new d.LegendSettings(a);this.balloon=new d.AmBalloon(a);this.previousEndDate=new Date(0);this.previousStartDate=new Date(0);this.dataSetCount=this.graphCount=0;this.chartCreated=!1;this.processTimeout=0;this.autoResize=this.extendToFullPeriod=!0;d.applyTheme(this,a,this.cname)},write:function(a){var b=this;if(b.listeners)for(var c in b.listeners){var e=b.listeners[c];b.addListener(e.event,e.method)}b.fire({type:"buildStarted",chart:b});b.afterWriteTO&&clearTimeout(b.afterWriteTO);0c?this.colors[c]:d.randomColor())}!a&&d.ifArray(b)&&(this.mainDataSet=this.dataSets[0]);this.getSelections()},getLastDate:function(a){var b=d.getDate(a,this.dataDateFormat,"fff");a=this.categoryAxesSettings.minPeriod; +b=d.changeDate(b,this.categoryAxesSettings.minPeriod,1,!0).getTime();-1==a.indexOf("fff")&&--b;return new Date(b)},getFirstDate:function(a){a=d.getDate(a,this.dataDateFormat,"fff");return new Date(d.resetDateToMin(a,this.categoryAxesSettings.minPeriod,1,this.firstDayOfWeek))},updateData:function(){var a=this,b=a.mainDataSet;if(b){a.parsingData=!1;var c=a.categoryAxesSettings;-1==d.getItemIndex(c.minPeriod,c.groupToPeriods)&&c.groupToPeriods.unshift(c.minPeriod);var e=b.dataProvider;if(d.ifArray(e)){var h= +b.categoryField;a.firstDate=a.getFirstDate(e[0][h]);a.lastDate=a.getLastDate(e[e.length-1][h]);a.periodSelector&&a.periodSelector.setRanges(a.firstDate,a.lastDate);b.dataParsed||(a.parsingData=!0,0=y[t]||!y[t]){r[t]={};r[t].amCategoryIdField=String(d.resetDateToMin(E,F,H,e).getTime());var G;for(G=0;Gf&&(u=d.newDate(E,b),u=d.changeDate(u,F,H,!0), +u=d.resetDateToMin(u,F,H,e),y[t]=u.getTime());if(C==f)for(var I in B)B.hasOwnProperty(I)&&(r[t][I]=B[I]);r[t][p]=d.newDate(E,b)}else for(F=0;Fv[u+"High"]&&(v[u+"High"]=x),isNaN(v[u+"AbsHigh"])&&(v[u+"AbsHigh"]=x),Math.abs(x)>v[u+"AbsHigh"]&&(v[u+"AbsHigh"]=x),v[u+"Close"]=x,H=d.getDecimals(v[u+"Sum"]),G=d.getDecimals(x), +isNaN(v[u+"Sum"])&&(v[u+"Sum"]=0),v[u+"Sum"]+=x,v[u+"Sum"]=d.roundTo(v[u+"Sum"],Math.max(H,G)),v[u+"Count"]++,v[u+"Average"]=v[u+"Sum"]/v[u+"Count"])}}}a.agregatedDataProviders=m;d.ifArray(a.stockEvents)?0=l&&a=h-e))return ak.getTime()&&(a=k);b.getTime()k.getTime()&&(b=k);r=d.getItemIndex(p,g.groupToPeriods);p=m;m=c.choosePeriod(r,a,b);c.currentPeriod=m;var r=d.extractPeriod(m), +z=d.getPeriodDuration(r.period,r.count);1>b.getTime()-a.getTime()&&(a=new Date(b.getTime()-1));var A=d.newDate(a);c.extendToFullPeriod&&(A.getTime()-h.getTime()<.1*z&&(A=d.resetDateToMin(a,r.period,r.count,y)),k.getTime()-b.getTime()<.1*z&&(b=d.resetDateToMin(k,r.period,r.count,y),b=d.changeDate(b,r.period,r.count,!0)));for(h=0;hn&&0n.getTime()&&(l=d.getPeriodDuration("DD",1),g=new Date(n.getTime()-l)),g.getTime()h&&(e=h);h=this.theme;this.unselectButtons();var k;for(k=b.length-1;0<=k;k--){var m=b[k],g=m.button;m.startTime&&m.endTime&&c==m.startTime&&e==m.endTime&&(this.unselectButtons(),g.className="amChartsButtonSelected "+a.classNamePrefix+"-period-input-selected", +h&&d.applyStyles(g.style,h.PeriodButtonSelected))}}this.skipMark=!1},unselectButtons:function(){var a=this.chart,b=this.periods,c,e=this.theme;for(c=b.length-1;0<=c;c--){var h=b[c].button;h.className="amChartsButton "+a.classNamePrefix+"-period-input";e&&d.applyStyles(h.style,e.PeriodButton)}},setDefaultPeriod:function(){var a=this.periods,b;if(this.chart.chartCreated)for(b=0;ba?(e=this.startTime+e*d,d=this.endTime+1*d):(e=this.startTime-e*d,d=this.endTime-1*d);ethis.lastTime&&(d=this.lastTime);ethis.availableSpace&&(this.stackDown=!0);this.set=a.set();this.cset=a.set();this.set.push(this.cset);this.set.doNotScale=!0;a=0;var c;for(c=0;c + + + + + + + + + + + + + + diff --git a/iguana/js/amcharts/images/dragIconRectBigBlack.png b/iguana/js/amcharts/images/dragIconRectBigBlack.png new file mode 100755 index 000000000..0d575c83f Binary files /dev/null and b/iguana/js/amcharts/images/dragIconRectBigBlack.png differ diff --git a/iguana/js/amcharts/images/dragIconRectBigBlack.svg b/iguana/js/amcharts/images/dragIconRectBigBlack.svg new file mode 100755 index 000000000..2771b3559 --- /dev/null +++ b/iguana/js/amcharts/images/dragIconRectBigBlack.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/iguana/js/amcharts/images/dragIconRectBigBlackH.png b/iguana/js/amcharts/images/dragIconRectBigBlackH.png new file mode 100755 index 000000000..293f19ff8 Binary files /dev/null and b/iguana/js/amcharts/images/dragIconRectBigBlackH.png differ diff --git a/iguana/js/amcharts/images/dragIconRectBigBlackH.svg b/iguana/js/amcharts/images/dragIconRectBigBlackH.svg new file mode 100755 index 000000000..2d09e5268 --- /dev/null +++ b/iguana/js/amcharts/images/dragIconRectBigBlackH.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/iguana/js/amcharts/images/dragIconRectBigH.png b/iguana/js/amcharts/images/dragIconRectBigH.png new file mode 100755 index 000000000..02e58a60d Binary files /dev/null and b/iguana/js/amcharts/images/dragIconRectBigH.png differ diff --git a/iguana/js/amcharts/images/dragIconRectBigH.svg b/iguana/js/amcharts/images/dragIconRectBigH.svg new file mode 100755 index 000000000..6535b0a01 --- /dev/null +++ b/iguana/js/amcharts/images/dragIconRectBigH.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/iguana/js/amcharts/images/dragIconRectSmall.png b/iguana/js/amcharts/images/dragIconRectSmall.png new file mode 100755 index 000000000..21e413e8d Binary files /dev/null and b/iguana/js/amcharts/images/dragIconRectSmall.png differ diff --git a/iguana/js/amcharts/images/dragIconRectSmall.svg b/iguana/js/amcharts/images/dragIconRectSmall.svg new file mode 100755 index 000000000..307092341 --- /dev/null +++ b/iguana/js/amcharts/images/dragIconRectSmall.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/iguana/js/amcharts/images/dragIconRectSmallBlack.png b/iguana/js/amcharts/images/dragIconRectSmallBlack.png new file mode 100755 index 000000000..ad102552a Binary files /dev/null and b/iguana/js/amcharts/images/dragIconRectSmallBlack.png differ diff --git a/iguana/js/amcharts/images/dragIconRectSmallBlack.svg b/iguana/js/amcharts/images/dragIconRectSmallBlack.svg new file mode 100755 index 000000000..a7f17495f --- /dev/null +++ b/iguana/js/amcharts/images/dragIconRectSmallBlack.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/iguana/js/amcharts/images/dragIconRectSmallBlackH.png b/iguana/js/amcharts/images/dragIconRectSmallBlackH.png new file mode 100755 index 000000000..feb6527f5 Binary files /dev/null and b/iguana/js/amcharts/images/dragIconRectSmallBlackH.png differ diff --git a/iguana/js/amcharts/images/dragIconRectSmallBlackH.svg b/iguana/js/amcharts/images/dragIconRectSmallBlackH.svg new file mode 100755 index 000000000..bf664af6d --- /dev/null +++ b/iguana/js/amcharts/images/dragIconRectSmallBlackH.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/iguana/js/amcharts/images/dragIconRectSmallH.png b/iguana/js/amcharts/images/dragIconRectSmallH.png new file mode 100755 index 000000000..93674740a Binary files /dev/null and b/iguana/js/amcharts/images/dragIconRectSmallH.png differ diff --git a/iguana/js/amcharts/images/dragIconRectSmallH.svg b/iguana/js/amcharts/images/dragIconRectSmallH.svg new file mode 100755 index 000000000..1aefbf910 --- /dev/null +++ b/iguana/js/amcharts/images/dragIconRectSmallH.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/iguana/js/amcharts/images/dragIconRoundBig.png b/iguana/js/amcharts/images/dragIconRoundBig.png new file mode 100755 index 000000000..794796a58 Binary files /dev/null and b/iguana/js/amcharts/images/dragIconRoundBig.png differ diff --git a/iguana/js/amcharts/images/dragIconRoundBig.svg b/iguana/js/amcharts/images/dragIconRoundBig.svg new file mode 100755 index 000000000..9144b9329 --- /dev/null +++ b/iguana/js/amcharts/images/dragIconRoundBig.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/iguana/js/amcharts/images/dragIconRoundBigBlack.png b/iguana/js/amcharts/images/dragIconRoundBigBlack.png new file mode 100755 index 000000000..047930ffa Binary files /dev/null and b/iguana/js/amcharts/images/dragIconRoundBigBlack.png differ diff --git a/iguana/js/amcharts/images/dragIconRoundBigBlack.svg b/iguana/js/amcharts/images/dragIconRoundBigBlack.svg new file mode 100755 index 000000000..7aaacc5e3 --- /dev/null +++ b/iguana/js/amcharts/images/dragIconRoundBigBlack.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/iguana/js/amcharts/images/dragIconRoundBigBlackH.png b/iguana/js/amcharts/images/dragIconRoundBigBlackH.png new file mode 100755 index 000000000..54120057a Binary files /dev/null and b/iguana/js/amcharts/images/dragIconRoundBigBlackH.png differ diff --git a/iguana/js/amcharts/images/dragIconRoundBigBlackH.svg b/iguana/js/amcharts/images/dragIconRoundBigBlackH.svg new file mode 100755 index 000000000..92616984e --- /dev/null +++ b/iguana/js/amcharts/images/dragIconRoundBigBlackH.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/iguana/js/amcharts/images/dragIconRoundBigH.png b/iguana/js/amcharts/images/dragIconRoundBigH.png new file mode 100755 index 000000000..5cbee673d Binary files /dev/null and b/iguana/js/amcharts/images/dragIconRoundBigH.png differ diff --git a/iguana/js/amcharts/images/dragIconRoundBigH.svg b/iguana/js/amcharts/images/dragIconRoundBigH.svg new file mode 100755 index 000000000..1daa258cd --- /dev/null +++ b/iguana/js/amcharts/images/dragIconRoundBigH.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/iguana/js/amcharts/images/dragIconRoundSmall.png b/iguana/js/amcharts/images/dragIconRoundSmall.png new file mode 100755 index 000000000..05703ebfb Binary files /dev/null and b/iguana/js/amcharts/images/dragIconRoundSmall.png differ diff --git a/iguana/js/amcharts/images/dragIconRoundSmall.svg b/iguana/js/amcharts/images/dragIconRoundSmall.svg new file mode 100755 index 000000000..083d819b6 --- /dev/null +++ b/iguana/js/amcharts/images/dragIconRoundSmall.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/iguana/js/amcharts/images/dragIconRoundSmallBlack.png b/iguana/js/amcharts/images/dragIconRoundSmallBlack.png new file mode 100755 index 000000000..76c07d2c9 Binary files /dev/null and b/iguana/js/amcharts/images/dragIconRoundSmallBlack.png differ diff --git a/iguana/js/amcharts/images/dragIconRoundSmallBlack.svg b/iguana/js/amcharts/images/dragIconRoundSmallBlack.svg new file mode 100755 index 000000000..3ab0d5c94 --- /dev/null +++ b/iguana/js/amcharts/images/dragIconRoundSmallBlack.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/iguana/js/amcharts/images/dragIconRoundSmallBlackH.png b/iguana/js/amcharts/images/dragIconRoundSmallBlackH.png new file mode 100755 index 000000000..e7efe4629 Binary files /dev/null and b/iguana/js/amcharts/images/dragIconRoundSmallBlackH.png differ diff --git a/iguana/js/amcharts/images/dragIconRoundSmallBlackH.svg b/iguana/js/amcharts/images/dragIconRoundSmallBlackH.svg new file mode 100755 index 000000000..f37f32b69 --- /dev/null +++ b/iguana/js/amcharts/images/dragIconRoundSmallBlackH.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/iguana/js/amcharts/images/dragIconRoundSmallH.png b/iguana/js/amcharts/images/dragIconRoundSmallH.png new file mode 100755 index 000000000..e04163d89 Binary files /dev/null and b/iguana/js/amcharts/images/dragIconRoundSmallH.png differ diff --git a/iguana/js/amcharts/images/dragIconRoundSmallH.svg b/iguana/js/amcharts/images/dragIconRoundSmallH.svg new file mode 100755 index 000000000..d066ec60c --- /dev/null +++ b/iguana/js/amcharts/images/dragIconRoundSmallH.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/iguana/js/amcharts/images/eraserIcon.gif b/iguana/js/amcharts/images/eraserIcon.gif new file mode 100755 index 000000000..c29d4be61 Binary files /dev/null and b/iguana/js/amcharts/images/eraserIcon.gif differ diff --git a/iguana/js/amcharts/images/eraserIcon.png b/iguana/js/amcharts/images/eraserIcon.png new file mode 100755 index 000000000..3a1d2965e Binary files /dev/null and b/iguana/js/amcharts/images/eraserIcon.png differ diff --git a/iguana/js/amcharts/images/eraserIcon.svg b/iguana/js/amcharts/images/eraserIcon.svg new file mode 100755 index 000000000..b84b9acc5 --- /dev/null +++ b/iguana/js/amcharts/images/eraserIcon.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/iguana/js/amcharts/images/eraserIconH.gif b/iguana/js/amcharts/images/eraserIconH.gif new file mode 100755 index 000000000..75069f524 Binary files /dev/null and b/iguana/js/amcharts/images/eraserIconH.gif differ diff --git a/iguana/js/amcharts/images/eraserIconH.png b/iguana/js/amcharts/images/eraserIconH.png new file mode 100755 index 000000000..2d704f520 Binary files /dev/null and b/iguana/js/amcharts/images/eraserIconH.png differ diff --git a/iguana/js/amcharts/images/eraserIconH.svg b/iguana/js/amcharts/images/eraserIconH.svg new file mode 100755 index 000000000..11490453e --- /dev/null +++ b/iguana/js/amcharts/images/eraserIconH.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/iguana/js/amcharts/images/export.png b/iguana/js/amcharts/images/export.png new file mode 100755 index 000000000..16435ab26 Binary files /dev/null and b/iguana/js/amcharts/images/export.png differ diff --git a/iguana/js/amcharts/images/exportWhite.png b/iguana/js/amcharts/images/exportWhite.png new file mode 100755 index 000000000..fab0b4282 Binary files /dev/null and b/iguana/js/amcharts/images/exportWhite.png differ diff --git a/iguana/js/amcharts/images/lens.png b/iguana/js/amcharts/images/lens.png new file mode 100755 index 000000000..439feed03 Binary files /dev/null and b/iguana/js/amcharts/images/lens.png differ diff --git a/iguana/js/amcharts/images/lens.svg b/iguana/js/amcharts/images/lens.svg new file mode 100755 index 000000000..75082c812 --- /dev/null +++ b/iguana/js/amcharts/images/lens.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/iguana/js/amcharts/images/lensWhite.png b/iguana/js/amcharts/images/lensWhite.png new file mode 100755 index 000000000..68408fac4 Binary files /dev/null and b/iguana/js/amcharts/images/lensWhite.png differ diff --git a/iguana/js/amcharts/images/lensWhite.svg b/iguana/js/amcharts/images/lensWhite.svg new file mode 100755 index 000000000..785608917 --- /dev/null +++ b/iguana/js/amcharts/images/lensWhite.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/iguana/js/amcharts/images/lensWhite_old.png b/iguana/js/amcharts/images/lensWhite_old.png new file mode 100755 index 000000000..2434fd61e Binary files /dev/null and b/iguana/js/amcharts/images/lensWhite_old.png differ diff --git a/iguana/js/amcharts/images/lens_old.png b/iguana/js/amcharts/images/lens_old.png new file mode 100755 index 000000000..8dcfcae2a Binary files /dev/null and b/iguana/js/amcharts/images/lens_old.png differ diff --git a/iguana/js/amcharts/images/pencilIcon.gif b/iguana/js/amcharts/images/pencilIcon.gif new file mode 100755 index 000000000..bd1d27cb9 Binary files /dev/null and b/iguana/js/amcharts/images/pencilIcon.gif differ diff --git a/iguana/js/amcharts/images/pencilIcon.png b/iguana/js/amcharts/images/pencilIcon.png new file mode 100755 index 000000000..4722db42c Binary files /dev/null and b/iguana/js/amcharts/images/pencilIcon.png differ diff --git a/iguana/js/amcharts/images/pencilIcon.svg b/iguana/js/amcharts/images/pencilIcon.svg new file mode 100755 index 000000000..6834bd1ec --- /dev/null +++ b/iguana/js/amcharts/images/pencilIcon.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + diff --git a/iguana/js/amcharts/images/pencilIconH.gif b/iguana/js/amcharts/images/pencilIconH.gif new file mode 100755 index 000000000..ef3b71069 Binary files /dev/null and b/iguana/js/amcharts/images/pencilIconH.gif differ diff --git a/iguana/js/amcharts/images/pencilIconH.png b/iguana/js/amcharts/images/pencilIconH.png new file mode 100755 index 000000000..a88540b6e Binary files /dev/null and b/iguana/js/amcharts/images/pencilIconH.png differ diff --git a/iguana/js/amcharts/images/pencilIconH.svg b/iguana/js/amcharts/images/pencilIconH.svg new file mode 100755 index 000000000..afcdde07c --- /dev/null +++ b/iguana/js/amcharts/images/pencilIconH.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + diff --git a/iguana/js/amcharts/images/xIcon.gif b/iguana/js/amcharts/images/xIcon.gif new file mode 100755 index 000000000..c66aad93c Binary files /dev/null and b/iguana/js/amcharts/images/xIcon.gif differ diff --git a/iguana/js/amcharts/images/xIcon.png b/iguana/js/amcharts/images/xIcon.png new file mode 100755 index 000000000..3848aa158 Binary files /dev/null and b/iguana/js/amcharts/images/xIcon.png differ diff --git a/iguana/js/amcharts/images/xIcon.svg b/iguana/js/amcharts/images/xIcon.svg new file mode 100755 index 000000000..204afadbc --- /dev/null +++ b/iguana/js/amcharts/images/xIcon.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/iguana/js/amcharts/images/xIconH.gif b/iguana/js/amcharts/images/xIconH.gif new file mode 100755 index 000000000..ae2b9199b Binary files /dev/null and b/iguana/js/amcharts/images/xIconH.gif differ diff --git a/iguana/js/amcharts/images/xIconH.png b/iguana/js/amcharts/images/xIconH.png new file mode 100755 index 000000000..2382c0cb5 Binary files /dev/null and b/iguana/js/amcharts/images/xIconH.png differ diff --git a/iguana/js/amcharts/images/xIconH.svg b/iguana/js/amcharts/images/xIconH.svg new file mode 100755 index 000000000..8ef59f895 --- /dev/null +++ b/iguana/js/amcharts/images/xIconH.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/iguana/js/amcharts/lang/az.js b/iguana/js/amcharts/lang/az.js new file mode 100755 index 000000000..740238ee3 --- /dev/null +++ b/iguana/js/amcharts/lang/az.js @@ -0,0 +1 @@ +AmCharts.translations.az = {"monthNames":["Yanvar","Fevral","Mart","Aprel","May","Iyun","Iyul","Avqust","Sentyabr","Oktyabr","Noyabr","Dekabr"],"shortMonthNames":["Yan","Fev","Mar","Apr","May","Iyn","Iyl","Avq","Sen","Okt","Noy","Dek"],"dayNames":["Bazar günü","Bazar ertəsi","Çərşənbə axşamı","Çərşənbə","Cümə axşamı","Cümə","Şənbə"],"shortDayNames":["Baz","Ber","Çax","Çər","Cax","Cüm","Şnb"],"zoomOutText":"Bütün göstər"} \ No newline at end of file diff --git a/iguana/js/amcharts/lang/bg.js b/iguana/js/amcharts/lang/bg.js new file mode 100755 index 000000000..ba92d1f79 --- /dev/null +++ b/iguana/js/amcharts/lang/bg.js @@ -0,0 +1 @@ +AmCharts.translations.bg = {"monthNames":["Януари","Февруари","Март","Април","Май","Юни","Юли","Август","Септември","Октомври","Ноември","Декември"],"shortMonthNames":["Яну","Фев","Мар","Апр","Май","Юни","Юли","Авг","Сеп","Окт","Ное","Дек"],"dayNames":["Неделя","Понеделник","Вторник","Сряда","Четвъртък","Петък","Събота"],"shortDayNames":["Нд","Пн","Вт","Ср","Чт","Пт","Сб"],"zoomOutText":"Покажи всички"} \ No newline at end of file diff --git a/iguana/js/amcharts/lang/de.js b/iguana/js/amcharts/lang/de.js new file mode 100755 index 000000000..59a2446f8 --- /dev/null +++ b/iguana/js/amcharts/lang/de.js @@ -0,0 +1 @@ +AmCharts.translations.de = {"monthNames":["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember"],"shortMonthNames":["Jan","Feb","Mär","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"],"dayNames":["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"],"shortDayNames":["So","Mo","Di","Mi","Do","Fr","Sa"],"zoomOutText":"Alle anzeigen"} \ No newline at end of file diff --git a/iguana/js/amcharts/lang/es.js b/iguana/js/amcharts/lang/es.js new file mode 100755 index 000000000..55febc90a --- /dev/null +++ b/iguana/js/amcharts/lang/es.js @@ -0,0 +1 @@ +AmCharts.translations.es = {"monthNames":["Enero","Febrero","Marzo","Abril","Mayo","Junio","Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre"],"shortMonthNames":["Ene","Feb","Mar","Abr","May","Jun","Jul","Ago","Sep","Oct","Nov","Dic"],"dayNames":["Domingo","Lunes","Martes","Miércoles","Jueves","Viernes","Sábado"],"shortDayNames":["Dom","Lun","Mar","Mié","Jue","Vie","Sáb"],"zoomOutText":"Mostrar todos"} \ No newline at end of file diff --git a/iguana/js/amcharts/lang/fi.js b/iguana/js/amcharts/lang/fi.js new file mode 100755 index 000000000..2fc518bbd --- /dev/null +++ b/iguana/js/amcharts/lang/fi.js @@ -0,0 +1 @@ +AmCharts.translations.fi = {"monthNames":["Tammikuu","Helmikuu","Maaliskuu","Huhtikuu","Toukokuu","Kesäkuu","Heinäkuu","Elokuu","Syyskuu","Lokakuu","Marraskuu","Joulukuu"],"shortMonthNames":["Tammi ","Helmi ","Maalis","Huhti ","Touko ","Kesä  ","Heinä ","Elo   ","Syys  ","Loka  ","Marras","Joulu "],"dayNames":["Sunnuntai","Maanantai","Tiistai","Keskiviikko","Torstai","Perjantai","Lauantai"],"shortDayNames":["Su","Ma","Ti","Ke","To","Pe","La"],"zoomOutText":"Näytä kaikki"} \ No newline at end of file diff --git a/iguana/js/amcharts/lang/fo.js b/iguana/js/amcharts/lang/fo.js new file mode 100755 index 000000000..496c5af6a --- /dev/null +++ b/iguana/js/amcharts/lang/fo.js @@ -0,0 +1 @@ +AmCharts.translations.fo = {"monthNames":["Januar","Februar","Mars","Apríl","Mai","Juni","Juli","August","September","Oktober","November","Desember"],"shortMonthNames":["Jan","Feb","Mar","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Des"],"dayNames":["Sunnudagur","Mánadagur","Týsdagur","Mikudagur","Hósdagur","Fríggjadagur","Leygardagur"],"shortDayNames":["Sun","Mán","Týs","Mik","Hós","Frí","Ley"],"zoomOutText":"Show all"} \ No newline at end of file diff --git a/iguana/js/amcharts/lang/fr.js b/iguana/js/amcharts/lang/fr.js new file mode 100755 index 000000000..c492ebe9e --- /dev/null +++ b/iguana/js/amcharts/lang/fr.js @@ -0,0 +1 @@ +AmCharts.translations.fr = {"monthNames":["Janvier","Février","Mars","Avril","Mai","Juin","Juillet","Août","Septembre","Octobre","Novembre","Décembre"],"shortMonthNames":["Janv.","Févr.","Mars","Avril","Mai","Juin","Juil.","Août","Sept.","Oct.","Nov.","Déc."],"dayNames":["Dimanche","Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi"],"shortDayNames":["Dim.","Lun.","Mar.","Mer.","Jeu.","Ven.","Sam."],"zoomOutText":"Voir tous"} \ No newline at end of file diff --git a/iguana/js/amcharts/lang/hr.js b/iguana/js/amcharts/lang/hr.js new file mode 100755 index 000000000..2c58700c1 --- /dev/null +++ b/iguana/js/amcharts/lang/hr.js @@ -0,0 +1 @@ +AmCharts.translations.hr = {"monthNames":["Siječanj","Veljača","Ožujak","Travanj","Svibanj","Lipanj","Srpanj","Kolovoz","Rujan","Listopad","Studeni","Prosinac"],"shortMonthNames":["Sij","Vel","Ožu","Tra","Svi","Lip","Srp","Kol","Ruj","Lis","Stu","Pro"],"dayNames":["Nedjelja","Ponedjeljak","Utorak","Srijeda","Četvrtak","Petak","Subota"],"shortDayNames":["Ned","Pon","Uto","Sri","Čet","Pet","Sub"],"zoomOutText":"Prikaži sve"} \ No newline at end of file diff --git a/iguana/js/amcharts/lang/hu.js b/iguana/js/amcharts/lang/hu.js new file mode 100755 index 000000000..dec9c8d6e --- /dev/null +++ b/iguana/js/amcharts/lang/hu.js @@ -0,0 +1 @@ +AmCharts.translations.hu = {"monthNames":["Január","Február","Március","Április","Május","Június","Július","Augusztus","Szeptember","Október","November","December"],"shortMonthNames":["Jan","Febr","Márc","Ápr","Máj","Jún","Júl","Aug","Szept","Okt","Nov","Dec"],"dayNames":["Vasárnap","Hétfő","Kedd","Szerda","Csütörtök","Péntek","Szombat"],"shortDayNames":["V","H","K","Sze","Cs","P","Szo"],"zoomOutText":"Összes"} \ No newline at end of file diff --git a/iguana/js/amcharts/lang/id.js b/iguana/js/amcharts/lang/id.js new file mode 100755 index 000000000..4caeef53d --- /dev/null +++ b/iguana/js/amcharts/lang/id.js @@ -0,0 +1 @@ +AmCharts.translations.id = {"monthNames":["Januari","Pebruari","Maret","April","Mei","Juni","Juli","Agustus","September","Oktober","November","Desember"],"shortMonthNames":["Jan","Peb","Mar","Apr","Mei","Jun","Jul","Agu","Sep","Okt","Nov","Des"],"dayNames":["Minggu","Senin","Selasa","Rabu","Kamis","Jumat","Sabtu"],"shortDayNames":["Min","Sen","Sel","Rab","Kam","Jum","Sab"],"zoomOutText":"Tampilkan semua"} \ No newline at end of file diff --git a/iguana/js/amcharts/lang/is.js b/iguana/js/amcharts/lang/is.js new file mode 100755 index 000000000..d1521091d --- /dev/null +++ b/iguana/js/amcharts/lang/is.js @@ -0,0 +1 @@ +AmCharts.translations.is = {"monthNames":["Janúar","Febrúar","Mars","Apríl","Maí","Júní","Júlí","Ágúst","September","Október","Nóvember","Desember"],"shortMonthNames":["Jan","Feb","Mar","Apr","Maí","Jún","Júl","Ágú","Sep","Okt","Nóv","Des"],"dayNames":["Sunnudagur","Mánudagur","Þriðjudagur","Miðvikudagur","Fimmtudagur","Föstudagur","Laugardagur"],"shortDayNames":["Sun","Mán","Þri","Mið","Fim","Fös","Lau"],"zoomOutText":"Sýna allt"} \ No newline at end of file diff --git a/iguana/js/amcharts/lang/it.js b/iguana/js/amcharts/lang/it.js new file mode 100755 index 000000000..db8d8b901 --- /dev/null +++ b/iguana/js/amcharts/lang/it.js @@ -0,0 +1 @@ +AmCharts.translations.it = {"monthNames":["Gennaio","Febbraio","Marzo","Aprile","Maggio","Giugno","Luglio","Agosto","Settembre","Ottobre","Novembre","Dicembre"],"shortMonthNames":["Gen","Feb","Mar","Apr","Mag","Giu","Lug","Ago","Set","Ott","Nov","Dic"],"dayNames":["Domenica","Lunedì","Martedì","Mercoledì","Giovedì","Venerdì","Sabato"],"shortDayNames":["Dom","Lun","Mar","Mer","Gio","Ven","Sab"],"zoomOutText":"Mostra tutti"} \ No newline at end of file diff --git a/iguana/js/amcharts/lang/ja.js b/iguana/js/amcharts/lang/ja.js new file mode 100755 index 000000000..e663bf2b5 --- /dev/null +++ b/iguana/js/amcharts/lang/ja.js @@ -0,0 +1 @@ +AmCharts.translations.ja = {"monthNames":["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],"shortMonthNames":["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],"dayNames":["日曜日","月曜日","火曜日","水曜日","木曜日","金曜日","土曜日"],"shortDayNames":["日","月","火","水","木","金","土"],"zoomOutText":"すべて表示"}; \ No newline at end of file diff --git a/iguana/js/amcharts/lang/ko.js b/iguana/js/amcharts/lang/ko.js new file mode 100755 index 000000000..714b956c1 --- /dev/null +++ b/iguana/js/amcharts/lang/ko.js @@ -0,0 +1 @@ +AmCharts.translations.ko = {"monthNames":["1월","2월","3월","4월","5월","6월","7월","8월","9월","10월","11월","12월"],"shortMonthNames":["1월","2월","3월","4월","5월","6월","7월","8월","9월","10월","11월","12월"],"dayNames":["일요일","월요일","화요일","수요일","목요일","금요일","토요일"],"shortDayNames":["일","월","화","수","목","금","토"],"zoomOutText":"모두 보기"}; \ No newline at end of file diff --git a/iguana/js/amcharts/lang/lt.js b/iguana/js/amcharts/lang/lt.js new file mode 100755 index 000000000..3a48b9443 --- /dev/null +++ b/iguana/js/amcharts/lang/lt.js @@ -0,0 +1 @@ +AmCharts.translations.lt = {"monthNames":["Sausio","Vasario","Kovo","Balandžio","Gegužės","Birželio","Liepos","Rugpjūčio","Rugsėjo","Spalio","Lapkričio","Gruodžio"],"shortMonthNames":["Sau","Vas","Kov","Bal","Geg","Bir","Lie","Rgp","Rgs","Spa","Lap","Grd"],"dayNames":["Sekmadienis","Pirmadienis","Antradienis","Trečiadienis","Ketvirtadienis","Penktadienis","Šeštadienis"],"shortDayNames":["Sk","Pr","An","Tr","Kt","Pn","Št"],"zoomOutText":"Rodyti viską"} \ No newline at end of file diff --git a/iguana/js/amcharts/lang/lv.js b/iguana/js/amcharts/lang/lv.js new file mode 100755 index 000000000..80795eb68 --- /dev/null +++ b/iguana/js/amcharts/lang/lv.js @@ -0,0 +1 @@ +AmCharts.translations.lv = {"monthNames":["Janvāris","Februāris","Marts","Aprīlis","Maijs","Jūnijs","Jūlijs","Augusts","Septembris","Oktobris","Novembris","Decembris"],"shortMonthNames":["Jan","Feb","Mar","Apr","Mai","Jūn","Jūl","Aug","Sep","Okt","Nov","Dec"],"dayNames":["Svētdiena","Pirmdiena","Otrdiena","Trešdiena","Ceturtdiena","Piektdiena","Sestdiena"],"shortDayNames":["Sv","P ","O ","T ","C ","Pk","S "],"zoomOutText":"Parādīt visu"} \ No newline at end of file diff --git a/iguana/js/amcharts/lang/mk.js b/iguana/js/amcharts/lang/mk.js new file mode 100755 index 000000000..ba1892363 --- /dev/null +++ b/iguana/js/amcharts/lang/mk.js @@ -0,0 +1 @@ +AmCharts.translations.mk = {"monthNames":["Јануари","Февруари","Март","Април","Мај","Јуни","Јули","Август","Септември","Октомври","Ноември","Декември"],"shortMonthNames":["Јан","Фев","Мар","Апр","Мај","Јун","Јул","Авг","Сеп","Окт","Ное","Дек"],"dayNames":["Недела","Понеделник","Вторник","Среда","Четврток","Петок","Сабота"],"shortDayNames":["Нед","Пон","Вто","Сре","Чет","Пет","Саб"],"zoomOutText":"Прикажи ги сите"} \ No newline at end of file diff --git a/iguana/js/amcharts/lang/mn.js b/iguana/js/amcharts/lang/mn.js new file mode 100755 index 000000000..cecb35d89 --- /dev/null +++ b/iguana/js/amcharts/lang/mn.js @@ -0,0 +1 @@ +AmCharts.translations.mn = {"monthNames":["Хулгана сарын","Үхэр сарын","Бар сарын","Туулай сарын","Луу сарын","Могой сарын","Морь сарын","Хонь сарын","Бич сарын","Тахиа сарын","Нохой сарын","Гахай сарын"],"shortMonthNames":["Хул","Үхэ","Бар","Туу","Луу","Мог","Мор","Хон","Бич","Тах","Нох","Гах"],"dayNames":["Ням","Даваа","Мягмар","Лхагва","Пүрэв","Баасан","Бямба"],"shortDayNames":["Ня","Да","Мя","Лх","Пү","Ба","Бя"],"zoomOutText":"Бүх харуулах"} \ No newline at end of file diff --git a/iguana/js/amcharts/lang/mt.js b/iguana/js/amcharts/lang/mt.js new file mode 100755 index 000000000..0a879d103 --- /dev/null +++ b/iguana/js/amcharts/lang/mt.js @@ -0,0 +1 @@ +AmCharts.translations.mt = {"monthNames":["Jannar","Frar","Marzu","April","Mejju","Ġunju","Lulju","Awwissu","Settembru","Ottubru","Novembru","Diċembru "],"shortMonthNames":["Jan","Fra","Mar","Apr","Mej","Ġun","Lul","Aww","Set","Ott","Nov","Diċ"],"dayNames":["Il-ħadd","It-tnejn","It-tlieta","L-erbgħa","Il-ħamis","Il-ġimgħa","Is-sibt"],"shortDayNames":["Ħad","Tne","Tli","Erb","Ħam","Ġim","Sib"],"zoomOutText":"Turi kollha"} \ No newline at end of file diff --git a/iguana/js/amcharts/lang/nl.js b/iguana/js/amcharts/lang/nl.js new file mode 100755 index 000000000..5b009f425 --- /dev/null +++ b/iguana/js/amcharts/lang/nl.js @@ -0,0 +1 @@ +AmCharts.translations.nl = {"monthNames":["Januari","Februari","Maart","April","Mei","Juni","Juli","Augustus","September","Oktober","November","December"],"shortMonthNames":["Jan","Feb","Mrt","Apr","Mei","Jun","Jul","Aug","Sep","Okt","Nov","Dec"],"dayNames":["Zondag","Maandag","Dinsdag","Woensdag","Donderdag","Vrijdag","Zaterdag"],"shortDayNames":["Zo","Ma","Di","Wo","Do","Vr","Za"],"zoomOutText":"Alles weergeven"} \ No newline at end of file diff --git a/iguana/js/amcharts/lang/no.js b/iguana/js/amcharts/lang/no.js new file mode 100755 index 000000000..e1b21afd3 --- /dev/null +++ b/iguana/js/amcharts/lang/no.js @@ -0,0 +1 @@ +AmCharts.translations.no = {"monthNames":["Januar","Februar","Mars","April","Mai","Juni","Juli","August","September","Oktober","November","Desember"],"shortMonthNames":["Jan.","Feb.","Mars","April","Mai","Juni","Juli","Aug.","Sep.","Okt.","Nov.","Des."],"dayNames":["Søndag","Mandag","Tirsdag","Onsdag","Torsdag","Fredag","Lørdag"],"shortDayNames":["Sø.","Ma.","Ti.","On.","To.","Fr.","Lø."],"zoomOutText":"Vis alle"} \ No newline at end of file diff --git a/iguana/js/amcharts/lang/pl.js b/iguana/js/amcharts/lang/pl.js new file mode 100755 index 000000000..1c9c39118 --- /dev/null +++ b/iguana/js/amcharts/lang/pl.js @@ -0,0 +1 @@ +AmCharts.translations.pl = {"monthNames":["Styczeń","Luty","Marzec","Kwiecień","Maj","Czerwiec","Lipiec","Sierpień","Wrzesień","Październik","Listopad","Grudzień"],"shortMonthNames":["Sty","Lut","Mar","Kwi","Maj","Cze","Lip","Sie","Wrz","Paź","Lis","Gru"],"dayNames":["Niedziela","Poniedziałek","Wtorek","Środa","Czwartek","Piątek","Sobota"],"shortDayNames":["Nie","Pon","Wto","Śro","Czw","Pią","Sob"],"zoomOutText":"Pokaż wszystko"} \ No newline at end of file diff --git a/iguana/js/amcharts/lang/pt.js b/iguana/js/amcharts/lang/pt.js new file mode 100755 index 000000000..c25770c7f --- /dev/null +++ b/iguana/js/amcharts/lang/pt.js @@ -0,0 +1 @@ +AmCharts.translations.pt = {"monthNames":["Janeiro","Fevereiro","Março","Abril","Maio","Junho","Julho","Agosto","Setembro","Outubro","Novembro","Dezembro"],"shortMonthNames":["Jan","Fev","Mar","Abr","Mai","Jun","Jul","Ago","Set","Out","Nov","Dez"],"dayNames":["Domingo","Segunda","Terça","Quarta","Quinta","Sexta","Sábado"],"shortDayNames":["Dom","Seg","Ter","Qua","Qui","Sex","Sáb"],"zoomOutText":"Mostrar todos"} \ No newline at end of file diff --git a/iguana/js/amcharts/lang/ro.js b/iguana/js/amcharts/lang/ro.js new file mode 100755 index 000000000..adea600f6 --- /dev/null +++ b/iguana/js/amcharts/lang/ro.js @@ -0,0 +1 @@ +AmCharts.translations.ro = {"monthNames":["Ianuarie","Februarie","Martie","Aprilie","Mai","Iunie","Iulie","August","Septembrie","Octombrie","Noiembrie","Decembrie"],"shortMonthNames":["Ian","Feb","Mar","Apr","Mai","Iun","Iul","Aug","Sep","Oct","Nov","Dec"],"dayNames":["Duminică","Luni","Marţi","Miercuri","Joi","Vineri","Sâmbătă"],"shortDayNames":["Du","Lu","Ma","Mi","Jo","Vi","Sb"],"zoomOutText":"Arată tot"} \ No newline at end of file diff --git a/iguana/js/amcharts/lang/ru.js b/iguana/js/amcharts/lang/ru.js new file mode 100755 index 000000000..c33aea990 --- /dev/null +++ b/iguana/js/amcharts/lang/ru.js @@ -0,0 +1 @@ +AmCharts.translations.ru = {"monthNames":["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"],"shortMonthNames":["Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек"],"dayNames":["Воскресенье","Понедельник","Вторник","Среда","Четверг","Пятница","Суббота"],"shortDayNames":["Вск","Пнд","Втр","Срд","Чтв","Птн","Сбт"],"zoomOutText":"Показать все"} \ No newline at end of file diff --git a/iguana/js/amcharts/lang/rw.js b/iguana/js/amcharts/lang/rw.js new file mode 100755 index 000000000..2e8e23cf7 --- /dev/null +++ b/iguana/js/amcharts/lang/rw.js @@ -0,0 +1 @@ +AmCharts.translations.rw = {"monthNames":["Mutarama","Gashyantare","Werurwe","Mata","Gicuransi","Kamena","Nyakanga","Kanama","Nzeli","Ukwakira","Ugushyingo","Ukuboza"],"shortMonthNames":["Mut","Gas","Wer","Mat","Gic","Kam","Nya","Kan","Nze","Ukw","Ugu","Uku"],"dayNames":["Ku cyumweru","Kuwa mbere","Kuwa kabiri","Kuwa gatatu","Kuwa kane","Kuwa gatanu","Kuwa gatandatu"],"shortDayNames":["Mwe","Mbe","Kab","Gtu","Kan","Gnu","Gnd"],"zoomOutText":"Show all"} \ No newline at end of file diff --git a/iguana/js/amcharts/lang/sk.js b/iguana/js/amcharts/lang/sk.js new file mode 100755 index 000000000..c6703464d --- /dev/null +++ b/iguana/js/amcharts/lang/sk.js @@ -0,0 +1 @@ +AmCharts.translations.sk = {"monthNames":["Január","Február","Marec","Apríl","Máj","Jún","Júl","August","September","Október","November","December"],"shortMonthNames":["Jan","Feb","Mar","Apr","Máj","Jún","Júl","Aug","Sep","Okt","Nov","Dec"],"dayNames":["Nedeľa","Pondelok","Utorok","Streda","Štvrtok","Piatok","Sobota"],"shortDayNames":["Ne","Po","Ut","St","Št","Pi","So"],"zoomOutText":"Zobraziť všetky"} \ No newline at end of file diff --git a/iguana/js/amcharts/lang/so.js b/iguana/js/amcharts/lang/so.js new file mode 100755 index 000000000..1fbd09e3b --- /dev/null +++ b/iguana/js/amcharts/lang/so.js @@ -0,0 +1 @@ +AmCharts.translations.so = {"monthNames":["Bisha koobaad","Bisha labaad","Bisha saddexaad","Bisha afraad","Bisha shanaad","Bisha lixaad","Bisha todobaad","Bisha sideedaad","Bisha sagaalaad","Bisha tobnaad","Bisha kow iyo tobnaad","Bisha laba iyo tobnaad"],"shortMonthNames":["Kob","Lab","Sad","Afr","Sha","Lix","Tod","Sid","Sag","Tob","Kit","Lit"],"dayNames":["Axad","Isniin","Salaaso","Arbaco","Khamiis","Jimco","Sabti"],"shortDayNames":["Axa","Isn","Sal","Arb","Kha","Jim","Sab"],"zoomOutText":"Tus dhammaan"} \ No newline at end of file diff --git a/iguana/js/amcharts/lang/th.js b/iguana/js/amcharts/lang/th.js new file mode 100755 index 000000000..95a5e7ae9 --- /dev/null +++ b/iguana/js/amcharts/lang/th.js @@ -0,0 +1 @@ +AmCharts.translations.th = {"monthNames":["มกราคม","กุมภาพันธ์","มีนาคม","เมษายน","พฤษภาคม","มิถุนายน","กรกฎาคม","สิงหาคม","กันยายน","ตุลาคม","พฤศจิกายน","ธันวาคม"],"shortMonthNames":["ม.ค.","ก.พ.","มี.ค.","เม.ย.","พ.ค.","มิ.ย.","ก.ค.","ส.ค.","ก.ย.","ต.ค.","พ.ย.","ธ.ค."],"dayNames":["อาทิตย์","จันทร์","อังคาร","พุธ","พฤหัสบดี","ศุกร์","เสาร์"],"shortDayNames":["อา.","จ.","อ.","พ.","พฤ.","ศ.","ส."],"zoomOutText":"แสดงทั้งหมด"} \ No newline at end of file diff --git a/iguana/js/amcharts/lang/tr.js b/iguana/js/amcharts/lang/tr.js new file mode 100755 index 000000000..886d9cd96 --- /dev/null +++ b/iguana/js/amcharts/lang/tr.js @@ -0,0 +1 @@ +AmCharts.translations.tr = {"monthNames":["Ocak","Şubat","Mart","Nisan","Mayıs","Haziran","Temmuz","Ağustos","Eylül","Ekim","Kasım","Aralık"],"shortMonthNames":["Oca","Şub","Mar","Nis","May","Haz","Tem","Ağu","Eyl","Eki","Kas","Ara"],"dayNames":["Pazar","Pazartesi","Salı","Çarşamba","Perşembe","Cuma","Cumartesi"],"shortDayNames":["Paz","Pzt","Sal","Çrş","Prş","Cum","Cts"],"zoomOutText":"Tümünü göster"} \ No newline at end of file diff --git a/iguana/js/amcharts/lang/zh.js b/iguana/js/amcharts/lang/zh.js new file mode 100755 index 000000000..f1e836ece --- /dev/null +++ b/iguana/js/amcharts/lang/zh.js @@ -0,0 +1,9 @@ +AmCharts.translations.zh = { + "monthNames": [ "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月" ], + "shortMonthNames": [ "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月" ], + "dayNames": [ "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" ], + "shortDayNames": [ "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" ], + "zoomOutText": "显示所有", + "am": "上午", + "pm": "下午" +} \ No newline at end of file diff --git a/iguana/js/amcharts/patterns/black/pattern1.png b/iguana/js/amcharts/patterns/black/pattern1.png new file mode 100755 index 000000000..bb7dc47cb Binary files /dev/null and b/iguana/js/amcharts/patterns/black/pattern1.png differ diff --git a/iguana/js/amcharts/patterns/black/pattern10.png b/iguana/js/amcharts/patterns/black/pattern10.png new file mode 100755 index 000000000..2549bf5ff Binary files /dev/null and b/iguana/js/amcharts/patterns/black/pattern10.png differ diff --git a/iguana/js/amcharts/patterns/black/pattern11.png b/iguana/js/amcharts/patterns/black/pattern11.png new file mode 100755 index 000000000..080647bba Binary files /dev/null and b/iguana/js/amcharts/patterns/black/pattern11.png differ diff --git a/iguana/js/amcharts/patterns/black/pattern12.png b/iguana/js/amcharts/patterns/black/pattern12.png new file mode 100755 index 000000000..5ce070d34 Binary files /dev/null and b/iguana/js/amcharts/patterns/black/pattern12.png differ diff --git a/iguana/js/amcharts/patterns/black/pattern13.png b/iguana/js/amcharts/patterns/black/pattern13.png new file mode 100755 index 000000000..a9d9e0e8c Binary files /dev/null and b/iguana/js/amcharts/patterns/black/pattern13.png differ diff --git a/iguana/js/amcharts/patterns/black/pattern14.png b/iguana/js/amcharts/patterns/black/pattern14.png new file mode 100755 index 000000000..a34e05e3f Binary files /dev/null and b/iguana/js/amcharts/patterns/black/pattern14.png differ diff --git a/iguana/js/amcharts/patterns/black/pattern15.png b/iguana/js/amcharts/patterns/black/pattern15.png new file mode 100755 index 000000000..91d293958 Binary files /dev/null and b/iguana/js/amcharts/patterns/black/pattern15.png differ diff --git a/iguana/js/amcharts/patterns/black/pattern16.png b/iguana/js/amcharts/patterns/black/pattern16.png new file mode 100755 index 000000000..3fd18a973 Binary files /dev/null and b/iguana/js/amcharts/patterns/black/pattern16.png differ diff --git a/iguana/js/amcharts/patterns/black/pattern17.png b/iguana/js/amcharts/patterns/black/pattern17.png new file mode 100755 index 000000000..d09beb9c3 Binary files /dev/null and b/iguana/js/amcharts/patterns/black/pattern17.png differ diff --git a/iguana/js/amcharts/patterns/black/pattern18.png b/iguana/js/amcharts/patterns/black/pattern18.png new file mode 100755 index 000000000..546b8f75a Binary files /dev/null and b/iguana/js/amcharts/patterns/black/pattern18.png differ diff --git a/iguana/js/amcharts/patterns/black/pattern19.png b/iguana/js/amcharts/patterns/black/pattern19.png new file mode 100755 index 000000000..193a543c3 Binary files /dev/null and b/iguana/js/amcharts/patterns/black/pattern19.png differ diff --git a/iguana/js/amcharts/patterns/black/pattern2.png b/iguana/js/amcharts/patterns/black/pattern2.png new file mode 100755 index 000000000..cd5ac78cc Binary files /dev/null and b/iguana/js/amcharts/patterns/black/pattern2.png differ diff --git a/iguana/js/amcharts/patterns/black/pattern20.png b/iguana/js/amcharts/patterns/black/pattern20.png new file mode 100755 index 000000000..f87b6d872 Binary files /dev/null and b/iguana/js/amcharts/patterns/black/pattern20.png differ diff --git a/iguana/js/amcharts/patterns/black/pattern21.png b/iguana/js/amcharts/patterns/black/pattern21.png new file mode 100755 index 000000000..da1a59a1f Binary files /dev/null and b/iguana/js/amcharts/patterns/black/pattern21.png differ diff --git a/iguana/js/amcharts/patterns/black/pattern3.png b/iguana/js/amcharts/patterns/black/pattern3.png new file mode 100755 index 000000000..c1a81f41e Binary files /dev/null and b/iguana/js/amcharts/patterns/black/pattern3.png differ diff --git a/iguana/js/amcharts/patterns/black/pattern4.png b/iguana/js/amcharts/patterns/black/pattern4.png new file mode 100755 index 000000000..e2f07c3e8 Binary files /dev/null and b/iguana/js/amcharts/patterns/black/pattern4.png differ diff --git a/iguana/js/amcharts/patterns/black/pattern5.png b/iguana/js/amcharts/patterns/black/pattern5.png new file mode 100755 index 000000000..efd52408f Binary files /dev/null and b/iguana/js/amcharts/patterns/black/pattern5.png differ diff --git a/iguana/js/amcharts/patterns/black/pattern6.png b/iguana/js/amcharts/patterns/black/pattern6.png new file mode 100755 index 000000000..709847da2 Binary files /dev/null and b/iguana/js/amcharts/patterns/black/pattern6.png differ diff --git a/iguana/js/amcharts/patterns/black/pattern7.png b/iguana/js/amcharts/patterns/black/pattern7.png new file mode 100755 index 000000000..458757e53 Binary files /dev/null and b/iguana/js/amcharts/patterns/black/pattern7.png differ diff --git a/iguana/js/amcharts/patterns/black/pattern8.png b/iguana/js/amcharts/patterns/black/pattern8.png new file mode 100755 index 000000000..5230e4c29 Binary files /dev/null and b/iguana/js/amcharts/patterns/black/pattern8.png differ diff --git a/iguana/js/amcharts/patterns/black/pattern9.png b/iguana/js/amcharts/patterns/black/pattern9.png new file mode 100755 index 000000000..be1efefbc Binary files /dev/null and b/iguana/js/amcharts/patterns/black/pattern9.png differ diff --git a/iguana/js/amcharts/patterns/chalk/pattern1.jpg b/iguana/js/amcharts/patterns/chalk/pattern1.jpg new file mode 100755 index 000000000..e3101b5de Binary files /dev/null and b/iguana/js/amcharts/patterns/chalk/pattern1.jpg differ diff --git a/iguana/js/amcharts/patterns/chalk/pattern1r.jpg b/iguana/js/amcharts/patterns/chalk/pattern1r.jpg new file mode 100755 index 000000000..2cdc0a888 Binary files /dev/null and b/iguana/js/amcharts/patterns/chalk/pattern1r.jpg differ diff --git a/iguana/js/amcharts/patterns/chalk/pattern2.jpg b/iguana/js/amcharts/patterns/chalk/pattern2.jpg new file mode 100755 index 000000000..fa4d4a511 Binary files /dev/null and b/iguana/js/amcharts/patterns/chalk/pattern2.jpg differ diff --git a/iguana/js/amcharts/patterns/chalk/pattern3.jpg b/iguana/js/amcharts/patterns/chalk/pattern3.jpg new file mode 100755 index 000000000..80611ba2a Binary files /dev/null and b/iguana/js/amcharts/patterns/chalk/pattern3.jpg differ diff --git a/iguana/js/amcharts/patterns/chalk/pattern4.jpg b/iguana/js/amcharts/patterns/chalk/pattern4.jpg new file mode 100755 index 000000000..690c5033d Binary files /dev/null and b/iguana/js/amcharts/patterns/chalk/pattern4.jpg differ diff --git a/iguana/js/amcharts/patterns/chalk/pattern5.jpg b/iguana/js/amcharts/patterns/chalk/pattern5.jpg new file mode 100755 index 000000000..108b46916 Binary files /dev/null and b/iguana/js/amcharts/patterns/chalk/pattern5.jpg differ diff --git a/iguana/js/amcharts/patterns/chalk/pattern6.jpg b/iguana/js/amcharts/patterns/chalk/pattern6.jpg new file mode 100755 index 000000000..3575a95f7 Binary files /dev/null and b/iguana/js/amcharts/patterns/chalk/pattern6.jpg differ diff --git a/iguana/js/amcharts/patterns/white/pattern1.png b/iguana/js/amcharts/patterns/white/pattern1.png new file mode 100755 index 000000000..4a7fc20d2 Binary files /dev/null and b/iguana/js/amcharts/patterns/white/pattern1.png differ diff --git a/iguana/js/amcharts/patterns/white/pattern10.png b/iguana/js/amcharts/patterns/white/pattern10.png new file mode 100755 index 000000000..c36de6ea6 Binary files /dev/null and b/iguana/js/amcharts/patterns/white/pattern10.png differ diff --git a/iguana/js/amcharts/patterns/white/pattern11.png b/iguana/js/amcharts/patterns/white/pattern11.png new file mode 100755 index 000000000..9c4ffd3a0 Binary files /dev/null and b/iguana/js/amcharts/patterns/white/pattern11.png differ diff --git a/iguana/js/amcharts/patterns/white/pattern12.png b/iguana/js/amcharts/patterns/white/pattern12.png new file mode 100755 index 000000000..f893c7bb2 Binary files /dev/null and b/iguana/js/amcharts/patterns/white/pattern12.png differ diff --git a/iguana/js/amcharts/patterns/white/pattern13.png b/iguana/js/amcharts/patterns/white/pattern13.png new file mode 100755 index 000000000..f44deea3d Binary files /dev/null and b/iguana/js/amcharts/patterns/white/pattern13.png differ diff --git a/iguana/js/amcharts/patterns/white/pattern14.png b/iguana/js/amcharts/patterns/white/pattern14.png new file mode 100755 index 000000000..6c0017813 Binary files /dev/null and b/iguana/js/amcharts/patterns/white/pattern14.png differ diff --git a/iguana/js/amcharts/patterns/white/pattern15.png b/iguana/js/amcharts/patterns/white/pattern15.png new file mode 100755 index 000000000..67a0d481c Binary files /dev/null and b/iguana/js/amcharts/patterns/white/pattern15.png differ diff --git a/iguana/js/amcharts/patterns/white/pattern16.png b/iguana/js/amcharts/patterns/white/pattern16.png new file mode 100755 index 000000000..f8ce24834 Binary files /dev/null and b/iguana/js/amcharts/patterns/white/pattern16.png differ diff --git a/iguana/js/amcharts/patterns/white/pattern17.png b/iguana/js/amcharts/patterns/white/pattern17.png new file mode 100755 index 000000000..729f9d4a6 Binary files /dev/null and b/iguana/js/amcharts/patterns/white/pattern17.png differ diff --git a/iguana/js/amcharts/patterns/white/pattern18.png b/iguana/js/amcharts/patterns/white/pattern18.png new file mode 100755 index 000000000..1b2d90a47 Binary files /dev/null and b/iguana/js/amcharts/patterns/white/pattern18.png differ diff --git a/iguana/js/amcharts/patterns/white/pattern19.png b/iguana/js/amcharts/patterns/white/pattern19.png new file mode 100755 index 000000000..5c3806e45 Binary files /dev/null and b/iguana/js/amcharts/patterns/white/pattern19.png differ diff --git a/iguana/js/amcharts/patterns/white/pattern2.png b/iguana/js/amcharts/patterns/white/pattern2.png new file mode 100755 index 000000000..7d80cbd04 Binary files /dev/null and b/iguana/js/amcharts/patterns/white/pattern2.png differ diff --git a/iguana/js/amcharts/patterns/white/pattern20.png b/iguana/js/amcharts/patterns/white/pattern20.png new file mode 100755 index 000000000..9c1830e94 Binary files /dev/null and b/iguana/js/amcharts/patterns/white/pattern20.png differ diff --git a/iguana/js/amcharts/patterns/white/pattern21.png b/iguana/js/amcharts/patterns/white/pattern21.png new file mode 100755 index 000000000..ba3586cf6 Binary files /dev/null and b/iguana/js/amcharts/patterns/white/pattern21.png differ diff --git a/iguana/js/amcharts/patterns/white/pattern3.png b/iguana/js/amcharts/patterns/white/pattern3.png new file mode 100755 index 000000000..66a61d8e9 Binary files /dev/null and b/iguana/js/amcharts/patterns/white/pattern3.png differ diff --git a/iguana/js/amcharts/patterns/white/pattern4.png b/iguana/js/amcharts/patterns/white/pattern4.png new file mode 100755 index 000000000..ec894ce84 Binary files /dev/null and b/iguana/js/amcharts/patterns/white/pattern4.png differ diff --git a/iguana/js/amcharts/patterns/white/pattern5.png b/iguana/js/amcharts/patterns/white/pattern5.png new file mode 100755 index 000000000..5b9314e34 Binary files /dev/null and b/iguana/js/amcharts/patterns/white/pattern5.png differ diff --git a/iguana/js/amcharts/patterns/white/pattern6.png b/iguana/js/amcharts/patterns/white/pattern6.png new file mode 100755 index 000000000..3f74e5b54 Binary files /dev/null and b/iguana/js/amcharts/patterns/white/pattern6.png differ diff --git a/iguana/js/amcharts/patterns/white/pattern7.png b/iguana/js/amcharts/patterns/white/pattern7.png new file mode 100755 index 000000000..bc7dbd0fc Binary files /dev/null and b/iguana/js/amcharts/patterns/white/pattern7.png differ diff --git a/iguana/js/amcharts/patterns/white/pattern8.png b/iguana/js/amcharts/patterns/white/pattern8.png new file mode 100755 index 000000000..0a1843511 Binary files /dev/null and b/iguana/js/amcharts/patterns/white/pattern8.png differ diff --git a/iguana/js/amcharts/patterns/white/pattern9.png b/iguana/js/amcharts/patterns/white/pattern9.png new file mode 100755 index 000000000..98caff473 Binary files /dev/null and b/iguana/js/amcharts/patterns/white/pattern9.png differ diff --git a/iguana/js/amcharts/plugins/dataloader/dataloader.js b/iguana/js/amcharts/plugins/dataloader/dataloader.js new file mode 100755 index 000000000..2e7b0d329 --- /dev/null +++ b/iguana/js/amcharts/plugins/dataloader/dataloader.js @@ -0,0 +1,744 @@ +/* +Plugin Name: amCharts Data Loader +Description: This plugin adds external data loading capabilities to all amCharts libraries. +Author: Martynas Majeris, amCharts +Version: 1.0.16 +Author URI: http://www.amcharts.com/ + +Copyright 2015 amCharts + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +Please note that the above license covers only this plugin. It by all means does +not apply to any other amCharts products that are covered by different licenses. +*/ + +/** + * TODO: + * incremental load + * XML support (?) + */ + +/* globals AmCharts, ActiveXObject */ +/* jshint -W061 */ + +/** + * Initialize language prompt container + */ +AmCharts.translations.dataLoader = {}; + +/** + * Set init handler + */ +AmCharts.addInitHandler( function( chart ) { + + /** + * Check if dataLoader is set (initialize it) + */ + if ( undefined === chart.dataLoader || !isObject( chart.dataLoader ) ) + chart.dataLoader = {}; + + /** + * Check charts version for compatibility: + * the first compatible version is 3.13 + */ + var version = chart.version.split( '.' ); + if ( ( Number( version[ 0 ] ) < 3 ) || ( 3 === Number( version[ 0 ] ) && ( Number( version[ 1 ] ) < 13 ) ) ) + return; + + /** + * Define object reference for easy access + */ + var l = chart.dataLoader; + l.remaining = 0; + l.percentLoaded = {}; + + /** + * Set defaults + */ + var defaults = { + 'async': true, + 'format': 'json', + 'showErrors': true, + 'showCurtain': true, + 'noStyles': false, + 'reload': 0, + 'timestamp': false, + 'delimiter': ',', + 'skip': 0, + 'skipEmpty': true, + 'emptyAs': undefined, + 'useColumnNames': false, + 'init': false, + 'progress': false, + 'reverse': false, + 'reloading': false, + 'complete': false, + 'error': false, + 'numberFields': [], + 'headers': [], + 'chart': chart + }; + + /** + * Create a function that can be used to load data (or reload via API) + */ + l.loadData = function() { + + /** + * Load all files in a row + */ + if ( 'stock' === chart.type ) { + + // delay this a little bit so the chart has the chance to build itself + setTimeout( function() { + + // preserve animation + if ( 0 > chart.panelsSettings.startDuration ) { + l.startDuration = chart.panelsSettings.startDuration; + chart.panelsSettings.startDuration = 0; + } + + // cycle through all of the data sets + for ( var x = 0; x < chart.dataSets.length; x++ ) { + var ds = chart.dataSets[ x ]; + + // load data + if ( undefined !== ds.dataLoader && undefined !== ds.dataLoader.url ) { + + callFunction( ds.dataLoader.init, ds.dataLoader, chart ); + ds.dataProvider = []; + applyDefaults( ds.dataLoader ); + loadFile( ds.dataLoader.url, ds, ds.dataLoader, 'dataProvider' ); + + } + + // load events data + if ( undefined !== ds.eventDataLoader && undefined !== ds.eventDataLoader.url ) { + + callFunction( ds.eventDataLoader.init, ds.eventDataLoader, chart ); + ds.events = []; + applyDefaults( ds.eventDataLoader ); + loadFile( ds.eventDataLoader.url, ds, ds.eventDataLoader, 'stockEvents' ); + + } + } + + }, 100 ); + + } else { + + callFunction( l.init, l, chart ); + + applyDefaults( l ); + + if ( undefined === l.url ) + return; + + // preserve animation + if ( undefined !== chart.startDuration && ( 0 < chart.startDuration ) ) { + l.startDuration = chart.startDuration; + chart.startDuration = 0; + } + + if ( 'gauge' === chart.type ) { + // set empty data set + if ( undefined === chart.arrows ) + chart.arrows = []; + + loadFile( l.url, chart, l, 'arrows' ); + } else { + // set empty data set + if ( undefined === chart.dataProvider ) + chart.dataProvider = chart.type === 'map' ? {} : []; + + loadFile( l.url, chart, l, 'dataProvider' ); + } + + } + + }; + + /** + * Trigger load + */ + l.loadData(); + + /** + * Loads a file and determines correct parsing mechanism for it + */ + function loadFile( url, holder, options, providerKey ) { + + // set default providerKey + if ( undefined === providerKey ) + providerKey = 'dataProvider'; + + // show curtain + if ( options.showCurtain ) + showCurtain( undefined, options.noStyles ); + + // increment loader count + l.remaining++; + + // set percent loaded for this file + l.percentLoaded[ url ] = 0; + + // hijack user-defined "progress" handler with our own, so that we can + // track progress + if ( options.progress !== undefined && typeof( options.progress ) === 'function' && options._progress === undefined ) { + options._progress = options.progress; + options.progress = function( percent ) { + // set progress + l.percentLoaded[ url ] = percent; + + // calculate global percent + var totalPercent = 0; + var fileCount = 0; + for ( var x in l.percentLoaded ) { + if ( l.percentLoaded.hasOwnProperty( x ) ) { + fileCount++; + totalPercent += l.percentLoaded[ x ]; + } + } + var globalPercent = Math.round( ( totalPercent / fileCount ) * 100 ) / 100; + + // call user function + options._progress.call( this, globalPercent, Math.round( percent * 100 ) / 100, url ); + }; + } + + // load the file + AmCharts.loadFile( url, options, function( response ) { + + // error? + if ( false === response ) { + callFunction( options.error, options, chart ); + raiseError( AmCharts.__( 'Error loading the file', chart.language ) + ': ' + url, false, options ); + } else { + + // determine the format + if ( undefined === options.format ) { + // TODO + options.format = 'json'; + } + + // lowercase + options.format = options.format.toLowerCase(); + + // invoke parsing function + switch ( options.format ) { + + case 'json': + + holder[ providerKey ] = AmCharts.parseJSON( response ); + + if ( false === holder[ providerKey ] ) { + callFunction( options.error, options, chart ); + raiseError( AmCharts.__( 'Error parsing JSON file', chart.language ) + ': ' + l.url, false, options ); + holder[ providerKey ] = []; + return; + } else { + holder[ providerKey ] = postprocess( holder[ providerKey ], options ); + callFunction( options.load, options, chart ); + } + + break; + + case 'csv': + + holder[ providerKey ] = AmCharts.parseCSV( response, options ); + + if ( false === holder[ providerKey ] ) { + callFunction( options.error, options, chart ); + raiseError( AmCharts.__( 'Error parsing CSV file', chart.language ) + ': ' + l.url, false, options ); + holder[ providerKey ] = []; + return; + } else { + holder[ providerKey ] = postprocess( holder[ providerKey ], options ); + callFunction( options.load, options, chart ); + } + + break; + + default: + callFunction( options.error, options, chart ); + raiseError( AmCharts.__( 'Unsupported data format', chart.language ) + ': ' + options.format, false, options.noStyles ); + return; + } + + // decrement remaining counter + l.remaining--; + + // we done? + if ( 0 === l.remaining ) { + + // callback + callFunction( options.complete, chart ); + + // take in the new data + if ( options.async ) { + + if ( 'map' === chart.type ) { + + // take in new data + chart.validateNow( true ); + + // remove curtain + removeCurtain(); + + } else { + + // add a dataUpdated event to handle post-load stuff + if ( 'gauge' !== chart.type ) { + chart.addListener( 'dataUpdated', function( event ) { + + // restore default period (stock chart) + if ( 'stock' === chart.type && !options.reloading && undefined !== chart.periodSelector ) { + chart.periodSelector.setDefaultPeriod(); + } + + // remove curtain + removeCurtain(); + + // remove this listener + chart.events.dataUpdated.pop(); + } ); + } + + + // take in new data + chart.validateData(); + + // invalidate size for the pie chart + // disabled for now as it is not longer necessary + /*if ( 'pie' === chart.type && chart.invalidateSize !== undefined ) + chart.invalidateSize();*/ + + // gauge chart does not trigger dataUpdated event + // let's explicitly remove the curtain for it + if ( 'gauge' === chart.type ) + removeCurtain(); + + // make the chart animate again + if ( l.startDuration ) { + if ( 'stock' === chart.type ) { + chart.panelsSettings.startDuration = l.startDuration; + for ( var x = 0; x < chart.panels.length; x++ ) { + chart.panels[ x ].startDuration = l.startDuration; + chart.panels[ x ].animateAgain(); + } + } else { + chart.startDuration = l.startDuration; + if ( chart.animateAgain !== undefined ) + chart.animateAgain(); + } + } + } + } + + } + + // schedule another load if necessary + if ( options.reload ) { + + if ( options.timeout ) + clearTimeout( options.timeout ); + + options.timeout = setTimeout( loadFile, 1000 * options.reload, url, holder, options ); + options.reloading = true; + + } + + } + + } ); + + } + + /** + * Checks if postProcess is set and invokes the handler + */ + function postprocess( data, options ) { + if ( undefined !== options.postProcess && isFunction( options.postProcess ) ) + try { + return options.postProcess.call( l, data, options, chart ); + } catch ( e ) { + raiseError( AmCharts.__( 'Error loading file', chart.language ) + ': ' + options.url, false, options ); + return data; + } else + return data; + } + + /** + * Returns true if argument is array + */ + function isObject( obj ) { + return 'object' === typeof( obj ); + } + + /** + * Returns true is argument is a function + */ + function isFunction( obj ) { + return 'function' === typeof( obj ); + } + + /** + * Applies defaults to config object + */ + function applyDefaults( obj ) { + for ( var x in defaults ) { + if ( defaults.hasOwnProperty( x ) ) + setDefault( obj, x, defaults[ x ] ); + } + } + + /** + * Checks if object property is set, sets with a default if it isn't + */ + function setDefault( obj, key, value ) { + if ( undefined === obj[ key ] ) + obj[ key ] = value; + } + + /** + * Raises an internal error (writes it out to console) + */ + function raiseError( msg, error, options ) { + + if ( options.showErrors ) + showCurtain( msg, options.noStyles ); + else { + removeCurtain(); + console.log( msg ); + } + + } + + /** + * Shows curtain over chart area + */ + function showCurtain( msg, noStyles ) { + + // remove previous curtain if there is one + removeCurtain(); + + // did we pass in the message? + if ( undefined === msg ) + msg = AmCharts.__( 'Loading data...', chart.language ); + + // create and populate curtain element + var curtain = document.createElement( 'div' ); + curtain.setAttribute( 'id', chart.div.id + '-curtain' ); + curtain.className = 'amcharts-dataloader-curtain'; + + if ( true !== noStyles ) { + curtain.style.position = 'absolute'; + curtain.style.top = 0; + curtain.style.left = 0; + curtain.style.width = ( undefined !== chart.realWidth ? chart.realWidth : chart.divRealWidth ) + 'px'; + curtain.style.height = ( undefined !== chart.realHeight ? chart.realHeight : chart.divRealHeight ) + 'px'; + curtain.style.textAlign = 'center'; + curtain.style.display = 'table'; + curtain.style.fontSize = '20px'; + try { + curtain.style.background = 'rgba(255, 255, 255, 0.3)'; + } catch ( e ) { + curtain.style.background = 'rgb(255, 255, 255)'; + } + curtain.innerHTML = '
' + msg + '
'; + } else { + curtain.innerHTML = msg; + } + chart.containerDiv.appendChild( curtain ); + + l.curtain = curtain; + } + + /** + * Removes the curtain + */ + function removeCurtain() { + try { + if ( undefined !== l.curtain ) + chart.containerDiv.removeChild( l.curtain ); + } catch ( e ) { + // do nothing + } + + l.curtain = undefined; + + } + + /** + * Execute callback function + */ + function callFunction( func, param1, param2, param3 ) { + if ( 'function' === typeof func ) + func.call( l, param1, param2, param3 ); + } + +}, [ 'pie', 'serial', 'xy', 'funnel', 'radar', 'gauge', 'gantt', 'stock', 'map' ] ); + + +/** + * Returns prompt in a chart language (set by chart.language) if it is + * available + */ +if ( undefined === AmCharts.__ ) { + AmCharts.__ = function( msg, language ) { + if ( undefined !== language && undefined !== AmCharts.translations.dataLoader[ language ] && undefined !== AmCharts.translations.dataLoader[ language ][ msg ] ) + return AmCharts.translations.dataLoader[ language ][ msg ]; + else + return msg; + }; +} + +/** + * Loads a file from url and calls function handler with the result + */ +AmCharts.loadFile = function( url, options, handler ) { + + // prepopulate options with minimal defaults if necessary + if ( typeof( options ) !== 'object' ) + options = {}; + if ( options.async === undefined ) + options.async = true; + + // create the request + var request; + if ( window.XMLHttpRequest ) { + // IE7+, Firefox, Chrome, Opera, Safari + request = new XMLHttpRequest(); + } else { + // code for IE6, IE5 + request = new ActiveXObject( 'Microsoft.XMLHTTP' ); + } + + // open the connection + try { + request.open( 'GET', options.timestamp ? AmCharts.timestampUrl( url ) : url, options.async ); + } catch ( e ) { + handler.call( this, false ); + } + + // add headers? + if ( options.headers !== undefined && options.headers.length ) { + for ( var i = 0; i < options.headers.length; i++ ) { + var header = options.headers[ i ]; + request.setRequestHeader( header.key, header.value ); + } + } + + // add onprogress handlers + if ( options.progress !== undefined && typeof( options.progress ) === 'function' ) { + request.onprogress = function( e ) { + var complete = ( e.loaded / e.total ) * 100; + options.progress.call( this, complete ); + } + } + + // set handler for data if async loading + request.onreadystatechange = function() { + + if ( 4 === request.readyState && 404 === request.status ) + handler.call( this, false ); + + else if ( 4 === request.readyState && 200 === request.status ) + handler.call( this, request.responseText ); + + }; + + // load the file + try { + request.send(); + } catch ( e ) { + handler.call( this, false ); + } + +}; + +/** + * Parses JSON string into an object + */ +AmCharts.parseJSON = function( response ) { + try { + if ( undefined !== JSON ) + return JSON.parse( response ); + else + return eval( response ); + } catch ( e ) { + return false; + } +}; + +/** + * Prases CSV string into an object + */ +AmCharts.parseCSV = function( response, options ) { + + // parse CSV into array + var data = AmCharts.CSVToArray( response, options.delimiter ); + + // do we need to cast some fields to numbers? + var numbers = options.numberFields && ( options.numberFields.length > 0 ); + + // init resuling array + var res = []; + var cols = []; + var col, i; + + // first row holds column names? + if ( options.useColumnNames ) { + cols = data.shift(); + + // normalize column names + for ( var x = 0; x < cols.length; x++ ) { + // trim + col = cols[ x ].replace( /^\s+|\s+$/gm, '' ); + + // check for empty + if ( '' === col ) + col = 'col' + x; + + cols[ x ] = col; + } + + if ( 0 < options.skip ) + options.skip--; + } + + // skip rows + for ( i = 0; i < options.skip; i++ ) + data.shift(); + + // iterate through the result set + var row; + while ( ( row = options.reverse ? data.pop() : data.shift() ) ) { + if ( options.skipEmpty && row.length === 1 && row[ 0 ] === '' ) + continue; + var dataPoint = {}; + for ( i = 0; i < row.length; i++ ) { + col = undefined === cols[ i ] ? 'col' + i : cols[ i ]; + dataPoint[ col ] = row[ i ] === "" ? options.emptyAs : row[ i ]; + + // check if we need to cast to integer + if ( numbers && options.numberFields.indexOf( col ) !== -1 ) + dataPoint[ col ] = Number( dataPoint[ col ] ); + } + res.push( dataPoint ); + } + + return res; +}; + +/** + * Parses CSV data into array + * Taken from here: (thanks!) + * http://www.bennadel.com/blog/1504-ask-ben-parsing-csv-strings-with-javascript-exec-regular-expression-command.htm + */ +AmCharts.CSVToArray = function( strData, strDelimiter ) { + // Check to see if the delimiter is defined. If not, + // then default to comma. + strDelimiter = ( strDelimiter || ',' ); + + // Create a regular expression to parse the CSV values. + var objPattern = new RegExp( + ( + // Delimiters. + "(\\" + strDelimiter + "|\\r?\\n|\\r|^)" + + + // Quoted fields. + "(?:\"([^\"]*(?:\"\"[^\"]*)*)\"|" + + + // Standard fields. + "([^\"\\" + strDelimiter + "\\r\\n]*))" + ), + "gi" + ); + + + // Create an array to hold our data. Give the array + // a default empty first row. + var arrData = [ + [] + ]; + + // Create an array to hold our individual pattern + // matching groups. + var arrMatches = null; + + + // Keep looping over the regular expression matches + // until we can no longer find a match. + while ( ( arrMatches = objPattern.exec( strData ) ) ) { + + // Get the delimiter that was found. + var strMatchedDelimiter = arrMatches[ 1 ]; + + // Check to see if the given delimiter has a length + // (is not the start of string) and if it matches + // field delimiter. If id does not, then we know + // that this delimiter is a row delimiter. + if ( + strMatchedDelimiter.length && + ( strMatchedDelimiter !== strDelimiter ) + ) { + + // Since we have reached a new row of data, + // add an empty row to our data array. + arrData.push( [] ); + + } + + + // Now that we have our delimiter out of the way, + // let's check to see which kind of value we + // captured (quoted or unquoted). + var strMatchedValue; + if ( arrMatches[ 2 ] ) { + + // We found a quoted value. When we capture + // this value, unescape any double quotes. + strMatchedValue = arrMatches[ 2 ].replace( + new RegExp( "\"\"", "g" ), + "\"" + ); + + } else { + + // We found a non-quoted value. + strMatchedValue = arrMatches[ 3 ]; + + } + + // Now that we have our value string, let's add + // it to the data array. + arrData[ arrData.length - 1 ].push( strMatchedValue ); + } + + // Return the parsed data. + return ( arrData ); +}; + +/** + * Appends timestamp to the url + */ +AmCharts.timestampUrl = function( url ) { + var p = url.split( '?' ); + if ( 1 === p.length ) + p[ 1 ] = new Date().getTime(); + else + p[ 1 ] += '&' + new Date().getTime(); + return p.join( '?' ); +}; \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/dataloader/dataloader.min.js b/iguana/js/amcharts/plugins/dataloader/dataloader.min.js new file mode 100755 index 000000000..b3727590c --- /dev/null +++ b/iguana/js/amcharts/plugins/dataloader/dataloader.min.js @@ -0,0 +1 @@ +AmCharts.translations.dataLoader={},AmCharts.addInitHandler(function(a){function e(b,d,g,h){void 0===h&&(h="dataProvider"),g.showCurtain&&l(void 0,g.noStyles),c.remaining++,c.percentLoaded[b]=0,void 0!==g.progress&&"function"==typeof g.progress&&void 0===g._progress&&(g._progress=g.progress,g.progress=function(a){c.percentLoaded[b]=a;var d=0,e=0;for(var f in c.percentLoaded)c.percentLoaded.hasOwnProperty(f)&&(e++,d+=c.percentLoaded[f]);var h=Math.round(d/e*100)/100;g._progress.call(this,h,Math.round(100*a)/100,b)}),AmCharts.loadFile(b,g,function(i){if(!1===i)n(g.error,g,a),k(AmCharts.__("Error loading the file",a.language)+": "+b,!1,g);else{switch(void 0===g.format&&(g.format="json"),g.format=g.format.toLowerCase(),g.format){case"json":if(d[h]=AmCharts.parseJSON(i),!1===d[h])return n(g.error,g,a),k(AmCharts.__("Error parsing JSON file",a.language)+": "+c.url,!1,g),void(d[h]=[]);d[h]=f(d[h],g),n(g.load,g,a);break;case"csv":if(d[h]=AmCharts.parseCSV(i,g),!1===d[h])return n(g.error,g,a),k(AmCharts.__("Error parsing CSV file",a.language)+": "+c.url,!1,g),void(d[h]=[]);d[h]=f(d[h],g),n(g.load,g,a);break;default:return n(g.error,g,a),void k(AmCharts.__("Unsupported data format",a.language)+": "+g.format,!1,g.noStyles)}if(c.remaining--,0===c.remaining&&(n(g.complete,a),g.async))if("map"===a.type)a.validateNow(!0),m();else if("gauge"!==a.type&&a.addListener("dataUpdated",function(b){"stock"!==a.type||g.reloading||void 0===a.periodSelector||a.periodSelector.setDefaultPeriod(),m(),a.events.dataUpdated.pop()}),a.validateData(),"gauge"===a.type&&m(),c.startDuration)if("stock"===a.type){a.panelsSettings.startDuration=c.startDuration;for(var j=0;j"}else e.innerHTML=b;a.containerDiv.appendChild(e),c.curtain=e}function m(){try{void 0!==c.curtain&&a.containerDiv.removeChild(c.curtain)}catch(b){}c.curtain=void 0}function n(a,b,d,e){"function"==typeof a&&a.call(c,b,d,e)}void 0!==a.dataLoader&&g(a.dataLoader)||(a.dataLoader={});var b=a.version.split(".");if(!(Number(b[0])<3||3===Number(b[0])&&Number(b[1])<13)){var c=a.dataLoader;c.remaining=0,c.percentLoaded={};var d={async:!0,format:"json",showErrors:!0,showCurtain:!0,noStyles:!1,reload:0,timestamp:!1,delimiter:",",skip:0,skipEmpty:!0,emptyAs:void 0,useColumnNames:!1,init:!1,progress:!1,reverse:!1,reloading:!1,complete:!1,error:!1,numberFields:[],headers:[],chart:a};c.loadData=function(){if("stock"===a.type)setTimeout(function(){0>a.panelsSettings.startDuration&&(c.startDuration=a.panelsSettings.startDuration,a.panelsSettings.startDuration=0);for(var b=0;b0,e=[],f=[];if(b.useColumnNames){f=c.shift();for(var i=0;iTexas is the second most populous (after California) and the second largest of the 50 U.S. states (after Alaska) in the United States of America, and the largest state in the 48 contiguous United States. Geographically located in the south central part of the country, Texas shares an international border with the Mexican states of Chihuahua, Coahuila, Nuevo León, and Tamaulipas to the south and borders the U.S. states of New Mexico to the west, Oklahoma to the north, Arkansas to the northeast, and Louisiana to the east. Texas has an area of 268,820 square miles (696,200 km2) and a growing population of over 26.9 million residents (July 2014).

" + }, { + "id": "US-UT", + "value": 2233169 + }, { + "id": "US-VT", + "value": 608827 + }, { + "id": "US-VA", + "value": 7078515 + }, { + "id": "US-WA", + "value": 5894121 + }, { + "id": "US-WV", + "value": 1808344 + }, { + "id": "US-WI", + "value": 5363675 + }, { + "id": "US-WY", + "value": 493782 + }] +} \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/dataloader/examples/data/map_areas.json b/iguana/js/amcharts/plugins/dataloader/examples/data/map_areas.json new file mode 100755 index 000000000..797c77723 --- /dev/null +++ b/iguana/js/amcharts/plugins/dataloader/examples/data/map_areas.json @@ -0,0 +1,152 @@ +[ { + "id": "US-AL", + "value": 4447100 +}, { + "id": "US-AK", + "value": 626932 +}, { + "id": "US-AZ", + "value": 5130632 +}, { + "id": "US-AR", + "value": 2673400 +}, { + "id": "US-CA", + "value": 33871648 +}, { + "id": "US-CO", + "value": 4301261 +}, { + "id": "US-CT", + "value": 3405565 +}, { + "id": "US-DE", + "value": 783600 +}, { + "id": "US-FL", + "value": 15982378 +}, { + "id": "US-GA", + "value": 8186453 +}, { + "id": "US-HI", + "value": 1211537 +}, { + "id": "US-ID", + "value": 1293953 +}, { + "id": "US-IL", + "value": 12419293 +}, { + "id": "US-IN", + "value": 6080485 +}, { + "id": "US-IA", + "value": 2926324 +}, { + "id": "US-KS", + "value": 2688418 +}, { + "id": "US-KY", + "value": 4041769 +}, { + "id": "US-LA", + "value": 4468976 +}, { + "id": "US-ME", + "value": 1274923 +}, { + "id": "US-MD", + "value": 5296486 +}, { + "id": "US-MA", + "value": 6349097 +}, { + "id": "US-MI", + "value": 9938444 +}, { + "id": "US-MN", + "value": 4919479 +}, { + "id": "US-MS", + "value": 2844658 +}, { + "id": "US-MO", + "value": 5595211 +}, { + "id": "US-MT", + "value": 902195 +}, { + "id": "US-NE", + "value": 1711263 +}, { + "id": "US-NV", + "value": 1998257 +}, { + "id": "US-NH", + "value": 1235786 +}, { + "id": "US-NJ", + "value": 8414350 +}, { + "id": "US-NM", + "value": 1819046 +}, { + "id": "US-NY", + "value": 18976457 +}, { + "id": "US-NC", + "value": 8049313 +}, { + "id": "US-ND", + "value": 642200 +}, { + "id": "US-OH", + "value": 11353140 +}, { + "id": "US-OK", + "value": 3450654 +}, { + "id": "US-OR", + "value": 3421399 +}, { + "id": "US-PA", + "value": 12281054 +}, { + "id": "US-RI", + "value": 1048319 +}, { + "id": "US-SC", + "value": 4012012 +}, { + "id": "US-SD", + "value": 754844 +}, { + "id": "US-TN", + "value": 5689283 +}, { + "id": "US-TX", + "value": 20851820, + "description": "

Texas is the second most populous (after California) and the second largest of the 50 U.S. states (after Alaska) in the United States of America, and the largest state in the 48 contiguous United States. Geographically located in the south central part of the country, Texas shares an international border with the Mexican states of Chihuahua, Coahuila, Nuevo León, and Tamaulipas to the south and borders the U.S. states of New Mexico to the west, Oklahoma to the north, Arkansas to the northeast, and Louisiana to the east. Texas has an area of 268,820 square miles (696,200 km2) and a growing population of over 26.9 million residents (July 2014).

" +}, { + "id": "US-UT", + "value": 2233169 +}, { + "id": "US-VT", + "value": 608827 +}, { + "id": "US-VA", + "value": 7078515 +}, { + "id": "US-WA", + "value": 5894121 +}, { + "id": "US-WV", + "value": 1808344 +}, { + "id": "US-WI", + "value": 5363675 +}, { + "id": "US-WY", + "value": 493782 +} ] \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/dataloader/examples/data/pie.csv b/iguana/js/amcharts/plugins/dataloader/examples/data/pie.csv new file mode 100755 index 000000000..c71ae9ee5 --- /dev/null +++ b/iguana/js/amcharts/plugins/dataloader/examples/data/pie.csv @@ -0,0 +1,8 @@ +country,litres +"Czech Republic",156.9 +"Ireland",131.1 +"Germany",115.8 +"Australia",109.9 +"Austria",108.3 +"UK",65 +"Belgium",50 \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/dataloader/examples/data/pie.json b/iguana/js/amcharts/plugins/dataloader/examples/data/pie.json new file mode 100755 index 000000000..d920b2254 --- /dev/null +++ b/iguana/js/amcharts/plugins/dataloader/examples/data/pie.json @@ -0,0 +1,22 @@ +[{ + "country": "Czech Republic", + "litres": 156.9 +}, { + "country": "Ireland", + "litres": 131.1 +}, { + "country": "Germany", + "litres": 115.8 +}, { + "country": "Australia", + "litres": 109.9 +}, { + "country": "Austria", + "litres": 108.3 +}, { + "country": "UK", + "litres": 65 +}, { + "country": "Belgium", + "litres": 50 +}] \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/dataloader/examples/data/serial.csv b/iguana/js/amcharts/plugins/dataloader/examples/data/serial.csv new file mode 100755 index 000000000..bc1236bf6 --- /dev/null +++ b/iguana/js/amcharts/plugins/dataloader/examples/data/serial.csv @@ -0,0 +1,20 @@ +year,cars,motorcycles,bicycles +2000,1587,650,121 +1995,1567,683,146 +1996,1617,691,138 +1997,1630,642,127 +1998,1660,699,105 +1999,1683,721,109 +2000,1691,737,112 +2001,1298,680,101 +2002,1275,664,97 +2003,1246,648,93 +2004,1218,637,101 +2005,1213,633,87 +2006,1199,621,79 +2007,1110,210,81 +2008,1165,232,75 +2009,1145,219,88 +2010,1163,201,82 +2011,1180,285,87 +2012,1159,277,71 \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/dataloader/examples/data/serial.json b/iguana/js/amcharts/plugins/dataloader/examples/data/serial.json new file mode 100755 index 000000000..889cff2ca --- /dev/null +++ b/iguana/js/amcharts/plugins/dataloader/examples/data/serial.json @@ -0,0 +1,96 @@ +[{ + "year": 2000, + "cars": 1587, + "motorcycles": 650, + "bicycles": 121 +}, { + "year": 1995, + "cars": 1567, + "motorcycles": 683, + "bicycles": 146 +}, { + "year": 1996, + "cars": 1617, + "motorcycles": 691, + "bicycles": 138 +}, { + "year": 1997, + "cars": 1630, + "motorcycles": 642, + "bicycles": 127 +}, { + "year": 1998, + "cars": 1660, + "motorcycles": 699, + "bicycles": 105 +}, { + "year": 1999, + "cars": 1683, + "motorcycles": 721, + "bicycles": 109 +}, { + "year": 2000, + "cars": 1691, + "motorcycles": 737, + "bicycles": 112 +}, { + "year": 2001, + "cars": 1298, + "motorcycles": 680, + "bicycles": 101 +}, { + "year": 2002, + "cars": 1275, + "motorcycles": 664, + "bicycles": 97 +}, { + "year": 2003, + "cars": 1246, + "motorcycles": 648, + "bicycles": 93 +}, { + "year": 2004, + "cars": 1218, + "motorcycles": 637, + "bicycles": 101 +}, { + "year": 2005, + "cars": 1213, + "motorcycles": 633, + "bicycles": 87 +}, { + "year": 2006, + "cars": 1199, + "motorcycles": 621, + "bicycles": 79 +}, { + "year": 2007, + "cars": 1110, + "motorcycles": 210, + "bicycles": 81 +}, { + "year": 2008, + "cars": 1165, + "motorcycles": 232, + "bicycles": 75 +}, { + "year": 2009, + "cars": 1145, + "motorcycles": 219, + "bicycles": 88 +}, { + "year": 2010, + "cars": 1163, + "motorcycles": 201, + "bicycles": 82 +}, { + "year": 2011, + "cars": 1180, + "motorcycles": 285, + "bicycles": 87 +}, { + "year": 2012, + "cars": 1159, + "motorcycles": 277, + "bicycles": 71 +}] \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/dataloader/examples/data/serial2.json b/iguana/js/amcharts/plugins/dataloader/examples/data/serial2.json new file mode 100755 index 000000000..396077182 --- /dev/null +++ b/iguana/js/amcharts/plugins/dataloader/examples/data/serial2.json @@ -0,0 +1,21 @@ +[{ + "year": 2005, + "income": 23.5, + "expenses": 18.1 +}, { + "year": 2006, + "income": 26.2, + "expenses": 22.8 +}, { + "year": 2007, + "income": 30.1, + "expenses": 23.9 +}, { + "year": 2008, + "income": 29.5, + "expenses": 25.1 +}, { + "year": 2009, + "income": 24.6, + "expenses": 25 +}] \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/dataloader/examples/gantt_json.html b/iguana/js/amcharts/plugins/dataloader/examples/gantt_json.html new file mode 100755 index 000000000..d715c5aca --- /dev/null +++ b/iguana/js/amcharts/plugins/dataloader/examples/gantt_json.html @@ -0,0 +1,70 @@ + + + + + + + amCharts Data Loader Example + + + + + + + + + + +
+ + + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/dataloader/examples/gauge_json.html b/iguana/js/amcharts/plugins/dataloader/examples/gauge_json.html new file mode 100755 index 000000000..68ee07514 --- /dev/null +++ b/iguana/js/amcharts/plugins/dataloader/examples/gauge_json.html @@ -0,0 +1,58 @@ + + + + + + + amCharts Data Loader Example + + + + + + + + +
+ + + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/dataloader/examples/map_json.html b/iguana/js/amcharts/plugins/dataloader/examples/map_json.html new file mode 100755 index 000000000..988ccaec8 --- /dev/null +++ b/iguana/js/amcharts/plugins/dataloader/examples/map_json.html @@ -0,0 +1,47 @@ + + + + + + + amCharts Data Loader Example + + + + + + + + + +
+ + + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/dataloader/examples/map_json_external_function.html b/iguana/js/amcharts/plugins/dataloader/examples/map_json_external_function.html new file mode 100755 index 000000000..2b6018db7 --- /dev/null +++ b/iguana/js/amcharts/plugins/dataloader/examples/map_json_external_function.html @@ -0,0 +1,55 @@ + + + + + + + amCharts Data Loader Example + + + + + + + + + +
+ + + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/dataloader/examples/pie_csv.html b/iguana/js/amcharts/plugins/dataloader/examples/pie_csv.html new file mode 100755 index 000000000..96bf588dd --- /dev/null +++ b/iguana/js/amcharts/plugins/dataloader/examples/pie_csv.html @@ -0,0 +1,58 @@ + + + + + + + amCharts Data Loader Example + + + + + + + + +
+ + + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/dataloader/examples/pie_json.html b/iguana/js/amcharts/plugins/dataloader/examples/pie_json.html new file mode 100755 index 000000000..9d9da85c5 --- /dev/null +++ b/iguana/js/amcharts/plugins/dataloader/examples/pie_json.html @@ -0,0 +1,44 @@ + + + + + + + amCharts Data Loader Example + + + + + + + + +
+ + + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/dataloader/examples/serial2_json.html b/iguana/js/amcharts/plugins/dataloader/examples/serial2_json.html new file mode 100755 index 000000000..a1b9bc9d8 --- /dev/null +++ b/iguana/js/amcharts/plugins/dataloader/examples/serial2_json.html @@ -0,0 +1,85 @@ + + + + + + + amCharts Data Loader Example + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/dataloader/examples/serial_csv.html b/iguana/js/amcharts/plugins/dataloader/examples/serial_csv.html new file mode 100755 index 000000000..ae35ff43a --- /dev/null +++ b/iguana/js/amcharts/plugins/dataloader/examples/serial_csv.html @@ -0,0 +1,112 @@ + + + + + + + amCharts Data Loader Example + + + + + + + + +
+ + + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/dataloader/examples/serial_json.html b/iguana/js/amcharts/plugins/dataloader/examples/serial_json.html new file mode 100755 index 000000000..5e18745ae --- /dev/null +++ b/iguana/js/amcharts/plugins/dataloader/examples/serial_json.html @@ -0,0 +1,108 @@ + + + + + + + amCharts Data Loader Example + + + + + + + + +
+ + + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/dataloader/examples/serial_with_dynamic_graphs.html b/iguana/js/amcharts/plugins/dataloader/examples/serial_with_dynamic_graphs.html new file mode 100755 index 000000000..a04350845 --- /dev/null +++ b/iguana/js/amcharts/plugins/dataloader/examples/serial_with_dynamic_graphs.html @@ -0,0 +1,100 @@ + + + + + + + amCharts Data Loader Example + + + + + + + + +
+ + + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/dataloader/examples/stock_csv_data_and_events.html b/iguana/js/amcharts/plugins/dataloader/examples/stock_csv_data_and_events.html new file mode 100755 index 000000000..18b304458 --- /dev/null +++ b/iguana/js/amcharts/plugins/dataloader/examples/stock_csv_data_and_events.html @@ -0,0 +1,312 @@ + + + + + + + amCharts Data Loader Example + + + + + + + + + +
+ + + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/dataloader/examples/stock_csv_progressbar.html b/iguana/js/amcharts/plugins/dataloader/examples/stock_csv_progressbar.html new file mode 100755 index 000000000..a0150ee39 --- /dev/null +++ b/iguana/js/amcharts/plugins/dataloader/examples/stock_csv_progressbar.html @@ -0,0 +1,371 @@ + + + + + + + amCharts Data Loader Example + + + + + + + + + + + + + + + +
+
+ +
+ + + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/dataloader/lang/en.js b/iguana/js/amcharts/plugins/dataloader/lang/en.js new file mode 100755 index 000000000..2190534be --- /dev/null +++ b/iguana/js/amcharts/plugins/dataloader/lang/en.js @@ -0,0 +1,6 @@ +AmCharts.translations.dataLoader.en = { + 'Error loading the file': 'Error loading the file', + 'Error parsing JSON file': 'Error parsing JSON file', + 'Unsupported data format': 'Unsupported data format', + 'Loading data...': 'Loading data...' +} \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/dataloader/lang/fr.js b/iguana/js/amcharts/plugins/dataloader/lang/fr.js new file mode 100755 index 000000000..7fd35896d --- /dev/null +++ b/iguana/js/amcharts/plugins/dataloader/lang/fr.js @@ -0,0 +1,6 @@ +AmCharts.translations.dataLoader.fr = { + 'Error loading the file': 'Erreur lors du chargement du fichier', + 'Error parsing JSON file': 'Erreur lors de l\'analyse du fichier JSON', + 'Unsupported data format': 'Le format des données n\'est pas supporté', + 'Loading data...': 'Chargement des données...' +} \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/dataloader/lang/lt.js b/iguana/js/amcharts/plugins/dataloader/lang/lt.js new file mode 100755 index 000000000..89a5e3295 --- /dev/null +++ b/iguana/js/amcharts/plugins/dataloader/lang/lt.js @@ -0,0 +1,6 @@ +AmCharts.translations.dataLoader.lt = { + 'Error loading the file': 'Nepavyko užkrauti failo', + 'Error parsing JSON file': 'Skaitant JSON failą įvyko klaida', + 'Unsupported data format': 'Nepalaikomas duomenų formatas', + 'Loading data...': 'Kraunami duomenys...' +} \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/dataloader/license.txt b/iguana/js/amcharts/plugins/dataloader/license.txt new file mode 100755 index 000000000..a765bc16b --- /dev/null +++ b/iguana/js/amcharts/plugins/dataloader/license.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/dataloader/readme.md b/iguana/js/amcharts/plugins/dataloader/readme.md new file mode 100755 index 000000000..caad9768d --- /dev/null +++ b/iguana/js/amcharts/plugins/dataloader/readme.md @@ -0,0 +1,374 @@ +# amCharts Data Loader + +Version: 1.0.16 + + +## Description + +By default all amCharts libraries accept data in JSON format. It needs to be +there when the web page loads, defined in-line or loaded via custom code. + +This plugin introduces are native wrapper that enables automatic loading of data +from external data data sources in CSV and JSON formats. + +Most of the times you will just need to provide a URL of the external data +source - static file or dynamically generated - and it will do the rest. + + +## Important notice + +Due to security measures implemented in most of the browsers, the external data +loader will work only when the page with the chart or map is loaded via web +server. + +So, any of the examples loaded locally (file:///) will not work. + +The page needs to be loaded via web server (http://) in order to work properly. + +Loading data from another domain than the web page is loaded is possible but is +a subject for `Access-Control-Allow-Origin` policies defined by the web server +you are loading data from. + +For more about loading data across domains use the following thread: +http://stackoverflow.com/questions/1653308/access-control-allow-origin-multiple-origin-domains + + +## Usage + +### 1) Include the minified version of file of this plugin. I.e.: + +``` + +``` + +(this needs to go after all the other amCharts includes) + +### 2) Add data source properties to your chart configuration. + +Regular (Serial, Pie, etc.) charts: + +``` +AmCharts.makeChart( "chartdiv", { + ..., + "dataLoader": { + "url": "data.json", + "format": "json" + } +} ); +``` + +Stock chart: + +``` +AmCharts.makeChart( "chartdiv", { + ..., + "dataSets": [{ + ..., + "dataLoader": { + "url": "data.csv", + "format": "csv", + "delimiter": ",", // column separator + "useColumnNames": true, // use first row for column names + "skip": 1 // skip header row + } + }] +} ); +``` + +That's it. The plugin will make sure the files are loaded and dataProvider is +populated with their content *before* the chart is built. + +Some formats, like CSV, will require additional parameters needed to parse the +data, such as "separator". + +If the "format" is omitted, the plugin will assume JSON. + + +## Complete list of available dataLoader settings + +Property | Default | Description +-------- | ------- | ----------- +async | true | If set to false (not recommended) everything will wait until data is fully loaded +complete | | Callback function to execute when loader is done +delimiter | , | [CSV only] a delimiter for columns (use \t for tab delimiters) +emptyAs | undefined | [CSV only] replace empty columns with whatever is set here +error | | Callback function to execute if file load fails +init | | Callback function to execute when Data Loader is initialized, before any loading starts +format | json | Type of data: json, csv +headers | | An array of objects with two properties (key and value) to attach to HTTP request +load | | Callback function to execute when file is successfully loaded (might be invoked multiple times) +noStyles | false | If set to true no styles will be applied to "Data loading" curtain +numberFields | | [CSV only] An array of fields in data to treat as numbers +postProcess | | If set to function reference, that function will be called to "post-process" loaded data before passing it on to chart. The handler function will receive two parameters: loaded data, Data Loader options +progress | | Set this to function reference to track progress of the load. The function will be passed in three parameters: global progress, individual file progress, file URL. +showErrors | true | Show loading errors in a chart curtain +showCurtain | true| Show curtain over the chart area when loading data +reload | 0 | Reload data every X seconds +reverse | false | [CSV only] add data points in revers order +skip | 0 | [CSV only] skip X first rows in data (includes first row if useColumnNames is used) +skipEmpty | true | [CSV only] Ignore empty lines in data +timestamp | false | Add current timestamp to data URLs (to avoid caching) +useColumnNames | false | [CSV only] Use first row in data as column names when parsing + + +## Using in JavaScript Stock Chart + +In JavaScript Stock Chart it works exactly the same as in other chart types, +with the exception that `dataLoader` is set as a property to the data set +definition. I.e.: + +``` +var chart = AmCharts.makeChart("chartdiv", { + "type": "stock", + ... + "dataSets": [{ + "title": "MSFT", + "fieldMappings": [{ + "fromField": "Open", + "toField": "open" + }, { + "fromField": "High", + "toField": "high" + }, { + "fromField": "Low", + "toField": "low" + }, { + "fromField": "Close", + "toField": "close" + }, { + "fromField": "Volume", + "toField": "volume" + }], + "compared": false, + "categoryField": "Date", + "dataLoader": { + "url": "data/MSFT.csv", + "format": "csv", + "showCurtain": true, + "showErrors": true, + "async": true, + "reverse": true, + "delimiter": ",", + "useColumnNames": true + } + } + }] +}); +``` + +### Can I also load event data the same way? + +Sure. You just add a `eventDataLoader` object to your data set. All the same +settings apply. + + +## Adding custom headers to HTTP requests + +If you want to add additional headers to your data load HTTP requests, use +"headers" array. Each header is an object with two keys: "key" and "value": + +``` +"dataLoader": { + "url": "data/serial.json", + "format": "json", + "headers": [{ + "key": "x-access-token", + "value": "123456789" + }] +} +``` + + +## Manually triggering a reload of all data + +Once chart is initialized, you can trigger the reload of all data manually by +calling `chart.dataLoader.loadData()` function. (replace "chart" with the actual +variable that holds reference to your chart object) + +## Using callback functions + +Data Loader can call your own function when certain event happens, like data +loading is complete, error occurs, etc. + +To set custom event handlers, use these config options: + +* "complete" +* "init" +* "load" +* "error" +* "progress" + +Example: + +``` +AmCharts.makeChart( "chartdiv", { + ..., + "dataSets": [{ + ..., + "dataLoader": { + "url": "data.json", + "init": function ( options, chart ) { + console.log( 'Loading started' ); + }, + "load": function ( options, chart ) { + console.log( 'Loaded file: ' + options.url ); + }, + "complete": function ( chart ) { + console.log( 'Woohoo! Finished loading' ); + }, + "error": function ( options, chart ) { + console.log( 'Ummm something went wrong loading this file: ' + options.url ); + }, + "progress": function( totalPercent, filePercent, url ) { + console.log( 'Total percent loaded: ' + Math.round( totalPercent ) ); + } + } + }] +} ); +``` + +## Translating into other languages + +Depending on configuration options the plugin will display a small number of +text prompts, like 'Data loading...'. + +Plugin will try matching chart's `language` property and display text prompts in +a corresponding language. For that the plugin needs to have the translations. + +Some of the plugin translations are in **lang** subdirectory. Simply include the +one you need. + +If there is no translation to your language readily available, just grab en.js, +copy it and translate. + +The structure is simple: + +``` +'The phrase in English': 'Translation' +``` + +The phrase in English must be left intact. + +When you're done, you can include your language as a JavaScript file. + +P.S. send us your translation so we can include it for the benefits of other +users. Thanks! + + +## Requirements + +This plugin requires at least 3.13 version of JavaScript Charts, JavaScript +Stock Chart or JavaScript Maps. + + +## Demos + +They're all in subdirectory /examples. + + +## Extending this plugin + +You're encouraged to modify, extend and make derivative plugins out of this +plugin. + +You can modify files, included in this archive or, better yet, fork this project +on GitHub: + +https://github.com/amcharts/dataloader + +We're curious types. Please let us know (contact@amcharts.com) if you do create +something new out of this plugin. + + +## License + +This plugin is licensed under Apache License 2.0. + +This basically means you're free to use or modify this plugin, even make your +own versions or completely different products out of it. + +Please see attached file "license.txt" for the complete license or online here: + +http://www.apache.org/licenses/LICENSE-2.0 + + +## Contact us + +* Email:contact@amcharts.com +* Web: http://www.amcharts.com/ +* Facebook: https://www.facebook.com/amcharts +* Twitter: https://twitter.com/amcharts + + +## Changelog + +### 1.0.16 +* Added "numberFields" config array + +### 1.0.15 +* Added "emptyAs" config property. Empty CSV values will be set to this (default `undefined`) + +### 1.0.14 +* Added "init" event handler, which is called **before** loading starts + +### 1.0.13 +* Added "progress" handler, which can be used to monitor data load progress + +### 1.0.12 +* Better default options handling in external calls to AmCharts.loadFile +* Fixed the latest version of Stock Chart not resetting to default pre-defined period +* New example: Using Data Loader functions externally (map_json_external_function.html) + +### 1.0.11 +* New translation: Added French translation. Thanks Remy! +* Tweaks to allow better animation after data load on Pie chart + +### 1.0.10 +* Fixed error related to headers not being set when using standalone data load functions + +### 1.0.9 +* Plugin will now ignore empty CSV lines by default (configurable with `skipEmpty` property) + +### 1.0.8 +* Added `headers` config variable which allows adding custom headers to HTTP requests + +### 1.0.7 +* Fixed an issue with the Pie chart when it is being loaded in inactive tab + +### 1.0.6 +* Added support for Gauge chart (loads `arrows` array) + +### 1.0.5 +* Fixed JS error if periodSelector was not defined in chart config +* Now all callback functions (complete, error, load) receive additional parameter: chart +* postProcess function will now have "this" context set to Data Loader object as well as receive chart reference as third paramater + +### 1.0.4 +* Added `chart.dataLoader.loadData()` function which can be used to manually trigger all data reload + +### 1.0.3 +* Fixed the bug where defaults were not being applied properly +* Fixed the bug with translations not being applied properly +* Cleaned up the code (to pass JSHint validation) + +### 1.0.2 +* Fixed the issue with modified Array prototypes + +### 1.0.1 +* Added `complete`, `load` and `error` properties that can be set with function handlers to be invoked on load completion, successful file load or failed load respectively +* Fixed language container initialization bug +* Fixed bug that was causing parse errors not be displayed + +### 1.0 +* Added GANTT chart support + +### 0.9.2 +* Added global data load methods that can be used to load and parse data by code outside plugin +* Trim CSV column names +* Translation added: Lithuanian + +### 0.9.1 +* Fix chart animations not playing after asynchronous load + +### 0.9 +* Initial release \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/export/LICENSE b/iguana/js/amcharts/plugins/export/LICENSE new file mode 100755 index 000000000..8f71f43fe --- /dev/null +++ b/iguana/js/amcharts/plugins/export/LICENSE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/iguana/js/amcharts/plugins/export/README.md b/iguana/js/amcharts/plugins/export/README.md new file mode 100755 index 000000000..b8cd7dfd6 --- /dev/null +++ b/iguana/js/amcharts/plugins/export/README.md @@ -0,0 +1,1149 @@ +# amCharts Export + +Version: 1.4.20 + + +## Description + +This plugin adds export capabilities to all amCharts products - charts and maps. + +It allows annotating and exporting chart or related data to various bitmap, +vector, document or data formats, such as PNG, JPG, PDF, SVG, JSON, XLSX and +many more. + + +## Important notice + +Please note that due to security measures implemented in modern browsers, some +or all export options might not work if the web page is loaded locally (via +file:///) or contain images loaded from different host than the web page itself. + + +## Usage + +### 1) Include the minified version of file of this plugin as well as the +bundled CSS file. I.e.: + +``` + + +``` + +Or if you'd rather use amCharts CDN: + +``` + + +``` + +(this needs to go after all the other amCharts includes) + +### 2) Enable `export` with default options: + +``` +AmCharts.makeChart( "chartdiv", { + ..., + "export": { + "enabled": true + } +} ); +``` + +### ... OR set your own custom options: + +``` +AmCharts.makeChart( "chartdiv", { + ..., + "export": { + "enabled": true, + "menu": [ { + "class": "export-main", + "menu": [ { + "label": "Download", + "menu": [ "PNG", "JPG", "CSV" ] + }, { + "label": "Annotate", + "action": "draw", + "menu": [ { + "class": "export-drawing", + "menu": [ "PNG", "JPG" ] + } ] + } ] + } ] + } +} ); +``` + + +## Loading external libraries needed for operation of this plugin + +The plugin relies on a number of different libraries, to export images, draw +annotations or generate download files. + +Those libraries need to be loaded for the plugin to work properly. + +There are two ways to load them. Choose the one that is right: + +### 1) Automatic (preferred) + +All libraries required for plugin operation are included withing plugins */libs* +subdirectory. + +The plugin will automatically try to look in chart's [`path`](http://docs.amcharts.com/3/javascriptcharts/AmSerialChart#path) +property. If your plugin files are located within plugins folder under amcharts +(as is the case with the default distributions), you don't need to do anything - +the libraries will load on-demand. + +If you are using relative url, note that it is relative to the web page you are +displaying your chart on, not the export.js library. + +In case you've moved the libs folder you need to tell the plugin where it is +`"libs": { "path": "../libs/" }` + +### 2) Manual + +You can also load all those JavaScript libraries by ` + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/export/examples/gantt.html b/iguana/js/amcharts/plugins/export/examples/gantt.html new file mode 100755 index 000000000..056f3b136 --- /dev/null +++ b/iguana/js/amcharts/plugins/export/examples/gantt.html @@ -0,0 +1,311 @@ + + + + + + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/export/examples/gauge.html b/iguana/js/amcharts/plugins/export/examples/gauge.html new file mode 100755 index 000000000..48cca2da9 --- /dev/null +++ b/iguana/js/amcharts/plugins/export/examples/gauge.html @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/export/examples/images/bicycle.png b/iguana/js/amcharts/plugins/export/examples/images/bicycle.png new file mode 100755 index 000000000..0873bf9b3 Binary files /dev/null and b/iguana/js/amcharts/plugins/export/examples/images/bicycle.png differ diff --git a/iguana/js/amcharts/plugins/export/examples/images/car.png b/iguana/js/amcharts/plugins/export/examples/images/car.png new file mode 100755 index 000000000..4214fb721 Binary files /dev/null and b/iguana/js/amcharts/plugins/export/examples/images/car.png differ diff --git a/iguana/js/amcharts/plugins/export/examples/images/motorcycle.png b/iguana/js/amcharts/plugins/export/examples/images/motorcycle.png new file mode 100755 index 000000000..47c6ce83f Binary files /dev/null and b/iguana/js/amcharts/plugins/export/examples/images/motorcycle.png differ diff --git a/iguana/js/amcharts/plugins/export/examples/index.html b/iguana/js/amcharts/plugins/export/examples/index.html new file mode 100755 index 000000000..247f55529 --- /dev/null +++ b/iguana/js/amcharts/plugins/export/examples/index.html @@ -0,0 +1,62 @@ + + + + + + + + + + + + + +
+ + +
+ + + + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/export/examples/map.html b/iguana/js/amcharts/plugins/export/examples/map.html new file mode 100755 index 000000000..4af3af63d --- /dev/null +++ b/iguana/js/amcharts/plugins/export/examples/map.html @@ -0,0 +1,209 @@ + + + + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/export/examples/pie1.html b/iguana/js/amcharts/plugins/export/examples/pie1.html new file mode 100755 index 000000000..a184752d5 --- /dev/null +++ b/iguana/js/amcharts/plugins/export/examples/pie1.html @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/export/examples/pie2.html b/iguana/js/amcharts/plugins/export/examples/pie2.html new file mode 100755 index 000000000..230003896 --- /dev/null +++ b/iguana/js/amcharts/plugins/export/examples/pie2.html @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/export/examples/pie3.html b/iguana/js/amcharts/plugins/export/examples/pie3.html new file mode 100755 index 000000000..7a30af3cf --- /dev/null +++ b/iguana/js/amcharts/plugins/export/examples/pie3.html @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + +
+
+ + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/export/examples/pie4.html b/iguana/js/amcharts/plugins/export/examples/pie4.html new file mode 100755 index 000000000..0b5dfbb85 --- /dev/null +++ b/iguana/js/amcharts/plugins/export/examples/pie4.html @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + +
+
+ + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/export/examples/radar.html b/iguana/js/amcharts/plugins/export/examples/radar.html new file mode 100755 index 000000000..b3dae3db5 --- /dev/null +++ b/iguana/js/amcharts/plugins/export/examples/radar.html @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/export/examples/serial1.html b/iguana/js/amcharts/plugins/export/examples/serial1.html new file mode 100755 index 000000000..cce7d8af8 --- /dev/null +++ b/iguana/js/amcharts/plugins/export/examples/serial1.html @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/export/examples/serial2.html b/iguana/js/amcharts/plugins/export/examples/serial2.html new file mode 100755 index 000000000..2291115cd --- /dev/null +++ b/iguana/js/amcharts/plugins/export/examples/serial2.html @@ -0,0 +1,112 @@ + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/iguana/js/amcharts/plugins/export/examples/serial3.html b/iguana/js/amcharts/plugins/export/examples/serial3.html new file mode 100755 index 000000000..9c05934d8 --- /dev/null +++ b/iguana/js/amcharts/plugins/export/examples/serial3.html @@ -0,0 +1,112 @@ + + + + + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/export/examples/stock.html b/iguana/js/amcharts/plugins/export/examples/stock.html new file mode 100755 index 000000000..657794460 --- /dev/null +++ b/iguana/js/amcharts/plugins/export/examples/stock.html @@ -0,0 +1,223 @@ + + + + + + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/export/examples/xy.html b/iguana/js/amcharts/plugins/export/examples/xy.html new file mode 100755 index 000000000..c1031265c --- /dev/null +++ b/iguana/js/amcharts/plugins/export/examples/xy.html @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/export/export.css b/iguana/js/amcharts/plugins/export/export.css new file mode 100755 index 000000000..c8dc32aac --- /dev/null +++ b/iguana/js/amcharts/plugins/export/export.css @@ -0,0 +1,348 @@ +/** + * Drawing mode + */ +.amcharts-export-canvas { + position: absolute; + display: none; + z-index: 1; + top: 0; + right: 0; + bottom: 0; + left: 0; + background-color: #fff; +} +.amcharts-export-canvas.active { + display: block; +} + +/** + * Menu; Rest state + */ +.amcharts-export-menu { + position: absolute; + z-index: 2; + opacity: 0.5; + color: #000; +} +.amcharts-main-div:hover .amcharts-export-menu, .amcharts-stock-div:hover .amcharts-export-menu { + opacity: 1; +} +.amcharts-export-menu-top-left > ul > li > ul:after { + content: ""; + position: absolute; + top: 13px; + right: 100%; + z-index: 1000; + border-top: 7px solid transparent; + border-left: 7px solid transparent; + border-right: 7px solid #fff; + border-bottom: 7px solid transparent; +} +.amcharts-export-menu-top-left > ul > li > ul > li:first-child > a:after { + content: ""; + position: absolute; + top: 12px; + right: 100%; + z-index: 1001; + border-top: 8px solid transparent; + border-left: 8px solid transparent; + border-right: 8px solid #e2e2e2; + border-bottom: 8px solid transparent; +} +.amcharts-export-menu-top-right > ul > li > ul:after { + content: ""; + position: absolute; + top: 13px; + left: 100%; + z-index: 1000; + border-top: 7px solid transparent; + border-left: 7px solid #fff; + border-right: 7px solid transparent; + border-bottom: 7px solid transparent; +} +.amcharts-export-menu-top-right > ul > li > ul > li:first-child > a:after { + content: ""; + position: absolute; + top: 12px; + left: 100%; + z-index: 1001; + border-top: 8px solid transparent; + border-left: 8px solid #e2e2e2; + border-right: 8px solid transparent; + border-bottom: 8px solid transparent; +} +.amcharts-export-menu-bottom-left > ul > li > ul:after { + content: ""; + position: absolute; + bottom: 13px; + right: 100%; + z-index: 1000; + border-top: 7px solid transparent; + border-left: 7px solid transparent; + border-right: 7px solid #fff; + border-bottom: 7px solid transparent; +} +.amcharts-export-menu-bottom-left > ul > li > ul > li:last-child > a:after { + content: ""; + position: absolute; + bottom: 12px; + right: 100%; + z-index: 1001; + border-top: 8px solid transparent; + border-left: 8px solid transparent; + border-right: 8px solid #e2e2e2; + border-bottom: 8px solid transparent; +} +.amcharts-export-menu-bottom-right > ul > li > ul:after { + content: ""; + position: absolute; + bottom: 13px; + left: 100%; + z-index: 1000; + border-top: 7px solid transparent; + border-left: 7px solid #fff; + border-right: 7px solid transparent; + border-bottom: 7px solid transparent; +} +.amcharts-export-menu-bottom-right > ul > li > ul > li:last-child > a:after { + content: ""; + position: absolute; + bottom: 12px; + left: 100%; + z-index: 1001; + border-top: 8px solid transparent; + border-left: 8px solid #e2e2e2; + border-right: 8px solid transparent; + border-bottom: 8px solid transparent; +} +.amcharts-export-menu ul { + list-style: none; + margin: 0; + padding: 0; +} +.amcharts-export-menu li { + position: relative; + display: block; + z-index: 1; +} +.amcharts-export-menu li > ul { + position: absolute; + display: none; + border: 1px solid #e2e2e2; + margin-top: -1px; + background: #fff; +} +.amcharts-export-menu li > a { + position: relative; + display: block; + color: #000; + text-decoration: none; + padding: 12px 12px; + z-index: 2; + white-space: nowrap; + border-bottom: 1px solid #f2f2f2; +} +.amcharts-export-menu li:last-child > a { + border-bottom: none; +} +.amcharts-export-menu li > a > img { + border: none; +} +.amcharts-export-menu-top-left { + top: 0; + left: 0; +} +.amcharts-export-menu-bottom-left { + bottom: 0; + left: 0; +} +.amcharts-export-menu-top-right { + top: 0; + right: 0; +} +.amcharts-export-menu-bottom-right { + bottom: 0; + right: 0; +} + +/** + * Menu; Hover state + */ +.amcharts-export-menu li:hover > ul { + display: block; +} +.amcharts-export-menu li:hover > a { + color: #fff; + background-color: #636363; +} +.amcharts-export-menu-top-left li:hover > ul { + left: 100%; + top: 0; +} +.amcharts-export-menu-bottom-left li:hover > ul { + left: 100%; + bottom: 0; +} +.amcharts-export-menu-top-right li:hover > ul { + top: 0; + right: 100%; +} +.amcharts-export-menu-bottom-right li:hover > ul { + bottom: 0; + right: 100%; +} + +/** + * Menu; custom class + */ +.amcharts-export-menu .export-main > a, .amcharts-export-menu .export-drawing > a, .amcharts-export-menu .export-delayed-capturing > a { + display: block; + overflow: hidden; + text-indent: -13333337px; + width: 36px; + height: 36px; + padding: 0; + background-repeat: no-repeat; + background-image: url('data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20width%3D%2211px%22%20height%3D%2214px%22%3E%3Cpath%20d%3D%22M3%2C0%20L8%2C0%20L8%2C5%20L11%2C5%20L5.5%2C10%20L0%2C5%20L3%2C5%20L03%2C0%22%20fill%3D%22%23888%22%2F%3E%3Crect%20x%3D%220%22%20y%3D%2212%22%20fill%3D%22%23888%22%20width%3D%2211%22%20height%3D%222%22%2F%3E%3C%2Fsvg%3E'); + background-color: #fff; + background-position: center; + -webkit-box-shadow: 1px 1px 3px 0px rgba(0,0,0,0.5); + -moz-box-shadow: 1px 1px 3px 0px rgba(0,0,0,0.5); + box-shadow: 1px 1px 3px 0px rgba(0,0,0,0.5); + border-radius: 18px; + margin: 8px 8px 0 10px; +} +.amcharts-export-menu .export-drawing > a { + background-image: url('data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20version%3D%221.1%22%20width%3D%2216px%22%20height%3D%2217px%22%3E%3Crect%20x%3D%220%22%20y%3D%2216%22%20fill%3D%22%23888%22%20width%3D%2214%22%20height%3D%221%22%2F%3E%3Cpath%20transform%3D%22translate(-12%2C-10)%22%20fill%3D%22%23888%22%20d%3D%22M17.098%2C20.305c-0.142%2C0.146%2C0.101%2C0.04%2C0.137%2C0.004c0.027-0.028%2C0.204-0.09%2C0.484-0.09c0.338%2C0%2C0.626%2C0.092%2C0.787%2C0.255%20c0.473%2C0.472%2C0.424%2C0.932%2C0.393%2C1.078l-2.521%2C1.055l-1.577-1.577l1.054-2.52c0.039-0.009%2C0.105-0.018%2C0.188-0.018%20c0.219%2C0%2C0.555%2C0.069%2C0.893%2C0.407c0.378%2C0.378%2C0.246%2C1.188%2C0.166%2C1.271C17.062%2C20.207%2C17.062%2C20.269%2C17.098%2C20.305z%20M26.984%2C14.472c-0.008-0.674-0.61-1.257-1.31-1.933c-0.134-0.129-0.679-0.673-0.809-0.808c-0.679-0.702-1.266-1.31-1.943-1.31%20c-0.37%2C0-0.734%2C0.207-1.114%2C0.587l-6.852%2C6.847c-0.012%2C0.016-2.877%2C7.354-2.877%2C7.354c-0.012%2C0.032%2C0%2C0.063%2C0.022%2C0.091%20c0.021%2C0.021%2C0.044%2C0.029%2C0.067%2C0.029c0.01%2C0%2C0.018-0.003%2C0.028-0.007c0%2C0%2C7.357-2.864%2C7.369-2.877l6.854-6.847%20C26.803%2C15.216%2C26.988%2C14.848%2C26.984%2C14.472z%22%2F%3E%3C%2Fsvg%3E'); +} +.amcharts-export-menu .export-main:hover, .amcharts-export-menu .export-drawing:hover { + padding-bottom: 100px; +} +.amcharts-export-menu.amcharts-export-menu-bottom-left .export-main:hover, .amcharts-export-menu.amcharts-export-menu-bottom-left .export-drawing:hover, .amcharts-export-menu.amcharts-export-menu-bottom-right .export-main:hover, .amcharts-export-menu.amcharts-export-menu-bottom-right .export-drawing:hover { + padding-bottom: 0; + padding-top: 100px; +} +.amcharts-export-menu .export-main:hover > a { + background-image: url('data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20width%3D%2211px%22%20height%3D%2214px%22%3E%3Cpath%20d%3D%22M3%2C0%20L8%2C0%20L8%2C5%20L11%2C5%20L5.5%2C10%20L0%2C5%20L3%2C5%20L03%2C0%22%20fill%3D%22%23fff%22%2F%3E%3Crect%20x%3D%220%22%20y%3D%2212%22%20fill%3D%22%23fff%22%20width%3D%2211%22%20height%3D%222%22%2F%3E%3C%2Fsvg%3E'); +} +.amcharts-export-menu .export-drawing:hover > a { + background-image: url('data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20version%3D%221.1%22%20width%3D%2216px%22%20height%3D%2217px%22%3E%3Crect%20x%3D%220%22%20y%3D%2216%22%20fill%3D%22%23FFF%22%20width%3D%2214%22%20height%3D%221%22%2F%3E%3Cpath%20transform%3D%22translate(-12%2C-10)%22%20fill%3D%22%23FFF%22%20d%3D%22M17.098%2C20.305c-0.142%2C0.146%2C0.101%2C0.04%2C0.137%2C0.004c0.027-0.028%2C0.204-0.09%2C0.484-0.09c0.338%2C0%2C0.626%2C0.092%2C0.787%2C0.255%20c0.473%2C0.472%2C0.424%2C0.932%2C0.393%2C1.078l-2.521%2C1.055l-1.577-1.577l1.054-2.52c0.039-0.009%2C0.105-0.018%2C0.188-0.018%20c0.219%2C0%2C0.555%2C0.069%2C0.893%2C0.407c0.378%2C0.378%2C0.246%2C1.188%2C0.166%2C1.271C17.062%2C20.207%2C17.062%2C20.269%2C17.098%2C20.305z%20M26.984%2C14.472c-0.008-0.674-0.61-1.257-1.31-1.933c-0.134-0.129-0.679-0.673-0.809-0.808c-0.679-0.702-1.266-1.31-1.943-1.31%20c-0.37%2C0-0.734%2C0.207-1.114%2C0.587l-6.852%2C6.847c-0.012%2C0.016-2.877%2C7.354-2.877%2C7.354c-0.012%2C0.032%2C0%2C0.063%2C0.022%2C0.091%20c0.021%2C0.021%2C0.044%2C0.029%2C0.067%2C0.029c0.01%2C0%2C0.018-0.003%2C0.028-0.007c0%2C0%2C7.357-2.864%2C7.369-2.877l6.854-6.847%20C26.803%2C15.216%2C26.988%2C14.848%2C26.984%2C14.472z%22%2F%3E%3C%2Fsvg%3E'); +} +.amcharts-export-menu .export-close > a, +.amcharts-export-menu .export-close:hover > a { + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAAQCAYAAADNo/U5AAAACXBIWXMAAAsTAAALEwEAmpwYAABBsGlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS41LWMwMjEgNzkuMTU1NzcyLCAyMDE0LzAxLzEzLTE5OjQ0OjAwICAgICAgICAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgICAgICAgICAgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiCiAgICAgICAgICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgICAgICAgICB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOnRpZmY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vdGlmZi8xLjAvIgogICAgICAgICAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyI+CiAgICAgICAgIDx4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ+eG1wLmRpZDo4M2Q5NDllYS1lMjE3LTQ3Y2QtYTU1Ni04MTQ3NmRjNWEwYWQ8L3htcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOkRvY3VtZW50SUQ+YWRvYmU6ZG9jaWQ6cGhvdG9zaG9wOjZhMTQ5MTc1LTNiODItMTE3OC05ZjZmLWY0MWMwNTYyYzQxYTwveG1wTU06RG9jdW1lbnRJRD4KICAgICAgICAgPHhtcE1NOkluc3RhbmNlSUQ+eG1wLmlpZDpkZGFhNTJkMi1mZDRiLTRkMmMtODEzOC01ZTEzNmQ4NGFjMDE8L3htcE1NOkluc3RhbmNlSUQ+CiAgICAgICAgIDx4bXBNTTpEZXJpdmVkRnJvbSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgIDxzdFJlZjppbnN0YW5jZUlEPnhtcC5paWQ6MDdhZmI1Y2UtYzQ1OS00YzQxLWJkMjItMTllMDJlMGE5YzVjPC9zdFJlZjppbnN0YW5jZUlEPgogICAgICAgICAgICA8c3RSZWY6ZG9jdW1lbnRJRD54bXAuZGlkOjA3YWZiNWNlLWM0NTktNGM0MS1iZDIyLTE5ZTAyZTBhOWM1Yzwvc3RSZWY6ZG9jdW1lbnRJRD4KICAgICAgICAgICAgPHN0UmVmOm9yaWdpbmFsRG9jdW1lbnRJRD54bXAuZGlkOjgzZDk0OWVhLWUyMTctNDdjZC1hNTU2LTgxNDc2ZGM1YTBhZDwvc3RSZWY6b3JpZ2luYWxEb2N1bWVudElEPgogICAgICAgICA8L3htcE1NOkRlcml2ZWRGcm9tPgogICAgICAgICA8eG1wTU06SGlzdG9yeT4KICAgICAgICAgICAgPHJkZjpTZXE+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPnNhdmVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDppbnN0YW5jZUlEPnhtcC5paWQ6YmY3ZmRlNGYtZDk2MS00Njk4LWI0ZjAtMDJlYjEwOWE4OTA4PC9zdEV2dDppbnN0YW5jZUlEPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6d2hlbj4yMDE1LTA1LTE1VDEzOjE3OjQ5KzAyOjAwPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6c29mdHdhcmVBZ2VudD5BZG9iZSBQaG90b3Nob3AgQ0MgMjAyMSAoTWFjaW50b3NoKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmNoYW5nZWQ+Lzwvc3RFdnQ6Y2hhbmdlZD4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPmNvbnZlcnRlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6cGFyYW1ldGVycz5mcm9tIGltYWdlL3BuZyB0byBhcHBsaWNhdGlvbi92bmQuYWRvYmUucGhvdG9zaG9wPC9zdEV2dDpwYXJhbWV0ZXJzPgogICAgICAgICAgICAgICA8L3JkZjpsaT4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDphY3Rpb24+ZGVyaXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6cGFyYW1ldGVycz5jb252ZXJ0ZWQgZnJvbSBpbWFnZS9wbmcgdG8gYXBwbGljYXRpb24vdm5kLmFkb2JlLnBob3Rvc2hvcDwvc3RFdnQ6cGFyYW1ldGVycz4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPnNhdmVkPC9zdEV2dDphY3Rpb24+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDppbnN0YW5jZUlEPnhtcC5paWQ6MDdhZmI1Y2UtYzQ1OS00YzQxLWJkMjItMTllMDJlMGE5YzVjPC9zdEV2dDppbnN0YW5jZUlEPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6d2hlbj4yMDE1LTA1LTE1VDEzOjE3OjQ5KzAyOjAwPC9zdEV2dDp3aGVuPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6c29mdHdhcmVBZ2VudD5BZG9iZSBQaG90b3Nob3AgQ0MgMjAyMSAoTWFjaW50b3NoKTwvc3RFdnQ6c29mdHdhcmVBZ2VudD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmNoYW5nZWQ+Lzwvc3RFdnQ6Y2hhbmdlZD4KICAgICAgICAgICAgICAgPC9yZGY6bGk+CiAgICAgICAgICAgICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0iUmVzb3VyY2UiPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6YWN0aW9uPmRlcml2ZWQ8L3N0RXZ0OmFjdGlvbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnBhcmFtZXRlcnM+Y29udmVydGVkIGZyb20gYXBwbGljYXRpb24vdm5kLmFkb2JlLnBob3Rvc2hvcCB0byBpbWFnZS9wbmc8L3N0RXZ0OnBhcmFtZXRlcnM+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICAgICA8cmRmOmxpIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OmFjdGlvbj5zYXZlZDwvc3RFdnQ6YWN0aW9uPgogICAgICAgICAgICAgICAgICA8c3RFdnQ6aW5zdGFuY2VJRD54bXAuaWlkOmRkYWE1MmQyLWZkNGItNGQyYy04MTM4LTVlMTM2ZDg0YWMwMTwvc3RFdnQ6aW5zdGFuY2VJRD4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OndoZW4+MjAxNS0wNS0xNVQxMzoyMToyMSswMjowMDwvc3RFdnQ6d2hlbj4KICAgICAgICAgICAgICAgICAgPHN0RXZ0OnNvZnR3YXJlQWdlbnQ+QWRvYmUgUGhvdG9zaG9wIENDIDIwMjEgKE1hY2ludG9zaCk8L3N0RXZ0OnNvZnR3YXJlQWdlbnQ+CiAgICAgICAgICAgICAgICAgIDxzdEV2dDpjaGFuZ2VkPi88L3N0RXZ0OmNoYW5nZWQ+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICA8L3JkZjpTZXE+CiAgICAgICAgIDwveG1wTU06SGlzdG9yeT4KICAgICAgICAgPHhtcDpDcmVhdG9yVG9vbD5BZG9iZSBQaG90b3Nob3AgQ0MgMjAxNCAoTWFjaW50b3NoKTwveG1wOkNyZWF0b3JUb29sPgogICAgICAgICA8eG1wOkNyZWF0ZURhdGU+MjAxNS0wNS0xNVQxMzoxMzoxNyswMjowMDwveG1wOkNyZWF0ZURhdGU+CiAgICAgICAgIDx4bXA6TW9kaWZ5RGF0ZT4yMDE1LTA1LTE1VDEzOjIxOjIxKzAyOjAwPC94bXA6TW9kaWZ5RGF0ZT4KICAgICAgICAgPHhtcDpNZXRhZGF0YURhdGU+MjAxNS0wNS0xNVQxMzoyMToyMSswMjowMDwveG1wOk1ldGFkYXRhRGF0ZT4KICAgICAgICAgPGRjOmZvcm1hdD5pbWFnZS9wbmc8L2RjOmZvcm1hdD4KICAgICAgICAgPHBob3Rvc2hvcDpDb2xvck1vZGU+MzwvcGhvdG9zaG9wOkNvbG9yTW9kZT4KICAgICAgICAgPHBob3Rvc2hvcDpUZXh0TGF5ZXJzPgogICAgICAgICAgICA8cmRmOkJhZz4KICAgICAgICAgICAgICAgPHJkZjpsaSByZGY6cGFyc2VUeXBlPSJSZXNvdXJjZSI+CiAgICAgICAgICAgICAgICAgIDxwaG90b3Nob3A6TGF5ZXJOYW1lPlg8L3Bob3Rvc2hvcDpMYXllck5hbWU+CiAgICAgICAgICAgICAgICAgIDxwaG90b3Nob3A6TGF5ZXJUZXh0Plg8L3Bob3Rvc2hvcDpMYXllclRleHQ+CiAgICAgICAgICAgICAgIDwvcmRmOmxpPgogICAgICAgICAgICA8L3JkZjpCYWc+CiAgICAgICAgIDwvcGhvdG9zaG9wOlRleHRMYXllcnM+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjcyMDAwMC8xMDAwMDwvdGlmZjpYUmVzb2x1dGlvbj4KICAgICAgICAgPHRpZmY6WVJlc29sdXRpb24+NzIwMDAwLzEwMDAwPC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpSZXNvbHV0aW9uVW5pdD4yPC90aWZmOlJlc29sdXRpb25Vbml0PgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjY1NTM1PC9leGlmOkNvbG9yU3BhY2U+CiAgICAgICAgIDxleGlmOlBpeGVsWERpbWVuc2lvbj4xMzwvZXhpZjpQaXhlbFhEaW1lbnNpb24+CiAgICAgICAgIDxleGlmOlBpeGVsWURpbWVuc2lvbj4xNjwvZXhpZjpQaXhlbFlEaW1lbnNpb24+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIAo8P3hwYWNrZXQgZW5kPSJ3Ij8+HyMp+AAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAA3UlEQVR42rSSXZECQQyEPygMrIVFAidhkQASQEIjYVsCSOAksBJAAlhAwvKSWcJBUQVVl6fM5Ke7k4z6vudTG/OFTQAktcAs/ja2TyVBUgVsgQq42F5PItYBCn8PTFNjAYvw5wM92x3gCNSSFCh1araLvAdNBi53VgMtgCuweRqE7RyogAPQxHsdcQBGf0cuaZ80APzaXn468urtniQ1CaXoayStct5AL4QfgToKfoBzIF2BadGVkVZRkIU7UdQDkqRZoDwJl3ROzea2u4LUvtpHOavkty9H/m9XfhsA0l9VuzQDWrIAAAAASUVORK5CYII=); +} + +/** + * Menu; Color picker + */ + +.amcharts-export-menu .export-drawing-color { + background: #000; + width: 35px; +} +.amcharts-export-menu .export-drawing-color > a { + display: block; + overflow: hidden; + text-indent: -13333337px; +} +.amcharts-export-menu .export-drawing-color-red { + background: #f00; +} +.amcharts-export-menu .export-drawing-color-green { + background: #0f0; +} +.amcharts-export-menu .export-drawing-color-blue { + background: #00f; +} +.amcharts-export-menu .export-drawing-color-white { + background: #fff; +} + +/* +** Fallback +*/ +.amcharts-export-fallback { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + background-color: #fff; +} +.amcharts-export-fallback textarea { + border: none; + outline: none; + position: absolute; + overflow: hidden; + width: 100%; + height: 100%; + padding: 20px; +} +.amcharts-export-fallback-message { + position: absolute; + z-index: 1; + padding: 20px; + width: 100%; + background-color: #fff; +} + +/* +** DELAYED CAPTURING +*/ +.amcharts-export-menu .export-delayed-capturing > a { + text-indent: 0px; + line-height: 36px; + vertical-align: middle; + text-align: center; + background-image: none; +} + +/* +** TRANSITION; OPACITY +*/ +.amcharts-export-menu, +.amcharts-export-canvas .canvas-container { + -webkit-transition: opacity 0.5s ease-out; + -moz-transition: opacity 0.5s ease-out; + -ms-transition: opacity 0.5s ease-out; + -o-transition: opacity 0.5s ease-out; + transition: opacity 0.5s ease-out; +} +.amcharts-export-canvas.dropbox .canvas-container { + opacity: 0.5; +} + + +/* +** SHAPE +*/ +.amcharts-export-menu .export-drawing-shape a { + font: 0/0 a; + text-shadow: none; + color: transparent; +} +.amcharts-export-menu li img { + height: 20px; +} + + +/* +** BRUSH +*/ +.amcharts-export-menu .export-drawing-width a { + text-align: center; +} +.amcharts-export-menu .export-drawing-width span { + display: block; + margin: 0 auto; +} +.amcharts-export-menu .export-drawing-width span > span { + display: block; + background: #000; + border-radius: 100%; +} +.amcharts-export-menu .export-drawing-shape a:hover img { + -webkit-filter: invert(100%); + filter: invert(100%); +} \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/export/export.js b/iguana/js/amcharts/plugins/export/export.js new file mode 100755 index 000000000..1ab4d5162 --- /dev/null +++ b/iguana/js/amcharts/plugins/export/export.js @@ -0,0 +1,3239 @@ +/* +Plugin Name: amCharts Export +Description: Adds export capabilities to amCharts products +Author: Benjamin Maertz, amCharts +Version: 1.4.20 +Author URI: http://www.amcharts.com/ + +Copyright 2015 amCharts + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +Please note that the above license covers only this plugin. It by all means does +not apply to any other amCharts products that are covered by different licenses. +*/ + +/* + ** Polyfill translation + */ +if ( !AmCharts.translations[ "export" ] ) { + AmCharts.translations[ "export" ] = {} +} +if ( !AmCharts.translations[ "export" ][ "en" ] ) { + AmCharts.translations[ "export" ][ "en" ] = { + "fallback.save.text": "CTRL + C to copy the data into the clipboard.", + "fallback.save.image": "Rightclick -> Save picture as... to save the image.", + + "capturing.delayed.menu.label": "{{duration}}", + "capturing.delayed.menu.title": "Click to cancel", + + "menu.label.print": "Print", + "menu.label.undo": "Undo", + "menu.label.redo": "Redo", + "menu.label.cancel": "Cancel", + + "menu.label.save.image": "Download as ...", + "menu.label.save.data": "Save as ...", + + "menu.label.draw": "Annotate ...", + "menu.label.draw.change": "Change ...", + "menu.label.draw.add": "Add ...", + "menu.label.draw.shapes": "Shape ...", + "menu.label.draw.colors": "Color ...", + "menu.label.draw.widths": "Size ...", + "menu.label.draw.opacities": "Opacity ...", + "menu.label.draw.text": "Text", + + "menu.label.draw.modes": "Mode ...", + "menu.label.draw.modes.pencil": "Pencil", + "menu.label.draw.modes.line": "Line", + "menu.label.draw.modes.arrow": "Arrow" + } +} + +/* + ** Polyfill export class + */ +( function() { + AmCharts[ "export" ] = function( chart, config ) { + var _this = { + name: "export", + version: "1.4.20", + libs: { + async: true, + autoLoad: true, + reload: false, + resources: [ { + "pdfmake/pdfmake.js": [ "pdfmake/vfs_fonts.js" ], + "jszip/jszip.js": [ "xlsx/xlsx.js" ] + }, "fabric.js/fabric.js", "FileSaver.js/FileSaver.js" ], + namespaces: { + "pdfmake.js": "pdfMake", + "jszip.js": "JSZip", + "xlsx.js": "XLSX", + "fabric.js": "fabric", + "FileSaver.js": "saveAs" + } + }, + config: {}, + setup: { + chart: chart, + hasBlob: false, + wrapper: false + }, + drawing: { + enabled: false, + undos: [], + redos: [], + buffer: { + position: { + x1: 0, + y1: 0, + x2: 0, + y2: 0, + xD: 0, + yD: 0 + } + }, + handler: { + undo: function( options, skipped ) { + var item = _this.drawing.undos.pop(); + if ( item ) { + item.selectable = true; + _this.drawing.redos.push( item ); + + if ( item.action == "added" ) { + _this.setup.fabric.remove( item.target ); + } + + var state = JSON.parse( item.state ); + item.target.set( state ); + + if ( item.target instanceof fabric.Group ) { + _this.drawing.handler.change( { + color: state.cfg.color, + width: state.cfg.width, + opacity: state.cfg.opacity + }, true, item.target ); + } + + _this.setup.fabric.renderAll(); + + // RECALL + if ( item.state == item.target.recentState && !skipped ) { + _this.drawing.handler.undo( item, true ); + } + } + }, + redo: function( options, skipped ) { + var item = _this.drawing.redos.pop(); + if ( item ) { + item.selectable = true; + _this.drawing.undos.push( item ); + + if ( item.action == "added" ) { + _this.setup.fabric.add( item.target ); + } + + var state = JSON.parse( item.state ); + item.target.recentState = item.state; + item.target.set( state ); + + if ( item.target instanceof fabric.Group ) { + _this.drawing.handler.change( { + color: state.cfg.color, + width: state.cfg.width, + opacity: state.cfg.opacity + }, true, item.target ); + } + + _this.setup.fabric.renderAll(); + + // RECALL + if ( item.action == "addified" ) { + _this.drawing.handler.redo(); + } + } + }, + done: function( options ) { + _this.drawing.buffer.enabled = false; + _this.drawing.undos = []; + _this.drawing.redos = []; + _this.createMenu( _this.config.menu ); + _this.setup.fabric.deactivateAll(); + + if ( _this.setup.wrapper ) { + _this.setup.chart.containerDiv.removeChild( _this.setup.wrapper ); + _this.setup.wrapper = false; + } + }, + add: function( options ) { + var cfg = _this.deepMerge( { + top: _this.setup.fabric.height / 2, + left: _this.setup.fabric.width / 2 + }, options || {} ); + var method = cfg.url.indexOf( ".svg" ) != -1 ? fabric.loadSVGFromURL : fabric.Image.fromURL; + + method( cfg.url, function( objects, options ) { + var group = options !== undefined ? fabric.util.groupSVGElements( objects, options ) : objects; + var ratio = false; + + // RESCALE ONLY IF IT EXCEEDS THE CANVAS + if ( group.height > _this.setup.fabric.height || group.width > _this.setup.fabric.width ) { + ratio = ( _this.setup.fabric.height / 2 ) / group.height; + } + + if ( cfg.top > _this.setup.fabric.height ) { + cfg.top = _this.setup.fabric.height / 2; + } + + if ( cfg.left > _this.setup.fabric.width ) { + cfg.left = _this.setup.fabric.width / 2; + } + + group.set( { + originX: "center", + originY: "center", + top: cfg.top, + left: cfg.left, + width: ratio ? group.width * ratio : group.width, + height: ratio ? group.height * ratio : group.height, + fill: _this.drawing.color + } ); + _this.setup.fabric.add( group ); + } ); + }, + change: function( options, skipped, target ) { + var cfg = _this.deepMerge( {}, options || {} ); + var state, i1, rgba; + var current = target || _this.drawing.buffer.target; + var objects = current ? current._objects ? current._objects : [ current ] : null; + + // UPDATE DRAWING OBJECT + if ( cfg.mode ) { + _this.drawing.mode = cfg.mode; + } + if ( cfg.width ) { + _this.drawing.width = cfg.width; + _this.drawing.fontSize = cfg.width * 3; + } + if ( cfg.fontSize ) { + _this.drawing.fontSize = cfg.fontSize; + } + if ( cfg.color ) { + _this.drawing.color = cfg.color; + } + if ( cfg.opacity ) { + _this.drawing.opacity = cfg.opacity; + } + + // APPLY OPACITY ON CURRENT COLOR + rgba = new fabric.Color( _this.drawing.color ).getSource(); + rgba.pop(); + rgba.push( _this.drawing.opacity ); + _this.drawing.color = "rgba(" + rgba.join() + ")"; + _this.setup.fabric.freeDrawingBrush.color = _this.drawing.color; + _this.setup.fabric.freeDrawingBrush.width = _this.drawing.width; + + // UPDATE CURRENT SELECTION + if ( current ) { + state = JSON.parse( current.recentState ).cfg; + + // UPDATE GIVE OPTIONS ONLY + if ( state ) { + cfg.color = cfg.color || state.color; + cfg.width = cfg.width || state.width; + cfg.opacity = cfg.opacity || state.opacity; + cfg.fontSize = cfg.fontSize || cfg.width * 3; + + rgba = new fabric.Color( cfg.color ).getSource(); + rgba.pop(); + rgba.push( cfg.opacity ); + cfg.color = "rgba(" + rgba.join() + ")"; + } + + // UPDATE OBJECTS + for ( i1 = 0; i1 < objects.length; i1++ ) { + if ( + objects[ i1 ] instanceof fabric.Text || + objects[ i1 ] instanceof fabric.PathGroup || + objects[ i1 ] instanceof fabric.Triangle + ) { + if ( cfg.color || cfg.opacity ) { + objects[ i1 ].set( { + fill: cfg.color + } ); + } + if ( cfg.fontSize ) { + objects[ i1 ].set( { + fontSize: cfg.fontSize + } ); + } + } else if ( + objects[ i1 ] instanceof fabric.Path || + objects[ i1 ] instanceof fabric.Line + ) { + if ( current instanceof fabric.Group ) { + if ( cfg.color || cfg.opacity ) { + objects[ i1 ].set( { + stroke: cfg.color + } ); + } + } else { + if ( cfg.color || cfg.opacity ) { + objects[ i1 ].set( { + stroke: cfg.color + } ); + } + if ( cfg.width ) { + objects[ i1 ].set( { + strokeWidth: cfg.width + } ); + } + } + } + } + + // ADD UNDO + if ( !skipped ) { + state = JSON.stringify( _this.deepMerge( current.saveState().originalState, { + cfg: { + color: cfg.color, + width: cfg.width, + opacity: cfg.opacity + } + } ) ); + current.recentState = state; + _this.drawing.redos = []; + _this.drawing.undos.push( { + action: "modified", + target: current, + state: state + } ); + } + + _this.setup.fabric.renderAll(); + } + }, + text: function( options ) { + var cfg = _this.deepMerge( { + text: _this.i18l( "menu.label.draw.text" ), + top: _this.setup.fabric.height / 2, + left: _this.setup.fabric.width / 2, + fontSize: _this.drawing.fontSize, + fontFamily: _this.setup.chart.fontFamily || "Verdana", + fill: _this.drawing.color + }, options || {} ); + + cfg.click = function() {}; + + var text = new fabric.IText( cfg.text, cfg ); + + _this.setup.fabric.add( text ); + _this.setup.fabric.setActiveObject( text ); + + text.selectAll(); + text.enterEditing(); + + return text; + }, + line: function( options ) { + var cfg = _this.deepMerge( { + x1: ( _this.setup.fabric.width / 2 ) - ( _this.setup.fabric.width / 10 ), + x2: ( _this.setup.fabric.width / 2 ) + ( _this.setup.fabric.width / 10 ), + y1: ( _this.setup.fabric.height / 2 ), + y2: ( _this.setup.fabric.height / 2 ), + angle: 90, + strokeLineCap: _this.drawing.lineCap, + arrow: _this.drawing.arrow, + color: _this.drawing.color, + width: _this.drawing.width, + group: [], + }, options || {} ); + var i1, arrow, arrowTop, arrowLeft; + var line = new fabric.Line( [ cfg.x1, cfg.y1, cfg.x2, cfg.y2 ], { + stroke: cfg.color, + strokeWidth: cfg.width, + strokeLineCap: cfg.strokeLineCap + } ); + + cfg.group.push( line ); + + if ( cfg.arrow ) { + cfg.angle = cfg.angle ? cfg.angle : _this.getAngle( cfg.x1, cfg.y1, cfg.x2, cfg.y2 ); + + if ( cfg.arrow == "start" ) { + arrowTop = cfg.y1 + ( cfg.width / 2 ); + arrowLeft = cfg.x1 + ( cfg.width / 2 ); + } else if ( cfg.arrow == "middle" ) { + arrowTop = cfg.y2 + ( cfg.width / 2 ) - ( ( cfg.y2 - cfg.y1 ) / 2 ); + arrowLeft = cfg.x2 + ( cfg.width / 2 ) - ( ( cfg.x2 - cfg.x1 ) / 2 ); + } else { // arrow: end + arrowTop = cfg.y2 + ( cfg.width / 2 ); + arrowLeft = cfg.x2 + ( cfg.width / 2 ); + } + + arrow = new fabric.Triangle( { + top: arrowTop, + left: arrowLeft, + fill: cfg.color, + height: cfg.width * 7, + width: cfg.width * 7, + angle: cfg.angle, + originX: "center", + originY: "bottom" + } ); + cfg.group.push( arrow ); + } + + if ( cfg.action != "config" ) { + if ( cfg.arrow ) { + var group = new fabric.Group( cfg.group ); + group.set( { + cfg: cfg, + fill: cfg.color, + action: cfg.action, + selectable: true, + known: cfg.action == "change" + } ); + if ( cfg.action == "change" ) { + _this.setup.fabric.setActiveObject( group ); + } + _this.setup.fabric.add( group ); + return group; + } else { + _this.setup.fabric.add( line ); + return line; + } + } else { + for ( i1 = 0; i1 < cfg.group.length; i1++ ) { + cfg.group[ i1 ].noUndo = true; + _this.setup.fabric.add( cfg.group[ i1 ] ); + } + } + return cfg; + } + } + }, + defaults: { + position: "top-right", + fileName: "amCharts", + action: "download", + overflow: true, + path: ( ( chart.path || "" ) + "plugins/export/" ), + formats: { + JPG: { + mimeType: "image/jpg", + extension: "jpg", + capture: true + }, + PNG: { + mimeType: "image/png", + extension: "png", + capture: true + }, + SVG: { + mimeType: "text/xml", + extension: "svg", + capture: true + }, + PDF: { + mimeType: "application/pdf", + extension: "pdf", + capture: true + }, + CSV: { + mimeType: "text/plain", + extension: "csv" + }, + JSON: { + mimeType: "text/plain", + extension: "json" + }, + XLSX: { + mimeType: "application/octet-stream", + extension: "xlsx" + } + }, + fabric: { + backgroundColor: "#FFFFFF", + removeImages: true, + selection: false, + drawing: { + enabled: true, + arrow: "end", + lineCap: "butt", + mode: "pencil", + modes: [ "pencil", "line", "arrow" ], + color: "#000000", + colors: [ "#000000", "#FFFFFF", "#FF0000", "#00FF00", "#0000FF" ], + shapes: [ "11.svg", "14.svg", "16.svg", "17.svg", "20.svg", "27.svg" ], + width: 1, + fontSize: 11, + widths: [ 1, 5, 10, 15 ], + opacity: 1, + opacities: [ 1, 0.8, 0.6, 0.4, 0.2 ], + menu: undefined, + autoClose: true + }, + border: { + fill: "", + fillOpacity: 0, + stroke: "#000000", + strokeWidth: 1, + strokeOpacity: 1 + } + }, + pdfMake: { + pageSize: "A4", + pageOrientation: "portrait", + images: {}, + content: [ "Saved from:", window.location.href, { + image: "reference", + fit: [ 515.28, 761.89 - ( 14.064 * 2 ) ] + } ] + }, + menu: undefined, + divId: null, + menuReviver: null, + menuWalker: null, + fallback: true, + keyListener: true, + fileListener: true + }, + + /** + * Returns translated message, takes english as default + */ + i18l: function( key, language ) { + var lang = language ? langugage : _this.setup.chart.language ? _this.setup.chart.language : "en"; + var catalog = AmCharts.translations[ _this.name ][ lang ] || AmCharts.translations[ _this.name ][ "en" ]; + + return catalog[ key ] || key; + }, + + /** + * Generates download file; if unsupported offers fallback to save manually + */ + download: function( data, type, filename ) { + // SAVE + if ( window.saveAs && _this.setup.hasBlob ) { + var blob = _this.toBlob( { + data: data, + type: type + }, function( data ) { + saveAs( data, filename ); + } ); + + // FALLBACK TEXTAREA + } else if ( _this.config.fallback && type == "text/plain" ) { + var div = document.createElement( "div" ); + var msg = document.createElement( "div" ); + var textarea = document.createElement( "textarea" ); + + msg.innerHTML = _this.i18l( "fallback.save.text" ); + + div.appendChild( msg ); + div.appendChild( textarea ); + msg.setAttribute( "class", "amcharts-export-fallback-message" ); + div.setAttribute( "class", "amcharts-export-fallback" ); + _this.setup.chart.containerDiv.appendChild( div ); + + // FULFILL TEXTAREA AND PRESELECT + textarea.setAttribute( "readonly", "" ); + textarea.value = data; + textarea.focus(); + textarea.select(); + + // UPDATE MENU + _this.createMenu( [ { + "class": "export-main export-close", + label: "Done", + click: function() { + _this.createMenu( _this.config.menu ); + _this.setup.chart.containerDiv.removeChild( div ); + } + } ] ); + + // FALLBACK IMAGE + } else if ( _this.config.fallback && type.split( "/" )[ 0 ] == "image" ) { + var div = document.createElement( "div" ); + var msg = document.createElement( "div" ); + var img = _this.toImage( { + data: data + } ); + + msg.innerHTML = _this.i18l( "fallback.save.image" ); + + // FULFILL TEXTAREA AND PRESELECT + div.appendChild( msg ); + div.appendChild( img ); + msg.setAttribute( "class", "amcharts-export-fallback-message" ); + div.setAttribute( "class", "amcharts-export-fallback" ); + _this.setup.chart.containerDiv.appendChild( div ); + + // UPDATE MENU + _this.createMenu( [ { + "class": "export-main export-close", + label: "Done", + click: function() { + _this.createMenu( _this.config.menu ); + _this.setup.chart.containerDiv.removeChild( div ); + } + } ] ); + + // ERROR + } else { + throw new Error( "Unable to create file. Ensure saveAs (FileSaver.js) is supported." ); + } + return data; + }, + + /** + * Generates script, links tags and places them into the document's head + * In case of reload it replaces the node to force the download + */ + loadResource: function( src, addons ) { + var i1, exist, node, item, check, type; + var url = src.indexOf( "//" ) != -1 ? src : [ _this.libs.path, src ].join( "" ); + + var loadCallback = function callback() { + if ( addons ) { + for ( i1 = 0; i1 < addons.length; i1++ ) { + _this.loadResource( addons[ i1 ] ); + } + } + } + + if ( src.indexOf( ".js" ) != -1 ) { + node = document.createElement( "script" ); + node.setAttribute( "type", "text/javascript" ); + node.setAttribute( "src", url ); + if ( _this.libs.async ) { + node.setAttribute( "async", "" ); + } + + } else if ( src.indexOf( ".css" ) != -1 ) { + node = document.createElement( "link" ); + node.setAttribute( "type", "text/css" ); + node.setAttribute( "rel", "stylesheet" ); + node.setAttribute( "href", url ); + } + + // NODE CHECK + for ( i1 = 0; i1 < document.head.childNodes.length; i1++ ) { + item = document.head.childNodes[ i1 ]; + check = item ? ( item.src || item.href ) : false; + type = item ? item.tagName : false; + + if ( item && check && check.indexOf( src ) != -1 ) { + if ( _this.libs.reload ) { + document.head.removeChild( item ); + } + exist = true; + break; + } + } + + // NAMESPACE CHECK + for ( i1 in _this.libs.namespaces ) { + var namespace = _this.libs.namespaces[ i1 ]; + var check = src.toLowerCase(); + var item = i1.toLowerCase(); + if ( check.indexOf( item ) != -1 && window[ namespace ] !== undefined ) { + exist = true; + break; + } + } + + if ( !exist || _this.libs.reload ) { + node.addEventListener( "load", loadCallback ); + document.head.appendChild( node ); + + if(!_this.listenersToRemove){ + _this.listenersToRemove = []; + } + + _this.listenersToRemove.push({node:node, method:loadCallback, event:"load"}); + } + }, + + /** + * Walker to generate the script,link tags + */ + loadDependencies: function() { + var i1, i2; + if ( _this.libs.autoLoad ) { + for ( i1 = 0; i1 < _this.libs.resources.length; i1++ ) { + if ( _this.libs.resources[ i1 ] instanceof Object ) { + for ( i2 in _this.libs.resources[ i1 ] ) { + _this.loadResource( i2, _this.libs.resources[ i1 ][ i2 ] ); + } + } else { + _this.loadResource( _this.libs.resources[ i1 ] ); + } + } + } + }, + + /** + * Converts string to number + */ + pxToNumber: function( attr, returnUndefined ) { + if ( !attr && returnUndefined ) { + return undefined; + } + return Number( String( attr ).replace( "px", "" ) ) || 0; + }, + + /** + * Converts number to string + */ + numberToPx: function( attr ) { + return String( attr ) + "px"; + }, + + /** + * Recursive method to merge the given objects together + * Overwrite flag replaces the value instead to crawl through + */ + deepMerge: function( a, b, overwrite ) { + var i1, v, type = b instanceof Array ? "array" : "object"; + + for ( i1 in b ) { + // PREVENT METHODS + if ( type == "array" && isNaN( i1 ) ) { + continue; + } + + v = b[ i1 ]; + + // NEW + if ( a[ i1 ] == undefined || overwrite ) { + if ( v instanceof Array ) { + a[ i1 ] = new Array(); + } else if ( v instanceof Function ) { + a[ i1 ] = function() {}; + } else if ( v instanceof Date ) { + a[ i1 ] = new Date(); + } else if ( v instanceof Object ) { + a[ i1 ] = new Object(); + } else if ( v instanceof Number ) { + a[ i1 ] = new Number(); + } else if ( v instanceof String ) { + a[ i1 ] = new String(); + } + } + + if ( + ( a instanceof Object || a instanceof Array ) && + ( v instanceof Object || v instanceof Array ) && + !( v instanceof Function || v instanceof Date || _this.isElement( v ) ) && + i1 != "chart" + ) { + _this.deepMerge( a[ i1 ], v, overwrite ); + } else { + if ( a instanceof Array && !overwrite ) { + a.push( v ); + } else { + a[ i1 ] = v; + } + } + } + return a; + }, + + /** + * Checks if given argument is a valid node + */ + isElement: function( thingy ) { + return thingy instanceof Object && thingy && thingy.nodeType === 1; + }, + + /** + * Checks if given argument contains a hashbang and returns it + */ + isHashbanged: function( thingy ) { + var str = String( thingy ).replace( /\"/g, "" ); + + return str.slice( 0, 3 ) == "url" ? str.slice( str.indexOf( "#" ) + 1, str.length - 1 ) : false; + }, + + /** + * Checks if given event has been thrown with pressed click / touch + */ + isPressed: function( event ) { + // IE EXCEPTION + if ( event.type == "mousemove" && event.which === 1 ) { + // IGNORE + + // OTHERS + } else if ( + event.type == "touchmove" || + event.buttons === 1 || + event.button === 1 || + event.which === 1 + ) { + _this.drawing.buffer.isPressed = true; + } else { + _this.drawing.buffer.isPressed = false; + } + return _this.drawing.buffer.isPressed; + }, + + /** + * Checks if given source is within the current origin + */ + isTainted: function( source ) { + var origin = String( window.location.origin || window.location.protocol + "//" + window.location.hostname + ( window.location.port ? ':' + window.location.port : '' ) ); + + // CHECK IF TAINTED + if ( + source && + source.indexOf( "//" ) != -1 && + source.indexOf( origin.replace( /.*:/, "" ) ) == -1 + ) { + return true; + } + return false; + }, + + /* + ** Checks several indicators for acceptance; + */ + isSupported: function() { + // CHECK CONFIG + if ( !_this.config.enabled ) { + return false; + } + + // CHECK IE; ATTEMPT TO ACCESS HEAD ELEMENT + if ( AmCharts.isIE && AmCharts.IEversion <= 9 ) { + if ( !Array.prototype.indexOf || !document.head || _this.config.fallback === false ) { + return false; + } + } + return true; + }, + + + getAngle: function( x1, y1, x2, y2 ) { + var x = x2 - x1; + var y = y2 - y1; + var angle; + if ( x == 0 ) { + if ( y == 0 ) { + angle = 0; + } else if ( y > 0 ) { + angle = Math.PI / 2; + } else { + angle = Math.PI * 3 / 2; + } + } else if ( y == 0 ) { + if ( x > 0 ) { + angle = 0; + } else { + angle = Math.PI; + } + } else { + if ( x < 0 ) { + angle = Math.atan( y / x ) + Math.PI; + } else if ( y < 0 ) { + angle = Math.atan( y / x ) + ( 2 * Math.PI ); + } else { + angle = Math.atan( y / x ); + } + } + return angle * 180 / Math.PI; + }, + + /** + * Recursive method which crawls upwards to gather the requested attribute + */ + gatherAttribute: function( elm, attr, limit, lvl ) { + var value, lvl = lvl ? lvl : 0, + limit = limit ? limit : 3; + if ( elm ) { + value = elm.getAttribute( attr ); + + if ( !value && lvl < limit ) { + return _this.gatherAttribute( elm.parentNode, attr, limit, lvl + 1 ); + } + } + return value; + }, + + /** + * Recursive method which crawls upwards to gather the requested classname + */ + gatherClassName: function( elm, className, limit, lvl ) { + var value, lvl = lvl ? lvl : 0, + limit = limit ? limit : 3; + + if ( _this.isElement( elm ) ) { + value = ( elm.getAttribute( "class" ) || "" ).split( " " ).indexOf( className ) != -1; + + if ( !value && lvl < limit ) { + return _this.gatherClassName( elm.parentNode, className, limit, lvl + 1 ); + } else if ( value ) { + value = elm; + } + } + return value; + }, + + /** + * Collects the clip-paths and patterns + */ + gatherElements: function( group, cfg, images ) { + var i1, i2; + for ( i1 = 0; i1 < group.children.length; i1++ ) { + var childNode = group.children[ i1 ]; + + // CLIPPATH + if ( childNode.tagName == "clipPath" ) { + var bbox = {}; + var transform = fabric.parseTransformAttribute( _this.gatherAttribute( childNode, "transform" ) ); + + // HIDE SIBLINGS; GATHER IT'S DIMENSIONS + for ( i2 = 0; i2 < childNode.childNodes.length; i2++ ) { + childNode.childNodes[ i2 ].setAttribute( "fill", "transparent" ); + bbox = { + x: _this.pxToNumber( childNode.childNodes[ i2 ].getAttribute( "x" ) ), + y: _this.pxToNumber( childNode.childNodes[ i2 ].getAttribute( "y" ) ), + width: _this.pxToNumber( childNode.childNodes[ i2 ].getAttribute( "width" ) ), + height: _this.pxToNumber( childNode.childNodes[ i2 ].getAttribute( "height" ) ) + } + } + + group.clippings[ childNode.id ] = { + svg: childNode, + bbox: bbox, + transform: transform + }; + + // PATTERN + } else if ( childNode.tagName == "pattern" ) { + var props = { + node: childNode, + source: childNode.getAttribute( "xlink:href" ), + width: Number( childNode.getAttribute( "width" ) ), + height: Number( childNode.getAttribute( "height" ) ), + repeat: "repeat" + } + + // GATHER BACKGROUND COLOR + for ( i2 = 0; i2 < childNode.childNodes.length; i2++ ) { + if ( childNode.childNodes[ i2 ].tagName == "rect" ) { + props.fill = childNode.childNodes[ i2 ].getAttribute( "fill" ); + } + } + + // TAINTED + if ( cfg.removeImages && _this.isTainted( props.source ) ) { + group.patterns[ childNode.id ] = props.fill ? props.fill : "transparent"; + } else { + images.included++; + + group.patterns[ props.node.id ] = props; + } + + // IMAGES + } else if ( childNode.tagName == "image" ) { + images.included++; + + // LOAD IMAGE MANUALLY; TO RERENDER THE CANVAS + fabric.Image.fromURL( childNode.getAttribute( "xlink:href" ), function( img ) { + images.loaded++; + } ); + } + } + return group; + }, + + /* + ** GATHER MOUSE POSITION; + */ + gatherPosition: function( event, type ) { + var ref = _this.drawing.buffer.position; + var ivt = fabric.util.invertTransform( _this.setup.fabric.viewportTransform ); + var pos; + + if ( event.type == "touchmove" ) { + if ( "touches" in event ) { + event = event.touches[ 0 ]; + } else if ( "changedTouches" in event ) { + event = event.changedTouches[ 0 ]; + } + } + + pos = fabric.util.transformPoint( _this.setup.fabric.getPointer( event, true ), ivt ); + + if ( type == 1 ) { + ref.x1 = pos.x; + ref.y1 = pos.y; + } + + ref.x2 = pos.x; + ref.y2 = pos.y; + ref.xD = ( ref.x1 - ref.x2 ) < 0 ? ( ref.x1 - ref.x2 ) * -1 : ( ref.x1 - ref.x2 ); + ref.yD = ( ref.y1 - ref.y2 ) < 0 ? ( ref.y1 - ref.y2 ) * -1 : ( ref.y1 - ref.y2 ); + + return ref; + }, + + /** + * Method to capture the current state of the chart + */ + capture: function( options, callback ) { + var i1; + var cfg = _this.deepMerge( _this.deepMerge( {}, _this.config.fabric ), options || {} ); + var groups = []; + var offset = { + x: 0, + y: 0, + pX: 0, + pY: 0, + width: _this.setup.chart.divRealWidth, + height: _this.setup.chart.divRealHeight + }; + var images = { + loaded: 0, + included: 0 + } + + fabric.ElementsParser.prototype.resolveGradient = function( obj, property ) { + + var instanceFillValue = obj.get( property ); + if ( !( /^url\(/ ).test( instanceFillValue ) ) { + return; + } + var gradientId = instanceFillValue.slice( instanceFillValue.indexOf( "#" ) + 1, instanceFillValue.length - 1 ); + if ( fabric.gradientDefs[ this.svgUid ][ gradientId ] ) { + obj.set( property, fabric.Gradient.fromElement( fabric.gradientDefs[ this.svgUid ][ gradientId ], obj ) ); + } + }; + + // BEFORE CAPTURING + _this.handleCallback( cfg.beforeCapture, cfg ); + + // GATHER SVGS + var svgs = _this.setup.chart.containerDiv.getElementsByTagName( "svg" ); + for ( i1 = 0; i1 < svgs.length; i1++ ) { + var group = { + svg: svgs[ i1 ], + parent: svgs[ i1 ].parentNode, + children: svgs[ i1 ].getElementsByTagName( "*" ), + offset: { + x: 0, + y: 0 + }, + patterns: {}, + clippings: {} + } + + // GATHER ELEMENTS + group = _this.gatherElements( group, cfg, images ); + + // APPEND GROUP + groups.push( group ); + } + + // GATHER EXTERNAL LEGEND + if ( _this.config.legend && _this.setup.chart.legend && _this.setup.chart.legend.position == "outside" ) { + var group = { + svg: _this.setup.chart.legend.container.container, + parent: _this.setup.chart.legend.container.container.parentNode, + children: _this.setup.chart.legend.container.container.getElementsByTagName( "*" ), + offset: { + x: 0, + y: 0 + }, + legend: { + type: [ "top", "left" ].indexOf( _this.config.legend.position ) != -1 ? "unshift" : "push", + position: _this.config.legend.position, + width: _this.config.legend.width ? _this.config.legend.width : _this.setup.chart.legend.container.width, + height: _this.config.legend.height ? _this.config.legend.height : _this.setup.chart.legend.container.height + }, + patterns: {}, + clippings: {} + } + + // ADAPT CANVAS DIMENSIONS + if ( [ "left", "right" ].indexOf( group.legend.position ) != -1 ) { + offset.width += group.legend.width; + offset.height = group.legend.height > offset.height ? group.legend.height : offset.height; + } else if ( [ "top", "bottom" ].indexOf( group.legend.position ) != -1 ) { + offset.height += group.legend.height; + } + + // GATHER ELEMENTS + group = _this.gatherElements( group, cfg, images ); + + // PRE/APPEND SVG + groups[ group.legend.type ]( group ); + } + + // CLEAR IF EXIST + _this.drawing.buffer.enabled = cfg.action == "draw"; + + _this.setup.wrapper = document.createElement( "div" ); + _this.setup.wrapper.setAttribute( "class", _this.setup.chart.classNamePrefix + "-export-canvas" ); + _this.setup.chart.containerDiv.appendChild( _this.setup.wrapper ); + + // STOCK CHART; SELECTOR OFFSET + if ( _this.setup.chart.type == "stock" ) { + var padding = { + top: 0, + right: 0, + bottom: 0, + left: 0 + } + if ( _this.setup.chart.leftContainer ) { + offset.width -= _this.setup.chart.leftContainer.offsetWidth; + padding.left = _this.setup.chart.leftContainer.offsetWidth + ( _this.setup.chart.panelsSettings.panelSpacing * 2 ); + } + if ( _this.setup.chart.rightContainer ) { + offset.width -= _this.setup.chart.rightContainer.offsetWidth; + padding.right = _this.setup.chart.rightContainer.offsetWidth + ( _this.setup.chart.panelsSettings.panelSpacing * 2 ); + } + if ( _this.setup.chart.periodSelector && [ "top", "bottom" ].indexOf( _this.setup.chart.periodSelector.position ) != -1 ) { + offset.height -= _this.setup.chart.periodSelector.offsetHeight + _this.setup.chart.panelsSettings.panelSpacing; + padding[ _this.setup.chart.periodSelector.position ] += _this.setup.chart.periodSelector.offsetHeight + _this.setup.chart.panelsSettings.panelSpacing; + } + if ( _this.setup.chart.dataSetSelector && [ "top", "bottom" ].indexOf( _this.setup.chart.dataSetSelector.position ) != -1 ) { + offset.height -= _this.setup.chart.dataSetSelector.offsetHeight; + padding[ _this.setup.chart.dataSetSelector.position ] += _this.setup.chart.dataSetSelector.offsetHeight; + } + + // APPLY OFFSET ON WRAPPER + _this.setup.wrapper.style.paddingTop = _this.numberToPx( padding.top ); + _this.setup.wrapper.style.paddingRight = _this.numberToPx( padding.right ); + _this.setup.wrapper.style.paddingBottom = _this.numberToPx( padding.bottom ); + _this.setup.wrapper.style.paddingLeft = _this.numberToPx( padding.left ); + } + + // CREATE CANVAS + _this.setup.canvas = document.createElement( "canvas" ); + _this.setup.wrapper.appendChild( _this.setup.canvas ); + _this.setup.fabric = new fabric.Canvas( _this.setup.canvas, _this.deepMerge( { + width: offset.width, + height: offset.height, + isDrawingMode: true + }, cfg ) ); + + // REAPPLY FOR SOME REASON + _this.deepMerge( _this.setup.fabric, cfg ); + _this.deepMerge( _this.setup.fabric.freeDrawingBrush, cfg.drawing ); + + // RELIABLE VARIABLES; UPDATE DRAWING + _this.deepMerge( _this.drawing, cfg.drawing ); + _this.drawing.handler.change( cfg.drawing ); + + // OBSERVE MOUSE EVENTS + _this.setup.fabric.on( "mouse:down", function( e ) { + var p = _this.gatherPosition( e.e, 1 ); + _this.drawing.buffer.pressedTS = Number( new Date() ); + _this.isPressed( e.e ); + } ); + _this.setup.fabric.on( "mouse:move", function( e ) { + var p = _this.gatherPosition( e.e, 2 ); + _this.isPressed( e.e ); + + // CREATE INITIAL LINE / ARROW; JUST ON LEFT CLICK + if ( _this.drawing.buffer.isPressed && !_this.drawing.buffer.line ) { + if ( !_this.drawing.buffer.isSelected && _this.drawing.mode != "pencil" && ( p.xD > 5 || p.xD > 5 ) ) { + _this.drawing.buffer.hasLine = true; + _this.setup.fabric.isDrawingMode = false; + _this.setup.fabric._onMouseUpInDrawingMode( e ); + _this.drawing.buffer.line = _this.drawing.handler.line( { + x1: p.x1, + y1: p.y1, + x2: p.x2, + y2: p.y2, + arrow: _this.drawing.mode == "line" ? false : _this.drawing.arrow, + action: "config" + } ); + } + } + + // UPDATE LINE / ARROW + if ( _this.drawing.buffer.line ) { + var obj, top, left; + var l = _this.drawing.buffer.line; + + l.x2 = p.x2; + l.y2 = p.y2; + + for ( i1 = 0; i1 < l.group.length; i1++ ) { + obj = l.group[ i1 ]; + + if ( obj instanceof fabric.Line ) { + obj.set( { + x2: l.x2, + y2: l.y2 + } ); + } else if ( obj instanceof fabric.Triangle ) { + l.angle = ( _this.getAngle( l.x1, l.y1, l.x2, l.y2 ) + 90 ); + + if ( l.arrow == "start" ) { + top = l.y1 + ( l.width / 2 ); + left = l.x1 + ( l.width / 2 ); + } else if ( l.arrow == "middle" ) { + top = l.y2 + ( l.width / 2 ) - ( ( l.y2 - l.y1 ) / 2 ); + left = l.x2 + ( l.width / 2 ) - ( ( l.x2 - l.x1 ) / 2 ); + } else { // arrow: end + top = l.y2 + ( l.width / 2 ); + left = l.x2 + ( l.width / 2 ); + } + + obj.set( { + top: top, + left: left, + angle: l.angle + } ); + } + } + _this.setup.fabric.renderAll(); + } + } ); + _this.setup.fabric.on( "mouse:up", function( e ) { + // SELECT TARGET + if ( Number( new Date() ) - _this.drawing.buffer.pressedTS < 200 ) { + var target = _this.setup.fabric.findTarget( e.e ); + if ( target && target.selectable ) { + _this.setup.fabric.setActiveObject( target ); + } + } + + // UPDATE LINE / ARROW + if ( _this.drawing.buffer.line ) { + for ( i1 = 0; i1 < _this.drawing.buffer.line.group.length; i1++ ) { + _this.drawing.buffer.line.group[ i1 ].remove(); + } + delete _this.drawing.buffer.line.action; + delete _this.drawing.buffer.line.group; + _this.drawing.handler.line( _this.drawing.buffer.line ); + } + _this.drawing.buffer.line = false; + _this.drawing.buffer.hasLine = false; + _this.drawing.buffer.isPressed = false; + } ); + + // OBSERVE OBJECT SELECTION + _this.setup.fabric.on( "object:selected", function( e ) { + _this.drawing.buffer.isSelected = true; + _this.drawing.buffer.target = e.target; + _this.setup.fabric.isDrawingMode = false; + } ); + _this.setup.fabric.on( "selection:cleared", function( e ) { + _this.drawing.buffer.onMouseDown = _this.setup.fabric.freeDrawingBrush.onMouseDown; + _this.drawing.buffer.target = false; + + // FREEHAND WORKAROUND + if ( _this.drawing.buffer.isSelected ) { + _this.setup.fabric._isCurrentlyDrawing = false; + _this.setup.fabric.freeDrawingBrush.onMouseDown = function() {}; + } + + // DELAYED DESELECTION TO PREVENT DRAWING + setTimeout( function() { + _this.drawing.buffer.isSelected = false; + _this.setup.fabric.isDrawingMode = true; + _this.setup.fabric.freeDrawingBrush.onMouseDown = _this.drawing.buffer.onMouseDown; + }, 10 ); + } ); + _this.setup.fabric.on( "path:created", function( e ) { + var item = e.path; + if ( Number( new Date() ) - _this.drawing.buffer.pressedTS < 200 || _this.drawing.buffer.hasLine ) { + _this.setup.fabric.remove( item ); + _this.setup.fabric.renderAll(); + return; + } + } ); + + // OBSERVE OBJECT MODIFICATIONS + _this.setup.fabric.on( "object:added", function( e ) { + var item = e.target; + var state = _this.deepMerge( item.saveState().originalState, { + cfg: { + color: _this.drawing.color, + width: _this.drawing.width, + opacity: _this.drawing.opacity, + fontSize: _this.drawing.fontSize + } + } ); + + if ( Number( new Date() ) - _this.drawing.buffer.pressedTS < 200 && !item.noUndo ) { + _this.setup.fabric.remove( item ); + _this.setup.fabric.renderAll(); + return; + } + + state = JSON.stringify( state ); + item.recentState = state; + + if ( item.selectable && !item.known && !item.noUndo ) { + _this.drawing.undos.push( { + action: "added", + target: item, + state: state + } ); + _this.drawing.undos.push( { + action: "addified", + target: item, + state: state + } ); + _this.drawing.redos = []; + } + + item.known = true; + _this.setup.fabric.isDrawingMode = true; + } ); + _this.setup.fabric.on( "object:modified", function( e ) { + var item = e.target; + var recentState = JSON.parse( item.recentState ); + var state = _this.deepMerge( item.saveState().originalState, { + cfg: recentState.cfg + } ); + + state = JSON.stringify( state ); + item.recentState = state; + + _this.drawing.undos.push( { + action: "modified", + target: item, + state: state + } ); + + _this.drawing.redos = []; + } ); + _this.setup.fabric.on( "text:changed", function( e ) { + var item = e.target; + clearTimeout( item.timer ); + item.timer = setTimeout( function() { + var state = JSON.stringify( item.saveState().originalState ); + + item.recentState = state; + + _this.drawing.redos = []; + _this.drawing.undos.push( { + action: "modified", + target: item, + state: state + } ); + }, 250 ); + } ); + + // DRAWING + if ( _this.drawing.buffer.enabled ) { + _this.setup.wrapper.setAttribute( "class", _this.setup.chart.classNamePrefix + "-export-canvas active" ); + _this.setup.wrapper.style.backgroundColor = cfg.backgroundColor; + _this.setup.wrapper.style.display = "block"; + + } else { + _this.setup.wrapper.setAttribute( "class", _this.setup.chart.classNamePrefix + "-export-canvas" ); + _this.setup.wrapper.style.display = "none"; + } + + for ( i1 = 0; i1 < groups.length; i1++ ) { + var group = groups[ i1 ]; + var isLegend = _this.gatherClassName( group.parent, _this.setup.chart.classNamePrefix + "-legend-div", 1 ); + var isPanel = _this.gatherClassName( group.parent, _this.setup.chart.classNamePrefix + "-stock-panel-div" ); + var isScrollbar = _this.gatherClassName( group.parent, _this.setup.chart.classNamePrefix + "-scrollbar-chart-div" ); + + // STOCK CHART; SVG OFFSET;; SVG OFFSET + if ( _this.setup.chart.type == "stock" && _this.setup.chart.legendSettings.position ) { + + // TOP / BOTTOM + if ( [ "top", "bottom" ].indexOf( _this.setup.chart.legendSettings.position ) != -1 ) { + + // POSITION; ABSOLUTE + if ( group.parent.style.top && group.parent.style.left ) { + group.offset.y = _this.pxToNumber( group.parent.style.top ); + group.offset.x = _this.pxToNumber( group.parent.style.left ); + + // POSITION; RELATIVE + } else { + group.offset.x = offset.x; + group.offset.y = offset.y; + offset.y += _this.pxToNumber( group.parent.style.height ); + + // LEGEND; OFFSET + if ( isPanel ) { + offset.pY = _this.pxToNumber( isPanel.style.marginTop ); + group.offset.y += offset.pY; + + // SCROLLBAR; OFFSET + } else if ( isScrollbar ) { + group.offset.y += offset.pY; + } + } + + // LEFT / RIGHT + } else if ( [ "left", "right" ].indexOf( _this.setup.chart.legendSettings.position ) != -1 ) { + group.offset.y = _this.pxToNumber( group.parent.style.top ) + offset.pY; + group.offset.x = _this.pxToNumber( group.parent.style.left ) + offset.pX; + + // LEGEND; OFFSET + if ( isLegend ) { + offset.pY += _this.pxToNumber( isPanel.style.height ) + _this.setup.chart.panelsSettings.panelSpacing; + + // SCROLLBAR; OFFSET + } else if ( isScrollbar ) { + group.offset.y -= _this.setup.chart.panelsSettings.panelSpacing; + } + } + + // REGULAR CHARTS; SVG OFFSET + } else { + // POSITION; ABSOLUTE + if ( group.parent.style.position == "absolute" ) { + group.offset.absolute = true; + group.offset.top = _this.pxToNumber( group.parent.style.top ); + group.offset.right = _this.pxToNumber( group.parent.style.right, true ); + group.offset.bottom = _this.pxToNumber( group.parent.style.bottom, true ); + group.offset.left = _this.pxToNumber( group.parent.style.left ); + group.offset.width = _this.pxToNumber( group.parent.style.width ); + group.offset.height = _this.pxToNumber( group.parent.style.height ); + + // POSITION; RELATIVE + } else if ( group.parent.style.top && group.parent.style.left ) { + group.offset.y = _this.pxToNumber( group.parent.style.top ); + group.offset.x = _this.pxToNumber( group.parent.style.left ); + + // POSITION; GENERIC + } else { + + // EXTERNAL LEGEND + if ( group.legend ) { + if ( group.legend.position == "left" ) { + offset.x += group.legend.width; + } else if ( group.legend.position == "right" ) { + group.offset.x += offset.width - group.legend.width; + } else if ( group.legend.position == "top" ) { + offset.y += group.legend.height; + } else if ( group.legend.position == "bottom" ) { + group.offset.y += offset.height - group.legend.height; // OFFSET.Y + } + + // NORMAL + } else { + group.offset.x = offset.x; + group.offset.y = offset.y + offset.pY; + offset.y += _this.pxToNumber( group.parent.style.height ); + } + } + + // PANEL OFFSET (STOCK CHARTS) + if ( isLegend && isPanel && isPanel.style.marginTop ) { + offset.y += _this.pxToNumber( isPanel.style.marginTop ); + group.offset.y += _this.pxToNumber( isPanel.style.marginTop ); + + // GENERAL LEFT / RIGHT POSITION + } else if ( _this.setup.chart.legend && [ "left", "right" ].indexOf( _this.setup.chart.legend.position ) != -1 ) { + group.offset.y = _this.pxToNumber( group.parent.style.top ); + group.offset.x = _this.pxToNumber( group.parent.style.left ); + } + } + + // ADD TO CANVAS + fabric.parseSVGDocument( group.svg, ( function( group ) { + return function( objects, options ) { + var i1; + var g = fabric.util.groupSVGElements( objects, options ); + var paths = []; + var tmp = { + selectable: false + }; + + // GROUP OFFSET; ABSOLUTE + if ( group.offset.absolute ) { + if ( group.offset.bottom !== undefined ) { + tmp.top = offset.height - group.offset.height - group.offset.bottom; + } else { + tmp.top = group.offset.top; + } + + if ( group.offset.right !== undefined ) { + tmp.left = offset.width - group.offset.width - group.offset.right; + } else { + tmp.left = group.offset.left; + } + + // GROUP OFFSET; REGULAR + } else { + tmp.top = group.offset.y; + tmp.left = group.offset.x; + } + + // WALKTHROUGH ELEMENTS + for ( i1 = 0; i1 < g.paths.length; i1++ ) { + var PID = null; + + // OPACITY; TODO: DISTINGUISH OPACITY TYPES + if ( g.paths[ i1 ] ) { + + // CHECK ORIGIN; REMOVE TAINTED + if ( cfg.removeImages && _this.isTainted( g.paths[ i1 ][ "xlink:href" ] ) ) { + continue; + } + + // SET OPACITY + if ( g.paths[ i1 ].fill instanceof Object ) { + + // MISINTERPRETATION OF FABRIC + if ( g.paths[ i1 ].fill.type == "radial" ) { + + // OTHERS + if ( ["pie","gauge"].indexOf(_this.setup.chart.type) == -1 ) { + g.paths[ i1 ].fill.coords.r2 = g.paths[ i1 ].fill.coords.r1 * -1; + g.paths[ i1 ].fill.coords.r1 = 0; + g.paths[ i1 ].set( { + opacity: g.paths[ i1 ].fillOpacity + } ); + } + } + + // FILLING; TODO: DISTINGUISH OPACITY TYPES + } else if ( PID = _this.isHashbanged( g.paths[ i1 ].fill ) ) { + + // PATTERN + if ( group.patterns && group.patterns[ PID ] ) { + + var props = group.patterns[ PID ]; + + // LOAD IMAGE MANUALLY; TO RERENDER THE CANVAS + fabric.Image.fromURL( props.source, ( function( props, i1 ) { + return function( img ) { + images.loaded++; + + var pattern = null; + var patternSourceCanvas = new fabric.StaticCanvas( undefined, { + backgroundColor: props.fill + } ); + patternSourceCanvas.add( img ); + + pattern = new fabric.Pattern( { + source: function() { + patternSourceCanvas.setDimensions( { + width: props.width, + height: props.height + } ); + return patternSourceCanvas.getElement(); + }, + repeat: 'repeat' + } ); + + g.paths[ i1 ].set( { + fill: pattern, + opacity: g.paths[ i1 ].fillOpacity + } ); + } + } )( props, i1 ) ); + } + } + + // CLIPPATH; + if ( PID = _this.isHashbanged( g.paths[ i1 ].clipPath ) ) { + + if ( group.clippings && group.clippings[ PID ] ) { + + // TODO: WAIT UNTIL FABRICJS HANDLES CLIPPATH FOR SVG OUTPUT + ( function( i1, PID ) { + var toSVG = g.paths[ i1 ].toSVG; + + g.paths[ i1 ].toSVG = function( original_reviver ) { + return toSVG.apply( this, [ function( string ) { + return original_reviver( string, group.clippings[ PID ] ); + } ] ); + } + } )( i1, PID ); + + g.paths[ i1 ].set( { + clipTo: ( function( i1, PID ) { + return function( ctx ) { + var cp = group.clippings[ PID ]; + var tm = this.transformMatrix || [ 1, 0, 0, 1, 0, 0 ]; + var dim = { + top: cp.bbox.y, + left: cp.bbox.x, + width: cp.bbox.width, + height: cp.bbox.height + } + + if ( _this.setup.chart.type == "map" ) { + dim.top += cp.transform[ 5 ]; + dim.left += cp.transform[ 4 ]; + } + + if ( cp.bbox.x && tm[ 4 ] && cp.bbox.y && tm[ 5 ] ) { + dim.top -= tm[ 5 ]; + dim.left -= tm[ 4 ]; + } + + ctx.rect( dim.left, dim.top, dim.width, dim.height ); + } + } )( i1, PID ) + } ); + } + } + + // TODO; WAIT FOR TSPAN SUPPORT FROM FABRICJS SIDE + if ( g.paths[ i1 ].TSPANWORKAROUND ) { + var parsedAttributes = fabric.parseAttributes( g.paths[ i1 ].svg, fabric.Text.ATTRIBUTE_NAMES ); + var options = fabric.util.object.extend( {}, parsedAttributes ); + + // CREATE NEW SET + var tmpBuffer = []; + for ( var i = 0; i < g.paths[ i1 ].svg.childNodes.length; i++ ) { + var textNode = g.paths[ i1 ].svg.childNodes[ i ]; + var textElement = fabric.Text.fromElement( textNode, options ); + + textElement.set( { + left: 0 + } ); + + tmpBuffer.push( textElement ); + } + + // HIDE ORIGINAL ELEMENT + g.paths[ i1 ].set( { + opacity: 0 + } ); + + // REPLACE BY GROUP AND CANCEL FIRST OFFSET + var tmpGroup = new fabric.Group( tmpBuffer, { + top: g.paths[ i1 ].top * -1 + } ); + g.paths[ i1 ] = tmpGroup; + } + } + paths.push( g.paths[ i1 ] ); + } + + // REPLACE WITH WHITELIST + g.paths = paths; + + // SET PROPS + g.set( tmp ); + + // ADD TO CANVAS + _this.setup.fabric.add( g ); + + // ADD BALLOONS + if ( group.svg.parentNode && group.svg.parentNode.getElementsByTagName ) { + var balloons = group.svg.parentNode.getElementsByClassName( _this.setup.chart.classNamePrefix + "-balloon-div" ); + for ( i1 = 0; i1 < balloons.length; i1++ ) { + if ( cfg.balloonFunction instanceof Function ) { + cfg.balloonFunction.apply( _this, [ balloons[ i1 ], group ] ); + } else { + var elm_parent = balloons[ i1 ]; + var style_parent = fabric.parseStyleAttribute( elm_parent ); + var style_text = fabric.parseStyleAttribute( elm_parent.childNodes[ 0 ] ); + var fabric_label = new fabric.Text( elm_parent.innerText || elm_parent.textContent || elm_parent.innerHTML, { + selectable: false, + top: style_parent.top + group.offset.y, + left: style_parent.left + group.offset.x, + fill: style_text[ "color" ], + fontSize: style_text[ "fontSize" ], + fontFamily: style_text[ "fontFamily" ], + textAlign: style_text[ "text-align" ] + } ); + + _this.setup.fabric.add( fabric_label ); + } + } + } + + if ( group.svg.nextSibling && group.svg.nextSibling.tagName == "A" ) { + var elm_parent = group.svg.nextSibling; + var style_parent = fabric.parseStyleAttribute( elm_parent ); + var fabric_label = new fabric.Text( elm_parent.innerText || elm_parent.textContent || elm_parent.innerHTML, { + selectable: false, + top: style_parent.top + group.offset.y, + left: style_parent.left + group.offset.x, + fill: style_parent[ "color" ], + fontSize: style_parent[ "fontSize" ], + fontFamily: style_parent[ "fontFamily" ], + opacity: style_parent[ "opacity" ] + } ); + + _this.setup.fabric.add( fabric_label ); + } + + groups.pop(); + + // TRIGGER CALLBACK WITH SAFETY DELAY + if ( !groups.length ) { + var timer = setInterval( function() { + if ( images.loaded == images.included ) { + clearTimeout( timer ); + _this.handleBorder( cfg ); + _this.handleCallback( cfg.afterCapture, cfg ); + _this.setup.fabric.renderAll(); + _this.handleCallback( callback, cfg ); + } + }, AmCharts.updateRate ); + } + } + + // IDENTIFY ELEMENTS THROUGH CLASSNAMES + } )( group ), function( svg, obj ) { + var i1; + var className = _this.gatherAttribute( svg, "class" ); + var visibility = _this.gatherAttribute( svg, "visibility" ); + var clipPath = _this.gatherAttribute( svg, "clip-path" ); + + obj.className = String( className ); + obj.classList = String( className ).split( " " ); + obj.clipPath = clipPath; + obj.svg = svg; + + // TODO; WAIT FOR TSPAN SUPPORT FROM FABRICJS SIDE + if ( svg.tagName == "text" && svg.childNodes.length > 1 ) { + obj.TSPANWORKAROUND = true; + } + + // HIDE HIDDEN ELEMENTS; TODO: FIND A BETTER WAY TO HANDLE THAT + if ( visibility == "hidden" ) { + obj.opacity = 0; + + // WALKTHROUGH ELEMENTS + } else { + + // TRANSPORT FILL/STROKE OPACITY + var attrs = [ "fill", "stroke" ]; + for ( i1 = 0; i1 < attrs.length; i1++ ) { + var attr = attrs[ i1 ] + var attrVal = String( svg.getAttribute( attr ) || "" ); + var attrOpacity = Number( svg.getAttribute( attr + "-opacity" ) || "1" ); + var attrRGBA = fabric.Color.fromHex( attrVal ).getSource(); + + // EXCEPTION + if ( obj.classList.indexOf( _this.setup.chart.classNamePrefix + "-guide-fill" ) != -1 && !attrVal ) { + attrOpacity = 0; + attrRGBA = fabric.Color.fromHex( "#000000" ).getSource(); + } + + if ( attrRGBA ) { + attrRGBA.pop(); + attrRGBA.push( attrOpacity ) + obj[ attr ] = "rgba(" + attrRGBA.join() + ")"; + obj[ attr + _this.capitalize( "opacity" ) ] = attrOpacity; + } + } + } + + // REVIVER + _this.handleCallback( cfg.reviver, obj, svg ); + } ); + } + }, + + /** + * Returns the current canvas + */ + toCanvas: function( options, callback ) { + var cfg = _this.deepMerge( { + // NUFFIN + }, options || {} ); + var data = _this.setup.canvas; + + _this.handleCallback( callback, data ); + + return data; + }, + + /** + * Returns an image; by default PNG + */ + toImage: function( options, callback ) { + var cfg = _this.deepMerge( { + format: "png", + quality: 1, + multiplier: this.config.multiplier + }, options || {} ); + var data = cfg.data; + var img = document.createElement( "img" ); + + if ( !cfg.data ) { + if ( cfg.lossless || cfg.format == "svg" ) { + data = _this.toSVG( _this.deepMerge( cfg, { + getBase64: true + } ) ); + } else { + data = _this.setup.fabric.toDataURL( cfg ); + } + } + + img.setAttribute( "src", data ); + + _this.handleCallback( callback, img ); + + return img; + }, + + /** + * Generates a blob instance image; returns base64 datastring + */ + toBlob: function( options, callback ) { + var cfg = _this.deepMerge( { + data: "empty", + type: "text/plain" + }, options || {} ); + var data; + var isBase64 = /^data:.+;base64,(.*)$/.exec( cfg.data ); + + // GATHER BODY + if ( isBase64 ) { + cfg.data = isBase64[ 0 ]; + cfg.type = cfg.data.slice( 5, cfg.data.indexOf( "," ) - 7 ); + cfg.data = _this.toByteArray( { + data: cfg.data.slice( cfg.data.indexOf( "," ) + 1, cfg.data.length ) + } ); + } + + if ( cfg.getByteArray ) { + data = cfg.data; + } else { + data = new Blob( [ cfg.data ], { + type: cfg.type + } ); + } + + _this.handleCallback( callback, data ); + + return data; + }, + + /** + * Generates JPG image; returns base64 datastring + */ + toJPG: function( options, callback ) { + var cfg = _this.deepMerge( { + format: "jpeg", + quality: 1, + multiplier: this.config.multiplier + }, options || {} ); + cfg.format = cfg.format.toLowerCase(); + var data = _this.setup.fabric.toDataURL( cfg ); + + _this.handleCallback( callback, data ); + + return data; + }, + + /** + * Generates PNG image; returns base64 datastring + */ + toPNG: function( options, callback ) { + var cfg = _this.deepMerge( { + format: "png", + quality: 1, + multiplier: this.config.multiplier + }, options || {} ); + var data = _this.setup.fabric.toDataURL( cfg ); + + _this.handleCallback( callback, data ); + + return data; + }, + + /** + * Generates SVG image; returns base64 datastring + */ + toSVG: function( options, callback ) { + var clipPaths = []; + var cfg = _this.deepMerge( { + reviver: function( string, clipPath ) { + var matcher = new RegExp( /\bstyle=(['"])(.*?)\1/ ); + var match = matcher.exec( string )[ 0 ].slice( 7, -1 ); + var styles = match.split( ";" ); + var replacement = []; + + // BEAUTIFY STYLES + for ( i1 = 0; i1 < styles.length; i1++ ) { + if ( styles[ i1 ] ) { + var pair = styles[ i1 ].replace( /\s/g, "" ).split( ":" ); + var key = pair[ 0 ]; + var value = pair[ 1 ]; + + if ( [ "fill", "stroke" ].indexOf( key ) != -1 ) { + value = fabric.Color.fromRgba( value ); + if ( value && value._source ) { + var color = "#" + value.toHex(); + var opacity = value._source[ 3 ]; + + replacement.push( [ key, color ].join( ":" ) ); + replacement.push( [ key + "-opacity", opacity ].join( ":" ) ); + } else { + replacement.push( styles[ i1 ] ); + } + } else if ( key != "opactiy" ) { + replacement.push( styles[ i1 ] ); + } + } + } + string = string.replace( match, replacement.join( ";" ) ); + + // TODO: WAIT UNTIL FABRICJS HANDLES CLIPPATH FOR SVG OUTPUT + if ( clipPath ) { + var sliceOffset = 2; + var end = string.slice( -sliceOffset ); + + if ( end != "/>" ) { + sliceOffset = 3; + end = string.slice( -sliceOffset ); + } + + var start = string.slice( 0, string.length - sliceOffset ); + var clipPathAttr = " clip-path=\"url(#" + clipPath.svg.id + ")\" "; + var clipPathString = new XMLSerializer().serializeToString( clipPath.svg ); + + string = start + clipPathAttr + end; + + clipPaths.push( clipPathString ); + } + + return string; + } + }, options || {} ); + var data = _this.setup.fabric.toSVG( cfg, cfg.reviver ); + + // TODO: WAIT UNTIL FABRICJS HANDLES CLIPPATH FOR SVG OUTPUT + if ( clipPaths.length ) { + var start = data.slice( 0, data.length - 6 ); + var end = data.slice( -6 ); + data = start + clipPaths.join( "" ) + end; + } + + if ( cfg.getBase64 ) { + data = "data:image/svg+xml;base64," + btoa( data ); + } + + _this.handleCallback( callback, data ); + + return data; + }, + + /** + * Generates PDF; returns base64 datastring + */ + toPDF: function( options, callback ) { + var cfg = _this.deepMerge( _this.deepMerge( { + multiplier: 2 + }, _this.config.pdfMake ), options || {}, true ); + cfg.images.reference = _this.toPNG( cfg ); + var data = new pdfMake.createPdf( cfg ); + + + if ( callback ) { + data.getDataUrl( ( function( callback ) { + return function() { + callback.apply( _this, arguments ); + } + } )( callback ) ); + } + + return data; + }, + + /** + * Generates an image; hides all elements on page to trigger native print method + */ + toPRINT: function( options, callback ) { + var i1; + var cfg = _this.deepMerge( { + delay: 1, + lossless: false + }, options || {} ); + var data = _this.toImage( cfg ); + var states = []; + var items = document.body.childNodes; + + data.setAttribute( "style", "width: 100%; max-height: 100%;" ); + + for ( i1 = 0; i1 < items.length; i1++ ) { + if ( _this.isElement( items[ i1 ] ) ) { + states[ i1 ] = items[ i1 ].style.display; + items[ i1 ].style.display = "none"; + } + } + + document.body.appendChild( data ); + window.print(); + + setTimeout( function() { + for ( i1 = 0; i1 < items.length; i1++ ) { + if ( _this.isElement( items[ i1 ] ) ) { + items[ i1 ].style.display = states[ i1 ]; + } + } + document.body.removeChild( data ); + _this.handleCallback( callback, data ); + }, cfg.delay ); + + return data; + }, + + /** + * Generates JSON string + */ + toJSON: function( options, callback ) { + var cfg = _this.deepMerge( { + dateFormat: _this.config.dateFormat || "dateObject", + }, options || {}, true ); + cfg.data = cfg.data ? cfg.data : _this.getChartData( cfg ); + var data = JSON.stringify( cfg.data, undefined, "\t" ); + + _this.handleCallback( callback, data ); + + return data; + }, + + /** + * Generates CSV string + */ + toCSV: function( options, callback ) { + var row, col; + var cfg = _this.deepMerge( { + data: _this.getChartData( options ), + delimiter: ",", + quotes: true, + escape: true, + withHeader: true + }, options || {}, true ); + var data = ""; + var cols = []; + var buffer = []; + + function enchant( value, column ) { + + // WRAP IN QUOTES + if ( typeof value === "string" ) { + if ( cfg.escape ) { + value = value.replace( '"', '""' ); + } + if ( cfg.quotes ) { + value = [ '"', value, '"' ].join( "" ); + } + } + + return value; + } + + // HEADER + for ( value in cfg.data[ 0 ] ) { + buffer.push( enchant( value ) ); + cols.push( value ); + } + if ( cfg.withHeader ) { + data += buffer.join( cfg.delimiter ) + "\n"; + } + + // BODY + for ( row in cfg.data ) { + buffer = []; + if ( !isNaN( row ) ) { + for ( col in cols ) { + if ( !isNaN( col ) ) { + var column = cols[ col ]; + var value = cfg.data[ row ][ column ]; + + buffer.push( enchant( value, column ) ); + } + } + data += buffer.join( cfg.delimiter ) + "\n"; + } + } + + _this.handleCallback( callback, data ); + + return data; + }, + + /** + * Generates excel sheet; returns base64 datastring + */ + toXLSX: function( options, callback ) { + var cfg = _this.deepMerge( { + name: "amCharts", + dateFormat: _this.config.dateFormat || "dateObject", + withHeader: true, + stringify: false + }, options || {}, true ); + var data = ""; + var wb = { + SheetNames: [], + Sheets: {} + } + + cfg.data = cfg.data ? cfg.data : _this.getChartData( cfg ); + + function datenum( v, date1904 ) { + if ( date1904 ) v += 1462; + var epoch = Date.parse( v ); + return ( epoch - new Date( Date.UTC( 1899, 11, 30 ) ) ) / ( 24 * 60 * 60 * 1000 ); + } + + function sheet_from_array_of_arrays( data, opts ) { + var ws = {}; + var range = { + s: { + c: 10000000, + r: 10000000 + }, + e: { + c: 0, + r: 0 + } + }; + for ( var R = 0; R != data.length; ++R ) { + for ( var C = 0; C != data[ R ].length; ++C ) { + if ( range.s.r > R ) range.s.r = R; + if ( range.s.c > C ) range.s.c = C; + if ( range.e.r < R ) range.e.r = R; + if ( range.e.c < C ) range.e.c = C; + var cell = { + v: data[ R ][ C ] + }; + if ( cell.v == null ) continue; + var cell_ref = XLSX.utils.encode_cell( { + c: C, + r: R + } ); + + if ( typeof cell.v === "number" ) cell.t = "n"; + else if ( typeof cell.v === "boolean" ) cell.t = "b"; + else if ( cell.v instanceof Date ) { + cell.t = "n"; + cell.z = XLSX.SSF._table[ 14 ]; + cell.v = datenum( cell.v ); + } else cell.t = "s"; + + ws[ cell_ref ] = cell; + } + } + if ( range.s.c < 10000000 ) ws[ "!ref" ] = XLSX.utils.encode_range( range ); + return ws; + } + + wb.SheetNames.push( cfg.name ); + wb.Sheets[ cfg.name ] = sheet_from_array_of_arrays( _this.toArray( cfg ) ); + + data = XLSX.write( wb, { + bookType: "xlsx", + bookSST: true, + type: "base64" + } ); + + data = "data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64," + data; + + _this.handleCallback( callback, data ); + + return data; + }, + + /** + * Generates an array of arrays + */ + toArray: function( options, callback ) { + var row, col; + var cfg = _this.deepMerge( { + data: _this.getChartData( options ), + withHeader: false, + stringify: true + }, options || {}, true ); + var data = []; + var cols = []; + + // HEADER + for ( col in cfg.data[ 0 ] ) { + cols.push( col ); + } + if ( cfg.withHeader ) { + data.push( cols ); + } + + // BODY + for ( row in cfg.data ) { + var buffer = []; + if ( !isNaN( row ) ) { + for ( col in cols ) { + if ( !isNaN( col ) ) { + var col = cols[ col ]; + var value = cfg.data[ row ][ col ]; + if ( value == null ) { + value = ""; + } else if ( cfg.stringify ) { + value = String( value ); + } else { + value = value; + } + buffer.push( value ); + } + } + data.push( buffer ); + } + } + + _this.handleCallback( callback, data ); + + return data; + }, + + /** + * Generates byte array with given base64 datastring; returns byte array + */ + toByteArray: function( options, callback ) { + var cfg = _this.deepMerge( { + // NUFFIN + }, options || {} ); + var Arr = ( typeof Uint8Array !== 'undefined' ) ? Uint8Array : Array + var PLUS = '+'.charCodeAt( 0 ) + var SLASH = '/'.charCodeAt( 0 ) + var NUMBER = '0'.charCodeAt( 0 ) + var LOWER = 'a'.charCodeAt( 0 ) + var UPPER = 'A'.charCodeAt( 0 ) + var data = b64ToByteArray( cfg.data ); + + function decode( elt ) { + var code = elt.charCodeAt( 0 ) + if ( code === PLUS ) + return 62 // '+' + if ( code === SLASH ) + return 63 // '/' + if ( code < NUMBER ) + return -1 //no match + if ( code < NUMBER + 10 ) + return code - NUMBER + 26 + 26 + if ( code < UPPER + 26 ) + return code - UPPER + if ( code < LOWER + 26 ) + return code - LOWER + 26 + } + + function b64ToByteArray( b64 ) { + var i, j, l, tmp, placeHolders, arr + + if ( b64.length % 4 > 0 ) { + throw new Error( 'Invalid string. Length must be a multiple of 4' ) + } + + // THE NUMBER OF EQUAL SIGNS (PLACE HOLDERS) + // IF THERE ARE TWO PLACEHOLDERS, THAN THE TWO CHARACTERS BEFORE IT + // REPRESENT ONE BYTE + // IF THERE IS ONLY ONE, THEN THE THREE CHARACTERS BEFORE IT REPRESENT 2 BYTES + // THIS IS JUST A CHEAP HACK TO NOT DO INDEXOF TWICE + var len = b64.length + placeHolders = '=' === b64.charAt( len - 2 ) ? 2 : '=' === b64.charAt( len - 1 ) ? 1 : 0 + + // BASE64 IS 4/3 + UP TO TWO CHARACTERS OF THE ORIGINAL DATA + arr = new Arr( b64.length * 3 / 4 - placeHolders ) + + // IF THERE ARE PLACEHOLDERS, ONLY GET UP TO THE LAST COMPLETE 4 CHARS + l = placeHolders > 0 ? b64.length - 4 : b64.length + + var L = 0 + + function push( v ) { + arr[ L++ ] = v + } + + for ( i = 0, j = 0; i < l; i += 4, j += 3 ) { + tmp = ( decode( b64.charAt( i ) ) << 18 ) | ( decode( b64.charAt( i + 1 ) ) << 12 ) | ( decode( b64.charAt( i + 2 ) ) << 6 ) | decode( b64.charAt( i + 3 ) ) + push( ( tmp & 0xFF0000 ) >> 16 ) + push( ( tmp & 0xFF00 ) >> 8 ) + push( tmp & 0xFF ) + } + + if ( placeHolders === 2 ) { + tmp = ( decode( b64.charAt( i ) ) << 2 ) | ( decode( b64.charAt( i + 1 ) ) >> 4 ) + push( tmp & 0xFF ) + } else if ( placeHolders === 1 ) { + tmp = ( decode( b64.charAt( i ) ) << 10 ) | ( decode( b64.charAt( i + 1 ) ) << 4 ) | ( decode( b64.charAt( i + 2 ) ) >> 2 ) + push( ( tmp >> 8 ) & 0xFF ) + push( tmp & 0xFF ) + } + + return arr + } + + _this.handleCallback( callback, data ); + + return data; + }, + + /** + * Callback handler; injects additional arguments to callback + */ + handleCallback: function( callback ) { + var i1, data = Array(); + if ( callback && callback instanceof Function ) { + for ( i1 = 0; i1 < arguments.length; i1++ ) { + if ( i1 > 0 ) { + data.push( arguments[ i1 ] ); + } + } + callback.apply( _this, data ); + } + }, + + /** + * Border handler; injects additional border to canvas + */ + handleBorder: function( options ) { + if ( _this.config.border instanceof Object ) { + var cfg = _this.deepMerge( _this.defaults.fabric.border, options.border || {}, true ); + var border = new fabric.Rect(); + + cfg.width = _this.setup.fabric.width - cfg.strokeWidth; + cfg.height = _this.setup.fabric.height - cfg.strokeWidth; + + border.set( cfg ); + + _this.setup.fabric.add( border ); + } + }, + + /** + * Handles drag/drop events; loads given imagery + */ + handleDropbox: function( e ) { + if ( _this.drawing.buffer.enabled ) { + e.preventDefault(); + e.stopPropagation(); + + // DRAG OVER + if ( e.type == "dragover" ) { + _this.setup.wrapper.setAttribute( "class", _this.setup.chart.classNamePrefix + "-export-canvas active dropbox" ); + + // DRAGLEAVE; DROP + } else { + _this.setup.wrapper.setAttribute( "class", _this.setup.chart.classNamePrefix + "-export-canvas active" ); + + if ( e.type == "drop" && e.dataTransfer.files.length ) { + for ( var i1 = 0; i1 < e.dataTransfer.files.length; i1++ ) { + var reader = new FileReader(); + reader.onloadend = ( function( index ) { + return function() { + _this.drawing.handler.add( { + url: reader.result, + top: e.layerY - ( index * 10 ), + left: e.layerX - ( index * 10 ) + } ); + } + } )( i1 ); + reader.readAsDataURL( e.dataTransfer.files[ i1 ] ); + } + } + } + } + }, + + /** + * Gathers chart data according to its type + */ + getChartData: function( options ) { + var cfg = _this.deepMerge( { + data: [], + titles: {}, + dateFields: [], + dataFields: [], + dataFieldsMap: {}, + exportTitles: _this.config.exportTitles, + exportFields: _this.config.exportFields, + exportSelection: _this.config.exportSelection, + columnNames: _this.config.columnNames + }, options || {}, true ); + var uid, i1, i2, i3; + var lookupFields = [ "valueField", "openField", "closeField", "highField", "lowField", "xField", "yField" ]; + + // HANDLE FIELDS + function addField( field, title, type ) { + + function checkExistance( field, type ) { + if ( cfg.dataFields.indexOf( field ) != -1 ) { + return checkExistance( [ field, ".", type ].join( "" ) ); + } + return field; + } + + if ( field && cfg.exportTitles && _this.setup.chart.type != "gantt" ) { + uid = checkExistance( field, type ); + cfg.dataFieldsMap[ uid ] = field; + cfg.dataFields.push( uid ); + cfg.titles[ uid ] = title || uid; + } + } + + if ( cfg.data.length == 0 ) { + // STOCK DATA; GATHER COMPARED GRAPHS + if ( _this.setup.chart.type == "stock" ) { + cfg.data = _this.setup.chart.mainDataSet.dataProvider; + + // CATEGORY AXIS + addField( _this.setup.chart.mainDataSet.categoryField ); + cfg.dateFields.push( _this.setup.chart.mainDataSet.categoryField ); + + // WALKTHROUGH GRAPHS + for ( i1 = 0; i1 < _this.setup.chart.mainDataSet.fieldMappings.length; i1++ ) { + var fieldMap = _this.setup.chart.mainDataSet.fieldMappings[ i1 ]; + for ( i2 = 0; i2 < _this.setup.chart.panels.length; i2++ ) { + var panel = _this.setup.chart.panels[ i2 ] + for ( i3 = 0; i3 < panel.stockGraphs.length; i3++ ) { + var graph = panel.stockGraphs[ i3 ]; + + for ( i4 = 0; i4 < lookupFields.length; i4++ ) { + if ( graph[ lookupFields[ i4 ] ] == fieldMap.toField ) { + addField( fieldMap.fromField, graph.title, lookupFields[ i4 ] ); + } + } + } + } + } + + // WALKTHROUGH COMPARISON AND MERGE IT'S DATA + for ( i1 = 0; i1 < _this.setup.chart.comparedGraphs.length; i1++ ) { + var graph = _this.setup.chart.comparedGraphs[ i1 ]; + for ( i2 = 0; i2 < graph.dataSet.dataProvider.length; i2++ ) { + for ( i3 = 0; i3 < graph.dataSet.fieldMappings.length; i3++ ) { + var fieldMap = graph.dataSet.fieldMappings[ i3 ]; + var uid = graph.dataSet.id + "_" + fieldMap.toField; + + if ( i2 < cfg.data.length ) { + cfg.data[ i2 ][ uid ] = graph.dataSet.dataProvider[ i2 ][ fieldMap.fromField ]; + + if ( !cfg.titles[ uid ] ) { + addField( uid, graph.dataSet.title ) + } + } + } + } + } + + // GANTT DATA; FLATTEN SEGMENTS + } else if ( _this.setup.chart.type == "gantt" ) { + // CATEGORY AXIS + addField( _this.setup.chart.categoryField ); + cfg.dateFields.push( _this.setup.chart.categoryField ); + + var field = _this.setup.chart.segmentsField; + for ( i1 = 0; i1 < _this.setup.chart.dataProvider.length; i1++ ) { + var dataItem = _this.setup.chart.dataProvider[ i1 ]; + if ( dataItem[ field ] ) { + for ( i2 = 0; i2 < dataItem[ field ].length; i2++ ) { + dataItem[ field ][ i2 ][ _this.setup.chart.categoryField ] = dataItem[ _this.setup.chart.categoryField ]; + cfg.data.push( dataItem[ field ][ i2 ] ); + } + } + } + + // GRAPHS + for ( i1 = 0; i1 < _this.setup.chart.graphs.length; i1++ ) { + var graph = _this.setup.chart.graphs[ i1 ]; + + for ( i2 = 0; i2 < lookupFields.length; i2++ ) { + var dataField = lookupFields[ i2 ]; + var graphField = graph[ dataField ]; + var title = graph.title; + + addField( graphField, graph.title, dataField ); + } + } + + // PIE/FUNNEL DATA; + } else if ( [ "pie", "funnel" ].indexOf( _this.setup.chart.type ) != -1 ) { + cfg.data = _this.setup.chart.dataProvider; + + // CATEGORY AXIS + addField( _this.setup.chart.titleField ); + cfg.dateFields.push( _this.setup.chart.titleField ); + + // VALUE + addField( _this.setup.chart.valueField ); + + // DEFAULT DATA; + } else if ( _this.setup.chart.type != "map" ) { + cfg.data = _this.setup.chart.dataProvider; + + // CATEGORY AXIS + if ( _this.setup.chart.categoryAxis ) { + addField( _this.setup.chart.categoryField, _this.setup.chart.categoryAxis.title ); + if ( _this.setup.chart.categoryAxis.parseDates !== false ) { + cfg.dateFields.push( _this.setup.chart.categoryField ); + } + } + + // GRAPHS + for ( i1 = 0; i1 < _this.setup.chart.graphs.length; i1++ ) { + var graph = _this.setup.chart.graphs[ i1 ]; + + for ( i2 = 0; i2 < lookupFields.length; i2++ ) { + var dataField = lookupFields[ i2 ]; + var graphField = graph[ dataField ]; + + addField( graphField, graph.title, dataField ); + } + } + } + } + return _this.processData( cfg ); + }, + + /** + * Walkthrough data to format dates and titles + */ + processData: function( options ) { + var cfg = _this.deepMerge( { + data: [], + titles: {}, + dateFields: [], + dataFields: [], + dataFieldsMap: {}, + dataDateFormat: _this.setup.chart.dataDateFormat, + dateFormat: _this.config.dateFormat || _this.setup.chart.dataDateFormat || "YYYY-MM-DD", + exportTitles: _this.config.exportTitles, + exportFields: _this.config.exportFields, + exportSelection: _this.config.exportSelection, + columnNames: _this.config.columnNames, + processData: _this.config.processData + }, options || {}, true ); + var i1, i2; + + if ( cfg.data.length ) { + // GATHER MISSING FIELDS + for ( i1 = 0; i1 < cfg.data.length; i1++ ) { + for ( i2 in cfg.data[ i1 ] ) { + if ( cfg.dataFields.indexOf( i2 ) == -1 ) { + cfg.dataFields.push( i2 ); + cfg.dataFieldsMap[ i2 ] = i2; + } + } + } + + // REMOVE FIELDS SELECTIVELY + if ( cfg.exportFields !== undefined ) { + cfg.dataFields = cfg.dataFields.filter( function( n ) { + return cfg.exportFields.indexOf( n ) != -1; + } ); + } + + // REBUILD DATA + var buffer = []; + for ( i1 = 0; i1 < cfg.data.length; i1++ ) { + var tmp = {}; + var skip = false; + for ( i2 = 0; i2 < cfg.dataFields.length; i2++ ) { + var uniqueField = cfg.dataFields[ i2 ]; + var dataField = cfg.dataFieldsMap[ uniqueField ]; + var title = ( cfg.columnNames && cfg.columnNames[ uniqueField ] ) || cfg.titles[ uniqueField ] || uniqueField; + var value = cfg.data[ i1 ][ dataField ]; + if ( value == null ) { + value = undefined; + } + + // TITLEFY + if ( cfg.exportTitles && _this.setup.chart.type != "gantt" ) { + if ( title in tmp ) { + title += [ "( ", uniqueField, " )" ].join( "" ); + } + } + + // PROCESS CATEGORY + if ( cfg.dateFields.indexOf( dataField ) != -1 ) { + + // CONVERT DATESTRING TO DATE OBJECT + if ( cfg.dataDateFormat && ( value instanceof String || typeof value == "string" ) ) { + value = AmCharts.stringToDate( value, cfg.dataDateFormat ); + + // CONVERT TIMESTAMP TO DATE OBJECT + } else if ( cfg.dateFormat && ( value instanceof Number || typeof value == "number" ) ) { + value = new Date( value ); + } + + // CATEGORY RANGE + if ( cfg.exportSelection ) { + if ( value instanceof Date ) { + if ( value < chart.startDate || value > chart.endDate ) { + skip = true; + } + + } else if ( i1 < chart.startIndex || i1 > chart.endIndex ) { + skip = true; + } + } + + // CATEGORY FORMAT + if ( cfg.dateFormat && cfg.dateFormat != "dateObject" && value instanceof Date ) { + value = AmCharts.formatDate( value, cfg.dateFormat ); + } + } + + tmp[ title ] = value; + } + if ( !skip ) { + buffer.push( tmp ); + } + } + cfg.data = buffer; + } + + if ( cfg.processData !== undefined ) { + return cfg.processData( cfg.data ); + + } else { + return cfg.data; + } + }, + + /** + * Prettifies string + */ + capitalize: function( string ) { + return string.charAt( 0 ).toUpperCase() + string.slice( 1 ).toLowerCase(); + }, + + /** + * Generates export menu; returns UL node + */ + createMenu: function( list, container ) { + var div; + + function buildList( list, container ) { + var i1, i2, ul = document.createElement( "ul" ); + for ( i1 = 0; i1 < list.length; i1++ ) { + var item = typeof list[ i1 ] === "string" ? { + format: list[ i1 ] + } : list[ i1 ]; + var li = document.createElement( "li" ); + var a = document.createElement( "a" ); + var img = document.createElement( "img" ); + var span = document.createElement( "span" ); + var action = String( item.action ? item.action : item.format ).toLowerCase(); + + item.format = String( item.format ).toUpperCase(); + + // MERGE WITH GIVEN FORMAT + if ( _this.config.formats[ item.format ] ) { + item = _this.deepMerge( { + label: item.icon ? "" : item.format, + format: item.format, + mimeType: _this.config.formats[ item.format ].mimeType, + extension: _this.config.formats[ item.format ].extension, + capture: _this.config.formats[ item.format ].capture, + action: _this.config.action, + fileName: _this.config.fileName + }, item ); + } else if ( !item.label ) { + item.label = item.label ? item.label : _this.i18l( "menu.label." + action ); + } + + // FILTER; TOGGLE FLAG + if ( [ "CSV", "JSON", "XLSX" ].indexOf( item.format ) != -1 && [ "map", "gauge" ].indexOf( _this.setup.chart.type ) != -1 ) { + continue; + + // BLOB EXCEPTION + } else if ( !_this.setup.hasBlob && item.format != "UNDEFINED" ) { + if ( item.mimeType && item.mimeType.split( "/" )[ 0 ] != "image" && item.mimeType != "text/plain" ) { + continue; + } + } + + // DRAWING + if ( item.action == "draw" ) { + if ( _this.config.fabric.drawing.enabled ) { + item.menu = item.menu ? item.menu : _this.config.fabric.drawing.menu; + item.click = ( function( item ) { + return function() { + this.capture( item, function() { + this.createMenu( item.menu ); + } ); + } + } )( item ); + } else { + item.menu = []; + } + + // DRAWING CHOICES + } else if ( !item.populated && item.action && item.action.indexOf( "draw." ) != -1 ) { + var type = item.action.split( "." )[ 1 ]; + var items = item[ type ] || _this.config.fabric.drawing[ type ] || []; + + item.menu = []; + item.populated = true; + + for ( i2 = 0; i2 < items.length; i2++ ) { + var tmp = { + "label": items[ i2 ] + } + + if ( type == "shapes" ) { + var io = items[ i2 ].indexOf( "//" ) == -1; + var url = ( io ? _this.config.path + "shapes/" : "" ) + items[ i2 ]; + + tmp.action = "add"; + tmp.url = url; + tmp.icon = url; + tmp.ignore = io; + tmp[ "class" ] = "export-drawing-shape"; + + } else if ( type == "colors" ) { + tmp.style = "background-color: " + items[ i2 ]; + tmp.action = "change"; + tmp.color = items[ i2 ]; + tmp[ "class" ] = "export-drawing-color"; + + } else if ( type == "widths" ) { + tmp.action = "change"; + tmp.width = items[ i2 ]; + tmp.label = document.createElement( "span" ); + + tmp.label.style.width = _this.numberToPx( items[ i2 ] ); + tmp.label.style.height = _this.numberToPx( items[ i2 ] ); + tmp[ "class" ] = "export-drawing-width"; + } else if ( type == "opacities" ) { + tmp.style = "opacity: " + items[ i2 ]; + tmp.action = "change"; + tmp.opacity = items[ i2 ]; + tmp.label = ( items[ i2 ] * 100 ) + "%"; + tmp[ "class" ] = "export-drawing-opacity"; + } else if ( type == "modes" ) { + tmp.label = _this.i18l( "menu.label.draw.modes." + items[ i2 ] ); + tmp.click = ( function( mode ) { + return function() { + _this.drawing.mode = mode; + } + } )( items[ i2 ] ); + tmp[ "class" ] = "export-drawing-mode"; + } + + item.menu.push( tmp ); + } + + // ADD CLICK HANDLER + } else if ( !item.click && !item.menu && !item.items ) { + // DRAWING METHODS + if ( _this.drawing.handler[ action ] instanceof Function ) { + item.action = action; + item.click = ( function( item ) { + return function() { + this.drawing.handler[ item.action ]( item ); + } + } )( item ); + + // DRAWING + } else if ( _this.drawing.buffer.enabled ) { + item.click = ( function( item ) { + return function() { + if ( this.config.drawing.autoClose ) { + this.drawing.handler.done(); + } + this[ "to" + item.format ]( item, function( data ) { + if ( item.action == "download" ) { + this.download( data, item.mimeType, [ item.fileName, item.extension ].join( "." ) ); + } + } ); + } + } )( item ); + + // REGULAR + } else if ( item.format != "UNDEFINED" ) { + item.click = ( function( item ) { + return function() { + if ( item.capture || item.action == "print" || item.format == "PRINT" ) { + this.capture( item, function() { + if ( this.config.drawing.autoClose ) { + this.drawing.handler.done(); + } + this[ "to" + item.format ]( item, function( data ) { + if ( item.action == "download" ) { + this.download( data, item.mimeType, [ item.fileName, item.extension ].join( "." ) ); + } + } ); + } ) + + } else if ( this[ "to" + item.format ] ) { + this[ "to" + item.format ]( item, function( data ) { + this.download( data, item.mimeType, [ item.fileName, item.extension ].join( "." ) ); + } ); + } else { + throw new Error( 'Invalid format. Could not determine output type.' ); + } + } + } )( item ); + } + } + + // HIDE EMPTY ONES + if ( item.menu !== undefined && !item.menu.length ) { + continue; + } + + // ADD LINK ATTR + a.setAttribute( "href", "#" ); + a.addEventListener( "click", ( function( callback, item ) { + return function( e ) { + e.preventDefault(); + var args = [ e, item ]; + + // DELAYED + if ( ( item.action == "draw" || item.format == "PRINT" || ( item.format != "UNDEFINED" && item.capture ) ) && !_this.drawing.enabled ) { + item.delay = item.delay ? item.delay : _this.config.delay; + if ( item.delay ) { + _this.delay( item, callback ); + return; + } + } + + callback.apply( _this, args ); + } + } )( item.click || function( e ) { + e.preventDefault(); + }, item ) ); + li.appendChild( a ); + + // ADD LABEL + if ( _this.isElement( item.label ) ) { + span.appendChild( item.label ); + } else { + span.innerHTML = item.label; + } + + // APPEND ITEMS + if ( item[ "class" ] ) { + li.className = item[ "class" ]; + } + + if ( item.style ) { + li.setAttribute( "style", item.style ); + } + + if ( item.icon ) { + img.setAttribute( "src", ( !item.ignore && item.icon.slice( 0, 10 ).indexOf( "//" ) == -1 ? chart.pathToImages : "" ) + item.icon ); + a.appendChild( img ); + } + if ( item.label ) { + a.appendChild( span ); + } + if ( item.title ) { + a.setAttribute( "title", item.title ); + } + + // CALLBACK; REVIVER FOR MENU ITEMS + if ( _this.config.menuReviver ) { + li = _this.config.menuReviver.apply( _this, [ item, li ] ); + } + + // ADD ELEMENTS FOR EASY ACCESS + item.elements = { + li: li, + a: a, + img: img, + span: span + } + + // ADD SUBLIST; JUST WITH ENTRIES + if ( ( item.menu || item.items ) && item.action != "draw" ) { + if ( buildList( item.menu || item.items, li ).childNodes.length ) { + ul.appendChild( li ); + } + } else { + ul.appendChild( li ); + } + } + + // JUST ADD THOSE WITH ENTRIES + if ( ul.childNodes.length ) { + container.appendChild( ul ); + } + + return ul; + } + + // DETERMINE CONTAINER + if ( !container ) { + if ( typeof _this.config.divId == "string" ) { + _this.config.divId = container = document.getElementById( _this.config.divId ); + } else if ( _this.isElement( _this.config.divId ) ) { + container = _this.config.divId; + } else { + container = _this.setup.chart.containerDiv; + } + } + + // CREATE / RESET MENU CONTAINER + if ( _this.isElement( _this.setup.menu ) ) { + _this.setup.menu.innerHTML = ""; + } else { + _this.setup.menu = document.createElement( "div" ); + } + _this.setup.menu.setAttribute( "class", _this.setup.chart.classNamePrefix + "-export-menu " + _this.setup.chart.classNamePrefix + "-export-menu-" + _this.config.position + " amExportButton" ); + + // CALLBACK; REPLACES THE MENU WALKER + if ( _this.config.menuWalker ) { + buildList = _this.config.menuWalker; + } + buildList.apply( this, [ list, _this.setup.menu ] ); + + // JUST ADD THOSE WITH ENTRIES + if ( _this.setup.menu.childNodes.length ) { + container.appendChild( _this.setup.menu ); + } + + return _this.setup.menu; + }, + + /** + * Method to trigger the callback delayed + */ + delay: function( options, callback ) { + var cfg = _this.deepMerge( { + delay: 3, + precision: 2 + }, options || {} ); + var t1, t2, start = Number( new Date() ); + var menu = _this.createMenu( [ { + label: _this.i18l( "capturing.delayed.menu.label" ).replace( "{{duration}}", AmCharts.toFixed( cfg.delay, cfg.precision ) ), + title: _this.i18l( "capturing.delayed.menu.title" ), + "class": "export-delayed-capturing", + click: function() { + clearTimeout( t1 ); + clearTimeout( t2 ); + _this.createMenu( _this.config.menu ); + } + } ] ); + var label = menu.getElementsByTagName( "a" )[ 0 ]; + + // MENU UPDATE + t1 = setInterval( function() { + var diff = cfg.delay - ( Number( new Date() ) - start ) / 1000; + if ( diff <= 0 ) { + clearTimeout( t1 ); + if ( cfg.action != "draw" ) { + _this.createMenu( _this.config.menu ); + } + } else if ( label ) { + label.innerHTML = _this.i18l( "capturing.delayed.menu.label" ).replace( "{{duration}}", AmCharts.toFixed( diff, 2 ) ); + } + }, 10 ); + + // CALLBACK + t2 = setTimeout( function() { + callback.apply( _this, arguments ); + }, cfg.delay * 1000 ); + }, + + /** + * Migration method to support old export setup + */ + migrateSetup: function( setup ) { + var cfg = { + enabled: true, + migrated: true, + libs: { + autoLoad: true + }, + menu: [] + }; + + function crawler( object ) { + var key; + for ( key in object ) { + var value = object[ key ]; + + if ( key.slice( 0, 6 ) == "export" && value ) { + cfg.menu.push( key.slice( 6 ) ); + } else if ( key == "userCFG" ) { + crawler( value ); + } else if ( key == "menuItems" ) { + cfg.menu = value; + } else if ( key == "libs" ) { + cfg.libs = value; + } else if ( typeof key == "string" ) { + cfg[ key ] = value; + } + } + } + + crawler( setup ); + + return cfg; + }, + + clear:function(){ + _this.setup = undefined; + if(_this.docListener){ + document.removeEventListener("keydown", _this.docListener); + } + var listenersToRemove = _this.listenersToRemove; + if(listenersToRemove){ + for(var i = 0; i < listenersToRemove.length; i++){ + var listenerToRemove = listenersToRemove[i]; + listenerToRemove.node.removeEventListener(listenerToRemove.event, listenerToRemove.method) + } + } + _this.listenersToRemove = []; + }, + + /* + ** Add event listener + */ + loadListeners: function() { + function handleClone( clone ) { + if ( clone ) { + clone.set( { + top: clone.top + 10, + left: clone.left + 10 + } ); + _this.setup.fabric.add( clone ); + } + } + + + + // OBSERVE; KEY LISTENER; DRAWING FEATURES + if ( _this.config.keyListener && _this.config.keyListener != "attached" ) { + + _this.docListener = function( e ) { + var current = _this.drawing.buffer.target; + + // REMOVE; key: BACKSPACE / DELETE + if ( ( e.keyCode == 8 || e.keyCode == 46 ) && current ) { + e.preventDefault(); + _this.setup.fabric.remove( current ); + + // ESCAPE DRAWIN MODE; key: escape + } else if ( e.keyCode == 27 && _this.drawing.enabled ) { + e.preventDefault(); + _this.drawing.handler.done(); + + // COPY; key: C + } else if ( e.keyCode == 67 && ( e.metaKey || e.ctrlKey ) && current ) { + _this.drawing.buffer.copy = current; + + // CUT; key: X + } else if ( e.keyCode == 88 && ( e.metaKey || e.ctrlKey ) && current ) { + _this.drawing.buffer.copy = current; + _this.setup.fabric.remove( current ); + + // PASTE; key: V + } else if ( e.keyCode == 86 && ( e.metaKey || e.ctrlKey ) ) { + if ( _this.drawing.buffer.copy ) { + handleClone( _this.drawing.buffer.copy.clone( handleClone ) ) + } + + // UNDO / REDO; key: Z + } else if ( e.keyCode == 90 && ( e.metaKey || e.ctrlKey ) ) { + e.preventDefault(); + if ( e.shiftKey ) { + _this.drawing.handler.redo(); + } else { + _this.drawing.handler.undo(); + } + } + } + + _this.config.keyListener = "attached"; + + document.addEventListener("keydown", _this.docListener); + } + + // OBSERVE; DRAG AND DROP LISTENER; DRAWING FEATURE + if ( _this.config.fileListener ) { + _this.setup.chart.containerDiv.addEventListener( "dragover", _this.handleDropbox ); + _this.setup.chart.containerDiv.addEventListener( "dragleave", _this.handleDropbox ); + _this.setup.chart.containerDiv.addEventListener( "drop", _this.handleDropbox ); + } + }, + + /** + * Initiate export menu; waits for chart container to place menu + */ + init: function() { + clearTimeout( _this.timer ); + + _this.timer = setInterval( function() { + if ( _this.setup.chart.containerDiv ) { + clearTimeout( _this.timer ); + + if ( _this.config.enabled ) { + // CREATE REFERENCE + _this.setup.chart.AmExport = _this; + + // OVERWRITE PARENT OVERFLOW + if ( _this.config.overflow ) { + _this.setup.chart.div.style.overflow = "visible"; + } + + // ATTACH EVENTS + _this.loadListeners(); + + // CREATE MENU + _this.createMenu( _this.config.menu ); + } + } + }, AmCharts.updateRate ); + + }, + + /** + * Initiates export instance; merges given config; attaches event listener + */ + construct: function() { + // ANNOTATION; MAP "DONE" + _this.drawing.handler.cancel = _this.drawing.handler.done; + + // CHECK BLOB CONSTRUCTOR + try { + _this.setup.hasBlob = !!new Blob; + } catch ( e ) {} + + // WORK AROUND TO BYPASS FILESAVER CHECK TRYING TO OPEN THE BLOB URL IN SAFARI BROWSER + window.safari = window.safari ? window.safari : {}; + + // OVERTAKE CHART FONTSIZE IF GIVEN + _this.defaults.fabric.drawing.fontSize = _this.setup.chart.fontSize || 11; + + // MERGE SETTINGS + _this.config.drawing = _this.deepMerge( _this.defaults.fabric.drawing, _this.config.drawing || {}, true ); + if ( _this.config.border ) { + _this.config.border = _this.deepMerge( _this.defaults.fabric.border, _this.config.border || {}, true ); + } + _this.deepMerge( _this.defaults.fabric, _this.config, true ); + _this.deepMerge( _this.defaults.fabric, _this.config.fabric || {}, true ); + _this.deepMerge( _this.defaults.pdfMake, _this.config, true ); + _this.deepMerge( _this.defaults.pdfMake, _this.config.pdfMake || {}, true ); + _this.deepMerge( _this.libs, _this.config.libs || {}, true ); + + // UPDATE CONFIG + _this.config.drawing = _this.defaults.fabric.drawing; + _this.config.fabric = _this.defaults.fabric; + _this.config.pdfMake = _this.defaults.pdfMake; + _this.config = _this.deepMerge( _this.defaults, _this.config, true ); + + // MERGE; SETUP DRAWING MENU + if ( _this.config.fabric.drawing.enabled ) { + if ( _this.config.fabric.drawing.menu === undefined ) { + _this.config.fabric.drawing.menu = []; + _this.deepMerge( _this.config.fabric.drawing.menu, [ { + "class": "export-drawing", + menu: [ { + label: _this.i18l( "menu.label.draw.add" ), + menu: [ { + label: _this.i18l( "menu.label.draw.shapes" ), + action: "draw.shapes" + }, { + label: _this.i18l( "menu.label.draw.text" ), + action: "text" + } ] + }, { + label: _this.i18l( "menu.label.draw.change" ), + menu: [ { + label: _this.i18l( "menu.label.draw.modes" ), + action: "draw.modes" + }, { + label: _this.i18l( "menu.label.draw.colors" ), + action: "draw.colors" + }, { + label: _this.i18l( "menu.label.draw.widths" ), + action: "draw.widths" + }, { + label: _this.i18l( "menu.label.draw.opacities" ), + action: "draw.opacities" + }, "UNDO", "REDO" ] + }, { + label: _this.i18l( "menu.label.save.image" ), + menu: [ "PNG", "JPG", "SVG", "PDF" ] + }, "PRINT", "CANCEL" ] + } ] ); + } + } + + // MERGE; SETUP MAIN MENU + if ( _this.config.menu === undefined ) { + _this.config.menu = []; + // PARENT MENU + _this.deepMerge( _this.config, { + menu: [ { + "class": "export-main", + menu: [ { + label: _this.i18l( "menu.label.save.image" ), + menu: [ "PNG", "JPG", "SVG", "PDF" ] + }, { + label: _this.i18l( "menu.label.save.data" ), + menu: [ "CSV", "XLSX", "JSON" ] + }, { + label: _this.i18l( "menu.label.draw" ), + action: "draw", + menu: _this.config.fabric.drawing.menu + }, { + format: "PRINT", + label: _this.i18l( "menu.label.print" ) + } ] + } ] + } ); + } + + // ADD MISSING PATH + if ( !_this.libs.path ) { + _this.libs.path = _this.config.path + "libs/"; + } + + // CHECK ACCEPTANCE + if ( _this.isSupported() ) { + // LOAD DEPENDENCIES + _this.loadDependencies( _this.libs.resources, _this.libs.reload ); + // ADD CLASSNAMES + _this.setup.chart.addClassNames = true; + // REFERENCE + _this.setup.chart[ _this.name ] = _this; + // INIT MENU; WAIT FOR CHART INSTANCE + _this.init(); + } + } + } + + // USE GIVEN CONFIG + if ( config ) { + _this.config = config; + + // USE CHART EXPORT CONFIG + } else if ( _this.setup.chart[ _this.name ] ) { + _this.config = _this.setup.chart[ _this.name ]; + + // MIGRATE OLD EXPORT CHART CONFIG + } else if ( _this.setup.chart.amExport || _this.setup.chart.exportConfig ) { + _this.config = _this.migrateSetup( _this.setup.chart.amExport || _this.setup.chart.exportConfig ); + + // EXIT; NO CONFIG + } else { + return; + } + + // CONSTRUCT INSTANCE + _this.construct(); + + // EXPORT SCOPE + return _this.deepMerge( this, _this ); + } +} )(); + +/** + * Set init handler + */ +AmCharts.addInitHandler( function( chart ) { + new AmCharts[ "export" ]( chart ); + +}, [ "pie", "serial", "xy", "funnel", "radar", "gauge", "stock", "map", "gantt" ] ); \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/export/export.min.js b/iguana/js/amcharts/plugins/export/export.min.js new file mode 100755 index 000000000..5fdb105fa --- /dev/null +++ b/iguana/js/amcharts/plugins/export/export.min.js @@ -0,0 +1,2 @@ +AmCharts.translations["export"]||(AmCharts.translations["export"]={}),AmCharts.translations["export"].en||(AmCharts.translations["export"].en={"fallback.save.text":"CTRL + C to copy the data into the clipboard.","fallback.save.image":"Rightclick -> Save picture as... to save the image.","capturing.delayed.menu.label":"{{duration}}","capturing.delayed.menu.title":"Click to cancel","menu.label.print":"Print","menu.label.undo":"Undo","menu.label.redo":"Redo","menu.label.cancel":"Cancel","menu.label.save.image":"Download as ...","menu.label.save.data":"Save as ...","menu.label.draw":"Annotate ...","menu.label.draw.change":"Change ...","menu.label.draw.add":"Add ...","menu.label.draw.shapes":"Shape ...","menu.label.draw.colors":"Color ...","menu.label.draw.widths":"Size ...","menu.label.draw.opacities":"Opacity ...","menu.label.draw.text":"Text","menu.label.draw.modes":"Mode ...","menu.label.draw.modes.pencil":"Pencil","menu.label.draw.modes.line":"Line","menu.label.draw.modes.arrow":"Arrow"}),function(){AmCharts["export"]=function(a,b){var c={name:"export",version:"1.4.20",libs:{async:!0,autoLoad:!0,reload:!1,resources:[{"pdfmake/pdfmake.js":["pdfmake/vfs_fonts.js"],"jszip/jszip.js":["xlsx/xlsx.js"]},"fabric.js/fabric.js","FileSaver.js/FileSaver.js"],namespaces:{"pdfmake.js":"pdfMake","jszip.js":"JSZip","xlsx.js":"XLSX","fabric.js":"fabric","FileSaver.js":"saveAs"}},config:{},setup:{chart:a,hasBlob:!1,wrapper:!1},drawing:{enabled:!1,undos:[],redos:[],buffer:{position:{x1:0,y1:0,x2:0,y2:0,xD:0,yD:0}},handler:{undo:function(a,b){var d=c.drawing.undos.pop();if(d){d.selectable=!0,c.drawing.redos.push(d),"added"==d.action&&c.setup.fabric.remove(d.target);var e=JSON.parse(d.state);d.target.set(e),d.target instanceof fabric.Group&&c.drawing.handler.change({color:e.cfg.color,width:e.cfg.width,opacity:e.cfg.opacity},!0,d.target),c.setup.fabric.renderAll(),d.state!=d.target.recentState||b||c.drawing.handler.undo(d,!0)}},redo:function(a,b){var d=c.drawing.redos.pop();if(d){d.selectable=!0,c.drawing.undos.push(d),"added"==d.action&&c.setup.fabric.add(d.target);var e=JSON.parse(d.state);d.target.recentState=d.state,d.target.set(e),d.target instanceof fabric.Group&&c.drawing.handler.change({color:e.cfg.color,width:e.cfg.width,opacity:e.cfg.opacity},!0,d.target),c.setup.fabric.renderAll(),"addified"==d.action&&c.drawing.handler.redo()}},done:function(a){c.drawing.buffer.enabled=!1,c.drawing.undos=[],c.drawing.redos=[],c.createMenu(c.config.menu),c.setup.fabric.deactivateAll(),c.setup.wrapper&&(c.setup.chart.containerDiv.removeChild(c.setup.wrapper),c.setup.wrapper=!1)},add:function(a){var b=c.deepMerge({top:c.setup.fabric.height/2,left:c.setup.fabric.width/2},a||{}),d=-1!=b.url.indexOf(".svg")?fabric.loadSVGFromURL:fabric.Image.fromURL;d(b.url,function(a,d){var e=void 0!==d?fabric.util.groupSVGElements(a,d):a,f=!1;(e.height>c.setup.fabric.height||e.width>c.setup.fabric.width)&&(f=c.setup.fabric.height/2/e.height),b.top>c.setup.fabric.height&&(b.top=c.setup.fabric.height/2),b.left>c.setup.fabric.width&&(b.left=c.setup.fabric.width/2),e.set({originX:"center",originY:"center",top:b.top,left:b.left,width:f?e.width*f:e.width,height:f?e.height*f:e.height,fill:c.drawing.color}),c.setup.fabric.add(e)})},change:function(a,b,d){var f,g,h,e=c.deepMerge({},a||{}),i=d||c.drawing.buffer.target,j=i?i._objects?i._objects:[i]:null;if(e.mode&&(c.drawing.mode=e.mode),e.width&&(c.drawing.width=e.width,c.drawing.fontSize=3*e.width),e.fontSize&&(c.drawing.fontSize=e.fontSize),e.color&&(c.drawing.color=e.color),e.opacity&&(c.drawing.opacity=e.opacity),h=new fabric.Color(c.drawing.color).getSource(),h.pop(),h.push(c.drawing.opacity),c.drawing.color="rgba("+h.join()+")",c.setup.fabric.freeDrawingBrush.color=c.drawing.color,c.setup.fabric.freeDrawingBrush.width=c.drawing.width,i){for(f=JSON.parse(i.recentState).cfg,f&&(e.color=e.color||f.color,e.width=e.width||f.width,e.opacity=e.opacity||f.opacity,e.fontSize=e.fontSize||3*e.width,h=new fabric.Color(e.color).getSource(),h.pop(),h.push(e.opacity),e.color="rgba("+h.join()+")"),g=0;g0?Math.PI/2:3*Math.PI/2:0==f?e>0?0:Math.PI:0>e?Math.atan(f/e)+Math.PI:0>f?Math.atan(f/e)+2*Math.PI:Math.atan(f/e),180*g/Math.PI},gatherAttribute:function(a,b,d,e){var f,e=e?e:0,d=d?d:3;return a&&(f=a.getAttribute(b),!f&&d>e)?c.gatherAttribute(a.parentNode,b,d,e+1):f},gatherClassName:function(a,b,d,e){var f,e=e?e:0,d=d?d:3;if(c.isElement(a)){if(f=-1!=(a.getAttribute("class")||"").split(" ").indexOf(b),!f&&d>e)return c.gatherClassName(a.parentNode,b,d,e+1);f&&(f=a)}return f},gatherElements:function(a,b,d){var e,f;for(e=0;eg.height?j.legend.height:g.height):-1!=["top","bottom"].indexOf(j.legend.position)&&(g.height+=j.legend.height),j=c.gatherElements(j,e,h),f[j.legend.type](j)}if(c.drawing.buffer.enabled="draw"==e.action,c.setup.wrapper=document.createElement("div"),c.setup.wrapper.setAttribute("class",c.setup.chart.classNamePrefix+"-export-canvas"),c.setup.chart.containerDiv.appendChild(c.setup.wrapper),"stock"==c.setup.chart.type){var k={top:0,right:0,bottom:0,left:0};c.setup.chart.leftContainer&&(g.width-=c.setup.chart.leftContainer.offsetWidth,k.left=c.setup.chart.leftContainer.offsetWidth+2*c.setup.chart.panelsSettings.panelSpacing),c.setup.chart.rightContainer&&(g.width-=c.setup.chart.rightContainer.offsetWidth,k.right=c.setup.chart.rightContainer.offsetWidth+2*c.setup.chart.panelsSettings.panelSpacing),c.setup.chart.periodSelector&&-1!=["top","bottom"].indexOf(c.setup.chart.periodSelector.position)&&(g.height-=c.setup.chart.periodSelector.offsetHeight+c.setup.chart.panelsSettings.panelSpacing,k[c.setup.chart.periodSelector.position]+=c.setup.chart.periodSelector.offsetHeight+c.setup.chart.panelsSettings.panelSpacing),c.setup.chart.dataSetSelector&&-1!=["top","bottom"].indexOf(c.setup.chart.dataSetSelector.position)&&(g.height-=c.setup.chart.dataSetSelector.offsetHeight,k[c.setup.chart.dataSetSelector.position]+=c.setup.chart.dataSetSelector.offsetHeight),c.setup.wrapper.style.paddingTop=c.numberToPx(k.top),c.setup.wrapper.style.paddingRight=c.numberToPx(k.right),c.setup.wrapper.style.paddingBottom=c.numberToPx(k.bottom),c.setup.wrapper.style.paddingLeft=c.numberToPx(k.left)}for(c.setup.canvas=document.createElement("canvas"),c.setup.wrapper.appendChild(c.setup.canvas),c.setup.fabric=new fabric.Canvas(c.setup.canvas,c.deepMerge({width:g.width,height:g.height,isDrawingMode:!0},e)),c.deepMerge(c.setup.fabric,e),c.deepMerge(c.setup.fabric.freeDrawingBrush,e.drawing),c.deepMerge(c.drawing,e.drawing),c.drawing.handler.change(e.drawing),c.setup.fabric.on("mouse:down",function(a){c.gatherPosition(a.e,1);c.drawing.buffer.pressedTS=Number(new Date),c.isPressed(a.e)}),c.setup.fabric.on("mouse:move",function(a){var b=c.gatherPosition(a.e,2);if(c.isPressed(a.e),c.drawing.buffer.isPressed&&!c.drawing.buffer.line&&!c.drawing.buffer.isSelected&&"pencil"!=c.drawing.mode&&(b.xD>5||b.xD>5)&&(c.drawing.buffer.hasLine=!0,c.setup.fabric.isDrawingMode=!1,c.setup.fabric._onMouseUpInDrawingMode(a),c.drawing.buffer.line=c.drawing.handler.line({x1:b.x1,y1:b.y1,x2:b.x2,y2:b.y2,arrow:"line"==c.drawing.mode?!1:c.drawing.arrow,action:"config"})),c.drawing.buffer.line){var e,f,g,h=c.drawing.buffer.line;for(h.x2=b.x2,h.y2=b.y2,d=0;d1&&(b.TSPANWORKAROUND=!0),"hidden"==g)b.opacity=0;else{var i=["fill","stroke"];for(d=0;d"!=n&&(m=3,n=a.slice(-m));var o=a.slice(0,a.length-m),p=' clip-path="url(#'+b.svg.id+')" ',q=(new XMLSerializer).serializeToString(b.svg);a=o+p+n,d.push(q)}return a}},a||{}),f=c.setup.fabric.toSVG(e,e.reviver);if(d.length){var g=f.slice(0,f.length-6),h=f.slice(-6);f=g+d.join("")+h}return e.getBase64&&(f="data:image/svg+xml;base64,"+btoa(f)),c.handleCallback(b,f),f},toPDF:function(a,b){var d=c.deepMerge(c.deepMerge({multiplier:2},c.config.pdfMake),a||{},!0);d.images.reference=c.toPNG(d);var e=new pdfMake.createPdf(d);return b&&e.getDataUrl(function(a){return function(){a.apply(c,arguments)}}(b)),e},toPRINT:function(a,b){var d,e=c.deepMerge({delay:1,lossless:!1},a||{}),f=c.toImage(e),g=[],h=document.body.childNodes;for(f.setAttribute("style","width: 100%; max-height: 100%;"),d=0;de&&(d.s.r=e),d.s.c>f&&(d.s.c=f),d.e.rb?-1:h+10>b?b-h+26+26:j+26>b?b-j:i+26>b?b-i+26:void 0}function m(a){function k(a){h[j++]=a}var b,c,d,f,g,h;if(a.length%4>0)throw new Error("Invalid string. Length must be a multiple of 4");var i=a.length;g="="===a.charAt(i-2)?2:"="===a.charAt(i-1)?1:0,h=new e(3*a.length/4-g),d=g>0?a.length-4:a.length;var j=0;for(b=0,c=0;d>b;b+=4,c+=3)f=l(a.charAt(b))<<18|l(a.charAt(b+1))<<12|l(a.charAt(b+2))<<6|l(a.charAt(b+3)),k((16711680&f)>>16),k((65280&f)>>8),k(255&f);return 2===g?(f=l(a.charAt(b))<<2|l(a.charAt(b+1))>>4,k(255&f)):1===g&&(f=l(a.charAt(b))<<10|l(a.charAt(b+1))<<4|l(a.charAt(b+2))>>2,k(f>>8&255),k(255&f)),h}var d=c.deepMerge({},a||{}),e="undefined"!=typeof Uint8Array?Uint8Array:Array,f="+".charCodeAt(0),g="/".charCodeAt(0),h="0".charCodeAt(0),i="a".charCodeAt(0),j="A".charCodeAt(0),k=m(d.data);return c.handleCallback(b,k),k},handleCallback:function(a){var b,d=Array();if(a&&a instanceof Function){for(b=0;b0&&d.push(arguments[b]);a.apply(c,d)}},handleBorder:function(a){if(c.config.border instanceof Object){var b=c.deepMerge(c.defaults.fabric.border,a.border||{},!0),d=new fabric.Rect;b.width=c.setup.fabric.width-b.strokeWidth,b.height=c.setup.fabric.height-b.strokeWidth,d.set(b),c.setup.fabric.add(d)}},handleDropbox:function(a){if(c.drawing.buffer.enabled)if(a.preventDefault(),a.stopPropagation(),"dragover"==a.type)c.setup.wrapper.setAttribute("class",c.setup.chart.classNamePrefix+"-export-canvas active dropbox");else if(c.setup.wrapper.setAttribute("class",c.setup.chart.classNamePrefix+"-export-canvas active"),"drop"==a.type&&a.dataTransfer.files.length)for(var b=0;ba.endDate)&&(i=!0):(ea.endIndex)&&(i=!0)),d.dateFormat&&"dateObject"!=d.dateFormat&&m instanceof Date&&(m=AmCharts.formatDate(m,d.dateFormat))),h[l]=m}i||g.push(h)}d.data=g}return void 0!==d.processData?d.processData(d.data):d.data},capitalize:function(a){return a.charAt(0).toUpperCase()+a.slice(1).toLowerCase()},createMenu:function(b,d){function f(b,d){var e,g,h=document.createElement("ul");for(e=0;e=a?(clearTimeout(e),"draw"!=d.action&&c.createMenu(c.config.menu)):i&&(i.innerHTML=c.i18l("capturing.delayed.menu.label").replace("{{duration}}",AmCharts.toFixed(a,2)))},10),f=setTimeout(function(){b.apply(c,arguments)},1e3*d.delay)},migrateSetup:function(a){function c(a){var d;for(d in a){var e=a[d];"export"==d.slice(0,6)&&e?b.menu.push(d.slice(6)):"userCFG"==d?c(e):"menuItems"==d?b.menu=e:"libs"==d?b.libs=e:"string"==typeof d&&(b[d]=e)}}var b={enabled:!0,migrated:!0,libs:{autoLoad:!0},menu:[]};return c(a),b},clear:function(){c.setup=void 0,c.docListener&&document.removeEventListener("keydown",c.docListener);var a=c.listenersToRemove;if(a)for(var b=0;b Bild speichern unter... um das Bild zu speichern.", + + "capturing.delayed.menu.label": "{{duration}}", + "capturing.delayed.menu.title": "Klicken zum Abbrechen.", + + "menu.label.print": "Drucken", + "menu.label.undo": "Rückgängig", + "menu.label.redo": "Wiederherstellen", + "menu.label.cancel": "Abbrechen", + + "menu.label.save.image": "Herunterladen als ...", + "menu.label.save.data": "Speichern als ...", + + "menu.label.draw": "Notieren ...", + "menu.label.draw.change": "Ändern ...", + "menu.label.draw.add": "Hinzufügen ...", + "menu.label.draw.shapes": "Form ...", + "menu.label.draw.colors": "Farbe ...", + "menu.label.draw.widths": "Größe ...", + "menu.label.draw.opacities": "Deckkraft ...", + "menu.label.draw.text": "Text", + + "menu.label.draw.modes": "Modus...", + "menu.label.draw.modes.pencil": "Stift", + "menu.label.draw.modes.line": "Linie", + "menu.label.draw.modes.arrow": "Pfeil" +} \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/export/lang/en.js b/iguana/js/amcharts/plugins/export/lang/en.js new file mode 100755 index 000000000..7e8d381a3 --- /dev/null +++ b/iguana/js/amcharts/plugins/export/lang/en.js @@ -0,0 +1,29 @@ +AmCharts.translations[ "export" ][ "en" ] = { + "fallback.save.text": "CTRL + C to copy the data into the clipboard.", + "fallback.save.image": "Rightclick -> Save picture as... to save the image.", + + "capturing.delayed.menu.label": "{{duration}}", + "capturing.delayed.menu.title": "Click to cancel", + + "menu.label.print": "Print", + "menu.label.undo": "Undo", + "menu.label.redo": "Redo", + "menu.label.cancel": "Cancel", + + "menu.label.save.image": "Download as ...", + "menu.label.save.data": "Save as ...", + + "menu.label.draw": "Annotate ...", + "menu.label.draw.change": "Change ...", + "menu.label.draw.add": "Add ...", + "menu.label.draw.shapes": "Shape ...", + "menu.label.draw.colors": "Color ...", + "menu.label.draw.widths": "Size ...", + "menu.label.draw.opacities": "Opacity ...", + "menu.label.draw.text": "Text", + + "menu.label.draw.modes": "Mode ...", + "menu.label.draw.modes.pencil": "Pencil", + "menu.label.draw.modes.line": "Line", + "menu.label.draw.modes.arrow": "Arrow" +} \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/export/lang/fr.js b/iguana/js/amcharts/plugins/export/lang/fr.js new file mode 100755 index 000000000..349db1268 --- /dev/null +++ b/iguana/js/amcharts/plugins/export/lang/fr.js @@ -0,0 +1,29 @@ +AmCharts.translations[ "export" ][ "fr" ] = { + "fallback.save.text": "CTRL + C pour copier dans le presse-papier.", + "fallback.save.image": "Clic-droit -> Enregistrer sous... pour sauvegarder l'image.", + + "capturing.delayed.menu.label": "{{duration}}", + "capturing.delayed.menu.title": "Cliquez pour annuler", + + "menu.label.print": "Imprimer", + "menu.label.undo": "Retour", + "menu.label.redo": "Refaire", + "menu.label.cancel": "Annuler", + + "menu.label.save.image": "Téléchargez en ...", + "menu.label.save.data": "Sauvegarder en ...", + + "menu.label.draw": "Annoter ...", + "menu.label.draw.change": "Changer le ...", + "menu.label.draw.add": "Ajouter ...", + "menu.label.draw.shapes": "Formes ...", + "menu.label.draw.colors": "Couleurs ...", + "menu.label.draw.widths": "Taille ...", + "menu.label.draw.opacities": "Opacité ...", + "menu.label.draw.text": "Texte", + + "menu.label.draw.modes": "Mode ...", + "menu.label.draw.modes.pencil": "Crayon", + "menu.label.draw.modes.line": "Ligne", + "menu.label.draw.modes.arrow": "Flèche" +} diff --git a/iguana/js/amcharts/plugins/export/lang/ko.js b/iguana/js/amcharts/plugins/export/lang/ko.js new file mode 100755 index 000000000..7b0d6364a --- /dev/null +++ b/iguana/js/amcharts/plugins/export/lang/ko.js @@ -0,0 +1,29 @@ +AmCharts.translations[ "export" ][ "ko" ] = { + "fallback.save.text": "CTRL + C 를 눌러 클립보드로 데이터를 복사합니다.", + "fallback.save.image": "마우스 오른쪽 클릭 -> 다른 이름으로 저장... 으로 이미지를 저장합니다.", + + "capturing.delayed.menu.label": "{{duration}}", + "capturing.delayed.menu.title": "취소하려면 클릭", + + "menu.label.print": "출력", + "menu.label.undo": "실행 취소", + "menu.label.redo": "다시 실행", + "menu.label.cancel": "취소", + + "menu.label.save.image": "다운로드 ...", + "menu.label.save.data": "데이터로 저장 ...", + + "menu.label.draw": "그리기", + "menu.label.draw.change": "바꾸기 ...", + "menu.label.draw.add": "삽입하기 ...", + "menu.label.draw.shapes": "모양 ...", + "menu.label.draw.colors": "색 변경 ...", + "menu.label.draw.widths": "크기 변경 ...", + "menu.label.draw.opacities": "투명도 변경 ...", + "menu.label.draw.text": "텍스트", + + "menu.label.draw.modes": "모드 변경 ...", + "menu.label.draw.modes.pencil": "펜", + "menu.label.draw.modes.line": "선", + "menu.label.draw.modes.arrow": "화살표" +} \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/export/lang/lt.js b/iguana/js/amcharts/plugins/export/lang/lt.js new file mode 100755 index 000000000..d6b2d0064 --- /dev/null +++ b/iguana/js/amcharts/plugins/export/lang/lt.js @@ -0,0 +1,29 @@ +AmCharts.translations[ "export" ][ "lt" ] = { + "fallback.save.text": "Spauskite CTRL + C jei norite nukopijuoti paveiksliuką.", + "fallback.save.image": "Spragtelkite dešinį klavišą ir pasirinkite \"Save picture as...\" jei norite išsaugoti paveiksliuką.", + + "capturing.delayed.menu.label": "{{duration}}", + "capturing.delayed.menu.title": "Nutraukti", + + "menu.label.print": "Spausdinti", + "menu.label.undo": "Atšaukti", + "menu.label.redo": "Pakartoti", + "menu.label.cancel": "Nutraukti", + + "menu.label.save.image": "Atsisiųsti ...", + "menu.label.save.data": "Išsaugoti ...", + + "menu.label.draw": "Anotuoti ...", + "menu.label.draw.change": "Keisti ...", + "menu.label.draw.add": "Pridėti ...", + "menu.label.draw.shapes": "Ikonėlę ...", + "menu.label.draw.colors": "Spalvą ...", + "menu.label.draw.widths": "Teptuką ...", + "menu.label.draw.opacities": "Nepermatomumas ...", + "menu.label.draw.text": "Tekstą", + + "menu.label.draw.modes": "Režimas ...", + "menu.label.draw.modes.pencil": "Tekstą", + "menu.label.draw.modes.line": "Linija", + "menu.label.draw.modes.arrow": "Rodyklė" +} \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/export/lang/pl.js b/iguana/js/amcharts/plugins/export/lang/pl.js new file mode 100755 index 000000000..1475249fc --- /dev/null +++ b/iguana/js/amcharts/plugins/export/lang/pl.js @@ -0,0 +1,29 @@ +AmCharts.translations[ "export" ][ "pl" ] = { + "fallback.save.text": "Naciśnij CTRL + C by skopiować dane do schowka.", + "fallback.save.image": "Prawy przycisk myszy -> Zapisz obrazek jako... by zapisać obrazek.", + + "capturing.delayed.menu.label": "{{duration}}", + "capturing.delayed.menu.title": "Kliknij by anulować", + + "menu.label.print": "Drukuj", + "menu.label.undo": "Cofnij", + "menu.label.redo": "Przywróć", + "menu.label.cancel": "Anuluj", + + "menu.label.save.image": "Pobierz jako ...", + "menu.label.save.data": "Zapisz jako ...", + + "menu.label.draw": "Rysuj ...", + "menu.label.draw.change": "Zmień ...", + "menu.label.draw.add": "Dodaj ...", + "menu.label.draw.shapes": "Kształt ...", + "menu.label.draw.colors": "Kolor ...", + "menu.label.draw.widths": "Rozmiar ...", + "menu.label.draw.opacities": "Przeźroczystość ...", + "menu.label.draw.text": "Tekst", + + "menu.label.draw.modes": "Tryb ...", + "menu.label.draw.modes.pencil": "Ołówek", + "menu.label.draw.modes.line": "Linia", + "menu.label.draw.modes.arrow": "Strzałka" +} \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/export/lang/pt.js b/iguana/js/amcharts/plugins/export/lang/pt.js new file mode 100755 index 000000000..eac4676b3 --- /dev/null +++ b/iguana/js/amcharts/plugins/export/lang/pt.js @@ -0,0 +1,35 @@ +/* + ** Versão em Português + ** Traduzido por Élton Reisdorfer + ** WebSite: http://eltonrst.tk + ** Facebook : http://facebook.com/elton.reisdorfer + */ +AmCharts.translations["export"]["pt"] = { + "fallback.save.text": "CTRL + C para copiar os dados para a área de transferência.", + "fallback.save.image": "Clique Direito -> Salvar imagem como... para salvar a imagem.", + + "capturing.delayed.menu.label": "{{duration}}", + "capturing.delayed.menu.title": "Clique para cancelar", + + "menu.label.print": "Imprimir", + "menu.label.undo": "Desfazer", + "menu.label.redo": "Refazer", + "menu.label.cancel": "Cancelar", + + "menu.label.save.image": "Baixar Como", + "menu.label.save.data": "Salvar Como", + + "menu.label.draw": "Editar", + "menu.label.draw.change": "Alterar", + "menu.label.draw.add": "Adicionar", + "menu.label.draw.shapes": "Forma", + "menu.label.draw.colors": "Cor", + "menu.label.draw.widths": "Tamanho", + "menu.label.draw.opacities": "Tranparência", + "menu.label.draw.text": "Texto", + + "menu.label.draw.modes": "Ferramenta", + "menu.label.draw.modes.pencil": "Pincel", + "menu.label.draw.modes.line": "Linha", + "menu.label.draw.modes.arrow": "Seta" +} diff --git a/iguana/js/amcharts/plugins/export/libs/FileSaver.js/FileSaver.js b/iguana/js/amcharts/plugins/export/libs/FileSaver.js/FileSaver.js new file mode 100755 index 000000000..11081a897 --- /dev/null +++ b/iguana/js/amcharts/plugins/export/libs/FileSaver.js/FileSaver.js @@ -0,0 +1,253 @@ +/* FileSaver.js + * A saveAs() FileSaver implementation. + * 2015-05-07.2 + * + * By Eli Grey, http://eligrey.com + * License: X11/MIT + * See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md + */ + +/*global self */ +/*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */ + +/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */ + +var saveAs = saveAs || (function(view) { + "use strict"; + // IE <10 is explicitly unsupported + if (typeof navigator !== "undefined" && /MSIE [1-9]\./.test(navigator.userAgent)) { + return; + } + var + doc = view.document + // only get URL when necessary in case Blob.js hasn't overridden it yet + , get_URL = function() { + return view.URL || view.webkitURL || view; + } + , save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a") + , can_use_save_link = "download" in save_link + , click = function(node) { + var event = doc.createEvent("MouseEvents"); + event.initMouseEvent( + "click", true, false, view, 0, 0, 0, 0, 0 + , false, false, false, false, 0, null + ); + node.dispatchEvent(event); + } + , webkit_req_fs = view.webkitRequestFileSystem + , req_fs = view.requestFileSystem || webkit_req_fs || view.mozRequestFileSystem + , throw_outside = function(ex) { + (view.setImmediate || view.setTimeout)(function() { + throw ex; + }, 0); + } + , force_saveable_type = "application/octet-stream" + , fs_min_size = 0 + // See https://code.google.com/p/chromium/issues/detail?id=375297#c7 and + // https://github.com/eligrey/FileSaver.js/commit/485930a#commitcomment-8768047 + // for the reasoning behind the timeout and revocation flow + , arbitrary_revoke_timeout = 500 // in ms + , revoke = function(file) { + var revoker = function() { + if (typeof file === "string") { // file is an object URL + get_URL().revokeObjectURL(file); + } else { // file is a File + file.remove(); + } + }; + if (view.chrome) { + revoker(); + } else { + setTimeout(revoker, arbitrary_revoke_timeout); + } + } + , dispatch = function(filesaver, event_types, event) { + event_types = [].concat(event_types); + var i = event_types.length; + while (i--) { + var listener = filesaver["on" + event_types[i]]; + if (typeof listener === "function") { + try { + listener.call(filesaver, event || filesaver); + } catch (ex) { + throw_outside(ex); + } + } + } + } + , auto_bom = function(blob) { + // prepend BOM for UTF-8 XML and text/* types (including HTML) + if (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) { + return new Blob(["\ufeff", blob], {type: blob.type}); + } + return blob; + } + , FileSaver = function(blob, name) { + blob = auto_bom(blob); + // First try a.download, then web filesystem, then object URLs + var + filesaver = this + , type = blob.type + , blob_changed = false + , object_url + , target_view + , dispatch_all = function() { + dispatch(filesaver, "writestart progress write writeend".split(" ")); + } + // on any filesys errors revert to saving with object URLs + , fs_error = function() { + // don't create more object URLs than needed + if (blob_changed || !object_url) { + object_url = get_URL().createObjectURL(blob); + } + if (target_view) { + target_view.location.href = object_url; + } else { + var new_tab = view.open(object_url, "_blank"); + if (new_tab == undefined && typeof safari !== "undefined") { + //Apple do not allow window.open, see http://bit.ly/1kZffRI + view.location.href = object_url + } + } + filesaver.readyState = filesaver.DONE; + dispatch_all(); + revoke(object_url); + } + , abortable = function(func) { + return function() { + if (filesaver.readyState !== filesaver.DONE) { + return func.apply(this, arguments); + } + }; + } + , create_if_not_found = {create: true, exclusive: false} + , slice + ; + filesaver.readyState = filesaver.INIT; + if (!name) { + name = "download"; + } + if (can_use_save_link) { + object_url = get_URL().createObjectURL(blob); + save_link.href = object_url; + save_link.download = name; + click(save_link); + filesaver.readyState = filesaver.DONE; + dispatch_all(); + revoke(object_url); + return; + } + // Object and web filesystem URLs have a problem saving in Google Chrome when + // viewed in a tab, so I force save with application/octet-stream + // http://code.google.com/p/chromium/issues/detail?id=91158 + // Update: Google errantly closed 91158, I submitted it again: + // https://code.google.com/p/chromium/issues/detail?id=389642 + if (view.chrome && type && type !== force_saveable_type) { + slice = blob.slice || blob.webkitSlice; + blob = slice.call(blob, 0, blob.size, force_saveable_type); + blob_changed = true; + } + // Since I can't be sure that the guessed media type will trigger a download + // in WebKit, I append .download to the filename. + // https://bugs.webkit.org/show_bug.cgi?id=65440 + if (webkit_req_fs && name !== "download") { + name += ".download"; + } + if (type === force_saveable_type || webkit_req_fs) { + target_view = view; + } + if (!req_fs) { + fs_error(); + return; + } + fs_min_size += blob.size; + req_fs(view.TEMPORARY, fs_min_size, abortable(function(fs) { + fs.root.getDirectory("saved", create_if_not_found, abortable(function(dir) { + var save = function() { + dir.getFile(name, create_if_not_found, abortable(function(file) { + file.createWriter(abortable(function(writer) { + writer.onwriteend = function(event) { + target_view.location.href = file.toURL(); + filesaver.readyState = filesaver.DONE; + dispatch(filesaver, "writeend", event); + revoke(file); + }; + writer.onerror = function() { + var error = writer.error; + if (error.code !== error.ABORT_ERR) { + fs_error(); + } + }; + "writestart progress write abort".split(" ").forEach(function(event) { + writer["on" + event] = filesaver["on" + event]; + }); + writer.write(blob); + filesaver.abort = function() { + writer.abort(); + filesaver.readyState = filesaver.DONE; + }; + filesaver.readyState = filesaver.WRITING; + }), fs_error); + }), fs_error); + }; + dir.getFile(name, {create: false}, abortable(function(file) { + // delete file if it already exists + file.remove(); + save(); + }), abortable(function(ex) { + if (ex.code === ex.NOT_FOUND_ERR) { + save(); + } else { + fs_error(); + } + })); + }), fs_error); + }), fs_error); + } + , FS_proto = FileSaver.prototype + , saveAs = function(blob, name) { + return new FileSaver(blob, name); + } + ; + // IE 10+ (native saveAs) + if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob) { + return function(blob, name) { + return navigator.msSaveOrOpenBlob(auto_bom(blob), name); + }; + } + + FS_proto.abort = function() { + var filesaver = this; + filesaver.readyState = filesaver.DONE; + dispatch(filesaver, "abort"); + }; + FS_proto.readyState = FS_proto.INIT = 0; + FS_proto.WRITING = 1; + FS_proto.DONE = 2; + + FS_proto.error = + FS_proto.onwritestart = + FS_proto.onprogress = + FS_proto.onwrite = + FS_proto.onabort = + FS_proto.onerror = + FS_proto.onwriteend = + null; + + return saveAs; +}( + typeof self !== "undefined" && self + || typeof window !== "undefined" && window + || this.content +)); +// `self` is undefined in Firefox for Android content script context +// while `this` is nsIContentFrameMessageManager +// with an attribute `content` that corresponds to the window + +if (typeof module !== "undefined" && module.exports) { + module.exports.saveAs = saveAs; +} else if ((typeof define !== "undefined" && define !== null) && (define.amd != null)) { + define([], function() { + return saveAs; + }); +} \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/export/libs/FileSaver.js/FileSaver.min.js b/iguana/js/amcharts/plugins/export/libs/FileSaver.js/FileSaver.min.js new file mode 100755 index 000000000..c0792332a --- /dev/null +++ b/iguana/js/amcharts/plugins/export/libs/FileSaver.js/FileSaver.min.js @@ -0,0 +1,2 @@ +/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */ +var saveAs=saveAs||function(e){"use strict";if("undefined"==typeof navigator||!/MSIE [1-9]\./.test(navigator.userAgent)){var t=e.document,n=function(){return e.URL||e.webkitURL||e},o=t.createElementNS("http://www.w3.org/1999/xhtml","a"),r="download"in o,i=function(n){var o=t.createEvent("MouseEvents");o.initMouseEvent("click",!0,!1,e,0,0,0,0,0,!1,!1,!1,!1,0,null),n.dispatchEvent(o)},a=e.webkitRequestFileSystem,c=e.requestFileSystem||a||e.mozRequestFileSystem,u=function(t){(e.setImmediate||e.setTimeout)(function(){throw t},0)},f="application/octet-stream",s=0,d=500,l=function(t){var o=function(){"string"==typeof t?n().revokeObjectURL(t):t.remove()};e.chrome?o():setTimeout(o,d)},v=function(e,t,n){t=[].concat(t);for(var o=t.length;o--;){var r=e["on"+t[o]];if("function"==typeof r)try{r.call(e,n||e)}catch(i){u(i)}}},p=function(e){return/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(e.type)?new Blob(["\ufeff",e],{type:e.type}):e},w=function(t,u){t=p(t);var d,w,y,m=this,S=t.type,h=!1,O=function(){v(m,"writestart progress write writeend".split(" "))},E=function(){if((h||!d)&&(d=n().createObjectURL(t)),w)w.location.href=d;else{var o=e.open(d,"_blank");void 0==o&&"undefined"!=typeof safari&&(e.location.href=d)}m.readyState=m.DONE,O(),l(d)},R=function(e){return function(){return m.readyState!==m.DONE?e.apply(this,arguments):void 0}},b={create:!0,exclusive:!1};return m.readyState=m.INIT,u||(u="download"),r?(d=n().createObjectURL(t),o.href=d,o.download=u,i(o),m.readyState=m.DONE,O(),void l(d)):(e.chrome&&S&&S!==f&&(y=t.slice||t.webkitSlice,t=y.call(t,0,t.size,f),h=!0),a&&"download"!==u&&(u+=".download"),(S===f||a)&&(w=e),c?(s+=t.size,void c(e.TEMPORARY,s,R(function(e){e.root.getDirectory("saved",b,R(function(e){var n=function(){e.getFile(u,b,R(function(e){e.createWriter(R(function(n){n.onwriteend=function(t){w.location.href=e.toURL(),m.readyState=m.DONE,v(m,"writeend",t),l(e)},n.onerror=function(){var e=n.error;e.code!==e.ABORT_ERR&&E()},"writestart progress write abort".split(" ").forEach(function(e){n["on"+e]=m["on"+e]}),n.write(t),m.abort=function(){n.abort(),m.readyState=m.DONE},m.readyState=m.WRITING}),E)}),E)};e.getFile(u,{create:!1},R(function(e){e.remove(),n()}),R(function(e){e.code===e.NOT_FOUND_ERR?n():E()}))}),E)}),E)):void E())},y=w.prototype,m=function(e,t){return new w(e,t)};return"undefined"!=typeof navigator&&navigator.msSaveOrOpenBlob?function(e,t){return navigator.msSaveOrOpenBlob(p(e),t)}:(y.abort=function(){var e=this;e.readyState=e.DONE,v(e,"abort")},y.readyState=y.INIT=0,y.WRITING=1,y.DONE=2,y.error=y.onwritestart=y.onprogress=y.onwrite=y.onabort=y.onerror=y.onwriteend=null,m)}}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||this.content);"undefined"!=typeof module&&module.exports?module.exports.saveAs=saveAs:"undefined"!=typeof define&&null!==define&&null!=define.amd&&define([],function(){return saveAs}); \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/export/libs/blob.js/blob.js b/iguana/js/amcharts/plugins/export/libs/blob.js/blob.js new file mode 100755 index 000000000..b4dda85fe --- /dev/null +++ b/iguana/js/amcharts/plugins/export/libs/blob.js/blob.js @@ -0,0 +1,211 @@ +/* Blob.js + * A Blob implementation. + * 2014-07-24 + * + * By Eli Grey, http://eligrey.com + * By Devin Samarin, https://github.com/dsamarin + * License: X11/MIT + * See https://github.com/eligrey/Blob.js/blob/master/LICENSE.md + */ + +/*global self, unescape */ +/*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true, + plusplus: true */ + +/*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */ + +(function (view) { + "use strict"; + + view.URL = view.URL || view.webkitURL; + + if (view.Blob && view.URL) { + try { + new Blob; + return; + } catch (e) {} + } + + // Internally we use a BlobBuilder implementation to base Blob off of + // in order to support older browsers that only have BlobBuilder + var BlobBuilder = view.BlobBuilder || view.WebKitBlobBuilder || view.MozBlobBuilder || (function(view) { + var + get_class = function(object) { + return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1]; + } + , FakeBlobBuilder = function BlobBuilder() { + this.data = []; + } + , FakeBlob = function Blob(data, type, encoding) { + this.data = data; + this.size = data.length; + this.type = type; + this.encoding = encoding; + } + , FBB_proto = FakeBlobBuilder.prototype + , FB_proto = FakeBlob.prototype + , FileReaderSync = view.FileReaderSync + , FileException = function(type) { + this.code = this[this.name = type]; + } + , file_ex_codes = ( + "NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR " + + "NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR" + ).split(" ") + , file_ex_code = file_ex_codes.length + , real_URL = view.URL || view.webkitURL || view + , real_create_object_URL = real_URL.createObjectURL + , real_revoke_object_URL = real_URL.revokeObjectURL + , URL = real_URL + , btoa = view.btoa + , atob = view.atob + + , ArrayBuffer = view.ArrayBuffer + , Uint8Array = view.Uint8Array + + , origin = /^[\w-]+:\/*\[?[\w\.:-]+\]?(?::[0-9]+)?/ + ; + FakeBlob.fake = FB_proto.fake = true; + while (file_ex_code--) { + FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1; + } + // Polyfill URL + if (!real_URL.createObjectURL) { + URL = view.URL = function(uri) { + var + uri_info = document.createElementNS("http://www.w3.org/1999/xhtml", "a") + , uri_origin + ; + uri_info.href = uri; + if (!("origin" in uri_info)) { + if (uri_info.protocol.toLowerCase() === "data:") { + uri_info.origin = null; + } else { + uri_origin = uri.match(origin); + uri_info.origin = uri_origin && uri_origin[1]; + } + } + return uri_info; + }; + } + URL.createObjectURL = function(blob) { + var + type = blob.type + , data_URI_header + ; + if (type === null) { + type = "application/octet-stream"; + } + if (blob instanceof FakeBlob) { + data_URI_header = "data:" + type; + if (blob.encoding === "base64") { + return data_URI_header + ";base64," + blob.data; + } else if (blob.encoding === "URI") { + return data_URI_header + "," + decodeURIComponent(blob.data); + } if (btoa) { + return data_URI_header + ";base64," + btoa(blob.data); + } else { + return data_URI_header + "," + encodeURIComponent(blob.data); + } + } else if (real_create_object_URL) { + return real_create_object_URL.call(real_URL, blob); + } + }; + URL.revokeObjectURL = function(object_URL) { + if (object_URL.substring(0, 5) !== "data:" && real_revoke_object_URL) { + real_revoke_object_URL.call(real_URL, object_URL); + } + }; + FBB_proto.append = function(data/*, endings*/) { + var bb = this.data; + // decode data to a binary string + if (Uint8Array && (data instanceof ArrayBuffer || data instanceof Uint8Array)) { + var + str = "" + , buf = new Uint8Array(data) + , i = 0 + , buf_len = buf.length + ; + for (; i < buf_len; i++) { + str += String.fromCharCode(buf[i]); + } + bb.push(str); + } else if (get_class(data) === "Blob" || get_class(data) === "File") { + if (FileReaderSync) { + var fr = new FileReaderSync; + bb.push(fr.readAsBinaryString(data)); + } else { + // async FileReader won't work as BlobBuilder is sync + throw new FileException("NOT_READABLE_ERR"); + } + } else if (data instanceof FakeBlob) { + if (data.encoding === "base64" && atob) { + bb.push(atob(data.data)); + } else if (data.encoding === "URI") { + bb.push(decodeURIComponent(data.data)); + } else if (data.encoding === "raw") { + bb.push(data.data); + } + } else { + if (typeof data !== "string") { + data += ""; // convert unsupported types to strings + } + // decode UTF-16 to binary string + bb.push(unescape(encodeURIComponent(data))); + } + }; + FBB_proto.getBlob = function(type) { + if (!arguments.length) { + type = null; + } + return new FakeBlob(this.data.join(""), type, "raw"); + }; + FBB_proto.toString = function() { + return "[object BlobBuilder]"; + }; + FB_proto.slice = function(start, end, type) { + var args = arguments.length; + if (args < 3) { + type = null; + } + return new FakeBlob( + this.data.slice(start, args > 1 ? end : this.data.length) + , type + , this.encoding + ); + }; + FB_proto.toString = function() { + return "[object Blob]"; + }; + FB_proto.close = function() { + this.size = 0; + delete this.data; + }; + return FakeBlobBuilder; + }(view)); + + view.Blob = function(blobParts, options) { + var type = options ? (options.type || "") : ""; + var builder = new BlobBuilder(); + if (blobParts) { + for (var i = 0, len = blobParts.length; i < len; i++) { + if (Uint8Array && blobParts[i] instanceof Uint8Array) { + builder.append(blobParts[i].buffer); + } + else { + builder.append(blobParts[i]); + } + } + } + var blob = builder.getBlob(type); + if (!blob.slice && blob.webkitSlice) { + blob.slice = blob.webkitSlice; + } + return blob; + }; + + var getPrototypeOf = Object.getPrototypeOf || function(object) { + return object.__proto__; + }; + view.Blob.prototype = getPrototypeOf(new view.Blob()); +}(typeof self !== "undefined" && self || typeof window !== "undefined" && window || this.content || this)); \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/export/libs/fabric.js/fabric.js b/iguana/js/amcharts/plugins/export/libs/fabric.js/fabric.js new file mode 100755 index 000000000..b2dcba5f6 --- /dev/null +++ b/iguana/js/amcharts/plugins/export/libs/fabric.js/fabric.js @@ -0,0 +1,23452 @@ +/* build: `node build.js modules=ALL exclude=json,gestures minifier=uglifyjs` */ +/*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */ + +var fabric = fabric || { version: "1.5.0" }; +if (typeof exports !== 'undefined') { + exports.fabric = fabric; +} + +if (typeof document !== 'undefined' && typeof window !== 'undefined') { + fabric.document = document; + fabric.window = window; + // ensure globality even if entire library were function wrapped (as in Meteor.js packaging system) + window.fabric = fabric; +} +else { + // assume we're running under node.js when document/window are not present + fabric.document = require("jsdom") + .jsdom(""); + + if (fabric.document.createWindow) { + fabric.window = fabric.document.createWindow(); + } else { + fabric.window = fabric.document.parentWindow; + } +} + +/** + * True when in environment that supports touch events + * @type boolean + */ +fabric.isTouchSupported = "ontouchstart" in fabric.document.documentElement; + +/** + * True when in environment that's probably Node.js + * @type boolean + */ +fabric.isLikelyNode = typeof Buffer !== 'undefined' && + typeof window === 'undefined'; + +/* _FROM_SVG_START_ */ +/** + * Attributes parsed from all SVG elements + * @type array + */ +fabric.SHARED_ATTRIBUTES = [ + "display", + "transform", + "fill", "fill-opacity", "fill-rule", + "opacity", + "stroke", "stroke-dasharray", "stroke-linecap", + "stroke-linejoin", "stroke-miterlimit", + "stroke-opacity", "stroke-width" +]; +/* _FROM_SVG_END_ */ + +/** + * Pixel per Inch as a default value set to 96. Can be changed for more realistic conversion. + */ +fabric.DPI = 96; +fabric.reNum = '(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:e[-+]?\\d+)?)'; + + +(function() { + + /** + * @private + * @param {String} eventName + * @param {Function} handler + */ + function _removeEventListener(eventName, handler) { + if (!this.__eventListeners[eventName]) { + return; + } + + if (handler) { + fabric.util.removeFromArray(this.__eventListeners[eventName], handler); + } + else { + this.__eventListeners[eventName].length = 0; + } + } + + /** + * Observes specified event + * @deprecated `observe` deprecated since 0.8.34 (use `on` instead) + * @memberOf fabric.Observable + * @alias on + * @param {String|Object} eventName Event name (eg. 'after:render') or object with key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler}) + * @param {Function} handler Function that receives a notification when an event of the specified type occurs + * @return {Self} thisArg + * @chainable + */ + function observe(eventName, handler) { + if (!this.__eventListeners) { + this.__eventListeners = { }; + } + // one object with key/value pairs was passed + if (arguments.length === 1) { + for (var prop in eventName) { + this.on(prop, eventName[prop]); + } + } + else { + if (!this.__eventListeners[eventName]) { + this.__eventListeners[eventName] = [ ]; + } + this.__eventListeners[eventName].push(handler); + } + return this; + } + + /** + * Stops event observing for a particular event handler. Calling this method + * without arguments removes all handlers for all events + * @deprecated `stopObserving` deprecated since 0.8.34 (use `off` instead) + * @memberOf fabric.Observable + * @alias off + * @param {String|Object} eventName Event name (eg. 'after:render') or object with key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler}) + * @param {Function} handler Function to be deleted from EventListeners + * @return {Self} thisArg + * @chainable + */ + function stopObserving(eventName, handler) { + if (!this.__eventListeners) { + return; + } + + // remove all key/value pairs (event name -> event handler) + if (arguments.length === 0) { + this.__eventListeners = { }; + } + // one object with key/value pairs was passed + else if (arguments.length === 1 && typeof arguments[0] === 'object') { + for (var prop in eventName) { + _removeEventListener.call(this, prop, eventName[prop]); + } + } + else { + _removeEventListener.call(this, eventName, handler); + } + return this; + } + + /** + * Fires event with an optional options object + * @deprecated `fire` deprecated since 1.0.7 (use `trigger` instead) + * @memberOf fabric.Observable + * @alias trigger + * @param {String} eventName Event name to fire + * @param {Object} [options] Options object + * @return {Self} thisArg + * @chainable + */ + function fire(eventName, options) { + if (!this.__eventListeners) { + return; + } + + var listenersForEvent = this.__eventListeners[eventName]; + if (!listenersForEvent) { + return; + } + + for (var i = 0, len = listenersForEvent.length; i < len; i++) { + // avoiding try/catch for perf. reasons + listenersForEvent[i].call(this, options || { }); + } + return this; + } + + /** + * @namespace fabric.Observable + * @tutorial {@link http://fabricjs.com/fabric-intro-part-2/#events} + * @see {@link http://fabricjs.com/events/|Events demo} + */ + fabric.Observable = { + observe: observe, + stopObserving: stopObserving, + fire: fire, + + on: observe, + off: stopObserving, + trigger: fire + }; +})(); + + +/** + * @namespace fabric.Collection + */ +fabric.Collection = { + + /** + * Adds objects to collection, then renders canvas (if `renderOnAddRemove` is not `false`) + * Objects should be instances of (or inherit from) fabric.Object + * @param {...fabric.Object} object Zero or more fabric instances + * @return {Self} thisArg + */ + add: function () { + this._objects.push.apply(this._objects, arguments); + for (var i = 0, length = arguments.length; i < length; i++) { + this._onObjectAdded(arguments[i]); + } + this.renderOnAddRemove && this.renderAll(); + return this; + }, + + /** + * Inserts an object into collection at specified index, then renders canvas (if `renderOnAddRemove` is not `false`) + * An object should be an instance of (or inherit from) fabric.Object + * @param {Object} object Object to insert + * @param {Number} index Index to insert object at + * @param {Boolean} nonSplicing When `true`, no splicing (shifting) of objects occurs + * @return {Self} thisArg + * @chainable + */ + insertAt: function (object, index, nonSplicing) { + var objects = this.getObjects(); + if (nonSplicing) { + objects[index] = object; + } + else { + objects.splice(index, 0, object); + } + this._onObjectAdded(object); + this.renderOnAddRemove && this.renderAll(); + return this; + }, + + /** + * Removes objects from a collection, then renders canvas (if `renderOnAddRemove` is not `false`) + * @param {...fabric.Object} object Zero or more fabric instances + * @return {Self} thisArg + * @chainable + */ + remove: function() { + var objects = this.getObjects(), + index; + + for (var i = 0, length = arguments.length; i < length; i++) { + index = objects.indexOf(arguments[i]); + + // only call onObjectRemoved if an object was actually removed + if (index !== -1) { + objects.splice(index, 1); + this._onObjectRemoved(arguments[i]); + } + } + + this.renderOnAddRemove && this.renderAll(); + return this; + }, + + /** + * Executes given function for each object in this group + * @param {Function} callback + * Callback invoked with current object as first argument, + * index - as second and an array of all objects - as third. + * Iteration happens in reverse order (for performance reasons). + * Callback is invoked in a context of Global Object (e.g. `window`) + * when no `context` argument is given + * + * @param {Object} context Context (aka thisObject) + * @return {Self} thisArg + */ + forEachObject: function(callback, context) { + var objects = this.getObjects(), + i = objects.length; + while (i--) { + callback.call(context, objects[i], i, objects); + } + return this; + }, + + /** + * Returns an array of children objects of this instance + * Type parameter introduced in 1.3.10 + * @param {String} [type] When specified, only objects of this type are returned + * @return {Array} + */ + getObjects: function(type) { + if (typeof type === 'undefined') { + return this._objects; + } + return this._objects.filter(function(o) { + return o.type === type; + }); + }, + + /** + * Returns object at specified index + * @param {Number} index + * @return {Self} thisArg + */ + item: function (index) { + return this.getObjects()[index]; + }, + + /** + * Returns true if collection contains no objects + * @return {Boolean} true if collection is empty + */ + isEmpty: function () { + return this.getObjects().length === 0; + }, + + /** + * Returns a size of a collection (i.e: length of an array containing its objects) + * @return {Number} Collection size + */ + size: function() { + return this.getObjects().length; + }, + + /** + * Returns true if collection contains an object + * @param {Object} object Object to check against + * @return {Boolean} `true` if collection contains an object + */ + contains: function(object) { + return this.getObjects().indexOf(object) > -1; + }, + + /** + * Returns number representation of a collection complexity + * @return {Number} complexity + */ + complexity: function () { + return this.getObjects().reduce(function (memo, current) { + memo += current.complexity ? current.complexity() : 0; + return memo; + }, 0); + } +}; + + +(function(global) { + + var sqrt = Math.sqrt, + atan2 = Math.atan2, + PiBy180 = Math.PI / 180; + + /** + * @namespace fabric.util + */ + fabric.util = { + + /** + * Removes value from an array. + * Presence of value (and its position in an array) is determined via `Array.prototype.indexOf` + * @static + * @memberOf fabric.util + * @param {Array} array + * @param {Any} value + * @return {Array} original array + */ + removeFromArray: function(array, value) { + var idx = array.indexOf(value); + if (idx !== -1) { + array.splice(idx, 1); + } + return array; + }, + + /** + * Returns random number between 2 specified ones. + * @static + * @memberOf fabric.util + * @param {Number} min lower limit + * @param {Number} max upper limit + * @return {Number} random value (between min and max) + */ + getRandomInt: function(min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; + }, + + /** + * Transforms degrees to radians. + * @static + * @memberOf fabric.util + * @param {Number} degrees value in degrees + * @return {Number} value in radians + */ + degreesToRadians: function(degrees) { + return degrees * PiBy180; + }, + + /** + * Transforms radians to degrees. + * @static + * @memberOf fabric.util + * @param {Number} radians value in radians + * @return {Number} value in degrees + */ + radiansToDegrees: function(radians) { + return radians / PiBy180; + }, + + /** + * Rotates `point` around `origin` with `radians` + * @static + * @memberOf fabric.util + * @param {fabric.Point} point The point to rotate + * @param {fabric.Point} origin The origin of the rotation + * @param {Number} radians The radians of the angle for the rotation + * @return {fabric.Point} The new rotated point + */ + rotatePoint: function(point, origin, radians) { + var sin = Math.sin(radians), + cos = Math.cos(radians); + + point.subtractEquals(origin); + + var rx = point.x * cos - point.y * sin, + ry = point.x * sin + point.y * cos; + + return new fabric.Point(rx, ry).addEquals(origin); + }, + + /** + * Apply transform t to point p + * @static + * @memberOf fabric.util + * @param {fabric.Point} p The point to transform + * @param {Array} t The transform + * @param {Boolean} [ignoreOffset] Indicates that the offset should not be applied + * @return {fabric.Point} The transformed point + */ + transformPoint: function(p, t, ignoreOffset) { + if (ignoreOffset) { + return new fabric.Point( + t[0] * p.x + t[2] * p.y, + t[1] * p.x + t[3] * p.y + ); + } + return new fabric.Point( + t[0] * p.x + t[2] * p.y + t[4], + t[1] * p.x + t[3] * p.y + t[5] + ); + }, + + /** + * Invert transformation t + * @static + * @memberOf fabric.util + * @param {Array} t The transform + * @return {Array} The inverted transform + */ + invertTransform: function(t) { + var r = t.slice(), + a = 1 / (t[0] * t[3] - t[1] * t[2]); + r = [a * t[3], -a * t[1], -a * t[2], a * t[0], 0, 0]; + var o = fabric.util.transformPoint({ x: t[4], y: t[5] }, r); + r[4] = -o.x; + r[5] = -o.y; + return r; + }, + + /** + * A wrapper around Number#toFixed, which contrary to native method returns number, not string. + * @static + * @memberOf fabric.util + * @param {Number|String} number number to operate on + * @param {Number} fractionDigits number of fraction digits to "leave" + * @return {Number} + */ + toFixed: function(number, fractionDigits) { + return parseFloat(Number(number).toFixed(fractionDigits)); + }, + + /** + * Converts from attribute value to pixel value if applicable. + * Returns converted pixels or original value not converted. + * @param {Number|String} value number to operate on + * @return {Number|String} + */ + parseUnit: function(value, fontSize) { + var unit = /\D{0,2}$/.exec(value), + number = parseFloat(value); + if (!fontSize) { + fontSize = fabric.Text.DEFAULT_SVG_FONT_SIZE; + } + switch (unit[0]) { + case 'mm': + return number * fabric.DPI / 25.4; + + case 'cm': + return number * fabric.DPI / 2.54; + + case 'in': + return number * fabric.DPI; + + case 'pt': + return number * fabric.DPI / 72; // or * 4 / 3 + + case 'pc': + return number * fabric.DPI / 72 * 12; // or * 16 + + case 'em': + return number * fontSize; + + default: + return number; + } + }, + + /** + * Function which always returns `false`. + * @static + * @memberOf fabric.util + * @return {Boolean} + */ + falseFunction: function() { + return false; + }, + + /** + * Returns klass "Class" object of given namespace + * @memberOf fabric.util + * @param {String} type Type of object (eg. 'circle') + * @param {String} namespace Namespace to get klass "Class" object from + * @return {Object} klass "Class" + */ + getKlass: function(type, namespace) { + // capitalize first letter only + type = fabric.util.string.camelize(type.charAt(0).toUpperCase() + type.slice(1)); + return fabric.util.resolveNamespace(namespace)[type]; + }, + + /** + * Returns object of given namespace + * @memberOf fabric.util + * @param {String} namespace Namespace string e.g. 'fabric.Image.filter' or 'fabric' + * @return {Object} Object for given namespace (default fabric) + */ + resolveNamespace: function(namespace) { + if (!namespace) { + return fabric; + } + + var parts = namespace.split('.'), + len = parts.length, + obj = global || fabric.window; + + for (var i = 0; i < len; ++i) { + obj = obj[parts[i]]; + } + + return obj; + }, + + /** + * Loads image element from given url and passes it to a callback + * @memberOf fabric.util + * @param {String} url URL representing an image + * @param {Function} callback Callback; invoked with loaded image + * @param {Any} [context] Context to invoke callback in + * @param {Object} [crossOrigin] crossOrigin value to set image element to + */ + loadImage: function(url, callback, context, crossOrigin) { + if (!url) { + callback && callback.call(context, url); + return; + } + + var img = fabric.util.createImage(); + + /** @ignore */ + img.onload = function () { + callback && callback.call(context, img); + img = img.onload = img.onerror = null; + }; + + /** @ignore */ + img.onerror = function() { + fabric.log('Error loading ' + img.src); + callback && callback.call(context, null, true); + img = img.onload = img.onerror = null; + }; + + // data-urls appear to be buggy with crossOrigin + // https://github.com/kangax/fabric.js/commit/d0abb90f1cd5c5ef9d2a94d3fb21a22330da3e0a#commitcomment-4513767 + // see https://code.google.com/p/chromium/issues/detail?id=315152 + // https://bugzilla.mozilla.org/show_bug.cgi?id=935069 + if (url.indexOf('data') !== 0 && typeof crossOrigin !== 'undefined') { + img.crossOrigin = crossOrigin; + } + + img.src = url; + }, + + /** + * Creates corresponding fabric instances from their object representations + * @static + * @memberOf fabric.util + * @param {Array} objects Objects to enliven + * @param {Function} callback Callback to invoke when all objects are created + * @param {String} namespace Namespace to get klass "Class" object from + * @param {Function} reviver Method for further parsing of object elements, + * called after each fabric object created. + */ + enlivenObjects: function(objects, callback, namespace, reviver) { + objects = objects || [ ]; + + function onLoaded() { + if (++numLoadedObjects === numTotalObjects) { + callback && callback(enlivenedObjects); + } + } + + var enlivenedObjects = [ ], + numLoadedObjects = 0, + numTotalObjects = objects.length; + + if (!numTotalObjects) { + callback && callback(enlivenedObjects); + return; + } + + objects.forEach(function (o, index) { + // if sparse array + if (!o || !o.type) { + onLoaded(); + return; + } + var klass = fabric.util.getKlass(o.type, namespace); + if (klass.async) { + klass.fromObject(o, function (obj, error) { + if (!error) { + enlivenedObjects[index] = obj; + reviver && reviver(o, enlivenedObjects[index]); + } + onLoaded(); + }); + } + else { + enlivenedObjects[index] = klass.fromObject(o); + reviver && reviver(o, enlivenedObjects[index]); + onLoaded(); + } + }); + }, + + /** + * Groups SVG elements (usually those retrieved from SVG document) + * @static + * @memberOf fabric.util + * @param {Array} elements SVG elements to group + * @param {Object} [options] Options object + * @return {fabric.Object|fabric.PathGroup} + */ + groupSVGElements: function(elements, options, path) { + var object; + + object = new fabric.PathGroup(elements, options); + + if (typeof path !== 'undefined') { + object.setSourcePath(path); + } + return object; + }, + + /** + * Populates an object with properties of another object + * @static + * @memberOf fabric.util + * @param {Object} source Source object + * @param {Object} destination Destination object + * @return {Array} properties Propertie names to include + */ + populateWithProperties: function(source, destination, properties) { + if (properties && Object.prototype.toString.call(properties) === '[object Array]') { + for (var i = 0, len = properties.length; i < len; i++) { + if (properties[i] in source) { + destination[properties[i]] = source[properties[i]]; + } + } + } + }, + + /** + * Draws a dashed line between two points + * + * This method is used to draw dashed line around selection area. + * See dotted stroke in canvas + * + * @param {CanvasRenderingContext2D} ctx context + * @param {Number} x start x coordinate + * @param {Number} y start y coordinate + * @param {Number} x2 end x coordinate + * @param {Number} y2 end y coordinate + * @param {Array} da dash array pattern + */ + drawDashedLine: function(ctx, x, y, x2, y2, da) { + var dx = x2 - x, + dy = y2 - y, + len = sqrt(dx * dx + dy * dy), + rot = atan2(dy, dx), + dc = da.length, + di = 0, + draw = true; + + ctx.save(); + ctx.translate(x, y); + ctx.moveTo(0, 0); + ctx.rotate(rot); + + x = 0; + while (len > x) { + x += da[di++ % dc]; + if (x > len) { + x = len; + } + ctx[draw ? 'lineTo' : 'moveTo'](x, 0); + draw = !draw; + } + + ctx.restore(); + }, + + /** + * Creates canvas element and initializes it via excanvas if necessary + * @static + * @memberOf fabric.util + * @param {CanvasElement} [canvasEl] optional canvas element to initialize; + * when not given, element is created implicitly + * @return {CanvasElement} initialized canvas element + */ + createCanvasElement: function(canvasEl) { + canvasEl || (canvasEl = fabric.document.createElement('canvas')); + //jscs:disable requireCamelCaseOrUpperCaseIdentifiers + if (!canvasEl.getContext && typeof G_vmlCanvasManager !== 'undefined') { + G_vmlCanvasManager.initElement(canvasEl); + } + //jscs:enable requireCamelCaseOrUpperCaseIdentifiers + return canvasEl; + }, + + /** + * Creates image element (works on client and node) + * @static + * @memberOf fabric.util + * @return {HTMLImageElement} HTML image element + */ + createImage: function() { + return fabric.isLikelyNode + ? new (require('canvas').Image)() + : fabric.document.createElement('img'); + }, + + /** + * Creates accessors (getXXX, setXXX) for a "class", based on "stateProperties" array + * @static + * @memberOf fabric.util + * @param {Object} klass "Class" to create accessors for + */ + createAccessors: function(klass) { + var proto = klass.prototype; + + for (var i = proto.stateProperties.length; i--; ) { + + var propName = proto.stateProperties[i], + capitalizedPropName = propName.charAt(0).toUpperCase() + propName.slice(1), + setterName = 'set' + capitalizedPropName, + getterName = 'get' + capitalizedPropName; + + // using `new Function` for better introspection + if (!proto[getterName]) { + proto[getterName] = (function(property) { + return new Function('return this.get("' + property + '")'); + })(propName); + } + if (!proto[setterName]) { + proto[setterName] = (function(property) { + return new Function('value', 'return this.set("' + property + '", value)'); + })(propName); + } + } + }, + + /** + * @static + * @memberOf fabric.util + * @param {fabric.Object} receiver Object implementing `clipTo` method + * @param {CanvasRenderingContext2D} ctx Context to clip + */ + clipContext: function(receiver, ctx) { + ctx.save(); + ctx.beginPath(); + receiver.clipTo(ctx); + ctx.clip(); + }, + + /** + * Multiply matrix A by matrix B to nest transformations + * @static + * @memberOf fabric.util + * @param {Array} a First transformMatrix + * @param {Array} b Second transformMatrix + * @return {Array} The product of the two transform matrices + */ + multiplyTransformMatrices: function(a, b) { + // Matrix multiply a * b + return [ + a[0] * b[0] + a[2] * b[1], + a[1] * b[0] + a[3] * b[1], + a[0] * b[2] + a[2] * b[3], + a[1] * b[2] + a[3] * b[3], + a[0] * b[4] + a[2] * b[5] + a[4], + a[1] * b[4] + a[3] * b[5] + a[5] + ]; + }, + + /** + * Returns string representation of function body + * @param {Function} fn Function to get body of + * @return {String} Function body + */ + getFunctionBody: function(fn) { + return (String(fn).match(/function[^{]*\{([\s\S]*)\}/) || {})[1]; + }, + + /** + * Returns true if context has transparent pixel + * at specified location (taking tolerance into account) + * @param {CanvasRenderingContext2D} ctx context + * @param {Number} x x coordinate + * @param {Number} y y coordinate + * @param {Number} tolerance Tolerance + */ + isTransparent: function(ctx, x, y, tolerance) { + + // If tolerance is > 0 adjust start coords to take into account. + // If moves off Canvas fix to 0 + if (tolerance > 0) { + if (x > tolerance) { + x -= tolerance; + } + else { + x = 0; + } + if (y > tolerance) { + y -= tolerance; + } + else { + y = 0; + } + } + + var _isTransparent = true, + imageData = ctx.getImageData(x, y, (tolerance * 2) || 1, (tolerance * 2) || 1); + + // Split image data - for tolerance > 1, pixelDataSize = 4; + for (var i = 3, l = imageData.data.length; i < l; i += 4) { + var temp = imageData.data[i]; + _isTransparent = temp <= 0; + if (_isTransparent === false) { + break; // Stop if colour found + } + } + + imageData = null; + + return _isTransparent; + } + }; + +})(typeof exports !== 'undefined' ? exports : this); + + +(function() { + + var arcToSegmentsCache = { }, + segmentToBezierCache = { }, + boundsOfCurveCache = { }, + _join = Array.prototype.join; + + /* Adapted from http://dxr.mozilla.org/mozilla-central/source/content/svg/content/src/nsSVGPathDataParser.cpp + * by Andrea Bogazzi code is under MPL. if you don't have a copy of the license you can take it here + * http://mozilla.org/MPL/2.0/ + */ + function arcToSegments(toX, toY, rx, ry, large, sweep, rotateX) { + var argsString = _join.call(arguments); + if (arcToSegmentsCache[argsString]) { + return arcToSegmentsCache[argsString]; + } + + var PI = Math.PI, th = rotateX * PI / 180, + sinTh = Math.sin(th), + cosTh = Math.cos(th), + fromX = 0, fromY = 0; + + rx = Math.abs(rx); + ry = Math.abs(ry); + + var px = -cosTh * toX * 0.5 - sinTh * toY * 0.5, + py = -cosTh * toY * 0.5 + sinTh * toX * 0.5, + rx2 = rx * rx, ry2 = ry * ry, py2 = py * py, px2 = px * px, + pl = rx2 * ry2 - rx2 * py2 - ry2 * px2, + root = 0; + + if (pl < 0) { + var s = Math.sqrt(1 - pl/(rx2 * ry2)); + rx *= s; + ry *= s; + } + else { + root = (large === sweep ? -1.0 : 1.0) * + Math.sqrt( pl /(rx2 * py2 + ry2 * px2)); + } + + var cx = root * rx * py / ry, + cy = -root * ry * px / rx, + cx1 = cosTh * cx - sinTh * cy + toX * 0.5, + cy1 = sinTh * cx + cosTh * cy + toY * 0.5, + mTheta = calcVectorAngle(1, 0, (px - cx) / rx, (py - cy) / ry), + dtheta = calcVectorAngle((px - cx) / rx, (py - cy) / ry, (-px - cx) / rx, (-py - cy) / ry); + + if (sweep === 0 && dtheta > 0) { + dtheta -= 2 * PI; + } + else if (sweep === 1 && dtheta < 0) { + dtheta += 2 * PI; + } + + // Convert into cubic bezier segments <= 90deg + var segments = Math.ceil(Math.abs(dtheta / PI * 2)), + result = [], mDelta = dtheta / segments, + mT = 8 / 3 * Math.sin(mDelta / 4) * Math.sin(mDelta / 4) / Math.sin(mDelta / 2), + th3 = mTheta + mDelta; + + for (var i = 0; i < segments; i++) { + result[i] = segmentToBezier(mTheta, th3, cosTh, sinTh, rx, ry, cx1, cy1, mT, fromX, fromY); + fromX = result[i][4]; + fromY = result[i][5]; + mTheta = th3; + th3 += mDelta; + } + arcToSegmentsCache[argsString] = result; + return result; + } + + function segmentToBezier(th2, th3, cosTh, sinTh, rx, ry, cx1, cy1, mT, fromX, fromY) { + var argsString2 = _join.call(arguments); + if (segmentToBezierCache[argsString2]) { + return segmentToBezierCache[argsString2]; + } + + var costh2 = Math.cos(th2), + sinth2 = Math.sin(th2), + costh3 = Math.cos(th3), + sinth3 = Math.sin(th3), + toX = cosTh * rx * costh3 - sinTh * ry * sinth3 + cx1, + toY = sinTh * rx * costh3 + cosTh * ry * sinth3 + cy1, + cp1X = fromX + mT * ( - cosTh * rx * sinth2 - sinTh * ry * costh2), + cp1Y = fromY + mT * ( - sinTh * rx * sinth2 + cosTh * ry * costh2), + cp2X = toX + mT * ( cosTh * rx * sinth3 + sinTh * ry * costh3), + cp2Y = toY + mT * ( sinTh * rx * sinth3 - cosTh * ry * costh3); + + segmentToBezierCache[argsString2] = [ + cp1X, cp1Y, + cp2X, cp2Y, + toX, toY + ]; + return segmentToBezierCache[argsString2]; + } + + /* + * Private + */ + function calcVectorAngle(ux, uy, vx, vy) { + var ta = Math.atan2(uy, ux), + tb = Math.atan2(vy, vx); + if (tb >= ta) { + return tb - ta; + } + else { + return 2 * Math.PI - (ta - tb); + } + } + + /** + * Draws arc + * @param {CanvasRenderingContext2D} ctx + * @param {Number} fx + * @param {Number} fy + * @param {Array} coords + */ + fabric.util.drawArc = function(ctx, fx, fy, coords) { + var rx = coords[0], + ry = coords[1], + rot = coords[2], + large = coords[3], + sweep = coords[4], + tx = coords[5], + ty = coords[6], + segs = [[ ], [ ], [ ], [ ]], + segsNorm = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot); + + for (var i = 0, len = segsNorm.length; i < len; i++) { + segs[i][0] = segsNorm[i][0] + fx; + segs[i][1] = segsNorm[i][1] + fy; + segs[i][2] = segsNorm[i][2] + fx; + segs[i][3] = segsNorm[i][3] + fy; + segs[i][4] = segsNorm[i][4] + fx; + segs[i][5] = segsNorm[i][5] + fy; + ctx.bezierCurveTo.apply(ctx, segs[i]); + } + }; + + /** + * Calculate bounding box of a elliptic-arc + * @param {Number} fx start point of arc + * @param {Number} fy + * @param {Number} rx horizontal radius + * @param {Number} ry vertical radius + * @param {Number} rot angle of horizontal axe + * @param {Number} large 1 or 0, whatever the arc is the big or the small on the 2 points + * @param {Number} sweep 1 or 0, 1 clockwise or counterclockwise direction + * @param {Number} tx end point of arc + * @param {Number} ty + */ + fabric.util.getBoundsOfArc = function(fx, fy, rx, ry, rot, large, sweep, tx, ty) { + + var fromX = 0, fromY = 0, bound = [ ], bounds = [ ], + segs = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot), + boundCopy = [[ ], [ ]]; + + for (var i = 0, len = segs.length; i < len; i++) { + bound = getBoundsOfCurve(fromX, fromY, segs[i][0], segs[i][1], segs[i][2], segs[i][3], segs[i][4], segs[i][5]); + boundCopy[0].x = bound[0].x + fx; + boundCopy[0].y = bound[0].y + fy; + boundCopy[1].x = bound[1].x + fx; + boundCopy[1].y = bound[1].y + fy; + bounds.push(boundCopy[0]); + bounds.push(boundCopy[1]); + fromX = segs[i][4]; + fromY = segs[i][5]; + } + return bounds; + }; + + /** + * Calculate bounding box of a beziercurve + * @param {Number} x0 starting point + * @param {Number} y0 + * @param {Number} x1 first control point + * @param {Number} y1 + * @param {Number} x2 secondo control point + * @param {Number} y2 + * @param {Number} x3 end of beizer + * @param {Number} y3 + */ + // taken from http://jsbin.com/ivomiq/56/edit no credits available for that. + function getBoundsOfCurve(x0, y0, x1, y1, x2, y2, x3, y3) { + var argsString = _join.call(arguments); + if (boundsOfCurveCache[argsString]) { + return boundsOfCurveCache[argsString]; + } + + var sqrt = Math.sqrt, + min = Math.min, max = Math.max, + abs = Math.abs, tvalues = [ ], + bounds = [[ ], [ ]], + a, b, c, t, t1, t2, b2ac, sqrtb2ac; + + b = 6 * x0 - 12 * x1 + 6 * x2; + a = -3 * x0 + 9 * x1 - 9 * x2 + 3 * x3; + c = 3 * x1 - 3 * x0; + + for (var i = 0; i < 2; ++i) { + if (i > 0) { + b = 6 * y0 - 12 * y1 + 6 * y2; + a = -3 * y0 + 9 * y1 - 9 * y2 + 3 * y3; + c = 3 * y1 - 3 * y0; + } + + if (abs(a) < 1e-12) { + if (abs(b) < 1e-12) { + continue; + } + t = -c / b; + if (0 < t && t < 1) { + tvalues.push(t); + } + continue; + } + b2ac = b * b - 4 * c * a; + if (b2ac < 0) { + continue; + } + sqrtb2ac = sqrt(b2ac); + t1 = (-b + sqrtb2ac) / (2 * a); + if (0 < t1 && t1 < 1) { + tvalues.push(t1); + } + t2 = (-b - sqrtb2ac) / (2 * a); + if (0 < t2 && t2 < 1) { + tvalues.push(t2); + } + } + + var x, y, j = tvalues.length, jlen = j, mt; + while (j--) { + t = tvalues[j]; + mt = 1 - t; + x = (mt * mt * mt * x0) + (3 * mt * mt * t * x1) + (3 * mt * t * t * x2) + (t * t * t * x3); + bounds[0][j] = x; + + y = (mt * mt * mt * y0) + (3 * mt * mt * t * y1) + (3 * mt * t * t * y2) + (t * t * t * y3); + bounds[1][j] = y; + } + + bounds[0][jlen] = x0; + bounds[1][jlen] = y0; + bounds[0][jlen + 1] = x3; + bounds[1][jlen + 1] = y3; + var result = [ + { + x: min.apply(null, bounds[0]), + y: min.apply(null, bounds[1]) + }, + { + x: max.apply(null, bounds[0]), + y: max.apply(null, bounds[1]) + } + ]; + boundsOfCurveCache[argsString] = result; + return result; + } + + fabric.util.getBoundsOfCurve = getBoundsOfCurve; + +})(); + + +(function() { + + var slice = Array.prototype.slice; + + /* _ES5_COMPAT_START_ */ + + if (!Array.prototype.indexOf) { + /** + * Finds index of an element in an array + * @param {Any} searchElement + * @param {Number} [fromIndex] + * @return {Number} + */ + Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) { + if (this === void 0 || this === null) { + throw new TypeError(); + } + var t = Object(this), len = t.length >>> 0; + if (len === 0) { + return -1; + } + var n = 0; + if (arguments.length > 0) { + n = Number(arguments[1]); + if (n !== n) { // shortcut for verifying if it's NaN + n = 0; + } + else if (n !== 0 && n !== Number.POSITIVE_INFINITY && n !== Number.NEGATIVE_INFINITY) { + n = (n > 0 || -1) * Math.floor(Math.abs(n)); + } + } + if (n >= len) { + return -1; + } + var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0); + for (; k < len; k++) { + if (k in t && t[k] === searchElement) { + return k; + } + } + return -1; + }; + } + + if (!Array.prototype.forEach) { + /** + * Iterates an array, invoking callback for each element + * @param {Function} fn Callback to invoke for each element + * @param {Object} [context] Context to invoke callback in + * @return {Array} + */ + Array.prototype.forEach = function(fn, context) { + for (var i = 0, len = this.length >>> 0; i < len; i++) { + if (i in this) { + fn.call(context, this[i], i, this); + } + } + }; + } + + if (!Array.prototype.map) { + /** + * Returns a result of iterating over an array, invoking callback for each element + * @param {Function} fn Callback to invoke for each element + * @param {Object} [context] Context to invoke callback in + * @return {Array} + */ + Array.prototype.map = function(fn, context) { + var result = [ ]; + for (var i = 0, len = this.length >>> 0; i < len; i++) { + if (i in this) { + result[i] = fn.call(context, this[i], i, this); + } + } + return result; + }; + } + + if (!Array.prototype.every) { + /** + * Returns true if a callback returns truthy value for all elements in an array + * @param {Function} fn Callback to invoke for each element + * @param {Object} [context] Context to invoke callback in + * @return {Boolean} + */ + Array.prototype.every = function(fn, context) { + for (var i = 0, len = this.length >>> 0; i < len; i++) { + if (i in this && !fn.call(context, this[i], i, this)) { + return false; + } + } + return true; + }; + } + + if (!Array.prototype.some) { + /** + * Returns true if a callback returns truthy value for at least one element in an array + * @param {Function} fn Callback to invoke for each element + * @param {Object} [context] Context to invoke callback in + * @return {Boolean} + */ + Array.prototype.some = function(fn, context) { + for (var i = 0, len = this.length >>> 0; i < len; i++) { + if (i in this && fn.call(context, this[i], i, this)) { + return true; + } + } + return false; + }; + } + + if (!Array.prototype.filter) { + /** + * Returns the result of iterating over elements in an array + * @param {Function} fn Callback to invoke for each element + * @param {Object} [context] Context to invoke callback in + * @return {Array} + */ + Array.prototype.filter = function(fn, context) { + var result = [ ], val; + for (var i = 0, len = this.length >>> 0; i < len; i++) { + if (i in this) { + val = this[i]; // in case fn mutates this + if (fn.call(context, val, i, this)) { + result.push(val); + } + } + } + return result; + }; + } + + if (!Array.prototype.reduce) { + /** + * Returns "folded" (reduced) result of iterating over elements in an array + * @param {Function} fn Callback to invoke for each element + * @param {Object} [initial] Object to use as the first argument to the first call of the callback + * @return {Any} + */ + Array.prototype.reduce = function(fn /*, initial*/) { + var len = this.length >>> 0, + i = 0, + rv; + + if (arguments.length > 1) { + rv = arguments[1]; + } + else { + do { + if (i in this) { + rv = this[i++]; + break; + } + // if array contains no values, no initial value to return + if (++i >= len) { + throw new TypeError(); + } + } + while (true); + } + for (; i < len; i++) { + if (i in this) { + rv = fn.call(null, rv, this[i], i, this); + } + } + return rv; + }; + } + + /* _ES5_COMPAT_END_ */ + + /** + * Invokes method on all items in a given array + * @memberOf fabric.util.array + * @param {Array} array Array to iterate over + * @param {String} method Name of a method to invoke + * @return {Array} + */ + function invoke(array, method) { + var args = slice.call(arguments, 2), result = [ ]; + for (var i = 0, len = array.length; i < len; i++) { + result[i] = args.length ? array[i][method].apply(array[i], args) : array[i][method].call(array[i]); + } + return result; + } + + /** + * Finds maximum value in array (not necessarily "first" one) + * @memberOf fabric.util.array + * @param {Array} array Array to iterate over + * @param {String} byProperty + * @return {Any} + */ + function max(array, byProperty) { + return find(array, byProperty, function(value1, value2) { + return value1 >= value2; + }); + } + + /** + * Finds minimum value in array (not necessarily "first" one) + * @memberOf fabric.util.array + * @param {Array} array Array to iterate over + * @param {String} byProperty + * @return {Any} + */ + function min(array, byProperty) { + return find(array, byProperty, function(value1, value2) { + return value1 < value2; + }); + } + + /** + * @private + */ + function find(array, byProperty, condition) { + if (!array || array.length === 0) { + return; + } + + var i = array.length - 1, + result = byProperty ? array[i][byProperty] : array[i]; + if (byProperty) { + while (i--) { + if (condition(array[i][byProperty], result)) { + result = array[i][byProperty]; + } + } + } + else { + while (i--) { + if (condition(array[i], result)) { + result = array[i]; + } + } + } + return result; + } + + /** + * @namespace fabric.util.array + */ + fabric.util.array = { + invoke: invoke, + min: min, + max: max + }; + +})(); + + +(function() { + + /** + * Copies all enumerable properties of one object to another + * @memberOf fabric.util.object + * @param {Object} destination Where to copy to + * @param {Object} source Where to copy from + * @return {Object} + */ + function extend(destination, source) { + // JScript DontEnum bug is not taken care of + for (var property in source) { + destination[property] = source[property]; + } + return destination; + } + + /** + * Creates an empty object and copies all enumerable properties of another object to it + * @memberOf fabric.util.object + * @param {Object} object Object to clone + * @return {Object} + */ + function clone(object) { + return extend({ }, object); + } + + /** @namespace fabric.util.object */ + fabric.util.object = { + extend: extend, + clone: clone + }; + +})(); + + +(function() { + + /* _ES5_COMPAT_START_ */ + if (!String.prototype.trim) { + /** + * Trims a string (removing whitespace from the beginning and the end) + * @function external:String#trim + * @see String#trim on MDN + */ + String.prototype.trim = function () { + // this trim is not fully ES3 or ES5 compliant, but it should cover most cases for now + return this.replace(/^[\s\xA0]+/, '').replace(/[\s\xA0]+$/, ''); + }; + } + /* _ES5_COMPAT_END_ */ + + /** + * Camelizes a string + * @memberOf fabric.util.string + * @param {String} string String to camelize + * @return {String} Camelized version of a string + */ + function camelize(string) { + return string.replace(/-+(.)?/g, function(match, character) { + return character ? character.toUpperCase() : ''; + }); + } + + /** + * Capitalizes a string + * @memberOf fabric.util.string + * @param {String} string String to capitalize + * @param {Boolean} [firstLetterOnly] If true only first letter is capitalized + * and other letters stay untouched, if false first letter is capitalized + * and other letters are converted to lowercase. + * @return {String} Capitalized version of a string + */ + function capitalize(string, firstLetterOnly) { + return string.charAt(0).toUpperCase() + + (firstLetterOnly ? string.slice(1) : string.slice(1).toLowerCase()); + } + + /** + * Escapes XML in a string + * @memberOf fabric.util.string + * @param {String} string String to escape + * @return {String} Escaped version of a string + */ + function escapeXml(string) { + return string.replace(/&/g, '&') + .replace(/"/g, '"') + .replace(/'/g, ''') + .replace(//g, '>'); + } + + /** + * String utilities + * @namespace fabric.util.string + */ + fabric.util.string = { + camelize: camelize, + capitalize: capitalize, + escapeXml: escapeXml + }; +}()); + + +/* _ES5_COMPAT_START_ */ +(function() { + + var slice = Array.prototype.slice, + apply = Function.prototype.apply, + Dummy = function() { }; + + if (!Function.prototype.bind) { + /** + * Cross-browser approximation of ES5 Function.prototype.bind (not fully spec conforming) + * @see Function#bind on MDN + * @param {Object} thisArg Object to bind function to + * @param {Any[]} [...] Values to pass to a bound function + * @return {Function} + */ + Function.prototype.bind = function(thisArg) { + var _this = this, args = slice.call(arguments, 1), bound; + if (args.length) { + bound = function() { + return apply.call(_this, this instanceof Dummy ? this : thisArg, args.concat(slice.call(arguments))); + }; + } + else { + /** @ignore */ + bound = function() { + return apply.call(_this, this instanceof Dummy ? this : thisArg, arguments); + }; + } + Dummy.prototype = this.prototype; + bound.prototype = new Dummy(); + + return bound; + }; + } + +})(); +/* _ES5_COMPAT_END_ */ + + +(function() { + + var slice = Array.prototype.slice, emptyFunction = function() { }, + + IS_DONTENUM_BUGGY = (function() { + for (var p in { toString: 1 }) { + if (p === 'toString') { + return false; + } + } + return true; + })(), + + /** @ignore */ + addMethods = function(klass, source, parent) { + for (var property in source) { + + if (property in klass.prototype && + typeof klass.prototype[property] === 'function' && + (source[property] + '').indexOf('callSuper') > -1) { + + klass.prototype[property] = (function(property) { + return function() { + + var superclass = this.constructor.superclass; + this.constructor.superclass = parent; + var returnValue = source[property].apply(this, arguments); + this.constructor.superclass = superclass; + + if (property !== 'initialize') { + return returnValue; + } + }; + })(property); + } + else { + klass.prototype[property] = source[property]; + } + + if (IS_DONTENUM_BUGGY) { + if (source.toString !== Object.prototype.toString) { + klass.prototype.toString = source.toString; + } + if (source.valueOf !== Object.prototype.valueOf) { + klass.prototype.valueOf = source.valueOf; + } + } + } + }; + + function Subclass() { } + + function callSuper(methodName) { + var fn = this.constructor.superclass.prototype[methodName]; + return (arguments.length > 1) + ? fn.apply(this, slice.call(arguments, 1)) + : fn.call(this); + } + + /** + * Helper for creation of "classes". + * @memberOf fabric.util + * @param {Function} [parent] optional "Class" to inherit from + * @param {Object} [properties] Properties shared by all instances of this class + * (be careful modifying objects defined here as this would affect all instances) + */ + function createClass() { + var parent = null, + properties = slice.call(arguments, 0); + + if (typeof properties[0] === 'function') { + parent = properties.shift(); + } + function klass() { + this.initialize.apply(this, arguments); + } + + klass.superclass = parent; + klass.subclasses = [ ]; + + if (parent) { + Subclass.prototype = parent.prototype; + klass.prototype = new Subclass(); + parent.subclasses.push(klass); + } + for (var i = 0, length = properties.length; i < length; i++) { + addMethods(klass, properties[i], parent); + } + if (!klass.prototype.initialize) { + klass.prototype.initialize = emptyFunction; + } + klass.prototype.constructor = klass; + klass.prototype.callSuper = callSuper; + return klass; + } + + fabric.util.createClass = createClass; +})(); + + +(function () { + + var unknown = 'unknown'; + + /* EVENT HANDLING */ + + function areHostMethods(object) { + var methodNames = Array.prototype.slice.call(arguments, 1), + t, i, len = methodNames.length; + for (i = 0; i < len; i++) { + t = typeof object[methodNames[i]]; + if (!(/^(?:function|object|unknown)$/).test(t)) { + return false; + } + } + return true; + } + + /** @ignore */ + var getElement, + setElement, + getUniqueId = (function () { + var uid = 0; + return function (element) { + return element.__uniqueID || (element.__uniqueID = 'uniqueID__' + uid++); + }; + })(); + + (function () { + var elements = { }; + /** @ignore */ + getElement = function (uid) { + return elements[uid]; + }; + /** @ignore */ + setElement = function (uid, element) { + elements[uid] = element; + }; + })(); + + function createListener(uid, handler) { + return { + handler: handler, + wrappedHandler: createWrappedHandler(uid, handler) + }; + } + + function createWrappedHandler(uid, handler) { + return function (e) { + handler.call(getElement(uid), e || fabric.window.event); + }; + } + + function createDispatcher(uid, eventName) { + return function (e) { + if (handlers[uid] && handlers[uid][eventName]) { + var handlersForEvent = handlers[uid][eventName]; + for (var i = 0, len = handlersForEvent.length; i < len; i++) { + handlersForEvent[i].call(this, e || fabric.window.event); + } + } + }; + } + + var shouldUseAddListenerRemoveListener = ( + areHostMethods(fabric.document.documentElement, 'addEventListener', 'removeEventListener') && + areHostMethods(fabric.window, 'addEventListener', 'removeEventListener')), + + shouldUseAttachEventDetachEvent = ( + areHostMethods(fabric.document.documentElement, 'attachEvent', 'detachEvent') && + areHostMethods(fabric.window, 'attachEvent', 'detachEvent')), + + // IE branch + listeners = { }, + + // DOM L0 branch + handlers = { }, + + addListener, removeListener; + + if (shouldUseAddListenerRemoveListener) { + /** @ignore */ + addListener = function (element, eventName, handler) { + element.addEventListener(eventName, handler, false); + }; + /** @ignore */ + removeListener = function (element, eventName, handler) { + element.removeEventListener(eventName, handler, false); + }; + } + + else if (shouldUseAttachEventDetachEvent) { + /** @ignore */ + addListener = function (element, eventName, handler) { + var uid = getUniqueId(element); + setElement(uid, element); + if (!listeners[uid]) { + listeners[uid] = { }; + } + if (!listeners[uid][eventName]) { + listeners[uid][eventName] = [ ]; + + } + var listener = createListener(uid, handler); + listeners[uid][eventName].push(listener); + element.attachEvent('on' + eventName, listener.wrappedHandler); + }; + /** @ignore */ + removeListener = function (element, eventName, handler) { + var uid = getUniqueId(element), listener; + if (listeners[uid] && listeners[uid][eventName]) { + for (var i = 0, len = listeners[uid][eventName].length; i < len; i++) { + listener = listeners[uid][eventName][i]; + if (listener && listener.handler === handler) { + element.detachEvent('on' + eventName, listener.wrappedHandler); + listeners[uid][eventName][i] = null; + } + } + } + }; + } + else { + /** @ignore */ + addListener = function (element, eventName, handler) { + var uid = getUniqueId(element); + if (!handlers[uid]) { + handlers[uid] = { }; + } + if (!handlers[uid][eventName]) { + handlers[uid][eventName] = [ ]; + var existingHandler = element['on' + eventName]; + if (existingHandler) { + handlers[uid][eventName].push(existingHandler); + } + element['on' + eventName] = createDispatcher(uid, eventName); + } + handlers[uid][eventName].push(handler); + }; + /** @ignore */ + removeListener = function (element, eventName, handler) { + var uid = getUniqueId(element); + if (handlers[uid] && handlers[uid][eventName]) { + var handlersForEvent = handlers[uid][eventName]; + for (var i = 0, len = handlersForEvent.length; i < len; i++) { + if (handlersForEvent[i] === handler) { + handlersForEvent.splice(i, 1); + } + } + } + }; + } + + /** + * Adds an event listener to an element + * @function + * @memberOf fabric.util + * @param {HTMLElement} element + * @param {String} eventName + * @param {Function} handler + */ + fabric.util.addListener = addListener; + + /** + * Removes an event listener from an element + * @function + * @memberOf fabric.util + * @param {HTMLElement} element + * @param {String} eventName + * @param {Function} handler + */ + fabric.util.removeListener = removeListener; + + /** + * Cross-browser wrapper for getting event's coordinates + * @memberOf fabric.util + * @param {Event} event Event object + * @param {HTMLCanvasElement} upperCanvasEl <canvas> element on which object selection is drawn + */ + function getPointer(event, upperCanvasEl) { + event || (event = fabric.window.event); + + var element = event.target || + (typeof event.srcElement !== unknown ? event.srcElement : null), + + scroll = fabric.util.getScrollLeftTop(element, upperCanvasEl); + + return { + x: pointerX(event) + scroll.left, + y: pointerY(event) + scroll.top + }; + } + + var pointerX = function(event) { + // looks like in IE (<9) clientX at certain point (apparently when mouseup fires on VML element) + // is represented as COM object, with all the consequences, like "unknown" type and error on [[Get]] + // need to investigate later + return (typeof event.clientX !== unknown ? event.clientX : 0); + }, + + pointerY = function(event) { + return (typeof event.clientY !== unknown ? event.clientY : 0); + }; + + function _getPointer(event, pageProp, clientProp) { + var touchProp = event.type === 'touchend' ? 'changedTouches' : 'touches'; + + return (event[touchProp] && event[touchProp][0] + ? (event[touchProp][0][pageProp] - (event[touchProp][0][pageProp] - event[touchProp][0][clientProp])) + || event[clientProp] + : event[clientProp]); + } + + if (fabric.isTouchSupported) { + pointerX = function(event) { + return _getPointer(event, 'pageX', 'clientX'); + }; + pointerY = function(event) { + return _getPointer(event, 'pageY', 'clientY'); + }; + } + + fabric.util.getPointer = getPointer; + + fabric.util.object.extend(fabric.util, fabric.Observable); + +})(); + + +(function () { + + /** + * Cross-browser wrapper for setting element's style + * @memberOf fabric.util + * @param {HTMLElement} element + * @param {Object} styles + * @return {HTMLElement} Element that was passed as a first argument + */ + function setStyle(element, styles) { + var elementStyle = element.style; + if (!elementStyle) { + return element; + } + if (typeof styles === 'string') { + element.style.cssText += ';' + styles; + return styles.indexOf('opacity') > -1 + ? setOpacity(element, styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) + : element; + } + for (var property in styles) { + if (property === 'opacity') { + setOpacity(element, styles[property]); + } + else { + var normalizedProperty = (property === 'float' || property === 'cssFloat') + ? (typeof elementStyle.styleFloat === 'undefined' ? 'cssFloat' : 'styleFloat') + : property; + elementStyle[normalizedProperty] = styles[property]; + } + } + return element; + } + + var parseEl = fabric.document.createElement('div'), + supportsOpacity = typeof parseEl.style.opacity === 'string', + supportsFilters = typeof parseEl.style.filter === 'string', + reOpacity = /alpha\s*\(\s*opacity\s*=\s*([^\)]+)\)/, + + /** @ignore */ + setOpacity = function (element) { return element; }; + + if (supportsOpacity) { + /** @ignore */ + setOpacity = function(element, value) { + element.style.opacity = value; + return element; + }; + } + else if (supportsFilters) { + /** @ignore */ + setOpacity = function(element, value) { + var es = element.style; + if (element.currentStyle && !element.currentStyle.hasLayout) { + es.zoom = 1; + } + if (reOpacity.test(es.filter)) { + value = value >= 0.9999 ? '' : ('alpha(opacity=' + (value * 100) + ')'); + es.filter = es.filter.replace(reOpacity, value); + } + else { + es.filter += ' alpha(opacity=' + (value * 100) + ')'; + } + return element; + }; + } + + fabric.util.setStyle = setStyle; + +})(); + + +(function() { + + var _slice = Array.prototype.slice; + + /** + * Takes id and returns an element with that id (if one exists in a document) + * @memberOf fabric.util + * @param {String|HTMLElement} id + * @return {HTMLElement|null} + */ + function getById(id) { + return typeof id === 'string' ? fabric.document.getElementById(id) : id; + } + + var sliceCanConvertNodelists, + /** + * Converts an array-like object (e.g. arguments or NodeList) to an array + * @memberOf fabric.util + * @param {Object} arrayLike + * @return {Array} + */ + toArray = function(arrayLike) { + return _slice.call(arrayLike, 0); + }; + + try { + sliceCanConvertNodelists = toArray(fabric.document.childNodes) instanceof Array; + } + catch (err) { } + + if (!sliceCanConvertNodelists) { + toArray = function(arrayLike) { + var arr = new Array(arrayLike.length), i = arrayLike.length; + while (i--) { + arr[i] = arrayLike[i]; + } + return arr; + }; + } + + /** + * Creates specified element with specified attributes + * @memberOf fabric.util + * @param {String} tagName Type of an element to create + * @param {Object} [attributes] Attributes to set on an element + * @return {HTMLElement} Newly created element + */ + function makeElement(tagName, attributes) { + var el = fabric.document.createElement(tagName); + for (var prop in attributes) { + if (prop === 'class') { + el.className = attributes[prop]; + } + else if (prop === 'for') { + el.htmlFor = attributes[prop]; + } + else { + el.setAttribute(prop, attributes[prop]); + } + } + return el; + } + + /** + * Adds class to an element + * @memberOf fabric.util + * @param {HTMLElement} element Element to add class to + * @param {String} className Class to add to an element + */ + function addClass(element, className) { + if (element && (' ' + element.className + ' ').indexOf(' ' + className + ' ') === -1) { + element.className += (element.className ? ' ' : '') + className; + } + } + + /** + * Wraps element with another element + * @memberOf fabric.util + * @param {HTMLElement} element Element to wrap + * @param {HTMLElement|String} wrapper Element to wrap with + * @param {Object} [attributes] Attributes to set on a wrapper + * @return {HTMLElement} wrapper + */ + function wrapElement(element, wrapper, attributes) { + if (typeof wrapper === 'string') { + wrapper = makeElement(wrapper, attributes); + } + if (element.parentNode) { + element.parentNode.replaceChild(wrapper, element); + } + wrapper.appendChild(element); + return wrapper; + } + + /** + * Returns element scroll offsets + * @memberOf fabric.util + * @param {HTMLElement} element Element to operate on + * @param {HTMLElement} upperCanvasEl Upper canvas element + * @return {Object} Object with left/top values + */ + function getScrollLeftTop(element, upperCanvasEl) { + + var firstFixedAncestor, + origElement, + left = 0, + top = 0, + docElement = fabric.document.documentElement, + body = fabric.document.body || { + scrollLeft: 0, scrollTop: 0 + }; + + origElement = element; + + while (element && element.parentNode && !firstFixedAncestor) { + + element = element.parentNode; + + if (element.nodeType === 1 && + fabric.util.getElementStyle(element, 'position') === 'fixed') { + firstFixedAncestor = element; + } + + if (element.nodeType === 1 && + origElement !== upperCanvasEl && + fabric.util.getElementStyle(element, 'position') === 'absolute') { + left = 0; + top = 0; + } + else if (element === fabric.document) { + left = body.scrollLeft || docElement.scrollLeft || 0; + top = body.scrollTop || docElement.scrollTop || 0; + } + else { + left += element.scrollLeft || 0; + top += element.scrollTop || 0; + } + } + + return { left: left, top: top }; + } + + /** + * Returns offset for a given element + * @function + * @memberOf fabric.util + * @param {HTMLElement} element Element to get offset for + * @return {Object} Object with "left" and "top" properties + */ + function getElementOffset(element) { + var docElem, + doc = element && element.ownerDocument, + box = { left: 0, top: 0 }, + offset = { left: 0, top: 0 }, + scrollLeftTop, + offsetAttributes = { + borderLeftWidth: 'left', + borderTopWidth: 'top', + paddingLeft: 'left', + paddingTop: 'top' + }; + + if (!doc) { + return { left: 0, top: 0 }; + } + + for (var attr in offsetAttributes) { + offset[offsetAttributes[attr]] += parseInt(getElementStyle(element, attr), 10) || 0; + } + + docElem = doc.documentElement; + if ( typeof element.getBoundingClientRect !== 'undefined' ) { + box = element.getBoundingClientRect(); + } + + scrollLeftTop = fabric.util.getScrollLeftTop(element, null); + + return { + left: box.left + scrollLeftTop.left - (docElem.clientLeft || 0) + offset.left, + top: box.top + scrollLeftTop.top - (docElem.clientTop || 0) + offset.top + }; + } + + /** + * Returns style attribute value of a given element + * @memberOf fabric.util + * @param {HTMLElement} element Element to get style attribute for + * @param {String} attr Style attribute to get for element + * @return {String} Style attribute value of the given element. + */ + var getElementStyle; + if (fabric.document.defaultView && fabric.document.defaultView.getComputedStyle) { + getElementStyle = function(element, attr) { + var style = fabric.document.defaultView.getComputedStyle(element, null); + return style ? style[attr] : undefined; + }; + } + else { + getElementStyle = function(element, attr) { + var value = element.style[attr]; + if (!value && element.currentStyle) { + value = element.currentStyle[attr]; + } + return value; + }; + } + + (function () { + var style = fabric.document.documentElement.style, + selectProp = 'userSelect' in style + ? 'userSelect' + : 'MozUserSelect' in style + ? 'MozUserSelect' + : 'WebkitUserSelect' in style + ? 'WebkitUserSelect' + : 'KhtmlUserSelect' in style + ? 'KhtmlUserSelect' + : ''; + + /** + * Makes element unselectable + * @memberOf fabric.util + * @param {HTMLElement} element Element to make unselectable + * @return {HTMLElement} Element that was passed in + */ + function makeElementUnselectable(element) { + if (typeof element.onselectstart !== 'undefined') { + element.onselectstart = fabric.util.falseFunction; + } + if (selectProp) { + element.style[selectProp] = 'none'; + } + else if (typeof element.unselectable === 'string') { + element.unselectable = 'on'; + } + return element; + } + + /** + * Makes element selectable + * @memberOf fabric.util + * @param {HTMLElement} element Element to make selectable + * @return {HTMLElement} Element that was passed in + */ + function makeElementSelectable(element) { + if (typeof element.onselectstart !== 'undefined') { + element.onselectstart = null; + } + if (selectProp) { + element.style[selectProp] = ''; + } + else if (typeof element.unselectable === 'string') { + element.unselectable = ''; + } + return element; + } + + fabric.util.makeElementUnselectable = makeElementUnselectable; + fabric.util.makeElementSelectable = makeElementSelectable; + })(); + + (function() { + + /** + * Inserts a script element with a given url into a document; invokes callback, when that script is finished loading + * @memberOf fabric.util + * @param {String} url URL of a script to load + * @param {Function} callback Callback to execute when script is finished loading + */ + function getScript(url, callback) { + var headEl = fabric.document.getElementsByTagName('head')[0], + scriptEl = fabric.document.createElement('script'), + loading = true; + + /** @ignore */ + scriptEl.onload = /** @ignore */ scriptEl.onreadystatechange = function(e) { + if (loading) { + if (typeof this.readyState === 'string' && + this.readyState !== 'loaded' && + this.readyState !== 'complete') { + return; + } + loading = false; + callback(e || fabric.window.event); + scriptEl = scriptEl.onload = scriptEl.onreadystatechange = null; + } + }; + scriptEl.src = url; + headEl.appendChild(scriptEl); + // causes issue in Opera + // headEl.removeChild(scriptEl); + } + + fabric.util.getScript = getScript; + })(); + + fabric.util.getById = getById; + fabric.util.toArray = toArray; + fabric.util.makeElement = makeElement; + fabric.util.addClass = addClass; + fabric.util.wrapElement = wrapElement; + fabric.util.getScrollLeftTop = getScrollLeftTop; + fabric.util.getElementOffset = getElementOffset; + fabric.util.getElementStyle = getElementStyle; + +})(); + + +(function() { + + function addParamToUrl(url, param) { + return url + (/\?/.test(url) ? '&' : '?') + param; + } + + var makeXHR = (function() { + var factories = [ + function() { return new ActiveXObject('Microsoft.XMLHTTP'); }, + function() { return new ActiveXObject('Msxml2.XMLHTTP'); }, + function() { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); }, + function() { return new XMLHttpRequest(); } + ]; + for (var i = factories.length; i--; ) { + try { + var req = factories[i](); + if (req) { + return factories[i]; + } + } + catch (err) { } + } + })(); + + function emptyFn() { } + + /** + * Cross-browser abstraction for sending XMLHttpRequest + * @memberOf fabric.util + * @param {String} url URL to send XMLHttpRequest to + * @param {Object} [options] Options object + * @param {String} [options.method="GET"] + * @param {Function} options.onComplete Callback to invoke when request is completed + * @return {XMLHttpRequest} request + */ + function request(url, options) { + + options || (options = { }); + + var method = options.method ? options.method.toUpperCase() : 'GET', + onComplete = options.onComplete || function() { }, + xhr = makeXHR(), + body; + + /** @ignore */ + xhr.onreadystatechange = function() { + if (xhr.readyState === 4) { + onComplete(xhr); + xhr.onreadystatechange = emptyFn; + } + }; + + if (method === 'GET') { + body = null; + if (typeof options.parameters === 'string') { + url = addParamToUrl(url, options.parameters); + } + } + + xhr.open(method, url, true); + + if (method === 'POST' || method === 'PUT') { + xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); + } + + xhr.send(body); + return xhr; + } + + fabric.util.request = request; +})(); + + +/** + * Wrapper around `console.log` (when available) + * @param {Any} [values] Values to log + */ +fabric.log = function() { }; + +/** + * Wrapper around `console.warn` (when available) + * @param {Any} [values] Values to log as a warning + */ +fabric.warn = function() { }; + +if (typeof console !== 'undefined') { + + ['log', 'warn'].forEach(function(methodName) { + + if (typeof console[methodName] !== 'undefined' && + typeof console[methodName].apply === 'function') { + + fabric[methodName] = function() { + return console[methodName].apply(console, arguments); + }; + } + }); +} + + +(function() { + + /** + * Changes value from one to another within certain period of time, invoking callbacks as value is being changed. + * @memberOf fabric.util + * @param {Object} [options] Animation options + * @param {Function} [options.onChange] Callback; invoked on every value change + * @param {Function} [options.onComplete] Callback; invoked when value change is completed + * @param {Number} [options.startValue=0] Starting value + * @param {Number} [options.endValue=100] Ending value + * @param {Number} [options.byValue=100] Value to modify the property by + * @param {Function} [options.easing] Easing function + * @param {Number} [options.duration=500] Duration of change (in ms) + */ + function animate(options) { + + requestAnimFrame(function(timestamp) { + options || (options = { }); + + var start = timestamp || +new Date(), + duration = options.duration || 500, + finish = start + duration, time, + onChange = options.onChange || function() { }, + abort = options.abort || function() { return false; }, + easing = options.easing || function(t, b, c, d) {return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;}, + startValue = 'startValue' in options ? options.startValue : 0, + endValue = 'endValue' in options ? options.endValue : 100, + byValue = options.byValue || endValue - startValue; + + options.onStart && options.onStart(); + + (function tick(ticktime) { + time = ticktime || +new Date(); + var currentTime = time > finish ? duration : (time - start); + if (abort()) { + options.onComplete && options.onComplete(); + return; + } + onChange(easing(currentTime, startValue, byValue, duration)); + if (time > finish) { + options.onComplete && options.onComplete(); + return; + } + requestAnimFrame(tick); + })(start); + }); + + } + + var _requestAnimFrame = fabric.window.requestAnimationFrame || + fabric.window.webkitRequestAnimationFrame || + fabric.window.mozRequestAnimationFrame || + fabric.window.oRequestAnimationFrame || + fabric.window.msRequestAnimationFrame || + function(callback) { + fabric.window.setTimeout(callback, 1000 / 60); + }; + /** + * requestAnimationFrame polyfill based on http://paulirish.com/2011/requestanimationframe-for-smart-animating/ + * In order to get a precise start time, `requestAnimFrame` should be called as an entry into the method + * @memberOf fabric.util + * @param {Function} callback Callback to invoke + * @param {DOMElement} element optional Element to associate with animation + */ + function requestAnimFrame() { + return _requestAnimFrame.apply(fabric.window, arguments); + } + + fabric.util.animate = animate; + fabric.util.requestAnimFrame = requestAnimFrame; + +})(); + + +(function() { + + function normalize(a, c, p, s) { + if (a < Math.abs(c)) { + a = c; + s = p / 4; + } + else { + s = p / (2 * Math.PI) * Math.asin(c / a); + } + return { a: a, c: c, p: p, s: s }; + } + + function elastic(opts, t, d) { + return opts.a * + Math.pow(2, 10 * (t -= 1)) * + Math.sin( (t * d - opts.s) * (2 * Math.PI) / opts.p ); + } + + /** + * Cubic easing out + * @memberOf fabric.util.ease + */ + function easeOutCubic(t, b, c, d) { + return c * ((t = t / d - 1) * t * t + 1) + b; + } + + /** + * Cubic easing in and out + * @memberOf fabric.util.ease + */ + function easeInOutCubic(t, b, c, d) { + t /= d/2; + if (t < 1) { + return c / 2 * t * t * t + b; + } + return c / 2 * ((t -= 2) * t * t + 2) + b; + } + + /** + * Quartic easing in + * @memberOf fabric.util.ease + */ + function easeInQuart(t, b, c, d) { + return c * (t /= d) * t * t * t + b; + } + + /** + * Quartic easing out + * @memberOf fabric.util.ease + */ + function easeOutQuart(t, b, c, d) { + return -c * ((t = t / d - 1) * t * t * t - 1) + b; + } + + /** + * Quartic easing in and out + * @memberOf fabric.util.ease + */ + function easeInOutQuart(t, b, c, d) { + t /= d / 2; + if (t < 1) { + return c / 2 * t * t * t * t + b; + } + return -c / 2 * ((t -= 2) * t * t * t - 2) + b; + } + + /** + * Quintic easing in + * @memberOf fabric.util.ease + */ + function easeInQuint(t, b, c, d) { + return c * (t /= d) * t * t * t * t + b; + } + + /** + * Quintic easing out + * @memberOf fabric.util.ease + */ + function easeOutQuint(t, b, c, d) { + return c * ((t = t / d - 1) * t * t * t * t + 1) + b; + } + + /** + * Quintic easing in and out + * @memberOf fabric.util.ease + */ + function easeInOutQuint(t, b, c, d) { + t /= d / 2; + if (t < 1) { + return c / 2 * t * t * t * t * t + b; + } + return c / 2 * ((t -= 2) * t * t * t * t + 2) + b; + } + + /** + * Sinusoidal easing in + * @memberOf fabric.util.ease + */ + function easeInSine(t, b, c, d) { + return -c * Math.cos(t / d * (Math.PI / 2)) + c + b; + } + + /** + * Sinusoidal easing out + * @memberOf fabric.util.ease + */ + function easeOutSine(t, b, c, d) { + return c * Math.sin(t / d * (Math.PI / 2)) + b; + } + + /** + * Sinusoidal easing in and out + * @memberOf fabric.util.ease + */ + function easeInOutSine(t, b, c, d) { + return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b; + } + + /** + * Exponential easing in + * @memberOf fabric.util.ease + */ + function easeInExpo(t, b, c, d) { + return (t === 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b; + } + + /** + * Exponential easing out + * @memberOf fabric.util.ease + */ + function easeOutExpo(t, b, c, d) { + return (t === d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b; + } + + /** + * Exponential easing in and out + * @memberOf fabric.util.ease + */ + function easeInOutExpo(t, b, c, d) { + if (t === 0) { + return b; + } + if (t === d) { + return b + c; + } + t /= d / 2; + if (t < 1) { + return c / 2 * Math.pow(2, 10 * (t - 1)) + b; + } + return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b; + } + + /** + * Circular easing in + * @memberOf fabric.util.ease + */ + function easeInCirc(t, b, c, d) { + return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b; + } + + /** + * Circular easing out + * @memberOf fabric.util.ease + */ + function easeOutCirc(t, b, c, d) { + return c * Math.sqrt(1 - (t = t / d - 1) * t) + b; + } + + /** + * Circular easing in and out + * @memberOf fabric.util.ease + */ + function easeInOutCirc(t, b, c, d) { + t /= d / 2; + if (t < 1) { + return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b; + } + return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b; + } + + /** + * Elastic easing in + * @memberOf fabric.util.ease + */ + function easeInElastic(t, b, c, d) { + var s = 1.70158, p = 0, a = c; + if (t === 0) { + return b; + } + t /= d; + if (t === 1) { + return b + c; + } + if (!p) { + p = d * 0.3; + } + var opts = normalize(a, c, p, s); + return -elastic(opts, t, d) + b; + } + + /** + * Elastic easing out + * @memberOf fabric.util.ease + */ + function easeOutElastic(t, b, c, d) { + var s = 1.70158, p = 0, a = c; + if (t === 0) { + return b; + } + t /= d; + if (t === 1) { + return b + c; + } + if (!p) { + p = d * 0.3; + } + var opts = normalize(a, c, p, s); + return opts.a * Math.pow(2, -10 * t) * Math.sin((t * d - opts.s) * (2 * Math.PI) / opts.p ) + opts.c + b; + } + + /** + * Elastic easing in and out + * @memberOf fabric.util.ease + */ + function easeInOutElastic(t, b, c, d) { + var s = 1.70158, p = 0, a = c; + if (t === 0) { + return b; + } + t /= d / 2; + if (t === 2) { + return b + c; + } + if (!p) { + p = d * (0.3 * 1.5); + } + var opts = normalize(a, c, p, s); + if (t < 1) { + return -0.5 * elastic(opts, t, d) + b; + } + return opts.a * Math.pow(2, -10 * (t -= 1)) * + Math.sin((t * d - opts.s) * (2 * Math.PI) / opts.p ) * 0.5 + opts.c + b; + } + + /** + * Backwards easing in + * @memberOf fabric.util.ease + */ + function easeInBack(t, b, c, d, s) { + if (s === undefined) { + s = 1.70158; + } + return c * (t /= d) * t * ((s + 1) * t - s) + b; + } + + /** + * Backwards easing out + * @memberOf fabric.util.ease + */ + function easeOutBack(t, b, c, d, s) { + if (s === undefined) { + s = 1.70158; + } + return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b; + } + + /** + * Backwards easing in and out + * @memberOf fabric.util.ease + */ + function easeInOutBack(t, b, c, d, s) { + if (s === undefined) { + s = 1.70158; + } + t /= d / 2; + if (t < 1) { + return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b; + } + return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b; + } + + /** + * Bouncing easing in + * @memberOf fabric.util.ease + */ + function easeInBounce(t, b, c, d) { + return c - easeOutBounce (d - t, 0, c, d) + b; + } + + /** + * Bouncing easing out + * @memberOf fabric.util.ease + */ + function easeOutBounce(t, b, c, d) { + if ((t /= d) < (1 / 2.75)) { + return c * (7.5625 * t * t) + b; + } + else if (t < (2/2.75)) { + return c * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75) + b; + } + else if (t < (2.5/2.75)) { + return c * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375) + b; + } + else { + return c * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375) + b; + } + } + + /** + * Bouncing easing in and out + * @memberOf fabric.util.ease + */ + function easeInOutBounce(t, b, c, d) { + if (t < d / 2) { + return easeInBounce (t * 2, 0, c, d) * 0.5 + b; + } + return easeOutBounce(t * 2 - d, 0, c, d) * 0.5 + c * 0.5 + b; + } + + /** + * Easing functions + * See Easing Equations by Robert Penner + * @namespace fabric.util.ease + */ + fabric.util.ease = { + + /** + * Quadratic easing in + * @memberOf fabric.util.ease + */ + easeInQuad: function(t, b, c, d) { + return c * (t /= d) * t + b; + }, + + /** + * Quadratic easing out + * @memberOf fabric.util.ease + */ + easeOutQuad: function(t, b, c, d) { + return -c * (t /= d) * (t - 2) + b; + }, + + /** + * Quadratic easing in and out + * @memberOf fabric.util.ease + */ + easeInOutQuad: function(t, b, c, d) { + t /= (d / 2); + if (t < 1) { + return c / 2 * t * t + b; + } + return -c / 2 * ((--t) * (t - 2) - 1) + b; + }, + + /** + * Cubic easing in + * @memberOf fabric.util.ease + */ + easeInCubic: function(t, b, c, d) { + return c * (t /= d) * t * t + b; + }, + + easeOutCubic: easeOutCubic, + easeInOutCubic: easeInOutCubic, + easeInQuart: easeInQuart, + easeOutQuart: easeOutQuart, + easeInOutQuart: easeInOutQuart, + easeInQuint: easeInQuint, + easeOutQuint: easeOutQuint, + easeInOutQuint: easeInOutQuint, + easeInSine: easeInSine, + easeOutSine: easeOutSine, + easeInOutSine: easeInOutSine, + easeInExpo: easeInExpo, + easeOutExpo: easeOutExpo, + easeInOutExpo: easeInOutExpo, + easeInCirc: easeInCirc, + easeOutCirc: easeOutCirc, + easeInOutCirc: easeInOutCirc, + easeInElastic: easeInElastic, + easeOutElastic: easeOutElastic, + easeInOutElastic: easeInOutElastic, + easeInBack: easeInBack, + easeOutBack: easeOutBack, + easeInOutBack: easeInOutBack, + easeInBounce: easeInBounce, + easeOutBounce: easeOutBounce, + easeInOutBounce: easeInOutBounce + }; + +}()); + + +(function(global) { + + 'use strict'; + + /** + * @name fabric + * @namespace + */ + + var fabric = global.fabric || (global.fabric = { }), + extend = fabric.util.object.extend, + capitalize = fabric.util.string.capitalize, + clone = fabric.util.object.clone, + toFixed = fabric.util.toFixed, + parseUnit = fabric.util.parseUnit, + multiplyTransformMatrices = fabric.util.multiplyTransformMatrices, + + attributesMap = { + cx: 'left', + x: 'left', + r: 'radius', + cy: 'top', + y: 'top', + display: 'visible', + visibility: 'visible', + transform: 'transformMatrix', + 'fill-opacity': 'fillOpacity', + 'fill-rule': 'fillRule', + 'font-family': 'fontFamily', + 'font-size': 'fontSize', + 'font-style': 'fontStyle', + 'font-weight': 'fontWeight', + 'stroke-dasharray': 'strokeDashArray', + 'stroke-linecap': 'strokeLineCap', + 'stroke-linejoin': 'strokeLineJoin', + 'stroke-miterlimit': 'strokeMiterLimit', + 'stroke-opacity': 'strokeOpacity', + 'stroke-width': 'strokeWidth', + 'text-decoration': 'textDecoration', + 'text-anchor': 'originX' + }, + + colorAttributes = { + stroke: 'strokeOpacity', + fill: 'fillOpacity' + }; + + fabric.cssRules = { }; + fabric.gradientDefs = { }; + + function normalizeAttr(attr) { + // transform attribute names + if (attr in attributesMap) { + return attributesMap[attr]; + } + return attr; + } + + function normalizeValue(attr, value, parentAttributes, fontSize) { + var isArray = Object.prototype.toString.call(value) === '[object Array]', + parsed; + + if ((attr === 'fill' || attr === 'stroke') && value === 'none') { + value = ''; + } + else if (attr === 'strokeDashArray') { + value = value.replace(/,/g, ' ').split(/\s+/).map(function(n) { + return parseFloat(n); + }); + } + else if (attr === 'transformMatrix') { + if (parentAttributes && parentAttributes.transformMatrix) { + value = multiplyTransformMatrices( + parentAttributes.transformMatrix, fabric.parseTransformAttribute(value)); + } + else { + value = fabric.parseTransformAttribute(value); + } + } + else if (attr === 'visible') { + value = (value === 'none' || value === 'hidden') ? false : true; + // display=none on parent element always takes precedence over child element + if (parentAttributes && parentAttributes.visible === false) { + value = false; + } + } + else if (attr === 'originX' /* text-anchor */) { + value = value === 'start' ? 'left' : value === 'end' ? 'right' : 'center'; + } + else { + parsed = isArray ? value.map(parseUnit) : parseUnit(value, fontSize); + } + + return (!isArray && isNaN(parsed) ? value : parsed); + } + + /** + * @private + * @param {Object} attributes Array of attributes to parse + */ + function _setStrokeFillOpacity(attributes) { + for (var attr in colorAttributes) { + + if (!attributes[attr] || typeof attributes[colorAttributes[attr]] === 'undefined') { + continue; + } + + if (attributes[attr].indexOf('url(') === 0) { + continue; + } + + var color = new fabric.Color(attributes[attr]); + attributes[attr] = color.setAlpha(toFixed(color.getAlpha() * attributes[colorAttributes[attr]], 2)).toRgba(); + } + return attributes; + } + + /** + * Parses "transform" attribute, returning an array of values + * @static + * @function + * @memberOf fabric + * @param {String} attributeValue String containing attribute value + * @return {Array} Array of 6 elements representing transformation matrix + */ + fabric.parseTransformAttribute = (function() { + function rotateMatrix(matrix, args) { + var angle = args[0]; + + matrix[0] = Math.cos(angle); + matrix[1] = Math.sin(angle); + matrix[2] = -Math.sin(angle); + matrix[3] = Math.cos(angle); + } + + function scaleMatrix(matrix, args) { + var multiplierX = args[0], + multiplierY = (args.length === 2) ? args[1] : args[0]; + + matrix[0] = multiplierX; + matrix[3] = multiplierY; + } + + function skewXMatrix(matrix, args) { + matrix[2] = Math.tan(fabric.util.degreesToRadians(args[0])); + } + + function skewYMatrix(matrix, args) { + matrix[1] = Math.tan(fabric.util.degreesToRadians(args[0])); + } + + function translateMatrix(matrix, args) { + matrix[4] = args[0]; + if (args.length === 2) { + matrix[5] = args[1]; + } + } + + // identity matrix + var iMatrix = [ + 1, // a + 0, // b + 0, // c + 1, // d + 0, // e + 0 // f + ], + + // == begin transform regexp + number = fabric.reNum, + + commaWsp = '(?:\\s+,?\\s*|,\\s*)', + + skewX = '(?:(skewX)\\s*\\(\\s*(' + number + ')\\s*\\))', + + skewY = '(?:(skewY)\\s*\\(\\s*(' + number + ')\\s*\\))', + + rotate = '(?:(rotate)\\s*\\(\\s*(' + number + ')(?:' + + commaWsp + '(' + number + ')' + + commaWsp + '(' + number + '))?\\s*\\))', + + scale = '(?:(scale)\\s*\\(\\s*(' + number + ')(?:' + + commaWsp + '(' + number + '))?\\s*\\))', + + translate = '(?:(translate)\\s*\\(\\s*(' + number + ')(?:' + + commaWsp + '(' + number + '))?\\s*\\))', + + matrix = '(?:(matrix)\\s*\\(\\s*' + + '(' + number + ')' + commaWsp + + '(' + number + ')' + commaWsp + + '(' + number + ')' + commaWsp + + '(' + number + ')' + commaWsp + + '(' + number + ')' + commaWsp + + '(' + number + ')' + + '\\s*\\))', + + transform = '(?:' + + matrix + '|' + + translate + '|' + + scale + '|' + + rotate + '|' + + skewX + '|' + + skewY + + ')', + + transforms = '(?:' + transform + '(?:' + commaWsp + transform + ')*' + ')', + + transformList = '^\\s*(?:' + transforms + '?)\\s*$', + + // http://www.w3.org/TR/SVG/coords.html#TransformAttribute + reTransformList = new RegExp(transformList), + // == end transform regexp + + reTransform = new RegExp(transform, 'g'); + + return function(attributeValue) { + + // start with identity matrix + var matrix = iMatrix.concat(), + matrices = [ ]; + + // return if no argument was given or + // an argument does not match transform attribute regexp + if (!attributeValue || (attributeValue && !reTransformList.test(attributeValue))) { + return matrix; + } + + attributeValue.replace(reTransform, function(match) { + + var m = new RegExp(transform).exec(match).filter(function (match) { + return (match !== '' && match != null); + }), + operation = m[1], + args = m.slice(2).map(parseFloat); + + switch (operation) { + case 'translate': + translateMatrix(matrix, args); + break; + case 'rotate': + args[0] = fabric.util.degreesToRadians(args[0]); + rotateMatrix(matrix, args); + break; + case 'scale': + scaleMatrix(matrix, args); + break; + case 'skewX': + skewXMatrix(matrix, args); + break; + case 'skewY': + skewYMatrix(matrix, args); + break; + case 'matrix': + matrix = args; + break; + } + + // snapshot current matrix into matrices array + matrices.push(matrix.concat()); + // reset + matrix = iMatrix.concat(); + }); + + var combinedMatrix = matrices[0]; + while (matrices.length > 1) { + matrices.shift(); + combinedMatrix = fabric.util.multiplyTransformMatrices(combinedMatrix, matrices[0]); + } + return combinedMatrix; + }; + })(); + + /** + * @private + */ + function parseStyleString(style, oStyle) { + var attr, value; + style.replace(/;$/, '').split(';').forEach(function (chunk) { + var pair = chunk.split(':'); + + attr = normalizeAttr(pair[0].trim().toLowerCase()); + value = normalizeValue(attr, pair[1].trim()); + + oStyle[attr] = value; + }); + } + + /** + * @private + */ + function parseStyleObject(style, oStyle) { + var attr, value; + for (var prop in style) { + if (typeof style[prop] === 'undefined') { + continue; + } + + attr = normalizeAttr(prop.toLowerCase()); + value = normalizeValue(attr, style[prop]); + + oStyle[attr] = value; + } + } + + /** + * @private + */ + function getGlobalStylesForElement(element, svgUid) { + var styles = { }; + for (var rule in fabric.cssRules[svgUid]) { + if (elementMatchesRule(element, rule.split(' '))) { + for (var property in fabric.cssRules[svgUid][rule]) { + styles[property] = fabric.cssRules[svgUid][rule][property]; + } + } + } + return styles; + } + + /** + * @private + */ + function elementMatchesRule(element, selectors) { + var firstMatching, parentMatching = true; + //start from rightmost selector. + firstMatching = selectorMatches(element, selectors.pop()); + if (firstMatching && selectors.length) { + parentMatching = doesSomeParentMatch(element, selectors); + } + return firstMatching && parentMatching && (selectors.length === 0); + } + + function doesSomeParentMatch(element, selectors) { + var selector, parentMatching = true; + while (element.parentNode && element.parentNode.nodeType === 1 && selectors.length) { + if (parentMatching) { + selector = selectors.pop(); + } + element = element.parentNode; + parentMatching = selectorMatches(element, selector); + } + return selectors.length === 0; + } + /** + * @private + */ + function selectorMatches(element, selector) { + var nodeName = element.nodeName, + classNames = element.getAttribute('class'), + id = element.getAttribute('id'), matcher; + // i check if a selector matches slicing away part from it. + // if i get empty string i should match + matcher = new RegExp('^' + nodeName, 'i'); + selector = selector.replace(matcher, ''); + if (id && selector.length) { + matcher = new RegExp('#' + id + '(?![a-zA-Z\\-]+)', 'i'); + selector = selector.replace(matcher, ''); + } + if (classNames && selector.length) { + classNames = classNames.split(' '); + for (var i = classNames.length; i--;) { + matcher = new RegExp('\\.' + classNames[i] + '(?![a-zA-Z\\-]+)', 'i'); + selector = selector.replace(matcher, ''); + } + } + return selector.length === 0; + } + + /** + * @private + */ + function parseUseDirectives(doc) { + var nodelist = doc.getElementsByTagName('use'); + while (nodelist.length) { + var el = nodelist[0], + xlink = el.getAttribute('xlink:href').substr(1), + x = el.getAttribute('x') || 0, + y = el.getAttribute('y') || 0, + el2 = doc.getElementById(xlink).cloneNode(true), + currentTrans = (el2.getAttribute('transform') || '') + ' translate(' + x + ', ' + y + ')', + parentNode; + + for (var j = 0, attrs = el.attributes, l = attrs.length; j < l; j++) { + var attr = attrs.item(j); + if (attr.nodeName === 'x' || attr.nodeName === 'y' || attr.nodeName === 'xlink:href') { + continue; + } + + if (attr.nodeName === 'transform') { + currentTrans = attr.nodeValue + ' ' + currentTrans; + } + else { + el2.setAttribute(attr.nodeName, attr.nodeValue); + } + } + + el2.setAttribute('transform', currentTrans); + el2.setAttribute('instantiated_by_use', '1'); + el2.removeAttribute('id'); + parentNode = el.parentNode; + parentNode.replaceChild(el2, el); + } + } + + // http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute + // matches, e.g.: +14.56e-12, etc. + var reViewBoxAttrValue = new RegExp( + '^' + + '\\s*(' + fabric.reNum + '+)\\s*,?' + + '\\s*(' + fabric.reNum + '+)\\s*,?' + + '\\s*(' + fabric.reNum + '+)\\s*,?' + + '\\s*(' + fabric.reNum + '+)\\s*' + + '$' + ); + + /** + * Add a element that envelop all child elements and makes the viewbox transformMatrix descend on all elements + */ + function addVBTransform(element, widthAttr, heightAttr) { + + var viewBoxAttr = element.getAttribute('viewBox'), + scaleX = 1, + scaleY = 1, + minX = 0, + minY = 0, + viewBoxWidth, viewBoxHeight, matrix, el; + + if (viewBoxAttr && (viewBoxAttr = viewBoxAttr.match(reViewBoxAttrValue))) { + minX = -parseFloat(viewBoxAttr[1]), + minY = -parseFloat(viewBoxAttr[2]), + viewBoxWidth = parseFloat(viewBoxAttr[3]), + viewBoxHeight = parseFloat(viewBoxAttr[4]); + } + else { + return; + } + if (widthAttr && widthAttr !== viewBoxWidth) { + scaleX = widthAttr / viewBoxWidth; + } + if (heightAttr && heightAttr !== viewBoxHeight) { + scaleY = heightAttr / viewBoxHeight; + } + + // default is to preserve aspect ratio + // preserveAspectRatio attribute to be implemented + scaleY = scaleX = (scaleX > scaleY ? scaleY : scaleX); + + if (!(scaleX !== 1 || scaleY !== 1 || minX !== 0 || minY !== 0)) { + return; + } + matrix = ' matrix(' + scaleX + + ' 0' + + ' 0 ' + + scaleY + ' ' + + (minX * scaleX) + ' ' + + (minY * scaleY) + ') '; + + if (element.tagName === 'svg') { + el = element.ownerDocument.createElement('g'); + while (element.firstChild != null) { + el.appendChild(element.firstChild); + } + element.appendChild(el); + } + else { + el = element; + matrix = el.getAttribute('transform') + matrix; + } + + el.setAttribute('transform', matrix); + } + + /** + * Parses an SVG document, converts it to an array of corresponding fabric.* instances and passes them to a callback + * @static + * @function + * @memberOf fabric + * @param {SVGDocument} doc SVG document to parse + * @param {Function} callback Callback to call when parsing is finished; It's being passed an array of elements (parsed from a document). + * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created. + */ + fabric.parseSVGDocument = (function() { + + var reAllowedSVGTagNames = /^(path|circle|polygon|polyline|ellipse|rect|line|image|text)$/, + reViewBoxTagNames = /^(symbol|image|marker|pattern|view)$/; + + function hasAncestorWithNodeName(element, nodeName) { + while (element && (element = element.parentNode)) { + if (nodeName.test(element.nodeName) && !element.getAttribute('instantiated_by_use')) { + return true; + } + } + return false; + } + + return function(doc, callback, reviver) { + if (!doc) { + return; + } + + parseUseDirectives(doc); + + var startTime = new Date(), + svgUid = fabric.Object.__uid++, + widthAttr, heightAttr, toBeParsed = false; + + if (doc.getAttribute('width') && doc.getAttribute('width') !== '100%') { + widthAttr = parseUnit(doc.getAttribute('width')); + } + if (doc.getAttribute('height') && doc.getAttribute('height') !== '100%') { + heightAttr = parseUnit(doc.getAttribute('height')); + } + + if (!widthAttr || !heightAttr) { + var viewBoxAttr = doc.getAttribute('viewBox'); + if (viewBoxAttr && (viewBoxAttr = viewBoxAttr.match(reViewBoxAttrValue))) { + widthAttr = parseFloat(viewBoxAttr[3]), + heightAttr = parseFloat(viewBoxAttr[4]); + } + else { + toBeParsed = true; + } + } + + addVBTransform(doc, widthAttr, heightAttr); + + var descendants = fabric.util.toArray(doc.getElementsByTagName('*')); + + if (descendants.length === 0 && fabric.isLikelyNode) { + // we're likely in node, where "o3-xml" library fails to gEBTN("*") + // https://github.com/ajaxorg/node-o3-xml/issues/21 + descendants = doc.selectNodes('//*[name(.)!="svg"]'); + var arr = [ ]; + for (var i = 0, len = descendants.length; i < len; i++) { + arr[i] = descendants[i]; + } + descendants = arr; + } + + var elements = descendants.filter(function(el) { + reViewBoxTagNames.test(el.tagName) && addVBTransform(el, 0, 0); + return reAllowedSVGTagNames.test(el.tagName) && + !hasAncestorWithNodeName(el, /^(?:pattern|defs|symbol)$/); // http://www.w3.org/TR/SVG/struct.html#DefsElement + }); + + if (!elements || (elements && !elements.length)) { + callback && callback([], {}); + return; + } + + var options = { + width: widthAttr, + height: heightAttr, + svgUid: svgUid, + toBeParsed: toBeParsed + }; + + fabric.gradientDefs[svgUid] = fabric.getGradientDefs(doc); + fabric.cssRules[svgUid] = fabric.getCSSRules(doc); + // Precedence of rules: style > class > attribute + fabric.parseElements(elements, function(instances) { + fabric.documentParsingTime = new Date() - startTime; + if (callback) { + callback(instances, options); + } + }, clone(options), reviver); + }; + })(); + + /** + * Used for caching SVG documents (loaded via `fabric.Canvas#loadSVGFromURL`) + * @namespace + */ + var svgCache = { + + /** + * @param {String} name + * @param {Function} callback + */ + has: function (name, callback) { + callback(false); + }, + + get: function () { + /* NOOP */ + }, + + set: function () { + /* NOOP */ + } + }; + + /** + * @private + */ + function _enlivenCachedObject(cachedObject) { + + var objects = cachedObject.objects, + options = cachedObject.options; + + objects = objects.map(function (o) { + return fabric[capitalize(o.type)].fromObject(o); + }); + + return ({ objects: objects, options: options }); + } + + /** + * @private + */ + function _createSVGPattern(markup, canvas, property) { + if (canvas[property] && canvas[property].toSVG) { + markup.push( + '', + '' + ); + } + } + + var reFontDeclaration = new RegExp( + '(normal|italic)?\\s*(normal|small-caps)?\\s*' + + '(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\s*(' + + fabric.reNum + + '(?:px|cm|mm|em|pt|pc|in)*)(?:\\/(normal|' + fabric.reNum + '))?\\s+(.*)'); + + extend(fabric, { + /** + * Parses a short font declaration, building adding its properties to a style object + * @static + * @function + * @memberOf fabric + * @param {String} value font declaration + * @param {Object} oStyle definition + */ + parseFontDeclaration: function(value, oStyle) { + var match = value.match(reFontDeclaration); + + if (!match) { + return; + } + var fontStyle = match[1], + // font variant is not used + // fontVariant = match[2], + fontWeight = match[3], + fontSize = match[4], + lineHeight = match[5], + fontFamily = match[6]; + + if (fontStyle) { + oStyle.fontStyle = fontStyle; + } + if (fontWeight) { + oStyle.fontWeight = isNaN(parseFloat(fontWeight)) ? fontWeight : parseFloat(fontWeight); + } + if (fontSize) { + oStyle.fontSize = parseUnit(fontSize); + } + if (fontFamily) { + oStyle.fontFamily = fontFamily; + } + if (lineHeight) { + oStyle.lineHeight = lineHeight === 'normal' ? 1 : lineHeight; + } + }, + + /** + * Parses an SVG document, returning all of the gradient declarations found in it + * @static + * @function + * @memberOf fabric + * @param {SVGDocument} doc SVG document to parse + * @return {Object} Gradient definitions; key corresponds to element id, value -- to gradient definition element + */ + getGradientDefs: function(doc) { + var linearGradientEls = doc.getElementsByTagName('linearGradient'), + radialGradientEls = doc.getElementsByTagName('radialGradient'), + el, i, j = 0, id, xlink, elList = [ ], + gradientDefs = { }, idsToXlinkMap = { }; + + elList.length = linearGradientEls.length + radialGradientEls.length; + i = linearGradientEls.length; + while (i--) { + elList[j++] = linearGradientEls[i]; + } + i = radialGradientEls.length; + while (i--) { + elList[j++] = radialGradientEls[i]; + } + + while (j--) { + el = elList[j]; + xlink = el.getAttribute('xlink:href'); + id = el.getAttribute('id'); + if (xlink) { + idsToXlinkMap[id] = xlink.substr(1); + } + gradientDefs[id] = el; + } + + for (id in idsToXlinkMap) { + var el2 = gradientDefs[idsToXlinkMap[id]].cloneNode(true); + el = gradientDefs[id]; + while (el2.firstChild) { + el.appendChild(el2.firstChild); + } + } + return gradientDefs; + }, + + /** + * Returns an object of attributes' name/value, given element and an array of attribute names; + * Parses parent "g" nodes recursively upwards. + * @static + * @memberOf fabric + * @param {DOMElement} element Element to parse + * @param {Array} attributes Array of attributes to parse + * @return {Object} object containing parsed attributes' names/values + */ + parseAttributes: function(element, attributes, svgUid) { + + if (!element) { + return; + } + + var value, + parentAttributes = { }, + fontSize; + + if (typeof svgUid === 'undefined') { + svgUid = element.getAttribute('svgUid'); + } + // if there's a parent container (`g` or `a` or `symbol` node), parse its attributes recursively upwards + if (element.parentNode && /^symbol|[g|a]$/i.test(element.parentNode.nodeName)) { + parentAttributes = fabric.parseAttributes(element.parentNode, attributes, svgUid); + } + fontSize = (parentAttributes && parentAttributes.fontSize ) || + element.getAttribute('font-size') || fabric.Text.DEFAULT_SVG_FONT_SIZE; + + var ownAttributes = attributes.reduce(function(memo, attr) { + value = element.getAttribute(attr); + if (value) { + attr = normalizeAttr(attr); + value = normalizeValue(attr, value, parentAttributes, fontSize); + + memo[attr] = value; + } + return memo; + }, { }); + + // add values parsed from style, which take precedence over attributes + // (see: http://www.w3.org/TR/SVG/styling.html#UsingPresentationAttributes) + ownAttributes = extend(ownAttributes, + extend(getGlobalStylesForElement(element, svgUid), fabric.parseStyleAttribute(element))); + if (ownAttributes.font) { + fabric.parseFontDeclaration(ownAttributes.font, ownAttributes); + } + return _setStrokeFillOpacity(extend(parentAttributes, ownAttributes)); + }, + + /** + * Transforms an array of svg elements to corresponding fabric.* instances + * @static + * @memberOf fabric + * @param {Array} elements Array of elements to parse + * @param {Function} callback Being passed an array of fabric instances (transformed from SVG elements) + * @param {Object} [options] Options object + * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created. + */ + parseElements: function(elements, callback, options, reviver) { + new fabric.ElementsParser(elements, callback, options, reviver).parse(); + }, + + /** + * Parses "style" attribute, retuning an object with values + * @static + * @memberOf fabric + * @param {SVGElement} element Element to parse + * @return {Object} Objects with values parsed from style attribute of an element + */ + parseStyleAttribute: function(element) { + var oStyle = { }, + style = element.getAttribute('style'); + + if (!style) { + return oStyle; + } + + if (typeof style === 'string') { + parseStyleString(style, oStyle); + } + else { + parseStyleObject(style, oStyle); + } + + return oStyle; + }, + + /** + * Parses "points" attribute, returning an array of values + * @static + * @memberOf fabric + * @param {String} points points attribute string + * @return {Array} array of points + */ + parsePointsAttribute: function(points) { + + // points attribute is required and must not be empty + if (!points) { + return null; + } + + // replace commas with whitespace and remove bookending whitespace + points = points.replace(/,/g, ' ').trim(); + + points = points.split(/\s+/); + var parsedPoints = [ ], i, len; + + i = 0; + len = points.length; + for (; i < len; i+=2) { + parsedPoints.push({ + x: parseFloat(points[i]), + y: parseFloat(points[i + 1]) + }); + } + + // odd number of points is an error + // if (parsedPoints.length % 2 !== 0) { + // return null; + // } + + return parsedPoints; + }, + + /** + * Returns CSS rules for a given SVG document + * @static + * @function + * @memberOf fabric + * @param {SVGDocument} doc SVG document to parse + * @return {Object} CSS rules of this document + */ + getCSSRules: function(doc) { + var styles = doc.getElementsByTagName('style'), + allRules = { }, rules; + + // very crude parsing of style contents + for (var i = 0, len = styles.length; i < len; i++) { + var styleContents = styles[i].textContent; + + // remove comments + styleContents = styleContents.replace(/\/\*[\s\S]*?\*\//g, ''); + if (styleContents.trim() === '') { + continue; + } + rules = styleContents.match(/[^{]*\{[\s\S]*?\}/g); + rules = rules.map(function(rule) { return rule.trim(); }); + + rules.forEach(function(rule) { + + var match = rule.match(/([\s\S]*?)\s*\{([^}]*)\}/), + ruleObj = { }, declaration = match[2].trim(), + propertyValuePairs = declaration.replace(/;$/, '').split(/\s*;\s*/); + + for (var i = 0, len = propertyValuePairs.length; i < len; i++) { + var pair = propertyValuePairs[i].split(/\s*:\s*/), + property = normalizeAttr(pair[0]), + value = normalizeValue(property, pair[1], pair[0]); + ruleObj[property] = value; + } + rule = match[1]; + rule.split(',').forEach(function(_rule) { + _rule = _rule.replace(/^svg/i, '').trim(); + if (_rule === '') { + return; + } + allRules[_rule] = fabric.util.object.clone(ruleObj); + }); + }); + } + return allRules; + }, + + /** + * Takes url corresponding to an SVG document, and parses it into a set of fabric objects. Note that SVG is fetched via XMLHttpRequest, so it needs to conform to SOP (Same Origin Policy) + * @memberof fabric + * @param {String} url + * @param {Function} callback + * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created. + */ + loadSVGFromURL: function(url, callback, reviver) { + + url = url.replace(/^\n\s*/, '').trim(); + svgCache.has(url, function (hasUrl) { + if (hasUrl) { + svgCache.get(url, function (value) { + var enlivedRecord = _enlivenCachedObject(value); + callback(enlivedRecord.objects, enlivedRecord.options); + }); + } + else { + new fabric.util.request(url, { + method: 'get', + onComplete: onComplete + }); + } + }); + + function onComplete(r) { + + var xml = r.responseXML; + if (xml && !xml.documentElement && fabric.window.ActiveXObject && r.responseText) { + xml = new ActiveXObject('Microsoft.XMLDOM'); + xml.async = 'false'; + //IE chokes on DOCTYPE + xml.loadXML(r.responseText.replace(//i, '')); + } + if (!xml || !xml.documentElement) { + return; + } + + fabric.parseSVGDocument(xml.documentElement, function (results, options) { + svgCache.set(url, { + objects: fabric.util.array.invoke(results, 'toObject'), + options: options + }); + callback(results, options); + }, reviver); + } + }, + + /** + * Takes string corresponding to an SVG document, and parses it into a set of fabric objects + * @memberof fabric + * @param {String} string + * @param {Function} callback + * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created. + */ + loadSVGFromString: function(string, callback, reviver) { + string = string.trim(); + var doc; + if (typeof DOMParser !== 'undefined') { + var parser = new DOMParser(); + if (parser && parser.parseFromString) { + doc = parser.parseFromString(string, 'text/xml'); + } + } + else if (fabric.window.ActiveXObject) { + doc = new ActiveXObject('Microsoft.XMLDOM'); + doc.async = 'false'; + // IE chokes on DOCTYPE + doc.loadXML(string.replace(//i, '')); + } + + fabric.parseSVGDocument(doc.documentElement, function (results, options) { + callback(results, options); + }, reviver); + }, + + /** + * Creates markup containing SVG font faces + * @param {Array} objects Array of fabric objects + * @return {String} + */ + createSVGFontFacesMarkup: function(objects) { + var markup = ''; + + for (var i = 0, len = objects.length; i < len; i++) { + if (objects[i].type !== 'text' || !objects[i].path) { + continue; + } + + markup += [ + //jscs:disable validateIndentation + '@font-face {', + 'font-family: ', objects[i].fontFamily, '; ', + 'src: url(\'', objects[i].path, '\')', + '}' + //jscs:enable validateIndentation + ].join(''); + } + + if (markup) { + markup = [ + //jscs:disable validateIndentation + '' + //jscs:enable validateIndentation + ].join(''); + } + + return markup; + }, + + /** + * Creates markup containing SVG referenced elements like patterns, gradients etc. + * @param {fabric.Canvas} canvas instance of fabric.Canvas + * @return {String} + */ + createSVGRefElementsMarkup: function(canvas) { + var markup = [ ]; + + _createSVGPattern(markup, canvas, 'backgroundColor'); + _createSVGPattern(markup, canvas, 'overlayColor'); + + return markup.join(''); + } + }); + +})(typeof exports !== 'undefined' ? exports : this); + + +fabric.ElementsParser = function(elements, callback, options, reviver) { + this.elements = elements; + this.callback = callback; + this.options = options; + this.reviver = reviver; + this.svgUid = (options && options.svgUid) || 0; +}; + +fabric.ElementsParser.prototype.parse = function() { + this.instances = new Array(this.elements.length); + this.numElements = this.elements.length; + + this.createObjects(); +}; + +fabric.ElementsParser.prototype.createObjects = function() { + for (var i = 0, len = this.elements.length; i < len; i++) { + this.elements[i].setAttribute('svgUid', this.svgUid); + (function(_this, i) { + setTimeout(function() { + _this.createObject(_this.elements[i], i); + }, 0); + })(this, i); + } +}; + +fabric.ElementsParser.prototype.createObject = function(el, index) { + var klass = fabric[fabric.util.string.capitalize(el.tagName)]; + if (klass && klass.fromElement) { + try { + this._createObject(klass, el, index); + } + catch (err) { + fabric.log(err); + } + } + else { + this.checkIfDone(); + } +}; + +fabric.ElementsParser.prototype._createObject = function(klass, el, index) { + if (klass.async) { + klass.fromElement(el, this.createCallback(index, el), this.options); + } + else { + var obj = klass.fromElement(el, this.options); + this.resolveGradient(obj, 'fill'); + this.resolveGradient(obj, 'stroke'); + this.reviver && this.reviver(el, obj); + this.instances[index] = obj; + this.checkIfDone(); + } +}; + +fabric.ElementsParser.prototype.createCallback = function(index, el) { + var _this = this; + return function(obj) { + _this.resolveGradient(obj, 'fill'); + _this.resolveGradient(obj, 'stroke'); + _this.reviver && _this.reviver(el, obj); + _this.instances[index] = obj; + _this.checkIfDone(); + }; +}; + +fabric.ElementsParser.prototype.resolveGradient = function(obj, property) { + + var instanceFillValue = obj.get(property); + if (!(/^url\(/).test(instanceFillValue)) { + return; + } + var gradientId = instanceFillValue.slice(5, instanceFillValue.length - 1); + if (fabric.gradientDefs[this.svgUid][gradientId]) { + obj.set(property, + fabric.Gradient.fromElement(fabric.gradientDefs[this.svgUid][gradientId], obj)); + } +}; + +fabric.ElementsParser.prototype.checkIfDone = function() { + if (--this.numElements === 0) { + this.instances = this.instances.filter(function(el) { + return el != null; + }); + this.callback(this.instances); + } +}; + + +(function(global) { + + 'use strict'; + + /* Adaptation of work of Kevin Lindsey (kevin@kevlindev.com) */ + + var fabric = global.fabric || (global.fabric = { }); + + if (fabric.Point) { + fabric.warn('fabric.Point is already defined'); + return; + } + + fabric.Point = Point; + + /** + * Point class + * @class fabric.Point + * @memberOf fabric + * @constructor + * @param {Number} x + * @param {Number} y + * @return {fabric.Point} thisArg + */ + function Point(x, y) { + this.x = x; + this.y = y; + } + + Point.prototype = /** @lends fabric.Point.prototype */ { + + constructor: Point, + + /** + * Adds another point to this one and returns another one + * @param {fabric.Point} that + * @return {fabric.Point} new Point instance with added values + */ + add: function (that) { + return new Point(this.x + that.x, this.y + that.y); + }, + + /** + * Adds another point to this one + * @param {fabric.Point} that + * @return {fabric.Point} thisArg + */ + addEquals: function (that) { + this.x += that.x; + this.y += that.y; + return this; + }, + + /** + * Adds value to this point and returns a new one + * @param {Number} scalar + * @return {fabric.Point} new Point with added value + */ + scalarAdd: function (scalar) { + return new Point(this.x + scalar, this.y + scalar); + }, + + /** + * Adds value to this point + * @param {Number} scalar + * @return {fabric.Point} thisArg + */ + scalarAddEquals: function (scalar) { + this.x += scalar; + this.y += scalar; + return this; + }, + + /** + * Subtracts another point from this point and returns a new one + * @param {fabric.Point} that + * @return {fabric.Point} new Point object with subtracted values + */ + subtract: function (that) { + return new Point(this.x - that.x, this.y - that.y); + }, + + /** + * Subtracts another point from this point + * @param {fabric.Point} that + * @return {fabric.Point} thisArg + */ + subtractEquals: function (that) { + this.x -= that.x; + this.y -= that.y; + return this; + }, + + /** + * Subtracts value from this point and returns a new one + * @param {Number} scalar + * @return {fabric.Point} + */ + scalarSubtract: function (scalar) { + return new Point(this.x - scalar, this.y - scalar); + }, + + /** + * Subtracts value from this point + * @param {Number} scalar + * @return {fabric.Point} thisArg + */ + scalarSubtractEquals: function (scalar) { + this.x -= scalar; + this.y -= scalar; + return this; + }, + + /** + * Miltiplies this point by a value and returns a new one + * @param {Number} scalar + * @return {fabric.Point} + */ + multiply: function (scalar) { + return new Point(this.x * scalar, this.y * scalar); + }, + + /** + * Miltiplies this point by a value + * @param {Number} scalar + * @return {fabric.Point} thisArg + */ + multiplyEquals: function (scalar) { + this.x *= scalar; + this.y *= scalar; + return this; + }, + + /** + * Divides this point by a value and returns a new one + * @param {Number} scalar + * @return {fabric.Point} + */ + divide: function (scalar) { + return new Point(this.x / scalar, this.y / scalar); + }, + + /** + * Divides this point by a value + * @param {Number} scalar + * @return {fabric.Point} thisArg + */ + divideEquals: function (scalar) { + this.x /= scalar; + this.y /= scalar; + return this; + }, + + /** + * Returns true if this point is equal to another one + * @param {fabric.Point} that + * @return {Boolean} + */ + eq: function (that) { + return (this.x === that.x && this.y === that.y); + }, + + /** + * Returns true if this point is less than another one + * @param {fabric.Point} that + * @return {Boolean} + */ + lt: function (that) { + return (this.x < that.x && this.y < that.y); + }, + + /** + * Returns true if this point is less than or equal to another one + * @param {fabric.Point} that + * @return {Boolean} + */ + lte: function (that) { + return (this.x <= that.x && this.y <= that.y); + }, + + /** + + * Returns true if this point is greater another one + * @param {fabric.Point} that + * @return {Boolean} + */ + gt: function (that) { + return (this.x > that.x && this.y > that.y); + }, + + /** + * Returns true if this point is greater than or equal to another one + * @param {fabric.Point} that + * @return {Boolean} + */ + gte: function (that) { + return (this.x >= that.x && this.y >= that.y); + }, + + /** + * Returns new point which is the result of linear interpolation with this one and another one + * @param {fabric.Point} that + * @param {Number} t + * @return {fabric.Point} + */ + lerp: function (that, t) { + return new Point(this.x + (that.x - this.x) * t, this.y + (that.y - this.y) * t); + }, + + /** + * Returns distance from this point and another one + * @param {fabric.Point} that + * @return {Number} + */ + distanceFrom: function (that) { + var dx = this.x - that.x, + dy = this.y - that.y; + return Math.sqrt(dx * dx + dy * dy); + }, + + /** + * Returns the point between this point and another one + * @param {fabric.Point} that + * @return {fabric.Point} + */ + midPointFrom: function (that) { + return new Point(this.x + (that.x - this.x)/2, this.y + (that.y - this.y)/2); + }, + + /** + * Returns a new point which is the min of this and another one + * @param {fabric.Point} that + * @return {fabric.Point} + */ + min: function (that) { + return new Point(Math.min(this.x, that.x), Math.min(this.y, that.y)); + }, + + /** + * Returns a new point which is the max of this and another one + * @param {fabric.Point} that + * @return {fabric.Point} + */ + max: function (that) { + return new Point(Math.max(this.x, that.x), Math.max(this.y, that.y)); + }, + + /** + * Returns string representation of this point + * @return {String} + */ + toString: function () { + return this.x + ',' + this.y; + }, + + /** + * Sets x/y of this point + * @param {Number} x + * @param {Number} y + */ + setXY: function (x, y) { + this.x = x; + this.y = y; + }, + + /** + * Sets x/y of this point from another point + * @param {fabric.Point} that + */ + setFromPoint: function (that) { + this.x = that.x; + this.y = that.y; + }, + + /** + * Swaps x/y of this point and another point + * @param {fabric.Point} that + */ + swap: function (that) { + var x = this.x, + y = this.y; + this.x = that.x; + this.y = that.y; + that.x = x; + that.y = y; + } + }; + +})(typeof exports !== 'undefined' ? exports : this); + + +(function(global) { + + 'use strict'; + + /* Adaptation of work of Kevin Lindsey (kevin@kevlindev.com) */ + var fabric = global.fabric || (global.fabric = { }); + + if (fabric.Intersection) { + fabric.warn('fabric.Intersection is already defined'); + return; + } + + /** + * Intersection class + * @class fabric.Intersection + * @memberOf fabric + * @constructor + */ + function Intersection(status) { + this.status = status; + this.points = []; + } + + fabric.Intersection = Intersection; + + fabric.Intersection.prototype = /** @lends fabric.Intersection.prototype */ { + + /** + * Appends a point to intersection + * @param {fabric.Point} point + */ + appendPoint: function (point) { + this.points.push(point); + }, + + /** + * Appends points to intersection + * @param {Array} points + */ + appendPoints: function (points) { + this.points = this.points.concat(points); + } + }; + + /** + * Checks if one line intersects another + * @static + * @param {fabric.Point} a1 + * @param {fabric.Point} a2 + * @param {fabric.Point} b1 + * @param {fabric.Point} b2 + * @return {fabric.Intersection} + */ + fabric.Intersection.intersectLineLine = function (a1, a2, b1, b2) { + var result, + uaT = (b2.x - b1.x) * (a1.y - b1.y) - (b2.y - b1.y) * (a1.x - b1.x), + ubT = (a2.x - a1.x) * (a1.y - b1.y) - (a2.y - a1.y) * (a1.x - b1.x), + uB = (b2.y - b1.y) * (a2.x - a1.x) - (b2.x - b1.x) * (a2.y - a1.y); + if (uB !== 0) { + var ua = uaT / uB, + ub = ubT / uB; + if (0 <= ua && ua <= 1 && 0 <= ub && ub <= 1) { + result = new Intersection('Intersection'); + result.points.push(new fabric.Point(a1.x + ua * (a2.x - a1.x), a1.y + ua * (a2.y - a1.y))); + } + else { + result = new Intersection(); + } + } + else { + if (uaT === 0 || ubT === 0) { + result = new Intersection('Coincident'); + } + else { + result = new Intersection('Parallel'); + } + } + return result; + }; + + /** + * Checks if line intersects polygon + * @static + * @param {fabric.Point} a1 + * @param {fabric.Point} a2 + * @param {Array} points + * @return {fabric.Intersection} + */ + fabric.Intersection.intersectLinePolygon = function(a1, a2, points) { + var result = new Intersection(), + length = points.length; + + for (var i = 0; i < length; i++) { + var b1 = points[i], + b2 = points[(i + 1) % length], + inter = Intersection.intersectLineLine(a1, a2, b1, b2); + + result.appendPoints(inter.points); + } + if (result.points.length > 0) { + result.status = 'Intersection'; + } + return result; + }; + + /** + * Checks if polygon intersects another polygon + * @static + * @param {Array} points1 + * @param {Array} points2 + * @return {fabric.Intersection} + */ + fabric.Intersection.intersectPolygonPolygon = function (points1, points2) { + var result = new Intersection(), + length = points1.length; + + for (var i = 0; i < length; i++) { + var a1 = points1[i], + a2 = points1[(i + 1) % length], + inter = Intersection.intersectLinePolygon(a1, a2, points2); + + result.appendPoints(inter.points); + } + if (result.points.length > 0) { + result.status = 'Intersection'; + } + return result; + }; + + /** + * Checks if polygon intersects rectangle + * @static + * @param {Array} points + * @param {Number} r1 + * @param {Number} r2 + * @return {fabric.Intersection} + */ + fabric.Intersection.intersectPolygonRectangle = function (points, r1, r2) { + var min = r1.min(r2), + max = r1.max(r2), + topRight = new fabric.Point(max.x, min.y), + bottomLeft = new fabric.Point(min.x, max.y), + inter1 = Intersection.intersectLinePolygon(min, topRight, points), + inter2 = Intersection.intersectLinePolygon(topRight, max, points), + inter3 = Intersection.intersectLinePolygon(max, bottomLeft, points), + inter4 = Intersection.intersectLinePolygon(bottomLeft, min, points), + result = new Intersection(); + + result.appendPoints(inter1.points); + result.appendPoints(inter2.points); + result.appendPoints(inter3.points); + result.appendPoints(inter4.points); + + if (result.points.length > 0) { + result.status = 'Intersection'; + } + return result; + }; + +})(typeof exports !== 'undefined' ? exports : this); + + +(function(global) { + + 'use strict'; + + var fabric = global.fabric || (global.fabric = { }); + + if (fabric.Color) { + fabric.warn('fabric.Color is already defined.'); + return; + } + + /** + * Color class + * The purpose of {@link fabric.Color} is to abstract and encapsulate common color operations; + * {@link fabric.Color} is a constructor and creates instances of {@link fabric.Color} objects. + * + * @class fabric.Color + * @param {String} color optional in hex or rgb(a) format + * @return {fabric.Color} thisArg + * @tutorial {@link http://fabricjs.com/fabric-intro-part-2/#colors} + */ + function Color(color) { + if (!color) { + this.setSource([0, 0, 0, 1]); + } + else { + this._tryParsingColor(color); + } + } + + fabric.Color = Color; + + fabric.Color.prototype = /** @lends fabric.Color.prototype */ { + + /** + * @private + * @param {String|Array} color Color value to parse + */ + _tryParsingColor: function(color) { + var source; + + if (color in Color.colorNameMap) { + color = Color.colorNameMap[color]; + } + + if (color === 'transparent') { + this.setSource([255, 255, 255, 0]); + return; + } + + source = Color.sourceFromHex(color); + + if (!source) { + source = Color.sourceFromRgb(color); + } + if (!source) { + source = Color.sourceFromHsl(color); + } + if (source) { + this.setSource(source); + } + }, + + /** + * Adapted from https://github.com/mjijackson + * @private + * @param {Number} r Red color value + * @param {Number} g Green color value + * @param {Number} b Blue color value + * @return {Array} Hsl color + */ + _rgbToHsl: function(r, g, b) { + r /= 255, g /= 255, b /= 255; + + var h, s, l, + max = fabric.util.array.max([r, g, b]), + min = fabric.util.array.min([r, g, b]); + + l = (max + min) / 2; + + if (max === min) { + h = s = 0; // achromatic + } + else { + var d = max - min; + s = l > 0.5 ? d / (2 - max - min) : d / (max + min); + switch (max) { + case r: + h = (g - b) / d + (g < b ? 6 : 0); + break; + case g: + h = (b - r) / d + 2; + break; + case b: + h = (r - g) / d + 4; + break; + } + h /= 6; + } + + return [ + Math.round(h * 360), + Math.round(s * 100), + Math.round(l * 100) + ]; + }, + + /** + * Returns source of this color (where source is an array representation; ex: [200, 200, 100, 1]) + * @return {Array} + */ + getSource: function() { + return this._source; + }, + + /** + * Sets source of this color (where source is an array representation; ex: [200, 200, 100, 1]) + * @param {Array} source + */ + setSource: function(source) { + this._source = source; + }, + + /** + * Returns color represenation in RGB format + * @return {String} ex: rgb(0-255,0-255,0-255) + */ + toRgb: function() { + var source = this.getSource(); + return 'rgb(' + source[0] + ',' + source[1] + ',' + source[2] + ')'; + }, + + /** + * Returns color represenation in RGBA format + * @return {String} ex: rgba(0-255,0-255,0-255,0-1) + */ + toRgba: function() { + var source = this.getSource(); + return 'rgba(' + source[0] + ',' + source[1] + ',' + source[2] + ',' + source[3] + ')'; + }, + + /** + * Returns color represenation in HSL format + * @return {String} ex: hsl(0-360,0%-100%,0%-100%) + */ + toHsl: function() { + var source = this.getSource(), + hsl = this._rgbToHsl(source[0], source[1], source[2]); + + return 'hsl(' + hsl[0] + ',' + hsl[1] + '%,' + hsl[2] + '%)'; + }, + + /** + * Returns color represenation in HSLA format + * @return {String} ex: hsla(0-360,0%-100%,0%-100%,0-1) + */ + toHsla: function() { + var source = this.getSource(), + hsl = this._rgbToHsl(source[0], source[1], source[2]); + + return 'hsla(' + hsl[0] + ',' + hsl[1] + '%,' + hsl[2] + '%,' + source[3] + ')'; + }, + + /** + * Returns color represenation in HEX format + * @return {String} ex: FF5555 + */ + toHex: function() { + var source = this.getSource(), r, g, b; + + r = source[0].toString(16); + r = (r.length === 1) ? ('0' + r) : r; + + g = source[1].toString(16); + g = (g.length === 1) ? ('0' + g) : g; + + b = source[2].toString(16); + b = (b.length === 1) ? ('0' + b) : b; + + return r.toUpperCase() + g.toUpperCase() + b.toUpperCase(); + }, + + /** + * Gets value of alpha channel for this color + * @return {Number} 0-1 + */ + getAlpha: function() { + return this.getSource()[3]; + }, + + /** + * Sets value of alpha channel for this color + * @param {Number} alpha Alpha value 0-1 + * @return {fabric.Color} thisArg + */ + setAlpha: function(alpha) { + var source = this.getSource(); + source[3] = alpha; + this.setSource(source); + return this; + }, + + /** + * Transforms color to its grayscale representation + * @return {fabric.Color} thisArg + */ + toGrayscale: function() { + var source = this.getSource(), + average = parseInt((source[0] * 0.3 + source[1] * 0.59 + source[2] * 0.11).toFixed(0), 10), + currentAlpha = source[3]; + this.setSource([average, average, average, currentAlpha]); + return this; + }, + + /** + * Transforms color to its black and white representation + * @param {Number} threshold + * @return {fabric.Color} thisArg + */ + toBlackWhite: function(threshold) { + var source = this.getSource(), + average = (source[0] * 0.3 + source[1] * 0.59 + source[2] * 0.11).toFixed(0), + currentAlpha = source[3]; + + threshold = threshold || 127; + + average = (Number(average) < Number(threshold)) ? 0 : 255; + this.setSource([average, average, average, currentAlpha]); + return this; + }, + + /** + * Overlays color with another color + * @param {String|fabric.Color} otherColor + * @return {fabric.Color} thisArg + */ + overlayWith: function(otherColor) { + if (!(otherColor instanceof Color)) { + otherColor = new Color(otherColor); + } + + var result = [], + alpha = this.getAlpha(), + otherAlpha = 0.5, + source = this.getSource(), + otherSource = otherColor.getSource(); + + for (var i = 0; i < 3; i++) { + result.push(Math.round((source[i] * (1 - otherAlpha)) + (otherSource[i] * otherAlpha))); + } + + result[3] = alpha; + this.setSource(result); + return this; + } + }; + + /** + * Regex matching color in RGB or RGBA formats (ex: rgb(0, 0, 0), rgba(255, 100, 10, 0.5), rgba( 255 , 100 , 10 , 0.5 ), rgb(1,1,1), rgba(100%, 60%, 10%, 0.5)) + * @static + * @field + * @memberOf fabric.Color + */ + fabric.Color.reRGBa = /^rgba?\(\s*(\d{1,3}(?:\.\d+)?\%?)\s*,\s*(\d{1,3}(?:\.\d+)?\%?)\s*,\s*(\d{1,3}(?:\.\d+)?\%?)\s*(?:\s*,\s*(\d+(?:\.\d+)?)\s*)?\)$/; + + /** + * Regex matching color in HSL or HSLA formats (ex: hsl(200, 80%, 10%), hsla(300, 50%, 80%, 0.5), hsla( 300 , 50% , 80% , 0.5 )) + * @static + * @field + * @memberOf fabric.Color + */ + fabric.Color.reHSLa = /^hsla?\(\s*(\d{1,3})\s*,\s*(\d{1,3}\%)\s*,\s*(\d{1,3}\%)\s*(?:\s*,\s*(\d+(?:\.\d+)?)\s*)?\)$/; + + /** + * Regex matching color in HEX format (ex: #FF5555, 010155, aff) + * @static + * @field + * @memberOf fabric.Color + */ + fabric.Color.reHex = /^#?([0-9a-f]{6}|[0-9a-f]{3})$/i; + + /** + * Map of the 17 basic color names with HEX code + * @static + * @field + * @memberOf fabric.Color + * @see: http://www.w3.org/TR/CSS2/syndata.html#color-units + */ + fabric.Color.colorNameMap = { + aqua: '#00FFFF', + black: '#000000', + blue: '#0000FF', + fuchsia: '#FF00FF', + gray: '#808080', + green: '#008000', + lime: '#00FF00', + maroon: '#800000', + navy: '#000080', + olive: '#808000', + orange: '#FFA500', + purple: '#800080', + red: '#FF0000', + silver: '#C0C0C0', + teal: '#008080', + white: '#FFFFFF', + yellow: '#FFFF00' + }; + + /** + * @private + * @param {Number} p + * @param {Number} q + * @param {Number} t + * @return {Number} + */ + function hue2rgb(p, q, t) { + if (t < 0) { + t += 1; + } + if (t > 1) { + t -= 1; + } + if (t < 1/6) { + return p + (q - p) * 6 * t; + } + if (t < 1/2) { + return q; + } + if (t < 2/3) { + return p + (q - p) * (2/3 - t) * 6; + } + return p; + } + + /** + * Returns new color object, when given a color in RGB format + * @memberOf fabric.Color + * @param {String} color Color value ex: rgb(0-255,0-255,0-255) + * @return {fabric.Color} + */ + fabric.Color.fromRgb = function(color) { + return Color.fromSource(Color.sourceFromRgb(color)); + }; + + /** + * Returns array represenatation (ex: [100, 100, 200, 1]) of a color that's in RGB or RGBA format + * @memberOf fabric.Color + * @param {String} color Color value ex: rgb(0-255,0-255,0-255), rgb(0%-100%,0%-100%,0%-100%) + * @return {Array} source + */ + fabric.Color.sourceFromRgb = function(color) { + var match = color.match(Color.reRGBa); + if (match) { + var r = parseInt(match[1], 10) / (/%$/.test(match[1]) ? 100 : 1) * (/%$/.test(match[1]) ? 255 : 1), + g = parseInt(match[2], 10) / (/%$/.test(match[2]) ? 100 : 1) * (/%$/.test(match[2]) ? 255 : 1), + b = parseInt(match[3], 10) / (/%$/.test(match[3]) ? 100 : 1) * (/%$/.test(match[3]) ? 255 : 1); + + return [ + parseInt(r, 10), + parseInt(g, 10), + parseInt(b, 10), + match[4] ? parseFloat(match[4]) : 1 + ]; + } + }; + + /** + * Returns new color object, when given a color in RGBA format + * @static + * @function + * @memberOf fabric.Color + * @param {String} color + * @return {fabric.Color} + */ + fabric.Color.fromRgba = Color.fromRgb; + + /** + * Returns new color object, when given a color in HSL format + * @param {String} color Color value ex: hsl(0-260,0%-100%,0%-100%) + * @memberOf fabric.Color + * @return {fabric.Color} + */ + fabric.Color.fromHsl = function(color) { + return Color.fromSource(Color.sourceFromHsl(color)); + }; + + /** + * Returns array represenatation (ex: [100, 100, 200, 1]) of a color that's in HSL or HSLA format. + * Adapted from https://github.com/mjijackson + * @memberOf fabric.Color + * @param {String} color Color value ex: hsl(0-360,0%-100%,0%-100%) or hsla(0-360,0%-100%,0%-100%, 0-1) + * @return {Array} source + * @see http://http://www.w3.org/TR/css3-color/#hsl-color + */ + fabric.Color.sourceFromHsl = function(color) { + var match = color.match(Color.reHSLa); + if (!match) { + return; + } + + var h = (((parseFloat(match[1]) % 360) + 360) % 360) / 360, + s = parseFloat(match[2]) / (/%$/.test(match[2]) ? 100 : 1), + l = parseFloat(match[3]) / (/%$/.test(match[3]) ? 100 : 1), + r, g, b; + + if (s === 0) { + r = g = b = l; + } + else { + var q = l <= 0.5 ? l * (s + 1) : l + s - l * s, + p = l * 2 - q; + + r = hue2rgb(p, q, h + 1/3); + g = hue2rgb(p, q, h); + b = hue2rgb(p, q, h - 1/3); + } + + return [ + Math.round(r * 255), + Math.round(g * 255), + Math.round(b * 255), + match[4] ? parseFloat(match[4]) : 1 + ]; + }; + + /** + * Returns new color object, when given a color in HSLA format + * @static + * @function + * @memberOf fabric.Color + * @param {String} color + * @return {fabric.Color} + */ + fabric.Color.fromHsla = Color.fromHsl; + + /** + * Returns new color object, when given a color in HEX format + * @static + * @memberOf fabric.Color + * @param {String} color Color value ex: FF5555 + * @return {fabric.Color} + */ + fabric.Color.fromHex = function(color) { + return Color.fromSource(Color.sourceFromHex(color)); + }; + + /** + * Returns array represenatation (ex: [100, 100, 200, 1]) of a color that's in HEX format + * @static + * @memberOf fabric.Color + * @param {String} color ex: FF5555 + * @return {Array} source + */ + fabric.Color.sourceFromHex = function(color) { + if (color.match(Color.reHex)) { + var value = color.slice(color.indexOf('#') + 1), + isShortNotation = (value.length === 3), + r = isShortNotation ? (value.charAt(0) + value.charAt(0)) : value.substring(0, 2), + g = isShortNotation ? (value.charAt(1) + value.charAt(1)) : value.substring(2, 4), + b = isShortNotation ? (value.charAt(2) + value.charAt(2)) : value.substring(4, 6); + + return [ + parseInt(r, 16), + parseInt(g, 16), + parseInt(b, 16), + 1 + ]; + } + }; + + /** + * Returns new color object, when given color in array representation (ex: [200, 100, 100, 0.5]) + * @static + * @memberOf fabric.Color + * @param {Array} source + * @return {fabric.Color} + */ + fabric.Color.fromSource = function(source) { + var oColor = new Color(); + oColor.setSource(source); + return oColor; + }; + +})(typeof exports !== 'undefined' ? exports : this); + + +(function() { + + /* _FROM_SVG_START_ */ + function getColorStop(el) { + var style = el.getAttribute('style'), + offset = el.getAttribute('offset'), + color, colorAlpha, opacity; + + // convert percents to absolute values + offset = parseFloat(offset) / (/%$/.test(offset) ? 100 : 1); + offset = offset < 0 ? 0 : offset > 1 ? 1 : offset; + if (style) { + var keyValuePairs = style.split(/\s*;\s*/); + + if (keyValuePairs[keyValuePairs.length - 1] === '') { + keyValuePairs.pop(); + } + + for (var i = keyValuePairs.length; i--; ) { + + var split = keyValuePairs[i].split(/\s*:\s*/), + key = split[0].trim(), + value = split[1].trim(); + + if (key === 'stop-color') { + color = value; + } + else if (key === 'stop-opacity') { + opacity = value; + } + } + } + + if (!color) { + color = el.getAttribute('stop-color') || 'rgb(0,0,0)'; + } + if (!opacity) { + opacity = el.getAttribute('stop-opacity'); + } + + color = new fabric.Color(color); + colorAlpha = color.getAlpha(); + opacity = isNaN(parseFloat(opacity)) ? 1 : parseFloat(opacity); + opacity *= colorAlpha; + + return { + offset: offset, + color: color.toRgb(), + opacity: opacity + }; + } + + function getLinearCoords(el) { + return { + x1: el.getAttribute('x1') || 0, + y1: el.getAttribute('y1') || 0, + x2: el.getAttribute('x2') || '100%', + y2: el.getAttribute('y2') || 0 + }; + } + + function getRadialCoords(el) { + return { + x1: el.getAttribute('fx') || el.getAttribute('cx') || '50%', + y1: el.getAttribute('fy') || el.getAttribute('cy') || '50%', + r1: 0, + x2: el.getAttribute('cx') || '50%', + y2: el.getAttribute('cy') || '50%', + r2: el.getAttribute('r') || '50%' + }; + } + /* _FROM_SVG_END_ */ + + /** + * Gradient class + * @class fabric.Gradient + * @tutorial {@link http://fabricjs.com/fabric-intro-part-2/#gradients} + * @see {@link fabric.Gradient#initialize} for constructor definition + */ + fabric.Gradient = fabric.util.createClass(/** @lends fabric.Gradient.prototype */ { + + /** + * Horizontal offset for aligning gradients coming from SVG when outside pathgroups + * @type Number + * @default 0 + */ + offsetX: 0, + + /** + * Vertical offset for aligning gradients coming from SVG when outside pathgroups + * @type Number + * @default 0 + */ + offsetY: 0, + + /** + * Constructor + * @param {Object} [options] Options object with type, coords, gradientUnits and colorStops + * @return {fabric.Gradient} thisArg + */ + initialize: function(options) { + options || (options = { }); + + var coords = { }; + + this.id = fabric.Object.__uid++; + this.type = options.type || 'linear'; + + coords = { + x1: options.coords.x1 || 0, + y1: options.coords.y1 || 0, + x2: options.coords.x2 || 0, + y2: options.coords.y2 || 0 + }; + + if (this.type === 'radial') { + coords.r1 = options.coords.r1 || 0; + coords.r2 = options.coords.r2 || 0; + } + this.coords = coords; + this.colorStops = options.colorStops.slice(); + if (options.gradientTransform) { + this.gradientTransform = options.gradientTransform; + } + this.offsetX = options.offsetX || this.offsetX; + this.offsetY = options.offsetY || this.offsetY; + }, + + /** + * Adds another colorStop + * @param {Object} colorStop Object with offset and color + * @return {fabric.Gradient} thisArg + */ + addColorStop: function(colorStop) { + for (var position in colorStop) { + var color = new fabric.Color(colorStop[position]); + this.colorStops.push({ + offset: position, + color: color.toRgb(), + opacity: color.getAlpha() + }); + } + return this; + }, + + /** + * Returns object representation of a gradient + * @return {Object} + */ + toObject: function() { + return { + type: this.type, + coords: this.coords, + colorStops: this.colorStops, + offsetX: this.offsetX, + offsetY: this.offsetY + }; + }, + + /* _TO_SVG_START_ */ + /** + * Returns SVG representation of an gradient + * @param {Object} object Object to create a gradient for + * @param {Boolean} normalize Whether coords should be normalized + * @return {String} SVG representation of an gradient (linear/radial) + */ + toSVG: function(object) { + var coords = fabric.util.object.clone(this.coords), + markup, commonAttributes; + + // colorStops must be sorted ascending + this.colorStops.sort(function(a, b) { + return a.offset - b.offset; + }); + + if (!(object.group && object.group.type === 'path-group')) { + for (var prop in coords) { + if (prop === 'x1' || prop === 'x2' || prop === 'r2') { + coords[prop] += this.offsetX - object.width / 2; + } + else if (prop === 'y1' || prop === 'y2') { + coords[prop] += this.offsetY - object.height / 2; + } + } + } + + commonAttributes = 'id="SVGID_' + this.id + + '" gradientUnits="userSpaceOnUse"'; + if (this.gradientTransform) { + commonAttributes += ' gradientTransform="matrix(' + this.gradientTransform.join(' ') + ')" '; + } + if (this.type === 'linear') { + markup = [ + //jscs:disable validateIndentation + '\n' + //jscs:enable validateIndentation + ]; + } + else if (this.type === 'radial') { + markup = [ + //jscs:disable validateIndentation + '\n' + //jscs:enable validateIndentation + ]; + } + + for (var i = 0; i < this.colorStops.length; i++) { + markup.push( + //jscs:disable validateIndentation + '\n' + //jscs:enable validateIndentation + ); + } + + markup.push((this.type === 'linear' ? '\n' : '\n')); + + return markup.join(''); + }, + /* _TO_SVG_END_ */ + + /** + * Returns an instance of CanvasGradient + * @param {CanvasRenderingContext2D} ctx Context to render on + * @return {CanvasGradient} + */ + toLive: function(ctx, object) { + var gradient, prop, coords = fabric.util.object.clone(this.coords); + + if (!this.type) { + return; + } + + if (object.group && object.group.type === 'path-group') { + for (prop in coords) { + if (prop === 'x1' || prop === 'x2') { + coords[prop] += -this.offsetX + object.width / 2; + } + else if (prop === 'y1' || prop === 'y2') { + coords[prop] += -this.offsetY + object.height / 2; + } + } + } + + if (object.type === 'text' || object.type === 'i-text') { + for (prop in coords) { + if (prop === 'x1' || prop === 'x2') { + coords[prop] -= object.width / 2; + } + else if (prop === 'y1' || prop === 'y2') { + coords[prop] -= object.height / 2; + } + } + } + + if (this.type === 'linear') { + gradient = ctx.createLinearGradient( + coords.x1, coords.y1, coords.x2, coords.y2); + } + else if (this.type === 'radial') { + gradient = ctx.createRadialGradient( + coords.x1, coords.y1, coords.r1, coords.x2, coords.y2, coords.r2); + } + + for (var i = 0, len = this.colorStops.length; i < len; i++) { + var color = this.colorStops[i].color, + opacity = this.colorStops[i].opacity, + offset = this.colorStops[i].offset; + + if (typeof opacity !== 'undefined') { + color = new fabric.Color(color).setAlpha(opacity).toRgba(); + } + gradient.addColorStop(parseFloat(offset), color); + } + + return gradient; + } + }); + + fabric.util.object.extend(fabric.Gradient, { + + /* _FROM_SVG_START_ */ + /** + * Returns {@link fabric.Gradient} instance from an SVG element + * @static + * @memberof fabric.Gradient + * @param {SVGGradientElement} el SVG gradient element + * @param {fabric.Object} instance + * @return {fabric.Gradient} Gradient instance + * @see http://www.w3.org/TR/SVG/pservers.html#LinearGradientElement + * @see http://www.w3.org/TR/SVG/pservers.html#RadialGradientElement + */ + fromElement: function(el, instance) { + + /** + * @example: + * + * + * + * + * + * + * OR + * + * + * + * + * + * + * OR + * + * + * + * + * + * + * + * OR + * + * + * + * + * + * + * + */ + + var colorStopEls = el.getElementsByTagName('stop'), + type = (el.nodeName === 'linearGradient' ? 'linear' : 'radial'), + gradientUnits = el.getAttribute('gradientUnits') || 'objectBoundingBox', + gradientTransform = el.getAttribute('gradientTransform'), + colorStops = [], + coords = { }, ellipseMatrix; + + if (type === 'linear') { + coords = getLinearCoords(el); + } + else if (type === 'radial') { + coords = getRadialCoords(el); + } + + for (var i = colorStopEls.length; i--; ) { + colorStops.push(getColorStop(colorStopEls[i])); + } + + ellipseMatrix = _convertPercentUnitsToValues(instance, coords, gradientUnits); + + var gradient = new fabric.Gradient({ + type: type, + coords: coords, + colorStops: colorStops, + offsetX: -instance.left, + offsetY: -instance.top + }); + + if (gradientTransform || ellipseMatrix !== '') { + gradient.gradientTransform = fabric.parseTransformAttribute((gradientTransform || '') + ellipseMatrix); + } + return gradient; + }, + /* _FROM_SVG_END_ */ + + /** + * Returns {@link fabric.Gradient} instance from its object representation + * @static + * @memberof fabric.Gradient + * @param {Object} obj + * @param {Object} [options] Options object + */ + forObject: function(obj, options) { + options || (options = { }); + _convertPercentUnitsToValues(obj, options.coords, 'userSpaceOnUse'); + return new fabric.Gradient(options); + } + }); + + /** + * @private + */ + function _convertPercentUnitsToValues(object, options, gradientUnits) { + var propValue, addFactor = 0, multFactor = 1, ellipseMatrix = ''; + for (var prop in options) { + propValue = parseFloat(options[prop], 10); + if (typeof options[prop] === 'string' && /^\d+%$/.test(options[prop])) { + multFactor = 0.01; + } + else { + multFactor = 1; + } + if (prop === 'x1' || prop === 'x2' || prop === 'r2') { + multFactor *= gradientUnits === 'objectBoundingBox' ? object.width : 1; + addFactor = gradientUnits === 'objectBoundingBox' ? object.left || 0 : 0; + } + else if (prop === 'y1' || prop === 'y2') { + multFactor *= gradientUnits === 'objectBoundingBox' ? object.height : 1; + addFactor = gradientUnits === 'objectBoundingBox' ? object.top || 0 : 0; + } + options[prop] = propValue * multFactor + addFactor; + } + if (object.type === 'ellipse' && + options.r2 !== null && + gradientUnits === 'objectBoundingBox' && + object.rx !== object.ry) { + + var scaleFactor = object.ry/object.rx; + ellipseMatrix = ' scale(1, ' + scaleFactor + ')'; + if (options.y1) { + options.y1 /= scaleFactor; + } + if (options.y2) { + options.y2 /= scaleFactor; + } + } + return ellipseMatrix; + } +})(); + + +/** + * Pattern class + * @class fabric.Pattern + * @see {@link http://fabricjs.com/patterns/|Pattern demo} + * @see {@link http://fabricjs.com/dynamic-patterns/|DynamicPattern demo} + * @see {@link fabric.Pattern#initialize} for constructor definition + */ +fabric.Pattern = fabric.util.createClass(/** @lends fabric.Pattern.prototype */ { + + /** + * Repeat property of a pattern (one of repeat, repeat-x, repeat-y or no-repeat) + * @type String + * @default + */ + repeat: 'repeat', + + /** + * Pattern horizontal offset from object's left/top corner + * @type Number + * @default + */ + offsetX: 0, + + /** + * Pattern vertical offset from object's left/top corner + * @type Number + * @default + */ + offsetY: 0, + + /** + * Constructor + * @param {Object} [options] Options object + * @return {fabric.Pattern} thisArg + */ + initialize: function(options) { + options || (options = { }); + + this.id = fabric.Object.__uid++; + + if (options.source) { + if (typeof options.source === 'string') { + // function string + if (typeof fabric.util.getFunctionBody(options.source) !== 'undefined') { + this.source = new Function(fabric.util.getFunctionBody(options.source)); + } + else { + // img src string + var _this = this; + this.source = fabric.util.createImage(); + fabric.util.loadImage(options.source, function(img) { + _this.source = img; + }); + } + } + else { + // img element + this.source = options.source; + } + } + if (options.repeat) { + this.repeat = options.repeat; + } + if (options.offsetX) { + this.offsetX = options.offsetX; + } + if (options.offsetY) { + this.offsetY = options.offsetY; + } + }, + + /** + * Returns object representation of a pattern + * @return {Object} Object representation of a pattern instance + */ + toObject: function() { + + var source; + + // callback + if (typeof this.source === 'function') { + source = String(this.source); + } + // element + else if (typeof this.source.src === 'string') { + source = this.source.src; + } + + return { + source: source, + repeat: this.repeat, + offsetX: this.offsetX, + offsetY: this.offsetY + }; + }, + + /* _TO_SVG_START_ */ + /** + * Returns SVG representation of a pattern + * @param {fabric.Object} object + * @return {String} SVG representation of a pattern + */ + toSVG: function(object) { + var patternSource = typeof this.source === 'function' ? this.source() : this.source, + patternWidth = patternSource.width / object.getWidth(), + patternHeight = patternSource.height / object.getHeight(), + patternOffsetX = this.offsetX / object.getWidth(), + patternOffsetY = this.offsetY / object.getHeight(), + patternImgSrc = ''; + if (this.repeat === 'repeat-x' || this.repeat === 'no-repeat') { + patternHeight = 1; + } + if (this.repeat === 'repeat-y' || this.repeat === 'no-repeat') { + patternWidth = 1; + } + if (patternSource.src) { + patternImgSrc = patternSource.src; + } + else if (patternSource.toDataURL) { + patternImgSrc = patternSource.toDataURL(); + } + + return '\n' + + '\n' + + '\n'; + }, + /* _TO_SVG_END_ */ + + /** + * Returns an instance of CanvasPattern + * @param {CanvasRenderingContext2D} ctx Context to create pattern + * @return {CanvasPattern} + */ + toLive: function(ctx) { + var source = typeof this.source === 'function' + ? this.source() + : this.source; + + // if the image failed to load, return, and allow rest to continue loading + if (!source) { + return ''; + } + + // if an image + if (typeof source.src !== 'undefined') { + if (!source.complete) { + return ''; + } + if (source.naturalWidth === 0 || source.naturalHeight === 0) { + return ''; + } + } + return ctx.createPattern(source, this.repeat); + } +}); + + +(function(global) { + + 'use strict'; + + var fabric = global.fabric || (global.fabric = { }), + toFixed = fabric.util.toFixed; + + if (fabric.Shadow) { + fabric.warn('fabric.Shadow is already defined.'); + return; + } + + /** + * Shadow class + * @class fabric.Shadow + * @see {@link http://fabricjs.com/shadows/|Shadow demo} + * @see {@link fabric.Shadow#initialize} for constructor definition + */ + fabric.Shadow = fabric.util.createClass(/** @lends fabric.Shadow.prototype */ { + + /** + * Shadow color + * @type String + * @default + */ + color: 'rgb(0,0,0)', + + /** + * Shadow blur + * @type Number + */ + blur: 0, + + /** + * Shadow horizontal offset + * @type Number + * @default + */ + offsetX: 0, + + /** + * Shadow vertical offset + * @type Number + * @default + */ + offsetY: 0, + + /** + * Whether the shadow should affect stroke operations + * @type Boolean + * @default + */ + affectStroke: false, + + /** + * Indicates whether toObject should include default values + * @type Boolean + * @default + */ + includeDefaultValues: true, + + /** + * Constructor + * @param {Object|String} [options] Options object with any of color, blur, offsetX, offsetX properties or string (e.g. "rgba(0,0,0,0.2) 2px 2px 10px, "2px 2px 10px rgba(0,0,0,0.2)") + * @return {fabric.Shadow} thisArg + */ + initialize: function(options) { + + if (typeof options === 'string') { + options = this._parseShadow(options); + } + + for (var prop in options) { + this[prop] = options[prop]; + } + + this.id = fabric.Object.__uid++; + }, + + /** + * @private + * @param {String} shadow Shadow value to parse + * @return {Object} Shadow object with color, offsetX, offsetY and blur + */ + _parseShadow: function(shadow) { + var shadowStr = shadow.trim(), + offsetsAndBlur = fabric.Shadow.reOffsetsAndBlur.exec(shadowStr) || [ ], + color = shadowStr.replace(fabric.Shadow.reOffsetsAndBlur, '') || 'rgb(0,0,0)'; + + return { + color: color.trim(), + offsetX: parseInt(offsetsAndBlur[1], 10) || 0, + offsetY: parseInt(offsetsAndBlur[2], 10) || 0, + blur: parseInt(offsetsAndBlur[3], 10) || 0 + }; + }, + + /** + * Returns a string representation of an instance + * @see http://www.w3.org/TR/css-text-decor-3/#text-shadow + * @return {String} Returns CSS3 text-shadow declaration + */ + toString: function() { + return [this.offsetX, this.offsetY, this.blur, this.color].join('px '); + }, + + /* _TO_SVG_START_ */ + /** + * Returns SVG representation of a shadow + * @param {fabric.Object} object + * @return {String} SVG representation of a shadow + */ + toSVG: function(object) { + var mode = 'SourceAlpha', fBoxX = 40, fBoxY = 40; + + if (object && (object.fill === this.color || object.stroke === this.color)) { + mode = 'SourceGraphic'; + } + + if (object.width && object.height) { + //http://www.w3.org/TR/SVG/filters.html#FilterEffectsRegion + // we add some extra space to filter box to contain the blur ( 20 ) + fBoxX = toFixed(Math.abs(this.offsetX / object.getWidth()), 2) * 100 + 20; + fBoxY = toFixed(Math.abs(this.offsetY / object.getHeight()), 2) * 100 + 20; + } + + return ( + '\n' + + '\t\n' + + '\t\n' + + '\t\n' + + '\t\n' + + '\t\t\n' + + '\t\t\n' + + '\t\n' + + '\n'); + }, + /* _TO_SVG_END_ */ + + /** + * Returns object representation of a shadow + * @return {Object} Object representation of a shadow instance + */ + toObject: function() { + if (this.includeDefaultValues) { + return { + color: this.color, + blur: this.blur, + offsetX: this.offsetX, + offsetY: this.offsetY + }; + } + var obj = { }, proto = fabric.Shadow.prototype; + if (this.color !== proto.color) { + obj.color = this.color; + } + if (this.blur !== proto.blur) { + obj.blur = this.blur; + } + if (this.offsetX !== proto.offsetX) { + obj.offsetX = this.offsetX; + } + if (this.offsetY !== proto.offsetY) { + obj.offsetY = this.offsetY; + } + return obj; + } + }); + + /** + * Regex matching shadow offsetX, offsetY and blur (ex: "2px 2px 10px rgba(0,0,0,0.2)", "rgb(0,255,0) 2px 2px") + * @static + * @field + * @memberOf fabric.Shadow + */ + fabric.Shadow.reOffsetsAndBlur = /(?:\s|^)(-?\d+(?:px)?(?:\s?|$))?(-?\d+(?:px)?(?:\s?|$))?(\d+(?:px)?)?(?:\s?|$)(?:$|\s)/; + +})(typeof exports !== 'undefined' ? exports : this); + + +(function () { + + 'use strict'; + + if (fabric.StaticCanvas) { + fabric.warn('fabric.StaticCanvas is already defined.'); + return; + } + + // aliases for faster resolution + var extend = fabric.util.object.extend, + getElementOffset = fabric.util.getElementOffset, + removeFromArray = fabric.util.removeFromArray, + + CANVAS_INIT_ERROR = new Error('Could not initialize `canvas` element'); + + /** + * Static canvas class + * @class fabric.StaticCanvas + * @mixes fabric.Collection + * @mixes fabric.Observable + * @see {@link http://fabricjs.com/static_canvas/|StaticCanvas demo} + * @see {@link fabric.StaticCanvas#initialize} for constructor definition + * @fires before:render + * @fires after:render + * @fires canvas:cleared + * @fires object:added + * @fires object:removed + */ + fabric.StaticCanvas = fabric.util.createClass(/** @lends fabric.StaticCanvas.prototype */ { + + /** + * Constructor + * @param {HTMLElement | String} el <canvas> element to initialize instance on + * @param {Object} [options] Options object + * @return {Object} thisArg + */ + initialize: function(el, options) { + options || (options = { }); + + this._initStatic(el, options); + fabric.StaticCanvas.activeInstance = this; + }, + + /** + * Background color of canvas instance. + * Should be set via {@link fabric.StaticCanvas#setBackgroundColor}. + * @type {(String|fabric.Pattern)} + * @default + */ + backgroundColor: '', + + /** + * Background image of canvas instance. + * Should be set via {@link fabric.StaticCanvas#setBackgroundImage}. + * Backwards incompatibility note: The "backgroundImageOpacity" + * and "backgroundImageStretch" properties are deprecated since 1.3.9. + * Use {@link fabric.Image#opacity}, {@link fabric.Image#width} and {@link fabric.Image#height}. + * @type fabric.Image + * @default + */ + backgroundImage: null, + + /** + * Overlay color of canvas instance. + * Should be set via {@link fabric.StaticCanvas#setOverlayColor} + * @since 1.3.9 + * @type {(String|fabric.Pattern)} + * @default + */ + overlayColor: '', + + /** + * Overlay image of canvas instance. + * Should be set via {@link fabric.StaticCanvas#setOverlayImage}. + * Backwards incompatibility note: The "overlayImageLeft" + * and "overlayImageTop" properties are deprecated since 1.3.9. + * Use {@link fabric.Image#left} and {@link fabric.Image#top}. + * @type fabric.Image + * @default + */ + overlayImage: null, + + /** + * Indicates whether toObject/toDatalessObject should include default values + * @type Boolean + * @default + */ + includeDefaultValues: true, + + /** + * Indicates whether objects' state should be saved + * @type Boolean + * @default + */ + stateful: true, + + /** + * Indicates whether {@link fabric.Collection.add}, {@link fabric.Collection.insertAt} and {@link fabric.Collection.remove} should also re-render canvas. + * Disabling this option could give a great performance boost when adding/removing a lot of objects to/from canvas at once + * (followed by a manual rendering after addition/deletion) + * @type Boolean + * @default + */ + renderOnAddRemove: true, + + /** + * Function that determines clipping of entire canvas area + * Being passed context as first argument. See clipping canvas area in {@link https://github.com/kangax/fabric.js/wiki/FAQ} + * @type Function + * @default + */ + clipTo: null, + + /** + * Indicates whether object controls (borders/controls) are rendered above overlay image + * @type Boolean + * @default + */ + controlsAboveOverlay: false, + + /** + * Indicates whether the browser can be scrolled when using a touchscreen and dragging on the canvas + * @type Boolean + * @default + */ + allowTouchScrolling: false, + + /** + * Indicates whether this canvas will use image smoothing, this is on by default in browsers + * @type Boolean + * @default + */ + imageSmoothingEnabled: true, + + /** + * Indicates whether objects should remain in current stack position when selected. When false objects are brought to top and rendered as part of the selection group + * @type Boolean + * @default + */ + preserveObjectStacking: false, + + /** + * The transformation (in the format of Canvas transform) which focuses the viewport + * @type Array + * @default + */ + viewportTransform: [1, 0, 0, 1, 0, 0], + + /** + * Callback; invoked right before object is about to be scaled/rotated + */ + onBeforeScaleRotate: function () { + /* NOOP */ + }, + + /** + * @private + * @param {HTMLElement | String} el <canvas> element to initialize instance on + * @param {Object} [options] Options object + */ + _initStatic: function(el, options) { + this._objects = []; + + this._createLowerCanvas(el); + this._initOptions(options); + this._setImageSmoothing(); + + if (options.overlayImage) { + this.setOverlayImage(options.overlayImage, this.renderAll.bind(this)); + } + if (options.backgroundImage) { + this.setBackgroundImage(options.backgroundImage, this.renderAll.bind(this)); + } + if (options.backgroundColor) { + this.setBackgroundColor(options.backgroundColor, this.renderAll.bind(this)); + } + if (options.overlayColor) { + this.setOverlayColor(options.overlayColor, this.renderAll.bind(this)); + } + this.calcOffset(); + }, + + /** + * Calculates canvas element offset relative to the document + * This method is also attached as "resize" event handler of window + * @return {fabric.Canvas} instance + * @chainable + */ + calcOffset: function () { + this._offset = getElementOffset(this.lowerCanvasEl); + return this; + }, + + /** + * Sets {@link fabric.StaticCanvas#overlayImage|overlay image} for this canvas + * @param {(fabric.Image|String)} image fabric.Image instance or URL of an image to set overlay to + * @param {Function} callback callback to invoke when image is loaded and set as an overlay + * @param {Object} [options] Optional options to set for the {@link fabric.Image|overlay image}. + * @return {fabric.Canvas} thisArg + * @chainable + * @see {@link http://jsfiddle.net/fabricjs/MnzHT/|jsFiddle demo} + * @example Normal overlayImage with left/top = 0 + * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), { + * // Needed to position overlayImage at 0/0 + * originX: 'left', + * originY: 'top' + * }); + * @example overlayImage with different properties + * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), { + * opacity: 0.5, + * angle: 45, + * left: 400, + * top: 400, + * originX: 'left', + * originY: 'top' + * }); + * @example Stretched overlayImage #1 - width/height correspond to canvas width/height + * fabric.Image.fromURL('http://fabricjs.com/assets/jail_cell_bars.png', function(img) { + * img.set({width: canvas.width, height: canvas.height, originX: 'left', originY: 'top'}); + * canvas.setOverlayImage(img, canvas.renderAll.bind(canvas)); + * }); + * @example Stretched overlayImage #2 - width/height correspond to canvas width/height + * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), { + * width: canvas.width, + * height: canvas.height, + * // Needed to position overlayImage at 0/0 + * originX: 'left', + * originY: 'top' + * }); + * @example overlayImage loaded from cross-origin + * canvas.setOverlayImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas), { + * opacity: 0.5, + * angle: 45, + * left: 400, + * top: 400, + * originX: 'left', + * originY: 'top', + * crossOrigin: 'anonymous' + * }); + */ + setOverlayImage: function (image, callback, options) { + return this.__setBgOverlayImage('overlayImage', image, callback, options); + }, + + /** + * Sets {@link fabric.StaticCanvas#backgroundImage|background image} for this canvas + * @param {(fabric.Image|String)} image fabric.Image instance or URL of an image to set background to + * @param {Function} callback Callback to invoke when image is loaded and set as background + * @param {Object} [options] Optional options to set for the {@link fabric.Image|background image}. + * @return {fabric.Canvas} thisArg + * @chainable + * @see {@link http://jsfiddle.net/fabricjs/YH9yD/|jsFiddle demo} + * @example Normal backgroundImage with left/top = 0 + * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), { + * // Needed to position backgroundImage at 0/0 + * originX: 'left', + * originY: 'top' + * }); + * @example backgroundImage with different properties + * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), { + * opacity: 0.5, + * angle: 45, + * left: 400, + * top: 400, + * originX: 'left', + * originY: 'top' + * }); + * @example Stretched backgroundImage #1 - width/height correspond to canvas width/height + * fabric.Image.fromURL('http://fabricjs.com/assets/honey_im_subtle.png', function(img) { + * img.set({width: canvas.width, height: canvas.height, originX: 'left', originY: 'top'}); + * canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas)); + * }); + * @example Stretched backgroundImage #2 - width/height correspond to canvas width/height + * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), { + * width: canvas.width, + * height: canvas.height, + * // Needed to position backgroundImage at 0/0 + * originX: 'left', + * originY: 'top' + * }); + * @example backgroundImage loaded from cross-origin + * canvas.setBackgroundImage('http://fabricjs.com/assets/honey_im_subtle.png', canvas.renderAll.bind(canvas), { + * opacity: 0.5, + * angle: 45, + * left: 400, + * top: 400, + * originX: 'left', + * originY: 'top', + * crossOrigin: 'anonymous' + * }); + */ + setBackgroundImage: function (image, callback, options) { + return this.__setBgOverlayImage('backgroundImage', image, callback, options); + }, + + /** + * Sets {@link fabric.StaticCanvas#overlayColor|background color} for this canvas + * @param {(String|fabric.Pattern)} overlayColor Color or pattern to set background color to + * @param {Function} callback Callback to invoke when background color is set + * @return {fabric.Canvas} thisArg + * @chainable + * @see {@link http://jsfiddle.net/fabricjs/pB55h/|jsFiddle demo} + * @example Normal overlayColor - color value + * canvas.setOverlayColor('rgba(255, 73, 64, 0.6)', canvas.renderAll.bind(canvas)); + * @example fabric.Pattern used as overlayColor + * canvas.setOverlayColor({ + * source: 'http://fabricjs.com/assets/escheresque_ste.png' + * }, canvas.renderAll.bind(canvas)); + * @example fabric.Pattern used as overlayColor with repeat and offset + * canvas.setOverlayColor({ + * source: 'http://fabricjs.com/assets/escheresque_ste.png', + * repeat: 'repeat', + * offsetX: 200, + * offsetY: 100 + * }, canvas.renderAll.bind(canvas)); + */ + setOverlayColor: function(overlayColor, callback) { + return this.__setBgOverlayColor('overlayColor', overlayColor, callback); + }, + + /** + * Sets {@link fabric.StaticCanvas#backgroundColor|background color} for this canvas + * @param {(String|fabric.Pattern)} backgroundColor Color or pattern to set background color to + * @param {Function} callback Callback to invoke when background color is set + * @return {fabric.Canvas} thisArg + * @chainable + * @see {@link http://jsfiddle.net/fabricjs/hXzvk/|jsFiddle demo} + * @example Normal backgroundColor - color value + * canvas.setBackgroundColor('rgba(255, 73, 64, 0.6)', canvas.renderAll.bind(canvas)); + * @example fabric.Pattern used as backgroundColor + * canvas.setBackgroundColor({ + * source: 'http://fabricjs.com/assets/escheresque_ste.png' + * }, canvas.renderAll.bind(canvas)); + * @example fabric.Pattern used as backgroundColor with repeat and offset + * canvas.setBackgroundColor({ + * source: 'http://fabricjs.com/assets/escheresque_ste.png', + * repeat: 'repeat', + * offsetX: 200, + * offsetY: 100 + * }, canvas.renderAll.bind(canvas)); + */ + setBackgroundColor: function(backgroundColor, callback) { + return this.__setBgOverlayColor('backgroundColor', backgroundColor, callback); + }, + + /** + * @private + * @see {@link http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-imagesmoothingenabled|WhatWG Canvas Standard} + */ + _setImageSmoothing: function() { + var ctx = this.getContext(); + + ctx.imageSmoothingEnabled = this.imageSmoothingEnabled; + ctx.webkitImageSmoothingEnabled = this.imageSmoothingEnabled; + ctx.mozImageSmoothingEnabled = this.imageSmoothingEnabled; + ctx.msImageSmoothingEnabled = this.imageSmoothingEnabled; + ctx.oImageSmoothingEnabled = this.imageSmoothingEnabled; + }, + + /** + * @private + * @param {String} property Property to set ({@link fabric.StaticCanvas#backgroundImage|backgroundImage} + * or {@link fabric.StaticCanvas#overlayImage|overlayImage}) + * @param {(fabric.Image|String|null)} image fabric.Image instance, URL of an image or null to set background or overlay to + * @param {Function} callback Callback to invoke when image is loaded and set as background or overlay + * @param {Object} [options] Optional options to set for the {@link fabric.Image|image}. + */ + __setBgOverlayImage: function(property, image, callback, options) { + if (typeof image === 'string') { + fabric.util.loadImage(image, function(img) { + this[property] = new fabric.Image(img, options); + callback && callback(); + }, this, options && options.crossOrigin); + } + else { + options && image.setOptions(options); + this[property] = image; + callback && callback(); + } + + return this; + }, + + /** + * @private + * @param {String} property Property to set ({@link fabric.StaticCanvas#backgroundColor|backgroundColor} + * or {@link fabric.StaticCanvas#overlayColor|overlayColor}) + * @param {(Object|String|null)} color Object with pattern information, color value or null + * @param {Function} [callback] Callback is invoked when color is set + */ + __setBgOverlayColor: function(property, color, callback) { + if (color && color.source) { + var _this = this; + fabric.util.loadImage(color.source, function(img) { + _this[property] = new fabric.Pattern({ + source: img, + repeat: color.repeat, + offsetX: color.offsetX, + offsetY: color.offsetY + }); + callback && callback(); + }); + } + else { + this[property] = color; + callback && callback(); + } + + return this; + }, + + /** + * @private + */ + _createCanvasElement: function() { + var element = fabric.document.createElement('canvas'); + if (!element.style) { + element.style = { }; + } + if (!element) { + throw CANVAS_INIT_ERROR; + } + this._initCanvasElement(element); + return element; + }, + + /** + * @private + * @param {HTMLElement} element + */ + _initCanvasElement: function(element) { + fabric.util.createCanvasElement(element); + + if (typeof element.getContext === 'undefined') { + throw CANVAS_INIT_ERROR; + } + }, + + /** + * @private + * @param {Object} [options] Options object + */ + _initOptions: function (options) { + for (var prop in options) { + this[prop] = options[prop]; + } + + this.width = this.width || parseInt(this.lowerCanvasEl.width, 10) || 0; + this.height = this.height || parseInt(this.lowerCanvasEl.height, 10) || 0; + + if (!this.lowerCanvasEl.style) { + return; + } + + this.lowerCanvasEl.width = this.width; + this.lowerCanvasEl.height = this.height; + + this.lowerCanvasEl.style.width = this.width + 'px'; + this.lowerCanvasEl.style.height = this.height + 'px'; + + this.viewportTransform = this.viewportTransform.slice(); + }, + + /** + * Creates a bottom canvas + * @private + * @param {HTMLElement} [canvasEl] + */ + _createLowerCanvas: function (canvasEl) { + this.lowerCanvasEl = fabric.util.getById(canvasEl) || this._createCanvasElement(); + this._initCanvasElement(this.lowerCanvasEl); + + fabric.util.addClass(this.lowerCanvasEl, 'lower-canvas'); + + if (this.interactive) { + this._applyCanvasStyle(this.lowerCanvasEl); + } + + this.contextContainer = this.lowerCanvasEl.getContext('2d'); + }, + + /** + * Returns canvas width (in px) + * @return {Number} + */ + getWidth: function () { + return this.width; + }, + + /** + * Returns canvas height (in px) + * @return {Number} + */ + getHeight: function () { + return this.height; + }, + + /** + * Sets width of this canvas instance + * @param {Number|String} value Value to set width to + * @param {Object} [options] Options object + * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions + * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions + * @return {fabric.Canvas} instance + * @chainable true + */ + setWidth: function (value, options) { + return this.setDimensions({ width: value }, options); + }, + + /** + * Sets height of this canvas instance + * @param {Number|String} value Value to set height to + * @param {Object} [options] Options object + * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions + * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions + * @return {fabric.Canvas} instance + * @chainable true + */ + setHeight: function (value, options) { + return this.setDimensions({ height: value }, options); + }, + + /** + * Sets dimensions (width, height) of this canvas instance. when options.cssOnly flag active you should also supply the unit of measure (px/%/em) + * @param {Object} dimensions Object with width/height properties + * @param {Number|String} [dimensions.width] Width of canvas element + * @param {Number|String} [dimensions.height] Height of canvas element + * @param {Object} [options] Options object + * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions + * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions + * @return {fabric.Canvas} thisArg + * @chainable + */ + setDimensions: function (dimensions, options) { + var cssValue; + + options = options || {}; + + for (var prop in dimensions) { + cssValue = dimensions[prop]; + + if (!options.cssOnly) { + this._setBackstoreDimension(prop, dimensions[prop]); + cssValue += 'px'; + } + + if (!options.backstoreOnly) { + this._setCssDimension(prop, cssValue); + } + } + + if (!options.cssOnly) { + this.renderAll(); + } + + this.calcOffset(); + + return this; + }, + + /** + * Helper for setting width/height + * @private + * @param {String} prop property (width|height) + * @param {Number} value value to set property to + * @return {fabric.Canvas} instance + * @chainable true + */ + _setBackstoreDimension: function (prop, value) { + this.lowerCanvasEl[prop] = value; + + if (this.upperCanvasEl) { + this.upperCanvasEl[prop] = value; + } + + if (this.cacheCanvasEl) { + this.cacheCanvasEl[prop] = value; + } + + this[prop] = value; + + return this; + }, + + /** + * Helper for setting css width/height + * @private + * @param {String} prop property (width|height) + * @param {String} value value to set property to + * @return {fabric.Canvas} instance + * @chainable true + */ + _setCssDimension: function (prop, value) { + this.lowerCanvasEl.style[prop] = value; + + if (this.upperCanvasEl) { + this.upperCanvasEl.style[prop] = value; + } + + if (this.wrapperEl) { + this.wrapperEl.style[prop] = value; + } + + return this; + }, + + /** + * Returns canvas zoom level + * @return {Number} + */ + getZoom: function () { + return Math.sqrt(this.viewportTransform[0] * this.viewportTransform[3]); + }, + + /** + * Sets viewport transform of this canvas instance + * @param {Array} vpt the transform in the form of context.transform + * @return {fabric.Canvas} instance + * @chainable true + */ + setViewportTransform: function (vpt) { + var activeGroup = this.getActiveGroup(); + this.viewportTransform = vpt; + this.renderAll(); + for (var i = 0, len = this._objects.length; i < len; i++) { + this._objects[i].setCoords(); + } + if (activeGroup) { + activeGroup.setCoords(); + } + return this; + }, + + /** + * Sets zoom level of this canvas instance, zoom centered around point + * @param {fabric.Point} point to zoom with respect to + * @param {Number} value to set zoom to, less than 1 zooms out + * @return {fabric.Canvas} instance + * @chainable true + */ + zoomToPoint: function (point, value) { + // TODO: just change the scale, preserve other transformations + var before = point; + point = fabric.util.transformPoint(point, fabric.util.invertTransform(this.viewportTransform)); + this.viewportTransform[0] = value; + this.viewportTransform[3] = value; + var after = fabric.util.transformPoint(point, this.viewportTransform); + this.viewportTransform[4] += before.x - after.x; + this.viewportTransform[5] += before.y - after.y; + this.renderAll(); + for (var i = 0, len = this._objects.length; i < len; i++) { + this._objects[i].setCoords(); + } + return this; + }, + + /** + * Sets zoom level of this canvas instance + * @param {Number} value to set zoom to, less than 1 zooms out + * @return {fabric.Canvas} instance + * @chainable true + */ + setZoom: function (value) { + this.zoomToPoint(new fabric.Point(0, 0), value); + return this; + }, + + /** + * Pan viewport so as to place point at top left corner of canvas + * @param {fabric.Point} point to move to + * @return {fabric.Canvas} instance + * @chainable true + */ + absolutePan: function (point) { + this.viewportTransform[4] = -point.x; + this.viewportTransform[5] = -point.y; + this.renderAll(); + for (var i = 0, len = this._objects.length; i < len; i++) { + this._objects[i].setCoords(); + } + return this; + }, + + /** + * Pans viewpoint relatively + * @param {fabric.Point} point (position vector) to move by + * @return {fabric.Canvas} instance + * @chainable true + */ + relativePan: function (point) { + return this.absolutePan(new fabric.Point( + -point.x - this.viewportTransform[4], + -point.y - this.viewportTransform[5] + )); + }, + + /** + * Returns <canvas> element corresponding to this instance + * @return {HTMLCanvasElement} + */ + getElement: function () { + return this.lowerCanvasEl; + }, + + /** + * Returns currently selected object, if any + * @return {fabric.Object} + */ + getActiveObject: function() { + return null; + }, + + /** + * Returns currently selected group of object, if any + * @return {fabric.Group} + */ + getActiveGroup: function() { + return null; + }, + + /** + * Given a context, renders an object on that context + * @param {CanvasRenderingContext2D} ctx Context to render object on + * @param {fabric.Object} object Object to render + * @private + */ + _draw: function (ctx, object) { + if (!object) { + return; + } + + ctx.save(); + var v = this.viewportTransform; + ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); + if (this._shouldRenderObject(object)) { + object.render(ctx); + } + ctx.restore(); + if (!this.controlsAboveOverlay) { + object._renderControls(ctx); + } + }, + + _shouldRenderObject: function(object) { + if (!object) { + return false; + } + return (object !== this.getActiveGroup() || !this.preserveObjectStacking); + }, + + /** + * @private + * @param {fabric.Object} obj Object that was added + */ + _onObjectAdded: function(obj) { + this.stateful && obj.setupState(); + obj.canvas = this; + obj.setCoords(); + this.fire('object:added', { target: obj }); + obj.fire('added'); + }, + + /** + * @private + * @param {fabric.Object} obj Object that was removed + */ + _onObjectRemoved: function(obj) { + // removing active object should fire "selection:cleared" events + if (this.getActiveObject() === obj) { + this.fire('before:selection:cleared', { target: obj }); + this._discardActiveObject(); + this.fire('selection:cleared'); + } + + this.fire('object:removed', { target: obj }); + obj.fire('removed'); + }, + + /** + * Clears specified context of canvas element + * @param {CanvasRenderingContext2D} ctx Context to clear + * @return {fabric.Canvas} thisArg + * @chainable + */ + clearContext: function(ctx) { + ctx.clearRect(0, 0, this.width, this.height); + return this; + }, + + /** + * Returns context of canvas where objects are drawn + * @return {CanvasRenderingContext2D} + */ + getContext: function () { + return this.contextContainer; + }, + + /** + * Clears all contexts (background, main, top) of an instance + * @return {fabric.Canvas} thisArg + * @chainable + */ + clear: function () { + this._objects.length = 0; + if (this.discardActiveGroup) { + this.discardActiveGroup(); + } + if (this.discardActiveObject) { + this.discardActiveObject(); + } + this.clearContext(this.contextContainer); + if (this.contextTop) { + this.clearContext(this.contextTop); + } + this.fire('canvas:cleared'); + this.renderAll(); + return this; + }, + + /** + * Renders both the top canvas and the secondary container canvas. + * @param {Boolean} [allOnTop] Whether we want to force all images to be rendered on the top canvas + * @return {fabric.Canvas} instance + * @chainable + */ + renderAll: function (allOnTop) { + var canvasToDrawOn = this[(allOnTop === true && this.interactive) ? 'contextTop' : 'contextContainer'], + activeGroup = this.getActiveGroup(); + + if (this.contextTop && this.selection && !this._groupSelector) { + this.clearContext(this.contextTop); + } + + if (!allOnTop) { + this.clearContext(canvasToDrawOn); + } + + this.fire('before:render'); + + if (this.clipTo) { + fabric.util.clipContext(this, canvasToDrawOn); + } + + this._renderBackground(canvasToDrawOn); + this._renderObjects(canvasToDrawOn, activeGroup); + this._renderActiveGroup(canvasToDrawOn, activeGroup); + + if (this.clipTo) { + canvasToDrawOn.restore(); + } + + this._renderOverlay(canvasToDrawOn); + + if (this.controlsAboveOverlay && this.interactive) { + this.drawControls(canvasToDrawOn); + } + + this.fire('after:render'); + + return this; + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {fabric.Group} activeGroup + */ + _renderObjects: function(ctx, activeGroup) { + var i, length; + + // fast path + if (!activeGroup || this.preserveObjectStacking) { + for (i = 0, length = this._objects.length; i < length; ++i) { + this._draw(ctx, this._objects[i]); + } + } + else { + for (i = 0, length = this._objects.length; i < length; ++i) { + if (this._objects[i] && !activeGroup.contains(this._objects[i])) { + this._draw(ctx, this._objects[i]); + } + } + } + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {fabric.Group} activeGroup + */ + _renderActiveGroup: function(ctx, activeGroup) { + + // delegate rendering to group selection (if one exists) + if (activeGroup) { + + //Store objects in group preserving order, then replace + var sortedObjects = []; + this.forEachObject(function (object) { + if (activeGroup.contains(object)) { + sortedObjects.push(object); + } + }); + activeGroup._set('objects', sortedObjects); + this._draw(ctx, activeGroup); + } + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderBackground: function(ctx) { + if (this.backgroundColor) { + ctx.fillStyle = this.backgroundColor.toLive + ? this.backgroundColor.toLive(ctx) + : this.backgroundColor; + + ctx.fillRect( + this.backgroundColor.offsetX || 0, + this.backgroundColor.offsetY || 0, + this.width, + this.height); + } + if (this.backgroundImage) { + this._draw(ctx, this.backgroundImage); + } + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderOverlay: function(ctx) { + if (this.overlayColor) { + ctx.fillStyle = this.overlayColor.toLive + ? this.overlayColor.toLive(ctx) + : this.overlayColor; + + ctx.fillRect( + this.overlayColor.offsetX || 0, + this.overlayColor.offsetY || 0, + this.width, + this.height); + } + if (this.overlayImage) { + this._draw(ctx, this.overlayImage); + } + }, + + /** + * Method to render only the top canvas. + * Also used to render the group selection box. + * @return {fabric.Canvas} thisArg + * @chainable + */ + renderTop: function () { + var ctx = this.contextTop || this.contextContainer; + this.clearContext(ctx); + + // we render the top context - last object + if (this.selection && this._groupSelector) { + this._drawSelection(); + } + + // delegate rendering to group selection if one exists + // used for drawing selection borders/controls + var activeGroup = this.getActiveGroup(); + if (activeGroup) { + activeGroup.render(ctx); + } + + this._renderOverlay(ctx); + + this.fire('after:render'); + + return this; + }, + + /** + * Returns coordinates of a center of canvas. + * Returned value is an object with top and left properties + * @return {Object} object with "top" and "left" number values + */ + getCenter: function () { + return { + top: this.getHeight() / 2, + left: this.getWidth() / 2 + }; + }, + + /** + * Centers object horizontally. + * You might need to call `setCoords` on an object after centering, to update controls area. + * @param {fabric.Object} object Object to center horizontally + * @return {fabric.Canvas} thisArg + */ + centerObjectH: function (object) { + this._centerObject(object, new fabric.Point(this.getCenter().left, object.getCenterPoint().y)); + this.renderAll(); + return this; + }, + + /** + * Centers object vertically. + * You might need to call `setCoords` on an object after centering, to update controls area. + * @param {fabric.Object} object Object to center vertically + * @return {fabric.Canvas} thisArg + * @chainable + */ + centerObjectV: function (object) { + this._centerObject(object, new fabric.Point(object.getCenterPoint().x, this.getCenter().top)); + this.renderAll(); + return this; + }, + + /** + * Centers object vertically and horizontally. + * You might need to call `setCoords` on an object after centering, to update controls area. + * @param {fabric.Object} object Object to center vertically and horizontally + * @return {fabric.Canvas} thisArg + * @chainable + */ + centerObject: function(object) { + var center = this.getCenter(); + + this._centerObject(object, new fabric.Point(center.left, center.top)); + this.renderAll(); + return this; + }, + + /** + * @private + * @param {fabric.Object} object Object to center + * @param {fabric.Point} center Center point + * @return {fabric.Canvas} thisArg + * @chainable + */ + _centerObject: function(object, center) { + object.setPositionByOrigin(center, 'center', 'center'); + return this; + }, + + /** + * Returs dataless JSON representation of canvas + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {String} json string + */ + toDatalessJSON: function (propertiesToInclude) { + return this.toDatalessObject(propertiesToInclude); + }, + + /** + * Returns object representation of canvas + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} object representation of an instance + */ + toObject: function (propertiesToInclude) { + return this._toObjectMethod('toObject', propertiesToInclude); + }, + + /** + * Returns dataless object representation of canvas + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} object representation of an instance + */ + toDatalessObject: function (propertiesToInclude) { + return this._toObjectMethod('toDatalessObject', propertiesToInclude); + }, + + /** + * @private + */ + _toObjectMethod: function (methodName, propertiesToInclude) { + + var data = { + objects: this._toObjects(methodName, propertiesToInclude) + }; + + extend(data, this.__serializeBgOverlay()); + + fabric.util.populateWithProperties(this, data, propertiesToInclude); + + return data; + }, + + /** + * @private + */ + _toObjects: function(methodName, propertiesToInclude) { + return this.getObjects().map(function(instance) { + return this._toObject(instance, methodName, propertiesToInclude); + }, this); + }, + + /** + * @private + */ + _toObject: function(instance, methodName, propertiesToInclude) { + var originalValue; + + if (!this.includeDefaultValues) { + originalValue = instance.includeDefaultValues; + instance.includeDefaultValues = false; + } + + //If the object is part of the current selection group, it should + //be transformed appropriately + //i.e. it should be serialised as it would appear if the selection group + //were to be destroyed. + var originalProperties = this._realizeGroupTransformOnObject(instance), + object = instance[methodName](propertiesToInclude); + if (!this.includeDefaultValues) { + instance.includeDefaultValues = originalValue; + } + + //Undo the damage we did by changing all of its properties + this._unwindGroupTransformOnObject(instance, originalProperties); + + return object; + }, + + /** + * Realises an object's group transformation on it + * @private + * @param {fabric.Object} [instance] the object to transform (gets mutated) + * @returns the original values of instance which were changed + */ + _realizeGroupTransformOnObject: function(instance) { + var layoutProps = ['angle', 'flipX', 'flipY', 'height', 'left', 'scaleX', 'scaleY', 'top', 'width']; + if (instance.group && instance.group === this.getActiveGroup()) { + //Copy all the positionally relevant properties across now + var originalValues = {}; + layoutProps.forEach(function(prop) { + originalValues[prop] = instance[prop]; + }); + this.getActiveGroup().realizeTransform(instance); + return originalValues; + } + else { + return null; + } + }, + + /* + * Restores the changed properties of instance + * @private + * @param {fabric.Object} [instance] the object to un-transform (gets mutated) + * @param {Object} [originalValues] the original values of instance, as returned by _realizeGroupTransformOnObject + */ + _unwindGroupTransformOnObject: function(instance, originalValues) { + if (originalValues) { + instance.set(originalValues); + } + }, + + /** + * @private + */ + __serializeBgOverlay: function() { + var data = { + background: (this.backgroundColor && this.backgroundColor.toObject) + ? this.backgroundColor.toObject() + : this.backgroundColor + }; + + if (this.overlayColor) { + data.overlay = this.overlayColor.toObject + ? this.overlayColor.toObject() + : this.overlayColor; + } + if (this.backgroundImage) { + data.backgroundImage = this.backgroundImage.toObject(); + } + if (this.overlayImage) { + data.overlayImage = this.overlayImage.toObject(); + } + + return data; + }, + + /* _TO_SVG_START_ */ + /** + * When true, getSvgTransform() will apply the StaticCanvas.viewportTransform to the SVG transformation. When true, + * a zoomed canvas will then produce zoomed SVG output. + * @type Boolean + * @default + */ + svgViewportTransformation: true, + + /** + * Returns SVG representation of canvas + * @function + * @param {Object} [options] Options object for SVG output + * @param {Boolean} [options.suppressPreamble=false] If true xml tag is not included + * @param {Object} [options.viewBox] SVG viewbox object + * @param {Number} [options.viewBox.x] x-cooridnate of viewbox + * @param {Number} [options.viewBox.y] y-coordinate of viewbox + * @param {Number} [options.viewBox.width] Width of viewbox + * @param {Number} [options.viewBox.height] Height of viewbox + * @param {String} [options.encoding=UTF-8] Encoding of SVG output + * @param {Function} [reviver] Method for further parsing of svg elements, called after each fabric object converted into svg representation. + * @return {String} SVG string + * @tutorial {@link http://fabricjs.com/fabric-intro-part-3/#serialization} + * @see {@link http://jsfiddle.net/fabricjs/jQ3ZZ/|jsFiddle demo} + * @example Normal SVG output + * var svg = canvas.toSVG(); + * @example SVG output without preamble (without <?xml ../>) + * var svg = canvas.toSVG({suppressPreamble: true}); + * @example SVG output with viewBox attribute + * var svg = canvas.toSVG({ + * viewBox: { + * x: 100, + * y: 100, + * width: 200, + * height: 300 + * } + * }); + * @example SVG output with different encoding (default: UTF-8) + * var svg = canvas.toSVG({encoding: 'ISO-8859-1'}); + * @example Modify SVG output with reviver function + * var svg = canvas.toSVG(null, function(svg) { + * return svg.replace('stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; ', ''); + * }); + */ + toSVG: function(options, reviver) { + options || (options = { }); + + var markup = []; + + this._setSVGPreamble(markup, options); + this._setSVGHeader(markup, options); + + this._setSVGBgOverlayColor(markup, 'backgroundColor'); + this._setSVGBgOverlayImage(markup, 'backgroundImage'); + + this._setSVGObjects(markup, reviver); + + this._setSVGBgOverlayColor(markup, 'overlayColor'); + this._setSVGBgOverlayImage(markup, 'overlayImage'); + + markup.push(''); + + return markup.join(''); + }, + + /** + * @private + */ + _setSVGPreamble: function(markup, options) { + if (!options.suppressPreamble) { + markup.push( + '', + '\n' + ); + } + }, + + /** + * @private + */ + _setSVGHeader: function(markup, options) { + var width, height, vpt; + + if (options.viewBox) { + width = options.viewBox.width; + height = options.viewBox.height; + } + else { + width = this.width; + height = this.height; + if (!this.svgViewportTransformation) { + vpt = this.viewportTransform; + width /= vpt[0]; + height /= vpt[3]; + } + } + + markup.push( + '', + 'Created with Fabric.js ', fabric.version, '', + '', + fabric.createSVGFontFacesMarkup(this.getObjects()), + fabric.createSVGRefElementsMarkup(this), + '' + ); + }, + + /** + * @private + */ + _setSVGObjects: function(markup, reviver) { + for (var i = 0, objects = this.getObjects(), len = objects.length; i < len; i++) { + var instance = objects[i], + //If the object is in a selection group, simulate what would happen to that + //object when the group is deselected + originalProperties = this._realizeGroupTransformOnObject(instance); + markup.push(instance.toSVG(reviver)); + this._unwindGroupTransformOnObject(instance, originalProperties); + } + }, + + /** + * @private + */ + _setSVGBgOverlayImage: function(markup, property) { + if (this[property] && this[property].toSVG) { + markup.push(this[property].toSVG()); + } + }, + + /** + * @private + */ + _setSVGBgOverlayColor: function(markup, property) { + if (this[property] && this[property].source) { + markup.push( + '' + ); + } + else if (this[property] && property === 'overlayColor') { + markup.push( + '' + ); + } + }, + /* _TO_SVG_END_ */ + + /** + * Moves an object to the bottom of the stack of drawn objects + * @param {fabric.Object} object Object to send to back + * @return {fabric.Canvas} thisArg + * @chainable + */ + sendToBack: function (object) { + removeFromArray(this._objects, object); + this._objects.unshift(object); + return this.renderAll && this.renderAll(); + }, + + /** + * Moves an object to the top of the stack of drawn objects + * @param {fabric.Object} object Object to send + * @return {fabric.Canvas} thisArg + * @chainable + */ + bringToFront: function (object) { + removeFromArray(this._objects, object); + this._objects.push(object); + return this.renderAll && this.renderAll(); + }, + + /** + * Moves an object down in stack of drawn objects + * @param {fabric.Object} object Object to send + * @param {Boolean} [intersecting] If `true`, send object behind next lower intersecting object + * @return {fabric.Canvas} thisArg + * @chainable + */ + sendBackwards: function (object, intersecting) { + var idx = this._objects.indexOf(object); + + // if object is not on the bottom of stack + if (idx !== 0) { + var newIdx = this._findNewLowerIndex(object, idx, intersecting); + + removeFromArray(this._objects, object); + this._objects.splice(newIdx, 0, object); + this.renderAll && this.renderAll(); + } + return this; + }, + + /** + * @private + */ + _findNewLowerIndex: function(object, idx, intersecting) { + var newIdx; + + if (intersecting) { + newIdx = idx; + + // traverse down the stack looking for the nearest intersecting object + for (var i = idx - 1; i >= 0; --i) { + + var isIntersecting = object.intersectsWithObject(this._objects[i]) || + object.isContainedWithinObject(this._objects[i]) || + this._objects[i].isContainedWithinObject(object); + + if (isIntersecting) { + newIdx = i; + break; + } + } + } + else { + newIdx = idx - 1; + } + + return newIdx; + }, + + /** + * Moves an object up in stack of drawn objects + * @param {fabric.Object} object Object to send + * @param {Boolean} [intersecting] If `true`, send object in front of next upper intersecting object + * @return {fabric.Canvas} thisArg + * @chainable + */ + bringForward: function (object, intersecting) { + var idx = this._objects.indexOf(object); + + // if object is not on top of stack (last item in an array) + if (idx !== this._objects.length - 1) { + var newIdx = this._findNewUpperIndex(object, idx, intersecting); + + removeFromArray(this._objects, object); + this._objects.splice(newIdx, 0, object); + this.renderAll && this.renderAll(); + } + return this; + }, + + /** + * @private + */ + _findNewUpperIndex: function(object, idx, intersecting) { + var newIdx; + + if (intersecting) { + newIdx = idx; + + // traverse up the stack looking for the nearest intersecting object + for (var i = idx + 1; i < this._objects.length; ++i) { + + var isIntersecting = object.intersectsWithObject(this._objects[i]) || + object.isContainedWithinObject(this._objects[i]) || + this._objects[i].isContainedWithinObject(object); + + if (isIntersecting) { + newIdx = i; + break; + } + } + } + else { + newIdx = idx + 1; + } + + return newIdx; + }, + + /** + * Moves an object to specified level in stack of drawn objects + * @param {fabric.Object} object Object to send + * @param {Number} index Position to move to + * @return {fabric.Canvas} thisArg + * @chainable + */ + moveTo: function (object, index) { + removeFromArray(this._objects, object); + this._objects.splice(index, 0, object); + return this.renderAll && this.renderAll(); + }, + + /** + * Clears a canvas element and removes all event listeners + * @return {fabric.Canvas} thisArg + * @chainable + */ + dispose: function () { + this.clear(); + this.interactive && this.removeListeners(); + return this; + }, + + /** + * Returns a string representation of an instance + * @return {String} string representation of an instance + */ + toString: function () { + return '#'; + } + }); + + extend(fabric.StaticCanvas.prototype, fabric.Observable); + extend(fabric.StaticCanvas.prototype, fabric.Collection); + extend(fabric.StaticCanvas.prototype, fabric.DataURLExporter); + + extend(fabric.StaticCanvas, /** @lends fabric.StaticCanvas */ { + + /** + * @static + * @type String + * @default + */ + EMPTY_JSON: '{"objects": [], "background": "white"}', + + /** + * Provides a way to check support of some of the canvas methods + * (either those of HTMLCanvasElement itself, or rendering context) + * + * @param {String} methodName Method to check support for; + * Could be one of "getImageData", "toDataURL", "toDataURLWithQuality" or "setLineDash" + * @return {Boolean | null} `true` if method is supported (or at least exists), + * `null` if canvas element or context can not be initialized + */ + supports: function (methodName) { + var el = fabric.util.createCanvasElement(); + + if (!el || !el.getContext) { + return null; + } + + var ctx = el.getContext('2d'); + if (!ctx) { + return null; + } + + switch (methodName) { + + case 'getImageData': + return typeof ctx.getImageData !== 'undefined'; + + case 'setLineDash': + return typeof ctx.setLineDash !== 'undefined'; + + case 'toDataURL': + return typeof el.toDataURL !== 'undefined'; + + case 'toDataURLWithQuality': + try { + el.toDataURL('image/jpeg', 0); + return true; + } + catch (e) { } + return false; + + default: + return null; + } + } + }); + + /** + * Returns JSON representation of canvas + * @function + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {String} JSON string + * @tutorial {@link http://fabricjs.com/fabric-intro-part-3/#serialization} + * @see {@link http://jsfiddle.net/fabricjs/pec86/|jsFiddle demo} + * @example JSON without additional properties + * var json = canvas.toJSON(); + * @example JSON with additional properties included + * var json = canvas.toJSON(['lockMovementX', 'lockMovementY', 'lockRotation', 'lockScalingX', 'lockScalingY', 'lockUniScaling']); + * @example JSON without default values + * canvas.includeDefaultValues = false; + * var json = canvas.toJSON(); + */ + fabric.StaticCanvas.prototype.toJSON = fabric.StaticCanvas.prototype.toObject; + +})(); + + +/** + * BaseBrush class + * @class fabric.BaseBrush + * @see {@link http://fabricjs.com/freedrawing/|Freedrawing demo} + */ +fabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype */ { + + /** + * Color of a brush + * @type String + * @default + */ + color: 'rgb(0, 0, 0)', + + /** + * Width of a brush + * @type Number + * @default + */ + width: 1, + + /** + * Shadow object representing shadow of this shape. + * Backwards incompatibility note: This property replaces "shadowColor" (String), "shadowOffsetX" (Number), + * "shadowOffsetY" (Number) and "shadowBlur" (Number) since v1.2.12 + * @type fabric.Shadow + * @default + */ + shadow: null, + + /** + * Line endings style of a brush (one of "butt", "round", "square") + * @type String + * @default + */ + strokeLineCap: 'round', + + /** + * Corner style of a brush (one of "bevil", "round", "miter") + * @type String + * @default + */ + strokeLineJoin: 'round', + + /** + * Stroke Dash Array. + * @type Array + * @default + */ + strokeDashArray: null, + + /** + * Sets shadow of an object + * @param {Object|String} [options] Options object or string (e.g. "2px 2px 10px rgba(0,0,0,0.2)") + * @return {fabric.Object} thisArg + * @chainable + */ + setShadow: function(options) { + this.shadow = new fabric.Shadow(options); + return this; + }, + + /** + * Sets brush styles + * @private + */ + _setBrushStyles: function() { + var ctx = this.canvas.contextTop; + + ctx.strokeStyle = this.color; + ctx.lineWidth = this.width; + ctx.lineCap = this.strokeLineCap; + ctx.lineJoin = this.strokeLineJoin; + if (this.strokeDashArray && fabric.StaticCanvas.supports('setLineDash')) { + ctx.setLineDash(this.strokeDashArray); + } + }, + + /** + * Sets brush shadow styles + * @private + */ + _setShadow: function() { + if (!this.shadow) { + return; + } + + var ctx = this.canvas.contextTop; + + ctx.shadowColor = this.shadow.color; + ctx.shadowBlur = this.shadow.blur; + ctx.shadowOffsetX = this.shadow.offsetX; + ctx.shadowOffsetY = this.shadow.offsetY; + }, + + /** + * Removes brush shadow styles + * @private + */ + _resetShadow: function() { + var ctx = this.canvas.contextTop; + + ctx.shadowColor = ''; + ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0; + } +}); + + +(function() { + + /** + * PencilBrush class + * @class fabric.PencilBrush + * @extends fabric.BaseBrush + */ + fabric.PencilBrush = fabric.util.createClass(fabric.BaseBrush, /** @lends fabric.PencilBrush.prototype */ { + + /** + * Constructor + * @param {fabric.Canvas} canvas + * @return {fabric.PencilBrush} Instance of a pencil brush + */ + initialize: function(canvas) { + this.canvas = canvas; + this._points = [ ]; + }, + + /** + * Inovoked on mouse down + * @param {Object} pointer + */ + onMouseDown: function(pointer) { + this._prepareForDrawing(pointer); + // capture coordinates immediately + // this allows to draw dots (when movement never occurs) + this._captureDrawingPath(pointer); + this._render(); + }, + + /** + * Inovoked on mouse move + * @param {Object} pointer + */ + onMouseMove: function(pointer) { + this._captureDrawingPath(pointer); + // redraw curve + // clear top canvas + this.canvas.clearContext(this.canvas.contextTop); + this._render(); + }, + + /** + * Invoked on mouse up + */ + onMouseUp: function() { + this._finalizeAndAddPath(); + }, + + /** + * @private + * @param {Object} pointer Actual mouse position related to the canvas. + */ + _prepareForDrawing: function(pointer) { + + var p = new fabric.Point(pointer.x, pointer.y); + + this._reset(); + this._addPoint(p); + + this.canvas.contextTop.moveTo(p.x, p.y); + }, + + /** + * @private + * @param {fabric.Point} point Point to be added to points array + */ + _addPoint: function(point) { + this._points.push(point); + }, + + /** + * Clear points array and set contextTop canvas style. + * @private + */ + _reset: function() { + this._points.length = 0; + + this._setBrushStyles(); + this._setShadow(); + }, + + /** + * @private + * @param {Object} pointer Actual mouse position related to the canvas. + */ + _captureDrawingPath: function(pointer) { + var pointerPoint = new fabric.Point(pointer.x, pointer.y); + this._addPoint(pointerPoint); + }, + + /** + * Draw a smooth path on the topCanvas using quadraticCurveTo + * @private + */ + _render: function() { + var ctx = this.canvas.contextTop, + v = this.canvas.viewportTransform, + p1 = this._points[0], + p2 = this._points[1]; + + ctx.save(); + ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); + ctx.beginPath(); + + //if we only have 2 points in the path and they are the same + //it means that the user only clicked the canvas without moving the mouse + //then we should be drawing a dot. A path isn't drawn between two identical dots + //that's why we set them apart a bit + if (this._points.length === 2 && p1.x === p2.x && p1.y === p2.y) { + p1.x -= 0.5; + p2.x += 0.5; + } + ctx.moveTo(p1.x, p1.y); + + for (var i = 1, len = this._points.length; i < len; i++) { + // we pick the point between pi + 1 & pi + 2 as the + // end point and p1 as our control point. + var midPoint = p1.midPointFrom(p2); + ctx.quadraticCurveTo(p1.x, p1.y, midPoint.x, midPoint.y); + + p1 = this._points[i]; + p2 = this._points[i + 1]; + } + // Draw last line as a straight line while + // we wait for the next point to be able to calculate + // the bezier control point + ctx.lineTo(p1.x, p1.y); + ctx.stroke(); + ctx.restore(); + }, + + /** + * Converts points to SVG path + * @param {Array} points Array of points + * @param {Number} minX + * @param {Number} minY + * @return {String} SVG path + */ + convertPointsToSVGPath: function(points) { + var path = [], + p1 = new fabric.Point(points[0].x, points[0].y), + p2 = new fabric.Point(points[1].x, points[1].y); + + path.push('M ', points[0].x, ' ', points[0].y, ' '); + for (var i = 1, len = points.length; i < len; i++) { + var midPoint = p1.midPointFrom(p2); + // p1 is our bezier control point + // midpoint is our endpoint + // start point is p(i-1) value. + path.push('Q ', p1.x, ' ', p1.y, ' ', midPoint.x, ' ', midPoint.y, ' '); + p1 = new fabric.Point(points[i].x, points[i].y); + if ((i + 1) < points.length) { + p2 = new fabric.Point(points[i + 1].x, points[i + 1].y); + } + } + path.push('L ', p1.x, ' ', p1.y, ' '); + return path; + }, + + /** + * Creates fabric.Path object to add on canvas + * @param {String} pathData Path data + * @return {fabric.Path} Path to add on canvas + */ + createPath: function(pathData) { + var path = new fabric.Path(pathData, { + fill: null, + stroke: this.color, + strokeWidth: this.width, + strokeLineCap: this.strokeLineCap, + strokeLineJoin: this.strokeLineJoin, + strokeDashArray: this.strokeDashArray, + originX: 'center', + originY: 'center' + }); + + if (this.shadow) { + this.shadow.affectStroke = true; + path.setShadow(this.shadow); + } + + return path; + }, + + /** + * On mouseup after drawing the path on contextTop canvas + * we use the points captured to create an new fabric path object + * and add it to the fabric canvas. + */ + _finalizeAndAddPath: function() { + var ctx = this.canvas.contextTop; + ctx.closePath(); + + var pathData = this.convertPointsToSVGPath(this._points).join(''); + if (pathData === 'M 0 0 Q 0 0 0 0 L 0 0') { + // do not create 0 width/height paths, as they are + // rendered inconsistently across browsers + // Firefox 4, for example, renders a dot, + // whereas Chrome 10 renders nothing + this.canvas.renderAll(); + return; + } + + var path = this.createPath(pathData); + + this.canvas.add(path); + path.setCoords(); + + this.canvas.clearContext(this.canvas.contextTop); + this._resetShadow(); + this.canvas.renderAll(); + + // fire event 'path' created + this.canvas.fire('path:created', { path: path }); + } + }); +})(); + + +/** + * CircleBrush class + * @class fabric.CircleBrush + */ +fabric.CircleBrush = fabric.util.createClass(fabric.BaseBrush, /** @lends fabric.CircleBrush.prototype */ { + + /** + * Width of a brush + * @type Number + * @default + */ + width: 10, + + /** + * Constructor + * @param {fabric.Canvas} canvas + * @return {fabric.CircleBrush} Instance of a circle brush + */ + initialize: function(canvas) { + this.canvas = canvas; + this.points = [ ]; + }, + /** + * Invoked inside on mouse down and mouse move + * @param {Object} pointer + */ + drawDot: function(pointer) { + var point = this.addPoint(pointer), + ctx = this.canvas.contextTop, + v = this.canvas.viewportTransform; + ctx.save(); + ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); + + ctx.fillStyle = point.fill; + ctx.beginPath(); + ctx.arc(point.x, point.y, point.radius, 0, Math.PI * 2, false); + ctx.closePath(); + ctx.fill(); + + ctx.restore(); + }, + + /** + * Invoked on mouse down + */ + onMouseDown: function(pointer) { + this.points.length = 0; + this.canvas.clearContext(this.canvas.contextTop); + this._setShadow(); + this.drawDot(pointer); + }, + + /** + * Invoked on mouse move + * @param {Object} pointer + */ + onMouseMove: function(pointer) { + this.drawDot(pointer); + }, + + /** + * Invoked on mouse up + */ + onMouseUp: function() { + var originalRenderOnAddRemove = this.canvas.renderOnAddRemove; + this.canvas.renderOnAddRemove = false; + + var circles = [ ]; + + for (var i = 0, len = this.points.length; i < len; i++) { + var point = this.points[i], + circle = new fabric.Circle({ + radius: point.radius, + left: point.x, + top: point.y, + originX: 'center', + originY: 'center', + fill: point.fill + }); + + this.shadow && circle.setShadow(this.shadow); + + circles.push(circle); + } + var group = new fabric.Group(circles, { originX: 'center', originY: 'center' }); + group.canvas = this.canvas; + + this.canvas.add(group); + this.canvas.fire('path:created', { path: group }); + + this.canvas.clearContext(this.canvas.contextTop); + this._resetShadow(); + this.canvas.renderOnAddRemove = originalRenderOnAddRemove; + this.canvas.renderAll(); + }, + + /** + * @param {Object} pointer + * @return {fabric.Point} Just added pointer point + */ + addPoint: function(pointer) { + var pointerPoint = new fabric.Point(pointer.x, pointer.y), + + circleRadius = fabric.util.getRandomInt( + Math.max(0, this.width - 20), this.width + 20) / 2, + + circleColor = new fabric.Color(this.color) + .setAlpha(fabric.util.getRandomInt(0, 100) / 100) + .toRgba(); + + pointerPoint.radius = circleRadius; + pointerPoint.fill = circleColor; + + this.points.push(pointerPoint); + + return pointerPoint; + } +}); + + +/** + * SprayBrush class + * @class fabric.SprayBrush + */ +fabric.SprayBrush = fabric.util.createClass( fabric.BaseBrush, /** @lends fabric.SprayBrush.prototype */ { + + /** + * Width of a spray + * @type Number + * @default + */ + width: 10, + + /** + * Density of a spray (number of dots per chunk) + * @type Number + * @default + */ + density: 20, + + /** + * Width of spray dots + * @type Number + * @default + */ + dotWidth: 1, + + /** + * Width variance of spray dots + * @type Number + * @default + */ + dotWidthVariance: 1, + + /** + * Whether opacity of a dot should be random + * @type Boolean + * @default + */ + randomOpacity: false, + + /** + * Whether overlapping dots (rectangles) should be removed (for performance reasons) + * @type Boolean + * @default + */ + optimizeOverlapping: true, + + /** + * Constructor + * @param {fabric.Canvas} canvas + * @return {fabric.SprayBrush} Instance of a spray brush + */ + initialize: function(canvas) { + this.canvas = canvas; + this.sprayChunks = [ ]; + }, + + /** + * Invoked on mouse down + * @param {Object} pointer + */ + onMouseDown: function(pointer) { + this.sprayChunks.length = 0; + this.canvas.clearContext(this.canvas.contextTop); + this._setShadow(); + + this.addSprayChunk(pointer); + this.render(); + }, + + /** + * Invoked on mouse move + * @param {Object} pointer + */ + onMouseMove: function(pointer) { + this.addSprayChunk(pointer); + this.render(); + }, + + /** + * Invoked on mouse up + */ + onMouseUp: function() { + var originalRenderOnAddRemove = this.canvas.renderOnAddRemove; + this.canvas.renderOnAddRemove = false; + + var rects = [ ]; + + for (var i = 0, ilen = this.sprayChunks.length; i < ilen; i++) { + var sprayChunk = this.sprayChunks[i]; + + for (var j = 0, jlen = sprayChunk.length; j < jlen; j++) { + + var rect = new fabric.Rect({ + width: sprayChunk[j].width, + height: sprayChunk[j].width, + left: sprayChunk[j].x + 1, + top: sprayChunk[j].y + 1, + originX: 'center', + originY: 'center', + fill: this.color + }); + + this.shadow && rect.setShadow(this.shadow); + rects.push(rect); + } + } + + if (this.optimizeOverlapping) { + rects = this._getOptimizedRects(rects); + } + + var group = new fabric.Group(rects, { originX: 'center', originY: 'center' }); + group.canvas = this.canvas; + + this.canvas.add(group); + this.canvas.fire('path:created', { path: group }); + + this.canvas.clearContext(this.canvas.contextTop); + this._resetShadow(); + this.canvas.renderOnAddRemove = originalRenderOnAddRemove; + this.canvas.renderAll(); + }, + + /** + * @private + * @param {Array} rects + */ + _getOptimizedRects: function(rects) { + + // avoid creating duplicate rects at the same coordinates + var uniqueRects = { }, key; + + for (var i = 0, len = rects.length; i < len; i++) { + key = rects[i].left + '' + rects[i].top; + if (!uniqueRects[key]) { + uniqueRects[key] = rects[i]; + } + } + var uniqueRectsArray = [ ]; + for (key in uniqueRects) { + uniqueRectsArray.push(uniqueRects[key]); + } + + return uniqueRectsArray; + }, + + /** + * Renders brush + */ + render: function() { + var ctx = this.canvas.contextTop; + ctx.fillStyle = this.color; + + var v = this.canvas.viewportTransform; + ctx.save(); + ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); + + for (var i = 0, len = this.sprayChunkPoints.length; i < len; i++) { + var point = this.sprayChunkPoints[i]; + if (typeof point.opacity !== 'undefined') { + ctx.globalAlpha = point.opacity; + } + ctx.fillRect(point.x, point.y, point.width, point.width); + } + ctx.restore(); + }, + + /** + * @param {Object} pointer + */ + addSprayChunk: function(pointer) { + this.sprayChunkPoints = [ ]; + + var x, y, width, radius = this.width / 2; + + for (var i = 0; i < this.density; i++) { + + x = fabric.util.getRandomInt(pointer.x - radius, pointer.x + radius); + y = fabric.util.getRandomInt(pointer.y - radius, pointer.y + radius); + + if (this.dotWidthVariance) { + width = fabric.util.getRandomInt( + // bottom clamp width to 1 + Math.max(1, this.dotWidth - this.dotWidthVariance), + this.dotWidth + this.dotWidthVariance); + } + else { + width = this.dotWidth; + } + + var point = new fabric.Point(x, y); + point.width = width; + + if (this.randomOpacity) { + point.opacity = fabric.util.getRandomInt(0, 100) / 100; + } + + this.sprayChunkPoints.push(point); + } + + this.sprayChunks.push(this.sprayChunkPoints); + } +}); + + +/** + * PatternBrush class + * @class fabric.PatternBrush + * @extends fabric.BaseBrush + */ +fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fabric.PatternBrush.prototype */ { + + getPatternSrc: function() { + + var dotWidth = 20, + dotDistance = 5, + patternCanvas = fabric.document.createElement('canvas'), + patternCtx = patternCanvas.getContext('2d'); + + patternCanvas.width = patternCanvas.height = dotWidth + dotDistance; + + patternCtx.fillStyle = this.color; + patternCtx.beginPath(); + patternCtx.arc(dotWidth / 2, dotWidth / 2, dotWidth / 2, 0, Math.PI * 2, false); + patternCtx.closePath(); + patternCtx.fill(); + + return patternCanvas; + }, + + getPatternSrcFunction: function() { + return String(this.getPatternSrc).replace('this.color', '"' + this.color + '"'); + }, + + /** + * Creates "pattern" instance property + */ + getPattern: function() { + return this.canvas.contextTop.createPattern(this.source || this.getPatternSrc(), 'repeat'); + }, + + /** + * Sets brush styles + */ + _setBrushStyles: function() { + this.callSuper('_setBrushStyles'); + this.canvas.contextTop.strokeStyle = this.getPattern(); + }, + + /** + * Creates path + */ + createPath: function(pathData) { + var path = this.callSuper('createPath', pathData); + path.stroke = new fabric.Pattern({ + source: this.source || this.getPatternSrcFunction() + }); + return path; + } +}); + + +(function() { + + var getPointer = fabric.util.getPointer, + degreesToRadians = fabric.util.degreesToRadians, + radiansToDegrees = fabric.util.radiansToDegrees, + atan2 = Math.atan2, + abs = Math.abs, + + STROKE_OFFSET = 0.5; + + /** + * Canvas class + * @class fabric.Canvas + * @extends fabric.StaticCanvas + * @tutorial {@link http://fabricjs.com/fabric-intro-part-1/#canvas} + * @see {@link fabric.Canvas#initialize} for constructor definition + * + * @fires object:modified + * @fires object:rotating + * @fires object:scaling + * @fires object:moving + * @fires object:selected + * + * @fires before:selection:cleared + * @fires selection:cleared + * @fires selection:created + * + * @fires path:created + * @fires mouse:down + * @fires mouse:move + * @fires mouse:up + * @fires mouse:over + * @fires mouse:out + * + */ + fabric.Canvas = fabric.util.createClass(fabric.StaticCanvas, /** @lends fabric.Canvas.prototype */ { + + /** + * Constructor + * @param {HTMLElement | String} el <canvas> element to initialize instance on + * @param {Object} [options] Options object + * @return {Object} thisArg + */ + initialize: function(el, options) { + options || (options = { }); + + this._initStatic(el, options); + this._initInteractive(); + this._createCacheCanvas(); + + fabric.Canvas.activeInstance = this; + }, + + /** + * When true, objects can be transformed by one side (unproportionally) + * @type Boolean + * @default + */ + uniScaleTransform: false, + + /** + * When true, objects use center point as the origin of scale transformation. + * Backwards incompatibility note: This property replaces "centerTransform" (Boolean). + * @since 1.3.4 + * @type Boolean + * @default + */ + centeredScaling: false, + + /** + * When true, objects use center point as the origin of rotate transformation. + * Backwards incompatibility note: This property replaces "centerTransform" (Boolean). + * @since 1.3.4 + * @type Boolean + * @default + */ + centeredRotation: false, + + /** + * Indicates that canvas is interactive. This property should not be changed. + * @type Boolean + * @default + */ + interactive: true, + + /** + * Indicates whether group selection should be enabled + * @type Boolean + * @default + */ + selection: true, + + /** + * Color of selection + * @type String + * @default + */ + selectionColor: 'rgba(100, 100, 255, 0.3)', // blue + + /** + * Default dash array pattern + * If not empty the selection border is dashed + * @type Array + */ + selectionDashArray: [ ], + + /** + * Color of the border of selection (usually slightly darker than color of selection itself) + * @type String + * @default + */ + selectionBorderColor: 'rgba(255, 255, 255, 0.3)', + + /** + * Width of a line used in object/group selection + * @type Number + * @default + */ + selectionLineWidth: 1, + + /** + * Default cursor value used when hovering over an object on canvas + * @type String + * @default + */ + hoverCursor: 'move', + + /** + * Default cursor value used when moving an object on canvas + * @type String + * @default + */ + moveCursor: 'move', + + /** + * Default cursor value used for the entire canvas + * @type String + * @default + */ + defaultCursor: 'default', + + /** + * Cursor value used during free drawing + * @type String + * @default + */ + freeDrawingCursor: 'crosshair', + + /** + * Cursor value used for rotation point + * @type String + * @default + */ + rotationCursor: 'crosshair', + + /** + * Default element class that's given to wrapper (div) element of canvas + * @type String + * @default + */ + containerClass: 'canvas-container', + + /** + * When true, object detection happens on per-pixel basis rather than on per-bounding-box + * @type Boolean + * @default + */ + perPixelTargetFind: false, + + /** + * Number of pixels around target pixel to tolerate (consider active) during object detection + * @type Number + * @default + */ + targetFindTolerance: 0, + + /** + * When true, target detection is skipped when hovering over canvas. This can be used to improve performance. + * @type Boolean + * @default + */ + skipTargetFind: false, + + /** + * @private + */ + _initInteractive: function() { + this._currentTransform = null; + this._groupSelector = null; + this._initWrapperElement(); + this._createUpperCanvas(); + this._initEventListeners(); + + this.freeDrawingBrush = fabric.PencilBrush && new fabric.PencilBrush(this); + + this.calcOffset(); + }, + + /** + * Resets the current transform to its original values and chooses the type of resizing based on the event + * @private + * @param {Event} e Event object fired on mousemove + */ + _resetCurrentTransform: function(e) { + var t = this._currentTransform; + + t.target.set({ + scaleX: t.original.scaleX, + scaleY: t.original.scaleY, + left: t.original.left, + top: t.original.top + }); + + if (this._shouldCenterTransform(e, t.target)) { + if (t.action === 'rotate') { + this._setOriginToCenter(t.target); + } + else { + if (t.originX !== 'center') { + if (t.originX === 'right') { + t.mouseXSign = -1; + } + else { + t.mouseXSign = 1; + } + } + if (t.originY !== 'center') { + if (t.originY === 'bottom') { + t.mouseYSign = -1; + } + else { + t.mouseYSign = 1; + } + } + + t.originX = 'center'; + t.originY = 'center'; + } + } + else { + t.originX = t.original.originX; + t.originY = t.original.originY; + } + }, + + /** + * Checks if point is contained within an area of given object + * @param {Event} e Event object + * @param {fabric.Object} target Object to test against + * @return {Boolean} true if point is contained within an area of given object + */ + containsPoint: function (e, target) { + var pointer = this.getPointer(e, true), + xy = this._normalizePointer(target, pointer); + + // http://www.geog.ubc.ca/courses/klink/gis.notes/ncgia/u32.html + // http://idav.ucdavis.edu/~okreylos/TAship/Spring2000/PointInPolygon.html + return (target.containsPoint(xy) || target._findTargetCorner(pointer)); + }, + + /** + * @private + */ + _normalizePointer: function (object, pointer) { + var activeGroup = this.getActiveGroup(), + x = pointer.x, + y = pointer.y, + isObjectInGroup = ( + activeGroup && + object.type !== 'group' && + activeGroup.contains(object)), + lt; + + if (isObjectInGroup) { + lt = new fabric.Point(activeGroup.left, activeGroup.top); + lt = fabric.util.transformPoint(lt, this.viewportTransform, true); + x -= lt.x; + y -= lt.y; + } + return { x: x, y: y }; + }, + + /** + * Returns true if object is transparent at a certain location + * @param {fabric.Object} target Object to check + * @param {Number} x Left coordinate + * @param {Number} y Top coordinate + * @return {Boolean} + */ + isTargetTransparent: function (target, x, y) { + var hasBorders = target.hasBorders, + transparentCorners = target.transparentCorners; + + target.hasBorders = target.transparentCorners = false; + + this._draw(this.contextCache, target); + + target.hasBorders = hasBorders; + target.transparentCorners = transparentCorners; + + var isTransparent = fabric.util.isTransparent( + this.contextCache, x, y, this.targetFindTolerance); + + this.clearContext(this.contextCache); + + return isTransparent; + }, + + /** + * @private + * @param {Event} e Event object + * @param {fabric.Object} target + */ + _shouldClearSelection: function (e, target) { + var activeGroup = this.getActiveGroup(), + activeObject = this.getActiveObject(); + + return ( + !target + || + (target && + activeGroup && + !activeGroup.contains(target) && + activeGroup !== target && + !e.shiftKey) + || + (target && !target.evented) + || + (target && + !target.selectable && + activeObject && + activeObject !== target) + ); + }, + + /** + * @private + * @param {Event} e Event object + * @param {fabric.Object} target + */ + _shouldCenterTransform: function (e, target) { + if (!target) { + return; + } + + var t = this._currentTransform, + centerTransform; + + if (t.action === 'scale' || t.action === 'scaleX' || t.action === 'scaleY') { + centerTransform = this.centeredScaling || target.centeredScaling; + } + else if (t.action === 'rotate') { + centerTransform = this.centeredRotation || target.centeredRotation; + } + + return centerTransform ? !e.altKey : e.altKey; + }, + + /** + * @private + */ + _getOriginFromCorner: function(target, corner) { + var origin = { + x: target.originX, + y: target.originY + }; + + if (corner === 'ml' || corner === 'tl' || corner === 'bl') { + origin.x = 'right'; + } + else if (corner === 'mr' || corner === 'tr' || corner === 'br') { + origin.x = 'left'; + } + + if (corner === 'tl' || corner === 'mt' || corner === 'tr') { + origin.y = 'bottom'; + } + else if (corner === 'bl' || corner === 'mb' || corner === 'br') { + origin.y = 'top'; + } + + return origin; + }, + + /** + * @private + */ + _getActionFromCorner: function(target, corner) { + var action = 'drag'; + if (corner) { + action = (corner === 'ml' || corner === 'mr') + ? 'scaleX' + : (corner === 'mt' || corner === 'mb') + ? 'scaleY' + : corner === 'mtr' + ? 'rotate' + : 'scale'; + } + return action; + }, + + /** + * @private + * @param {Event} e Event object + * @param {fabric.Object} target + */ + _setupCurrentTransform: function (e, target) { + if (!target) { + return; + } + + var pointer = this.getPointer(e), + corner = target._findTargetCorner(this.getPointer(e, true)), + action = this._getActionFromCorner(target, corner), + origin = this._getOriginFromCorner(target, corner); + + this._currentTransform = { + target: target, + action: action, + scaleX: target.scaleX, + scaleY: target.scaleY, + offsetX: pointer.x - target.left, + offsetY: pointer.y - target.top, + originX: origin.x, + originY: origin.y, + ex: pointer.x, + ey: pointer.y, + left: target.left, + top: target.top, + theta: degreesToRadians(target.angle), + width: target.width * target.scaleX, + mouseXSign: 1, + mouseYSign: 1 + }; + + this._currentTransform.original = { + left: target.left, + top: target.top, + scaleX: target.scaleX, + scaleY: target.scaleY, + originX: origin.x, + originY: origin.y + }; + + this._resetCurrentTransform(e); + }, + + /** + * Translates object by "setting" its left/top + * @private + * @param {Number} x pointer's x coordinate + * @param {Number} y pointer's y coordinate + */ + _translateObject: function (x, y) { + var target = this._currentTransform.target; + + if (!target.get('lockMovementX')) { + target.set('left', x - this._currentTransform.offsetX); + } + if (!target.get('lockMovementY')) { + target.set('top', y - this._currentTransform.offsetY); + } + }, + + /** + * Scales object by invoking its scaleX/scaleY methods + * @private + * @param {Number} x pointer's x coordinate + * @param {Number} y pointer's y coordinate + * @param {String} by Either 'x' or 'y' - specifies dimension constraint by which to scale an object. + * When not provided, an object is scaled by both dimensions equally + */ + _scaleObject: function (x, y, by) { + var t = this._currentTransform, + target = t.target, + lockScalingX = target.get('lockScalingX'), + lockScalingY = target.get('lockScalingY'), + lockScalingFlip = target.get('lockScalingFlip'); + + if (lockScalingX && lockScalingY) { + return; + } + + // Get the constraint point + var constraintPosition = target.translateToOriginPoint(target.getCenterPoint(), t.originX, t.originY), + localMouse = target.toLocalPoint(new fabric.Point(x, y), t.originX, t.originY); + + this._setLocalMouse(localMouse, t); + + // Actually scale the object + this._setObjectScale(localMouse, t, lockScalingX, lockScalingY, by, lockScalingFlip); + + // Make sure the constraints apply + target.setPositionByOrigin(constraintPosition, t.originX, t.originY); + }, + + /** + * @private + */ + _setObjectScale: function(localMouse, transform, lockScalingX, lockScalingY, by, lockScalingFlip) { + var target = transform.target, forbidScalingX = false, forbidScalingY = false, + strokeWidth = target.stroke ? target.strokeWidth : 0; + + transform.newScaleX = localMouse.x / (target.width + strokeWidth / 2); + transform.newScaleY = localMouse.y / (target.height + strokeWidth / 2); + + if (lockScalingFlip && transform.newScaleX <= 0 && transform.newScaleX < target.scaleX) { + forbidScalingX = true; + } + + if (lockScalingFlip && transform.newScaleY <= 0 && transform.newScaleY < target.scaleY) { + forbidScalingY = true; + } + + if (by === 'equally' && !lockScalingX && !lockScalingY) { + forbidScalingX || forbidScalingY || this._scaleObjectEqually(localMouse, target, transform); + } + else if (!by) { + forbidScalingX || lockScalingX || target.set('scaleX', transform.newScaleX); + forbidScalingY || lockScalingY || target.set('scaleY', transform.newScaleY); + } + else if (by === 'x' && !target.get('lockUniScaling')) { + forbidScalingX || lockScalingX || target.set('scaleX', transform.newScaleX); + } + else if (by === 'y' && !target.get('lockUniScaling')) { + forbidScalingY || lockScalingY || target.set('scaleY', transform.newScaleY); + } + + forbidScalingX || forbidScalingY || this._flipObject(transform, by); + + }, + + /** + * @private + */ + _scaleObjectEqually: function(localMouse, target, transform) { + + var dist = localMouse.y + localMouse.x, + strokeWidth = target.stroke ? target.strokeWidth : 0, + lastDist = (target.height + (strokeWidth / 2)) * transform.original.scaleY + + (target.width + (strokeWidth / 2)) * transform.original.scaleX; + + // We use transform.scaleX/Y instead of target.scaleX/Y + // because the object may have a min scale and we'll loose the proportions + transform.newScaleX = transform.original.scaleX * dist / lastDist; + transform.newScaleY = transform.original.scaleY * dist / lastDist; + + target.set('scaleX', transform.newScaleX); + target.set('scaleY', transform.newScaleY); + }, + + /** + * @private + */ + _flipObject: function(transform, by) { + if (transform.newScaleX < 0 && by !== 'y') { + if (transform.originX === 'left') { + transform.originX = 'right'; + } + else if (transform.originX === 'right') { + transform.originX = 'left'; + } + } + + if (transform.newScaleY < 0 && by !== 'x') { + if (transform.originY === 'top') { + transform.originY = 'bottom'; + } + else if (transform.originY === 'bottom') { + transform.originY = 'top'; + } + } + }, + + /** + * @private + */ + _setLocalMouse: function(localMouse, t) { + var target = t.target; + + if (t.originX === 'right') { + localMouse.x *= -1; + } + else if (t.originX === 'center') { + localMouse.x *= t.mouseXSign * 2; + + if (localMouse.x < 0) { + t.mouseXSign = -t.mouseXSign; + } + } + + if (t.originY === 'bottom') { + localMouse.y *= -1; + } + else if (t.originY === 'center') { + localMouse.y *= t.mouseYSign * 2; + + if (localMouse.y < 0) { + t.mouseYSign = -t.mouseYSign; + } + } + + // adjust the mouse coordinates when dealing with padding + if (abs(localMouse.x) > target.padding) { + if (localMouse.x < 0) { + localMouse.x += target.padding; + } + else { + localMouse.x -= target.padding; + } + } + else { // mouse is within the padding, set to 0 + localMouse.x = 0; + } + + if (abs(localMouse.y) > target.padding) { + if (localMouse.y < 0) { + localMouse.y += target.padding; + } + else { + localMouse.y -= target.padding; + } + } + else { + localMouse.y = 0; + } + }, + + /** + * Rotates object by invoking its rotate method + * @private + * @param {Number} x pointer's x coordinate + * @param {Number} y pointer's y coordinate + */ + _rotateObject: function (x, y) { + + var t = this._currentTransform; + + if (t.target.get('lockRotation')) { + return; + } + + var lastAngle = atan2(t.ey - t.top, t.ex - t.left), + curAngle = atan2(y - t.top, x - t.left), + angle = radiansToDegrees(curAngle - lastAngle + t.theta); + + // normalize angle to positive value + if (angle < 0) { + angle = 360 + angle; + } + + t.target.angle = angle % 360; + }, + + /** + * Set the cursor type of the canvas element + * @param {String} value Cursor type of the canvas element. + * @see http://www.w3.org/TR/css3-ui/#cursor + */ + setCursor: function (value) { + this.upperCanvasEl.style.cursor = value; + }, + + /** + * @private + */ + _resetObjectTransform: function (target) { + target.scaleX = 1; + target.scaleY = 1; + target.setAngle(0); + }, + + /** + * @private + */ + _drawSelection: function () { + var ctx = this.contextTop, + groupSelector = this._groupSelector, + left = groupSelector.left, + top = groupSelector.top, + aleft = abs(left), + atop = abs(top); + + ctx.fillStyle = this.selectionColor; + + ctx.fillRect( + groupSelector.ex - ((left > 0) ? 0 : -left), + groupSelector.ey - ((top > 0) ? 0 : -top), + aleft, + atop + ); + + ctx.lineWidth = this.selectionLineWidth; + ctx.strokeStyle = this.selectionBorderColor; + + // selection border + if (this.selectionDashArray.length > 1) { + + var px = groupSelector.ex + STROKE_OFFSET - ((left > 0) ? 0: aleft), + py = groupSelector.ey + STROKE_OFFSET - ((top > 0) ? 0: atop); + + ctx.beginPath(); + + fabric.util.drawDashedLine(ctx, px, py, px + aleft, py, this.selectionDashArray); + fabric.util.drawDashedLine(ctx, px, py + atop - 1, px + aleft, py + atop - 1, this.selectionDashArray); + fabric.util.drawDashedLine(ctx, px, py, px, py + atop, this.selectionDashArray); + fabric.util.drawDashedLine(ctx, px + aleft - 1, py, px + aleft - 1, py + atop, this.selectionDashArray); + + ctx.closePath(); + ctx.stroke(); + } + else { + ctx.strokeRect( + groupSelector.ex + STROKE_OFFSET - ((left > 0) ? 0 : aleft), + groupSelector.ey + STROKE_OFFSET - ((top > 0) ? 0 : atop), + aleft, + atop + ); + } + }, + + /** + * @private + */ + _isLastRenderedObject: function(e) { + return ( + this.controlsAboveOverlay && + this.lastRenderedObjectWithControlsAboveOverlay && + this.lastRenderedObjectWithControlsAboveOverlay.visible && + this.containsPoint(e, this.lastRenderedObjectWithControlsAboveOverlay) && + this.lastRenderedObjectWithControlsAboveOverlay._findTargetCorner(this.getPointer(e, true))); + }, + + /** + * Method that determines what object we are clicking on + * @param {Event} e mouse event + * @param {Boolean} skipGroup when true, group is skipped and only objects are traversed through + */ + findTarget: function (e, skipGroup) { + if (this.skipTargetFind) { + return; + } + + if (this._isLastRenderedObject(e)) { + return this.lastRenderedObjectWithControlsAboveOverlay; + } + + // first check current group (if one exists) + var activeGroup = this.getActiveGroup(); + if (activeGroup && !skipGroup && this.containsPoint(e, activeGroup)) { + return activeGroup; + } + + var target = this._searchPossibleTargets(e); + this._fireOverOutEvents(target); + + return target; + }, + + /** + * @private + */ + _fireOverOutEvents: function(target) { + if (target) { + if (this._hoveredTarget !== target) { + this.fire('mouse:over', { target: target }); + target.fire('mouseover'); + if (this._hoveredTarget) { + this.fire('mouse:out', { target: this._hoveredTarget }); + this._hoveredTarget.fire('mouseout'); + } + this._hoveredTarget = target; + } + } + else if (this._hoveredTarget) { + this.fire('mouse:out', { target: this._hoveredTarget }); + this._hoveredTarget.fire('mouseout'); + this._hoveredTarget = null; + } + }, + + /** + * @private + */ + _checkTarget: function(e, obj, pointer) { + if (obj && + obj.visible && + obj.evented && + this.containsPoint(e, obj)){ + if ((this.perPixelTargetFind || obj.perPixelTargetFind) && !obj.isEditing) { + var isTransparent = this.isTargetTransparent(obj, pointer.x, pointer.y); + if (!isTransparent) { + return true; + } + } + else { + return true; + } + } + }, + + /** + * @private + */ + _searchPossibleTargets: function(e) { + + // Cache all targets where their bounding box contains point. + var target, + pointer = this.getPointer(e, true), + i = this._objects.length; + // Do not check for currently grouped objects, since we check the parent group itself. + while (i--) { + if (!this._objects[i].group && this._checkTarget(e, this._objects[i], pointer)){ + this.relatedTarget = this._objects[i]; + target = this._objects[i]; + break; + } + } + + return target; + }, + + /** + * Returns pointer coordinates relative to canvas. + * @param {Event} e + * @return {Object} object with "x" and "y" number values + */ + getPointer: function (e, ignoreZoom, upperCanvasEl) { + if (!upperCanvasEl) { + upperCanvasEl = this.upperCanvasEl; + } + var pointer = getPointer(e, upperCanvasEl), + bounds = upperCanvasEl.getBoundingClientRect(), + boundsWidth = bounds.width || 0, + boundsHeight = bounds.height || 0, + cssScale; + + if (!boundsWidth || !boundsHeight ) { + if ('top' in bounds && 'bottom' in bounds) { + boundsHeight = Math.abs( bounds.top - bounds.bottom ); + } + if ('right' in bounds && 'left' in bounds) { + boundsWidth = Math.abs( bounds.right - bounds.left ); + } + } + + this.calcOffset(); + + pointer.x = pointer.x - this._offset.left; + pointer.y = pointer.y - this._offset.top; + if (!ignoreZoom) { + pointer = fabric.util.transformPoint( + pointer, + fabric.util.invertTransform(this.viewportTransform) + ); + } + + if (boundsWidth === 0 || boundsHeight === 0) { + // If bounds are not available (i.e. not visible), do not apply scale. + cssScale = { width: 1, height: 1 }; + } + else { + cssScale = { + width: upperCanvasEl.width / boundsWidth, + height: upperCanvasEl.height / boundsHeight + }; + } + + return { + x: pointer.x * cssScale.width, + y: pointer.y * cssScale.height + }; + }, + + /** + * @private + * @throws {CANVAS_INIT_ERROR} If canvas can not be initialized + */ + _createUpperCanvas: function () { + var lowerCanvasClass = this.lowerCanvasEl.className.replace(/\s*lower-canvas\s*/, ''); + + this.upperCanvasEl = this._createCanvasElement(); + fabric.util.addClass(this.upperCanvasEl, 'upper-canvas ' + lowerCanvasClass); + + this.wrapperEl.appendChild(this.upperCanvasEl); + + this._copyCanvasStyle(this.lowerCanvasEl, this.upperCanvasEl); + this._applyCanvasStyle(this.upperCanvasEl); + this.contextTop = this.upperCanvasEl.getContext('2d'); + }, + + /** + * @private + */ + _createCacheCanvas: function () { + this.cacheCanvasEl = this._createCanvasElement(); + this.cacheCanvasEl.setAttribute('width', this.width); + this.cacheCanvasEl.setAttribute('height', this.height); + this.contextCache = this.cacheCanvasEl.getContext('2d'); + }, + + /** + * @private + */ + _initWrapperElement: function () { + this.wrapperEl = fabric.util.wrapElement(this.lowerCanvasEl, 'div', { + 'class': this.containerClass + }); + fabric.util.setStyle(this.wrapperEl, { + width: this.getWidth() + 'px', + height: this.getHeight() + 'px', + position: 'relative' + }); + fabric.util.makeElementUnselectable(this.wrapperEl); + }, + + /** + * @private + * @param {HTMLElement} element canvas element to apply styles on + */ + _applyCanvasStyle: function (element) { + var width = this.getWidth() || element.width, + height = this.getHeight() || element.height; + + fabric.util.setStyle(element, { + position: 'absolute', + width: width + 'px', + height: height + 'px', + left: 0, + top: 0 + }); + element.width = width; + element.height = height; + fabric.util.makeElementUnselectable(element); + }, + + /** + * Copys the the entire inline style from one element (fromEl) to another (toEl) + * @private + * @param {Element} fromEl Element style is copied from + * @param {Element} toEl Element copied style is applied to + */ + _copyCanvasStyle: function (fromEl, toEl) { + toEl.style.cssText = fromEl.style.cssText; + }, + + /** + * Returns context of canvas where object selection is drawn + * @return {CanvasRenderingContext2D} + */ + getSelectionContext: function() { + return this.contextTop; + }, + + /** + * Returns <canvas> element on which object selection is drawn + * @return {HTMLCanvasElement} + */ + getSelectionElement: function () { + return this.upperCanvasEl; + }, + + /** + * @private + * @param {Object} object + */ + _setActiveObject: function(object) { + if (this._activeObject) { + this._activeObject.set('active', false); + } + this._activeObject = object; + object.set('active', true); + }, + + /** + * Sets given object as the only active object on canvas + * @param {fabric.Object} object Object to set as an active one + * @param {Event} [e] Event (passed along when firing "object:selected") + * @return {fabric.Canvas} thisArg + * @chainable + */ + setActiveObject: function (object, e) { + this._setActiveObject(object); + this.renderAll(); + this.fire('object:selected', { target: object, e: e }); + object.fire('selected', { e: e }); + return this; + }, + + /** + * Returns currently active object + * @return {fabric.Object} active object + */ + getActiveObject: function () { + return this._activeObject; + }, + + /** + * @private + */ + _discardActiveObject: function() { + if (this._activeObject) { + this._activeObject.set('active', false); + } + this._activeObject = null; + }, + + /** + * Discards currently active object + * @return {fabric.Canvas} thisArg + * @chainable + */ + discardActiveObject: function (e) { + this._discardActiveObject(); + this.renderAll(); + this.fire('selection:cleared', { e: e }); + return this; + }, + + /** + * @private + * @param {fabric.Group} group + */ + _setActiveGroup: function(group) { + this._activeGroup = group; + if (group) { + group.set('active', true); + } + }, + + /** + * Sets active group to a speicified one + * @param {fabric.Group} group Group to set as a current one + * @return {fabric.Canvas} thisArg + * @chainable + */ + setActiveGroup: function (group, e) { + this._setActiveGroup(group); + if (group) { + this.fire('object:selected', { target: group, e: e }); + group.fire('selected', { e: e }); + } + return this; + }, + + /** + * Returns currently active group + * @return {fabric.Group} Current group + */ + getActiveGroup: function () { + return this._activeGroup; + }, + + /** + * @private + */ + _discardActiveGroup: function() { + var g = this.getActiveGroup(); + if (g) { + g.destroy(); + } + this.setActiveGroup(null); + }, + + /** + * Discards currently active group + * @return {fabric.Canvas} thisArg + */ + discardActiveGroup: function (e) { + this._discardActiveGroup(); + this.fire('selection:cleared', { e: e }); + return this; + }, + + /** + * Deactivates all objects on canvas, removing any active group or object + * @return {fabric.Canvas} thisArg + */ + deactivateAll: function () { + var allObjects = this.getObjects(), + i = 0, + len = allObjects.length; + for ( ; i < len; i++) { + allObjects[i].set('active', false); + } + this._discardActiveGroup(); + this._discardActiveObject(); + return this; + }, + + /** + * Deactivates all objects and dispatches appropriate events + * @return {fabric.Canvas} thisArg + */ + deactivateAllWithDispatch: function (e) { + var activeObject = this.getActiveGroup() || this.getActiveObject(); + if (activeObject) { + this.fire('before:selection:cleared', { target: activeObject, e: e }); + } + this.deactivateAll(); + if (activeObject) { + this.fire('selection:cleared', { e: e }); + } + return this; + }, + + /** + * Draws objects' controls (borders/controls) + * @param {CanvasRenderingContext2D} ctx Context to render controls on + */ + drawControls: function(ctx) { + var activeGroup = this.getActiveGroup(); + if (activeGroup) { + this._drawGroupControls(ctx, activeGroup); + } + else { + this._drawObjectsControls(ctx); + } + }, + + /** + * @private + */ + _drawGroupControls: function(ctx, activeGroup) { + activeGroup._renderControls(ctx); + }, + + /** + * @private + */ + _drawObjectsControls: function(ctx) { + for (var i = 0, len = this._objects.length; i < len; ++i) { + if (!this._objects[i] || !this._objects[i].active) { + continue; + } + this._objects[i]._renderControls(ctx); + this.lastRenderedObjectWithControlsAboveOverlay = this._objects[i]; + } + } + }); + + // copying static properties manually to work around Opera's bug, + // where "prototype" property is enumerable and overrides existing prototype + for (var prop in fabric.StaticCanvas) { + if (prop !== 'prototype') { + fabric.Canvas[prop] = fabric.StaticCanvas[prop]; + } + } + + if (fabric.isTouchSupported) { + /** @ignore */ + fabric.Canvas.prototype._setCursorFromEvent = function() { }; + } + + /** + * @class fabric.Element + * @alias fabric.Canvas + * @deprecated Use {@link fabric.Canvas} instead. + * @constructor + */ + fabric.Element = fabric.Canvas; +})(); + + +(function() { + + var cursorOffset = { + mt: 0, // n + tr: 1, // ne + mr: 2, // e + br: 3, // se + mb: 4, // s + bl: 5, // sw + ml: 6, // w + tl: 7 // nw + }, + addListener = fabric.util.addListener, + removeListener = fabric.util.removeListener; + + fabric.util.object.extend(fabric.Canvas.prototype, /** @lends fabric.Canvas.prototype */ { + + /** + * Map of cursor style values for each of the object controls + * @private + */ + cursorMap: [ + 'n-resize', + 'ne-resize', + 'e-resize', + 'se-resize', + 's-resize', + 'sw-resize', + 'w-resize', + 'nw-resize' + ], + + /** + * Adds mouse listeners to canvas + * @private + */ + _initEventListeners: function () { + + this._bindEvents(); + + addListener(fabric.window, 'resize', this._onResize); + + // mouse events + addListener(this.upperCanvasEl, 'mousedown', this._onMouseDown); + addListener(this.upperCanvasEl, 'mousemove', this._onMouseMove); + addListener(this.upperCanvasEl, 'mousewheel', this._onMouseWheel); + + // touch events + addListener(this.upperCanvasEl, 'touchstart', this._onMouseDown); + addListener(this.upperCanvasEl, 'touchmove', this._onMouseMove); + + if (typeof eventjs !== 'undefined' && 'add' in eventjs) { + eventjs.add(this.upperCanvasEl, 'gesture', this._onGesture); + eventjs.add(this.upperCanvasEl, 'drag', this._onDrag); + eventjs.add(this.upperCanvasEl, 'orientation', this._onOrientationChange); + eventjs.add(this.upperCanvasEl, 'shake', this._onShake); + eventjs.add(this.upperCanvasEl, 'longpress', this._onLongPress); + } + }, + + /** + * @private + */ + _bindEvents: function() { + this._onMouseDown = this._onMouseDown.bind(this); + this._onMouseMove = this._onMouseMove.bind(this); + this._onMouseUp = this._onMouseUp.bind(this); + this._onResize = this._onResize.bind(this); + this._onGesture = this._onGesture.bind(this); + this._onDrag = this._onDrag.bind(this); + this._onShake = this._onShake.bind(this); + this._onLongPress = this._onLongPress.bind(this); + this._onOrientationChange = this._onOrientationChange.bind(this); + this._onMouseWheel = this._onMouseWheel.bind(this); + }, + + /** + * Removes all event listeners + */ + removeListeners: function() { + removeListener(fabric.window, 'resize', this._onResize); + + removeListener(this.upperCanvasEl, 'mousedown', this._onMouseDown); + removeListener(this.upperCanvasEl, 'mousemove', this._onMouseMove); + removeListener(this.upperCanvasEl, 'mousewheel', this._onMouseWheel); + + removeListener(this.upperCanvasEl, 'touchstart', this._onMouseDown); + removeListener(this.upperCanvasEl, 'touchmove', this._onMouseMove); + + if (typeof eventjs !== 'undefined' && 'remove' in eventjs) { + eventjs.remove(this.upperCanvasEl, 'gesture', this._onGesture); + eventjs.remove(this.upperCanvasEl, 'drag', this._onDrag); + eventjs.remove(this.upperCanvasEl, 'orientation', this._onOrientationChange); + eventjs.remove(this.upperCanvasEl, 'shake', this._onShake); + eventjs.remove(this.upperCanvasEl, 'longpress', this._onLongPress); + } + }, + + /** + * @private + * @param {Event} [e] Event object fired on Event.js gesture + * @param {Event} [self] Inner Event object + */ + _onGesture: function(e, self) { + this.__onTransformGesture && this.__onTransformGesture(e, self); + }, + + /** + * @private + * @param {Event} [e] Event object fired on Event.js drag + * @param {Event} [self] Inner Event object + */ + _onDrag: function(e, self) { + this.__onDrag && this.__onDrag(e, self); + }, + + /** + * @private + * @param {Event} [e] Event object fired on Event.js wheel event + * @param {Event} [self] Inner Event object + */ + _onMouseWheel: function(e, self) { + this.__onMouseWheel && this.__onMouseWheel(e, self); + }, + + /** + * @private + * @param {Event} [e] Event object fired on Event.js orientation change + * @param {Event} [self] Inner Event object + */ + _onOrientationChange: function(e, self) { + this.__onOrientationChange && this.__onOrientationChange(e, self); + }, + + /** + * @private + * @param {Event} [e] Event object fired on Event.js shake + * @param {Event} [self] Inner Event object + */ + _onShake: function(e, self) { + this.__onShake && this.__onShake(e, self); + }, + /** + * @private + * @param {Event} [e] Event object fired on Event.js shake + * @param {Event} [self] Inner Event object + */ + _onLongPress: function(e, self) { + this.__onLongPress && this.__onLongPress(e, self); + }, + + /** + * @private + * @param {Event} e Event object fired on mousedown + */ + _onMouseDown: function (e) { + this.__onMouseDown(e); + + addListener(fabric.document, 'touchend', this._onMouseUp); + addListener(fabric.document, 'touchmove', this._onMouseMove); + + removeListener(this.upperCanvasEl, 'mousemove', this._onMouseMove); + removeListener(this.upperCanvasEl, 'touchmove', this._onMouseMove); + + if (e.type === 'touchstart') { + // Unbind mousedown to prevent double triggers from touch devices + removeListener(this.upperCanvasEl, 'mousedown', this._onMouseDown); + } + else { + addListener(fabric.document, 'mouseup', this._onMouseUp); + addListener(fabric.document, 'mousemove', this._onMouseMove); + } + }, + + /** + * @private + * @param {Event} e Event object fired on mouseup + */ + _onMouseUp: function (e) { + this.__onMouseUp(e); + + removeListener(fabric.document, 'mouseup', this._onMouseUp); + removeListener(fabric.document, 'touchend', this._onMouseUp); + + removeListener(fabric.document, 'mousemove', this._onMouseMove); + removeListener(fabric.document, 'touchmove', this._onMouseMove); + + addListener(this.upperCanvasEl, 'mousemove', this._onMouseMove); + addListener(this.upperCanvasEl, 'touchmove', this._onMouseMove); + + if (e.type === 'touchend') { + // Wait 400ms before rebinding mousedown to prevent double triggers + // from touch devices + var _this = this; + setTimeout(function() { + addListener(_this.upperCanvasEl, 'mousedown', _this._onMouseDown); + }, 400); + } + }, + + /** + * @private + * @param {Event} e Event object fired on mousemove + */ + _onMouseMove: function (e) { + !this.allowTouchScrolling && e.preventDefault && e.preventDefault(); + this.__onMouseMove(e); + }, + + /** + * @private + */ + _onResize: function () { + this.calcOffset(); + }, + + /** + * Decides whether the canvas should be redrawn in mouseup and mousedown events. + * @private + * @param {Object} target + * @param {Object} pointer + */ + _shouldRender: function(target, pointer) { + var activeObject = this.getActiveGroup() || this.getActiveObject(); + + return !!( + (target && ( + target.isMoving || + target !== activeObject)) + || + (!target && !!activeObject) + || + (!target && !activeObject && !this._groupSelector) + || + (pointer && + this._previousPointer && + this.selection && ( + pointer.x !== this._previousPointer.x || + pointer.y !== this._previousPointer.y)) + ); + }, + + /** + * Method that defines the actions when mouse is released on canvas. + * The method resets the currentTransform parameters, store the image corner + * position in the image object and render the canvas on top. + * @private + * @param {Event} e Event object fired on mouseup + */ + __onMouseUp: function (e) { + var target; + + if (this.isDrawingMode && this._isCurrentlyDrawing) { + this._onMouseUpInDrawingMode(e); + return; + } + + if (this._currentTransform) { + this._finalizeCurrentTransform(); + target = this._currentTransform.target; + } + else { + target = this.findTarget(e, true); + } + + var shouldRender = this._shouldRender(target, this.getPointer(e)); + + this._maybeGroupObjects(e); + + if (target) { + target.isMoving = false; + } + + shouldRender && this.renderAll(); + + this._handleCursorAndEvent(e, target); + }, + + _handleCursorAndEvent: function(e, target) { + this._setCursorFromEvent(e, target); + + // TODO: why are we doing this? + var _this = this; + setTimeout(function () { + _this._setCursorFromEvent(e, target); + }, 50); + + this.fire('mouse:up', { target: target, e: e }); + target && target.fire('mouseup', { e: e }); + }, + + /** + * @private + */ + _finalizeCurrentTransform: function() { + + var transform = this._currentTransform, + target = transform.target; + + if (target._scaling) { + target._scaling = false; + } + + target.setCoords(); + + // only fire :modified event if target coordinates were changed during mousedown-mouseup + if (this.stateful && target.hasStateChanged()) { + this.fire('object:modified', { target: target }); + target.fire('modified'); + } + + this._restoreOriginXY(target); + }, + + /** + * @private + * @param {Object} target Object to restore + */ + _restoreOriginXY: function(target) { + if (this._previousOriginX && this._previousOriginY) { + + var originPoint = target.translateToOriginPoint( + target.getCenterPoint(), + this._previousOriginX, + this._previousOriginY); + + target.originX = this._previousOriginX; + target.originY = this._previousOriginY; + + target.left = originPoint.x; + target.top = originPoint.y; + + this._previousOriginX = null; + this._previousOriginY = null; + } + }, + + /** + * @private + * @param {Event} e Event object fired on mousedown + */ + _onMouseDownInDrawingMode: function(e) { + this._isCurrentlyDrawing = true; + this.discardActiveObject(e).renderAll(); + if (this.clipTo) { + fabric.util.clipContext(this, this.contextTop); + } + var ivt = fabric.util.invertTransform(this.viewportTransform), + pointer = fabric.util.transformPoint(this.getPointer(e, true), ivt); + this.freeDrawingBrush.onMouseDown(pointer); + this.fire('mouse:down', { e: e }); + + var target = this.findTarget(e); + if (typeof target !== 'undefined') { + target.fire('mousedown', { e: e, target: target }); + } + }, + + /** + * @private + * @param {Event} e Event object fired on mousemove + */ + _onMouseMoveInDrawingMode: function(e) { + if (this._isCurrentlyDrawing) { + var ivt = fabric.util.invertTransform(this.viewportTransform), + pointer = fabric.util.transformPoint(this.getPointer(e, true), ivt); + this.freeDrawingBrush.onMouseMove(pointer); + } + this.setCursor(this.freeDrawingCursor); + this.fire('mouse:move', { e: e }); + + var target = this.findTarget(e); + if (typeof target !== 'undefined') { + target.fire('mousemove', { e: e, target: target }); + } + }, + + /** + * @private + * @param {Event} e Event object fired on mouseup + */ + _onMouseUpInDrawingMode: function(e) { + this._isCurrentlyDrawing = false; + if (this.clipTo) { + this.contextTop.restore(); + } + this.freeDrawingBrush.onMouseUp(); + this.fire('mouse:up', { e: e }); + + var target = this.findTarget(e); + if (typeof target !== 'undefined') { + target.fire('mouseup', { e: e, target: target }); + } + }, + + /** + * Method that defines the actions when mouse is clic ked on canvas. + * The method inits the currentTransform parameters and renders all the + * canvas so the current image can be placed on the top canvas and the rest + * in on the container one. + * @private + * @param {Event} e Event object fired on mousedown + */ + __onMouseDown: function (e) { + + // accept only left clicks + var isLeftClick = 'which' in e ? e.which === 1 : e.button === 1; + if (!isLeftClick && !fabric.isTouchSupported) { + return; + } + + if (this.isDrawingMode) { + this._onMouseDownInDrawingMode(e); + return; + } + + // ignore if some object is being transformed at this moment + if (this._currentTransform) { + return; + } + + var target = this.findTarget(e), + pointer = this.getPointer(e, true); + + // save pointer for check in __onMouseUp event + this._previousPointer = pointer; + + var shouldRender = this._shouldRender(target, pointer), + shouldGroup = this._shouldGroup(e, target); + + if (this._shouldClearSelection(e, target)) { + this._clearSelection(e, target, pointer); + } + else if (shouldGroup) { + this._handleGrouping(e, target); + target = this.getActiveGroup(); + } + + if (target && target.selectable && !shouldGroup) { + this._beforeTransform(e, target); + this._setupCurrentTransform(e, target); + } + // we must renderAll so that active image is placed on the top canvas + shouldRender && this.renderAll(); + + this.fire('mouse:down', { target: target, e: e }); + target && target.fire('mousedown', { e: e }); + }, + + /** + * @private + */ + _beforeTransform: function(e, target) { + this.stateful && target.saveState(); + + // determine if it's a drag or rotate case + if (target._findTargetCorner(this.getPointer(e))) { + this.onBeforeScaleRotate(target); + } + + if (target !== this.getActiveGroup() && target !== this.getActiveObject()) { + this.deactivateAll(); + this.setActiveObject(target, e); + } + }, + + /** + * @private + */ + _clearSelection: function(e, target, pointer) { + this.deactivateAllWithDispatch(e); + + if (target && target.selectable) { + this.setActiveObject(target, e); + } + else if (this.selection) { + this._groupSelector = { + ex: pointer.x, + ey: pointer.y, + top: 0, + left: 0 + }; + } + }, + + /** + * @private + * @param {Object} target Object for that origin is set to center + */ + _setOriginToCenter: function(target) { + this._previousOriginX = this._currentTransform.target.originX; + this._previousOriginY = this._currentTransform.target.originY; + + var center = target.getCenterPoint(); + + target.originX = 'center'; + target.originY = 'center'; + + target.left = center.x; + target.top = center.y; + + this._currentTransform.left = target.left; + this._currentTransform.top = target.top; + }, + + /** + * @private + * @param {Object} target Object for that center is set to origin + */ + _setCenterToOrigin: function(target) { + var originPoint = target.translateToOriginPoint( + target.getCenterPoint(), + this._previousOriginX, + this._previousOriginY); + + target.originX = this._previousOriginX; + target.originY = this._previousOriginY; + + target.left = originPoint.x; + target.top = originPoint.y; + + this._previousOriginX = null; + this._previousOriginY = null; + }, + + /** + * Method that defines the actions when mouse is hovering the canvas. + * The currentTransform parameter will definde whether the user is rotating/scaling/translating + * an image or neither of them (only hovering). A group selection is also possible and would cancel + * all any other type of action. + * In case of an image transformation only the top canvas will be rendered. + * @private + * @param {Event} e Event object fired on mousemove + */ + __onMouseMove: function (e) { + + var target, pointer; + + if (this.isDrawingMode) { + this._onMouseMoveInDrawingMode(e); + return; + } + if (typeof e.touches !== 'undefined' && e.touches.length > 1) { + return; + } + + var groupSelector = this._groupSelector; + + // We initially clicked in an empty area, so we draw a box for multiple selection + if (groupSelector) { + pointer = this.getPointer(e, true); + + groupSelector.left = pointer.x - groupSelector.ex; + groupSelector.top = pointer.y - groupSelector.ey; + + this.renderTop(); + } + else if (!this._currentTransform) { + + target = this.findTarget(e); + + if (!target || target && !target.selectable) { + this.setCursor(this.defaultCursor); + } + else { + this._setCursorFromEvent(e, target); + } + } + else { + this._transformObject(e); + } + + this.fire('mouse:move', { target: target, e: e }); + target && target.fire('mousemove', { e: e }); + }, + + /** + * @private + * @param {Event} e Event fired on mousemove + */ + _transformObject: function(e) { + var pointer = this.getPointer(e), + transform = this._currentTransform; + + transform.reset = false, + transform.target.isMoving = true; + + this._beforeScaleTransform(e, transform); + this._performTransformAction(e, transform, pointer); + + this.renderAll(); + }, + + /** + * @private + */ + _performTransformAction: function(e, transform, pointer) { + var x = pointer.x, + y = pointer.y, + target = transform.target, + action = transform.action; + + if (action === 'rotate') { + this._rotateObject(x, y); + this._fire('rotating', target, e); + } + else if (action === 'scale') { + this._onScale(e, transform, x, y); + this._fire('scaling', target, e); + } + else if (action === 'scaleX') { + this._scaleObject(x, y, 'x'); + this._fire('scaling', target, e); + } + else if (action === 'scaleY') { + this._scaleObject(x, y, 'y'); + this._fire('scaling', target, e); + } + else { + this._translateObject(x, y); + this._fire('moving', target, e); + this.setCursor(this.moveCursor); + } + }, + + /** + * @private + */ + _fire: function(eventName, target, e) { + this.fire('object:' + eventName, { target: target, e: e }); + target.fire(eventName, { e: e }); + }, + + /** + * @private + */ + _beforeScaleTransform: function(e, transform) { + if (transform.action === 'scale' || transform.action === 'scaleX' || transform.action === 'scaleY') { + var centerTransform = this._shouldCenterTransform(e, transform.target); + + // Switch from a normal resize to center-based + if ((centerTransform && (transform.originX !== 'center' || transform.originY !== 'center')) || + // Switch from center-based resize to normal one + (!centerTransform && transform.originX === 'center' && transform.originY === 'center') + ) { + this._resetCurrentTransform(e); + transform.reset = true; + } + } + }, + + /** + * @private + */ + _onScale: function(e, transform, x, y) { + // rotate object only if shift key is not pressed + // and if it is not a group we are transforming + if ((e.shiftKey || this.uniScaleTransform) && !transform.target.get('lockUniScaling')) { + transform.currentAction = 'scale'; + this._scaleObject(x, y); + } + else { + // Switch from a normal resize to proportional + if (!transform.reset && transform.currentAction === 'scale') { + this._resetCurrentTransform(e, transform.target); + } + + transform.currentAction = 'scaleEqually'; + this._scaleObject(x, y, 'equally'); + } + }, + + /** + * Sets the cursor depending on where the canvas is being hovered. + * Note: very buggy in Opera + * @param {Event} e Event object + * @param {Object} target Object that the mouse is hovering, if so. + */ + _setCursorFromEvent: function (e, target) { + if (!target || !target.selectable) { + this.setCursor(this.defaultCursor); + return false; + } + else { + var activeGroup = this.getActiveGroup(), + // only show proper corner when group selection is not active + corner = target._findTargetCorner + && (!activeGroup || !activeGroup.contains(target)) + && target._findTargetCorner(this.getPointer(e, true)); + + if (!corner) { + this.setCursor(target.hoverCursor || this.hoverCursor); + } + else { + this._setCornerCursor(corner, target); + } + } + return true; + }, + + /** + * @private + */ + _setCornerCursor: function(corner, target) { + if (corner in cursorOffset) { + this.setCursor(this._getRotatedCornerCursor(corner, target)); + } + else if (corner === 'mtr' && target.hasRotatingPoint) { + this.setCursor(this.rotationCursor); + } + else { + this.setCursor(this.defaultCursor); + return false; + } + }, + + /** + * @private + */ + _getRotatedCornerCursor: function(corner, target) { + var n = Math.round((target.getAngle() % 360) / 45); + + if (n < 0) { + n += 8; // full circle ahead + } + n += cursorOffset[corner]; + // normalize n to be from 0 to 7 + n %= 8; + + return this.cursorMap[n]; + } + }); +})(); + + +(function() { + + var min = Math.min, + max = Math.max; + + fabric.util.object.extend(fabric.Canvas.prototype, /** @lends fabric.Canvas.prototype */ { + + /** + * @private + * @param {Event} e Event object + * @param {fabric.Object} target + * @return {Boolean} + */ + _shouldGroup: function(e, target) { + var activeObject = this.getActiveObject(); + return e.shiftKey && + (this.getActiveGroup() || (activeObject && activeObject !== target)) + && this.selection; + }, + + /** + * @private + * @param {Event} e Event object + * @param {fabric.Object} target + */ + _handleGrouping: function (e, target) { + + if (target === this.getActiveGroup()) { + + // if it's a group, find target again, this time skipping group + target = this.findTarget(e, true); + + // if even object is not found, bail out + if (!target || target.isType('group')) { + return; + } + } + if (this.getActiveGroup()) { + this._updateActiveGroup(target, e); + } + else { + this._createActiveGroup(target, e); + } + + if (this._activeGroup) { + this._activeGroup.saveCoords(); + } + }, + + /** + * @private + */ + _updateActiveGroup: function(target, e) { + var activeGroup = this.getActiveGroup(); + + if (activeGroup.contains(target)) { + + activeGroup.removeWithUpdate(target); + this._resetObjectTransform(activeGroup); + target.set('active', false); + + if (activeGroup.size() === 1) { + // remove group alltogether if after removal it only contains 1 object + this.discardActiveGroup(e); + // activate last remaining object + this.setActiveObject(activeGroup.item(0)); + return; + } + } + else { + activeGroup.addWithUpdate(target); + this._resetObjectTransform(activeGroup); + } + this.fire('selection:created', { target: activeGroup, e: e }); + activeGroup.set('active', true); + }, + + /** + * @private + */ + _createActiveGroup: function(target, e) { + + if (this._activeObject && target !== this._activeObject) { + + var group = this._createGroup(target); + group.addWithUpdate(); + + this.setActiveGroup(group); + this._activeObject = null; + + this.fire('selection:created', { target: group, e: e }); + } + + target.set('active', true); + }, + + /** + * @private + * @param {Object} target + */ + _createGroup: function(target) { + + var objects = this.getObjects(), + isActiveLower = objects.indexOf(this._activeObject) < objects.indexOf(target), + groupObjects = isActiveLower + ? [ this._activeObject, target ] + : [ target, this._activeObject ]; + + return new fabric.Group(groupObjects, { + canvas: this + }); + }, + + /** + * @private + * @param {Event} e mouse event + */ + _groupSelectedObjects: function (e) { + + var group = this._collectObjects(); + + // do not create group for 1 element only + if (group.length === 1) { + this.setActiveObject(group[0], e); + } + else if (group.length > 1) { + group = new fabric.Group(group.reverse(), { + canvas: this + }); + group.addWithUpdate(); + this.setActiveGroup(group, e); + group.saveCoords(); + this.fire('selection:created', { target: group }); + this.renderAll(); + } + }, + + /** + * @private + */ + _collectObjects: function() { + var group = [ ], + currentObject, + x1 = this._groupSelector.ex, + y1 = this._groupSelector.ey, + x2 = x1 + this._groupSelector.left, + y2 = y1 + this._groupSelector.top, + selectionX1Y1 = new fabric.Point(min(x1, x2), min(y1, y2)), + selectionX2Y2 = new fabric.Point(max(x1, x2), max(y1, y2)), + isClick = x1 === x2 && y1 === y2; + + for (var i = this._objects.length; i--; ) { + currentObject = this._objects[i]; + + if (!currentObject || !currentObject.selectable || !currentObject.visible) { + continue; + } + + if (currentObject.intersectsWithRect(selectionX1Y1, selectionX2Y2) || + currentObject.isContainedWithinRect(selectionX1Y1, selectionX2Y2) || + currentObject.containsPoint(selectionX1Y1) || + currentObject.containsPoint(selectionX2Y2) + ) { + currentObject.set('active', true); + group.push(currentObject); + + // only add one object if it's a click + if (isClick) { + break; + } + } + } + + return group; + }, + + /** + * @private + */ + _maybeGroupObjects: function(e) { + if (this.selection && this._groupSelector) { + this._groupSelectedObjects(e); + } + + var activeGroup = this.getActiveGroup(); + if (activeGroup) { + activeGroup.setObjectsCoords().setCoords(); + activeGroup.isMoving = false; + this.setCursor(this.defaultCursor); + } + + // clear selection and current transformation + this._groupSelector = null; + this._currentTransform = null; + } + }); + +})(); + + +fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ { + + /** + * Exports canvas element to a dataurl image. Note that when multiplier is used, cropping is scaled appropriately + * @param {Object} [options] Options object + * @param {String} [options.format=png] The format of the output image. Either "jpeg" or "png" + * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg. + * @param {Number} [options.multiplier=1] Multiplier to scale by + * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14 + * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14 + * @param {Number} [options.width] Cropping width. Introduced in v1.2.14 + * @param {Number} [options.height] Cropping height. Introduced in v1.2.14 + * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format + * @see {@link http://jsfiddle.net/fabricjs/NfZVb/|jsFiddle demo} + * @example Generate jpeg dataURL with lower quality + * var dataURL = canvas.toDataURL({ + * format: 'jpeg', + * quality: 0.8 + * }); + * @example Generate cropped png dataURL (clipping of canvas) + * var dataURL = canvas.toDataURL({ + * format: 'png', + * left: 100, + * top: 100, + * width: 200, + * height: 200 + * }); + * @example Generate double scaled png dataURL + * var dataURL = canvas.toDataURL({ + * format: 'png', + * multiplier: 2 + * }); + */ + toDataURL: function (options) { + options || (options = { }); + + var format = options.format || 'png', + quality = options.quality || 1, + multiplier = options.multiplier || 1, + cropping = { + left: options.left, + top: options.top, + width: options.width, + height: options.height + }; + + if (multiplier !== 1) { + return this.__toDataURLWithMultiplier(format, quality, cropping, multiplier); + } + else { + return this.__toDataURL(format, quality, cropping); + } + }, + + /** + * @private + */ + __toDataURL: function(format, quality, cropping) { + + this.renderAll(true); + + var canvasEl = this.upperCanvasEl || this.lowerCanvasEl, + croppedCanvasEl = this.__getCroppedCanvas(canvasEl, cropping); + + // to avoid common confusion https://github.com/kangax/fabric.js/issues/806 + if (format === 'jpg') { + format = 'jpeg'; + } + + var data = (fabric.StaticCanvas.supports('toDataURLWithQuality')) + ? (croppedCanvasEl || canvasEl).toDataURL('image/' + format, quality) + : (croppedCanvasEl || canvasEl).toDataURL('image/' + format); + + this.contextTop && this.clearContext(this.contextTop); + this.renderAll(); + + if (croppedCanvasEl) { + croppedCanvasEl = null; + } + + return data; + }, + + /** + * @private + */ + __getCroppedCanvas: function(canvasEl, cropping) { + + var croppedCanvasEl, + croppedCtx, + shouldCrop = 'left' in cropping || + 'top' in cropping || + 'width' in cropping || + 'height' in cropping; + + if (shouldCrop) { + + croppedCanvasEl = fabric.util.createCanvasElement(); + croppedCtx = croppedCanvasEl.getContext('2d'); + + croppedCanvasEl.width = cropping.width || this.width; + croppedCanvasEl.height = cropping.height || this.height; + + croppedCtx.drawImage(canvasEl, -cropping.left || 0, -cropping.top || 0); + } + + return croppedCanvasEl; + }, + + /** + * @private + */ + __toDataURLWithMultiplier: function(format, quality, cropping, multiplier) { + + var origWidth = this.getWidth(), + origHeight = this.getHeight(), + scaledWidth = origWidth * multiplier, + scaledHeight = origHeight * multiplier, + activeObject = this.getActiveObject(), + activeGroup = this.getActiveGroup(), + + ctx = this.contextTop || this.contextContainer; + + if (multiplier > 1) { + this.setWidth(scaledWidth).setHeight(scaledHeight); + } + ctx.scale(multiplier, multiplier); + + if (cropping.left) { + cropping.left *= multiplier; + } + if (cropping.top) { + cropping.top *= multiplier; + } + if (cropping.width) { + cropping.width *= multiplier; + } + else if (multiplier < 1) { + cropping.width = scaledWidth; + } + if (cropping.height) { + cropping.height *= multiplier; + } + else if (multiplier < 1) { + cropping.height = scaledHeight; + } + + if (activeGroup) { + // not removing group due to complications with restoring it with correct state afterwords + this._tempRemoveBordersControlsFromGroup(activeGroup); + } + else if (activeObject && this.deactivateAll) { + this.deactivateAll(); + } + + this.renderAll(true); + + var data = this.__toDataURL(format, quality, cropping); + + // restoring width, height for `renderAll` to draw + // background properly (while context is scaled) + this.width = origWidth; + this.height = origHeight; + + ctx.scale(1 / multiplier, 1 / multiplier); + this.setWidth(origWidth).setHeight(origHeight); + + if (activeGroup) { + this._restoreBordersControlsOnGroup(activeGroup); + } + else if (activeObject && this.setActiveObject) { + this.setActiveObject(activeObject); + } + + this.contextTop && this.clearContext(this.contextTop); + this.renderAll(); + + return data; + }, + + /** + * Exports canvas element to a dataurl image (allowing to change image size via multiplier). + * @deprecated since 1.0.13 + * @param {String} format (png|jpeg) + * @param {Number} multiplier + * @param {Number} quality (0..1) + * @return {String} + */ + toDataURLWithMultiplier: function (format, multiplier, quality) { + return this.toDataURL({ + format: format, + multiplier: multiplier, + quality: quality + }); + }, + + /** + * @private + */ + _tempRemoveBordersControlsFromGroup: function(group) { + group.origHasControls = group.hasControls; + group.origBorderColor = group.borderColor; + + group.hasControls = true; + group.borderColor = 'rgba(0,0,0,0)'; + + group.forEachObject(function(o) { + o.origBorderColor = o.borderColor; + o.borderColor = 'rgba(0,0,0,0)'; + }); + }, + + /** + * @private + */ + _restoreBordersControlsOnGroup: function(group) { + group.hideControls = group.origHideControls; + group.borderColor = group.origBorderColor; + + group.forEachObject(function(o) { + o.borderColor = o.origBorderColor; + delete o.origBorderColor; + }); + } +}); + + +fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ { + + /** + * Populates canvas with data from the specified dataless JSON. + * JSON format must conform to the one of {@link fabric.Canvas#toDatalessJSON} + * @deprecated since 1.2.2 + * @param {String|Object} json JSON string or object + * @param {Function} callback Callback, invoked when json is parsed + * and corresponding objects (e.g: {@link fabric.Image}) + * are initialized + * @param {Function} [reviver] Method for further parsing of JSON elements, called after each fabric object created. + * @return {fabric.Canvas} instance + * @chainable + * @tutorial {@link http://fabricjs.com/fabric-intro-part-3/#deserialization} + */ + loadFromDatalessJSON: function (json, callback, reviver) { + return this.loadFromJSON(json, callback, reviver); + }, + + /** + * Populates canvas with data from the specified JSON. + * JSON format must conform to the one of {@link fabric.Canvas#toJSON} + * @param {String|Object} json JSON string or object + * @param {Function} callback Callback, invoked when json is parsed + * and corresponding objects (e.g: {@link fabric.Image}) + * are initialized + * @param {Function} [reviver] Method for further parsing of JSON elements, called after each fabric object created. + * @return {fabric.Canvas} instance + * @chainable + * @tutorial {@link http://fabricjs.com/fabric-intro-part-3/#deserialization} + * @see {@link http://jsfiddle.net/fabricjs/fmgXt/|jsFiddle demo} + * @example loadFromJSON + * canvas.loadFromJSON(json, canvas.renderAll.bind(canvas)); + * @example loadFromJSON with reviver + * canvas.loadFromJSON(json, canvas.renderAll.bind(canvas), function(o, object) { + * // `o` = json object + * // `object` = fabric.Object instance + * // ... do some stuff ... + * }); + */ + loadFromJSON: function (json, callback, reviver) { + if (!json) { + return; + } + + // serialize if it wasn't already + var serialized = (typeof json === 'string') + ? JSON.parse(json) + : json; + + this.clear(); + + var _this = this; + this._enlivenObjects(serialized.objects, function () { + _this._setBgOverlay(serialized, callback); + }, reviver); + + return this; + }, + + /** + * @private + * @param {Object} serialized Object with background and overlay information + * @param {Function} callback Invoked after all background and overlay images/patterns loaded + */ + _setBgOverlay: function(serialized, callback) { + var _this = this, + loaded = { + backgroundColor: false, + overlayColor: false, + backgroundImage: false, + overlayImage: false + }; + + if (!serialized.backgroundImage && !serialized.overlayImage && !serialized.background && !serialized.overlay) { + callback && callback(); + return; + } + + var cbIfLoaded = function () { + if (loaded.backgroundImage && loaded.overlayImage && loaded.backgroundColor && loaded.overlayColor) { + _this.renderAll(); + callback && callback(); + } + }; + + this.__setBgOverlay('backgroundImage', serialized.backgroundImage, loaded, cbIfLoaded); + this.__setBgOverlay('overlayImage', serialized.overlayImage, loaded, cbIfLoaded); + this.__setBgOverlay('backgroundColor', serialized.background, loaded, cbIfLoaded); + this.__setBgOverlay('overlayColor', serialized.overlay, loaded, cbIfLoaded); + + cbIfLoaded(); + }, + + /** + * @private + * @param {String} property Property to set (backgroundImage, overlayImage, backgroundColor, overlayColor) + * @param {(Object|String)} value Value to set + * @param {Object} loaded Set loaded property to true if property is set + * @param {Object} callback Callback function to invoke after property is set + */ + __setBgOverlay: function(property, value, loaded, callback) { + var _this = this; + + if (!value) { + loaded[property] = true; + return; + } + + if (property === 'backgroundImage' || property === 'overlayImage') { + fabric.Image.fromObject(value, function(img) { + _this[property] = img; + loaded[property] = true; + callback && callback(); + }); + } + else { + this['set' + fabric.util.string.capitalize(property, true)](value, function() { + loaded[property] = true; + callback && callback(); + }); + } + }, + + /** + * @private + * @param {Array} objects + * @param {Function} callback + * @param {Function} [reviver] + */ + _enlivenObjects: function (objects, callback, reviver) { + var _this = this; + + if (!objects || objects.length === 0) { + callback && callback(); + return; + } + + var renderOnAddRemove = this.renderOnAddRemove; + this.renderOnAddRemove = false; + + fabric.util.enlivenObjects(objects, function(enlivenedObjects) { + enlivenedObjects.forEach(function(obj, index) { + _this.insertAt(obj, index, true); + }); + + _this.renderOnAddRemove = renderOnAddRemove; + callback && callback(); + }, null, reviver); + }, + + /** + * @private + * @param {String} format + * @param {Function} callback + */ + _toDataURL: function (format, callback) { + this.clone(function (clone) { + callback(clone.toDataURL(format)); + }); + }, + + /** + * @private + * @param {String} format + * @param {Number} multiplier + * @param {Function} callback + */ + _toDataURLWithMultiplier: function (format, multiplier, callback) { + this.clone(function (clone) { + callback(clone.toDataURLWithMultiplier(format, multiplier)); + }); + }, + + /** + * Clones canvas instance + * @param {Object} [callback] Receives cloned instance as a first argument + * @param {Array} [properties] Array of properties to include in the cloned canvas and children + */ + clone: function (callback, properties) { + var data = JSON.stringify(this.toJSON(properties)); + this.cloneWithoutData(function(clone) { + clone.loadFromJSON(data, function() { + callback && callback(clone); + }); + }); + }, + + /** + * Clones canvas instance without cloning existing data. + * This essentially copies canvas dimensions, clipping properties, etc. + * but leaves data empty (so that you can populate it with your own) + * @param {Object} [callback] Receives cloned instance as a first argument + */ + cloneWithoutData: function(callback) { + var el = fabric.document.createElement('canvas'); + + el.width = this.getWidth(); + el.height = this.getHeight(); + + var clone = new fabric.Canvas(el); + clone.clipTo = this.clipTo; + if (this.backgroundImage) { + clone.setBackgroundImage(this.backgroundImage.src, function() { + clone.renderAll(); + callback && callback(clone); + }); + clone.backgroundImageOpacity = this.backgroundImageOpacity; + clone.backgroundImageStretch = this.backgroundImageStretch; + } + else { + callback && callback(clone); + } + } +}); + + +(function(global) { + + 'use strict'; + + var fabric = global.fabric || (global.fabric = { }), + extend = fabric.util.object.extend, + toFixed = fabric.util.toFixed, + capitalize = fabric.util.string.capitalize, + degreesToRadians = fabric.util.degreesToRadians, + supportsLineDash = fabric.StaticCanvas.supports('setLineDash'); + + if (fabric.Object) { + return; + } + + /** + * Root object class from which all 2d shape classes inherit from + * @class fabric.Object + * @tutorial {@link http://fabricjs.com/fabric-intro-part-1/#objects} + * @see {@link fabric.Object#initialize} for constructor definition + * + * @fires added + * @fires removed + * + * @fires selected + * @fires modified + * @fires rotating + * @fires scaling + * @fires moving + * + * @fires mousedown + * @fires mouseup + */ + fabric.Object = fabric.util.createClass(/** @lends fabric.Object.prototype */ { + + /** + * Retrieves object's {@link fabric.Object#clipTo|clipping function} + * @method getClipTo + * @memberOf fabric.Object.prototype + * @return {Function} + */ + + /** + * Sets object's {@link fabric.Object#clipTo|clipping function} + * @method setClipTo + * @memberOf fabric.Object.prototype + * @param {Function} clipTo Clipping function + * @return {fabric.Object} thisArg + * @chainable + */ + + /** + * Retrieves object's {@link fabric.Object#transformMatrix|transformMatrix} + * @method getTransformMatrix + * @memberOf fabric.Object.prototype + * @return {Array} transformMatrix + */ + + /** + * Sets object's {@link fabric.Object#transformMatrix|transformMatrix} + * @method setTransformMatrix + * @memberOf fabric.Object.prototype + * @param {Array} transformMatrix + * @return {fabric.Object} thisArg + * @chainable + */ + + /** + * Retrieves object's {@link fabric.Object#visible|visible} state + * @method getVisible + * @memberOf fabric.Object.prototype + * @return {Boolean} True if visible + */ + + /** + * Sets object's {@link fabric.Object#visible|visible} state + * @method setVisible + * @memberOf fabric.Object.prototype + * @param {Boolean} value visible value + * @return {fabric.Object} thisArg + * @chainable + */ + + /** + * Retrieves object's {@link fabric.Object#shadow|shadow} + * @method getShadow + * @memberOf fabric.Object.prototype + * @return {Object} Shadow instance + */ + + /** + * Retrieves object's {@link fabric.Object#stroke|stroke} + * @method getStroke + * @memberOf fabric.Object.prototype + * @return {String} stroke value + */ + + /** + * Sets object's {@link fabric.Object#stroke|stroke} + * @method setStroke + * @memberOf fabric.Object.prototype + * @param {String} value stroke value + * @return {fabric.Object} thisArg + * @chainable + */ + + /** + * Retrieves object's {@link fabric.Object#strokeWidth|strokeWidth} + * @method getStrokeWidth + * @memberOf fabric.Object.prototype + * @return {Number} strokeWidth value + */ + + /** + * Sets object's {@link fabric.Object#strokeWidth|strokeWidth} + * @method setStrokeWidth + * @memberOf fabric.Object.prototype + * @param {Number} value strokeWidth value + * @return {fabric.Object} thisArg + * @chainable + */ + + /** + * Retrieves object's {@link fabric.Object#originX|originX} + * @method getOriginX + * @memberOf fabric.Object.prototype + * @return {String} originX value + */ + + /** + * Sets object's {@link fabric.Object#originX|originX} + * @method setOriginX + * @memberOf fabric.Object.prototype + * @param {String} value originX value + * @return {fabric.Object} thisArg + * @chainable + */ + + /** + * Retrieves object's {@link fabric.Object#originY|originY} + * @method getOriginY + * @memberOf fabric.Object.prototype + * @return {String} originY value + */ + + /** + * Sets object's {@link fabric.Object#originY|originY} + * @method setOriginY + * @memberOf fabric.Object.prototype + * @param {String} value originY value + * @return {fabric.Object} thisArg + * @chainable + */ + + /** + * Retrieves object's {@link fabric.Object#fill|fill} + * @method getFill + * @memberOf fabric.Object.prototype + * @return {String} Fill value + */ + + /** + * Sets object's {@link fabric.Object#fill|fill} + * @method setFill + * @memberOf fabric.Object.prototype + * @param {String} value Fill value + * @return {fabric.Object} thisArg + * @chainable + */ + + /** + * Retrieves object's {@link fabric.Object#opacity|opacity} + * @method getOpacity + * @memberOf fabric.Object.prototype + * @return {Number} Opacity value (0-1) + */ + + /** + * Sets object's {@link fabric.Object#opacity|opacity} + * @method setOpacity + * @memberOf fabric.Object.prototype + * @param {Number} value Opacity value (0-1) + * @return {fabric.Object} thisArg + * @chainable + */ + + /** + * Retrieves object's {@link fabric.Object#angle|angle} (in degrees) + * @method getAngle + * @memberOf fabric.Object.prototype + * @return {Number} + */ + + /** + * Retrieves object's {@link fabric.Object#top|top position} + * @method getTop + * @memberOf fabric.Object.prototype + * @return {Number} Top value (in pixels) + */ + + /** + * Sets object's {@link fabric.Object#top|top position} + * @method setTop + * @memberOf fabric.Object.prototype + * @param {Number} value Top value (in pixels) + * @return {fabric.Object} thisArg + * @chainable + */ + + /** + * Retrieves object's {@link fabric.Object#left|left position} + * @method getLeft + * @memberOf fabric.Object.prototype + * @return {Number} Left value (in pixels) + */ + + /** + * Sets object's {@link fabric.Object#left|left position} + * @method setLeft + * @memberOf fabric.Object.prototype + * @param {Number} value Left value (in pixels) + * @return {fabric.Object} thisArg + * @chainable + */ + + /** + * Retrieves object's {@link fabric.Object#scaleX|scaleX} value + * @method getScaleX + * @memberOf fabric.Object.prototype + * @return {Number} scaleX value + */ + + /** + * Sets object's {@link fabric.Object#scaleX|scaleX} value + * @method setScaleX + * @memberOf fabric.Object.prototype + * @param {Number} value scaleX value + * @return {fabric.Object} thisArg + * @chainable + */ + + /** + * Retrieves object's {@link fabric.Object#scaleY|scaleY} value + * @method getScaleY + * @memberOf fabric.Object.prototype + * @return {Number} scaleY value + */ + + /** + * Sets object's {@link fabric.Object#scaleY|scaleY} value + * @method setScaleY + * @memberOf fabric.Object.prototype + * @param {Number} value scaleY value + * @return {fabric.Object} thisArg + * @chainable + */ + + /** + * Retrieves object's {@link fabric.Object#flipX|flipX} value + * @method getFlipX + * @memberOf fabric.Object.prototype + * @return {Boolean} flipX value + */ + + /** + * Sets object's {@link fabric.Object#flipX|flipX} value + * @method setFlipX + * @memberOf fabric.Object.prototype + * @param {Boolean} value flipX value + * @return {fabric.Object} thisArg + * @chainable + */ + + /** + * Retrieves object's {@link fabric.Object#flipY|flipY} value + * @method getFlipY + * @memberOf fabric.Object.prototype + * @return {Boolean} flipY value + */ + + /** + * Sets object's {@link fabric.Object#flipY|flipY} value + * @method setFlipY + * @memberOf fabric.Object.prototype + * @param {Boolean} value flipY value + * @return {fabric.Object} thisArg + * @chainable + */ + + /** + * Type of an object (rect, circle, path, etc.). + * Note that this property is meant to be read-only and not meant to be modified. + * If you modify, certain parts of Fabric (such as JSON loading) won't work correctly. + * @type String + * @default + */ + type: 'object', + + /** + * Horizontal origin of transformation of an object (one of "left", "right", "center") + * See http://jsfiddle.net/1ow02gea/40/ on how originX/originY affect objects in groups + * @type String + * @default + */ + originX: 'left', + + /** + * Vertical origin of transformation of an object (one of "top", "bottom", "center") + * See http://jsfiddle.net/1ow02gea/40/ on how originX/originY affect objects in groups + * @type String + * @default + */ + originY: 'top', + + /** + * Top position of an object. Note that by default it's relative to object center. You can change this by setting originY={top/center/bottom} + * @type Number + * @default + */ + top: 0, + + /** + * Left position of an object. Note that by default it's relative to object center. You can change this by setting originX={left/center/right} + * @type Number + * @default + */ + left: 0, + + /** + * Object width + * @type Number + * @default + */ + width: 0, + + /** + * Object height + * @type Number + * @default + */ + height: 0, + + /** + * Object scale factor (horizontal) + * @type Number + * @default + */ + scaleX: 1, + + /** + * Object scale factor (vertical) + * @type Number + * @default + */ + scaleY: 1, + + /** + * When true, an object is rendered as flipped horizontally + * @type Boolean + * @default + */ + flipX: false, + + /** + * When true, an object is rendered as flipped vertically + * @type Boolean + * @default + */ + flipY: false, + + /** + * Opacity of an object + * @type Number + * @default + */ + opacity: 1, + + /** + * Angle of rotation of an object (in degrees) + * @type Number + * @default + */ + angle: 0, + + /** + * Size of object's controlling corners (in pixels) + * @type Number + * @default + */ + cornerSize: 12, + + /** + * When true, object's controlling corners are rendered as transparent inside (i.e. stroke instead of fill) + * @type Boolean + * @default + */ + transparentCorners: true, + + /** + * Default cursor value used when hovering over this object on canvas + * @type String + * @default + */ + hoverCursor: null, + + /** + * Padding between object and its controlling borders (in pixels) + * @type Number + * @default + */ + padding: 0, + + /** + * Color of controlling borders of an object (when it's active) + * @type String + * @default + */ + borderColor: 'rgba(102,153,255,0.75)', + + /** + * Color of controlling corners of an object (when it's active) + * @type String + * @default + */ + cornerColor: 'rgba(102,153,255,0.5)', + + /** + * When true, this object will use center point as the origin of transformation + * when being scaled via the controls. + * Backwards incompatibility note: This property replaces "centerTransform" (Boolean). + * @since 1.3.4 + * @type Boolean + * @default + */ + centeredScaling: false, + + /** + * When true, this object will use center point as the origin of transformation + * when being rotated via the controls. + * Backwards incompatibility note: This property replaces "centerTransform" (Boolean). + * @since 1.3.4 + * @type Boolean + * @default + */ + centeredRotation: true, + + /** + * Color of object's fill + * @type String + * @default + */ + fill: 'rgb(0,0,0)', + + /** + * Fill rule used to fill an object + * accepted values are nonzero, evenodd + * Backwards incompatibility note: This property was used for setting globalCompositeOperation until v1.4.12 (use `fabric.Object#globalCompositeOperation` instead) + * @type String + * @default + */ + fillRule: 'nonzero', + + /** + * Composite rule used for canvas globalCompositeOperation + * @type String + * @default + */ + globalCompositeOperation: 'source-over', + + /** + * Background color of an object. Only works with text objects at the moment. + * @type String + * @default + */ + backgroundColor: '', + + /** + * When defined, an object is rendered via stroke and this property specifies its color + * @type String + * @default + */ + stroke: null, + + /** + * Width of a stroke used to render this object + * @type Number + * @default + */ + strokeWidth: 1, + + /** + * Array specifying dash pattern of an object's stroke (stroke must be defined) + * @type Array + */ + strokeDashArray: null, + + /** + * Line endings style of an object's stroke (one of "butt", "round", "square") + * @type String + * @default + */ + strokeLineCap: 'butt', + + /** + * Corner style of an object's stroke (one of "bevil", "round", "miter") + * @type String + * @default + */ + strokeLineJoin: 'miter', + + /** + * Maximum miter length (used for strokeLineJoin = "miter") of an object's stroke + * @type Number + * @default + */ + strokeMiterLimit: 10, + + /** + * Shadow object representing shadow of this shape + * @type fabric.Shadow + * @default + */ + shadow: null, + + /** + * Opacity of object's controlling borders when object is active and moving + * @type Number + * @default + */ + borderOpacityWhenMoving: 0.4, + + /** + * Scale factor of object's controlling borders + * @type Number + * @default + */ + borderScaleFactor: 1, + + /** + * Transform matrix (similar to SVG's transform matrix) + * @type Array + */ + transformMatrix: null, + + /** + * Minimum allowed scale value of an object + * @type Number + * @default + */ + minScaleLimit: 0.01, + + /** + * When set to `false`, an object can not be selected for modification (using either point-click-based or group-based selection). + * But events still fire on it. + * @type Boolean + * @default + */ + selectable: true, + + /** + * When set to `false`, an object can not be a target of events. All events propagate through it. Introduced in v1.3.4 + * @type Boolean + * @default + */ + evented: true, + + /** + * When set to `false`, an object is not rendered on canvas + * @type Boolean + * @default + */ + visible: true, + + /** + * When set to `false`, object's controls are not displayed and can not be used to manipulate object + * @type Boolean + * @default + */ + hasControls: true, + + /** + * When set to `false`, object's controlling borders are not rendered + * @type Boolean + * @default + */ + hasBorders: true, + + /** + * When set to `false`, object's controlling rotating point will not be visible or selectable + * @type Boolean + * @default + */ + hasRotatingPoint: true, + + /** + * Offset for object's controlling rotating point (when enabled via `hasRotatingPoint`) + * @type Number + * @default + */ + rotatingPointOffset: 40, + + /** + * When set to `true`, objects are "found" on canvas on per-pixel basis rather than according to bounding box + * @type Boolean + * @default + */ + perPixelTargetFind: false, + + /** + * When `false`, default object's values are not included in its serialization + * @type Boolean + * @default + */ + includeDefaultValues: true, + + /** + * Function that determines clipping of an object (context is passed as a first argument) + * Note that context origin is at the object's center point (not left/top corner) + * @type Function + */ + clipTo: null, + + /** + * When `true`, object horizontal movement is locked + * @type Boolean + * @default + */ + lockMovementX: false, + + /** + * When `true`, object vertical movement is locked + * @type Boolean + * @default + */ + lockMovementY: false, + + /** + * When `true`, object rotation is locked + * @type Boolean + * @default + */ + lockRotation: false, + + /** + * When `true`, object horizontal scaling is locked + * @type Boolean + * @default + */ + lockScalingX: false, + + /** + * When `true`, object vertical scaling is locked + * @type Boolean + * @default + */ + lockScalingY: false, + + /** + * When `true`, object non-uniform scaling is locked + * @type Boolean + * @default + */ + lockUniScaling: false, + + /** + * When `true`, object cannot be flipped by scaling into negative values + * @type Boolean + * @default + */ + + lockScalingFlip: false, + /** + * List of properties to consider when checking if state + * of an object is changed (fabric.Object#hasStateChanged) + * as well as for history (undo/redo) purposes + * @type Array + */ + stateProperties: ( + 'top left width height scaleX scaleY flipX flipY originX originY transformMatrix ' + + 'stroke strokeWidth strokeDashArray strokeLineCap strokeLineJoin strokeMiterLimit ' + + 'angle opacity fill fillRule globalCompositeOperation shadow clipTo visible backgroundColor' + ).split(' '), + + /** + * Constructor + * @param {Object} [options] Options object + */ + initialize: function(options) { + if (options) { + this.setOptions(options); + } + }, + + /** + * @private + * @param {Object} [options] Options object + */ + _initGradient: function(options) { + if (options.fill && options.fill.colorStops && !(options.fill instanceof fabric.Gradient)) { + this.set('fill', new fabric.Gradient(options.fill)); + } + }, + + /** + * @private + * @param {Object} [options] Options object + */ + _initPattern: function(options) { + if (options.fill && options.fill.source && !(options.fill instanceof fabric.Pattern)) { + this.set('fill', new fabric.Pattern(options.fill)); + } + if (options.stroke && options.stroke.source && !(options.stroke instanceof fabric.Pattern)) { + this.set('stroke', new fabric.Pattern(options.stroke)); + } + }, + + /** + * @private + * @param {Object} [options] Options object + */ + _initClipping: function(options) { + if (!options.clipTo || typeof options.clipTo !== 'string') { + return; + } + + var functionBody = fabric.util.getFunctionBody(options.clipTo); + if (typeof functionBody !== 'undefined') { + this.clipTo = new Function('ctx', functionBody); + } + }, + + /** + * Sets object's properties from options + * @param {Object} [options] Options object + */ + setOptions: function(options) { + for (var prop in options) { + this.set(prop, options[prop]); + } + this._initGradient(options); + this._initPattern(options); + this._initClipping(options); + }, + + /** + * Transforms context when rendering an object + * @param {CanvasRenderingContext2D} ctx Context + * @param {Boolean} fromLeft When true, context is transformed to object's top/left corner. This is used when rendering text on Node + */ + transform: function(ctx, fromLeft) { + var center = fromLeft ? this._getLeftTopCoords() : this.getCenterPoint(); + ctx.translate(center.x, center.y); + ctx.rotate(degreesToRadians(this.angle)); + ctx.scale( + this.scaleX * (this.flipX ? -1 : 1), + this.scaleY * (this.flipY ? -1 : 1) + ); + }, + + /** + * Returns an object representation of an instance + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} Object representation of an instance + */ + toObject: function(propertiesToInclude) { + var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS, + + object = { + type: this.type, + originX: this.originX, + originY: this.originY, + left: toFixed(this.left, NUM_FRACTION_DIGITS), + top: toFixed(this.top, NUM_FRACTION_DIGITS), + width: toFixed(this.width, NUM_FRACTION_DIGITS), + height: toFixed(this.height, NUM_FRACTION_DIGITS), + fill: (this.fill && this.fill.toObject) ? this.fill.toObject() : this.fill, + stroke: (this.stroke && this.stroke.toObject) ? this.stroke.toObject() : this.stroke, + strokeWidth: toFixed(this.strokeWidth, NUM_FRACTION_DIGITS), + strokeDashArray: this.strokeDashArray, + strokeLineCap: this.strokeLineCap, + strokeLineJoin: this.strokeLineJoin, + strokeMiterLimit: toFixed(this.strokeMiterLimit, NUM_FRACTION_DIGITS), + scaleX: toFixed(this.scaleX, NUM_FRACTION_DIGITS), + scaleY: toFixed(this.scaleY, NUM_FRACTION_DIGITS), + angle: toFixed(this.getAngle(), NUM_FRACTION_DIGITS), + flipX: this.flipX, + flipY: this.flipY, + opacity: toFixed(this.opacity, NUM_FRACTION_DIGITS), + shadow: (this.shadow && this.shadow.toObject) ? this.shadow.toObject() : this.shadow, + visible: this.visible, + clipTo: this.clipTo && String(this.clipTo), + backgroundColor: this.backgroundColor, + fillRule: this.fillRule, + globalCompositeOperation: this.globalCompositeOperation + }; + + if (!this.includeDefaultValues) { + object = this._removeDefaultValues(object); + } + + fabric.util.populateWithProperties(this, object, propertiesToInclude); + + return object; + }, + + /** + * Returns (dataless) object representation of an instance + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} Object representation of an instance + */ + toDatalessObject: function(propertiesToInclude) { + // will be overwritten by subclasses + return this.toObject(propertiesToInclude); + }, + + /** + * @private + * @param {Object} object + */ + _removeDefaultValues: function(object) { + var prototype = fabric.util.getKlass(object.type).prototype, + stateProperties = prototype.stateProperties; + + stateProperties.forEach(function(prop) { + if (object[prop] === prototype[prop]) { + delete object[prop]; + } + }); + + return object; + }, + + /** + * Returns a string representation of an instance + * @return {String} + */ + toString: function() { + return '#'; + }, + + /** + * Basic getter + * @param {String} property Property name + * @return {Any} value of a property + */ + get: function(property) { + return this[property]; + }, + + /** + * @private + */ + _setObject: function(obj) { + for (var prop in obj) { + this._set(prop, obj[prop]); + } + }, + + /** + * Sets property to a given value. When changing position/dimension -related properties (left, top, scale, angle, etc.) `set` does not update position of object's borders/controls. If you need to update those, call `setCoords()`. + * @param {String|Object} key Property name or object (if object, iterate over the object properties) + * @param {Object|Function} value Property value (if function, the value is passed into it and its return value is used as a new one) + * @return {fabric.Object} thisArg + * @chainable + */ + set: function(key, value) { + if (typeof key === 'object') { + this._setObject(key); + } + else { + if (typeof value === 'function' && key !== 'clipTo') { + this._set(key, value(this.get(key))); + } + else { + this._set(key, value); + } + } + return this; + }, + + /** + * @private + * @param {String} key + * @param {Any} value + * @return {fabric.Object} thisArg + */ + _set: function(key, value) { + var shouldConstrainValue = (key === 'scaleX' || key === 'scaleY'); + + if (shouldConstrainValue) { + value = this._constrainScale(value); + } + if (key === 'scaleX' && value < 0) { + this.flipX = !this.flipX; + value *= -1; + } + else if (key === 'scaleY' && value < 0) { + this.flipY = !this.flipY; + value *= -1; + } + else if (key === 'width' || key === 'height') { + this.minScaleLimit = toFixed(Math.min(0.1, 1/Math.max(this.width, this.height)), 2); + } + else if (key === 'shadow' && value && !(value instanceof fabric.Shadow)) { + value = new fabric.Shadow(value); + } + + this[key] = value; + + return this; + }, + + /** + * Toggles specified property from `true` to `false` or from `false` to `true` + * @param {String} property Property to toggle + * @return {fabric.Object} thisArg + * @chainable + */ + toggle: function(property) { + var value = this.get(property); + if (typeof value === 'boolean') { + this.set(property, !value); + } + return this; + }, + + /** + * Sets sourcePath of an object + * @param {String} value Value to set sourcePath to + * @return {fabric.Object} thisArg + * @chainable + */ + setSourcePath: function(value) { + this.sourcePath = value; + return this; + }, + + /** + * Retrieves viewportTransform from Object's canvas if possible + * @method getViewportTransform + * @memberOf fabric.Object.prototype + * @return {Boolean} flipY value // TODO + */ + getViewportTransform: function() { + if (this.canvas && this.canvas.viewportTransform) { + return this.canvas.viewportTransform; + } + return [1, 0, 0, 1, 0, 0]; + }, + + /** + * Renders an object on a specified context + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {Boolean} [noTransform] When true, context is not transformed + */ + render: function(ctx, noTransform) { + // do not render if width/height are zeros or object is not visible + if ((this.width === 0 && this.height === 0) || !this.visible) { + return; + } + + ctx.save(); + + //setup fill rule for current object + this._setupCompositeOperation(ctx); + if (!noTransform) { + this.transform(ctx); + } + this._setStrokeStyles(ctx); + this._setFillStyles(ctx); + if (this.transformMatrix) { + ctx.transform.apply(ctx, this.transformMatrix); + } + this._setOpacity(ctx); + this._setShadow(ctx); + this.clipTo && fabric.util.clipContext(this, ctx); + this._render(ctx, noTransform); + this.clipTo && ctx.restore(); + this._removeShadow(ctx); + this._restoreCompositeOperation(ctx); + + ctx.restore(); + }, + + /* @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _setOpacity: function(ctx) { + if (this.group) { + this.group._setOpacity(ctx); + } + ctx.globalAlpha *= this.opacity; + }, + + _setStrokeStyles: function(ctx) { + if (this.stroke) { + ctx.lineWidth = this.strokeWidth; + ctx.lineCap = this.strokeLineCap; + ctx.lineJoin = this.strokeLineJoin; + ctx.miterLimit = this.strokeMiterLimit; + ctx.strokeStyle = this.stroke.toLive + ? this.stroke.toLive(ctx, this) + : this.stroke; + } + }, + + _setFillStyles: function(ctx) { + if (this.fill) { + ctx.fillStyle = this.fill.toLive + ? this.fill.toLive(ctx, this) + : this.fill; + } + }, + + /** + * Renders controls and borders for the object + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {Boolean} [noTransform] When true, context is not transformed + */ + _renderControls: function(ctx, noTransform) { + if (!this.active || noTransform) { + return; + } + var vpt = this.getViewportTransform(); + ctx.save(); + var center; + if (this.group) { + center = fabric.util.transformPoint(this.group.getCenterPoint(), vpt); + ctx.translate(center.x, center.y); + ctx.rotate(degreesToRadians(this.group.angle)); + } + center = fabric.util.transformPoint(this.getCenterPoint(), vpt, null != this.group); + if (this.group) { + center.x *= this.group.scaleX; + center.y *= this.group.scaleY; + } + ctx.translate(center.x, center.y); + ctx.rotate(degreesToRadians(this.angle)); + this.drawBorders(ctx); + this.drawControls(ctx); + ctx.restore(); + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _setShadow: function(ctx) { + if (!this.shadow) { + return; + } + + var multX = (this.canvas && this.canvas.viewportTransform[0]) || 1, + multY = (this.canvas && this.canvas.viewportTransform[3]) || 1; + + ctx.shadowColor = this.shadow.color; + ctx.shadowBlur = this.shadow.blur * (multX + multY) * (this.scaleX + this.scaleY) / 4; + ctx.shadowOffsetX = this.shadow.offsetX * multX * this.scaleX; + ctx.shadowOffsetY = this.shadow.offsetY * multY * this.scaleY; + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _removeShadow: function(ctx) { + if (!this.shadow) { + return; + } + + ctx.shadowColor = ''; + ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0; + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderFill: function(ctx) { + if (!this.fill) { + return; + } + + ctx.save(); + if (this.fill.gradientTransform) { + var g = this.fill.gradientTransform; + ctx.transform.apply(ctx, g); + } + if (this.fill.toLive) { + ctx.translate( + -this.width / 2 + this.fill.offsetX || 0, + -this.height / 2 + this.fill.offsetY || 0); + } + if (this.fillRule === 'evenodd') { + ctx.fill('evenodd'); + } + else { + ctx.fill(); + } + ctx.restore(); + if (this.shadow && !this.shadow.affectStroke) { + this._removeShadow(ctx); + } + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderStroke: function(ctx) { + if (!this.stroke || this.strokeWidth === 0) { + return; + } + + ctx.save(); + if (this.strokeDashArray) { + // Spec requires the concatenation of two copies the dash list when the number of elements is odd + if (1 & this.strokeDashArray.length) { + this.strokeDashArray.push.apply(this.strokeDashArray, this.strokeDashArray); + } + if (supportsLineDash) { + ctx.setLineDash(this.strokeDashArray); + this._stroke && this._stroke(ctx); + } + else { + this._renderDashedStroke && this._renderDashedStroke(ctx); + } + ctx.stroke(); + } + else { + if (this.stroke.gradientTransform) { + var g = this.stroke.gradientTransform; + ctx.transform.apply(ctx, g); + } + this._stroke ? this._stroke(ctx) : ctx.stroke(); + } + this._removeShadow(ctx); + ctx.restore(); + }, + + /** + * Clones an instance + * @param {Function} callback Callback is invoked with a clone as a first argument + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {fabric.Object} clone of an instance + */ + clone: function(callback, propertiesToInclude) { + if (this.constructor.fromObject) { + return this.constructor.fromObject(this.toObject(propertiesToInclude), callback); + } + return new fabric.Object(this.toObject(propertiesToInclude)); + }, + + /** + * Creates an instance of fabric.Image out of an object + * @param {Function} callback callback, invoked with an instance as a first argument + * @return {fabric.Object} thisArg + */ + cloneAsImage: function(callback) { + var dataUrl = this.toDataURL(); + fabric.util.loadImage(dataUrl, function(img) { + if (callback) { + callback(new fabric.Image(img)); + } + }); + return this; + }, + + /** + * Converts an object into a data-url-like string + * @param {Object} options Options object + * @param {String} [options.format=png] The format of the output image. Either "jpeg" or "png" + * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg. + * @param {Number} [options.multiplier=1] Multiplier to scale by + * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14 + * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14 + * @param {Number} [options.width] Cropping width. Introduced in v1.2.14 + * @param {Number} [options.height] Cropping height. Introduced in v1.2.14 + * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format + */ + toDataURL: function(options) { + options || (options = { }); + + var el = fabric.util.createCanvasElement(), + boundingRect = this.getBoundingRect(); + + el.width = boundingRect.width; + el.height = boundingRect.height; + + fabric.util.wrapElement(el, 'div'); + var canvas = new fabric.StaticCanvas(el); + + // to avoid common confusion https://github.com/kangax/fabric.js/issues/806 + if (options.format === 'jpg') { + options.format = 'jpeg'; + } + + if (options.format === 'jpeg') { + canvas.backgroundColor = '#fff'; + } + + var origParams = { + active: this.get('active'), + left: this.getLeft(), + top: this.getTop() + }; + + this.set('active', false); + this.setPositionByOrigin(new fabric.Point(el.width / 2, el.height / 2), 'center', 'center'); + + var originalCanvas = this.canvas; + canvas.add(this); + var data = canvas.toDataURL(options); + + this.set(origParams).setCoords(); + this.canvas = originalCanvas; + + canvas.dispose(); + canvas = null; + + return data; + }, + + /** + * Returns true if specified type is identical to the type of an instance + * @param {String} type Type to check against + * @return {Boolean} + */ + isType: function(type) { + return this.type === type; + }, + + /** + * Returns complexity of an instance + * @return {Number} complexity of this instance + */ + complexity: function() { + return 0; + }, + + /** + * Returns a JSON representation of an instance + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} JSON + */ + toJSON: function(propertiesToInclude) { + // delegate, not alias + return this.toObject(propertiesToInclude); + }, + + /** + * Sets gradient (fill or stroke) of an object + * Backwards incompatibility note: This method was named "setGradientFill" until v1.1.0 + * @param {String} property Property name 'stroke' or 'fill' + * @param {Object} [options] Options object + * @param {String} [options.type] Type of gradient 'radial' or 'linear' + * @param {Number} [options.x1=0] x-coordinate of start point + * @param {Number} [options.y1=0] y-coordinate of start point + * @param {Number} [options.x2=0] x-coordinate of end point + * @param {Number} [options.y2=0] y-coordinate of end point + * @param {Number} [options.r1=0] Radius of start point (only for radial gradients) + * @param {Number} [options.r2=0] Radius of end point (only for radial gradients) + * @param {Object} [options.colorStops] Color stops object eg. {0: 'ff0000', 1: '000000'} + * @return {fabric.Object} thisArg + * @chainable + * @see {@link http://jsfiddle.net/fabricjs/58y8b/|jsFiddle demo} + * @example Set linear gradient + * object.setGradient('fill', { + * type: 'linear', + * x1: -object.width / 2, + * y1: 0, + * x2: object.width / 2, + * y2: 0, + * colorStops: { + * 0: 'red', + * 0.5: '#005555', + * 1: 'rgba(0,0,255,0.5)' + * } + * }); + * canvas.renderAll(); + * @example Set radial gradient + * object.setGradient('fill', { + * type: 'radial', + * x1: 0, + * y1: 0, + * x2: 0, + * y2: 0, + * r1: object.width / 2, + * r2: 10, + * colorStops: { + * 0: 'red', + * 0.5: '#005555', + * 1: 'rgba(0,0,255,0.5)' + * } + * }); + * canvas.renderAll(); + */ + setGradient: function(property, options) { + options || (options = { }); + + var gradient = { colorStops: [] }; + + gradient.type = options.type || (options.r1 || options.r2 ? 'radial' : 'linear'); + gradient.coords = { + x1: options.x1, + y1: options.y1, + x2: options.x2, + y2: options.y2 + }; + + if (options.r1 || options.r2) { + gradient.coords.r1 = options.r1; + gradient.coords.r2 = options.r2; + } + + for (var position in options.colorStops) { + var color = new fabric.Color(options.colorStops[position]); + gradient.colorStops.push({ + offset: position, + color: color.toRgb(), + opacity: color.getAlpha() + }); + } + + return this.set(property, fabric.Gradient.forObject(this, gradient)); + }, + + /** + * Sets pattern fill of an object + * @param {Object} options Options object + * @param {(String|HTMLImageElement)} options.source Pattern source + * @param {String} [options.repeat=repeat] Repeat property of a pattern (one of repeat, repeat-x, repeat-y or no-repeat) + * @param {Number} [options.offsetX=0] Pattern horizontal offset from object's left/top corner + * @param {Number} [options.offsetY=0] Pattern vertical offset from object's left/top corner + * @return {fabric.Object} thisArg + * @chainable + * @see {@link http://jsfiddle.net/fabricjs/QT3pa/|jsFiddle demo} + * @example Set pattern + * fabric.util.loadImage('http://fabricjs.com/assets/escheresque_ste.png', function(img) { + * object.setPatternFill({ + * source: img, + * repeat: 'repeat' + * }); + * canvas.renderAll(); + * }); + */ + setPatternFill: function(options) { + return this.set('fill', new fabric.Pattern(options)); + }, + + /** + * Sets {@link fabric.Object#shadow|shadow} of an object + * @param {Object|String} [options] Options object or string (e.g. "2px 2px 10px rgba(0,0,0,0.2)") + * @param {String} [options.color=rgb(0,0,0)] Shadow color + * @param {Number} [options.blur=0] Shadow blur + * @param {Number} [options.offsetX=0] Shadow horizontal offset + * @param {Number} [options.offsetY=0] Shadow vertical offset + * @return {fabric.Object} thisArg + * @chainable + * @see {@link http://jsfiddle.net/fabricjs/7gvJG/|jsFiddle demo} + * @example Set shadow with string notation + * object.setShadow('2px 2px 10px rgba(0,0,0,0.2)'); + * canvas.renderAll(); + * @example Set shadow with object notation + * object.setShadow({ + * color: 'red', + * blur: 10, + * offsetX: 20, + * offsetY: 20 + * }); + * canvas.renderAll(); + */ + setShadow: function(options) { + return this.set('shadow', options ? new fabric.Shadow(options) : null); + }, + + /** + * Sets "color" of an instance (alias of `set('fill', …)`) + * @param {String} color Color value + * @return {fabric.Object} thisArg + * @chainable + */ + setColor: function(color) { + this.set('fill', color); + return this; + }, + + /** + * Sets "angle" of an instance + * @param {Number} angle Angle value (in degrees) + * @return {fabric.Object} thisArg + * @chainable + */ + setAngle: function(angle) { + var shouldCenterOrigin = (this.originX !== 'center' || this.originY !== 'center') && this.centeredRotation; + + if (shouldCenterOrigin) { + this._setOriginToCenter(); + } + + this.set('angle', angle); + + if (shouldCenterOrigin) { + this._resetOrigin(); + } + + return this; + }, + + /** + * Centers object horizontally on canvas to which it was added last. + * You might need to call `setCoords` on an object after centering, to update controls area. + * @return {fabric.Object} thisArg + * @chainable + */ + centerH: function () { + this.canvas.centerObjectH(this); + return this; + }, + + /** + * Centers object vertically on canvas to which it was added last. + * You might need to call `setCoords` on an object after centering, to update controls area. + * @return {fabric.Object} thisArg + * @chainable + */ + centerV: function () { + this.canvas.centerObjectV(this); + return this; + }, + + /** + * Centers object vertically and horizontally on canvas to which is was added last + * You might need to call `setCoords` on an object after centering, to update controls area. + * @return {fabric.Object} thisArg + * @chainable + */ + center: function () { + this.canvas.centerObject(this); + return this; + }, + + /** + * Removes object from canvas to which it was added last + * @return {fabric.Object} thisArg + * @chainable + */ + remove: function() { + this.canvas.remove(this); + return this; + }, + + /** + * Returns coordinates of a pointer relative to an object + * @param {Event} e Event to operate upon + * @param {Object} [pointer] Pointer to operate upon (instead of event) + * @return {Object} Coordinates of a pointer (x, y) + */ + getLocalPointer: function(e, pointer) { + pointer = pointer || this.canvas.getPointer(e); + var objectLeftTop = this.translateToOriginPoint(this.getCenterPoint(), 'left', 'top'); + return { + x: pointer.x - objectLeftTop.x, + y: pointer.y - objectLeftTop.y + }; + }, + + /** + * Sets canvas globalCompositeOperation for specific object + * custom composition operation for the particular object can be specifed using globalCompositeOperation property + * @param {CanvasRenderingContext2D} ctx Rendering canvas context + */ + _setupCompositeOperation: function (ctx) { + if (this.globalCompositeOperation) { + this._prevGlobalCompositeOperation = ctx.globalCompositeOperation; + ctx.globalCompositeOperation = this.globalCompositeOperation; + } + }, + + /** + * Restores previously saved canvas globalCompositeOperation after obeject rendering + * @param {CanvasRenderingContext2D} ctx Rendering canvas context + */ + _restoreCompositeOperation: function (ctx) { + if (this.globalCompositeOperation && this._prevGlobalCompositeOperation) { + ctx.globalCompositeOperation = this._prevGlobalCompositeOperation; + } + } + }); + + fabric.util.createAccessors(fabric.Object); + + /** + * Alias for {@link fabric.Object.prototype.setAngle} + * @alias rotate -> setAngle + * @memberof fabric.Object + */ + fabric.Object.prototype.rotate = fabric.Object.prototype.setAngle; + + extend(fabric.Object.prototype, fabric.Observable); + + /** + * Defines the number of fraction digits to use when serializing object values. + * You can use it to increase/decrease precision of such values like left, top, scaleX, scaleY, etc. + * @static + * @memberof fabric.Object + * @constant + * @type Number + */ + fabric.Object.NUM_FRACTION_DIGITS = 2; + + /** + * Unique id used internally when creating SVG elements + * @static + * @memberof fabric.Object + * @type Number + */ + fabric.Object.__uid = 0; + +})(typeof exports !== 'undefined' ? exports : this); + + +(function() { + + var degreesToRadians = fabric.util.degreesToRadians; + + fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { + + /** + * Translates the coordinates from origin to center coordinates (based on the object's dimensions) + * @param {fabric.Point} point The point which corresponds to the originX and originY params + * @param {String} originX Horizontal origin: 'left', 'center' or 'right' + * @param {String} originY Vertical origin: 'top', 'center' or 'bottom' + * @return {fabric.Point} + */ + translateToCenterPoint: function(point, originX, originY) { + var cx = point.x, + cy = point.y, + strokeWidth = this.stroke ? this.strokeWidth : 0; + + if (originX === 'left') { + cx = point.x + (this.getWidth() + strokeWidth * this.scaleX) / 2; + } + else if (originX === 'right') { + cx = point.x - (this.getWidth() + strokeWidth * this.scaleX) / 2; + } + + if (originY === 'top') { + cy = point.y + (this.getHeight() + strokeWidth * this.scaleY) / 2; + } + else if (originY === 'bottom') { + cy = point.y - (this.getHeight() + strokeWidth * this.scaleY) / 2; + } + + // Apply the reverse rotation to the point (it's already scaled properly) + return fabric.util.rotatePoint(new fabric.Point(cx, cy), point, degreesToRadians(this.angle)); + }, + + /** + * Translates the coordinates from center to origin coordinates (based on the object's dimensions) + * @param {fabric.Point} center The point which corresponds to center of the object + * @param {String} originX Horizontal origin: 'left', 'center' or 'right' + * @param {String} originY Vertical origin: 'top', 'center' or 'bottom' + * @return {fabric.Point} + */ + translateToOriginPoint: function(center, originX, originY) { + var x = center.x, + y = center.y, + strokeWidth = this.stroke ? this.strokeWidth : 0; + + // Get the point coordinates + if (originX === 'left') { + x = center.x - (this.getWidth() + strokeWidth * this.scaleX) / 2; + } + else if (originX === 'right') { + x = center.x + (this.getWidth() + strokeWidth * this.scaleX) / 2; + } + if (originY === 'top') { + y = center.y - (this.getHeight() + strokeWidth * this.scaleY) / 2; + } + else if (originY === 'bottom') { + y = center.y + (this.getHeight() + strokeWidth * this.scaleY) / 2; + } + + // Apply the rotation to the point (it's already scaled properly) + return fabric.util.rotatePoint(new fabric.Point(x, y), center, degreesToRadians(this.angle)); + }, + + /** + * Returns the real center coordinates of the object + * @return {fabric.Point} + */ + getCenterPoint: function() { + var leftTop = new fabric.Point(this.left, this.top); + return this.translateToCenterPoint(leftTop, this.originX, this.originY); + }, + + /** + * Returns the coordinates of the object based on center coordinates + * @param {fabric.Point} point The point which corresponds to the originX and originY params + * @return {fabric.Point} + */ + // getOriginPoint: function(center) { + // return this.translateToOriginPoint(center, this.originX, this.originY); + // }, + + /** + * Returns the coordinates of the object as if it has a different origin + * @param {String} originX Horizontal origin: 'left', 'center' or 'right' + * @param {String} originY Vertical origin: 'top', 'center' or 'bottom' + * @return {fabric.Point} + */ + getPointByOrigin: function(originX, originY) { + var center = this.getCenterPoint(); + return this.translateToOriginPoint(center, originX, originY); + }, + + /** + * Returns the point in local coordinates + * @param {fabric.Point} point The point relative to the global coordinate system + * @param {String} originX Horizontal origin: 'left', 'center' or 'right' + * @param {String} originY Vertical origin: 'top', 'center' or 'bottom' + * @return {fabric.Point} + */ + toLocalPoint: function(point, originX, originY) { + var center = this.getCenterPoint(), + strokeWidth = this.stroke ? this.strokeWidth : 0, + x, y; + + if (originX && originY) { + if (originX === 'left') { + x = center.x - (this.getWidth() + strokeWidth * this.scaleX) / 2; + } + else if (originX === 'right') { + x = center.x + (this.getWidth() + strokeWidth * this.scaleX) / 2; + } + else { + x = center.x; + } + + if (originY === 'top') { + y = center.y - (this.getHeight() + strokeWidth * this.scaleY) / 2; + } + else if (originY === 'bottom') { + y = center.y + (this.getHeight() + strokeWidth * this.scaleY) / 2; + } + else { + y = center.y; + } + } + else { + x = this.left; + y = this.top; + } + + return fabric.util.rotatePoint(new fabric.Point(point.x, point.y), center, -degreesToRadians(this.angle)) + .subtractEquals(new fabric.Point(x, y)); + }, + + /** + * Returns the point in global coordinates + * @param {fabric.Point} The point relative to the local coordinate system + * @return {fabric.Point} + */ + // toGlobalPoint: function(point) { + // return fabric.util.rotatePoint(point, this.getCenterPoint(), degreesToRadians(this.angle)).addEquals(new fabric.Point(this.left, this.top)); + // }, + + /** + * Sets the position of the object taking into consideration the object's origin + * @param {fabric.Point} pos The new position of the object + * @param {String} originX Horizontal origin: 'left', 'center' or 'right' + * @param {String} originY Vertical origin: 'top', 'center' or 'bottom' + * @return {void} + */ + setPositionByOrigin: function(pos, originX, originY) { + var center = this.translateToCenterPoint(pos, originX, originY), + position = this.translateToOriginPoint(center, this.originX, this.originY); + + this.set('left', position.x); + this.set('top', position.y); + }, + + /** + * @param {String} to One of 'left', 'center', 'right' + */ + adjustPosition: function(to) { + var angle = degreesToRadians(this.angle), + hypotHalf = this.getWidth() / 2, + xHalf = Math.cos(angle) * hypotHalf, + yHalf = Math.sin(angle) * hypotHalf, + hypotFull = this.getWidth(), + xFull = Math.cos(angle) * hypotFull, + yFull = Math.sin(angle) * hypotFull; + + if (this.originX === 'center' && to === 'left' || + this.originX === 'right' && to === 'center') { + // move half left + this.left -= xHalf; + this.top -= yHalf; + } + else if (this.originX === 'left' && to === 'center' || + this.originX === 'center' && to === 'right') { + // move half right + this.left += xHalf; + this.top += yHalf; + } + else if (this.originX === 'left' && to === 'right') { + // move full right + this.left += xFull; + this.top += yFull; + } + else if (this.originX === 'right' && to === 'left') { + // move full left + this.left -= xFull; + this.top -= yFull; + } + + this.setCoords(); + this.originX = to; + }, + + /** + * Sets the origin/position of the object to it's center point + * @private + * @return {void} + */ + _setOriginToCenter: function() { + this._originalOriginX = this.originX; + this._originalOriginY = this.originY; + + var center = this.getCenterPoint(); + + this.originX = 'center'; + this.originY = 'center'; + + this.left = center.x; + this.top = center.y; + }, + + /** + * Resets the origin/position of the object to it's original origin + * @private + * @return {void} + */ + _resetOrigin: function() { + var originPoint = this.translateToOriginPoint( + this.getCenterPoint(), + this._originalOriginX, + this._originalOriginY); + + this.originX = this._originalOriginX; + this.originY = this._originalOriginY; + + this.left = originPoint.x; + this.top = originPoint.y; + + this._originalOriginX = null; + this._originalOriginY = null; + }, + + /** + * @private + */ + _getLeftTopCoords: function() { + return this.translateToOriginPoint(this.getCenterPoint(), 'left', 'center'); + } + }); + +})(); + + +(function() { + + var degreesToRadians = fabric.util.degreesToRadians; + + fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { + + /** + * Object containing coordinates of object's controls + * @type Object + * @default + */ + oCoords: null, + + /** + * Checks if object intersects with an area formed by 2 points + * @param {Object} pointTL top-left point of area + * @param {Object} pointBR bottom-right point of area + * @return {Boolean} true if object intersects with an area formed by 2 points + */ + intersectsWithRect: function(pointTL, pointBR) { + var oCoords = this.oCoords, + tl = new fabric.Point(oCoords.tl.x, oCoords.tl.y), + tr = new fabric.Point(oCoords.tr.x, oCoords.tr.y), + bl = new fabric.Point(oCoords.bl.x, oCoords.bl.y), + br = new fabric.Point(oCoords.br.x, oCoords.br.y), + intersection = fabric.Intersection.intersectPolygonRectangle( + [tl, tr, br, bl], + pointTL, + pointBR + ); + return intersection.status === 'Intersection'; + }, + + /** + * Checks if object intersects with another object + * @param {Object} other Object to test + * @return {Boolean} true if object intersects with another object + */ + intersectsWithObject: function(other) { + // extracts coords + function getCoords(oCoords) { + return { + tl: new fabric.Point(oCoords.tl.x, oCoords.tl.y), + tr: new fabric.Point(oCoords.tr.x, oCoords.tr.y), + bl: new fabric.Point(oCoords.bl.x, oCoords.bl.y), + br: new fabric.Point(oCoords.br.x, oCoords.br.y) + }; + } + var thisCoords = getCoords(this.oCoords), + otherCoords = getCoords(other.oCoords), + intersection = fabric.Intersection.intersectPolygonPolygon( + [thisCoords.tl, thisCoords.tr, thisCoords.br, thisCoords.bl], + [otherCoords.tl, otherCoords.tr, otherCoords.br, otherCoords.bl] + ); + + return intersection.status === 'Intersection'; + }, + + /** + * Checks if object is fully contained within area of another object + * @param {Object} other Object to test + * @return {Boolean} true if object is fully contained within area of another object + */ + isContainedWithinObject: function(other) { + var boundingRect = other.getBoundingRect(), + point1 = new fabric.Point(boundingRect.left, boundingRect.top), + point2 = new fabric.Point(boundingRect.left + boundingRect.width, boundingRect.top + boundingRect.height); + + return this.isContainedWithinRect(point1, point2); + }, + + /** + * Checks if object is fully contained within area formed by 2 points + * @param {Object} pointTL top-left point of area + * @param {Object} pointBR bottom-right point of area + * @return {Boolean} true if object is fully contained within area formed by 2 points + */ + isContainedWithinRect: function(pointTL, pointBR) { + var boundingRect = this.getBoundingRect(); + + return ( + boundingRect.left >= pointTL.x && + boundingRect.left + boundingRect.width <= pointBR.x && + boundingRect.top >= pointTL.y && + boundingRect.top + boundingRect.height <= pointBR.y + ); + }, + + /** + * Checks if point is inside the object + * @param {fabric.Point} point Point to check against + * @return {Boolean} true if point is inside the object + */ + containsPoint: function(point) { + var lines = this._getImageLines(this.oCoords), + xPoints = this._findCrossPoints(point, lines); + + // if xPoints is odd then point is inside the object + return (xPoints !== 0 && xPoints % 2 === 1); + }, + + /** + * Method that returns an object with the object edges in it, given the coordinates of the corners + * @private + * @param {Object} oCoords Coordinates of the object corners + */ + _getImageLines: function(oCoords) { + return { + topline: { + o: oCoords.tl, + d: oCoords.tr + }, + rightline: { + o: oCoords.tr, + d: oCoords.br + }, + bottomline: { + o: oCoords.br, + d: oCoords.bl + }, + leftline: { + o: oCoords.bl, + d: oCoords.tl + } + }; + }, + + /** + * Helper method to determine how many cross points are between the 4 object edges + * and the horizontal line determined by a point on canvas + * @private + * @param {fabric.Point} point Point to check + * @param {Object} oCoords Coordinates of the object being evaluated + */ + _findCrossPoints: function(point, oCoords) { + var b1, b2, a1, a2, xi, yi, + xcount = 0, + iLine; + + for (var lineKey in oCoords) { + iLine = oCoords[lineKey]; + // optimisation 1: line below point. no cross + if ((iLine.o.y < point.y) && (iLine.d.y < point.y)) { + continue; + } + // optimisation 2: line above point. no cross + if ((iLine.o.y >= point.y) && (iLine.d.y >= point.y)) { + continue; + } + // optimisation 3: vertical line case + if ((iLine.o.x === iLine.d.x) && (iLine.o.x >= point.x)) { + xi = iLine.o.x; + yi = point.y; + } + // calculate the intersection point + else { + b1 = 0; + b2 = (iLine.d.y - iLine.o.y) / (iLine.d.x - iLine.o.x); + a1 = point.y - b1 * point.x; + a2 = iLine.o.y - b2 * iLine.o.x; + + xi = - (a1 - a2) / (b1 - b2); + yi = a1 + b1 * xi; + } + // dont count xi < point.x cases + if (xi >= point.x) { + xcount += 1; + } + // optimisation 4: specific for square images + if (xcount === 2) { + break; + } + } + return xcount; + }, + + /** + * Returns width of an object's bounding rectangle + * @deprecated since 1.0.4 + * @return {Number} width value + */ + getBoundingRectWidth: function() { + return this.getBoundingRect().width; + }, + + /** + * Returns height of an object's bounding rectangle + * @deprecated since 1.0.4 + * @return {Number} height value + */ + getBoundingRectHeight: function() { + return this.getBoundingRect().height; + }, + + /** + * Returns coordinates of object's bounding rectangle (left, top, width, height) + * @return {Object} Object with left, top, width, height properties + */ + getBoundingRect: function() { + this.oCoords || this.setCoords(); + + var xCoords = [this.oCoords.tl.x, this.oCoords.tr.x, this.oCoords.br.x, this.oCoords.bl.x], + minX = fabric.util.array.min(xCoords), + maxX = fabric.util.array.max(xCoords), + width = Math.abs(minX - maxX), + + yCoords = [this.oCoords.tl.y, this.oCoords.tr.y, this.oCoords.br.y, this.oCoords.bl.y], + minY = fabric.util.array.min(yCoords), + maxY = fabric.util.array.max(yCoords), + height = Math.abs(minY - maxY); + + return { + left: minX, + top: minY, + width: width, + height: height + }; + }, + + /** + * Returns width of an object + * @return {Number} width value + */ + getWidth: function() { + return this.width * this.scaleX; + }, + + /** + * Returns height of an object + * @return {Number} height value + */ + getHeight: function() { + return this.height * this.scaleY; + }, + + /** + * Makes sure the scale is valid and modifies it if necessary + * @private + * @param {Number} value + * @return {Number} + */ + _constrainScale: function(value) { + if (Math.abs(value) < this.minScaleLimit) { + if (value < 0) { + return -this.minScaleLimit; + } + else { + return this.minScaleLimit; + } + } + return value; + }, + + /** + * Scales an object (equally by x and y) + * @param {Number} value Scale factor + * @return {fabric.Object} thisArg + * @chainable + */ + scale: function(value) { + value = this._constrainScale(value); + + if (value < 0) { + this.flipX = !this.flipX; + this.flipY = !this.flipY; + value *= -1; + } + + this.scaleX = value; + this.scaleY = value; + this.setCoords(); + return this; + }, + + /** + * Scales an object to a given width, with respect to bounding box (scaling by x/y equally) + * @param {Number} value New width value + * @return {fabric.Object} thisArg + * @chainable + */ + scaleToWidth: function(value) { + // adjust to bounding rect factor so that rotated shapes would fit as well + var boundingRectFactor = this.getBoundingRectWidth() / this.getWidth(); + return this.scale(value / this.width / boundingRectFactor); + }, + + /** + * Scales an object to a given height, with respect to bounding box (scaling by x/y equally) + * @param {Number} value New height value + * @return {fabric.Object} thisArg + * @chainable + */ + scaleToHeight: function(value) { + // adjust to bounding rect factor so that rotated shapes would fit as well + var boundingRectFactor = this.getBoundingRectHeight() / this.getHeight(); + return this.scale(value / this.height / boundingRectFactor); + }, + + /** + * Sets corner position coordinates based on current angle, width and height + * See https://github.com/kangax/fabric.js/wiki/When-to-call-setCoords + * @return {fabric.Object} thisArg + * @chainable + */ + setCoords: function() { + var theta = degreesToRadians(this.angle), + vpt = this.getViewportTransform(), + f = function (p) { + return fabric.util.transformPoint(p, vpt); + }, + p = this._calculateCurrentDimensions(false), + currentWidth = p.x, currentHeight = p.y; + + // If width is negative, make postive. Fixes path selection issue + if (currentWidth < 0) { + currentWidth = Math.abs(currentWidth); + } + + var _hypotenuse = Math.sqrt( + Math.pow(currentWidth / 2, 2) + + Math.pow(currentHeight / 2, 2)), + + _angle = Math.atan( + isFinite(currentHeight / currentWidth) + ? currentHeight / currentWidth + : 0), + + // offset added for rotate and scale actions + offsetX = Math.cos(_angle + theta) * _hypotenuse, + offsetY = Math.sin(_angle + theta) * _hypotenuse, + sinTh = Math.sin(theta), + cosTh = Math.cos(theta), + coords = this.getCenterPoint(), + wh = new fabric.Point(currentWidth, currentHeight), + _tl = new fabric.Point(coords.x - offsetX, coords.y - offsetY), + _tr = new fabric.Point(_tl.x + (wh.x * cosTh), _tl.y + (wh.x * sinTh)), + bl = f(new fabric.Point(_tl.x - (wh.y * sinTh), _tl.y + (wh.y * cosTh))), + br = f(new fabric.Point(_tr.x - (wh.y * sinTh), _tr.y + (wh.y * cosTh))), + tl = f(_tl), + tr = f(_tr), + ml = new fabric.Point((tl.x + bl.x)/2, (tl.y + bl.y)/2), + mt = new fabric.Point((tr.x + tl.x)/2, (tr.y + tl.y)/2), + mr = new fabric.Point((br.x + tr.x)/2, (br.y + tr.y)/2), + mb = new fabric.Point((br.x + bl.x)/2, (br.y + bl.y)/2), + mtr = new fabric.Point(mt.x + sinTh * this.rotatingPointOffset, mt.y - cosTh * this.rotatingPointOffset); + // debugging + + /* setTimeout(function() { + canvas.contextTop.fillStyle = 'green'; + canvas.contextTop.fillRect(mb.x, mb.y, 3, 3); + canvas.contextTop.fillRect(bl.x, bl.y, 3, 3); + canvas.contextTop.fillRect(br.x, br.y, 3, 3); + canvas.contextTop.fillRect(tl.x, tl.y, 3, 3); + canvas.contextTop.fillRect(tr.x, tr.y, 3, 3); + canvas.contextTop.fillRect(ml.x, ml.y, 3, 3); + canvas.contextTop.fillRect(mr.x, mr.y, 3, 3); + canvas.contextTop.fillRect(mt.x, mt.y, 3, 3); + canvas.contextTop.fillRect(mtr.x, mtr.y, 3, 3); + }, 50); */ + + this.oCoords = { + // corners + tl: tl, tr: tr, br: br, bl: bl, + // middle + ml: ml, mt: mt, mr: mr, mb: mb, + // rotating point + mtr: mtr + }; + + // set coordinates of the draggable boxes in the corners used to scale/rotate the image + this._setCornerCoords && this._setCornerCoords(); + + return this; + } + }); +})(); + + +fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { + + /** + * Moves an object to the bottom of the stack of drawn objects + * @return {fabric.Object} thisArg + * @chainable + */ + sendToBack: function() { + if (this.group) { + fabric.StaticCanvas.prototype.sendToBack.call(this.group, this); + } + else { + this.canvas.sendToBack(this); + } + return this; + }, + + /** + * Moves an object to the top of the stack of drawn objects + * @return {fabric.Object} thisArg + * @chainable + */ + bringToFront: function() { + if (this.group) { + fabric.StaticCanvas.prototype.bringToFront.call(this.group, this); + } + else { + this.canvas.bringToFront(this); + } + return this; + }, + + /** + * Moves an object down in stack of drawn objects + * @param {Boolean} [intersecting] If `true`, send object behind next lower intersecting object + * @return {fabric.Object} thisArg + * @chainable + */ + sendBackwards: function(intersecting) { + if (this.group) { + fabric.StaticCanvas.prototype.sendBackwards.call(this.group, this, intersecting); + } + else { + this.canvas.sendBackwards(this, intersecting); + } + return this; + }, + + /** + * Moves an object up in stack of drawn objects + * @param {Boolean} [intersecting] If `true`, send object in front of next upper intersecting object + * @return {fabric.Object} thisArg + * @chainable + */ + bringForward: function(intersecting) { + if (this.group) { + fabric.StaticCanvas.prototype.bringForward.call(this.group, this, intersecting); + } + else { + this.canvas.bringForward(this, intersecting); + } + return this; + }, + + /** + * Moves an object to specified level in stack of drawn objects + * @param {Number} index New position of object + * @return {fabric.Object} thisArg + * @chainable + */ + moveTo: function(index) { + if (this.group) { + fabric.StaticCanvas.prototype.moveTo.call(this.group, this, index); + } + else { + this.canvas.moveTo(this, index); + } + return this; + } +}); + + +/* _TO_SVG_START_ */ +fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { + + /** + * Returns styles-string for svg-export + * @return {String} + */ + getSvgStyles: function() { + + var fill = this.fill + ? (this.fill.toLive ? 'url(#SVGID_' + this.fill.id + ')' : this.fill) + : 'none', + fillRule = this.fillRule, + stroke = this.stroke + ? (this.stroke.toLive ? 'url(#SVGID_' + this.stroke.id + ')' : this.stroke) + : 'none', + + strokeWidth = this.strokeWidth ? this.strokeWidth : '0', + strokeDashArray = this.strokeDashArray ? this.strokeDashArray.join(' ') : '', + strokeLineCap = this.strokeLineCap ? this.strokeLineCap : 'butt', + strokeLineJoin = this.strokeLineJoin ? this.strokeLineJoin : 'miter', + strokeMiterLimit = this.strokeMiterLimit ? this.strokeMiterLimit : '4', + opacity = typeof this.opacity !== 'undefined' ? this.opacity : '1', + + visibility = this.visible ? '' : ' visibility: hidden;', + filter = this.shadow ? 'filter: url(#SVGID_' + this.shadow.id + ');' : ''; + + return [ + 'stroke: ', stroke, '; ', + 'stroke-width: ', strokeWidth, '; ', + 'stroke-dasharray: ', strokeDashArray, '; ', + 'stroke-linecap: ', strokeLineCap, '; ', + 'stroke-linejoin: ', strokeLineJoin, '; ', + 'stroke-miterlimit: ', strokeMiterLimit, '; ', + 'fill: ', fill, '; ', + 'fill-rule: ', fillRule, '; ', + 'opacity: ', opacity, ';', + filter, + visibility + ].join(''); + }, + + /** + * Returns transform-string for svg-export + * @return {String} + */ + getSvgTransform: function() { + if (this.group && this.group.type === 'path-group') { + return ''; + } + var toFixed = fabric.util.toFixed, + angle = this.getAngle(), + vpt = !this.canvas || this.canvas.svgViewportTransformation ? this.getViewportTransform() : [1, 0, 0, 1, 0, 0], + center = fabric.util.transformPoint(this.getCenterPoint(), vpt), + + NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS, + + translatePart = this.type === 'path-group' ? '' : 'translate(' + + toFixed(center.x, NUM_FRACTION_DIGITS) + + ' ' + + toFixed(center.y, NUM_FRACTION_DIGITS) + + ')', + + anglePart = angle !== 0 + ? (' rotate(' + toFixed(angle, NUM_FRACTION_DIGITS) + ')') + : '', + + scalePart = (this.scaleX === 1 && this.scaleY === 1 && vpt[0] === 1 && vpt[3] === 1) + ? '' : + (' scale(' + + toFixed(this.scaleX * vpt[0], NUM_FRACTION_DIGITS) + + ' ' + + toFixed(this.scaleY * vpt[3], NUM_FRACTION_DIGITS) + + ')'), + + addTranslateX = this.type === 'path-group' ? this.width * vpt[0] : 0, + + flipXPart = this.flipX ? ' matrix(-1 0 0 1 ' + addTranslateX + ' 0) ' : '', + + addTranslateY = this.type === 'path-group' ? this.height * vpt[3] : 0, + + flipYPart = this.flipY ? ' matrix(1 0 0 -1 0 ' + addTranslateY + ')' : ''; + + return [ + translatePart, anglePart, scalePart, flipXPart, flipYPart + ].join(''); + }, + + /** + * Returns transform-string for svg-export from the transform matrix of single elements + * @return {String} + */ + getSvgTransformMatrix: function() { + return this.transformMatrix ? ' matrix(' + this.transformMatrix.join(' ') + ') ' : ''; + }, + + /** + * @private + */ + _createBaseSVGMarkup: function() { + var markup = [ ]; + + if (this.fill && this.fill.toLive) { + markup.push(this.fill.toSVG(this, false)); + } + if (this.stroke && this.stroke.toLive) { + markup.push(this.stroke.toSVG(this, false)); + } + if (this.shadow) { + markup.push(this.shadow.toSVG(this)); + } + return markup; + } +}); +/* _TO_SVG_END_ */ + + +/* + Depends on `stateProperties` +*/ +fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { + + /** + * Returns true if object state (one of its state properties) was changed + * @return {Boolean} true if instance' state has changed since `{@link fabric.Object#saveState}` was called + */ + hasStateChanged: function() { + return this.stateProperties.some(function(prop) { + return this.get(prop) !== this.originalState[prop]; + }, this); + }, + + /** + * Saves state of an object + * @param {Object} [options] Object with additional `stateProperties` array to include when saving state + * @return {fabric.Object} thisArg + */ + saveState: function(options) { + this.stateProperties.forEach(function(prop) { + this.originalState[prop] = this.get(prop); + }, this); + + if (options && options.stateProperties) { + options.stateProperties.forEach(function(prop) { + this.originalState[prop] = this.get(prop); + }, this); + } + + return this; + }, + + /** + * Setups state of an object + * @return {fabric.Object} thisArg + */ + setupState: function() { + this.originalState = { }; + this.saveState(); + + return this; + } +}); + + +(function() { + + var degreesToRadians = fabric.util.degreesToRadians, + //jscs:disable requireCamelCaseOrUpperCaseIdentifiers + isVML = function() { return typeof G_vmlCanvasManager !== 'undefined'; }; + //jscs:enable requireCamelCaseOrUpperCaseIdentifiers + + fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { + + /** + * The object interactivity controls. + * @private + */ + _controlsVisibility: null, + + /** + * Determines which corner has been clicked + * @private + * @param {Object} pointer The pointer indicating the mouse position + * @return {String|Boolean} corner code (tl, tr, bl, br, etc.), or false if nothing is found + */ + _findTargetCorner: function(pointer) { + if (!this.hasControls || !this.active) { + return false; + } + + var ex = pointer.x, + ey = pointer.y, + xPoints, + lines; + + for (var i in this.oCoords) { + + if (!this.isControlVisible(i)) { + continue; + } + + if (i === 'mtr' && !this.hasRotatingPoint) { + continue; + } + + if (this.get('lockUniScaling') && + (i === 'mt' || i === 'mr' || i === 'mb' || i === 'ml')) { + continue; + } + + lines = this._getImageLines(this.oCoords[i].corner); + + // debugging + + // canvas.contextTop.fillRect(lines.bottomline.d.x, lines.bottomline.d.y, 2, 2); + // canvas.contextTop.fillRect(lines.bottomline.o.x, lines.bottomline.o.y, 2, 2); + + // canvas.contextTop.fillRect(lines.leftline.d.x, lines.leftline.d.y, 2, 2); + // canvas.contextTop.fillRect(lines.leftline.o.x, lines.leftline.o.y, 2, 2); + + // canvas.contextTop.fillRect(lines.topline.d.x, lines.topline.d.y, 2, 2); + // canvas.contextTop.fillRect(lines.topline.o.x, lines.topline.o.y, 2, 2); + + // canvas.contextTop.fillRect(lines.rightline.d.x, lines.rightline.d.y, 2, 2); + // canvas.contextTop.fillRect(lines.rightline.o.x, lines.rightline.o.y, 2, 2); + + xPoints = this._findCrossPoints({ x: ex, y: ey }, lines); + if (xPoints !== 0 && xPoints % 2 === 1) { + this.__corner = i; + return i; + } + } + return false; + }, + + /** + * Sets the coordinates of the draggable boxes in the corners of + * the image used to scale/rotate it. + * @private + */ + _setCornerCoords: function() { + var coords = this.oCoords, + newTheta = degreesToRadians(45 - this.angle), + cornerHypotenuse = Math.sqrt(2 * Math.pow(this.cornerSize, 2)) / 2, + cosHalfOffset = cornerHypotenuse * Math.cos(newTheta), + sinHalfOffset = cornerHypotenuse * Math.sin(newTheta), + x, y; + + for (var point in coords) { + x = coords[point].x; + y = coords[point].y; + coords[point].corner = { + tl: { + x: x - sinHalfOffset, + y: y - cosHalfOffset + }, + tr: { + x: x + cosHalfOffset, + y: y - sinHalfOffset + }, + bl: { + x: x - cosHalfOffset, + y: y + sinHalfOffset + }, + br: { + x: x + sinHalfOffset, + y: y + cosHalfOffset + } + }; + } + }, + + _calculateCurrentDimensions: function(shouldTransform) { + var vpt = this.getViewportTransform(), + strokeWidth = this.strokeWidth, + w = this.width, + h = this.height, + capped = this.strokeLineCap === 'round' || this.strokeLineCap === 'square', + vLine = this.type === 'line' && this.width === 0, + hLine = this.type === 'line' && this.height === 0, + sLine = vLine || hLine, + strokeW = (capped && hLine) || !sLine, + strokeH = (capped && vLine) || !sLine; + + if (vLine) { + w = strokeWidth; + } + else if (hLine) { + h = strokeWidth; + } + if (strokeW) { + w += (w < 0 ? -strokeWidth : strokeWidth); + } + if (strokeH) { + h += (h < 0 ? -strokeWidth : strokeWidth); + } + + w = w * this.scaleX + 2 * this.padding; + h = h * this.scaleY + 2 * this.padding; + + if (shouldTransform) { + return fabric.util.transformPoint(new fabric.Point(w, h), vpt, true); + } + return { x: w, y: h }; + }, + + /** + * Draws borders of an object's bounding box. + * Requires public properties: width, height + * Requires public options: padding, borderColor + * @param {CanvasRenderingContext2D} ctx Context to draw on + * @return {fabric.Object} thisArg + * @chainable + */ + drawBorders: function(ctx) { + if (!this.hasBorders) { + return this; + } + + ctx.save(); + + ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1; + ctx.strokeStyle = this.borderColor; + ctx.lineWidth = 1 / this.borderScaleFactor; + + var wh = this._calculateCurrentDimensions(true), + width = wh.x, + height = wh.y; + if (this.group) { + width = width * this.group.scaleX; + height = height * this.group.scaleY; + } + + ctx.strokeRect( + ~~(-(width / 2)) - 0.5, // offset needed to make lines look sharper + ~~(-(height / 2)) - 0.5, + ~~(width) + 1, // double offset needed to make lines look sharper + ~~(height) + 1 + ); + + if (this.hasRotatingPoint && this.isControlVisible('mtr') && !this.get('lockRotation') && this.hasControls) { + + var rotateHeight = -height / 2; + + ctx.beginPath(); + ctx.moveTo(0, rotateHeight); + ctx.lineTo(0, rotateHeight - this.rotatingPointOffset); + ctx.closePath(); + ctx.stroke(); + } + + ctx.restore(); + return this; + }, + + /** + * Draws corners of an object's bounding box. + * Requires public properties: width, height + * Requires public options: cornerSize, padding + * @param {CanvasRenderingContext2D} ctx Context to draw on + * @return {fabric.Object} thisArg + * @chainable + */ + drawControls: function(ctx) { + if (!this.hasControls) { + return this; + } + + var wh = this._calculateCurrentDimensions(true), + width = wh.x, + height = wh.y, + left = -(width / 2), + top = -(height / 2), + scaleOffset = this.cornerSize / 2, + methodName = this.transparentCorners ? 'strokeRect' : 'fillRect'; + + ctx.save(); + + ctx.lineWidth = 1; + + ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1; + ctx.strokeStyle = ctx.fillStyle = this.cornerColor; + + // top-left + this._drawControl('tl', ctx, methodName, + left - scaleOffset, + top - scaleOffset); + + // top-right + this._drawControl('tr', ctx, methodName, + left + width - scaleOffset, + top - scaleOffset); + + // bottom-left + this._drawControl('bl', ctx, methodName, + left - scaleOffset, + top + height - scaleOffset); + + // bottom-right + this._drawControl('br', ctx, methodName, + left + width - scaleOffset, + top + height - scaleOffset); + + if (!this.get('lockUniScaling')) { + + // middle-top + this._drawControl('mt', ctx, methodName, + left + width/2 - scaleOffset, + top - scaleOffset); + + // middle-bottom + this._drawControl('mb', ctx, methodName, + left + width/2 - scaleOffset, + top + height - scaleOffset); + + // middle-right + this._drawControl('mr', ctx, methodName, + left + width - scaleOffset, + top + height/2 - scaleOffset); + + // middle-left + this._drawControl('ml', ctx, methodName, + left - scaleOffset, + top + height/2 - scaleOffset); + } + + // middle-top-rotate + if (this.hasRotatingPoint) { + this._drawControl('mtr', ctx, methodName, + left + width/2 - scaleOffset, + top - this.rotatingPointOffset - scaleOffset); + } + + ctx.restore(); + + return this; + }, + + /** + * @private + */ + _drawControl: function(control, ctx, methodName, left, top) { + if (!this.isControlVisible(control)) { + return; + } + var size = this.cornerSize; + isVML() || this.transparentCorners || ctx.clearRect(left, top, size, size); + ctx[methodName](left, top, size, size); + }, + + /** + * Returns true if the specified control is visible, false otherwise. + * @param {String} controlName The name of the control. Possible values are 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr'. + * @returns {Boolean} true if the specified control is visible, false otherwise + */ + isControlVisible: function(controlName) { + return this._getControlsVisibility()[controlName]; + }, + + /** + * Sets the visibility of the specified control. + * @param {String} controlName The name of the control. Possible values are 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr'. + * @param {Boolean} visible true to set the specified control visible, false otherwise + * @return {fabric.Object} thisArg + * @chainable + */ + setControlVisible: function(controlName, visible) { + this._getControlsVisibility()[controlName] = visible; + return this; + }, + + /** + * Sets the visibility state of object controls. + * @param {Object} [options] Options object + * @param {Boolean} [options.bl] true to enable the bottom-left control, false to disable it + * @param {Boolean} [options.br] true to enable the bottom-right control, false to disable it + * @param {Boolean} [options.mb] true to enable the middle-bottom control, false to disable it + * @param {Boolean} [options.ml] true to enable the middle-left control, false to disable it + * @param {Boolean} [options.mr] true to enable the middle-right control, false to disable it + * @param {Boolean} [options.mt] true to enable the middle-top control, false to disable it + * @param {Boolean} [options.tl] true to enable the top-left control, false to disable it + * @param {Boolean} [options.tr] true to enable the top-right control, false to disable it + * @param {Boolean} [options.mtr] true to enable the middle-top-rotate control, false to disable it + * @return {fabric.Object} thisArg + * @chainable + */ + setControlsVisibility: function(options) { + options || (options = { }); + + for (var p in options) { + this.setControlVisible(p, options[p]); + } + return this; + }, + + /** + * Returns the instance of the control visibility set for this object. + * @private + * @returns {Object} + */ + _getControlsVisibility: function() { + if (!this._controlsVisibility) { + this._controlsVisibility = { + tl: true, + tr: true, + br: true, + bl: true, + ml: true, + mt: true, + mr: true, + mb: true, + mtr: true + }; + } + return this._controlsVisibility; + } + }); +})(); + + +fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ { + + /** + * Animation duration (in ms) for fx* methods + * @type Number + * @default + */ + FX_DURATION: 500, + + /** + * Centers object horizontally with animation. + * @param {fabric.Object} object Object to center + * @param {Object} [callbacks] Callbacks object with optional "onComplete" and/or "onChange" properties + * @param {Function} [callbacks.onComplete] Invoked on completion + * @param {Function} [callbacks.onChange] Invoked on every step of animation + * @return {fabric.Canvas} thisArg + * @chainable + */ + fxCenterObjectH: function (object, callbacks) { + callbacks = callbacks || { }; + + var empty = function() { }, + onComplete = callbacks.onComplete || empty, + onChange = callbacks.onChange || empty, + _this = this; + + fabric.util.animate({ + startValue: object.get('left'), + endValue: this.getCenter().left, + duration: this.FX_DURATION, + onChange: function(value) { + object.set('left', value); + _this.renderAll(); + onChange(); + }, + onComplete: function() { + object.setCoords(); + onComplete(); + } + }); + + return this; + }, + + /** + * Centers object vertically with animation. + * @param {fabric.Object} object Object to center + * @param {Object} [callbacks] Callbacks object with optional "onComplete" and/or "onChange" properties + * @param {Function} [callbacks.onComplete] Invoked on completion + * @param {Function} [callbacks.onChange] Invoked on every step of animation + * @return {fabric.Canvas} thisArg + * @chainable + */ + fxCenterObjectV: function (object, callbacks) { + callbacks = callbacks || { }; + + var empty = function() { }, + onComplete = callbacks.onComplete || empty, + onChange = callbacks.onChange || empty, + _this = this; + + fabric.util.animate({ + startValue: object.get('top'), + endValue: this.getCenter().top, + duration: this.FX_DURATION, + onChange: function(value) { + object.set('top', value); + _this.renderAll(); + onChange(); + }, + onComplete: function() { + object.setCoords(); + onComplete(); + } + }); + + return this; + }, + + /** + * Same as `fabric.Canvas#remove` but animated + * @param {fabric.Object} object Object to remove + * @param {Object} [callbacks] Callbacks object with optional "onComplete" and/or "onChange" properties + * @param {Function} [callbacks.onComplete] Invoked on completion + * @param {Function} [callbacks.onChange] Invoked on every step of animation + * @return {fabric.Canvas} thisArg + * @chainable + */ + fxRemove: function (object, callbacks) { + callbacks = callbacks || { }; + + var empty = function() { }, + onComplete = callbacks.onComplete || empty, + onChange = callbacks.onChange || empty, + _this = this; + + fabric.util.animate({ + startValue: object.get('opacity'), + endValue: 0, + duration: this.FX_DURATION, + onStart: function() { + object.set('active', false); + }, + onChange: function(value) { + object.set('opacity', value); + _this.renderAll(); + onChange(); + }, + onComplete: function () { + _this.remove(object); + onComplete(); + } + }); + + return this; + } +}); + +fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { + /** + * Animates object's properties + * @param {String|Object} property Property to animate (if string) or properties to animate (if object) + * @param {Number|Object} value Value to animate property to (if string was given first) or options object + * @return {fabric.Object} thisArg + * @tutorial {@link http://fabricjs.com/fabric-intro-part-2/#animation} + * @chainable + * + * As object — multiple properties + * + * object.animate({ left: ..., top: ... }); + * object.animate({ left: ..., top: ... }, { duration: ... }); + * + * As string — one property + * + * object.animate('left', ...); + * object.animate('left', { duration: ... }); + * + */ + animate: function() { + if (arguments[0] && typeof arguments[0] === 'object') { + var propsToAnimate = [ ], prop, skipCallbacks; + for (prop in arguments[0]) { + propsToAnimate.push(prop); + } + for (var i = 0, len = propsToAnimate.length; i < len; i++) { + prop = propsToAnimate[i]; + skipCallbacks = i !== len - 1; + this._animate(prop, arguments[0][prop], arguments[1], skipCallbacks); + } + } + else { + this._animate.apply(this, arguments); + } + return this; + }, + + /** + * @private + * @param {String} property Property to animate + * @param {String} to Value to animate to + * @param {Object} [options] Options object + * @param {Boolean} [skipCallbacks] When true, callbacks like onchange and oncomplete are not invoked + */ + _animate: function(property, to, options, skipCallbacks) { + var _this = this, propPair; + + to = to.toString(); + + if (!options) { + options = { }; + } + else { + options = fabric.util.object.clone(options); + } + + if (~property.indexOf('.')) { + propPair = property.split('.'); + } + + var currentValue = propPair + ? this.get(propPair[0])[propPair[1]] + : this.get(property); + + if (!('from' in options)) { + options.from = currentValue; + } + + if (~to.indexOf('=')) { + to = currentValue + parseFloat(to.replace('=', '')); + } + else { + to = parseFloat(to); + } + + fabric.util.animate({ + startValue: options.from, + endValue: to, + byValue: options.by, + easing: options.easing, + duration: options.duration, + abort: options.abort && function() { + return options.abort.call(_this); + }, + onChange: function(value) { + if (propPair) { + _this[propPair[0]][propPair[1]] = value; + } + else { + _this.set(property, value); + } + if (skipCallbacks) { + return; + } + options.onChange && options.onChange(); + }, + onComplete: function() { + if (skipCallbacks) { + return; + } + + _this.setCoords(); + options.onComplete && options.onComplete(); + } + }); + } +}); + + +(function(global) { + + 'use strict'; + + var fabric = global.fabric || (global.fabric = { }), + extend = fabric.util.object.extend, + coordProps = { x1: 1, x2: 1, y1: 1, y2: 1 }, + supportsLineDash = fabric.StaticCanvas.supports('setLineDash'); + + if (fabric.Line) { + fabric.warn('fabric.Line is already defined'); + return; + } + + /** + * Line class + * @class fabric.Line + * @extends fabric.Object + * @see {@link fabric.Line#initialize} for constructor definition + */ + fabric.Line = fabric.util.createClass(fabric.Object, /** @lends fabric.Line.prototype */ { + + /** + * Type of an object + * @type String + * @default + */ + type: 'line', + + /** + * x value or first line edge + * @type Number + * @default + */ + x1: 0, + + /** + * y value or first line edge + * @type Number + * @default + */ + y1: 0, + + /** + * x value or second line edge + * @type Number + * @default + */ + x2: 0, + + /** + * y value or second line edge + * @type Number + * @default + */ + y2: 0, + + /** + * Constructor + * @param {Array} [points] Array of points + * @param {Object} [options] Options object + * @return {fabric.Line} thisArg + */ + initialize: function(points, options) { + options = options || { }; + + if (!points) { + points = [0, 0, 0, 0]; + } + + this.callSuper('initialize', options); + + this.set('x1', points[0]); + this.set('y1', points[1]); + this.set('x2', points[2]); + this.set('y2', points[3]); + + this._setWidthHeight(options); + }, + + /** + * @private + * @param {Object} [options] Options + */ + _setWidthHeight: function(options) { + options || (options = { }); + + this.width = Math.abs(this.x2 - this.x1); + this.height = Math.abs(this.y2 - this.y1); + + this.left = 'left' in options + ? options.left + : this._getLeftToOriginX(); + + this.top = 'top' in options + ? options.top + : this._getTopToOriginY(); + }, + + /** + * @private + * @param {String} key + * @param {Any} value + */ + _set: function(key, value) { + this.callSuper('_set', key, value); + if (typeof coordProps[key] !== 'undefined') { + this._setWidthHeight(); + } + return this; + }, + + /** + * @private + * @return {Number} leftToOriginX Distance from left edge of canvas to originX of Line. + */ + _getLeftToOriginX: makeEdgeToOriginGetter( + { // property names + origin: 'originX', + axis1: 'x1', + axis2: 'x2', + dimension: 'width' + }, + { // possible values of origin + nearest: 'left', + center: 'center', + farthest: 'right' + } + ), + + /** + * @private + * @return {Number} topToOriginY Distance from top edge of canvas to originY of Line. + */ + _getTopToOriginY: makeEdgeToOriginGetter( + { // property names + origin: 'originY', + axis1: 'y1', + axis2: 'y2', + dimension: 'height' + }, + { // possible values of origin + nearest: 'top', + center: 'center', + farthest: 'bottom' + } + ), + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _render: function(ctx, noTransform) { + ctx.beginPath(); + + if (noTransform) { + // Line coords are distances from left-top of canvas to origin of line. + // To render line in a path-group, we need to translate them to + // distances from center of path-group to center of line. + var cp = this.getCenterPoint(); + ctx.translate( + cp.x - this.strokeWidth / 2, + cp.y - this.strokeWidth / 2 + ); + } + + if (!this.strokeDashArray || this.strokeDashArray && supportsLineDash) { + // move from center (of virtual box) to its left/top corner + // we can't assume x1, y1 is top left and x2, y2 is bottom right + var p = this.calcLinePoints(); + ctx.moveTo(p.x1, p.y1); + ctx.lineTo(p.x2, p.y2); + } + + ctx.lineWidth = this.strokeWidth; + + // TODO: test this + // make sure setting "fill" changes color of a line + // (by copying fillStyle to strokeStyle, since line is stroked, not filled) + var origStrokeStyle = ctx.strokeStyle; + ctx.strokeStyle = this.stroke || ctx.fillStyle; + this.stroke && this._renderStroke(ctx); + ctx.strokeStyle = origStrokeStyle; + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderDashedStroke: function(ctx) { + var p = this.calcLinePoints(); + + ctx.beginPath(); + fabric.util.drawDashedLine(ctx, p.x1, p.y1, p.x2, p.y2, this.strokeDashArray); + ctx.closePath(); + }, + + /** + * Returns object representation of an instance + * @methd toObject + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} object representation of an instance + */ + toObject: function(propertiesToInclude) { + return extend(this.callSuper('toObject', propertiesToInclude), this.calcLinePoints()); + }, + + /** + * Recalculates line points given width and height + * @private + */ + calcLinePoints: function() { + var xMult = this.x1 <= this.x2 ? -1 : 1, + yMult = this.y1 <= this.y2 ? -1 : 1, + x1 = (xMult * this.width * 0.5), + y1 = (yMult * this.height * 0.5), + x2 = (xMult * this.width * -0.5), + y2 = (yMult * this.height * -0.5); + + return { + x1: x1, + x2: x2, + y1: y1, + y2: y2 + }; + }, + + /* _TO_SVG_START_ */ + /** + * Returns SVG representation of an instance + * @param {Function} [reviver] Method for further parsing of svg representation. + * @return {String} svg representation of an instance + */ + toSVG: function(reviver) { + var markup = this._createBaseSVGMarkup(), + p = { x1: this.x1, x2: this.x2, y1: this.y1, y2: this.y2 }; + + if (!(this.group && this.group.type === 'path-group')) { + p = this.calcLinePoints(); + } + markup.push( + '\n' + ); + + return reviver ? reviver(markup.join('')) : markup.join(''); + }, + /* _TO_SVG_END_ */ + + /** + * Returns complexity of an instance + * @return {Number} complexity + */ + complexity: function() { + return 1; + } + }); + + /* _FROM_SVG_START_ */ + /** + * List of attribute names to account for when parsing SVG element (used by {@link fabric.Line.fromElement}) + * @static + * @memberOf fabric.Line + * @see http://www.w3.org/TR/SVG/shapes.html#LineElement + */ + fabric.Line.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('x1 y1 x2 y2'.split(' ')); + + /** + * Returns fabric.Line instance from an SVG element + * @static + * @memberOf fabric.Line + * @param {SVGElement} element Element to parse + * @param {Object} [options] Options object + * @return {fabric.Line} instance of fabric.Line + */ + fabric.Line.fromElement = function(element, options) { + var parsedAttributes = fabric.parseAttributes(element, fabric.Line.ATTRIBUTE_NAMES), + points = [ + parsedAttributes.x1 || 0, + parsedAttributes.y1 || 0, + parsedAttributes.x2 || 0, + parsedAttributes.y2 || 0 + ]; + return new fabric.Line(points, extend(parsedAttributes, options)); + }; + /* _FROM_SVG_END_ */ + + /** + * Returns fabric.Line instance from an object representation + * @static + * @memberOf fabric.Line + * @param {Object} object Object to create an instance from + * @return {fabric.Line} instance of fabric.Line + */ + fabric.Line.fromObject = function(object) { + var points = [object.x1, object.y1, object.x2, object.y2]; + return new fabric.Line(points, object); + }; + + /** + * Produces a function that calculates distance from canvas edge to Line origin. + */ + function makeEdgeToOriginGetter(propertyNames, originValues) { + var origin = propertyNames.origin, + axis1 = propertyNames.axis1, + axis2 = propertyNames.axis2, + dimension = propertyNames.dimension, + nearest = originValues.nearest, + center = originValues.center, + farthest = originValues.farthest; + + return function() { + switch (this.get(origin)) { + case nearest: + return Math.min(this.get(axis1), this.get(axis2)); + case center: + return Math.min(this.get(axis1), this.get(axis2)) + (0.5 * this.get(dimension)); + case farthest: + return Math.max(this.get(axis1), this.get(axis2)); + } + }; + + } + +})(typeof exports !== 'undefined' ? exports : this); + + +(function(global) { + + 'use strict'; + + var fabric = global.fabric || (global.fabric = { }), + pi = Math.PI, + extend = fabric.util.object.extend; + + if (fabric.Circle) { + fabric.warn('fabric.Circle is already defined.'); + return; + } + + /** + * Circle class + * @class fabric.Circle + * @extends fabric.Object + * @see {@link fabric.Circle#initialize} for constructor definition + */ + fabric.Circle = fabric.util.createClass(fabric.Object, /** @lends fabric.Circle.prototype */ { + + /** + * Type of an object + * @type String + * @default + */ + type: 'circle', + + /** + * Radius of this circle + * @type Number + * @default + */ + radius: 0, + + /** + * Start angle of the circle, moving clockwise + * @type Number + * @default 0 + */ + startAngle: 0, + + /** + * End angle of the circle + * @type Number + * @default 2Pi + */ + endAngle: pi * 2, + + /** + * Constructor + * @param {Object} [options] Options object + * @return {fabric.Circle} thisArg + */ + initialize: function(options) { + options = options || { }; + + this.callSuper('initialize', options); + this.set('radius', options.radius || 0); + this.startAngle = options.startAngle || this.startAngle; + this.endAngle = options.endAngle || this.endAngle; + }, + + /** + * @private + * @param {String} key + * @param {Any} value + * @return {fabric.Circle} thisArg + */ + _set: function(key, value) { + this.callSuper('_set', key, value); + + if (key === 'radius') { + this.setRadius(value); + } + + return this; + }, + + /** + * Returns object representation of an instance + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} object representation of an instance + */ + toObject: function(propertiesToInclude) { + return extend(this.callSuper('toObject', propertiesToInclude), { + radius: this.get('radius'), + startAngle: this.startAngle, + endAngle: this.endAngle + }); + }, + + /* _TO_SVG_START_ */ + /** + * Returns svg representation of an instance + * @param {Function} [reviver] Method for further parsing of svg representation. + * @return {String} svg representation of an instance + */ + toSVG: function(reviver) { + var markup = this._createBaseSVGMarkup(), x = 0, y = 0, + angle = (this.endAngle - this.startAngle) % ( 2 * pi); + + if (angle === 0) { + if (this.group && this.group.type === 'path-group') { + x = this.left + this.radius; + y = this.top + this.radius; + } + markup.push( + '\n' + ); + } + else { + var startX = Math.cos(this.startAngle) * this.radius, + startY = Math.sin(this.startAngle) * this.radius, + endX = Math.cos(this.endAngle) * this.radius, + endY = Math.sin(this.endAngle) * this.radius, + largeFlag = angle > pi ? '1' : '0'; + + markup.push( + '\n' + ); + } + + return reviver ? reviver(markup.join('')) : markup.join(''); + }, + /* _TO_SVG_END_ */ + + /** + * @private + * @param {CanvasRenderingContext2D} ctx context to render on + * @param {Boolean} [noTransform] When true, context is not transformed + */ + _render: function(ctx, noTransform) { + ctx.beginPath(); + ctx.arc(noTransform ? this.left + this.radius : 0, + noTransform ? this.top + this.radius : 0, + this.radius, + this.startAngle, + this.endAngle, false); + this._renderFill(ctx); + this._renderStroke(ctx); + }, + + /** + * Returns horizontal radius of an object (according to how an object is scaled) + * @return {Number} + */ + getRadiusX: function() { + return this.get('radius') * this.get('scaleX'); + }, + + /** + * Returns vertical radius of an object (according to how an object is scaled) + * @return {Number} + */ + getRadiusY: function() { + return this.get('radius') * this.get('scaleY'); + }, + + /** + * Sets radius of an object (and updates width accordingly) + * @return {Number} + */ + setRadius: function(value) { + this.radius = value; + this.set('width', value * 2).set('height', value * 2); + }, + + /** + * Returns complexity of an instance + * @return {Number} complexity of this instance + */ + complexity: function() { + return 1; + } + }); + + /* _FROM_SVG_START_ */ + /** + * List of attribute names to account for when parsing SVG element (used by {@link fabric.Circle.fromElement}) + * @static + * @memberOf fabric.Circle + * @see: http://www.w3.org/TR/SVG/shapes.html#CircleElement + */ + fabric.Circle.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('cx cy r'.split(' ')); + + /** + * Returns {@link fabric.Circle} instance from an SVG element + * @static + * @memberOf fabric.Circle + * @param {SVGElement} element Element to parse + * @param {Object} [options] Options object + * @throws {Error} If value of `r` attribute is missing or invalid + * @return {fabric.Circle} Instance of fabric.Circle + */ + fabric.Circle.fromElement = function(element, options) { + options || (options = { }); + + var parsedAttributes = fabric.parseAttributes(element, fabric.Circle.ATTRIBUTE_NAMES); + + if (!isValidRadius(parsedAttributes)) { + throw new Error('value of `r` attribute is required and can not be negative'); + } + + parsedAttributes.left = parsedAttributes.left || 0; + parsedAttributes.top = parsedAttributes.top || 0; + + var obj = new fabric.Circle(extend(parsedAttributes, options)); + + obj.left -= obj.radius; + obj.top -= obj.radius; + return obj; + }; + + /** + * @private + */ + function isValidRadius(attributes) { + return (('radius' in attributes) && (attributes.radius >= 0)); + } + /* _FROM_SVG_END_ */ + + /** + * Returns {@link fabric.Circle} instance from an object representation + * @static + * @memberOf fabric.Circle + * @param {Object} object Object to create an instance from + * @return {Object} Instance of fabric.Circle + */ + fabric.Circle.fromObject = function(object) { + return new fabric.Circle(object); + }; + +})(typeof exports !== 'undefined' ? exports : this); + + +(function(global) { + + 'use strict'; + + var fabric = global.fabric || (global.fabric = { }); + + if (fabric.Triangle) { + fabric.warn('fabric.Triangle is already defined'); + return; + } + + /** + * Triangle class + * @class fabric.Triangle + * @extends fabric.Object + * @return {fabric.Triangle} thisArg + * @see {@link fabric.Triangle#initialize} for constructor definition + */ + fabric.Triangle = fabric.util.createClass(fabric.Object, /** @lends fabric.Triangle.prototype */ { + + /** + * Type of an object + * @type String + * @default + */ + type: 'triangle', + + /** + * Constructor + * @param {Object} [options] Options object + * @return {Object} thisArg + */ + initialize: function(options) { + options = options || { }; + + this.callSuper('initialize', options); + + this.set('width', options.width || 100) + .set('height', options.height || 100); + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _render: function(ctx) { + var widthBy2 = this.width / 2, + heightBy2 = this.height / 2; + + ctx.beginPath(); + ctx.moveTo(-widthBy2, heightBy2); + ctx.lineTo(0, -heightBy2); + ctx.lineTo(widthBy2, heightBy2); + ctx.closePath(); + + this._renderFill(ctx); + this._renderStroke(ctx); + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderDashedStroke: function(ctx) { + var widthBy2 = this.width / 2, + heightBy2 = this.height / 2; + + ctx.beginPath(); + fabric.util.drawDashedLine(ctx, -widthBy2, heightBy2, 0, -heightBy2, this.strokeDashArray); + fabric.util.drawDashedLine(ctx, 0, -heightBy2, widthBy2, heightBy2, this.strokeDashArray); + fabric.util.drawDashedLine(ctx, widthBy2, heightBy2, -widthBy2, heightBy2, this.strokeDashArray); + ctx.closePath(); + }, + + /* _TO_SVG_START_ */ + /** + * Returns SVG representation of an instance + * @param {Function} [reviver] Method for further parsing of svg representation. + * @return {String} svg representation of an instance + */ + toSVG: function(reviver) { + var markup = this._createBaseSVGMarkup(), + widthBy2 = this.width / 2, + heightBy2 = this.height / 2, + points = [ + -widthBy2 + ' ' + heightBy2, + '0 ' + -heightBy2, + widthBy2 + ' ' + heightBy2 + ] + .join(','); + + markup.push( + '' + ); + + return reviver ? reviver(markup.join('')) : markup.join(''); + }, + /* _TO_SVG_END_ */ + + /** + * Returns complexity of an instance + * @return {Number} complexity of this instance + */ + complexity: function() { + return 1; + } + }); + + /** + * Returns fabric.Triangle instance from an object representation + * @static + * @memberOf fabric.Triangle + * @param {Object} object Object to create an instance from + * @return {Object} instance of Canvas.Triangle + */ + fabric.Triangle.fromObject = function(object) { + return new fabric.Triangle(object); + }; + +})(typeof exports !== 'undefined' ? exports : this); + + +(function(global) { + + 'use strict'; + + var fabric = global.fabric || (global.fabric = { }), + piBy2 = Math.PI * 2, + extend = fabric.util.object.extend; + + if (fabric.Ellipse) { + fabric.warn('fabric.Ellipse is already defined.'); + return; + } + + /** + * Ellipse class + * @class fabric.Ellipse + * @extends fabric.Object + * @return {fabric.Ellipse} thisArg + * @see {@link fabric.Ellipse#initialize} for constructor definition + */ + fabric.Ellipse = fabric.util.createClass(fabric.Object, /** @lends fabric.Ellipse.prototype */ { + + /** + * Type of an object + * @type String + * @default + */ + type: 'ellipse', + + /** + * Horizontal radius + * @type Number + * @default + */ + rx: 0, + + /** + * Vertical radius + * @type Number + * @default + */ + ry: 0, + + /** + * Constructor + * @param {Object} [options] Options object + * @return {fabric.Ellipse} thisArg + */ + initialize: function(options) { + options = options || { }; + + this.callSuper('initialize', options); + + this.set('rx', options.rx || 0); + this.set('ry', options.ry || 0); + }, + + /** + * @private + * @param {String} key + * @param {Any} value + * @return {fabric.Ellipse} thisArg + */ + _set: function(key, value) { + this.callSuper('_set', key, value); + switch (key) { + + case 'rx': + this.rx = value; + this.set('width', value * 2); + break; + + case 'ry': + this.ry = value; + this.set('height', value * 2); + break; + + } + return this; + }, + + /** + * Returns horizontal radius of an object (according to how an object is scaled) + * @return {Number} + */ + getRx: function() { + return this.get('rx') * this.get('scaleX'); + }, + + /** + * Returns Vertical radius of an object (according to how an object is scaled) + * @return {Number} + */ + getRy: function() { + return this.get('ry') * this.get('scaleY'); + }, + + /** + * Returns object representation of an instance + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} object representation of an instance + */ + toObject: function(propertiesToInclude) { + return extend(this.callSuper('toObject', propertiesToInclude), { + rx: this.get('rx'), + ry: this.get('ry') + }); + }, + + /* _TO_SVG_START_ */ + /** + * Returns svg representation of an instance + * @param {Function} [reviver] Method for further parsing of svg representation. + * @return {String} svg representation of an instance + */ + toSVG: function(reviver) { + var markup = this._createBaseSVGMarkup(), x = 0, y = 0; + if (this.group && this.group.type === 'path-group') { + x = this.left + this.rx; + y = this.top + this.ry; + } + markup.push( + '\n' + ); + + return reviver ? reviver(markup.join('')) : markup.join(''); + }, + /* _TO_SVG_END_ */ + + /** + * @private + * @param {CanvasRenderingContext2D} ctx context to render on + * @param {Boolean} [noTransform] When true, context is not transformed + */ + _render: function(ctx, noTransform) { + ctx.beginPath(); + ctx.save(); + ctx.transform(1, 0, 0, this.ry/this.rx, 0, 0); + ctx.arc( + noTransform ? this.left + this.rx : 0, + noTransform ? (this.top + this.ry) * this.rx/this.ry : 0, + this.rx, + 0, + piBy2, + false); + ctx.restore(); + this._renderFill(ctx); + this._renderStroke(ctx); + }, + + /** + * Returns complexity of an instance + * @return {Number} complexity + */ + complexity: function() { + return 1; + } + }); + + /* _FROM_SVG_START_ */ + /** + * List of attribute names to account for when parsing SVG element (used by {@link fabric.Ellipse.fromElement}) + * @static + * @memberOf fabric.Ellipse + * @see http://www.w3.org/TR/SVG/shapes.html#EllipseElement + */ + fabric.Ellipse.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('cx cy rx ry'.split(' ')); + + /** + * Returns {@link fabric.Ellipse} instance from an SVG element + * @static + * @memberOf fabric.Ellipse + * @param {SVGElement} element Element to parse + * @param {Object} [options] Options object + * @return {fabric.Ellipse} + */ + fabric.Ellipse.fromElement = function(element, options) { + options || (options = { }); + + var parsedAttributes = fabric.parseAttributes(element, fabric.Ellipse.ATTRIBUTE_NAMES); + + parsedAttributes.left = parsedAttributes.left || 0; + parsedAttributes.top = parsedAttributes.top || 0; + + var ellipse = new fabric.Ellipse(extend(parsedAttributes, options)); + + ellipse.top -= ellipse.ry; + ellipse.left -= ellipse.rx; + return ellipse; + }; + /* _FROM_SVG_END_ */ + + /** + * Returns {@link fabric.Ellipse} instance from an object representation + * @static + * @memberOf fabric.Ellipse + * @param {Object} object Object to create an instance from + * @return {fabric.Ellipse} + */ + fabric.Ellipse.fromObject = function(object) { + return new fabric.Ellipse(object); + }; + +})(typeof exports !== 'undefined' ? exports : this); + + +(function(global) { + + 'use strict'; + + var fabric = global.fabric || (global.fabric = { }), + extend = fabric.util.object.extend; + + if (fabric.Rect) { + console.warn('fabric.Rect is already defined'); + return; + } + + var stateProperties = fabric.Object.prototype.stateProperties.concat(); + stateProperties.push('rx', 'ry', 'x', 'y'); + + /** + * Rectangle class + * @class fabric.Rect + * @extends fabric.Object + * @return {fabric.Rect} thisArg + * @see {@link fabric.Rect#initialize} for constructor definition + */ + fabric.Rect = fabric.util.createClass(fabric.Object, /** @lends fabric.Rect.prototype */ { + + /** + * List of properties to consider when checking if state of an object is changed ({@link fabric.Object#hasStateChanged}) + * as well as for history (undo/redo) purposes + * @type Array + */ + stateProperties: stateProperties, + + /** + * Type of an object + * @type String + * @default + */ + type: 'rect', + + /** + * Horizontal border radius + * @type Number + * @default + */ + rx: 0, + + /** + * Vertical border radius + * @type Number + * @default + */ + ry: 0, + + /** + * Used to specify dash pattern for stroke on this object + * @type Array + */ + strokeDashArray: null, + + /** + * Constructor + * @param {Object} [options] Options object + * @return {Object} thisArg + */ + initialize: function(options) { + options = options || { }; + + this.callSuper('initialize', options); + this._initRxRy(); + + }, + + /** + * Initializes rx/ry attributes + * @private + */ + _initRxRy: function() { + if (this.rx && !this.ry) { + this.ry = this.rx; + } + else if (this.ry && !this.rx) { + this.rx = this.ry; + } + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _render: function(ctx, noTransform) { + + // optimize 1x1 case (used in spray brush) + if (this.width === 1 && this.height === 1) { + ctx.fillRect(0, 0, 1, 1); + return; + } + + var rx = this.rx ? Math.min(this.rx, this.width / 2) : 0, + ry = this.ry ? Math.min(this.ry, this.height / 2) : 0, + w = this.width, + h = this.height, + x = noTransform ? this.left : -this.width / 2, + y = noTransform ? this.top : -this.height / 2, + isRounded = rx !== 0 || ry !== 0, + k = 1 - 0.5522847498 /* "magic number" for bezier approximations of arcs (http://itc.ktu.lt/itc354/Riskus354.pdf) */; + + ctx.beginPath(); + + ctx.moveTo(x + rx, y); + + ctx.lineTo(x + w - rx, y); + isRounded && ctx.bezierCurveTo(x + w - k * rx, y, x + w, y + k * ry, x + w, y + ry); + + ctx.lineTo(x + w, y + h - ry); + isRounded && ctx.bezierCurveTo(x + w, y + h - k * ry, x + w - k * rx, y + h, x + w - rx, y + h); + + ctx.lineTo(x + rx, y + h); + isRounded && ctx.bezierCurveTo(x + k * rx, y + h, x, y + h - k * ry, x, y + h - ry); + + ctx.lineTo(x, y + ry); + isRounded && ctx.bezierCurveTo(x, y + k * ry, x + k * rx, y, x + rx, y); + + ctx.closePath(); + + this._renderFill(ctx); + this._renderStroke(ctx); + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderDashedStroke: function(ctx) { + var x = -this.width / 2, + y = -this.height / 2, + w = this.width, + h = this.height; + + ctx.beginPath(); + fabric.util.drawDashedLine(ctx, x, y, x + w, y, this.strokeDashArray); + fabric.util.drawDashedLine(ctx, x + w, y, x + w, y + h, this.strokeDashArray); + fabric.util.drawDashedLine(ctx, x + w, y + h, x, y + h, this.strokeDashArray); + fabric.util.drawDashedLine(ctx, x, y + h, x, y, this.strokeDashArray); + ctx.closePath(); + }, + + /** + * Returns object representation of an instance + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} object representation of an instance + */ + toObject: function(propertiesToInclude) { + var object = extend(this.callSuper('toObject', propertiesToInclude), { + rx: this.get('rx') || 0, + ry: this.get('ry') || 0 + }); + if (!this.includeDefaultValues) { + this._removeDefaultValues(object); + } + return object; + }, + + /* _TO_SVG_START_ */ + /** + * Returns svg representation of an instance + * @param {Function} [reviver] Method for further parsing of svg representation. + * @return {String} svg representation of an instance + */ + toSVG: function(reviver) { + var markup = this._createBaseSVGMarkup(), x = this.left, y = this.top; + if (!(this.group && this.group.type === 'path-group')) { + x = -this.width / 2; + y = -this.height / 2; + } + markup.push( + '\n'); + + return reviver ? reviver(markup.join('')) : markup.join(''); + }, + /* _TO_SVG_END_ */ + + /** + * Returns complexity of an instance + * @return {Number} complexity + */ + complexity: function() { + return 1; + } + }); + + /* _FROM_SVG_START_ */ + /** + * List of attribute names to account for when parsing SVG element (used by `fabric.Rect.fromElement`) + * @static + * @memberOf fabric.Rect + * @see: http://www.w3.org/TR/SVG/shapes.html#RectElement + */ + fabric.Rect.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat('x y rx ry width height'.split(' ')); + + /** + * Returns {@link fabric.Rect} instance from an SVG element + * @static + * @memberOf fabric.Rect + * @param {SVGElement} element Element to parse + * @param {Object} [options] Options object + * @return {fabric.Rect} Instance of fabric.Rect + */ + fabric.Rect.fromElement = function(element, options) { + if (!element) { + return null; + } + options = options || { }; + + var parsedAttributes = fabric.parseAttributes(element, fabric.Rect.ATTRIBUTE_NAMES); + + parsedAttributes.left = parsedAttributes.left || 0; + parsedAttributes.top = parsedAttributes.top || 0; + var rect = new fabric.Rect(extend((options ? fabric.util.object.clone(options) : { }), parsedAttributes)); + rect.visible = rect.width > 0 && rect.height > 0; + return rect; + }; + /* _FROM_SVG_END_ */ + + /** + * Returns {@link fabric.Rect} instance from an object representation + * @static + * @memberOf fabric.Rect + * @param {Object} object Object to create an instance from + * @return {Object} instance of fabric.Rect + */ + fabric.Rect.fromObject = function(object) { + return new fabric.Rect(object); + }; + +})(typeof exports !== 'undefined' ? exports : this); + + +(function(global) { + + 'use strict'; + + var fabric = global.fabric || (global.fabric = { }); + + if (fabric.Polyline) { + fabric.warn('fabric.Polyline is already defined'); + return; + } + + /** + * Polyline class + * @class fabric.Polyline + * @extends fabric.Object + * @see {@link fabric.Polyline#initialize} for constructor definition + */ + fabric.Polyline = fabric.util.createClass(fabric.Object, /** @lends fabric.Polyline.prototype */ { + + /** + * Type of an object + * @type String + * @default + */ + type: 'polyline', + + /** + * Points array + * @type Array + * @default + */ + points: null, + + /** + * Minimum X from points values, necessary to offset points + * @type Number + * @default + */ + minX: 0, + + /** + * Minimum Y from points values, necessary to offset points + * @type Number + * @default + */ + minY: 0, + + /** + * Constructor + * @param {Array} points Array of points (where each point is an object with x and y) + * @param {Object} [options] Options object + * @param {Boolean} [skipOffset] Whether points offsetting should be skipped + * @return {fabric.Polyline} thisArg + * @example + * var poly = new fabric.Polyline([ + * { x: 10, y: 10 }, + * { x: 50, y: 30 }, + * { x: 40, y: 70 }, + * { x: 60, y: 50 }, + * { x: 100, y: 150 }, + * { x: 40, y: 100 } + * ], { + * stroke: 'red', + * left: 100, + * top: 100 + * }); + */ + initialize: function(points, options) { + return fabric.Polygon.prototype.initialize.call(this, points, options); + }, + + /** + * @private + */ + _calcDimensions: function() { + return fabric.Polygon.prototype._calcDimensions.call(this); + }, + + /** + * @private + */ + _applyPointOffset: function() { + return fabric.Polygon.prototype._applyPointOffset.call(this); + }, + + /** + * Returns object representation of an instance + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} Object representation of an instance + */ + toObject: function(propertiesToInclude) { + return fabric.Polygon.prototype.toObject.call(this, propertiesToInclude); + }, + + /* _TO_SVG_START_ */ + /** + * Returns SVG representation of an instance + * @param {Function} [reviver] Method for further parsing of svg representation. + * @return {String} svg representation of an instance + */ + toSVG: function(reviver) { + return fabric.Polygon.prototype.toSVG.call(this, reviver); + }, + /* _TO_SVG_END_ */ + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _render: function(ctx) { + if (!fabric.Polygon.prototype.commonRender.call(this, ctx)) { + return; + } + this._renderFill(ctx); + this._renderStroke(ctx); + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderDashedStroke: function(ctx) { + var p1, p2; + + ctx.beginPath(); + for (var i = 0, len = this.points.length; i < len; i++) { + p1 = this.points[i]; + p2 = this.points[i + 1] || p1; + fabric.util.drawDashedLine(ctx, p1.x, p1.y, p2.x, p2.y, this.strokeDashArray); + } + }, + + /** + * Returns complexity of an instance + * @return {Number} complexity of this instance + */ + complexity: function() { + return this.get('points').length; + } + }); + + /* _FROM_SVG_START_ */ + /** + * List of attribute names to account for when parsing SVG element (used by {@link fabric.Polyline.fromElement}) + * @static + * @memberOf fabric.Polyline + * @see: http://www.w3.org/TR/SVG/shapes.html#PolylineElement + */ + fabric.Polyline.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat(); + + /** + * Returns fabric.Polyline instance from an SVG element + * @static + * @memberOf fabric.Polyline + * @param {SVGElement} element Element to parse + * @param {Object} [options] Options object + * @return {fabric.Polyline} Instance of fabric.Polyline + */ + fabric.Polyline.fromElement = function(element, options) { + if (!element) { + return null; + } + options || (options = { }); + + var points = fabric.parsePointsAttribute(element.getAttribute('points')), + parsedAttributes = fabric.parseAttributes(element, fabric.Polyline.ATTRIBUTE_NAMES); + + return new fabric.Polyline(points, fabric.util.object.extend(parsedAttributes, options)); + }; + /* _FROM_SVG_END_ */ + + /** + * Returns fabric.Polyline instance from an object representation + * @static + * @memberOf fabric.Polyline + * @param {Object} object Object to create an instance from + * @return {fabric.Polyline} Instance of fabric.Polyline + */ + fabric.Polyline.fromObject = function(object) { + var points = object.points; + return new fabric.Polyline(points, object, true); + }; + +})(typeof exports !== 'undefined' ? exports : this); + + +(function(global) { + + 'use strict'; + + var fabric = global.fabric || (global.fabric = { }), + extend = fabric.util.object.extend, + min = fabric.util.array.min, + max = fabric.util.array.max, + toFixed = fabric.util.toFixed; + + if (fabric.Polygon) { + fabric.warn('fabric.Polygon is already defined'); + return; + } + + /** + * Polygon class + * @class fabric.Polygon + * @extends fabric.Object + * @see {@link fabric.Polygon#initialize} for constructor definition + */ + fabric.Polygon = fabric.util.createClass(fabric.Object, /** @lends fabric.Polygon.prototype */ { + + /** + * Type of an object + * @type String + * @default + */ + type: 'polygon', + + /** + * Points array + * @type Array + * @default + */ + points: null, + + /** + * Minimum X from points values, necessary to offset points + * @type Number + * @default + */ + minX: 0, + + /** + * Minimum Y from points values, necessary to offset points + * @type Number + * @default + */ + minY: 0, + + /** + * Constructor + * @param {Array} points Array of points + * @param {Object} [options] Options object + * @return {fabric.Polygon} thisArg + */ + initialize: function(points, options) { + options = options || { }; + this.points = points || [ ]; + this.callSuper('initialize', options); + this._calcDimensions(); + if (!('top' in options)) { + this.top = this.minY; + } + if (!('left' in options)) { + this.left = this.minX; + } + }, + + /** + * @private + */ + _calcDimensions: function() { + + var points = this.points, + minX = min(points, 'x'), + minY = min(points, 'y'), + maxX = max(points, 'x'), + maxY = max(points, 'y'); + + this.width = (maxX - minX) || 0; + this.height = (maxY - minY) || 0; + + this.minX = minX || 0, + this.minY = minY || 0; + }, + + /** + * @private + */ + _applyPointOffset: function() { + // change points to offset polygon into a bounding box + // executed one time + this.points.forEach(function(p) { + p.x -= (this.minX + this.width / 2); + p.y -= (this.minY + this.height / 2); + }, this); + }, + + /** + * Returns object representation of an instance + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} Object representation of an instance + */ + toObject: function(propertiesToInclude) { + return extend(this.callSuper('toObject', propertiesToInclude), { + points: this.points.concat() + }); + }, + + /* _TO_SVG_START_ */ + /** + * Returns svg representation of an instance + * @param {Function} [reviver] Method for further parsing of svg representation. + * @return {String} svg representation of an instance + */ + toSVG: function(reviver) { + var points = [], + markup = this._createBaseSVGMarkup(); + + for (var i = 0, len = this.points.length; i < len; i++) { + points.push(toFixed(this.points[i].x, 2), ',', toFixed(this.points[i].y, 2), ' '); + } + + markup.push( + '<', this.type, ' ', + 'points="', points.join(''), + '" style="', this.getSvgStyles(), + '" transform="', this.getSvgTransform(), + ' ', this.getSvgTransformMatrix(), + '"/>\n' + ); + + return reviver ? reviver(markup.join('')) : markup.join(''); + }, + /* _TO_SVG_END_ */ + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _render: function(ctx) { + if (!this.commonRender(ctx)) { + return; + } + this._renderFill(ctx); + if (this.stroke || this.strokeDashArray) { + ctx.closePath(); + this._renderStroke(ctx); + } + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + commonRender: function(ctx) { + var point, len = this.points.length; + + if (!len || isNaN(this.points[len - 1].y)) { + // do not draw if no points or odd points + // NaN comes from parseFloat of a empty string in parser + return false; + } + + ctx.beginPath(); + + if (this._applyPointOffset) { + if (!(this.group && this.group.type === 'path-group')) { + this._applyPointOffset(); + } + this._applyPointOffset = null; + } + + ctx.moveTo(this.points[0].x, this.points[0].y); + for (var i = 0; i < len; i++) { + point = this.points[i]; + ctx.lineTo(point.x, point.y); + } + return true; + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderDashedStroke: function(ctx) { + fabric.Polyline.prototype._renderDashedStroke.call(this, ctx); + ctx.closePath(); + }, + + /** + * Returns complexity of an instance + * @return {Number} complexity of this instance + */ + complexity: function() { + return this.points.length; + } + }); + + /* _FROM_SVG_START_ */ + /** + * List of attribute names to account for when parsing SVG element (used by `fabric.Polygon.fromElement`) + * @static + * @memberOf fabric.Polygon + * @see: http://www.w3.org/TR/SVG/shapes.html#PolygonElement + */ + fabric.Polygon.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat(); + + /** + * Returns {@link fabric.Polygon} instance from an SVG element + * @static + * @memberOf fabric.Polygon + * @param {SVGElement} element Element to parse + * @param {Object} [options] Options object + * @return {fabric.Polygon} Instance of fabric.Polygon + */ + fabric.Polygon.fromElement = function(element, options) { + if (!element) { + return null; + } + + options || (options = { }); + + var points = fabric.parsePointsAttribute(element.getAttribute('points')), + parsedAttributes = fabric.parseAttributes(element, fabric.Polygon.ATTRIBUTE_NAMES); + + return new fabric.Polygon(points, extend(parsedAttributes, options)); + }; + /* _FROM_SVG_END_ */ + + /** + * Returns fabric.Polygon instance from an object representation + * @static + * @memberOf fabric.Polygon + * @param {Object} object Object to create an instance from + * @return {fabric.Polygon} Instance of fabric.Polygon + */ + fabric.Polygon.fromObject = function(object) { + return new fabric.Polygon(object.points, object, true); + }; + +})(typeof exports !== 'undefined' ? exports : this); + + +(function(global) { + + 'use strict'; + + var fabric = global.fabric || (global.fabric = { }), + min = fabric.util.array.min, + max = fabric.util.array.max, + extend = fabric.util.object.extend, + _toString = Object.prototype.toString, + drawArc = fabric.util.drawArc, + commandLengths = { + m: 2, + l: 2, + h: 1, + v: 1, + c: 6, + s: 4, + q: 4, + t: 2, + a: 7 + }, + repeatedCommands = { + m: 'l', + M: 'L' + }; + + if (fabric.Path) { + fabric.warn('fabric.Path is already defined'); + return; + } + + /** + * Path class + * @class fabric.Path + * @extends fabric.Object + * @tutorial {@link http://fabricjs.com/fabric-intro-part-1/#path_and_pathgroup} + * @see {@link fabric.Path#initialize} for constructor definition + */ + fabric.Path = fabric.util.createClass(fabric.Object, /** @lends fabric.Path.prototype */ { + + /** + * Type of an object + * @type String + * @default + */ + type: 'path', + + /** + * Array of path points + * @type Array + * @default + */ + path: null, + + /** + * Minimum X from points values, necessary to offset points + * @type Number + * @default + */ + minX: 0, + + /** + * Minimum Y from points values, necessary to offset points + * @type Number + * @default + */ + minY: 0, + + /** + * Constructor + * @param {Array|String} path Path data (sequence of coordinates and corresponding "command" tokens) + * @param {Object} [options] Options object + * @return {fabric.Path} thisArg + */ + initialize: function(path, options) { + options = options || { }; + + this.setOptions(options); + + if (!path) { + throw new Error('`path` argument is required'); + } + + var fromArray = _toString.call(path) === '[object Array]'; + + this.path = fromArray + ? path + // one of commands (m,M,l,L,q,Q,c,C,etc.) followed by non-command characters (i.e. command values) + : path.match && path.match(/[mzlhvcsqta][^mzlhvcsqta]*/gi); + + if (!this.path) { + return; + } + + if (!fromArray) { + this.path = this._parsePath(); + } + + this._setPositionDimensions(); + + if (options.sourcePath) { + this.setSourcePath(options.sourcePath); + } + }, + + /** + * @private + */ + _setPositionDimensions: function() { + var calcDim = this._parseDimensions(); + + this.minX = calcDim.left; + this.minY = calcDim.top; + this.width = calcDim.width; + this.height = calcDim.height; + + calcDim.left += this.originX === 'center' + ? this.width / 2 + : this.originX === 'right' + ? this.width + : 0; + + calcDim.top += this.originY === 'center' + ? this.height / 2 + : this.originY === 'bottom' + ? this.height + : 0; + + this.top = this.top || calcDim.top; + this.left = this.left || calcDim.left; + + this.pathOffset = this.pathOffset || { + x: this.minX + this.width / 2, + y: this.minY + this.height / 2 + }; + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx context to render path on + */ + _render: function(ctx) { + var current, // current instruction + previous = null, + subpathStartX = 0, + subpathStartY = 0, + x = 0, // current x + y = 0, // current y + controlX = 0, // current control point x + controlY = 0, // current control point y + tempX, + tempY, + l = -this.pathOffset.x, + t = -this.pathOffset.y; + + if (this.group && this.group.type === 'path-group') { + l = 0; + t = 0; + } + + ctx.beginPath(); + + for (var i = 0, len = this.path.length; i < len; ++i) { + + current = this.path[i]; + + switch (current[0]) { // first letter + + case 'l': // lineto, relative + x += current[1]; + y += current[2]; + ctx.lineTo(x + l, y + t); + break; + + case 'L': // lineto, absolute + x = current[1]; + y = current[2]; + ctx.lineTo(x + l, y + t); + break; + + case 'h': // horizontal lineto, relative + x += current[1]; + ctx.lineTo(x + l, y + t); + break; + + case 'H': // horizontal lineto, absolute + x = current[1]; + ctx.lineTo(x + l, y + t); + break; + + case 'v': // vertical lineto, relative + y += current[1]; + ctx.lineTo(x + l, y + t); + break; + + case 'V': // verical lineto, absolute + y = current[1]; + ctx.lineTo(x + l, y + t); + break; + + case 'm': // moveTo, relative + x += current[1]; + y += current[2]; + subpathStartX = x; + subpathStartY = y; + ctx.moveTo(x + l, y + t); + break; + + case 'M': // moveTo, absolute + x = current[1]; + y = current[2]; + subpathStartX = x; + subpathStartY = y; + ctx.moveTo(x + l, y + t); + break; + + case 'c': // bezierCurveTo, relative + tempX = x + current[5]; + tempY = y + current[6]; + controlX = x + current[3]; + controlY = y + current[4]; + ctx.bezierCurveTo( + x + current[1] + l, // x1 + y + current[2] + t, // y1 + controlX + l, // x2 + controlY + t, // y2 + tempX + l, + tempY + t + ); + x = tempX; + y = tempY; + break; + + case 'C': // bezierCurveTo, absolute + x = current[5]; + y = current[6]; + controlX = current[3]; + controlY = current[4]; + ctx.bezierCurveTo( + current[1] + l, + current[2] + t, + controlX + l, + controlY + t, + x + l, + y + t + ); + break; + + case 's': // shorthand cubic bezierCurveTo, relative + + // transform to absolute x,y + tempX = x + current[3]; + tempY = y + current[4]; + + if (previous[0].match(/[CcSs]/) === null) { + // If there is no previous command or if the previous command was not a C, c, S, or s, + // the control point is coincident with the current point + controlX = x; + controlY = y; + } + else { + // calculate reflection of previous control points + controlX = 2 * x - controlX; + controlY = 2 * y - controlY; + } + + ctx.bezierCurveTo( + controlX + l, + controlY + t, + x + current[1] + l, + y + current[2] + t, + tempX + l, + tempY + t + ); + // set control point to 2nd one of this command + // "... the first control point is assumed to be + // the reflection of the second control point on + // the previous command relative to the current point." + controlX = x + current[1]; + controlY = y + current[2]; + + x = tempX; + y = tempY; + break; + + case 'S': // shorthand cubic bezierCurveTo, absolute + tempX = current[3]; + tempY = current[4]; + if (previous[0].match(/[CcSs]/) === null) { + // If there is no previous command or if the previous command was not a C, c, S, or s, + // the control point is coincident with the current point + controlX = x; + controlY = y; + } + else { + // calculate reflection of previous control points + controlX = 2 * x - controlX; + controlY = 2 * y - controlY; + } + ctx.bezierCurveTo( + controlX + l, + controlY + t, + current[1] + l, + current[2] + t, + tempX + l, + tempY + t + ); + x = tempX; + y = tempY; + + // set control point to 2nd one of this command + // "... the first control point is assumed to be + // the reflection of the second control point on + // the previous command relative to the current point." + controlX = current[1]; + controlY = current[2]; + + break; + + case 'q': // quadraticCurveTo, relative + // transform to absolute x,y + tempX = x + current[3]; + tempY = y + current[4]; + + controlX = x + current[1]; + controlY = y + current[2]; + + ctx.quadraticCurveTo( + controlX + l, + controlY + t, + tempX + l, + tempY + t + ); + x = tempX; + y = tempY; + break; + + case 'Q': // quadraticCurveTo, absolute + tempX = current[3]; + tempY = current[4]; + + ctx.quadraticCurveTo( + current[1] + l, + current[2] + t, + tempX + l, + tempY + t + ); + x = tempX; + y = tempY; + controlX = current[1]; + controlY = current[2]; + break; + + case 't': // shorthand quadraticCurveTo, relative + + // transform to absolute x,y + tempX = x + current[1]; + tempY = y + current[2]; + + if (previous[0].match(/[QqTt]/) === null) { + // If there is no previous command or if the previous command was not a Q, q, T or t, + // assume the control point is coincident with the current point + controlX = x; + controlY = y; + } + else { + // calculate reflection of previous control point + controlX = 2 * x - controlX; + controlY = 2 * y - controlY; + } + + ctx.quadraticCurveTo( + controlX + l, + controlY + t, + tempX + l, + tempY + t + ); + x = tempX; + y = tempY; + + break; + + case 'T': + tempX = current[1]; + tempY = current[2]; + + if (previous[0].match(/[QqTt]/) === null) { + // If there is no previous command or if the previous command was not a Q, q, T or t, + // assume the control point is coincident with the current point + controlX = x; + controlY = y; + } + else { + // calculate reflection of previous control point + controlX = 2 * x - controlX; + controlY = 2 * y - controlY; + } + ctx.quadraticCurveTo( + controlX + l, + controlY + t, + tempX + l, + tempY + t + ); + x = tempX; + y = tempY; + break; + + case 'a': + // TODO: optimize this + drawArc(ctx, x + l, y + t, [ + current[1], + current[2], + current[3], + current[4], + current[5], + current[6] + x + l, + current[7] + y + t + ]); + x += current[6]; + y += current[7]; + break; + + case 'A': + // TODO: optimize this + drawArc(ctx, x + l, y + t, [ + current[1], + current[2], + current[3], + current[4], + current[5], + current[6] + l, + current[7] + t + ]); + x = current[6]; + y = current[7]; + break; + + case 'z': + case 'Z': + x = subpathStartX; + y = subpathStartY; + ctx.closePath(); + break; + } + previous = current; + } + this._renderFill(ctx); + this._renderStroke(ctx); + }, + + /** + * Returns string representation of an instance + * @return {String} string representation of an instance + */ + toString: function() { + return '#'; + }, + + /** + * Returns object representation of an instance + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} object representation of an instance + */ + toObject: function(propertiesToInclude) { + var o = extend(this.callSuper('toObject', propertiesToInclude), { + path: this.path.map(function(item) { return item.slice() }), + pathOffset: this.pathOffset + }); + if (this.sourcePath) { + o.sourcePath = this.sourcePath; + } + if (this.transformMatrix) { + o.transformMatrix = this.transformMatrix; + } + return o; + }, + + /** + * Returns dataless object representation of an instance + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} object representation of an instance + */ + toDatalessObject: function(propertiesToInclude) { + var o = this.toObject(propertiesToInclude); + if (this.sourcePath) { + o.path = this.sourcePath; + } + delete o.sourcePath; + return o; + }, + + /* _TO_SVG_START_ */ + /** + * Returns svg representation of an instance + * @param {Function} [reviver] Method for further parsing of svg representation. + * @return {String} svg representation of an instance + */ + toSVG: function(reviver) { + var chunks = [], + markup = this._createBaseSVGMarkup(), addTransform = ''; + + for (var i = 0, len = this.path.length; i < len; i++) { + chunks.push(this.path[i].join(' ')); + } + var path = chunks.join(' '); + if (!(this.group && this.group.type === 'path-group')) { + addTransform = ' translate(' + (-this.pathOffset.x) + ', ' + (-this.pathOffset.y) + ') '; + } + markup.push( + //jscs:disable validateIndentation + '\n' + //jscs:enable validateIndentation + ); + + return reviver ? reviver(markup.join('')) : markup.join(''); + }, + /* _TO_SVG_END_ */ + + /** + * Returns number representation of an instance complexity + * @return {Number} complexity of this instance + */ + complexity: function() { + return this.path.length; + }, + + /** + * @private + */ + _parsePath: function() { + var result = [ ], + coords = [ ], + currentPath, + parsed, + re = /([-+]?((\d+\.\d+)|((\d+)|(\.\d+)))(?:e[-+]?\d+)?)/ig, + match, + coordsStr; + + for (var i = 0, coordsParsed, len = this.path.length; i < len; i++) { + currentPath = this.path[i]; + + coordsStr = currentPath.slice(1).trim(); + coords.length = 0; + + while ((match = re.exec(coordsStr))) { + coords.push(match[0]); + } + + coordsParsed = [ currentPath.charAt(0) ]; + + for (var j = 0, jlen = coords.length; j < jlen; j++) { + parsed = parseFloat(coords[j]); + if (!isNaN(parsed)) { + coordsParsed.push(parsed); + } + } + + var command = coordsParsed[0], + commandLength = commandLengths[command.toLowerCase()], + repeatedCommand = repeatedCommands[command] || command; + + if (coordsParsed.length - 1 > commandLength) { + for (var k = 1, klen = coordsParsed.length; k < klen; k += commandLength) { + result.push([ command ].concat(coordsParsed.slice(k, k + commandLength))); + command = repeatedCommand; + } + } + else { + result.push(coordsParsed); + } + } + + return result; + }, + + /** + * @private + */ + _parseDimensions: function() { + + var aX = [], + aY = [], + current, // current instruction + previous = null, + subpathStartX = 0, + subpathStartY = 0, + x = 0, // current x + y = 0, // current y + controlX = 0, // current control point x + controlY = 0, // current control point y + tempX, + tempY, + bounds; + + for (var i = 0, len = this.path.length; i < len; ++i) { + + current = this.path[i]; + + switch (current[0]) { // first letter + + case 'l': // lineto, relative + x += current[1]; + y += current[2]; + bounds = [ ]; + break; + + case 'L': // lineto, absolute + x = current[1]; + y = current[2]; + bounds = [ ]; + break; + + case 'h': // horizontal lineto, relative + x += current[1]; + bounds = [ ]; + break; + + case 'H': // horizontal lineto, absolute + x = current[1]; + bounds = [ ]; + break; + + case 'v': // vertical lineto, relative + y += current[1]; + bounds = [ ]; + break; + + case 'V': // verical lineto, absolute + y = current[1]; + bounds = [ ]; + break; + + case 'm': // moveTo, relative + x += current[1]; + y += current[2]; + subpathStartX = x; + subpathStartY = y; + bounds = [ ]; + break; + + case 'M': // moveTo, absolute + x = current[1]; + y = current[2]; + subpathStartX = x; + subpathStartY = y; + bounds = [ ]; + break; + + case 'c': // bezierCurveTo, relative + tempX = x + current[5]; + tempY = y + current[6]; + controlX = x + current[3]; + controlY = y + current[4]; + bounds = fabric.util.getBoundsOfCurve(x, y, + x + current[1], // x1 + y + current[2], // y1 + controlX, // x2 + controlY, // y2 + tempX, + tempY + ); + x = tempX; + y = tempY; + break; + + case 'C': // bezierCurveTo, absolute + x = current[5]; + y = current[6]; + controlX = current[3]; + controlY = current[4]; + bounds = fabric.util.getBoundsOfCurve(x, y, + current[1], + current[2], + controlX, + controlY, + x, + y + ); + break; + + case 's': // shorthand cubic bezierCurveTo, relative + + // transform to absolute x,y + tempX = x + current[3]; + tempY = y + current[4]; + + if (previous[0].match(/[CcSs]/) === null) { + // If there is no previous command or if the previous command was not a C, c, S, or s, + // the control point is coincident with the current point + controlX = x; + controlY = y; + } + else { + // calculate reflection of previous control points + controlX = 2 * x - controlX; + controlY = 2 * y - controlY; + } + + bounds = fabric.util.getBoundsOfCurve(x, y, + controlX, + controlY, + x + current[1], + y + current[2], + tempX, + tempY + ); + // set control point to 2nd one of this command + // "... the first control point is assumed to be + // the reflection of the second control point on + // the previous command relative to the current point." + controlX = x + current[1]; + controlY = y + current[2]; + x = tempX; + y = tempY; + break; + + case 'S': // shorthand cubic bezierCurveTo, absolute + tempX = current[3]; + tempY = current[4]; + if (previous[0].match(/[CcSs]/) === null) { + // If there is no previous command or if the previous command was not a C, c, S, or s, + // the control point is coincident with the current point + controlX = x; + controlY = y; + } + else { + // calculate reflection of previous control points + controlX = 2 * x - controlX; + controlY = 2 * y - controlY; + } + bounds = fabric.util.getBoundsOfCurve(x, y, + controlX, + controlY, + current[1], + current[2], + tempX, + tempY + ); + x = tempX; + y = tempY; + // set control point to 2nd one of this command + // "... the first control point is assumed to be + // the reflection of the second control point on + // the previous command relative to the current point." + controlX = current[1]; + controlY = current[2]; + break; + + case 'q': // quadraticCurveTo, relative + // transform to absolute x,y + tempX = x + current[3]; + tempY = y + current[4]; + controlX = x + current[1]; + controlY = y + current[2]; + bounds = fabric.util.getBoundsOfCurve(x, y, + controlX, + controlY, + controlX, + controlY, + tempX, + tempY + ); + x = tempX; + y = tempY; + break; + + case 'Q': // quadraticCurveTo, absolute + controlX = current[1]; + controlY = current[2]; + bounds = fabric.util.getBoundsOfCurve(x, y, + controlX, + controlY, + controlX, + controlY, + current[3], + current[4] + ); + x = current[3]; + y = current[4]; + break; + + case 't': // shorthand quadraticCurveTo, relative + // transform to absolute x,y + tempX = x + current[1]; + tempY = y + current[2]; + if (previous[0].match(/[QqTt]/) === null) { + // If there is no previous command or if the previous command was not a Q, q, T or t, + // assume the control point is coincident with the current point + controlX = x; + controlY = y; + } + else { + // calculate reflection of previous control point + controlX = 2 * x - controlX; + controlY = 2 * y - controlY; + } + + bounds = fabric.util.getBoundsOfCurve(x, y, + controlX, + controlY, + controlX, + controlY, + tempX, + tempY + ); + x = tempX; + y = tempY; + + break; + + case 'T': + tempX = current[1]; + tempY = current[2]; + + if (previous[0].match(/[QqTt]/) === null) { + // If there is no previous command or if the previous command was not a Q, q, T or t, + // assume the control point is coincident with the current point + controlX = x; + controlY = y; + } + else { + // calculate reflection of previous control point + controlX = 2 * x - controlX; + controlY = 2 * y - controlY; + } + bounds = fabric.util.getBoundsOfCurve(x, y, + controlX, + controlY, + controlX, + controlY, + tempX, + tempY + ); + x = tempX; + y = tempY; + break; + + case 'a': + // TODO: optimize this + bounds = fabric.util.getBoundsOfArc(x, y, + current[1], + current[2], + current[3], + current[4], + current[5], + current[6] + x, + current[7] + y + ); + x += current[6]; + y += current[7]; + break; + + case 'A': + // TODO: optimize this + bounds = fabric.util.getBoundsOfArc(x, y, + current[1], + current[2], + current[3], + current[4], + current[5], + current[6], + current[7] + ); + x = current[6]; + y = current[7]; + break; + + case 'z': + case 'Z': + x = subpathStartX; + y = subpathStartY; + break; + } + previous = current; + bounds.forEach(function (point) { + aX.push(point.x); + aY.push(point.y); + }); + aX.push(x); + aY.push(y); + } + + var minX = min(aX), + minY = min(aY), + maxX = max(aX), + maxY = max(aY), + deltaX = maxX - minX, + deltaY = maxY - minY, + + o = { + left: minX, + top: minY, + width: deltaX, + height: deltaY + }; + + return o; + } + }); + + /** + * Creates an instance of fabric.Path from an object + * @static + * @memberOf fabric.Path + * @param {Object} object + * @param {Function} callback Callback to invoke when an fabric.Path instance is created + */ + fabric.Path.fromObject = function(object, callback) { + if (typeof object.path === 'string') { + fabric.loadSVGFromURL(object.path, function (elements) { + var path = elements[0], + pathUrl = object.path; + + delete object.path; + + fabric.util.object.extend(path, object); + path.setSourcePath(pathUrl); + + callback(path); + }); + } + else { + callback(new fabric.Path(object.path, object)); + } + }; + + /* _FROM_SVG_START_ */ + /** + * List of attribute names to account for when parsing SVG element (used by `fabric.Path.fromElement`) + * @static + * @memberOf fabric.Path + * @see http://www.w3.org/TR/SVG/paths.html#PathElement + */ + fabric.Path.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat(['d']); + + /** + * Creates an instance of fabric.Path from an SVG element + * @static + * @memberOf fabric.Path + * @param {SVGElement} element to parse + * @param {Function} callback Callback to invoke when an fabric.Path instance is created + * @param {Object} [options] Options object + */ + fabric.Path.fromElement = function(element, callback, options) { + var parsedAttributes = fabric.parseAttributes(element, fabric.Path.ATTRIBUTE_NAMES); + callback && callback(new fabric.Path(parsedAttributes.d, extend(parsedAttributes, options))); + }; + /* _FROM_SVG_END_ */ + + /** + * Indicates that instances of this type are async + * @static + * @memberOf fabric.Path + * @type Boolean + * @default + */ + fabric.Path.async = true; + +})(typeof exports !== 'undefined' ? exports : this); + + +(function(global) { + + 'use strict'; + + var fabric = global.fabric || (global.fabric = { }), + extend = fabric.util.object.extend, + invoke = fabric.util.array.invoke, + parentToObject = fabric.Object.prototype.toObject; + + if (fabric.PathGroup) { + fabric.warn('fabric.PathGroup is already defined'); + return; + } + + /** + * Path group class + * @class fabric.PathGroup + * @extends fabric.Path + * @tutorial {@link http://fabricjs.com/fabric-intro-part-1/#path_and_pathgroup} + * @see {@link fabric.PathGroup#initialize} for constructor definition + */ + fabric.PathGroup = fabric.util.createClass(fabric.Path, /** @lends fabric.PathGroup.prototype */ { + + /** + * Type of an object + * @type String + * @default + */ + type: 'path-group', + + /** + * Fill value + * @type String + * @default + */ + fill: '', + + /** + * Constructor + * @param {Array} paths + * @param {Object} [options] Options object + * @return {fabric.PathGroup} thisArg + */ + initialize: function(paths, options) { + + options = options || { }; + this.paths = paths || [ ]; + + for (var i = this.paths.length; i--;) { + this.paths[i].group = this; + } + + if (options.toBeParsed) { + this.parseDimensionsFromPaths(options); + delete options.toBeParsed; + } + this.setOptions(options); + this.setCoords(); + + if (options.sourcePath) { + this.setSourcePath(options.sourcePath); + } + }, + + /** + * Calculate width and height based on paths contained + */ + parseDimensionsFromPaths: function(options) { + var points, p, xC = [ ], yC = [ ], path, height, width, + m = this.transformMatrix; + for (var j = this.paths.length; j--;) { + path = this.paths[j]; + height = path.height + path.strokeWidth; + width = path.width + path.strokeWidth; + points = [ + { x: path.left, y: path.top }, + { x: path.left + width, y: path.top }, + { x: path.left, y: path.top + height }, + { x: path.left + width, y: path.top + height } + ]; + for (var i = 0; i < points.length; i++) { + p = points[i]; + if (m) { + p = fabric.util.transformPoint(p, m, false); + } + xC.push(p.x); + yC.push(p.y); + } + } + options.width = Math.max.apply(null, xC); + options.height = Math.max.apply(null, yC); + }, + + /** + * Renders this group on a specified context + * @param {CanvasRenderingContext2D} ctx Context to render this instance on + */ + render: function(ctx) { + // do not render if object is not visible + if (!this.visible) { + return; + } + + ctx.save(); + + if (this.transformMatrix) { + ctx.transform.apply(ctx, this.transformMatrix); + } + this.transform(ctx); + + this._setShadow(ctx); + this.clipTo && fabric.util.clipContext(this, ctx); + ctx.translate(-this.width/2, -this.height/2); + for (var i = 0, l = this.paths.length; i < l; ++i) { + this.paths[i].render(ctx, true); + } + this.clipTo && ctx.restore(); + this._removeShadow(ctx); + ctx.restore(); + }, + + /** + * Sets certain property to a certain value + * @param {String} prop + * @param {Any} value + * @return {fabric.PathGroup} thisArg + */ + _set: function(prop, value) { + + if (prop === 'fill' && value && this.isSameColor()) { + var i = this.paths.length; + while (i--) { + this.paths[i]._set(prop, value); + } + } + + return this.callSuper('_set', prop, value); + }, + + /** + * Returns object representation of this path group + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} object representation of an instance + */ + toObject: function(propertiesToInclude) { + var o = extend(parentToObject.call(this, propertiesToInclude), { + paths: invoke(this.getObjects(), 'toObject', propertiesToInclude) + }); + if (this.sourcePath) { + o.sourcePath = this.sourcePath; + } + return o; + }, + + /** + * Returns dataless object representation of this path group + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} dataless object representation of an instance + */ + toDatalessObject: function(propertiesToInclude) { + var o = this.toObject(propertiesToInclude); + if (this.sourcePath) { + o.paths = this.sourcePath; + } + return o; + }, + + /* _TO_SVG_START_ */ + /** + * Returns svg representation of an instance + * @param {Function} [reviver] Method for further parsing of svg representation. + * @return {String} svg representation of an instance + */ + toSVG: function(reviver) { + var objects = this.getObjects(), + p = this.getPointByOrigin('left', 'top'), + translatePart = 'translate(' + p.x + ' ' + p.y + ')', + markup = [ + //jscs:disable validateIndentation + '\n' + //jscs:enable validateIndentation + ]; + + for (var i = 0, len = objects.length; i < len; i++) { + markup.push(objects[i].toSVG(reviver)); + } + markup.push('\n'); + + return reviver ? reviver(markup.join('')) : markup.join(''); + }, + /* _TO_SVG_END_ */ + + /** + * Returns a string representation of this path group + * @return {String} string representation of an object + */ + toString: function() { + return '#'; + }, + + /** + * Returns true if all paths in this group are of same color + * @return {Boolean} true if all paths are of the same color (`fill`) + */ + isSameColor: function() { + var firstPathFill = (this.getObjects()[0].get('fill') || '').toLowerCase(); + return this.getObjects().every(function(path) { + return (path.get('fill') || '').toLowerCase() === firstPathFill; + }); + }, + + /** + * Returns number representation of object's complexity + * @return {Number} complexity + */ + complexity: function() { + return this.paths.reduce(function(total, path) { + return total + ((path && path.complexity) ? path.complexity() : 0); + }, 0); + }, + + /** + * Returns all paths in this path group + * @return {Array} array of path objects included in this path group + */ + getObjects: function() { + return this.paths; + } + }); + + /** + * Creates fabric.PathGroup instance from an object representation + * @static + * @memberOf fabric.PathGroup + * @param {Object} object Object to create an instance from + * @param {Function} callback Callback to invoke when an fabric.PathGroup instance is created + */ + fabric.PathGroup.fromObject = function(object, callback) { + if (typeof object.paths === 'string') { + fabric.loadSVGFromURL(object.paths, function (elements) { + + var pathUrl = object.paths; + delete object.paths; + + var pathGroup = fabric.util.groupSVGElements(elements, object, pathUrl); + + callback(pathGroup); + }); + } + else { + fabric.util.enlivenObjects(object.paths, function(enlivenedObjects) { + delete object.paths; + callback(new fabric.PathGroup(enlivenedObjects, object)); + }); + } + }; + + /** + * Indicates that instances of this type are async + * @static + * @memberOf fabric.PathGroup + * @type Boolean + * @default + */ + fabric.PathGroup.async = true; + +})(typeof exports !== 'undefined' ? exports : this); + + +(function(global) { + + 'use strict'; + + var fabric = global.fabric || (global.fabric = { }), + extend = fabric.util.object.extend, + min = fabric.util.array.min, + max = fabric.util.array.max, + invoke = fabric.util.array.invoke; + + if (fabric.Group) { + return; + } + + // lock-related properties, for use in fabric.Group#get + // to enable locking behavior on group + // when one of its objects has lock-related properties set + var _lockProperties = { + lockMovementX: true, + lockMovementY: true, + lockRotation: true, + lockScalingX: true, + lockScalingY: true, + lockUniScaling: true + }; + + /** + * Group class + * @class fabric.Group + * @extends fabric.Object + * @mixes fabric.Collection + * @tutorial {@link http://fabricjs.com/fabric-intro-part-3/#groups} + * @see {@link fabric.Group#initialize} for constructor definition + */ + fabric.Group = fabric.util.createClass(fabric.Object, fabric.Collection, /** @lends fabric.Group.prototype */ { + + /** + * Type of an object + * @type String + * @default + */ + type: 'group', + + /** + * Constructor + * @param {Object} objects Group objects + * @param {Object} [options] Options object + * @return {Object} thisArg + */ + initialize: function(objects, options) { + options = options || { }; + + this._objects = objects || []; + for (var i = this._objects.length; i--; ) { + this._objects[i].group = this; + } + + this.originalState = { }; + this.callSuper('initialize'); + + if (options.originX) { + this.originX = options.originX; + } + + if (options.originY) { + this.originY = options.originY; + } + + this._calcBounds(); + this._updateObjectsCoords(); + + this.callSuper('initialize', options); + + this.setCoords(); + this.saveCoords(); + }, + + /** + * @private + */ + _updateObjectsCoords: function() { + this.forEachObject(this._updateObjectCoords, this); + }, + + /** + * @private + */ + _updateObjectCoords: function(object) { + var objectLeft = object.getLeft(), + objectTop = object.getTop(), + center = this.getCenterPoint(); + + object.set({ + originalLeft: objectLeft, + originalTop: objectTop, + left: objectLeft - center.x, + top: objectTop - center.y + }); + + object.setCoords(); + + // do not display corners of objects enclosed in a group + object.__origHasControls = object.hasControls; + object.hasControls = false; + }, + + /** + * Returns string represenation of a group + * @return {String} + */ + toString: function() { + return '#'; + }, + + /** + * Adds an object to a group; Then recalculates group's dimension, position. + * @param {Object} object + * @return {fabric.Group} thisArg + * @chainable + */ + addWithUpdate: function(object) { + this._restoreObjectsState(); + if (object) { + this._objects.push(object); + object.group = this; + } + // since _restoreObjectsState set objects inactive + this.forEachObject(this._setObjectActive, this); + this._calcBounds(); + this._updateObjectsCoords(); + return this; + }, + + /** + * @private + */ + _setObjectActive: function(object) { + object.set('active', true); + object.group = this; + }, + + /** + * Removes an object from a group; Then recalculates group's dimension, position. + * @param {Object} object + * @return {fabric.Group} thisArg + * @chainable + */ + removeWithUpdate: function(object) { + this._moveFlippedObject(object); + this._restoreObjectsState(); + + // since _restoreObjectsState set objects inactive + this.forEachObject(this._setObjectActive, this); + + this.remove(object); + this._calcBounds(); + this._updateObjectsCoords(); + + return this; + }, + + /** + * @private + */ + _onObjectAdded: function(object) { + object.group = this; + }, + + /** + * @private + */ + _onObjectRemoved: function(object) { + delete object.group; + object.set('active', false); + }, + + /** + * Properties that are delegated to group objects when reading/writing + * @param {Object} delegatedProperties + */ + delegatedProperties: { + fill: true, + opacity: true, + fontFamily: true, + fontWeight: true, + fontSize: true, + fontStyle: true, + lineHeight: true, + textDecoration: true, + textAlign: true, + backgroundColor: true + }, + + /** + * @private + */ + _set: function(key, value) { + if (key in this.delegatedProperties) { + var i = this._objects.length; + while (i--) { + this._objects[i].set(key, value); + } + } + this.callSuper('_set', key, value); + }, + + /** + * Returns object representation of an instance + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} object representation of an instance + */ + toObject: function(propertiesToInclude) { + return extend(this.callSuper('toObject', propertiesToInclude), { + objects: invoke(this._objects, 'toObject', propertiesToInclude) + }); + }, + + /** + * Renders instance on a given context + * @param {CanvasRenderingContext2D} ctx context to render instance on + */ + render: function(ctx) { + // do not render if object is not visible + if (!this.visible) { + return; + } + + ctx.save(); + this.clipTo && fabric.util.clipContext(this, ctx); + this.transform(ctx); + // the array is now sorted in order of highest first, so start from end + for (var i = 0, len = this._objects.length; i < len; i++) { + this._renderObject(this._objects[i], ctx); + } + + this.clipTo && ctx.restore(); + + ctx.restore(); + }, + + /** + * Renders controls and borders for the object + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {Boolean} [noTransform] When true, context is not transformed + */ + _renderControls: function(ctx, noTransform) { + this.callSuper('_renderControls', ctx, noTransform); + for (var i = 0, len = this._objects.length; i < len; i++) { + this._objects[i]._renderControls(ctx); + } + }, + + /** + * @private + */ + _renderObject: function(object, ctx) { + var originalHasRotatingPoint = object.hasRotatingPoint; + + // do not render if object is not visible + if (!object.visible) { + return; + } + + object.hasRotatingPoint = false; + + object.render(ctx); + + object.hasRotatingPoint = originalHasRotatingPoint; + }, + + /** + * Retores original state of each of group objects (original state is that which was before group was created). + * @private + * @return {fabric.Group} thisArg + * @chainable + */ + _restoreObjectsState: function() { + this._objects.forEach(this._restoreObjectState, this); + return this; + }, + + /** + * Realises the transform from this group onto the supplied object + * i.e. it tells you what would happen if the supplied object was in + * the group, and then the group was destroyed. It mutates the supplied + * object. + * @param {fabric.Object} object + * @return {fabric.Object} transformedObject + */ + realizeTransform: function(object) { + this._moveFlippedObject(object); + this._setObjectPosition(object); + return object; + }, + /** + * Moves a flipped object to the position where it's displayed + * @private + * @param {fabric.Object} object + * @return {fabric.Group} thisArg + */ + _moveFlippedObject: function(object) { + var oldOriginX = object.get('originX'), + oldOriginY = object.get('originY'), + center = object.getCenterPoint(); + + object.set({ + originX: 'center', + originY: 'center', + left: center.x, + top: center.y + }); + + this._toggleFlipping(object); + + var newOrigin = object.getPointByOrigin(oldOriginX, oldOriginY); + + object.set({ + originX: oldOriginX, + originY: oldOriginY, + left: newOrigin.x, + top: newOrigin.y + }); + + return this; + }, + + /** + * @private + */ + _toggleFlipping: function(object) { + if (this.flipX) { + object.toggle('flipX'); + object.set('left', -object.get('left')); + object.setAngle(-object.getAngle()); + } + if (this.flipY) { + object.toggle('flipY'); + object.set('top', -object.get('top')); + object.setAngle(-object.getAngle()); + } + }, + + /** + * Restores original state of a specified object in group + * @private + * @param {fabric.Object} object + * @return {fabric.Group} thisArg + */ + _restoreObjectState: function(object) { + this._setObjectPosition(object); + + object.setCoords(); + object.hasControls = object.__origHasControls; + delete object.__origHasControls; + object.set('active', false); + object.setCoords(); + delete object.group; + + return this; + }, + + /** + * @private + */ + _setObjectPosition: function(object) { + var center = this.getCenterPoint(), + rotated = this._getRotatedLeftTop(object); + + object.set({ + angle: object.getAngle() + this.getAngle(), + left: center.x + rotated.left, + top: center.y + rotated.top, + scaleX: object.get('scaleX') * this.get('scaleX'), + scaleY: object.get('scaleY') * this.get('scaleY') + }); + }, + + /** + * @private + */ + _getRotatedLeftTop: function(object) { + var groupAngle = this.getAngle() * (Math.PI / 180); + return { + left: (-Math.sin(groupAngle) * object.getTop() * this.get('scaleY') + + Math.cos(groupAngle) * object.getLeft() * this.get('scaleX')), + + top: (Math.cos(groupAngle) * object.getTop() * this.get('scaleY') + + Math.sin(groupAngle) * object.getLeft() * this.get('scaleX')) + }; + }, + + /** + * Destroys a group (restoring state of its objects) + * @return {fabric.Group} thisArg + * @chainable + */ + destroy: function() { + this._objects.forEach(this._moveFlippedObject, this); + return this._restoreObjectsState(); + }, + + /** + * Saves coordinates of this instance (to be used together with `hasMoved`) + * @saveCoords + * @return {fabric.Group} thisArg + * @chainable + */ + saveCoords: function() { + this._originalLeft = this.get('left'); + this._originalTop = this.get('top'); + return this; + }, + + /** + * Checks whether this group was moved (since `saveCoords` was called last) + * @return {Boolean} true if an object was moved (since fabric.Group#saveCoords was called) + */ + hasMoved: function() { + return this._originalLeft !== this.get('left') || + this._originalTop !== this.get('top'); + }, + + /** + * Sets coordinates of all group objects + * @return {fabric.Group} thisArg + * @chainable + */ + setObjectsCoords: function() { + this.forEachObject(function(object) { + object.setCoords(); + }); + return this; + }, + + /** + * @private + */ + _calcBounds: function(onlyWidthHeight) { + var aX = [], + aY = [], + o, prop, + props = ['tr', 'br', 'bl', 'tl']; + + for (var i = 0, len = this._objects.length; i < len; ++i) { + o = this._objects[i]; + o.setCoords(); + for (var j = 0; j < props.length; j++) { + prop = props[j]; + aX.push(o.oCoords[prop].x); + aY.push(o.oCoords[prop].y); + } + } + + this.set(this._getBounds(aX, aY, onlyWidthHeight)); + }, + + /** + * @private + */ + _getBounds: function(aX, aY, onlyWidthHeight) { + var ivt = fabric.util.invertTransform(this.getViewportTransform()), + minXY = fabric.util.transformPoint(new fabric.Point(min(aX), min(aY)), ivt), + maxXY = fabric.util.transformPoint(new fabric.Point(max(aX), max(aY)), ivt), + obj = { + width: (maxXY.x - minXY.x) || 0, + height: (maxXY.y - minXY.y) || 0 + }; + + if (!onlyWidthHeight) { + obj.left = minXY.x || 0; + obj.top = minXY.y || 0; + if (this.originX === 'center') { + obj.left += obj.width / 2; + } + if (this.originX === 'right') { + obj.left += obj.width; + } + if (this.originY === 'center') { + obj.top += obj.height / 2; + } + if (this.originY === 'bottom') { + obj.top += obj.height; + } + } + return obj; + }, + + /* _TO_SVG_START_ */ + /** + * Returns svg representation of an instance + * @param {Function} [reviver] Method for further parsing of svg representation. + * @return {String} svg representation of an instance + */ + toSVG: function(reviver) { + var markup = [ + //jscs:disable validateIndentation + '\n' + //jscs:enable validateIndentation + ]; + + for (var i = 0, len = this._objects.length; i < len; i++) { + markup.push(this._objects[i].toSVG(reviver)); + } + + markup.push('\n'); + + return reviver ? reviver(markup.join('')) : markup.join(''); + }, + /* _TO_SVG_END_ */ + + /** + * Returns requested property + * @param {String} prop Property to get + * @return {Any} + */ + get: function(prop) { + if (prop in _lockProperties) { + if (this[prop]) { + return this[prop]; + } + else { + for (var i = 0, len = this._objects.length; i < len; i++) { + if (this._objects[i][prop]) { + return true; + } + } + return false; + } + } + else { + if (prop in this.delegatedProperties) { + return this._objects[0] && this._objects[0].get(prop); + } + return this[prop]; + } + } + }); + + /** + * Returns {@link fabric.Group} instance from an object representation + * @static + * @memberOf fabric.Group + * @param {Object} object Object to create a group from + * @param {Function} [callback] Callback to invoke when an group instance is created + * @return {fabric.Group} An instance of fabric.Group + */ + fabric.Group.fromObject = function(object, callback) { + fabric.util.enlivenObjects(object.objects, function(enlivenedObjects) { + delete object.objects; + callback && callback(new fabric.Group(enlivenedObjects, object)); + }); + }; + + /** + * Indicates that instances of this type are async + * @static + * @memberOf fabric.Group + * @type Boolean + * @default + */ + fabric.Group.async = true; + +})(typeof exports !== 'undefined' ? exports : this); + + +(function(global) { + + 'use strict'; + + var extend = fabric.util.object.extend; + + if (!global.fabric) { + global.fabric = { }; + } + + if (global.fabric.Image) { + fabric.warn('fabric.Image is already defined.'); + return; + } + + /** + * Image class + * @class fabric.Image + * @extends fabric.Object + * @tutorial {@link http://fabricjs.com/fabric-intro-part-1/#images} + * @see {@link fabric.Image#initialize} for constructor definition + */ + fabric.Image = fabric.util.createClass(fabric.Object, /** @lends fabric.Image.prototype */ { + + /** + * Type of an object + * @type String + * @default + */ + type: 'image', + + /** + * crossOrigin value (one of "", "anonymous", "allow-credentials") + * @see https://developer.mozilla.org/en-US/docs/HTML/CORS_settings_attributes + * @type String + * @default + */ + crossOrigin: '', + + /** + * AlignX value, part of preserveAspectRatio (one of "none", "mid", "min", "max") + * @see http://www.w3.org/TR/SVG/coords.html#PreserveAspectRatioAttribute + * This parameter defines how the picture is aligned to its viewport when image element width differs from image width. + * @type String + * @default + */ + alignX: 'none', + + /** + * AlignY value, part of preserveAspectRatio (one of "none", "mid", "min", "max") + * @see http://www.w3.org/TR/SVG/coords.html#PreserveAspectRatioAttribute + * This parameter defines how the picture is aligned to its viewport when image element height differs from image height. + * @type String + * @default + */ + alignY: 'none', + + /** + * meetOrSlice value, part of preserveAspectRatio (one of "meet", "slice"). + * if meet the image is always fully visibile, if slice the viewport is always filled with image. + * @see http://www.w3.org/TR/SVG/coords.html#PreserveAspectRatioAttribute + * @type String + * @default + */ + meetOrSlice: 'meet', + + /** + * private + * contains last value of scaleX to detect + * if the Image got resized after the last Render + * @type Number + */ + _lastScaleX: 1, + + /** + * private + * contains last value of scaleY to detect + * if the Image got resized after the last Render + * @type Number + */ + _lastScaleY: 1, + + /** + * Constructor + * @param {HTMLImageElement | String} element Image element + * @param {Object} [options] Options object + * @return {fabric.Image} thisArg + */ + initialize: function(element, options) { + options || (options = { }); + + this.filters = [ ]; + this.resizeFilters = [ ]; + this.callSuper('initialize', options); + + this._initElement(element, options); + this._initConfig(options); + + if (options.filters) { + this.filters = options.filters; + this.applyFilters(); + } + }, + + /** + * Returns image element which this instance if based on + * @return {HTMLImageElement} Image element + */ + getElement: function() { + return this._element; + }, + + /** + * Sets image element for this instance to a specified one. + * If filters defined they are applied to new image. + * You might need to call `canvas.renderAll` and `object.setCoords` after replacing, to render new image and update controls area. + * @param {HTMLImageElement} element + * @param {Function} [callback] Callback is invoked when all filters have been applied and new image is generated + * @param {Object} [options] Options object + * @return {fabric.Image} thisArg + * @chainable + */ + setElement: function(element, callback, options) { + this._element = element; + this._originalElement = element; + this._initConfig(options); + + if (this.filters.length !== 0) { + this.applyFilters(callback); + } + else if (callback) { + callback(); + } + + return this; + }, + + /** + * Sets crossOrigin value (on an instance and corresponding image element) + * @return {fabric.Image} thisArg + * @chainable + */ + setCrossOrigin: function(value) { + this.crossOrigin = value; + this._element.crossOrigin = value; + + return this; + }, + + /** + * Returns original size of an image + * @return {Object} Object with "width" and "height" properties + */ + getOriginalSize: function() { + var element = this.getElement(); + return { + width: element.width, + height: element.height + }; + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _stroke: function(ctx) { + ctx.save(); + this._setStrokeStyles(ctx); + ctx.beginPath(); + ctx.strokeRect(-this.width / 2, -this.height / 2, this.width, this.height); + ctx.closePath(); + ctx.restore(); + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderDashedStroke: function(ctx) { + var x = -this.width / 2, + y = -this.height / 2, + w = this.width, + h = this.height; + + ctx.save(); + this._setStrokeStyles(ctx); + + ctx.beginPath(); + fabric.util.drawDashedLine(ctx, x, y, x + w, y, this.strokeDashArray); + fabric.util.drawDashedLine(ctx, x + w, y, x + w, y + h, this.strokeDashArray); + fabric.util.drawDashedLine(ctx, x + w, y + h, x, y + h, this.strokeDashArray); + fabric.util.drawDashedLine(ctx, x, y + h, x, y, this.strokeDashArray); + ctx.closePath(); + ctx.restore(); + }, + + /** + * Returns object representation of an instance + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} Object representation of an instance + */ + toObject: function(propertiesToInclude) { + return extend(this.callSuper('toObject', propertiesToInclude), { + src: this._originalElement.src || this._originalElement._src, + filters: this.filters.map(function(filterObj) { + return filterObj && filterObj.toObject(); + }), + crossOrigin: this.crossOrigin, + alignX: this.alignX, + alignY: this.alignY, + meetOrSlice: this.meetOrSlice + }); + }, + + /* _TO_SVG_START_ */ + /** + * Returns SVG representation of an instance + * @param {Function} [reviver] Method for further parsing of svg representation. + * @return {String} svg representation of an instance + */ + toSVG: function(reviver) { + var markup = [], x = -this.width / 2, y = -this.height / 2, + preserveAspectRatio = 'none'; + if (this.group && this.group.type === 'path-group') { + x = this.left; + y = this.top; + } + if (this.alignX !== 'none' && this.alignY !== 'none') { + preserveAspectRatio = 'x' + this.alignX + 'Y' + this.alignY + ' ' + this.meetOrSlice; + } + markup.push( + '\n', + '\n' + ); + + if (this.stroke || this.strokeDashArray) { + var origFill = this.fill; + this.fill = null; + markup.push( + '\n' + ); + this.fill = origFill; + } + + markup.push('\n'); + + return reviver ? reviver(markup.join('')) : markup.join(''); + }, + /* _TO_SVG_END_ */ + + /** + * Returns source of an image + * @return {String} Source of an image + */ + getSrc: function() { + if (this.getElement()) { + return this.getElement().src || this.getElement()._src; + } + }, + + /** + * Sets source of an image + * @param {String} src Source string (URL) + * @param {Function} [callback] Callback is invoked when image has been loaded (and all filters have been applied) + * @param {Object} [options] Options object + * @return {fabric.Image} thisArg + * @chainable + */ + setSrc: function(src, callback, options) { + fabric.util.loadImage(src, function(img) { + return this.setElement(img, callback, options); + }, this, options && options.crossOrigin); + }, + + /** + * Returns string representation of an instance + * @return {String} String representation of an instance + */ + toString: function() { + return '#'; + }, + + /** + * Returns a clone of an instance + * @param {Function} callback Callback is invoked with a clone as a first argument + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + */ + clone: function(callback, propertiesToInclude) { + this.constructor.fromObject(this.toObject(propertiesToInclude), callback); + }, + + /** + * Applies filters assigned to this image (from "filters" array) + * @method applyFilters + * @param {Function} callback Callback is invoked when all filters have been applied and new image is generated + * @return {fabric.Image} thisArg + * @chainable + */ + applyFilters: function(callback, filters, imgElement, forResizing) { + + filters = filters || this.filters; + imgElement = imgElement || this._originalElement; + + if (!imgElement) { + return; + } + + var imgEl = imgElement, + canvasEl = fabric.util.createCanvasElement(), + replacement = fabric.util.createImage(), + _this = this; + + canvasEl.width = imgEl.width; + canvasEl.height = imgEl.height; + canvasEl.getContext('2d').drawImage(imgEl, 0, 0, imgEl.width, imgEl.height); + + if (filters.length === 0) { + this._element = imgElement; + callback && callback(); + return canvasEl; + } + filters.forEach(function(filter) { + filter && filter.applyTo(canvasEl, filter.scaleX || _this.scaleX, filter.scaleY || _this.scaleY); + if (!forResizing && filter && filter.type === 'Resize') { + _this.width *= filter.scaleX; + _this.height *= filter.scaleY; + } + }); + + /** @ignore */ + replacement.width = canvasEl.width; + replacement.height = canvasEl.height; + + if (fabric.isLikelyNode) { + replacement.src = canvasEl.toBuffer(undefined, fabric.Image.pngCompression); + // onload doesn't fire in some node versions, so we invoke callback manually + _this._element = replacement; + !forResizing && (_this._filteredEl = replacement); + callback && callback(); + } + else { + replacement.onload = function() { + _this._element = replacement; + !forResizing && (_this._filteredEl = replacement); + callback && callback(); + replacement.onload = canvasEl = imgEl = null; + }; + replacement.src = canvasEl.toDataURL('image/png'); + } + return canvasEl; + }, + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _render: function(ctx, noTransform) { + var x, y, imageMargins = this._findMargins(), elementToDraw; + + x = (noTransform ? this.left : -this.width / 2); + y = (noTransform ? this.top : -this.height / 2); + + if (this.meetOrSlice === 'slice') { + ctx.beginPath(); + ctx.rect(x, y, this.width, this.height); + ctx.clip(); + } + + if (this.isMoving === false && this.resizeFilters.length && this._needsResize()) { + this._lastScaleX = this.scaleX; + this._lastScaleY = this.scaleY; + elementToDraw = this.applyFilters(null, this.resizeFilters, this._filteredEl || this._originalElement, true); + } + else { + elementToDraw = this._element; + } + elementToDraw && ctx.drawImage(elementToDraw, + x + imageMargins.marginX, + y + imageMargins.marginY, + imageMargins.width, + imageMargins.height + ); + + this._renderStroke(ctx); + }, + /** + * @private, needed to check if image needs resize + */ + _needsResize: function() { + return (this.scaleX !== this._lastScaleX || this.scaleY !== this._lastScaleY); + }, + + /** + * @private + */ + _findMargins: function() { + var width = this.width, height = this.height, scales, + scale, marginX = 0, marginY = 0; + + if (this.alignX !== 'none' || this.alignY !== 'none') { + scales = [this.width / this._element.width, this.height / this._element.height]; + scale = this.meetOrSlice === 'meet' + ? Math.min.apply(null, scales) : Math.max.apply(null, scales); + width = this._element.width * scale; + height = this._element.height * scale; + if (this.alignX === 'Mid') { + marginX = (this.width - width) / 2; + } + if (this.alignX === 'Max') { + marginX = this.width - width; + } + if (this.alignY === 'Mid') { + marginY = (this.height - height) / 2; + } + if (this.alignY === 'Max') { + marginY = this.height - height; + } + } + return { + width: width, + height: height, + marginX: marginX, + marginY: marginY + }; + }, + + /** + * @private + */ + _resetWidthHeight: function() { + var element = this.getElement(); + + this.set('width', element.width); + this.set('height', element.height); + }, + + /** + * The Image class's initialization method. This method is automatically + * called by the constructor. + * @private + * @param {HTMLImageElement|String} element The element representing the image + */ + _initElement: function(element) { + this.setElement(fabric.util.getById(element)); + fabric.util.addClass(this.getElement(), fabric.Image.CSS_CANVAS); + }, + + /** + * @private + * @param {Object} [options] Options object + */ + _initConfig: function(options) { + options || (options = { }); + this.setOptions(options); + this._setWidthHeight(options); + if (this._element && this.crossOrigin) { + this._element.crossOrigin = this.crossOrigin; + } + }, + + /** + * @private + * @param {Object} object Object with filters property + * @param {Function} callback Callback to invoke when all fabric.Image.filters instances are created + */ + _initFilters: function(object, callback) { + if (object.filters && object.filters.length) { + fabric.util.enlivenObjects(object.filters, function(enlivenedObjects) { + callback && callback(enlivenedObjects); + }, 'fabric.Image.filters'); + } + else { + callback && callback(); + } + }, + + /** + * @private + * @param {Object} [options] Object with width/height properties + */ + _setWidthHeight: function(options) { + this.width = 'width' in options + ? options.width + : (this.getElement() + ? this.getElement().width || 0 + : 0); + + this.height = 'height' in options + ? options.height + : (this.getElement() + ? this.getElement().height || 0 + : 0); + }, + + /** + * Returns complexity of an instance + * @return {Number} complexity of this instance + */ + complexity: function() { + return 1; + } + }); + + /** + * Default CSS class name for canvas + * @static + * @type String + * @default + */ + fabric.Image.CSS_CANVAS = 'canvas-img'; + + /** + * Alias for getSrc + * @static + */ + fabric.Image.prototype.getSvgSrc = fabric.Image.prototype.getSrc; + + /** + * Creates an instance of fabric.Image from its object representation + * @static + * @param {Object} object Object to create an instance from + * @param {Function} [callback] Callback to invoke when an image instance is created + */ + fabric.Image.fromObject = function(object, callback) { + fabric.util.loadImage(object.src, function(img) { + fabric.Image.prototype._initFilters.call(object, object, function(filters) { + object.filters = filters || [ ]; + var instance = new fabric.Image(img, object); + callback && callback(instance); + }); + }, null, object.crossOrigin); + }; + + /** + * Creates an instance of fabric.Image from an URL string + * @static + * @param {String} url URL to create an image from + * @param {Function} [callback] Callback to invoke when image is created (newly created image is passed as a first argument) + * @param {Object} [imgOptions] Options object + */ + fabric.Image.fromURL = function(url, callback, imgOptions) { + fabric.util.loadImage(url, function(img) { + callback && callback(new fabric.Image(img, imgOptions)); + }, null, imgOptions && imgOptions.crossOrigin); + }; + + /* _FROM_SVG_START_ */ + /** + * List of attribute names to account for when parsing SVG element (used by {@link fabric.Image.fromElement}) + * @static + * @see {@link http://www.w3.org/TR/SVG/struct.html#ImageElement} + */ + fabric.Image.ATTRIBUTE_NAMES = + fabric.SHARED_ATTRIBUTES.concat('x y width height preserveAspectRatio xlink:href'.split(' ')); + + /** + * Returns {@link fabric.Image} instance from an SVG element + * @static + * @param {SVGElement} element Element to parse + * @param {Function} callback Callback to execute when fabric.Image object is created + * @param {Object} [options] Options object + * @return {fabric.Image} Instance of fabric.Image + */ + fabric.Image.fromElement = function(element, callback, options) { + var parsedAttributes = fabric.parseAttributes(element, fabric.Image.ATTRIBUTE_NAMES), + align = 'xMidYMid', meetOrSlice = 'meet', alignX, alignY, aspectRatioAttrs; + + if (parsedAttributes.preserveAspectRatio) { + aspectRatioAttrs = parsedAttributes.preserveAspectRatio.split(' '); + } + + if (aspectRatioAttrs && aspectRatioAttrs.length) { + meetOrSlice = aspectRatioAttrs.pop(); + if (meetOrSlice !== 'meet' && meetOrSlice !== 'slice') { + align = meetOrSlice; + meetOrSlice = 'meet'; + } + else if (aspectRatioAttrs.length) { + align = aspectRatioAttrs.pop(); + } + } + //divide align in alignX and alignY + alignX = align !== 'none' ? align.slice(1, 4) : 'none'; + alignY = align !== 'none' ? align.slice(5, 8) : 'none'; + parsedAttributes.alignX = alignX; + parsedAttributes.alignY = alignY; + parsedAttributes.meetOrSlice = meetOrSlice; + fabric.Image.fromURL(parsedAttributes['xlink:href'], callback, + extend((options ? fabric.util.object.clone(options) : { }), parsedAttributes)); + }; + /* _FROM_SVG_END_ */ + + /** + * Indicates that instances of this type are async + * @static + * @type Boolean + * @default + */ + fabric.Image.async = true; + + /** + * Indicates compression level used when generating PNG under Node (in applyFilters). Any of 0-9 + * @static + * @type Number + * @default + */ + fabric.Image.pngCompression = 1; + +})(typeof exports !== 'undefined' ? exports : this); + + +fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ { + + /** + * @private + * @return {Number} angle value + */ + _getAngleValueForStraighten: function() { + var angle = this.getAngle() % 360; + if (angle > 0) { + return Math.round((angle - 1) / 90) * 90; + } + return Math.round(angle / 90) * 90; + }, + + /** + * Straightens an object (rotating it from current angle to one of 0, 90, 180, 270, etc. depending on which is closer) + * @return {fabric.Object} thisArg + * @chainable + */ + straighten: function() { + this.setAngle(this._getAngleValueForStraighten()); + return this; + }, + + /** + * Same as {@link fabric.Object.prototype.straighten} but with animation + * @param {Object} callbacks Object with callback functions + * @param {Function} [callbacks.onComplete] Invoked on completion + * @param {Function} [callbacks.onChange] Invoked on every step of animation + * @return {fabric.Object} thisArg + * @chainable + */ + fxStraighten: function(callbacks) { + callbacks = callbacks || { }; + + var empty = function() { }, + onComplete = callbacks.onComplete || empty, + onChange = callbacks.onChange || empty, + _this = this; + + fabric.util.animate({ + startValue: this.get('angle'), + endValue: this._getAngleValueForStraighten(), + duration: this.FX_DURATION, + onChange: function(value) { + _this.setAngle(value); + onChange(); + }, + onComplete: function() { + _this.setCoords(); + onComplete(); + }, + onStart: function() { + _this.set('active', false); + } + }); + + return this; + } +}); + +fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ { + + /** + * Straightens object, then rerenders canvas + * @param {fabric.Object} object Object to straighten + * @return {fabric.Canvas} thisArg + * @chainable + */ + straightenObject: function (object) { + object.straighten(); + this.renderAll(); + return this; + }, + + /** + * Same as {@link fabric.Canvas.prototype.straightenObject}, but animated + * @param {fabric.Object} object Object to straighten + * @return {fabric.Canvas} thisArg + * @chainable + */ + fxStraightenObject: function (object) { + object.fxStraighten({ + onChange: this.renderAll.bind(this) + }); + return this; + } +}); + + +/** + * @namespace fabric.Image.filters + * @memberOf fabric.Image + * @tutorial {@link http://fabricjs.com/fabric-intro-part-2/#image_filters} + * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo} + */ +fabric.Image.filters = fabric.Image.filters || { }; + +/** + * Root filter class from which all filter classes inherit from + * @class fabric.Image.filters.BaseFilter + * @memberOf fabric.Image.filters + */ +fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Image.filters.BaseFilter.prototype */ { + + /** + * Filter type + * @param {String} type + * @default + */ + type: 'BaseFilter', + + /** + * Constructor + * @param {Object} [options] Options object + */ + initialize: function(options) { + if (options) { + this.setOptions(options); + } + }, + + /** + * Sets filter's properties from options + * @param {Object} [options] Options object + */ + setOptions: function(options) { + for (var prop in options) { + this[prop] = options[prop]; + } + }, + + /** + * Returns object representation of an instance + * @return {Object} Object representation of an instance + */ + toObject: function() { + return { type: this.type }; + }, + + /** + * Returns a JSON representation of an instance + * @return {Object} JSON + */ + toJSON: function() { + // delegate, not alias + return this.toObject(); + } +}); + + +(function(global) { + + 'use strict'; + + var fabric = global.fabric || (global.fabric = { }), + extend = fabric.util.object.extend; + + /** + * Brightness filter class + * @class fabric.Image.filters.Brightness + * @memberOf fabric.Image.filters + * @extends fabric.Image.filters.BaseFilter + * @see {@link fabric.Image.filters.Brightness#initialize} for constructor definition + * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo} + * @example + * var filter = new fabric.Image.filters.Brightness({ + * brightness: 200 + * }); + * object.filters.push(filter); + * object.applyFilters(canvas.renderAll.bind(canvas)); + */ + fabric.Image.filters.Brightness = fabric.util.createClass(fabric.Image.filters.BaseFilter, /** @lends fabric.Image.filters.Brightness.prototype */ { + + /** + * Filter type + * @param {String} type + * @default + */ + type: 'Brightness', + + /** + * Constructor + * @memberOf fabric.Image.filters.Brightness.prototype + * @param {Object} [options] Options object + * @param {Number} [options.brightness=0] Value to brighten the image up (0..255) + */ + initialize: function(options) { + options = options || { }; + this.brightness = options.brightness || 0; + }, + + /** + * Applies filter to canvas element + * @param {Object} canvasEl Canvas element to apply filter to + */ + applyTo: function(canvasEl) { + var context = canvasEl.getContext('2d'), + imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), + data = imageData.data, + brightness = this.brightness; + + for (var i = 0, len = data.length; i < len; i += 4) { + data[i] += brightness; + data[i + 1] += brightness; + data[i + 2] += brightness; + } + + context.putImageData(imageData, 0, 0); + }, + + /** + * Returns object representation of an instance + * @return {Object} Object representation of an instance + */ + toObject: function() { + return extend(this.callSuper('toObject'), { + brightness: this.brightness + }); + } + }); + + /** + * Returns filter instance from an object representation + * @static + * @param {Object} object Object to create an instance from + * @return {fabric.Image.filters.Brightness} Instance of fabric.Image.filters.Brightness + */ + fabric.Image.filters.Brightness.fromObject = function(object) { + return new fabric.Image.filters.Brightness(object); + }; + +})(typeof exports !== 'undefined' ? exports : this); + + +(function(global) { + + 'use strict'; + + var fabric = global.fabric || (global.fabric = { }), + extend = fabric.util.object.extend; + + /** + * Adapted from html5rocks article + * @class fabric.Image.filters.Convolute + * @memberOf fabric.Image.filters + * @extends fabric.Image.filters.BaseFilter + * @see {@link fabric.Image.filters.Convolute#initialize} for constructor definition + * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo} + * @example Sharpen filter + * var filter = new fabric.Image.filters.Convolute({ + * matrix: [ 0, -1, 0, + * -1, 5, -1, + * 0, -1, 0 ] + * }); + * object.filters.push(filter); + * object.applyFilters(canvas.renderAll.bind(canvas)); + * @example Blur filter + * var filter = new fabric.Image.filters.Convolute({ + * matrix: [ 1/9, 1/9, 1/9, + * 1/9, 1/9, 1/9, + * 1/9, 1/9, 1/9 ] + * }); + * object.filters.push(filter); + * object.applyFilters(canvas.renderAll.bind(canvas)); + * @example Emboss filter + * var filter = new fabric.Image.filters.Convolute({ + * matrix: [ 1, 1, 1, + * 1, 0.7, -1, + * -1, -1, -1 ] + * }); + * object.filters.push(filter); + * object.applyFilters(canvas.renderAll.bind(canvas)); + * @example Emboss filter with opaqueness + * var filter = new fabric.Image.filters.Convolute({ + * opaque: true, + * matrix: [ 1, 1, 1, + * 1, 0.7, -1, + * -1, -1, -1 ] + * }); + * object.filters.push(filter); + * object.applyFilters(canvas.renderAll.bind(canvas)); + */ + fabric.Image.filters.Convolute = fabric.util.createClass(fabric.Image.filters.BaseFilter, /** @lends fabric.Image.filters.Convolute.prototype */ { + + /** + * Filter type + * @param {String} type + * @default + */ + type: 'Convolute', + + /** + * Constructor + * @memberOf fabric.Image.filters.Convolute.prototype + * @param {Object} [options] Options object + * @param {Boolean} [options.opaque=false] Opaque value (true/false) + * @param {Array} [options.matrix] Filter matrix + */ + initialize: function(options) { + options = options || { }; + + this.opaque = options.opaque; + this.matrix = options.matrix || [ + 0, 0, 0, + 0, 1, 0, + 0, 0, 0 + ]; + + var canvasEl = fabric.util.createCanvasElement(); + this.tmpCtx = canvasEl.getContext('2d'); + }, + + /** + * @private + */ + _createImageData: function(w, h) { + return this.tmpCtx.createImageData(w, h); + }, + + /** + * Applies filter to canvas element + * @param {Object} canvasEl Canvas element to apply filter to + */ + applyTo: function(canvasEl) { + + var weights = this.matrix, + context = canvasEl.getContext('2d'), + pixels = context.getImageData(0, 0, canvasEl.width, canvasEl.height), + + side = Math.round(Math.sqrt(weights.length)), + halfSide = Math.floor(side/2), + src = pixels.data, + sw = pixels.width, + sh = pixels.height, + + // pad output by the convolution matrix + w = sw, + h = sh, + output = this._createImageData(w, h), + + dst = output.data, + + // go through the destination image pixels + alphaFac = this.opaque ? 1 : 0; + + for (var y = 0; y < h; y++) { + for (var x = 0; x < w; x++) { + var sy = y, + sx = x, + dstOff = (y * w + x) * 4, + // calculate the weighed sum of the source image pixels that + // fall under the convolution matrix + r = 0, g = 0, b = 0, a = 0; + + for (var cy = 0; cy < side; cy++) { + for (var cx = 0; cx < side; cx++) { + + var scy = sy + cy - halfSide, + scx = sx + cx - halfSide; + + /* jshint maxdepth:5 */ + if (scy < 0 || scy > sh || scx < 0 || scx > sw) { + continue; + } + + var srcOff = (scy * sw + scx) * 4, + wt = weights[cy * side + cx]; + + r += src[srcOff] * wt; + g += src[srcOff + 1] * wt; + b += src[srcOff + 2] * wt; + a += src[srcOff + 3] * wt; + } + } + dst[dstOff] = r; + dst[dstOff + 1] = g; + dst[dstOff + 2] = b; + dst[dstOff + 3] = a + alphaFac * (255 - a); + } + } + + context.putImageData(output, 0, 0); + }, + + /** + * Returns object representation of an instance + * @return {Object} Object representation of an instance + */ + toObject: function() { + return extend(this.callSuper('toObject'), { + opaque: this.opaque, + matrix: this.matrix + }); + } + }); + + /** + * Returns filter instance from an object representation + * @static + * @param {Object} object Object to create an instance from + * @return {fabric.Image.filters.Convolute} Instance of fabric.Image.filters.Convolute + */ + fabric.Image.filters.Convolute.fromObject = function(object) { + return new fabric.Image.filters.Convolute(object); + }; + +})(typeof exports !== 'undefined' ? exports : this); + + +(function(global) { + + 'use strict'; + + var fabric = global.fabric || (global.fabric = { }), + extend = fabric.util.object.extend; + + /** + * GradientTransparency filter class + * @class fabric.Image.filters.GradientTransparency + * @memberOf fabric.Image.filters + * @extends fabric.Image.filters.BaseFilter + * @see {@link fabric.Image.filters.GradientTransparency#initialize} for constructor definition + * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo} + * @example + * var filter = new fabric.Image.filters.GradientTransparency({ + * threshold: 200 + * }); + * object.filters.push(filter); + * object.applyFilters(canvas.renderAll.bind(canvas)); + */ + fabric.Image.filters.GradientTransparency = fabric.util.createClass(fabric.Image.filters.BaseFilter, /** @lends fabric.Image.filters.GradientTransparency.prototype */ { + + /** + * Filter type + * @param {String} type + * @default + */ + type: 'GradientTransparency', + + /** + * Constructor + * @memberOf fabric.Image.filters.GradientTransparency.prototype + * @param {Object} [options] Options object + * @param {Number} [options.threshold=100] Threshold value + */ + initialize: function(options) { + options = options || { }; + this.threshold = options.threshold || 100; + }, + + /** + * Applies filter to canvas element + * @param {Object} canvasEl Canvas element to apply filter to + */ + applyTo: function(canvasEl) { + var context = canvasEl.getContext('2d'), + imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), + data = imageData.data, + threshold = this.threshold, + total = data.length; + + for (var i = 0, len = data.length; i < len; i += 4) { + data[i + 3] = threshold + 255 * (total - i) / total; + } + + context.putImageData(imageData, 0, 0); + }, + + /** + * Returns object representation of an instance + * @return {Object} Object representation of an instance + */ + toObject: function() { + return extend(this.callSuper('toObject'), { + threshold: this.threshold + }); + } + }); + + /** + * Returns filter instance from an object representation + * @static + * @param {Object} object Object to create an instance from + * @return {fabric.Image.filters.GradientTransparency} Instance of fabric.Image.filters.GradientTransparency + */ + fabric.Image.filters.GradientTransparency.fromObject = function(object) { + return new fabric.Image.filters.GradientTransparency(object); + }; + +})(typeof exports !== 'undefined' ? exports : this); + + +(function(global) { + + 'use strict'; + + var fabric = global.fabric || (global.fabric = { }); + + /** + * Grayscale image filter class + * @class fabric.Image.filters.Grayscale + * @memberOf fabric.Image.filters + * @extends fabric.Image.filters.BaseFilter + * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo} + * @example + * var filter = new fabric.Image.filters.Grayscale(); + * object.filters.push(filter); + * object.applyFilters(canvas.renderAll.bind(canvas)); + */ + fabric.Image.filters.Grayscale = fabric.util.createClass(fabric.Image.filters.BaseFilter, /** @lends fabric.Image.filters.Grayscale.prototype */ { + + /** + * Filter type + * @param {String} type + * @default + */ + type: 'Grayscale', + + /** + * Applies filter to canvas element + * @memberOf fabric.Image.filters.Grayscale.prototype + * @param {Object} canvasEl Canvas element to apply filter to + */ + applyTo: function(canvasEl) { + var context = canvasEl.getContext('2d'), + imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), + data = imageData.data, + len = imageData.width * imageData.height * 4, + index = 0, + average; + + while (index < len) { + average = (data[index] + data[index + 1] + data[index + 2]) / 3; + data[index] = average; + data[index + 1] = average; + data[index + 2] = average; + index += 4; + } + + context.putImageData(imageData, 0, 0); + } + }); + + /** + * Returns filter instance from an object representation + * @static + * @return {fabric.Image.filters.Grayscale} Instance of fabric.Image.filters.Grayscale + */ + fabric.Image.filters.Grayscale.fromObject = function() { + return new fabric.Image.filters.Grayscale(); + }; + +})(typeof exports !== 'undefined' ? exports : this); + + +(function(global) { + + 'use strict'; + + var fabric = global.fabric || (global.fabric = { }); + + /** + * Invert filter class + * @class fabric.Image.filters.Invert + * @memberOf fabric.Image.filters + * @extends fabric.Image.filters.BaseFilter + * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo} + * @example + * var filter = new fabric.Image.filters.Invert(); + * object.filters.push(filter); + * object.applyFilters(canvas.renderAll.bind(canvas)); + */ + fabric.Image.filters.Invert = fabric.util.createClass(fabric.Image.filters.BaseFilter, /** @lends fabric.Image.filters.Invert.prototype */ { + + /** + * Filter type + * @param {String} type + * @default + */ + type: 'Invert', + + /** + * Applies filter to canvas element + * @memberOf fabric.Image.filters.Invert.prototype + * @param {Object} canvasEl Canvas element to apply filter to + */ + applyTo: function(canvasEl) { + var context = canvasEl.getContext('2d'), + imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), + data = imageData.data, + iLen = data.length, i; + + for (i = 0; i < iLen; i+=4) { + data[i] = 255 - data[i]; + data[i + 1] = 255 - data[i + 1]; + data[i + 2] = 255 - data[i + 2]; + } + + context.putImageData(imageData, 0, 0); + } + }); + + /** + * Returns filter instance from an object representation + * @static + * @return {fabric.Image.filters.Invert} Instance of fabric.Image.filters.Invert + */ + fabric.Image.filters.Invert.fromObject = function() { + return new fabric.Image.filters.Invert(); + }; + +})(typeof exports !== 'undefined' ? exports : this); + + +(function(global) { + + 'use strict'; + + var fabric = global.fabric || (global.fabric = { }), + extend = fabric.util.object.extend; + + /** + * Mask filter class + * See http://resources.aleph-1.com/mask/ + * @class fabric.Image.filters.Mask + * @memberOf fabric.Image.filters + * @extends fabric.Image.filters.BaseFilter + * @see {@link fabric.Image.filters.Mask#initialize} for constructor definition + */ + fabric.Image.filters.Mask = fabric.util.createClass(fabric.Image.filters.BaseFilter, /** @lends fabric.Image.filters.Mask.prototype */ { + + /** + * Filter type + * @param {String} type + * @default + */ + type: 'Mask', + + /** + * Constructor + * @memberOf fabric.Image.filters.Mask.prototype + * @param {Object} [options] Options object + * @param {fabric.Image} [options.mask] Mask image object + * @param {Number} [options.channel=0] Rgb channel (0, 1, 2 or 3) + */ + initialize: function(options) { + options = options || { }; + + this.mask = options.mask; + this.channel = [ 0, 1, 2, 3 ].indexOf(options.channel) > -1 ? options.channel : 0; + }, + + /** + * Applies filter to canvas element + * @param {Object} canvasEl Canvas element to apply filter to + */ + applyTo: function(canvasEl) { + if (!this.mask) { + return; + } + + var context = canvasEl.getContext('2d'), + imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), + data = imageData.data, + maskEl = this.mask.getElement(), + maskCanvasEl = fabric.util.createCanvasElement(), + channel = this.channel, + i, + iLen = imageData.width * imageData.height * 4; + + maskCanvasEl.width = maskEl.width; + maskCanvasEl.height = maskEl.height; + + maskCanvasEl.getContext('2d').drawImage(maskEl, 0, 0, maskEl.width, maskEl.height); + + var maskImageData = maskCanvasEl.getContext('2d').getImageData(0, 0, maskEl.width, maskEl.height), + maskData = maskImageData.data; + + for (i = 0; i < iLen; i += 4) { + data[i + 3] = maskData[i + channel]; + } + + context.putImageData(imageData, 0, 0); + }, + + /** + * Returns object representation of an instance + * @return {Object} Object representation of an instance + */ + toObject: function() { + return extend(this.callSuper('toObject'), { + mask: this.mask.toObject(), + channel: this.channel + }); + } + }); + + /** + * Returns filter instance from an object representation + * @static + * @param {Object} object Object to create an instance from + * @param {Function} [callback] Callback to invoke when a mask filter instance is created + */ + fabric.Image.filters.Mask.fromObject = function(object, callback) { + fabric.util.loadImage(object.mask.src, function(img) { + object.mask = new fabric.Image(img, object.mask); + callback && callback(new fabric.Image.filters.Mask(object)); + }); + }; + + /** + * Indicates that instances of this type are async + * @static + * @type Boolean + * @default + */ + fabric.Image.filters.Mask.async = true; + +})(typeof exports !== 'undefined' ? exports : this); + + +(function(global) { + + 'use strict'; + + var fabric = global.fabric || (global.fabric = { }), + extend = fabric.util.object.extend; + + /** + * Noise filter class + * @class fabric.Image.filters.Noise + * @memberOf fabric.Image.filters + * @extends fabric.Image.filters.BaseFilter + * @see {@link fabric.Image.filters.Noise#initialize} for constructor definition + * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo} + * @example + * var filter = new fabric.Image.filters.Noise({ + * noise: 700 + * }); + * object.filters.push(filter); + * object.applyFilters(canvas.renderAll.bind(canvas)); + */ + fabric.Image.filters.Noise = fabric.util.createClass(fabric.Image.filters.BaseFilter, /** @lends fabric.Image.filters.Noise.prototype */ { + + /** + * Filter type + * @param {String} type + * @default + */ + type: 'Noise', + + /** + * Constructor + * @memberOf fabric.Image.filters.Noise.prototype + * @param {Object} [options] Options object + * @param {Number} [options.noise=0] Noise value + */ + initialize: function(options) { + options = options || { }; + this.noise = options.noise || 0; + }, + + /** + * Applies filter to canvas element + * @param {Object} canvasEl Canvas element to apply filter to + */ + applyTo: function(canvasEl) { + var context = canvasEl.getContext('2d'), + imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), + data = imageData.data, + noise = this.noise, rand; + + for (var i = 0, len = data.length; i < len; i += 4) { + + rand = (0.5 - Math.random()) * noise; + + data[i] += rand; + data[i + 1] += rand; + data[i + 2] += rand; + } + + context.putImageData(imageData, 0, 0); + }, + + /** + * Returns object representation of an instance + * @return {Object} Object representation of an instance + */ + toObject: function() { + return extend(this.callSuper('toObject'), { + noise: this.noise + }); + } + }); + + /** + * Returns filter instance from an object representation + * @static + * @param {Object} object Object to create an instance from + * @return {fabric.Image.filters.Noise} Instance of fabric.Image.filters.Noise + */ + fabric.Image.filters.Noise.fromObject = function(object) { + return new fabric.Image.filters.Noise(object); + }; + +})(typeof exports !== 'undefined' ? exports : this); + + +(function(global) { + + 'use strict'; + + var fabric = global.fabric || (global.fabric = { }), + extend = fabric.util.object.extend; + + /** + * Pixelate filter class + * @class fabric.Image.filters.Pixelate + * @memberOf fabric.Image.filters + * @extends fabric.Image.filters.BaseFilter + * @see {@link fabric.Image.filters.Pixelate#initialize} for constructor definition + * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo} + * @example + * var filter = new fabric.Image.filters.Pixelate({ + * blocksize: 8 + * }); + * object.filters.push(filter); + * object.applyFilters(canvas.renderAll.bind(canvas)); + */ + fabric.Image.filters.Pixelate = fabric.util.createClass(fabric.Image.filters.BaseFilter, /** @lends fabric.Image.filters.Pixelate.prototype */ { + + /** + * Filter type + * @param {String} type + * @default + */ + type: 'Pixelate', + + /** + * Constructor + * @memberOf fabric.Image.filters.Pixelate.prototype + * @param {Object} [options] Options object + * @param {Number} [options.blocksize=4] Blocksize for pixelate + */ + initialize: function(options) { + options = options || { }; + this.blocksize = options.blocksize || 4; + }, + + /** + * Applies filter to canvas element + * @param {Object} canvasEl Canvas element to apply filter to + */ + applyTo: function(canvasEl) { + var context = canvasEl.getContext('2d'), + imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), + data = imageData.data, + iLen = imageData.height, + jLen = imageData.width, + index, i, j, r, g, b, a; + + for (i = 0; i < iLen; i += this.blocksize) { + for (j = 0; j < jLen; j += this.blocksize) { + + index = (i * 4) * jLen + (j * 4); + + r = data[index]; + g = data[index + 1]; + b = data[index + 2]; + a = data[index + 3]; + + /* + blocksize: 4 + + [1,x,x,x,1] + [x,x,x,x,1] + [x,x,x,x,1] + [x,x,x,x,1] + [1,1,1,1,1] + */ + + for (var _i = i, _ilen = i + this.blocksize; _i < _ilen; _i++) { + for (var _j = j, _jlen = j + this.blocksize; _j < _jlen; _j++) { + index = (_i * 4) * jLen + (_j * 4); + data[index] = r; + data[index + 1] = g; + data[index + 2] = b; + data[index + 3] = a; + } + } + } + } + + context.putImageData(imageData, 0, 0); + }, + + /** + * Returns object representation of an instance + * @return {Object} Object representation of an instance + */ + toObject: function() { + return extend(this.callSuper('toObject'), { + blocksize: this.blocksize + }); + } + }); + + /** + * Returns filter instance from an object representation + * @static + * @param {Object} object Object to create an instance from + * @return {fabric.Image.filters.Pixelate} Instance of fabric.Image.filters.Pixelate + */ + fabric.Image.filters.Pixelate.fromObject = function(object) { + return new fabric.Image.filters.Pixelate(object); + }; + +})(typeof exports !== 'undefined' ? exports : this); + + +(function(global) { + + 'use strict'; + + var fabric = global.fabric || (global.fabric = { }), + extend = fabric.util.object.extend; + + /** + * Remove white filter class + * @class fabric.Image.filters.RemoveWhite + * @memberOf fabric.Image.filters + * @extends fabric.Image.filters.BaseFilter + * @see {@link fabric.Image.filters.RemoveWhite#initialize} for constructor definition + * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo} + * @example + * var filter = new fabric.Image.filters.RemoveWhite({ + * threshold: 40, + * distance: 140 + * }); + * object.filters.push(filter); + * object.applyFilters(canvas.renderAll.bind(canvas)); + */ + fabric.Image.filters.RemoveWhite = fabric.util.createClass(fabric.Image.filters.BaseFilter, /** @lends fabric.Image.filters.RemoveWhite.prototype */ { + + /** + * Filter type + * @param {String} type + * @default + */ + type: 'RemoveWhite', + + /** + * Constructor + * @memberOf fabric.Image.filters.RemoveWhite.prototype + * @param {Object} [options] Options object + * @param {Number} [options.threshold=30] Threshold value + * @param {Number} [options.distance=20] Distance value + */ + initialize: function(options) { + options = options || { }; + this.threshold = options.threshold || 30; + this.distance = options.distance || 20; + }, + + /** + * Applies filter to canvas element + * @param {Object} canvasEl Canvas element to apply filter to + */ + applyTo: function(canvasEl) { + var context = canvasEl.getContext('2d'), + imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), + data = imageData.data, + threshold = this.threshold, + distance = this.distance, + limit = 255 - threshold, + abs = Math.abs, + r, g, b; + + for (var i = 0, len = data.length; i < len; i += 4) { + r = data[i]; + g = data[i + 1]; + b = data[i + 2]; + + if (r > limit && + g > limit && + b > limit && + abs(r - g) < distance && + abs(r - b) < distance && + abs(g - b) < distance + ) { + data[i + 3] = 1; + } + } + + context.putImageData(imageData, 0, 0); + }, + + /** + * Returns object representation of an instance + * @return {Object} Object representation of an instance + */ + toObject: function() { + return extend(this.callSuper('toObject'), { + threshold: this.threshold, + distance: this.distance + }); + } + }); + + /** + * Returns filter instance from an object representation + * @static + * @param {Object} object Object to create an instance from + * @return {fabric.Image.filters.RemoveWhite} Instance of fabric.Image.filters.RemoveWhite + */ + fabric.Image.filters.RemoveWhite.fromObject = function(object) { + return new fabric.Image.filters.RemoveWhite(object); + }; + +})(typeof exports !== 'undefined' ? exports : this); + + +(function(global) { + + 'use strict'; + + var fabric = global.fabric || (global.fabric = { }); + + /** + * Sepia filter class + * @class fabric.Image.filters.Sepia + * @memberOf fabric.Image.filters + * @extends fabric.Image.filters.BaseFilter + * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo} + * @example + * var filter = new fabric.Image.filters.Sepia(); + * object.filters.push(filter); + * object.applyFilters(canvas.renderAll.bind(canvas)); + */ + fabric.Image.filters.Sepia = fabric.util.createClass(fabric.Image.filters.BaseFilter, /** @lends fabric.Image.filters.Sepia.prototype */ { + + /** + * Filter type + * @param {String} type + * @default + */ + type: 'Sepia', + + /** + * Applies filter to canvas element + * @memberOf fabric.Image.filters.Sepia.prototype + * @param {Object} canvasEl Canvas element to apply filter to + */ + applyTo: function(canvasEl) { + var context = canvasEl.getContext('2d'), + imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), + data = imageData.data, + iLen = data.length, i, avg; + + for (i = 0; i < iLen; i+=4) { + avg = 0.3 * data[i] + 0.59 * data[i + 1] + 0.11 * data[i + 2]; + data[i] = avg + 100; + data[i + 1] = avg + 50; + data[i + 2] = avg + 255; + } + + context.putImageData(imageData, 0, 0); + } + }); + + /** + * Returns filter instance from an object representation + * @static + * @return {fabric.Image.filters.Sepia} Instance of fabric.Image.filters.Sepia + */ + fabric.Image.filters.Sepia.fromObject = function() { + return new fabric.Image.filters.Sepia(); + }; + +})(typeof exports !== 'undefined' ? exports : this); + + +(function(global) { + + 'use strict'; + + var fabric = global.fabric || (global.fabric = { }); + + /** + * Sepia2 filter class + * @class fabric.Image.filters.Sepia2 + * @memberOf fabric.Image.filters + * @extends fabric.Image.filters.BaseFilter + * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo} + * @example + * var filter = new fabric.Image.filters.Sepia2(); + * object.filters.push(filter); + * object.applyFilters(canvas.renderAll.bind(canvas)); + */ + fabric.Image.filters.Sepia2 = fabric.util.createClass(fabric.Image.filters.BaseFilter, /** @lends fabric.Image.filters.Sepia2.prototype */ { + + /** + * Filter type + * @param {String} type + * @default + */ + type: 'Sepia2', + + /** + * Applies filter to canvas element + * @memberOf fabric.Image.filters.Sepia.prototype + * @param {Object} canvasEl Canvas element to apply filter to + */ + applyTo: function(canvasEl) { + var context = canvasEl.getContext('2d'), + imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), + data = imageData.data, + iLen = data.length, i, r, g, b; + + for (i = 0; i < iLen; i+=4) { + r = data[i]; + g = data[i + 1]; + b = data[i + 2]; + + data[i] = (r * 0.393 + g * 0.769 + b * 0.189 ) / 1.351; + data[i + 1] = (r * 0.349 + g * 0.686 + b * 0.168 ) / 1.203; + data[i + 2] = (r * 0.272 + g * 0.534 + b * 0.131 ) / 2.140; + } + + context.putImageData(imageData, 0, 0); + } + }); + + /** + * Returns filter instance from an object representation + * @static + * @return {fabric.Image.filters.Sepia2} Instance of fabric.Image.filters.Sepia2 + */ + fabric.Image.filters.Sepia2.fromObject = function() { + return new fabric.Image.filters.Sepia2(); + }; + +})(typeof exports !== 'undefined' ? exports : this); + + +(function(global) { + + 'use strict'; + + var fabric = global.fabric || (global.fabric = { }), + extend = fabric.util.object.extend; + + /** + * Tint filter class + * Adapted from https://github.com/mezzoblue/PaintbrushJS + * @class fabric.Image.filters.Tint + * @memberOf fabric.Image.filters + * @extends fabric.Image.filters.BaseFilter + * @see {@link fabric.Image.filters.Tint#initialize} for constructor definition + * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo} + * @example Tint filter with hex color and opacity + * var filter = new fabric.Image.filters.Tint({ + * color: '#3513B0', + * opacity: 0.5 + * }); + * object.filters.push(filter); + * object.applyFilters(canvas.renderAll.bind(canvas)); + * @example Tint filter with rgba color + * var filter = new fabric.Image.filters.Tint({ + * color: 'rgba(53, 21, 176, 0.5)' + * }); + * object.filters.push(filter); + * object.applyFilters(canvas.renderAll.bind(canvas)); + */ + fabric.Image.filters.Tint = fabric.util.createClass(fabric.Image.filters.BaseFilter, /** @lends fabric.Image.filters.Tint.prototype */ { + + /** + * Filter type + * @param {String} type + * @default + */ + type: 'Tint', + + /** + * Constructor + * @memberOf fabric.Image.filters.Tint.prototype + * @param {Object} [options] Options object + * @param {String} [options.color=#000000] Color to tint the image with + * @param {Number} [options.opacity] Opacity value that controls the tint effect's transparency (0..1) + */ + initialize: function(options) { + options = options || { }; + + this.color = options.color || '#000000'; + this.opacity = typeof options.opacity !== 'undefined' + ? options.opacity + : new fabric.Color(this.color).getAlpha(); + }, + + /** + * Applies filter to canvas element + * @param {Object} canvasEl Canvas element to apply filter to + */ + applyTo: function(canvasEl) { + var context = canvasEl.getContext('2d'), + imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), + data = imageData.data, + iLen = data.length, i, + tintR, tintG, tintB, + r, g, b, alpha1, + source; + + source = new fabric.Color(this.color).getSource(); + + tintR = source[0] * this.opacity; + tintG = source[1] * this.opacity; + tintB = source[2] * this.opacity; + + alpha1 = 1 - this.opacity; + + for (i = 0; i < iLen; i+=4) { + r = data[i]; + g = data[i + 1]; + b = data[i + 2]; + + // alpha compositing + data[i] = tintR + r * alpha1; + data[i + 1] = tintG + g * alpha1; + data[i + 2] = tintB + b * alpha1; + } + + context.putImageData(imageData, 0, 0); + }, + + /** + * Returns object representation of an instance + * @return {Object} Object representation of an instance + */ + toObject: function() { + return extend(this.callSuper('toObject'), { + color: this.color, + opacity: this.opacity + }); + } + }); + + /** + * Returns filter instance from an object representation + * @static + * @param {Object} object Object to create an instance from + * @return {fabric.Image.filters.Tint} Instance of fabric.Image.filters.Tint + */ + fabric.Image.filters.Tint.fromObject = function(object) { + return new fabric.Image.filters.Tint(object); + }; + +})(typeof exports !== 'undefined' ? exports : this); + + +(function(global) { + + 'use strict'; + + var fabric = global.fabric || (global.fabric = { }), + extend = fabric.util.object.extend; + + /** + * Multiply filter class + * Adapted from http://www.laurenscorijn.com/articles/colormath-basics + * @class fabric.Image.filters.Multiply + * @memberOf fabric.Image.filters + * @extends fabric.Image.filters.BaseFilter + * @example Multiply filter with hex color + * var filter = new fabric.Image.filters.Multiply({ + * color: '#F0F' + * }); + * object.filters.push(filter); + * object.applyFilters(canvas.renderAll.bind(canvas)); + * @example Multiply filter with rgb color + * var filter = new fabric.Image.filters.Multiply({ + * color: 'rgb(53, 21, 176)' + * }); + * object.filters.push(filter); + * object.applyFilters(canvas.renderAll.bind(canvas)); + */ + fabric.Image.filters.Multiply = fabric.util.createClass(fabric.Image.filters.BaseFilter, /** @lends fabric.Image.filters.Multiply.prototype */ { + + /** + * Filter type + * @param {String} type + * @default + */ + type: 'Multiply', + + /** + * Constructor + * @memberOf fabric.Image.filters.Multiply.prototype + * @param {Object} [options] Options object + * @param {String} [options.color=#000000] Color to multiply the image pixels with + */ + initialize: function(options) { + options = options || { }; + + this.color = options.color || '#000000'; + }, + + /** + * Applies filter to canvas element + * @param {Object} canvasEl Canvas element to apply filter to + */ + applyTo: function(canvasEl) { + var context = canvasEl.getContext('2d'), + imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), + data = imageData.data, + iLen = data.length, i, + source; + + source = new fabric.Color(this.color).getSource(); + + for (i = 0; i < iLen; i+=4) { + data[i] *= source[0] / 255; + data[i + 1] *= source[1] / 255; + data[i + 2] *= source[2] / 255; + } + + context.putImageData(imageData, 0, 0); + }, + + /** + * Returns object representation of an instance + * @return {Object} Object representation of an instance + */ + toObject: function() { + return extend(this.callSuper('toObject'), { + color: this.color + }); + } + }); + + /** + * Returns filter instance from an object representation + * @static + * @param {Object} object Object to create an instance from + * @return {fabric.Image.filters.Multiply} Instance of fabric.Image.filters.Multiply + */ + fabric.Image.filters.Multiply.fromObject = function(object) { + return new fabric.Image.filters.Multiply(object); + }; + +})(typeof exports !== 'undefined' ? exports : this); + + +(function(global) { + 'use strict'; + + var fabric = global.fabric; + + /** + * Color Blend filter class + * @class fabric.Image.filter.Blend + * @memberOf fabric.Image.filters + * @extends fabric.Image.filters.BaseFilter + * @example + * var filter = new fabric.Image.filters.Blend({ + * color: '#000', + * mode: 'multiply' + * }); + * + * var filter = new fabric.Image.filters.Blend({ + * image: fabricImageObject, + * mode: 'multiply', + * alpha: 0.5 + * }); + + * object.filters.push(filter); + * object.applyFilters(canvas.renderAll.bind(canvas)); + */ + fabric.Image.filters.Blend = fabric.util.createClass({ + type: 'Blend', + + initialize: function(options) { + options = options || {}; + this.color = options.color || '#000'; + this.image = options.image || false; + this.mode = options.mode || 'multiply'; + this.alpha = options.alpha || 1; + }, + + applyTo: function(canvasEl) { + var context = canvasEl.getContext('2d'), + imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height), + data = imageData.data, + tr, tg, tb, + r, g, b, + _r, _g, _b, + source, + isImage = false; + + if (this.image) { + // Blend images + isImage = true; + + var _el = fabric.util.createCanvasElement(); + _el.width = this.image.width; + _el.height = this.image.height; + + var tmpCanvas = new fabric.StaticCanvas(_el); + tmpCanvas.add(this.image); + var context2 = tmpCanvas.getContext('2d'); + source = context2.getImageData(0, 0, tmpCanvas.width, tmpCanvas.height).data; + } + else { + // Blend color + source = new fabric.Color(this.color).getSource(); + + tr = source[0] * this.alpha; + tg = source[1] * this.alpha; + tb = source[2] * this.alpha; + } + + for (var i = 0, len = data.length; i < len; i += 4) { + + r = data[i]; + g = data[i + 1]; + b = data[i + 2]; + + if (isImage) { + tr = source[i] * this.alpha; + tg = source[i + 1] * this.alpha; + tb = source[i + 2] * this.alpha; + } + + switch (this.mode) { + case 'multiply': + data[i] = r * tr / 255; + data[i + 1] = g * tg / 255; + data[i + 2] = b * tb / 255; + break; + case 'screen': + data[i] = 1 - (1 - r) * (1 - tr); + data[i + 1] = 1 - (1 - g) * (1 - tg); + data[i + 2] = 1 - (1 - b) * (1 - tb); + break; + case 'add': + data[i] = Math.min(255, r + tr); + data[i + 1] = Math.min(255, g + tg); + data[i + 2] = Math.min(255, b + tb); + break; + case 'diff': + case 'difference': + data[i] = Math.abs(r - tr); + data[i + 1] = Math.abs(g - tg); + data[i + 2] = Math.abs(b - tb); + break; + case 'subtract': + _r = r - tr; + _g = g - tg; + _b = b - tb; + + data[i] = (_r < 0) ? 0 : _r; + data[i + 1] = (_g < 0) ? 0 : _g; + data[i + 2] = (_b < 0) ? 0 : _b; + break; + case 'darken': + data[i] = Math.min(r, tr); + data[i + 1] = Math.min(g, tg); + data[i + 2] = Math.min(b, tb); + break; + case 'lighten': + data[i] = Math.max(r, tr); + data[i + 1] = Math.max(g, tg); + data[i + 2] = Math.max(b, tb); + break; + } + } + + context.putImageData(imageData, 0, 0); + }, + + /** + * Returns object representation of an instance + * @return {Object} Object representation of an instance + */ + toObject: function() { + return { + color: this.color, + image: this.image, + mode: this.mode, + alpha: this.alpha + }; + } + }); + + fabric.Image.filters.Blend.fromObject = function(object) { + return new fabric.Image.filters.Blend(object); + }; +})(typeof exports !== 'undefined' ? exports : this); + + +(function(global) { + + 'use strict'; + + var fabric = global.fabric || (global.fabric = { }), pow = Math.pow, floor = Math.floor, + sqrt = Math.sqrt, abs = Math.abs, max = Math.max, round = Math.round, sin = Math.sin, + ceil = Math.ceil; + + /** + * Resize image filter class + * @class fabric.Image.filters.Resize + * @memberOf fabric.Image.filters + * @extends fabric.Image.filters.BaseFilter + * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo} + * @example + * var filter = new fabric.Image.filters.Resize(); + * object.filters.push(filter); + * object.applyFilters(canvas.renderAll.bind(canvas)); + */ + fabric.Image.filters.Resize = fabric.util.createClass(fabric.Image.filters.BaseFilter, /** @lends fabric.Image.filters.Resize.prototype */ { + + /** + * Filter type + * @param {String} type + * @default + */ + type: 'Resize', + + /** + * Resize type + * @param {String} resizeType + * @default + */ + resizeType: 'hermite', + + /** + * Scale factor for resizing, x axis + * @param {Number} scaleX + * @default + */ + scaleX: 0, + + /** + * Scale factor for resizing, y axis + * @param {Number} scaleY + * @default + */ + scaleY: 0, + + /** + * LanczosLobes parameter for lanczos filter + * @param {Number} lanczosLobes + * @default + */ + lanczosLobes: 3, + + /** + * Applies filter to canvas element + * @memberOf fabric.Image.filters.Resize.prototype + * @param {Object} canvasEl Canvas element to apply filter to + */ + applyTo: function(canvasEl, scaleX, scaleY) { + + this.rcpScaleX = 1 / scaleX; + this.rcpScaleY = 1 / scaleY; + + var oW = canvasEl.width, oH = canvasEl.height, + dW = round(oW * scaleX), dH = round(oH * scaleY), + imageData; + + if (this.resizeType === 'sliceHack') { + imageData = this.sliceByTwo(canvasEl, oW, oH, dW, dH); + } + if (this.resizeType === 'hermite') { + imageData = this.hermiteFastResize(canvasEl, oW, oH, dW, dH); + } + if (this.resizeType === 'bilinear') { + imageData = this.bilinearFiltering(canvasEl, oW, oH, dW, dH); + } + if (this.resizeType === 'lanczos') { + imageData = this.lanczosResize(canvasEl, oW, oH, dW, dH); + } + canvasEl.width = dW; + canvasEl.height = dH; + canvasEl.getContext('2d').putImageData(imageData, 0, 0); + }, + + sliceByTwo: function(canvasEl, width, height, newWidth, newHeight) { + var context = canvasEl.getContext('2d'), imageData, + multW = 0.5, multH = 0.5, signW = 1, signH = 1, + doneW = false, doneH = false, stepW = width, stepH = height, + tmpCanvas = fabric.util.createCanvasElement(), + tmpCtx = tmpCanvas.getContext('2d'); + newWidth = floor(newWidth); + newHeight = floor(newHeight); + tmpCanvas.width = max(newWidth, width); + tmpCanvas.height = max(newHeight, height); + + if (newWidth > width) { + multW = 2; + signW = -1; + } + if (newHeight > height) { + multH = 2; + signH = -1; + } + imageData = context.getImageData(0, 0, width, height); + canvasEl.width = max(newWidth, width); + canvasEl.height = max(newHeight, height); + context.putImageData(imageData, 0, 0); + + while (!doneW || !doneH) { + width = stepW; + height = stepH; + if (newWidth * signW < floor(stepW * multW * signW)) { + stepW = floor(stepW * multW); + } + else { + stepW = newWidth; + doneW = true; + } + if (newHeight * signH < floor(stepH * multH * signH)) { + stepH = floor(stepH * multH); + } + else { + stepH = newHeight; + doneH = true; + } + imageData = context.getImageData(0, 0, width, height); + tmpCtx.putImageData(imageData, 0, 0); + context.clearRect(0, 0, stepW, stepH); + context.drawImage(tmpCanvas, 0, 0, width, height, 0, 0, stepW, stepH); + } + return context.getImageData(0, 0, newWidth, newHeight); + }, + + lanczosResize: function(canvasEl, oW, oH, dW, dH) { + + function lanczosCreate(lobes) { + return function(x) { + if (x > lobes) { + return 0; + } + x *= Math.PI; + if (abs(x) < 1e-16) { + return 1; + } + var xx = x / lobes; + return sin(x) * sin(xx) / x / xx; + }; + } + + function process(u) { + var v, i, weight, idx, a, red, green, + blue, alpha, fX, fY; + center.x = (u + 0.5) * ratioX; + icenter.x = floor(center.x); + for (v = 0; v < dH; v++) { + center.y = (v + 0.5) * ratioY; + icenter.y = floor(center.y); + a = 0, red = 0, green = 0, blue = 0, alpha = 0; + for (i = icenter.x - range2X; i <= icenter.x + range2X; i++) { + if (i < 0 || i >= oW) { + continue; + } + fX = floor(1000 * abs(i - center.x)); + if (!cacheLanc[fX]) { + cacheLanc[fX] = { }; + } + for (var j = icenter.y - range2Y; j <= icenter.y + range2Y; j++) { + if (j < 0 || j >= oH) { + continue; + } + fY = floor(1000 * abs(j - center.y)); + if (!cacheLanc[fX][fY]) { + cacheLanc[fX][fY] = lanczos(sqrt(pow(fX * rcpRatioX, 2) + pow(fY * rcpRatioY, 2)) / 1000); + } + weight = cacheLanc[fX][fY]; + if (weight > 0) { + idx = (j * oW + i) * 4; + a += weight; + red += weight * srcData[idx]; + green += weight * srcData[idx + 1]; + blue += weight * srcData[idx + 2]; + alpha += weight * srcData[idx + 3]; + } + } + } + idx = (v * dW + u) * 4; + destData[idx] = red / a; + destData[idx + 1] = green / a; + destData[idx + 2] = blue / a; + destData[idx + 3] = alpha / a; + } + + if (++u < dW) { + return process(u); + } + else { + return destImg; + } + } + + var context = canvasEl.getContext('2d'), + srcImg = context.getImageData(0, 0, oW, oH), + destImg = context.getImageData(0, 0, dW, dH), + srcData = srcImg.data, destData = destImg.data, + lanczos = lanczosCreate(this.lanczosLobes), + ratioX = this.rcpScaleX, ratioY = this.rcpScaleY, + rcpRatioX = 2 / this.rcpScaleX, rcpRatioY = 2 / this.rcpScaleY, + range2X = ceil(ratioX * this.lanczosLobes / 2), + range2Y = ceil(ratioY * this.lanczosLobes / 2), + cacheLanc = { }, center = { }, icenter = { }; + + return process(0); + }, + + bilinearFiltering: function(canvasEl, w, h, w2, h2) { + var a, b, c, d, x, y, i, j, xDiff, yDiff, chnl, + color, offset = 0, origPix, ratioX = this.rcpScaleX, + ratioY = this.rcpScaleY, context = canvasEl.getContext('2d'), + w4 = 4 * (w - 1), img = context.getImageData(0, 0, w, h), + pixels = img.data, destImage = context.getImageData(0, 0, w2, h2), + destPixels = destImage.data; + for (i = 0; i < h2; i++) { + for (j = 0; j < w2; j++) { + x = floor(ratioX * j); + y = floor(ratioY * i); + xDiff = ratioX * j - x; + yDiff = ratioY * i - y; + origPix = 4 * (y * w + x); + + for (chnl = 0; chnl < 4; chnl++) { + a = pixels[origPix + chnl]; + b = pixels[origPix + 4 + chnl]; + c = pixels[origPix + w4 + chnl]; + d = pixels[origPix + w4 + 4 + chnl]; + color = a * (1 - xDiff) * (1 - yDiff) + b * xDiff * (1 - yDiff) + + c * yDiff * (1 - xDiff) + d * xDiff * yDiff; + destPixels[offset++] = color; + } + } + } + return destImage; + }, + + hermiteFastResize: function(canvasEl, oW, oH, dW, dH) { + var ratioW = this.rcpScaleX, ratioH = this.rcpScaleY, + ratioWHalf = ceil(ratioW / 2), + ratioHHalf = ceil(ratioH / 2), + context = canvasEl.getContext('2d'), + img = context.getImageData(0, 0, oW, oH), data = img.data, + img2 = context.getImageData(0, 0, dW, dH), data2 = img2.data; + for (var j = 0; j < dH; j++) { + for (var i = 0; i < dW; i++) { + var x2 = (i + j * dW) * 4, weight = 0, weights = 0, weightsAlpha = 0, + gxR = 0, gxG = 0, gxB = 0, gxA = 0, centerY = (j + 0.5) * ratioH; + for (var yy = floor(j * ratioH); yy < (j + 1) * ratioH; yy++) { + var dy = abs(centerY - (yy + 0.5)) / ratioHHalf, + centerX = (i + 0.5) * ratioW, w0 = dy * dy; + for (var xx = floor(i * ratioW); xx < (i + 1) * ratioW; xx++) { + var dx = abs(centerX - (xx + 0.5)) / ratioWHalf, + w = sqrt(w0 + dx * dx); + /*jshint maxdepth:5 */ + if (w > 1 && w < -1) { + continue; + } + //hermite filter + weight = 2 * w * w * w - 3 * w * w + 1; + if (weight > 0) { + dx = 4 * (xx + yy * oW); + //alpha + gxA += weight * data[dx + 3]; + weightsAlpha += weight; + //colors + /*jshint maxdepth:6 */ + if (data[dx + 3] < 255) { + weight = weight * data[dx + 3] / 250; + } + /*jshint maxdepth:5 */ + gxR += weight * data[dx]; + gxG += weight * data[dx + 1]; + gxB += weight * data[dx + 2]; + weights += weight; + } + /*jshint maxdepth:4 */ + } + } + data2[x2] = gxR / weights; + data2[x2 + 1] = gxG / weights; + data2[x2 + 2] = gxB / weights; + data2[x2 + 3] = gxA / weightsAlpha; + } + } + return img2; + }, + + /** + * Returns object representation of an instance + * @return {Object} Object representation of an instance + */ + toObject: function() { + return { + type: this.type, + scaleX: this.scaleX, + scaley: this.scaleY, + resizeType: this.resizeType, + lanczosLobes: this.lanczosLobes + }; + } + }); + + /** + * Returns filter instance from an object representation + * @static + * @return {fabric.Image.filters.Resize} Instance of fabric.Image.filters.Resize + */ + fabric.Image.filters.Resize.fromObject = function() { + return new fabric.Image.filters.Resize(); + }; + +})(typeof exports !== 'undefined' ? exports : this); + + +(function(global) { + + 'use strict'; + + var fabric = global.fabric || (global.fabric = { }), + extend = fabric.util.object.extend, + clone = fabric.util.object.clone, + toFixed = fabric.util.toFixed, + supportsLineDash = fabric.StaticCanvas.supports('setLineDash'); + + if (fabric.Text) { + fabric.warn('fabric.Text is already defined'); + return; + } + + var stateProperties = fabric.Object.prototype.stateProperties.concat(); + stateProperties.push( + 'fontFamily', + 'fontWeight', + 'fontSize', + 'text', + 'textDecoration', + 'textAlign', + 'fontStyle', + 'lineHeight', + 'textBackgroundColor' + ); + + /** + * Text class + * @class fabric.Text + * @extends fabric.Object + * @return {fabric.Text} thisArg + * @tutorial {@link http://fabricjs.com/fabric-intro-part-2/#text} + * @see {@link fabric.Text#initialize} for constructor definition + */ + fabric.Text = fabric.util.createClass(fabric.Object, /** @lends fabric.Text.prototype */ { + + /** + * Properties which when set cause object to change dimensions + * @type Object + * @private + */ + _dimensionAffectingProps: { + fontSize: true, + fontWeight: true, + fontFamily: true, + fontStyle: true, + lineHeight: true, + stroke: true, + strokeWidth: true, + text: true, + textAlign: true + }, + + /** + * @private + */ + _reNewline: /\r?\n/, + + /** + * Retrieves object's fontSize + * @method getFontSize + * @memberOf fabric.Text.prototype + * @return {String} Font size (in pixels) + */ + + /** + * Sets object's fontSize + * @method setFontSize + * @memberOf fabric.Text.prototype + * @param {Number} fontSize Font size (in pixels) + * @return {fabric.Text} + * @chainable + */ + + /** + * Retrieves object's fontWeight + * @method getFontWeight + * @memberOf fabric.Text.prototype + * @return {(String|Number)} Font weight + */ + + /** + * Sets object's fontWeight + * @method setFontWeight + * @memberOf fabric.Text.prototype + * @param {(Number|String)} fontWeight Font weight + * @return {fabric.Text} + * @chainable + */ + + /** + * Retrieves object's fontFamily + * @method getFontFamily + * @memberOf fabric.Text.prototype + * @return {String} Font family + */ + + /** + * Sets object's fontFamily + * @method setFontFamily + * @memberOf fabric.Text.prototype + * @param {String} fontFamily Font family + * @return {fabric.Text} + * @chainable + */ + + /** + * Retrieves object's text + * @method getText + * @memberOf fabric.Text.prototype + * @return {String} text + */ + + /** + * Sets object's text + * @method setText + * @memberOf fabric.Text.prototype + * @param {String} text Text + * @return {fabric.Text} + * @chainable + */ + + /** + * Retrieves object's textDecoration + * @method getTextDecoration + * @memberOf fabric.Text.prototype + * @return {String} Text decoration + */ + + /** + * Sets object's textDecoration + * @method setTextDecoration + * @memberOf fabric.Text.prototype + * @param {String} textDecoration Text decoration + * @return {fabric.Text} + * @chainable + */ + + /** + * Retrieves object's fontStyle + * @method getFontStyle + * @memberOf fabric.Text.prototype + * @return {String} Font style + */ + + /** + * Sets object's fontStyle + * @method setFontStyle + * @memberOf fabric.Text.prototype + * @param {String} fontStyle Font style + * @return {fabric.Text} + * @chainable + */ + + /** + * Retrieves object's lineHeight + * @method getLineHeight + * @memberOf fabric.Text.prototype + * @return {Number} Line height + */ + + /** + * Sets object's lineHeight + * @method setLineHeight + * @memberOf fabric.Text.prototype + * @param {Number} lineHeight Line height + * @return {fabric.Text} + * @chainable + */ + + /** + * Retrieves object's textAlign + * @method getTextAlign + * @memberOf fabric.Text.prototype + * @return {String} Text alignment + */ + + /** + * Sets object's textAlign + * @method setTextAlign + * @memberOf fabric.Text.prototype + * @param {String} textAlign Text alignment + * @return {fabric.Text} + * @chainable + */ + + /** + * Retrieves object's textBackgroundColor + * @method getTextBackgroundColor + * @memberOf fabric.Text.prototype + * @return {String} Text background color + */ + + /** + * Sets object's textBackgroundColor + * @method setTextBackgroundColor + * @memberOf fabric.Text.prototype + * @param {String} textBackgroundColor Text background color + * @return {fabric.Text} + * @chainable + */ + + /** + * Type of an object + * @type String + * @default + */ + type: 'text', + + /** + * Font size (in pixels) + * @type Number + * @default + */ + fontSize: 40, + + /** + * Font weight (e.g. bold, normal, 400, 600, 800) + * @type {(Number|String)} + * @default + */ + fontWeight: 'normal', + + /** + * Font family + * @type String + * @default + */ + fontFamily: 'Times New Roman', + + /** + * Text decoration Possible values: "", "underline", "overline" or "line-through". + * @type String + * @default + */ + textDecoration: '', + + /** + * Text alignment. Possible values: "left", "center", or "right". + * @type String + * @default + */ + textAlign: 'left', + + /** + * Font style . Possible values: "", "normal", "italic" or "oblique". + * @type String + * @default + */ + fontStyle: '', + + /** + * Line height + * @type Number + * @default + */ + lineHeight: 1.16, + + /** + * Background color of text lines + * @type String + * @default + */ + textBackgroundColor: '', + + /** + * List of properties to consider when checking if + * state of an object is changed ({@link fabric.Object#hasStateChanged}) + * as well as for history (undo/redo) purposes + * @type Array + */ + stateProperties: stateProperties, + + /** + * When defined, an object is rendered via stroke and this property specifies its color. + * Backwards incompatibility note: This property was named "strokeStyle" until v1.1.6 + * @type String + * @default + */ + stroke: null, + + /** + * Shadow object representing shadow of this shape. + * Backwards incompatibility note: This property was named "textShadow" (String) until v1.2.11 + * @type fabric.Shadow + * @default + */ + shadow: null, + + /** + * @private + */ + _fontSizeFraction: 0.25, + + /** + * Text Line proportion to font Size (in pixels) + * @type Number + * @default + */ + _fontSizeMult: 1.13, + + /** + * Constructor + * @param {String} text Text string + * @param {Object} [options] Options object + * @return {fabric.Text} thisArg + */ + initialize: function(text, options) { + options = options || { }; + this.text = text; + this.__skipDimension = true; + this.setOptions(options); + this.__skipDimension = false; + this._initDimensions(); + }, + + /** + * Renders text object on offscreen canvas, so that it would get dimensions + * @private + */ + _initDimensions: function(ctx) { + if (this.__skipDimension) { + return; + } + if (!ctx) { + ctx = fabric.util.createCanvasElement().getContext('2d'); + this._setTextStyles(ctx); + } + this._textLines = this.text.split(this._reNewline); + this._clearCache(); + var currentTextAlign = this.textAlign; + this.textAlign = 'left'; + this.width = this._getTextWidth(ctx); + this.textAlign = currentTextAlign; + this.height = this._getTextHeight(ctx); + }, + + /** + * Returns string representation of an instance + * @return {String} String representation of text object + */ + toString: function() { + return '#'; + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _render: function(ctx) { + + this.clipTo && fabric.util.clipContext(this, ctx); + + this._renderTextBackground(ctx); + this._renderText(ctx); + + this._renderTextDecoration(ctx); + this.clipTo && ctx.restore(); + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderText: function(ctx) { + ctx.save(); + this._translateForTextAlign(ctx); + this._setOpacity(ctx); + this._setShadow(ctx); + this._setupCompositeOperation(ctx); + this._renderTextFill(ctx); + this._renderTextStroke(ctx); + this._restoreCompositeOperation(ctx); + this._removeShadow(ctx); + ctx.restore(); + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _translateForTextAlign: function(ctx) { + if (this.textAlign !== 'left' && this.textAlign !== 'justify') { + ctx.translate(this.textAlign === 'center' ? (this.width / 2) : this.width, 0); + } + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _setTextStyles: function(ctx) { + ctx.textBaseline = 'alphabetic'; + if (!this.skipTextAlign) { + ctx.textAlign = this.textAlign; + } + ctx.font = this._getFontDeclaration(); + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + * @return {Number} Height of fabric.Text object + */ + _getTextHeight: function() { + return this._textLines.length * this._getHeightOfLine(); + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + * @return {Number} Maximum width of fabric.Text object + */ + _getTextWidth: function(ctx) { + var maxWidth = this._getLineWidth(ctx, 0); + + for (var i = 1, len = this._textLines.length; i < len; i++) { + var currentLineWidth = this._getLineWidth(ctx, i); + if (currentLineWidth > maxWidth) { + maxWidth = currentLineWidth; + } + } + return maxWidth; + }, + + /** + * @private + * @param {String} method Method name ("fillText" or "strokeText") + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {String} chars Chars to render + * @param {Number} left Left position of text + * @param {Number} top Top position of text + */ + _renderChars: function(method, ctx, chars, left, top) { + ctx[method](chars, left, top); + }, + + /** + * @private + * @param {String} method Method name ("fillText" or "strokeText") + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {String} line Text to render + * @param {Number} left Left position of text + * @param {Number} top Top position of text + * @param {Number} lineIndex Index of a line in a text + */ + _renderTextLine: function(method, ctx, line, left, top, lineIndex) { + // lift the line by quarter of fontSize + top -= this.fontSize * this._fontSizeFraction; + + // short-circuit + if (this.textAlign !== 'justify') { + this._renderChars(method, ctx, line, left, top, lineIndex); + return; + } + + var lineWidth = this._getLineWidth(ctx, lineIndex), + totalWidth = this.width; + if (totalWidth >= lineWidth) { + // stretch the line + var words = line.split(/\s+/), + wordsWidth = this._getWidthOfWords(ctx, line, lineIndex), + widthDiff = totalWidth - wordsWidth, + numSpaces = words.length - 1, + spaceWidth = widthDiff / numSpaces, + leftOffset = 0; + + for (var i = 0, len = words.length; i < len; i++) { + this._renderChars(method, ctx, words[i], left + leftOffset, top, lineIndex); + leftOffset += ctx.measureText(words[i]).width + spaceWidth; + } + } + else { + this._renderChars(method, ctx, line, left, top, lineIndex); + } + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {Number} line + */ + _getWidthOfWords: function (ctx, line) { + return ctx.measureText(line.replace(/\s+/g, '')).width; + }, + + /** + * @private + * @return {Number} Left offset + */ + _getLeftOffset: function() { + return -this.width / 2; + }, + + /** + * @private + * @return {Number} Top offset + */ + _getTopOffset: function() { + return -this.height / 2; + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderTextFill: function(ctx) { + if (!this.fill && !this._skipFillStrokeCheck) { + return; + } + + var lineHeights = 0; + + for (var i = 0, len = this._textLines.length; i < len; i++) { + var heightOfLine = this._getHeightOfLine(ctx, i), + maxHeight = heightOfLine / this.lineHeight; + + this._renderTextLine( + 'fillText', + ctx, + this._textLines[i], + this._getLeftOffset(), + this._getTopOffset() + lineHeights + maxHeight, + i + ); + lineHeights += heightOfLine; + } + if (this.shadow && !this.shadow.affectStroke) { + this._removeShadow(ctx); + } + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderTextStroke: function(ctx) { + if ((!this.stroke || this.strokeWidth === 0) && !this._skipFillStrokeCheck) { + return; + } + + var lineHeights = 0; + + ctx.save(); + + if (this.strokeDashArray) { + // Spec requires the concatenation of two copies the dash list when the number of elements is odd + if (1 & this.strokeDashArray.length) { + this.strokeDashArray.push.apply(this.strokeDashArray, this.strokeDashArray); + } + supportsLineDash && ctx.setLineDash(this.strokeDashArray); + } + + ctx.beginPath(); + for (var i = 0, len = this._textLines.length; i < len; i++) { + var heightOfLine = this._getHeightOfLine(ctx, i), + maxHeight = heightOfLine / this.lineHeight; + + this._renderTextLine( + 'strokeText', + ctx, + this._textLines[i], + this._getLeftOffset(), + this._getTopOffset() + lineHeights + maxHeight, + i + ); + lineHeights += heightOfLine; + } + ctx.closePath(); + ctx.restore(); + }, + + _getHeightOfLine: function() { + return this.fontSize * this._fontSizeMult * this.lineHeight; + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {Array} textLines Array of all text lines + */ + _renderTextBackground: function(ctx) { + this._renderTextBoxBackground(ctx); + this._renderTextLinesBackground(ctx); + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderTextBoxBackground: function(ctx) { + if (!this.backgroundColor) { + return; + } + + ctx.save(); + ctx.fillStyle = this.backgroundColor; + + ctx.fillRect( + this._getLeftOffset(), + this._getTopOffset(), + this.width, + this.height + ); + + ctx.restore(); + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderTextLinesBackground: function(ctx) { + var lineTopOffset = 0, heightOfLine = this._getHeightOfLine(); + if (!this.textBackgroundColor) { + return; + } + + ctx.save(); + ctx.fillStyle = this.textBackgroundColor; + + for (var i = 0, len = this._textLines.length; i < len; i++) { + + if (this._textLines[i] !== '') { + + var lineWidth = this._getLineWidth(ctx, i), + lineLeftOffset = this._getLineLeftOffset(lineWidth); + + ctx.fillRect( + this._getLeftOffset() + lineLeftOffset, + this._getTopOffset() + lineTopOffset, + lineWidth, + this.fontSize * this._fontSizeMult + ); + } + lineTopOffset += heightOfLine; + } + ctx.restore(); + }, + + /** + * @private + * @param {Number} lineWidth Width of text line + * @return {Number} Line left offset + */ + _getLineLeftOffset: function(lineWidth) { + if (this.textAlign === 'center') { + return (this.width - lineWidth) / 2; + } + if (this.textAlign === 'right') { + return this.width - lineWidth; + } + return 0; + }, + + /** + * @private + */ + _clearCache: function() { + this.__lineWidths = [ ]; + this.__lineHeights = [ ]; + this.__lineOffsets = [ ]; + }, + + /** + * @private + */ + _shouldClearCache: function() { + var shouldClear = false; + for (var prop in this._dimensionAffectingProps) { + if (this['__' + prop] !== this[prop]) { + this['__' + prop] = this[prop]; + shouldClear = true; + } + } + return shouldClear; + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + * @return {Number} Line width + */ + _getLineWidth: function(ctx, lineIndex) { + if (this.__lineWidths[lineIndex]) { + return this.__lineWidths[lineIndex]; + } + this.__lineWidths[lineIndex] = ctx.measureText(this._textLines[lineIndex]).width; + return this.__lineWidths[lineIndex]; + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderTextDecoration: function(ctx) { + if (!this.textDecoration) { + return; + } + + var halfOfVerticalBox = this.height / 2, + _this = this, offsets = []; + + /** @ignore */ + function renderLinesAtOffset(offsets) { + var i, lineHeight = 0, len, j, oLen; + for (i = 0, len = _this._textLines.length; i < len; i++) { + + var lineWidth = _this._getLineWidth(ctx, i), + lineLeftOffset = _this._getLineLeftOffset(lineWidth), + heightOfLine = _this._getHeightOfLine(ctx, i); + + for (j = 0, oLen = offsets.length; j < oLen; j++) { + ctx.fillRect( + _this._getLeftOffset() + lineLeftOffset, + lineHeight + (_this._fontSizeMult - 1 + offsets[j] ) * _this.fontSize - halfOfVerticalBox, + lineWidth, + _this.fontSize / 15); + } + lineHeight += heightOfLine; + } + } + + if (this.textDecoration.indexOf('underline') > -1) { + offsets.push(0.85); // 1 - 3/16 + } + if (this.textDecoration.indexOf('line-through') > -1) { + offsets.push(0.43); + } + if (this.textDecoration.indexOf('overline') > -1) { + offsets.push(-0.12); + } + + if (offsets.length > 0) { + renderLinesAtOffset(offsets); + } + }, + + /** + * @private + */ + _getFontDeclaration: function() { + return [ + // node-canvas needs "weight style", while browsers need "style weight" + (fabric.isLikelyNode ? this.fontWeight : this.fontStyle), + (fabric.isLikelyNode ? this.fontStyle : this.fontWeight), + this.fontSize + 'px', + (fabric.isLikelyNode ? ('"' + this.fontFamily + '"') : this.fontFamily) + ].join(' '); + }, + + /** + * Renders text instance on a specified context + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + render: function(ctx, noTransform) { + // do not render if object is not visible + if (!this.visible) { + return; + } + + ctx.save(); + this._setTextStyles(ctx); + + if (this._shouldClearCache()) { + this._initDimensions(ctx); + } + if (!noTransform) { + this.transform(ctx); + } + this._setStrokeStyles(ctx); + this._setFillStyles(ctx); + if (this.transformMatrix) { + ctx.transform.apply(ctx, this.transformMatrix); + } + if (this.group && this.group.type === 'path-group') { + ctx.translate(this.left, this.top); + } + this._render(ctx); + ctx.restore(); + }, + + /** + * Returns object representation of an instance + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} Object representation of an instance + */ + toObject: function(propertiesToInclude) { + var object = extend(this.callSuper('toObject', propertiesToInclude), { + text: this.text, + fontSize: this.fontSize, + fontWeight: this.fontWeight, + fontFamily: this.fontFamily, + fontStyle: this.fontStyle, + lineHeight: this.lineHeight, + textDecoration: this.textDecoration, + textAlign: this.textAlign, + textBackgroundColor: this.textBackgroundColor + }); + if (!this.includeDefaultValues) { + this._removeDefaultValues(object); + } + return object; + }, + + /* _TO_SVG_START_ */ + /** + * Returns SVG representation of an instance + * @param {Function} [reviver] Method for further parsing of svg representation. + * @return {String} svg representation of an instance + */ + toSVG: function(reviver) { + var markup = this._createBaseSVGMarkup(), + offsets = this._getSVGLeftTopOffsets(this.ctx), + textAndBg = this._getSVGTextAndBg(offsets.textTop, offsets.textLeft); + this._wrapSVGTextAndBg(markup, textAndBg); + + return reviver ? reviver(markup.join('')) : markup.join(''); + }, + + /** + * @private + */ + _getSVGLeftTopOffsets: function(ctx) { + var lineTop = this._getHeightOfLine(ctx, 0), + textLeft = -this.width / 2, + textTop = 0; + + return { + textLeft: textLeft + (this.group && this.group.type === 'path-group' ? this.left : 0), + textTop: textTop + (this.group && this.group.type === 'path-group' ? -this.top : 0), + lineTop: lineTop + }; + }, + + /** + * @private + */ + _wrapSVGTextAndBg: function(markup, textAndBg) { + markup.push( + '\t\n', + textAndBg.textBgRects.join(''), + '\t\t', + textAndBg.textSpans.join(''), + '\n', + '\t\n' + ); + }, + + /** + * @private + * @param {Number} textTopOffset Text top offset + * @param {Number} textLeftOffset Text left offset + * @return {Object} + */ + _getSVGTextAndBg: function(textTopOffset, textLeftOffset) { + var textSpans = [ ], + textBgRects = [ ], + height = 0; + // bounding-box background + this._setSVGBg(textBgRects); + + // text and text-background + for (var i = 0, len = this._textLines.length; i < len; i++) { + if (this.textBackgroundColor) { + this._setSVGTextLineBg(textBgRects, i, textLeftOffset, textTopOffset, height); + } + this._setSVGTextLineText(i, textSpans, height, textLeftOffset, textTopOffset, textBgRects); + height += this._getHeightOfLine(this.ctx, i); + } + + return { + textSpans: textSpans, + textBgRects: textBgRects + }; + }, + + _setSVGTextLineText: function(i, textSpans, height, textLeftOffset, textTopOffset) { + var yPos = this.fontSize * (this._fontSizeMult - this._fontSizeFraction) + - textTopOffset + height - this.height / 2; + textSpans.push( + ' elements since setting opacity + // on containing one doesn't work in Illustrator + this._getFillAttributes(this.fill), '>', + fabric.util.string.escapeXml(this._textLines[i]), + '' + ); + }, + + _setSVGTextLineBg: function(textBgRects, i, textLeftOffset, textTopOffset, height) { + textBgRects.push( + '\t\t\n'); + }, + + _setSVGBg: function(textBgRects) { + if (this.backgroundColor) { + textBgRects.push( + '\t\t\n'); + } + }, + + /** + * Adobe Illustrator (at least CS5) is unable to render rgba()-based fill values + * we work around it by "moving" alpha channel into opacity attribute and setting fill's alpha to 1 + * + * @private + * @param {Any} value + * @return {String} + */ + _getFillAttributes: function(value) { + var fillColor = (value && typeof value === 'string') ? new fabric.Color(value) : ''; + if (!fillColor || !fillColor.getSource() || fillColor.getAlpha() === 1) { + return 'fill="' + value + '"'; + } + return 'opacity="' + fillColor.getAlpha() + '" fill="' + fillColor.setAlpha(1).toRgb() + '"'; + }, + /* _TO_SVG_END_ */ + + /** + * Sets specified property to a specified value + * @param {String} key + * @param {Any} value + * @return {fabric.Text} thisArg + * @chainable + */ + _set: function(key, value) { + this.callSuper('_set', key, value); + + if (key in this._dimensionAffectingProps) { + this._initDimensions(); + this.setCoords(); + } + }, + + /** + * Returns complexity of an instance + * @return {Number} complexity + */ + complexity: function() { + return 1; + } + }); + + /* _FROM_SVG_START_ */ + /** + * List of attribute names to account for when parsing SVG element (used by {@link fabric.Text.fromElement}) + * @static + * @memberOf fabric.Text + * @see: http://www.w3.org/TR/SVG/text.html#TextElement + */ + fabric.Text.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat( + 'x y dx dy font-family font-style font-weight font-size text-decoration text-anchor'.split(' ')); + + /** + * Default SVG font size + * @static + * @memberOf fabric.Text + */ + fabric.Text.DEFAULT_SVG_FONT_SIZE = 16; + + /** + * Returns fabric.Text instance from an SVG element (not yet implemented) + * @static + * @memberOf fabric.Text + * @param {SVGElement} element Element to parse + * @param {Object} [options] Options object + * @return {fabric.Text} Instance of fabric.Text + */ + fabric.Text.fromElement = function(element, options) { + if (!element) { + return null; + } + + var parsedAttributes = fabric.parseAttributes(element, fabric.Text.ATTRIBUTE_NAMES); + options = fabric.util.object.extend((options ? fabric.util.object.clone(options) : { }), parsedAttributes); + + options.top = options.top || 0; + options.left = options.left || 0; + if ('dx' in parsedAttributes) { + options.left += parsedAttributes.dx; + } + if ('dy' in parsedAttributes) { + options.top += parsedAttributes.dy; + } + if (!('fontSize' in options)) { + options.fontSize = fabric.Text.DEFAULT_SVG_FONT_SIZE; + } + + if (!options.originX) { + options.originX = 'left'; + } + var textContent = element.textContent.replace(/^\s+|\s+$|\n+/g, '').replace(/\s+/g, ' '), + text = new fabric.Text(textContent, options), + /* + Adjust positioning: + x/y attributes in SVG correspond to the bottom-left corner of text bounding box + top/left properties in Fabric correspond to center point of text bounding box + */ + offX = 0; + + if (text.originX === 'left') { + offX = text.getWidth() / 2; + } + if (text.originX === 'right') { + offX = -text.getWidth() / 2; + } + text.set({ + left: text.getLeft() + offX, + top: text.getTop() - text.getHeight() / 2 + text.fontSize * (0.18 + text._fontSizeFraction) /* 0.3 is the old lineHeight */ + }); + + return text; + }; + /* _FROM_SVG_END_ */ + + /** + * Returns fabric.Text instance from an object representation + * @static + * @memberOf fabric.Text + * @param {Object} object Object to create an instance from + * @return {fabric.Text} Instance of fabric.Text + */ + fabric.Text.fromObject = function(object) { + return new fabric.Text(object.text, clone(object)); + }; + + fabric.util.createAccessors(fabric.Text); + +})(typeof exports !== 'undefined' ? exports : this); + + +(function() { + + var clone = fabric.util.object.clone; + + /** + * IText class (introduced in v1.4) Events are also fired with "text:" + * prefix when observing canvas. + * @class fabric.IText + * @extends fabric.Text + * @mixes fabric.Observable + * + * @fires changed + * @fires selection:changed + * @fires editing:entered + * @fires editing:exited + * + * @return {fabric.IText} thisArg + * @see {@link fabric.IText#initialize} for constructor definition + * + *

Supported key combinations:

+ *
+   *   Move cursor:                    left, right, up, down
+   *   Select character:               shift + left, shift + right
+   *   Select text vertically:         shift + up, shift + down
+   *   Move cursor by word:            alt + left, alt + right
+   *   Select words:                   shift + alt + left, shift + alt + right
+   *   Move cursor to line start/end:  cmd + left, cmd + right or home, end
+   *   Select till start/end of line:  cmd + shift + left, cmd + shift + right or shift + home, shift + end
+   *   Jump to start/end of text:      cmd + up, cmd + down
+   *   Select till start/end of text:  cmd + shift + up, cmd + shift + down or shift + pgUp, shift + pgDown
+   *   Delete character:               backspace
+   *   Delete word:                    alt + backspace
+   *   Delete line:                    cmd + backspace
+   *   Forward delete:                 delete
+   *   Copy text:                      ctrl/cmd + c
+   *   Paste text:                     ctrl/cmd + v
+   *   Cut text:                       ctrl/cmd + x
+   *   Select entire text:             ctrl/cmd + a
+   *   Quit editing                    tab or esc
+   * 
+ * + *

Supported mouse/touch combination

+ *
+   *   Position cursor:                click/touch
+   *   Create selection:               click/touch & drag
+   *   Create selection:               click & shift + click
+   *   Select word:                    double click
+   *   Select line:                    triple click
+   * 
+ */ + fabric.IText = fabric.util.createClass(fabric.Text, fabric.Observable, /** @lends fabric.IText.prototype */ { + + /** + * Type of an object + * @type String + * @default + */ + type: 'i-text', + + /** + * Index where text selection starts (or where cursor is when there is no selection) + * @type Nubmer + * @default + */ + selectionStart: 0, + + /** + * Index where text selection ends + * @type Nubmer + * @default + */ + selectionEnd: 0, + + /** + * Color of text selection + * @type String + * @default + */ + selectionColor: 'rgba(17,119,255,0.3)', + + /** + * Indicates whether text is in editing mode + * @type Boolean + * @default + */ + isEditing: false, + + /** + * Indicates whether a text can be edited + * @type Boolean + * @default + */ + editable: true, + + /** + * Border color of text object while it's in editing mode + * @type String + * @default + */ + editingBorderColor: 'rgba(102,153,255,0.25)', + + /** + * Width of cursor (in px) + * @type Number + * @default + */ + cursorWidth: 2, + + /** + * Color of default cursor (when not overwritten by character style) + * @type String + * @default + */ + cursorColor: '#333', + + /** + * Delay between cursor blink (in ms) + * @type Number + * @default + */ + cursorDelay: 1000, + + /** + * Duration of cursor fadein (in ms) + * @type Number + * @default + */ + cursorDuration: 600, + + /** + * Object containing character styles + * (where top-level properties corresponds to line number and 2nd-level properties -- to char number in a line) + * @type Object + * @default + */ + styles: null, + + /** + * Indicates whether internal text char widths can be cached + * @type Boolean + * @default + */ + caching: true, + + /** + * @private + * @type Boolean + * @default + */ + _skipFillStrokeCheck: false, + + /** + * @private + */ + _reSpace: /\s|\n/, + + /** + * @private + */ + _currentCursorOpacity: 0, + + /** + * @private + */ + _selectionDirection: null, + + /** + * @private + */ + _abortCursorAnimation: false, + + /** + * @private + */ + _charWidthsCache: { }, + + /** + * Constructor + * @param {String} text Text string + * @param {Object} [options] Options object + * @return {fabric.IText} thisArg + */ + initialize: function(text, options) { + this.styles = options ? (options.styles || { }) : { }; + this.callSuper('initialize', text, options); + this.initBehavior(); + }, + + /** + * @private + */ + _clearCache: function() { + this.callSuper('_clearCache'); + this.__maxFontHeights = [ ]; + this.__widthOfSpace = [ ]; + }, + + /** + * Returns true if object has no styling + */ + isEmptyStyles: function() { + if (!this.styles) { + return true; + } + var obj = this.styles; + + for (var p1 in obj) { + for (var p2 in obj[p1]) { + /*jshint unused:false */ + for (var p3 in obj[p1][p2]) { + return false; + } + } + } + return true; + }, + + /** + * Sets selection start (left boundary of a selection) + * @param {Number} index Index to set selection start to + */ + setSelectionStart: function(index) { + index = Math.max(index, 0); + if (this.selectionStart !== index) { + this.fire('selection:changed'); + this.canvas && this.canvas.fire('text:selection:changed', { target: this }); + this.selectionStart = index; + } + this._updateTextarea(); + }, + + /** + * Sets selection end (right boundary of a selection) + * @param {Number} index Index to set selection end to + */ + setSelectionEnd: function(index) { + index = Math.min(index, this.text.length); + if (this.selectionEnd !== index) { + this.fire('selection:changed'); + this.canvas && this.canvas.fire('text:selection:changed', { target: this }); + this.selectionEnd = index; + } + this._updateTextarea(); + }, + + /** + * Gets style of a current selection/cursor (at the start position) + * @param {Number} [startIndex] Start index to get styles at + * @param {Number} [endIndex] End index to get styles at + * @return {Object} styles Style object at a specified (or current) index + */ + getSelectionStyles: function(startIndex, endIndex) { + + if (arguments.length === 2) { + var styles = [ ]; + for (var i = startIndex; i < endIndex; i++) { + styles.push(this.getSelectionStyles(i)); + } + return styles; + } + + var loc = this.get2DCursorLocation(startIndex); + if (this.styles[loc.lineIndex]) { + return this.styles[loc.lineIndex][loc.charIndex] || { }; + } + + return { }; + }, + + /** + * Sets style of a current selection + * @param {Object} [styles] Styles object + * @return {fabric.IText} thisArg + * @chainable + */ + setSelectionStyles: function(styles) { + if (this.selectionStart === this.selectionEnd) { + this._extendStyles(this.selectionStart, styles); + } + else { + for (var i = this.selectionStart; i < this.selectionEnd; i++) { + this._extendStyles(i, styles); + } + } + /* not included in _extendStyles to avoid clearing cache more than once */ + this._clearCache(); + return this; + }, + + /** + * @private + */ + _extendStyles: function(index, styles) { + var loc = this.get2DCursorLocation(index); + + if (!this.styles[loc.lineIndex]) { + this.styles[loc.lineIndex] = { }; + } + if (!this.styles[loc.lineIndex][loc.charIndex]) { + this.styles[loc.lineIndex][loc.charIndex] = { }; + } + fabric.util.object.extend(this.styles[loc.lineIndex][loc.charIndex], styles); + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _render: function(ctx) { + this.callSuper('_render', ctx); + this.ctx = ctx; + this.isEditing && this.renderCursorOrSelection(); + }, + + /** + * Renders cursor or selection (depending on what exists) + */ + renderCursorOrSelection: function() { + if (!this.active) { + return; + } + + var chars = this.text.split(''), + boundaries, ctx; + + if (this.canvas.contextTop) { + ctx = this.canvas.contextTop; + ctx.save(); + ctx.transform.apply(ctx, this.canvas.viewportTransform); + this.transform(ctx); + } + else { + ctx = this.ctx; + ctx.save(); + } + + if (this.selectionStart === this.selectionEnd) { + boundaries = this._getCursorBoundaries(chars, 'cursor'); + this.renderCursor(boundaries, ctx); + } + else { + boundaries = this._getCursorBoundaries(chars, 'selection'); + this.renderSelection(chars, boundaries, ctx); + } + + ctx.restore(); + }, + + /** + * Returns 2d representation (lineIndex and charIndex) of cursor (or selection start) + * @param {Number} [selectionStart] Optional index. When not given, current selectionStart is used. + */ + get2DCursorLocation: function(selectionStart) { + if (typeof selectionStart === 'undefined') { + selectionStart = this.selectionStart; + } + var textBeforeCursor = this.text.slice(0, selectionStart), + linesBeforeCursor = textBeforeCursor.split(this._reNewline); + + return { + lineIndex: linesBeforeCursor.length - 1, + charIndex: linesBeforeCursor[linesBeforeCursor.length - 1].length + }; + }, + + /** + * Returns complete style of char at the current cursor + * @param {Number} lineIndex Line index + * @param {Number} charIndex Char index + * @return {Object} Character style + */ + getCurrentCharStyle: function(lineIndex, charIndex) { + var style = this.styles[lineIndex] && this.styles[lineIndex][charIndex === 0 ? 0 : (charIndex - 1)]; + + return { + fontSize: style && style.fontSize || this.fontSize, + fill: style && style.fill || this.fill, + textBackgroundColor: style && style.textBackgroundColor || this.textBackgroundColor, + textDecoration: style && style.textDecoration || this.textDecoration, + fontFamily: style && style.fontFamily || this.fontFamily, + fontWeight: style && style.fontWeight || this.fontWeight, + fontStyle: style && style.fontStyle || this.fontStyle, + stroke: style && style.stroke || this.stroke, + strokeWidth: style && style.strokeWidth || this.strokeWidth + }; + }, + + /** + * Returns fontSize of char at the current cursor + * @param {Number} lineIndex Line index + * @param {Number} charIndex Char index + * @return {Number} Character font size + */ + getCurrentCharFontSize: function(lineIndex, charIndex) { + return ( + this.styles[lineIndex] && + this.styles[lineIndex][charIndex === 0 ? 0 : (charIndex - 1)] && + this.styles[lineIndex][charIndex === 0 ? 0 : (charIndex - 1)].fontSize) || this.fontSize; + }, + + /** + * Returns color (fill) of char at the current cursor + * @param {Number} lineIndex Line index + * @param {Number} charIndex Char index + * @return {String} Character color (fill) + */ + getCurrentCharColor: function(lineIndex, charIndex) { + return ( + this.styles[lineIndex] && + this.styles[lineIndex][charIndex === 0 ? 0 : (charIndex - 1)] && + this.styles[lineIndex][charIndex === 0 ? 0 : (charIndex - 1)].fill) || this.cursorColor; + }, + + /** + * Returns cursor boundaries (left, top, leftOffset, topOffset) + * @private + * @param {Array} chars Array of characters + * @param {String} typeOfBoundaries + */ + _getCursorBoundaries: function(chars, typeOfBoundaries) { + + // left/top are left/top of entire text box + // leftOffset/topOffset are offset from that left/top point of a text box + + var left = Math.round(this._getLeftOffset()), + top = this._getTopOffset(), + + offsets = this._getCursorBoundariesOffsets( + chars, typeOfBoundaries); + + return { + left: left, + top: top, + leftOffset: offsets.left + offsets.lineLeft, + topOffset: offsets.top + }; + }, + + /** + * @private + */ + _getCursorBoundariesOffsets: function(chars, typeOfBoundaries) { + + var lineLeftOffset = 0, + + lineIndex = 0, + charIndex = 0, + topOffset = 0, + leftOffset = 0; + + for (var i = 0; i < this.selectionStart; i++) { + if (chars[i] === '\n') { + leftOffset = 0; + topOffset += this._getHeightOfLine(this.ctx, lineIndex); + + lineIndex++; + charIndex = 0; + } + else { + leftOffset += this._getWidthOfChar(this.ctx, chars[i], lineIndex, charIndex); + charIndex++; + } + + lineLeftOffset = this._getCachedLineOffset(lineIndex); + } + if (typeOfBoundaries === 'cursor') { + topOffset += (1 - this._fontSizeFraction) * this._getHeightOfLine(this.ctx, lineIndex) / this.lineHeight + - this.getCurrentCharFontSize(lineIndex, charIndex) * (1 - this._fontSizeFraction); + } + + return { + top: topOffset, + left: leftOffset, + lineLeft: lineLeftOffset + }; + }, + + /** + * @private + */ + _getCachedLineOffset: function(lineIndex) { + var widthOfLine = this._getLineWidth(this.ctx, lineIndex); + + return this.__lineOffsets[lineIndex] || + (this.__lineOffsets[lineIndex] = this._getLineLeftOffset(widthOfLine)); + }, + + /** + * Renders cursor + * @param {Object} boundaries + * @param {CanvasRenderingContext2D} ctx transformed context to draw on + */ + renderCursor: function(boundaries, ctx) { + + var cursorLocation = this.get2DCursorLocation(), + lineIndex = cursorLocation.lineIndex, + charIndex = cursorLocation.charIndex, + charHeight = this.getCurrentCharFontSize(lineIndex, charIndex), + leftOffset = (lineIndex === 0 && charIndex === 0) + ? this._getCachedLineOffset(lineIndex) + : boundaries.leftOffset; + + ctx.fillStyle = this.getCurrentCharColor(lineIndex, charIndex); + ctx.globalAlpha = this.__isMousedown ? 1 : this._currentCursorOpacity; + + ctx.fillRect( + boundaries.left + leftOffset, + boundaries.top + boundaries.topOffset, + this.cursorWidth / this.scaleX, + charHeight); + + }, + + /** + * Renders text selection + * @param {Array} chars Array of characters + * @param {Object} boundaries Object with left/top/leftOffset/topOffset + * @param {CanvasRenderingContext2D} ctx transformed context to draw on + */ + renderSelection: function(chars, boundaries, ctx) { + + ctx.fillStyle = this.selectionColor; + + var start = this.get2DCursorLocation(this.selectionStart), + end = this.get2DCursorLocation(this.selectionEnd), + startLine = start.lineIndex, + endLine = end.lineIndex; + + for (var i = startLine; i <= endLine; i++) { + var lineOffset = this._getCachedLineOffset(i) || 0, + lineHeight = this._getHeightOfLine(this.ctx, i), + boxWidth = 0, line = this._textLines[i]; + + if (i === startLine) { + for (var j = 0, len = line.length; j < len; j++) { + if (j >= start.charIndex && (i !== endLine || j < end.charIndex)) { + boxWidth += this._getWidthOfChar(ctx, line[j], i, j); + } + if (j < start.charIndex) { + lineOffset += this._getWidthOfChar(ctx, line[j], i, j); + } + } + } + else if (i > startLine && i < endLine) { + boxWidth += this._getLineWidth(ctx, i) || 5; + } + else if (i === endLine) { + for (var j2 = 0, j2len = end.charIndex; j2 < j2len; j2++) { + boxWidth += this._getWidthOfChar(ctx, line[j2], i, j2); + } + } + + ctx.fillRect( + boundaries.left + lineOffset, + boundaries.top + boundaries.topOffset, + boxWidth, + lineHeight); + + boundaries.topOffset += lineHeight; + } + }, + + /** + * @private + * @param {String} method + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderChars: function(method, ctx, line, left, top, lineIndex) { + + if (this.isEmptyStyles()) { + return this._renderCharsFast(method, ctx, line, left, top); + } + + this.skipTextAlign = true; + + // set proper box offset + left -= this.textAlign === 'center' + ? (this.width / 2) + : (this.textAlign === 'right') + ? this.width + : 0; + + // set proper line offset + var lineHeight = this._getHeightOfLine(ctx, lineIndex), + lineLeftOffset = this._getCachedLineOffset(lineIndex), + chars = line.split(''), + prevStyle, + charsToRender = ''; + + left += lineLeftOffset || 0; + + ctx.save(); + top -= lineHeight / this.lineHeight * this._fontSizeFraction; + for (var i = 0, len = chars.length; i <= len; i++) { + prevStyle = prevStyle || this.getCurrentCharStyle(lineIndex, i); + var thisStyle = this.getCurrentCharStyle(lineIndex, i + 1); + + if (this._hasStyleChanged(prevStyle, thisStyle) || i === len) { + this._renderChar(method, ctx, lineIndex, i - 1, charsToRender, left, top, lineHeight); + charsToRender = ''; + prevStyle = thisStyle; + } + charsToRender += chars[i]; + } + + ctx.restore(); + }, + + /** + * @private + * @param {String} method + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {String} line Content of the line + * @param {Number} left Left coordinate + * @param {Number} top Top coordinate + */ + _renderCharsFast: function(method, ctx, line, left, top) { + this.skipTextAlign = false; + + if (method === 'fillText' && this.fill) { + this.callSuper('_renderChars', method, ctx, line, left, top); + } + if (method === 'strokeText' && ((this.stroke && this.strokeWidth > 0) || this.skipFillStrokeCheck)) { + this.callSuper('_renderChars', method, ctx, line, left, top); + } + }, + + /** + * @private + * @param {String} method + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {Number} lineIndex + * @param {Number} i + * @param {String} _char + * @param {Number} left Left coordinate + * @param {Number} top Top coordinate + * @param {Number} lineHeight Height of the line + */ + _renderChar: function(method, ctx, lineIndex, i, _char, left, top, lineHeight) { + var decl, charWidth, charHeight, + offset = this._fontSizeFraction * lineHeight / this.lineHeight; + + if (this.styles && this.styles[lineIndex] && (decl = this.styles[lineIndex][i])) { + + var shouldStroke = decl.stroke || this.stroke, + shouldFill = decl.fill || this.fill; + + ctx.save(); + charWidth = this._applyCharStylesGetWidth(ctx, _char, lineIndex, i, decl); + charHeight = this._getHeightOfChar(ctx, _char, lineIndex, i); + + if (shouldFill) { + ctx.fillText(_char, left, top); + } + if (shouldStroke) { + ctx.strokeText(_char, left, top); + } + + this._renderCharDecoration(ctx, decl, left, top, offset, charWidth, charHeight); + ctx.restore(); + + ctx.translate(charWidth, 0); + } + else { + if (method === 'strokeText' && this.stroke) { + ctx[method](_char, left, top); + } + if (method === 'fillText' && this.fill) { + ctx[method](_char, left, top); + } + charWidth = this._applyCharStylesGetWidth(ctx, _char, lineIndex, i); + this._renderCharDecoration(ctx, null, left, top, offset, charWidth, this.fontSize); + + ctx.translate(ctx.measureText(_char).width, 0); + } + }, + + /** + * @private + * @param {Object} prevStyle + * @param {Object} thisStyle + */ + _hasStyleChanged: function(prevStyle, thisStyle) { + return (prevStyle.fill !== thisStyle.fill || + prevStyle.fontSize !== thisStyle.fontSize || + prevStyle.textBackgroundColor !== thisStyle.textBackgroundColor || + prevStyle.textDecoration !== thisStyle.textDecoration || + prevStyle.fontFamily !== thisStyle.fontFamily || + prevStyle.fontWeight !== thisStyle.fontWeight || + prevStyle.fontStyle !== thisStyle.fontStyle || + prevStyle.stroke !== thisStyle.stroke || + prevStyle.strokeWidth !== thisStyle.strokeWidth + ); + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderCharDecoration: function(ctx, styleDeclaration, left, top, offset, charWidth, charHeight) { + + var textDecoration = styleDeclaration + ? (styleDeclaration.textDecoration || this.textDecoration) + : this.textDecoration; + + if (!textDecoration) { + return; + } + + if (textDecoration.indexOf('underline') > -1) { + ctx.fillRect( + left, + top + charHeight / 10, + charWidth , + charHeight / 15 + ); + } + if (textDecoration.indexOf('line-through') > -1) { + ctx.fillRect( + left, + top - charHeight * (this._fontSizeFraction + this._fontSizeMult - 1) + charHeight / 15, + charWidth, + charHeight / 15 + ); + } + if (textDecoration.indexOf('overline') > -1) { + ctx.fillRect( + left, + top - (this._fontSizeMult - this._fontSizeFraction) * charHeight, + charWidth, + charHeight / 15 + ); + } + }, + + /** + * @private + * @param {String} method + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {String} line + */ + _renderTextLine: function(method, ctx, line, left, top, lineIndex) { + // to "cancel" this.fontSize subtraction in fabric.Text#_renderTextLine + // the adding 0.03 is just to align text with itext by overlap test + if (!this.isEmptyStyles()) { + top += this.fontSize * (this._fontSizeFraction + 0.03); + } + this.callSuper('_renderTextLine', method, ctx, line, left, top, lineIndex); + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderTextDecoration: function(ctx) { + if (this.isEmptyStyles()) { + return this.callSuper('_renderTextDecoration', ctx); + } + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderTextLinesBackground: function(ctx) { + if (!this.textBackgroundColor && !this.styles) { + return; + } + + ctx.save(); + + if (this.textBackgroundColor) { + ctx.fillStyle = this.textBackgroundColor; + } + + var lineHeights = 0; + + for (var i = 0, len = this._textLines.length; i < len; i++) { + + var heightOfLine = this._getHeightOfLine(ctx, i); + if (this._textLines[i] === '') { + lineHeights += heightOfLine; + continue; + } + + var lineWidth = this._getLineWidth(ctx, i), + lineLeftOffset = this._getCachedLineOffset(i); + + if (this.textBackgroundColor) { + ctx.fillStyle = this.textBackgroundColor; + + ctx.fillRect( + this._getLeftOffset() + lineLeftOffset, + this._getTopOffset() + lineHeights, + lineWidth, + heightOfLine / this.lineHeight + ); + } + if (this.styles[i]) { + for (var j = 0, jlen = this._textLines[i].length; j < jlen; j++) { + if (this.styles[i] && this.styles[i][j] && this.styles[i][j].textBackgroundColor) { + + var _char = this._textLines[i][j]; + + ctx.fillStyle = this.styles[i][j].textBackgroundColor; + + ctx.fillRect( + this._getLeftOffset() + lineLeftOffset + this._getWidthOfCharsAt(ctx, i, j), + this._getTopOffset() + lineHeights, + this._getWidthOfChar(ctx, _char, i, j) + 1, + heightOfLine / this.lineHeight + ); + } + } + } + lineHeights += heightOfLine; + } + ctx.restore(); + }, + + /** + * @private + */ + _getCacheProp: function(_char, styleDeclaration) { + return _char + + styleDeclaration.fontFamily + + styleDeclaration.fontSize + + styleDeclaration.fontWeight + + styleDeclaration.fontStyle + + styleDeclaration.shadow; + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {String} _char + * @param {Number} lineIndex + * @param {Number} charIndex + * @param {Object} [decl] + */ + _applyCharStylesGetWidth: function(ctx, _char, lineIndex, charIndex, decl) { + var styleDeclaration = decl || + (this.styles[lineIndex] && + this.styles[lineIndex][charIndex]); + + if (styleDeclaration) { + // cloning so that original style object is not polluted with following font declarations + styleDeclaration = clone(styleDeclaration); + } + else { + styleDeclaration = { }; + } + + this._applyFontStyles(styleDeclaration); + + var cacheProp = this._getCacheProp(_char, styleDeclaration); + + // short-circuit if no styles + if (this.isEmptyStyles() && this._charWidthsCache[cacheProp] && this.caching) { + return this._charWidthsCache[cacheProp]; + } + + if (typeof styleDeclaration.shadow === 'string') { + styleDeclaration.shadow = new fabric.Shadow(styleDeclaration.shadow); + } + + var fill = styleDeclaration.fill || this.fill; + ctx.fillStyle = fill.toLive + ? fill.toLive(ctx, this) + : fill; + + if (styleDeclaration.stroke) { + ctx.strokeStyle = (styleDeclaration.stroke && styleDeclaration.stroke.toLive) + ? styleDeclaration.stroke.toLive(ctx, this) + : styleDeclaration.stroke; + } + + ctx.lineWidth = styleDeclaration.strokeWidth || this.strokeWidth; + ctx.font = this._getFontDeclaration.call(styleDeclaration); + this._setShadow.call(styleDeclaration, ctx); + + if (!this.caching) { + return ctx.measureText(_char).width; + } + + if (!this._charWidthsCache[cacheProp]) { + this._charWidthsCache[cacheProp] = ctx.measureText(_char).width; + } + + return this._charWidthsCache[cacheProp]; + }, + + /** + * @private + * @param {Object} styleDeclaration + */ + _applyFontStyles: function(styleDeclaration) { + if (!styleDeclaration.fontFamily) { + styleDeclaration.fontFamily = this.fontFamily; + } + if (!styleDeclaration.fontSize) { + styleDeclaration.fontSize = this.fontSize; + } + if (!styleDeclaration.fontWeight) { + styleDeclaration.fontWeight = this.fontWeight; + } + if (!styleDeclaration.fontStyle) { + styleDeclaration.fontStyle = this.fontStyle; + } + }, + + /** + * @private + * @param {Number} lineIndex + * @param {Number} charIndex + */ + _getStyleDeclaration: function(lineIndex, charIndex) { + return (this.styles[lineIndex] && this.styles[lineIndex][charIndex]) + ? clone(this.styles[lineIndex][charIndex]) + : { }; + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _getWidthOfChar: function(ctx, _char, lineIndex, charIndex) { + if (this.textAlign === 'justify' && /\s/.test(_char)) { + return this._getWidthOfSpace(ctx, lineIndex); + } + + var styleDeclaration = this._getStyleDeclaration(lineIndex, charIndex); + this._applyFontStyles(styleDeclaration); + var cacheProp = this._getCacheProp(_char, styleDeclaration); + + if (this._charWidthsCache[cacheProp] && this.caching) { + return this._charWidthsCache[cacheProp]; + } + else if (ctx) { + ctx.save(); + var width = this._applyCharStylesGetWidth(ctx, _char, lineIndex, charIndex); + ctx.restore(); + return width; + } + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _getHeightOfChar: function(ctx, _char, lineIndex, charIndex) { + if (this.styles[lineIndex] && this.styles[lineIndex][charIndex]) { + return this.styles[lineIndex][charIndex].fontSize || this.fontSize; + } + return this.fontSize; + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _getHeightOfCharAt: function(ctx, lineIndex, charIndex) { + var _char = this._textLines[lineIndex][charIndex]; + return this._getHeightOfChar(ctx, _char, lineIndex, charIndex); + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _getWidthOfCharsAt: function(ctx, lineIndex, charIndex) { + var width = 0, i, _char; + for (i = 0; i < charIndex; i++) { + _char = this._textLines[lineIndex][i]; + width += this._getWidthOfChar(ctx, _char, lineIndex, i); + } + return width; + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _getLineWidth: function(ctx, lineIndex) { + if (this.__lineWidths[lineIndex]) { + return this.__lineWidths[lineIndex]; + } + this.__lineWidths[lineIndex] = this._getWidthOfCharsAt(ctx, lineIndex, this._textLines[lineIndex].length); + return this.__lineWidths[lineIndex]; + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {Number} lineIndex + */ + _getWidthOfSpace: function (ctx, lineIndex) { + if (this.__widthOfSpace[lineIndex]) { + return this.__widthOfSpace[lineIndex]; + } + var line = this._textLines[lineIndex], + wordsWidth = this._getWidthOfWords(ctx, line, lineIndex), + widthDiff = this.width - wordsWidth, + numSpaces = line.length - line.replace(/\s+/g, '').length, + width = widthDiff / numSpaces; + this.__widthOfSpace[lineIndex] = width; + return width; + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {Number} line + * @param {Number} lineIndex + */ + _getWidthOfWords: function (ctx, line, lineIndex) { + var width = 0; + + for (var charIndex = 0; charIndex < line.length; charIndex++) { + var _char = line[charIndex]; + + if (!_char.match(/\s/)) { + width += this._getWidthOfChar(ctx, _char, lineIndex, charIndex); + } + } + + return width; + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _getHeightOfLine: function(ctx, lineIndex) { + if (this.__lineHeights[lineIndex]) { + return this.__lineHeights[lineIndex]; + } + + var line = this._textLines[lineIndex], + maxHeight = this._getHeightOfChar(ctx, line[0], lineIndex, 0); + + for (var i = 1, len = line.length; i < len; i++) { + var currentCharHeight = this._getHeightOfChar(ctx, line[i], lineIndex, i); + if (currentCharHeight > maxHeight) { + maxHeight = currentCharHeight; + } + } + this.__maxFontHeights[lineIndex] = maxHeight; + this.__lineHeights[lineIndex] = maxHeight * this.lineHeight * this._fontSizeMult; + return this.__lineHeights[lineIndex]; + }, + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _getTextHeight: function(ctx) { + var height = 0; + for (var i = 0, len = this._textLines.length; i < len; i++) { + height += this._getHeightOfLine(ctx, i); + } + return height; + }, + + /** + * This method is overwritten to account for different top offset + * @private + */ + _renderTextBoxBackground: function(ctx) { + if (!this.backgroundColor) { + return; + } + + ctx.save(); + ctx.fillStyle = this.backgroundColor; + + ctx.fillRect( + this._getLeftOffset(), + this._getTopOffset(), + this.width, + this.height + ); + + ctx.restore(); + }, + + /** + * Returns object representation of an instance + * @method toObject + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} object representation of an instance + */ + toObject: function(propertiesToInclude) { + return fabric.util.object.extend(this.callSuper('toObject', propertiesToInclude), { + styles: clone(this.styles) + }); + } + }); + + /** + * Returns fabric.IText instance from an object representation + * @static + * @memberOf fabric.IText + * @param {Object} object Object to create an instance from + * @return {fabric.IText} instance of fabric.IText + */ + fabric.IText.fromObject = function(object) { + return new fabric.IText(object.text, clone(object)); + }; +})(); + + +(function() { + + var clone = fabric.util.object.clone; + + fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ { + + /** + * Initializes all the interactive behavior of IText + */ + initBehavior: function() { + this.initAddedHandler(); + this.initRemovedHandler(); + this.initCursorSelectionHandlers(); + this.initDoubleClickSimulation(); + }, + + /** + * Initializes "selected" event handler + */ + initSelectedHandler: function() { + this.on('selected', function() { + + var _this = this; + setTimeout(function() { + _this.selected = true; + }, 100); + }); + }, + + /** + * Initializes "added" event handler + */ + initAddedHandler: function() { + var _this = this; + this.on('added', function() { + if (this.canvas && !this.canvas._hasITextHandlers) { + this.canvas._hasITextHandlers = true; + this._initCanvasHandlers(); + } + + // Track IText instances per-canvas. Only register in this array once added + // to a canvas; we don't want to leak a reference to the instance forever + // simply because it existed at some point. + // + // (Might be added to a collection, but not on a canvas.) + if (_this.canvas) { + _this.canvas._iTextInstances = _this.canvas._iTextInstances || []; + _this.canvas._iTextInstances.push(_this); + } + }); + }, + + initRemovedHandler: function() { + var _this = this; + this.on('removed', function() { + // (Might be removed from a collection, but not on a canvas.) + if (_this.canvas) { + _this.canvas._iTextInstances = _this.canvas._iTextInstances || []; + fabric.util.removeFromArray(_this.canvas._iTextInstances, _this); + } + }); + }, + + /** + * @private + */ + _initCanvasHandlers: function() { + var _this = this; + + this.canvas.on('selection:cleared', function() { + fabric.IText.prototype.exitEditingOnOthers(_this.canvas); + }); + + this.canvas.on('mouse:up', function() { + if (_this.canvas._iTextInstances) { + _this.canvas._iTextInstances.forEach(function(obj) { + obj.__isMousedown = false; + }); + } + }); + + this.canvas.on('object:selected', function() { + fabric.IText.prototype.exitEditingOnOthers(_this.canvas); + }); + }, + + /** + * @private + */ + _tick: function() { + this._currentTickState = this._animateCursor(this, 1, this.cursorDuration, '_onTickComplete'); + }, + + /** + * @private + */ + _animateCursor: function(obj, targetOpacity, duration, completeMethod) { + + var tickState; + + tickState = { + isAborted: false, + abort: function() { + this.isAborted = true; + }, + }; + + obj.animate('_currentCursorOpacity', targetOpacity, { + duration: duration, + onComplete: function() { + if (!tickState.isAborted) { + obj[completeMethod](); + } + }, + onChange: function() { + if (obj.canvas) { + obj.canvas.clearContext(obj.canvas.contextTop || obj.ctx); + obj.renderCursorOrSelection(); + } + }, + abort: function() { + return tickState.isAborted; + } + }); + return tickState; + }, + + /** + * @private + */ + _onTickComplete: function() { + + var _this = this; + + if (this._cursorTimeout1) { + clearTimeout(this._cursorTimeout1); + } + this._cursorTimeout1 = setTimeout(function() { + _this._currentTickCompleteState = _this._animateCursor(_this, 0, this.cursorDuration / 2, '_tick'); + }, 100); + }, + + /** + * Initializes delayed cursor + */ + initDelayedCursor: function(restart) { + var _this = this, + delay = restart ? 0 : this.cursorDelay; + + this._currentTickState && this._currentTickState.abort(); + this._currentTickCompleteState && this._currentTickCompleteState.abort(); + clearTimeout(this._cursorTimeout1); + this._currentCursorOpacity = 1; + if (this.canvas) { + this.canvas.clearContext(this.canvas.contextTop || this.ctx); + this.renderCursorOrSelection(); + } + if (this._cursorTimeout2) { + clearTimeout(this._cursorTimeout2); + } + this._cursorTimeout2 = setTimeout(function() { + _this._tick(); + }, delay); + }, + + /** + * Aborts cursor animation and clears all timeouts + */ + abortCursorAnimation: function() { + this._currentTickState && this._currentTickState.abort(); + this._currentTickCompleteState && this._currentTickCompleteState.abort(); + + clearTimeout(this._cursorTimeout1); + clearTimeout(this._cursorTimeout2); + + this._currentCursorOpacity = 0; + this.canvas && this.canvas.clearContext(this.canvas.contextTop || this.ctx); + }, + + /** + * Selects entire text + */ + selectAll: function() { + this.setSelectionStart(0); + this.setSelectionEnd(this.text.length); + }, + + /** + * Returns selected text + * @return {String} + */ + getSelectedText: function() { + return this.text.slice(this.selectionStart, this.selectionEnd); + }, + + /** + * Find new selection index representing start of current word according to current selection index + * @param {Number} startFrom Surrent selection index + * @return {Number} New selection index + */ + findWordBoundaryLeft: function(startFrom) { + var offset = 0, index = startFrom - 1; + + // remove space before cursor first + if (this._reSpace.test(this.text.charAt(index))) { + while (this._reSpace.test(this.text.charAt(index))) { + offset++; + index--; + } + } + while (/\S/.test(this.text.charAt(index)) && index > -1) { + offset++; + index--; + } + + return startFrom - offset; + }, + + /** + * Find new selection index representing end of current word according to current selection index + * @param {Number} startFrom Current selection index + * @return {Number} New selection index + */ + findWordBoundaryRight: function(startFrom) { + var offset = 0, index = startFrom; + + // remove space after cursor first + if (this._reSpace.test(this.text.charAt(index))) { + while (this._reSpace.test(this.text.charAt(index))) { + offset++; + index++; + } + } + while (/\S/.test(this.text.charAt(index)) && index < this.text.length) { + offset++; + index++; + } + + return startFrom + offset; + }, + + /** + * Find new selection index representing start of current line according to current selection index + * @param {Number} startFrom Current selection index + * @return {Number} New selection index + */ + findLineBoundaryLeft: function(startFrom) { + var offset = 0, index = startFrom - 1; + + while (!/\n/.test(this.text.charAt(index)) && index > -1) { + offset++; + index--; + } + + return startFrom - offset; + }, + + /** + * Find new selection index representing end of current line according to current selection index + * @param {Number} startFrom Current selection index + * @return {Number} New selection index + */ + findLineBoundaryRight: function(startFrom) { + var offset = 0, index = startFrom; + + while (!/\n/.test(this.text.charAt(index)) && index < this.text.length) { + offset++; + index++; + } + + return startFrom + offset; + }, + + /** + * Returns number of newlines in selected text + * @return {Number} Number of newlines in selected text + */ + getNumNewLinesInSelectedText: function() { + var selectedText = this.getSelectedText(), + numNewLines = 0; + + for (var i = 0, chars = selectedText.split(''), len = chars.length; i < len; i++) { + if (chars[i] === '\n') { + numNewLines++; + } + } + return numNewLines; + }, + + /** + * Finds index corresponding to beginning or end of a word + * @param {Number} selectionStart Index of a character + * @param {Number} direction: 1 or -1 + * @return {Number} Index of the beginning or end of a word + */ + searchWordBoundary: function(selectionStart, direction) { + var index = this._reSpace.test(this.text.charAt(selectionStart)) ? selectionStart - 1 : selectionStart, + _char = this.text.charAt(index), + reNonWord = /[ \n\.,;!\?\-]/; + + while (!reNonWord.test(_char) && index > 0 && index < this.text.length) { + index += direction; + _char = this.text.charAt(index); + } + if (reNonWord.test(_char) && _char !== '\n') { + index += direction === 1 ? 0 : 1; + } + return index; + }, + + /** + * Selects a word based on the index + * @param {Number} selectionStart Index of a character + */ + selectWord: function(selectionStart) { + var newSelectionStart = this.searchWordBoundary(selectionStart, -1), /* search backwards */ + newSelectionEnd = this.searchWordBoundary(selectionStart, 1); /* search forward */ + + this.setSelectionStart(newSelectionStart); + this.setSelectionEnd(newSelectionEnd); + }, + + /** + * Selects a line based on the index + * @param {Number} selectionStart Index of a character + */ + selectLine: function(selectionStart) { + var newSelectionStart = this.findLineBoundaryLeft(selectionStart), + newSelectionEnd = this.findLineBoundaryRight(selectionStart); + + this.setSelectionStart(newSelectionStart); + this.setSelectionEnd(newSelectionEnd); + }, + + /** + * Enters editing state + * @return {fabric.IText} thisArg + * @chainable + */ + enterEditing: function() { + if (this.isEditing || !this.editable) { + return; + } + + if (this.canvas) { + this.exitEditingOnOthers(this.canvas); + } + + this.isEditing = true; + + this.initHiddenTextarea(); + this.hiddenTextarea.focus(); + this._updateTextarea(); + this._saveEditingProps(); + this._setEditingProps(); + + this._tick(); + this.fire('editing:entered'); + + if (!this.canvas) { + return this; + } + + this.canvas.renderAll(); + this.canvas.fire('text:editing:entered', { target: this }); + this.initMouseMoveHandler(); + return this; + }, + + exitEditingOnOthers: function(canvas) { + if (canvas._iTextInstances) { + canvas._iTextInstances.forEach(function(obj) { + obj.selected = false; + if (obj.isEditing) { + obj.exitEditing(); + } + }); + } + }, + + /** + * Initializes "mousemove" event handler + */ + initMouseMoveHandler: function() { + var _this = this; + this.canvas.on('mouse:move', function(options) { + if (!_this.__isMousedown || !_this.isEditing) { + return; + } + + var newSelectionStart = _this.getSelectionStartFromPointer(options.e); + if (newSelectionStart >= _this.__selectionStartOnMouseDown) { + _this.setSelectionStart(_this.__selectionStartOnMouseDown); + _this.setSelectionEnd(newSelectionStart); + } + else { + _this.setSelectionStart(newSelectionStart); + _this.setSelectionEnd(_this.__selectionStartOnMouseDown); + } + }); + }, + + /** + * @private + */ + _setEditingProps: function() { + this.hoverCursor = 'text'; + + if (this.canvas) { + this.canvas.defaultCursor = this.canvas.moveCursor = 'text'; + } + + this.borderColor = this.editingBorderColor; + + this.hasControls = this.selectable = false; + this.lockMovementX = this.lockMovementY = true; + }, + + /** + * @private + */ + _updateTextarea: function() { + if (!this.hiddenTextarea) { + return; + } + + this.hiddenTextarea.value = this.text; + this.hiddenTextarea.selectionStart = this.selectionStart; + this.hiddenTextarea.selectionEnd = this.selectionEnd; + }, + + /** + * @private + */ + _saveEditingProps: function() { + this._savedProps = { + hasControls: this.hasControls, + borderColor: this.borderColor, + lockMovementX: this.lockMovementX, + lockMovementY: this.lockMovementY, + hoverCursor: this.hoverCursor, + defaultCursor: this.canvas && this.canvas.defaultCursor, + moveCursor: this.canvas && this.canvas.moveCursor + }; + }, + + /** + * @private + */ + _restoreEditingProps: function() { + if (!this._savedProps) { + return; + } + + this.hoverCursor = this._savedProps.overCursor; + this.hasControls = this._savedProps.hasControls; + this.borderColor = this._savedProps.borderColor; + this.lockMovementX = this._savedProps.lockMovementX; + this.lockMovementY = this._savedProps.lockMovementY; + + if (this.canvas) { + this.canvas.defaultCursor = this._savedProps.defaultCursor; + this.canvas.moveCursor = this._savedProps.moveCursor; + } + }, + + /** + * Exits from editing state + * @return {fabric.IText} thisArg + * @chainable + */ + exitEditing: function() { + + this.selected = false; + this.isEditing = false; + this.selectable = true; + + this.selectionEnd = this.selectionStart; + this.hiddenTextarea && this.canvas && this.hiddenTextarea.parentNode.removeChild(this.hiddenTextarea); + this.hiddenTextarea = null; + + this.abortCursorAnimation(); + this._restoreEditingProps(); + this._currentCursorOpacity = 0; + + this.fire('editing:exited'); + this.canvas && this.canvas.fire('text:editing:exited', { target: this }); + + return this; + }, + + /** + * @private + */ + _removeExtraneousStyles: function() { + for (var prop in this.styles) { + if (!this._textLines[prop]) { + delete this.styles[prop]; + } + } + }, + + /** + * @private + */ + _removeCharsFromTo: function(start, end) { + + var i = end; + while (i !== start) { + + var prevIndex = this.get2DCursorLocation(i).charIndex; + i--; + + var index = this.get2DCursorLocation(i).charIndex, + isNewline = index > prevIndex; + + if (isNewline) { + this.removeStyleObject(isNewline, i + 1); + } + else { + this.removeStyleObject(this.get2DCursorLocation(i).charIndex === 0, i); + } + + } + + this.text = this.text.slice(0, start) + + this.text.slice(end); + this._clearCache(); + }, + + /** + * Inserts a character where cursor is (replacing selection if one exists) + * @param {String} _chars Characters to insert + */ + insertChars: function(_chars, useCopiedStyle) { + var isEndOfLine = this.text.slice(this.selectionStart, this.selectionStart + 1) === '\n'; + + this.text = this.text.slice(0, this.selectionStart) + + _chars + + this.text.slice(this.selectionEnd); + + if (this.selectionStart === this.selectionEnd) { + this.insertStyleObjects(_chars, isEndOfLine, useCopiedStyle); + } + // else if (this.selectionEnd - this.selectionStart > 1) { + // TODO: replace styles properly + // console.log('replacing MORE than 1 char'); + // } + this.setSelectionStart(this.selectionStart + _chars.length); + this.setSelectionEnd(this.selectionStart); + this._clearCache(); + this.canvas && this.canvas.renderAll(); + + this.setCoords(); + this.fire('changed'); + this.canvas && this.canvas.fire('text:changed', { target: this }); + }, + + /** + * Inserts new style object + * @param {Number} lineIndex Index of a line + * @param {Number} charIndex Index of a char + * @param {Boolean} isEndOfLine True if it's end of line + */ + insertNewlineStyleObject: function(lineIndex, charIndex, isEndOfLine) { + + this.shiftLineStyles(lineIndex, +1); + + if (!this.styles[lineIndex + 1]) { + this.styles[lineIndex + 1] = { }; + } + + var currentCharStyle = this.styles[lineIndex][charIndex - 1], + newLineStyles = { }; + + // if there's nothing after cursor, + // we clone current char style onto the next (otherwise empty) line + if (isEndOfLine) { + newLineStyles[0] = clone(currentCharStyle); + this.styles[lineIndex + 1] = newLineStyles; + } + // otherwise we clone styles of all chars + // after cursor onto the next line, from the beginning + else { + for (var index in this.styles[lineIndex]) { + if (parseInt(index, 10) >= charIndex) { + newLineStyles[parseInt(index, 10) - charIndex] = this.styles[lineIndex][index]; + // remove lines from the previous line since they're on a new line now + delete this.styles[lineIndex][index]; + } + } + this.styles[lineIndex + 1] = newLineStyles; + } + this._clearCache(); + }, + + /** + * Inserts style object for a given line/char index + * @param {Number} lineIndex Index of a line + * @param {Number} charIndex Index of a char + * @param {Object} [style] Style object to insert, if given + */ + insertCharStyleObject: function(lineIndex, charIndex, style) { + + var currentLineStyles = this.styles[lineIndex], + currentLineStylesCloned = clone(currentLineStyles); + + if (charIndex === 0 && !style) { + charIndex = 1; + } + + // shift all char styles by 1 forward + // 0,1,2,3 -> (charIndex=2) -> 0,1,3,4 -> (insert 2) -> 0,1,2,3,4 + for (var index in currentLineStylesCloned) { + var numericIndex = parseInt(index, 10); + if (numericIndex >= charIndex) { + currentLineStyles[numericIndex + 1] = currentLineStylesCloned[numericIndex]; + //delete currentLineStyles[index]; + } + } + + this.styles[lineIndex][charIndex] = + style || clone(currentLineStyles[charIndex - 1]); + this._clearCache(); + }, + + /** + * Inserts style object(s) + * @param {String} _chars Characters at the location where style is inserted + * @param {Boolean} isEndOfLine True if it's end of line + * @param {Boolean} [useCopiedStyle] Style to insert + */ + insertStyleObjects: function(_chars, isEndOfLine, useCopiedStyle) { + // removed shortcircuit over isEmptyStyles + + var cursorLocation = this.get2DCursorLocation(), + lineIndex = cursorLocation.lineIndex, + charIndex = cursorLocation.charIndex; + + if (!this.styles[lineIndex]) { + this.styles[lineIndex] = { }; + } + + if (_chars === '\n') { + this.insertNewlineStyleObject(lineIndex, charIndex, isEndOfLine); + } + else { + if (useCopiedStyle) { + this._insertStyles(this.copiedStyles); + } + else { + // TODO: support multiple style insertion if _chars.length > 1 + this.insertCharStyleObject(lineIndex, charIndex); + } + } + }, + + /** + * @private + */ + _insertStyles: function(styles) { + for (var i = 0, len = styles.length; i < len; i++) { + + var cursorLocation = this.get2DCursorLocation(this.selectionStart + i), + lineIndex = cursorLocation.lineIndex, + charIndex = cursorLocation.charIndex; + + this.insertCharStyleObject(lineIndex, charIndex, styles[i]); + } + }, + + /** + * Shifts line styles up or down + * @param {Number} lineIndex Index of a line + * @param {Number} offset Can be -1 or +1 + */ + shiftLineStyles: function(lineIndex, offset) { + // shift all line styles by 1 upward + var clonedStyles = clone(this.styles); + for (var line in this.styles) { + var numericLine = parseInt(line, 10); + if (numericLine > lineIndex) { + this.styles[numericLine + offset] = clonedStyles[numericLine]; + } + } + }, + + /** + * Removes style object + * @param {Boolean} isBeginningOfLine True if cursor is at the beginning of line + * @param {Number} [index] Optional index. When not given, current selectionStart is used. + */ + removeStyleObject: function(isBeginningOfLine, index) { + + var cursorLocation = this.get2DCursorLocation(index), + lineIndex = cursorLocation.lineIndex, + charIndex = cursorLocation.charIndex; + + if (isBeginningOfLine) { + + var textOnPreviousLine = this._textLines[lineIndex - 1], + newCharIndexOnPrevLine = textOnPreviousLine + ? textOnPreviousLine.length + : 0; + + if (!this.styles[lineIndex - 1]) { + this.styles[lineIndex - 1] = { }; + } + + for (charIndex in this.styles[lineIndex]) { + this.styles[lineIndex - 1][parseInt(charIndex, 10) + newCharIndexOnPrevLine] + = this.styles[lineIndex][charIndex]; + } + + this.shiftLineStyles(lineIndex, -1); + } + else { + var currentLineStyles = this.styles[lineIndex]; + + if (currentLineStyles) { + var offset = this.selectionStart === this.selectionEnd ? -1 : 0; + delete currentLineStyles[charIndex + offset]; + // console.log('deleting', lineIndex, charIndex + offset); + } + + var currentLineStylesCloned = clone(currentLineStyles); + + // shift all styles by 1 backwards + for (var i in currentLineStylesCloned) { + var numericIndex = parseInt(i, 10); + if (numericIndex >= charIndex && numericIndex !== 0) { + currentLineStyles[numericIndex - 1] = currentLineStylesCloned[numericIndex]; + delete currentLineStyles[numericIndex]; + } + } + } + }, + + /** + * Inserts new line + */ + insertNewline: function() { + this.insertChars('\n'); + } + }); +})(); + + +fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ { + /** + * Initializes "dbclick" event handler + */ + initDoubleClickSimulation: function() { + + // for double click + this.__lastClickTime = +new Date(); + + // for triple click + this.__lastLastClickTime = +new Date(); + + this.__lastPointer = { }; + + this.on('mousedown', this.onMouseDown.bind(this)); + }, + + onMouseDown: function(options) { + + this.__newClickTime = +new Date(); + var newPointer = this.canvas.getPointer(options.e); + + if (this.isTripleClick(newPointer)) { + this.fire('tripleclick', options); + this._stopEvent(options.e); + } + else if (this.isDoubleClick(newPointer)) { + this.fire('dblclick', options); + this._stopEvent(options.e); + } + + this.__lastLastClickTime = this.__lastClickTime; + this.__lastClickTime = this.__newClickTime; + this.__lastPointer = newPointer; + this.__lastIsEditing = this.isEditing; + this.__lastSelected = this.selected; + }, + + isDoubleClick: function(newPointer) { + return this.__newClickTime - this.__lastClickTime < 500 && + this.__lastPointer.x === newPointer.x && + this.__lastPointer.y === newPointer.y && this.__lastIsEditing; + }, + + isTripleClick: function(newPointer) { + return this.__newClickTime - this.__lastClickTime < 500 && + this.__lastClickTime - this.__lastLastClickTime < 500 && + this.__lastPointer.x === newPointer.x && + this.__lastPointer.y === newPointer.y; + }, + + /** + * @private + */ + _stopEvent: function(e) { + e.preventDefault && e.preventDefault(); + e.stopPropagation && e.stopPropagation(); + }, + + /** + * Initializes event handlers related to cursor or selection + */ + initCursorSelectionHandlers: function() { + this.initSelectedHandler(); + this.initMousedownHandler(); + this.initMouseupHandler(); + this.initClicks(); + }, + + /** + * Initializes double and triple click event handlers + */ + initClicks: function() { + this.on('dblclick', function(options) { + this.selectWord(this.getSelectionStartFromPointer(options.e)); + }); + this.on('tripleclick', function(options) { + this.selectLine(this.getSelectionStartFromPointer(options.e)); + }); + }, + + /** + * Initializes "mousedown" event handler + */ + initMousedownHandler: function() { + this.on('mousedown', function(options) { + + var pointer = this.canvas.getPointer(options.e); + + this.__mousedownX = pointer.x; + this.__mousedownY = pointer.y; + this.__isMousedown = true; + + if (this.hiddenTextarea && this.canvas) { + this.canvas.wrapperEl.appendChild(this.hiddenTextarea); + } + + if (this.selected) { + this.setCursorByClick(options.e); + } + + if (this.isEditing) { + this.__selectionStartOnMouseDown = this.selectionStart; + this.initDelayedCursor(true); + } + }); + }, + + /** + * @private + */ + _isObjectMoved: function(e) { + var pointer = this.canvas.getPointer(e); + + return this.__mousedownX !== pointer.x || + this.__mousedownY !== pointer.y; + }, + + /** + * Initializes "mouseup" event handler + */ + initMouseupHandler: function() { + this.on('mouseup', function(options) { + this.__isMousedown = false; + if (this._isObjectMoved(options.e)) { + return; + } + + if (this.__lastSelected) { + this.enterEditing(); + this.initDelayedCursor(true); + } + this.selected = true; + }); + }, + + /** + * Changes cursor location in a text depending on passed pointer (x/y) object + * @param {Event} e Event object + */ + setCursorByClick: function(e) { + var newSelectionStart = this.getSelectionStartFromPointer(e); + + if (e.shiftKey) { + if (newSelectionStart < this.selectionStart) { + this.setSelectionEnd(this.selectionStart); + this.setSelectionStart(newSelectionStart); + } + else { + this.setSelectionEnd(newSelectionStart); + } + } + else { + this.setSelectionStart(newSelectionStart); + this.setSelectionEnd(newSelectionStart); + } + }, + + /** + * @private + * @param {Event} e Event object + * @return {Object} Coordinates of a pointer (x, y) + */ + _getLocalRotatedPointer: function(e) { + var pointer = this.canvas.getPointer(e), + + pClicked = new fabric.Point(pointer.x, pointer.y), + pLeftTop = new fabric.Point(this.left, this.top), + + rotated = fabric.util.rotatePoint( + pClicked, pLeftTop, fabric.util.degreesToRadians(-this.angle)); + + return this.getLocalPointer(e, rotated); + }, + + /** + * Returns index of a character corresponding to where an object was clicked + * @param {Event} e Event object + * @return {Number} Index of a character + */ + getSelectionStartFromPointer: function(e) { + var mouseOffset = this._getLocalRotatedPointer(e), + prevWidth = 0, + width = 0, + height = 0, + charIndex = 0, + newSelectionStart, + line; + + for (var i = 0, len = this._textLines.length; i < len; i++) { + line = this._textLines[i].split(''); + height += this._getHeightOfLine(this.ctx, i) * this.scaleY; + + var widthOfLine = this._getLineWidth(this.ctx, i), + lineLeftOffset = this._getLineLeftOffset(widthOfLine); + + width = lineLeftOffset * this.scaleX; + + if (this.flipX) { + // when oject is horizontally flipped we reverse chars + this._textLines[i] = line.reverse().join(''); + } + + for (var j = 0, jlen = line.length; j < jlen; j++) { + + var _char = line[j]; + prevWidth = width; + + width += this._getWidthOfChar(this.ctx, _char, i, this.flipX ? jlen - j : j) * + this.scaleX; + + if (height <= mouseOffset.y || width <= mouseOffset.x) { + charIndex++; + continue; + } + + return this._getNewSelectionStartFromOffset( + mouseOffset, prevWidth, width, charIndex + i, jlen); + } + + if (mouseOffset.y < height) { + return this._getNewSelectionStartFromOffset( + mouseOffset, prevWidth, width, charIndex + i, jlen); + } + } + + // clicked somewhere after all chars, so set at the end + if (typeof newSelectionStart === 'undefined') { + return this.text.length; + } + }, + + /** + * @private + */ + _getNewSelectionStartFromOffset: function(mouseOffset, prevWidth, width, index, jlen) { + + var distanceBtwLastCharAndCursor = mouseOffset.x - prevWidth, + distanceBtwNextCharAndCursor = width - mouseOffset.x, + offset = distanceBtwNextCharAndCursor > distanceBtwLastCharAndCursor ? 0 : 1, + newSelectionStart = index + offset; + + // if object is horizontally flipped, mirror cursor location from the end + if (this.flipX) { + newSelectionStart = jlen - newSelectionStart; + } + + if (newSelectionStart > this.text.length) { + newSelectionStart = this.text.length; + } + + return newSelectionStart; + } +}); + + +fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ { + + /** + * Initializes hidden textarea (needed to bring up keyboard in iOS) + */ + initHiddenTextarea: function() { + this.hiddenTextarea = fabric.document.createElement('textarea'); + + this.hiddenTextarea.setAttribute('autocapitalize', 'off'); + this.hiddenTextarea.style.cssText = 'position: fixed; bottom: 20px; left: 0px; opacity: 0;' + + ' width: 0px; height: 0px; z-index: -999;'; + fabric.document.body.appendChild(this.hiddenTextarea); + + fabric.util.addListener(this.hiddenTextarea, 'keydown', this.onKeyDown.bind(this)); + fabric.util.addListener(this.hiddenTextarea, 'keypress', this.onKeyPress.bind(this)); + fabric.util.addListener(this.hiddenTextarea, 'copy', this.copy.bind(this)); + fabric.util.addListener(this.hiddenTextarea, 'paste', this.paste.bind(this)); + + if (!this._clickHandlerInitialized && this.canvas) { + fabric.util.addListener(this.canvas.upperCanvasEl, 'click', this.onClick.bind(this)); + this._clickHandlerInitialized = true; + } + }, + + /** + * @private + */ + _keysMap: { + 8: 'removeChars', + 9: 'exitEditing', + 27: 'exitEditing', + 13: 'insertNewline', + 33: 'moveCursorUp', + 34: 'moveCursorDown', + 35: 'moveCursorRight', + 36: 'moveCursorLeft', + 37: 'moveCursorLeft', + 38: 'moveCursorUp', + 39: 'moveCursorRight', + 40: 'moveCursorDown', + 46: 'forwardDelete' + }, + + /** + * @private + */ + _ctrlKeysMap: { + 65: 'selectAll', + 88: 'cut' + }, + + onClick: function() { + // No need to trigger click event here, focus is enough to have the keyboard appear on Android + this.hiddenTextarea && this.hiddenTextarea.focus(); + }, + + /** + * Handles keyup event + * @param {Event} e Event object + */ + onKeyDown: function(e) { + if (!this.isEditing) { + return; + } + if (e.keyCode in this._keysMap) { + this[this._keysMap[e.keyCode]](e); + } + else if ((e.keyCode in this._ctrlKeysMap) && (e.ctrlKey || e.metaKey)) { + this[this._ctrlKeysMap[e.keyCode]](e); + } + else { + return; + } + e.stopImmediatePropagation(); + e.preventDefault(); + this.canvas && this.canvas.renderAll(); + }, + + /** + * Forward delete + */ + forwardDelete: function(e) { + if (this.selectionStart === this.selectionEnd) { + this.moveCursorRight(e); + } + this.removeChars(e); + }, + + /** + * Copies selected text + * @param {Event} e Event object + */ + copy: function(e) { + var selectedText = this.getSelectedText(), + clipboardData = this._getClipboardData(e); + + // Check for backward compatibility with old browsers + if (clipboardData) { + clipboardData.setData('text', selectedText); + } + + this.copiedText = selectedText; + this.copiedStyles = this.getSelectionStyles( + this.selectionStart, + this.selectionEnd); + }, + + /** + * Pastes text + * @param {Event} e Event object + */ + paste: function(e) { + var copiedText = null, + clipboardData = this._getClipboardData(e); + + // Check for backward compatibility with old browsers + if (clipboardData) { + copiedText = clipboardData.getData('text'); + } + else { + copiedText = this.copiedText; + } + + if (copiedText) { + this.insertChars(copiedText, true); + } + }, + + /** + * Cuts text + * @param {Event} e Event object + */ + cut: function(e) { + if (this.selectionStart === this.selectionEnd) { + return; + } + + this.copy(); + this.removeChars(e); + }, + + /** + * @private + * @param {Event} e Event object + * @return {Object} Clipboard data object + */ + _getClipboardData: function(e) { + return e && (e.clipboardData || fabric.window.clipboardData); + }, + + /** + * Handles keypress event + * @param {Event} e Event object + */ + onKeyPress: function(e) { + if (!this.isEditing || e.metaKey || e.ctrlKey) { + return; + } + if (e.which !== 0) { + this.insertChars(String.fromCharCode(e.which)); + } + e.stopPropagation(); + }, + + /** + * Gets start offset of a selection + * @param {Event} e Event object + * @param {Boolean} isRight + * @return {Number} + */ + getDownCursorOffset: function(e, isRight) { + var selectionProp = isRight ? this.selectionEnd : this.selectionStart, + _char, lineLeftOffset, + textBeforeCursor = this.text.slice(0, selectionProp), + textAfterCursor = this.text.slice(selectionProp), + + textOnSameLineBeforeCursor = textBeforeCursor.slice(textBeforeCursor.lastIndexOf('\n') + 1), + textOnSameLineAfterCursor = textAfterCursor.match(/(.*)\n?/)[1], + textOnNextLine = (textAfterCursor.match(/.*\n(.*)\n?/) || { })[1] || '', + + cursorLocation = this.get2DCursorLocation(selectionProp); + + // if on last line, down cursor goes to end of line + if (cursorLocation.lineIndex === this._textLines.length - 1 || e.metaKey || e.keyCode === 34) { + + // move to the end of a text + return this.text.length - selectionProp; + } + + var widthOfSameLineBeforeCursor = this._getLineWidth(this.ctx, cursorLocation.lineIndex); + lineLeftOffset = this._getLineLeftOffset(widthOfSameLineBeforeCursor); + + var widthOfCharsOnSameLineBeforeCursor = lineLeftOffset, + lineIndex = cursorLocation.lineIndex; + + for (var i = 0, len = textOnSameLineBeforeCursor.length; i < len; i++) { + _char = textOnSameLineBeforeCursor[i]; + widthOfCharsOnSameLineBeforeCursor += this._getWidthOfChar(this.ctx, _char, lineIndex, i); + } + + var indexOnNextLine = this._getIndexOnNextLine( + cursorLocation, textOnNextLine, widthOfCharsOnSameLineBeforeCursor); + + return textOnSameLineAfterCursor.length + 1 + indexOnNextLine; + }, + + /** + * @private + */ + _getIndexOnNextLine: function(cursorLocation, textOnNextLine, widthOfCharsOnSameLineBeforeCursor) { + var lineIndex = cursorLocation.lineIndex + 1, + widthOfNextLine = this._getLineWidth(this.ctx, lineIndex), + lineLeftOffset = this._getLineLeftOffset(widthOfNextLine), + widthOfCharsOnNextLine = lineLeftOffset, + indexOnNextLine = 0, + foundMatch; + + for (var j = 0, jlen = textOnNextLine.length; j < jlen; j++) { + + var _char = textOnNextLine[j], + widthOfChar = this._getWidthOfChar(this.ctx, _char, lineIndex, j); + + widthOfCharsOnNextLine += widthOfChar; + + if (widthOfCharsOnNextLine > widthOfCharsOnSameLineBeforeCursor) { + + foundMatch = true; + + var leftEdge = widthOfCharsOnNextLine - widthOfChar, + rightEdge = widthOfCharsOnNextLine, + offsetFromLeftEdge = Math.abs(leftEdge - widthOfCharsOnSameLineBeforeCursor), + offsetFromRightEdge = Math.abs(rightEdge - widthOfCharsOnSameLineBeforeCursor); + + indexOnNextLine = offsetFromRightEdge < offsetFromLeftEdge ? j + 1 : j; + + break; + } + } + + // reached end + if (!foundMatch) { + indexOnNextLine = textOnNextLine.length; + } + + return indexOnNextLine; + }, + + /** + * Moves cursor down + * @param {Event} e Event object + */ + moveCursorDown: function(e) { + this.abortCursorAnimation(); + this._currentCursorOpacity = 1; + + var offset = this.getDownCursorOffset(e, this._selectionDirection === 'right'); + + if (e.shiftKey) { + this.moveCursorDownWithShift(offset); + } + else { + this.moveCursorDownWithoutShift(offset); + } + + this.initDelayedCursor(); + }, + + /** + * Moves cursor down without keeping selection + * @param {Number} offset + */ + moveCursorDownWithoutShift: function(offset) { + this._selectionDirection = 'right'; + this.setSelectionStart(this.selectionStart + offset); + this.setSelectionEnd(this.selectionStart); + }, + + /** + * private + */ + swapSelectionPoints: function() { + var swapSel = this.selectionEnd; + this.setSelectionEnd(this.selectionStart); + this.setSelectionStart(swapSel); + }, + + /** + * Moves cursor down while keeping selection + * @param {Number} offset + */ + moveCursorDownWithShift: function(offset) { + if (this.selectionEnd === this.selectionStart) { + this._selectionDirection = 'right'; + } + if (this._selectionDirection === 'right') { + this.setSelectionEnd(this.selectionEnd + offset); + } + else { + this.setSelectionStart(this.selectionStart + offset); + } + if (this.selectionEnd < this.selectionStart && this._selectionDirection === 'left') { + this.swapSelectionPoints(); + this._selectionDirection = 'right'; + } + if (this.selectionEnd > this.text.length) { + this.setSelectionEnd(this.text.length); + } + }, + + /** + * @param {Event} e Event object + * @param {Boolean} isRight + * @return {Number} + */ + getUpCursorOffset: function(e, isRight) { + var selectionProp = isRight ? this.selectionEnd : this.selectionStart, + cursorLocation = this.get2DCursorLocation(selectionProp); + // if on first line, up cursor goes to start of line + if (cursorLocation.lineIndex === 0 || e.metaKey || e.keyCode === 33) { + return selectionProp; + } + + var textBeforeCursor = this.text.slice(0, selectionProp), + textOnSameLineBeforeCursor = textBeforeCursor.slice(textBeforeCursor.lastIndexOf('\n') + 1), + textOnPreviousLine = (textBeforeCursor.match(/\n?(.*)\n.*$/) || {})[1] || '', + _char, + widthOfSameLineBeforeCursor = this._getLineWidth(this.ctx, cursorLocation.lineIndex), + lineLeftOffset = this._getLineLeftOffset(widthOfSameLineBeforeCursor), + widthOfCharsOnSameLineBeforeCursor = lineLeftOffset, + lineIndex = cursorLocation.lineIndex; + + for (var i = 0, len = textOnSameLineBeforeCursor.length; i < len; i++) { + _char = textOnSameLineBeforeCursor[i]; + widthOfCharsOnSameLineBeforeCursor += this._getWidthOfChar(this.ctx, _char, lineIndex, i); + } + + var indexOnPrevLine = this._getIndexOnPrevLine( + cursorLocation, textOnPreviousLine, widthOfCharsOnSameLineBeforeCursor); + + return textOnPreviousLine.length - indexOnPrevLine + textOnSameLineBeforeCursor.length; + }, + + /** + * @private + */ + _getIndexOnPrevLine: function(cursorLocation, textOnPreviousLine, widthOfCharsOnSameLineBeforeCursor) { + + var lineIndex = cursorLocation.lineIndex - 1, + widthOfPreviousLine = this._getLineWidth(this.ctx, lineIndex), + lineLeftOffset = this._getLineLeftOffset(widthOfPreviousLine), + widthOfCharsOnPreviousLine = lineLeftOffset, + indexOnPrevLine = 0, + foundMatch; + + for (var j = 0, jlen = textOnPreviousLine.length; j < jlen; j++) { + + var _char = textOnPreviousLine[j], + widthOfChar = this._getWidthOfChar(this.ctx, _char, lineIndex, j); + + widthOfCharsOnPreviousLine += widthOfChar; + + if (widthOfCharsOnPreviousLine > widthOfCharsOnSameLineBeforeCursor) { + + foundMatch = true; + + var leftEdge = widthOfCharsOnPreviousLine - widthOfChar, + rightEdge = widthOfCharsOnPreviousLine, + offsetFromLeftEdge = Math.abs(leftEdge - widthOfCharsOnSameLineBeforeCursor), + offsetFromRightEdge = Math.abs(rightEdge - widthOfCharsOnSameLineBeforeCursor); + + indexOnPrevLine = offsetFromRightEdge < offsetFromLeftEdge ? j : (j - 1); + + break; + } + } + + // reached end + if (!foundMatch) { + indexOnPrevLine = textOnPreviousLine.length - 1; + } + + return indexOnPrevLine; + }, + + /** + * Moves cursor up + * @param {Event} e Event object + */ + moveCursorUp: function(e) { + + this.abortCursorAnimation(); + this._currentCursorOpacity = 1; + + var offset = this.getUpCursorOffset(e, this._selectionDirection === 'right'); + if (e.shiftKey) { + this.moveCursorUpWithShift(offset); + } + else { + this.moveCursorUpWithoutShift(offset); + } + + this.initDelayedCursor(); + }, + + /** + * Moves cursor up with shift + * @param {Number} offset + */ + moveCursorUpWithShift: function(offset) { + if (this.selectionEnd === this.selectionStart) { + this._selectionDirection = 'left'; + } + if (this._selectionDirection === 'right') { + this.setSelectionEnd(this.selectionEnd - offset); + } + else { + this.setSelectionStart(this.selectionStart - offset); + } + if (this.selectionEnd < this.selectionStart && this._selectionDirection === 'right') { + this.swapSelectionPoints(); + this._selectionDirection = 'left'; + } + }, + + /** + * Moves cursor up without shift + * @param {Number} offset + */ + moveCursorUpWithoutShift: function(offset) { + if (this.selectionStart === this.selectionEnd) { + this.setSelectionStart(this.selectionStart - offset); + } + this.setSelectionEnd(this.selectionStart); + + this._selectionDirection = 'left'; + }, + + /** + * Moves cursor left + * @param {Event} e Event object + */ + moveCursorLeft: function(e) { + if (this.selectionStart === 0 && this.selectionEnd === 0) { + return; + } + + this.abortCursorAnimation(); + this._currentCursorOpacity = 1; + + if (e.shiftKey) { + this.moveCursorLeftWithShift(e); + } + else { + this.moveCursorLeftWithoutShift(e); + } + + this.initDelayedCursor(); + }, + + /** + * @private + */ + _move: function(e, prop, direction) { + var propMethod = (prop === 'selectionStart' ? 'setSelectionStart' : 'setSelectionEnd'); + if (e.altKey) { + this[propMethod](this['findWordBoundary' + direction](this[prop])); + } + else if (e.metaKey || e.keyCode === 35 || e.keyCode === 36 ) { + this[propMethod](this['findLineBoundary' + direction](this[prop])); + } + else { + this[propMethod](this[prop] + (direction === 'Left' ? -1 : 1)); + } + }, + + /** + * @private + */ + _moveLeft: function(e, prop) { + this._move(e, prop, 'Left'); + }, + + /** + * @private + */ + _moveRight: function(e, prop) { + this._move(e, prop, 'Right'); + }, + + /** + * Moves cursor left without keeping selection + * @param {Event} e + */ + moveCursorLeftWithoutShift: function(e) { + this._selectionDirection = 'left'; + + // only move cursor when there is no selection, + // otherwise we discard it, and leave cursor on same place + if (this.selectionEnd === this.selectionStart) { + this._moveLeft(e, 'selectionStart'); + } + this.setSelectionEnd(this.selectionStart); + }, + + /** + * Moves cursor left while keeping selection + * @param {Event} e + */ + moveCursorLeftWithShift: function(e) { + if (this._selectionDirection === 'right' && this.selectionStart !== this.selectionEnd) { + this._moveLeft(e, 'selectionEnd'); + } + else { + this._selectionDirection = 'left'; + this._moveLeft(e, 'selectionStart'); + + // increase selection by one if it's a newline + if (this.text.charAt(this.selectionStart) === '\n') { + this.setSelectionStart(this.selectionStart - 1); + } + } + }, + + /** + * Moves cursor right + * @param {Event} e Event object + */ + moveCursorRight: function(e) { + if (this.selectionStart >= this.text.length && this.selectionEnd >= this.text.length) { + return; + } + + this.abortCursorAnimation(); + this._currentCursorOpacity = 1; + + if (e.shiftKey) { + this.moveCursorRightWithShift(e); + } + else { + this.moveCursorRightWithoutShift(e); + } + + this.initDelayedCursor(); + }, + + /** + * Moves cursor right while keeping selection + * @param {Event} e + */ + moveCursorRightWithShift: function(e) { + if (this._selectionDirection === 'left' && this.selectionStart !== this.selectionEnd) { + this._moveRight(e, 'selectionStart'); + } + else { + this._selectionDirection = 'right'; + this._moveRight(e, 'selectionEnd'); + + // increase selection by one if it's a newline + if (this.text.charAt(this.selectionEnd - 1) === '\n') { + this.setSelectionEnd(this.selectionEnd + 1); + } + } + }, + + /** + * Moves cursor right without keeping selection + * @param {Event} e Event object + */ + moveCursorRightWithoutShift: function(e) { + this._selectionDirection = 'right'; + + if (this.selectionStart === this.selectionEnd) { + this._moveRight(e, 'selectionStart'); + this.setSelectionEnd(this.selectionStart); + } + else { + this.setSelectionEnd(this.selectionEnd + this.getNumNewLinesInSelectedText()); + this.setSelectionStart(this.selectionEnd); + } + }, + + /** + * Removes characters selected by selection + * @param {Event} e Event object + */ + removeChars: function(e) { + if (this.selectionStart === this.selectionEnd) { + this._removeCharsNearCursor(e); + } + else { + this._removeCharsFromTo(this.selectionStart, this.selectionEnd); + } + + this.setSelectionEnd(this.selectionStart); + + this._removeExtraneousStyles(); + + this._clearCache(); + this.canvas && this.canvas.renderAll(); + + this.setCoords(); + this.fire('changed'); + this.canvas && this.canvas.fire('text:changed', { target: this }); + }, + + /** + * @private + * @param {Event} e Event object + */ + _removeCharsNearCursor: function(e) { + if (this.selectionStart !== 0) { + + if (e.metaKey) { + // remove all till the start of current line + var leftLineBoundary = this.findLineBoundaryLeft(this.selectionStart); + + this._removeCharsFromTo(leftLineBoundary, this.selectionStart); + this.setSelectionStart(leftLineBoundary); + } + else if (e.altKey) { + // remove all till the start of current word + var leftWordBoundary = this.findWordBoundaryLeft(this.selectionStart); + + this._removeCharsFromTo(leftWordBoundary, this.selectionStart); + this.setSelectionStart(leftWordBoundary); + } + else { + var isBeginningOfLine = this.text.slice(this.selectionStart - 1, this.selectionStart) === '\n'; + this.removeStyleObject(isBeginningOfLine); + this.setSelectionStart(this.selectionStart - 1); + this.text = this.text.slice(0, this.selectionStart) + + this.text.slice(this.selectionStart + 1); + } + } + } +}); + + +/* _TO_SVG_START_ */ +fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.prototype */ { + + /** + * @private + */ + _setSVGTextLineText: function(lineIndex, textSpans, height, textLeftOffset, textTopOffset, textBgRects) { + if (!this.styles[lineIndex]) { + this.callSuper('_setSVGTextLineText', + lineIndex, textSpans, height, textLeftOffset, textTopOffset); + } + else { + this._setSVGTextLineChars( + lineIndex, textSpans, height, textLeftOffset, textBgRects); + } + }, + + /** + * @private + */ + _setSVGTextLineChars: function(lineIndex, textSpans, height, textLeftOffset, textBgRects) { + + var chars = this._textLines[lineIndex].split(''), + charOffset = 0, + lineLeftOffset = this._getSVGLineLeftOffset(lineIndex) - this.width / 2, + lineOffset = this._getSVGLineTopOffset(lineIndex), + heightOfLine = this._getHeightOfLine(this.ctx, lineIndex); + + for (var i = 0, len = chars.length; i < len; i++) { + var styleDecl = this.styles[lineIndex][i] || { }; + + textSpans.push( + this._createTextCharSpan( + chars[i], styleDecl, lineLeftOffset, lineOffset.lineTop + lineOffset.offset, charOffset)); + + var charWidth = this._getWidthOfChar(this.ctx, chars[i], lineIndex, i); + + if (styleDecl.textBackgroundColor) { + textBgRects.push( + this._createTextCharBg( + styleDecl, lineLeftOffset, lineOffset.lineTop, heightOfLine, charWidth, charOffset)); + } + + charOffset += charWidth; + } + }, + + /** + * @private + */ + _getSVGLineLeftOffset: function(lineIndex) { + return fabric.util.toFixed(this._getLineLeftOffset(this.__lineWidths[lineIndex]), 2); + }, + + /** + * @private + */ + _getSVGLineTopOffset: function(lineIndex) { + var lineTopOffset = 0, lastHeight = 0; + for (var j = 0; j < lineIndex; j++) { + lineTopOffset += this._getHeightOfLine(this.ctx, j); + } + lastHeight = this._getHeightOfLine(this.ctx, j); + return { + lineTop: lineTopOffset, + offset: (this._fontSizeMult - this._fontSizeFraction) * lastHeight / (this.lineHeight * this._fontSizeMult) + }; + }, + + /** + * @private + */ + _createTextCharBg: function(styleDecl, lineLeftOffset, lineTopOffset, heightOfLine, charWidth, charOffset) { + return [ + //jscs:disable validateIndentation + '' + //jscs:enable validateIndentation + ].join(''); + }, + + /** + * @private + */ + _createTextCharSpan: function(_char, styleDecl, lineLeftOffset, lineTopOffset, charOffset) { + + var fillStyles = this.getSvgStyles.call(fabric.util.object.extend({ + visible: true, + fill: this.fill, + stroke: this.stroke, + type: 'text' + }, styleDecl)); + + return [ + //jscs:disable validateIndentation + '', + fabric.util.string.escapeXml(_char), + '' + //jscs:enable validateIndentation + ].join(''); + } +}); +/* _TO_SVG_END_ */ + + +(function() { + + if (typeof document !== 'undefined' && typeof window !== 'undefined') { + return; + } + + var DOMParser = require('xmldom').DOMParser, + URL = require('url'), + HTTP = require('http'), + HTTPS = require('https'), + + Canvas = require('canvas'), + Image = require('canvas').Image; + + /** @private */ + function request(url, encoding, callback) { + var oURL = URL.parse(url); + + // detect if http or https is used + if ( !oURL.port ) { + oURL.port = ( oURL.protocol.indexOf('https:') === 0 ) ? 443 : 80; + } + + // assign request handler based on protocol + var reqHandler = (oURL.protocol.indexOf('https:') === 0 ) ? HTTPS : HTTP, + req = reqHandler.request({ + hostname: oURL.hostname, + port: oURL.port, + path: oURL.path, + method: 'GET' + }, function(response) { + var body = ''; + if (encoding) { + response.setEncoding(encoding); + } + response.on('end', function () { + callback(body); + }); + response.on('data', function (chunk) { + if (response.statusCode === 200) { + body += chunk; + } + }); + }); + + req.on('error', function(err) { + if (err.errno === process.ECONNREFUSED) { + fabric.log('ECONNREFUSED: connection refused to ' + oURL.hostname + ':' + oURL.port); + } + else { + fabric.log(err.message); + } + }); + + req.end(); + } + + /** @private */ + function requestFs(path, callback) { + var fs = require('fs'); + fs.readFile(path, function (err, data) { + if (err) { + fabric.log(err); + throw err; + } + else { + callback(data); + } + }); + } + + fabric.util.loadImage = function(url, callback, context) { + function createImageAndCallBack(data) { + img.src = new Buffer(data, 'binary'); + // preserving original url, which seems to be lost in node-canvas + img._src = url; + callback && callback.call(context, img); + } + var img = new Image(); + if (url && (url instanceof Buffer || url.indexOf('data') === 0)) { + img.src = img._src = url; + callback && callback.call(context, img); + } + else if (url && url.indexOf('http') !== 0) { + requestFs(url, createImageAndCallBack); + } + else if (url) { + request(url, 'binary', createImageAndCallBack); + } + else { + callback && callback.call(context, url); + } + }; + + fabric.loadSVGFromURL = function(url, callback, reviver) { + url = url.replace(/^\n\s*/, '').replace(/\?.*$/, '').trim(); + if (url.indexOf('http') !== 0) { + requestFs(url, function(body) { + fabric.loadSVGFromString(body.toString(), callback, reviver); + }); + } + else { + request(url, '', function(body) { + fabric.loadSVGFromString(body, callback, reviver); + }); + } + }; + + fabric.loadSVGFromString = function(string, callback, reviver) { + var doc = new DOMParser().parseFromString(string); + fabric.parseSVGDocument(doc.documentElement, function(results, options) { + callback && callback(results, options); + }, reviver); + }; + + fabric.util.getScript = function(url, callback) { + request(url, '', function(body) { + eval(body); + callback && callback(); + }); + }; + + fabric.Image.fromObject = function(object, callback) { + fabric.util.loadImage(object.src, function(img) { + var oImg = new fabric.Image(img); + + oImg._initConfig(object); + oImg._initFilters(object, function(filters) { + oImg.filters = filters || [ ]; + callback && callback(oImg); + }); + }); + }; + + /** + * Only available when running fabric on node.js + * @param {Number} width Canvas width + * @param {Number} height Canvas height + * @param {Object} [options] Options to pass to FabricCanvas. + * @param {Object} [nodeCanvasOptions] Options to pass to NodeCanvas. + * @return {Object} wrapped canvas instance + */ + fabric.createCanvasForNode = function(width, height, options, nodeCanvasOptions) { + nodeCanvasOptions = nodeCanvasOptions || options; + + var canvasEl = fabric.document.createElement('canvas'), + nodeCanvas = new Canvas(width || 600, height || 600, nodeCanvasOptions); + + // jsdom doesn't create style on canvas element, so here be temp. workaround + canvasEl.style = { }; + + canvasEl.width = nodeCanvas.width; + canvasEl.height = nodeCanvas.height; + + var FabricCanvas = fabric.Canvas || fabric.StaticCanvas, + fabricCanvas = new FabricCanvas(canvasEl, options); + + fabricCanvas.contextContainer = nodeCanvas.getContext('2d'); + fabricCanvas.nodeCanvas = nodeCanvas; + fabricCanvas.Font = Canvas.Font; + + return fabricCanvas; + }; + + /** @ignore */ + fabric.StaticCanvas.prototype.createPNGStream = function() { + return this.nodeCanvas.createPNGStream(); + }; + + fabric.StaticCanvas.prototype.createJPEGStream = function(opts) { + return this.nodeCanvas.createJPEGStream(opts); + }; + + var origSetWidth = fabric.StaticCanvas.prototype.setWidth; + fabric.StaticCanvas.prototype.setWidth = function(width, options) { + origSetWidth.call(this, width, options); + this.nodeCanvas.width = width; + return this; + }; + if (fabric.Canvas) { + fabric.Canvas.prototype.setWidth = fabric.StaticCanvas.prototype.setWidth; + } + + var origSetHeight = fabric.StaticCanvas.prototype.setHeight; + fabric.StaticCanvas.prototype.setHeight = function(height, options) { + origSetHeight.call(this, height, options); + this.nodeCanvas.height = height; + return this; + }; + if (fabric.Canvas) { + fabric.Canvas.prototype.setHeight = fabric.StaticCanvas.prototype.setHeight; + } + +})(); diff --git a/iguana/js/amcharts/plugins/export/libs/fabric.js/fabric.min.js b/iguana/js/amcharts/plugins/export/libs/fabric.js/fabric.min.js new file mode 100755 index 000000000..ddd6a411a --- /dev/null +++ b/iguana/js/amcharts/plugins/export/libs/fabric.js/fabric.min.js @@ -0,0 +1,15 @@ +var fabric=fabric||{version:"1.5.0"};if(typeof exports!=="undefined"){exports.fabric=fabric}if(typeof document!=="undefined"&&typeof window!=="undefined"){fabric.document=document;fabric.window=window;window.fabric=fabric}else{fabric.document=require("jsdom").jsdom("");if(fabric.document.createWindow){fabric.window=fabric.document.createWindow()}else{fabric.window=fabric.document.parentWindow}}fabric.isTouchSupported="ontouchstart"in fabric.document.documentElement;fabric.isLikelyNode=typeof Buffer!=="undefined"&&typeof window==="undefined";fabric.SHARED_ATTRIBUTES=["display","transform","fill","fill-opacity","fill-rule","opacity","stroke","stroke-dasharray","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width"];fabric.DPI=96;fabric.reNum="(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:e[-+]?\\d+)?)";(function(){function _removeEventListener(eventName,handler){if(!this.__eventListeners[eventName]){return}if(handler){fabric.util.removeFromArray(this.__eventListeners[eventName],handler)}else{this.__eventListeners[eventName].length=0}}function observe(eventName,handler){if(!this.__eventListeners){this.__eventListeners={}}if(arguments.length===1){for(var prop in eventName){this.on(prop,eventName[prop])}}else{if(!this.__eventListeners[eventName]){this.__eventListeners[eventName]=[]}this.__eventListeners[eventName].push(handler)}return this}function stopObserving(eventName,handler){if(!this.__eventListeners){return}if(arguments.length===0){this.__eventListeners={}}else if(arguments.length===1&&typeof arguments[0]==="object"){for(var prop in eventName){_removeEventListener.call(this,prop,eventName[prop])}}else{_removeEventListener.call(this,eventName,handler)}return this}function fire(eventName,options){if(!this.__eventListeners){return}var listenersForEvent=this.__eventListeners[eventName];if(!listenersForEvent){return}for(var i=0,len=listenersForEvent.length;i-1},complexity:function(){return this.getObjects().reduce(function(memo,current){memo+=current.complexity?current.complexity():0;return memo},0)}};(function(global){var sqrt=Math.sqrt,atan2=Math.atan2,PiBy180=Math.PI/180;fabric.util={removeFromArray:function(array,value){var idx=array.indexOf(value);if(idx!==-1){array.splice(idx,1)}return array},getRandomInt:function(min,max){return Math.floor(Math.random()*(max-min+1))+min},degreesToRadians:function(degrees){return degrees*PiBy180},radiansToDegrees:function(radians){return radians/PiBy180},rotatePoint:function(point,origin,radians){var sin=Math.sin(radians),cos=Math.cos(radians);point.subtractEquals(origin);var rx=point.x*cos-point.y*sin,ry=point.x*sin+point.y*cos;return new fabric.Point(rx,ry).addEquals(origin)},transformPoint:function(p,t,ignoreOffset){if(ignoreOffset){return new fabric.Point(t[0]*p.x+t[2]*p.y,t[1]*p.x+t[3]*p.y)}return new fabric.Point(t[0]*p.x+t[2]*p.y+t[4],t[1]*p.x+t[3]*p.y+t[5])},invertTransform:function(t){var r=t.slice(),a=1/(t[0]*t[3]-t[1]*t[2]);r=[a*t[3],-a*t[1],-a*t[2],a*t[0],0,0];var o=fabric.util.transformPoint({x:t[4],y:t[5]},r);r[4]=-o.x;r[5]=-o.y;return r},toFixed:function(number,fractionDigits){return parseFloat(Number(number).toFixed(fractionDigits))},parseUnit:function(value,fontSize){var unit=/\D{0,2}$/.exec(value),number=parseFloat(value);if(!fontSize){fontSize=fabric.Text.DEFAULT_SVG_FONT_SIZE}switch(unit[0]){case"mm":return number*fabric.DPI/25.4;case"cm":return number*fabric.DPI/2.54;case"in":return number*fabric.DPI;case"pt":return number*fabric.DPI/72;case"pc":return number*fabric.DPI/72*12;case"em":return number*fontSize;default:return number}},falseFunction:function(){return false},getKlass:function(type,namespace){type=fabric.util.string.camelize(type.charAt(0).toUpperCase()+type.slice(1));return fabric.util.resolveNamespace(namespace)[type]},resolveNamespace:function(namespace){if(!namespace){return fabric}var parts=namespace.split("."),len=parts.length,obj=global||fabric.window;for(var i=0;ix){x+=da[di++%dc];if(x>len){x=len}ctx[draw?"lineTo":"moveTo"](x,0);draw=!draw}ctx.restore()},createCanvasElement:function(canvasEl){canvasEl||(canvasEl=fabric.document.createElement("canvas"));if(!canvasEl.getContext&&typeof G_vmlCanvasManager!=="undefined"){G_vmlCanvasManager.initElement(canvasEl)}return canvasEl},createImage:function(){return fabric.isLikelyNode?new(require("canvas").Image):fabric.document.createElement("img")},createAccessors:function(klass){var proto=klass.prototype;for(var i=proto.stateProperties.length;i--;){var propName=proto.stateProperties[i],capitalizedPropName=propName.charAt(0).toUpperCase()+propName.slice(1),setterName="set"+capitalizedPropName,getterName="get"+capitalizedPropName;if(!proto[getterName]){proto[getterName]=function(property){return new Function('return this.get("'+property+'")')}(propName)}if(!proto[setterName]){proto[setterName]=function(property){return new Function("value",'return this.set("'+property+'", value)')}(propName)}}},clipContext:function(receiver,ctx){ctx.save();ctx.beginPath();receiver.clipTo(ctx);ctx.clip()},multiplyTransformMatrices:function(a,b){return[a[0]*b[0]+a[2]*b[1],a[1]*b[0]+a[3]*b[1],a[0]*b[2]+a[2]*b[3],a[1]*b[2]+a[3]*b[3],a[0]*b[4]+a[2]*b[5]+a[4],a[1]*b[4]+a[3]*b[5]+a[5]]},getFunctionBody:function(fn){return(String(fn).match(/function[^{]*\{([\s\S]*)\}/)||{})[1]},isTransparent:function(ctx,x,y,tolerance){if(tolerance>0){if(x>tolerance){x-=tolerance}else{x=0}if(y>tolerance){y-=tolerance}else{y=0}}var _isTransparent=true,imageData=ctx.getImageData(x,y,tolerance*2||1,tolerance*2||1);for(var i=3,l=imageData.data.length;i0){dtheta-=2*PI}else if(sweep===1&&dtheta<0){dtheta+=2*PI}var segments=Math.ceil(Math.abs(dtheta/PI*2)),result=[],mDelta=dtheta/segments,mT=8/3*Math.sin(mDelta/4)*Math.sin(mDelta/4)/Math.sin(mDelta/2),th3=mTheta+mDelta;for(var i=0;i=ta){return tb-ta}else{return 2*Math.PI-(ta-tb)}}fabric.util.drawArc=function(ctx,fx,fy,coords){var rx=coords[0],ry=coords[1],rot=coords[2],large=coords[3],sweep=coords[4],tx=coords[5],ty=coords[6],segs=[[],[],[],[]],segsNorm=arcToSegments(tx-fx,ty-fy,rx,ry,large,sweep,rot);for(var i=0,len=segsNorm.length;i0){b=6*y0-12*y1+6*y2;a=-3*y0+9*y1-9*y2+3*y3;c=3*y1-3*y0}if(abs(a)<1e-12){if(abs(b)<1e-12){continue}t=-c/b;if(0>>0;if(len===0){return-1}var n=0;if(arguments.length>0){n=Number(arguments[1]);if(n!==n){n=0}else if(n!==0&&n!==Number.POSITIVE_INFINITY&&n!==Number.NEGATIVE_INFINITY){n=(n>0||-1)*Math.floor(Math.abs(n))}}if(n>=len){return-1}var k=n>=0?n:Math.max(len-Math.abs(n),0);for(;k>>0;i>>0;i>>0;i>>0;i>>0;i>>0,i=0,rv;if(arguments.length>1){rv=arguments[1]}else{do{if(i in this){rv=this[i++];break}if(++i>=len){throw new TypeError}}while(true)}for(;i=value2})}function min(array,byProperty){return find(array,byProperty,function(value1,value2){return value1/g,">")}fabric.util.string={camelize:camelize,capitalize:capitalize,escapeXml:escapeXml}})();(function(){var slice=Array.prototype.slice,apply=Function.prototype.apply,Dummy=function(){};if(!Function.prototype.bind){Function.prototype.bind=function(thisArg){var _this=this,args=slice.call(arguments,1),bound;if(args.length){bound=function(){return apply.call(_this,this instanceof Dummy?this:thisArg,args.concat(slice.call(arguments)))}}else{bound=function(){return apply.call(_this,this instanceof Dummy?this:thisArg,arguments)}}Dummy.prototype=this.prototype;bound.prototype=new Dummy;return bound}}})();(function(){var slice=Array.prototype.slice,emptyFunction=function(){},IS_DONTENUM_BUGGY=function(){for(var p in{toString:1}){if(p==="toString"){return false}}return true}(),addMethods=function(klass,source,parent){for(var property in source){if(property in klass.prototype&&typeof klass.prototype[property]==="function"&&(source[property]+"").indexOf("callSuper")>-1){klass.prototype[property]=function(property){return function(){var superclass=this.constructor.superclass;this.constructor.superclass=parent;var returnValue=source[property].apply(this,arguments);this.constructor.superclass=superclass;if(property!=="initialize"){return returnValue}}}(property)}else{klass.prototype[property]=source[property]}if(IS_DONTENUM_BUGGY){if(source.toString!==Object.prototype.toString){klass.prototype.toString=source.toString}if(source.valueOf!==Object.prototype.valueOf){klass.prototype.valueOf=source.valueOf}}}};function Subclass(){}function callSuper(methodName){var fn=this.constructor.superclass.prototype[methodName];return arguments.length>1?fn.apply(this,slice.call(arguments,1)):fn.call(this)}function createClass(){var parent=null,properties=slice.call(arguments,0);if(typeof properties[0]==="function"){parent=properties.shift()}function klass(){this.initialize.apply(this,arguments)}klass.superclass=parent;klass.subclasses=[];if(parent){Subclass.prototype=parent.prototype;klass.prototype=new Subclass;parent.subclasses.push(klass)}for(var i=0,length=properties.length;i-1?setOpacity(element,styles.match(/opacity:\s*(\d?\.?\d*)/)[1]):element}for(var property in styles){if(property==="opacity"){setOpacity(element,styles[property])}else{var normalizedProperty=property==="float"||property==="cssFloat"?typeof elementStyle.styleFloat==="undefined"?"cssFloat":"styleFloat":property;elementStyle[normalizedProperty]=styles[property]}}return element}var parseEl=fabric.document.createElement("div"),supportsOpacity=typeof parseEl.style.opacity==="string",supportsFilters=typeof parseEl.style.filter==="string",reOpacity=/alpha\s*\(\s*opacity\s*=\s*([^\)]+)\)/,setOpacity=function(element){return element};if(supportsOpacity){setOpacity=function(element,value){element.style.opacity=value;return element}}else if(supportsFilters){setOpacity=function(element,value){var es=element.style;if(element.currentStyle&&!element.currentStyle.hasLayout){es.zoom=1}if(reOpacity.test(es.filter)){value=value>=.9999?"":"alpha(opacity="+value*100+")";es.filter=es.filter.replace(reOpacity,value)}else{es.filter+=" alpha(opacity="+value*100+")"}return element}}fabric.util.setStyle=setStyle})();(function(){var _slice=Array.prototype.slice;function getById(id){return typeof id==="string"?fabric.document.getElementById(id):id}var sliceCanConvertNodelists,toArray=function(arrayLike){return _slice.call(arrayLike,0)};try{sliceCanConvertNodelists=toArray(fabric.document.childNodes)instanceof Array}catch(err){}if(!sliceCanConvertNodelists){toArray=function(arrayLike){var arr=new Array(arrayLike.length),i=arrayLike.length;while(i--){arr[i]=arrayLike[i]}return arr}}function makeElement(tagName,attributes){var el=fabric.document.createElement(tagName);for(var prop in attributes){if(prop==="class"){el.className=attributes[prop]}else if(prop==="for"){el.htmlFor=attributes[prop]}else{el.setAttribute(prop,attributes[prop])}}return el}function addClass(element,className){if(element&&(" "+element.className+" ").indexOf(" "+className+" ")===-1){element.className+=(element.className?" ":"")+className}}function wrapElement(element,wrapper,attributes){if(typeof wrapper==="string"){wrapper=makeElement(wrapper,attributes)}if(element.parentNode){element.parentNode.replaceChild(wrapper,element)}wrapper.appendChild(element);return wrapper}function getScrollLeftTop(element,upperCanvasEl){var firstFixedAncestor,origElement,left=0,top=0,docElement=fabric.document.documentElement,body=fabric.document.body||{scrollLeft:0,scrollTop:0};origElement=element;while(element&&element.parentNode&&!firstFixedAncestor){element=element.parentNode;if(element.nodeType===1&&fabric.util.getElementStyle(element,"position")==="fixed"){firstFixedAncestor=element}if(element.nodeType===1&&origElement!==upperCanvasEl&&fabric.util.getElementStyle(element,"position")==="absolute"){left=0;top=0}else if(element===fabric.document){left=body.scrollLeft||docElement.scrollLeft||0;top=body.scrollTop||docElement.scrollTop||0}else{left+=element.scrollLeft||0;top+=element.scrollTop||0}}return{left:left,top:top}}function getElementOffset(element){var docElem,doc=element&&element.ownerDocument,box={left:0,top:0},offset={left:0,top:0},scrollLeftTop,offsetAttributes={borderLeftWidth:"left",borderTopWidth:"top",paddingLeft:"left",paddingTop:"top"};if(!doc){return{left:0,top:0}}for(var attr in offsetAttributes){offset[offsetAttributes[attr]]+=parseInt(getElementStyle(element,attr),10)||0}docElem=doc.documentElement;if(typeof element.getBoundingClientRect!=="undefined"){box=element.getBoundingClientRect()}scrollLeftTop=fabric.util.getScrollLeftTop(element,null);return{left:box.left+scrollLeftTop.left-(docElem.clientLeft||0)+offset.left,top:box.top+scrollLeftTop.top-(docElem.clientTop||0)+offset.top}}var getElementStyle;if(fabric.document.defaultView&&fabric.document.defaultView.getComputedStyle){getElementStyle=function(element,attr){var style=fabric.document.defaultView.getComputedStyle(element,null);return style?style[attr]:undefined}}else{getElementStyle=function(element,attr){var value=element.style[attr];if(!value&&element.currentStyle){value=element.currentStyle[attr]}return value}}(function(){var style=fabric.document.documentElement.style,selectProp="userSelect"in style?"userSelect":"MozUserSelect"in style?"MozUserSelect":"WebkitUserSelect"in style?"WebkitUserSelect":"KhtmlUserSelect"in style?"KhtmlUserSelect":"";function makeElementUnselectable(element){if(typeof element.onselectstart!=="undefined"){element.onselectstart=fabric.util.falseFunction}if(selectProp){element.style[selectProp]="none"}else if(typeof element.unselectable==="string"){element.unselectable="on"}return element}function makeElementSelectable(element){if(typeof element.onselectstart!=="undefined"){element.onselectstart=null}if(selectProp){element.style[selectProp]=""}else if(typeof element.unselectable==="string"){element.unselectable=""}return element}fabric.util.makeElementUnselectable=makeElementUnselectable;fabric.util.makeElementSelectable=makeElementSelectable})();(function(){function getScript(url,callback){var headEl=fabric.document.getElementsByTagName("head")[0],scriptEl=fabric.document.createElement("script"),loading=true;scriptEl.onload=scriptEl.onreadystatechange=function(e){if(loading){if(typeof this.readyState==="string"&&this.readyState!=="loaded"&&this.readyState!=="complete"){return}loading=false;callback(e||fabric.window.event);scriptEl=scriptEl.onload=scriptEl.onreadystatechange=null}};scriptEl.src=url;headEl.appendChild(scriptEl)}fabric.util.getScript=getScript})();fabric.util.getById=getById;fabric.util.toArray=toArray;fabric.util.makeElement=makeElement;fabric.util.addClass=addClass;fabric.util.wrapElement=wrapElement;fabric.util.getScrollLeftTop=getScrollLeftTop;fabric.util.getElementOffset=getElementOffset;fabric.util.getElementStyle=getElementStyle})();(function(){function addParamToUrl(url,param){return url+(/\?/.test(url)?"&":"?")+param}var makeXHR=function(){var factories=[function(){return new ActiveXObject("Microsoft.XMLHTTP")},function(){return new ActiveXObject("Msxml2.XMLHTTP")},function(){return new ActiveXObject("Msxml2.XMLHTTP.3.0")},function(){return new XMLHttpRequest}];for(var i=factories.length;i--;){try{var req=factories[i]();if(req){return factories[i]}}catch(err){}}}();function emptyFn(){}function request(url,options){options||(options={});var method=options.method?options.method.toUpperCase():"GET",onComplete=options.onComplete||function(){},xhr=makeXHR(),body;xhr.onreadystatechange=function(){if(xhr.readyState===4){onComplete(xhr);xhr.onreadystatechange=emptyFn}};if(method==="GET"){body=null;if(typeof options.parameters==="string"){url=addParamToUrl(url,options.parameters)}}xhr.open(method,url,true);if(method==="POST"||method==="PUT"){xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded")}xhr.send(body);return xhr}fabric.util.request=request})();fabric.log=function(){};fabric.warn=function(){};if(typeof console!=="undefined"){["log","warn"].forEach(function(methodName){if(typeof console[methodName]!=="undefined"&&typeof console[methodName].apply==="function"){fabric[methodName]=function(){return console[methodName].apply(console,arguments)}}})}(function(){function animate(options){requestAnimFrame(function(timestamp){options||(options={});var start=timestamp||+new Date,duration=options.duration||500,finish=start+duration,time,onChange=options.onChange||function(){},abort=options.abort||function(){return false},easing=options.easing||function(t,b,c,d){return-c*Math.cos(t/d*(Math.PI/2))+c+b},startValue="startValue"in options?options.startValue:0,endValue="endValue"in options?options.endValue:100,byValue=options.byValue||endValue-startValue;options.onStart&&options.onStart();(function tick(ticktime){time=ticktime||+new Date;var currentTime=time>finish?duration:time-start;if(abort()){options.onComplete&&options.onComplete();return}onChange(easing(currentTime,startValue,byValue,duration));if(time>finish){options.onComplete&&options.onComplete();return}requestAnimFrame(tick)})(start)})}var _requestAnimFrame=fabric.window.requestAnimationFrame||fabric.window.webkitRequestAnimationFrame||fabric.window.mozRequestAnimationFrame||fabric.window.oRequestAnimationFrame||fabric.window.msRequestAnimationFrame||function(callback){fabric.window.setTimeout(callback,1e3/60)};function requestAnimFrame(){return _requestAnimFrame.apply(fabric.window,arguments)}fabric.util.animate=animate;fabric.util.requestAnimFrame=requestAnimFrame})();(function(){function normalize(a,c,p,s){if(a1){matrices.shift();combinedMatrix=fabric.util.multiplyTransformMatrices(combinedMatrix,matrices[0])}return combinedMatrix}}();function parseStyleString(style,oStyle){var attr,value;style.replace(/;$/,"").split(";").forEach(function(chunk){var pair=chunk.split(":");attr=normalizeAttr(pair[0].trim().toLowerCase());value=normalizeValue(attr,pair[1].trim());oStyle[attr]=value})}function parseStyleObject(style,oStyle){var attr,value;for(var prop in style){if(typeof style[prop]==="undefined"){continue}attr=normalizeAttr(prop.toLowerCase());value=normalizeValue(attr,style[prop]);oStyle[attr]=value}}function getGlobalStylesForElement(element,svgUid){var styles={};for(var rule in fabric.cssRules[svgUid]){if(elementMatchesRule(element,rule.split(" "))){for(var property in fabric.cssRules[svgUid][rule]){styles[property]=fabric.cssRules[svgUid][rule][property]}}}return styles}function elementMatchesRule(element,selectors){var firstMatching,parentMatching=true;firstMatching=selectorMatches(element,selectors.pop());if(firstMatching&&selectors.length){parentMatching=doesSomeParentMatch(element,selectors)}return firstMatching&&parentMatching&&selectors.length===0}function doesSomeParentMatch(element,selectors){var selector,parentMatching=true;while(element.parentNode&&element.parentNode.nodeType===1&&selectors.length){if(parentMatching){selector=selectors.pop()}element=element.parentNode;parentMatching=selectorMatches(element,selector)}return selectors.length===0}function selectorMatches(element,selector){var nodeName=element.nodeName,classNames=element.getAttribute("class"),id=element.getAttribute("id"),matcher;matcher=new RegExp("^"+nodeName,"i");selector=selector.replace(matcher,"");if(id&&selector.length){matcher=new RegExp("#"+id+"(?![a-zA-Z\\-]+)","i");selector=selector.replace(matcher,"")}if(classNames&&selector.length){classNames=classNames.split(" ");for(var i=classNames.length;i--;){matcher=new RegExp("\\."+classNames[i]+"(?![a-zA-Z\\-]+)","i");selector=selector.replace(matcher,"")}}return selector.length===0}function parseUseDirectives(doc){var nodelist=doc.getElementsByTagName("use");while(nodelist.length){var el=nodelist[0],xlink=el.getAttribute("xlink:href").substr(1),x=el.getAttribute("x")||0,y=el.getAttribute("y")||0,el2=doc.getElementById(xlink).cloneNode(true),currentTrans=(el2.getAttribute("transform")||"")+" translate("+x+", "+y+")",parentNode;for(var j=0,attrs=el.attributes,l=attrs.length;jscaleY?scaleY:scaleX;if(!(scaleX!==1||scaleY!==1||minX!==0||minY!==0)){return}matrix=" matrix("+scaleX+" 0"+" 0 "+scaleY+" "+minX*scaleX+" "+minY*scaleY+") ";if(element.tagName==="svg"){el=element.ownerDocument.createElement("g");while(element.firstChild!=null){el.appendChild(element.firstChild)}element.appendChild(el)}else{el=element;matrix=el.getAttribute("transform")+matrix}el.setAttribute("transform",matrix)}fabric.parseSVGDocument=function(){var reAllowedSVGTagNames=/^(path|circle|polygon|polyline|ellipse|rect|line|image|text)$/,reViewBoxTagNames=/^(symbol|image|marker|pattern|view)$/;function hasAncestorWithNodeName(element,nodeName){while(element&&(element=element.parentNode)){if(nodeName.test(element.nodeName)&&!element.getAttribute("instantiated_by_use")){return true}}return false}return function(doc,callback,reviver){if(!doc){return}parseUseDirectives(doc);var startTime=new Date,svgUid=fabric.Object.__uid++,widthAttr,heightAttr,toBeParsed=false;if(doc.getAttribute("width")&&doc.getAttribute("width")!=="100%"){widthAttr=parseUnit(doc.getAttribute("width"))}if(doc.getAttribute("height")&&doc.getAttribute("height")!=="100%"){heightAttr=parseUnit(doc.getAttribute("height"))}if(!widthAttr||!heightAttr){var viewBoxAttr=doc.getAttribute("viewBox");if(viewBoxAttr&&(viewBoxAttr=viewBoxAttr.match(reViewBoxAttrValue))){widthAttr=parseFloat(viewBoxAttr[3]),heightAttr=parseFloat(viewBoxAttr[4])}else{toBeParsed=true}}addVBTransform(doc,widthAttr,heightAttr);var descendants=fabric.util.toArray(doc.getElementsByTagName("*"));if(descendants.length===0&&fabric.isLikelyNode){descendants=doc.selectNodes('//*[name(.)!="svg"]');var arr=[];for(var i=0,len=descendants.length;i','')}}var reFontDeclaration=new RegExp("(normal|italic)?\\s*(normal|small-caps)?\\s*"+"(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\s*("+fabric.reNum+"(?:px|cm|mm|em|pt|pc|in)*)(?:\\/(normal|"+fabric.reNum+"))?\\s+(.*)");extend(fabric,{parseFontDeclaration:function(value,oStyle){var match=value.match(reFontDeclaration);if(!match){return}var fontStyle=match[1],fontWeight=match[3],fontSize=match[4],lineHeight=match[5],fontFamily=match[6];if(fontStyle){oStyle.fontStyle=fontStyle}if(fontWeight){oStyle.fontWeight=isNaN(parseFloat(fontWeight))?fontWeight:parseFloat(fontWeight)}if(fontSize){oStyle.fontSize=parseUnit(fontSize)}if(fontFamily){oStyle.fontFamily=fontFamily}if(lineHeight){oStyle.lineHeight=lineHeight==="normal"?1:lineHeight}},getGradientDefs:function(doc){var linearGradientEls=doc.getElementsByTagName("linearGradient"),radialGradientEls=doc.getElementsByTagName("radialGradient"),el,i,j=0,id,xlink,elList=[],gradientDefs={},idsToXlinkMap={};elList.length=linearGradientEls.length+radialGradientEls.length;i=linearGradientEls.length;while(i--){elList[j++]=linearGradientEls[i]}i=radialGradientEls.length;while(i--){elList[j++]=radialGradientEls[i]}while(j--){el=elList[j];xlink=el.getAttribute("xlink:href");id=el.getAttribute("id");if(xlink){idsToXlinkMap[id]=xlink.substr(1)}gradientDefs[id]=el}for(id in idsToXlinkMap){var el2=gradientDefs[idsToXlinkMap[id]].cloneNode(true);el=gradientDefs[id];while(el2.firstChild){el.appendChild(el2.firstChild)}}return gradientDefs},parseAttributes:function(element,attributes,svgUid){if(!element){return}var value,parentAttributes={},fontSize;if(typeof svgUid==="undefined"){svgUid=element.getAttribute("svgUid")}if(element.parentNode&&/^symbol|[g|a]$/i.test(element.parentNode.nodeName)){parentAttributes=fabric.parseAttributes(element.parentNode,attributes,svgUid)}fontSize=parentAttributes&&parentAttributes.fontSize||element.getAttribute("font-size")||fabric.Text.DEFAULT_SVG_FONT_SIZE;var ownAttributes=attributes.reduce(function(memo,attr){value=element.getAttribute(attr);if(value){attr=normalizeAttr(attr);value=normalizeValue(attr,value,parentAttributes,fontSize);memo[attr]=value}return memo},{});ownAttributes=extend(ownAttributes,extend(getGlobalStylesForElement(element,svgUid),fabric.parseStyleAttribute(element)));if(ownAttributes.font){fabric.parseFontDeclaration(ownAttributes.font,ownAttributes)}return _setStrokeFillOpacity(extend(parentAttributes,ownAttributes))},parseElements:function(elements,callback,options,reviver){new fabric.ElementsParser(elements,callback,options,reviver).parse()},parseStyleAttribute:function(element){var oStyle={},style=element.getAttribute("style");if(!style){return oStyle}if(typeof style==="string"){parseStyleString(style,oStyle)}else{parseStyleObject(style,oStyle)}return oStyle},parsePointsAttribute:function(points){if(!points){return null}points=points.replace(/,/g," ").trim();points=points.split(/\s+/);var parsedPoints=[],i,len;i=0;len=points.length;for(;i/i,""))}if(!xml||!xml.documentElement){return}fabric.parseSVGDocument(xml.documentElement,function(results,options){svgCache.set(url,{objects:fabric.util.array.invoke(results,"toObject"),options:options});callback(results,options)},reviver)}},loadSVGFromString:function(string,callback,reviver){string=string.trim();var doc;if(typeof DOMParser!=="undefined"){var parser=new DOMParser;if(parser&&parser.parseFromString){doc=parser.parseFromString(string,"text/xml")}}else if(fabric.window.ActiveXObject){doc=new ActiveXObject("Microsoft.XMLDOM");doc.async="false";doc.loadXML(string.replace(//i,""))}fabric.parseSVGDocument(doc.documentElement,function(results,options){callback(results,options)},reviver)},createSVGFontFacesMarkup:function(objects){var markup="";for(var i=0,len=objects.length;i',"",""].join("")}return markup},createSVGRefElementsMarkup:function(canvas){var markup=[];_createSVGPattern(markup,canvas,"backgroundColor");_createSVGPattern(markup,canvas,"overlayColor");return markup.join("")}})})(typeof exports!=="undefined"?exports:this);fabric.ElementsParser=function(elements,callback,options,reviver){this.elements=elements;this.callback=callback;this.options=options;this.reviver=reviver;this.svgUid=options&&options.svgUid||0};fabric.ElementsParser.prototype.parse=function(){this.instances=new Array(this.elements.length);this.numElements=this.elements.length;this.createObjects()};fabric.ElementsParser.prototype.createObjects=function(){for(var i=0,len=this.elements.length;ithat.x&&this.y>that.y},gte:function(that){return this.x>=that.x&&this.y>=that.y},lerp:function(that,t){return new Point(this.x+(that.x-this.x)*t,this.y+(that.y-this.y)*t)},distanceFrom:function(that){var dx=this.x-that.x,dy=this.y-that.y;return Math.sqrt(dx*dx+dy*dy)},midPointFrom:function(that){return new Point(this.x+(that.x-this.x)/2,this.y+(that.y-this.y)/2)},min:function(that){return new Point(Math.min(this.x,that.x),Math.min(this.y,that.y))},max:function(that){return new Point(Math.max(this.x,that.x),Math.max(this.y,that.y))},toString:function(){return this.x+","+this.y},setXY:function(x,y){this.x=x;this.y=y},setFromPoint:function(that){this.x=that.x;this.y=that.y},swap:function(that){var x=this.x,y=this.y;this.x=that.x;this.y=that.y;that.x=x;that.y=y}}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={});if(fabric.Intersection){fabric.warn("fabric.Intersection is already defined");return}function Intersection(status){this.status=status;this.points=[]}fabric.Intersection=Intersection;fabric.Intersection.prototype={appendPoint:function(point){this.points.push(point)},appendPoints:function(points){this.points=this.points.concat(points)}};fabric.Intersection.intersectLineLine=function(a1,a2,b1,b2){var result,uaT=(b2.x-b1.x)*(a1.y-b1.y)-(b2.y-b1.y)*(a1.x-b1.x),ubT=(a2.x-a1.x)*(a1.y-b1.y)-(a2.y-a1.y)*(a1.x-b1.x),uB=(b2.y-b1.y)*(a2.x-a1.x)-(b2.x-b1.x)*(a2.y-a1.y);if(uB!==0){var ua=uaT/uB,ub=ubT/uB;if(0<=ua&&ua<=1&&0<=ub&&ub<=1){result=new Intersection("Intersection");result.points.push(new fabric.Point(a1.x+ua*(a2.x-a1.x),a1.y+ua*(a2.y-a1.y)))}else{result=new Intersection}}else{if(uaT===0||ubT===0){result=new Intersection("Coincident")}else{result=new Intersection("Parallel")}}return result};fabric.Intersection.intersectLinePolygon=function(a1,a2,points){var result=new Intersection,length=points.length;for(var i=0;i0){result.status="Intersection"}return result};fabric.Intersection.intersectPolygonPolygon=function(points1,points2){var result=new Intersection,length=points1.length;for(var i=0;i0){result.status="Intersection"}return result};fabric.Intersection.intersectPolygonRectangle=function(points,r1,r2){var min=r1.min(r2),max=r1.max(r2),topRight=new fabric.Point(max.x,min.y),bottomLeft=new fabric.Point(min.x,max.y),inter1=Intersection.intersectLinePolygon(min,topRight,points),inter2=Intersection.intersectLinePolygon(topRight,max,points),inter3=Intersection.intersectLinePolygon(max,bottomLeft,points),inter4=Intersection.intersectLinePolygon(bottomLeft,min,points),result=new Intersection;result.appendPoints(inter1.points);result.appendPoints(inter2.points);result.appendPoints(inter3.points);result.appendPoints(inter4.points);if(result.points.length>0){result.status="Intersection"}return result}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={});if(fabric.Color){fabric.warn("fabric.Color is already defined.");return}function Color(color){if(!color){this.setSource([0,0,0,1])}else{this._tryParsingColor(color)}}fabric.Color=Color;fabric.Color.prototype={_tryParsingColor:function(color){var source;if(color in Color.colorNameMap){color=Color.colorNameMap[color]}if(color==="transparent"){this.setSource([255,255,255,0]);return}source=Color.sourceFromHex(color);if(!source){source=Color.sourceFromRgb(color)}if(!source){source=Color.sourceFromHsl(color)}if(source){this.setSource(source)}},_rgbToHsl:function(r,g,b){r/=255,g/=255,b/=255;var h,s,l,max=fabric.util.array.max([r,g,b]),min=fabric.util.array.min([r,g,b]);l=(max+min)/2;if(max===min){h=s=0}else{var d=max-min;s=l>.5?d/(2-max-min):d/(max+min);switch(max){case r:h=(g-b)/d+(g1){t-=1}if(t<1/6){return p+(q-p)*6*t}if(t<1/2){return q}if(t<2/3){return p+(q-p)*(2/3-t)*6}return p}fabric.Color.fromRgb=function(color){return Color.fromSource(Color.sourceFromRgb(color))};fabric.Color.sourceFromRgb=function(color){var match=color.match(Color.reRGBa);if(match){var r=parseInt(match[1],10)/(/%$/.test(match[1])?100:1)*(/%$/.test(match[1])?255:1),g=parseInt(match[2],10)/(/%$/.test(match[2])?100:1)*(/%$/.test(match[2])?255:1),b=parseInt(match[3],10)/(/%$/.test(match[3])?100:1)*(/%$/.test(match[3])?255:1);return[parseInt(r,10),parseInt(g,10),parseInt(b,10),match[4]?parseFloat(match[4]):1]}};fabric.Color.fromRgba=Color.fromRgb; + +fabric.Color.fromHsl=function(color){return Color.fromSource(Color.sourceFromHsl(color))};fabric.Color.sourceFromHsl=function(color){var match=color.match(Color.reHSLa);if(!match){return}var h=(parseFloat(match[1])%360+360)%360/360,s=parseFloat(match[2])/(/%$/.test(match[2])?100:1),l=parseFloat(match[3])/(/%$/.test(match[3])?100:1),r,g,b;if(s===0){r=g=b=l}else{var q=l<=.5?l*(s+1):l+s-l*s,p=l*2-q;r=hue2rgb(p,q,h+1/3);g=hue2rgb(p,q,h);b=hue2rgb(p,q,h-1/3)}return[Math.round(r*255),Math.round(g*255),Math.round(b*255),match[4]?parseFloat(match[4]):1]};fabric.Color.fromHsla=Color.fromHsl;fabric.Color.fromHex=function(color){return Color.fromSource(Color.sourceFromHex(color))};fabric.Color.sourceFromHex=function(color){if(color.match(Color.reHex)){var value=color.slice(color.indexOf("#")+1),isShortNotation=value.length===3,r=isShortNotation?value.charAt(0)+value.charAt(0):value.substring(0,2),g=isShortNotation?value.charAt(1)+value.charAt(1):value.substring(2,4),b=isShortNotation?value.charAt(2)+value.charAt(2):value.substring(4,6);return[parseInt(r,16),parseInt(g,16),parseInt(b,16),1]}};fabric.Color.fromSource=function(source){var oColor=new Color;oColor.setSource(source);return oColor}})(typeof exports!=="undefined"?exports:this);(function(){function getColorStop(el){var style=el.getAttribute("style"),offset=el.getAttribute("offset"),color,colorAlpha,opacity;offset=parseFloat(offset)/(/%$/.test(offset)?100:1);offset=offset<0?0:offset>1?1:offset;if(style){var keyValuePairs=style.split(/\s*;\s*/);if(keyValuePairs[keyValuePairs.length-1]===""){keyValuePairs.pop()}for(var i=keyValuePairs.length;i--;){var split=keyValuePairs[i].split(/\s*:\s*/),key=split[0].trim(),value=split[1].trim();if(key==="stop-color"){color=value}else if(key==="stop-opacity"){opacity=value}}}if(!color){color=el.getAttribute("stop-color")||"rgb(0,0,0)"}if(!opacity){opacity=el.getAttribute("stop-opacity")}color=new fabric.Color(color);colorAlpha=color.getAlpha();opacity=isNaN(parseFloat(opacity))?1:parseFloat(opacity);opacity*=colorAlpha;return{offset:offset,color:color.toRgb(),opacity:opacity}}function getLinearCoords(el){return{x1:el.getAttribute("x1")||0,y1:el.getAttribute("y1")||0,x2:el.getAttribute("x2")||"100%",y2:el.getAttribute("y2")||0}}function getRadialCoords(el){return{x1:el.getAttribute("fx")||el.getAttribute("cx")||"50%",y1:el.getAttribute("fy")||el.getAttribute("cy")||"50%",r1:0,x2:el.getAttribute("cx")||"50%",y2:el.getAttribute("cy")||"50%",r2:el.getAttribute("r")||"50%"}}fabric.Gradient=fabric.util.createClass({offsetX:0,offsetY:0,initialize:function(options){options||(options={});var coords={};this.id=fabric.Object.__uid++;this.type=options.type||"linear";coords={x1:options.coords.x1||0,y1:options.coords.y1||0,x2:options.coords.x2||0,y2:options.coords.y2||0};if(this.type==="radial"){coords.r1=options.coords.r1||0;coords.r2=options.coords.r2||0}this.coords=coords;this.colorStops=options.colorStops.slice();if(options.gradientTransform){this.gradientTransform=options.gradientTransform}this.offsetX=options.offsetX||this.offsetX;this.offsetY=options.offsetY||this.offsetY},addColorStop:function(colorStop){for(var position in colorStop){var color=new fabric.Color(colorStop[position]);this.colorStops.push({offset:position,color:color.toRgb(),opacity:color.getAlpha()})}return this},toObject:function(){return{type:this.type,coords:this.coords,colorStops:this.colorStops,offsetX:this.offsetX,offsetY:this.offsetY}},toSVG:function(object){var coords=fabric.util.object.clone(this.coords),markup,commonAttributes;this.colorStops.sort(function(a,b){return a.offset-b.offset});if(!(object.group&&object.group.type==="path-group")){for(var prop in coords){if(prop==="x1"||prop==="x2"||prop==="r2"){coords[prop]+=this.offsetX-object.width/2}else if(prop==="y1"||prop==="y2"){coords[prop]+=this.offsetY-object.height/2}}}commonAttributes='id="SVGID_'+this.id+'" gradientUnits="userSpaceOnUse"';if(this.gradientTransform){commonAttributes+=' gradientTransform="matrix('+this.gradientTransform.join(" ")+')" '}if(this.type==="linear"){markup=["\n']}else if(this.type==="radial"){markup=["\n']}for(var i=0;i\n')}markup.push(this.type==="linear"?"\n":"\n");return markup.join("")},toLive:function(ctx,object){var gradient,prop,coords=fabric.util.object.clone(this.coords);if(!this.type){return}if(object.group&&object.group.type==="path-group"){for(prop in coords){if(prop==="x1"||prop==="x2"){coords[prop]+=-this.offsetX+object.width/2}else if(prop==="y1"||prop==="y2"){coords[prop]+=-this.offsetY+object.height/2}}}if(object.type==="text"||object.type==="i-text"){for(prop in coords){if(prop==="x1"||prop==="x2"){coords[prop]-=object.width/2}else if(prop==="y1"||prop==="y2"){coords[prop]-=object.height/2}}}if(this.type==="linear"){gradient=ctx.createLinearGradient(coords.x1,coords.y1,coords.x2,coords.y2)}else if(this.type==="radial"){gradient=ctx.createRadialGradient(coords.x1,coords.y1,coords.r1,coords.x2,coords.y2,coords.r2)}for(var i=0,len=this.colorStops.length;i\n'+'\n'+"\n"},toLive:function(ctx){var source=typeof this.source==="function"?this.source():this.source;if(!source){return""}if(typeof source.src!=="undefined"){if(!source.complete){return""}if(source.naturalWidth===0||source.naturalHeight===0){return""}}return ctx.createPattern(source,this.repeat)}});(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),toFixed=fabric.util.toFixed;if(fabric.Shadow){fabric.warn("fabric.Shadow is already defined.");return}fabric.Shadow=fabric.util.createClass({color:"rgb(0,0,0)",blur:0,offsetX:0,offsetY:0,affectStroke:false,includeDefaultValues:true,initialize:function(options){if(typeof options==="string"){options=this._parseShadow(options)}for(var prop in options){this[prop]=options[prop]}this.id=fabric.Object.__uid++},_parseShadow:function(shadow){var shadowStr=shadow.trim(),offsetsAndBlur=fabric.Shadow.reOffsetsAndBlur.exec(shadowStr)||[],color=shadowStr.replace(fabric.Shadow.reOffsetsAndBlur,"")||"rgb(0,0,0)";return{color:color.trim(),offsetX:parseInt(offsetsAndBlur[1],10)||0,offsetY:parseInt(offsetsAndBlur[2],10)||0,blur:parseInt(offsetsAndBlur[3],10)||0}},toString:function(){return[this.offsetX,this.offsetY,this.blur,this.color].join("px ")},toSVG:function(object){var mode="SourceAlpha",fBoxX=40,fBoxY=40;if(object&&(object.fill===this.color||object.stroke===this.color)){mode="SourceGraphic"}if(object.width&&object.height){fBoxX=toFixed(Math.abs(this.offsetX/object.getWidth()),2)*100+20;fBoxY=toFixed(Math.abs(this.offsetY/object.getHeight()),2)*100+20}return'\n"+' \n'+' \n'+' \n'+" \n"+" \n"+' \n'+" \n"+"\n"},toObject:function(){if(this.includeDefaultValues){return{color:this.color,blur:this.blur,offsetX:this.offsetX,offsetY:this.offsetY}}var obj={},proto=fabric.Shadow.prototype;if(this.color!==proto.color){obj.color=this.color}if(this.blur!==proto.blur){obj.blur=this.blur}if(this.offsetX!==proto.offsetX){obj.offsetX=this.offsetX}if(this.offsetY!==proto.offsetY){obj.offsetY=this.offsetY}return obj}});fabric.Shadow.reOffsetsAndBlur=/(?:\s|^)(-?\d+(?:px)?(?:\s?|$))?(-?\d+(?:px)?(?:\s?|$))?(\d+(?:px)?)?(?:\s?|$)(?:$|\s)/})(typeof exports!=="undefined"?exports:this);(function(){"use strict";if(fabric.StaticCanvas){fabric.warn("fabric.StaticCanvas is already defined.");return}var extend=fabric.util.object.extend,getElementOffset=fabric.util.getElementOffset,removeFromArray=fabric.util.removeFromArray,CANVAS_INIT_ERROR=new Error("Could not initialize `canvas` element");fabric.StaticCanvas=fabric.util.createClass({initialize:function(el,options){options||(options={});this._initStatic(el,options);fabric.StaticCanvas.activeInstance=this},backgroundColor:"",backgroundImage:null,overlayColor:"",overlayImage:null,includeDefaultValues:true,stateful:true,renderOnAddRemove:true,clipTo:null,controlsAboveOverlay:false,allowTouchScrolling:false,imageSmoothingEnabled:true,preserveObjectStacking:false,viewportTransform:[1,0,0,1,0,0],onBeforeScaleRotate:function(){},_initStatic:function(el,options){this._objects=[];this._createLowerCanvas(el);this._initOptions(options);this._setImageSmoothing();if(options.overlayImage){this.setOverlayImage(options.overlayImage,this.renderAll.bind(this))}if(options.backgroundImage){this.setBackgroundImage(options.backgroundImage,this.renderAll.bind(this))}if(options.backgroundColor){this.setBackgroundColor(options.backgroundColor,this.renderAll.bind(this))}if(options.overlayColor){this.setOverlayColor(options.overlayColor,this.renderAll.bind(this))}this.calcOffset()},calcOffset:function(){this._offset=getElementOffset(this.lowerCanvasEl);return this},setOverlayImage:function(image,callback,options){return this.__setBgOverlayImage("overlayImage",image,callback,options)},setBackgroundImage:function(image,callback,options){return this.__setBgOverlayImage("backgroundImage",image,callback,options)},setOverlayColor:function(overlayColor,callback){return this.__setBgOverlayColor("overlayColor",overlayColor,callback)},setBackgroundColor:function(backgroundColor,callback){return this.__setBgOverlayColor("backgroundColor",backgroundColor,callback)},_setImageSmoothing:function(){var ctx=this.getContext();ctx.imageSmoothingEnabled=this.imageSmoothingEnabled;ctx.webkitImageSmoothingEnabled=this.imageSmoothingEnabled;ctx.mozImageSmoothingEnabled=this.imageSmoothingEnabled;ctx.msImageSmoothingEnabled=this.imageSmoothingEnabled;ctx.oImageSmoothingEnabled=this.imageSmoothingEnabled},__setBgOverlayImage:function(property,image,callback,options){if(typeof image==="string"){fabric.util.loadImage(image,function(img){this[property]=new fabric.Image(img,options);callback&&callback()},this,options&&options.crossOrigin)}else{options&&image.setOptions(options);this[property]=image;callback&&callback()}return this},__setBgOverlayColor:function(property,color,callback){if(color&&color.source){var _this=this;fabric.util.loadImage(color.source,function(img){_this[property]=new fabric.Pattern({source:img,repeat:color.repeat,offsetX:color.offsetX,offsetY:color.offsetY});callback&&callback()})}else{this[property]=color;callback&&callback()}return this},_createCanvasElement:function(){var element=fabric.document.createElement("canvas");if(!element.style){element.style={}}if(!element){throw CANVAS_INIT_ERROR}this._initCanvasElement(element);return element},_initCanvasElement:function(element){fabric.util.createCanvasElement(element);if(typeof element.getContext==="undefined"){throw CANVAS_INIT_ERROR}},_initOptions:function(options){for(var prop in options){this[prop]=options[prop]}this.width=this.width||parseInt(this.lowerCanvasEl.width,10)||0;this.height=this.height||parseInt(this.lowerCanvasEl.height,10)||0;if(!this.lowerCanvasEl.style){return}this.lowerCanvasEl.width=this.width;this.lowerCanvasEl.height=this.height;this.lowerCanvasEl.style.width=this.width+"px";this.lowerCanvasEl.style.height=this.height+"px";this.viewportTransform=this.viewportTransform.slice()},_createLowerCanvas:function(canvasEl){this.lowerCanvasEl=fabric.util.getById(canvasEl)||this._createCanvasElement();this._initCanvasElement(this.lowerCanvasEl);fabric.util.addClass(this.lowerCanvasEl,"lower-canvas");if(this.interactive){this._applyCanvasStyle(this.lowerCanvasEl)}this.contextContainer=this.lowerCanvasEl.getContext("2d")},getWidth:function(){return this.width},getHeight:function(){return this.height},setWidth:function(value,options){return this.setDimensions({width:value},options)},setHeight:function(value,options){return this.setDimensions({height:value},options)},setDimensions:function(dimensions,options){var cssValue;options=options||{};for(var prop in dimensions){cssValue=dimensions[prop];if(!options.cssOnly){this._setBackstoreDimension(prop,dimensions[prop]);cssValue+="px"}if(!options.backstoreOnly){this._setCssDimension(prop,cssValue)}}if(!options.cssOnly){this.renderAll()}this.calcOffset();return this},_setBackstoreDimension:function(prop,value){this.lowerCanvasEl[prop]=value;if(this.upperCanvasEl){this.upperCanvasEl[prop]=value}if(this.cacheCanvasEl){this.cacheCanvasEl[prop]=value}this[prop]=value;return this},_setCssDimension:function(prop,value){this.lowerCanvasEl.style[prop]=value;if(this.upperCanvasEl){this.upperCanvasEl.style[prop]=value}if(this.wrapperEl){this.wrapperEl.style[prop]=value}return this},getZoom:function(){return Math.sqrt(this.viewportTransform[0]*this.viewportTransform[3])},setViewportTransform:function(vpt){var activeGroup=this.getActiveGroup();this.viewportTransform=vpt;this.renderAll();for(var i=0,len=this._objects.length;i");return markup.join("")},_setSVGPreamble:function(markup,options){if(!options.suppressPreamble){markup.push('','\n')}},_setSVGHeader:function(markup,options){var width,height,vpt;if(options.viewBox){width=options.viewBox.width;height=options.viewBox.height}else{width=this.width;height=this.height;if(!this.svgViewportTransformation){vpt=this.viewportTransform;width/=vpt[0];height/=vpt[3]}}markup.push("',"Created with Fabric.js ",fabric.version,"","",fabric.createSVGFontFacesMarkup(this.getObjects()),fabric.createSVGRefElementsMarkup(this),"")},_setSVGObjects:function(markup,reviver){for(var i=0,objects=this.getObjects(),len=objects.length;i
")}else if(this[property]&&property==="overlayColor"){markup.push('")}},sendToBack:function(object){removeFromArray(this._objects,object);this._objects.unshift(object);return this.renderAll&&this.renderAll()},bringToFront:function(object){removeFromArray(this._objects,object);this._objects.push(object);return this.renderAll&&this.renderAll()},sendBackwards:function(object,intersecting){var idx=this._objects.indexOf(object);if(idx!==0){var newIdx=this._findNewLowerIndex(object,idx,intersecting);removeFromArray(this._objects,object);this._objects.splice(newIdx,0,object);this.renderAll&&this.renderAll()}return this},_findNewLowerIndex:function(object,idx,intersecting){var newIdx;if(intersecting){newIdx=idx;for(var i=idx-1;i>=0;--i){var isIntersecting=object.intersectsWithObject(this._objects[i])||object.isContainedWithinObject(this._objects[i])||this._objects[i].isContainedWithinObject(object);if(isIntersecting){newIdx=i;break}}}else{newIdx=idx-1}return newIdx},bringForward:function(object,intersecting){var idx=this._objects.indexOf(object);if(idx!==this._objects.length-1){var newIdx=this._findNewUpperIndex(object,idx,intersecting);removeFromArray(this._objects,object);this._objects.splice(newIdx,0,object);this.renderAll&&this.renderAll()}return this},_findNewUpperIndex:function(object,idx,intersecting){var newIdx;if(intersecting){newIdx=idx;for(var i=idx+1;i"}});extend(fabric.StaticCanvas.prototype,fabric.Observable);extend(fabric.StaticCanvas.prototype,fabric.Collection);extend(fabric.StaticCanvas.prototype,fabric.DataURLExporter);extend(fabric.StaticCanvas,{EMPTY_JSON:'{"objects": [], "background": "white"}',supports:function(methodName){var el=fabric.util.createCanvasElement();if(!el||!el.getContext){return null}var ctx=el.getContext("2d");if(!ctx){return null}switch(methodName){case"getImageData":return typeof ctx.getImageData!=="undefined";case"setLineDash":return typeof ctx.setLineDash!=="undefined";case"toDataURL":return typeof el.toDataURL!=="undefined";case"toDataURLWithQuality":try{el.toDataURL("image/jpeg",0);return true}catch(e){}return false;default:return null}}});fabric.StaticCanvas.prototype.toJSON=fabric.StaticCanvas.prototype.toObject})();fabric.BaseBrush=fabric.util.createClass({color:"rgb(0, 0, 0)",width:1,shadow:null,strokeLineCap:"round",strokeLineJoin:"round",strokeDashArray:null,setShadow:function(options){this.shadow=new fabric.Shadow(options);return this},_setBrushStyles:function(){var ctx=this.canvas.contextTop;ctx.strokeStyle=this.color;ctx.lineWidth=this.width;ctx.lineCap=this.strokeLineCap;ctx.lineJoin=this.strokeLineJoin;if(this.strokeDashArray&&fabric.StaticCanvas.supports("setLineDash")){ctx.setLineDash(this.strokeDashArray)}},_setShadow:function(){if(!this.shadow){return}var ctx=this.canvas.contextTop;ctx.shadowColor=this.shadow.color;ctx.shadowBlur=this.shadow.blur;ctx.shadowOffsetX=this.shadow.offsetX;ctx.shadowOffsetY=this.shadow.offsetY},_resetShadow:function(){var ctx=this.canvas.contextTop;ctx.shadowColor="";ctx.shadowBlur=ctx.shadowOffsetX=ctx.shadowOffsetY=0}});(function(){fabric.PencilBrush=fabric.util.createClass(fabric.BaseBrush,{initialize:function(canvas){this.canvas=canvas;this._points=[]},onMouseDown:function(pointer){this._prepareForDrawing(pointer);this._captureDrawingPath(pointer);this._render()},onMouseMove:function(pointer){this._captureDrawingPath(pointer);this.canvas.clearContext(this.canvas.contextTop);this._render()},onMouseUp:function(){this._finalizeAndAddPath()},_prepareForDrawing:function(pointer){var p=new fabric.Point(pointer.x,pointer.y);this._reset();this._addPoint(p);this.canvas.contextTop.moveTo(p.x,p.y)},_addPoint:function(point){this._points.push(point)},_reset:function(){this._points.length=0;this._setBrushStyles();this._setShadow()},_captureDrawingPath:function(pointer){var pointerPoint=new fabric.Point(pointer.x,pointer.y);this._addPoint(pointerPoint)},_render:function(){ +var ctx=this.canvas.contextTop,v=this.canvas.viewportTransform,p1=this._points[0],p2=this._points[1];ctx.save();ctx.transform(v[0],v[1],v[2],v[3],v[4],v[5]);ctx.beginPath();if(this._points.length===2&&p1.x===p2.x&&p1.y===p2.y){p1.x-=.5;p2.x+=.5}ctx.moveTo(p1.x,p1.y);for(var i=1,len=this._points.length;itarget.padding){if(localMouse.x<0){localMouse.x+=target.padding}else{localMouse.x-=target.padding}}else{localMouse.x=0}if(abs(localMouse.y)>target.padding){if(localMouse.y<0){localMouse.y+=target.padding}else{localMouse.y-=target.padding}}else{localMouse.y=0}},_rotateObject:function(x,y){var t=this._currentTransform;if(t.target.get("lockRotation")){return}var lastAngle=atan2(t.ey-t.top,t.ex-t.left),curAngle=atan2(y-t.top,x-t.left),angle=radiansToDegrees(curAngle-lastAngle+t.theta);if(angle<0){angle=360+angle}t.target.angle=angle%360},setCursor:function(value){this.upperCanvasEl.style.cursor=value},_resetObjectTransform:function(target){target.scaleX=1;target.scaleY=1;target.setAngle(0)},_drawSelection:function(){var ctx=this.contextTop,groupSelector=this._groupSelector,left=groupSelector.left,top=groupSelector.top,aleft=abs(left),atop=abs(top);ctx.fillStyle=this.selectionColor;ctx.fillRect(groupSelector.ex-(left>0?0:-left),groupSelector.ey-(top>0?0:-top),aleft,atop);ctx.lineWidth=this.selectionLineWidth;ctx.strokeStyle=this.selectionBorderColor;if(this.selectionDashArray.length>1){var px=groupSelector.ex+STROKE_OFFSET-(left>0?0:aleft),py=groupSelector.ey+STROKE_OFFSET-(top>0?0:atop);ctx.beginPath();fabric.util.drawDashedLine(ctx,px,py,px+aleft,py,this.selectionDashArray);fabric.util.drawDashedLine(ctx,px,py+atop-1,px+aleft,py+atop-1,this.selectionDashArray);fabric.util.drawDashedLine(ctx,px,py,px,py+atop,this.selectionDashArray);fabric.util.drawDashedLine(ctx,px+aleft-1,py,px+aleft-1,py+atop,this.selectionDashArray);ctx.closePath();ctx.stroke()}else{ctx.strokeRect(groupSelector.ex+STROKE_OFFSET-(left>0?0:aleft),groupSelector.ey+STROKE_OFFSET-(top>0?0:atop),aleft,atop)}},_isLastRenderedObject:function(e){return this.controlsAboveOverlay&&this.lastRenderedObjectWithControlsAboveOverlay&&this.lastRenderedObjectWithControlsAboveOverlay.visible&&this.containsPoint(e,this.lastRenderedObjectWithControlsAboveOverlay)&&this.lastRenderedObjectWithControlsAboveOverlay._findTargetCorner(this.getPointer(e,true))},findTarget:function(e,skipGroup){if(this.skipTargetFind){return}if(this._isLastRenderedObject(e)){return this.lastRenderedObjectWithControlsAboveOverlay}var activeGroup=this.getActiveGroup();if(activeGroup&&!skipGroup&&this.containsPoint(e,activeGroup)){return activeGroup}var target=this._searchPossibleTargets(e);this._fireOverOutEvents(target);return target},_fireOverOutEvents:function(target){if(target){if(this._hoveredTarget!==target){this.fire("mouse:over",{target:target});target.fire("mouseover");if(this._hoveredTarget){this.fire("mouse:out",{target:this._hoveredTarget});this._hoveredTarget.fire("mouseout")}this._hoveredTarget=target}}else if(this._hoveredTarget){this.fire("mouse:out",{target:this._hoveredTarget});this._hoveredTarget.fire("mouseout");this._hoveredTarget=null}},_checkTarget:function(e,obj,pointer){if(obj&&obj.visible&&obj.evented&&this.containsPoint(e,obj)){if((this.perPixelTargetFind||obj.perPixelTargetFind)&&!obj.isEditing){var isTransparent=this.isTargetTransparent(obj,pointer.x,pointer.y);if(!isTransparent){return true}}else{return true}}},_searchPossibleTargets:function(e){var target,pointer=this.getPointer(e,true),i=this._objects.length;while(i--){if(!this._objects[i].group&&this._checkTarget(e,this._objects[i],pointer)){this.relatedTarget=this._objects[i];target=this._objects[i];break}}return target},getPointer:function(e,ignoreZoom,upperCanvasEl){if(!upperCanvasEl){upperCanvasEl=this.upperCanvasEl}var pointer=getPointer(e,upperCanvasEl),bounds=upperCanvasEl.getBoundingClientRect(),boundsWidth=bounds.width||0,boundsHeight=bounds.height||0,cssScale;if(!boundsWidth||!boundsHeight){if("top"in bounds&&"bottom"in bounds){boundsHeight=Math.abs(bounds.top-bounds.bottom)}if("right"in bounds&&"left"in bounds){boundsWidth=Math.abs(bounds.right-bounds.left)}}this.calcOffset();pointer.x=pointer.x-this._offset.left;pointer.y=pointer.y-this._offset.top;if(!ignoreZoom){pointer=fabric.util.transformPoint(pointer,fabric.util.invertTransform(this.viewportTransform))}if(boundsWidth===0||boundsHeight===0){cssScale={width:1,height:1}}else{cssScale={width:upperCanvasEl.width/boundsWidth,height:upperCanvasEl.height/boundsHeight}}return{x:pointer.x*cssScale.width,y:pointer.y*cssScale.height}},_createUpperCanvas:function(){var lowerCanvasClass=this.lowerCanvasEl.className.replace(/\s*lower-canvas\s*/,"");this.upperCanvasEl=this._createCanvasElement();fabric.util.addClass(this.upperCanvasEl,"upper-canvas "+lowerCanvasClass);this.wrapperEl.appendChild(this.upperCanvasEl);this._copyCanvasStyle(this.lowerCanvasEl,this.upperCanvasEl);this._applyCanvasStyle(this.upperCanvasEl);this.contextTop=this.upperCanvasEl.getContext("2d")},_createCacheCanvas:function(){this.cacheCanvasEl=this._createCanvasElement();this.cacheCanvasEl.setAttribute("width",this.width);this.cacheCanvasEl.setAttribute("height",this.height);this.contextCache=this.cacheCanvasEl.getContext("2d")},_initWrapperElement:function(){this.wrapperEl=fabric.util.wrapElement(this.lowerCanvasEl,"div",{"class":this.containerClass});fabric.util.setStyle(this.wrapperEl,{width:this.getWidth()+"px",height:this.getHeight()+"px",position:"relative"});fabric.util.makeElementUnselectable(this.wrapperEl)},_applyCanvasStyle:function(element){var width=this.getWidth()||element.width,height=this.getHeight()||element.height;fabric.util.setStyle(element,{position:"absolute",width:width+"px",height:height+"px",left:0,top:0});element.width=width;element.height=height;fabric.util.makeElementUnselectable(element)},_copyCanvasStyle:function(fromEl,toEl){toEl.style.cssText=fromEl.style.cssText},getSelectionContext:function(){return this.contextTop},getSelectionElement:function(){return this.upperCanvasEl},_setActiveObject:function(object){if(this._activeObject){this._activeObject.set("active",false)}this._activeObject=object;object.set("active",true)},setActiveObject:function(object,e){this._setActiveObject(object);this.renderAll();this.fire("object:selected",{target:object,e:e});object.fire("selected",{e:e});return this},getActiveObject:function(){return this._activeObject},_discardActiveObject:function(){if(this._activeObject){this._activeObject.set("active",false)}this._activeObject=null},discardActiveObject:function(e){this._discardActiveObject();this.renderAll();this.fire("selection:cleared",{e:e});return this},_setActiveGroup:function(group){this._activeGroup=group;if(group){group.set("active",true)}},setActiveGroup:function(group,e){this._setActiveGroup(group);if(group){this.fire("object:selected",{target:group,e:e});group.fire("selected",{e:e})}return this},getActiveGroup:function(){return this._activeGroup},_discardActiveGroup:function(){var g=this.getActiveGroup();if(g){g.destroy()}this.setActiveGroup(null)},discardActiveGroup:function(e){this._discardActiveGroup();this.fire("selection:cleared",{e:e});return this},deactivateAll:function(){var allObjects=this.getObjects(),i=0,len=allObjects.length;for(;i1){ +return}var groupSelector=this._groupSelector;if(groupSelector){pointer=this.getPointer(e,true);groupSelector.left=pointer.x-groupSelector.ex;groupSelector.top=pointer.y-groupSelector.ey;this.renderTop()}else if(!this._currentTransform){target=this.findTarget(e);if(!target||target&&!target.selectable){this.setCursor(this.defaultCursor)}else{this._setCursorFromEvent(e,target)}}else{this._transformObject(e)}this.fire("mouse:move",{target:target,e:e});target&&target.fire("mousemove",{e:e})},_transformObject:function(e){var pointer=this.getPointer(e),transform=this._currentTransform;transform.reset=false,transform.target.isMoving=true;this._beforeScaleTransform(e,transform);this._performTransformAction(e,transform,pointer);this.renderAll()},_performTransformAction:function(e,transform,pointer){var x=pointer.x,y=pointer.y,target=transform.target,action=transform.action;if(action==="rotate"){this._rotateObject(x,y);this._fire("rotating",target,e)}else if(action==="scale"){this._onScale(e,transform,x,y);this._fire("scaling",target,e)}else if(action==="scaleX"){this._scaleObject(x,y,"x");this._fire("scaling",target,e)}else if(action==="scaleY"){this._scaleObject(x,y,"y");this._fire("scaling",target,e)}else{this._translateObject(x,y);this._fire("moving",target,e);this.setCursor(this.moveCursor)}},_fire:function(eventName,target,e){this.fire("object:"+eventName,{target:target,e:e});target.fire(eventName,{e:e})},_beforeScaleTransform:function(e,transform){if(transform.action==="scale"||transform.action==="scaleX"||transform.action==="scaleY"){var centerTransform=this._shouldCenterTransform(e,transform.target);if(centerTransform&&(transform.originX!=="center"||transform.originY!=="center")||!centerTransform&&transform.originX==="center"&&transform.originY==="center"){this._resetCurrentTransform(e);transform.reset=true}}},_onScale:function(e,transform,x,y){if((e.shiftKey||this.uniScaleTransform)&&!transform.target.get("lockUniScaling")){transform.currentAction="scale";this._scaleObject(x,y)}else{if(!transform.reset&&transform.currentAction==="scale"){this._resetCurrentTransform(e,transform.target)}transform.currentAction="scaleEqually";this._scaleObject(x,y,"equally")}},_setCursorFromEvent:function(e,target){if(!target||!target.selectable){this.setCursor(this.defaultCursor);return false}else{var activeGroup=this.getActiveGroup(),corner=target._findTargetCorner&&(!activeGroup||!activeGroup.contains(target))&&target._findTargetCorner(this.getPointer(e,true));if(!corner){this.setCursor(target.hoverCursor||this.hoverCursor)}else{this._setCornerCursor(corner,target)}}return true},_setCornerCursor:function(corner,target){if(corner in cursorOffset){this.setCursor(this._getRotatedCornerCursor(corner,target))}else if(corner==="mtr"&&target.hasRotatingPoint){this.setCursor(this.rotationCursor)}else{this.setCursor(this.defaultCursor);return false}},_getRotatedCornerCursor:function(corner,target){var n=Math.round(target.getAngle()%360/45);if(n<0){n+=8}n+=cursorOffset[corner];n%=8;return this.cursorMap[n]}})})();(function(){var min=Math.min,max=Math.max;fabric.util.object.extend(fabric.Canvas.prototype,{_shouldGroup:function(e,target){var activeObject=this.getActiveObject();return e.shiftKey&&(this.getActiveGroup()||activeObject&&activeObject!==target)&&this.selection},_handleGrouping:function(e,target){if(target===this.getActiveGroup()){target=this.findTarget(e,true);if(!target||target.isType("group")){return}}if(this.getActiveGroup()){this._updateActiveGroup(target,e)}else{this._createActiveGroup(target,e)}if(this._activeGroup){this._activeGroup.saveCoords()}},_updateActiveGroup:function(target,e){var activeGroup=this.getActiveGroup();if(activeGroup.contains(target)){activeGroup.removeWithUpdate(target);this._resetObjectTransform(activeGroup);target.set("active",false);if(activeGroup.size()===1){this.discardActiveGroup(e);this.setActiveObject(activeGroup.item(0));return}}else{activeGroup.addWithUpdate(target);this._resetObjectTransform(activeGroup)}this.fire("selection:created",{target:activeGroup,e:e});activeGroup.set("active",true)},_createActiveGroup:function(target,e){if(this._activeObject&&target!==this._activeObject){var group=this._createGroup(target);group.addWithUpdate();this.setActiveGroup(group);this._activeObject=null;this.fire("selection:created",{target:group,e:e})}target.set("active",true)},_createGroup:function(target){var objects=this.getObjects(),isActiveLower=objects.indexOf(this._activeObject)1){group=new fabric.Group(group.reverse(),{canvas:this});group.addWithUpdate();this.setActiveGroup(group,e);group.saveCoords();this.fire("selection:created",{target:group});this.renderAll()}},_collectObjects:function(){var group=[],currentObject,x1=this._groupSelector.ex,y1=this._groupSelector.ey,x2=x1+this._groupSelector.left,y2=y1+this._groupSelector.top,selectionX1Y1=new fabric.Point(min(x1,x2),min(y1,y2)),selectionX2Y2=new fabric.Point(max(x1,x2),max(y1,y2)),isClick=x1===x2&&y1===y2;for(var i=this._objects.length;i--;){currentObject=this._objects[i];if(!currentObject||!currentObject.selectable||!currentObject.visible){continue}if(currentObject.intersectsWithRect(selectionX1Y1,selectionX2Y2)||currentObject.isContainedWithinRect(selectionX1Y1,selectionX2Y2)||currentObject.containsPoint(selectionX1Y1)||currentObject.containsPoint(selectionX2Y2)){currentObject.set("active",true);group.push(currentObject);if(isClick){break}}}return group},_maybeGroupObjects:function(e){if(this.selection&&this._groupSelector){this._groupSelectedObjects(e)}var activeGroup=this.getActiveGroup();if(activeGroup){activeGroup.setObjectsCoords().setCoords();activeGroup.isMoving=false;this.setCursor(this.defaultCursor)}this._groupSelector=null;this._currentTransform=null}})})();fabric.util.object.extend(fabric.StaticCanvas.prototype,{toDataURL:function(options){options||(options={});var format=options.format||"png",quality=options.quality||1,multiplier=options.multiplier||1,cropping={left:options.left,top:options.top,width:options.width,height:options.height};if(multiplier!==1){return this.__toDataURLWithMultiplier(format,quality,cropping,multiplier)}else{return this.__toDataURL(format,quality,cropping)}},__toDataURL:function(format,quality,cropping){this.renderAll(true);var canvasEl=this.upperCanvasEl||this.lowerCanvasEl,croppedCanvasEl=this.__getCroppedCanvas(canvasEl,cropping);if(format==="jpg"){format="jpeg"}var data=fabric.StaticCanvas.supports("toDataURLWithQuality")?(croppedCanvasEl||canvasEl).toDataURL("image/"+format,quality):(croppedCanvasEl||canvasEl).toDataURL("image/"+format);this.contextTop&&this.clearContext(this.contextTop);this.renderAll();if(croppedCanvasEl){croppedCanvasEl=null}return data},__getCroppedCanvas:function(canvasEl,cropping){var croppedCanvasEl,croppedCtx,shouldCrop="left"in cropping||"top"in cropping||"width"in cropping||"height"in cropping;if(shouldCrop){croppedCanvasEl=fabric.util.createCanvasElement();croppedCtx=croppedCanvasEl.getContext("2d");croppedCanvasEl.width=cropping.width||this.width;croppedCanvasEl.height=cropping.height||this.height;croppedCtx.drawImage(canvasEl,-cropping.left||0,-cropping.top||0)}return croppedCanvasEl},__toDataURLWithMultiplier:function(format,quality,cropping,multiplier){var origWidth=this.getWidth(),origHeight=this.getHeight(),scaledWidth=origWidth*multiplier,scaledHeight=origHeight*multiplier,activeObject=this.getActiveObject(),activeGroup=this.getActiveGroup(),ctx=this.contextTop||this.contextContainer;if(multiplier>1){this.setWidth(scaledWidth).setHeight(scaledHeight)}ctx.scale(multiplier,multiplier);if(cropping.left){cropping.left*=multiplier}if(cropping.top){cropping.top*=multiplier}if(cropping.width){cropping.width*=multiplier}else if(multiplier<1){cropping.width=scaledWidth}if(cropping.height){cropping.height*=multiplier}else if(multiplier<1){cropping.height=scaledHeight}if(activeGroup){this._tempRemoveBordersControlsFromGroup(activeGroup)}else if(activeObject&&this.deactivateAll){this.deactivateAll()}this.renderAll(true);var data=this.__toDataURL(format,quality,cropping);this.width=origWidth;this.height=origHeight;ctx.scale(1/multiplier,1/multiplier);this.setWidth(origWidth).setHeight(origHeight);if(activeGroup){this._restoreBordersControlsOnGroup(activeGroup)}else if(activeObject&&this.setActiveObject){this.setActiveObject(activeObject)}this.contextTop&&this.clearContext(this.contextTop);this.renderAll();return data},toDataURLWithMultiplier:function(format,multiplier,quality){return this.toDataURL({format:format,multiplier:multiplier,quality:quality})},_tempRemoveBordersControlsFromGroup:function(group){group.origHasControls=group.hasControls;group.origBorderColor=group.borderColor;group.hasControls=true;group.borderColor="rgba(0,0,0,0)";group.forEachObject(function(o){o.origBorderColor=o.borderColor;o.borderColor="rgba(0,0,0,0)"})},_restoreBordersControlsOnGroup:function(group){group.hideControls=group.origHideControls;group.borderColor=group.origBorderColor;group.forEachObject(function(o){o.borderColor=o.origBorderColor;delete o.origBorderColor})}});fabric.util.object.extend(fabric.StaticCanvas.prototype,{loadFromDatalessJSON:function(json,callback,reviver){return this.loadFromJSON(json,callback,reviver)},loadFromJSON:function(json,callback,reviver){if(!json){return}var serialized=typeof json==="string"?JSON.parse(json):json;this.clear();var _this=this;this._enlivenObjects(serialized.objects,function(){_this._setBgOverlay(serialized,callback)},reviver);return this},_setBgOverlay:function(serialized,callback){var _this=this,loaded={backgroundColor:false,overlayColor:false,backgroundImage:false,overlayImage:false};if(!serialized.backgroundImage&&!serialized.overlayImage&&!serialized.background&&!serialized.overlay){callback&&callback();return}var cbIfLoaded=function(){if(loaded.backgroundImage&&loaded.overlayImage&&loaded.backgroundColor&&loaded.overlayColor){_this.renderAll();callback&&callback()}};this.__setBgOverlay("backgroundImage",serialized.backgroundImage,loaded,cbIfLoaded);this.__setBgOverlay("overlayImage",serialized.overlayImage,loaded,cbIfLoaded);this.__setBgOverlay("backgroundColor",serialized.background,loaded,cbIfLoaded);this.__setBgOverlay("overlayColor",serialized.overlay,loaded,cbIfLoaded);cbIfLoaded()},__setBgOverlay:function(property,value,loaded,callback){var _this=this;if(!value){loaded[property]=true;return}if(property==="backgroundImage"||property==="overlayImage"){fabric.Image.fromObject(value,function(img){_this[property]=img;loaded[property]=true;callback&&callback()})}else{this["set"+fabric.util.string.capitalize(property,true)](value,function(){loaded[property]=true;callback&&callback()})}},_enlivenObjects:function(objects,callback,reviver){var _this=this;if(!objects||objects.length===0){callback&&callback();return}var renderOnAddRemove=this.renderOnAddRemove;this.renderOnAddRemove=false;fabric.util.enlivenObjects(objects,function(enlivenedObjects){enlivenedObjects.forEach(function(obj,index){_this.insertAt(obj,index,true)});_this.renderOnAddRemove=renderOnAddRemove;callback&&callback()},null,reviver)},_toDataURL:function(format,callback){this.clone(function(clone){callback(clone.toDataURL(format))})},_toDataURLWithMultiplier:function(format,multiplier,callback){this.clone(function(clone){callback(clone.toDataURLWithMultiplier(format,multiplier))})},clone:function(callback,properties){var data=JSON.stringify(this.toJSON(properties));this.cloneWithoutData(function(clone){clone.loadFromJSON(data,function(){callback&&callback(clone)})})},cloneWithoutData:function(callback){var el=fabric.document.createElement("canvas");el.width=this.getWidth();el.height=this.getHeight();var clone=new fabric.Canvas(el);clone.clipTo=this.clipTo;if(this.backgroundImage){clone.setBackgroundImage(this.backgroundImage.src,function(){clone.renderAll();callback&&callback(clone)});clone.backgroundImageOpacity=this.backgroundImageOpacity;clone.backgroundImageStretch=this.backgroundImageStretch}else{callback&&callback(clone)}}});(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),extend=fabric.util.object.extend,toFixed=fabric.util.toFixed,capitalize=fabric.util.string.capitalize,degreesToRadians=fabric.util.degreesToRadians,supportsLineDash=fabric.StaticCanvas.supports("setLineDash");if(fabric.Object){return}fabric.Object=fabric.util.createClass({type:"object",originX:"left",originY:"top",top:0,left:0,width:0,height:0,scaleX:1,scaleY:1,flipX:false,flipY:false,opacity:1,angle:0,cornerSize:12,transparentCorners:true,hoverCursor:null,padding:0,borderColor:"rgba(102,153,255,0.75)",cornerColor:"rgba(102,153,255,0.5)",centeredScaling:false,centeredRotation:true,fill:"rgb(0,0,0)",fillRule:"nonzero",globalCompositeOperation:"source-over",backgroundColor:"",stroke:null,strokeWidth:1,strokeDashArray:null,strokeLineCap:"butt",strokeLineJoin:"miter",strokeMiterLimit:10,shadow:null,borderOpacityWhenMoving:.4,borderScaleFactor:1,transformMatrix:null,minScaleLimit:.01,selectable:true,evented:true,visible:true,hasControls:true,hasBorders:true,hasRotatingPoint:true,rotatingPointOffset:40,perPixelTargetFind:false,includeDefaultValues:true,clipTo:null,lockMovementX:false,lockMovementY:false,lockRotation:false,lockScalingX:false,lockScalingY:false,lockUniScaling:false,lockScalingFlip:false,stateProperties:("top left width height scaleX scaleY flipX flipY originX originY transformMatrix "+"stroke strokeWidth strokeDashArray strokeLineCap strokeLineJoin strokeMiterLimit "+"angle opacity fill fillRule globalCompositeOperation shadow clipTo visible backgroundColor").split(" "),initialize:function(options){if(options){this.setOptions(options)}},_initGradient:function(options){if(options.fill&&options.fill.colorStops&&!(options.fill instanceof fabric.Gradient)){this.set("fill",new fabric.Gradient(options.fill))}},_initPattern:function(options){if(options.fill&&options.fill.source&&!(options.fill instanceof fabric.Pattern)){this.set("fill",new fabric.Pattern(options.fill))}if(options.stroke&&options.stroke.source&&!(options.stroke instanceof fabric.Pattern)){this.set("stroke",new fabric.Pattern(options.stroke))}},_initClipping:function(options){if(!options.clipTo||typeof options.clipTo!=="string"){return}var functionBody=fabric.util.getFunctionBody(options.clipTo);if(typeof functionBody!=="undefined"){this.clipTo=new Function("ctx",functionBody)}},setOptions:function(options){for(var prop in options){this.set(prop,options[prop])}this._initGradient(options);this._initPattern(options);this._initClipping(options)},transform:function(ctx,fromLeft){var center=fromLeft?this._getLeftTopCoords():this.getCenterPoint();ctx.translate(center.x,center.y);ctx.rotate(degreesToRadians(this.angle));ctx.scale(this.scaleX*(this.flipX?-1:1),this.scaleY*(this.flipY?-1:1))},toObject:function(propertiesToInclude){var NUM_FRACTION_DIGITS=fabric.Object.NUM_FRACTION_DIGITS,object={type:this.type,originX:this.originX,originY:this.originY,left:toFixed(this.left,NUM_FRACTION_DIGITS),top:toFixed(this.top,NUM_FRACTION_DIGITS),width:toFixed(this.width,NUM_FRACTION_DIGITS),height:toFixed(this.height,NUM_FRACTION_DIGITS),fill:this.fill&&this.fill.toObject?this.fill.toObject():this.fill,stroke:this.stroke&&this.stroke.toObject?this.stroke.toObject():this.stroke,strokeWidth:toFixed(this.strokeWidth,NUM_FRACTION_DIGITS),strokeDashArray:this.strokeDashArray,strokeLineCap:this.strokeLineCap,strokeLineJoin:this.strokeLineJoin,strokeMiterLimit:toFixed(this.strokeMiterLimit,NUM_FRACTION_DIGITS),scaleX:toFixed(this.scaleX,NUM_FRACTION_DIGITS),scaleY:toFixed(this.scaleY,NUM_FRACTION_DIGITS),angle:toFixed(this.getAngle(),NUM_FRACTION_DIGITS),flipX:this.flipX,flipY:this.flipY,opacity:toFixed(this.opacity,NUM_FRACTION_DIGITS),shadow:this.shadow&&this.shadow.toObject?this.shadow.toObject():this.shadow,visible:this.visible,clipTo:this.clipTo&&String(this.clipTo),backgroundColor:this.backgroundColor,fillRule:this.fillRule,globalCompositeOperation:this.globalCompositeOperation};if(!this.includeDefaultValues){object=this._removeDefaultValues(object)}fabric.util.populateWithProperties(this,object,propertiesToInclude);return object},toDatalessObject:function(propertiesToInclude){return this.toObject(propertiesToInclude)},_removeDefaultValues:function(object){var prototype=fabric.util.getKlass(object.type).prototype,stateProperties=prototype.stateProperties;stateProperties.forEach(function(prop){if(object[prop]===prototype[prop]){delete object[prop]}});return object},toString:function(){return"#"},get:function(property){return this[property]},_setObject:function(obj){for(var prop in obj){this._set(prop,obj[prop])}},set:function(key,value){if(typeof key==="object"){this._setObject(key)}else{if(typeof value==="function"&&key!=="clipTo"){this._set(key,value(this.get(key)))}else{this._set(key,value)}}return this},_set:function(key,value){var shouldConstrainValue=key==="scaleX"||key==="scaleY";if(shouldConstrainValue){value=this._constrainScale(value)}if(key==="scaleX"&&value<0){this.flipX=!this.flipX;value*=-1}else if(key==="scaleY"&&value<0){this.flipY=!this.flipY;value*=-1}else if(key==="width"||key==="height"){this.minScaleLimit=toFixed(Math.min(.1,1/Math.max(this.width,this.height)),2)}else if(key==="shadow"&&value&&!(value instanceof fabric.Shadow)){value=new fabric.Shadow(value)}this[key]=value;return this},toggle:function(property){var value=this.get(property);if(typeof value==="boolean"){this.set(property,!value)}return this},setSourcePath:function(value){this.sourcePath=value;return this},getViewportTransform:function(){if(this.canvas&&this.canvas.viewportTransform){return this.canvas.viewportTransform}return[1,0,0,1,0,0]},render:function(ctx,noTransform){if(this.width===0&&this.height===0||!this.visible){return}ctx.save();this._setupCompositeOperation(ctx);if(!noTransform){this.transform(ctx)}this._setStrokeStyles(ctx);this._setFillStyles(ctx);if(this.transformMatrix){ctx.transform.apply(ctx,this.transformMatrix)}this._setOpacity(ctx);this._setShadow(ctx);this.clipTo&&fabric.util.clipContext(this,ctx);this._render(ctx,noTransform);this.clipTo&&ctx.restore();this._removeShadow(ctx);this._restoreCompositeOperation(ctx);ctx.restore()},_setOpacity:function(ctx){if(this.group){this.group._setOpacity(ctx)}ctx.globalAlpha*=this.opacity},_setStrokeStyles:function(ctx){if(this.stroke){ctx.lineWidth=this.strokeWidth;ctx.lineCap=this.strokeLineCap;ctx.lineJoin=this.strokeLineJoin;ctx.miterLimit=this.strokeMiterLimit;ctx.strokeStyle=this.stroke.toLive?this.stroke.toLive(ctx,this):this.stroke}},_setFillStyles:function(ctx){if(this.fill){ctx.fillStyle=this.fill.toLive?this.fill.toLive(ctx,this):this.fill}},_renderControls:function(ctx,noTransform){if(!this.active||noTransform){return}var vpt=this.getViewportTransform();ctx.save();var center;if(this.group){center=fabric.util.transformPoint(this.group.getCenterPoint(),vpt);ctx.translate(center.x,center.y);ctx.rotate(degreesToRadians(this.group.angle))}center=fabric.util.transformPoint(this.getCenterPoint(),vpt,null!=this.group);if(this.group){center.x*=this.group.scaleX;center.y*=this.group.scaleY}ctx.translate(center.x,center.y);ctx.rotate(degreesToRadians(this.angle));this.drawBorders(ctx);this.drawControls(ctx);ctx.restore()},_setShadow:function(ctx){if(!this.shadow){return}var multX=this.canvas&&this.canvas.viewportTransform[0]||1,multY=this.canvas&&this.canvas.viewportTransform[3]||1;ctx.shadowColor=this.shadow.color;ctx.shadowBlur=this.shadow.blur*(multX+multY)*(this.scaleX+this.scaleY)/4;ctx.shadowOffsetX=this.shadow.offsetX*multX*this.scaleX;ctx.shadowOffsetY=this.shadow.offsetY*multY*this.scaleY},_removeShadow:function(ctx){if(!this.shadow){return}ctx.shadowColor="";ctx.shadowBlur=ctx.shadowOffsetX=ctx.shadowOffsetY=0},_renderFill:function(ctx){if(!this.fill){return}ctx.save();if(this.fill.gradientTransform){var g=this.fill.gradientTransform;ctx.transform.apply(ctx,g)}if(this.fill.toLive){ctx.translate(-this.width/2+this.fill.offsetX||0,-this.height/2+this.fill.offsetY||0)}if(this.fillRule==="evenodd"){ctx.fill("evenodd")}else{ctx.fill()}ctx.restore();if(this.shadow&&!this.shadow.affectStroke){this._removeShadow(ctx)}},_renderStroke:function(ctx){if(!this.stroke||this.strokeWidth===0){return}ctx.save();if(this.strokeDashArray){if(1&this.strokeDashArray.length){this.strokeDashArray.push.apply(this.strokeDashArray,this.strokeDashArray)}if(supportsLineDash){ctx.setLineDash(this.strokeDashArray);this._stroke&&this._stroke(ctx)}else{this._renderDashedStroke&&this._renderDashedStroke(ctx)}ctx.stroke()}else{if(this.stroke.gradientTransform){var g=this.stroke.gradientTransform;ctx.transform.apply(ctx,g)}this._stroke?this._stroke(ctx):ctx.stroke()}this._removeShadow(ctx);ctx.restore()},clone:function(callback,propertiesToInclude){if(this.constructor.fromObject){return this.constructor.fromObject(this.toObject(propertiesToInclude),callback)}return new fabric.Object(this.toObject(propertiesToInclude))},cloneAsImage:function(callback){var dataUrl=this.toDataURL();fabric.util.loadImage(dataUrl,function(img){if(callback){callback(new fabric.Image(img))}});return this},toDataURL:function(options){options||(options={});var el=fabric.util.createCanvasElement(),boundingRect=this.getBoundingRect();el.width=boundingRect.width;el.height=boundingRect.height;fabric.util.wrapElement(el,"div");var canvas=new fabric.StaticCanvas(el);if(options.format==="jpg"){options.format="jpeg"}if(options.format==="jpeg"){canvas.backgroundColor="#fff"}var origParams={active:this.get("active"),left:this.getLeft(),top:this.getTop()};this.set("active",false);this.setPositionByOrigin(new fabric.Point(el.width/2,el.height/2),"center","center");var originalCanvas=this.canvas;canvas.add(this);var data=canvas.toDataURL(options);this.set(origParams).setCoords();this.canvas=originalCanvas;canvas.dispose();canvas=null;return data},isType:function(type){return this.type===type},complexity:function(){return 0},toJSON:function(propertiesToInclude){return this.toObject(propertiesToInclude)},setGradient:function(property,options){options||(options={});var gradient={colorStops:[]};gradient.type=options.type||(options.r1||options.r2?"radial":"linear");gradient.coords={x1:options.x1,y1:options.y1,x2:options.x2,y2:options.y2};if(options.r1||options.r2){gradient.coords.r1=options.r1;gradient.coords.r2=options.r2}for(var position in options.colorStops){var color=new fabric.Color(options.colorStops[position]);gradient.colorStops.push({offset:position,color:color.toRgb(),opacity:color.getAlpha()})}return this.set(property,fabric.Gradient.forObject(this,gradient))},setPatternFill:function(options){return this.set("fill",new fabric.Pattern(options))},setShadow:function(options){return this.set("shadow",options?new fabric.Shadow(options):null)},setColor:function(color){this.set("fill",color);return this},setAngle:function(angle){var shouldCenterOrigin=(this.originX!=="center"||this.originY!=="center")&&this.centeredRotation;if(shouldCenterOrigin){this._setOriginToCenter()}this.set("angle",angle);if(shouldCenterOrigin){this._resetOrigin()}return this},centerH:function(){this.canvas.centerObjectH(this);return this},centerV:function(){this.canvas.centerObjectV(this);return this},center:function(){this.canvas.centerObject(this);return this},remove:function(){this.canvas.remove(this);return this},getLocalPointer:function(e,pointer){pointer=pointer||this.canvas.getPointer(e);var objectLeftTop=this.translateToOriginPoint(this.getCenterPoint(),"left","top");return{x:pointer.x-objectLeftTop.x,y:pointer.y-objectLeftTop.y}},_setupCompositeOperation:function(ctx){if(this.globalCompositeOperation){this._prevGlobalCompositeOperation=ctx.globalCompositeOperation;ctx.globalCompositeOperation=this.globalCompositeOperation}},_restoreCompositeOperation:function(ctx){if(this.globalCompositeOperation&&this._prevGlobalCompositeOperation){ctx.globalCompositeOperation=this._prevGlobalCompositeOperation}}});fabric.util.createAccessors(fabric.Object);fabric.Object.prototype.rotate=fabric.Object.prototype.setAngle;extend(fabric.Object.prototype,fabric.Observable);fabric.Object.NUM_FRACTION_DIGITS=2;fabric.Object.__uid=0})(typeof exports!=="undefined"?exports:this);(function(){var degreesToRadians=fabric.util.degreesToRadians;fabric.util.object.extend(fabric.Object.prototype,{translateToCenterPoint:function(point,originX,originY){var cx=point.x,cy=point.y,strokeWidth=this.stroke?this.strokeWidth:0;if(originX==="left"){cx=point.x+(this.getWidth()+strokeWidth*this.scaleX)/2}else if(originX==="right"){cx=point.x-(this.getWidth()+strokeWidth*this.scaleX)/2}if(originY==="top"){cy=point.y+(this.getHeight()+strokeWidth*this.scaleY)/2}else if(originY==="bottom"){cy=point.y-(this.getHeight()+strokeWidth*this.scaleY)/2}return fabric.util.rotatePoint(new fabric.Point(cx,cy),point,degreesToRadians(this.angle))},translateToOriginPoint:function(center,originX,originY){var x=center.x,y=center.y,strokeWidth=this.stroke?this.strokeWidth:0;if(originX==="left"){x=center.x-(this.getWidth()+strokeWidth*this.scaleX)/2}else if(originX==="right"){x=center.x+(this.getWidth()+strokeWidth*this.scaleX)/2}if(originY==="top"){y=center.y-(this.getHeight()+strokeWidth*this.scaleY)/2}else if(originY==="bottom"){y=center.y+(this.getHeight()+strokeWidth*this.scaleY)/2}return fabric.util.rotatePoint(new fabric.Point(x,y),center,degreesToRadians(this.angle))},getCenterPoint:function(){var leftTop=new fabric.Point(this.left,this.top);return this.translateToCenterPoint(leftTop,this.originX,this.originY)},getPointByOrigin:function(originX,originY){var center=this.getCenterPoint();return this.translateToOriginPoint(center,originX,originY)},toLocalPoint:function(point,originX,originY){var center=this.getCenterPoint(),strokeWidth=this.stroke?this.strokeWidth:0,x,y;if(originX&&originY){if(originX==="left"){x=center.x-(this.getWidth()+strokeWidth*this.scaleX)/2}else if(originX==="right"){x=center.x+(this.getWidth()+strokeWidth*this.scaleX)/2}else{x=center.x}if(originY==="top"){y=center.y-(this.getHeight()+strokeWidth*this.scaleY)/2}else if(originY==="bottom"){y=center.y+(this.getHeight()+strokeWidth*this.scaleY)/2}else{y=center.y}}else{x=this.left;y=this.top}return fabric.util.rotatePoint(new fabric.Point(point.x,point.y),center,-degreesToRadians(this.angle)).subtractEquals(new fabric.Point(x,y))},setPositionByOrigin:function(pos,originX,originY){var center=this.translateToCenterPoint(pos,originX,originY),position=this.translateToOriginPoint(center,this.originX,this.originY);this.set("left",position.x);this.set("top",position.y)},adjustPosition:function(to){var angle=degreesToRadians(this.angle),hypotHalf=this.getWidth()/2,xHalf=Math.cos(angle)*hypotHalf,yHalf=Math.sin(angle)*hypotHalf,hypotFull=this.getWidth(),xFull=Math.cos(angle)*hypotFull,yFull=Math.sin(angle)*hypotFull;if(this.originX==="center"&&to==="left"||this.originX==="right"&&to==="center"){this.left-=xHalf;this.top-=yHalf}else if(this.originX==="left"&&to==="center"||this.originX==="center"&&to==="right"){this.left+=xHalf;this.top+=yHalf}else if(this.originX==="left"&&to==="right"){this.left+=xFull;this.top+=yFull}else if(this.originX==="right"&&to==="left"){this.left-=xFull;this.top-=yFull}this.setCoords();this.originX=to},_setOriginToCenter:function(){this._originalOriginX=this.originX;this._originalOriginY=this.originY;var center=this.getCenterPoint();this.originX="center";this.originY="center";this.left=center.x;this.top=center.y},_resetOrigin:function(){var originPoint=this.translateToOriginPoint(this.getCenterPoint(),this._originalOriginX,this._originalOriginY);this.originX=this._originalOriginX;this.originY=this._originalOriginY;this.left=originPoint.x;this.top=originPoint.y;this._originalOriginX=null;this._originalOriginY=null},_getLeftTopCoords:function(){return this.translateToOriginPoint(this.getCenterPoint(),"left","center")}})})();(function(){var degreesToRadians=fabric.util.degreesToRadians;fabric.util.object.extend(fabric.Object.prototype,{oCoords:null,intersectsWithRect:function(pointTL,pointBR){var oCoords=this.oCoords,tl=new fabric.Point(oCoords.tl.x,oCoords.tl.y),tr=new fabric.Point(oCoords.tr.x,oCoords.tr.y),bl=new fabric.Point(oCoords.bl.x,oCoords.bl.y),br=new fabric.Point(oCoords.br.x,oCoords.br.y),intersection=fabric.Intersection.intersectPolygonRectangle([tl,tr,br,bl],pointTL,pointBR);return intersection.status==="Intersection"},intersectsWithObject:function(other){function getCoords(oCoords){return{tl:new fabric.Point(oCoords.tl.x,oCoords.tl.y),tr:new fabric.Point(oCoords.tr.x,oCoords.tr.y),bl:new fabric.Point(oCoords.bl.x,oCoords.bl.y),br:new fabric.Point(oCoords.br.x,oCoords.br.y)}}var thisCoords=getCoords(this.oCoords),otherCoords=getCoords(other.oCoords),intersection=fabric.Intersection.intersectPolygonPolygon([thisCoords.tl,thisCoords.tr,thisCoords.br,thisCoords.bl],[otherCoords.tl,otherCoords.tr,otherCoords.br,otherCoords.bl]);return intersection.status==="Intersection"},isContainedWithinObject:function(other){var boundingRect=other.getBoundingRect(),point1=new fabric.Point(boundingRect.left,boundingRect.top),point2=new fabric.Point(boundingRect.left+boundingRect.width,boundingRect.top+boundingRect.height);return this.isContainedWithinRect(point1,point2)},isContainedWithinRect:function(pointTL,pointBR){var boundingRect=this.getBoundingRect();return boundingRect.left>=pointTL.x&&boundingRect.left+boundingRect.width<=pointBR.x&&boundingRect.top>=pointTL.y&&boundingRect.top+boundingRect.height<=pointBR.y},containsPoint:function(point){var lines=this._getImageLines(this.oCoords),xPoints=this._findCrossPoints(point,lines);return xPoints!==0&&xPoints%2===1},_getImageLines:function(oCoords){return{topline:{o:oCoords.tl,d:oCoords.tr},rightline:{o:oCoords.tr,d:oCoords.br},bottomline:{o:oCoords.br,d:oCoords.bl},leftline:{o:oCoords.bl,d:oCoords.tl}}},_findCrossPoints:function(point,oCoords){var b1,b2,a1,a2,xi,yi,xcount=0,iLine;for(var lineKey in oCoords){iLine=oCoords[lineKey];if(iLine.o.y=point.y&&iLine.d.y>=point.y){continue}if(iLine.o.x===iLine.d.x&&iLine.o.x>=point.x){xi=iLine.o.x;yi=point.y}else{b1=0;b2=(iLine.d.y-iLine.o.y)/(iLine.d.x-iLine.o.x);a1=point.y-b1*point.x;a2=iLine.o.y-b2*iLine.o.x;xi=-(a1-a2)/(b1-b2);yi=a1+b1*xi}if(xi>=point.x){xcount+=1}if(xcount===2){break}}return xcount},getBoundingRectWidth:function(){return this.getBoundingRect().width},getBoundingRectHeight:function(){return this.getBoundingRect().height},getBoundingRect:function(){this.oCoords||this.setCoords();var xCoords=[this.oCoords.tl.x,this.oCoords.tr.x,this.oCoords.br.x,this.oCoords.bl.x],minX=fabric.util.array.min(xCoords),maxX=fabric.util.array.max(xCoords),width=Math.abs(minX-maxX),yCoords=[this.oCoords.tl.y,this.oCoords.tr.y,this.oCoords.br.y,this.oCoords.bl.y],minY=fabric.util.array.min(yCoords),maxY=fabric.util.array.max(yCoords),height=Math.abs(minY-maxY);return{left:minX,top:minY,width:width,height:height}},getWidth:function(){return this.width*this.scaleX},getHeight:function(){return this.height*this.scaleY},_constrainScale:function(value){if(Math.abs(value)\n');return reviver?reviver(markup.join("")):markup.join("")},complexity:function(){return 1}});fabric.Line.ATTRIBUTE_NAMES=fabric.SHARED_ATTRIBUTES.concat("x1 y1 x2 y2".split(" "));fabric.Line.fromElement=function(element,options){var parsedAttributes=fabric.parseAttributes(element,fabric.Line.ATTRIBUTE_NAMES),points=[parsedAttributes.x1||0,parsedAttributes.y1||0,parsedAttributes.x2||0,parsedAttributes.y2||0];return new fabric.Line(points,extend(parsedAttributes,options))};fabric.Line.fromObject=function(object){var points=[object.x1,object.y1,object.x2,object.y2];return new fabric.Line(points,object)};function makeEdgeToOriginGetter(propertyNames,originValues){var origin=propertyNames.origin,axis1=propertyNames.axis1,axis2=propertyNames.axis2,dimension=propertyNames.dimension,nearest=originValues.nearest,center=originValues.center,farthest=originValues.farthest;return function(){switch(this.get(origin)){case nearest:return Math.min(this.get(axis1),this.get(axis2));case center:return Math.min(this.get(axis1),this.get(axis2))+.5*this.get(dimension);case farthest:return Math.max(this.get(axis1),this.get(axis2))}}}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),pi=Math.PI,extend=fabric.util.object.extend;if(fabric.Circle){fabric.warn("fabric.Circle is already defined.");return}fabric.Circle=fabric.util.createClass(fabric.Object,{type:"circle",radius:0,startAngle:0,endAngle:pi*2,initialize:function(options){options=options||{};this.callSuper("initialize",options);this.set("radius",options.radius||0);this.startAngle=options.startAngle||this.startAngle;this.endAngle=options.endAngle||this.endAngle},_set:function(key,value){this.callSuper("_set",key,value);if(key==="radius"){this.setRadius(value)}return this},toObject:function(propertiesToInclude){return extend(this.callSuper("toObject",propertiesToInclude),{radius:this.get("radius"),startAngle:this.startAngle,endAngle:this.endAngle})},toSVG:function(reviver){var markup=this._createBaseSVGMarkup(),x=0,y=0,angle=(this.endAngle-this.startAngle)%(2*pi);if(angle===0){if(this.group&&this.group.type==="path-group"){x=this.left+this.radius;y=this.top+this.radius}markup.push("\n')}else{var startX=Math.cos(this.startAngle)*this.radius,startY=Math.sin(this.startAngle)*this.radius,endX=Math.cos(this.endAngle)*this.radius,endY=Math.sin(this.endAngle)*this.radius,largeFlag=angle>pi?"1":"0";markup.push('\n')}return reviver?reviver(markup.join("")):markup.join("")},_render:function(ctx,noTransform){ctx.beginPath();ctx.arc(noTransform?this.left+this.radius:0,noTransform?this.top+this.radius:0,this.radius,this.startAngle,this.endAngle,false);this._renderFill(ctx);this._renderStroke(ctx)},getRadiusX:function(){return this.get("radius")*this.get("scaleX")},getRadiusY:function(){return this.get("radius")*this.get("scaleY")},setRadius:function(value){this.radius=value;this.set("width",value*2).set("height",value*2)},complexity:function(){return 1}});fabric.Circle.ATTRIBUTE_NAMES=fabric.SHARED_ATTRIBUTES.concat("cx cy r".split(" "));fabric.Circle.fromElement=function(element,options){options||(options={});var parsedAttributes=fabric.parseAttributes(element,fabric.Circle.ATTRIBUTE_NAMES);if(!isValidRadius(parsedAttributes)){throw new Error("value of `r` attribute is required and can not be negative")}parsedAttributes.left=parsedAttributes.left||0;parsedAttributes.top=parsedAttributes.top||0;var obj=new fabric.Circle(extend(parsedAttributes,options));obj.left-=obj.radius;obj.top-=obj.radius;return obj};function isValidRadius(attributes){return"radius"in attributes&&attributes.radius>=0}fabric.Circle.fromObject=function(object){return new fabric.Circle(object)}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={});if(fabric.Triangle){fabric.warn("fabric.Triangle is already defined");return}fabric.Triangle=fabric.util.createClass(fabric.Object,{type:"triangle",initialize:function(options){options=options||{};this.callSuper("initialize",options);this.set("width",options.width||100).set("height",options.height||100)},_render:function(ctx){var widthBy2=this.width/2,heightBy2=this.height/2;ctx.beginPath();ctx.moveTo(-widthBy2,heightBy2);ctx.lineTo(0,-heightBy2);ctx.lineTo(widthBy2,heightBy2);ctx.closePath();this._renderFill(ctx);this._renderStroke(ctx)},_renderDashedStroke:function(ctx){var widthBy2=this.width/2,heightBy2=this.height/2;ctx.beginPath();fabric.util.drawDashedLine(ctx,-widthBy2,heightBy2,0,-heightBy2,this.strokeDashArray);fabric.util.drawDashedLine(ctx,0,-heightBy2,widthBy2,heightBy2,this.strokeDashArray);fabric.util.drawDashedLine(ctx,widthBy2,heightBy2,-widthBy2,heightBy2,this.strokeDashArray);ctx.closePath()},toSVG:function(reviver){var markup=this._createBaseSVGMarkup(),widthBy2=this.width/2,heightBy2=this.height/2,points=[-widthBy2+" "+heightBy2,"0 "+-heightBy2,widthBy2+" "+heightBy2].join(",");markup.push("');return reviver?reviver(markup.join("")):markup.join("")},complexity:function(){return 1}});fabric.Triangle.fromObject=function(object){return new fabric.Triangle(object)}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),piBy2=Math.PI*2,extend=fabric.util.object.extend;if(fabric.Ellipse){fabric.warn("fabric.Ellipse is already defined.");return}fabric.Ellipse=fabric.util.createClass(fabric.Object,{type:"ellipse",rx:0,ry:0,initialize:function(options){options=options||{};this.callSuper("initialize",options);this.set("rx",options.rx||0);this.set("ry",options.ry||0)},_set:function(key,value){this.callSuper("_set",key,value);switch(key){case"rx":this.rx=value;this.set("width",value*2);break;case"ry":this.ry=value;this.set("height",value*2);break}return this},getRx:function(){return this.get("rx")*this.get("scaleX")},getRy:function(){return this.get("ry")*this.get("scaleY")},toObject:function(propertiesToInclude){return extend(this.callSuper("toObject",propertiesToInclude),{rx:this.get("rx"),ry:this.get("ry")})},toSVG:function(reviver){var markup=this._createBaseSVGMarkup(),x=0,y=0;if(this.group&&this.group.type==="path-group"){x=this.left+this.rx;y=this.top+this.ry}markup.push("\n');return reviver?reviver(markup.join("")):markup.join("")},_render:function(ctx,noTransform){ctx.beginPath();ctx.save();ctx.transform(1,0,0,this.ry/this.rx,0,0);ctx.arc(noTransform?this.left+this.rx:0,noTransform?(this.top+this.ry)*this.rx/this.ry:0,this.rx,0,piBy2,false);ctx.restore();this._renderFill(ctx);this._renderStroke(ctx)},complexity:function(){return 1}});fabric.Ellipse.ATTRIBUTE_NAMES=fabric.SHARED_ATTRIBUTES.concat("cx cy rx ry".split(" "));fabric.Ellipse.fromElement=function(element,options){options||(options={});var parsedAttributes=fabric.parseAttributes(element,fabric.Ellipse.ATTRIBUTE_NAMES);parsedAttributes.left=parsedAttributes.left||0;parsedAttributes.top=parsedAttributes.top||0;var ellipse=new fabric.Ellipse(extend(parsedAttributes,options));ellipse.top-=ellipse.ry;ellipse.left-=ellipse.rx;return ellipse};fabric.Ellipse.fromObject=function(object){return new fabric.Ellipse(object)}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),extend=fabric.util.object.extend;if(fabric.Rect){console.warn("fabric.Rect is already defined");return}var stateProperties=fabric.Object.prototype.stateProperties.concat();stateProperties.push("rx","ry","x","y");fabric.Rect=fabric.util.createClass(fabric.Object,{stateProperties:stateProperties,type:"rect",rx:0,ry:0,strokeDashArray:null,initialize:function(options){options=options||{};this.callSuper("initialize",options);this._initRxRy()},_initRxRy:function(){if(this.rx&&!this.ry){this.ry=this.rx}else if(this.ry&&!this.rx){this.rx=this.ry}},_render:function(ctx,noTransform){if(this.width===1&&this.height===1){ctx.fillRect(0,0,1,1);return}var rx=this.rx?Math.min(this.rx,this.width/2):0,ry=this.ry?Math.min(this.ry,this.height/2):0,w=this.width,h=this.height,x=noTransform?this.left:-this.width/2,y=noTransform?this.top:-this.height/2,isRounded=rx!==0||ry!==0,k=1-.5522847498;ctx.beginPath();ctx.moveTo(x+rx,y);ctx.lineTo(x+w-rx,y);isRounded&&ctx.bezierCurveTo(x+w-k*rx,y,x+w,y+k*ry,x+w,y+ry);ctx.lineTo(x+w,y+h-ry);isRounded&&ctx.bezierCurveTo(x+w,y+h-k*ry,x+w-k*rx,y+h,x+w-rx,y+h);ctx.lineTo(x+rx,y+h);isRounded&&ctx.bezierCurveTo(x+k*rx,y+h,x,y+h-k*ry,x,y+h-ry);ctx.lineTo(x,y+ry);isRounded&&ctx.bezierCurveTo(x,y+k*ry,x+k*rx,y,x+rx,y);ctx.closePath();this._renderFill(ctx);this._renderStroke(ctx)},_renderDashedStroke:function(ctx){var x=-this.width/2,y=-this.height/2,w=this.width,h=this.height;ctx.beginPath();fabric.util.drawDashedLine(ctx,x,y,x+w,y,this.strokeDashArray);fabric.util.drawDashedLine(ctx,x+w,y,x+w,y+h,this.strokeDashArray);fabric.util.drawDashedLine(ctx,x+w,y+h,x,y+h,this.strokeDashArray);fabric.util.drawDashedLine(ctx,x,y+h,x,y,this.strokeDashArray);ctx.closePath()},toObject:function(propertiesToInclude){var object=extend(this.callSuper("toObject",propertiesToInclude),{rx:this.get("rx")||0,ry:this.get("ry")||0});if(!this.includeDefaultValues){this._removeDefaultValues(object)}return object},toSVG:function(reviver){var markup=this._createBaseSVGMarkup(),x=this.left,y=this.top;if(!(this.group&&this.group.type==="path-group")){x=-this.width/2;y=-this.height/2}markup.push("\n');return reviver?reviver(markup.join("")):markup.join("")},complexity:function(){return 1}});fabric.Rect.ATTRIBUTE_NAMES=fabric.SHARED_ATTRIBUTES.concat("x y rx ry width height".split(" "));fabric.Rect.fromElement=function(element,options){if(!element){return null}options=options||{};var parsedAttributes=fabric.parseAttributes(element,fabric.Rect.ATTRIBUTE_NAMES);parsedAttributes.left=parsedAttributes.left||0;parsedAttributes.top=parsedAttributes.top||0;var rect=new fabric.Rect(extend(options?fabric.util.object.clone(options):{},parsedAttributes));rect.visible=rect.width>0&&rect.height>0;return rect};fabric.Rect.fromObject=function(object){return new fabric.Rect(object)}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={});if(fabric.Polyline){fabric.warn("fabric.Polyline is already defined");return}fabric.Polyline=fabric.util.createClass(fabric.Object,{type:"polyline",points:null,minX:0,minY:0,initialize:function(points,options){return fabric.Polygon.prototype.initialize.call(this,points,options)},_calcDimensions:function(){return fabric.Polygon.prototype._calcDimensions.call(this)},_applyPointOffset:function(){return fabric.Polygon.prototype._applyPointOffset.call(this)},toObject:function(propertiesToInclude){return fabric.Polygon.prototype.toObject.call(this,propertiesToInclude)},toSVG:function(reviver){return fabric.Polygon.prototype.toSVG.call(this,reviver)},_render:function(ctx){if(!fabric.Polygon.prototype.commonRender.call(this,ctx)){return}this._renderFill(ctx);this._renderStroke(ctx)},_renderDashedStroke:function(ctx){var p1,p2;ctx.beginPath();for(var i=0,len=this.points.length;i\n');return reviver?reviver(markup.join("")):markup.join("")},_render:function(ctx){if(!this.commonRender(ctx)){return}this._renderFill(ctx);if(this.stroke||this.strokeDashArray){ctx.closePath();this._renderStroke(ctx)}},commonRender:function(ctx){var point,len=this.points.length;if(!len||isNaN(this.points[len-1].y)){return false}ctx.beginPath();if(this._applyPointOffset){if(!(this.group&&this.group.type==="path-group")){this._applyPointOffset()}this._applyPointOffset=null}ctx.moveTo(this.points[0].x,this.points[0].y);for(var i=0;i"},toObject:function(propertiesToInclude){var o=extend(this.callSuper("toObject",propertiesToInclude),{path:this.path.map(function(item){return item.slice()}),pathOffset:this.pathOffset});if(this.sourcePath){o.sourcePath=this.sourcePath}if(this.transformMatrix){o.transformMatrix=this.transformMatrix}return o},toDatalessObject:function(propertiesToInclude){var o=this.toObject(propertiesToInclude);if(this.sourcePath){o.path=this.sourcePath}delete o.sourcePath;return o},toSVG:function(reviver){var chunks=[],markup=this._createBaseSVGMarkup(),addTransform="";for(var i=0,len=this.path.length;i\n");return reviver?reviver(markup.join("")):markup.join("")},complexity:function(){return this.path.length},_parsePath:function(){var result=[],coords=[],currentPath,parsed,re=/([-+]?((\d+\.\d+)|((\d+)|(\.\d+)))(?:e[-+]?\d+)?)/gi,match,coordsStr;for(var i=0,coordsParsed,len=this.path.length;icommandLength){for(var k=1,klen=coordsParsed.length;k\n"];for(var i=0,len=objects.length;i\n");return reviver?reviver(markup.join("")):markup.join("")},toString:function(){return"#"},isSameColor:function(){var firstPathFill=(this.getObjects()[0].get("fill")||"").toLowerCase();return this.getObjects().every(function(path){return(path.get("fill")||"").toLowerCase()===firstPathFill})},complexity:function(){return this.paths.reduce(function(total,path){return total+(path&&path.complexity?path.complexity():0)},0)},getObjects:function(){return this.paths}});fabric.PathGroup.fromObject=function(object,callback){if(typeof object.paths==="string"){fabric.loadSVGFromURL(object.paths,function(elements){var pathUrl=object.paths;delete object.paths;var pathGroup=fabric.util.groupSVGElements(elements,object,pathUrl);callback(pathGroup)})}else{fabric.util.enlivenObjects(object.paths,function(enlivenedObjects){delete object.paths;callback(new fabric.PathGroup(enlivenedObjects,object))})}};fabric.PathGroup.async=true})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),extend=fabric.util.object.extend,min=fabric.util.array.min,max=fabric.util.array.max,invoke=fabric.util.array.invoke;if(fabric.Group){return}var _lockProperties={lockMovementX:true,lockMovementY:true,lockRotation:true,lockScalingX:true,lockScalingY:true,lockUniScaling:true};fabric.Group=fabric.util.createClass(fabric.Object,fabric.Collection,{type:"group",initialize:function(objects,options){options=options||{};this._objects=objects||[];for(var i=this._objects.length;i--;){this._objects[i].group=this}this.originalState={};this.callSuper("initialize");if(options.originX){this.originX=options.originX}if(options.originY){this.originY=options.originY}this._calcBounds();this._updateObjectsCoords();this.callSuper("initialize",options);this.setCoords();this.saveCoords()},_updateObjectsCoords:function(){this.forEachObject(this._updateObjectCoords,this)},_updateObjectCoords:function(object){var objectLeft=object.getLeft(),objectTop=object.getTop(),center=this.getCenterPoint();object.set({originalLeft:objectLeft,originalTop:objectTop,left:objectLeft-center.x,top:objectTop-center.y});object.setCoords();object.__origHasControls=object.hasControls;object.hasControls=false},toString:function(){return"#"},addWithUpdate:function(object){this._restoreObjectsState();if(object){this._objects.push(object);object.group=this}this.forEachObject(this._setObjectActive,this);this._calcBounds();this._updateObjectsCoords();return this},_setObjectActive:function(object){object.set("active",true);object.group=this},removeWithUpdate:function(object){this._moveFlippedObject(object);this._restoreObjectsState();this.forEachObject(this._setObjectActive,this);this.remove(object);this._calcBounds();this._updateObjectsCoords();return this},_onObjectAdded:function(object){object.group=this},_onObjectRemoved:function(object){delete object.group;object.set("active",false)},delegatedProperties:{fill:true,opacity:true,fontFamily:true,fontWeight:true,fontSize:true,fontStyle:true,lineHeight:true,textDecoration:true,textAlign:true,backgroundColor:true},_set:function(key,value){if(key in this.delegatedProperties){var i=this._objects.length;while(i--){this._objects[i].set(key,value)}}this.callSuper("_set",key,value)},toObject:function(propertiesToInclude){return extend(this.callSuper("toObject",propertiesToInclude),{objects:invoke(this._objects,"toObject",propertiesToInclude)})},render:function(ctx){if(!this.visible){return}ctx.save();this.clipTo&&fabric.util.clipContext(this,ctx);this.transform(ctx);for(var i=0,len=this._objects.length;i\n'];for(var i=0,len=this._objects.length;i\n");return reviver?reviver(markup.join("")):markup.join("")},get:function(prop){if(prop in _lockProperties){if(this[prop]){return this[prop]}else{for(var i=0,len=this._objects.length;i\n','\n");if(this.stroke||this.strokeDashArray){var origFill=this.fill;this.fill=null;markup.push("\n');this.fill=origFill}markup.push("
\n");return reviver?reviver(markup.join("")):markup.join("")},getSrc:function(){if(this.getElement()){return this.getElement().src||this.getElement()._src}},setSrc:function(src,callback,options){fabric.util.loadImage(src,function(img){return this.setElement(img,callback,options)},this,options&&options.crossOrigin)},toString:function(){return'#'},clone:function(callback,propertiesToInclude){this.constructor.fromObject(this.toObject(propertiesToInclude),callback)},applyFilters:function(callback,filters,imgElement,forResizing){filters=filters||this.filters;imgElement=imgElement||this._originalElement;if(!imgElement){return}var imgEl=imgElement,canvasEl=fabric.util.createCanvasElement(),replacement=fabric.util.createImage(),_this=this;canvasEl.width=imgEl.width;canvasEl.height=imgEl.height;canvasEl.getContext("2d").drawImage(imgEl,0,0,imgEl.width,imgEl.height);if(filters.length===0){this._element=imgElement;callback&&callback();return canvasEl}filters.forEach(function(filter){filter&&filter.applyTo(canvasEl,filter.scaleX||_this.scaleX,filter.scaleY||_this.scaleY);if(!forResizing&&filter&&filter.type==="Resize"){_this.width*=filter.scaleX;_this.height*=filter.scaleY}});replacement.width=canvasEl.width;replacement.height=canvasEl.height;if(fabric.isLikelyNode){replacement.src=canvasEl.toBuffer(undefined,fabric.Image.pngCompression);_this._element=replacement;!forResizing&&(_this._filteredEl=replacement);callback&&callback()}else{replacement.onload=function(){_this._element=replacement;!forResizing&&(_this._filteredEl=replacement);callback&&callback();replacement.onload=canvasEl=imgEl=null};replacement.src=canvasEl.toDataURL("image/png")}return canvasEl},_render:function(ctx,noTransform){var x,y,imageMargins=this._findMargins(),elementToDraw;x=noTransform?this.left:-this.width/2;y=noTransform?this.top:-this.height/2;if(this.meetOrSlice==="slice"){ctx.beginPath();ctx.rect(x,y,this.width,this.height);ctx.clip()}if(this.isMoving===false&&this.resizeFilters.length&&this._needsResize()){this._lastScaleX=this.scaleX;this._lastScaleY=this.scaleY;elementToDraw=this.applyFilters(null,this.resizeFilters,this._filteredEl||this._originalElement,true)}else{elementToDraw=this._element}elementToDraw&&ctx.drawImage(elementToDraw,x+imageMargins.marginX,y+imageMargins.marginY,imageMargins.width,imageMargins.height);this._renderStroke(ctx)},_needsResize:function(){return this.scaleX!==this._lastScaleX||this.scaleY!==this._lastScaleY},_findMargins:function(){var width=this.width,height=this.height,scales,scale,marginX=0,marginY=0;if(this.alignX!=="none"||this.alignY!=="none"){scales=[this.width/this._element.width,this.height/this._element.height];scale=this.meetOrSlice==="meet"?Math.min.apply(null,scales):Math.max.apply(null,scales);width=this._element.width*scale;height=this._element.height*scale;if(this.alignX==="Mid"){marginX=(this.width-width)/2}if(this.alignX==="Max"){marginX=this.width-width}if(this.alignY==="Mid"){marginY=(this.height-height)/2}if(this.alignY==="Max"){marginY=this.height-height}}return{width:width,height:height,marginX:marginX,marginY:marginY}},_resetWidthHeight:function(){var element=this.getElement();this.set("width",element.width);this.set("height",element.height)},_initElement:function(element){this.setElement(fabric.util.getById(element));fabric.util.addClass(this.getElement(),fabric.Image.CSS_CANVAS)},_initConfig:function(options){options||(options={});this.setOptions(options);this._setWidthHeight(options);if(this._element&&this.crossOrigin){this._element.crossOrigin=this.crossOrigin}},_initFilters:function(object,callback){if(object.filters&&object.filters.length){fabric.util.enlivenObjects(object.filters,function(enlivenedObjects){callback&&callback(enlivenedObjects)},"fabric.Image.filters")}else{callback&&callback()}},_setWidthHeight:function(options){this.width="width"in options?options.width:this.getElement()?this.getElement().width||0:0;this.height="height"in options?options.height:this.getElement()?this.getElement().height||0:0},complexity:function(){return 1}});fabric.Image.CSS_CANVAS="canvas-img";fabric.Image.prototype.getSvgSrc=fabric.Image.prototype.getSrc;fabric.Image.fromObject=function(object,callback){fabric.util.loadImage(object.src,function(img){fabric.Image.prototype._initFilters.call(object,object,function(filters){object.filters=filters||[];var instance=new fabric.Image(img,object);callback&&callback(instance)})},null,object.crossOrigin)};fabric.Image.fromURL=function(url,callback,imgOptions){fabric.util.loadImage(url,function(img){callback&&callback(new fabric.Image(img,imgOptions))},null,imgOptions&&imgOptions.crossOrigin)};fabric.Image.ATTRIBUTE_NAMES=fabric.SHARED_ATTRIBUTES.concat("x y width height preserveAspectRatio xlink:href".split(" "));fabric.Image.fromElement=function(element,callback,options){var parsedAttributes=fabric.parseAttributes(element,fabric.Image.ATTRIBUTE_NAMES),align="xMidYMid",meetOrSlice="meet",alignX,alignY,aspectRatioAttrs;if(parsedAttributes.preserveAspectRatio){aspectRatioAttrs=parsedAttributes.preserveAspectRatio.split(" ")}if(aspectRatioAttrs&&aspectRatioAttrs.length){meetOrSlice=aspectRatioAttrs.pop();if(meetOrSlice!=="meet"&&meetOrSlice!=="slice"){align=meetOrSlice;meetOrSlice="meet"}else if(aspectRatioAttrs.length){align=aspectRatioAttrs.pop()}}alignX=align!=="none"?align.slice(1,4):"none";alignY=align!=="none"?align.slice(5,8):"none";parsedAttributes.alignX=alignX;parsedAttributes.alignY=alignY;parsedAttributes.meetOrSlice=meetOrSlice;fabric.Image.fromURL(parsedAttributes["xlink:href"],callback,extend(options?fabric.util.object.clone(options):{},parsedAttributes))};fabric.Image.async=true;fabric.Image.pngCompression=1})(typeof exports!=="undefined"?exports:this);fabric.util.object.extend(fabric.Object.prototype,{_getAngleValueForStraighten:function(){var angle=this.getAngle()%360;if(angle>0){return Math.round((angle-1)/90)*90}return Math.round(angle/90)*90},straighten:function(){this.setAngle(this._getAngleValueForStraighten());return this},fxStraighten:function(callbacks){callbacks=callbacks||{};var empty=function(){},onComplete=callbacks.onComplete||empty,onChange=callbacks.onChange||empty,_this=this;fabric.util.animate({startValue:this.get("angle"),endValue:this._getAngleValueForStraighten(),duration:this.FX_DURATION,onChange:function(value){_this.setAngle(value);onChange()},onComplete:function(){_this.setCoords();onComplete()},onStart:function(){_this.set("active",false)}});return this}});fabric.util.object.extend(fabric.StaticCanvas.prototype,{straightenObject:function(object){object.straighten();this.renderAll();return this},fxStraightenObject:function(object){object.fxStraighten({onChange:this.renderAll.bind(this)});return this}});fabric.Image.filters=fabric.Image.filters||{};fabric.Image.filters.BaseFilter=fabric.util.createClass({type:"BaseFilter",initialize:function(options){if(options){this.setOptions(options)}},setOptions:function(options){for(var prop in options){this[prop]=options[prop]}},toObject:function(){return{type:this.type}},toJSON:function(){return this.toObject()}});(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),extend=fabric.util.object.extend;fabric.Image.filters.Brightness=fabric.util.createClass(fabric.Image.filters.BaseFilter,{type:"Brightness",initialize:function(options){options=options||{};this.brightness=options.brightness||0},applyTo:function(canvasEl){var context=canvasEl.getContext("2d"),imageData=context.getImageData(0,0,canvasEl.width,canvasEl.height),data=imageData.data,brightness=this.brightness;for(var i=0,len=data.length;ish||scx<0||scx>sw){continue}var srcOff=(scy*sw+scx)*4,wt=weights[cy*side+cx];r+=src[srcOff]*wt;g+=src[srcOff+1]*wt;b+=src[srcOff+2]*wt;a+=src[srcOff+3]*wt}}dst[dstOff]=r;dst[dstOff+1]=g;dst[dstOff+2]=b;dst[dstOff+3]=a+alphaFac*(255-a)}}context.putImageData(output,0,0)},toObject:function(){return extend(this.callSuper("toObject"),{opaque:this.opaque,matrix:this.matrix})}});fabric.Image.filters.Convolute.fromObject=function(object){return new fabric.Image.filters.Convolute(object); + +}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),extend=fabric.util.object.extend;fabric.Image.filters.GradientTransparency=fabric.util.createClass(fabric.Image.filters.BaseFilter,{type:"GradientTransparency",initialize:function(options){options=options||{};this.threshold=options.threshold||100},applyTo:function(canvasEl){var context=canvasEl.getContext("2d"),imageData=context.getImageData(0,0,canvasEl.width,canvasEl.height),data=imageData.data,threshold=this.threshold,total=data.length;for(var i=0,len=data.length;i-1?options.channel:0},applyTo:function(canvasEl){if(!this.mask){return}var context=canvasEl.getContext("2d"),imageData=context.getImageData(0,0,canvasEl.width,canvasEl.height),data=imageData.data,maskEl=this.mask.getElement(),maskCanvasEl=fabric.util.createCanvasElement(),channel=this.channel,i,iLen=imageData.width*imageData.height*4;maskCanvasEl.width=maskEl.width;maskCanvasEl.height=maskEl.height;maskCanvasEl.getContext("2d").drawImage(maskEl,0,0,maskEl.width,maskEl.height);var maskImageData=maskCanvasEl.getContext("2d").getImageData(0,0,maskEl.width,maskEl.height),maskData=maskImageData.data;for(i=0;ilimit&&g>limit&&b>limit&&abs(r-g)width){multW=2;signW=-1}if(newHeight>height){multH=2;signH=-1}imageData=context.getImageData(0,0,width,height);canvasEl.width=max(newWidth,width);canvasEl.height=max(newHeight,height);context.putImageData(imageData,0,0);while(!doneW||!doneH){width=stepW;height=stepH;if(newWidth*signWlobes){return 0}x*=Math.PI;if(abs(x)<1e-16){return 1}var xx=x/lobes;return sin(x)*sin(xx)/x/xx}}function process(u){var v,i,weight,idx,a,red,green,blue,alpha,fX,fY;center.x=(u+.5)*ratioX;icenter.x=floor(center.x);for(v=0;v=oW){continue}fX=floor(1e3*abs(i-center.x));if(!cacheLanc[fX]){cacheLanc[fX]={}}for(var j=icenter.y-range2Y;j<=icenter.y+range2Y;j++){if(j<0||j>=oH){continue}fY=floor(1e3*abs(j-center.y));if(!cacheLanc[fX][fY]){cacheLanc[fX][fY]=lanczos(sqrt(pow(fX*rcpRatioX,2)+pow(fY*rcpRatioY,2))/1e3)}weight=cacheLanc[fX][fY];if(weight>0){idx=(j*oW+i)*4;a+=weight;red+=weight*srcData[idx];green+=weight*srcData[idx+1];blue+=weight*srcData[idx+2];alpha+=weight*srcData[idx+3]}}}idx=(v*dW+u)*4;destData[idx]=red/a;destData[idx+1]=green/a;destData[idx+2]=blue/a;destData[idx+3]=alpha/a}if(++u1&&w<-1){continue}weight=2*w*w*w-3*w*w+1;if(weight>0){dx=4*(xx+yy*oW);gxA+=weight*data[dx+3];weightsAlpha+=weight;if(data[dx+3]<255){weight=weight*data[dx+3]/250}gxR+=weight*data[dx];gxG+=weight*data[dx+1];gxB+=weight*data[dx+2];weights+=weight}}}data2[x2]=gxR/weights;data2[x2+1]=gxG/weights;data2[x2+2]=gxB/weights;data2[x2+3]=gxA/weightsAlpha}}return img2},toObject:function(){return{type:this.type,scaleX:this.scaleX,scaley:this.scaleY,resizeType:this.resizeType,lanczosLobes:this.lanczosLobes}}});fabric.Image.filters.Resize.fromObject=function(){return new fabric.Image.filters.Resize}})(typeof exports!=="undefined"?exports:this);(function(global){"use strict";var fabric=global.fabric||(global.fabric={}),extend=fabric.util.object.extend,clone=fabric.util.object.clone,toFixed=fabric.util.toFixed,supportsLineDash=fabric.StaticCanvas.supports("setLineDash");if(fabric.Text){fabric.warn("fabric.Text is already defined");return}var stateProperties=fabric.Object.prototype.stateProperties.concat();stateProperties.push("fontFamily","fontWeight","fontSize","text","textDecoration","textAlign","fontStyle","lineHeight","textBackgroundColor");fabric.Text=fabric.util.createClass(fabric.Object,{_dimensionAffectingProps:{fontSize:true,fontWeight:true,fontFamily:true,fontStyle:true,lineHeight:true,stroke:true,strokeWidth:true,text:true,textAlign:true},_reNewline:/\r?\n/,type:"text",fontSize:40,fontWeight:"normal",fontFamily:"Times New Roman",textDecoration:"",textAlign:"left",fontStyle:"",lineHeight:1.16,textBackgroundColor:"",stateProperties:stateProperties,stroke:null,shadow:null,_fontSizeFraction:.25,_fontSizeMult:1.13,initialize:function(text,options){options=options||{};this.text=text;this.__skipDimension=true;this.setOptions(options);this.__skipDimension=false;this._initDimensions()},_initDimensions:function(ctx){if(this.__skipDimension){return}if(!ctx){ctx=fabric.util.createCanvasElement().getContext("2d");this._setTextStyles(ctx)}this._textLines=this.text.split(this._reNewline);this._clearCache();var currentTextAlign=this.textAlign;this.textAlign="left";this.width=this._getTextWidth(ctx);this.textAlign=currentTextAlign;this.height=this._getTextHeight(ctx)},toString:function(){return"#'},_render:function(ctx){this.clipTo&&fabric.util.clipContext(this,ctx);this._renderTextBackground(ctx);this._renderText(ctx);this._renderTextDecoration(ctx);this.clipTo&&ctx.restore()},_renderText:function(ctx){ctx.save();this._translateForTextAlign(ctx);this._setOpacity(ctx);this._setShadow(ctx);this._setupCompositeOperation(ctx);this._renderTextFill(ctx);this._renderTextStroke(ctx);this._restoreCompositeOperation(ctx);this._removeShadow(ctx);ctx.restore()},_translateForTextAlign:function(ctx){if(this.textAlign!=="left"&&this.textAlign!=="justify"){ctx.translate(this.textAlign==="center"?this.width/2:this.width,0)}},_setTextStyles:function(ctx){ctx.textBaseline="alphabetic";if(!this.skipTextAlign){ctx.textAlign=this.textAlign}ctx.font=this._getFontDeclaration()},_getTextHeight:function(){return this._textLines.length*this._getHeightOfLine()},_getTextWidth:function(ctx){var maxWidth=this._getLineWidth(ctx,0);for(var i=1,len=this._textLines.length;imaxWidth){maxWidth=currentLineWidth}}return maxWidth},_renderChars:function(method,ctx,chars,left,top){ctx[method](chars,left,top)},_renderTextLine:function(method,ctx,line,left,top,lineIndex){top-=this.fontSize*this._fontSizeFraction;if(this.textAlign!=="justify"){this._renderChars(method,ctx,line,left,top,lineIndex);return}var lineWidth=this._getLineWidth(ctx,lineIndex),totalWidth=this.width;if(totalWidth>=lineWidth){var words=line.split(/\s+/),wordsWidth=this._getWidthOfWords(ctx,line,lineIndex),widthDiff=totalWidth-wordsWidth,numSpaces=words.length-1,spaceWidth=widthDiff/numSpaces,leftOffset=0;for(var i=0,len=words.length;i-1){offsets.push(.85)}if(this.textDecoration.indexOf("line-through")>-1){offsets.push(.43)}if(this.textDecoration.indexOf("overline")>-1){offsets.push(-.12)}if(offsets.length>0){renderLinesAtOffset(offsets)}},_getFontDeclaration:function(){return[fabric.isLikelyNode?this.fontWeight:this.fontStyle,fabric.isLikelyNode?this.fontStyle:this.fontWeight,this.fontSize+"px",fabric.isLikelyNode?'"'+this.fontFamily+'"':this.fontFamily].join(" ")},render:function(ctx,noTransform){if(!this.visible){return}ctx.save();this._setTextStyles(ctx);if(this._shouldClearCache()){this._initDimensions(ctx)}if(!noTransform){this.transform(ctx)}this._setStrokeStyles(ctx);this._setFillStyles(ctx);if(this.transformMatrix){ctx.transform.apply(ctx,this.transformMatrix)}if(this.group&&this.group.type==="path-group"){ctx.translate(this.left,this.top)}this._render(ctx);ctx.restore()},toObject:function(propertiesToInclude){var object=extend(this.callSuper("toObject",propertiesToInclude),{text:this.text,fontSize:this.fontSize,fontWeight:this.fontWeight,fontFamily:this.fontFamily,fontStyle:this.fontStyle,lineHeight:this.lineHeight,textDecoration:this.textDecoration,textAlign:this.textAlign,textBackgroundColor:this.textBackgroundColor});if(!this.includeDefaultValues){this._removeDefaultValues(object)}return object},toSVG:function(reviver){var markup=this._createBaseSVGMarkup(),offsets=this._getSVGLeftTopOffsets(this.ctx),textAndBg=this._getSVGTextAndBg(offsets.textTop,offsets.textLeft);this._wrapSVGTextAndBg(markup,textAndBg);return reviver?reviver(markup.join("")):markup.join("")},_getSVGLeftTopOffsets:function(ctx){var lineTop=this._getHeightOfLine(ctx,0),textLeft=-this.width/2,textTop=0;return{textLeft:textLeft+(this.group&&this.group.type==="path-group"?this.left:0),textTop:textTop+(this.group&&this.group.type==="path-group"?-this.top:0),lineTop:lineTop}},_wrapSVGTextAndBg:function(markup,textAndBg){markup.push(' \n',textAndBg.textBgRects.join("")," ',textAndBg.textSpans.join(""),"\n"," \n")},_getSVGTextAndBg:function(textTopOffset,textLeftOffset){var textSpans=[],textBgRects=[],height=0;this._setSVGBg(textBgRects);for(var i=0,len=this._textLines.length;i",fabric.util.string.escapeXml(this._textLines[i]),"")},_setSVGTextLineBg:function(textBgRects,i,textLeftOffset,textTopOffset,height){textBgRects.push(" \n')},_setSVGBg:function(textBgRects){if(this.backgroundColor){textBgRects.push(" \n')}},_getFillAttributes:function(value){var fillColor=value&&typeof value==="string"?new fabric.Color(value):"";if(!fillColor||!fillColor.getSource()||fillColor.getAlpha()===1){return'fill="'+value+'"'}return'opacity="'+fillColor.getAlpha()+'" fill="'+fillColor.setAlpha(1).toRgb()+'"'},_set:function(key,value){this.callSuper("_set",key,value);if(key in this._dimensionAffectingProps){this._initDimensions();this.setCoords()}},complexity:function(){return 1}});fabric.Text.ATTRIBUTE_NAMES=fabric.SHARED_ATTRIBUTES.concat("x y dx dy font-family font-style font-weight font-size text-decoration text-anchor".split(" "));fabric.Text.DEFAULT_SVG_FONT_SIZE=16;fabric.Text.fromElement=function(element,options){if(!element){return null}var parsedAttributes=fabric.parseAttributes(element,fabric.Text.ATTRIBUTE_NAMES);options=fabric.util.object.extend(options?fabric.util.object.clone(options):{},parsedAttributes);options.top=options.top||0;options.left=options.left||0;if("dx"in parsedAttributes){options.left+=parsedAttributes.dx}if("dy"in parsedAttributes){options.top+=parsedAttributes.dy}if(!("fontSize"in options)){options.fontSize=fabric.Text.DEFAULT_SVG_FONT_SIZE}if(!options.originX){options.originX="left"}var textContent=element.textContent.replace(/^\s+|\s+$|\n+/g,"").replace(/\s+/g," "),text=new fabric.Text(textContent,options),offX=0;if(text.originX==="left"){offX=text.getWidth()/2}if(text.originX==="right"){offX=-text.getWidth()/2}text.set({left:text.getLeft()+offX,top:text.getTop()-text.getHeight()/2+text.fontSize*(.18+text._fontSizeFraction)});return text};fabric.Text.fromObject=function(object){return new fabric.Text(object.text,clone(object))};fabric.util.createAccessors(fabric.Text)})(typeof exports!=="undefined"?exports:this);(function(){var clone=fabric.util.object.clone;fabric.IText=fabric.util.createClass(fabric.Text,fabric.Observable,{type:"i-text",selectionStart:0,selectionEnd:0,selectionColor:"rgba(17,119,255,0.3)",isEditing:false,editable:true,editingBorderColor:"rgba(102,153,255,0.25)",cursorWidth:2,cursorColor:"#333",cursorDelay:1e3,cursorDuration:600,styles:null,caching:true,_skipFillStrokeCheck:false,_reSpace:/\s|\n/,_currentCursorOpacity:0,_selectionDirection:null,_abortCursorAnimation:false,_charWidthsCache:{},initialize:function(text,options){this.styles=options?options.styles||{}:{};this.callSuper("initialize",text,options);this.initBehavior()},_clearCache:function(){this.callSuper("_clearCache");this.__maxFontHeights=[];this.__widthOfSpace=[]},isEmptyStyles:function(){if(!this.styles){return true}var obj=this.styles;for(var p1 in obj){for(var p2 in obj[p1]){for(var p3 in obj[p1][p2]){return false}}}return true},setSelectionStart:function(index){index=Math.max(index,0);if(this.selectionStart!==index){this.fire("selection:changed");this.canvas&&this.canvas.fire("text:selection:changed",{target:this});this.selectionStart=index}this._updateTextarea()},setSelectionEnd:function(index){index=Math.min(index,this.text.length);if(this.selectionEnd!==index){this.fire("selection:changed");this.canvas&&this.canvas.fire("text:selection:changed",{target:this});this.selectionEnd=index}this._updateTextarea(); + +},getSelectionStyles:function(startIndex,endIndex){if(arguments.length===2){var styles=[];for(var i=startIndex;i=start.charIndex&&(i!==endLine||jstartLine&&i0||this.skipFillStrokeCheck)){this.callSuper("_renderChars",method,ctx,line,left,top)}},_renderChar:function(method,ctx,lineIndex,i,_char,left,top,lineHeight){var decl,charWidth,charHeight,offset=this._fontSizeFraction*lineHeight/this.lineHeight;if(this.styles&&this.styles[lineIndex]&&(decl=this.styles[lineIndex][i])){var shouldStroke=decl.stroke||this.stroke,shouldFill=decl.fill||this.fill;ctx.save();charWidth=this._applyCharStylesGetWidth(ctx,_char,lineIndex,i,decl);charHeight=this._getHeightOfChar(ctx,_char,lineIndex,i);if(shouldFill){ctx.fillText(_char,left,top)}if(shouldStroke){ctx.strokeText(_char,left,top)}this._renderCharDecoration(ctx,decl,left,top,offset,charWidth,charHeight);ctx.restore();ctx.translate(charWidth,0)}else{if(method==="strokeText"&&this.stroke){ctx[method](_char,left,top)}if(method==="fillText"&&this.fill){ctx[method](_char,left,top)}charWidth=this._applyCharStylesGetWidth(ctx,_char,lineIndex,i);this._renderCharDecoration(ctx,null,left,top,offset,charWidth,this.fontSize);ctx.translate(ctx.measureText(_char).width,0)}},_hasStyleChanged:function(prevStyle,thisStyle){return prevStyle.fill!==thisStyle.fill||prevStyle.fontSize!==thisStyle.fontSize||prevStyle.textBackgroundColor!==thisStyle.textBackgroundColor||prevStyle.textDecoration!==thisStyle.textDecoration||prevStyle.fontFamily!==thisStyle.fontFamily||prevStyle.fontWeight!==thisStyle.fontWeight||prevStyle.fontStyle!==thisStyle.fontStyle||prevStyle.stroke!==thisStyle.stroke||prevStyle.strokeWidth!==thisStyle.strokeWidth},_renderCharDecoration:function(ctx,styleDeclaration,left,top,offset,charWidth,charHeight){var textDecoration=styleDeclaration?styleDeclaration.textDecoration||this.textDecoration:this.textDecoration;if(!textDecoration){return}if(textDecoration.indexOf("underline")>-1){ctx.fillRect(left,top+charHeight/10,charWidth,charHeight/15)}if(textDecoration.indexOf("line-through")>-1){ctx.fillRect(left,top-charHeight*(this._fontSizeFraction+this._fontSizeMult-1)+charHeight/15,charWidth,charHeight/15)}if(textDecoration.indexOf("overline")>-1){ctx.fillRect(left,top-(this._fontSizeMult-this._fontSizeFraction)*charHeight,charWidth,charHeight/15)}},_renderTextLine:function(method,ctx,line,left,top,lineIndex){if(!this.isEmptyStyles()){top+=this.fontSize*(this._fontSizeFraction+.03)}this.callSuper("_renderTextLine",method,ctx,line,left,top,lineIndex)},_renderTextDecoration:function(ctx){if(this.isEmptyStyles()){return this.callSuper("_renderTextDecoration",ctx)}},_renderTextLinesBackground:function(ctx){if(!this.textBackgroundColor&&!this.styles){return}ctx.save();if(this.textBackgroundColor){ctx.fillStyle=this.textBackgroundColor}var lineHeights=0;for(var i=0,len=this._textLines.length;imaxHeight){maxHeight=currentCharHeight}}this.__maxFontHeights[lineIndex]=maxHeight;this.__lineHeights[lineIndex]=maxHeight*this.lineHeight*this._fontSizeMult;return this.__lineHeights[lineIndex]},_getTextHeight:function(ctx){var height=0;for(var i=0,len=this._textLines.length;i-1){offset++;index--}return startFrom-offset},findWordBoundaryRight:function(startFrom){var offset=0,index=startFrom;if(this._reSpace.test(this.text.charAt(index))){while(this._reSpace.test(this.text.charAt(index))){offset++;index++}}while(/\S/.test(this.text.charAt(index))&&index-1){offset++;index--}return startFrom-offset},findLineBoundaryRight:function(startFrom){var offset=0,index=startFrom;while(!/\n/.test(this.text.charAt(index))&&index0&&index=_this.__selectionStartOnMouseDown){_this.setSelectionStart(_this.__selectionStartOnMouseDown);_this.setSelectionEnd(newSelectionStart)}else{_this.setSelectionStart(newSelectionStart);_this.setSelectionEnd(_this.__selectionStartOnMouseDown)}})},_setEditingProps:function(){this.hoverCursor="text";if(this.canvas){this.canvas.defaultCursor=this.canvas.moveCursor="text"}this.borderColor=this.editingBorderColor;this.hasControls=this.selectable=false;this.lockMovementX=this.lockMovementY=true},_updateTextarea:function(){if(!this.hiddenTextarea){return}this.hiddenTextarea.value=this.text;this.hiddenTextarea.selectionStart=this.selectionStart;this.hiddenTextarea.selectionEnd=this.selectionEnd},_saveEditingProps:function(){this._savedProps={hasControls:this.hasControls,borderColor:this.borderColor,lockMovementX:this.lockMovementX,lockMovementY:this.lockMovementY,hoverCursor:this.hoverCursor,defaultCursor:this.canvas&&this.canvas.defaultCursor,moveCursor:this.canvas&&this.canvas.moveCursor}},_restoreEditingProps:function(){if(!this._savedProps){return}this.hoverCursor=this._savedProps.overCursor;this.hasControls=this._savedProps.hasControls;this.borderColor=this._savedProps.borderColor;this.lockMovementX=this._savedProps.lockMovementX;this.lockMovementY=this._savedProps.lockMovementY;if(this.canvas){this.canvas.defaultCursor=this._savedProps.defaultCursor;this.canvas.moveCursor=this._savedProps.moveCursor}},exitEditing:function(){this.selected=false;this.isEditing=false;this.selectable=true;this.selectionEnd=this.selectionStart;this.hiddenTextarea&&this.canvas&&this.hiddenTextarea.parentNode.removeChild(this.hiddenTextarea);this.hiddenTextarea=null;this.abortCursorAnimation();this._restoreEditingProps();this._currentCursorOpacity=0;this.fire("editing:exited");this.canvas&&this.canvas.fire("text:editing:exited",{target:this});return this},_removeExtraneousStyles:function(){for(var prop in this.styles){if(!this._textLines[prop]){delete this.styles[prop]}}},_removeCharsFromTo:function(start,end){var i=end;while(i!==start){var prevIndex=this.get2DCursorLocation(i).charIndex;i--;var index=this.get2DCursorLocation(i).charIndex,isNewline=index>prevIndex;if(isNewline){this.removeStyleObject(isNewline,i+1)}else{this.removeStyleObject(this.get2DCursorLocation(i).charIndex===0,i)}}this.text=this.text.slice(0,start)+this.text.slice(end);this._clearCache()},insertChars:function(_chars,useCopiedStyle){var isEndOfLine=this.text.slice(this.selectionStart,this.selectionStart+1)==="\n";this.text=this.text.slice(0,this.selectionStart)+_chars+this.text.slice(this.selectionEnd);if(this.selectionStart===this.selectionEnd){this.insertStyleObjects(_chars,isEndOfLine,useCopiedStyle)}this.setSelectionStart(this.selectionStart+_chars.length);this.setSelectionEnd(this.selectionStart);this._clearCache();this.canvas&&this.canvas.renderAll();this.setCoords();this.fire("changed");this.canvas&&this.canvas.fire("text:changed",{target:this})},insertNewlineStyleObject:function(lineIndex,charIndex,isEndOfLine){this.shiftLineStyles(lineIndex,+1);if(!this.styles[lineIndex+1]){this.styles[lineIndex+1]={}}var currentCharStyle=this.styles[lineIndex][charIndex-1],newLineStyles={};if(isEndOfLine){newLineStyles[0]=clone(currentCharStyle);this.styles[lineIndex+1]=newLineStyles}else{for(var index in this.styles[lineIndex]){if(parseInt(index,10)>=charIndex){newLineStyles[parseInt(index,10)-charIndex]=this.styles[lineIndex][index];delete this.styles[lineIndex][index]}}this.styles[lineIndex+1]=newLineStyles}this._clearCache()},insertCharStyleObject:function(lineIndex,charIndex,style){var currentLineStyles=this.styles[lineIndex],currentLineStylesCloned=clone(currentLineStyles);if(charIndex===0&&!style){charIndex=1}for(var index in currentLineStylesCloned){var numericIndex=parseInt(index,10);if(numericIndex>=charIndex){currentLineStyles[numericIndex+1]=currentLineStylesCloned[numericIndex]}}this.styles[lineIndex][charIndex]=style||clone(currentLineStyles[charIndex-1]);this._clearCache()},insertStyleObjects:function(_chars,isEndOfLine,useCopiedStyle){var cursorLocation=this.get2DCursorLocation(),lineIndex=cursorLocation.lineIndex,charIndex=cursorLocation.charIndex;if(!this.styles[lineIndex]){this.styles[lineIndex]={}}if(_chars==="\n"){this.insertNewlineStyleObject(lineIndex,charIndex,isEndOfLine)}else{if(useCopiedStyle){this._insertStyles(this.copiedStyles)}else{this.insertCharStyleObject(lineIndex,charIndex)}}},_insertStyles:function(styles){for(var i=0,len=styles.length;ilineIndex){this.styles[numericLine+offset]=clonedStyles[numericLine]}}},removeStyleObject:function(isBeginningOfLine,index){var cursorLocation=this.get2DCursorLocation(index),lineIndex=cursorLocation.lineIndex,charIndex=cursorLocation.charIndex;if(isBeginningOfLine){var textOnPreviousLine=this._textLines[lineIndex-1],newCharIndexOnPrevLine=textOnPreviousLine?textOnPreviousLine.length:0;if(!this.styles[lineIndex-1]){this.styles[lineIndex-1]={}}for(charIndex in this.styles[lineIndex]){this.styles[lineIndex-1][parseInt(charIndex,10)+newCharIndexOnPrevLine]=this.styles[lineIndex][charIndex]}this.shiftLineStyles(lineIndex,-1)}else{var currentLineStyles=this.styles[lineIndex];if(currentLineStyles){var offset=this.selectionStart===this.selectionEnd?-1:0;delete currentLineStyles[charIndex+offset]}var currentLineStylesCloned=clone(currentLineStyles);for(var i in currentLineStylesCloned){var numericIndex=parseInt(i,10);if(numericIndex>=charIndex&&numericIndex!==0){currentLineStyles[numericIndex-1]=currentLineStylesCloned[numericIndex];delete currentLineStyles[numericIndex]}}}},insertNewline:function(){this.insertChars("\n")}})})();fabric.util.object.extend(fabric.IText.prototype,{initDoubleClickSimulation:function(){this.__lastClickTime=+new Date;this.__lastLastClickTime=+new Date;this.__lastPointer={};this.on("mousedown",this.onMouseDown.bind(this))},onMouseDown:function(options){this.__newClickTime=+new Date;var newPointer=this.canvas.getPointer(options.e);if(this.isTripleClick(newPointer)){this.fire("tripleclick",options);this._stopEvent(options.e)}else if(this.isDoubleClick(newPointer)){this.fire("dblclick",options);this._stopEvent(options.e)}this.__lastLastClickTime=this.__lastClickTime;this.__lastClickTime=this.__newClickTime;this.__lastPointer=newPointer;this.__lastIsEditing=this.isEditing;this.__lastSelected=this.selected},isDoubleClick:function(newPointer){return this.__newClickTime-this.__lastClickTime<500&&this.__lastPointer.x===newPointer.x&&this.__lastPointer.y===newPointer.y&&this.__lastIsEditing},isTripleClick:function(newPointer){return this.__newClickTime-this.__lastClickTime<500&&this.__lastClickTime-this.__lastLastClickTime<500&&this.__lastPointer.x===newPointer.x&&this.__lastPointer.y===newPointer.y},_stopEvent:function(e){e.preventDefault&&e.preventDefault();e.stopPropagation&&e.stopPropagation()},initCursorSelectionHandlers:function(){this.initSelectedHandler();this.initMousedownHandler();this.initMouseupHandler();this.initClicks()},initClicks:function(){this.on("dblclick",function(options){this.selectWord(this.getSelectionStartFromPointer(options.e))});this.on("tripleclick",function(options){this.selectLine(this.getSelectionStartFromPointer(options.e))})},initMousedownHandler:function(){this.on("mousedown",function(options){var pointer=this.canvas.getPointer(options.e);this.__mousedownX=pointer.x;this.__mousedownY=pointer.y;this.__isMousedown=true;if(this.hiddenTextarea&&this.canvas){this.canvas.wrapperEl.appendChild(this.hiddenTextarea)}if(this.selected){this.setCursorByClick(options.e)}if(this.isEditing){this.__selectionStartOnMouseDown=this.selectionStart;this.initDelayedCursor(true)}})},_isObjectMoved:function(e){var pointer=this.canvas.getPointer(e);return this.__mousedownX!==pointer.x||this.__mousedownY!==pointer.y},initMouseupHandler:function(){this.on("mouseup",function(options){this.__isMousedown=false;if(this._isObjectMoved(options.e)){return}if(this.__lastSelected){this.enterEditing();this.initDelayedCursor(true)}this.selected=true})},setCursorByClick:function(e){var newSelectionStart=this.getSelectionStartFromPointer(e);if(e.shiftKey){if(newSelectionStartdistanceBtwLastCharAndCursor?0:1,newSelectionStart=index+offset;if(this.flipX){newSelectionStart=jlen-newSelectionStart}if(newSelectionStart>this.text.length){newSelectionStart=this.text.length}return newSelectionStart}});fabric.util.object.extend(fabric.IText.prototype,{initHiddenTextarea:function(){this.hiddenTextarea=fabric.document.createElement("textarea");this.hiddenTextarea.setAttribute("autocapitalize","off");this.hiddenTextarea.style.cssText="position: fixed; bottom: 20px; left: 0px; opacity: 0;"+" width: 0px; height: 0px; z-index: -999;";fabric.document.body.appendChild(this.hiddenTextarea); + +fabric.util.addListener(this.hiddenTextarea,"keydown",this.onKeyDown.bind(this));fabric.util.addListener(this.hiddenTextarea,"keypress",this.onKeyPress.bind(this));fabric.util.addListener(this.hiddenTextarea,"copy",this.copy.bind(this));fabric.util.addListener(this.hiddenTextarea,"paste",this.paste.bind(this));if(!this._clickHandlerInitialized&&this.canvas){fabric.util.addListener(this.canvas.upperCanvasEl,"click",this.onClick.bind(this));this._clickHandlerInitialized=true}},_keysMap:{8:"removeChars",9:"exitEditing",27:"exitEditing",13:"insertNewline",33:"moveCursorUp",34:"moveCursorDown",35:"moveCursorRight",36:"moveCursorLeft",37:"moveCursorLeft",38:"moveCursorUp",39:"moveCursorRight",40:"moveCursorDown",46:"forwardDelete"},_ctrlKeysMap:{65:"selectAll",88:"cut"},onClick:function(){this.hiddenTextarea&&this.hiddenTextarea.focus()},onKeyDown:function(e){if(!this.isEditing){return}if(e.keyCode in this._keysMap){this[this._keysMap[e.keyCode]](e)}else if(e.keyCode in this._ctrlKeysMap&&(e.ctrlKey||e.metaKey)){this[this._ctrlKeysMap[e.keyCode]](e)}else{return}e.stopImmediatePropagation();e.preventDefault();this.canvas&&this.canvas.renderAll()},forwardDelete:function(e){if(this.selectionStart===this.selectionEnd){this.moveCursorRight(e)}this.removeChars(e)},copy:function(e){var selectedText=this.getSelectedText(),clipboardData=this._getClipboardData(e);if(clipboardData){clipboardData.setData("text",selectedText)}this.copiedText=selectedText;this.copiedStyles=this.getSelectionStyles(this.selectionStart,this.selectionEnd)},paste:function(e){var copiedText=null,clipboardData=this._getClipboardData(e);if(clipboardData){copiedText=clipboardData.getData("text")}else{copiedText=this.copiedText}if(copiedText){this.insertChars(copiedText,true)}},cut:function(e){if(this.selectionStart===this.selectionEnd){return}this.copy();this.removeChars(e)},_getClipboardData:function(e){return e&&(e.clipboardData||fabric.window.clipboardData)},onKeyPress:function(e){if(!this.isEditing||e.metaKey||e.ctrlKey){return}if(e.which!==0){this.insertChars(String.fromCharCode(e.which))}e.stopPropagation()},getDownCursorOffset:function(e,isRight){var selectionProp=isRight?this.selectionEnd:this.selectionStart,_char,lineLeftOffset,textBeforeCursor=this.text.slice(0,selectionProp),textAfterCursor=this.text.slice(selectionProp),textOnSameLineBeforeCursor=textBeforeCursor.slice(textBeforeCursor.lastIndexOf("\n")+1),textOnSameLineAfterCursor=textAfterCursor.match(/(.*)\n?/)[1],textOnNextLine=(textAfterCursor.match(/.*\n(.*)\n?/)||{})[1]||"",cursorLocation=this.get2DCursorLocation(selectionProp);if(cursorLocation.lineIndex===this._textLines.length-1||e.metaKey||e.keyCode===34){return this.text.length-selectionProp}var widthOfSameLineBeforeCursor=this._getLineWidth(this.ctx,cursorLocation.lineIndex);lineLeftOffset=this._getLineLeftOffset(widthOfSameLineBeforeCursor);var widthOfCharsOnSameLineBeforeCursor=lineLeftOffset,lineIndex=cursorLocation.lineIndex;for(var i=0,len=textOnSameLineBeforeCursor.length;iwidthOfCharsOnSameLineBeforeCursor){foundMatch=true;var leftEdge=widthOfCharsOnNextLine-widthOfChar,rightEdge=widthOfCharsOnNextLine,offsetFromLeftEdge=Math.abs(leftEdge-widthOfCharsOnSameLineBeforeCursor),offsetFromRightEdge=Math.abs(rightEdge-widthOfCharsOnSameLineBeforeCursor);indexOnNextLine=offsetFromRightEdgethis.text.length){this.setSelectionEnd(this.text.length)}},getUpCursorOffset:function(e,isRight){var selectionProp=isRight?this.selectionEnd:this.selectionStart,cursorLocation=this.get2DCursorLocation(selectionProp);if(cursorLocation.lineIndex===0||e.metaKey||e.keyCode===33){return selectionProp}var textBeforeCursor=this.text.slice(0,selectionProp),textOnSameLineBeforeCursor=textBeforeCursor.slice(textBeforeCursor.lastIndexOf("\n")+1),textOnPreviousLine=(textBeforeCursor.match(/\n?(.*)\n.*$/)||{})[1]||"",_char,widthOfSameLineBeforeCursor=this._getLineWidth(this.ctx,cursorLocation.lineIndex),lineLeftOffset=this._getLineLeftOffset(widthOfSameLineBeforeCursor),widthOfCharsOnSameLineBeforeCursor=lineLeftOffset,lineIndex=cursorLocation.lineIndex;for(var i=0,len=textOnSameLineBeforeCursor.length;iwidthOfCharsOnSameLineBeforeCursor){foundMatch=true;var leftEdge=widthOfCharsOnPreviousLine-widthOfChar,rightEdge=widthOfCharsOnPreviousLine,offsetFromLeftEdge=Math.abs(leftEdge-widthOfCharsOnSameLineBeforeCursor),offsetFromRightEdge=Math.abs(rightEdge-widthOfCharsOnSameLineBeforeCursor);indexOnPrevLine=offsetFromRightEdge=this.text.length&&this.selectionEnd>=this.text.length){return}this.abortCursorAnimation();this._currentCursorOpacity=1;if(e.shiftKey){this.moveCursorRightWithShift(e)}else{this.moveCursorRightWithoutShift(e)}this.initDelayedCursor()},moveCursorRightWithShift:function(e){if(this._selectionDirection==="left"&&this.selectionStart!==this.selectionEnd){this._moveRight(e,"selectionStart")}else{this._selectionDirection="right";this._moveRight(e,"selectionEnd");if(this.text.charAt(this.selectionEnd-1)==="\n"){this.setSelectionEnd(this.selectionEnd+1)}}},moveCursorRightWithoutShift:function(e){this._selectionDirection="right";if(this.selectionStart===this.selectionEnd){this._moveRight(e,"selectionStart");this.setSelectionEnd(this.selectionStart)}else{this.setSelectionEnd(this.selectionEnd+this.getNumNewLinesInSelectedText());this.setSelectionStart(this.selectionEnd)}},removeChars:function(e){if(this.selectionStart===this.selectionEnd){this._removeCharsNearCursor(e)}else{this._removeCharsFromTo(this.selectionStart,this.selectionEnd)}this.setSelectionEnd(this.selectionStart);this._removeExtraneousStyles();this._clearCache();this.canvas&&this.canvas.renderAll();this.setCoords();this.fire("changed");this.canvas&&this.canvas.fire("text:changed",{target:this})},_removeCharsNearCursor:function(e){if(this.selectionStart!==0){if(e.metaKey){var leftLineBoundary=this.findLineBoundaryLeft(this.selectionStart);this._removeCharsFromTo(leftLineBoundary,this.selectionStart);this.setSelectionStart(leftLineBoundary)}else if(e.altKey){var leftWordBoundary=this.findWordBoundaryLeft(this.selectionStart);this._removeCharsFromTo(leftWordBoundary,this.selectionStart);this.setSelectionStart(leftWordBoundary)}else{var isBeginningOfLine=this.text.slice(this.selectionStart-1,this.selectionStart)==="\n";this.removeStyleObject(isBeginningOfLine);this.setSelectionStart(this.selectionStart-1);this.text=this.text.slice(0,this.selectionStart)+this.text.slice(this.selectionStart+1)}}}});fabric.util.object.extend(fabric.IText.prototype,{_setSVGTextLineText:function(lineIndex,textSpans,height,textLeftOffset,textTopOffset,textBgRects){if(!this.styles[lineIndex]){this.callSuper("_setSVGTextLineText",lineIndex,textSpans,height,textLeftOffset,textTopOffset)}else{this._setSVGTextLineChars(lineIndex,textSpans,height,textLeftOffset,textBgRects)}},_setSVGTextLineChars:function(lineIndex,textSpans,height,textLeftOffset,textBgRects){var chars=this._textLines[lineIndex].split(""),charOffset=0,lineLeftOffset=this._getSVGLineLeftOffset(lineIndex)-this.width/2,lineOffset=this._getSVGLineTopOffset(lineIndex),heightOfLine=this._getHeightOfLine(this.ctx,lineIndex);for(var i=0,len=chars.length;i'].join("")},_createTextCharSpan:function(_char,styleDecl,lineLeftOffset,lineTopOffset,charOffset){var fillStyles=this.getSvgStyles.call(fabric.util.object.extend({visible:true,fill:this.fill,stroke:this.stroke,type:"text"},styleDecl));return['',fabric.util.string.escapeXml(_char),""].join("")}});(function(){if(typeof document!=="undefined"&&typeof window!=="undefined"){return}var DOMParser=require("xmldom").DOMParser,URL=require("url"),HTTP=require("http"),HTTPS=require("https"),Canvas=require("canvas"),Image=require("canvas").Image;function request(url,encoding,callback){var oURL=URL.parse(url);if(!oURL.port){oURL.port=oURL.protocol.indexOf("https:")===0?443:80}var reqHandler=oURL.protocol.indexOf("https:")===0?HTTPS:HTTP,req=reqHandler.request({hostname:oURL.hostname,port:oURL.port,path:oURL.path,method:"GET"},function(response){var body="";if(encoding){response.setEncoding(encoding)}response.on("end",function(){callback(body)});response.on("data",function(chunk){if(response.statusCode===200){body+=chunk}})});req.on("error",function(err){if(err.errno===process.ECONNREFUSED){fabric.log("ECONNREFUSED: connection refused to "+oURL.hostname+":"+oURL.port)}else{fabric.log(err.message)}});req.end()}function requestFs(path,callback){var fs=require("fs");fs.readFile(path,function(err,data){if(err){fabric.log(err);throw err}else{callback(data)}})}fabric.util.loadImage=function(url,callback,context){function createImageAndCallBack(data){img.src=new Buffer(data,"binary");img._src=url;callback&&callback.call(context,img)}var img=new Image;if(url&&(url instanceof Buffer||url.indexOf("data")===0)){img.src=img._src=url;callback&&callback.call(context,img)}else if(url&&url.indexOf("http")!==0){requestFs(url,createImageAndCallBack)}else if(url){request(url,"binary",createImageAndCallBack)}else{callback&&callback.call(context,url)}};fabric.loadSVGFromURL=function(url,callback,reviver){url=url.replace(/^\n\s*/,"").replace(/\?.*$/,"").trim();if(url.indexOf("http")!==0){requestFs(url,function(body){fabric.loadSVGFromString(body.toString(),callback,reviver)})}else{request(url,"",function(body){fabric.loadSVGFromString(body,callback,reviver)})}};fabric.loadSVGFromString=function(string,callback,reviver){var doc=(new DOMParser).parseFromString(string);fabric.parseSVGDocument(doc.documentElement,function(results,options){callback&&callback(results,options)},reviver)};fabric.util.getScript=function(url,callback){request(url,"",function(body){eval(body);callback&&callback()})};fabric.Image.fromObject=function(object,callback){fabric.util.loadImage(object.src,function(img){var oImg=new fabric.Image(img);oImg._initConfig(object);oImg._initFilters(object,function(filters){oImg.filters=filters||[];callback&&callback(oImg)})})};fabric.createCanvasForNode=function(width,height,options,nodeCanvasOptions){nodeCanvasOptions=nodeCanvasOptions||options;var canvasEl=fabric.document.createElement("canvas"),nodeCanvas=new Canvas(width||600,height||600,nodeCanvasOptions);canvasEl.style={};canvasEl.width=nodeCanvas.width;canvasEl.height=nodeCanvas.height;var FabricCanvas=fabric.Canvas||fabric.StaticCanvas,fabricCanvas=new FabricCanvas(canvasEl,options);fabricCanvas.contextContainer=nodeCanvas.getContext("2d");fabricCanvas.nodeCanvas=nodeCanvas;fabricCanvas.Font=Canvas.Font;return fabricCanvas};fabric.StaticCanvas.prototype.createPNGStream=function(){return this.nodeCanvas.createPNGStream()};fabric.StaticCanvas.prototype.createJPEGStream=function(opts){return this.nodeCanvas.createJPEGStream(opts)};var origSetWidth=fabric.StaticCanvas.prototype.setWidth;fabric.StaticCanvas.prototype.setWidth=function(width,options){origSetWidth.call(this,width,options);this.nodeCanvas.width=width;return this};if(fabric.Canvas){fabric.Canvas.prototype.setWidth=fabric.StaticCanvas.prototype.setWidth}var origSetHeight=fabric.StaticCanvas.prototype.setHeight;fabric.StaticCanvas.prototype.setHeight=function(height,options){origSetHeight.call(this,height,options);this.nodeCanvas.height=height;return this};if(fabric.Canvas){fabric.Canvas.prototype.setHeight=fabric.StaticCanvas.prototype.setHeight}})(); \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/export/libs/jszip/jszip.js b/iguana/js/amcharts/plugins/export/libs/jszip/jszip.js new file mode 100755 index 000000000..6eb28315c --- /dev/null +++ b/iguana/js/amcharts/plugins/export/libs/jszip/jszip.js @@ -0,0 +1,9155 @@ +/*! + +JSZip - A Javascript class for generating and reading zip files + + +(c) 2009-2014 Stuart Knightley +Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip/master/LICENSE.markdown. + +JSZip uses the library pako released under the MIT license : +https://github.com/nodeca/pako/blob/master/LICENSE +*/ +!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.JSZip=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o> 2; + enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); + enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); + enc4 = chr3 & 63; + + if (isNaN(chr2)) { + enc3 = enc4 = 64; + } + else if (isNaN(chr3)) { + enc4 = 64; + } + + output = output + _keyStr.charAt(enc1) + _keyStr.charAt(enc2) + _keyStr.charAt(enc3) + _keyStr.charAt(enc4); + + } + + return output; +}; + +// public method for decoding +exports.decode = function(input, utf8) { + var output = ""; + var chr1, chr2, chr3; + var enc1, enc2, enc3, enc4; + var i = 0; + + input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); + + while (i < input.length) { + + enc1 = _keyStr.indexOf(input.charAt(i++)); + enc2 = _keyStr.indexOf(input.charAt(i++)); + enc3 = _keyStr.indexOf(input.charAt(i++)); + enc4 = _keyStr.indexOf(input.charAt(i++)); + + chr1 = (enc1 << 2) | (enc2 >> 4); + chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); + chr3 = ((enc3 & 3) << 6) | enc4; + + output = output + String.fromCharCode(chr1); + + if (enc3 != 64) { + output = output + String.fromCharCode(chr2); + } + if (enc4 != 64) { + output = output + String.fromCharCode(chr3); + } + + } + + return output; + +}; + +},{}],2:[function(_dereq_,module,exports){ +'use strict'; +function CompressedObject() { + this.compressedSize = 0; + this.uncompressedSize = 0; + this.crc32 = 0; + this.compressionMethod = null; + this.compressedContent = null; +} + +CompressedObject.prototype = { + /** + * Return the decompressed content in an unspecified format. + * The format will depend on the decompressor. + * @return {Object} the decompressed content. + */ + getContent: function() { + return null; // see implementation + }, + /** + * Return the compressed content in an unspecified format. + * The format will depend on the compressed conten source. + * @return {Object} the compressed content. + */ + getCompressedContent: function() { + return null; // see implementation + } +}; +module.exports = CompressedObject; + +},{}],3:[function(_dereq_,module,exports){ +'use strict'; +exports.STORE = { + magic: "\x00\x00", + compress: function(content, compressionOptions) { + return content; // no compression + }, + uncompress: function(content) { + return content; // no compression + }, + compressInputType: null, + uncompressInputType: null +}; +exports.DEFLATE = _dereq_('./flate'); + +},{"./flate":8}],4:[function(_dereq_,module,exports){ +'use strict'; + +var utils = _dereq_('./utils'); + +var table = [ + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, + 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, + 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, + 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, + 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, + 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, + 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, + 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, + 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, + 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, + 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, + 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, + 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, + 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, + 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, + 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, + 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, + 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, + 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, + 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, + 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, + 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, + 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, + 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, + 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, + 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, + 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, + 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, + 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, + 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, + 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, + 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, + 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, + 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, + 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, + 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, + 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, + 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, + 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, + 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, + 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, + 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, + 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, + 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, + 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, + 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, + 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, + 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, + 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, + 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, + 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, + 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, + 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, + 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D +]; + +/** + * + * Javascript crc32 + * http://www.webtoolkit.info/ + * + */ +module.exports = function crc32(input, crc) { + if (typeof input === "undefined" || !input.length) { + return 0; + } + + var isArray = utils.getTypeOf(input) !== "string"; + + if (typeof(crc) == "undefined") { + crc = 0; + } + var x = 0; + var y = 0; + var b = 0; + + crc = crc ^ (-1); + for (var i = 0, iTop = input.length; i < iTop; i++) { + b = isArray ? input[i] : input.charCodeAt(i); + y = (crc ^ b) & 0xFF; + x = table[y]; + crc = (crc >>> 8) ^ x; + } + + return crc ^ (-1); +}; +// vim: set shiftwidth=4 softtabstop=4: + +},{"./utils":21}],5:[function(_dereq_,module,exports){ +'use strict'; +var utils = _dereq_('./utils'); + +function DataReader(data) { + this.data = null; // type : see implementation + this.length = 0; + this.index = 0; +} +DataReader.prototype = { + /** + * Check that the offset will not go too far. + * @param {string} offset the additional offset to check. + * @throws {Error} an Error if the offset is out of bounds. + */ + checkOffset: function(offset) { + this.checkIndex(this.index + offset); + }, + /** + * Check that the specifed index will not be too far. + * @param {string} newIndex the index to check. + * @throws {Error} an Error if the index is out of bounds. + */ + checkIndex: function(newIndex) { + if (this.length < newIndex || newIndex < 0) { + throw new Error("End of data reached (data length = " + this.length + ", asked index = " + (newIndex) + "). Corrupted zip ?"); + } + }, + /** + * Change the index. + * @param {number} newIndex The new index. + * @throws {Error} if the new index is out of the data. + */ + setIndex: function(newIndex) { + this.checkIndex(newIndex); + this.index = newIndex; + }, + /** + * Skip the next n bytes. + * @param {number} n the number of bytes to skip. + * @throws {Error} if the new index is out of the data. + */ + skip: function(n) { + this.setIndex(this.index + n); + }, + /** + * Get the byte at the specified index. + * @param {number} i the index to use. + * @return {number} a byte. + */ + byteAt: function(i) { + // see implementations + }, + /** + * Get the next number with a given byte size. + * @param {number} size the number of bytes to read. + * @return {number} the corresponding number. + */ + readInt: function(size) { + var result = 0, + i; + this.checkOffset(size); + for (i = this.index + size - 1; i >= this.index; i--) { + result = (result << 8) + this.byteAt(i); + } + this.index += size; + return result; + }, + /** + * Get the next string with a given byte size. + * @param {number} size the number of bytes to read. + * @return {string} the corresponding string. + */ + readString: function(size) { + return utils.transformTo("string", this.readData(size)); + }, + /** + * Get raw data without conversion, bytes. + * @param {number} size the number of bytes to read. + * @return {Object} the raw data, implementation specific. + */ + readData: function(size) { + // see implementations + }, + /** + * Find the last occurence of a zip signature (4 bytes). + * @param {string} sig the signature to find. + * @return {number} the index of the last occurence, -1 if not found. + */ + lastIndexOfSignature: function(sig) { + // see implementations + }, + /** + * Get the next date. + * @return {Date} the date. + */ + readDate: function() { + var dostime = this.readInt(4); + return new Date( + ((dostime >> 25) & 0x7f) + 1980, // year + ((dostime >> 21) & 0x0f) - 1, // month + (dostime >> 16) & 0x1f, // day + (dostime >> 11) & 0x1f, // hour + (dostime >> 5) & 0x3f, // minute + (dostime & 0x1f) << 1); // second + } +}; +module.exports = DataReader; + +},{"./utils":21}],6:[function(_dereq_,module,exports){ +'use strict'; +exports.base64 = false; +exports.binary = false; +exports.dir = false; +exports.createFolders = false; +exports.date = null; +exports.compression = null; +exports.compressionOptions = null; +exports.comment = null; +exports.unixPermissions = null; +exports.dosPermissions = null; + +},{}],7:[function(_dereq_,module,exports){ +'use strict'; +var utils = _dereq_('./utils'); + +/** + * @deprecated + * This function will be removed in a future version without replacement. + */ +exports.string2binary = function(str) { + return utils.string2binary(str); +}; + +/** + * @deprecated + * This function will be removed in a future version without replacement. + */ +exports.string2Uint8Array = function(str) { + return utils.transformTo("uint8array", str); +}; + +/** + * @deprecated + * This function will be removed in a future version without replacement. + */ +exports.uint8Array2String = function(array) { + return utils.transformTo("string", array); +}; + +/** + * @deprecated + * This function will be removed in a future version without replacement. + */ +exports.string2Blob = function(str) { + var buffer = utils.transformTo("arraybuffer", str); + return utils.arrayBuffer2Blob(buffer); +}; + +/** + * @deprecated + * This function will be removed in a future version without replacement. + */ +exports.arrayBuffer2Blob = function(buffer) { + return utils.arrayBuffer2Blob(buffer); +}; + +/** + * @deprecated + * This function will be removed in a future version without replacement. + */ +exports.transformTo = function(outputType, input) { + return utils.transformTo(outputType, input); +}; + +/** + * @deprecated + * This function will be removed in a future version without replacement. + */ +exports.getTypeOf = function(input) { + return utils.getTypeOf(input); +}; + +/** + * @deprecated + * This function will be removed in a future version without replacement. + */ +exports.checkSupport = function(type) { + return utils.checkSupport(type); +}; + +/** + * @deprecated + * This value will be removed in a future version without replacement. + */ +exports.MAX_VALUE_16BITS = utils.MAX_VALUE_16BITS; + +/** + * @deprecated + * This value will be removed in a future version without replacement. + */ +exports.MAX_VALUE_32BITS = utils.MAX_VALUE_32BITS; + + +/** + * @deprecated + * This function will be removed in a future version without replacement. + */ +exports.pretty = function(str) { + return utils.pretty(str); +}; + +/** + * @deprecated + * This function will be removed in a future version without replacement. + */ +exports.findCompression = function(compressionMethod) { + return utils.findCompression(compressionMethod); +}; + +/** + * @deprecated + * This function will be removed in a future version without replacement. + */ +exports.isRegExp = function (object) { + return utils.isRegExp(object); +}; + + +},{"./utils":21}],8:[function(_dereq_,module,exports){ +'use strict'; +var USE_TYPEDARRAY = (typeof Uint8Array !== 'undefined') && (typeof Uint16Array !== 'undefined') && (typeof Uint32Array !== 'undefined'); + +var pako = _dereq_("pako"); +exports.uncompressInputType = USE_TYPEDARRAY ? "uint8array" : "array"; +exports.compressInputType = USE_TYPEDARRAY ? "uint8array" : "array"; + +exports.magic = "\x08\x00"; +exports.compress = function(input, compressionOptions) { + return pako.deflateRaw(input, { + level : compressionOptions.level || -1 // default compression + }); +}; +exports.uncompress = function(input) { + return pako.inflateRaw(input); +}; + +},{"pako":24}],9:[function(_dereq_,module,exports){ +'use strict'; + +var base64 = _dereq_('./base64'); + +/** +Usage: + zip = new JSZip(); + zip.file("hello.txt", "Hello, World!").file("tempfile", "nothing"); + zip.folder("images").file("smile.gif", base64Data, {base64: true}); + zip.file("Xmas.txt", "Ho ho ho !", {date : new Date("December 25, 2007 00:00:01")}); + zip.remove("tempfile"); + + base64zip = zip.generate(); + +**/ + +/** + * Representation a of zip file in js + * @constructor + * @param {String=|ArrayBuffer=|Uint8Array=} data the data to load, if any (optional). + * @param {Object=} options the options for creating this objects (optional). + */ +function JSZip(data, options) { + // if this constructor is used without `new`, it adds `new` before itself: + if(!(this instanceof JSZip)) return new JSZip(data, options); + + // object containing the files : + // { + // "folder/" : {...}, + // "folder/data.txt" : {...} + // } + this.files = {}; + + this.comment = null; + + // Where we are in the hierarchy + this.root = ""; + if (data) { + this.load(data, options); + } + this.clone = function() { + var newObj = new JSZip(); + for (var i in this) { + if (typeof this[i] !== "function") { + newObj[i] = this[i]; + } + } + return newObj; + }; +} +JSZip.prototype = _dereq_('./object'); +JSZip.prototype.load = _dereq_('./load'); +JSZip.support = _dereq_('./support'); +JSZip.defaults = _dereq_('./defaults'); + +/** + * @deprecated + * This namespace will be removed in a future version without replacement. + */ +JSZip.utils = _dereq_('./deprecatedPublicUtils'); + +JSZip.base64 = { + /** + * @deprecated + * This method will be removed in a future version without replacement. + */ + encode : function(input) { + return base64.encode(input); + }, + /** + * @deprecated + * This method will be removed in a future version without replacement. + */ + decode : function(input) { + return base64.decode(input); + } +}; +JSZip.compressions = _dereq_('./compressions'); +module.exports = JSZip; + +},{"./base64":1,"./compressions":3,"./defaults":6,"./deprecatedPublicUtils":7,"./load":10,"./object":13,"./support":17}],10:[function(_dereq_,module,exports){ +'use strict'; +var base64 = _dereq_('./base64'); +var ZipEntries = _dereq_('./zipEntries'); +module.exports = function(data, options) { + var files, zipEntries, i, input; + options = options || {}; + if (options.base64) { + data = base64.decode(data); + } + + zipEntries = new ZipEntries(data, options); + files = zipEntries.files; + for (i = 0; i < files.length; i++) { + input = files[i]; + this.file(input.fileName, input.decompressed, { + binary: true, + optimizedBinaryString: true, + date: input.date, + dir: input.dir, + comment : input.fileComment.length ? input.fileComment : null, + unixPermissions : input.unixPermissions, + dosPermissions : input.dosPermissions, + createFolders: options.createFolders + }); + } + if (zipEntries.zipComment.length) { + this.comment = zipEntries.zipComment; + } + + return this; +}; + +},{"./base64":1,"./zipEntries":22}],11:[function(_dereq_,module,exports){ +(function (Buffer){ +'use strict'; +module.exports = function(data, encoding){ + return new Buffer(data, encoding); +}; +module.exports.test = function(b){ + return Buffer.isBuffer(b); +}; + +}).call(this,(typeof Buffer !== "undefined" ? Buffer : undefined)) +},{}],12:[function(_dereq_,module,exports){ +'use strict'; +var Uint8ArrayReader = _dereq_('./uint8ArrayReader'); + +function NodeBufferReader(data) { + this.data = data; + this.length = this.data.length; + this.index = 0; +} +NodeBufferReader.prototype = new Uint8ArrayReader(); + +/** + * @see DataReader.readData + */ +NodeBufferReader.prototype.readData = function(size) { + this.checkOffset(size); + var result = this.data.slice(this.index, this.index + size); + this.index += size; + return result; +}; +module.exports = NodeBufferReader; + +},{"./uint8ArrayReader":18}],13:[function(_dereq_,module,exports){ +'use strict'; +var support = _dereq_('./support'); +var utils = _dereq_('./utils'); +var crc32 = _dereq_('./crc32'); +var signature = _dereq_('./signature'); +var defaults = _dereq_('./defaults'); +var base64 = _dereq_('./base64'); +var compressions = _dereq_('./compressions'); +var CompressedObject = _dereq_('./compressedObject'); +var nodeBuffer = _dereq_('./nodeBuffer'); +var utf8 = _dereq_('./utf8'); +var StringWriter = _dereq_('./stringWriter'); +var Uint8ArrayWriter = _dereq_('./uint8ArrayWriter'); + +/** + * Returns the raw data of a ZipObject, decompress the content if necessary. + * @param {ZipObject} file the file to use. + * @return {String|ArrayBuffer|Uint8Array|Buffer} the data. + */ +var getRawData = function(file) { + if (file._data instanceof CompressedObject) { + file._data = file._data.getContent(); + file.options.binary = true; + file.options.base64 = false; + + if (utils.getTypeOf(file._data) === "uint8array") { + var copy = file._data; + // when reading an arraybuffer, the CompressedObject mechanism will keep it and subarray() a Uint8Array. + // if we request a file in the same format, we might get the same Uint8Array or its ArrayBuffer (the original zip file). + file._data = new Uint8Array(copy.length); + // with an empty Uint8Array, Opera fails with a "Offset larger than array size" + if (copy.length !== 0) { + file._data.set(copy, 0); + } + } + } + return file._data; +}; + +/** + * Returns the data of a ZipObject in a binary form. If the content is an unicode string, encode it. + * @param {ZipObject} file the file to use. + * @return {String|ArrayBuffer|Uint8Array|Buffer} the data. + */ +var getBinaryData = function(file) { + var result = getRawData(file), + type = utils.getTypeOf(result); + if (type === "string") { + if (!file.options.binary) { + // unicode text ! + // unicode string => binary string is a painful process, check if we can avoid it. + if (support.nodebuffer) { + return nodeBuffer(result, "utf-8"); + } + } + return file.asBinary(); + } + return result; +}; + +/** + * Transform this._data into a string. + * @param {function} filter a function String -> String, applied if not null on the result. + * @return {String} the string representing this._data. + */ +var dataToString = function(asUTF8) { + var result = getRawData(this); + if (result === null || typeof result === "undefined") { + return ""; + } + // if the data is a base64 string, we decode it before checking the encoding ! + if (this.options.base64) { + result = base64.decode(result); + } + if (asUTF8 && this.options.binary) { + // JSZip.prototype.utf8decode supports arrays as input + // skip to array => string step, utf8decode will do it. + result = out.utf8decode(result); + } + else { + // no utf8 transformation, do the array => string step. + result = utils.transformTo("string", result); + } + + if (!asUTF8 && !this.options.binary) { + result = utils.transformTo("string", out.utf8encode(result)); + } + return result; +}; +/** + * A simple object representing a file in the zip file. + * @constructor + * @param {string} name the name of the file + * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data + * @param {Object} options the options of the file + */ +var ZipObject = function(name, data, options) { + this.name = name; + this.dir = options.dir; + this.date = options.date; + this.comment = options.comment; + this.unixPermissions = options.unixPermissions; + this.dosPermissions = options.dosPermissions; + + this._data = data; + this.options = options; + + /* + * This object contains initial values for dir and date. + * With them, we can check if the user changed the deprecated metadata in + * `ZipObject#options` or not. + */ + this._initialMetadata = { + dir : options.dir, + date : options.date + }; +}; + +ZipObject.prototype = { + /** + * Return the content as UTF8 string. + * @return {string} the UTF8 string. + */ + asText: function() { + return dataToString.call(this, true); + }, + /** + * Returns the binary content. + * @return {string} the content as binary. + */ + asBinary: function() { + return dataToString.call(this, false); + }, + /** + * Returns the content as a nodejs Buffer. + * @return {Buffer} the content as a Buffer. + */ + asNodeBuffer: function() { + var result = getBinaryData(this); + return utils.transformTo("nodebuffer", result); + }, + /** + * Returns the content as an Uint8Array. + * @return {Uint8Array} the content as an Uint8Array. + */ + asUint8Array: function() { + var result = getBinaryData(this); + return utils.transformTo("uint8array", result); + }, + /** + * Returns the content as an ArrayBuffer. + * @return {ArrayBuffer} the content as an ArrayBufer. + */ + asArrayBuffer: function() { + return this.asUint8Array().buffer; + } +}; + +/** + * Transform an integer into a string in hexadecimal. + * @private + * @param {number} dec the number to convert. + * @param {number} bytes the number of bytes to generate. + * @returns {string} the result. + */ +var decToHex = function(dec, bytes) { + var hex = "", + i; + for (i = 0; i < bytes; i++) { + hex += String.fromCharCode(dec & 0xff); + dec = dec >>> 8; + } + return hex; +}; + +/** + * Merge the objects passed as parameters into a new one. + * @private + * @param {...Object} var_args All objects to merge. + * @return {Object} a new object with the data of the others. + */ +var extend = function() { + var result = {}, i, attr; + for (i = 0; i < arguments.length; i++) { // arguments is not enumerable in some browsers + for (attr in arguments[i]) { + if (arguments[i].hasOwnProperty(attr) && typeof result[attr] === "undefined") { + result[attr] = arguments[i][attr]; + } + } + } + return result; +}; + +/** + * Transforms the (incomplete) options from the user into the complete + * set of options to create a file. + * @private + * @param {Object} o the options from the user. + * @return {Object} the complete set of options. + */ +var prepareFileAttrs = function(o) { + o = o || {}; + if (o.base64 === true && (o.binary === null || o.binary === undefined)) { + o.binary = true; + } + o = extend(o, defaults); + o.date = o.date || new Date(); + if (o.compression !== null) o.compression = o.compression.toUpperCase(); + + return o; +}; + +/** + * Add a file in the current folder. + * @private + * @param {string} name the name of the file + * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data of the file + * @param {Object} o the options of the file + * @return {Object} the new file. + */ +var fileAdd = function(name, data, o) { + // be sure sub folders exist + var dataType = utils.getTypeOf(data), + parent; + + o = prepareFileAttrs(o); + + if (typeof o.unixPermissions === "string") { + o.unixPermissions = parseInt(o.unixPermissions, 8); + } + + // UNX_IFDIR 0040000 see zipinfo.c + if (o.unixPermissions && (o.unixPermissions & 0x4000)) { + o.dir = true; + } + // Bit 4 Directory + if (o.dosPermissions && (o.dosPermissions & 0x0010)) { + o.dir = true; + } + + if (o.dir) { + name = forceTrailingSlash(name); + } + + if (o.createFolders && (parent = parentFolder(name))) { + folderAdd.call(this, parent, true); + } + + if (o.dir || data === null || typeof data === "undefined") { + o.base64 = false; + o.binary = false; + data = null; + dataType = null; + } + else if (dataType === "string") { + if (o.binary && !o.base64) { + // optimizedBinaryString == true means that the file has already been filtered with a 0xFF mask + if (o.optimizedBinaryString !== true) { + // this is a string, not in a base64 format. + // Be sure that this is a correct "binary string" + data = utils.string2binary(data); + } + } + } + else { // arraybuffer, uint8array, ... + o.base64 = false; + o.binary = true; + + if (!dataType && !(data instanceof CompressedObject)) { + throw new Error("The data of '" + name + "' is in an unsupported format !"); + } + + // special case : it's way easier to work with Uint8Array than with ArrayBuffer + if (dataType === "arraybuffer") { + data = utils.transformTo("uint8array", data); + } + } + + var object = new ZipObject(name, data, o); + this.files[name] = object; + return object; +}; + +/** + * Find the parent folder of the path. + * @private + * @param {string} path the path to use + * @return {string} the parent folder, or "" + */ +var parentFolder = function (path) { + if (path.slice(-1) == '/') { + path = path.substring(0, path.length - 1); + } + var lastSlash = path.lastIndexOf('/'); + return (lastSlash > 0) ? path.substring(0, lastSlash) : ""; +}; + + +/** + * Returns the path with a slash at the end. + * @private + * @param {String} path the path to check. + * @return {String} the path with a trailing slash. + */ +var forceTrailingSlash = function(path) { + // Check the name ends with a / + if (path.slice(-1) != "/") { + path += "/"; // IE doesn't like substr(-1) + } + return path; +}; +/** + * Add a (sub) folder in the current folder. + * @private + * @param {string} name the folder's name + * @param {boolean=} [createFolders] If true, automatically create sub + * folders. Defaults to false. + * @return {Object} the new folder. + */ +var folderAdd = function(name, createFolders) { + createFolders = (typeof createFolders !== 'undefined') ? createFolders : false; + + name = forceTrailingSlash(name); + + // Does this folder already exist? + if (!this.files[name]) { + fileAdd.call(this, name, null, { + dir: true, + createFolders: createFolders + }); + } + return this.files[name]; +}; + +/** + * Generate a JSZip.CompressedObject for a given zipOject. + * @param {ZipObject} file the object to read. + * @param {JSZip.compression} compression the compression to use. + * @param {Object} compressionOptions the options to use when compressing. + * @return {JSZip.CompressedObject} the compressed result. + */ +var generateCompressedObjectFrom = function(file, compression, compressionOptions) { + var result = new CompressedObject(), + content; + + // the data has not been decompressed, we might reuse things ! + if (file._data instanceof CompressedObject) { + result.uncompressedSize = file._data.uncompressedSize; + result.crc32 = file._data.crc32; + + if (result.uncompressedSize === 0 || file.dir) { + compression = compressions['STORE']; + result.compressedContent = ""; + result.crc32 = 0; + } + else if (file._data.compressionMethod === compression.magic) { + result.compressedContent = file._data.getCompressedContent(); + } + else { + content = file._data.getContent(); + // need to decompress / recompress + result.compressedContent = compression.compress(utils.transformTo(compression.compressInputType, content), compressionOptions); + } + } + else { + // have uncompressed data + content = getBinaryData(file); + if (!content || content.length === 0 || file.dir) { + compression = compressions['STORE']; + content = ""; + } + result.uncompressedSize = content.length; + result.crc32 = crc32(content); + result.compressedContent = compression.compress(utils.transformTo(compression.compressInputType, content), compressionOptions); + } + + result.compressedSize = result.compressedContent.length; + result.compressionMethod = compression.magic; + + return result; +}; + + + + +/** + * Generate the UNIX part of the external file attributes. + * @param {Object} unixPermissions the unix permissions or null. + * @param {Boolean} isDir true if the entry is a directory, false otherwise. + * @return {Number} a 32 bit integer. + * + * adapted from http://unix.stackexchange.com/questions/14705/the-zip-formats-external-file-attribute : + * + * TTTTsstrwxrwxrwx0000000000ADVSHR + * ^^^^____________________________ file type, see zipinfo.c (UNX_*) + * ^^^_________________________ setuid, setgid, sticky + * ^^^^^^^^^________________ permissions + * ^^^^^^^^^^______ not used ? + * ^^^^^^ DOS attribute bits : Archive, Directory, Volume label, System file, Hidden, Read only + */ +var generateUnixExternalFileAttr = function (unixPermissions, isDir) { + + var result = unixPermissions; + if (!unixPermissions) { + // I can't use octal values in strict mode, hence the hexa. + // 040775 => 0x41fd + // 0100664 => 0x81b4 + result = isDir ? 0x41fd : 0x81b4; + } + + return (result & 0xFFFF) << 16; +}; + +/** + * Generate the DOS part of the external file attributes. + * @param {Object} dosPermissions the dos permissions or null. + * @param {Boolean} isDir true if the entry is a directory, false otherwise. + * @return {Number} a 32 bit integer. + * + * Bit 0 Read-Only + * Bit 1 Hidden + * Bit 2 System + * Bit 3 Volume Label + * Bit 4 Directory + * Bit 5 Archive + */ +var generateDosExternalFileAttr = function (dosPermissions, isDir) { + + // the dir flag is already set for compatibility + + return (dosPermissions || 0) & 0x3F; +}; + +/** + * Generate the various parts used in the construction of the final zip file. + * @param {string} name the file name. + * @param {ZipObject} file the file content. + * @param {JSZip.CompressedObject} compressedObject the compressed object. + * @param {number} offset the current offset from the start of the zip file. + * @param {String} platform let's pretend we are this platform (change platform dependents fields) + * @return {object} the zip parts. + */ +var generateZipParts = function(name, file, compressedObject, offset, platform) { + var data = compressedObject.compressedContent, + utfEncodedFileName = utils.transformTo("string", utf8.utf8encode(file.name)), + comment = file.comment || "", + utfEncodedComment = utils.transformTo("string", utf8.utf8encode(comment)), + useUTF8ForFileName = utfEncodedFileName.length !== file.name.length, + useUTF8ForComment = utfEncodedComment.length !== comment.length, + o = file.options, + dosTime, + dosDate, + extraFields = "", + unicodePathExtraField = "", + unicodeCommentExtraField = "", + dir, date; + + + // handle the deprecated options.dir + if (file._initialMetadata.dir !== file.dir) { + dir = file.dir; + } else { + dir = o.dir; + } + + // handle the deprecated options.date + if(file._initialMetadata.date !== file.date) { + date = file.date; + } else { + date = o.date; + } + + var extFileAttr = 0; + var versionMadeBy = 0; + if (dir) { + // dos or unix, we set the dos dir flag + extFileAttr |= 0x00010; + } + if(platform === "UNIX") { + versionMadeBy = 0x031E; // UNIX, version 3.0 + extFileAttr |= generateUnixExternalFileAttr(file.unixPermissions, dir); + } else { // DOS or other, fallback to DOS + versionMadeBy = 0x0014; // DOS, version 2.0 + extFileAttr |= generateDosExternalFileAttr(file.dosPermissions, dir); + } + + // date + // @see http://www.delorie.com/djgpp/doc/rbinter/it/52/13.html + // @see http://www.delorie.com/djgpp/doc/rbinter/it/65/16.html + // @see http://www.delorie.com/djgpp/doc/rbinter/it/66/16.html + + dosTime = date.getHours(); + dosTime = dosTime << 6; + dosTime = dosTime | date.getMinutes(); + dosTime = dosTime << 5; + dosTime = dosTime | date.getSeconds() / 2; + + dosDate = date.getFullYear() - 1980; + dosDate = dosDate << 4; + dosDate = dosDate | (date.getMonth() + 1); + dosDate = dosDate << 5; + dosDate = dosDate | date.getDate(); + + if (useUTF8ForFileName) { + // set the unicode path extra field. unzip needs at least one extra + // field to correctly handle unicode path, so using the path is as good + // as any other information. This could improve the situation with + // other archive managers too. + // This field is usually used without the utf8 flag, with a non + // unicode path in the header (winrar, winzip). This helps (a bit) + // with the messy Windows' default compressed folders feature but + // breaks on p7zip which doesn't seek the unicode path extra field. + // So for now, UTF-8 everywhere ! + unicodePathExtraField = + // Version + decToHex(1, 1) + + // NameCRC32 + decToHex(crc32(utfEncodedFileName), 4) + + // UnicodeName + utfEncodedFileName; + + extraFields += + // Info-ZIP Unicode Path Extra Field + "\x75\x70" + + // size + decToHex(unicodePathExtraField.length, 2) + + // content + unicodePathExtraField; + } + + if(useUTF8ForComment) { + + unicodeCommentExtraField = + // Version + decToHex(1, 1) + + // CommentCRC32 + decToHex(this.crc32(utfEncodedComment), 4) + + // UnicodeName + utfEncodedComment; + + extraFields += + // Info-ZIP Unicode Path Extra Field + "\x75\x63" + + // size + decToHex(unicodeCommentExtraField.length, 2) + + // content + unicodeCommentExtraField; + } + + var header = ""; + + // version needed to extract + header += "\x0A\x00"; + // general purpose bit flag + // set bit 11 if utf8 + header += (useUTF8ForFileName || useUTF8ForComment) ? "\x00\x08" : "\x00\x00"; + // compression method + header += compressedObject.compressionMethod; + // last mod file time + header += decToHex(dosTime, 2); + // last mod file date + header += decToHex(dosDate, 2); + // crc-32 + header += decToHex(compressedObject.crc32, 4); + // compressed size + header += decToHex(compressedObject.compressedSize, 4); + // uncompressed size + header += decToHex(compressedObject.uncompressedSize, 4); + // file name length + header += decToHex(utfEncodedFileName.length, 2); + // extra field length + header += decToHex(extraFields.length, 2); + + + var fileRecord = signature.LOCAL_FILE_HEADER + header + utfEncodedFileName + extraFields; + + var dirRecord = signature.CENTRAL_FILE_HEADER + + // version made by (00: DOS) + decToHex(versionMadeBy, 2) + + // file header (common to file and central directory) + header + + // file comment length + decToHex(utfEncodedComment.length, 2) + + // disk number start + "\x00\x00" + + // internal file attributes TODO + "\x00\x00" + + // external file attributes + decToHex(extFileAttr, 4) + + // relative offset of local header + decToHex(offset, 4) + + // file name + utfEncodedFileName + + // extra field + extraFields + + // file comment + utfEncodedComment; + + return { + fileRecord: fileRecord, + dirRecord: dirRecord, + compressedObject: compressedObject + }; +}; + + +// return the actual prototype of JSZip +var out = { + /** + * Read an existing zip and merge the data in the current JSZip object. + * The implementation is in jszip-load.js, don't forget to include it. + * @param {String|ArrayBuffer|Uint8Array|Buffer} stream The stream to load + * @param {Object} options Options for loading the stream. + * options.base64 : is the stream in base64 ? default : false + * @return {JSZip} the current JSZip object + */ + load: function(stream, options) { + throw new Error("Load method is not defined. Is the file jszip-load.js included ?"); + }, + + /** + * Filter nested files/folders with the specified function. + * @param {Function} search the predicate to use : + * function (relativePath, file) {...} + * It takes 2 arguments : the relative path and the file. + * @return {Array} An array of matching elements. + */ + filter: function(search) { + var result = [], + filename, relativePath, file, fileClone; + for (filename in this.files) { + if (!this.files.hasOwnProperty(filename)) { + continue; + } + file = this.files[filename]; + // return a new object, don't let the user mess with our internal objects :) + fileClone = new ZipObject(file.name, file._data, extend(file.options)); + relativePath = filename.slice(this.root.length, filename.length); + if (filename.slice(0, this.root.length) === this.root && // the file is in the current root + search(relativePath, fileClone)) { // and the file matches the function + result.push(fileClone); + } + } + return result; + }, + + /** + * Add a file to the zip file, or search a file. + * @param {string|RegExp} name The name of the file to add (if data is defined), + * the name of the file to find (if no data) or a regex to match files. + * @param {String|ArrayBuffer|Uint8Array|Buffer} data The file data, either raw or base64 encoded + * @param {Object} o File options + * @return {JSZip|Object|Array} this JSZip object (when adding a file), + * a file (when searching by string) or an array of files (when searching by regex). + */ + file: function(name, data, o) { + if (arguments.length === 1) { + if (utils.isRegExp(name)) { + var regexp = name; + return this.filter(function(relativePath, file) { + return !file.dir && regexp.test(relativePath); + }); + } + else { // text + return this.filter(function(relativePath, file) { + return !file.dir && relativePath === name; + })[0] || null; + } + } + else { // more than one argument : we have data ! + name = this.root + name; + fileAdd.call(this, name, data, o); + } + return this; + }, + + /** + * Add a directory to the zip file, or search. + * @param {String|RegExp} arg The name of the directory to add, or a regex to search folders. + * @return {JSZip} an object with the new directory as the root, or an array containing matching folders. + */ + folder: function(arg) { + if (!arg) { + return this; + } + + if (utils.isRegExp(arg)) { + return this.filter(function(relativePath, file) { + return file.dir && arg.test(relativePath); + }); + } + + // else, name is a new folder + var name = this.root + arg; + var newFolder = folderAdd.call(this, name); + + // Allow chaining by returning a new object with this folder as the root + var ret = this.clone(); + ret.root = newFolder.name; + return ret; + }, + + /** + * Delete a file, or a directory and all sub-files, from the zip + * @param {string} name the name of the file to delete + * @return {JSZip} this JSZip object + */ + remove: function(name) { + name = this.root + name; + var file = this.files[name]; + if (!file) { + // Look for any folders + if (name.slice(-1) != "/") { + name += "/"; + } + file = this.files[name]; + } + + if (file && !file.dir) { + // file + delete this.files[name]; + } else { + // maybe a folder, delete recursively + var kids = this.filter(function(relativePath, file) { + return file.name.slice(0, name.length) === name; + }); + for (var i = 0; i < kids.length; i++) { + delete this.files[kids[i].name]; + } + } + + return this; + }, + + /** + * Generate the complete zip file + * @param {Object} options the options to generate the zip file : + * - base64, (deprecated, use type instead) true to generate base64. + * - compression, "STORE" by default. + * - type, "base64" by default. Values are : string, base64, uint8array, arraybuffer, blob. + * @return {String|Uint8Array|ArrayBuffer|Buffer|Blob} the zip file + */ + generate: function(options) { + options = extend(options || {}, { + base64: true, + compression: "STORE", + compressionOptions : null, + type: "base64", + platform: "DOS", + comment: null, + mimeType: 'application/zip' + }); + + utils.checkSupport(options.type); + + // accept nodejs `process.platform` + if( + options.platform === 'darwin' || + options.platform === 'freebsd' || + options.platform === 'linux' || + options.platform === 'sunos' + ) { + options.platform = "UNIX"; + } + if (options.platform === 'win32') { + options.platform = "DOS"; + } + + var zipData = [], + localDirLength = 0, + centralDirLength = 0, + writer, i, + utfEncodedComment = utils.transformTo("string", this.utf8encode(options.comment || this.comment || "")); + + // first, generate all the zip parts. + for (var name in this.files) { + if (!this.files.hasOwnProperty(name)) { + continue; + } + var file = this.files[name]; + + var compressionName = file.options.compression || options.compression.toUpperCase(); + var compression = compressions[compressionName]; + if (!compression) { + throw new Error(compressionName + " is not a valid compression method !"); + } + var compressionOptions = file.options.compressionOptions || options.compressionOptions || {}; + + var compressedObject = generateCompressedObjectFrom.call(this, file, compression, compressionOptions); + + var zipPart = generateZipParts.call(this, name, file, compressedObject, localDirLength, options.platform); + localDirLength += zipPart.fileRecord.length + compressedObject.compressedSize; + centralDirLength += zipPart.dirRecord.length; + zipData.push(zipPart); + } + + var dirEnd = ""; + + // end of central dir signature + dirEnd = signature.CENTRAL_DIRECTORY_END + + // number of this disk + "\x00\x00" + + // number of the disk with the start of the central directory + "\x00\x00" + + // total number of entries in the central directory on this disk + decToHex(zipData.length, 2) + + // total number of entries in the central directory + decToHex(zipData.length, 2) + + // size of the central directory 4 bytes + decToHex(centralDirLength, 4) + + // offset of start of central directory with respect to the starting disk number + decToHex(localDirLength, 4) + + // .ZIP file comment length + decToHex(utfEncodedComment.length, 2) + + // .ZIP file comment + utfEncodedComment; + + + // we have all the parts (and the total length) + // time to create a writer ! + var typeName = options.type.toLowerCase(); + if(typeName==="uint8array"||typeName==="arraybuffer"||typeName==="blob"||typeName==="nodebuffer") { + writer = new Uint8ArrayWriter(localDirLength + centralDirLength + dirEnd.length); + }else{ + writer = new StringWriter(localDirLength + centralDirLength + dirEnd.length); + } + + for (i = 0; i < zipData.length; i++) { + writer.append(zipData[i].fileRecord); + writer.append(zipData[i].compressedObject.compressedContent); + } + for (i = 0; i < zipData.length; i++) { + writer.append(zipData[i].dirRecord); + } + + writer.append(dirEnd); + + var zip = writer.finalize(); + + + + switch(options.type.toLowerCase()) { + // case "zip is an Uint8Array" + case "uint8array" : + case "arraybuffer" : + case "nodebuffer" : + return utils.transformTo(options.type.toLowerCase(), zip); + case "blob" : + return utils.arrayBuffer2Blob(utils.transformTo("arraybuffer", zip), options.mimeType); + // case "zip is a string" + case "base64" : + return (options.base64) ? base64.encode(zip) : zip; + default : // case "string" : + return zip; + } + + }, + + /** + * @deprecated + * This method will be removed in a future version without replacement. + */ + crc32: function (input, crc) { + return crc32(input, crc); + }, + + /** + * @deprecated + * This method will be removed in a future version without replacement. + */ + utf8encode: function (string) { + return utils.transformTo("string", utf8.utf8encode(string)); + }, + + /** + * @deprecated + * This method will be removed in a future version without replacement. + */ + utf8decode: function (input) { + return utf8.utf8decode(input); + } +}; +module.exports = out; + +},{"./base64":1,"./compressedObject":2,"./compressions":3,"./crc32":4,"./defaults":6,"./nodeBuffer":11,"./signature":14,"./stringWriter":16,"./support":17,"./uint8ArrayWriter":19,"./utf8":20,"./utils":21}],14:[function(_dereq_,module,exports){ +'use strict'; +exports.LOCAL_FILE_HEADER = "PK\x03\x04"; +exports.CENTRAL_FILE_HEADER = "PK\x01\x02"; +exports.CENTRAL_DIRECTORY_END = "PK\x05\x06"; +exports.ZIP64_CENTRAL_DIRECTORY_LOCATOR = "PK\x06\x07"; +exports.ZIP64_CENTRAL_DIRECTORY_END = "PK\x06\x06"; +exports.DATA_DESCRIPTOR = "PK\x07\x08"; + +},{}],15:[function(_dereq_,module,exports){ +'use strict'; +var DataReader = _dereq_('./dataReader'); +var utils = _dereq_('./utils'); + +function StringReader(data, optimizedBinaryString) { + this.data = data; + if (!optimizedBinaryString) { + this.data = utils.string2binary(this.data); + } + this.length = this.data.length; + this.index = 0; +} +StringReader.prototype = new DataReader(); +/** + * @see DataReader.byteAt + */ +StringReader.prototype.byteAt = function(i) { + return this.data.charCodeAt(i); +}; +/** + * @see DataReader.lastIndexOfSignature + */ +StringReader.prototype.lastIndexOfSignature = function(sig) { + return this.data.lastIndexOf(sig); +}; +/** + * @see DataReader.readData + */ +StringReader.prototype.readData = function(size) { + this.checkOffset(size); + // this will work because the constructor applied the "& 0xff" mask. + var result = this.data.slice(this.index, this.index + size); + this.index += size; + return result; +}; +module.exports = StringReader; + +},{"./dataReader":5,"./utils":21}],16:[function(_dereq_,module,exports){ +'use strict'; + +var utils = _dereq_('./utils'); + +/** + * An object to write any content to a string. + * @constructor + */ +var StringWriter = function() { + this.data = []; +}; +StringWriter.prototype = { + /** + * Append any content to the current string. + * @param {Object} input the content to add. + */ + append: function(input) { + input = utils.transformTo("string", input); + this.data.push(input); + }, + /** + * Finalize the construction an return the result. + * @return {string} the generated string. + */ + finalize: function() { + return this.data.join(""); + } +}; + +module.exports = StringWriter; + +},{"./utils":21}],17:[function(_dereq_,module,exports){ +(function (Buffer){ +'use strict'; +exports.base64 = true; +exports.array = true; +exports.string = true; +exports.arraybuffer = typeof ArrayBuffer !== "undefined" && typeof Uint8Array !== "undefined"; +// contains true if JSZip can read/generate nodejs Buffer, false otherwise. +// Browserify will provide a Buffer implementation for browsers, which is +// an augmented Uint8Array (i.e., can be used as either Buffer or U8). +exports.nodebuffer = typeof Buffer !== "undefined"; +// contains true if JSZip can read/generate Uint8Array, false otherwise. +exports.uint8array = typeof Uint8Array !== "undefined"; + +if (typeof ArrayBuffer === "undefined") { + exports.blob = false; +} +else { + var buffer = new ArrayBuffer(0); + try { + exports.blob = new Blob([buffer], { + type: "application/zip" + }).size === 0; + } + catch (e) { + try { + var Builder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder; + var builder = new Builder(); + builder.append(buffer); + exports.blob = builder.getBlob('application/zip').size === 0; + } + catch (e) { + exports.blob = false; + } + } +} + +}).call(this,(typeof Buffer !== "undefined" ? Buffer : undefined)) +},{}],18:[function(_dereq_,module,exports){ +'use strict'; +var DataReader = _dereq_('./dataReader'); + +function Uint8ArrayReader(data) { + if (data) { + this.data = data; + this.length = this.data.length; + this.index = 0; + } +} +Uint8ArrayReader.prototype = new DataReader(); +/** + * @see DataReader.byteAt + */ +Uint8ArrayReader.prototype.byteAt = function(i) { + return this.data[i]; +}; +/** + * @see DataReader.lastIndexOfSignature + */ +Uint8ArrayReader.prototype.lastIndexOfSignature = function(sig) { + var sig0 = sig.charCodeAt(0), + sig1 = sig.charCodeAt(1), + sig2 = sig.charCodeAt(2), + sig3 = sig.charCodeAt(3); + for (var i = this.length - 4; i >= 0; --i) { + if (this.data[i] === sig0 && this.data[i + 1] === sig1 && this.data[i + 2] === sig2 && this.data[i + 3] === sig3) { + return i; + } + } + + return -1; +}; +/** + * @see DataReader.readData + */ +Uint8ArrayReader.prototype.readData = function(size) { + this.checkOffset(size); + if(size === 0) { + // in IE10, when using subarray(idx, idx), we get the array [0x00] instead of []. + return new Uint8Array(0); + } + var result = this.data.subarray(this.index, this.index + size); + this.index += size; + return result; +}; +module.exports = Uint8ArrayReader; + +},{"./dataReader":5}],19:[function(_dereq_,module,exports){ +'use strict'; + +var utils = _dereq_('./utils'); + +/** + * An object to write any content to an Uint8Array. + * @constructor + * @param {number} length The length of the array. + */ +var Uint8ArrayWriter = function(length) { + this.data = new Uint8Array(length); + this.index = 0; +}; +Uint8ArrayWriter.prototype = { + /** + * Append any content to the current array. + * @param {Object} input the content to add. + */ + append: function(input) { + if (input.length !== 0) { + // with an empty Uint8Array, Opera fails with a "Offset larger than array size" + input = utils.transformTo("uint8array", input); + this.data.set(input, this.index); + this.index += input.length; + } + }, + /** + * Finalize the construction an return the result. + * @return {Uint8Array} the generated array. + */ + finalize: function() { + return this.data; + } +}; + +module.exports = Uint8ArrayWriter; + +},{"./utils":21}],20:[function(_dereq_,module,exports){ +'use strict'; + +var utils = _dereq_('./utils'); +var support = _dereq_('./support'); +var nodeBuffer = _dereq_('./nodeBuffer'); + +/** + * The following functions come from pako, from pako/lib/utils/strings + * released under the MIT license, see pako https://github.com/nodeca/pako/ + */ + +// Table with utf8 lengths (calculated by first byte of sequence) +// Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS, +// because max possible codepoint is 0x10ffff +var _utf8len = new Array(256); +for (var i=0; i<256; i++) { + _utf8len[i] = (i >= 252 ? 6 : i >= 248 ? 5 : i >= 240 ? 4 : i >= 224 ? 3 : i >= 192 ? 2 : 1); +} +_utf8len[254]=_utf8len[254]=1; // Invalid sequence start + +// convert string to array (typed, when possible) +var string2buf = function (str) { + var buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0; + + // count binary size + for (m_pos = 0; m_pos < str_len; m_pos++) { + c = str.charCodeAt(m_pos); + if ((c & 0xfc00) === 0xd800 && (m_pos+1 < str_len)) { + c2 = str.charCodeAt(m_pos+1); + if ((c2 & 0xfc00) === 0xdc00) { + c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); + m_pos++; + } + } + buf_len += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4; + } + + // allocate buffer + if (support.uint8array) { + buf = new Uint8Array(buf_len); + } else { + buf = new Array(buf_len); + } + + // convert + for (i=0, m_pos = 0; i < buf_len; m_pos++) { + c = str.charCodeAt(m_pos); + if ((c & 0xfc00) === 0xd800 && (m_pos+1 < str_len)) { + c2 = str.charCodeAt(m_pos+1); + if ((c2 & 0xfc00) === 0xdc00) { + c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); + m_pos++; + } + } + if (c < 0x80) { + /* one byte */ + buf[i++] = c; + } else if (c < 0x800) { + /* two bytes */ + buf[i++] = 0xC0 | (c >>> 6); + buf[i++] = 0x80 | (c & 0x3f); + } else if (c < 0x10000) { + /* three bytes */ + buf[i++] = 0xE0 | (c >>> 12); + buf[i++] = 0x80 | (c >>> 6 & 0x3f); + buf[i++] = 0x80 | (c & 0x3f); + } else { + /* four bytes */ + buf[i++] = 0xf0 | (c >>> 18); + buf[i++] = 0x80 | (c >>> 12 & 0x3f); + buf[i++] = 0x80 | (c >>> 6 & 0x3f); + buf[i++] = 0x80 | (c & 0x3f); + } + } + + return buf; +}; + +// Calculate max possible position in utf8 buffer, +// that will not break sequence. If that's not possible +// - (very small limits) return max size as is. +// +// buf[] - utf8 bytes array +// max - length limit (mandatory); +var utf8border = function(buf, max) { + var pos; + + max = max || buf.length; + if (max > buf.length) { max = buf.length; } + + // go back from last position, until start of sequence found + pos = max-1; + while (pos >= 0 && (buf[pos] & 0xC0) === 0x80) { pos--; } + + // Fuckup - very small and broken sequence, + // return max, because we should return something anyway. + if (pos < 0) { return max; } + + // If we came to start of buffer - that means vuffer is too small, + // return max too. + if (pos === 0) { return max; } + + return (pos + _utf8len[buf[pos]] > max) ? pos : max; +}; + +// convert array to string +var buf2string = function (buf) { + var str, i, out, c, c_len; + var len = buf.length; + + // Reserve max possible length (2 words per char) + // NB: by unknown reasons, Array is significantly faster for + // String.fromCharCode.apply than Uint16Array. + var utf16buf = new Array(len*2); + + for (out=0, i=0; i 4) { utf16buf[out++] = 0xfffd; i += c_len-1; continue; } + + // apply mask on first byte + c &= c_len === 2 ? 0x1f : c_len === 3 ? 0x0f : 0x07; + // join the rest + while (c_len > 1 && i < len) { + c = (c << 6) | (buf[i++] & 0x3f); + c_len--; + } + + // terminated by end of string? + if (c_len > 1) { utf16buf[out++] = 0xfffd; continue; } + + if (c < 0x10000) { + utf16buf[out++] = c; + } else { + c -= 0x10000; + utf16buf[out++] = 0xd800 | ((c >> 10) & 0x3ff); + utf16buf[out++] = 0xdc00 | (c & 0x3ff); + } + } + + // shrinkBuf(utf16buf, out) + if (utf16buf.length !== out) { + if(utf16buf.subarray) { + utf16buf = utf16buf.subarray(0, out); + } else { + utf16buf.length = out; + } + } + + // return String.fromCharCode.apply(null, utf16buf); + return utils.applyFromCharCode(utf16buf); +}; + + +// That's all for the pako functions. + + +/** + * Transform a javascript string into an array (typed if possible) of bytes, + * UTF-8 encoded. + * @param {String} str the string to encode + * @return {Array|Uint8Array|Buffer} the UTF-8 encoded string. + */ +exports.utf8encode = function utf8encode(str) { + if (support.nodebuffer) { + return nodeBuffer(str, "utf-8"); + } + + return string2buf(str); +}; + + +/** + * Transform a bytes array (or a representation) representing an UTF-8 encoded + * string into a javascript string. + * @param {Array|Uint8Array|Buffer} buf the data de decode + * @return {String} the decoded string. + */ +exports.utf8decode = function utf8decode(buf) { + if (support.nodebuffer) { + return utils.transformTo("nodebuffer", buf).toString("utf-8"); + } + + buf = utils.transformTo(support.uint8array ? "uint8array" : "array", buf); + + // return buf2string(buf); + // Chrome prefers to work with "small" chunks of data + // for the method buf2string. + // Firefox and Chrome has their own shortcut, IE doesn't seem to really care. + var result = [], k = 0, len = buf.length, chunk = 65536; + while (k < len) { + var nextBoundary = utf8border(buf, Math.min(k + chunk, len)); + if (support.uint8array) { + result.push(buf2string(buf.subarray(k, nextBoundary))); + } else { + result.push(buf2string(buf.slice(k, nextBoundary))); + } + k = nextBoundary; + } + return result.join(""); + +}; +// vim: set shiftwidth=4 softtabstop=4: + +},{"./nodeBuffer":11,"./support":17,"./utils":21}],21:[function(_dereq_,module,exports){ +'use strict'; +var support = _dereq_('./support'); +var compressions = _dereq_('./compressions'); +var nodeBuffer = _dereq_('./nodeBuffer'); +/** + * Convert a string to a "binary string" : a string containing only char codes between 0 and 255. + * @param {string} str the string to transform. + * @return {String} the binary string. + */ +exports.string2binary = function(str) { + var result = ""; + for (var i = 0; i < str.length; i++) { + result += String.fromCharCode(str.charCodeAt(i) & 0xff); + } + return result; +}; +exports.arrayBuffer2Blob = function(buffer, mimeType) { + exports.checkSupport("blob"); + mimeType = mimeType || 'application/zip'; + + try { + // Blob constructor + return new Blob([buffer], { + type: mimeType + }); + } + catch (e) { + + try { + // deprecated, browser only, old way + var Builder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder; + var builder = new Builder(); + builder.append(buffer); + return builder.getBlob(mimeType); + } + catch (e) { + + // well, fuck ?! + throw new Error("Bug : can't construct the Blob."); + } + } + + +}; +/** + * The identity function. + * @param {Object} input the input. + * @return {Object} the same input. + */ +function identity(input) { + return input; +} + +/** + * Fill in an array with a string. + * @param {String} str the string to use. + * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to fill in (will be mutated). + * @return {Array|ArrayBuffer|Uint8Array|Buffer} the updated array. + */ +function stringToArrayLike(str, array) { + for (var i = 0; i < str.length; ++i) { + array[i] = str.charCodeAt(i) & 0xFF; + } + return array; +} + +/** + * Transform an array-like object to a string. + * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to transform. + * @return {String} the result. + */ +function arrayLikeToString(array) { + // Performances notes : + // -------------------- + // String.fromCharCode.apply(null, array) is the fastest, see + // see http://jsperf.com/converting-a-uint8array-to-a-string/2 + // but the stack is limited (and we can get huge arrays !). + // + // result += String.fromCharCode(array[i]); generate too many strings ! + // + // This code is inspired by http://jsperf.com/arraybuffer-to-string-apply-performance/2 + var chunk = 65536; + var result = [], + len = array.length, + type = exports.getTypeOf(array), + k = 0, + canUseApply = true; + try { + switch(type) { + case "uint8array": + String.fromCharCode.apply(null, new Uint8Array(0)); + break; + case "nodebuffer": + String.fromCharCode.apply(null, nodeBuffer(0)); + break; + } + } catch(e) { + canUseApply = false; + } + + // no apply : slow and painful algorithm + // default browser on android 4.* + if (!canUseApply) { + var resultStr = ""; + for(var i = 0; i < array.length;i++) { + resultStr += String.fromCharCode(array[i]); + } + return resultStr; + } + while (k < len && chunk > 1) { + try { + if (type === "array" || type === "nodebuffer") { + result.push(String.fromCharCode.apply(null, array.slice(k, Math.min(k + chunk, len)))); + } + else { + result.push(String.fromCharCode.apply(null, array.subarray(k, Math.min(k + chunk, len)))); + } + k += chunk; + } + catch (e) { + chunk = Math.floor(chunk / 2); + } + } + return result.join(""); +} + +exports.applyFromCharCode = arrayLikeToString; + + +/** + * Copy the data from an array-like to an other array-like. + * @param {Array|ArrayBuffer|Uint8Array|Buffer} arrayFrom the origin array. + * @param {Array|ArrayBuffer|Uint8Array|Buffer} arrayTo the destination array which will be mutated. + * @return {Array|ArrayBuffer|Uint8Array|Buffer} the updated destination array. + */ +function arrayLikeToArrayLike(arrayFrom, arrayTo) { + for (var i = 0; i < arrayFrom.length; i++) { + arrayTo[i] = arrayFrom[i]; + } + return arrayTo; +} + +// a matrix containing functions to transform everything into everything. +var transform = {}; + +// string to ? +transform["string"] = { + "string": identity, + "array": function(input) { + return stringToArrayLike(input, new Array(input.length)); + }, + "arraybuffer": function(input) { + return transform["string"]["uint8array"](input).buffer; + }, + "uint8array": function(input) { + return stringToArrayLike(input, new Uint8Array(input.length)); + }, + "nodebuffer": function(input) { + return stringToArrayLike(input, nodeBuffer(input.length)); + } +}; + +// array to ? +transform["array"] = { + "string": arrayLikeToString, + "array": identity, + "arraybuffer": function(input) { + return (new Uint8Array(input)).buffer; + }, + "uint8array": function(input) { + return new Uint8Array(input); + }, + "nodebuffer": function(input) { + return nodeBuffer(input); + } +}; + +// arraybuffer to ? +transform["arraybuffer"] = { + "string": function(input) { + return arrayLikeToString(new Uint8Array(input)); + }, + "array": function(input) { + return arrayLikeToArrayLike(new Uint8Array(input), new Array(input.byteLength)); + }, + "arraybuffer": identity, + "uint8array": function(input) { + return new Uint8Array(input); + }, + "nodebuffer": function(input) { + return nodeBuffer(new Uint8Array(input)); + } +}; + +// uint8array to ? +transform["uint8array"] = { + "string": arrayLikeToString, + "array": function(input) { + return arrayLikeToArrayLike(input, new Array(input.length)); + }, + "arraybuffer": function(input) { + return input.buffer; + }, + "uint8array": identity, + "nodebuffer": function(input) { + return nodeBuffer(input); + } +}; + +// nodebuffer to ? +transform["nodebuffer"] = { + "string": arrayLikeToString, + "array": function(input) { + return arrayLikeToArrayLike(input, new Array(input.length)); + }, + "arraybuffer": function(input) { + return transform["nodebuffer"]["uint8array"](input).buffer; + }, + "uint8array": function(input) { + return arrayLikeToArrayLike(input, new Uint8Array(input.length)); + }, + "nodebuffer": identity +}; + +/** + * Transform an input into any type. + * The supported output type are : string, array, uint8array, arraybuffer, nodebuffer. + * If no output type is specified, the unmodified input will be returned. + * @param {String} outputType the output type. + * @param {String|Array|ArrayBuffer|Uint8Array|Buffer} input the input to convert. + * @throws {Error} an Error if the browser doesn't support the requested output type. + */ +exports.transformTo = function(outputType, input) { + if (!input) { + // undefined, null, etc + // an empty string won't harm. + input = ""; + } + if (!outputType) { + return input; + } + exports.checkSupport(outputType); + var inputType = exports.getTypeOf(input); + var result = transform[inputType][outputType](input); + return result; +}; + +/** + * Return the type of the input. + * The type will be in a format valid for JSZip.utils.transformTo : string, array, uint8array, arraybuffer. + * @param {Object} input the input to identify. + * @return {String} the (lowercase) type of the input. + */ +exports.getTypeOf = function(input) { + if (typeof input === "string") { + return "string"; + } + if (Object.prototype.toString.call(input) === "[object Array]") { + return "array"; + } + if (support.nodebuffer && nodeBuffer.test(input)) { + return "nodebuffer"; + } + if (support.uint8array && input instanceof Uint8Array) { + return "uint8array"; + } + if (support.arraybuffer && input instanceof ArrayBuffer) { + return "arraybuffer"; + } +}; + +/** + * Throw an exception if the type is not supported. + * @param {String} type the type to check. + * @throws {Error} an Error if the browser doesn't support the requested type. + */ +exports.checkSupport = function(type) { + var supported = support[type.toLowerCase()]; + if (!supported) { + throw new Error(type + " is not supported by this browser"); + } +}; +exports.MAX_VALUE_16BITS = 65535; +exports.MAX_VALUE_32BITS = -1; // well, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" is parsed as -1 + +/** + * Prettify a string read as binary. + * @param {string} str the string to prettify. + * @return {string} a pretty string. + */ +exports.pretty = function(str) { + var res = '', + code, i; + for (i = 0; i < (str || "").length; i++) { + code = str.charCodeAt(i); + res += '\\x' + (code < 16 ? "0" : "") + code.toString(16).toUpperCase(); + } + return res; +}; + +/** + * Find a compression registered in JSZip. + * @param {string} compressionMethod the method magic to find. + * @return {Object|null} the JSZip compression object, null if none found. + */ +exports.findCompression = function(compressionMethod) { + for (var method in compressions) { + if (!compressions.hasOwnProperty(method)) { + continue; + } + if (compressions[method].magic === compressionMethod) { + return compressions[method]; + } + } + return null; +}; +/** +* Cross-window, cross-Node-context regular expression detection +* @param {Object} object Anything +* @return {Boolean} true if the object is a regular expression, +* false otherwise +*/ +exports.isRegExp = function (object) { + return Object.prototype.toString.call(object) === "[object RegExp]"; +}; + + +},{"./compressions":3,"./nodeBuffer":11,"./support":17}],22:[function(_dereq_,module,exports){ +'use strict'; +var StringReader = _dereq_('./stringReader'); +var NodeBufferReader = _dereq_('./nodeBufferReader'); +var Uint8ArrayReader = _dereq_('./uint8ArrayReader'); +var utils = _dereq_('./utils'); +var sig = _dereq_('./signature'); +var ZipEntry = _dereq_('./zipEntry'); +var support = _dereq_('./support'); +var jszipProto = _dereq_('./object'); +// class ZipEntries {{{ +/** + * All the entries in the zip file. + * @constructor + * @param {String|ArrayBuffer|Uint8Array} data the binary stream to load. + * @param {Object} loadOptions Options for loading the stream. + */ +function ZipEntries(data, loadOptions) { + this.files = []; + this.loadOptions = loadOptions; + if (data) { + this.load(data); + } +} +ZipEntries.prototype = { + /** + * Check that the reader is on the speficied signature. + * @param {string} expectedSignature the expected signature. + * @throws {Error} if it is an other signature. + */ + checkSignature: function(expectedSignature) { + var signature = this.reader.readString(4); + if (signature !== expectedSignature) { + throw new Error("Corrupted zip or bug : unexpected signature " + "(" + utils.pretty(signature) + ", expected " + utils.pretty(expectedSignature) + ")"); + } + }, + /** + * Read the end of the central directory. + */ + readBlockEndOfCentral: function() { + this.diskNumber = this.reader.readInt(2); + this.diskWithCentralDirStart = this.reader.readInt(2); + this.centralDirRecordsOnThisDisk = this.reader.readInt(2); + this.centralDirRecords = this.reader.readInt(2); + this.centralDirSize = this.reader.readInt(4); + this.centralDirOffset = this.reader.readInt(4); + + this.zipCommentLength = this.reader.readInt(2); + // warning : the encoding depends of the system locale + // On a linux machine with LANG=en_US.utf8, this field is utf8 encoded. + // On a windows machine, this field is encoded with the localized windows code page. + this.zipComment = this.reader.readString(this.zipCommentLength); + // To get consistent behavior with the generation part, we will assume that + // this is utf8 encoded. + this.zipComment = jszipProto.utf8decode(this.zipComment); + }, + /** + * Read the end of the Zip 64 central directory. + * Not merged with the method readEndOfCentral : + * The end of central can coexist with its Zip64 brother, + * I don't want to read the wrong number of bytes ! + */ + readBlockZip64EndOfCentral: function() { + this.zip64EndOfCentralSize = this.reader.readInt(8); + this.versionMadeBy = this.reader.readString(2); + this.versionNeeded = this.reader.readInt(2); + this.diskNumber = this.reader.readInt(4); + this.diskWithCentralDirStart = this.reader.readInt(4); + this.centralDirRecordsOnThisDisk = this.reader.readInt(8); + this.centralDirRecords = this.reader.readInt(8); + this.centralDirSize = this.reader.readInt(8); + this.centralDirOffset = this.reader.readInt(8); + + this.zip64ExtensibleData = {}; + var extraDataSize = this.zip64EndOfCentralSize - 44, + index = 0, + extraFieldId, + extraFieldLength, + extraFieldValue; + while (index < extraDataSize) { + extraFieldId = this.reader.readInt(2); + extraFieldLength = this.reader.readInt(4); + extraFieldValue = this.reader.readString(extraFieldLength); + this.zip64ExtensibleData[extraFieldId] = { + id: extraFieldId, + length: extraFieldLength, + value: extraFieldValue + }; + } + }, + /** + * Read the end of the Zip 64 central directory locator. + */ + readBlockZip64EndOfCentralLocator: function() { + this.diskWithZip64CentralDirStart = this.reader.readInt(4); + this.relativeOffsetEndOfZip64CentralDir = this.reader.readInt(8); + this.disksCount = this.reader.readInt(4); + if (this.disksCount > 1) { + throw new Error("Multi-volumes zip are not supported"); + } + }, + /** + * Read the local files, based on the offset read in the central part. + */ + readLocalFiles: function() { + var i, file; + for (i = 0; i < this.files.length; i++) { + file = this.files[i]; + this.reader.setIndex(file.localHeaderOffset); + this.checkSignature(sig.LOCAL_FILE_HEADER); + file.readLocalPart(this.reader); + file.handleUTF8(); + file.processAttributes(); + } + }, + /** + * Read the central directory. + */ + readCentralDir: function() { + var file; + + this.reader.setIndex(this.centralDirOffset); + while (this.reader.readString(4) === sig.CENTRAL_FILE_HEADER) { + file = new ZipEntry({ + zip64: this.zip64 + }, this.loadOptions); + file.readCentralPart(this.reader); + this.files.push(file); + } + }, + /** + * Read the end of central directory. + */ + readEndOfCentral: function() { + var offset = this.reader.lastIndexOfSignature(sig.CENTRAL_DIRECTORY_END); + if (offset === -1) { + // Check if the content is a truncated zip or complete garbage. + // A "LOCAL_FILE_HEADER" is not required at the beginning (auto + // extractible zip for example) but it can give a good hint. + // If an ajax request was used without responseType, we will also + // get unreadable data. + var isGarbage = true; + try { + this.reader.setIndex(0); + this.checkSignature(sig.LOCAL_FILE_HEADER); + isGarbage = false; + } catch (e) {} + + if (isGarbage) { + throw new Error("Can't find end of central directory : is this a zip file ? " + + "If it is, see http://stuk.github.io/jszip/documentation/howto/read_zip.html"); + } else { + throw new Error("Corrupted zip : can't find end of central directory"); + } + } + this.reader.setIndex(offset); + this.checkSignature(sig.CENTRAL_DIRECTORY_END); + this.readBlockEndOfCentral(); + + + /* extract from the zip spec : + 4) If one of the fields in the end of central directory + record is too small to hold required data, the field + should be set to -1 (0xFFFF or 0xFFFFFFFF) and the + ZIP64 format record should be created. + 5) The end of central directory record and the + Zip64 end of central directory locator record must + reside on the same disk when splitting or spanning + an archive. + */ + if (this.diskNumber === utils.MAX_VALUE_16BITS || this.diskWithCentralDirStart === utils.MAX_VALUE_16BITS || this.centralDirRecordsOnThisDisk === utils.MAX_VALUE_16BITS || this.centralDirRecords === utils.MAX_VALUE_16BITS || this.centralDirSize === utils.MAX_VALUE_32BITS || this.centralDirOffset === utils.MAX_VALUE_32BITS) { + this.zip64 = true; + + /* + Warning : the zip64 extension is supported, but ONLY if the 64bits integer read from + the zip file can fit into a 32bits integer. This cannot be solved : Javascript represents + all numbers as 64-bit double precision IEEE 754 floating point numbers. + So, we have 53bits for integers and bitwise operations treat everything as 32bits. + see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Bitwise_Operators + and http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf section 8.5 + */ + + // should look for a zip64 EOCD locator + offset = this.reader.lastIndexOfSignature(sig.ZIP64_CENTRAL_DIRECTORY_LOCATOR); + if (offset === -1) { + throw new Error("Corrupted zip : can't find the ZIP64 end of central directory locator"); + } + this.reader.setIndex(offset); + this.checkSignature(sig.ZIP64_CENTRAL_DIRECTORY_LOCATOR); + this.readBlockZip64EndOfCentralLocator(); + + // now the zip64 EOCD record + this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir); + this.checkSignature(sig.ZIP64_CENTRAL_DIRECTORY_END); + this.readBlockZip64EndOfCentral(); + } + }, + prepareReader: function(data) { + var type = utils.getTypeOf(data); + if (type === "string" && !support.uint8array) { + this.reader = new StringReader(data, this.loadOptions.optimizedBinaryString); + } + else if (type === "nodebuffer") { + this.reader = new NodeBufferReader(data); + } + else { + this.reader = new Uint8ArrayReader(utils.transformTo("uint8array", data)); + } + }, + /** + * Read a zip file and create ZipEntries. + * @param {String|ArrayBuffer|Uint8Array|Buffer} data the binary string representing a zip file. + */ + load: function(data) { + this.prepareReader(data); + this.readEndOfCentral(); + this.readCentralDir(); + this.readLocalFiles(); + } +}; +// }}} end of ZipEntries +module.exports = ZipEntries; + +},{"./nodeBufferReader":12,"./object":13,"./signature":14,"./stringReader":15,"./support":17,"./uint8ArrayReader":18,"./utils":21,"./zipEntry":23}],23:[function(_dereq_,module,exports){ +'use strict'; +var StringReader = _dereq_('./stringReader'); +var utils = _dereq_('./utils'); +var CompressedObject = _dereq_('./compressedObject'); +var jszipProto = _dereq_('./object'); + +var MADE_BY_DOS = 0x00; +var MADE_BY_UNIX = 0x03; + +// class ZipEntry {{{ +/** + * An entry in the zip file. + * @constructor + * @param {Object} options Options of the current file. + * @param {Object} loadOptions Options for loading the stream. + */ +function ZipEntry(options, loadOptions) { + this.options = options; + this.loadOptions = loadOptions; +} +ZipEntry.prototype = { + /** + * say if the file is encrypted. + * @return {boolean} true if the file is encrypted, false otherwise. + */ + isEncrypted: function() { + // bit 1 is set + return (this.bitFlag & 0x0001) === 0x0001; + }, + /** + * say if the file has utf-8 filename/comment. + * @return {boolean} true if the filename/comment is in utf-8, false otherwise. + */ + useUTF8: function() { + // bit 11 is set + return (this.bitFlag & 0x0800) === 0x0800; + }, + /** + * Prepare the function used to generate the compressed content from this ZipFile. + * @param {DataReader} reader the reader to use. + * @param {number} from the offset from where we should read the data. + * @param {number} length the length of the data to read. + * @return {Function} the callback to get the compressed content (the type depends of the DataReader class). + */ + prepareCompressedContent: function(reader, from, length) { + return function() { + var previousIndex = reader.index; + reader.setIndex(from); + var compressedFileData = reader.readData(length); + reader.setIndex(previousIndex); + + return compressedFileData; + }; + }, + /** + * Prepare the function used to generate the uncompressed content from this ZipFile. + * @param {DataReader} reader the reader to use. + * @param {number} from the offset from where we should read the data. + * @param {number} length the length of the data to read. + * @param {JSZip.compression} compression the compression used on this file. + * @param {number} uncompressedSize the uncompressed size to expect. + * @return {Function} the callback to get the uncompressed content (the type depends of the DataReader class). + */ + prepareContent: function(reader, from, length, compression, uncompressedSize) { + return function() { + + var compressedFileData = utils.transformTo(compression.uncompressInputType, this.getCompressedContent()); + var uncompressedFileData = compression.uncompress(compressedFileData); + + if (uncompressedFileData.length !== uncompressedSize) { + throw new Error("Bug : uncompressed data size mismatch"); + } + + return uncompressedFileData; + }; + }, + /** + * Read the local part of a zip file and add the info in this object. + * @param {DataReader} reader the reader to use. + */ + readLocalPart: function(reader) { + var compression, localExtraFieldsLength; + + // we already know everything from the central dir ! + // If the central dir data are false, we are doomed. + // On the bright side, the local part is scary : zip64, data descriptors, both, etc. + // The less data we get here, the more reliable this should be. + // Let's skip the whole header and dash to the data ! + reader.skip(22); + // in some zip created on windows, the filename stored in the central dir contains \ instead of /. + // Strangely, the filename here is OK. + // I would love to treat these zip files as corrupted (see http://www.info-zip.org/FAQ.html#backslashes + // or APPNOTE#4.4.17.1, "All slashes MUST be forward slashes '/'") but there are a lot of bad zip generators... + // Search "unzip mismatching "local" filename continuing with "central" filename version" on + // the internet. + // + // I think I see the logic here : the central directory is used to display + // content and the local directory is used to extract the files. Mixing / and \ + // may be used to display \ to windows users and use / when extracting the files. + // Unfortunately, this lead also to some issues : http://seclists.org/fulldisclosure/2009/Sep/394 + this.fileNameLength = reader.readInt(2); + localExtraFieldsLength = reader.readInt(2); // can't be sure this will be the same as the central dir + this.fileName = reader.readString(this.fileNameLength); + reader.skip(localExtraFieldsLength); + + if (this.compressedSize == -1 || this.uncompressedSize == -1) { + throw new Error("Bug or corrupted zip : didn't get enough informations from the central directory " + "(compressedSize == -1 || uncompressedSize == -1)"); + } + + compression = utils.findCompression(this.compressionMethod); + if (compression === null) { // no compression found + throw new Error("Corrupted zip : compression " + utils.pretty(this.compressionMethod) + " unknown (inner file : " + this.fileName + ")"); + } + this.decompressed = new CompressedObject(); + this.decompressed.compressedSize = this.compressedSize; + this.decompressed.uncompressedSize = this.uncompressedSize; + this.decompressed.crc32 = this.crc32; + this.decompressed.compressionMethod = this.compressionMethod; + this.decompressed.getCompressedContent = this.prepareCompressedContent(reader, reader.index, this.compressedSize, compression); + this.decompressed.getContent = this.prepareContent(reader, reader.index, this.compressedSize, compression, this.uncompressedSize); + + // we need to compute the crc32... + if (this.loadOptions.checkCRC32) { + this.decompressed = utils.transformTo("string", this.decompressed.getContent()); + if (jszipProto.crc32(this.decompressed) !== this.crc32) { + throw new Error("Corrupted zip : CRC32 mismatch"); + } + } + }, + + /** + * Read the central part of a zip file and add the info in this object. + * @param {DataReader} reader the reader to use. + */ + readCentralPart: function(reader) { + this.versionMadeBy = reader.readInt(2); + this.versionNeeded = reader.readInt(2); + this.bitFlag = reader.readInt(2); + this.compressionMethod = reader.readString(2); + this.date = reader.readDate(); + this.crc32 = reader.readInt(4); + this.compressedSize = reader.readInt(4); + this.uncompressedSize = reader.readInt(4); + this.fileNameLength = reader.readInt(2); + this.extraFieldsLength = reader.readInt(2); + this.fileCommentLength = reader.readInt(2); + this.diskNumberStart = reader.readInt(2); + this.internalFileAttributes = reader.readInt(2); + this.externalFileAttributes = reader.readInt(4); + this.localHeaderOffset = reader.readInt(4); + + if (this.isEncrypted()) { + throw new Error("Encrypted zip are not supported"); + } + + this.fileName = reader.readString(this.fileNameLength); + this.readExtraFields(reader); + this.parseZIP64ExtraField(reader); + this.fileComment = reader.readString(this.fileCommentLength); + }, + + /** + * Parse the external file attributes and get the unix/dos permissions. + */ + processAttributes: function () { + this.unixPermissions = null; + this.dosPermissions = null; + var madeBy = this.versionMadeBy >> 8; + + // Check if we have the DOS directory flag set. + // We look for it in the DOS and UNIX permissions + // but some unknown platform could set it as a compatibility flag. + this.dir = this.externalFileAttributes & 0x0010 ? true : false; + + if(madeBy === MADE_BY_DOS) { + // first 6 bits (0 to 5) + this.dosPermissions = this.externalFileAttributes & 0x3F; + } + + if(madeBy === MADE_BY_UNIX) { + this.unixPermissions = (this.externalFileAttributes >> 16) & 0xFFFF; + // the octal permissions are in (this.unixPermissions & 0x01FF).toString(8); + } + + // fail safe : if the name ends with a / it probably means a folder + if (!this.dir && this.fileName.slice(-1) === '/') { + this.dir = true; + } + }, + + /** + * Parse the ZIP64 extra field and merge the info in the current ZipEntry. + * @param {DataReader} reader the reader to use. + */ + parseZIP64ExtraField: function(reader) { + + if (!this.extraFields[0x0001]) { + return; + } + + // should be something, preparing the extra reader + var extraReader = new StringReader(this.extraFields[0x0001].value); + + // I really hope that these 64bits integer can fit in 32 bits integer, because js + // won't let us have more. + if (this.uncompressedSize === utils.MAX_VALUE_32BITS) { + this.uncompressedSize = extraReader.readInt(8); + } + if (this.compressedSize === utils.MAX_VALUE_32BITS) { + this.compressedSize = extraReader.readInt(8); + } + if (this.localHeaderOffset === utils.MAX_VALUE_32BITS) { + this.localHeaderOffset = extraReader.readInt(8); + } + if (this.diskNumberStart === utils.MAX_VALUE_32BITS) { + this.diskNumberStart = extraReader.readInt(4); + } + }, + /** + * Read the central part of a zip file and add the info in this object. + * @param {DataReader} reader the reader to use. + */ + readExtraFields: function(reader) { + var start = reader.index, + extraFieldId, + extraFieldLength, + extraFieldValue; + + this.extraFields = this.extraFields || {}; + + while (reader.index < start + this.extraFieldsLength) { + extraFieldId = reader.readInt(2); + extraFieldLength = reader.readInt(2); + extraFieldValue = reader.readString(extraFieldLength); + + this.extraFields[extraFieldId] = { + id: extraFieldId, + length: extraFieldLength, + value: extraFieldValue + }; + } + }, + /** + * Apply an UTF8 transformation if needed. + */ + handleUTF8: function() { + if (this.useUTF8()) { + this.fileName = jszipProto.utf8decode(this.fileName); + this.fileComment = jszipProto.utf8decode(this.fileComment); + } else { + var upath = this.findExtraFieldUnicodePath(); + if (upath !== null) { + this.fileName = upath; + } + var ucomment = this.findExtraFieldUnicodeComment(); + if (ucomment !== null) { + this.fileComment = ucomment; + } + } + }, + + /** + * Find the unicode path declared in the extra field, if any. + * @return {String} the unicode path, null otherwise. + */ + findExtraFieldUnicodePath: function() { + var upathField = this.extraFields[0x7075]; + if (upathField) { + var extraReader = new StringReader(upathField.value); + + // wrong version + if (extraReader.readInt(1) !== 1) { + return null; + } + + // the crc of the filename changed, this field is out of date. + if (jszipProto.crc32(this.fileName) !== extraReader.readInt(4)) { + return null; + } + + return jszipProto.utf8decode(extraReader.readString(upathField.length - 5)); + } + return null; + }, + + /** + * Find the unicode comment declared in the extra field, if any. + * @return {String} the unicode comment, null otherwise. + */ + findExtraFieldUnicodeComment: function() { + var ucommentField = this.extraFields[0x6375]; + if (ucommentField) { + var extraReader = new StringReader(ucommentField.value); + + // wrong version + if (extraReader.readInt(1) !== 1) { + return null; + } + + // the crc of the comment changed, this field is out of date. + if (jszipProto.crc32(this.fileComment) !== extraReader.readInt(4)) { + return null; + } + + return jszipProto.utf8decode(extraReader.readString(ucommentField.length - 5)); + } + return null; + } +}; +module.exports = ZipEntry; + +},{"./compressedObject":2,"./object":13,"./stringReader":15,"./utils":21}],24:[function(_dereq_,module,exports){ +// Top level file is just a mixin of submodules & constants +'use strict'; + +var assign = _dereq_('./lib/utils/common').assign; + +var deflate = _dereq_('./lib/deflate'); +var inflate = _dereq_('./lib/inflate'); +var constants = _dereq_('./lib/zlib/constants'); + +var pako = {}; + +assign(pako, deflate, inflate, constants); + +module.exports = pako; +},{"./lib/deflate":25,"./lib/inflate":26,"./lib/utils/common":27,"./lib/zlib/constants":30}],25:[function(_dereq_,module,exports){ +'use strict'; + + +var zlib_deflate = _dereq_('./zlib/deflate.js'); +var utils = _dereq_('./utils/common'); +var strings = _dereq_('./utils/strings'); +var msg = _dereq_('./zlib/messages'); +var zstream = _dereq_('./zlib/zstream'); + + +/* Public constants ==========================================================*/ +/* ===========================================================================*/ + +var Z_NO_FLUSH = 0; +var Z_FINISH = 4; + +var Z_OK = 0; +var Z_STREAM_END = 1; + +var Z_DEFAULT_COMPRESSION = -1; + +var Z_DEFAULT_STRATEGY = 0; + +var Z_DEFLATED = 8; + +/* ===========================================================================*/ + + +/** + * class Deflate + * + * Generic JS-style wrapper for zlib calls. If you don't need + * streaming behaviour - use more simple functions: [[deflate]], + * [[deflateRaw]] and [[gzip]]. + **/ + +/* internal + * Deflate.chunks -> Array + * + * Chunks of output data, if [[Deflate#onData]] not overriden. + **/ + +/** + * Deflate.result -> Uint8Array|Array + * + * Compressed result, generated by default [[Deflate#onData]] + * and [[Deflate#onEnd]] handlers. Filled after you push last chunk + * (call [[Deflate#push]] with `Z_FINISH` / `true` param). + **/ + +/** + * Deflate.err -> Number + * + * Error code after deflate finished. 0 (Z_OK) on success. + * You will not need it in real life, because deflate errors + * are possible only on wrong options or bad `onData` / `onEnd` + * custom handlers. + **/ + +/** + * Deflate.msg -> String + * + * Error message, if [[Deflate.err]] != 0 + **/ + + +/** + * new Deflate(options) + * - options (Object): zlib deflate options. + * + * Creates new deflator instance with specified params. Throws exception + * on bad params. Supported options: + * + * - `level` + * - `windowBits` + * - `memLevel` + * - `strategy` + * + * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) + * for more information on these. + * + * Additional options, for internal needs: + * + * - `chunkSize` - size of generated data chunks (16K by default) + * - `raw` (Boolean) - do raw deflate + * - `gzip` (Boolean) - create gzip wrapper + * - `to` (String) - if equal to 'string', then result will be "binary string" + * (each char code [0..255]) + * - `header` (Object) - custom header for gzip + * - `text` (Boolean) - true if compressed data believed to be text + * - `time` (Number) - modification time, unix timestamp + * - `os` (Number) - operation system code + * - `extra` (Array) - array of bytes with extra data (max 65536) + * - `name` (String) - file name (binary string) + * - `comment` (String) - comment (binary string) + * - `hcrc` (Boolean) - true if header crc should be added + * + * ##### Example: + * + * ```javascript + * var pako = require('pako') + * , chunk1 = Uint8Array([1,2,3,4,5,6,7,8,9]) + * , chunk2 = Uint8Array([10,11,12,13,14,15,16,17,18,19]); + * + * var deflate = new pako.Deflate({ level: 3}); + * + * deflate.push(chunk1, false); + * deflate.push(chunk2, true); // true -> last chunk + * + * if (deflate.err) { throw new Error(deflate.err); } + * + * console.log(deflate.result); + * ``` + **/ +var Deflate = function(options) { + + this.options = utils.assign({ + level: Z_DEFAULT_COMPRESSION, + method: Z_DEFLATED, + chunkSize: 16384, + windowBits: 15, + memLevel: 8, + strategy: Z_DEFAULT_STRATEGY, + to: '' + }, options || {}); + + var opt = this.options; + + if (opt.raw && (opt.windowBits > 0)) { + opt.windowBits = -opt.windowBits; + } + + else if (opt.gzip && (opt.windowBits > 0) && (opt.windowBits < 16)) { + opt.windowBits += 16; + } + + this.err = 0; // error code, if happens (0 = Z_OK) + this.msg = ''; // error message + this.ended = false; // used to avoid multiple onEnd() calls + this.chunks = []; // chunks of compressed data + + this.strm = new zstream(); + this.strm.avail_out = 0; + + var status = zlib_deflate.deflateInit2( + this.strm, + opt.level, + opt.method, + opt.windowBits, + opt.memLevel, + opt.strategy + ); + + if (status !== Z_OK) { + throw new Error(msg[status]); + } + + if (opt.header) { + zlib_deflate.deflateSetHeader(this.strm, opt.header); + } +}; + +/** + * Deflate#push(data[, mode]) -> Boolean + * - data (Uint8Array|Array|String): input data. Strings will be converted to + * utf8 byte sequence. + * - mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes. + * See constants. Skipped or `false` means Z_NO_FLUSH, `true` meansh Z_FINISH. + * + * Sends input data to deflate pipe, generating [[Deflate#onData]] calls with + * new compressed chunks. Returns `true` on success. The last data block must have + * mode Z_FINISH (or `true`). That flush internal pending buffers and call + * [[Deflate#onEnd]]. + * + * On fail call [[Deflate#onEnd]] with error code and return false. + * + * We strongly recommend to use `Uint8Array` on input for best speed (output + * array format is detected automatically). Also, don't skip last param and always + * use the same type in your code (boolean or number). That will improve JS speed. + * + * For regular `Array`-s make sure all elements are [0..255]. + * + * ##### Example + * + * ```javascript + * push(chunk, false); // push one of data chunks + * ... + * push(chunk, true); // push last chunk + * ``` + **/ +Deflate.prototype.push = function(data, mode) { + var strm = this.strm; + var chunkSize = this.options.chunkSize; + var status, _mode; + + if (this.ended) { return false; } + + _mode = (mode === ~~mode) ? mode : ((mode === true) ? Z_FINISH : Z_NO_FLUSH); + + // Convert data if needed + if (typeof data === 'string') { + // If we need to compress text, change encoding to utf8. + strm.input = strings.string2buf(data); + } else { + strm.input = data; + } + + strm.next_in = 0; + strm.avail_in = strm.input.length; + + do { + if (strm.avail_out === 0) { + strm.output = new utils.Buf8(chunkSize); + strm.next_out = 0; + strm.avail_out = chunkSize; + } + status = zlib_deflate.deflate(strm, _mode); /* no bad return value */ + + if (status !== Z_STREAM_END && status !== Z_OK) { + this.onEnd(status); + this.ended = true; + return false; + } + if (strm.avail_out === 0 || (strm.avail_in === 0 && _mode === Z_FINISH)) { + if (this.options.to === 'string') { + this.onData(strings.buf2binstring(utils.shrinkBuf(strm.output, strm.next_out))); + } else { + this.onData(utils.shrinkBuf(strm.output, strm.next_out)); + } + } + } while ((strm.avail_in > 0 || strm.avail_out === 0) && status !== Z_STREAM_END); + + // Finalize on the last chunk. + if (_mode === Z_FINISH) { + status = zlib_deflate.deflateEnd(this.strm); + this.onEnd(status); + this.ended = true; + return status === Z_OK; + } + + return true; +}; + + +/** + * Deflate#onData(chunk) -> Void + * - chunk (Uint8Array|Array|String): ouput data. Type of array depends + * on js engine support. When string output requested, each chunk + * will be string. + * + * By default, stores data blocks in `chunks[]` property and glue + * those in `onEnd`. Override this handler, if you need another behaviour. + **/ +Deflate.prototype.onData = function(chunk) { + this.chunks.push(chunk); +}; + + +/** + * Deflate#onEnd(status) -> Void + * - status (Number): deflate status. 0 (Z_OK) on success, + * other if not. + * + * Called once after you tell deflate that input stream complete + * or error happenned. By default - join collected chunks, + * free memory and fill `results` / `err` properties. + **/ +Deflate.prototype.onEnd = function(status) { + // On success - join + if (status === Z_OK) { + if (this.options.to === 'string') { + this.result = this.chunks.join(''); + } else { + this.result = utils.flattenChunks(this.chunks); + } + } + this.chunks = []; + this.err = status; + this.msg = this.strm.msg; +}; + + +/** + * deflate(data[, options]) -> Uint8Array|Array|String + * - data (Uint8Array|Array|String): input data to compress. + * - options (Object): zlib deflate options. + * + * Compress `data` with deflate alrorythm and `options`. + * + * Supported options are: + * + * - level + * - windowBits + * - memLevel + * - strategy + * + * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) + * for more information on these. + * + * Sugar (options): + * + * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify + * negative windowBits implicitly. + * - `to` (String) - if equal to 'string', then result will be "binary string" + * (each char code [0..255]) + * + * ##### Example: + * + * ```javascript + * var pako = require('pako') + * , data = Uint8Array([1,2,3,4,5,6,7,8,9]); + * + * console.log(pako.deflate(data)); + * ``` + **/ +function deflate(input, options) { + var deflator = new Deflate(options); + + deflator.push(input, true); + + // That will never happens, if you don't cheat with options :) + if (deflator.err) { throw deflator.msg; } + + return deflator.result; +} + + +/** + * deflateRaw(data[, options]) -> Uint8Array|Array|String + * - data (Uint8Array|Array|String): input data to compress. + * - options (Object): zlib deflate options. + * + * The same as [[deflate]], but creates raw data, without wrapper + * (header and adler32 crc). + **/ +function deflateRaw(input, options) { + options = options || {}; + options.raw = true; + return deflate(input, options); +} + + +/** + * gzip(data[, options]) -> Uint8Array|Array|String + * - data (Uint8Array|Array|String): input data to compress. + * - options (Object): zlib deflate options. + * + * The same as [[deflate]], but create gzip wrapper instead of + * deflate one. + **/ +function gzip(input, options) { + options = options || {}; + options.gzip = true; + return deflate(input, options); +} + + +exports.Deflate = Deflate; +exports.deflate = deflate; +exports.deflateRaw = deflateRaw; +exports.gzip = gzip; +},{"./utils/common":27,"./utils/strings":28,"./zlib/deflate.js":32,"./zlib/messages":37,"./zlib/zstream":39}],26:[function(_dereq_,module,exports){ +'use strict'; + + +var zlib_inflate = _dereq_('./zlib/inflate.js'); +var utils = _dereq_('./utils/common'); +var strings = _dereq_('./utils/strings'); +var c = _dereq_('./zlib/constants'); +var msg = _dereq_('./zlib/messages'); +var zstream = _dereq_('./zlib/zstream'); +var gzheader = _dereq_('./zlib/gzheader'); + + +/** + * class Inflate + * + * Generic JS-style wrapper for zlib calls. If you don't need + * streaming behaviour - use more simple functions: [[inflate]] + * and [[inflateRaw]]. + **/ + +/* internal + * inflate.chunks -> Array + * + * Chunks of output data, if [[Inflate#onData]] not overriden. + **/ + +/** + * Inflate.result -> Uint8Array|Array|String + * + * Uncompressed result, generated by default [[Inflate#onData]] + * and [[Inflate#onEnd]] handlers. Filled after you push last chunk + * (call [[Inflate#push]] with `Z_FINISH` / `true` param). + **/ + +/** + * Inflate.err -> Number + * + * Error code after inflate finished. 0 (Z_OK) on success. + * Should be checked if broken data possible. + **/ + +/** + * Inflate.msg -> String + * + * Error message, if [[Inflate.err]] != 0 + **/ + + +/** + * new Inflate(options) + * - options (Object): zlib inflate options. + * + * Creates new inflator instance with specified params. Throws exception + * on bad params. Supported options: + * + * - `windowBits` + * + * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) + * for more information on these. + * + * Additional options, for internal needs: + * + * - `chunkSize` - size of generated data chunks (16K by default) + * - `raw` (Boolean) - do raw inflate + * - `to` (String) - if equal to 'string', then result will be converted + * from utf8 to utf16 (javascript) string. When string output requested, + * chunk length can differ from `chunkSize`, depending on content. + * + * By default, when no options set, autodetect deflate/gzip data format via + * wrapper header. + * + * ##### Example: + * + * ```javascript + * var pako = require('pako') + * , chunk1 = Uint8Array([1,2,3,4,5,6,7,8,9]) + * , chunk2 = Uint8Array([10,11,12,13,14,15,16,17,18,19]); + * + * var inflate = new pako.Inflate({ level: 3}); + * + * inflate.push(chunk1, false); + * inflate.push(chunk2, true); // true -> last chunk + * + * if (inflate.err) { throw new Error(inflate.err); } + * + * console.log(inflate.result); + * ``` + **/ +var Inflate = function(options) { + + this.options = utils.assign({ + chunkSize: 16384, + windowBits: 0, + to: '' + }, options || {}); + + var opt = this.options; + + // Force window size for `raw` data, if not set directly, + // because we have no header for autodetect. + if (opt.raw && (opt.windowBits >= 0) && (opt.windowBits < 16)) { + opt.windowBits = -opt.windowBits; + if (opt.windowBits === 0) { opt.windowBits = -15; } + } + + // If `windowBits` not defined (and mode not raw) - set autodetect flag for gzip/deflate + if ((opt.windowBits >= 0) && (opt.windowBits < 16) && + !(options && options.windowBits)) { + opt.windowBits += 32; + } + + // Gzip header has no info about windows size, we can do autodetect only + // for deflate. So, if window size not set, force it to max when gzip possible + if ((opt.windowBits > 15) && (opt.windowBits < 48)) { + // bit 3 (16) -> gzipped data + // bit 4 (32) -> autodetect gzip/deflate + if ((opt.windowBits & 15) === 0) { + opt.windowBits |= 15; + } + } + + this.err = 0; // error code, if happens (0 = Z_OK) + this.msg = ''; // error message + this.ended = false; // used to avoid multiple onEnd() calls + this.chunks = []; // chunks of compressed data + + this.strm = new zstream(); + this.strm.avail_out = 0; + + var status = zlib_inflate.inflateInit2( + this.strm, + opt.windowBits + ); + + if (status !== c.Z_OK) { + throw new Error(msg[status]); + } + + this.header = new gzheader(); + + zlib_inflate.inflateGetHeader(this.strm, this.header); +}; + +/** + * Inflate#push(data[, mode]) -> Boolean + * - data (Uint8Array|Array|String): input data + * - mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes. + * See constants. Skipped or `false` means Z_NO_FLUSH, `true` meansh Z_FINISH. + * + * Sends input data to inflate pipe, generating [[Inflate#onData]] calls with + * new output chunks. Returns `true` on success. The last data block must have + * mode Z_FINISH (or `true`). That flush internal pending buffers and call + * [[Inflate#onEnd]]. + * + * On fail call [[Inflate#onEnd]] with error code and return false. + * + * We strongly recommend to use `Uint8Array` on input for best speed (output + * format is detected automatically). Also, don't skip last param and always + * use the same type in your code (boolean or number). That will improve JS speed. + * + * For regular `Array`-s make sure all elements are [0..255]. + * + * ##### Example + * + * ```javascript + * push(chunk, false); // push one of data chunks + * ... + * push(chunk, true); // push last chunk + * ``` + **/ +Inflate.prototype.push = function(data, mode) { + var strm = this.strm; + var chunkSize = this.options.chunkSize; + var status, _mode; + var next_out_utf8, tail, utf8str; + + if (this.ended) { return false; } + _mode = (mode === ~~mode) ? mode : ((mode === true) ? c.Z_FINISH : c.Z_NO_FLUSH); + + // Convert data if needed + if (typeof data === 'string') { + // Only binary strings can be decompressed on practice + strm.input = strings.binstring2buf(data); + } else { + strm.input = data; + } + + strm.next_in = 0; + strm.avail_in = strm.input.length; + + do { + if (strm.avail_out === 0) { + strm.output = new utils.Buf8(chunkSize); + strm.next_out = 0; + strm.avail_out = chunkSize; + } + + status = zlib_inflate.inflate(strm, c.Z_NO_FLUSH); /* no bad return value */ + + if (status !== c.Z_STREAM_END && status !== c.Z_OK) { + this.onEnd(status); + this.ended = true; + return false; + } + + if (strm.next_out) { + if (strm.avail_out === 0 || status === c.Z_STREAM_END || (strm.avail_in === 0 && _mode === c.Z_FINISH)) { + + if (this.options.to === 'string') { + + next_out_utf8 = strings.utf8border(strm.output, strm.next_out); + + tail = strm.next_out - next_out_utf8; + utf8str = strings.buf2string(strm.output, next_out_utf8); + + // move tail + strm.next_out = tail; + strm.avail_out = chunkSize - tail; + if (tail) { utils.arraySet(strm.output, strm.output, next_out_utf8, tail, 0); } + + this.onData(utf8str); + + } else { + this.onData(utils.shrinkBuf(strm.output, strm.next_out)); + } + } + } + } while ((strm.avail_in > 0) && status !== c.Z_STREAM_END); + + if (status === c.Z_STREAM_END) { + _mode = c.Z_FINISH; + } + // Finalize on the last chunk. + if (_mode === c.Z_FINISH) { + status = zlib_inflate.inflateEnd(this.strm); + this.onEnd(status); + this.ended = true; + return status === c.Z_OK; + } + + return true; +}; + + +/** + * Inflate#onData(chunk) -> Void + * - chunk (Uint8Array|Array|String): ouput data. Type of array depends + * on js engine support. When string output requested, each chunk + * will be string. + * + * By default, stores data blocks in `chunks[]` property and glue + * those in `onEnd`. Override this handler, if you need another behaviour. + **/ +Inflate.prototype.onData = function(chunk) { + this.chunks.push(chunk); +}; + + +/** + * Inflate#onEnd(status) -> Void + * - status (Number): inflate status. 0 (Z_OK) on success, + * other if not. + * + * Called once after you tell inflate that input stream complete + * or error happenned. By default - join collected chunks, + * free memory and fill `results` / `err` properties. + **/ +Inflate.prototype.onEnd = function(status) { + // On success - join + if (status === c.Z_OK) { + if (this.options.to === 'string') { + // Glue & convert here, until we teach pako to send + // utf8 alligned strings to onData + this.result = this.chunks.join(''); + } else { + this.result = utils.flattenChunks(this.chunks); + } + } + this.chunks = []; + this.err = status; + this.msg = this.strm.msg; +}; + + +/** + * inflate(data[, options]) -> Uint8Array|Array|String + * - data (Uint8Array|Array|String): input data to decompress. + * - options (Object): zlib inflate options. + * + * Decompress `data` with inflate/ungzip and `options`. Autodetect + * format via wrapper header by default. That's why we don't provide + * separate `ungzip` method. + * + * Supported options are: + * + * - windowBits + * + * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced) + * for more information. + * + * Sugar (options): + * + * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify + * negative windowBits implicitly. + * - `to` (String) - if equal to 'string', then result will be converted + * from utf8 to utf16 (javascript) string. When string output requested, + * chunk length can differ from `chunkSize`, depending on content. + * + * + * ##### Example: + * + * ```javascript + * var pako = require('pako') + * , input = pako.deflate([1,2,3,4,5,6,7,8,9]) + * , output; + * + * try { + * output = pako.inflate(input); + * } catch (err) + * console.log(err); + * } + * ``` + **/ +function inflate(input, options) { + var inflator = new Inflate(options); + + inflator.push(input, true); + + // That will never happens, if you don't cheat with options :) + if (inflator.err) { throw inflator.msg; } + + return inflator.result; +} + + +/** + * inflateRaw(data[, options]) -> Uint8Array|Array|String + * - data (Uint8Array|Array|String): input data to decompress. + * - options (Object): zlib inflate options. + * + * The same as [[inflate]], but creates raw data, without wrapper + * (header and adler32 crc). + **/ +function inflateRaw(input, options) { + options = options || {}; + options.raw = true; + return inflate(input, options); +} + + +/** + * ungzip(data[, options]) -> Uint8Array|Array|String + * - data (Uint8Array|Array|String): input data to decompress. + * - options (Object): zlib inflate options. + * + * Just shortcut to [[inflate]], because it autodetects format + * by header.content. Done for convenience. + **/ + + +exports.Inflate = Inflate; +exports.inflate = inflate; +exports.inflateRaw = inflateRaw; +exports.ungzip = inflate; + +},{"./utils/common":27,"./utils/strings":28,"./zlib/constants":30,"./zlib/gzheader":33,"./zlib/inflate.js":35,"./zlib/messages":37,"./zlib/zstream":39}],27:[function(_dereq_,module,exports){ +'use strict'; + + +var TYPED_OK = (typeof Uint8Array !== 'undefined') && + (typeof Uint16Array !== 'undefined') && + (typeof Int32Array !== 'undefined'); + + +exports.assign = function (obj /*from1, from2, from3, ...*/) { + var sources = Array.prototype.slice.call(arguments, 1); + while (sources.length) { + var source = sources.shift(); + if (!source) { continue; } + + if (typeof(source) !== 'object') { + throw new TypeError(source + 'must be non-object'); + } + + for (var p in source) { + if (source.hasOwnProperty(p)) { + obj[p] = source[p]; + } + } + } + + return obj; +}; + + +// reduce buffer size, avoiding mem copy +exports.shrinkBuf = function (buf, size) { + if (buf.length === size) { return buf; } + if (buf.subarray) { return buf.subarray(0, size); } + buf.length = size; + return buf; +}; + + +var fnTyped = { + arraySet: function (dest, src, src_offs, len, dest_offs) { + if (src.subarray && dest.subarray) { + dest.set(src.subarray(src_offs, src_offs+len), dest_offs); + return; + } + // Fallback to ordinary array + for(var i=0; i= 252 ? 6 : i >= 248 ? 5 : i >= 240 ? 4 : i >= 224 ? 3 : i >= 192 ? 2 : 1); +} +_utf8len[254]=_utf8len[254]=1; // Invalid sequence start + + +// convert string to array (typed, when possible) +exports.string2buf = function (str) { + var buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0; + + // count binary size + for (m_pos = 0; m_pos < str_len; m_pos++) { + c = str.charCodeAt(m_pos); + if ((c & 0xfc00) === 0xd800 && (m_pos+1 < str_len)) { + c2 = str.charCodeAt(m_pos+1); + if ((c2 & 0xfc00) === 0xdc00) { + c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); + m_pos++; + } + } + buf_len += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4; + } + + // allocate buffer + buf = new utils.Buf8(buf_len); + + // convert + for (i=0, m_pos = 0; i < buf_len; m_pos++) { + c = str.charCodeAt(m_pos); + if ((c & 0xfc00) === 0xd800 && (m_pos+1 < str_len)) { + c2 = str.charCodeAt(m_pos+1); + if ((c2 & 0xfc00) === 0xdc00) { + c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); + m_pos++; + } + } + if (c < 0x80) { + /* one byte */ + buf[i++] = c; + } else if (c < 0x800) { + /* two bytes */ + buf[i++] = 0xC0 | (c >>> 6); + buf[i++] = 0x80 | (c & 0x3f); + } else if (c < 0x10000) { + /* three bytes */ + buf[i++] = 0xE0 | (c >>> 12); + buf[i++] = 0x80 | (c >>> 6 & 0x3f); + buf[i++] = 0x80 | (c & 0x3f); + } else { + /* four bytes */ + buf[i++] = 0xf0 | (c >>> 18); + buf[i++] = 0x80 | (c >>> 12 & 0x3f); + buf[i++] = 0x80 | (c >>> 6 & 0x3f); + buf[i++] = 0x80 | (c & 0x3f); + } + } + + return buf; +}; + +// Helper (used in 2 places) +function buf2binstring(buf, len) { + // use fallback for big arrays to avoid stack overflow + if (len < 65537) { + if ((buf.subarray && STR_APPLY_UIA_OK) || (!buf.subarray && STR_APPLY_OK)) { + return String.fromCharCode.apply(null, utils.shrinkBuf(buf, len)); + } + } + + var result = ''; + for(var i=0; i < len; i++) { + result += String.fromCharCode(buf[i]); + } + return result; +} + + +// Convert byte array to binary string +exports.buf2binstring = function(buf) { + return buf2binstring(buf, buf.length); +}; + + +// Convert binary string (typed, when possible) +exports.binstring2buf = function(str) { + var buf = new utils.Buf8(str.length); + for(var i=0, len=buf.length; i < len; i++) { + buf[i] = str.charCodeAt(i); + } + return buf; +}; + + +// convert array to string +exports.buf2string = function (buf, max) { + var i, out, c, c_len; + var len = max || buf.length; + + // Reserve max possible length (2 words per char) + // NB: by unknown reasons, Array is significantly faster for + // String.fromCharCode.apply than Uint16Array. + var utf16buf = new Array(len*2); + + for (out=0, i=0; i 4) { utf16buf[out++] = 0xfffd; i += c_len-1; continue; } + + // apply mask on first byte + c &= c_len === 2 ? 0x1f : c_len === 3 ? 0x0f : 0x07; + // join the rest + while (c_len > 1 && i < len) { + c = (c << 6) | (buf[i++] & 0x3f); + c_len--; + } + + // terminated by end of string? + if (c_len > 1) { utf16buf[out++] = 0xfffd; continue; } + + if (c < 0x10000) { + utf16buf[out++] = c; + } else { + c -= 0x10000; + utf16buf[out++] = 0xd800 | ((c >> 10) & 0x3ff); + utf16buf[out++] = 0xdc00 | (c & 0x3ff); + } + } + + return buf2binstring(utf16buf, out); +}; + + +// Calculate max possible position in utf8 buffer, +// that will not break sequence. If that's not possible +// - (very small limits) return max size as is. +// +// buf[] - utf8 bytes array +// max - length limit (mandatory); +exports.utf8border = function(buf, max) { + var pos; + + max = max || buf.length; + if (max > buf.length) { max = buf.length; } + + // go back from last position, until start of sequence found + pos = max-1; + while (pos >= 0 && (buf[pos] & 0xC0) === 0x80) { pos--; } + + // Fuckup - very small and broken sequence, + // return max, because we should return something anyway. + if (pos < 0) { return max; } + + // If we came to start of buffer - that means vuffer is too small, + // return max too. + if (pos === 0) { return max; } + + return (pos + _utf8len[buf[pos]] > max) ? pos : max; +}; + +},{"./common":27}],29:[function(_dereq_,module,exports){ +'use strict'; + +// Note: adler32 takes 12% for level 0 and 2% for level 6. +// It doesn't worth to make additional optimizationa as in original. +// Small size is preferable. + +function adler32(adler, buf, len, pos) { + var s1 = (adler & 0xffff) |0 + , s2 = ((adler >>> 16) & 0xffff) |0 + , n = 0; + + while (len !== 0) { + // Set limit ~ twice less than 5552, to keep + // s2 in 31-bits, because we force signed ints. + // in other case %= will fail. + n = len > 2000 ? 2000 : len; + len -= n; + + do { + s1 = (s1 + buf[pos++]) |0; + s2 = (s2 + s1) |0; + } while (--n); + + s1 %= 65521; + s2 %= 65521; + } + + return (s1 | (s2 << 16)) |0; +} + + +module.exports = adler32; +},{}],30:[function(_dereq_,module,exports){ +module.exports = { + + /* Allowed flush values; see deflate() and inflate() below for details */ + Z_NO_FLUSH: 0, + Z_PARTIAL_FLUSH: 1, + Z_SYNC_FLUSH: 2, + Z_FULL_FLUSH: 3, + Z_FINISH: 4, + Z_BLOCK: 5, + Z_TREES: 6, + + /* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ + Z_OK: 0, + Z_STREAM_END: 1, + Z_NEED_DICT: 2, + Z_ERRNO: -1, + Z_STREAM_ERROR: -2, + Z_DATA_ERROR: -3, + //Z_MEM_ERROR: -4, + Z_BUF_ERROR: -5, + //Z_VERSION_ERROR: -6, + + /* compression levels */ + Z_NO_COMPRESSION: 0, + Z_BEST_SPEED: 1, + Z_BEST_COMPRESSION: 9, + Z_DEFAULT_COMPRESSION: -1, + + + Z_FILTERED: 1, + Z_HUFFMAN_ONLY: 2, + Z_RLE: 3, + Z_FIXED: 4, + Z_DEFAULT_STRATEGY: 0, + + /* Possible values of the data_type field (though see inflate()) */ + Z_BINARY: 0, + Z_TEXT: 1, + //Z_ASCII: 1, // = Z_TEXT (deprecated) + Z_UNKNOWN: 2, + + /* The deflate compression method */ + Z_DEFLATED: 8 + //Z_NULL: null // Use -1 or null inline, depending on var type +}; +},{}],31:[function(_dereq_,module,exports){ +'use strict'; + +// Note: we can't get significant speed boost here. +// So write code to minimize size - no pregenerated tables +// and array tools dependencies. + + +// Use ordinary array, since untyped makes no boost here +function makeTable() { + var c, table = []; + + for(var n =0; n < 256; n++){ + c = n; + for(var k =0; k < 8; k++){ + c = ((c&1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1)); + } + table[n] = c; + } + + return table; +} + +// Create table on load. Just 255 signed longs. Not a problem. +var crcTable = makeTable(); + + +function crc32(crc, buf, len, pos) { + var t = crcTable + , end = pos + len; + + crc = crc ^ (-1); + + for (var i = pos; i < end; i++ ) { + crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xFF]; + } + + return (crc ^ (-1)); // >>> 0; +} + + +module.exports = crc32; +},{}],32:[function(_dereq_,module,exports){ +'use strict'; + +var utils = _dereq_('../utils/common'); +var trees = _dereq_('./trees'); +var adler32 = _dereq_('./adler32'); +var crc32 = _dereq_('./crc32'); +var msg = _dereq_('./messages'); + +/* Public constants ==========================================================*/ +/* ===========================================================================*/ + + +/* Allowed flush values; see deflate() and inflate() below for details */ +var Z_NO_FLUSH = 0; +var Z_PARTIAL_FLUSH = 1; +//var Z_SYNC_FLUSH = 2; +var Z_FULL_FLUSH = 3; +var Z_FINISH = 4; +var Z_BLOCK = 5; +//var Z_TREES = 6; + + +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ +var Z_OK = 0; +var Z_STREAM_END = 1; +//var Z_NEED_DICT = 2; +//var Z_ERRNO = -1; +var Z_STREAM_ERROR = -2; +var Z_DATA_ERROR = -3; +//var Z_MEM_ERROR = -4; +var Z_BUF_ERROR = -5; +//var Z_VERSION_ERROR = -6; + + +/* compression levels */ +//var Z_NO_COMPRESSION = 0; +//var Z_BEST_SPEED = 1; +//var Z_BEST_COMPRESSION = 9; +var Z_DEFAULT_COMPRESSION = -1; + + +var Z_FILTERED = 1; +var Z_HUFFMAN_ONLY = 2; +var Z_RLE = 3; +var Z_FIXED = 4; +var Z_DEFAULT_STRATEGY = 0; + +/* Possible values of the data_type field (though see inflate()) */ +//var Z_BINARY = 0; +//var Z_TEXT = 1; +//var Z_ASCII = 1; // = Z_TEXT +var Z_UNKNOWN = 2; + + +/* The deflate compression method */ +var Z_DEFLATED = 8; + +/*============================================================================*/ + + +var MAX_MEM_LEVEL = 9; +/* Maximum value for memLevel in deflateInit2 */ +var MAX_WBITS = 15; +/* 32K LZ77 window */ +var DEF_MEM_LEVEL = 8; + + +var LENGTH_CODES = 29; +/* number of length codes, not counting the special END_BLOCK code */ +var LITERALS = 256; +/* number of literal bytes 0..255 */ +var L_CODES = LITERALS + 1 + LENGTH_CODES; +/* number of Literal or Length codes, including the END_BLOCK code */ +var D_CODES = 30; +/* number of distance codes */ +var BL_CODES = 19; +/* number of codes used to transfer the bit lengths */ +var HEAP_SIZE = 2*L_CODES + 1; +/* maximum heap size */ +var MAX_BITS = 15; +/* All codes must not exceed MAX_BITS bits */ + +var MIN_MATCH = 3; +var MAX_MATCH = 258; +var MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1); + +var PRESET_DICT = 0x20; + +var INIT_STATE = 42; +var EXTRA_STATE = 69; +var NAME_STATE = 73; +var COMMENT_STATE = 91; +var HCRC_STATE = 103; +var BUSY_STATE = 113; +var FINISH_STATE = 666; + +var BS_NEED_MORE = 1; /* block not completed, need more input or more output */ +var BS_BLOCK_DONE = 2; /* block flush performed */ +var BS_FINISH_STARTED = 3; /* finish started, need only more output at next deflate */ +var BS_FINISH_DONE = 4; /* finish done, accept no more input or output */ + +var OS_CODE = 0x03; // Unix :) . Don't detect, use this default. + +function err(strm, errorCode) { + strm.msg = msg[errorCode]; + return errorCode; +} + +function rank(f) { + return ((f) << 1) - ((f) > 4 ? 9 : 0); +} + +function zero(buf) { var len = buf.length; while (--len >= 0) { buf[len] = 0; } } + + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output goes + * through this function so some applications may wish to modify it + * to avoid allocating a large strm->output buffer and copying into it. + * (See also read_buf()). + */ +function flush_pending(strm) { + var s = strm.state; + + //_tr_flush_bits(s); + var len = s.pending; + if (len > strm.avail_out) { + len = strm.avail_out; + } + if (len === 0) { return; } + + utils.arraySet(strm.output, s.pending_buf, s.pending_out, len, strm.next_out); + strm.next_out += len; + s.pending_out += len; + strm.total_out += len; + strm.avail_out -= len; + s.pending -= len; + if (s.pending === 0) { + s.pending_out = 0; + } +} + + +function flush_block_only (s, last) { + trees._tr_flush_block(s, (s.block_start >= 0 ? s.block_start : -1), s.strstart - s.block_start, last); + s.block_start = s.strstart; + flush_pending(s.strm); +} + + +function put_byte(s, b) { + s.pending_buf[s.pending++] = b; +} + + +/* ========================================================================= + * Put a short in the pending buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * pending_buf. + */ +function putShortMSB(s, b) { +// put_byte(s, (Byte)(b >> 8)); +// put_byte(s, (Byte)(b & 0xff)); + s.pending_buf[s.pending++] = (b >>> 8) & 0xff; + s.pending_buf[s.pending++] = b & 0xff; +} + + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->input buffer and copying from it. + * (See also flush_pending()). + */ +function read_buf(strm, buf, start, size) { + var len = strm.avail_in; + + if (len > size) { len = size; } + if (len === 0) { return 0; } + + strm.avail_in -= len; + + utils.arraySet(buf, strm.input, strm.next_in, len, start); + if (strm.state.wrap === 1) { + strm.adler = adler32(strm.adler, buf, len, start); + } + + else if (strm.state.wrap === 2) { + strm.adler = crc32(strm.adler, buf, len, start); + } + + strm.next_in += len; + strm.total_in += len; + + return len; +} + + +/* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. + */ +function longest_match(s, cur_match) { + var chain_length = s.max_chain_length; /* max hash chain length */ + var scan = s.strstart; /* current string */ + var match; /* matched string */ + var len; /* length of current match */ + var best_len = s.prev_length; /* best match length so far */ + var nice_match = s.nice_match; /* stop if match long enough */ + var limit = (s.strstart > (s.w_size - MIN_LOOKAHEAD)) ? + s.strstart - (s.w_size - MIN_LOOKAHEAD) : 0/*NIL*/; + + var _win = s.window; // shortcut + + var wmask = s.w_mask; + var prev = s.prev; + + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + + var strend = s.strstart + MAX_MATCH; + var scan_end1 = _win[scan + best_len - 1]; + var scan_end = _win[scan + best_len]; + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + // Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s.prev_length >= s.good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if (nice_match > s.lookahead) { nice_match = s.lookahead; } + + // Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + do { + // Assert(cur_match < s->strstart, "no future"); + match = cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2. Note that the checks below + * for insufficient lookahead only occur occasionally for performance + * reasons. Therefore uninitialized memory will be accessed, and + * conditional jumps will be made that depend on those values. + * However the length of the match is limited to the lookahead, so + * the output of deflate is not affected by the uninitialized values. + */ + + if (_win[match + best_len] !== scan_end || + _win[match + best_len - 1] !== scan_end1 || + _win[match] !== _win[scan] || + _win[++match] !== _win[scan + 1]) { + continue; + } + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2; + match++; + // Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + /*jshint noempty:false*/ + } while (_win[++scan] === _win[++match] && _win[++scan] === _win[++match] && + _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && + _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && + _win[++scan] === _win[++match] && _win[++scan] === _win[++match] && + scan < strend); + + // Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (strend - scan); + scan = strend - MAX_MATCH; + + if (len > best_len) { + s.match_start = cur_match; + best_len = len; + if (len >= nice_match) { + break; + } + scan_end1 = _win[scan + best_len - 1]; + scan_end = _win[scan + best_len]; + } + } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length !== 0); + + if (best_len <= s.lookahead) { + return best_len; + } + return s.lookahead; +} + + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +function fill_window(s) { + var _w_size = s.w_size; + var p, n, m, more, str; + + //Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); + + do { + more = s.window_size - s.lookahead - s.strstart; + + // JS ints have 32 bit, block below not needed + /* Deal with !@#$% 64K limit: */ + //if (sizeof(int) <= 2) { + // if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + // more = wsize; + // + // } else if (more == (unsigned)(-1)) { + // /* Very unlikely, but possible on 16 bit machine if + // * strstart == 0 && lookahead == 1 (input done a byte at time) + // */ + // more--; + // } + //} + + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (s.strstart >= _w_size + (_w_size - MIN_LOOKAHEAD)) { + + utils.arraySet(s.window, s.window, _w_size, _w_size, 0); + s.match_start -= _w_size; + s.strstart -= _w_size; + /* we now have strstart >= MAX_DIST */ + s.block_start -= _w_size; + + /* Slide the hash table (could be avoided with 32 bit values + at the expense of memory usage). We slide even when level == 0 + to keep the hash table consistent if we switch back to level > 0 + later. (Using level 0 permanently is not an optimal usage of + zlib, so we don't care about this pathological case.) + */ + + n = s.hash_size; + p = n; + do { + m = s.head[--p]; + s.head[p] = (m >= _w_size ? m - _w_size : 0); + } while (--n); + + n = _w_size; + p = n; + do { + m = s.prev[--p]; + s.prev[p] = (m >= _w_size ? m - _w_size : 0); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); + + more += _w_size; + } + if (s.strm.avail_in === 0) { + break; + } + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + //Assert(more >= 2, "more < 2"); + n = read_buf(s.strm, s.window, s.strstart + s.lookahead, more); + s.lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s.lookahead + s.insert >= MIN_MATCH) { + str = s.strstart - s.insert; + s.ins_h = s.window[str]; + + /* UPDATE_HASH(s, s->ins_h, s->window[str + 1]); */ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + 1]) & s.hash_mask; +//#if MIN_MATCH != 3 +// Call update_hash() MIN_MATCH-3 more times +//#endif + while (s.insert) { + /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + MIN_MATCH-1]) & s.hash_mask; + + s.prev[str & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = str; + str++; + s.insert--; + if (s.lookahead + s.insert < MIN_MATCH) { + break; + } + } + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + + } while (s.lookahead < MIN_LOOKAHEAD && s.strm.avail_in !== 0); + + /* If the WIN_INIT bytes after the end of the current data have never been + * written, then zero those bytes in order to avoid memory check reports of + * the use of uninitialized (or uninitialised as Julian writes) bytes by + * the longest match routines. Update the high water mark for the next + * time through here. WIN_INIT is set to MAX_MATCH since the longest match + * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. + */ +// if (s.high_water < s.window_size) { +// var curr = s.strstart + s.lookahead; +// var init = 0; +// +// if (s.high_water < curr) { +// /* Previous high water mark below current data -- zero WIN_INIT +// * bytes or up to end of window, whichever is less. +// */ +// init = s.window_size - curr; +// if (init > WIN_INIT) +// init = WIN_INIT; +// zmemzero(s->window + curr, (unsigned)init); +// s->high_water = curr + init; +// } +// else if (s->high_water < (ulg)curr + WIN_INIT) { +// /* High water mark at or above current data, but below current data +// * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up +// * to end of window, whichever is less. +// */ +// init = (ulg)curr + WIN_INIT - s->high_water; +// if (init > s->window_size - s->high_water) +// init = s->window_size - s->high_water; +// zmemzero(s->window + s->high_water, (unsigned)init); +// s->high_water += init; +// } +// } +// +// Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, +// "not enough room for search"); +} + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * This function does not insert new strings in the dictionary since + * uncompressible data is probably not useful. This function is used + * only for the level=0 compression option. + * NOTE: this function should be optimized to avoid extra copying from + * window to pending_buf. + */ +function deflate_stored(s, flush) { + /* Stored blocks are limited to 0xffff bytes, pending_buf is limited + * to pending_buf_size, and each stored block has a 5 byte header: + */ + var max_block_size = 0xffff; + + if (max_block_size > s.pending_buf_size - 5) { + max_block_size = s.pending_buf_size - 5; + } + + /* Copy as much as possible from input to output: */ + for (;;) { + /* Fill the window as much as possible: */ + if (s.lookahead <= 1) { + + //Assert(s->strstart < s->w_size+MAX_DIST(s) || + // s->block_start >= (long)s->w_size, "slide too late"); +// if (!(s.strstart < s.w_size + (s.w_size - MIN_LOOKAHEAD) || +// s.block_start >= s.w_size)) { +// throw new Error("slide too late"); +// } + + fill_window(s); + if (s.lookahead === 0 && flush === Z_NO_FLUSH) { + return BS_NEED_MORE; + } + + if (s.lookahead === 0) { + break; + } + /* flush the current block */ + } + //Assert(s->block_start >= 0L, "block gone"); +// if (s.block_start < 0) throw new Error("block gone"); + + s.strstart += s.lookahead; + s.lookahead = 0; + + /* Emit a stored block if pending_buf will be full: */ + var max_start = s.block_start + max_block_size; + + if (s.strstart === 0 || s.strstart >= max_start) { + /* strstart == 0 is possible when wraparound on 16-bit machine */ + s.lookahead = s.strstart - max_start; + s.strstart = max_start; + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + + + } + /* Flush if we may have to slide, otherwise block_start may become + * negative and the data will be gone: + */ + if (s.strstart - s.block_start >= (s.w_size - MIN_LOOKAHEAD)) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + } + + s.insert = 0; + + if (flush === Z_FINISH) { + /*** FLUSH_BLOCK(s, 1); ***/ + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + /***/ + return BS_FINISH_DONE; + } + + if (s.strstart > s.block_start) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + + return BS_NEED_MORE; +} + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +function deflate_fast(s, flush) { + var hash_head; /* head of the hash chain */ + var bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s.lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) { + return BS_NEED_MORE; + } + if (s.lookahead === 0) { + break; /* flush the current block */ + } + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = 0/*NIL*/; + if (s.lookahead >= MIN_MATCH) { + /*** INSERT_STRING(s, s.strstart, hash_head); ***/ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; + hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = s.strstart; + /***/ + } + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head !== 0/*NIL*/ && ((s.strstart - hash_head) <= (s.w_size - MIN_LOOKAHEAD))) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s.match_length = longest_match(s, hash_head); + /* longest_match() sets match_start */ + } + if (s.match_length >= MIN_MATCH) { + // check_match(s, s.strstart, s.match_start, s.match_length); // for debug only + + /*** _tr_tally_dist(s, s.strstart - s.match_start, + s.match_length - MIN_MATCH, bflush); ***/ + bflush = trees._tr_tally(s, s.strstart - s.match_start, s.match_length - MIN_MATCH); + + s.lookahead -= s.match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ + if (s.match_length <= s.max_lazy_match/*max_insert_length*/ && s.lookahead >= MIN_MATCH) { + s.match_length--; /* string at strstart already in table */ + do { + s.strstart++; + /*** INSERT_STRING(s, s.strstart, hash_head); ***/ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; + hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = s.strstart; + /***/ + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } while (--s.match_length !== 0); + s.strstart++; + } else + { + s.strstart += s.match_length; + s.match_length = 0; + s.ins_h = s.window[s.strstart]; + /* UPDATE_HASH(s, s.ins_h, s.window[s.strstart+1]); */ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + 1]) & s.hash_mask; + +//#if MIN_MATCH != 3 +// Call UPDATE_HASH() MIN_MATCH-3 more times +//#endif + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + } else { + /* No match, output a literal byte */ + //Tracevv((stderr,"%c", s.window[s.strstart])); + /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ + bflush = trees._tr_tally(s, 0, s.window[s.strstart]); + + s.lookahead--; + s.strstart++; + } + if (bflush) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + } + s.insert = ((s.strstart < (MIN_MATCH-1)) ? s.strstart : MIN_MATCH-1); + if (flush === Z_FINISH) { + /*** FLUSH_BLOCK(s, 1); ***/ + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + /***/ + return BS_FINISH_DONE; + } + if (s.last_lit) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + return BS_BLOCK_DONE; +} + +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +function deflate_slow(s, flush) { + var hash_head; /* head of hash chain */ + var bflush; /* set if current block must be flushed */ + + var max_insert; + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s.lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) { + return BS_NEED_MORE; + } + if (s.lookahead === 0) { break; } /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = 0/*NIL*/; + if (s.lookahead >= MIN_MATCH) { + /*** INSERT_STRING(s, s.strstart, hash_head); ***/ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; + hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = s.strstart; + /***/ + } + + /* Find the longest match, discarding those <= prev_length. + */ + s.prev_length = s.match_length; + s.prev_match = s.match_start; + s.match_length = MIN_MATCH-1; + + if (hash_head !== 0/*NIL*/ && s.prev_length < s.max_lazy_match && + s.strstart - hash_head <= (s.w_size-MIN_LOOKAHEAD)/*MAX_DIST(s)*/) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + s.match_length = longest_match(s, hash_head); + /* longest_match() sets match_start */ + + if (s.match_length <= 5 && + (s.strategy === Z_FILTERED || (s.match_length === MIN_MATCH && s.strstart - s.match_start > 4096/*TOO_FAR*/))) { + + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + s.match_length = MIN_MATCH-1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s.prev_length >= MIN_MATCH && s.match_length <= s.prev_length) { + max_insert = s.strstart + s.lookahead - MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + //check_match(s, s.strstart-1, s.prev_match, s.prev_length); + + /***_tr_tally_dist(s, s.strstart - 1 - s.prev_match, + s.prev_length - MIN_MATCH, bflush);***/ + bflush = trees._tr_tally(s, s.strstart - 1- s.prev_match, s.prev_length - MIN_MATCH); + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s.lookahead -= s.prev_length-1; + s.prev_length -= 2; + do { + if (++s.strstart <= max_insert) { + /*** INSERT_STRING(s, s.strstart, hash_head); ***/ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; + hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h]; + s.head[s.ins_h] = s.strstart; + /***/ + } + } while (--s.prev_length !== 0); + s.match_available = 0; + s.match_length = MIN_MATCH-1; + s.strstart++; + + if (bflush) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + + } else if (s.match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + //Tracevv((stderr,"%c", s->window[s->strstart-1])); + /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/ + bflush = trees._tr_tally(s, 0, s.window[s.strstart-1]); + + if (bflush) { + /*** FLUSH_BLOCK_ONLY(s, 0) ***/ + flush_block_only(s, false); + /***/ + } + s.strstart++; + s.lookahead--; + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s.match_available = 1; + s.strstart++; + s.lookahead--; + } + } + //Assert (flush != Z_NO_FLUSH, "no flush?"); + if (s.match_available) { + //Tracevv((stderr,"%c", s->window[s->strstart-1])); + /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/ + bflush = trees._tr_tally(s, 0, s.window[s.strstart-1]); + + s.match_available = 0; + } + s.insert = s.strstart < MIN_MATCH-1 ? s.strstart : MIN_MATCH-1; + if (flush === Z_FINISH) { + /*** FLUSH_BLOCK(s, 1); ***/ + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + /***/ + return BS_FINISH_DONE; + } + if (s.last_lit) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + + return BS_BLOCK_DONE; +} + + +/* =========================================================================== + * For Z_RLE, simply look for runs of bytes, generate matches only of distance + * one. Do not maintain a hash table. (It will be regenerated if this run of + * deflate switches away from Z_RLE.) + */ +function deflate_rle(s, flush) { + var bflush; /* set if current block must be flushed */ + var prev; /* byte at distance one to match */ + var scan, strend; /* scan goes up to strend for length of run */ + + var _win = s.window; + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the longest run, plus one for the unrolled loop. + */ + if (s.lookahead <= MAX_MATCH) { + fill_window(s); + if (s.lookahead <= MAX_MATCH && flush === Z_NO_FLUSH) { + return BS_NEED_MORE; + } + if (s.lookahead === 0) { break; } /* flush the current block */ + } + + /* See how many times the previous byte repeats */ + s.match_length = 0; + if (s.lookahead >= MIN_MATCH && s.strstart > 0) { + scan = s.strstart - 1; + prev = _win[scan]; + if (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan]) { + strend = s.strstart + MAX_MATCH; + do { + /*jshint noempty:false*/ + } while (prev === _win[++scan] && prev === _win[++scan] && + prev === _win[++scan] && prev === _win[++scan] && + prev === _win[++scan] && prev === _win[++scan] && + prev === _win[++scan] && prev === _win[++scan] && + scan < strend); + s.match_length = MAX_MATCH - (strend - scan); + if (s.match_length > s.lookahead) { + s.match_length = s.lookahead; + } + } + //Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan"); + } + + /* Emit match if have run of MIN_MATCH or longer, else emit literal */ + if (s.match_length >= MIN_MATCH) { + //check_match(s, s.strstart, s.strstart - 1, s.match_length); + + /*** _tr_tally_dist(s, 1, s.match_length - MIN_MATCH, bflush); ***/ + bflush = trees._tr_tally(s, 1, s.match_length - MIN_MATCH); + + s.lookahead -= s.match_length; + s.strstart += s.match_length; + s.match_length = 0; + } else { + /* No match, output a literal byte */ + //Tracevv((stderr,"%c", s->window[s->strstart])); + /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ + bflush = trees._tr_tally(s, 0, s.window[s.strstart]); + + s.lookahead--; + s.strstart++; + } + if (bflush) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + } + s.insert = 0; + if (flush === Z_FINISH) { + /*** FLUSH_BLOCK(s, 1); ***/ + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + /***/ + return BS_FINISH_DONE; + } + if (s.last_lit) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + return BS_BLOCK_DONE; +} + +/* =========================================================================== + * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. + * (It will be regenerated if this run of deflate switches away from Huffman.) + */ +function deflate_huff(s, flush) { + var bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we have a literal to write. */ + if (s.lookahead === 0) { + fill_window(s); + if (s.lookahead === 0) { + if (flush === Z_NO_FLUSH) { + return BS_NEED_MORE; + } + break; /* flush the current block */ + } + } + + /* Output a literal byte */ + s.match_length = 0; + //Tracevv((stderr,"%c", s->window[s->strstart])); + /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/ + bflush = trees._tr_tally(s, 0, s.window[s.strstart]); + s.lookahead--; + s.strstart++; + if (bflush) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + } + s.insert = 0; + if (flush === Z_FINISH) { + /*** FLUSH_BLOCK(s, 1); ***/ + flush_block_only(s, true); + if (s.strm.avail_out === 0) { + return BS_FINISH_STARTED; + } + /***/ + return BS_FINISH_DONE; + } + if (s.last_lit) { + /*** FLUSH_BLOCK(s, 0); ***/ + flush_block_only(s, false); + if (s.strm.avail_out === 0) { + return BS_NEED_MORE; + } + /***/ + } + return BS_BLOCK_DONE; +} + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +var Config = function (good_length, max_lazy, nice_length, max_chain, func) { + this.good_length = good_length; + this.max_lazy = max_lazy; + this.nice_length = nice_length; + this.max_chain = max_chain; + this.func = func; +}; + +var configuration_table; + +configuration_table = [ + /* good lazy nice chain */ + new Config(0, 0, 0, 0, deflate_stored), /* 0 store only */ + new Config(4, 4, 8, 4, deflate_fast), /* 1 max speed, no lazy matches */ + new Config(4, 5, 16, 8, deflate_fast), /* 2 */ + new Config(4, 6, 32, 32, deflate_fast), /* 3 */ + + new Config(4, 4, 16, 16, deflate_slow), /* 4 lazy matches */ + new Config(8, 16, 32, 32, deflate_slow), /* 5 */ + new Config(8, 16, 128, 128, deflate_slow), /* 6 */ + new Config(8, 32, 128, 256, deflate_slow), /* 7 */ + new Config(32, 128, 258, 1024, deflate_slow), /* 8 */ + new Config(32, 258, 258, 4096, deflate_slow) /* 9 max compression */ +]; + + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +function lm_init(s) { + s.window_size = 2 * s.w_size; + + /*** CLEAR_HASH(s); ***/ + zero(s.head); // Fill with NIL (= 0); + + /* Set the default configuration parameters: + */ + s.max_lazy_match = configuration_table[s.level].max_lazy; + s.good_match = configuration_table[s.level].good_length; + s.nice_match = configuration_table[s.level].nice_length; + s.max_chain_length = configuration_table[s.level].max_chain; + + s.strstart = 0; + s.block_start = 0; + s.lookahead = 0; + s.insert = 0; + s.match_length = s.prev_length = MIN_MATCH - 1; + s.match_available = 0; + s.ins_h = 0; +} + + +function DeflateState() { + this.strm = null; /* pointer back to this zlib stream */ + this.status = 0; /* as the name implies */ + this.pending_buf = null; /* output still pending */ + this.pending_buf_size = 0; /* size of pending_buf */ + this.pending_out = 0; /* next pending byte to output to the stream */ + this.pending = 0; /* nb of bytes in the pending buffer */ + this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */ + this.gzhead = null; /* gzip header information to write */ + this.gzindex = 0; /* where in extra, name, or comment */ + this.method = Z_DEFLATED; /* can only be DEFLATED */ + this.last_flush = -1; /* value of flush param for previous deflate call */ + + this.w_size = 0; /* LZ77 window size (32K by default) */ + this.w_bits = 0; /* log2(w_size) (8..16) */ + this.w_mask = 0; /* w_size - 1 */ + + this.window = null; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. + */ + + this.window_size = 0; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + this.prev = null; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + this.head = null; /* Heads of the hash chains or NIL. */ + + this.ins_h = 0; /* hash index of string to be inserted */ + this.hash_size = 0; /* number of elements in hash table */ + this.hash_bits = 0; /* log2(hash_size) */ + this.hash_mask = 0; /* hash_size-1 */ + + this.hash_shift = 0; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + this.block_start = 0; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + this.match_length = 0; /* length of best match */ + this.prev_match = 0; /* previous match */ + this.match_available = 0; /* set if previous match exists */ + this.strstart = 0; /* start of string to insert */ + this.match_start = 0; /* start of matching string */ + this.lookahead = 0; /* number of valid bytes ahead in window */ + + this.prev_length = 0; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + this.max_chain_length = 0; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + this.max_lazy_match = 0; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ + // That's alias to max_lazy_match, don't use directly + //this.max_insert_length = 0; + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + this.level = 0; /* compression level (1..9) */ + this.strategy = 0; /* favor or force Huffman coding*/ + + this.good_match = 0; + /* Use a faster search when the previous match is longer than this */ + + this.nice_match = 0; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + + /* Didn't use ct_data typedef below to suppress compiler warning */ + + // struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + // struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + // struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + // Use flat array of DOUBLE size, with interleaved fata, + // because JS does not support effective + this.dyn_ltree = new utils.Buf16(HEAP_SIZE * 2); + this.dyn_dtree = new utils.Buf16((2*D_CODES+1) * 2); + this.bl_tree = new utils.Buf16((2*BL_CODES+1) * 2); + zero(this.dyn_ltree); + zero(this.dyn_dtree); + zero(this.bl_tree); + + this.l_desc = null; /* desc. for literal tree */ + this.d_desc = null; /* desc. for distance tree */ + this.bl_desc = null; /* desc. for bit length tree */ + + //ush bl_count[MAX_BITS+1]; + this.bl_count = new utils.Buf16(MAX_BITS+1); + /* number of codes at each bit length for an optimal tree */ + + //int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + this.heap = new utils.Buf16(2*L_CODES+1); /* heap used to build the Huffman trees */ + zero(this.heap); + + this.heap_len = 0; /* number of elements in the heap */ + this.heap_max = 0; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + this.depth = new utils.Buf16(2*L_CODES+1); //uch depth[2*L_CODES+1]; + zero(this.depth); + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + this.l_buf = 0; /* buffer index for literals or lengths */ + + this.lit_bufsize = 0; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + this.last_lit = 0; /* running index in l_buf */ + + this.d_buf = 0; + /* Buffer index for distances. To simplify the code, d_buf and l_buf have + * the same number of elements. To use different lengths, an extra flag + * array would be necessary. + */ + + this.opt_len = 0; /* bit length of current block with optimal trees */ + this.static_len = 0; /* bit length of current block with static trees */ + this.matches = 0; /* number of string matches in current block */ + this.insert = 0; /* bytes at end of window left to insert */ + + + this.bi_buf = 0; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + this.bi_valid = 0; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + + // Used for window memory init. We safely ignore it for JS. That makes + // sense only for pointers and memory check tools. + //this.high_water = 0; + /* High water mark offset in window for initialized bytes -- bytes above + * this are set to zero in order to avoid memory check warnings when + * longest match routines access bytes past the input. This is then + * updated to the new high water mark. + */ +} + + +function deflateResetKeep(strm) { + var s; + + if (!strm || !strm.state) { + return err(strm, Z_STREAM_ERROR); + } + + strm.total_in = strm.total_out = 0; + strm.data_type = Z_UNKNOWN; + + s = strm.state; + s.pending = 0; + s.pending_out = 0; + + if (s.wrap < 0) { + s.wrap = -s.wrap; + /* was made negative by deflate(..., Z_FINISH); */ + } + s.status = (s.wrap ? INIT_STATE : BUSY_STATE); + strm.adler = (s.wrap === 2) ? + 0 // crc32(0, Z_NULL, 0) + : + 1; // adler32(0, Z_NULL, 0) + s.last_flush = Z_NO_FLUSH; + trees._tr_init(s); + return Z_OK; +} + + +function deflateReset(strm) { + var ret = deflateResetKeep(strm); + if (ret === Z_OK) { + lm_init(strm.state); + } + return ret; +} + + +function deflateSetHeader(strm, head) { + if (!strm || !strm.state) { return Z_STREAM_ERROR; } + if (strm.state.wrap !== 2) { return Z_STREAM_ERROR; } + strm.state.gzhead = head; + return Z_OK; +} + + +function deflateInit2(strm, level, method, windowBits, memLevel, strategy) { + if (!strm) { // === Z_NULL + return Z_STREAM_ERROR; + } + var wrap = 1; + + if (level === Z_DEFAULT_COMPRESSION) { + level = 6; + } + + if (windowBits < 0) { /* suppress zlib wrapper */ + wrap = 0; + windowBits = -windowBits; + } + + else if (windowBits > 15) { + wrap = 2; /* write gzip wrapper instead */ + windowBits -= 16; + } + + + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method !== Z_DEFLATED || + windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_FIXED) { + return err(strm, Z_STREAM_ERROR); + } + + + if (windowBits === 8) { + windowBits = 9; + } + /* until 256-byte window bug fixed */ + + var s = new DeflateState(); + + strm.state = s; + s.strm = strm; + + s.wrap = wrap; + s.gzhead = null; + s.w_bits = windowBits; + s.w_size = 1 << s.w_bits; + s.w_mask = s.w_size - 1; + + s.hash_bits = memLevel + 7; + s.hash_size = 1 << s.hash_bits; + s.hash_mask = s.hash_size - 1; + s.hash_shift = ~~((s.hash_bits + MIN_MATCH - 1) / MIN_MATCH); + + s.window = new utils.Buf8(s.w_size * 2); + s.head = new utils.Buf16(s.hash_size); + s.prev = new utils.Buf16(s.w_size); + + // Don't need mem init magic for JS. + //s.high_water = 0; /* nothing written to s->window yet */ + + s.lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + s.pending_buf_size = s.lit_bufsize * 4; + s.pending_buf = new utils.Buf8(s.pending_buf_size); + + s.d_buf = s.lit_bufsize >> 1; + s.l_buf = (1 + 2) * s.lit_bufsize; + + s.level = level; + s.strategy = strategy; + s.method = method; + + return deflateReset(strm); +} + +function deflateInit(strm, level) { + return deflateInit2(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY); +} + + +function deflate(strm, flush) { + var old_flush, s; + var beg, val; // for gzip header write only + + if (!strm || !strm.state || + flush > Z_BLOCK || flush < 0) { + return strm ? err(strm, Z_STREAM_ERROR) : Z_STREAM_ERROR; + } + + s = strm.state; + + if (!strm.output || + (!strm.input && strm.avail_in !== 0) || + (s.status === FINISH_STATE && flush !== Z_FINISH)) { + return err(strm, (strm.avail_out === 0) ? Z_BUF_ERROR : Z_STREAM_ERROR); + } + + s.strm = strm; /* just in case */ + old_flush = s.last_flush; + s.last_flush = flush; + + /* Write the header */ + if (s.status === INIT_STATE) { + + if (s.wrap === 2) { // GZIP header + strm.adler = 0; //crc32(0L, Z_NULL, 0); + put_byte(s, 31); + put_byte(s, 139); + put_byte(s, 8); + if (!s.gzhead) { // s->gzhead == Z_NULL + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, s.level === 9 ? 2 : + (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ? + 4 : 0)); + put_byte(s, OS_CODE); + s.status = BUSY_STATE; + } + else { + put_byte(s, (s.gzhead.text ? 1 : 0) + + (s.gzhead.hcrc ? 2 : 0) + + (!s.gzhead.extra ? 0 : 4) + + (!s.gzhead.name ? 0 : 8) + + (!s.gzhead.comment ? 0 : 16) + ); + put_byte(s, s.gzhead.time & 0xff); + put_byte(s, (s.gzhead.time >> 8) & 0xff); + put_byte(s, (s.gzhead.time >> 16) & 0xff); + put_byte(s, (s.gzhead.time >> 24) & 0xff); + put_byte(s, s.level === 9 ? 2 : + (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ? + 4 : 0)); + put_byte(s, s.gzhead.os & 0xff); + if (s.gzhead.extra && s.gzhead.extra.length) { + put_byte(s, s.gzhead.extra.length & 0xff); + put_byte(s, (s.gzhead.extra.length >> 8) & 0xff); + } + if (s.gzhead.hcrc) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending, 0); + } + s.gzindex = 0; + s.status = EXTRA_STATE; + } + } + else // DEFLATE header + { + var header = (Z_DEFLATED + ((s.w_bits - 8) << 4)) << 8; + var level_flags = -1; + + if (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2) { + level_flags = 0; + } else if (s.level < 6) { + level_flags = 1; + } else if (s.level === 6) { + level_flags = 2; + } else { + level_flags = 3; + } + header |= (level_flags << 6); + if (s.strstart !== 0) { header |= PRESET_DICT; } + header += 31 - (header % 31); + + s.status = BUSY_STATE; + putShortMSB(s, header); + + /* Save the adler32 of the preset dictionary: */ + if (s.strstart !== 0) { + putShortMSB(s, strm.adler >>> 16); + putShortMSB(s, strm.adler & 0xffff); + } + strm.adler = 1; // adler32(0L, Z_NULL, 0); + } + } + +//#ifdef GZIP + if (s.status === EXTRA_STATE) { + if (s.gzhead.extra/* != Z_NULL*/) { + beg = s.pending; /* start of bytes to update crc */ + + while (s.gzindex < (s.gzhead.extra.length & 0xffff)) { + if (s.pending === s.pending_buf_size) { + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); + } + flush_pending(strm); + beg = s.pending; + if (s.pending === s.pending_buf_size) { + break; + } + } + put_byte(s, s.gzhead.extra[s.gzindex] & 0xff); + s.gzindex++; + } + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); + } + if (s.gzindex === s.gzhead.extra.length) { + s.gzindex = 0; + s.status = NAME_STATE; + } + } + else { + s.status = NAME_STATE; + } + } + if (s.status === NAME_STATE) { + if (s.gzhead.name/* != Z_NULL*/) { + beg = s.pending; /* start of bytes to update crc */ + //int val; + + do { + if (s.pending === s.pending_buf_size) { + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); + } + flush_pending(strm); + beg = s.pending; + if (s.pending === s.pending_buf_size) { + val = 1; + break; + } + } + // JS specific: little magic to add zero terminator to end of string + if (s.gzindex < s.gzhead.name.length) { + val = s.gzhead.name.charCodeAt(s.gzindex++) & 0xff; + } else { + val = 0; + } + put_byte(s, val); + } while (val !== 0); + + if (s.gzhead.hcrc && s.pending > beg){ + strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); + } + if (val === 0) { + s.gzindex = 0; + s.status = COMMENT_STATE; + } + } + else { + s.status = COMMENT_STATE; + } + } + if (s.status === COMMENT_STATE) { + if (s.gzhead.comment/* != Z_NULL*/) { + beg = s.pending; /* start of bytes to update crc */ + //int val; + + do { + if (s.pending === s.pending_buf_size) { + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); + } + flush_pending(strm); + beg = s.pending; + if (s.pending === s.pending_buf_size) { + val = 1; + break; + } + } + // JS specific: little magic to add zero terminator to end of string + if (s.gzindex < s.gzhead.comment.length) { + val = s.gzhead.comment.charCodeAt(s.gzindex++) & 0xff; + } else { + val = 0; + } + put_byte(s, val); + } while (val !== 0); + + if (s.gzhead.hcrc && s.pending > beg) { + strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg); + } + if (val === 0) { + s.status = HCRC_STATE; + } + } + else { + s.status = HCRC_STATE; + } + } + if (s.status === HCRC_STATE) { + if (s.gzhead.hcrc) { + if (s.pending + 2 > s.pending_buf_size) { + flush_pending(strm); + } + if (s.pending + 2 <= s.pending_buf_size) { + put_byte(s, strm.adler & 0xff); + put_byte(s, (strm.adler >> 8) & 0xff); + strm.adler = 0; //crc32(0L, Z_NULL, 0); + s.status = BUSY_STATE; + } + } + else { + s.status = BUSY_STATE; + } + } +//#endif + + /* Flush as much pending output as possible */ + if (s.pending !== 0) { + flush_pending(strm); + if (strm.avail_out === 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s.last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUF_ERROR. + */ + } else if (strm.avail_in === 0 && rank(flush) <= rank(old_flush) && + flush !== Z_FINISH) { + return err(strm, Z_BUF_ERROR); + } + + /* User must not provide more input after the first FINISH: */ + if (s.status === FINISH_STATE && strm.avail_in !== 0) { + return err(strm, Z_BUF_ERROR); + } + + /* Start a new block or continue the current one. + */ + if (strm.avail_in !== 0 || s.lookahead !== 0 || + (flush !== Z_NO_FLUSH && s.status !== FINISH_STATE)) { + var bstate = (s.strategy === Z_HUFFMAN_ONLY) ? deflate_huff(s, flush) : + (s.strategy === Z_RLE ? deflate_rle(s, flush) : + configuration_table[s.level].func(s, flush)); + + if (bstate === BS_FINISH_STARTED || bstate === BS_FINISH_DONE) { + s.status = FINISH_STATE; + } + if (bstate === BS_NEED_MORE || bstate === BS_FINISH_STARTED) { + if (strm.avail_out === 0) { + s.last_flush = -1; + /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate === BS_BLOCK_DONE) { + if (flush === Z_PARTIAL_FLUSH) { + trees._tr_align(s); + } + else if (flush !== Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ + + trees._tr_stored_block(s, 0, 0, false); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush === Z_FULL_FLUSH) { + /*** CLEAR_HASH(s); ***/ /* forget history */ + zero(s.head); // Fill with NIL (= 0); + + if (s.lookahead === 0) { + s.strstart = 0; + s.block_start = 0; + s.insert = 0; + } + } + } + flush_pending(strm); + if (strm.avail_out === 0) { + s.last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + //Assert(strm->avail_out > 0, "bug2"); + //if (strm.avail_out <= 0) { throw new Error("bug2");} + + if (flush !== Z_FINISH) { return Z_OK; } + if (s.wrap <= 0) { return Z_STREAM_END; } + + /* Write the trailer */ + if (s.wrap === 2) { + put_byte(s, strm.adler & 0xff); + put_byte(s, (strm.adler >> 8) & 0xff); + put_byte(s, (strm.adler >> 16) & 0xff); + put_byte(s, (strm.adler >> 24) & 0xff); + put_byte(s, strm.total_in & 0xff); + put_byte(s, (strm.total_in >> 8) & 0xff); + put_byte(s, (strm.total_in >> 16) & 0xff); + put_byte(s, (strm.total_in >> 24) & 0xff); + } + else + { + putShortMSB(s, strm.adler >>> 16); + putShortMSB(s, strm.adler & 0xffff); + } + + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + if (s.wrap > 0) { s.wrap = -s.wrap; } + /* write the trailer only once! */ + return s.pending !== 0 ? Z_OK : Z_STREAM_END; +} + +function deflateEnd(strm) { + var status; + + if (!strm/*== Z_NULL*/ || !strm.state/*== Z_NULL*/) { + return Z_STREAM_ERROR; + } + + status = strm.state.status; + if (status !== INIT_STATE && + status !== EXTRA_STATE && + status !== NAME_STATE && + status !== COMMENT_STATE && + status !== HCRC_STATE && + status !== BUSY_STATE && + status !== FINISH_STATE + ) { + return err(strm, Z_STREAM_ERROR); + } + + strm.state = null; + + return status === BUSY_STATE ? err(strm, Z_DATA_ERROR) : Z_OK; +} + +/* ========================================================================= + * Copy the source state to the destination state + */ +//function deflateCopy(dest, source) { +// +//} + +exports.deflateInit = deflateInit; +exports.deflateInit2 = deflateInit2; +exports.deflateReset = deflateReset; +exports.deflateResetKeep = deflateResetKeep; +exports.deflateSetHeader = deflateSetHeader; +exports.deflate = deflate; +exports.deflateEnd = deflateEnd; +exports.deflateInfo = 'pako deflate (from Nodeca project)'; + +/* Not implemented +exports.deflateBound = deflateBound; +exports.deflateCopy = deflateCopy; +exports.deflateSetDictionary = deflateSetDictionary; +exports.deflateParams = deflateParams; +exports.deflatePending = deflatePending; +exports.deflatePrime = deflatePrime; +exports.deflateTune = deflateTune; +*/ +},{"../utils/common":27,"./adler32":29,"./crc32":31,"./messages":37,"./trees":38}],33:[function(_dereq_,module,exports){ +'use strict'; + + +function GZheader() { + /* true if compressed data believed to be text */ + this.text = 0; + /* modification time */ + this.time = 0; + /* extra flags (not used when writing a gzip file) */ + this.xflags = 0; + /* operating system */ + this.os = 0; + /* pointer to extra field or Z_NULL if none */ + this.extra = null; + /* extra field length (valid if extra != Z_NULL) */ + this.extra_len = 0; // Actually, we don't need it in JS, + // but leave for few code modifications + + // + // Setup limits is not necessary because in js we should not preallocate memory + // for inflate use constant limit in 65536 bytes + // + + /* space at extra (only when reading header) */ + // this.extra_max = 0; + /* pointer to zero-terminated file name or Z_NULL */ + this.name = ''; + /* space at name (only when reading header) */ + // this.name_max = 0; + /* pointer to zero-terminated comment or Z_NULL */ + this.comment = ''; + /* space at comment (only when reading header) */ + // this.comm_max = 0; + /* true if there was or will be a header crc */ + this.hcrc = 0; + /* true when done reading gzip header (not used when writing a gzip file) */ + this.done = false; +} + +module.exports = GZheader; +},{}],34:[function(_dereq_,module,exports){ +'use strict'; + +// See state defs from inflate.js +var BAD = 30; /* got a data error -- remain here until reset */ +var TYPE = 12; /* i: waiting for type bits, including last-flag bit */ + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state.mode === LEN + strm.avail_in >= 6 + strm.avail_out >= 258 + start >= strm.avail_out + state.bits < 8 + + On return, state.mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm.avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm.avail_out >= 258 for each loop to avoid checking for + output space. + */ +module.exports = function inflate_fast(strm, start) { + var state; + var _in; /* local strm.input */ + var last; /* have enough input while in < last */ + var _out; /* local strm.output */ + var beg; /* inflate()'s initial strm.output */ + var end; /* while out < end, enough space available */ +//#ifdef INFLATE_STRICT + var dmax; /* maximum distance from zlib header */ +//#endif + var wsize; /* window size or zero if not using window */ + var whave; /* valid bytes in the window */ + var wnext; /* window write index */ + var window; /* allocated sliding window, if wsize != 0 */ + var hold; /* local strm.hold */ + var bits; /* local strm.bits */ + var lcode; /* local strm.lencode */ + var dcode; /* local strm.distcode */ + var lmask; /* mask for first level of length codes */ + var dmask; /* mask for first level of distance codes */ + var here; /* retrieved table entry */ + var op; /* code bits, operation, extra bits, or */ + /* window position, window bytes to copy */ + var len; /* match length, unused bytes */ + var dist; /* match distance */ + var from; /* where to copy match from */ + var from_source; + + + var input, output; // JS specific, because we have no pointers + + /* copy state to local variables */ + state = strm.state; + //here = state.here; + _in = strm.next_in; + input = strm.input; + last = _in + (strm.avail_in - 5); + _out = strm.next_out; + output = strm.output; + beg = _out - (start - strm.avail_out); + end = _out + (strm.avail_out - 257); +//#ifdef INFLATE_STRICT + dmax = state.dmax; +//#endif + wsize = state.wsize; + whave = state.whave; + wnext = state.wnext; + window = state.window; + hold = state.hold; + bits = state.bits; + lcode = state.lencode; + dcode = state.distcode; + lmask = (1 << state.lenbits) - 1; + dmask = (1 << state.distbits) - 1; + + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + + top: + do { + if (bits < 15) { + hold += input[_in++] << bits; + bits += 8; + hold += input[_in++] << bits; + bits += 8; + } + + here = lcode[hold & lmask]; + + dolen: + for (;;) { // Goto emulation + op = here >>> 24/*here.bits*/; + hold >>>= op; + bits -= op; + op = (here >>> 16) & 0xff/*here.op*/; + if (op === 0) { /* literal */ + //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + // "inflate: literal '%c'\n" : + // "inflate: literal 0x%02x\n", here.val)); + output[_out++] = here & 0xffff/*here.val*/; + } + else if (op & 16) { /* length base */ + len = here & 0xffff/*here.val*/; + op &= 15; /* number of extra bits */ + if (op) { + if (bits < op) { + hold += input[_in++] << bits; + bits += 8; + } + len += hold & ((1 << op) - 1); + hold >>>= op; + bits -= op; + } + //Tracevv((stderr, "inflate: length %u\n", len)); + if (bits < 15) { + hold += input[_in++] << bits; + bits += 8; + hold += input[_in++] << bits; + bits += 8; + } + here = dcode[hold & dmask]; + + dodist: + for (;;) { // goto emulation + op = here >>> 24/*here.bits*/; + hold >>>= op; + bits -= op; + op = (here >>> 16) & 0xff/*here.op*/; + + if (op & 16) { /* distance base */ + dist = here & 0xffff/*here.val*/; + op &= 15; /* number of extra bits */ + if (bits < op) { + hold += input[_in++] << bits; + bits += 8; + if (bits < op) { + hold += input[_in++] << bits; + bits += 8; + } + } + dist += hold & ((1 << op) - 1); +//#ifdef INFLATE_STRICT + if (dist > dmax) { + strm.msg = 'invalid distance too far back'; + state.mode = BAD; + break top; + } +//#endif + hold >>>= op; + bits -= op; + //Tracevv((stderr, "inflate: distance %u\n", dist)); + op = _out - beg; /* max distance in output */ + if (dist > op) { /* see if copy from window */ + op = dist - op; /* distance back in window */ + if (op > whave) { + if (state.sane) { + strm.msg = 'invalid distance too far back'; + state.mode = BAD; + break top; + } + +// (!) This block is disabled in zlib defailts, +// don't enable it for binary compatibility +//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR +// if (len <= op - whave) { +// do { +// output[_out++] = 0; +// } while (--len); +// continue top; +// } +// len -= op - whave; +// do { +// output[_out++] = 0; +// } while (--op > whave); +// if (op === 0) { +// from = _out - dist; +// do { +// output[_out++] = output[from++]; +// } while (--len); +// continue top; +// } +//#endif + } + from = 0; // window index + from_source = window; + if (wnext === 0) { /* very common case */ + from += wsize - op; + if (op < len) { /* some from window */ + len -= op; + do { + output[_out++] = window[from++]; + } while (--op); + from = _out - dist; /* rest from output */ + from_source = output; + } + } + else if (wnext < op) { /* wrap around window */ + from += wsize + wnext - op; + op -= wnext; + if (op < len) { /* some from end of window */ + len -= op; + do { + output[_out++] = window[from++]; + } while (--op); + from = 0; + if (wnext < len) { /* some from start of window */ + op = wnext; + len -= op; + do { + output[_out++] = window[from++]; + } while (--op); + from = _out - dist; /* rest from output */ + from_source = output; + } + } + } + else { /* contiguous in window */ + from += wnext - op; + if (op < len) { /* some from window */ + len -= op; + do { + output[_out++] = window[from++]; + } while (--op); + from = _out - dist; /* rest from output */ + from_source = output; + } + } + while (len > 2) { + output[_out++] = from_source[from++]; + output[_out++] = from_source[from++]; + output[_out++] = from_source[from++]; + len -= 3; + } + if (len) { + output[_out++] = from_source[from++]; + if (len > 1) { + output[_out++] = from_source[from++]; + } + } + } + else { + from = _out - dist; /* copy direct from output */ + do { /* minimum length is three */ + output[_out++] = output[from++]; + output[_out++] = output[from++]; + output[_out++] = output[from++]; + len -= 3; + } while (len > 2); + if (len) { + output[_out++] = output[from++]; + if (len > 1) { + output[_out++] = output[from++]; + } + } + } + } + else if ((op & 64) === 0) { /* 2nd level distance code */ + here = dcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))]; + continue dodist; + } + else { + strm.msg = 'invalid distance code'; + state.mode = BAD; + break top; + } + + break; // need to emulate goto via "continue" + } + } + else if ((op & 64) === 0) { /* 2nd level length code */ + here = lcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))]; + continue dolen; + } + else if (op & 32) { /* end-of-block */ + //Tracevv((stderr, "inflate: end of block\n")); + state.mode = TYPE; + break top; + } + else { + strm.msg = 'invalid literal/length code'; + state.mode = BAD; + break top; + } + + break; // need to emulate goto via "continue" + } + } while (_in < last && _out < end); + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + len = bits >> 3; + _in -= len; + bits -= len << 3; + hold &= (1 << bits) - 1; + + /* update state and return */ + strm.next_in = _in; + strm.next_out = _out; + strm.avail_in = (_in < last ? 5 + (last - _in) : 5 - (_in - last)); + strm.avail_out = (_out < end ? 257 + (end - _out) : 257 - (_out - end)); + state.hold = hold; + state.bits = bits; + return; +}; + +},{}],35:[function(_dereq_,module,exports){ +'use strict'; + + +var utils = _dereq_('../utils/common'); +var adler32 = _dereq_('./adler32'); +var crc32 = _dereq_('./crc32'); +var inflate_fast = _dereq_('./inffast'); +var inflate_table = _dereq_('./inftrees'); + +var CODES = 0; +var LENS = 1; +var DISTS = 2; + +/* Public constants ==========================================================*/ +/* ===========================================================================*/ + + +/* Allowed flush values; see deflate() and inflate() below for details */ +//var Z_NO_FLUSH = 0; +//var Z_PARTIAL_FLUSH = 1; +//var Z_SYNC_FLUSH = 2; +//var Z_FULL_FLUSH = 3; +var Z_FINISH = 4; +var Z_BLOCK = 5; +var Z_TREES = 6; + + +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ +var Z_OK = 0; +var Z_STREAM_END = 1; +var Z_NEED_DICT = 2; +//var Z_ERRNO = -1; +var Z_STREAM_ERROR = -2; +var Z_DATA_ERROR = -3; +var Z_MEM_ERROR = -4; +var Z_BUF_ERROR = -5; +//var Z_VERSION_ERROR = -6; + +/* The deflate compression method */ +var Z_DEFLATED = 8; + + +/* STATES ====================================================================*/ +/* ===========================================================================*/ + + +var HEAD = 1; /* i: waiting for magic header */ +var FLAGS = 2; /* i: waiting for method and flags (gzip) */ +var TIME = 3; /* i: waiting for modification time (gzip) */ +var OS = 4; /* i: waiting for extra flags and operating system (gzip) */ +var EXLEN = 5; /* i: waiting for extra length (gzip) */ +var EXTRA = 6; /* i: waiting for extra bytes (gzip) */ +var NAME = 7; /* i: waiting for end of file name (gzip) */ +var COMMENT = 8; /* i: waiting for end of comment (gzip) */ +var HCRC = 9; /* i: waiting for header crc (gzip) */ +var DICTID = 10; /* i: waiting for dictionary check value */ +var DICT = 11; /* waiting for inflateSetDictionary() call */ +var TYPE = 12; /* i: waiting for type bits, including last-flag bit */ +var TYPEDO = 13; /* i: same, but skip check to exit inflate on new block */ +var STORED = 14; /* i: waiting for stored size (length and complement) */ +var COPY_ = 15; /* i/o: same as COPY below, but only first time in */ +var COPY = 16; /* i/o: waiting for input or output to copy stored block */ +var TABLE = 17; /* i: waiting for dynamic block table lengths */ +var LENLENS = 18; /* i: waiting for code length code lengths */ +var CODELENS = 19; /* i: waiting for length/lit and distance code lengths */ +var LEN_ = 20; /* i: same as LEN below, but only first time in */ +var LEN = 21; /* i: waiting for length/lit/eob code */ +var LENEXT = 22; /* i: waiting for length extra bits */ +var DIST = 23; /* i: waiting for distance code */ +var DISTEXT = 24; /* i: waiting for distance extra bits */ +var MATCH = 25; /* o: waiting for output space to copy string */ +var LIT = 26; /* o: waiting for output space to write literal */ +var CHECK = 27; /* i: waiting for 32-bit check value */ +var LENGTH = 28; /* i: waiting for 32-bit length (gzip) */ +var DONE = 29; /* finished check, done -- remain here until reset */ +var BAD = 30; /* got a data error -- remain here until reset */ +var MEM = 31; /* got an inflate() memory error -- remain here until reset */ +var SYNC = 32; /* looking for synchronization bytes to restart inflate() */ + +/* ===========================================================================*/ + + + +var ENOUGH_LENS = 852; +var ENOUGH_DISTS = 592; +//var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS); + +var MAX_WBITS = 15; +/* 32K LZ77 window */ +var DEF_WBITS = MAX_WBITS; + + +function ZSWAP32(q) { + return (((q >>> 24) & 0xff) + + ((q >>> 8) & 0xff00) + + ((q & 0xff00) << 8) + + ((q & 0xff) << 24)); +} + + +function InflateState() { + this.mode = 0; /* current inflate mode */ + this.last = false; /* true if processing last block */ + this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */ + this.havedict = false; /* true if dictionary provided */ + this.flags = 0; /* gzip header method and flags (0 if zlib) */ + this.dmax = 0; /* zlib header max distance (INFLATE_STRICT) */ + this.check = 0; /* protected copy of check value */ + this.total = 0; /* protected copy of output count */ + // TODO: may be {} + this.head = null; /* where to save gzip header information */ + + /* sliding window */ + this.wbits = 0; /* log base 2 of requested window size */ + this.wsize = 0; /* window size or zero if not using window */ + this.whave = 0; /* valid bytes in the window */ + this.wnext = 0; /* window write index */ + this.window = null; /* allocated sliding window, if needed */ + + /* bit accumulator */ + this.hold = 0; /* input bit accumulator */ + this.bits = 0; /* number of bits in "in" */ + + /* for string and stored block copying */ + this.length = 0; /* literal or length of data to copy */ + this.offset = 0; /* distance back to copy string from */ + + /* for table and code decoding */ + this.extra = 0; /* extra bits needed */ + + /* fixed and dynamic code tables */ + this.lencode = null; /* starting table for length/literal codes */ + this.distcode = null; /* starting table for distance codes */ + this.lenbits = 0; /* index bits for lencode */ + this.distbits = 0; /* index bits for distcode */ + + /* dynamic table building */ + this.ncode = 0; /* number of code length code lengths */ + this.nlen = 0; /* number of length code lengths */ + this.ndist = 0; /* number of distance code lengths */ + this.have = 0; /* number of code lengths in lens[] */ + this.next = null; /* next available space in codes[] */ + + this.lens = new utils.Buf16(320); /* temporary storage for code lengths */ + this.work = new utils.Buf16(288); /* work area for code table building */ + + /* + because we don't have pointers in js, we use lencode and distcode directly + as buffers so we don't need codes + */ + //this.codes = new utils.Buf32(ENOUGH); /* space for code tables */ + this.lendyn = null; /* dynamic table for length/literal codes (JS specific) */ + this.distdyn = null; /* dynamic table for distance codes (JS specific) */ + this.sane = 0; /* if false, allow invalid distance too far */ + this.back = 0; /* bits back of last unprocessed length/lit */ + this.was = 0; /* initial length of match */ +} + +function inflateResetKeep(strm) { + var state; + + if (!strm || !strm.state) { return Z_STREAM_ERROR; } + state = strm.state; + strm.total_in = strm.total_out = state.total = 0; + strm.msg = ''; /*Z_NULL*/ + if (state.wrap) { /* to support ill-conceived Java test suite */ + strm.adler = state.wrap & 1; + } + state.mode = HEAD; + state.last = 0; + state.havedict = 0; + state.dmax = 32768; + state.head = null/*Z_NULL*/; + state.hold = 0; + state.bits = 0; + //state.lencode = state.distcode = state.next = state.codes; + state.lencode = state.lendyn = new utils.Buf32(ENOUGH_LENS); + state.distcode = state.distdyn = new utils.Buf32(ENOUGH_DISTS); + + state.sane = 1; + state.back = -1; + //Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + +function inflateReset(strm) { + var state; + + if (!strm || !strm.state) { return Z_STREAM_ERROR; } + state = strm.state; + state.wsize = 0; + state.whave = 0; + state.wnext = 0; + return inflateResetKeep(strm); + +} + +function inflateReset2(strm, windowBits) { + var wrap; + var state; + + /* get the state */ + if (!strm || !strm.state) { return Z_STREAM_ERROR; } + state = strm.state; + + /* extract wrap request from windowBits parameter */ + if (windowBits < 0) { + wrap = 0; + windowBits = -windowBits; + } + else { + wrap = (windowBits >> 4) + 1; + if (windowBits < 48) { + windowBits &= 15; + } + } + + /* set number of window bits, free window if different */ + if (windowBits && (windowBits < 8 || windowBits > 15)) { + return Z_STREAM_ERROR; + } + if (state.window !== null && state.wbits !== windowBits) { + state.window = null; + } + + /* update state and reset the rest of it */ + state.wrap = wrap; + state.wbits = windowBits; + return inflateReset(strm); +} + +function inflateInit2(strm, windowBits) { + var ret; + var state; + + if (!strm) { return Z_STREAM_ERROR; } + //strm.msg = Z_NULL; /* in case we return an error */ + + state = new InflateState(); + + //if (state === Z_NULL) return Z_MEM_ERROR; + //Tracev((stderr, "inflate: allocated\n")); + strm.state = state; + state.window = null/*Z_NULL*/; + ret = inflateReset2(strm, windowBits); + if (ret !== Z_OK) { + strm.state = null/*Z_NULL*/; + } + return ret; +} + +function inflateInit(strm) { + return inflateInit2(strm, DEF_WBITS); +} + + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +var virgin = true; + +var lenfix, distfix; // We have no pointers in JS, so keep tables separate + +function fixedtables(state) { + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + var sym; + + lenfix = new utils.Buf32(512); + distfix = new utils.Buf32(32); + + /* literal/length table */ + sym = 0; + while (sym < 144) { state.lens[sym++] = 8; } + while (sym < 256) { state.lens[sym++] = 9; } + while (sym < 280) { state.lens[sym++] = 7; } + while (sym < 288) { state.lens[sym++] = 8; } + + inflate_table(LENS, state.lens, 0, 288, lenfix, 0, state.work, {bits: 9}); + + /* distance table */ + sym = 0; + while (sym < 32) { state.lens[sym++] = 5; } + + inflate_table(DISTS, state.lens, 0, 32, distfix, 0, state.work, {bits: 5}); + + /* do this just once */ + virgin = false; + } + + state.lencode = lenfix; + state.lenbits = 9; + state.distcode = distfix; + state.distbits = 5; +} + + +/* + Update the window with the last wsize (normally 32K) bytes written before + returning. If window does not exist yet, create it. This is only called + when a window is already in use, or when output has been written during this + inflate call, but the end of the deflate stream has not been reached yet. + It is also called to create a window for dictionary data when a dictionary + is loaded. + + Providing output buffers larger than 32K to inflate() should provide a speed + advantage, since only the last 32K of output is copied to the sliding window + upon return from inflate(), and since all distances after the first 32K of + output will fall in the output data, making match copies simpler and faster. + The advantage may be dependent on the size of the processor's data caches. + */ +function updatewindow(strm, src, end, copy) { + var dist; + var state = strm.state; + + /* if it hasn't been done already, allocate space for the window */ + if (state.window === null) { + state.wsize = 1 << state.wbits; + state.wnext = 0; + state.whave = 0; + + state.window = new utils.Buf8(state.wsize); + } + + /* copy state->wsize or less output bytes into the circular window */ + if (copy >= state.wsize) { + utils.arraySet(state.window,src, end - state.wsize, state.wsize, 0); + state.wnext = 0; + state.whave = state.wsize; + } + else { + dist = state.wsize - state.wnext; + if (dist > copy) { + dist = copy; + } + //zmemcpy(state->window + state->wnext, end - copy, dist); + utils.arraySet(state.window,src, end - copy, dist, state.wnext); + copy -= dist; + if (copy) { + //zmemcpy(state->window, end - copy, copy); + utils.arraySet(state.window,src, end - copy, copy, 0); + state.wnext = copy; + state.whave = state.wsize; + } + else { + state.wnext += dist; + if (state.wnext === state.wsize) { state.wnext = 0; } + if (state.whave < state.wsize) { state.whave += dist; } + } + } + return 0; +} + +function inflate(strm, flush) { + var state; + var input, output; // input/output buffers + var next; /* next input INDEX */ + var put; /* next output INDEX */ + var have, left; /* available input and output */ + var hold; /* bit buffer */ + var bits; /* bits in bit buffer */ + var _in, _out; /* save starting available input and output */ + var copy; /* number of stored or match bytes to copy */ + var from; /* where to copy match bytes from */ + var from_source; + var here = 0; /* current decoding table entry */ + var here_bits, here_op, here_val; // paked "here" denormalized (JS specific) + //var last; /* parent table entry */ + var last_bits, last_op, last_val; // paked "last" denormalized (JS specific) + var len; /* length to copy for repeats, bits to drop */ + var ret; /* return code */ + var hbuf = new utils.Buf8(4); /* buffer for gzip header crc calculation */ + var opts; + + var n; // temporary var for NEED_BITS + + var order = /* permutation of code lengths */ + [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]; + + + if (!strm || !strm.state || !strm.output || + (!strm.input && strm.avail_in !== 0)) { + return Z_STREAM_ERROR; + } + + state = strm.state; + if (state.mode === TYPE) { state.mode = TYPEDO; } /* skip check */ + + + //--- LOAD() --- + put = strm.next_out; + output = strm.output; + left = strm.avail_out; + next = strm.next_in; + input = strm.input; + have = strm.avail_in; + hold = state.hold; + bits = state.bits; + //--- + + _in = have; + _out = left; + ret = Z_OK; + + inf_leave: // goto emulation + for (;;) { + switch (state.mode) { + case HEAD: + if (state.wrap === 0) { + state.mode = TYPEDO; + break; + } + //=== NEEDBITS(16); + while (bits < 16) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if ((state.wrap & 2) && hold === 0x8b1f) { /* gzip header */ + state.check = 0/*crc32(0L, Z_NULL, 0)*/; + //=== CRC2(state.check, hold); + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + state.check = crc32(state.check, hbuf, 2, 0); + //===// + + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = FLAGS; + break; + } + state.flags = 0; /* expect zlib header */ + if (state.head) { + state.head.done = false; + } + if (!(state.wrap & 1) || /* check if zlib header allowed */ + (((hold & 0xff)/*BITS(8)*/ << 8) + (hold >> 8)) % 31) { + strm.msg = 'incorrect header check'; + state.mode = BAD; + break; + } + if ((hold & 0x0f)/*BITS(4)*/ !== Z_DEFLATED) { + strm.msg = 'unknown compression method'; + state.mode = BAD; + break; + } + //--- DROPBITS(4) ---// + hold >>>= 4; + bits -= 4; + //---// + len = (hold & 0x0f)/*BITS(4)*/ + 8; + if (state.wbits === 0) { + state.wbits = len; + } + else if (len > state.wbits) { + strm.msg = 'invalid window size'; + state.mode = BAD; + break; + } + state.dmax = 1 << len; + //Tracev((stderr, "inflate: zlib header ok\n")); + strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/; + state.mode = hold & 0x200 ? DICTID : TYPE; + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + break; + case FLAGS: + //=== NEEDBITS(16); */ + while (bits < 16) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.flags = hold; + if ((state.flags & 0xff) !== Z_DEFLATED) { + strm.msg = 'unknown compression method'; + state.mode = BAD; + break; + } + if (state.flags & 0xe000) { + strm.msg = 'unknown header flags set'; + state.mode = BAD; + break; + } + if (state.head) { + state.head.text = ((hold >> 8) & 1); + } + if (state.flags & 0x0200) { + //=== CRC2(state.check, hold); + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + state.check = crc32(state.check, hbuf, 2, 0); + //===// + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = TIME; + /* falls through */ + case TIME: + //=== NEEDBITS(32); */ + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if (state.head) { + state.head.time = hold; + } + if (state.flags & 0x0200) { + //=== CRC4(state.check, hold) + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + hbuf[2] = (hold >>> 16) & 0xff; + hbuf[3] = (hold >>> 24) & 0xff; + state.check = crc32(state.check, hbuf, 4, 0); + //=== + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = OS; + /* falls through */ + case OS: + //=== NEEDBITS(16); */ + while (bits < 16) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if (state.head) { + state.head.xflags = (hold & 0xff); + state.head.os = (hold >> 8); + } + if (state.flags & 0x0200) { + //=== CRC2(state.check, hold); + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + state.check = crc32(state.check, hbuf, 2, 0); + //===// + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = EXLEN; + /* falls through */ + case EXLEN: + if (state.flags & 0x0400) { + //=== NEEDBITS(16); */ + while (bits < 16) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.length = hold; + if (state.head) { + state.head.extra_len = hold; + } + if (state.flags & 0x0200) { + //=== CRC2(state.check, hold); + hbuf[0] = hold & 0xff; + hbuf[1] = (hold >>> 8) & 0xff; + state.check = crc32(state.check, hbuf, 2, 0); + //===// + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + } + else if (state.head) { + state.head.extra = null/*Z_NULL*/; + } + state.mode = EXTRA; + /* falls through */ + case EXTRA: + if (state.flags & 0x0400) { + copy = state.length; + if (copy > have) { copy = have; } + if (copy) { + if (state.head) { + len = state.head.extra_len - state.length; + if (!state.head.extra) { + // Use untyped array for more conveniend processing later + state.head.extra = new Array(state.head.extra_len); + } + utils.arraySet( + state.head.extra, + input, + next, + // extra field is limited to 65536 bytes + // - no need for additional size check + copy, + /*len + copy > state.head.extra_max - len ? state.head.extra_max : copy,*/ + len + ); + //zmemcpy(state.head.extra + len, next, + // len + copy > state.head.extra_max ? + // state.head.extra_max - len : copy); + } + if (state.flags & 0x0200) { + state.check = crc32(state.check, input, copy, next); + } + have -= copy; + next += copy; + state.length -= copy; + } + if (state.length) { break inf_leave; } + } + state.length = 0; + state.mode = NAME; + /* falls through */ + case NAME: + if (state.flags & 0x0800) { + if (have === 0) { break inf_leave; } + copy = 0; + do { + // TODO: 2 or 1 bytes? + len = input[next + copy++]; + /* use constant limit because in js we should not preallocate memory */ + if (state.head && len && + (state.length < 65536 /*state.head.name_max*/)) { + state.head.name += String.fromCharCode(len); + } + } while (len && copy < have); + + if (state.flags & 0x0200) { + state.check = crc32(state.check, input, copy, next); + } + have -= copy; + next += copy; + if (len) { break inf_leave; } + } + else if (state.head) { + state.head.name = null; + } + state.length = 0; + state.mode = COMMENT; + /* falls through */ + case COMMENT: + if (state.flags & 0x1000) { + if (have === 0) { break inf_leave; } + copy = 0; + do { + len = input[next + copy++]; + /* use constant limit because in js we should not preallocate memory */ + if (state.head && len && + (state.length < 65536 /*state.head.comm_max*/)) { + state.head.comment += String.fromCharCode(len); + } + } while (len && copy < have); + if (state.flags & 0x0200) { + state.check = crc32(state.check, input, copy, next); + } + have -= copy; + next += copy; + if (len) { break inf_leave; } + } + else if (state.head) { + state.head.comment = null; + } + state.mode = HCRC; + /* falls through */ + case HCRC: + if (state.flags & 0x0200) { + //=== NEEDBITS(16); */ + while (bits < 16) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if (hold !== (state.check & 0xffff)) { + strm.msg = 'header crc mismatch'; + state.mode = BAD; + break; + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + } + if (state.head) { + state.head.hcrc = ((state.flags >> 9) & 1); + state.head.done = true; + } + strm.adler = state.check = 0 /*crc32(0L, Z_NULL, 0)*/; + state.mode = TYPE; + break; + case DICTID: + //=== NEEDBITS(32); */ + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + strm.adler = state.check = ZSWAP32(hold); + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = DICT; + /* falls through */ + case DICT: + if (state.havedict === 0) { + //--- RESTORE() --- + strm.next_out = put; + strm.avail_out = left; + strm.next_in = next; + strm.avail_in = have; + state.hold = hold; + state.bits = bits; + //--- + return Z_NEED_DICT; + } + strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/; + state.mode = TYPE; + /* falls through */ + case TYPE: + if (flush === Z_BLOCK || flush === Z_TREES) { break inf_leave; } + /* falls through */ + case TYPEDO: + if (state.last) { + //--- BYTEBITS() ---// + hold >>>= bits & 7; + bits -= bits & 7; + //---// + state.mode = CHECK; + break; + } + //=== NEEDBITS(3); */ + while (bits < 3) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.last = (hold & 0x01)/*BITS(1)*/; + //--- DROPBITS(1) ---// + hold >>>= 1; + bits -= 1; + //---// + + switch ((hold & 0x03)/*BITS(2)*/) { + case 0: /* stored block */ + //Tracev((stderr, "inflate: stored block%s\n", + // state.last ? " (last)" : "")); + state.mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + //Tracev((stderr, "inflate: fixed codes block%s\n", + // state.last ? " (last)" : "")); + state.mode = LEN_; /* decode codes */ + if (flush === Z_TREES) { + //--- DROPBITS(2) ---// + hold >>>= 2; + bits -= 2; + //---// + break inf_leave; + } + break; + case 2: /* dynamic block */ + //Tracev((stderr, "inflate: dynamic codes block%s\n", + // state.last ? " (last)" : "")); + state.mode = TABLE; + break; + case 3: + strm.msg = 'invalid block type'; + state.mode = BAD; + } + //--- DROPBITS(2) ---// + hold >>>= 2; + bits -= 2; + //---// + break; + case STORED: + //--- BYTEBITS() ---// /* go to byte boundary */ + hold >>>= bits & 7; + bits -= bits & 7; + //---// + //=== NEEDBITS(32); */ + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if ((hold & 0xffff) !== ((hold >>> 16) ^ 0xffff)) { + strm.msg = 'invalid stored block lengths'; + state.mode = BAD; + break; + } + state.length = hold & 0xffff; + //Tracev((stderr, "inflate: stored length %u\n", + // state.length)); + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + state.mode = COPY_; + if (flush === Z_TREES) { break inf_leave; } + /* falls through */ + case COPY_: + state.mode = COPY; + /* falls through */ + case COPY: + copy = state.length; + if (copy) { + if (copy > have) { copy = have; } + if (copy > left) { copy = left; } + if (copy === 0) { break inf_leave; } + //--- zmemcpy(put, next, copy); --- + utils.arraySet(output, input, next, copy, put); + //---// + have -= copy; + next += copy; + left -= copy; + put += copy; + state.length -= copy; + break; + } + //Tracev((stderr, "inflate: stored end\n")); + state.mode = TYPE; + break; + case TABLE: + //=== NEEDBITS(14); */ + while (bits < 14) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.nlen = (hold & 0x1f)/*BITS(5)*/ + 257; + //--- DROPBITS(5) ---// + hold >>>= 5; + bits -= 5; + //---// + state.ndist = (hold & 0x1f)/*BITS(5)*/ + 1; + //--- DROPBITS(5) ---// + hold >>>= 5; + bits -= 5; + //---// + state.ncode = (hold & 0x0f)/*BITS(4)*/ + 4; + //--- DROPBITS(4) ---// + hold >>>= 4; + bits -= 4; + //---// +//#ifndef PKZIP_BUG_WORKAROUND + if (state.nlen > 286 || state.ndist > 30) { + strm.msg = 'too many length or distance symbols'; + state.mode = BAD; + break; + } +//#endif + //Tracev((stderr, "inflate: table sizes ok\n")); + state.have = 0; + state.mode = LENLENS; + /* falls through */ + case LENLENS: + while (state.have < state.ncode) { + //=== NEEDBITS(3); + while (bits < 3) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.lens[order[state.have++]] = (hold & 0x07);//BITS(3); + //--- DROPBITS(3) ---// + hold >>>= 3; + bits -= 3; + //---// + } + while (state.have < 19) { + state.lens[order[state.have++]] = 0; + } + // We have separate tables & no pointers. 2 commented lines below not needed. + //state.next = state.codes; + //state.lencode = state.next; + // Switch to use dynamic table + state.lencode = state.lendyn; + state.lenbits = 7; + + opts = {bits: state.lenbits}; + ret = inflate_table(CODES, state.lens, 0, 19, state.lencode, 0, state.work, opts); + state.lenbits = opts.bits; + + if (ret) { + strm.msg = 'invalid code lengths set'; + state.mode = BAD; + break; + } + //Tracev((stderr, "inflate: code lengths ok\n")); + state.have = 0; + state.mode = CODELENS; + /* falls through */ + case CODELENS: + while (state.have < state.nlen + state.ndist) { + for (;;) { + here = state.lencode[hold & ((1 << state.lenbits) - 1)];/*BITS(state.lenbits)*/ + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if ((here_bits) <= bits) { break; } + //--- PULLBYTE() ---// + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + if (here_val < 16) { + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + state.lens[state.have++] = here_val; + } + else { + if (here_val === 16) { + //=== NEEDBITS(here.bits + 2); + n = here_bits + 2; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + if (state.have === 0) { + strm.msg = 'invalid bit length repeat'; + state.mode = BAD; + break; + } + len = state.lens[state.have - 1]; + copy = 3 + (hold & 0x03);//BITS(2); + //--- DROPBITS(2) ---// + hold >>>= 2; + bits -= 2; + //---// + } + else if (here_val === 17) { + //=== NEEDBITS(here.bits + 3); + n = here_bits + 3; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + len = 0; + copy = 3 + (hold & 0x07);//BITS(3); + //--- DROPBITS(3) ---// + hold >>>= 3; + bits -= 3; + //---// + } + else { + //=== NEEDBITS(here.bits + 7); + n = here_bits + 7; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + len = 0; + copy = 11 + (hold & 0x7f);//BITS(7); + //--- DROPBITS(7) ---// + hold >>>= 7; + bits -= 7; + //---// + } + if (state.have + copy > state.nlen + state.ndist) { + strm.msg = 'invalid bit length repeat'; + state.mode = BAD; + break; + } + while (copy--) { + state.lens[state.have++] = len; + } + } + } + + /* handle error breaks in while */ + if (state.mode === BAD) { break; } + + /* check for end-of-block code (better have one) */ + if (state.lens[256] === 0) { + strm.msg = 'invalid code -- missing end-of-block'; + state.mode = BAD; + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (9 and 6) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state.lenbits = 9; + + opts = {bits: state.lenbits}; + ret = inflate_table(LENS, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts); + // We have separate tables & no pointers. 2 commented lines below not needed. + // state.next_index = opts.table_index; + state.lenbits = opts.bits; + // state.lencode = state.next; + + if (ret) { + strm.msg = 'invalid literal/lengths set'; + state.mode = BAD; + break; + } + + state.distbits = 6; + //state.distcode.copy(state.codes); + // Switch to use dynamic table + state.distcode = state.distdyn; + opts = {bits: state.distbits}; + ret = inflate_table(DISTS, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts); + // We have separate tables & no pointers. 2 commented lines below not needed. + // state.next_index = opts.table_index; + state.distbits = opts.bits; + // state.distcode = state.next; + + if (ret) { + strm.msg = 'invalid distances set'; + state.mode = BAD; + break; + } + //Tracev((stderr, 'inflate: codes ok\n')); + state.mode = LEN_; + if (flush === Z_TREES) { break inf_leave; } + /* falls through */ + case LEN_: + state.mode = LEN; + /* falls through */ + case LEN: + if (have >= 6 && left >= 258) { + //--- RESTORE() --- + strm.next_out = put; + strm.avail_out = left; + strm.next_in = next; + strm.avail_in = have; + state.hold = hold; + state.bits = bits; + //--- + inflate_fast(strm, _out); + //--- LOAD() --- + put = strm.next_out; + output = strm.output; + left = strm.avail_out; + next = strm.next_in; + input = strm.input; + have = strm.avail_in; + hold = state.hold; + bits = state.bits; + //--- + + if (state.mode === TYPE) { + state.back = -1; + } + break; + } + state.back = 0; + for (;;) { + here = state.lencode[hold & ((1 << state.lenbits) -1)]; /*BITS(state.lenbits)*/ + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if (here_bits <= bits) { break; } + //--- PULLBYTE() ---// + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + if (here_op && (here_op & 0xf0) === 0) { + last_bits = here_bits; + last_op = here_op; + last_val = here_val; + for (;;) { + here = state.lencode[last_val + + ((hold & ((1 << (last_bits + last_op)) -1))/*BITS(last.bits + last.op)*/ >> last_bits)]; + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if ((last_bits + here_bits) <= bits) { break; } + //--- PULLBYTE() ---// + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + //--- DROPBITS(last.bits) ---// + hold >>>= last_bits; + bits -= last_bits; + //---// + state.back += last_bits; + } + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + state.back += here_bits; + state.length = here_val; + if (here_op === 0) { + //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + // "inflate: literal '%c'\n" : + // "inflate: literal 0x%02x\n", here.val)); + state.mode = LIT; + break; + } + if (here_op & 32) { + //Tracevv((stderr, "inflate: end of block\n")); + state.back = -1; + state.mode = TYPE; + break; + } + if (here_op & 64) { + strm.msg = 'invalid literal/length code'; + state.mode = BAD; + break; + } + state.extra = here_op & 15; + state.mode = LENEXT; + /* falls through */ + case LENEXT: + if (state.extra) { + //=== NEEDBITS(state.extra); + n = state.extra; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.length += hold & ((1 << state.extra) -1)/*BITS(state.extra)*/; + //--- DROPBITS(state.extra) ---// + hold >>>= state.extra; + bits -= state.extra; + //---// + state.back += state.extra; + } + //Tracevv((stderr, "inflate: length %u\n", state.length)); + state.was = state.length; + state.mode = DIST; + /* falls through */ + case DIST: + for (;;) { + here = state.distcode[hold & ((1 << state.distbits) -1)];/*BITS(state.distbits)*/ + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if ((here_bits) <= bits) { break; } + //--- PULLBYTE() ---// + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + if ((here_op & 0xf0) === 0) { + last_bits = here_bits; + last_op = here_op; + last_val = here_val; + for (;;) { + here = state.distcode[last_val + + ((hold & ((1 << (last_bits + last_op)) -1))/*BITS(last.bits + last.op)*/ >> last_bits)]; + here_bits = here >>> 24; + here_op = (here >>> 16) & 0xff; + here_val = here & 0xffff; + + if ((last_bits + here_bits) <= bits) { break; } + //--- PULLBYTE() ---// + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + //---// + } + //--- DROPBITS(last.bits) ---// + hold >>>= last_bits; + bits -= last_bits; + //---// + state.back += last_bits; + } + //--- DROPBITS(here.bits) ---// + hold >>>= here_bits; + bits -= here_bits; + //---// + state.back += here_bits; + if (here_op & 64) { + strm.msg = 'invalid distance code'; + state.mode = BAD; + break; + } + state.offset = here_val; + state.extra = (here_op) & 15; + state.mode = DISTEXT; + /* falls through */ + case DISTEXT: + if (state.extra) { + //=== NEEDBITS(state.extra); + n = state.extra; + while (bits < n) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + state.offset += hold & ((1 << state.extra) -1)/*BITS(state.extra)*/; + //--- DROPBITS(state.extra) ---// + hold >>>= state.extra; + bits -= state.extra; + //---// + state.back += state.extra; + } +//#ifdef INFLATE_STRICT + if (state.offset > state.dmax) { + strm.msg = 'invalid distance too far back'; + state.mode = BAD; + break; + } +//#endif + //Tracevv((stderr, "inflate: distance %u\n", state.offset)); + state.mode = MATCH; + /* falls through */ + case MATCH: + if (left === 0) { break inf_leave; } + copy = _out - left; + if (state.offset > copy) { /* copy from window */ + copy = state.offset - copy; + if (copy > state.whave) { + if (state.sane) { + strm.msg = 'invalid distance too far back'; + state.mode = BAD; + break; + } +// (!) This block is disabled in zlib defailts, +// don't enable it for binary compatibility +//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR +// Trace((stderr, "inflate.c too far\n")); +// copy -= state.whave; +// if (copy > state.length) { copy = state.length; } +// if (copy > left) { copy = left; } +// left -= copy; +// state.length -= copy; +// do { +// output[put++] = 0; +// } while (--copy); +// if (state.length === 0) { state.mode = LEN; } +// break; +//#endif + } + if (copy > state.wnext) { + copy -= state.wnext; + from = state.wsize - copy; + } + else { + from = state.wnext - copy; + } + if (copy > state.length) { copy = state.length; } + from_source = state.window; + } + else { /* copy from output */ + from_source = output; + from = put - state.offset; + copy = state.length; + } + if (copy > left) { copy = left; } + left -= copy; + state.length -= copy; + do { + output[put++] = from_source[from++]; + } while (--copy); + if (state.length === 0) { state.mode = LEN; } + break; + case LIT: + if (left === 0) { break inf_leave; } + output[put++] = state.length; + left--; + state.mode = LEN; + break; + case CHECK: + if (state.wrap) { + //=== NEEDBITS(32); + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + // Use '|' insdead of '+' to make sure that result is signed + hold |= input[next++] << bits; + bits += 8; + } + //===// + _out -= left; + strm.total_out += _out; + state.total += _out; + if (_out) { + strm.adler = state.check = + /*UPDATE(state.check, put - _out, _out);*/ + (state.flags ? crc32(state.check, output, _out, put - _out) : adler32(state.check, output, _out, put - _out)); + + } + _out = left; + // NB: crc32 stored as signed 32-bit int, ZSWAP32 returns signed too + if ((state.flags ? hold : ZSWAP32(hold)) !== state.check) { + strm.msg = 'incorrect data check'; + state.mode = BAD; + break; + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + //Tracev((stderr, "inflate: check matches trailer\n")); + } + state.mode = LENGTH; + /* falls through */ + case LENGTH: + if (state.wrap && state.flags) { + //=== NEEDBITS(32); + while (bits < 32) { + if (have === 0) { break inf_leave; } + have--; + hold += input[next++] << bits; + bits += 8; + } + //===// + if (hold !== (state.total & 0xffffffff)) { + strm.msg = 'incorrect length check'; + state.mode = BAD; + break; + } + //=== INITBITS(); + hold = 0; + bits = 0; + //===// + //Tracev((stderr, "inflate: length matches trailer\n")); + } + state.mode = DONE; + /* falls through */ + case DONE: + ret = Z_STREAM_END; + break inf_leave; + case BAD: + ret = Z_DATA_ERROR; + break inf_leave; + case MEM: + return Z_MEM_ERROR; + case SYNC: + /* falls through */ + default: + return Z_STREAM_ERROR; + } + } + + // inf_leave <- here is real place for "goto inf_leave", emulated via "break inf_leave" + + /* + Return from inflate(), updating the total counts and the check value. + If there was no progress during the inflate() call, return a buffer + error. Call updatewindow() to create and/or update the window state. + Note: a memory error from inflate() is non-recoverable. + */ + + //--- RESTORE() --- + strm.next_out = put; + strm.avail_out = left; + strm.next_in = next; + strm.avail_in = have; + state.hold = hold; + state.bits = bits; + //--- + + if (state.wsize || (_out !== strm.avail_out && state.mode < BAD && + (state.mode < CHECK || flush !== Z_FINISH))) { + if (updatewindow(strm, strm.output, strm.next_out, _out - strm.avail_out)) { + state.mode = MEM; + return Z_MEM_ERROR; + } + } + _in -= strm.avail_in; + _out -= strm.avail_out; + strm.total_in += _in; + strm.total_out += _out; + state.total += _out; + if (state.wrap && _out) { + strm.adler = state.check = /*UPDATE(state.check, strm.next_out - _out, _out);*/ + (state.flags ? crc32(state.check, output, _out, strm.next_out - _out) : adler32(state.check, output, _out, strm.next_out - _out)); + } + strm.data_type = state.bits + (state.last ? 64 : 0) + + (state.mode === TYPE ? 128 : 0) + + (state.mode === LEN_ || state.mode === COPY_ ? 256 : 0); + if (((_in === 0 && _out === 0) || flush === Z_FINISH) && ret === Z_OK) { + ret = Z_BUF_ERROR; + } + return ret; +} + +function inflateEnd(strm) { + + if (!strm || !strm.state /*|| strm->zfree == (free_func)0*/) { + return Z_STREAM_ERROR; + } + + var state = strm.state; + if (state.window) { + state.window = null; + } + strm.state = null; + return Z_OK; +} + +function inflateGetHeader(strm, head) { + var state; + + /* check state */ + if (!strm || !strm.state) { return Z_STREAM_ERROR; } + state = strm.state; + if ((state.wrap & 2) === 0) { return Z_STREAM_ERROR; } + + /* save header structure */ + state.head = head; + head.done = false; + return Z_OK; +} + + +exports.inflateReset = inflateReset; +exports.inflateReset2 = inflateReset2; +exports.inflateResetKeep = inflateResetKeep; +exports.inflateInit = inflateInit; +exports.inflateInit2 = inflateInit2; +exports.inflate = inflate; +exports.inflateEnd = inflateEnd; +exports.inflateGetHeader = inflateGetHeader; +exports.inflateInfo = 'pako inflate (from Nodeca project)'; + +/* Not implemented +exports.inflateCopy = inflateCopy; +exports.inflateGetDictionary = inflateGetDictionary; +exports.inflateMark = inflateMark; +exports.inflatePrime = inflatePrime; +exports.inflateSetDictionary = inflateSetDictionary; +exports.inflateSync = inflateSync; +exports.inflateSyncPoint = inflateSyncPoint; +exports.inflateUndermine = inflateUndermine; +*/ +},{"../utils/common":27,"./adler32":29,"./crc32":31,"./inffast":34,"./inftrees":36}],36:[function(_dereq_,module,exports){ +'use strict'; + + +var utils = _dereq_('../utils/common'); + +var MAXBITS = 15; +var ENOUGH_LENS = 852; +var ENOUGH_DISTS = 592; +//var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS); + +var CODES = 0; +var LENS = 1; +var DISTS = 2; + +var lbase = [ /* Length codes 257..285 base */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 +]; + +var lext = [ /* Length codes 257..285 extra */ + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78 +]; + +var dbase = [ /* Distance codes 0..29 base */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577, 0, 0 +]; + +var dext = [ /* Distance codes 0..29 extra */ + 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, + 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, + 28, 28, 29, 29, 64, 64 +]; + +module.exports = function inflate_table(type, lens, lens_index, codes, table, table_index, work, opts) +{ + var bits = opts.bits; + //here = opts.here; /* table entry for duplication */ + + var len = 0; /* a code's length in bits */ + var sym = 0; /* index of code symbols */ + var min = 0, max = 0; /* minimum and maximum code lengths */ + var root = 0; /* number of index bits for root table */ + var curr = 0; /* number of index bits for current table */ + var drop = 0; /* code bits to drop for sub-table */ + var left = 0; /* number of prefix codes available */ + var used = 0; /* code entries in table used */ + var huff = 0; /* Huffman code */ + var incr; /* for incrementing code, index */ + var fill; /* index for replicating entries */ + var low; /* low bits for current root entry */ + var mask; /* mask for low root bits */ + var next; /* next available space in table */ + var base = null; /* base value table to use */ + var base_index = 0; +// var shoextra; /* extra bits table to use */ + var end; /* use base and extra for symbol > end */ + var count = new utils.Buf16(MAXBITS+1); //[MAXBITS+1]; /* number of codes of each length */ + var offs = new utils.Buf16(MAXBITS+1); //[MAXBITS+1]; /* offsets in table for each length */ + var extra = null; + var extra_index = 0; + + var here_bits, here_op, here_val; + + /* + Process a set of code lengths to create a canonical Huffman code. The + code lengths are lens[0..codes-1]. Each length corresponds to the + symbols 0..codes-1. The Huffman code is generated by first sorting the + symbols by length from short to long, and retaining the symbol order + for codes with equal lengths. Then the code starts with all zero bits + for the first code of the shortest length, and the codes are integer + increments for the same length, and zeros are appended as the length + increases. For the deflate format, these bits are stored backwards + from their more natural integer increment ordering, and so when the + decoding tables are built in the large loop below, the integer codes + are incremented backwards. + + This routine assumes, but does not check, that all of the entries in + lens[] are in the range 0..MAXBITS. The caller must assure this. + 1..MAXBITS is interpreted as that code length. zero means that that + symbol does not occur in this code. + + The codes are sorted by computing a count of codes for each length, + creating from that a table of starting indices for each length in the + sorted table, and then entering the symbols in order in the sorted + table. The sorted table is work[], with that space being provided by + the caller. + + The length counts are used for other purposes as well, i.e. finding + the minimum and maximum length codes, determining if there are any + codes at all, checking for a valid set of lengths, and looking ahead + at length counts to determine sub-table sizes when building the + decoding tables. + */ + + /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ + for (len = 0; len <= MAXBITS; len++) { + count[len] = 0; + } + for (sym = 0; sym < codes; sym++) { + count[lens[lens_index + sym]]++; + } + + /* bound code lengths, force root to be within code lengths */ + root = bits; + for (max = MAXBITS; max >= 1; max--) { + if (count[max] !== 0) { break; } + } + if (root > max) { + root = max; + } + if (max === 0) { /* no symbols to code at all */ + //table.op[opts.table_index] = 64; //here.op = (var char)64; /* invalid code marker */ + //table.bits[opts.table_index] = 1; //here.bits = (var char)1; + //table.val[opts.table_index++] = 0; //here.val = (var short)0; + table[table_index++] = (1 << 24) | (64 << 16) | 0; + + + //table.op[opts.table_index] = 64; + //table.bits[opts.table_index] = 1; + //table.val[opts.table_index++] = 0; + table[table_index++] = (1 << 24) | (64 << 16) | 0; + + opts.bits = 1; + return 0; /* no symbols, but wait for decoding to report error */ + } + for (min = 1; min < max; min++) { + if (count[min] !== 0) { break; } + } + if (root < min) { + root = min; + } + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; + left -= count[len]; + if (left < 0) { + return -1; + } /* over-subscribed */ + } + if (left > 0 && (type === CODES || max !== 1)) { + return -1; /* incomplete set */ + } + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) { + offs[len + 1] = offs[len] + count[len]; + } + + /* sort symbols by length, by symbol order within each length */ + for (sym = 0; sym < codes; sym++) { + if (lens[lens_index + sym] !== 0) { + work[offs[lens[lens_index + sym]]++] = sym; + } + } + + /* + Create and fill in decoding tables. In this loop, the table being + filled is at next and has curr index bits. The code being used is huff + with length len. That code is converted to an index by dropping drop + bits off of the bottom. For codes where len is less than drop + curr, + those top drop + curr - len bits are incremented through all values to + fill the table with replicated entries. + + root is the number of index bits for the root table. When len exceeds + root, sub-tables are created pointed to by the root entry with an index + of the low root bits of huff. This is saved in low to check for when a + new sub-table should be started. drop is zero when the root table is + being filled, and drop is root when sub-tables are being filled. + + When a new sub-table is needed, it is necessary to look ahead in the + code lengths to determine what size sub-table is needed. The length + counts are used for this, and so count[] is decremented as codes are + entered in the tables. + + used keeps track of how many table entries have been allocated from the + provided *table space. It is checked for LENS and DIST tables against + the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in + the initial root table size constants. See the comments in inftrees.h + for more information. + + sym increments through all symbols, and the loop terminates when + all codes of length max, i.e. all codes, have been processed. This + routine permits incomplete codes, so another loop after this one fills + in the rest of the decoding tables with invalid code markers. + */ + + /* set up for code type */ + // poor man optimization - use if-else instead of switch, + // to avoid deopts in old v8 + if (type === CODES) { + base = extra = work; /* dummy value--not used */ + end = 19; + } else if (type === LENS) { + base = lbase; + base_index -= 257; + extra = lext; + extra_index -= 257; + end = 256; + } else { /* DISTS */ + base = dbase; + extra = dext; + end = -1; + } + + /* initialize opts for loop */ + huff = 0; /* starting code */ + sym = 0; /* starting code symbol */ + len = min; /* starting code length */ + next = table_index; /* current table to fill in */ + curr = root; /* current table index bits */ + drop = 0; /* current bits to drop from code for index */ + low = -1; /* trigger new sub-table when len > root */ + used = 1 << root; /* use root table entries */ + mask = used - 1; /* mask for comparing low */ + + /* check available table space */ + if ((type === LENS && used > ENOUGH_LENS) || + (type === DISTS && used > ENOUGH_DISTS)) { + return 1; + } + + var i=0; + /* process all codes and make table entries */ + for (;;) { + i++; + /* create table entry */ + here_bits = len - drop; + if (work[sym] < end) { + here_op = 0; + here_val = work[sym]; + } + else if (work[sym] > end) { + here_op = extra[extra_index + work[sym]]; + here_val = base[base_index + work[sym]]; + } + else { + here_op = 32 + 64; /* end of block */ + here_val = 0; + } + + /* replicate for those indices with low len bits equal to huff */ + incr = 1 << (len - drop); + fill = 1 << curr; + min = fill; /* save offset to next table */ + do { + fill -= incr; + table[next + (huff >> drop) + fill] = (here_bits << 24) | (here_op << 16) | here_val |0; + } while (fill !== 0); + + /* backwards increment the len-bit code huff */ + incr = 1 << (len - 1); + while (huff & incr) { + incr >>= 1; + } + if (incr !== 0) { + huff &= incr - 1; + huff += incr; + } else { + huff = 0; + } + + /* go to next symbol, update count, len */ + sym++; + if (--count[len] === 0) { + if (len === max) { break; } + len = lens[lens_index + work[sym]]; + } + + /* create new sub-table if needed */ + if (len > root && (huff & mask) !== low) { + /* if first time, transition to sub-tables */ + if (drop === 0) { + drop = root; + } + + /* increment past last table */ + next += min; /* here min is 1 << curr */ + + /* determine length of next table */ + curr = len - drop; + left = 1 << curr; + while (curr + drop < max) { + left -= count[curr + drop]; + if (left <= 0) { break; } + curr++; + left <<= 1; + } + + /* check for enough space */ + used += 1 << curr; + if ((type === LENS && used > ENOUGH_LENS) || + (type === DISTS && used > ENOUGH_DISTS)) { + return 1; + } + + /* point entry in root table to sub-table */ + low = huff & mask; + /*table.op[low] = curr; + table.bits[low] = root; + table.val[low] = next - opts.table_index;*/ + table[low] = (root << 24) | (curr << 16) | (next - table_index) |0; + } + } + + /* fill in remaining table entry if code is incomplete (guaranteed to have + at most one remaining entry, since if the code is incomplete, the + maximum code length that was allowed to get this far is one bit) */ + if (huff !== 0) { + //table.op[next + huff] = 64; /* invalid code marker */ + //table.bits[next + huff] = len - drop; + //table.val[next + huff] = 0; + table[next + huff] = ((len - drop) << 24) | (64 << 16) |0; + } + + /* set return parameters */ + //opts.table_index += used; + opts.bits = root; + return 0; +}; + +},{"../utils/common":27}],37:[function(_dereq_,module,exports){ +'use strict'; + +module.exports = { + '2': 'need dictionary', /* Z_NEED_DICT 2 */ + '1': 'stream end', /* Z_STREAM_END 1 */ + '0': '', /* Z_OK 0 */ + '-1': 'file error', /* Z_ERRNO (-1) */ + '-2': 'stream error', /* Z_STREAM_ERROR (-2) */ + '-3': 'data error', /* Z_DATA_ERROR (-3) */ + '-4': 'insufficient memory', /* Z_MEM_ERROR (-4) */ + '-5': 'buffer error', /* Z_BUF_ERROR (-5) */ + '-6': 'incompatible version' /* Z_VERSION_ERROR (-6) */ +}; +},{}],38:[function(_dereq_,module,exports){ +'use strict'; + + +var utils = _dereq_('../utils/common'); + +/* Public constants ==========================================================*/ +/* ===========================================================================*/ + + +//var Z_FILTERED = 1; +//var Z_HUFFMAN_ONLY = 2; +//var Z_RLE = 3; +var Z_FIXED = 4; +//var Z_DEFAULT_STRATEGY = 0; + +/* Possible values of the data_type field (though see inflate()) */ +var Z_BINARY = 0; +var Z_TEXT = 1; +//var Z_ASCII = 1; // = Z_TEXT +var Z_UNKNOWN = 2; + +/*============================================================================*/ + + +function zero(buf) { var len = buf.length; while (--len >= 0) { buf[len] = 0; } } + +// From zutil.h + +var STORED_BLOCK = 0; +var STATIC_TREES = 1; +var DYN_TREES = 2; +/* The three kinds of block type */ + +var MIN_MATCH = 3; +var MAX_MATCH = 258; +/* The minimum and maximum match lengths */ + +// From deflate.h +/* =========================================================================== + * Internal compression state. + */ + +var LENGTH_CODES = 29; +/* number of length codes, not counting the special END_BLOCK code */ + +var LITERALS = 256; +/* number of literal bytes 0..255 */ + +var L_CODES = LITERALS + 1 + LENGTH_CODES; +/* number of Literal or Length codes, including the END_BLOCK code */ + +var D_CODES = 30; +/* number of distance codes */ + +var BL_CODES = 19; +/* number of codes used to transfer the bit lengths */ + +var HEAP_SIZE = 2*L_CODES + 1; +/* maximum heap size */ + +var MAX_BITS = 15; +/* All codes must not exceed MAX_BITS bits */ + +var Buf_size = 16; +/* size of bit buffer in bi_buf */ + + +/* =========================================================================== + * Constants + */ + +var MAX_BL_BITS = 7; +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +var END_BLOCK = 256; +/* end of block literal code */ + +var REP_3_6 = 16; +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +var REPZ_3_10 = 17; +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +var REPZ_11_138 = 18; +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +var extra_lbits = /* extra bits for each length code */ + [0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0]; + +var extra_dbits = /* extra bits for each distance code */ + [0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13]; + +var extra_blbits = /* extra bits for each bit length code */ + [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7]; + +var bl_order = + [16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]; +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +// We pre-fill arrays with 0 to avoid uninitialized gaps + +var DIST_CODE_LEN = 512; /* see definition of array dist_code below */ + +// !!!! Use flat array insdead of structure, Freq = i*2, Len = i*2+1 +var static_ltree = new Array((L_CODES+2) * 2); +zero(static_ltree); +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init + * below). + */ + +var static_dtree = new Array(D_CODES * 2); +zero(static_dtree); +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + +var _dist_code = new Array(DIST_CODE_LEN); +zero(_dist_code); +/* Distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + +var _length_code = new Array(MAX_MATCH-MIN_MATCH+1); +zero(_length_code); +/* length code for each normalized match length (0 == MIN_MATCH) */ + +var base_length = new Array(LENGTH_CODES); +zero(base_length); +/* First normalized length for each code (0 = MIN_MATCH) */ + +var base_dist = new Array(D_CODES); +zero(base_dist); +/* First normalized distance for each code (0 = distance of 1) */ + + +var StaticTreeDesc = function (static_tree, extra_bits, extra_base, elems, max_length) { + + this.static_tree = static_tree; /* static tree or NULL */ + this.extra_bits = extra_bits; /* extra bits for each code or NULL */ + this.extra_base = extra_base; /* base index for extra_bits */ + this.elems = elems; /* max number of elements in the tree */ + this.max_length = max_length; /* max bit length for the codes */ + + // show if `static_tree` has data or dummy - needed for monomorphic objects + this.has_stree = static_tree && static_tree.length; +}; + + +var static_l_desc; +var static_d_desc; +var static_bl_desc; + + +var TreeDesc = function(dyn_tree, stat_desc) { + this.dyn_tree = dyn_tree; /* the dynamic tree */ + this.max_code = 0; /* largest code with non zero frequency */ + this.stat_desc = stat_desc; /* the corresponding static tree */ +}; + + + +function d_code(dist) { + return dist < 256 ? _dist_code[dist] : _dist_code[256 + (dist >>> 7)]; +} + + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +function put_short (s, w) { +// put_byte(s, (uch)((w) & 0xff)); +// put_byte(s, (uch)((ush)(w) >> 8)); + s.pending_buf[s.pending++] = (w) & 0xff; + s.pending_buf[s.pending++] = (w >>> 8) & 0xff; +} + + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +function send_bits(s, value, length) { + if (s.bi_valid > (Buf_size - length)) { + s.bi_buf |= (value << s.bi_valid) & 0xffff; + put_short(s, s.bi_buf); + s.bi_buf = value >> (Buf_size - s.bi_valid); + s.bi_valid += length - Buf_size; + } else { + s.bi_buf |= (value << s.bi_valid) & 0xffff; + s.bi_valid += length; + } +} + + +function send_code(s, c, tree) { + send_bits(s, tree[c*2]/*.Code*/, tree[c*2 + 1]/*.Len*/); +} + + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +function bi_reverse(code, len) { + var res = 0; + do { + res |= code & 1; + code >>>= 1; + res <<= 1; + } while (--len > 0); + return res >>> 1; +} + + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +function bi_flush(s) { + if (s.bi_valid === 16) { + put_short(s, s.bi_buf); + s.bi_buf = 0; + s.bi_valid = 0; + + } else if (s.bi_valid >= 8) { + s.pending_buf[s.pending++] = s.bi_buf & 0xff; + s.bi_buf >>= 8; + s.bi_valid -= 8; + } +} + + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +function gen_bitlen(s, desc) +// deflate_state *s; +// tree_desc *desc; /* the tree descriptor */ +{ + var tree = desc.dyn_tree; + var max_code = desc.max_code; + var stree = desc.stat_desc.static_tree; + var has_stree = desc.stat_desc.has_stree; + var extra = desc.stat_desc.extra_bits; + var base = desc.stat_desc.extra_base; + var max_length = desc.stat_desc.max_length; + var h; /* heap index */ + var n, m; /* iterate over the tree elements */ + var bits; /* bit length */ + var xbits; /* extra bits */ + var f; /* frequency */ + var overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) { + s.bl_count[bits] = 0; + } + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s.heap[s.heap_max]*2 + 1]/*.Len*/ = 0; /* root of the heap */ + + for (h = s.heap_max+1; h < HEAP_SIZE; h++) { + n = s.heap[h]; + bits = tree[tree[n*2 +1]/*.Dad*/ * 2 + 1]/*.Len*/ + 1; + if (bits > max_length) { + bits = max_length; + overflow++; + } + tree[n*2 + 1]/*.Len*/ = bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) { continue; } /* not a leaf node */ + + s.bl_count[bits]++; + xbits = 0; + if (n >= base) { + xbits = extra[n-base]; + } + f = tree[n * 2]/*.Freq*/; + s.opt_len += f * (bits + xbits); + if (has_stree) { + s.static_len += f * (stree[n*2 + 1]/*.Len*/ + xbits); + } + } + if (overflow === 0) { return; } + + // Trace((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length-1; + while (s.bl_count[bits] === 0) { bits--; } + s.bl_count[bits]--; /* move one leaf down the tree */ + s.bl_count[bits+1] += 2; /* move one overflow item as its brother */ + s.bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits !== 0; bits--) { + n = s.bl_count[bits]; + while (n !== 0) { + m = s.heap[--h]; + if (m > max_code) { continue; } + if (tree[m*2 + 1]/*.Len*/ !== bits) { + // Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s.opt_len += (bits - tree[m*2 + 1]/*.Len*/)*tree[m*2]/*.Freq*/; + tree[m*2 + 1]/*.Len*/ = bits; + } + n--; + } + } +} + + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +function gen_codes(tree, max_code, bl_count) +// ct_data *tree; /* the tree to decorate */ +// int max_code; /* largest code with non zero frequency */ +// ushf *bl_count; /* number of codes at each bit length */ +{ + var next_code = new Array(MAX_BITS+1); /* next code value for each bit length */ + var code = 0; /* running code value */ + var bits; /* bit index */ + var n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = (code + bl_count[bits-1]) << 1; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + //Assert (code + bl_count[MAX_BITS]-1 == (1< length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + base_length[code] = length; + for (n = 0; n < (1< dist code (0..29) */ + dist = 0; + for (code = 0 ; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ + for ( ; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { + _dist_code[256 + dist++] = code; + } + } + //Assert (dist == 256, "tr_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) { + bl_count[bits] = 0; + } + + n = 0; + while (n <= 143) { + static_ltree[n*2 + 1]/*.Len*/ = 8; + n++; + bl_count[8]++; + } + while (n <= 255) { + static_ltree[n*2 + 1]/*.Len*/ = 9; + n++; + bl_count[9]++; + } + while (n <= 279) { + static_ltree[n*2 + 1]/*.Len*/ = 7; + n++; + bl_count[7]++; + } + while (n <= 287) { + static_ltree[n*2 + 1]/*.Len*/ = 8; + n++; + bl_count[8]++; + } + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes(static_ltree, L_CODES+1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n*2 + 1]/*.Len*/ = 5; + static_dtree[n*2]/*.Code*/ = bi_reverse(n, 5); + } + + // Now data ready and we can init static trees + static_l_desc = new StaticTreeDesc(static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS); + static_d_desc = new StaticTreeDesc(static_dtree, extra_dbits, 0, D_CODES, MAX_BITS); + static_bl_desc =new StaticTreeDesc(new Array(0), extra_blbits, 0, BL_CODES, MAX_BL_BITS); + + //static_init_done = true; +} + + +/* =========================================================================== + * Initialize a new block. + */ +function init_block(s) { + var n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) { s.dyn_ltree[n*2]/*.Freq*/ = 0; } + for (n = 0; n < D_CODES; n++) { s.dyn_dtree[n*2]/*.Freq*/ = 0; } + for (n = 0; n < BL_CODES; n++) { s.bl_tree[n*2]/*.Freq*/ = 0; } + + s.dyn_ltree[END_BLOCK*2]/*.Freq*/ = 1; + s.opt_len = s.static_len = 0; + s.last_lit = s.matches = 0; +} + + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +function bi_windup(s) +{ + if (s.bi_valid > 8) { + put_short(s, s.bi_buf); + } else if (s.bi_valid > 0) { + //put_byte(s, (Byte)s->bi_buf); + s.pending_buf[s.pending++] = s.bi_buf; + } + s.bi_buf = 0; + s.bi_valid = 0; +} + +/* =========================================================================== + * Copy a stored block, storing first the length and its + * one's complement if requested. + */ +function copy_block(s, buf, len, header) +//DeflateState *s; +//charf *buf; /* the input data */ +//unsigned len; /* its length */ +//int header; /* true if block header must be written */ +{ + bi_windup(s); /* align on byte boundary */ + + if (header) { + put_short(s, len); + put_short(s, ~len); + } +// while (len--) { +// put_byte(s, *buf++); +// } + utils.arraySet(s.pending_buf, s.window, buf, len, s.pending); + s.pending += len; +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +function smaller(tree, n, m, depth) { + var _n2 = n*2; + var _m2 = m*2; + return (tree[_n2]/*.Freq*/ < tree[_m2]/*.Freq*/ || + (tree[_n2]/*.Freq*/ === tree[_m2]/*.Freq*/ && depth[n] <= depth[m])); +} + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +function pqdownheap(s, tree, k) +// deflate_state *s; +// ct_data *tree; /* the tree to restore */ +// int k; /* node to move down */ +{ + var v = s.heap[k]; + var j = k << 1; /* left son of k */ + while (j <= s.heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s.heap_len && + smaller(tree, s.heap[j+1], s.heap[j], s.depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s.heap[j], s.depth)) { break; } + + /* Exchange v with the smallest son */ + s.heap[k] = s.heap[j]; + k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s.heap[k] = v; +} + + +// inlined manually +// var SMALLEST = 1; + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +function compress_block(s, ltree, dtree) +// deflate_state *s; +// const ct_data *ltree; /* literal tree */ +// const ct_data *dtree; /* distance tree */ +{ + var dist; /* distance of matched string */ + var lc; /* match length or unmatched char (if dist == 0) */ + var lx = 0; /* running index in l_buf */ + var code; /* the code to send */ + var extra; /* number of extra bits to send */ + + if (s.last_lit !== 0) { + do { + dist = (s.pending_buf[s.d_buf + lx*2] << 8) | (s.pending_buf[s.d_buf + lx*2 + 1]); + lc = s.pending_buf[s.l_buf + lx]; + lx++; + + if (dist === 0) { + send_code(s, lc, ltree); /* send a literal byte */ + //Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code(s, code+LITERALS+1, ltree); /* send the length code */ + extra = extra_lbits[code]; + if (extra !== 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + //Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra !== 0) { + dist -= base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ + //Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, + // "pendingBuf overflow"); + + } while (lx < s.last_lit); + } + + send_code(s, END_BLOCK, ltree); +} + + +/* =========================================================================== + * Construct one Huffman tree and assigns the code bit strings and lengths. + * Update the total bit length for the current block. + * IN assertion: the field freq is set for all tree elements. + * OUT assertions: the fields len and code are set to the optimal bit length + * and corresponding code. The length opt_len is updated; static_len is + * also updated if stree is not null. The field max_code is set. + */ +function build_tree(s, desc) +// deflate_state *s; +// tree_desc *desc; /* the tree descriptor */ +{ + var tree = desc.dyn_tree; + var stree = desc.stat_desc.static_tree; + var has_stree = desc.stat_desc.has_stree; + var elems = desc.stat_desc.elems; + var n, m; /* iterate over heap elements */ + var max_code = -1; /* largest code with non zero frequency */ + var node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + s.heap_len = 0; + s.heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n * 2]/*.Freq*/ !== 0) { + s.heap[++s.heap_len] = max_code = n; + s.depth[n] = 0; + + } else { + tree[n*2 + 1]/*.Len*/ = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s.heap_len < 2) { + node = s.heap[++s.heap_len] = (max_code < 2 ? ++max_code : 0); + tree[node * 2]/*.Freq*/ = 1; + s.depth[node] = 0; + s.opt_len--; + + if (has_stree) { + s.static_len -= stree[node*2 + 1]/*.Len*/; + } + /* node is 0 or 1 so it does not have extra bits */ + } + desc.max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = (s.heap_len >> 1/*int /2*/); n >= 1; n--) { pqdownheap(s, tree, n); } + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + //pqremove(s, tree, n); /* n = node of least frequency */ + /*** pqremove ***/ + n = s.heap[1/*SMALLEST*/]; + s.heap[1/*SMALLEST*/] = s.heap[s.heap_len--]; + pqdownheap(s, tree, 1/*SMALLEST*/); + /***/ + + m = s.heap[1/*SMALLEST*/]; /* m = node of next least frequency */ + + s.heap[--s.heap_max] = n; /* keep the nodes sorted by frequency */ + s.heap[--s.heap_max] = m; + + /* Create a new node father of n and m */ + tree[node * 2]/*.Freq*/ = tree[n * 2]/*.Freq*/ + tree[m * 2]/*.Freq*/; + s.depth[node] = (s.depth[n] >= s.depth[m] ? s.depth[n] : s.depth[m]) + 1; + tree[n*2 + 1]/*.Dad*/ = tree[m*2 + 1]/*.Dad*/ = node; + + /* and insert the new node in the heap */ + s.heap[1/*SMALLEST*/] = node++; + pqdownheap(s, tree, 1/*SMALLEST*/); + + } while (s.heap_len >= 2); + + s.heap[--s.heap_max] = s.heap[1/*SMALLEST*/]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes(tree, max_code, s.bl_count); +} + + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +function scan_tree(s, tree, max_code) +// deflate_state *s; +// ct_data *tree; /* the tree to be scanned */ +// int max_code; /* and its largest code of non zero frequency */ +{ + var n; /* iterates over all tree elements */ + var prevlen = -1; /* last emitted length */ + var curlen; /* length of current code */ + + var nextlen = tree[0*2 + 1]/*.Len*/; /* length of next code */ + + var count = 0; /* repeat count of the current code */ + var max_count = 7; /* max repeat count */ + var min_count = 4; /* min repeat count */ + + if (nextlen === 0) { + max_count = 138; + min_count = 3; + } + tree[(max_code+1)*2 + 1]/*.Len*/ = 0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; + nextlen = tree[(n+1)*2 + 1]/*.Len*/; + + if (++count < max_count && curlen === nextlen) { + continue; + + } else if (count < min_count) { + s.bl_tree[curlen * 2]/*.Freq*/ += count; + + } else if (curlen !== 0) { + + if (curlen !== prevlen) { s.bl_tree[curlen * 2]/*.Freq*/++; } + s.bl_tree[REP_3_6*2]/*.Freq*/++; + + } else if (count <= 10) { + s.bl_tree[REPZ_3_10*2]/*.Freq*/++; + + } else { + s.bl_tree[REPZ_11_138*2]/*.Freq*/++; + } + + count = 0; + prevlen = curlen; + + if (nextlen === 0) { + max_count = 138; + min_count = 3; + + } else if (curlen === nextlen) { + max_count = 6; + min_count = 3; + + } else { + max_count = 7; + min_count = 4; + } + } +} + + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +function send_tree(s, tree, max_code) +// deflate_state *s; +// ct_data *tree; /* the tree to be scanned */ +// int max_code; /* and its largest code of non zero frequency */ +{ + var n; /* iterates over all tree elements */ + var prevlen = -1; /* last emitted length */ + var curlen; /* length of current code */ + + var nextlen = tree[0*2 + 1]/*.Len*/; /* length of next code */ + + var count = 0; /* repeat count of the current code */ + var max_count = 7; /* max repeat count */ + var min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen === 0) { + max_count = 138; + min_count = 3; + } + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; + nextlen = tree[(n+1)*2 + 1]/*.Len*/; + + if (++count < max_count && curlen === nextlen) { + continue; + + } else if (count < min_count) { + do { send_code(s, curlen, s.bl_tree); } while (--count !== 0); + + } else if (curlen !== 0) { + if (curlen !== prevlen) { + send_code(s, curlen, s.bl_tree); + count--; + } + //Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s.bl_tree); + send_bits(s, count-3, 2); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s.bl_tree); + send_bits(s, count-3, 3); + + } else { + send_code(s, REPZ_11_138, s.bl_tree); + send_bits(s, count-11, 7); + } + + count = 0; + prevlen = curlen; + if (nextlen === 0) { + max_count = 138; + min_count = 3; + + } else if (curlen === nextlen) { + max_count = 6; + min_count = 3; + + } else { + max_count = 7; + min_count = 4; + } + } +} + + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +function build_bl_tree(s) { + var max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, s.dyn_ltree, s.l_desc.max_code); + scan_tree(s, s.dyn_dtree, s.d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, s.bl_desc); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { + if (s.bl_tree[bl_order[max_blindex]*2 + 1]/*.Len*/ !== 0) { + break; + } + } + /* Update opt_len to include the bit length tree and counts */ + s.opt_len += 3*(max_blindex+1) + 5+5+4; + //Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + // s->opt_len, s->static_len)); + + return max_blindex; +} + + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +function send_all_trees(s, lcodes, dcodes, blcodes) +// deflate_state *s; +// int lcodes, dcodes, blcodes; /* number of codes for each tree */ +{ + var rank; /* index in bl_order */ + + //Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + //Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + // "too many codes"); + //Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes-1, 5); + send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + //Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s.bl_tree[bl_order[rank]*2 + 1]/*.Len*/, 3); + } + //Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + + send_tree(s, s.dyn_ltree, lcodes-1); /* literal tree */ + //Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + + send_tree(s, s.dyn_dtree, dcodes-1); /* distance tree */ + //Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +} + + +/* =========================================================================== + * Check if the data type is TEXT or BINARY, using the following algorithm: + * - TEXT if the two conditions below are satisfied: + * a) There are no non-portable control characters belonging to the + * "black list" (0..6, 14..25, 28..31). + * b) There is at least one printable character belonging to the + * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). + * - BINARY otherwise. + * - The following partially-portable control characters form a + * "gray list" that is ignored in this detection algorithm: + * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). + * IN assertion: the fields Freq of dyn_ltree are set. + */ +function detect_data_type(s) { + /* black_mask is the bit mask of black-listed bytes + * set bits 0..6, 14..25, and 28..31 + * 0xf3ffc07f = binary 11110011111111111100000001111111 + */ + var black_mask = 0xf3ffc07f; + var n; + + /* Check for non-textual ("black-listed") bytes. */ + for (n = 0; n <= 31; n++, black_mask >>>= 1) { + if ((black_mask & 1) && (s.dyn_ltree[n*2]/*.Freq*/ !== 0)) { + return Z_BINARY; + } + } + + /* Check for textual ("white-listed") bytes. */ + if (s.dyn_ltree[9 * 2]/*.Freq*/ !== 0 || s.dyn_ltree[10 * 2]/*.Freq*/ !== 0 || + s.dyn_ltree[13 * 2]/*.Freq*/ !== 0) { + return Z_TEXT; + } + for (n = 32; n < LITERALS; n++) { + if (s.dyn_ltree[n * 2]/*.Freq*/ !== 0) { + return Z_TEXT; + } + } + + /* There are no "black-listed" or "white-listed" bytes: + * this stream either is empty or has tolerated ("gray-listed") bytes only. + */ + return Z_BINARY; +} + + +var static_init_done = false; + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +function _tr_init(s) +{ + + if (!static_init_done) { + tr_static_init(); + static_init_done = true; + } + + s.l_desc = new TreeDesc(s.dyn_ltree, static_l_desc); + s.d_desc = new TreeDesc(s.dyn_dtree, static_d_desc); + s.bl_desc = new TreeDesc(s.bl_tree, static_bl_desc); + + s.bi_buf = 0; + s.bi_valid = 0; + + /* Initialize the first block of the first file: */ + init_block(s); +} + + +/* =========================================================================== + * Send a stored block + */ +function _tr_stored_block(s, buf, stored_len, last) +//DeflateState *s; +//charf *buf; /* input block */ +//ulg stored_len; /* length of input block */ +//int last; /* one if this is the last block for a file */ +{ + send_bits(s, (STORED_BLOCK<<1)+(last ? 1 : 0), 3); /* send block type */ + copy_block(s, buf, stored_len, true); /* with header */ +} + + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + */ +function _tr_align(s) { + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); + bi_flush(s); +} + + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. + */ +function _tr_flush_block(s, buf, stored_len, last) +//DeflateState *s; +//charf *buf; /* input block, or NULL if too old */ +//ulg stored_len; /* length of input block */ +//int last; /* one if this is the last block for a file */ +{ + var opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + var max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (s.level > 0) { + + /* Check if the file is binary or text */ + if (s.strm.data_type === Z_UNKNOWN) { + s.strm.data_type = detect_data_type(s); + } + + /* Construct the literal and distance trees */ + build_tree(s, s.l_desc); + // Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + // s->static_len)); + + build_tree(s, s.d_desc); + // Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + // s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute the block lengths in bytes. */ + opt_lenb = (s.opt_len+3+7) >>> 3; + static_lenb = (s.static_len+3+7) >>> 3; + + // Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + // opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + // s->last_lit)); + + if (static_lenb <= opt_lenb) { opt_lenb = static_lenb; } + + } else { + // Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + + if ((stored_len+4 <= opt_lenb) && (buf !== -1)) { + /* 4: two words for the lengths */ + + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + _tr_stored_block(s, buf, stored_len, last); + + } else if (s.strategy === Z_FIXED || static_lenb === opt_lenb) { + + send_bits(s, (STATIC_TREES<<1) + (last ? 1 : 0), 3); + compress_block(s, static_ltree, static_dtree); + + } else { + send_bits(s, (DYN_TREES<<1) + (last ? 1 : 0), 3); + send_all_trees(s, s.l_desc.max_code+1, s.d_desc.max_code+1, max_blindex+1); + compress_block(s, s.dyn_ltree, s.dyn_dtree); + } + // Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB + * and uLong implemented on 32 bits. + */ + init_block(s); + + if (last) { + bi_windup(s); + } + // Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, + // s->compressed_len-7*last)); +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +function _tr_tally(s, dist, lc) +// deflate_state *s; +// unsigned dist; /* distance of matched string */ +// unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ +{ + //var out_length, in_length, dcode; + + s.pending_buf[s.d_buf + s.last_lit * 2] = (dist >>> 8) & 0xff; + s.pending_buf[s.d_buf + s.last_lit * 2 + 1] = dist & 0xff; + + s.pending_buf[s.l_buf + s.last_lit] = lc & 0xff; + s.last_lit++; + + if (dist === 0) { + /* lc is the unmatched char */ + s.dyn_ltree[lc*2]/*.Freq*/++; + } else { + s.matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + //Assert((ush)dist < (ush)MAX_DIST(s) && + // (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + // (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); + + s.dyn_ltree[(_length_code[lc]+LITERALS+1) * 2]/*.Freq*/++; + s.dyn_dtree[d_code(dist) * 2]/*.Freq*/++; + } + +// (!) This block is disabled in zlib defailts, +// don't enable it for binary compatibility + +//#ifdef TRUNCATE_BLOCK +// /* Try to guess if it is profitable to stop the current block here */ +// if ((s.last_lit & 0x1fff) === 0 && s.level > 2) { +// /* Compute an upper bound for the compressed length */ +// out_length = s.last_lit*8; +// in_length = s.strstart - s.block_start; +// +// for (dcode = 0; dcode < D_CODES; dcode++) { +// out_length += s.dyn_dtree[dcode*2]/*.Freq*/ * (5 + extra_dbits[dcode]); +// } +// out_length >>>= 3; +// //Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", +// // s->last_lit, in_length, out_length, +// // 100L - out_length*100L/in_length)); +// if (s.matches < (s.last_lit>>1)/*int /2*/ && out_length < (in_length>>1)/*int /2*/) { +// return true; +// } +// } +//#endif + + return (s.last_lit === s.lit_bufsize-1); + /* We avoid equality with lit_bufsize because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ +} + +exports._tr_init = _tr_init; +exports._tr_stored_block = _tr_stored_block; +exports._tr_flush_block = _tr_flush_block; +exports._tr_tally = _tr_tally; +exports._tr_align = _tr_align; +},{"../utils/common":27}],39:[function(_dereq_,module,exports){ +'use strict'; + + +function ZStream() { + /* next input byte */ + this.input = null; // JS specific, because we have no pointers + this.next_in = 0; + /* number of bytes available at input */ + this.avail_in = 0; + /* total number of input bytes read so far */ + this.total_in = 0; + /* next output byte should be put there */ + this.output = null; // JS specific, because we have no pointers + this.next_out = 0; + /* remaining free space at output */ + this.avail_out = 0; + /* total number of bytes output so far */ + this.total_out = 0; + /* last error message, NULL if no error */ + this.msg = ''/*Z_NULL*/; + /* not visible by applications */ + this.state = null; + /* best guess about the data type: binary or text */ + this.data_type = 2/*Z_UNKNOWN*/; + /* adler32 value of the uncompressed data */ + this.adler = 0; +} + +module.exports = ZStream; +},{}]},{},[9]) +(9) +}); \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/export/libs/jszip/jszip.min.js b/iguana/js/amcharts/plugins/export/libs/jszip/jszip.min.js new file mode 100755 index 000000000..a09f35b86 --- /dev/null +++ b/iguana/js/amcharts/plugins/export/libs/jszip/jszip.min.js @@ -0,0 +1,14 @@ +/*! + +JSZip - A Javascript class for generating and reading zip files + + +(c) 2009-2014 Stuart Knightley +Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip/master/LICENSE.markdown. + +JSZip uses the library pako released under the MIT license : +https://github.com/nodeca/pako/blob/master/LICENSE +*/ +!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;"undefined"!=typeof window?b=window:"undefined"!=typeof global?b=global:"undefined"!=typeof self&&(b=self),b.JSZip=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);throw new Error("Cannot find module '"+g+"'")}var j=c[g]={exports:{}};b[g][0].call(j.exports,function(a){var c=b[g][1][a];return e(c?c:a)},j,j.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g>2,g=(3&b)<<4|c>>4,h=(15&c)<<2|e>>6,i=63&e,isNaN(c)?h=i=64:isNaN(e)&&(i=64),j=j+d.charAt(f)+d.charAt(g)+d.charAt(h)+d.charAt(i);return j},c.decode=function(a){var b,c,e,f,g,h,i,j="",k=0;for(a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");k>4,c=(15&g)<<4|h>>2,e=(3&h)<<6|i,j+=String.fromCharCode(b),64!=h&&(j+=String.fromCharCode(c)),64!=i&&(j+=String.fromCharCode(e));return j}},{}],2:[function(a,b){"use strict";function c(){this.compressedSize=0,this.uncompressedSize=0,this.crc32=0,this.compressionMethod=null,this.compressedContent=null}c.prototype={getContent:function(){return null},getCompressedContent:function(){return null}},b.exports=c},{}],3:[function(a,b,c){"use strict";c.STORE={magic:"\x00\x00",compress:function(a){return a},uncompress:function(a){return a},compressInputType:null,uncompressInputType:null},c.DEFLATE=a("./flate")},{"./flate":8}],4:[function(a,b){"use strict";var c=a("./utils"),d=[0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918e3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117];b.exports=function(a,b){if("undefined"==typeof a||!a.length)return 0;var e="string"!==c.getTypeOf(a);"undefined"==typeof b&&(b=0);var f=0,g=0,h=0;b=-1^b;for(var i=0,j=a.length;j>i;i++)h=e?a[i]:a.charCodeAt(i),g=255&(b^h),f=d[g],b=b>>>8^f;return-1^b}},{"./utils":21}],5:[function(a,b){"use strict";function c(){this.data=null,this.length=0,this.index=0}var d=a("./utils");c.prototype={checkOffset:function(a){this.checkIndex(this.index+a)},checkIndex:function(a){if(this.lengtha)throw new Error("End of data reached (data length = "+this.length+", asked index = "+a+"). Corrupted zip ?")},setIndex:function(a){this.checkIndex(a),this.index=a},skip:function(a){this.setIndex(this.index+a)},byteAt:function(){},readInt:function(a){var b,c=0;for(this.checkOffset(a),b=this.index+a-1;b>=this.index;b--)c=(c<<8)+this.byteAt(b);return this.index+=a,c},readString:function(a){return d.transformTo("string",this.readData(a))},readData:function(){},lastIndexOfSignature:function(){},readDate:function(){var a=this.readInt(4);return new Date((a>>25&127)+1980,(a>>21&15)-1,a>>16&31,a>>11&31,a>>5&63,(31&a)<<1)}},b.exports=c},{"./utils":21}],6:[function(a,b,c){"use strict";c.base64=!1,c.binary=!1,c.dir=!1,c.createFolders=!1,c.date=null,c.compression=null,c.compressionOptions=null,c.comment=null,c.unixPermissions=null,c.dosPermissions=null},{}],7:[function(a,b,c){"use strict";var d=a("./utils");c.string2binary=function(a){return d.string2binary(a)},c.string2Uint8Array=function(a){return d.transformTo("uint8array",a)},c.uint8Array2String=function(a){return d.transformTo("string",a)},c.string2Blob=function(a){var b=d.transformTo("arraybuffer",a);return d.arrayBuffer2Blob(b)},c.arrayBuffer2Blob=function(a){return d.arrayBuffer2Blob(a)},c.transformTo=function(a,b){return d.transformTo(a,b)},c.getTypeOf=function(a){return d.getTypeOf(a)},c.checkSupport=function(a){return d.checkSupport(a)},c.MAX_VALUE_16BITS=d.MAX_VALUE_16BITS,c.MAX_VALUE_32BITS=d.MAX_VALUE_32BITS,c.pretty=function(a){return d.pretty(a)},c.findCompression=function(a){return d.findCompression(a)},c.isRegExp=function(a){return d.isRegExp(a)}},{"./utils":21}],8:[function(a,b,c){"use strict";var d="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Uint32Array,e=a("pako");c.uncompressInputType=d?"uint8array":"array",c.compressInputType=d?"uint8array":"array",c.magic="\b\x00",c.compress=function(a,b){return e.deflateRaw(a,{level:b.level||-1})},c.uncompress=function(a){return e.inflateRaw(a)}},{pako:24}],9:[function(a,b){"use strict";function c(a,b){return this instanceof c?(this.files={},this.comment=null,this.root="",a&&this.load(a,b),void(this.clone=function(){var a=new c;for(var b in this)"function"!=typeof this[b]&&(a[b]=this[b]);return a})):new c(a,b)}var d=a("./base64");c.prototype=a("./object"),c.prototype.load=a("./load"),c.support=a("./support"),c.defaults=a("./defaults"),c.utils=a("./deprecatedPublicUtils"),c.base64={encode:function(a){return d.encode(a)},decode:function(a){return d.decode(a)}},c.compressions=a("./compressions"),b.exports=c},{"./base64":1,"./compressions":3,"./defaults":6,"./deprecatedPublicUtils":7,"./load":10,"./object":13,"./support":17}],10:[function(a,b){"use strict";var c=a("./base64"),d=a("./zipEntries");b.exports=function(a,b){var e,f,g,h;for(b=b||{},b.base64&&(a=c.decode(a)),f=new d(a,b),e=f.files,g=0;gc;c++)d+=String.fromCharCode(255&a),a>>>=8;return d},t=function(){var a,b,c={};for(a=0;a0?a.substring(0,b):""},x=function(a){return"/"!=a.slice(-1)&&(a+="/"),a},y=function(a,b){return b="undefined"!=typeof b?b:!1,a=x(a),this.files[a]||v.call(this,a,null,{dir:!0,createFolders:b}),this.files[a]},z=function(a,b,c){var f,g=new j;return a._data instanceof j?(g.uncompressedSize=a._data.uncompressedSize,g.crc32=a._data.crc32,0===g.uncompressedSize||a.dir?(b=i.STORE,g.compressedContent="",g.crc32=0):a._data.compressionMethod===b.magic?g.compressedContent=a._data.getCompressedContent():(f=a._data.getContent(),g.compressedContent=b.compress(d.transformTo(b.compressInputType,f),c))):(f=p(a),(!f||0===f.length||a.dir)&&(b=i.STORE,f=""),g.uncompressedSize=f.length,g.crc32=e(f),g.compressedContent=b.compress(d.transformTo(b.compressInputType,f),c)),g.compressedSize=g.compressedContent.length,g.compressionMethod=b.magic,g},A=function(a,b){var c=a;return a||(c=b?16893:33204),(65535&c)<<16},B=function(a){return 63&(a||0)},C=function(a,b,c,g,h){var i,j,k,m,n=(c.compressedContent,d.transformTo("string",l.utf8encode(b.name))),o=b.comment||"",p=d.transformTo("string",l.utf8encode(o)),q=n.length!==b.name.length,r=p.length!==o.length,t=b.options,u="",v="",w="";k=b._initialMetadata.dir!==b.dir?b.dir:t.dir,m=b._initialMetadata.date!==b.date?b.date:t.date;var x=0,y=0;k&&(x|=16),"UNIX"===h?(y=798,x|=A(b.unixPermissions,k)):(y=20,x|=B(b.dosPermissions,k)),i=m.getHours(),i<<=6,i|=m.getMinutes(),i<<=5,i|=m.getSeconds()/2,j=m.getFullYear()-1980,j<<=4,j|=m.getMonth()+1,j<<=5,j|=m.getDate(),q&&(v=s(1,1)+s(e(n),4)+n,u+="up"+s(v.length,2)+v),r&&(w=s(1,1)+s(this.crc32(p),4)+p,u+="uc"+s(w.length,2)+w);var z="";z+="\n\x00",z+=q||r?"\x00\b":"\x00\x00",z+=c.compressionMethod,z+=s(i,2),z+=s(j,2),z+=s(c.crc32,4),z+=s(c.compressedSize,4),z+=s(c.uncompressedSize,4),z+=s(n.length,2),z+=s(u.length,2);var C=f.LOCAL_FILE_HEADER+z+n+u,D=f.CENTRAL_FILE_HEADER+s(y,2)+z+s(p.length,2)+"\x00\x00\x00\x00"+s(x,4)+s(g,4)+n+u+p;return{fileRecord:C,dirRecord:D,compressedObject:c}},D={load:function(){throw new Error("Load method is not defined. Is the file jszip-load.js included ?")},filter:function(a){var b,c,d,e,f=[];for(b in this.files)this.files.hasOwnProperty(b)&&(d=this.files[b],e=new r(d.name,d._data,t(d.options)),c=b.slice(this.root.length,b.length),b.slice(0,this.root.length)===this.root&&a(c,e)&&f.push(e));return f},file:function(a,b,c){if(1===arguments.length){if(d.isRegExp(a)){var e=a;return this.filter(function(a,b){return!b.dir&&e.test(a)})}return this.filter(function(b,c){return!c.dir&&b===a})[0]||null}return a=this.root+a,v.call(this,a,b,c),this},folder:function(a){if(!a)return this;if(d.isRegExp(a))return this.filter(function(b,c){return c.dir&&a.test(b)});var b=this.root+a,c=y.call(this,b),e=this.clone();return e.root=c.name,e},remove:function(a){a=this.root+a;var b=this.files[a];if(b||("/"!=a.slice(-1)&&(a+="/"),b=this.files[a]),b&&!b.dir)delete this.files[a];else for(var c=this.filter(function(b,c){return c.name.slice(0,a.length)===a}),d=0;d=0;--f)if(this.data[f]===b&&this.data[f+1]===c&&this.data[f+2]===d&&this.data[f+3]===e)return f;return-1},c.prototype.readData=function(a){if(this.checkOffset(a),0===a)return new Uint8Array(0);var b=this.data.subarray(this.index,this.index+a);return this.index+=a,b},b.exports=c},{"./dataReader":5}],19:[function(a,b){"use strict";var c=a("./utils"),d=function(a){this.data=new Uint8Array(a),this.index=0};d.prototype={append:function(a){0!==a.length&&(a=c.transformTo("uint8array",a),this.data.set(a,this.index),this.index+=a.length)},finalize:function(){return this.data}},b.exports=d},{"./utils":21}],20:[function(a,b,c){"use strict";for(var d=a("./utils"),e=a("./support"),f=a("./nodeBuffer"),g=new Array(256),h=0;256>h;h++)g[h]=h>=252?6:h>=248?5:h>=240?4:h>=224?3:h>=192?2:1;g[254]=g[254]=1;var i=function(a){var b,c,d,f,g,h=a.length,i=0;for(f=0;h>f;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),i+=128>c?1:2048>c?2:65536>c?3:4;for(b=e.uint8array?new Uint8Array(i):new Array(i),g=0,f=0;i>g;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),128>c?b[g++]=c:2048>c?(b[g++]=192|c>>>6,b[g++]=128|63&c):65536>c?(b[g++]=224|c>>>12,b[g++]=128|c>>>6&63,b[g++]=128|63&c):(b[g++]=240|c>>>18,b[g++]=128|c>>>12&63,b[g++]=128|c>>>6&63,b[g++]=128|63&c);return b},j=function(a,b){var c;for(b=b||a.length,b>a.length&&(b=a.length),c=b-1;c>=0&&128===(192&a[c]);)c--;return 0>c?b:0===c?b:c+g[a[c]]>b?c:b},k=function(a){var b,c,e,f,h=a.length,i=new Array(2*h);for(c=0,b=0;h>b;)if(e=a[b++],128>e)i[c++]=e;else if(f=g[e],f>4)i[c++]=65533,b+=f-1;else{for(e&=2===f?31:3===f?15:7;f>1&&h>b;)e=e<<6|63&a[b++],f--;f>1?i[c++]=65533:65536>e?i[c++]=e:(e-=65536,i[c++]=55296|e>>10&1023,i[c++]=56320|1023&e)}return i.length!==c&&(i.subarray?i=i.subarray(0,c):i.length=c),d.applyFromCharCode(i)};c.utf8encode=function(a){return e.nodebuffer?f(a,"utf-8"):i(a)},c.utf8decode=function(a){if(e.nodebuffer)return d.transformTo("nodebuffer",a).toString("utf-8");a=d.transformTo(e.uint8array?"uint8array":"array",a);for(var b=[],c=0,f=a.length,g=65536;f>c;){var h=j(a,Math.min(c+g,f));b.push(e.uint8array?k(a.subarray(c,h)):k(a.slice(c,h))),c=h}return b.join("")}},{"./nodeBuffer":11,"./support":17,"./utils":21}],21:[function(a,b,c){"use strict";function d(a){return a}function e(a,b){for(var c=0;cg&&b>1;)try{d.push("array"===f||"nodebuffer"===f?String.fromCharCode.apply(null,a.slice(g,Math.min(g+b,e))):String.fromCharCode.apply(null,a.subarray(g,Math.min(g+b,e)))),g+=b}catch(i){b=Math.floor(b/2)}return d.join("")}function g(a,b){for(var c=0;cb?"0":"")+b.toString(16).toUpperCase();return d},c.findCompression=function(a){for(var b in i)if(i.hasOwnProperty(b)&&i[b].magic===a)return i[b];return null},c.isRegExp=function(a){return"[object RegExp]"===Object.prototype.toString.call(a)}},{"./compressions":3,"./nodeBuffer":11,"./support":17}],22:[function(a,b){"use strict";function c(a,b){this.files=[],this.loadOptions=b,a&&this.load(a)}var d=a("./stringReader"),e=a("./nodeBufferReader"),f=a("./uint8ArrayReader"),g=a("./utils"),h=a("./signature"),i=a("./zipEntry"),j=a("./support"),k=a("./object");c.prototype={checkSignature:function(a){var b=this.reader.readString(4);if(b!==a)throw new Error("Corrupted zip or bug : unexpected signature ("+g.pretty(b)+", expected "+g.pretty(a)+")")},readBlockEndOfCentral:function(){this.diskNumber=this.reader.readInt(2),this.diskWithCentralDirStart=this.reader.readInt(2),this.centralDirRecordsOnThisDisk=this.reader.readInt(2),this.centralDirRecords=this.reader.readInt(2),this.centralDirSize=this.reader.readInt(4),this.centralDirOffset=this.reader.readInt(4),this.zipCommentLength=this.reader.readInt(2),this.zipComment=this.reader.readString(this.zipCommentLength),this.zipComment=k.utf8decode(this.zipComment)},readBlockZip64EndOfCentral:function(){this.zip64EndOfCentralSize=this.reader.readInt(8),this.versionMadeBy=this.reader.readString(2),this.versionNeeded=this.reader.readInt(2),this.diskNumber=this.reader.readInt(4),this.diskWithCentralDirStart=this.reader.readInt(4),this.centralDirRecordsOnThisDisk=this.reader.readInt(8),this.centralDirRecords=this.reader.readInt(8),this.centralDirSize=this.reader.readInt(8),this.centralDirOffset=this.reader.readInt(8),this.zip64ExtensibleData={};for(var a,b,c,d=this.zip64EndOfCentralSize-44,e=0;d>e;)a=this.reader.readInt(2),b=this.reader.readInt(4),c=this.reader.readString(b),this.zip64ExtensibleData[a]={id:a,length:b,value:c}},readBlockZip64EndOfCentralLocator:function(){if(this.diskWithZip64CentralDirStart=this.reader.readInt(4),this.relativeOffsetEndOfZip64CentralDir=this.reader.readInt(8),this.disksCount=this.reader.readInt(4),this.disksCount>1)throw new Error("Multi-volumes zip are not supported")},readLocalFiles:function(){var a,b;for(a=0;a>8;this.dir=16&this.externalFileAttributes?!0:!1,a===h&&(this.dosPermissions=63&this.externalFileAttributes),a===i&&(this.unixPermissions=this.externalFileAttributes>>16&65535),this.dir||"/"!==this.fileName.slice(-1)||(this.dir=!0)},parseZIP64ExtraField:function(){if(this.extraFields[1]){var a=new d(this.extraFields[1].value);this.uncompressedSize===e.MAX_VALUE_32BITS&&(this.uncompressedSize=a.readInt(8)),this.compressedSize===e.MAX_VALUE_32BITS&&(this.compressedSize=a.readInt(8)),this.localHeaderOffset===e.MAX_VALUE_32BITS&&(this.localHeaderOffset=a.readInt(8)),this.diskNumberStart===e.MAX_VALUE_32BITS&&(this.diskNumberStart=a.readInt(4))}},readExtraFields:function(a){var b,c,d,e=a.index;for(this.extraFields=this.extraFields||{};a.index0?b.windowBits=-b.windowBits:b.gzip&&b.windowBits>0&&b.windowBits<16&&(b.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new k,this.strm.avail_out=0;var c=g.deflateInit2(this.strm,b.level,b.method,b.windowBits,b.memLevel,b.strategy);if(c!==n)throw new Error(j[c]);b.header&&g.deflateSetHeader(this.strm,b.header)};s.prototype.push=function(a,b){var c,d,e=this.strm,f=this.options.chunkSize;if(this.ended)return!1;d=b===~~b?b:b===!0?m:l,e.input="string"==typeof a?i.string2buf(a):a,e.next_in=0,e.avail_in=e.input.length;do{if(0===e.avail_out&&(e.output=new h.Buf8(f),e.next_out=0,e.avail_out=f),c=g.deflate(e,d),c!==o&&c!==n)return this.onEnd(c),this.ended=!0,!1;(0===e.avail_out||0===e.avail_in&&d===m)&&this.onData("string"===this.options.to?i.buf2binstring(h.shrinkBuf(e.output,e.next_out)):h.shrinkBuf(e.output,e.next_out))}while((e.avail_in>0||0===e.avail_out)&&c!==o);return d===m?(c=g.deflateEnd(this.strm),this.onEnd(c),this.ended=!0,c===n):!0},s.prototype.onData=function(a){this.chunks.push(a)},s.prototype.onEnd=function(a){a===n&&(this.result="string"===this.options.to?this.chunks.join(""):h.flattenChunks(this.chunks)),this.chunks=[],this.err=a,this.msg=this.strm.msg},c.Deflate=s,c.deflate=d,c.deflateRaw=e,c.gzip=f},{"./utils/common":27,"./utils/strings":28,"./zlib/deflate.js":32,"./zlib/messages":37,"./zlib/zstream":39}],26:[function(a,b,c){"use strict";function d(a,b){var c=new m(b);if(c.push(a,!0),c.err)throw c.msg;return c.result}function e(a,b){return b=b||{},b.raw=!0,d(a,b)}var f=a("./zlib/inflate.js"),g=a("./utils/common"),h=a("./utils/strings"),i=a("./zlib/constants"),j=a("./zlib/messages"),k=a("./zlib/zstream"),l=a("./zlib/gzheader"),m=function(a){this.options=g.assign({chunkSize:16384,windowBits:0,to:""},a||{});var b=this.options;b.raw&&b.windowBits>=0&&b.windowBits<16&&(b.windowBits=-b.windowBits,0===b.windowBits&&(b.windowBits=-15)),!(b.windowBits>=0&&b.windowBits<16)||a&&a.windowBits||(b.windowBits+=32),b.windowBits>15&&b.windowBits<48&&0===(15&b.windowBits)&&(b.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new k,this.strm.avail_out=0;var c=f.inflateInit2(this.strm,b.windowBits);if(c!==i.Z_OK)throw new Error(j[c]);this.header=new l,f.inflateGetHeader(this.strm,this.header)};m.prototype.push=function(a,b){var c,d,e,j,k,l=this.strm,m=this.options.chunkSize;if(this.ended)return!1;d=b===~~b?b:b===!0?i.Z_FINISH:i.Z_NO_FLUSH,l.input="string"==typeof a?h.binstring2buf(a):a,l.next_in=0,l.avail_in=l.input.length;do{if(0===l.avail_out&&(l.output=new g.Buf8(m),l.next_out=0,l.avail_out=m),c=f.inflate(l,i.Z_NO_FLUSH),c!==i.Z_STREAM_END&&c!==i.Z_OK)return this.onEnd(c),this.ended=!0,!1;l.next_out&&(0===l.avail_out||c===i.Z_STREAM_END||0===l.avail_in&&d===i.Z_FINISH)&&("string"===this.options.to?(e=h.utf8border(l.output,l.next_out),j=l.next_out-e,k=h.buf2string(l.output,e),l.next_out=j,l.avail_out=m-j,j&&g.arraySet(l.output,l.output,e,j,0),this.onData(k)):this.onData(g.shrinkBuf(l.output,l.next_out)))}while(l.avail_in>0&&c!==i.Z_STREAM_END);return c===i.Z_STREAM_END&&(d=i.Z_FINISH),d===i.Z_FINISH?(c=f.inflateEnd(this.strm),this.onEnd(c),this.ended=!0,c===i.Z_OK):!0},m.prototype.onData=function(a){this.chunks.push(a)},m.prototype.onEnd=function(a){a===i.Z_OK&&(this.result="string"===this.options.to?this.chunks.join(""):g.flattenChunks(this.chunks)),this.chunks=[],this.err=a,this.msg=this.strm.msg},c.Inflate=m,c.inflate=d,c.inflateRaw=e,c.ungzip=d},{"./utils/common":27,"./utils/strings":28,"./zlib/constants":30,"./zlib/gzheader":33,"./zlib/inflate.js":35,"./zlib/messages":37,"./zlib/zstream":39}],27:[function(a,b,c){"use strict";var d="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Int32Array;c.assign=function(a){for(var b=Array.prototype.slice.call(arguments,1);b.length;){var c=b.shift();if(c){if("object"!=typeof c)throw new TypeError(c+"must be non-object");for(var d in c)c.hasOwnProperty(d)&&(a[d]=c[d])}}return a},c.shrinkBuf=function(a,b){return a.length===b?a:a.subarray?a.subarray(0,b):(a.length=b,a)};var e={arraySet:function(a,b,c,d,e){if(b.subarray&&a.subarray)return void a.set(b.subarray(c,c+d),e);for(var f=0;d>f;f++)a[e+f]=b[c+f]},flattenChunks:function(a){var b,c,d,e,f,g;for(d=0,b=0,c=a.length;c>b;b++)d+=a[b].length;for(g=new Uint8Array(d),e=0,b=0,c=a.length;c>b;b++)f=a[b],g.set(f,e),e+=f.length;return g}},f={arraySet:function(a,b,c,d,e){for(var f=0;d>f;f++)a[e+f]=b[c+f]},flattenChunks:function(a){return[].concat.apply([],a)}};c.setTyped=function(a){a?(c.Buf8=Uint8Array,c.Buf16=Uint16Array,c.Buf32=Int32Array,c.assign(c,e)):(c.Buf8=Array,c.Buf16=Array,c.Buf32=Array,c.assign(c,f))},c.setTyped(d)},{}],28:[function(a,b,c){"use strict";function d(a,b){if(65537>b&&(a.subarray&&g||!a.subarray&&f))return String.fromCharCode.apply(null,e.shrinkBuf(a,b));for(var c="",d=0;b>d;d++)c+=String.fromCharCode(a[d]);return c}var e=a("./common"),f=!0,g=!0;try{String.fromCharCode.apply(null,[0])}catch(h){f=!1}try{String.fromCharCode.apply(null,new Uint8Array(1))}catch(h){g=!1}for(var i=new e.Buf8(256),j=0;256>j;j++)i[j]=j>=252?6:j>=248?5:j>=240?4:j>=224?3:j>=192?2:1;i[254]=i[254]=1,c.string2buf=function(a){var b,c,d,f,g,h=a.length,i=0;for(f=0;h>f;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),i+=128>c?1:2048>c?2:65536>c?3:4;for(b=new e.Buf8(i),g=0,f=0;i>g;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),128>c?b[g++]=c:2048>c?(b[g++]=192|c>>>6,b[g++]=128|63&c):65536>c?(b[g++]=224|c>>>12,b[g++]=128|c>>>6&63,b[g++]=128|63&c):(b[g++]=240|c>>>18,b[g++]=128|c>>>12&63,b[g++]=128|c>>>6&63,b[g++]=128|63&c);return b},c.buf2binstring=function(a){return d(a,a.length)},c.binstring2buf=function(a){for(var b=new e.Buf8(a.length),c=0,d=b.length;d>c;c++)b[c]=a.charCodeAt(c);return b},c.buf2string=function(a,b){var c,e,f,g,h=b||a.length,j=new Array(2*h);for(e=0,c=0;h>c;)if(f=a[c++],128>f)j[e++]=f;else if(g=i[f],g>4)j[e++]=65533,c+=g-1;else{for(f&=2===g?31:3===g?15:7;g>1&&h>c;)f=f<<6|63&a[c++],g--;g>1?j[e++]=65533:65536>f?j[e++]=f:(f-=65536,j[e++]=55296|f>>10&1023,j[e++]=56320|1023&f)}return d(j,e)},c.utf8border=function(a,b){var c;for(b=b||a.length,b>a.length&&(b=a.length),c=b-1;c>=0&&128===(192&a[c]);)c--;return 0>c?b:0===c?b:c+i[a[c]]>b?c:b}},{"./common":27}],29:[function(a,b){"use strict";function c(a,b,c,d){for(var e=65535&a|0,f=a>>>16&65535|0,g=0;0!==c;){g=c>2e3?2e3:c,c-=g;do e=e+b[d++]|0,f=f+e|0;while(--g);e%=65521,f%=65521}return e|f<<16|0}b.exports=c},{}],30:[function(a,b){b.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8}},{}],31:[function(a,b){"use strict";function c(){for(var a,b=[],c=0;256>c;c++){a=c;for(var d=0;8>d;d++)a=1&a?3988292384^a>>>1:a>>>1;b[c]=a}return b}function d(a,b,c,d){var f=e,g=d+c;a=-1^a;for(var h=d;g>h;h++)a=a>>>8^f[255&(a^b[h])];return-1^a}var e=c();b.exports=d},{}],32:[function(a,b,c){"use strict";function d(a,b){return a.msg=G[b],b}function e(a){return(a<<1)-(a>4?9:0)}function f(a){for(var b=a.length;--b>=0;)a[b]=0}function g(a){var b=a.state,c=b.pending;c>a.avail_out&&(c=a.avail_out),0!==c&&(C.arraySet(a.output,b.pending_buf,b.pending_out,c,a.next_out),a.next_out+=c,b.pending_out+=c,a.total_out+=c,a.avail_out-=c,b.pending-=c,0===b.pending&&(b.pending_out=0))}function h(a,b){D._tr_flush_block(a,a.block_start>=0?a.block_start:-1,a.strstart-a.block_start,b),a.block_start=a.strstart,g(a.strm)}function i(a,b){a.pending_buf[a.pending++]=b}function j(a,b){a.pending_buf[a.pending++]=b>>>8&255,a.pending_buf[a.pending++]=255&b}function k(a,b,c,d){var e=a.avail_in;return e>d&&(e=d),0===e?0:(a.avail_in-=e,C.arraySet(b,a.input,a.next_in,e,c),1===a.state.wrap?a.adler=E(a.adler,b,e,c):2===a.state.wrap&&(a.adler=F(a.adler,b,e,c)),a.next_in+=e,a.total_in+=e,e)}function l(a,b){var c,d,e=a.max_chain_length,f=a.strstart,g=a.prev_length,h=a.nice_match,i=a.strstart>a.w_size-jb?a.strstart-(a.w_size-jb):0,j=a.window,k=a.w_mask,l=a.prev,m=a.strstart+ib,n=j[f+g-1],o=j[f+g];a.prev_length>=a.good_match&&(e>>=2),h>a.lookahead&&(h=a.lookahead);do if(c=b,j[c+g]===o&&j[c+g-1]===n&&j[c]===j[f]&&j[++c]===j[f+1]){f+=2,c++;do;while(j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&m>f);if(d=ib-(m-f),f=m-ib,d>g){if(a.match_start=b,g=d,d>=h)break;n=j[f+g-1],o=j[f+g]}}while((b=l[b&k])>i&&0!==--e);return g<=a.lookahead?g:a.lookahead}function m(a){var b,c,d,e,f,g=a.w_size;do{if(e=a.window_size-a.lookahead-a.strstart,a.strstart>=g+(g-jb)){C.arraySet(a.window,a.window,g,g,0),a.match_start-=g,a.strstart-=g,a.block_start-=g,c=a.hash_size,b=c;do d=a.head[--b],a.head[b]=d>=g?d-g:0;while(--c);c=g,b=c;do d=a.prev[--b],a.prev[b]=d>=g?d-g:0;while(--c);e+=g}if(0===a.strm.avail_in)break;if(c=k(a.strm,a.window,a.strstart+a.lookahead,e),a.lookahead+=c,a.lookahead+a.insert>=hb)for(f=a.strstart-a.insert,a.ins_h=a.window[f],a.ins_h=(a.ins_h<a.pending_buf_size-5&&(c=a.pending_buf_size-5);;){if(a.lookahead<=1){if(m(a),0===a.lookahead&&b===H)return sb;if(0===a.lookahead)break}a.strstart+=a.lookahead,a.lookahead=0;var d=a.block_start+c;if((0===a.strstart||a.strstart>=d)&&(a.lookahead=a.strstart-d,a.strstart=d,h(a,!1),0===a.strm.avail_out))return sb;if(a.strstart-a.block_start>=a.w_size-jb&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=0,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.strstart>a.block_start&&(h(a,!1),0===a.strm.avail_out)?sb:sb}function o(a,b){for(var c,d;;){if(a.lookahead=hb&&(a.ins_h=(a.ins_h<=hb)if(d=D._tr_tally(a,a.strstart-a.match_start,a.match_length-hb),a.lookahead-=a.match_length,a.match_length<=a.max_lazy_match&&a.lookahead>=hb){a.match_length--;do a.strstart++,a.ins_h=(a.ins_h<=hb&&(a.ins_h=(a.ins_h<4096)&&(a.match_length=hb-1)),a.prev_length>=hb&&a.match_length<=a.prev_length){e=a.strstart+a.lookahead-hb,d=D._tr_tally(a,a.strstart-1-a.prev_match,a.prev_length-hb),a.lookahead-=a.prev_length-1,a.prev_length-=2;do++a.strstart<=e&&(a.ins_h=(a.ins_h<=hb&&a.strstart>0&&(e=a.strstart-1,d=g[e],d===g[++e]&&d===g[++e]&&d===g[++e])){f=a.strstart+ib;do;while(d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&f>e);a.match_length=ib-(f-e),a.match_length>a.lookahead&&(a.match_length=a.lookahead)}if(a.match_length>=hb?(c=D._tr_tally(a,1,a.match_length-hb),a.lookahead-=a.match_length,a.strstart+=a.match_length,a.match_length=0):(c=D._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++),c&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=0,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function r(a,b){for(var c;;){if(0===a.lookahead&&(m(a),0===a.lookahead)){if(b===H)return sb;break}if(a.match_length=0,c=D._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++,c&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=0,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function s(a){a.window_size=2*a.w_size,f(a.head),a.max_lazy_match=B[a.level].max_lazy,a.good_match=B[a.level].good_length,a.nice_match=B[a.level].nice_length,a.max_chain_length=B[a.level].max_chain,a.strstart=0,a.block_start=0,a.lookahead=0,a.insert=0,a.match_length=a.prev_length=hb-1,a.match_available=0,a.ins_h=0}function t(){this.strm=null,this.status=0,this.pending_buf=null,this.pending_buf_size=0,this.pending_out=0,this.pending=0,this.wrap=0,this.gzhead=null,this.gzindex=0,this.method=Y,this.last_flush=-1,this.w_size=0,this.w_bits=0,this.w_mask=0,this.window=null,this.window_size=0,this.prev=null,this.head=null,this.ins_h=0,this.hash_size=0,this.hash_bits=0,this.hash_mask=0,this.hash_shift=0,this.block_start=0,this.match_length=0,this.prev_match=0,this.match_available=0,this.strstart=0,this.match_start=0,this.lookahead=0,this.prev_length=0,this.max_chain_length=0,this.max_lazy_match=0,this.level=0,this.strategy=0,this.good_match=0,this.nice_match=0,this.dyn_ltree=new C.Buf16(2*fb),this.dyn_dtree=new C.Buf16(2*(2*db+1)),this.bl_tree=new C.Buf16(2*(2*eb+1)),f(this.dyn_ltree),f(this.dyn_dtree),f(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new C.Buf16(gb+1),this.heap=new C.Buf16(2*cb+1),f(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new C.Buf16(2*cb+1),f(this.depth),this.l_buf=0,this.lit_bufsize=0,this.last_lit=0,this.d_buf=0,this.opt_len=0,this.static_len=0,this.matches=0,this.insert=0,this.bi_buf=0,this.bi_valid=0}function u(a){var b;return a&&a.state?(a.total_in=a.total_out=0,a.data_type=X,b=a.state,b.pending=0,b.pending_out=0,b.wrap<0&&(b.wrap=-b.wrap),b.status=b.wrap?lb:qb,a.adler=2===b.wrap?0:1,b.last_flush=H,D._tr_init(b),M):d(a,O)}function v(a){var b=u(a);return b===M&&s(a.state),b}function w(a,b){return a&&a.state?2!==a.state.wrap?O:(a.state.gzhead=b,M):O}function x(a,b,c,e,f,g){if(!a)return O;var h=1;if(b===R&&(b=6),0>e?(h=0,e=-e):e>15&&(h=2,e-=16),1>f||f>Z||c!==Y||8>e||e>15||0>b||b>9||0>g||g>V)return d(a,O);8===e&&(e=9);var i=new t;return a.state=i,i.strm=a,i.wrap=h,i.gzhead=null,i.w_bits=e,i.w_size=1<>1,i.l_buf=3*i.lit_bufsize,i.level=b,i.strategy=g,i.method=c,v(a)}function y(a,b){return x(a,b,Y,$,_,W)}function z(a,b){var c,h,k,l;if(!a||!a.state||b>L||0>b)return a?d(a,O):O;if(h=a.state,!a.output||!a.input&&0!==a.avail_in||h.status===rb&&b!==K)return d(a,0===a.avail_out?Q:O);if(h.strm=a,c=h.last_flush,h.last_flush=b,h.status===lb)if(2===h.wrap)a.adler=0,i(h,31),i(h,139),i(h,8),h.gzhead?(i(h,(h.gzhead.text?1:0)+(h.gzhead.hcrc?2:0)+(h.gzhead.extra?4:0)+(h.gzhead.name?8:0)+(h.gzhead.comment?16:0)),i(h,255&h.gzhead.time),i(h,h.gzhead.time>>8&255),i(h,h.gzhead.time>>16&255),i(h,h.gzhead.time>>24&255),i(h,9===h.level?2:h.strategy>=T||h.level<2?4:0),i(h,255&h.gzhead.os),h.gzhead.extra&&h.gzhead.extra.length&&(i(h,255&h.gzhead.extra.length),i(h,h.gzhead.extra.length>>8&255)),h.gzhead.hcrc&&(a.adler=F(a.adler,h.pending_buf,h.pending,0)),h.gzindex=0,h.status=mb):(i(h,0),i(h,0),i(h,0),i(h,0),i(h,0),i(h,9===h.level?2:h.strategy>=T||h.level<2?4:0),i(h,wb),h.status=qb);else{var m=Y+(h.w_bits-8<<4)<<8,n=-1;n=h.strategy>=T||h.level<2?0:h.level<6?1:6===h.level?2:3,m|=n<<6,0!==h.strstart&&(m|=kb),m+=31-m%31,h.status=qb,j(h,m),0!==h.strstart&&(j(h,a.adler>>>16),j(h,65535&a.adler)),a.adler=1}if(h.status===mb)if(h.gzhead.extra){for(k=h.pending;h.gzindex<(65535&h.gzhead.extra.length)&&(h.pending!==h.pending_buf_size||(h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending!==h.pending_buf_size));)i(h,255&h.gzhead.extra[h.gzindex]),h.gzindex++;h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),h.gzindex===h.gzhead.extra.length&&(h.gzindex=0,h.status=nb)}else h.status=nb;if(h.status===nb)if(h.gzhead.name){k=h.pending;do{if(h.pending===h.pending_buf_size&&(h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending===h.pending_buf_size)){l=1;break}l=h.gzindexk&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),0===l&&(h.gzindex=0,h.status=ob)}else h.status=ob;if(h.status===ob)if(h.gzhead.comment){k=h.pending;do{if(h.pending===h.pending_buf_size&&(h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending===h.pending_buf_size)){l=1;break}l=h.gzindexk&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),0===l&&(h.status=pb)}else h.status=pb;if(h.status===pb&&(h.gzhead.hcrc?(h.pending+2>h.pending_buf_size&&g(a),h.pending+2<=h.pending_buf_size&&(i(h,255&a.adler),i(h,a.adler>>8&255),a.adler=0,h.status=qb)):h.status=qb),0!==h.pending){if(g(a),0===a.avail_out)return h.last_flush=-1,M}else if(0===a.avail_in&&e(b)<=e(c)&&b!==K)return d(a,Q);if(h.status===rb&&0!==a.avail_in)return d(a,Q);if(0!==a.avail_in||0!==h.lookahead||b!==H&&h.status!==rb){var o=h.strategy===T?r(h,b):h.strategy===U?q(h,b):B[h.level].func(h,b);if((o===ub||o===vb)&&(h.status=rb),o===sb||o===ub)return 0===a.avail_out&&(h.last_flush=-1),M;if(o===tb&&(b===I?D._tr_align(h):b!==L&&(D._tr_stored_block(h,0,0,!1),b===J&&(f(h.head),0===h.lookahead&&(h.strstart=0,h.block_start=0,h.insert=0))),g(a),0===a.avail_out))return h.last_flush=-1,M}return b!==K?M:h.wrap<=0?N:(2===h.wrap?(i(h,255&a.adler),i(h,a.adler>>8&255),i(h,a.adler>>16&255),i(h,a.adler>>24&255),i(h,255&a.total_in),i(h,a.total_in>>8&255),i(h,a.total_in>>16&255),i(h,a.total_in>>24&255)):(j(h,a.adler>>>16),j(h,65535&a.adler)),g(a),h.wrap>0&&(h.wrap=-h.wrap),0!==h.pending?M:N)}function A(a){var b;return a&&a.state?(b=a.state.status,b!==lb&&b!==mb&&b!==nb&&b!==ob&&b!==pb&&b!==qb&&b!==rb?d(a,O):(a.state=null,b===qb?d(a,P):M)):O}var B,C=a("../utils/common"),D=a("./trees"),E=a("./adler32"),F=a("./crc32"),G=a("./messages"),H=0,I=1,J=3,K=4,L=5,M=0,N=1,O=-2,P=-3,Q=-5,R=-1,S=1,T=2,U=3,V=4,W=0,X=2,Y=8,Z=9,$=15,_=8,ab=29,bb=256,cb=bb+1+ab,db=30,eb=19,fb=2*cb+1,gb=15,hb=3,ib=258,jb=ib+hb+1,kb=32,lb=42,mb=69,nb=73,ob=91,pb=103,qb=113,rb=666,sb=1,tb=2,ub=3,vb=4,wb=3,xb=function(a,b,c,d,e){this.good_length=a,this.max_lazy=b,this.nice_length=c,this.max_chain=d,this.func=e};B=[new xb(0,0,0,0,n),new xb(4,4,8,4,o),new xb(4,5,16,8,o),new xb(4,6,32,32,o),new xb(4,4,16,16,p),new xb(8,16,32,32,p),new xb(8,16,128,128,p),new xb(8,32,128,256,p),new xb(32,128,258,1024,p),new xb(32,258,258,4096,p)],c.deflateInit=y,c.deflateInit2=x,c.deflateReset=v,c.deflateResetKeep=u,c.deflateSetHeader=w,c.deflate=z,c.deflateEnd=A,c.deflateInfo="pako deflate (from Nodeca project)"},{"../utils/common":27,"./adler32":29,"./crc32":31,"./messages":37,"./trees":38}],33:[function(a,b){"use strict";function c(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1}b.exports=c},{}],34:[function(a,b){"use strict";var c=30,d=12;b.exports=function(a,b){var e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C;e=a.state,f=a.next_in,B=a.input,g=f+(a.avail_in-5),h=a.next_out,C=a.output,i=h-(b-a.avail_out),j=h+(a.avail_out-257),k=e.dmax,l=e.wsize,m=e.whave,n=e.wnext,o=e.window,p=e.hold,q=e.bits,r=e.lencode,s=e.distcode,t=(1<q&&(p+=B[f++]<>>24,p>>>=w,q-=w,w=v>>>16&255,0===w)C[h++]=65535&v;else{if(!(16&w)){if(0===(64&w)){v=r[(65535&v)+(p&(1<q&&(p+=B[f++]<>>=w,q-=w),15>q&&(p+=B[f++]<>>24,p>>>=w,q-=w,w=v>>>16&255,!(16&w)){if(0===(64&w)){v=s[(65535&v)+(p&(1<q&&(p+=B[f++]<q&&(p+=B[f++]<k){a.msg="invalid distance too far back",e.mode=c;break a}if(p>>>=w,q-=w,w=h-i,y>w){if(w=y-w,w>m&&e.sane){a.msg="invalid distance too far back",e.mode=c;break a}if(z=0,A=o,0===n){if(z+=l-w,x>w){x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}}else if(w>n){if(z+=l+n-w,w-=n,x>w){x-=w;do C[h++]=o[z++];while(--w);if(z=0,x>n){w=n,x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}}}else if(z+=n-w,x>w){x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}for(;x>2;)C[h++]=A[z++],C[h++]=A[z++],C[h++]=A[z++],x-=3;x&&(C[h++]=A[z++],x>1&&(C[h++]=A[z++]))}else{z=h-y;do C[h++]=C[z++],C[h++]=C[z++],C[h++]=C[z++],x-=3;while(x>2);x&&(C[h++]=C[z++],x>1&&(C[h++]=C[z++]))}break}}break}}while(g>f&&j>h);x=q>>3,f-=x,q-=x<<3,p&=(1<f?5+(g-f):5-(f-g),a.avail_out=j>h?257+(j-h):257-(h-j),e.hold=p,e.bits=q}},{}],35:[function(a,b,c){"use strict";function d(a){return(a>>>24&255)+(a>>>8&65280)+((65280&a)<<8)+((255&a)<<24)}function e(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new r.Buf16(320),this.work=new r.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function f(a){var b;return a&&a.state?(b=a.state,a.total_in=a.total_out=b.total=0,a.msg="",b.wrap&&(a.adler=1&b.wrap),b.mode=K,b.last=0,b.havedict=0,b.dmax=32768,b.head=null,b.hold=0,b.bits=0,b.lencode=b.lendyn=new r.Buf32(ob),b.distcode=b.distdyn=new r.Buf32(pb),b.sane=1,b.back=-1,C):F}function g(a){var b;return a&&a.state?(b=a.state,b.wsize=0,b.whave=0,b.wnext=0,f(a)):F}function h(a,b){var c,d;return a&&a.state?(d=a.state,0>b?(c=0,b=-b):(c=(b>>4)+1,48>b&&(b&=15)),b&&(8>b||b>15)?F:(null!==d.window&&d.wbits!==b&&(d.window=null),d.wrap=c,d.wbits=b,g(a))):F}function i(a,b){var c,d;return a?(d=new e,a.state=d,d.window=null,c=h(a,b),c!==C&&(a.state=null),c):F}function j(a){return i(a,rb)}function k(a){if(sb){var b;for(p=new r.Buf32(512),q=new r.Buf32(32),b=0;144>b;)a.lens[b++]=8;for(;256>b;)a.lens[b++]=9;for(;280>b;)a.lens[b++]=7;for(;288>b;)a.lens[b++]=8;for(v(x,a.lens,0,288,p,0,a.work,{bits:9}),b=0;32>b;)a.lens[b++]=5;v(y,a.lens,0,32,q,0,a.work,{bits:5}),sb=!1}a.lencode=p,a.lenbits=9,a.distcode=q,a.distbits=5}function l(a,b,c,d){var e,f=a.state;return null===f.window&&(f.wsize=1<=f.wsize?(r.arraySet(f.window,b,c-f.wsize,f.wsize,0),f.wnext=0,f.whave=f.wsize):(e=f.wsize-f.wnext,e>d&&(e=d),r.arraySet(f.window,b,c-d,e,f.wnext),d-=e,d?(r.arraySet(f.window,b,c-d,d,0),f.wnext=d,f.whave=f.wsize):(f.wnext+=e,f.wnext===f.wsize&&(f.wnext=0),f.whaven;){if(0===i)break a;i--,m+=e[g++]<>>8&255,c.check=t(c.check,Bb,2,0),m=0,n=0,c.mode=L;break}if(c.flags=0,c.head&&(c.head.done=!1),!(1&c.wrap)||(((255&m)<<8)+(m>>8))%31){a.msg="incorrect header check",c.mode=lb;break}if((15&m)!==J){a.msg="unknown compression method",c.mode=lb;break}if(m>>>=4,n-=4,wb=(15&m)+8,0===c.wbits)c.wbits=wb;else if(wb>c.wbits){a.msg="invalid window size",c.mode=lb;break}c.dmax=1<n;){if(0===i)break a;i--,m+=e[g++]<>8&1),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0)),m=0,n=0,c.mode=M;case M:for(;32>n;){if(0===i)break a;i--,m+=e[g++]<>>8&255,Bb[2]=m>>>16&255,Bb[3]=m>>>24&255,c.check=t(c.check,Bb,4,0)),m=0,n=0,c.mode=N;case N:for(;16>n;){if(0===i)break a;i--,m+=e[g++]<>8),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0)),m=0,n=0,c.mode=O;case O:if(1024&c.flags){for(;16>n;){if(0===i)break a;i--,m+=e[g++]<>>8&255,c.check=t(c.check,Bb,2,0)),m=0,n=0}else c.head&&(c.head.extra=null);c.mode=P;case P:if(1024&c.flags&&(q=c.length,q>i&&(q=i),q&&(c.head&&(wb=c.head.extra_len-c.length,c.head.extra||(c.head.extra=new Array(c.head.extra_len)),r.arraySet(c.head.extra,e,g,q,wb)),512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,c.length-=q),c.length))break a;c.length=0,c.mode=Q;case Q:if(2048&c.flags){if(0===i)break a;q=0;do wb=e[g+q++],c.head&&wb&&c.length<65536&&(c.head.name+=String.fromCharCode(wb));while(wb&&i>q);if(512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,wb)break a}else c.head&&(c.head.name=null);c.length=0,c.mode=R;case R:if(4096&c.flags){if(0===i)break a;q=0;do wb=e[g+q++],c.head&&wb&&c.length<65536&&(c.head.comment+=String.fromCharCode(wb));while(wb&&i>q);if(512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,wb)break a}else c.head&&(c.head.comment=null);c.mode=S;case S:if(512&c.flags){for(;16>n;){if(0===i)break a;i--,m+=e[g++]<>9&1,c.head.done=!0),a.adler=c.check=0,c.mode=V;break;case T:for(;32>n;){if(0===i)break a;i--,m+=e[g++]<>>=7&n,n-=7&n,c.mode=ib;break}for(;3>n;){if(0===i)break a;i--,m+=e[g++]<>>=1,n-=1,3&m){case 0:c.mode=X;break;case 1:if(k(c),c.mode=bb,b===B){m>>>=2,n-=2;break a}break;case 2:c.mode=$;break;case 3:a.msg="invalid block type",c.mode=lb}m>>>=2,n-=2;break;case X:for(m>>>=7&n,n-=7&n;32>n;){if(0===i)break a;i--,m+=e[g++]<>>16^65535)){a.msg="invalid stored block lengths",c.mode=lb;break}if(c.length=65535&m,m=0,n=0,c.mode=Y,b===B)break a;case Y:c.mode=Z;case Z:if(q=c.length){if(q>i&&(q=i),q>j&&(q=j),0===q)break a;r.arraySet(f,e,g,q,h),i-=q,g+=q,j-=q,h+=q,c.length-=q;break}c.mode=V;break;case $:for(;14>n;){if(0===i)break a;i--,m+=e[g++]<>>=5,n-=5,c.ndist=(31&m)+1,m>>>=5,n-=5,c.ncode=(15&m)+4,m>>>=4,n-=4,c.nlen>286||c.ndist>30){a.msg="too many length or distance symbols",c.mode=lb;break}c.have=0,c.mode=_;case _:for(;c.haven;){if(0===i)break a;i--,m+=e[g++]<>>=3,n-=3}for(;c.have<19;)c.lens[Cb[c.have++]]=0;if(c.lencode=c.lendyn,c.lenbits=7,yb={bits:c.lenbits},xb=v(w,c.lens,0,19,c.lencode,0,c.work,yb),c.lenbits=yb.bits,xb){a.msg="invalid code lengths set",c.mode=lb;break}c.have=0,c.mode=ab;case ab:for(;c.have>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=qb);){if(0===i)break a;i--,m+=e[g++]<sb)m>>>=qb,n-=qb,c.lens[c.have++]=sb;else{if(16===sb){for(zb=qb+2;zb>n;){if(0===i)break a;i--,m+=e[g++]<>>=qb,n-=qb,0===c.have){a.msg="invalid bit length repeat",c.mode=lb;break}wb=c.lens[c.have-1],q=3+(3&m),m>>>=2,n-=2}else if(17===sb){for(zb=qb+3;zb>n;){if(0===i)break a;i--,m+=e[g++]<>>=qb,n-=qb,wb=0,q=3+(7&m),m>>>=3,n-=3}else{for(zb=qb+7;zb>n;){if(0===i)break a;i--,m+=e[g++]<>>=qb,n-=qb,wb=0,q=11+(127&m),m>>>=7,n-=7}if(c.have+q>c.nlen+c.ndist){a.msg="invalid bit length repeat",c.mode=lb;break}for(;q--;)c.lens[c.have++]=wb}}if(c.mode===lb)break;if(0===c.lens[256]){a.msg="invalid code -- missing end-of-block",c.mode=lb;break}if(c.lenbits=9,yb={bits:c.lenbits},xb=v(x,c.lens,0,c.nlen,c.lencode,0,c.work,yb),c.lenbits=yb.bits,xb){a.msg="invalid literal/lengths set",c.mode=lb;break}if(c.distbits=6,c.distcode=c.distdyn,yb={bits:c.distbits},xb=v(y,c.lens,c.nlen,c.ndist,c.distcode,0,c.work,yb),c.distbits=yb.bits,xb){a.msg="invalid distances set",c.mode=lb;break}if(c.mode=bb,b===B)break a;case bb:c.mode=cb;case cb:if(i>=6&&j>=258){a.next_out=h,a.avail_out=j,a.next_in=g,a.avail_in=i,c.hold=m,c.bits=n,u(a,p),h=a.next_out,f=a.output,j=a.avail_out,g=a.next_in,e=a.input,i=a.avail_in,m=c.hold,n=c.bits,c.mode===V&&(c.back=-1); +break}for(c.back=0;Ab=c.lencode[m&(1<>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=qb);){if(0===i)break a;i--,m+=e[g++]<>tb)],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=tb+qb);){if(0===i)break a;i--,m+=e[g++]<>>=tb,n-=tb,c.back+=tb}if(m>>>=qb,n-=qb,c.back+=qb,c.length=sb,0===rb){c.mode=hb;break}if(32&rb){c.back=-1,c.mode=V;break}if(64&rb){a.msg="invalid literal/length code",c.mode=lb;break}c.extra=15&rb,c.mode=db;case db:if(c.extra){for(zb=c.extra;zb>n;){if(0===i)break a;i--,m+=e[g++]<>>=c.extra,n-=c.extra,c.back+=c.extra}c.was=c.length,c.mode=eb;case eb:for(;Ab=c.distcode[m&(1<>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=qb);){if(0===i)break a;i--,m+=e[g++]<>tb)],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=tb+qb);){if(0===i)break a;i--,m+=e[g++]<>>=tb,n-=tb,c.back+=tb}if(m>>>=qb,n-=qb,c.back+=qb,64&rb){a.msg="invalid distance code",c.mode=lb;break}c.offset=sb,c.extra=15&rb,c.mode=fb;case fb:if(c.extra){for(zb=c.extra;zb>n;){if(0===i)break a;i--,m+=e[g++]<>>=c.extra,n-=c.extra,c.back+=c.extra}if(c.offset>c.dmax){a.msg="invalid distance too far back",c.mode=lb;break}c.mode=gb;case gb:if(0===j)break a;if(q=p-j,c.offset>q){if(q=c.offset-q,q>c.whave&&c.sane){a.msg="invalid distance too far back",c.mode=lb;break}q>c.wnext?(q-=c.wnext,ob=c.wsize-q):ob=c.wnext-q,q>c.length&&(q=c.length),pb=c.window}else pb=f,ob=h-c.offset,q=c.length;q>j&&(q=j),j-=q,c.length-=q;do f[h++]=pb[ob++];while(--q);0===c.length&&(c.mode=cb);break;case hb:if(0===j)break a;f[h++]=c.length,j--,c.mode=cb;break;case ib:if(c.wrap){for(;32>n;){if(0===i)break a;i--,m|=e[g++]<n;){if(0===i)break a;i--,m+=e[g++]<=D;D++)P[D]=0;for(E=0;o>E;E++)P[b[n+E]]++;for(H=C,G=d;G>=1&&0===P[G];G--);if(H>G&&(H=G),0===G)return p[q++]=20971520,p[q++]=20971520,s.bits=1,0;for(F=1;G>F&&0===P[F];F++);for(F>H&&(H=F),K=1,D=1;d>=D;D++)if(K<<=1,K-=P[D],0>K)return-1;if(K>0&&(a===g||1!==G))return-1;for(Q[1]=0,D=1;d>D;D++)Q[D+1]=Q[D]+P[D];for(E=0;o>E;E++)0!==b[n+E]&&(r[Q[b[n+E]]++]=E);if(a===g?(N=R=r,y=19):a===h?(N=j,O-=257,R=k,S-=257,y=256):(N=l,R=m,y=-1),M=0,E=0,D=F,x=q,I=H,J=0,v=-1,L=1<e||a===i&&L>f)return 1;for(var T=0;;){T++,z=D-J,r[E]y?(A=R[S+r[E]],B=N[O+r[E]]):(A=96,B=0),t=1<>J)+u]=z<<24|A<<16|B|0;while(0!==u);for(t=1<>=1;if(0!==t?(M&=t-1,M+=t):M=0,E++,0===--P[D]){if(D===G)break;D=b[n+r[E]]}if(D>H&&(M&w)!==v){for(0===J&&(J=H),x+=F,I=D-J,K=1<I+J&&(K-=P[I+J],!(0>=K));)I++,K<<=1;if(L+=1<e||a===i&&L>f)return 1;v=M&w,p[v]=H<<24|I<<16|x-q|0}}return 0!==M&&(p[x+M]=D-J<<24|64<<16|0),s.bits=H,0}},{"../utils/common":27}],37:[function(a,b){"use strict";b.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}},{}],38:[function(a,b,c){"use strict";function d(a){for(var b=a.length;--b>=0;)a[b]=0}function e(a){return 256>a?gb[a]:gb[256+(a>>>7)]}function f(a,b){a.pending_buf[a.pending++]=255&b,a.pending_buf[a.pending++]=b>>>8&255}function g(a,b,c){a.bi_valid>V-c?(a.bi_buf|=b<>V-a.bi_valid,a.bi_valid+=c-V):(a.bi_buf|=b<>>=1,c<<=1;while(--b>0);return c>>>1}function j(a){16===a.bi_valid?(f(a,a.bi_buf),a.bi_buf=0,a.bi_valid=0):a.bi_valid>=8&&(a.pending_buf[a.pending++]=255&a.bi_buf,a.bi_buf>>=8,a.bi_valid-=8)}function k(a,b){var c,d,e,f,g,h,i=b.dyn_tree,j=b.max_code,k=b.stat_desc.static_tree,l=b.stat_desc.has_stree,m=b.stat_desc.extra_bits,n=b.stat_desc.extra_base,o=b.stat_desc.max_length,p=0;for(f=0;U>=f;f++)a.bl_count[f]=0;for(i[2*a.heap[a.heap_max]+1]=0,c=a.heap_max+1;T>c;c++)d=a.heap[c],f=i[2*i[2*d+1]+1]+1,f>o&&(f=o,p++),i[2*d+1]=f,d>j||(a.bl_count[f]++,g=0,d>=n&&(g=m[d-n]),h=i[2*d],a.opt_len+=h*(f+g),l&&(a.static_len+=h*(k[2*d+1]+g)));if(0!==p){do{for(f=o-1;0===a.bl_count[f];)f--;a.bl_count[f]--,a.bl_count[f+1]+=2,a.bl_count[o]--,p-=2}while(p>0);for(f=o;0!==f;f--)for(d=a.bl_count[f];0!==d;)e=a.heap[--c],e>j||(i[2*e+1]!==f&&(a.opt_len+=(f-i[2*e+1])*i[2*e],i[2*e+1]=f),d--)}}function l(a,b,c){var d,e,f=new Array(U+1),g=0;for(d=1;U>=d;d++)f[d]=g=g+c[d-1]<<1;for(e=0;b>=e;e++){var h=a[2*e+1];0!==h&&(a[2*e]=i(f[h]++,h))}}function m(){var a,b,c,d,e,f=new Array(U+1);for(c=0,d=0;O-1>d;d++)for(ib[d]=c,a=0;a<1<<_[d];a++)hb[c++]=d;for(hb[c-1]=d,e=0,d=0;16>d;d++)for(jb[d]=e,a=0;a<1<>=7;R>d;d++)for(jb[d]=e<<7,a=0;a<1<=b;b++)f[b]=0;for(a=0;143>=a;)eb[2*a+1]=8,a++,f[8]++;for(;255>=a;)eb[2*a+1]=9,a++,f[9]++;for(;279>=a;)eb[2*a+1]=7,a++,f[7]++;for(;287>=a;)eb[2*a+1]=8,a++,f[8]++;for(l(eb,Q+1,f),a=0;R>a;a++)fb[2*a+1]=5,fb[2*a]=i(a,5);kb=new nb(eb,_,P+1,Q,U),lb=new nb(fb,ab,0,R,U),mb=new nb(new Array(0),bb,0,S,W)}function n(a){var b;for(b=0;Q>b;b++)a.dyn_ltree[2*b]=0;for(b=0;R>b;b++)a.dyn_dtree[2*b]=0;for(b=0;S>b;b++)a.bl_tree[2*b]=0;a.dyn_ltree[2*X]=1,a.opt_len=a.static_len=0,a.last_lit=a.matches=0}function o(a){a.bi_valid>8?f(a,a.bi_buf):a.bi_valid>0&&(a.pending_buf[a.pending++]=a.bi_buf),a.bi_buf=0,a.bi_valid=0}function p(a,b,c,d){o(a),d&&(f(a,c),f(a,~c)),E.arraySet(a.pending_buf,a.window,b,c,a.pending),a.pending+=c}function q(a,b,c,d){var e=2*b,f=2*c;return a[e]c;c++)0!==f[2*c]?(a.heap[++a.heap_len]=j=c,a.depth[c]=0):f[2*c+1]=0;for(;a.heap_len<2;)e=a.heap[++a.heap_len]=2>j?++j:0,f[2*e]=1,a.depth[e]=0,a.opt_len--,h&&(a.static_len-=g[2*e+1]);for(b.max_code=j,c=a.heap_len>>1;c>=1;c--)r(a,f,c);e=i;do c=a.heap[1],a.heap[1]=a.heap[a.heap_len--],r(a,f,1),d=a.heap[1],a.heap[--a.heap_max]=c,a.heap[--a.heap_max]=d,f[2*e]=f[2*c]+f[2*d],a.depth[e]=(a.depth[c]>=a.depth[d]?a.depth[c]:a.depth[d])+1,f[2*c+1]=f[2*d+1]=e,a.heap[1]=e++,r(a,f,1);while(a.heap_len>=2);a.heap[--a.heap_max]=a.heap[1],k(a,b),l(f,j,a.bl_count)}function u(a,b,c){var d,e,f=-1,g=b[1],h=0,i=7,j=4;for(0===g&&(i=138,j=3),b[2*(c+1)+1]=65535,d=0;c>=d;d++)e=g,g=b[2*(d+1)+1],++hh?a.bl_tree[2*e]+=h:0!==e?(e!==f&&a.bl_tree[2*e]++,a.bl_tree[2*Y]++):10>=h?a.bl_tree[2*Z]++:a.bl_tree[2*$]++,h=0,f=e,0===g?(i=138,j=3):e===g?(i=6,j=3):(i=7,j=4))}function v(a,b,c){var d,e,f=-1,i=b[1],j=0,k=7,l=4;for(0===i&&(k=138,l=3),d=0;c>=d;d++)if(e=i,i=b[2*(d+1)+1],!(++jj){do h(a,e,a.bl_tree);while(0!==--j)}else 0!==e?(e!==f&&(h(a,e,a.bl_tree),j--),h(a,Y,a.bl_tree),g(a,j-3,2)):10>=j?(h(a,Z,a.bl_tree),g(a,j-3,3)):(h(a,$,a.bl_tree),g(a,j-11,7));j=0,f=e,0===i?(k=138,l=3):e===i?(k=6,l=3):(k=7,l=4)}}function w(a){var b;for(u(a,a.dyn_ltree,a.l_desc.max_code),u(a,a.dyn_dtree,a.d_desc.max_code),t(a,a.bl_desc),b=S-1;b>=3&&0===a.bl_tree[2*cb[b]+1];b--);return a.opt_len+=3*(b+1)+5+5+4,b}function x(a,b,c,d){var e;for(g(a,b-257,5),g(a,c-1,5),g(a,d-4,4),e=0;d>e;e++)g(a,a.bl_tree[2*cb[e]+1],3);v(a,a.dyn_ltree,b-1),v(a,a.dyn_dtree,c-1)}function y(a){var b,c=4093624447;for(b=0;31>=b;b++,c>>>=1)if(1&c&&0!==a.dyn_ltree[2*b])return G;if(0!==a.dyn_ltree[18]||0!==a.dyn_ltree[20]||0!==a.dyn_ltree[26])return H;for(b=32;P>b;b++)if(0!==a.dyn_ltree[2*b])return H;return G}function z(a){pb||(m(),pb=!0),a.l_desc=new ob(a.dyn_ltree,kb),a.d_desc=new ob(a.dyn_dtree,lb),a.bl_desc=new ob(a.bl_tree,mb),a.bi_buf=0,a.bi_valid=0,n(a)}function A(a,b,c,d){g(a,(J<<1)+(d?1:0),3),p(a,b,c,!0)}function B(a){g(a,K<<1,3),h(a,X,eb),j(a)}function C(a,b,c,d){var e,f,h=0;a.level>0?(a.strm.data_type===I&&(a.strm.data_type=y(a)),t(a,a.l_desc),t(a,a.d_desc),h=w(a),e=a.opt_len+3+7>>>3,f=a.static_len+3+7>>>3,e>=f&&(e=f)):e=f=c+5,e>=c+4&&-1!==b?A(a,b,c,d):a.strategy===F||f===e?(g(a,(K<<1)+(d?1:0),3),s(a,eb,fb)):(g(a,(L<<1)+(d?1:0),3),x(a,a.l_desc.max_code+1,a.d_desc.max_code+1,h+1),s(a,a.dyn_ltree,a.dyn_dtree)),n(a),d&&o(a)}function D(a,b,c){return a.pending_buf[a.d_buf+2*a.last_lit]=b>>>8&255,a.pending_buf[a.d_buf+2*a.last_lit+1]=255&b,a.pending_buf[a.l_buf+a.last_lit]=255&c,a.last_lit++,0===b?a.dyn_ltree[2*c]++:(a.matches++,b--,a.dyn_ltree[2*(hb[c]+P+1)]++,a.dyn_dtree[2*e(b)]++),a.last_lit===a.lit_bufsize-1}var E=a("../utils/common"),F=4,G=0,H=1,I=2,J=0,K=1,L=2,M=3,N=258,O=29,P=256,Q=P+1+O,R=30,S=19,T=2*Q+1,U=15,V=16,W=7,X=256,Y=16,Z=17,$=18,_=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],ab=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],bb=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],cb=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],db=512,eb=new Array(2*(Q+2));d(eb);var fb=new Array(2*R);d(fb);var gb=new Array(db);d(gb);var hb=new Array(N-M+1);d(hb);var ib=new Array(O);d(ib);var jb=new Array(R);d(jb);var kb,lb,mb,nb=function(a,b,c,d,e){this.static_tree=a,this.extra_bits=b,this.extra_base=c,this.elems=d,this.max_length=e,this.has_stree=a&&a.length},ob=function(a,b){this.dyn_tree=a,this.max_code=0,this.stat_desc=b},pb=!1;c._tr_init=z,c._tr_stored_block=A,c._tr_flush_block=C,c._tr_tally=D,c._tr_align=B},{"../utils/common":27}],39:[function(a,b){"use strict";function c(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}b.exports=c},{}]},{},[9])(9)}); \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/export/libs/pdfmake/pdfmake.js b/iguana/js/amcharts/plugins/export/libs/pdfmake/pdfmake.js new file mode 100755 index 000000000..9e68e29ea --- /dev/null +++ b/iguana/js/amcharts/plugins/export/libs/pdfmake/pdfmake.js @@ -0,0 +1,66555 @@ +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; + +/******/ // The require function +/******/ function __webpack_require__(moduleId) { + +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; + +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ exports: {}, +/******/ id: moduleId, +/******/ loaded: false +/******/ }; + +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + +/******/ // Flag the module as loaded +/******/ module.loaded = true; + +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } + + +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; + +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; + +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; + +/******/ // Load entry module and return exports +/******/ return __webpack_require__(0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ function(module, exports, __webpack_require__) { + + /* WEBPACK VAR INJECTION */(function(global) {module.exports = global["pdfMake"] = __webpack_require__(1); + /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()))) + +/***/ }, +/* 1 */ +/***/ function(module, exports, __webpack_require__) { + + /* WEBPACK VAR INJECTION */(function(Buffer) {/* jslint node: true */ + /* jslint browser: true */ + /* global BlobBuilder */ + 'use strict'; + + var PdfPrinter = __webpack_require__(6); + var saveAs = __webpack_require__(105); + + var defaultClientFonts = { + Roboto: { + normal: 'Roboto-Regular.ttf', + bold: 'Roboto-Medium.ttf', + italics: 'Roboto-Italic.ttf', + bolditalics: 'Roboto-Italic.ttf' + } + }; + + function Document(docDefinition, fonts, vfs) { + this.docDefinition = docDefinition; + this.fonts = fonts || defaultClientFonts; + this.vfs = vfs; + } + + Document.prototype._createDoc = function(options, callback) { + var printer = new PdfPrinter(this.fonts); + printer.fs.bindFS(this.vfs); + + var doc = printer.createPdfKitDocument(this.docDefinition, options); + var chunks = []; + var result; + + doc.on('data', function(chunk) { + chunks.push(chunk); + }); + doc.on('end', function() { + result = Buffer.concat(chunks); + callback(result, doc._pdfMakePages); + }); + doc.end(); + }; + + Document.prototype._getPages = function(options, cb){ + if (!cb) throw 'getBuffer is an async method and needs a callback argument'; + this._createDoc(options, function(ignoreBuffer, pages){ + cb(pages); + }); + }; + + Document.prototype.open = function(message) { + // we have to open the window immediately and store the reference + // otherwise popup blockers will stop us + var win = window.open('', '_blank'); + + try { + this.getDataUrl(function(result) { + win.location.href = result; + }); + } catch(e) { + win.close(); + throw e; + } + }; + + + Document.prototype.print = function() { + this.getDataUrl(function(dataUrl) { + var iFrame = document.createElement('iframe'); + iFrame.style.position = 'absolute'; + iFrame.style.left = '-99999px'; + iFrame.src = dataUrl; + iFrame.onload = function() { + function removeIFrame(){ + document.body.removeChild(iFrame); + document.removeEventListener('click', removeIFrame); + } + document.addEventListener('click', removeIFrame, false); + }; + + document.body.appendChild(iFrame); + }, { autoPrint: true }); + }; + + Document.prototype.download = function(defaultFileName, cb) { + if(typeof defaultFileName === "function") { + cb = defaultFileName; + defaultFileName = null; + } + + defaultFileName = defaultFileName || 'file.pdf'; + this.getBuffer(function (result) { + var blob; + try { + blob = new Blob([result], { type: 'application/pdf' }); + } + catch (e) { + // Old browser which can't handle it without making it an byte array (ie10) + if (e.name == "InvalidStateError") { + var byteArray = new Uint8Array(result); + blob = new Blob([byteArray.buffer], { type: 'application/pdf' }); + } + } + if (blob) { + saveAs(blob, defaultFileName); + } + else { + throw 'Could not generate blob'; + } + if (typeof cb === "function") { + cb(); + } + }); + }; + + Document.prototype.getBase64 = function(cb, options) { + if (!cb) throw 'getBase64 is an async method and needs a callback argument'; + this._createDoc(options, function(buffer) { + cb(buffer.toString('base64')); + }); + }; + + Document.prototype.getDataUrl = function(cb, options) { + if (!cb) throw 'getDataUrl is an async method and needs a callback argument'; + this._createDoc(options, function(buffer) { + cb('data:application/pdf;base64,' + buffer.toString('base64')); + }); + }; + + Document.prototype.getBuffer = function(cb, options) { + if (!cb) throw 'getBuffer is an async method and needs a callback argument'; + this._createDoc(options, function(buffer){ + cb(buffer); + }); + }; + + module.exports = { + createPdf: function(docDefinition) { + return new Document(docDefinition, window.pdfMake.fonts, window.pdfMake.vfs); + } + }; + + /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(2).Buffer)) + +/***/ }, +/* 2 */ +/***/ function(module, exports, __webpack_require__) { + + /* WEBPACK VAR INJECTION */(function(Buffer) {/*! + * The buffer module from node.js, for the browser. + * + * @author Feross Aboukhadijeh + * @license MIT + */ + + var base64 = __webpack_require__(3) + var ieee754 = __webpack_require__(4) + var isArray = __webpack_require__(5) + + exports.Buffer = Buffer + exports.SlowBuffer = SlowBuffer + exports.INSPECT_MAX_BYTES = 50 + Buffer.poolSize = 8192 // not used by this implementation + + var rootParent = {} + + /** + * If `Buffer.TYPED_ARRAY_SUPPORT`: + * === true Use Uint8Array implementation (fastest) + * === false Use Object implementation (most compatible, even IE6) + * + * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, + * Opera 11.6+, iOS 4.2+. + * + * Due to various browser bugs, sometimes the Object implementation will be used even + * when the browser supports typed arrays. + * + * Note: + * + * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances, + * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. + * + * - Safari 5-7 lacks support for changing the `Object.prototype.constructor` property + * on objects. + * + * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. + * + * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of + * incorrect length in some situations. + + * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they + * get the Object implementation, which is slower but behaves correctly. + */ + Buffer.TYPED_ARRAY_SUPPORT = (function () { + function Bar () {} + try { + var arr = new Uint8Array(1) + arr.foo = function () { return 42 } + arr.constructor = Bar + return arr.foo() === 42 && // typed array instances can be augmented + arr.constructor === Bar && // constructor can be set + typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` + arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray` + } catch (e) { + return false + } + })() + + function kMaxLength () { + return Buffer.TYPED_ARRAY_SUPPORT + ? 0x7fffffff + : 0x3fffffff + } + + /** + * Class: Buffer + * ============= + * + * The Buffer constructor returns instances of `Uint8Array` that are augmented + * with function properties for all the node `Buffer` API functions. We use + * `Uint8Array` so that square bracket notation works as expected -- it returns + * a single octet. + * + * By augmenting the instances, we can avoid modifying the `Uint8Array` + * prototype. + */ + function Buffer (arg) { + if (!(this instanceof Buffer)) { + // Avoid going through an ArgumentsAdaptorTrampoline in the common case. + if (arguments.length > 1) return new Buffer(arg, arguments[1]) + return new Buffer(arg) + } + + this.length = 0 + this.parent = undefined + + // Common case. + if (typeof arg === 'number') { + return fromNumber(this, arg) + } + + // Slightly less common case. + if (typeof arg === 'string') { + return fromString(this, arg, arguments.length > 1 ? arguments[1] : 'utf8') + } + + // Unusual. + return fromObject(this, arg) + } + + function fromNumber (that, length) { + that = allocate(that, length < 0 ? 0 : checked(length) | 0) + if (!Buffer.TYPED_ARRAY_SUPPORT) { + for (var i = 0; i < length; i++) { + that[i] = 0 + } + } + return that + } + + function fromString (that, string, encoding) { + if (typeof encoding !== 'string' || encoding === '') encoding = 'utf8' + + // Assumption: byteLength() return value is always < kMaxLength. + var length = byteLength(string, encoding) | 0 + that = allocate(that, length) + + that.write(string, encoding) + return that + } + + function fromObject (that, object) { + if (Buffer.isBuffer(object)) return fromBuffer(that, object) + + if (isArray(object)) return fromArray(that, object) + + if (object == null) { + throw new TypeError('must start with number, buffer, array or string') + } + + if (typeof ArrayBuffer !== 'undefined') { + if (object.buffer instanceof ArrayBuffer) { + return fromTypedArray(that, object) + } + if (object instanceof ArrayBuffer) { + return fromArrayBuffer(that, object) + } + } + + if (object.length) return fromArrayLike(that, object) + + return fromJsonObject(that, object) + } + + function fromBuffer (that, buffer) { + var length = checked(buffer.length) | 0 + that = allocate(that, length) + buffer.copy(that, 0, 0, length) + return that + } + + function fromArray (that, array) { + var length = checked(array.length) | 0 + that = allocate(that, length) + for (var i = 0; i < length; i += 1) { + that[i] = array[i] & 255 + } + return that + } + + // Duplicate of fromArray() to keep fromArray() monomorphic. + function fromTypedArray (that, array) { + var length = checked(array.length) | 0 + that = allocate(that, length) + // Truncating the elements is probably not what people expect from typed + // arrays with BYTES_PER_ELEMENT > 1 but it's compatible with the behavior + // of the old Buffer constructor. + for (var i = 0; i < length; i += 1) { + that[i] = array[i] & 255 + } + return that + } + + function fromArrayBuffer (that, array) { + if (Buffer.TYPED_ARRAY_SUPPORT) { + // Return an augmented `Uint8Array` instance, for best performance + array.byteLength + that = Buffer._augment(new Uint8Array(array)) + } else { + // Fallback: Return an object instance of the Buffer class + that = fromTypedArray(that, new Uint8Array(array)) + } + return that + } + + function fromArrayLike (that, array) { + var length = checked(array.length) | 0 + that = allocate(that, length) + for (var i = 0; i < length; i += 1) { + that[i] = array[i] & 255 + } + return that + } + + // Deserialize { type: 'Buffer', data: [1,2,3,...] } into a Buffer object. + // Returns a zero-length buffer for inputs that don't conform to the spec. + function fromJsonObject (that, object) { + var array + var length = 0 + + if (object.type === 'Buffer' && isArray(object.data)) { + array = object.data + length = checked(array.length) | 0 + } + that = allocate(that, length) + + for (var i = 0; i < length; i += 1) { + that[i] = array[i] & 255 + } + return that + } + + function allocate (that, length) { + if (Buffer.TYPED_ARRAY_SUPPORT) { + // Return an augmented `Uint8Array` instance, for best performance + that = Buffer._augment(new Uint8Array(length)) + } else { + // Fallback: Return an object instance of the Buffer class + that.length = length + that._isBuffer = true + } + + var fromPool = length !== 0 && length <= Buffer.poolSize >>> 1 + if (fromPool) that.parent = rootParent + + return that + } + + function checked (length) { + // Note: cannot use `length < kMaxLength` here because that fails when + // length is NaN (which is otherwise coerced to zero.) + if (length >= kMaxLength()) { + throw new RangeError('Attempt to allocate Buffer larger than maximum ' + + 'size: 0x' + kMaxLength().toString(16) + ' bytes') + } + return length | 0 + } + + function SlowBuffer (subject, encoding) { + if (!(this instanceof SlowBuffer)) return new SlowBuffer(subject, encoding) + + var buf = new Buffer(subject, encoding) + delete buf.parent + return buf + } + + Buffer.isBuffer = function isBuffer (b) { + return !!(b != null && b._isBuffer) + } + + Buffer.compare = function compare (a, b) { + if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { + throw new TypeError('Arguments must be Buffers') + } + + if (a === b) return 0 + + var x = a.length + var y = b.length + + var i = 0 + var len = Math.min(x, y) + while (i < len) { + if (a[i] !== b[i]) break + + ++i + } + + if (i !== len) { + x = a[i] + y = b[i] + } + + if (x < y) return -1 + if (y < x) return 1 + return 0 + } + + Buffer.isEncoding = function isEncoding (encoding) { + switch (String(encoding).toLowerCase()) { + case 'hex': + case 'utf8': + case 'utf-8': + case 'ascii': + case 'binary': + case 'base64': + case 'raw': + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return true + default: + return false + } + } + + Buffer.concat = function concat (list, length) { + if (!isArray(list)) throw new TypeError('list argument must be an Array of Buffers.') + + if (list.length === 0) { + return new Buffer(0) + } + + var i + if (length === undefined) { + length = 0 + for (i = 0; i < list.length; i++) { + length += list[i].length + } + } + + var buf = new Buffer(length) + var pos = 0 + for (i = 0; i < list.length; i++) { + var item = list[i] + item.copy(buf, pos) + pos += item.length + } + return buf + } + + function byteLength (string, encoding) { + if (typeof string !== 'string') string = '' + string + + var len = string.length + if (len === 0) return 0 + + // Use a for loop to avoid recursion + var loweredCase = false + for (;;) { + switch (encoding) { + case 'ascii': + case 'binary': + // Deprecated + case 'raw': + case 'raws': + return len + case 'utf8': + case 'utf-8': + return utf8ToBytes(string).length + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return len * 2 + case 'hex': + return len >>> 1 + case 'base64': + return base64ToBytes(string).length + default: + if (loweredCase) return utf8ToBytes(string).length // assume utf8 + encoding = ('' + encoding).toLowerCase() + loweredCase = true + } + } + } + Buffer.byteLength = byteLength + + // pre-set for values that may exist in the future + Buffer.prototype.length = undefined + Buffer.prototype.parent = undefined + + function slowToString (encoding, start, end) { + var loweredCase = false + + start = start | 0 + end = end === undefined || end === Infinity ? this.length : end | 0 + + if (!encoding) encoding = 'utf8' + if (start < 0) start = 0 + if (end > this.length) end = this.length + if (end <= start) return '' + + while (true) { + switch (encoding) { + case 'hex': + return hexSlice(this, start, end) + + case 'utf8': + case 'utf-8': + return utf8Slice(this, start, end) + + case 'ascii': + return asciiSlice(this, start, end) + + case 'binary': + return binarySlice(this, start, end) + + case 'base64': + return base64Slice(this, start, end) + + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return utf16leSlice(this, start, end) + + default: + if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) + encoding = (encoding + '').toLowerCase() + loweredCase = true + } + } + } + + Buffer.prototype.toString = function toString () { + var length = this.length | 0 + if (length === 0) return '' + if (arguments.length === 0) return utf8Slice(this, 0, length) + return slowToString.apply(this, arguments) + } + + Buffer.prototype.equals = function equals (b) { + if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') + if (this === b) return true + return Buffer.compare(this, b) === 0 + } + + Buffer.prototype.inspect = function inspect () { + var str = '' + var max = exports.INSPECT_MAX_BYTES + if (this.length > 0) { + str = this.toString('hex', 0, max).match(/.{2}/g).join(' ') + if (this.length > max) str += ' ... ' + } + return '' + } + + Buffer.prototype.compare = function compare (b) { + if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') + if (this === b) return 0 + return Buffer.compare(this, b) + } + + Buffer.prototype.indexOf = function indexOf (val, byteOffset) { + if (byteOffset > 0x7fffffff) byteOffset = 0x7fffffff + else if (byteOffset < -0x80000000) byteOffset = -0x80000000 + byteOffset >>= 0 + + if (this.length === 0) return -1 + if (byteOffset >= this.length) return -1 + + // Negative offsets start from the end of the buffer + if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0) + + if (typeof val === 'string') { + if (val.length === 0) return -1 // special case: looking for empty string always fails + return String.prototype.indexOf.call(this, val, byteOffset) + } + if (Buffer.isBuffer(val)) { + return arrayIndexOf(this, val, byteOffset) + } + if (typeof val === 'number') { + if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') { + return Uint8Array.prototype.indexOf.call(this, val, byteOffset) + } + return arrayIndexOf(this, [ val ], byteOffset) + } + + function arrayIndexOf (arr, val, byteOffset) { + var foundIndex = -1 + for (var i = 0; byteOffset + i < arr.length; i++) { + if (arr[byteOffset + i] === val[foundIndex === -1 ? 0 : i - foundIndex]) { + if (foundIndex === -1) foundIndex = i + if (i - foundIndex + 1 === val.length) return byteOffset + foundIndex + } else { + foundIndex = -1 + } + } + return -1 + } + + throw new TypeError('val must be string, number or Buffer') + } + + // `get` is deprecated + Buffer.prototype.get = function get (offset) { + console.log('.get() is deprecated. Access using array indexes instead.') + return this.readUInt8(offset) + } + + // `set` is deprecated + Buffer.prototype.set = function set (v, offset) { + console.log('.set() is deprecated. Access using array indexes instead.') + return this.writeUInt8(v, offset) + } + + function hexWrite (buf, string, offset, length) { + offset = Number(offset) || 0 + var remaining = buf.length - offset + if (!length) { + length = remaining + } else { + length = Number(length) + if (length > remaining) { + length = remaining + } + } + + // must be an even number of digits + var strLen = string.length + if (strLen % 2 !== 0) throw new Error('Invalid hex string') + + if (length > strLen / 2) { + length = strLen / 2 + } + for (var i = 0; i < length; i++) { + var parsed = parseInt(string.substr(i * 2, 2), 16) + if (isNaN(parsed)) throw new Error('Invalid hex string') + buf[offset + i] = parsed + } + return i + } + + function utf8Write (buf, string, offset, length) { + return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) + } + + function asciiWrite (buf, string, offset, length) { + return blitBuffer(asciiToBytes(string), buf, offset, length) + } + + function binaryWrite (buf, string, offset, length) { + return asciiWrite(buf, string, offset, length) + } + + function base64Write (buf, string, offset, length) { + return blitBuffer(base64ToBytes(string), buf, offset, length) + } + + function ucs2Write (buf, string, offset, length) { + return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) + } + + Buffer.prototype.write = function write (string, offset, length, encoding) { + // Buffer#write(string) + if (offset === undefined) { + encoding = 'utf8' + length = this.length + offset = 0 + // Buffer#write(string, encoding) + } else if (length === undefined && typeof offset === 'string') { + encoding = offset + length = this.length + offset = 0 + // Buffer#write(string, offset[, length][, encoding]) + } else if (isFinite(offset)) { + offset = offset | 0 + if (isFinite(length)) { + length = length | 0 + if (encoding === undefined) encoding = 'utf8' + } else { + encoding = length + length = undefined + } + // legacy write(string, encoding, offset, length) - remove in v0.13 + } else { + var swap = encoding + encoding = offset + offset = length | 0 + length = swap + } + + var remaining = this.length - offset + if (length === undefined || length > remaining) length = remaining + + if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) { + throw new RangeError('attempt to write outside buffer bounds') + } + + if (!encoding) encoding = 'utf8' + + var loweredCase = false + for (;;) { + switch (encoding) { + case 'hex': + return hexWrite(this, string, offset, length) + + case 'utf8': + case 'utf-8': + return utf8Write(this, string, offset, length) + + case 'ascii': + return asciiWrite(this, string, offset, length) + + case 'binary': + return binaryWrite(this, string, offset, length) + + case 'base64': + // Warning: maxLength not taken into account in base64Write + return base64Write(this, string, offset, length) + + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return ucs2Write(this, string, offset, length) + + default: + if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) + encoding = ('' + encoding).toLowerCase() + loweredCase = true + } + } + } + + Buffer.prototype.toJSON = function toJSON () { + return { + type: 'Buffer', + data: Array.prototype.slice.call(this._arr || this, 0) + } + } + + function base64Slice (buf, start, end) { + if (start === 0 && end === buf.length) { + return base64.fromByteArray(buf) + } else { + return base64.fromByteArray(buf.slice(start, end)) + } + } + + function utf8Slice (buf, start, end) { + end = Math.min(buf.length, end) + var res = [] + + var i = start + while (i < end) { + var firstByte = buf[i] + var codePoint = null + var bytesPerSequence = (firstByte > 0xEF) ? 4 + : (firstByte > 0xDF) ? 3 + : (firstByte > 0xBF) ? 2 + : 1 + + if (i + bytesPerSequence <= end) { + var secondByte, thirdByte, fourthByte, tempCodePoint + + switch (bytesPerSequence) { + case 1: + if (firstByte < 0x80) { + codePoint = firstByte + } + break + case 2: + secondByte = buf[i + 1] + if ((secondByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F) + if (tempCodePoint > 0x7F) { + codePoint = tempCodePoint + } + } + break + case 3: + secondByte = buf[i + 1] + thirdByte = buf[i + 2] + if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F) + if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) { + codePoint = tempCodePoint + } + } + break + case 4: + secondByte = buf[i + 1] + thirdByte = buf[i + 2] + fourthByte = buf[i + 3] + if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F) + if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) { + codePoint = tempCodePoint + } + } + } + } + + if (codePoint === null) { + // we did not generate a valid codePoint so insert a + // replacement char (U+FFFD) and advance only 1 byte + codePoint = 0xFFFD + bytesPerSequence = 1 + } else if (codePoint > 0xFFFF) { + // encode to utf16 (surrogate pair dance) + codePoint -= 0x10000 + res.push(codePoint >>> 10 & 0x3FF | 0xD800) + codePoint = 0xDC00 | codePoint & 0x3FF + } + + res.push(codePoint) + i += bytesPerSequence + } + + return decodeCodePointsArray(res) + } + + // Based on http://stackoverflow.com/a/22747272/680742, the browser with + // the lowest limit is Chrome, with 0x10000 args. + // We go 1 magnitude less, for safety + var MAX_ARGUMENTS_LENGTH = 0x1000 + + function decodeCodePointsArray (codePoints) { + var len = codePoints.length + if (len <= MAX_ARGUMENTS_LENGTH) { + return String.fromCharCode.apply(String, codePoints) // avoid extra slice() + } + + // Decode in chunks to avoid "call stack size exceeded". + var res = '' + var i = 0 + while (i < len) { + res += String.fromCharCode.apply( + String, + codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH) + ) + } + return res + } + + function asciiSlice (buf, start, end) { + var ret = '' + end = Math.min(buf.length, end) + + for (var i = start; i < end; i++) { + ret += String.fromCharCode(buf[i] & 0x7F) + } + return ret + } + + function binarySlice (buf, start, end) { + var ret = '' + end = Math.min(buf.length, end) + + for (var i = start; i < end; i++) { + ret += String.fromCharCode(buf[i]) + } + return ret + } + + function hexSlice (buf, start, end) { + var len = buf.length + + if (!start || start < 0) start = 0 + if (!end || end < 0 || end > len) end = len + + var out = '' + for (var i = start; i < end; i++) { + out += toHex(buf[i]) + } + return out + } + + function utf16leSlice (buf, start, end) { + var bytes = buf.slice(start, end) + var res = '' + for (var i = 0; i < bytes.length; i += 2) { + res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256) + } + return res + } + + Buffer.prototype.slice = function slice (start, end) { + var len = this.length + start = ~~start + end = end === undefined ? len : ~~end + + if (start < 0) { + start += len + if (start < 0) start = 0 + } else if (start > len) { + start = len + } + + if (end < 0) { + end += len + if (end < 0) end = 0 + } else if (end > len) { + end = len + } + + if (end < start) end = start + + var newBuf + if (Buffer.TYPED_ARRAY_SUPPORT) { + newBuf = Buffer._augment(this.subarray(start, end)) + } else { + var sliceLen = end - start + newBuf = new Buffer(sliceLen, undefined) + for (var i = 0; i < sliceLen; i++) { + newBuf[i] = this[i + start] + } + } + + if (newBuf.length) newBuf.parent = this.parent || this + + return newBuf + } + + /* + * Need to make sure that buffer isn't trying to write out of bounds. + */ + function checkOffset (offset, ext, length) { + if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint') + if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length') + } + + Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkOffset(offset, byteLength, this.length) + + var val = this[offset] + var mul = 1 + var i = 0 + while (++i < byteLength && (mul *= 0x100)) { + val += this[offset + i] * mul + } + + return val + } + + Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) { + checkOffset(offset, byteLength, this.length) + } + + var val = this[offset + --byteLength] + var mul = 1 + while (byteLength > 0 && (mul *= 0x100)) { + val += this[offset + --byteLength] * mul + } + + return val + } + + Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { + if (!noAssert) checkOffset(offset, 1, this.length) + return this[offset] + } + + Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + return this[offset] | (this[offset + 1] << 8) + } + + Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + return (this[offset] << 8) | this[offset + 1] + } + + Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return ((this[offset]) | + (this[offset + 1] << 8) | + (this[offset + 2] << 16)) + + (this[offset + 3] * 0x1000000) + } + + Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return (this[offset] * 0x1000000) + + ((this[offset + 1] << 16) | + (this[offset + 2] << 8) | + this[offset + 3]) + } + + Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkOffset(offset, byteLength, this.length) + + var val = this[offset] + var mul = 1 + var i = 0 + while (++i < byteLength && (mul *= 0x100)) { + val += this[offset + i] * mul + } + mul *= 0x80 + + if (val >= mul) val -= Math.pow(2, 8 * byteLength) + + return val + } + + Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkOffset(offset, byteLength, this.length) + + var i = byteLength + var mul = 1 + var val = this[offset + --i] + while (i > 0 && (mul *= 0x100)) { + val += this[offset + --i] * mul + } + mul *= 0x80 + + if (val >= mul) val -= Math.pow(2, 8 * byteLength) + + return val + } + + Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { + if (!noAssert) checkOffset(offset, 1, this.length) + if (!(this[offset] & 0x80)) return (this[offset]) + return ((0xff - this[offset] + 1) * -1) + } + + Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + var val = this[offset] | (this[offset + 1] << 8) + return (val & 0x8000) ? val | 0xFFFF0000 : val + } + + Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + var val = this[offset + 1] | (this[offset] << 8) + return (val & 0x8000) ? val | 0xFFFF0000 : val + } + + Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return (this[offset]) | + (this[offset + 1] << 8) | + (this[offset + 2] << 16) | + (this[offset + 3] << 24) + } + + Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return (this[offset] << 24) | + (this[offset + 1] << 16) | + (this[offset + 2] << 8) | + (this[offset + 3]) + } + + Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + return ieee754.read(this, offset, true, 23, 4) + } + + Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + return ieee754.read(this, offset, false, 23, 4) + } + + Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 8, this.length) + return ieee754.read(this, offset, true, 52, 8) + } + + Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 8, this.length) + return ieee754.read(this, offset, false, 52, 8) + } + + function checkInt (buf, value, offset, ext, max, min) { + if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance') + if (value > max || value < min) throw new RangeError('value is out of bounds') + if (offset + ext > buf.length) throw new RangeError('index out of range') + } + + Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0) + + var mul = 1 + var i = 0 + this[offset] = value & 0xFF + while (++i < byteLength && (mul *= 0x100)) { + this[offset + i] = (value / mul) & 0xFF + } + + return offset + byteLength + } + + Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0) + + var i = byteLength - 1 + var mul = 1 + this[offset + i] = value & 0xFF + while (--i >= 0 && (mul *= 0x100)) { + this[offset + i] = (value / mul) & 0xFF + } + + return offset + byteLength + } + + Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0) + if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) + this[offset] = value + return offset + 1 + } + + function objectWriteUInt16 (buf, value, offset, littleEndian) { + if (value < 0) value = 0xffff + value + 1 + for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) { + buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> + (littleEndian ? i : 1 - i) * 8 + } + } + + Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = value + this[offset + 1] = (value >>> 8) + } else { + objectWriteUInt16(this, value, offset, true) + } + return offset + 2 + } + + Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 8) + this[offset + 1] = value + } else { + objectWriteUInt16(this, value, offset, false) + } + return offset + 2 + } + + function objectWriteUInt32 (buf, value, offset, littleEndian) { + if (value < 0) value = 0xffffffff + value + 1 + for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) { + buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff + } + } + + Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset + 3] = (value >>> 24) + this[offset + 2] = (value >>> 16) + this[offset + 1] = (value >>> 8) + this[offset] = value + } else { + objectWriteUInt32(this, value, offset, true) + } + return offset + 4 + } + + Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 24) + this[offset + 1] = (value >>> 16) + this[offset + 2] = (value >>> 8) + this[offset + 3] = value + } else { + objectWriteUInt32(this, value, offset, false) + } + return offset + 4 + } + + Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) { + var limit = Math.pow(2, 8 * byteLength - 1) + + checkInt(this, value, offset, byteLength, limit - 1, -limit) + } + + var i = 0 + var mul = 1 + var sub = value < 0 ? 1 : 0 + this[offset] = value & 0xFF + while (++i < byteLength && (mul *= 0x100)) { + this[offset + i] = ((value / mul) >> 0) - sub & 0xFF + } + + return offset + byteLength + } + + Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) { + var limit = Math.pow(2, 8 * byteLength - 1) + + checkInt(this, value, offset, byteLength, limit - 1, -limit) + } + + var i = byteLength - 1 + var mul = 1 + var sub = value < 0 ? 1 : 0 + this[offset + i] = value & 0xFF + while (--i >= 0 && (mul *= 0x100)) { + this[offset + i] = ((value / mul) >> 0) - sub & 0xFF + } + + return offset + byteLength + } + + Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80) + if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) + if (value < 0) value = 0xff + value + 1 + this[offset] = value + return offset + 1 + } + + Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = value + this[offset + 1] = (value >>> 8) + } else { + objectWriteUInt16(this, value, offset, true) + } + return offset + 2 + } + + Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 8) + this[offset + 1] = value + } else { + objectWriteUInt16(this, value, offset, false) + } + return offset + 2 + } + + Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = value + this[offset + 1] = (value >>> 8) + this[offset + 2] = (value >>> 16) + this[offset + 3] = (value >>> 24) + } else { + objectWriteUInt32(this, value, offset, true) + } + return offset + 4 + } + + Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) + if (value < 0) value = 0xffffffff + value + 1 + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 24) + this[offset + 1] = (value >>> 16) + this[offset + 2] = (value >>> 8) + this[offset + 3] = value + } else { + objectWriteUInt32(this, value, offset, false) + } + return offset + 4 + } + + function checkIEEE754 (buf, value, offset, ext, max, min) { + if (value > max || value < min) throw new RangeError('value is out of bounds') + if (offset + ext > buf.length) throw new RangeError('index out of range') + if (offset < 0) throw new RangeError('index out of range') + } + + function writeFloat (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) + } + ieee754.write(buf, value, offset, littleEndian, 23, 4) + return offset + 4 + } + + Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { + return writeFloat(this, value, offset, true, noAssert) + } + + Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) { + return writeFloat(this, value, offset, false, noAssert) + } + + function writeDouble (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308) + } + ieee754.write(buf, value, offset, littleEndian, 52, 8) + return offset + 8 + } + + Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { + return writeDouble(this, value, offset, true, noAssert) + } + + Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { + return writeDouble(this, value, offset, false, noAssert) + } + + // copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) + Buffer.prototype.copy = function copy (target, targetStart, start, end) { + if (!start) start = 0 + if (!end && end !== 0) end = this.length + if (targetStart >= target.length) targetStart = target.length + if (!targetStart) targetStart = 0 + if (end > 0 && end < start) end = start + + // Copy 0 bytes; we're done + if (end === start) return 0 + if (target.length === 0 || this.length === 0) return 0 + + // Fatal error conditions + if (targetStart < 0) { + throw new RangeError('targetStart out of bounds') + } + if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds') + if (end < 0) throw new RangeError('sourceEnd out of bounds') + + // Are we oob? + if (end > this.length) end = this.length + if (target.length - targetStart < end - start) { + end = target.length - targetStart + start + } + + var len = end - start + var i + + if (this === target && start < targetStart && targetStart < end) { + // descending copy from end + for (i = len - 1; i >= 0; i--) { + target[i + targetStart] = this[i + start] + } + } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { + // ascending copy from start + for (i = 0; i < len; i++) { + target[i + targetStart] = this[i + start] + } + } else { + target._set(this.subarray(start, start + len), targetStart) + } + + return len + } + + // fill(value, start=0, end=buffer.length) + Buffer.prototype.fill = function fill (value, start, end) { + if (!value) value = 0 + if (!start) start = 0 + if (!end) end = this.length + + if (end < start) throw new RangeError('end < start') + + // Fill 0 bytes; we're done + if (end === start) return + if (this.length === 0) return + + if (start < 0 || start >= this.length) throw new RangeError('start out of bounds') + if (end < 0 || end > this.length) throw new RangeError('end out of bounds') + + var i + if (typeof value === 'number') { + for (i = start; i < end; i++) { + this[i] = value + } + } else { + var bytes = utf8ToBytes(value.toString()) + var len = bytes.length + for (i = start; i < end; i++) { + this[i] = bytes[i % len] + } + } + + return this + } + + /** + * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance. + * Added in Node 0.12. Only available in browsers that support ArrayBuffer. + */ + Buffer.prototype.toArrayBuffer = function toArrayBuffer () { + if (typeof Uint8Array !== 'undefined') { + if (Buffer.TYPED_ARRAY_SUPPORT) { + return (new Buffer(this)).buffer + } else { + var buf = new Uint8Array(this.length) + for (var i = 0, len = buf.length; i < len; i += 1) { + buf[i] = this[i] + } + return buf.buffer + } + } else { + throw new TypeError('Buffer.toArrayBuffer not supported in this browser') + } + } + + // HELPER FUNCTIONS + // ================ + + var BP = Buffer.prototype + + /** + * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods + */ + Buffer._augment = function _augment (arr) { + arr.constructor = Buffer + arr._isBuffer = true + + // save reference to original Uint8Array set method before overwriting + arr._set = arr.set + + // deprecated + arr.get = BP.get + arr.set = BP.set + + arr.write = BP.write + arr.toString = BP.toString + arr.toLocaleString = BP.toString + arr.toJSON = BP.toJSON + arr.equals = BP.equals + arr.compare = BP.compare + arr.indexOf = BP.indexOf + arr.copy = BP.copy + arr.slice = BP.slice + arr.readUIntLE = BP.readUIntLE + arr.readUIntBE = BP.readUIntBE + arr.readUInt8 = BP.readUInt8 + arr.readUInt16LE = BP.readUInt16LE + arr.readUInt16BE = BP.readUInt16BE + arr.readUInt32LE = BP.readUInt32LE + arr.readUInt32BE = BP.readUInt32BE + arr.readIntLE = BP.readIntLE + arr.readIntBE = BP.readIntBE + arr.readInt8 = BP.readInt8 + arr.readInt16LE = BP.readInt16LE + arr.readInt16BE = BP.readInt16BE + arr.readInt32LE = BP.readInt32LE + arr.readInt32BE = BP.readInt32BE + arr.readFloatLE = BP.readFloatLE + arr.readFloatBE = BP.readFloatBE + arr.readDoubleLE = BP.readDoubleLE + arr.readDoubleBE = BP.readDoubleBE + arr.writeUInt8 = BP.writeUInt8 + arr.writeUIntLE = BP.writeUIntLE + arr.writeUIntBE = BP.writeUIntBE + arr.writeUInt16LE = BP.writeUInt16LE + arr.writeUInt16BE = BP.writeUInt16BE + arr.writeUInt32LE = BP.writeUInt32LE + arr.writeUInt32BE = BP.writeUInt32BE + arr.writeIntLE = BP.writeIntLE + arr.writeIntBE = BP.writeIntBE + arr.writeInt8 = BP.writeInt8 + arr.writeInt16LE = BP.writeInt16LE + arr.writeInt16BE = BP.writeInt16BE + arr.writeInt32LE = BP.writeInt32LE + arr.writeInt32BE = BP.writeInt32BE + arr.writeFloatLE = BP.writeFloatLE + arr.writeFloatBE = BP.writeFloatBE + arr.writeDoubleLE = BP.writeDoubleLE + arr.writeDoubleBE = BP.writeDoubleBE + arr.fill = BP.fill + arr.inspect = BP.inspect + arr.toArrayBuffer = BP.toArrayBuffer + + return arr + } + + var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g + + function base64clean (str) { + // Node strips out invalid characters like \n and \t from the string, base64-js does not + str = stringtrim(str).replace(INVALID_BASE64_RE, '') + // Node converts strings with length < 2 to '' + if (str.length < 2) return '' + // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not + while (str.length % 4 !== 0) { + str = str + '=' + } + return str + } + + function stringtrim (str) { + if (str.trim) return str.trim() + return str.replace(/^\s+|\s+$/g, '') + } + + function toHex (n) { + if (n < 16) return '0' + n.toString(16) + return n.toString(16) + } + + function utf8ToBytes (string, units) { + units = units || Infinity + var codePoint + var length = string.length + var leadSurrogate = null + var bytes = [] + + for (var i = 0; i < length; i++) { + codePoint = string.charCodeAt(i) + + // is surrogate component + if (codePoint > 0xD7FF && codePoint < 0xE000) { + // last char was a lead + if (!leadSurrogate) { + // no lead yet + if (codePoint > 0xDBFF) { + // unexpected trail + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + continue + } else if (i + 1 === length) { + // unpaired lead + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + continue + } + + // valid lead + leadSurrogate = codePoint + + continue + } + + // 2 leads in a row + if (codePoint < 0xDC00) { + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + leadSurrogate = codePoint + continue + } + + // valid surrogate pair + codePoint = leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00 | 0x10000 + } else if (leadSurrogate) { + // valid bmp char, but last char was a lead + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + } + + leadSurrogate = null + + // encode utf8 + if (codePoint < 0x80) { + if ((units -= 1) < 0) break + bytes.push(codePoint) + } else if (codePoint < 0x800) { + if ((units -= 2) < 0) break + bytes.push( + codePoint >> 0x6 | 0xC0, + codePoint & 0x3F | 0x80 + ) + } else if (codePoint < 0x10000) { + if ((units -= 3) < 0) break + bytes.push( + codePoint >> 0xC | 0xE0, + codePoint >> 0x6 & 0x3F | 0x80, + codePoint & 0x3F | 0x80 + ) + } else if (codePoint < 0x110000) { + if ((units -= 4) < 0) break + bytes.push( + codePoint >> 0x12 | 0xF0, + codePoint >> 0xC & 0x3F | 0x80, + codePoint >> 0x6 & 0x3F | 0x80, + codePoint & 0x3F | 0x80 + ) + } else { + throw new Error('Invalid code point') + } + } + + return bytes + } + + function asciiToBytes (str) { + var byteArray = [] + for (var i = 0; i < str.length; i++) { + // Node's code seems to be doing this and not & 0x7F.. + byteArray.push(str.charCodeAt(i) & 0xFF) + } + return byteArray + } + + function utf16leToBytes (str, units) { + var c, hi, lo + var byteArray = [] + for (var i = 0; i < str.length; i++) { + if ((units -= 2) < 0) break + + c = str.charCodeAt(i) + hi = c >> 8 + lo = c % 256 + byteArray.push(lo) + byteArray.push(hi) + } + + return byteArray + } + + function base64ToBytes (str) { + return base64.toByteArray(base64clean(str)) + } + + function blitBuffer (src, dst, offset, length) { + for (var i = 0; i < length; i++) { + if ((i + offset >= dst.length) || (i >= src.length)) break + dst[i + offset] = src[i] + } + return i + } + + /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(2).Buffer)) + +/***/ }, +/* 3 */ +/***/ function(module, exports, __webpack_require__) { + + var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + + ;(function (exports) { + 'use strict'; + + var Arr = (typeof Uint8Array !== 'undefined') + ? Uint8Array + : Array + + var PLUS = '+'.charCodeAt(0) + var SLASH = '/'.charCodeAt(0) + var NUMBER = '0'.charCodeAt(0) + var LOWER = 'a'.charCodeAt(0) + var UPPER = 'A'.charCodeAt(0) + var PLUS_URL_SAFE = '-'.charCodeAt(0) + var SLASH_URL_SAFE = '_'.charCodeAt(0) + + function decode (elt) { + var code = elt.charCodeAt(0) + if (code === PLUS || + code === PLUS_URL_SAFE) + return 62 // '+' + if (code === SLASH || + code === SLASH_URL_SAFE) + return 63 // '/' + if (code < NUMBER) + return -1 //no match + if (code < NUMBER + 10) + return code - NUMBER + 26 + 26 + if (code < UPPER + 26) + return code - UPPER + if (code < LOWER + 26) + return code - LOWER + 26 + } + + function b64ToByteArray (b64) { + var i, j, l, tmp, placeHolders, arr + + if (b64.length % 4 > 0) { + throw new Error('Invalid string. Length must be a multiple of 4') + } + + // the number of equal signs (place holders) + // if there are two placeholders, than the two characters before it + // represent one byte + // if there is only one, then the three characters before it represent 2 bytes + // this is just a cheap hack to not do indexOf twice + var len = b64.length + placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0 + + // base64 is 4/3 + up to two characters of the original data + arr = new Arr(b64.length * 3 / 4 - placeHolders) + + // if there are placeholders, only get up to the last complete 4 chars + l = placeHolders > 0 ? b64.length - 4 : b64.length + + var L = 0 + + function push (v) { + arr[L++] = v + } + + for (i = 0, j = 0; i < l; i += 4, j += 3) { + tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3)) + push((tmp & 0xFF0000) >> 16) + push((tmp & 0xFF00) >> 8) + push(tmp & 0xFF) + } + + if (placeHolders === 2) { + tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4) + push(tmp & 0xFF) + } else if (placeHolders === 1) { + tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2) + push((tmp >> 8) & 0xFF) + push(tmp & 0xFF) + } + + return arr + } + + function uint8ToBase64 (uint8) { + var i, + extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes + output = "", + temp, length + + function encode (num) { + return lookup.charAt(num) + } + + function tripletToBase64 (num) { + return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F) + } + + // go through the array every three bytes, we'll deal with trailing stuff later + for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) { + temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) + output += tripletToBase64(temp) + } + + // pad the end with zeros, but make sure to not forget the extra bytes + switch (extraBytes) { + case 1: + temp = uint8[uint8.length - 1] + output += encode(temp >> 2) + output += encode((temp << 4) & 0x3F) + output += '==' + break + case 2: + temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1]) + output += encode(temp >> 10) + output += encode((temp >> 4) & 0x3F) + output += encode((temp << 2) & 0x3F) + output += '=' + break + } + + return output + } + + exports.toByteArray = b64ToByteArray + exports.fromByteArray = uint8ToBase64 + }( false ? (this.base64js = {}) : exports)) + + +/***/ }, +/* 4 */ +/***/ function(module, exports) { + + exports.read = function (buffer, offset, isLE, mLen, nBytes) { + var e, m + var eLen = nBytes * 8 - mLen - 1 + var eMax = (1 << eLen) - 1 + var eBias = eMax >> 1 + var nBits = -7 + var i = isLE ? (nBytes - 1) : 0 + var d = isLE ? -1 : 1 + var s = buffer[offset + i] + + i += d + + e = s & ((1 << (-nBits)) - 1) + s >>= (-nBits) + nBits += eLen + for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {} + + m = e & ((1 << (-nBits)) - 1) + e >>= (-nBits) + nBits += mLen + for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {} + + if (e === 0) { + e = 1 - eBias + } else if (e === eMax) { + return m ? NaN : ((s ? -1 : 1) * Infinity) + } else { + m = m + Math.pow(2, mLen) + e = e - eBias + } + return (s ? -1 : 1) * m * Math.pow(2, e - mLen) + } + + exports.write = function (buffer, value, offset, isLE, mLen, nBytes) { + var e, m, c + var eLen = nBytes * 8 - mLen - 1 + var eMax = (1 << eLen) - 1 + var eBias = eMax >> 1 + var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0) + var i = isLE ? 0 : (nBytes - 1) + var d = isLE ? 1 : -1 + var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0 + + value = Math.abs(value) + + if (isNaN(value) || value === Infinity) { + m = isNaN(value) ? 1 : 0 + e = eMax + } else { + e = Math.floor(Math.log(value) / Math.LN2) + if (value * (c = Math.pow(2, -e)) < 1) { + e-- + c *= 2 + } + if (e + eBias >= 1) { + value += rt / c + } else { + value += rt * Math.pow(2, 1 - eBias) + } + if (value * c >= 2) { + e++ + c /= 2 + } + + if (e + eBias >= eMax) { + m = 0 + e = eMax + } else if (e + eBias >= 1) { + m = (value * c - 1) * Math.pow(2, mLen) + e = e + eBias + } else { + m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen) + e = 0 + } + } + + for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} + + e = (e << mLen) | m + eLen += mLen + for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} + + buffer[offset + i - d] |= s * 128 + } + + +/***/ }, +/* 5 */ +/***/ function(module, exports) { + + + /** + * isArray + */ + + var isArray = Array.isArray; + + /** + * toString + */ + + var str = Object.prototype.toString; + + /** + * Whether or not the given `val` + * is an array. + * + * example: + * + * isArray([]); + * // > true + * isArray(arguments); + * // > false + * isArray(''); + * // > false + * + * @param {mixed} val + * @return {bool} + */ + + module.exports = isArray || function (val) { + return !! val && '[object Array]' == str.call(val); + }; + + +/***/ }, +/* 6 */ +/***/ function(module, exports, __webpack_require__) { + + /* jslint node: true */ + /* global window */ + 'use strict'; + + var _ = __webpack_require__(7); + var FontProvider = __webpack_require__(9); + var LayoutBuilder = __webpack_require__(11); + var PdfKit = __webpack_require__(24); + var PDFReference = __webpack_require__(46); + var sizes = __webpack_require__(102); + var ImageMeasure = __webpack_require__(103); + var textDecorator = __webpack_require__(104); + var FontProvider = __webpack_require__(9); + + //////////////////////////////////////// + // PdfPrinter + + /** + * @class Creates an instance of a PdfPrinter which turns document definition into a pdf + * + * @param {Object} fontDescriptors font definition dictionary + * + * @example + * var fontDescriptors = { + * Roboto: { + * normal: 'fonts/Roboto-Regular.ttf', + * bold: 'fonts/Roboto-Medium.ttf', + * italics: 'fonts/Roboto-Italic.ttf', + * bolditalics: 'fonts/Roboto-Italic.ttf' + * } + * }; + * + * var printer = new PdfPrinter(fontDescriptors); + */ + function PdfPrinter(fontDescriptors) { + this.fontDescriptors = fontDescriptors; + } + + /** + * Executes layout engine for the specified document and renders it into a pdfkit document + * ready to be saved. + * + * @param {Object} docDefinition document definition + * @param {Object} docDefinition.content an array describing the pdf structure (for more information take a look at the examples in the /examples folder) + * @param {Object} [docDefinition.defaultStyle] default (implicit) style definition + * @param {Object} [docDefinition.styles] dictionary defining all styles which can be used in the document + * @param {Object} [docDefinition.pageSize] page size (pdfkit units, A4 dimensions by default) + * @param {Number} docDefinition.pageSize.width width + * @param {Number} docDefinition.pageSize.height height + * @param {Object} [docDefinition.pageMargins] page margins (pdfkit units) + * + * @example + * + * var docDefinition = { + * content: [ + * 'First paragraph', + * 'Second paragraph, this time a little bit longer', + * { text: 'Third paragraph, slightly bigger font size', fontSize: 20 }, + * { text: 'Another paragraph using a named style', style: 'header' }, + * { text: ['playing with ', 'inlines' ] }, + * { text: ['and ', { text: 'restyling ', bold: true }, 'them'] }, + * ], + * styles: { + * header: { fontSize: 30, bold: true } + * } + * } + * + * var pdfDoc = printer.createPdfKitDocument(docDefinition); + * + * pdfDoc.pipe(fs.createWriteStream('sample.pdf')); + * pdfDoc.end(); + * + * @return {Object} a pdfKit document object which can be saved or encode to data-url + */ + PdfPrinter.prototype.createPdfKitDocument = function(docDefinition, options) { + options = options || {}; + + var pageSize = pageSize2widthAndHeight(docDefinition.pageSize || 'a4'); + + if(docDefinition.pageOrientation === 'landscape') { + pageSize = { width: pageSize.height, height: pageSize.width}; + } + pageSize.orientation = docDefinition.pageOrientation === 'landscape' ? docDefinition.pageOrientation : 'portrait'; + + this.pdfKitDoc = new PdfKit({ size: [ pageSize.width, pageSize.height ], compress: false}); + this.pdfKitDoc.info.Producer = 'pdfmake'; + this.pdfKitDoc.info.Creator = 'pdfmake'; + this.fontProvider = new FontProvider(this.fontDescriptors, this.pdfKitDoc); + + docDefinition.images = docDefinition.images || {}; + + var builder = new LayoutBuilder( + pageSize, + fixPageMargins(docDefinition.pageMargins || 40), + new ImageMeasure(this.pdfKitDoc, docDefinition.images)); + + registerDefaultTableLayouts(builder); + if (options.tableLayouts) { + builder.registerTableLayouts(options.tableLayouts); + } + + var pages = builder.layoutDocument(docDefinition.content, this.fontProvider, docDefinition.styles || {}, docDefinition.defaultStyle || { fontSize: 12, font: 'Roboto' }, docDefinition.background, docDefinition.header, docDefinition.footer, docDefinition.images, docDefinition.watermark, docDefinition.pageBreakBefore); + + renderPages(pages, this.fontProvider, this.pdfKitDoc); + + if(options.autoPrint){ + var printActionRef = this.pdfKitDoc.ref({ + Type: 'Action', + S: 'Named', + N: 'Print' + }); + this.pdfKitDoc._root.data.OpenAction = printActionRef; + printActionRef.end(); + } + return this.pdfKitDoc; + }; + + function fixPageMargins(margin) { + if (!margin) return null; + + if (typeof margin === 'number' || margin instanceof Number) { + margin = { left: margin, right: margin, top: margin, bottom: margin }; + } else if (margin instanceof Array) { + if (margin.length === 2) { + margin = { left: margin[0], top: margin[1], right: margin[0], bottom: margin[1] }; + } else if (margin.length === 4) { + margin = { left: margin[0], top: margin[1], right: margin[2], bottom: margin[3] }; + } else throw 'Invalid pageMargins definition'; + } + + return margin; + } + + function registerDefaultTableLayouts(layoutBuilder) { + layoutBuilder.registerTableLayouts({ + noBorders: { + hLineWidth: function(i) { return 0; }, + vLineWidth: function(i) { return 0; }, + paddingLeft: function(i) { return i && 4 || 0; }, + paddingRight: function(i, node) { return (i < node.table.widths.length - 1) ? 4 : 0; }, + }, + headerLineOnly: { + hLineWidth: function(i, node) { + if (i === 0 || i === node.table.body.length) return 0; + return (i === node.table.headerRows) ? 2 : 0; + }, + vLineWidth: function(i) { return 0; }, + paddingLeft: function(i) { + return i === 0 ? 0 : 8; + }, + paddingRight: function(i, node) { + return (i === node.table.widths.length - 1) ? 0 : 8; + } + }, + lightHorizontalLines: { + hLineWidth: function(i, node) { + if (i === 0 || i === node.table.body.length) return 0; + return (i === node.table.headerRows) ? 2 : 1; + }, + vLineWidth: function(i) { return 0; }, + hLineColor: function(i) { return i === 1 ? 'black' : '#aaa'; }, + paddingLeft: function(i) { + return i === 0 ? 0 : 8; + }, + paddingRight: function(i, node) { + return (i === node.table.widths.length - 1) ? 0 : 8; + } + } + }); + } + + var defaultLayout = { + hLineWidth: function(i, node) { return 1; }, //return node.table.headerRows && i === node.table.headerRows && 3 || 0; }, + vLineWidth: function(i, node) { return 1; }, + hLineColor: function(i, node) { return 'black'; }, + vLineColor: function(i, node) { return 'black'; }, + paddingLeft: function(i, node) { return 4; }, //i && 4 || 0; }, + paddingRight: function(i, node) { return 4; }, //(i < node.table.widths.length - 1) ? 4 : 0; }, + paddingTop: function(i, node) { return 2; }, + paddingBottom: function(i, node) { return 2; } + }; + + function pageSize2widthAndHeight(pageSize) { + if (typeof pageSize == 'string' || pageSize instanceof String) { + var size = sizes[pageSize.toUpperCase()]; + if (!size) throw ('Page size ' + pageSize + ' not recognized'); + return { width: size[0], height: size[1] }; + } + + return pageSize; + } + + function StringObject(str){ + this.isString = true; + this.toString = function(){ + return str; + }; + } + + function updatePageOrientationInOptions(currentPage, pdfKitDoc) { + var previousPageOrientation = pdfKitDoc.options.size[0] > pdfKitDoc.options.size[1] ? 'landscape' : 'portrait'; + + if(currentPage.pageSize.orientation !== previousPageOrientation) { + var width = pdfKitDoc.options.size[0]; + var height = pdfKitDoc.options.size[1]; + pdfKitDoc.options.size = [height, width]; + } + } + + function renderPages(pages, fontProvider, pdfKitDoc) { + pdfKitDoc._pdfMakePages = pages; + for (var i = 0; i < pages.length; i++) { + if (i > 0) { + updatePageOrientationInOptions(pages[i], pdfKitDoc); + pdfKitDoc.addPage(pdfKitDoc.options); + } + + var page = pages[i]; + for(var ii = 0, il = page.items.length; ii < il; ii++) { + var item = page.items[ii]; + switch(item.type) { + case 'vector': + renderVector(item.item, pdfKitDoc); + break; + case 'line': + renderLine(item.item, item.item.x, item.item.y, pdfKitDoc); + break; + case 'image': + renderImage(item.item, item.item.x, item.item.y, pdfKitDoc); + break; + } + } + if(page.watermark){ + renderWatermark(page, pdfKitDoc); + } + + fontProvider.setFontRefsToPdfDoc(); + } + } + + function renderLine(line, x, y, pdfKitDoc) { + x = x || 0; + y = y || 0; + + var ascenderHeight = line.getAscenderHeight(); + + textDecorator.drawBackground(line, x, y, pdfKitDoc); + + //TODO: line.optimizeInlines(); + for(var i = 0, l = line.inlines.length; i < l; i++) { + var inline = line.inlines[i]; + + pdfKitDoc.fill(inline.color || 'black'); + + pdfKitDoc.save(); + pdfKitDoc.transform(1, 0, 0, -1, 0, pdfKitDoc.page.height); + + + var encoded = inline.font.encode(inline.text); + pdfKitDoc.addContent('BT'); + + pdfKitDoc.addContent('' + (x + inline.x) + ' ' + (pdfKitDoc.page.height - y - ascenderHeight) + ' Td'); + pdfKitDoc.addContent('/' + encoded.fontId + ' ' + inline.fontSize + ' Tf'); + + pdfKitDoc.addContent('<' + encoded.encodedText + '> Tj'); + + pdfKitDoc.addContent('ET'); + pdfKitDoc.restore(); + } + + textDecorator.drawDecorations(line, x, y, pdfKitDoc); + + } + + function renderWatermark(page, pdfKitDoc){ + var watermark = page.watermark; + + pdfKitDoc.fill('black'); + pdfKitDoc.opacity(0.6); + + pdfKitDoc.save(); + pdfKitDoc.transform(1, 0, 0, -1, 0, pdfKitDoc.page.height); + + var angle = Math.atan2(pdfKitDoc.page.height, pdfKitDoc.page.width) * 180/Math.PI; + pdfKitDoc.rotate(angle, {origin: [pdfKitDoc.page.width/2, pdfKitDoc.page.height/2]}); + + var encoded = watermark.font.encode(watermark.text); + pdfKitDoc.addContent('BT'); + pdfKitDoc.addContent('' + (pdfKitDoc.page.width/2 - watermark.size.size.width/2) + ' ' + (pdfKitDoc.page.height/2 - watermark.size.size.height/4) + ' Td'); + pdfKitDoc.addContent('/' + encoded.fontId + ' ' + watermark.size.fontSize + ' Tf'); + pdfKitDoc.addContent('<' + encoded.encodedText + '> Tj'); + pdfKitDoc.addContent('ET'); + pdfKitDoc.restore(); + } + + function renderVector(vector, pdfDoc) { + //TODO: pdf optimization (there's no need to write all properties everytime) + pdfDoc.lineWidth(vector.lineWidth || 1); + if (vector.dash) { + pdfDoc.dash(vector.dash.length, { space: vector.dash.space || vector.dash.length }); + } else { + pdfDoc.undash(); + } + pdfDoc.fillOpacity(vector.fillOpacity || 1); + pdfDoc.strokeOpacity(vector.strokeOpacity || 1); + pdfDoc.lineJoin(vector.lineJoin || 'miter'); + + //TODO: clipping + + switch(vector.type) { + case 'ellipse': + pdfDoc.ellipse(vector.x, vector.y, vector.r1, vector.r2); + break; + case 'rect': + if (vector.r) { + pdfDoc.roundedRect(vector.x, vector.y, vector.w, vector.h, vector.r); + } else { + pdfDoc.rect(vector.x, vector.y, vector.w, vector.h); + } + break; + case 'line': + pdfDoc.moveTo(vector.x1, vector.y1); + pdfDoc.lineTo(vector.x2, vector.y2); + break; + case 'polyline': + if (vector.points.length === 0) break; + + pdfDoc.moveTo(vector.points[0].x, vector.points[0].y); + for(var i = 1, l = vector.points.length; i < l; i++) { + pdfDoc.lineTo(vector.points[i].x, vector.points[i].y); + } + + if (vector.points.length > 1) { + var p1 = vector.points[0]; + var pn = vector.points[vector.points.length - 1]; + + if (vector.closePath || p1.x === pn.x && p1.y === pn.y) { + pdfDoc.closePath(); + } + } + break; + } + + if (vector.color && vector.lineColor) { + pdfDoc.fillAndStroke(vector.color, vector.lineColor); + } else if (vector.color) { + pdfDoc.fill(vector.color); + } else { + pdfDoc.stroke(vector.lineColor || 'black'); + } + } + + function renderImage(image, x, y, pdfKitDoc) { + pdfKitDoc.image(image.image, image.x, image.y, { width: image._width, height: image._height }); + } + + module.exports = PdfPrinter; + + + /* temporary browser extension */ + PdfPrinter.prototype.fs = __webpack_require__(44); + + +/***/ }, +/* 7 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(module, global) {/** + * @license + * lodash 3.1.0 (Custom Build) + * Build: `lodash modern -d -o ./index.js` + * Copyright 2012-2015 The Dojo Foundation + * Based on Underscore.js 1.7.0 + * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ + ;(function() { + + /** Used as a safe reference for `undefined` in pre-ES5 environments. */ + var undefined; + + /** Used as the semantic version number. */ + var VERSION = '3.1.0'; + + /** Used to compose bitmasks for wrapper metadata. */ + var BIND_FLAG = 1, + BIND_KEY_FLAG = 2, + CURRY_BOUND_FLAG = 4, + CURRY_FLAG = 8, + CURRY_RIGHT_FLAG = 16, + PARTIAL_FLAG = 32, + PARTIAL_RIGHT_FLAG = 64, + REARG_FLAG = 128, + ARY_FLAG = 256; + + /** Used as default options for `_.trunc`. */ + var DEFAULT_TRUNC_LENGTH = 30, + DEFAULT_TRUNC_OMISSION = '...'; + + /** Used to detect when a function becomes hot. */ + var HOT_COUNT = 150, + HOT_SPAN = 16; + + /** Used to indicate the type of lazy iteratees. */ + var LAZY_FILTER_FLAG = 0, + LAZY_MAP_FLAG = 1, + LAZY_WHILE_FLAG = 2; + + /** Used as the `TypeError` message for "Functions" methods. */ + var FUNC_ERROR_TEXT = 'Expected a function'; + + /** Used as the internal argument placeholder. */ + var PLACEHOLDER = '__lodash_placeholder__'; + + /** `Object#toString` result references. */ + var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag = '[object Object]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + weakMapTag = '[object WeakMap]'; + + var arrayBufferTag = '[object ArrayBuffer]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + + /** Used to match empty string literals in compiled template source. */ + var reEmptyStringLeading = /\b__p \+= '';/g, + reEmptyStringMiddle = /\b(__p \+=) '' \+/g, + reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; + + /** Used to match HTML entities and HTML characters. */ + var reEscapedHtml = /&(?:amp|lt|gt|quot|#39|#96);/g, + reUnescapedHtml = /[&<>"'`]/g, + reHasEscapedHtml = RegExp(reEscapedHtml.source), + reHasUnescapedHtml = RegExp(reUnescapedHtml.source); + + /** Used to match template delimiters. */ + var reEscape = /<%-([\s\S]+?)%>/g, + reEvaluate = /<%([\s\S]+?)%>/g, + reInterpolate = /<%=([\s\S]+?)%>/g; + + /** + * Used to match ES template delimiters. + * See the [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-template-literal-lexical-components) + * for more details. + */ + var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; + + /** Used to match `RegExp` flags from their coerced string values. */ + var reFlags = /\w*$/; + + /** Used to detect named functions. */ + var reFuncName = /^\s*function[ \n\r\t]+\w/; + + /** Used to detect hexadecimal string values. */ + var reHexPrefix = /^0[xX]/; + + /** Used to detect host constructors (Safari > 5). */ + var reHostCtor = /^\[object .+?Constructor\]$/; + + /** Used to match latin-1 supplementary letters (excluding mathematical operators). */ + var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g; + + /** Used to ensure capturing order of template delimiters. */ + var reNoMatch = /($^)/; + + /** + * Used to match `RegExp` special characters. + * See this [article on `RegExp` characters](http://www.regular-expressions.info/characters.html#special) + * for more details. + */ + var reRegExpChars = /[.*+?^${}()|[\]\/\\]/g, + reHasRegExpChars = RegExp(reRegExpChars.source); + + /** Used to detect functions containing a `this` reference. */ + var reThis = /\bthis\b/; + + /** Used to match unescaped characters in compiled string literals. */ + var reUnescapedString = /['\n\r\u2028\u2029\\]/g; + + /** Used to match words to create compound words. */ + var reWords = (function() { + var upper = '[A-Z\\xc0-\\xd6\\xd8-\\xde]', + lower = '[a-z\\xdf-\\xf6\\xf8-\\xff]+'; + + return RegExp(upper + '{2,}(?=' + upper + lower + ')|' + upper + '?' + lower + '|' + upper + '+|[0-9]+', 'g'); + }()); + + /** Used to detect and test for whitespace. */ + var whitespace = ( + // Basic whitespace characters. + ' \t\x0b\f\xa0\ufeff' + + + // Line terminators. + '\n\r\u2028\u2029' + + + // Unicode category "Zs" space separators. + '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000' + ); + + /** Used to assign default `context` object properties. */ + var contextProps = [ + 'Array', 'ArrayBuffer', 'Date', 'Error', 'Float32Array', 'Float64Array', + 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Math', 'Number', + 'Object', 'RegExp', 'Set', 'String', '_', 'clearTimeout', 'document', + 'isFinite', 'parseInt', 'setTimeout', 'TypeError', 'Uint8Array', + 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap', + 'window', 'WinRTError' + ]; + + /** Used to make template sourceURLs easier to identify. */ + var templateCounter = -1; + + /** Used to identify `toStringTag` values of typed arrays. */ + var typedArrayTags = {}; + typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = + typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = + typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = + typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = + typedArrayTags[uint32Tag] = true; + typedArrayTags[argsTag] = typedArrayTags[arrayTag] = + typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = + typedArrayTags[dateTag] = typedArrayTags[errorTag] = + typedArrayTags[funcTag] = typedArrayTags[mapTag] = + typedArrayTags[numberTag] = typedArrayTags[objectTag] = + typedArrayTags[regexpTag] = typedArrayTags[setTag] = + typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false; + + /** Used to identify `toStringTag` values supported by `_.clone`. */ + var cloneableTags = {}; + cloneableTags[argsTag] = cloneableTags[arrayTag] = + cloneableTags[arrayBufferTag] = cloneableTags[boolTag] = + cloneableTags[dateTag] = cloneableTags[float32Tag] = + cloneableTags[float64Tag] = cloneableTags[int8Tag] = + cloneableTags[int16Tag] = cloneableTags[int32Tag] = + cloneableTags[numberTag] = cloneableTags[objectTag] = + cloneableTags[regexpTag] = cloneableTags[stringTag] = + cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = + cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; + cloneableTags[errorTag] = cloneableTags[funcTag] = + cloneableTags[mapTag] = cloneableTags[setTag] = + cloneableTags[weakMapTag] = false; + + /** Used as an internal `_.debounce` options object by `_.throttle`. */ + var debounceOptions = { + 'leading': false, + 'maxWait': 0, + 'trailing': false + }; + + /** Used to map latin-1 supplementary letters to basic latin letters. */ + var deburredLetters = { + '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A', + '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a', + '\xc7': 'C', '\xe7': 'c', + '\xd0': 'D', '\xf0': 'd', + '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E', + '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e', + '\xcC': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I', + '\xeC': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i', + '\xd1': 'N', '\xf1': 'n', + '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O', + '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o', + '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U', + '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u', + '\xdd': 'Y', '\xfd': 'y', '\xff': 'y', + '\xc6': 'Ae', '\xe6': 'ae', + '\xde': 'Th', '\xfe': 'th', + '\xdf': 'ss' + }; + + /** Used to map characters to HTML entities. */ + var htmlEscapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '`': '`' + }; + + /** Used to map HTML entities to characters. */ + var htmlUnescapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + ''': "'", + '`': '`' + }; + + /** Used to determine if values are of the language type `Object`. */ + var objectTypes = { + 'function': true, + 'object': true + }; + + /** Used to escape characters for inclusion in compiled string literals. */ + var stringEscapes = { + '\\': '\\', + "'": "'", + '\n': 'n', + '\r': 'r', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + /** + * Used as a reference to the global object. + * + * The `this` value is used if it is the global object to avoid Greasemonkey's + * restricted `window` object, otherwise the `window` object is used. + */ + var root = (objectTypes[typeof window] && window !== (this && this.window)) ? window : this; + + /** Detect free variable `exports`. */ + var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports; + + /** Detect free variable `module`. */ + var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; + + /** Detect free variable `global` from Node.js or Browserified code and use it as `root`. */ + var freeGlobal = freeExports && freeModule && typeof global == 'object' && global; + if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal || freeGlobal.self === freeGlobal)) { + root = freeGlobal; + } + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = freeModule && freeModule.exports === freeExports && freeExports; + + /*--------------------------------------------------------------------------*/ + + /** + * The base implementation of `compareAscending` which compares values and + * sorts them in ascending order without guaranteeing a stable sort. + * + * @private + * @param {*} value The value to compare to `other`. + * @param {*} other The value to compare to `value`. + * @returns {number} Returns the sort order indicator for `value`. + */ + function baseCompareAscending(value, other) { + if (value !== other) { + var valIsReflexive = value === value, + othIsReflexive = other === other; + + if (value > other || !valIsReflexive || (typeof value == 'undefined' && othIsReflexive)) { + return 1; + } + if (value < other || !othIsReflexive || (typeof other == 'undefined' && valIsReflexive)) { + return -1; + } + } + return 0; + } + + /** + * The base implementation of `_.indexOf` without support for binary searches. + * + * @private + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseIndexOf(array, value, fromIndex) { + if (value !== value) { + return indexOfNaN(array, fromIndex); + } + var index = (fromIndex || 0) - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * The base implementation of `_.sortBy` and `_.sortByAll` which uses `comparer` + * to define the sort order of `array` and replaces criteria objects with their + * corresponding values. + * + * @private + * @param {Array} array The array to sort. + * @param {Function} comparer The function to define sort order. + * @returns {Array} Returns `array`. + */ + function baseSortBy(array, comparer) { + var length = array.length; + + array.sort(comparer); + while (length--) { + array[length] = array[length].value; + } + return array; + } + + /** + * Converts `value` to a string if it is not one. An empty string is returned + * for `null` or `undefined` values. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ + function baseToString(value) { + if (typeof value == 'string') { + return value; + } + return value == null ? '' : (value + ''); + } + + /** + * Used by `_.max` and `_.min` as the default callback for string values. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the code unit of the first character of the string. + */ + function charAtCallback(string) { + return string.charCodeAt(0); + } + + /** + * Used by `_.trim` and `_.trimLeft` to get the index of the first character + * of `string` that is not found in `chars`. + * + * @private + * @param {string} string The string to inspect. + * @param {string} chars The characters to find. + * @returns {number} Returns the index of the first character not found in `chars`. + */ + function charsLeftIndex(string, chars) { + var index = -1, + length = string.length; + + while (++index < length && chars.indexOf(string.charAt(index)) > -1) {} + return index; + } + + /** + * Used by `_.trim` and `_.trimRight` to get the index of the last character + * of `string` that is not found in `chars`. + * + * @private + * @param {string} string The string to inspect. + * @param {string} chars The characters to find. + * @returns {number} Returns the index of the last character not found in `chars`. + */ + function charsRightIndex(string, chars) { + var index = string.length; + + while (index-- && chars.indexOf(string.charAt(index)) > -1) {} + return index; + } + + /** + * Used by `_.sortBy` to compare transformed elements of a collection and stable + * sort them in ascending order. + * + * @private + * @param {Object} object The object to compare to `other`. + * @param {Object} other The object to compare to `object`. + * @returns {number} Returns the sort order indicator for `object`. + */ + function compareAscending(object, other) { + return baseCompareAscending(object.criteria, other.criteria) || (object.index - other.index); + } + + /** + * Used by `_.sortByAll` to compare multiple properties of each element + * in a collection and stable sort them in ascending order. + * + * @private + * @param {Object} object The object to compare to `other`. + * @param {Object} other The object to compare to `object`. + * @returns {number} Returns the sort order indicator for `object`. + */ + function compareMultipleAscending(object, other) { + var index = -1, + objCriteria = object.criteria, + othCriteria = other.criteria, + length = objCriteria.length; + + while (++index < length) { + var result = baseCompareAscending(objCriteria[index], othCriteria[index]); + if (result) { + return result; + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to provide the same value for + // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 + // for more details. + // + // This also ensures a stable sort in V8 and other engines. + // See https://code.google.com/p/v8/issues/detail?id=90 for more details. + return object.index - other.index; + } + + /** + * Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters. + * + * @private + * @param {string} letter The matched letter to deburr. + * @returns {string} Returns the deburred letter. + */ + function deburrLetter(letter) { + return deburredLetters[letter]; + } + + /** + * Used by `_.escape` to convert characters to HTML entities. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeHtmlChar(chr) { + return htmlEscapes[chr]; + } + + /** + * Used by `_.template` to escape characters for inclusion in compiled + * string literals. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeStringChar(chr) { + return '\\' + stringEscapes[chr]; + } + + /** + * Gets the index at which the first occurrence of `NaN` is found in `array`. + * If `fromRight` is provided elements of `array` are iterated from right to left. + * + * @private + * @param {Array} array The array to search. + * @param {number} [fromIndex] The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched `NaN`, else `-1`. + */ + function indexOfNaN(array, fromIndex, fromRight) { + var length = array.length, + index = fromRight ? (fromIndex || length) : ((fromIndex || 0) - 1); + + while ((fromRight ? index-- : ++index < length)) { + var other = array[index]; + if (other !== other) { + return index; + } + } + return -1; + } + + /** + * Checks if `value` is object-like. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + */ + function isObjectLike(value) { + return (value && typeof value == 'object') || false; + } + + /** + * Used by `trimmedLeftIndex` and `trimmedRightIndex` to determine if a + * character code is whitespace. + * + * @private + * @param {number} charCode The character code to inspect. + * @returns {boolean} Returns `true` if `charCode` is whitespace, else `false`. + */ + function isSpace(charCode) { + return ((charCode <= 160 && (charCode >= 9 && charCode <= 13) || charCode == 32 || charCode == 160) || charCode == 5760 || charCode == 6158 || + (charCode >= 8192 && (charCode <= 8202 || charCode == 8232 || charCode == 8233 || charCode == 8239 || charCode == 8287 || charCode == 12288 || charCode == 65279))); + } + + /** + * Replaces all `placeholder` elements in `array` with an internal placeholder + * and returns an array of their indexes. + * + * @private + * @param {Array} array The array to modify. + * @param {*} placeholder The placeholder to replace. + * @returns {Array} Returns the new array of placeholder indexes. + */ + function replaceHolders(array, placeholder) { + var index = -1, + length = array.length, + resIndex = -1, + result = []; + + while (++index < length) { + if (array[index] === placeholder) { + array[index] = PLACEHOLDER; + result[++resIndex] = index; + } + } + return result; + } + + /** + * An implementation of `_.uniq` optimized for sorted arrays without support + * for callback shorthands and `this` binding. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The function invoked per iteration. + * @returns {Array} Returns the new duplicate-value-free array. + */ + function sortedUniq(array, iteratee) { + var seen, + index = -1, + length = array.length, + resIndex = -1, + result = []; + + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value, index, array) : value; + + if (!index || seen !== computed) { + seen = computed; + result[++resIndex] = value; + } + } + return result; + } + + /** + * Used by `_.trim` and `_.trimLeft` to get the index of the first non-whitespace + * character of `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the index of the first non-whitespace character. + */ + function trimmedLeftIndex(string) { + var index = -1, + length = string.length; + + while (++index < length && isSpace(string.charCodeAt(index))) {} + return index; + } + + /** + * Used by `_.trim` and `_.trimRight` to get the index of the last non-whitespace + * character of `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the index of the last non-whitespace character. + */ + function trimmedRightIndex(string) { + var index = string.length; + + while (index-- && isSpace(string.charCodeAt(index))) {} + return index; + } + + /** + * Used by `_.unescape` to convert HTML entities to characters. + * + * @private + * @param {string} chr The matched character to unescape. + * @returns {string} Returns the unescaped character. + */ + function unescapeHtmlChar(chr) { + return htmlUnescapes[chr]; + } + + /*--------------------------------------------------------------------------*/ + + /** + * Create a new pristine `lodash` function using the given `context` object. + * + * @static + * @memberOf _ + * @category Utility + * @param {Object} [context=root] The context object. + * @returns {Function} Returns a new `lodash` function. + * @example + * + * _.mixin({ 'add': function(a, b) { return a + b; } }); + * + * var lodash = _.runInContext(); + * lodash.mixin({ 'sub': function(a, b) { return a - b; } }); + * + * _.isFunction(_.add); + * // => true + * _.isFunction(_.sub); + * // => false + * + * lodash.isFunction(lodash.add); + * // => false + * lodash.isFunction(lodash.sub); + * // => true + * + * // using `context` to mock `Date#getTime` use in `_.now` + * var mock = _.runInContext({ + * 'Date': function() { + * return { 'getTime': getTimeMock }; + * } + * }); + * + * // or creating a suped-up `defer` in Node.js + * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer; + */ + function runInContext(context) { + // Avoid issues with some ES3 environments that attempt to use values, named + // after built-in constructors like `Object`, for the creation of literals. + // ES5 clears this up by stating that literals must use built-in constructors. + // See https://es5.github.io/#x11.1.5 for more details. + context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root; + + /** Native constructor references. */ + var Array = context.Array, + Date = context.Date, + Error = context.Error, + Function = context.Function, + Math = context.Math, + Number = context.Number, + Object = context.Object, + RegExp = context.RegExp, + String = context.String, + TypeError = context.TypeError; + + /** Used for native method references. */ + var arrayProto = Array.prototype, + objectProto = Object.prototype; + + /** Used to detect DOM support. */ + var document = (document = context.window) && document.document; + + /** Used to resolve the decompiled source of functions. */ + var fnToString = Function.prototype.toString; + + /** Used to the length of n-tuples for `_.unzip`. */ + var getLength = baseProperty('length'); + + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** Used to generate unique IDs. */ + var idCounter = 0; + + /** + * Used to resolve the `toStringTag` of values. + * See the [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring) + * for more details. + */ + var objToString = objectProto.toString; + + /** Used to restore the original `_` reference in `_.noConflict`. */ + var oldDash = context._; + + /** Used to detect if a method is native. */ + var reNative = RegExp('^' + + escapeRegExp(objToString) + .replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' + ); + + /** Native method references. */ + var ArrayBuffer = isNative(ArrayBuffer = context.ArrayBuffer) && ArrayBuffer, + bufferSlice = isNative(bufferSlice = ArrayBuffer && new ArrayBuffer(0).slice) && bufferSlice, + ceil = Math.ceil, + clearTimeout = context.clearTimeout, + floor = Math.floor, + getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf, + push = arrayProto.push, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + Set = isNative(Set = context.Set) && Set, + setTimeout = context.setTimeout, + splice = arrayProto.splice, + Uint8Array = isNative(Uint8Array = context.Uint8Array) && Uint8Array, + unshift = arrayProto.unshift, + WeakMap = isNative(WeakMap = context.WeakMap) && WeakMap; + + /** Used to clone array buffers. */ + var Float64Array = (function() { + // Safari 5 errors when using an array buffer to initialize a typed array + // where the array buffer's `byteLength` is not a multiple of the typed + // array's `BYTES_PER_ELEMENT`. + try { + var func = isNative(func = context.Float64Array) && func, + result = new func(new ArrayBuffer(10), 0, 1) && func; + } catch(e) {} + return result; + }()); + + /* Native method references for those with the same name as other `lodash` methods. */ + var nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray, + nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate, + nativeIsFinite = context.isFinite, + nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys, + nativeMax = Math.max, + nativeMin = Math.min, + nativeNow = isNative(nativeNow = Date.now) && nativeNow, + nativeNumIsFinite = isNative(nativeNumIsFinite = Number.isFinite) && nativeNumIsFinite, + nativeParseInt = context.parseInt, + nativeRandom = Math.random; + + /** Used as references for `-Infinity` and `Infinity`. */ + var NEGATIVE_INFINITY = Number.NEGATIVE_INFINITY, + POSITIVE_INFINITY = Number.POSITIVE_INFINITY; + + /** Used as references for the maximum length and index of an array. */ + var MAX_ARRAY_LENGTH = Math.pow(2, 32) - 1, + MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1, + HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; + + /** Used as the size, in bytes, of each `Float64Array` element. */ + var FLOAT64_BYTES_PER_ELEMENT = Float64Array ? Float64Array.BYTES_PER_ELEMENT : 0; + + /** + * Used as the maximum length of an array-like value. + * See the [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer) + * for more details. + */ + var MAX_SAFE_INTEGER = Math.pow(2, 53) - 1; + + /** Used to store function metadata. */ + var metaMap = WeakMap && new WeakMap; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` object which wraps `value` to enable intuitive chaining. + * Methods that operate on and return arrays, collections, and functions can + * be chained together. Methods that return a boolean or single value will + * automatically end the chain returning the unwrapped value. Explicit chaining + * may be enabled using `_.chain`. The execution of chained methods is lazy, + * that is, execution is deferred until `_#value` is implicitly or explicitly + * called. + * + * Lazy evaluation allows several methods to support shortcut fusion. Shortcut + * fusion is an optimization that merges iteratees to avoid creating intermediate + * arrays and reduce the number of iteratee executions. + * + * Chaining is supported in custom builds as long as the `_#value` method is + * directly or indirectly included in the build. + * + * In addition to lodash methods, wrappers also have the following `Array` methods: + * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`, + * and `unshift` + * + * The wrapper functions that support shortcut fusion are: + * `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `filter`, `first`, + * `initial`, `last`, `map`, `pluck`, `reject`, `rest`, `reverse`, `slice`, + * `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `where` + * + * The chainable wrapper functions are: + * `after`, `ary`, `assign`, `at`, `before`, `bind`, `bindAll`, `bindKey`, + * `callback`, `chain`, `chunk`, `compact`, `concat`, `constant`, `countBy`, + * `create`, `curry`, `debounce`, `defaults`, `defer`, `delay`, `difference`, + * `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `filter`, `flatten`, + * `flattenDeep`, `flow`, `flowRight`, `forEach`, `forEachRight`, `forIn`, + * `forInRight`, `forOwn`, `forOwnRight`, `functions`, `groupBy`, `indexBy`, + * `initial`, `intersection`, `invert`, `invoke`, `keys`, `keysIn`, `map`, + * `mapValues`, `matches`, `memoize`, `merge`, `mixin`, `negate`, `noop`, + * `omit`, `once`, `pairs`, `partial`, `partialRight`, `partition`, `pick`, + * `pluck`, `property`, `propertyOf`, `pull`, `pullAt`, `push`, `range`, + * `rearg`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, + * `sortBy`, `sortByAll`, `splice`, `take`, `takeRight`, `takeRightWhile`, + * `takeWhile`, `tap`, `throttle`, `thru`, `times`, `toArray`, `toPlainObject`, + * `transform`, `union`, `uniq`, `unshift`, `unzip`, `values`, `valuesIn`, + * `where`, `without`, `wrap`, `xor`, `zip`, and `zipObject` + * + * The wrapper functions that are **not** chainable by default are: + * `attempt`, `camelCase`, `capitalize`, `clone`, `cloneDeep`, `deburr`, + * `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, + * `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, `has`, + * `identity`, `includes`, `indexOf`, `isArguments`, `isArray`, `isBoolean`, + * `isDate`, `isElement`, `isEmpty`, `isEqual`, `isError`, `isFinite`, + * `isFunction`, `isMatch`, `isNative`, `isNaN`, `isNull`, `isNumber`, + * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, + * `isTypedArray`, `join`, `kebabCase`, `last`, `lastIndexOf`, `max`, `min`, + * `noConflict`, `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, + * `random`, `reduce`, `reduceRight`, `repeat`, `result`, `runInContext`, + * `shift`, `size`, `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, + * `startCase`, `startsWith`, `template`, `trim`, `trimLeft`, `trimRight`, + * `trunc`, `unescape`, `uniqueId`, `value`, and `words` + * + * The wrapper function `sample` will return a wrapped value when `n` is provided, + * otherwise an unwrapped value is returned. + * + * @name _ + * @constructor + * @category Chain + * @param {*} value The value to wrap in a `lodash` instance. + * @returns {Object} Returns a `lodash` instance. + * @example + * + * var wrapped = _([1, 2, 3]); + * + * // returns an unwrapped value + * wrapped.reduce(function(sum, n) { return sum + n; }); + * // => 6 + * + * // returns a wrapped value + * var squares = wrapped.map(function(n) { return n * n; }); + * + * _.isArray(squares); + * // => false + * + * _.isArray(squares.value()); + * // => true + */ + function lodash(value) { + if (isObjectLike(value) && !isArray(value)) { + if (value instanceof LodashWrapper) { + return value; + } + if (hasOwnProperty.call(value, '__wrapped__')) { + return new LodashWrapper(value.__wrapped__, value.__chain__, arrayCopy(value.__actions__)); + } + } + return new LodashWrapper(value); + } + + /** + * The base constructor for creating `lodash` wrapper objects. + * + * @private + * @param {*} value The value to wrap. + * @param {boolean} [chainAll] Enable chaining for all wrapper methods. + * @param {Array} [actions=[]] Actions to peform to resolve the unwrapped value. + */ + function LodashWrapper(value, chainAll, actions) { + this.__actions__ = actions || []; + this.__chain__ = !!chainAll; + this.__wrapped__ = value; + } + + /** + * An object environment feature flags. + * + * @static + * @memberOf _ + * @type Object + */ + var support = lodash.support = {}; + + (function(x) { + + /** + * Detect if functions can be decompiled by `Function#toString` + * (all but Firefox OS certified apps, older Opera mobile browsers, and + * the PlayStation 3; forced `false` for Windows 8 apps). + * + * @memberOf _.support + * @type boolean + */ + support.funcDecomp = !isNative(context.WinRTError) && reThis.test(runInContext); + + /** + * Detect if `Function#name` is supported (all but IE). + * + * @memberOf _.support + * @type boolean + */ + support.funcNames = typeof Function.name == 'string'; + + /** + * Detect if the DOM is supported. + * + * @memberOf _.support + * @type boolean + */ + try { + support.dom = document.createDocumentFragment().nodeType === 11; + } catch(e) { + support.dom = false; + } + + /** + * Detect if `arguments` object indexes are non-enumerable. + * + * In Firefox < 4, IE < 9, PhantomJS, and Safari < 5.1 `arguments` object + * indexes are non-enumerable. Chrome < 25 and Node.js < 0.11.0 treat + * `arguments` object indexes as non-enumerable and fail `hasOwnProperty` + * checks for indexes that exceed their function's formal parameters with + * associated values of `0`. + * + * @memberOf _.support + * @type boolean + */ + try { + support.nonEnumArgs = !propertyIsEnumerable.call(arguments, 1); + } catch(e) { + support.nonEnumArgs = true; + } + }(0, 0)); + + /** + * By default, the template delimiters used by lodash are like those in + * embedded Ruby (ERB). Change the following template settings to use + * alternative delimiters. + * + * @static + * @memberOf _ + * @type Object + */ + lodash.templateSettings = { + + /** + * Used to detect `data` property values to be HTML-escaped. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'escape': reEscape, + + /** + * Used to detect code to be evaluated. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'evaluate': reEvaluate, + + /** + * Used to detect `data` property values to inject. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'interpolate': reInterpolate, + + /** + * Used to reference the data object in the template text. + * + * @memberOf _.templateSettings + * @type string + */ + 'variable': '', + + /** + * Used to import variables into the compiled template. + * + * @memberOf _.templateSettings + * @type Object + */ + 'imports': { + + /** + * A reference to the `lodash` function. + * + * @memberOf _.templateSettings.imports + * @type Function + */ + '_': lodash + } + }; + + /*------------------------------------------------------------------------*/ + + /** + * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. + * + * @private + * @param {*} value The value to wrap. + */ + function LazyWrapper(value) { + this.actions = null; + this.dir = 1; + this.dropCount = 0; + this.filtered = false; + this.iteratees = null; + this.takeCount = POSITIVE_INFINITY; + this.views = null; + this.wrapped = value; + } + + /** + * Creates a clone of the lazy wrapper object. + * + * @private + * @name clone + * @memberOf LazyWrapper + * @returns {Object} Returns the cloned `LazyWrapper` object. + */ + function lazyClone() { + var actions = this.actions, + iteratees = this.iteratees, + views = this.views, + result = new LazyWrapper(this.wrapped); + + result.actions = actions ? arrayCopy(actions) : null; + result.dir = this.dir; + result.dropCount = this.dropCount; + result.filtered = this.filtered; + result.iteratees = iteratees ? arrayCopy(iteratees) : null; + result.takeCount = this.takeCount; + result.views = views ? arrayCopy(views) : null; + return result; + } + + /** + * Reverses the direction of lazy iteration. + * + * @private + * @name reverse + * @memberOf LazyWrapper + * @returns {Object} Returns the new reversed `LazyWrapper` object. + */ + function lazyReverse() { + if (this.filtered) { + var result = new LazyWrapper(this); + result.dir = -1; + result.filtered = true; + } else { + result = this.clone(); + result.dir *= -1; + } + return result; + } + + /** + * Extracts the unwrapped value from its lazy wrapper. + * + * @private + * @name value + * @memberOf LazyWrapper + * @returns {*} Returns the unwrapped value. + */ + function lazyValue() { + var array = this.wrapped.value(); + if (!isArray(array)) { + return baseWrapperValue(array, this.actions); + } + var dir = this.dir, + isRight = dir < 0, + view = getView(0, array.length, this.views), + start = view.start, + end = view.end, + length = end - start, + dropCount = this.dropCount, + takeCount = nativeMin(length, this.takeCount - dropCount), + index = isRight ? end : start - 1, + iteratees = this.iteratees, + iterLength = iteratees ? iteratees.length : 0, + resIndex = 0, + result = []; + + outer: + while (length-- && resIndex < takeCount) { + index += dir; + + var iterIndex = -1, + value = array[index]; + + while (++iterIndex < iterLength) { + var data = iteratees[iterIndex], + iteratee = data.iteratee, + computed = iteratee(value, index, array), + type = data.type; + + if (type == LAZY_MAP_FLAG) { + value = computed; + } else if (!computed) { + if (type == LAZY_FILTER_FLAG) { + continue outer; + } else { + break outer; + } + } + } + if (dropCount) { + dropCount--; + } else { + result[resIndex++] = value; + } + } + return result; + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates a cache object to store key/value pairs. + * + * @private + * @static + * @name Cache + * @memberOf _.memoize + */ + function MapCache() { + this.__data__ = {}; + } + + /** + * Removes `key` and its value from the cache. + * + * @private + * @name delete + * @memberOf _.memoize.Cache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed successfully, else `false`. + */ + function mapDelete(key) { + return this.has(key) && delete this.__data__[key]; + } + + /** + * Gets the cached value for `key`. + * + * @private + * @name get + * @memberOf _.memoize.Cache + * @param {string} key The key of the value to get. + * @returns {*} Returns the cached value. + */ + function mapGet(key) { + return key == '__proto__' ? undefined : this.__data__[key]; + } + + /** + * Checks if a cached value for `key` exists. + * + * @private + * @name has + * @memberOf _.memoize.Cache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function mapHas(key) { + return key != '__proto__' && hasOwnProperty.call(this.__data__, key); + } + + /** + * Adds `value` to `key` of the cache. + * + * @private + * @name set + * @memberOf _.memoize.Cache + * @param {string} key The key of the value to cache. + * @param {*} value The value to cache. + * @returns {Object} Returns the cache object. + */ + function mapSet(key, value) { + if (key != '__proto__') { + this.__data__[key] = value; + } + return this; + } + + /*------------------------------------------------------------------------*/ + + /** + * + * Creates a cache object to store unique values. + * + * @private + * @param {Array} [values] The values to cache. + */ + function SetCache(values) { + var length = values ? values.length : 0; + + this.data = { 'hash': nativeCreate(null), 'set': new Set }; + while (length--) { + this.push(values[length]); + } + } + + /** + * Checks if `value` is in `cache` mimicking the return signature of + * `_.indexOf` by returning `0` if the value is found, else `-1`. + * + * @private + * @param {Object} cache The cache to search. + * @param {*} value The value to search for. + * @returns {number} Returns `0` if `value` is found, else `-1`. + */ + function cacheIndexOf(cache, value) { + var data = cache.data, + result = (typeof value == 'string' || isObject(value)) ? data.set.has(value) : data.hash[value]; + + return result ? 0 : -1; + } + + /** + * Adds `value` to the cache. + * + * @private + * @name push + * @memberOf SetCache + * @param {*} value The value to cache. + */ + function cachePush(value) { + var data = this.data; + if (typeof value == 'string' || isObject(value)) { + data.set.add(value); + } else { + data.hash[value] = true; + } + } + + /*------------------------------------------------------------------------*/ + + /** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ + function arrayCopy(source, array) { + var index = -1, + length = source.length; + + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; + } + + /** + * A specialized version of `_.forEach` for arrays without support for callback + * shorthands or `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEach(array, iteratee) { + var index = -1, + length = array.length; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; + } + + /** + * A specialized version of `_.forEachRight` for arrays without support for + * callback shorthands or `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEachRight(array, iteratee) { + var length = array.length; + + while (length--) { + if (iteratee(array[length], length, array) === false) { + break; + } + } + return array; + } + + /** + * A specialized version of `_.every` for arrays without support for callback + * shorthands or `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false`. + */ + function arrayEvery(array, predicate) { + var index = -1, + length = array.length; + + while (++index < length) { + if (!predicate(array[index], index, array)) { + return false; + } + } + return true; + } + + /** + * A specialized version of `_.filter` for arrays without support for callback + * shorthands or `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ + function arrayFilter(array, predicate) { + var index = -1, + length = array.length, + resIndex = -1, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[++resIndex] = value; + } + } + return result; + } + + /** + * A specialized version of `_.map` for arrays without support for callback + * shorthands or `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function arrayMap(array, iteratee) { + var index = -1, + length = array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; + } + + /** + * A specialized version of `_.max` for arrays without support for iteratees. + * + * @private + * @param {Array} array The array to iterate over. + * @returns {*} Returns the maximum value. + */ + function arrayMax(array) { + var index = -1, + length = array.length, + result = NEGATIVE_INFINITY; + + while (++index < length) { + var value = array[index]; + if (value > result) { + result = value; + } + } + return result; + } + + /** + * A specialized version of `_.min` for arrays without support for iteratees. + * + * @private + * @param {Array} array The array to iterate over. + * @returns {*} Returns the minimum value. + */ + function arrayMin(array) { + var index = -1, + length = array.length, + result = POSITIVE_INFINITY; + + while (++index < length) { + var value = array[index]; + if (value < result) { + result = value; + } + } + return result; + } + + /** + * A specialized version of `_.reduce` for arrays without support for callback + * shorthands or `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initFromArray] Specify using the first element of `array` + * as the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduce(array, iteratee, accumulator, initFromArray) { + var index = -1, + length = array.length; + + if (initFromArray && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; + } + + /** + * A specialized version of `_.reduceRight` for arrays without support for + * callback shorthands or `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initFromArray] Specify using the last element of `array` + * as the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduceRight(array, iteratee, accumulator, initFromArray) { + var length = array.length; + if (initFromArray && length) { + accumulator = array[--length]; + } + while (length--) { + accumulator = iteratee(accumulator, array[length], length, array); + } + return accumulator; + } + + /** + * A specialized version of `_.some` for arrays without support for callback + * shorthands or `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ + function arraySome(array, predicate) { + var index = -1, + length = array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; + } + + /** + * Used by `_.defaults` to customize its `_.assign` use. + * + * @private + * @param {*} objectValue The destination object property value. + * @param {*} sourceValue The source object property value. + * @returns {*} Returns the value to assign to the destination object. + */ + function assignDefaults(objectValue, sourceValue) { + return typeof objectValue == 'undefined' ? sourceValue : objectValue; + } + + /** + * Used by `_.template` to customize its `_.assign` use. + * + * **Note:** This method is like `assignDefaults` except that it ignores + * inherited property values when checking if a property is `undefined`. + * + * @private + * @param {*} objectValue The destination object property value. + * @param {*} sourceValue The source object property value. + * @param {string} key The key associated with the object and source values. + * @param {Object} object The destination object. + * @returns {*} Returns the value to assign to the destination object. + */ + function assignOwnDefaults(objectValue, sourceValue, key, object) { + return (typeof objectValue == 'undefined' || !hasOwnProperty.call(object, key)) + ? sourceValue + : objectValue; + } + + /** + * The base implementation of `_.assign` without support for argument juggling, + * multiple sources, and `this` binding `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {Function} [customizer] The function to customize assigning values. + * @returns {Object} Returns the destination object. + */ + function baseAssign(object, source, customizer) { + var props = keys(source); + if (!customizer) { + return baseCopy(source, object, props); + } + var index = -1, + length = props.length + + while (++index < length) { + var key = props[index], + value = object[key], + result = customizer(value, source[key], key, object, source); + + if ((result === result ? result !== value : value === value) || + (typeof value == 'undefined' && !(key in object))) { + object[key] = result; + } + } + return object; + } + + /** + * The base implementation of `_.at` without support for strings and individual + * key arguments. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {number[]|string[]} [props] The property names or indexes of elements to pick. + * @returns {Array} Returns the new array of picked elements. + */ + function baseAt(collection, props) { + var index = -1, + length = collection.length, + isArr = isLength(length), + propsLength = props.length, + result = Array(propsLength); + + while(++index < propsLength) { + var key = props[index]; + if (isArr) { + key = parseFloat(key); + result[index] = isIndex(key, length) ? collection[key] : undefined; + } else { + result[index] = collection[key]; + } + } + return result; + } + + /** + * Copies the properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Object} [object={}] The object to copy properties to. + * @param {Array} props The property names to copy. + * @returns {Object} Returns `object`. + */ + function baseCopy(source, object, props) { + if (!props) { + props = object; + object = {}; + } + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + object[key] = source[key]; + } + return object; + } + + /** + * The base implementation of `_.bindAll` without support for individual + * method name arguments. + * + * @private + * @param {Object} object The object to bind and assign the bound methods to. + * @param {string[]} methodNames The object method names to bind. + * @returns {Object} Returns `object`. + */ + function baseBindAll(object, methodNames) { + var index = -1, + length = methodNames.length; + + while (++index < length) { + var key = methodNames[index]; + object[key] = createWrapper(object[key], BIND_FLAG, object); + } + return object; + } + + /** + * The base implementation of `_.callback` which supports specifying the + * number of arguments to provide to `func`. + * + * @private + * @param {*} [func=_.identity] The value to convert to a callback. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {number} [argCount] The number of arguments to provide to `func`. + * @returns {Function} Returns the callback. + */ + function baseCallback(func, thisArg, argCount) { + var type = typeof func; + if (type == 'function') { + return (typeof thisArg != 'undefined' && isBindable(func)) + ? bindCallback(func, thisArg, argCount) + : func; + } + if (func == null) { + return identity; + } + // Handle "_.property" and "_.matches" style callback shorthands. + return type == 'object' + ? baseMatches(func) + : baseProperty(func + ''); + } + + /** + * The base implementation of `_.clone` without support for argument juggling + * and `this` binding `customizer` functions. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @param {Function} [customizer] The function to customize cloning values. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The object `value` belongs to. + * @param {Array} [stackA=[]] Tracks traversed source objects. + * @param {Array} [stackB=[]] Associates clones with source counterparts. + * @returns {*} Returns the cloned value. + */ + function baseClone(value, isDeep, customizer, key, object, stackA, stackB) { + var result; + if (customizer) { + result = object ? customizer(value, key, object) : customizer(value); + } + if (typeof result != 'undefined') { + return result; + } + if (!isObject(value)) { + return value; + } + var isArr = isArray(value); + if (isArr) { + result = initCloneArray(value); + if (!isDeep) { + return arrayCopy(value, result); + } + } else { + var tag = objToString.call(value), + isFunc = tag == funcTag; + + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + result = initCloneObject(isFunc ? {} : value); + if (!isDeep) { + return baseCopy(value, result, keys(value)); + } + } else { + return cloneableTags[tag] + ? initCloneByTag(value, tag, isDeep) + : (object ? value : {}); + } + } + // Check for circular references and return corresponding clone. + stackA || (stackA = []); + stackB || (stackB = []); + + var length = stackA.length; + while (length--) { + if (stackA[length] == value) { + return stackB[length]; + } + } + // Add the source value to the stack of traversed objects and associate it with its clone. + stackA.push(value); + stackB.push(result); + + // Recursively populate clone (susceptible to call stack limits). + (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) { + result[key] = baseClone(subValue, isDeep, customizer, key, value, stackA, stackB); + }); + return result; + } + + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ + var baseCreate = (function() { + function Object() {} + return function(prototype) { + if (isObject(prototype)) { + Object.prototype = prototype; + var result = new Object; + Object.prototype = null; + } + return result || context.Object(); + }; + }()); + + /** + * The base implementation of `_.delay` and `_.defer` which accepts an index + * of where to slice the arguments to provide to `func`. + * + * @private + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {Object} args The `arguments` object to slice and provide to `func`. + * @returns {number} Returns the timer id. + */ + function baseDelay(func, wait, args, fromIndex) { + if (!isFunction(func)) { + throw new TypeError(FUNC_ERROR_TEXT); + } + return setTimeout(function() { func.apply(undefined, baseSlice(args, fromIndex)); }, wait); + } + + /** + * The base implementation of `_.difference` which accepts a single array + * of values to exclude. + * + * @private + * @param {Array} array The array to inspect. + * @param {Array} values The values to exclude. + * @returns {Array} Returns the new array of filtered values. + */ + function baseDifference(array, values) { + var length = array ? array.length : 0, + result = []; + + if (!length) { + return result; + } + var index = -1, + indexOf = getIndexOf(), + isCommon = indexOf == baseIndexOf, + cache = isCommon && values.length >= 200 && createCache(values), + valuesLength = values.length; + + if (cache) { + indexOf = cacheIndexOf; + isCommon = false; + values = cache; + } + outer: + while (++index < length) { + var value = array[index]; + + if (isCommon && value === value) { + var valuesIndex = valuesLength; + while (valuesIndex--) { + if (values[valuesIndex] === value) { + continue outer; + } + } + result.push(value); + } + else if (indexOf(values, value) < 0) { + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.forEach` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object|string} Returns `collection`. + */ + function baseEach(collection, iteratee) { + var length = collection ? collection.length : 0; + if (!isLength(length)) { + return baseForOwn(collection, iteratee); + } + var index = -1, + iterable = toObject(collection); + + while (++index < length) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + } + + /** + * The base implementation of `_.forEachRight` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object|string} Returns `collection`. + */ + function baseEachRight(collection, iteratee) { + var length = collection ? collection.length : 0; + if (!isLength(length)) { + return baseForOwnRight(collection, iteratee); + } + var iterable = toObject(collection); + while (length--) { + if (iteratee(iterable[length], length, iterable) === false) { + break; + } + } + return collection; + } + + /** + * The base implementation of `_.every` without support for callback + * shorthands or `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false` + */ + function baseEvery(collection, predicate) { + var result = true; + baseEach(collection, function(value, index, collection) { + result = !!predicate(value, index, collection); + return result; + }); + return result; + } + + /** + * The base implementation of `_.filter` without support for callback + * shorthands or `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ + function baseFilter(collection, predicate) { + var result = []; + baseEach(collection, function(value, index, collection) { + if (predicate(value, index, collection)) { + result.push(value); + } + }); + return result; + } + + /** + * The base implementation of `_.find`, `_.findLast`, `_.findKey`, and `_.findLastKey`, + * without support for callback shorthands and `this` binding, which iterates + * over `collection` using the provided `eachFunc`. + * + * @private + * @param {Array|Object|string} collection The collection to search. + * @param {Function} predicate The function invoked per iteration. + * @param {Function} eachFunc The function to iterate over `collection`. + * @param {boolean} [retKey] Specify returning the key of the found element + * instead of the element itself. + * @returns {*} Returns the found element or its key, else `undefined`. + */ + function baseFind(collection, predicate, eachFunc, retKey) { + var result; + eachFunc(collection, function(value, key, collection) { + if (predicate(value, key, collection)) { + result = retKey ? key : value; + return false; + } + }); + return result; + } + + /** + * The base implementation of `_.flatten` with added support for restricting + * flattening and specifying the start index. + * + * @private + * @param {Array} array The array to flatten. + * @param {boolean} [isDeep] Specify a deep flatten. + * @param {boolean} [isStrict] Restrict flattening to arrays and `arguments` objects. + * @param {number} [fromIndex=0] The index to start from. + * @returns {Array} Returns the new flattened array. + */ + function baseFlatten(array, isDeep, isStrict, fromIndex) { + var index = (fromIndex || 0) - 1, + length = array.length, + resIndex = -1, + result = []; + + while (++index < length) { + var value = array[index]; + + if (isObjectLike(value) && isLength(value.length) && (isArray(value) || isArguments(value))) { + if (isDeep) { + // Recursively flatten arrays (susceptible to call stack limits). + value = baseFlatten(value, isDeep, isStrict); + } + var valIndex = -1, + valLength = value.length; + + result.length += valLength; + while (++valIndex < valLength) { + result[++resIndex] = value[valIndex]; + } + } else if (!isStrict) { + result[++resIndex] = value; + } + } + return result; + } + + /** + * The base implementation of `baseForIn` and `baseForOwn` which iterates + * over `object` properties returned by `keysFunc` invoking `iteratee` for + * each property. Iterator functions may exit iteration early by explicitly + * returning `false`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ + function baseFor(object, iteratee, keysFunc) { + var index = -1, + iterable = toObject(object), + props = keysFunc(object), + length = props.length; + + while (++index < length) { + var key = props[index]; + if (iteratee(iterable[key], key, iterable) === false) { + break; + } + } + return object; + } + + /** + * This function is like `baseFor` except that it iterates over properties + * in the opposite order. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ + function baseForRight(object, iteratee, keysFunc) { + var iterable = toObject(object), + props = keysFunc(object), + length = props.length; + + while (length--) { + var key = props[length]; + if (iteratee(iterable[key], key, iterable) === false) { + break; + } + } + return object; + } + + /** + * The base implementation of `_.forIn` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForIn(object, iteratee) { + return baseFor(object, iteratee, keysIn); + } + + /** + * The base implementation of `_.forOwn` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForOwn(object, iteratee) { + return baseFor(object, iteratee, keys); + } + + /** + * The base implementation of `_.forOwnRight` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForOwnRight(object, iteratee) { + return baseForRight(object, iteratee, keys); + } + + /** + * The base implementation of `_.functions` which creates an array of + * `object` function property names filtered from those provided. + * + * @private + * @param {Object} object The object to inspect. + * @param {Array} props The property names to filter. + * @returns {Array} Returns the new array of filtered property names. + */ + function baseFunctions(object, props) { + var index = -1, + length = props.length, + resIndex = -1, + result = []; + + while (++index < length) { + var key = props[index]; + if (isFunction(object[key])) { + result[++resIndex] = key; + } + } + return result; + } + + /** + * The base implementation of `_.invoke` which requires additional arguments + * to be provided as an array of arguments rather than individually. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|string} methodName The name of the method to invoke or + * the function invoked per iteration. + * @param {Array} [args] The arguments to invoke the method with. + * @returns {Array} Returns the array of results. + */ + function baseInvoke(collection, methodName, args) { + var index = -1, + isFunc = typeof methodName == 'function', + length = collection ? collection.length : 0, + result = isLength(length) ? Array(length) : []; + + baseEach(collection, function(value) { + var func = isFunc ? methodName : (value != null && value[methodName]); + result[++index] = func ? func.apply(value, args) : undefined; + }); + return result; + } + + /** + * The base implementation of `_.isEqual` without support for `this` binding + * `customizer` functions. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {Function} [customizer] The function to customize comparing values. + * @param {boolean} [isWhere] Specify performing partial comparisons. + * @param {Array} [stackA] Tracks traversed `value` objects. + * @param {Array} [stackB] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ + function baseIsEqual(value, other, customizer, isWhere, stackA, stackB) { + // Exit early for identical values. + if (value === other) { + // Treat `+0` vs. `-0` as not equal. + return value !== 0 || (1 / value == 1 / other); + } + var valType = typeof value, + othType = typeof other; + + // Exit early for unlike primitive values. + if ((valType != 'function' && valType != 'object' && othType != 'function' && othType != 'object') || + value == null || other == null) { + // Return `false` unless both values are `NaN`. + return value !== value && other !== other; + } + return baseIsEqualDeep(value, other, baseIsEqual, customizer, isWhere, stackA, stackB); + } + + /** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparing objects. + * @param {boolean} [isWhere] Specify performing partial comparisons. + * @param {Array} [stackA=[]] Tracks traversed `value` objects. + * @param {Array} [stackB=[]] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function baseIsEqualDeep(object, other, equalFunc, customizer, isWhere, stackA, stackB) { + var objIsArr = isArray(object), + othIsArr = isArray(other), + objTag = arrayTag, + othTag = arrayTag; + + if (!objIsArr) { + objTag = objToString.call(object); + if (objTag == argsTag) { + objTag = objectTag; + } else if (objTag != objectTag) { + objIsArr = isTypedArray(object); + } + } + if (!othIsArr) { + othTag = objToString.call(other); + if (othTag == argsTag) { + othTag = objectTag; + } else if (othTag != objectTag) { + othIsArr = isTypedArray(other); + } + } + var objIsObj = objTag == objectTag, + othIsObj = othTag == objectTag, + isSameTag = objTag == othTag; + + if (isSameTag && !(objIsArr || objIsObj)) { + return equalByTag(object, other, objTag); + } + var valWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), + othWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); + + if (valWrapped || othWrapped) { + return equalFunc(valWrapped ? object.value() : object, othWrapped ? other.value() : other, customizer, isWhere, stackA, stackB); + } + if (!isSameTag) { + return false; + } + // Assume cyclic values are equal. + // For more information on detecting circular references see https://es5.github.io/#JO. + stackA || (stackA = []); + stackB || (stackB = []); + + var length = stackA.length; + while (length--) { + if (stackA[length] == object) { + return stackB[length] == other; + } + } + // Add `object` and `other` to the stack of traversed objects. + stackA.push(object); + stackB.push(other); + + var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isWhere, stackA, stackB); + + stackA.pop(); + stackB.pop(); + + return result; + } + + /** + * The base implementation of `_.isMatch` without support for callback + * shorthands or `this` binding. + * + * @private + * @param {Object} source The object to inspect. + * @param {Array} props The source property names to match. + * @param {Array} values The source values to match. + * @param {Array} strictCompareFlags Strict comparison flags for source values. + * @param {Function} [customizer] The function to customize comparing objects. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ + function baseIsMatch(object, props, values, strictCompareFlags, customizer) { + var length = props.length; + if (object == null) { + return !length; + } + var index = -1, + noCustomizer = !customizer; + + while (++index < length) { + if ((noCustomizer && strictCompareFlags[index]) + ? values[index] !== object[props[index]] + : !hasOwnProperty.call(object, props[index]) + ) { + return false; + } + } + index = -1; + while (++index < length) { + var key = props[index]; + if (noCustomizer && strictCompareFlags[index]) { + var result = hasOwnProperty.call(object, key); + } else { + var objValue = object[key], + srcValue = values[index]; + + result = customizer ? customizer(objValue, srcValue, key) : undefined; + if (typeof result == 'undefined') { + result = baseIsEqual(srcValue, objValue, customizer, true); + } + } + if (!result) { + return false; + } + } + return true; + } + + /** + * The base implementation of `_.map` without support for callback shorthands + * or `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function baseMap(collection, iteratee) { + var result = []; + baseEach(collection, function(value, key, collection) { + result.push(iteratee(value, key, collection)); + }); + return result; + } + + /** + * The base implementation of `_.matches` which supports specifying whether + * `source` should be cloned. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new function. + */ + function baseMatches(source) { + var props = keys(source), + length = props.length; + + if (length == 1) { + var key = props[0], + value = source[key]; + + if (isStrictComparable(value)) { + return function(object) { + return object != null && value === object[key] && hasOwnProperty.call(object, key); + }; + } + } + var values = Array(length), + strictCompareFlags = Array(length); + + while (length--) { + value = source[props[length]]; + values[length] = value; + strictCompareFlags[length] = isStrictComparable(value); + } + return function(object) { + return baseIsMatch(object, props, values, strictCompareFlags); + }; + } + + /** + * The base implementation of `_.merge` without support for argument juggling, + * multiple sources, and `this` binding `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {Function} [customizer] The function to customize merging properties. + * @param {Array} [stackA=[]] Tracks traversed source objects. + * @param {Array} [stackB=[]] Associates values with source counterparts. + * @returns {Object} Returns the destination object. + */ + function baseMerge(object, source, customizer, stackA, stackB) { + var isSrcArr = isLength(source.length) && (isArray(source) || isTypedArray(source)); + + (isSrcArr ? arrayEach : baseForOwn)(source, function(srcValue, key, source) { + if (isObjectLike(srcValue)) { + stackA || (stackA = []); + stackB || (stackB = []); + return baseMergeDeep(object, source, key, baseMerge, customizer, stackA, stackB); + } + var value = object[key], + result = customizer ? customizer(value, srcValue, key, object, source) : undefined, + isCommon = typeof result == 'undefined'; + + if (isCommon) { + result = srcValue; + } + if ((isSrcArr || typeof result != 'undefined') && + (isCommon || (result === result ? result !== value : value === value))) { + object[key] = result; + } + }); + return object; + } + + /** + * A specialized version of `baseMerge` for arrays and objects which performs + * deep merges and tracks traversed objects enabling objects with circular + * references to be merged. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {string} key The key of the value to merge. + * @param {Function} mergeFunc The function to merge values. + * @param {Function} [customizer] The function to customize merging properties. + * @param {Array} [stackA=[]] Tracks traversed source objects. + * @param {Array} [stackB=[]] Associates values with source counterparts. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function baseMergeDeep(object, source, key, mergeFunc, customizer, stackA, stackB) { + var length = stackA.length, + srcValue = source[key]; + + while (length--) { + if (stackA[length] == srcValue) { + object[key] = stackB[length]; + return; + } + } + var value = object[key], + result = customizer ? customizer(value, srcValue, key, object, source) : undefined, + isCommon = typeof result == 'undefined'; + + if (isCommon) { + result = srcValue; + if (isLength(srcValue.length) && (isArray(srcValue) || isTypedArray(srcValue))) { + result = isArray(value) + ? value + : (value ? arrayCopy(value) : []); + } + else if (isPlainObject(srcValue) || isArguments(srcValue)) { + result = isArguments(value) + ? toPlainObject(value) + : (isPlainObject(value) ? value : {}); + } + else { + isCommon = false; + } + } + // Add the source value to the stack of traversed objects and associate + // it with its merged value. + stackA.push(srcValue); + stackB.push(result); + + if (isCommon) { + // Recursively merge objects and arrays (susceptible to call stack limits). + object[key] = mergeFunc(result, srcValue, customizer, stackA, stackB); + } else if (result === result ? result !== value : value === value) { + object[key] = result; + } + } + + /** + * The base implementation of `_.property` which does not coerce `key` to a string. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new function. + */ + function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; + } + + /** + * The base implementation of `_.pullAt` without support for individual + * index arguments. + * + * @private + * @param {Array} array The array to modify. + * @param {number[]} indexes The indexes of elements to remove. + * @returns {Array} Returns the new array of removed elements. + */ + function basePullAt(array, indexes) { + var length = indexes.length, + result = baseAt(array, indexes); + + indexes.sort(baseCompareAscending); + while (length--) { + var index = parseFloat(indexes[length]); + if (index != previous && isIndex(index)) { + var previous = index; + splice.call(array, index, 1); + } + } + return result; + } + + /** + * The base implementation of `_.random` without support for argument juggling + * and returning floating-point numbers. + * + * @private + * @param {number} min The minimum possible value. + * @param {number} max The maximum possible value. + * @returns {number} Returns the random number. + */ + function baseRandom(min, max) { + return min + floor(nativeRandom() * (max - min + 1)); + } + + /** + * The base implementation of `_.reduce` and `_.reduceRight` without support + * for callback shorthands or `this` binding, which iterates over `collection` + * using the provided `eachFunc`. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} accumulator The initial value. + * @param {boolean} initFromCollection Specify using the first or last element + * of `collection` as the initial value. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the accumulated value. + */ + function baseReduce(collection, iteratee, accumulator, initFromCollection, eachFunc) { + eachFunc(collection, function(value, index, collection) { + accumulator = initFromCollection + ? (initFromCollection = false, value) + : iteratee(accumulator, value, index, collection) + }); + return accumulator; + } + + /** + * The base implementation of `setData` without support for hot loop detection. + * + * @private + * @param {Function} func The function to associate metadata with. + * @param {*} data The metadata. + * @returns {Function} Returns `func`. + */ + var baseSetData = !metaMap ? identity : function(func, data) { + metaMap.set(func, data); + return func; + }; + + /** + * The base implementation of `_.slice` without an iteratee call guard. + * + * @private + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ + function baseSlice(array, start, end) { + var index = -1, + length = array.length; + + start = start == null ? 0 : (+start || 0); + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = (typeof end == 'undefined' || end > length) ? length : (+end || 0); + if (end < 0) { + end += length; + } + length = start > end ? 0 : (end - start) >>> 0; + start >>>= 0; + + var result = Array(length); + while (++index < length) { + result[index] = array[index + start]; + } + return result; + } + + /** + * The base implementation of `_.some` without support for callback shorthands + * or `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ + function baseSome(collection, predicate) { + var result; + + baseEach(collection, function(value, index, collection) { + result = predicate(value, index, collection); + return !result; + }); + return !!result; + } + + /** + * The base implementation of `_.uniq` without support for callback shorthands + * and `this` binding. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The function invoked per iteration. + * @returns {Array} Returns the new duplicate-value-free array. + */ + function baseUniq(array, iteratee) { + var index = -1, + indexOf = getIndexOf(), + length = array.length, + isCommon = indexOf == baseIndexOf, + isLarge = isCommon && length >= 200, + seen = isLarge && createCache(), + result = []; + + if (seen) { + indexOf = cacheIndexOf; + isCommon = false; + } else { + isLarge = false; + seen = iteratee ? [] : result; + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value, index, array) : value; + + if (isCommon && value === value) { + var seenIndex = seen.length; + while (seenIndex--) { + if (seen[seenIndex] === computed) { + continue outer; + } + } + if (iteratee) { + seen.push(computed); + } + result.push(value); + } + else if (indexOf(seen, computed) < 0) { + if (iteratee || isLarge) { + seen.push(computed); + } + result.push(value); + } + } + return result; + } + + /** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * returned by `keysFunc`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ + function baseValues(object, props) { + var index = -1, + length = props.length, + result = Array(length); + + while (++index < length) { + result[index] = object[props[index]]; + } + return result; + } + + /** + * The base implementation of `wrapperValue` which returns the result of + * performing a sequence of actions on the unwrapped `value`, where each + * successive action is supplied the return value of the previous. + * + * @private + * @param {*} value The unwrapped value. + * @param {Array} actions Actions to peform to resolve the unwrapped value. + * @returns {*} Returns the resolved unwrapped value. + */ + function baseWrapperValue(value, actions) { + var result = value; + if (result instanceof LazyWrapper) { + result = result.value(); + } + var index = -1, + length = actions.length; + + while (++index < length) { + var args = [result], + action = actions[index]; + + push.apply(args, action.args); + result = action.func.apply(action.thisArg, args); + } + return result; + } + + /** + * Performs a binary search of `array` to determine the index at which `value` + * should be inserted into `array` in order to maintain its sort order. + * + * @private + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {boolean} [retHighest] Specify returning the highest, instead + * of the lowest, index at which a value should be inserted into `array`. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + */ + function binaryIndex(array, value, retHighest) { + var low = 0, + high = array ? array.length : low; + + if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) { + while (low < high) { + var mid = (low + high) >>> 1, + computed = array[mid]; + + if (retHighest ? (computed <= value) : (computed < value)) { + low = mid + 1; + } else { + high = mid; + } + } + return high; + } + return binaryIndexBy(array, value, identity, retHighest); + } + + /** + * This function is like `binaryIndex` except that it invokes `iteratee` for + * `value` and each element of `array` to compute their sort ranking. The + * iteratee is invoked with one argument; (value). + * + * @private + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function} iteratee The function invoked per iteration. + * @param {boolean} [retHighest] Specify returning the highest, instead + * of the lowest, index at which a value should be inserted into `array`. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + */ + function binaryIndexBy(array, value, iteratee, retHighest) { + value = iteratee(value); + + var low = 0, + high = array ? array.length : 0, + valIsNaN = value !== value, + valIsUndef = typeof value == 'undefined'; + + while (low < high) { + var mid = floor((low + high) / 2), + computed = iteratee(array[mid]), + isReflexive = computed === computed; + + if (valIsNaN) { + var setLow = isReflexive || retHighest; + } else if (valIsUndef) { + setLow = isReflexive && (retHighest || typeof computed != 'undefined'); + } else { + setLow = retHighest ? (computed <= value) : (computed < value); + } + if (setLow) { + low = mid + 1; + } else { + high = mid; + } + } + return nativeMin(high, MAX_ARRAY_INDEX); + } + + /** + * A specialized version of `baseCallback` which only supports `this` binding + * and specifying the number of arguments to provide to `func`. + * + * @private + * @param {Function} func The function to bind. + * @param {*} thisArg The `this` binding of `func`. + * @param {number} [argCount] The number of arguments to provide to `func`. + * @returns {Function} Returns the callback. + */ + function bindCallback(func, thisArg, argCount) { + if (typeof func != 'function') { + return identity; + } + if (typeof thisArg == 'undefined') { + return func; + } + switch (argCount) { + case 1: return function(value) { + return func.call(thisArg, value); + }; + case 3: return function(value, index, collection) { + return func.call(thisArg, value, index, collection); + }; + case 4: return function(accumulator, value, index, collection) { + return func.call(thisArg, accumulator, value, index, collection); + }; + case 5: return function(value, other, key, object, source) { + return func.call(thisArg, value, other, key, object, source); + }; + } + return function() { + return func.apply(thisArg, arguments); + }; + } + + /** + * Creates a clone of the given array buffer. + * + * @private + * @param {ArrayBuffer} buffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ + function bufferClone(buffer) { + return bufferSlice.call(buffer, 0); + } + if (!bufferSlice) { + // PhantomJS has `ArrayBuffer` and `Uint8Array` but not `Float64Array`. + bufferClone = !(ArrayBuffer && Uint8Array) ? constant(null) : function(buffer) { + var byteLength = buffer.byteLength, + floatLength = Float64Array ? floor(byteLength / FLOAT64_BYTES_PER_ELEMENT) : 0, + offset = floatLength * FLOAT64_BYTES_PER_ELEMENT, + result = new ArrayBuffer(byteLength); + + if (floatLength) { + var view = new Float64Array(result, 0, floatLength); + view.set(new Float64Array(buffer, 0, floatLength)); + } + if (byteLength != offset) { + view = new Uint8Array(result, offset); + view.set(new Uint8Array(buffer, offset)); + } + return result; + }; + } + + /** + * Creates an array that is the composition of partially applied arguments, + * placeholders, and provided arguments into a single array of arguments. + * + * @private + * @param {Array|Object} args The provided arguments. + * @param {Array} partials The arguments to prepend to those provided. + * @param {Array} holders The `partials` placeholder indexes. + * @returns {Array} Returns the new array of composed arguments. + */ + function composeArgs(args, partials, holders) { + var holdersLength = holders.length, + argsIndex = -1, + argsLength = nativeMax(args.length - holdersLength, 0), + leftIndex = -1, + leftLength = partials.length, + result = Array(argsLength + leftLength); + + while (++leftIndex < leftLength) { + result[leftIndex] = partials[leftIndex]; + } + while (++argsIndex < holdersLength) { + result[holders[argsIndex]] = args[argsIndex]; + } + while (argsLength--) { + result[leftIndex++] = args[argsIndex++]; + } + return result; + } + + /** + * This function is like `composeArgs` except that the arguments composition + * is tailored for `_.partialRight`. + * + * @private + * @param {Array|Object} args The provided arguments. + * @param {Array} partials The arguments to append to those provided. + * @param {Array} holders The `partials` placeholder indexes. + * @returns {Array} Returns the new array of composed arguments. + */ + function composeArgsRight(args, partials, holders) { + var holdersIndex = -1, + holdersLength = holders.length, + argsIndex = -1, + argsLength = nativeMax(args.length - holdersLength, 0), + rightIndex = -1, + rightLength = partials.length, + result = Array(argsLength + rightLength); + + while (++argsIndex < argsLength) { + result[argsIndex] = args[argsIndex]; + } + var pad = argsIndex; + while (++rightIndex < rightLength) { + result[pad + rightIndex] = partials[rightIndex]; + } + while (++holdersIndex < holdersLength) { + result[pad + holders[holdersIndex]] = args[argsIndex++]; + } + return result; + } + + /** + * Creates a function that aggregates a collection, creating an accumulator + * object composed from the results of running each element in the collection + * through an iteratee. The `setter` sets the keys and values of the accumulator + * object. If `initializer` is provided initializes the accumulator object. + * + * @private + * @param {Function} setter The function to set keys and values of the accumulator object. + * @param {Function} [initializer] The function to initialize the accumulator object. + * @returns {Function} Returns the new aggregator function. + */ + function createAggregator(setter, initializer) { + return function(collection, iteratee, thisArg) { + var result = initializer ? initializer() : {}; + iteratee = getCallback(iteratee, thisArg, 3); + + if (isArray(collection)) { + var index = -1, + length = collection.length; + + while (++index < length) { + var value = collection[index]; + setter(result, value, iteratee(value, index, collection), collection); + } + } else { + baseEach(collection, function(value, key, collection) { + setter(result, value, iteratee(value, key, collection), collection); + }); + } + return result; + }; + } + + /** + * Creates a function that assigns properties of source object(s) to a given + * destination object. + * + * @private + * @param {Function} assigner The function to assign values. + * @returns {Function} Returns the new assigner function. + */ + function createAssigner(assigner) { + return function() { + var length = arguments.length, + object = arguments[0]; + + if (length < 2 || object == null) { + return object; + } + if (length > 3 && isIterateeCall(arguments[1], arguments[2], arguments[3])) { + length = 2; + } + // Juggle arguments. + if (length > 3 && typeof arguments[length - 2] == 'function') { + var customizer = bindCallback(arguments[--length - 1], arguments[length--], 5); + } else if (length > 2 && typeof arguments[length - 1] == 'function') { + customizer = arguments[--length]; + } + var index = 0; + while (++index < length) { + var source = arguments[index]; + if (source) { + assigner(object, source, customizer); + } + } + return object; + }; + } + + /** + * Creates a function that wraps `func` and invokes it with the `this` + * binding of `thisArg`. + * + * @private + * @param {Function} func The function to bind. + * @param {*} [thisArg] The `this` binding of `func`. + * @returns {Function} Returns the new bound function. + */ + function createBindWrapper(func, thisArg) { + var Ctor = createCtorWrapper(func); + + function wrapper() { + return (this instanceof wrapper ? Ctor : func).apply(thisArg, arguments); + } + return wrapper; + } + + /** + * Creates a `Set` cache object to optimize linear searches of large arrays. + * + * @private + * @param {Array} [values] The values to cache. + * @returns {null|Object} Returns the new cache object if `Set` is supported, else `null`. + */ + var createCache = !(nativeCreate && Set) ? constant(null) : function(values) { + return new SetCache(values); + }; + + /** + * Creates a function that produces compound words out of the words in a + * given string. + * + * @private + * @param {Function} callback The function to combine each word. + * @returns {Function} Returns the new compounder function. + */ + function createCompounder(callback) { + return function(string) { + var index = -1, + array = words(deburr(string)), + length = array.length, + result = ''; + + while (++index < length) { + result = callback(result, array[index], index); + } + return result; + }; + } + + /** + * Creates a function that produces an instance of `Ctor` regardless of + * whether it was invoked as part of a `new` expression or by `call` or `apply`. + * + * @private + * @param {Function} Ctor The constructor to wrap. + * @returns {Function} Returns the new wrapped function. + */ + function createCtorWrapper(Ctor) { + return function() { + var thisBinding = baseCreate(Ctor.prototype), + result = Ctor.apply(thisBinding, arguments); + + // Mimic the constructor's `return` behavior. + // See https://es5.github.io/#x13.2.2 for more details. + return isObject(result) ? result : thisBinding; + }; + } + + /** + * Creates a function that gets the extremum value of a collection. + * + * @private + * @param {Function} arrayFunc The function to get the extremum value from an array. + * @param {boolean} [isMin] Specify returning the minimum, instead of the maximum, + * extremum value. + * @returns {Function} Returns the new extremum function. + */ + function createExtremum(arrayFunc, isMin) { + return function(collection, iteratee, thisArg) { + if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { + iteratee = null; + } + var func = getCallback(), + noIteratee = iteratee == null; + + if (!(func === baseCallback && noIteratee)) { + noIteratee = false; + iteratee = func(iteratee, thisArg, 3); + } + if (noIteratee) { + var isArr = isArray(collection); + if (!isArr && isString(collection)) { + iteratee = charAtCallback; + } else { + return arrayFunc(isArr ? collection : toIterable(collection)); + } + } + return extremumBy(collection, iteratee, isMin); + }; + } + + /** + * Creates a function that wraps `func` and invokes it with optional `this` + * binding of, partial application, and currying. + * + * @private + * @param {Function|string} func The function or method name to reference. + * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to prepend to those provided to the new function. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [partialsRight] The arguments to append to those provided to the new function. + * @param {Array} [holdersRight] The `partialsRight` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) { + var isAry = bitmask & ARY_FLAG, + isBind = bitmask & BIND_FLAG, + isBindKey = bitmask & BIND_KEY_FLAG, + isCurry = bitmask & CURRY_FLAG, + isCurryBound = bitmask & CURRY_BOUND_FLAG, + isCurryRight = bitmask & CURRY_RIGHT_FLAG; + + var Ctor = !isBindKey && createCtorWrapper(func), + key = func; + + function wrapper() { + // Avoid `arguments` object use disqualifying optimizations by + // converting it to an array before providing it to other functions. + var length = arguments.length, + index = length, + args = Array(length); + + while (index--) { + args[index] = arguments[index]; + } + if (partials) { + args = composeArgs(args, partials, holders); + } + if (partialsRight) { + args = composeArgsRight(args, partialsRight, holdersRight); + } + if (isCurry || isCurryRight) { + var placeholder = wrapper.placeholder, + argsHolders = replaceHolders(args, placeholder); + + length -= argsHolders.length; + if (length < arity) { + var newArgPos = argPos ? arrayCopy(argPos) : null, + newArity = nativeMax(arity - length, 0), + newsHolders = isCurry ? argsHolders : null, + newHoldersRight = isCurry ? null : argsHolders, + newPartials = isCurry ? args : null, + newPartialsRight = isCurry ? null : args; + + bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG); + bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG); + + if (!isCurryBound) { + bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG); + } + var result = createHybridWrapper(func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, newArity); + result.placeholder = placeholder; + return result; + } + } + var thisBinding = isBind ? thisArg : this; + if (isBindKey) { + func = thisBinding[key]; + } + if (argPos) { + args = reorder(args, argPos); + } + if (isAry && ary < args.length) { + args.length = ary; + } + return (this instanceof wrapper ? (Ctor || createCtorWrapper(func)) : func).apply(thisBinding, args); + } + return wrapper; + } + + /** + * Creates the pad required for `string` based on the given padding length. + * The `chars` string may be truncated if the number of padding characters + * exceeds the padding length. + * + * @private + * @param {string} string The string to create padding for. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the pad for `string`. + */ + function createPad(string, length, chars) { + var strLength = string.length; + length = +length; + + if (strLength >= length || !nativeIsFinite(length)) { + return ''; + } + var padLength = length - strLength; + chars = chars == null ? ' ' : (chars + ''); + return repeat(chars, ceil(padLength / chars.length)).slice(0, padLength); + } + + /** + * Creates a function that wraps `func` and invokes it with the optional `this` + * binding of `thisArg` and the `partials` prepended to those provided to + * the wrapper. + * + * @private + * @param {Function} func The function to partially apply arguments to. + * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details. + * @param {*} thisArg The `this` binding of `func`. + * @param {Array} partials The arguments to prepend to those provided to the new function. + * @returns {Function} Returns the new bound function. + */ + function createPartialWrapper(func, bitmask, thisArg, partials) { + var isBind = bitmask & BIND_FLAG, + Ctor = createCtorWrapper(func); + + function wrapper() { + // Avoid `arguments` object use disqualifying optimizations by + // converting it to an array before providing it `func`. + var argsIndex = -1, + argsLength = arguments.length, + leftIndex = -1, + leftLength = partials.length, + args = Array(argsLength + leftLength); + + while (++leftIndex < leftLength) { + args[leftIndex] = partials[leftIndex]; + } + while (argsLength--) { + args[leftIndex++] = arguments[++argsIndex]; + } + return (this instanceof wrapper ? Ctor : func).apply(isBind ? thisArg : this, args); + } + return wrapper; + } + + /** + * Creates a function that either curries or invokes `func` with optional + * `this` binding and partially applied arguments. + * + * @private + * @param {Function|string} func The function or method name to reference. + * @param {number} bitmask The bitmask of flags. + * The bitmask may be composed of the following flags: + * 1 - `_.bind` + * 2 - `_.bindKey` + * 4 - `_.curry` or `_.curryRight` of a bound function + * 8 - `_.curry` + * 16 - `_.curryRight` + * 32 - `_.partial` + * 64 - `_.partialRight` + * 128 - `_.rearg` + * 256 - `_.ary` + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to be partially applied. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) { + var isBindKey = bitmask & BIND_KEY_FLAG; + if (!isBindKey && !isFunction(func)) { + throw new TypeError(FUNC_ERROR_TEXT); + } + var length = partials ? partials.length : 0; + if (!length) { + bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG); + partials = holders = null; + } + length -= (holders ? holders.length : 0); + if (bitmask & PARTIAL_RIGHT_FLAG) { + var partialsRight = partials, + holdersRight = holders; + + partials = holders = null; + } + var data = !isBindKey && getData(func), + newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity]; + + if (data && data !== true) { + mergeData(newData, data); + bitmask = newData[1]; + arity = newData[9]; + } + newData[9] = arity == null + ? (isBindKey ? 0 : func.length) + : (nativeMax(arity - length, 0) || 0); + + if (bitmask == BIND_FLAG) { + var result = createBindWrapper(newData[0], newData[2]); + } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !newData[4].length) { + result = createPartialWrapper.apply(null, newData); + } else { + result = createHybridWrapper.apply(null, newData); + } + var setter = data ? baseSetData : setData; + return setter(result, newData); + } + + /** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparing arrays. + * @param {boolean} [isWhere] Specify performing partial comparisons. + * @param {Array} [stackA] Tracks traversed `value` objects. + * @param {Array} [stackB] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ + function equalArrays(array, other, equalFunc, customizer, isWhere, stackA, stackB) { + var index = -1, + arrLength = array.length, + othLength = other.length, + result = true; + + if (arrLength != othLength && !(isWhere && othLength > arrLength)) { + return false; + } + // Deep compare the contents, ignoring non-numeric properties. + while (result && ++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; + + result = undefined; + if (customizer) { + result = isWhere + ? customizer(othValue, arrValue, index) + : customizer(arrValue, othValue, index); + } + if (typeof result == 'undefined') { + // Recursively compare arrays (susceptible to call stack limits). + if (isWhere) { + var othIndex = othLength; + while (othIndex--) { + othValue = other[othIndex]; + result = (arrValue && arrValue === othValue) || equalFunc(arrValue, othValue, customizer, isWhere, stackA, stackB); + if (result) { + break; + } + } + } else { + result = (arrValue && arrValue === othValue) || equalFunc(arrValue, othValue, customizer, isWhere, stackA, stackB); + } + } + } + return !!result; + } + + /** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} value The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalByTag(object, other, tag) { + switch (tag) { + case boolTag: + case dateTag: + // Coerce dates and booleans to numbers, dates to milliseconds and booleans + // to `1` or `0` treating invalid dates coerced to `NaN` as not equal. + return +object == +other; + + case errorTag: + return object.name == other.name && object.message == other.message; + + case numberTag: + // Treat `NaN` vs. `NaN` as equal. + return (object != +object) + ? other != +other + // But, treat `-0` vs. `+0` as not equal. + : (object == 0 ? ((1 / object) == (1 / other)) : object == +other); + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings primitives and string + // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details. + return object == (other + ''); + } + return false; + } + + /** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparing values. + * @param {boolean} [isWhere] Specify performing partial comparisons. + * @param {Array} [stackA] Tracks traversed `value` objects. + * @param {Array} [stackB] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalObjects(object, other, equalFunc, customizer, isWhere, stackA, stackB) { + var objProps = keys(object), + objLength = objProps.length, + othProps = keys(other), + othLength = othProps.length; + + if (objLength != othLength && !isWhere) { + return false; + } + var hasCtor, + index = -1; + + while (++index < objLength) { + var key = objProps[index], + result = hasOwnProperty.call(other, key); + + if (result) { + var objValue = object[key], + othValue = other[key]; + + result = undefined; + if (customizer) { + result = isWhere + ? customizer(othValue, objValue, key) + : customizer(objValue, othValue, key); + } + if (typeof result == 'undefined') { + // Recursively compare objects (susceptible to call stack limits). + result = (objValue && objValue === othValue) || equalFunc(objValue, othValue, customizer, isWhere, stackA, stackB); + } + } + if (!result) { + return false; + } + hasCtor || (hasCtor = key == 'constructor'); + } + if (!hasCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && typeof othCtor == 'function' && othCtor instanceof othCtor)) { + return false; + } + } + return true; + } + + /** + * Gets the extremum value of `collection` invoking `iteratee` for each value + * in `collection` to generate the criterion by which the value is ranked. + * The `iteratee` is invoked with three arguments; (value, index, collection). + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {boolean} [isMin] Specify returning the minimum, instead of the + * maximum, extremum value. + * @returns {*} Returns the extremum value. + */ + function extremumBy(collection, iteratee, isMin) { + var exValue = isMin ? POSITIVE_INFINITY : NEGATIVE_INFINITY, + computed = exValue, + result = computed; + + baseEach(collection, function(value, index, collection) { + var current = iteratee(value, index, collection); + if ((isMin ? current < computed : current > computed) || (current === exValue && current === result)) { + computed = current; + result = value; + } + }); + return result; + } + + /** + * Gets the appropriate "callback" function. If the `_.callback` method is + * customized this function returns the custom method, otherwise it returns + * the `baseCallback` function. If arguments are provided the chosen function + * is invoked with them and its result is returned. + * + * @private + * @returns {Function} Returns the chosen function or its result. + */ + function getCallback(func, thisArg, argCount) { + var result = lodash.callback || callback; + result = result === callback ? baseCallback : result; + return argCount ? result(func, thisArg, argCount) : result; + } + + /** + * Gets metadata for `func`. + * + * @private + * @param {Function} func The function to query. + * @returns {*} Returns the metadata for `func`. + */ + var getData = !metaMap ? noop : function(func) { + return metaMap.get(func); + }; + + /** + * Gets the appropriate "indexOf" function. If the `_.indexOf` method is + * customized this function returns the custom method, otherwise it returns + * the `baseIndexOf` function. If arguments are provided the chosen function + * is invoked with them and its result is returned. + * + * @private + * @returns {Function|number} Returns the chosen function or its result. + */ + function getIndexOf(collection, target, fromIndex) { + var result = lodash.indexOf || indexOf; + result = result === indexOf ? baseIndexOf : result; + return collection ? result(collection, target, fromIndex) : result; + } + + /** + * Gets the view, applying any `transforms` to the `start` and `end` positions. + * + * @private + * @param {number} start The start of the view. + * @param {number} end The end of the view. + * @param {Array} [transforms] The transformations to apply to the view. + * @returns {Object} Returns an object containing the `start` and `end` + * positions of the view. + */ + function getView(start, end, transforms) { + var index = -1, + length = transforms ? transforms.length : 0; + + while (++index < length) { + var data = transforms[index], + size = data.size; + + switch (data.type) { + case 'drop': start += size; break; + case 'dropRight': end -= size; break; + case 'take': end = nativeMin(end, start + size); break; + case 'takeRight': start = nativeMax(start, end - size); break; + } + } + return { 'start': start, 'end': end }; + } + + /** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ + function initCloneArray(array) { + var length = array.length, + result = new array.constructor(length); + + // Add array properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; + } + + /** + * Initializes an object clone. + * + * @private + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneObject(object) { + var Ctor = object.constructor; + if (!(typeof Ctor == 'function' && Ctor instanceof Ctor)) { + Ctor = Object; + } + return new Ctor; + } + + /** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneByTag(object, tag, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return bufferClone(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + var buffer = object.buffer; + return new Ctor(isDeep ? bufferClone(buffer) : buffer, object.byteOffset, object.length); + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + var result = new Ctor(object.source, reFlags.exec(object)); + result.lastIndex = object.lastIndex; + } + return result; + } + + /** + * Checks if `func` is eligible for `this` binding. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is eligible, else `false`. + */ + function isBindable(func) { + var support = lodash.support, + result = !(support.funcNames ? func.name : support.funcDecomp); + + if (!result) { + var source = fnToString.call(func); + if (!support.funcNames) { + result = !reFuncName.test(source); + } + if (!result) { + // Check if `func` references the `this` keyword and store the result. + result = reThis.test(source) || isNative(func); + baseSetData(func, result); + } + } + return result; + } + + /** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ + function isIndex(value, length) { + value = +value; + length = length == null ? MAX_SAFE_INTEGER : length; + return value > -1 && value % 1 == 0 && value < length; + } + + /** + * Checks if the provided arguments are from an iteratee call. + * + * @private + * @param {*} value The potential iteratee value argument. + * @param {*} index The potential iteratee index or key argument. + * @param {*} object The potential iteratee object argument. + * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`. + */ + function isIterateeCall(value, index, object) { + if (!isObject(object)) { + return false; + } + var type = typeof index; + if (type == 'number') { + var length = object.length, + prereq = isLength(length) && isIndex(index, length); + } else { + prereq = type == 'string' && index in object; + } + return prereq && object[index] === value; + } + + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This function is based on ES `ToLength`. See the + * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength) + * for more details. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + */ + function isLength(value) { + return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + } + + /** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ + function isStrictComparable(value) { + return value === value && (value === 0 ? ((1 / value) > 0) : !isObject(value)); + } + + /** + * Merges the function metadata of `source` into `data`. + * + * Merging metadata reduces the number of wrappers required to invoke a function. + * This is possible because methods like `_.bind`, `_.curry`, and `_.partial` + * may be applied regardless of execution order. Methods like `_.ary` and `_.rearg` + * augment function arguments, making the order in which they are executed important, + * preventing the merging of metadata. However, we make an exception for a safe + * common case where curried functions have `_.ary` and or `_.rearg` applied. + * + * @private + * @param {Array} data The destination metadata. + * @param {Array} source The source metadata. + * @returns {Array} Returns `data`. + */ + function mergeData(data, source) { + var bitmask = data[1], + srcBitmask = source[1], + newBitmask = bitmask | srcBitmask; + + var arityFlags = ARY_FLAG | REARG_FLAG, + bindFlags = BIND_FLAG | BIND_KEY_FLAG, + comboFlags = arityFlags | bindFlags | CURRY_BOUND_FLAG | CURRY_RIGHT_FLAG; + + var isAry = bitmask & ARY_FLAG && !(srcBitmask & ARY_FLAG), + isRearg = bitmask & REARG_FLAG && !(srcBitmask & REARG_FLAG), + argPos = (isRearg ? data : source)[7], + ary = (isAry ? data : source)[8]; + + var isCommon = !(bitmask >= REARG_FLAG && srcBitmask > bindFlags) && + !(bitmask > bindFlags && srcBitmask >= REARG_FLAG); + + var isCombo = (newBitmask >= arityFlags && newBitmask <= comboFlags) && + (bitmask < REARG_FLAG || ((isRearg || isAry) && argPos.length <= ary)); + + // Exit early if metadata can't be merged. + if (!(isCommon || isCombo)) { + return data; + } + // Use source `thisArg` if available. + if (srcBitmask & BIND_FLAG) { + data[2] = source[2]; + // Set when currying a bound function. + newBitmask |= (bitmask & BIND_FLAG) ? 0 : CURRY_BOUND_FLAG; + } + // Compose partial arguments. + var value = source[3]; + if (value) { + var partials = data[3]; + data[3] = partials ? composeArgs(partials, value, source[4]) : arrayCopy(value); + data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : arrayCopy(source[4]); + } + // Compose partial right arguments. + value = source[5]; + if (value) { + partials = data[5]; + data[5] = partials ? composeArgsRight(partials, value, source[6]) : arrayCopy(value); + data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : arrayCopy(source[6]); + } + // Use source `argPos` if available. + value = source[7]; + if (value) { + data[7] = arrayCopy(value); + } + // Use source `ary` if it's smaller. + if (srcBitmask & ARY_FLAG) { + data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]); + } + // Use source `arity` if one is not provided. + if (data[9] == null) { + data[9] = source[9]; + } + // Use source `func` and merge bitmasks. + data[0] = source[0]; + data[1] = newBitmask; + + return data; + } + + /** + * A specialized version of `_.pick` that picks `object` properties specified + * by the `props` array. + * + * @private + * @param {Object} object The source object. + * @param {string[]} props The property names to pick. + * @returns {Object} Returns the new object. + */ + function pickByArray(object, props) { + object = toObject(object); + + var index = -1, + length = props.length, + result = {}; + + while (++index < length) { + var key = props[index]; + if (key in object) { + result[key] = object[key]; + } + } + return result; + } + + /** + * A specialized version of `_.pick` that picks `object` properties `predicate` + * returns truthy for. + * + * @private + * @param {Object} object The source object. + * @param {Function} predicate The function invoked per iteration. + * @returns {Object} Returns the new object. + */ + function pickByCallback(object, predicate) { + var result = {}; + baseForIn(object, function(value, key, object) { + if (predicate(value, key, object)) { + result[key] = value; + } + }); + return result; + } + + /** + * Reorder `array` according to the specified indexes where the element at + * the first index is assigned as the first element, the element at + * the second index is assigned as the second element, and so on. + * + * @private + * @param {Array} array The array to reorder. + * @param {Array} indexes The arranged array indexes. + * @returns {Array} Returns `array`. + */ + function reorder(array, indexes) { + var arrLength = array.length, + length = nativeMin(indexes.length, arrLength), + oldArray = arrayCopy(array); + + while (length--) { + var index = indexes[length]; + array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined; + } + return array; + } + + /** + * Sets metadata for `func`. + * + * **Note:** If this function becomes hot, i.e. is invoked a lot in a short + * period of time, it will trip its breaker and transition to an identity function + * to avoid garbage collection pauses in V8. See [V8 issue 2070](https://code.google.com/p/v8/issues/detail?id=2070) + * for more details. + * + * @private + * @param {Function} func The function to associate metadata with. + * @param {*} data The metadata. + * @returns {Function} Returns `func`. + */ + var setData = (function() { + var count = 0, + lastCalled = 0; + + return function(key, value) { + var stamp = now(), + remaining = HOT_SPAN - (stamp - lastCalled); + + lastCalled = stamp; + if (remaining > 0) { + if (++count >= HOT_COUNT) { + return key; + } + } else { + count = 0; + } + return baseSetData(key, value); + }; + }()); + + /** + * A fallback implementation of `_.isPlainObject` which checks if `value` + * is an object created by the `Object` constructor or has a `[[Prototype]]` + * of `null`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + */ + function shimIsPlainObject(value) { + var Ctor, + support = lodash.support; + + // Exit early for non `Object` objects. + if (!(isObjectLike(value) && objToString.call(value) == objectTag) || + (!hasOwnProperty.call(value, 'constructor') && + (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) { + return false; + } + // IE < 9 iterates inherited properties before own properties. If the first + // iterated property is an object's own property then there are no inherited + // enumerable properties. + var result; + // In most environments an object's own properties are iterated before + // its inherited properties. If the last iterated property is an object's + // own property then there are no inherited enumerable properties. + baseForIn(value, function(subValue, key) { + result = key; + }); + return typeof result == 'undefined' || hasOwnProperty.call(value, result); + } + + /** + * A fallback implementation of `Object.keys` which creates an array of the + * own enumerable property names of `object`. + * + * @private + * @param {Object} object The object to inspect. + * @returns {Array} Returns the array of property names. + */ + function shimKeys(object) { + var props = keysIn(object), + propsLength = props.length, + length = propsLength && object.length, + support = lodash.support; + + var allowIndexes = length && isLength(length) && + (isArray(object) || (support.nonEnumArgs && isArguments(object))); + + var index = -1, + result = []; + + while (++index < propsLength) { + var key = props[index]; + if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) { + result.push(key); + } + } + return result; + } + + /** + * Converts `value` to an array-like object if it is not one. + * + * @private + * @param {*} value The value to process. + * @returns {Array|Object} Returns the array-like object. + */ + function toIterable(value) { + if (value == null) { + return []; + } + if (!isLength(value.length)) { + return values(value); + } + return isObject(value) ? value : Object(value); + } + + /** + * Converts `value` to an object if it is not one. + * + * @private + * @param {*} value The value to process. + * @returns {Object} Returns the object. + */ + function toObject(value) { + return isObject(value) ? value : Object(value); + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates an array of elements split into groups the length of `size`. + * If `collection` can't be split evenly, the final chunk will be the remaining + * elements. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to process. + * @param {numer} [size=1] The length of each chunk. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the new array containing chunks. + * @example + * + * _.chunk(['a', 'b', 'c', 'd'], 2); + * // => [['a', 'b'], ['c', 'd']] + * + * _.chunk(['a', 'b', 'c', 'd'], 3); + * // => [['a', 'b', 'c'], ['d']] + */ + function chunk(array, size, guard) { + if (guard ? isIterateeCall(array, size, guard) : size == null) { + size = 1; + } else { + size = nativeMax(+size || 1, 1); + } + var index = 0, + length = array ? array.length : 0, + resIndex = -1, + result = Array(ceil(length / size)); + + while (index < length) { + result[++resIndex] = baseSlice(array, index, (index += size)); + } + return result; + } + + /** + * Creates an array with all falsey values removed. The values `false`, `null`, + * `0`, `""`, `undefined`, and `NaN` are falsey. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to compact. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.compact([0, 1, false, 2, '', 3]); + * // => [1, 2, 3] + */ + function compact(array) { + var index = -1, + length = array ? array.length : 0, + resIndex = -1, + result = []; + + while (++index < length) { + var value = array[index]; + if (value) { + result[++resIndex] = value; + } + } + return result; + } + + /** + * Creates an array excluding all values of the provided arrays using + * `SameValueZero` for equality comparisons. + * + * **Note:** `SameValueZero` comparisons are like strict equality comparisons, + * e.g. `===`, except that `NaN` matches `NaN`. See the + * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * for more details. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The arrays of values to exclude. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.difference([1, 2, 3], [5, 2, 10]); + * // => [1, 3] + */ + function difference() { + var index = -1, + length = arguments.length; + + while (++index < length) { + var value = arguments[index]; + if (isArray(value) || isArguments(value)) { + break; + } + } + return baseDifference(value, baseFlatten(arguments, false, true, ++index)); + } + + /** + * Creates a slice of `array` with `n` elements dropped from the beginning. + * + * @static + * @memberOf _ + * @type Function + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to drop. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.drop([1, 2, 3]); + * // => [2, 3] + * + * _.drop([1, 2, 3], 2); + * // => [3] + * + * _.drop([1, 2, 3], 5); + * // => [] + * + * _.drop([1, 2, 3], 0); + * // => [1, 2, 3] + */ + function drop(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; + } + return baseSlice(array, n < 0 ? 0 : n); + } + + /** + * Creates a slice of `array` with `n` elements dropped from the end. + * + * @static + * @memberOf _ + * @type Function + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to drop. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.dropRight([1, 2, 3]); + * // => [1, 2] + * + * _.dropRight([1, 2, 3], 2); + * // => [1] + * + * _.dropRight([1, 2, 3], 5); + * // => [] + * + * _.dropRight([1, 2, 3], 0); + * // => [1, 2, 3] + */ + function dropRight(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; + } + n = length - (+n || 0); + return baseSlice(array, 0, n < 0 ? 0 : n); + } + + /** + * Creates a slice of `array` excluding elements dropped from the end. + * Elements are dropped until `predicate` returns falsey. The predicate is + * bound to `thisArg` and invoked with three arguments; (value, index, array). + * + * If a property name is provided for `predicate` the created "_.property" + * style callback returns the property value of the given element. + * + * If an object is provided for `predicate` the created "_.matches" style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @type Function + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per element. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.dropRightWhile([1, 2, 3], function(n) { return n > 1; }); + * // => [1] + * + * var users = [ + * { 'user': 'barney', 'status': 'busy', 'active': false }, + * { 'user': 'fred', 'status': 'busy', 'active': true }, + * { 'user': 'pebbles', 'status': 'away', 'active': true } + * ]; + * + * // using the "_.property" callback shorthand + * _.pluck(_.dropRightWhile(users, 'active'), 'user'); + * // => ['barney'] + * + * // using the "_.matches" callback shorthand + * _.pluck(_.dropRightWhile(users, { 'status': 'away' }), 'user'); + * // => ['barney', 'fred'] + */ + function dropRightWhile(array, predicate, thisArg) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + predicate = getCallback(predicate, thisArg, 3); + while (length-- && predicate(array[length], length, array)) {} + return baseSlice(array, 0, length + 1); + } + + /** + * Creates a slice of `array` excluding elements dropped from the beginning. + * Elements are dropped until `predicate` returns falsey. The predicate is + * bound to `thisArg` and invoked with three arguments; (value, index, array). + * + * If a property name is provided for `predicate` the created "_.property" + * style callback returns the property value of the given element. + * + * If an object is provided for `predicate` the created "_.matches" style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @type Function + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per element. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.dropWhile([1, 2, 3], function(n) { return n < 3; }); + * // => [3] + * + * var users = [ + * { 'user': 'barney', 'status': 'busy', 'active': true }, + * { 'user': 'fred', 'status': 'busy', 'active': false }, + * { 'user': 'pebbles', 'status': 'away', 'active': true } + * ]; + * + * // using the "_.property" callback shorthand + * _.pluck(_.dropWhile(users, 'active'), 'user'); + * // => ['fred', 'pebbles'] + * + * // using the "_.matches" callback shorthand + * _.pluck(_.dropWhile(users, { 'status': 'busy' }), 'user'); + * // => ['pebbles'] + */ + function dropWhile(array, predicate, thisArg) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + var index = -1; + predicate = getCallback(predicate, thisArg, 3); + while (++index < length && predicate(array[index], index, array)) {} + return baseSlice(array, index); + } + + /** + * This method is like `_.find` except that it returns the index of the first + * element `predicate` returns truthy for, instead of the element itself. + * + * If a property name is provided for `predicate` the created "_.property" + * style callback returns the property value of the given element. + * + * If an object is provided for `predicate` the created "_.matches" style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. If a property name or object is provided it is used to + * create a "_.property" or "_.matches" style callback respectively. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': true }, + * { 'user': 'pebbles', 'age': 1, 'active': false } + * ]; + * + * _.findIndex(users, function(chr) { return chr.age < 40; }); + * // => 0 + * + * // using the "_.matches" callback shorthand + * _.findIndex(users, { 'age': 1 }); + * // => 2 + * + * // using the "_.property" callback shorthand + * _.findIndex(users, 'active'); + * // => 1 + */ + function findIndex(array, predicate, thisArg) { + var index = -1, + length = array ? array.length : 0; + + predicate = getCallback(predicate, thisArg, 3); + while (++index < length) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; + } + + /** + * This method is like `_.findIndex` except that it iterates over elements + * of `collection` from right to left. + * + * If a property name is provided for `predicate` the created "_.property" + * style callback returns the property value of the given element. + * + * If an object is provided for `predicate` the created "_.matches" style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. If a property name or object is provided it is used to + * create a "_.property" or "_.matches" style callback respectively. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false }, + * { 'user': 'pebbles', 'age': 1, 'active': false } + * ]; + * + * _.findLastIndex(users, function(chr) { return chr.age < 40; }); + * // => 2 + * + * // using the "_.matches" callback shorthand + * _.findLastIndex(users, { 'age': 40 }); + * // => 1 + * + * // using the "_.property" callback shorthand + * _.findLastIndex(users, 'active'); + * // => 0 + */ + function findLastIndex(array, predicate, thisArg) { + var length = array ? array.length : 0; + predicate = getCallback(predicate, thisArg, 3); + while (length--) { + if (predicate(array[length], length, array)) { + return length; + } + } + return -1; + } + + /** + * Gets the first element of `array`. + * + * @static + * @memberOf _ + * @alias head + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the first element of `array`. + * @example + * + * _.first([1, 2, 3]); + * // => 1 + * + * _.first([]); + * // => undefined + */ + function first(array) { + return array ? array[0] : undefined; + } + + /** + * Flattens a nested array. If `isDeep` is `true` the array is recursively + * flattened, otherwise it is only flattened a single level. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to flatten. + * @param {boolean} [isDeep] Specify a deep flatten. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2], [3, [[4]]]]); + * // => [1, 2, 3, [[4]]]; + * + * // using `isDeep` + * _.flatten([1, [2], [3, [[4]]]], true); + * // => [1, 2, 3, 4]; + */ + function flatten(array, isDeep, guard) { + var length = array ? array.length : 0; + if (guard && isIterateeCall(array, isDeep, guard)) { + isDeep = false; + } + return length ? baseFlatten(array, isDeep) : []; + } + + /** + * Recursively flattens a nested array. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to recursively flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flattenDeep([1, [2], [3, [[4]]]]); + * // => [1, 2, 3, 4]; + */ + function flattenDeep(array) { + var length = array ? array.length : 0; + return length ? baseFlatten(array, true) : []; + } + + /** + * Gets the index at which the first occurrence of `value` is found in `array` + * using `SameValueZero` for equality comparisons. If `fromIndex` is negative, + * it is used as the offset from the end of `array`. If `array` is sorted + * providing `true` for `fromIndex` performs a faster binary search. + * + * **Note:** `SameValueZero` comparisons are like strict equality comparisons, + * e.g. `===`, except that `NaN` matches `NaN`. See the + * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * for more details. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {boolean|number} [fromIndex=0] The index to search from or `true` + * to perform a binary search on a sorted array. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.indexOf([1, 2, 3, 1, 2, 3], 2); + * // => 1 + * + * // using `fromIndex` + * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3); + * // => 4 + * + * // performing a binary search + * _.indexOf([4, 4, 5, 5, 6, 6], 5, true); + * // => 2 + */ + function indexOf(array, value, fromIndex) { + var length = array ? array.length : 0; + if (!length) { + return -1; + } + if (typeof fromIndex == 'number') { + fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0); + } else if (fromIndex) { + var index = binaryIndex(array, value), + other = array[index]; + + return (value === value ? value === other : other !== other) ? index : -1; + } + return baseIndexOf(array, value, fromIndex); + } + + /** + * Gets all but the last element of `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.initial([1, 2, 3]); + * // => [1, 2] + */ + function initial(array) { + return dropRight(array, 1); + } + + /** + * Creates an array of unique values in all provided arrays using `SameValueZero` + * for equality comparisons. + * + * **Note:** `SameValueZero` comparisons are like strict equality comparisons, + * e.g. `===`, except that `NaN` matches `NaN`. See the + * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * for more details. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of shared values. + * @example + * + * _.intersection([1, 2, 3], [5, 2, 1, 4], [2, 1]); + * // => [1, 2] + */ + function intersection() { + var args = [], + argsIndex = -1, + argsLength = arguments.length, + caches = [], + indexOf = getIndexOf(), + isCommon = indexOf == baseIndexOf; + + while (++argsIndex < argsLength) { + var value = arguments[argsIndex]; + if (isArray(value) || isArguments(value)) { + args.push(value); + caches.push(isCommon && value.length >= 120 && createCache(argsIndex && value)); + } + } + argsLength = args.length; + var array = args[0], + index = -1, + length = array ? array.length : 0, + result = [], + seen = caches[0]; + + outer: + while (++index < length) { + value = array[index]; + if ((seen ? cacheIndexOf(seen, value) : indexOf(result, value)) < 0) { + argsIndex = argsLength; + while (--argsIndex) { + var cache = caches[argsIndex]; + if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value)) < 0) { + continue outer; + } + } + if (seen) { + seen.push(value); + } + result.push(value); + } + } + return result; + } + + /** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ + function last(array) { + var length = array ? array.length : 0; + return length ? array[length - 1] : undefined; + } + + /** + * This method is like `_.indexOf` except that it iterates over elements of + * `array` from right to left. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {boolean|number} [fromIndex=array.length-1] The index to search from + * or `true` to perform a binary search on a sorted array. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2); + * // => 4 + * + * // using `fromIndex` + * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3); + * // => 1 + * + * // performing a binary search + * _.lastIndexOf([4, 4, 5, 5, 6, 6], 5, true); + * // => 3 + */ + function lastIndexOf(array, value, fromIndex) { + var length = array ? array.length : 0; + if (!length) { + return -1; + } + var index = length; + if (typeof fromIndex == 'number') { + index = (fromIndex < 0 ? nativeMax(length + fromIndex, 0) : nativeMin(fromIndex || 0, length - 1)) + 1; + } else if (fromIndex) { + index = binaryIndex(array, value, true) - 1; + var other = array[index]; + return (value === value ? value === other : other !== other) ? index : -1; + } + if (value !== value) { + return indexOfNaN(array, index, true); + } + while (index--) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * Removes all provided values from `array` using `SameValueZero` for equality + * comparisons. + * + * **Notes:** + * - Unlike `_.without`, this method mutates `array`. + * - `SameValueZero` comparisons are like strict equality comparisons, e.g. `===`, + * except that `NaN` matches `NaN`. See the [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * for more details. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {...*} [values] The values to remove. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3, 1, 2, 3]; + * _.pull(array, 2, 3); + * console.log(array); + * // => [1, 1] + */ + function pull() { + var array = arguments[0]; + if (!(array && array.length)) { + return array; + } + var index = 0, + indexOf = getIndexOf(), + length = arguments.length; + + while (++index < length) { + var fromIndex = 0, + value = arguments[index]; + + while ((fromIndex = indexOf(array, value, fromIndex)) > -1) { + splice.call(array, fromIndex, 1); + } + } + return array; + } + + /** + * Removes elements from `array` corresponding to the given indexes and returns + * an array of the removed elements. Indexes may be specified as an array of + * indexes or as individual arguments. + * + * **Note:** Unlike `_.at`, this method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {...(number|number[])} [indexes] The indexes of elements to remove, + * specified as individual indexes or arrays of indexes. + * @returns {Array} Returns the new array of removed elements. + * @example + * + * var array = [5, 10, 15, 20]; + * var evens = _.pullAt(array, [1, 3]); + * + * console.log(array); + * // => [5, 15] + * + * console.log(evens); + * // => [10, 20] + */ + function pullAt(array) { + return basePullAt(array || [], baseFlatten(arguments, false, false, 1)); + } + + /** + * Removes all elements from `array` that `predicate` returns truthy for + * and returns an array of the removed elements. The predicate is bound to + * `thisArg` and invoked with three arguments; (value, index, array). + * + * If a property name is provided for `predicate` the created "_.property" + * style callback returns the property value of the given element. + * + * If an object is provided for `predicate` the created "_.matches" style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * **Note:** Unlike `_.filter`, this method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. If a property name or object is provided it is used to + * create a "_.property" or "_.matches" style callback respectively. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the new array of removed elements. + * @example + * + * var array = [1, 2, 3, 4]; + * var evens = _.remove(array, function(n) { return n % 2 == 0; }); + * + * console.log(array); + * // => [1, 3] + * + * console.log(evens); + * // => [2, 4] + */ + function remove(array, predicate, thisArg) { + var index = -1, + length = array ? array.length : 0, + result = []; + + predicate = getCallback(predicate, thisArg, 3); + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result.push(value); + splice.call(array, index--, 1); + length--; + } + } + return result; + } + + /** + * Gets all but the first element of `array`. + * + * @static + * @memberOf _ + * @alias tail + * @category Array + * @param {Array} array The array to query. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.rest([1, 2, 3]); + * // => [2, 3] + */ + function rest(array) { + return drop(array, 1); + } + + /** + * Creates a slice of `array` from `start` up to, but not including, `end`. + * + * **Note:** This function is used instead of `Array#slice` to support node + * lists in IE < 9 and to ensure dense arrays are returned. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ + function slice(array, start, end) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (end && typeof end != 'number' && isIterateeCall(array, start, end)) { + start = 0; + end = length; + } + return baseSlice(array, start, end); + } + + /** + * Uses a binary search to determine the lowest index at which `value` should + * be inserted into `array` in order to maintain its sort order. If an iteratee + * function is provided it is invoked for `value` and each element of `array` + * to compute their sort ranking. The iteratee is bound to `thisArg` and + * invoked with one argument; (value). + * + * If a property name is provided for `predicate` the created "_.property" + * style callback returns the property value of the given element. + * + * If an object is provided for `predicate` the created "_.matches" style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. If a property name or object is provided it is used to + * create a "_.property" or "_.matches" style callback respectively. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * _.sortedIndex([30, 50], 40); + * // => 1 + * + * _.sortedIndex([4, 4, 5, 5, 6, 6], 5); + * // => 2 + * + * var dict = { 'data': { 'thirty': 30, 'forty': 40, 'fifty': 50 } }; + * + * // using an iteratee function + * _.sortedIndex(['thirty', 'fifty'], 'forty', function(word) { + * return this.data[word]; + * }, dict); + * // => 1 + * + * // using the "_.property" callback shorthand + * _.sortedIndex([{ 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); + * // => 1 + */ + function sortedIndex(array, value, iteratee, thisArg) { + var func = getCallback(iteratee); + return (func === baseCallback && iteratee == null) + ? binaryIndex(array, value) + : binaryIndexBy(array, value, func(iteratee, thisArg, 1)); + } + + /** + * This method is like `_.sortedIndex` except that it returns the highest + * index at which `value` should be inserted into `array` in order to + * maintain its sort order. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. If a property name or object is provided it is used to + * create a "_.property" or "_.matches" style callback respectively. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * _.sortedLastIndex([4, 4, 5, 5, 6, 6], 5); + * // => 4 + */ + function sortedLastIndex(array, value, iteratee, thisArg) { + var func = getCallback(iteratee); + return (func === baseCallback && iteratee == null) + ? binaryIndex(array, value, true) + : binaryIndexBy(array, value, func(iteratee, thisArg, 1), true); + } + + /** + * Creates a slice of `array` with `n` elements taken from the beginning. + * + * @static + * @memberOf _ + * @type Function + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to take. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.take([1, 2, 3]); + * // => [1] + * + * _.take([1, 2, 3], 2); + * // => [1, 2] + * + * _.take([1, 2, 3], 5); + * // => [1, 2, 3] + * + * _.take([1, 2, 3], 0); + * // => [] + */ + function take(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; + } + return baseSlice(array, 0, n < 0 ? 0 : n); + } + + /** + * Creates a slice of `array` with `n` elements taken from the end. + * + * @static + * @memberOf _ + * @type Function + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to take. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.takeRight([1, 2, 3]); + * // => [3] + * + * _.takeRight([1, 2, 3], 2); + * // => [2, 3] + * + * _.takeRight([1, 2, 3], 5); + * // => [1, 2, 3] + * + * _.takeRight([1, 2, 3], 0); + * // => [] + */ + function takeRight(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; + } + n = length - (+n || 0); + return baseSlice(array, n < 0 ? 0 : n); + } + + /** + * Creates a slice of `array` with elements taken from the end. Elements are + * taken until `predicate` returns falsey. The predicate is bound to `thisArg` + * and invoked with three arguments; (value, index, array). + * + * If a property name is provided for `predicate` the created "_.property" + * style callback returns the property value of the given element. + * + * If an object is provided for `predicate` the created "_.matches" style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @type Function + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per element. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.takeRightWhile([1, 2, 3], function(n) { return n > 1; }); + * // => [2, 3] + * + * var users = [ + * { 'user': 'barney', 'status': 'busy', 'active': false }, + * { 'user': 'fred', 'status': 'busy', 'active': true }, + * { 'user': 'pebbles', 'status': 'away', 'active': true } + * ]; + * + * // using the "_.property" callback shorthand + * _.pluck(_.takeRightWhile(users, 'active'), 'user'); + * // => ['fred', 'pebbles'] + * + * // using the "_.matches" callback shorthand + * _.pluck(_.takeRightWhile(users, { 'status': 'away' }), 'user'); + * // => ['pebbles'] + */ + function takeRightWhile(array, predicate, thisArg) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + predicate = getCallback(predicate, thisArg, 3); + while (length-- && predicate(array[length], length, array)) {} + return baseSlice(array, length + 1); + } + + /** + * Creates a slice of `array` with elements taken from the beginning. Elements + * are taken until `predicate` returns falsey. The predicate is bound to + * `thisArg` and invoked with three arguments; (value, index, array). + * + * If a property name is provided for `predicate` the created "_.property" + * style callback returns the property value of the given element. + * + * If an object is provided for `predicate` the created "_.matches" style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @type Function + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per element. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.takeWhile([1, 2, 3], function(n) { return n < 3; }); + * // => [1, 2] + * + * var users = [ + * { 'user': 'barney', 'status': 'busy', 'active': true }, + * { 'user': 'fred', 'status': 'busy', 'active': false }, + * { 'user': 'pebbles', 'status': 'away', 'active': true } + * ]; + * + * // using the "_.property" callback shorthand + * _.pluck(_.takeWhile(users, 'active'), 'user'); + * // => ['barney'] + * + * // using the "_.matches" callback shorthand + * _.pluck(_.takeWhile(users, { 'status': 'busy' }), 'user'); + * // => ['barney', 'fred'] + */ + function takeWhile(array, predicate, thisArg) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + var index = -1; + predicate = getCallback(predicate, thisArg, 3); + while (++index < length && predicate(array[index], index, array)) {} + return baseSlice(array, 0, index); + } + + /** + * Creates an array of unique values, in order, of the provided arrays using + * `SameValueZero` for equality comparisons. + * + * **Note:** `SameValueZero` comparisons are like strict equality comparisons, + * e.g. `===`, except that `NaN` matches `NaN`. See the + * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * for more details. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.union([1, 2, 3], [5, 2, 1, 4], [2, 1]); + * // => [1, 2, 3, 5, 4] + */ + function union() { + return baseUniq(baseFlatten(arguments, false, true)); + } + + /** + * Creates a duplicate-value-free version of an array using `SameValueZero` + * for equality comparisons. Providing `true` for `isSorted` performs a faster + * search algorithm for sorted arrays. If an iteratee function is provided it + * is invoked for each value in the array to generate the criterion by which + * uniqueness is computed. The `iteratee` is bound to `thisArg` and invoked + * with three arguments; (value, index, array). + * + * If a property name is provided for `predicate` the created "_.property" + * style callback returns the property value of the given element. + * + * If an object is provided for `predicate` the created "_.matches" style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * **Note:** `SameValueZero` comparisons are like strict equality comparisons, + * e.g. `===`, except that `NaN` matches `NaN`. See the + * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * for more details. + * + * @static + * @memberOf _ + * @alias unique + * @category Array + * @param {Array} array The array to inspect. + * @param {boolean} [isSorted] Specify the array is sorted. + * @param {Function|Object|string} [iteratee] The function invoked per iteration. + * If a property name or object is provided it is used to create a "_.property" + * or "_.matches" style callback respectively. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new duplicate-value-free array. + * @example + * + * _.uniq([1, 2, 1]); + * // => [1, 2] + * + * // using `isSorted` + * _.uniq([1, 1, 2], true); + * // => [1, 2] + * + * // using an iteratee function + * _.uniq([1, 2.5, 1.5, 2], function(n) { return this.floor(n); }, Math); + * // => [1, 2.5] + * + * // using the "_.property" callback shorthand + * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }, { 'x': 2 }] + */ + function uniq(array, isSorted, iteratee, thisArg) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + // Juggle arguments. + if (typeof isSorted != 'boolean' && isSorted != null) { + thisArg = iteratee; + iteratee = isIterateeCall(array, isSorted, thisArg) ? null : isSorted; + isSorted = false; + } + var func = getCallback(); + if (!(func === baseCallback && iteratee == null)) { + iteratee = func(iteratee, thisArg, 3); + } + return (isSorted && getIndexOf() == baseIndexOf) + ? sortedUniq(array, iteratee) + : baseUniq(array, iteratee); + } + + /** + * This method is like `_.zip` except that it accepts an array of grouped + * elements and creates an array regrouping the elements to their pre-`_.zip` + * configuration. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array of grouped elements to process. + * @returns {Array} Returns the new array of regrouped elements. + * @example + * + * var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]); + * // => [['fred', 30, true], ['barney', 40, false]] + * + * _.unzip(zipped); + * // => [['fred', 'barney'], [30, 40], [true, false]] + */ + function unzip(array) { + var index = -1, + length = (array && array.length && arrayMax(arrayMap(array, getLength))) >>> 0, + result = Array(length); + + while (++index < length) { + result[index] = arrayMap(array, baseProperty(index)); + } + return result; + } + + /** + * Creates an array excluding all provided values using `SameValueZero` for + * equality comparisons. + * + * **Note:** `SameValueZero` comparisons are like strict equality comparisons, + * e.g. `===`, except that `NaN` matches `NaN`. See the + * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * for more details. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to filter. + * @param {...*} [values] The values to exclude. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1); + * // => [2, 3, 4] + */ + function without(array) { + return baseDifference(array, baseSlice(arguments, 1)); + } + + /** + * Creates an array that is the symmetric difference of the provided arrays. + * See [Wikipedia](https://en.wikipedia.org/wiki/Symmetric_difference) for + * more details. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of values. + * @example + * + * _.xor([1, 2, 3], [5, 2, 1, 4]); + * // => [3, 5, 4] + * + * _.xor([1, 2, 5], [2, 3, 5], [3, 4, 5]); + * // => [1, 4, 5] + */ + function xor() { + var index = -1, + length = arguments.length; + + while (++index < length) { + var array = arguments[index]; + if (isArray(array) || isArguments(array)) { + var result = result + ? baseDifference(result, array).concat(baseDifference(array, result)) + : array; + } + } + return result ? baseUniq(result) : []; + } + + /** + * Creates an array of grouped elements, the first of which contains the first + * elements of the given arrays, the second of which contains the second elements + * of the given arrays, and so on. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to process. + * @returns {Array} Returns the new array of grouped elements. + * @example + * + * _.zip(['fred', 'barney'], [30, 40], [true, false]); + * // => [['fred', 30, true], ['barney', 40, false]] + */ + function zip() { + var length = arguments.length, + array = Array(length); + + while (length--) { + array[length] = arguments[length]; + } + return unzip(array); + } + + /** + * Creates an object composed from arrays of property names and values. Provide + * either a single two dimensional array, e.g. `[[key1, value1], [key2, value2]]` + * or two arrays, one of property names and one of corresponding values. + * + * @static + * @memberOf _ + * @alias object + * @category Array + * @param {Array} props The property names. + * @param {Array} [values=[]] The property values. + * @returns {Object} Returns the new object. + * @example + * + * _.zipObject(['fred', 'barney'], [30, 40]); + * // => { 'fred': 30, 'barney': 40 } + */ + function zipObject(props, values) { + var index = -1, + length = props ? props.length : 0, + result = {}; + + if (length && !values && !isArray(props[0])) { + values = []; + } + while (++index < length) { + var key = props[index]; + if (values) { + result[key] = values[index]; + } else if (key) { + result[key[0]] = key[1]; + } + } + return result; + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates a `lodash` object that wraps `value` with explicit method + * chaining enabled. + * + * @static + * @memberOf _ + * @category Chain + * @param {*} value The value to wrap. + * @returns {Object} Returns the new `lodash` object. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'pebbles', 'age': 1 } + * ]; + * + * var youngest = _.chain(users) + * .sortBy('age') + * .map(function(chr) { return chr.user + ' is ' + chr.age; }) + * .first() + * .value(); + * // => 'pebbles is 1' + */ + function chain(value) { + var result = lodash(value); + result.__chain__ = true; + return result; + } + + /** + * This method invokes `interceptor` and returns `value`. The interceptor is + * bound to `thisArg` and invoked with one argument; (value). The purpose of + * this method is to "tap into" a method chain in order to perform operations + * on intermediate results within the chain. + * + * @static + * @memberOf _ + * @category Chain + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @param {*} [thisArg] The `this` binding of `interceptor`. + * @returns {*} Returns `value`. + * @example + * + * _([1, 2, 3]) + * .tap(function(array) { array.pop(); }) + * .reverse() + * .value(); + * // => [2, 1] + */ + function tap(value, interceptor, thisArg) { + interceptor.call(thisArg, value); + return value; + } + + /** + * This method is like `_.tap` except that it returns the result of `interceptor`. + * + * @static + * @memberOf _ + * @category Chain + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @param {*} [thisArg] The `this` binding of `interceptor`. + * @returns {*} Returns the result of `interceptor`. + * @example + * + * _([1, 2, 3]) + * .last() + * .thru(function(value) { return [value]; }) + * .value(); + * // => [3] + */ + function thru(value, interceptor, thisArg) { + return interceptor.call(thisArg, value); + } + + /** + * Enables explicit method chaining on the wrapper object. + * + * @name chain + * @memberOf _ + * @category Chain + * @returns {*} Returns the `lodash` object. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * // without explicit chaining + * _(users).first(); + * // => { 'user': 'barney', 'age': 36 } + * + * // with explicit chaining + * _(users).chain() + * .first() + * .pick('user') + * .value(); + * // => { 'user': 'barney' } + */ + function wrapperChain() { + return chain(this); + } + + /** + * Reverses the wrapped array so the first element becomes the last, the + * second element becomes the second to last, and so on. + * + * **Note:** This method mutates the wrapped array. + * + * @name reverse + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new reversed `lodash` object. + * @example + * + * var array = [1, 2, 3]; + * + * _(array).reverse().value() + * // => [3, 2, 1] + * + * console.log(array); + * // => [3, 2, 1] + */ + function wrapperReverse() { + var value = this.__wrapped__; + if (value instanceof LazyWrapper) { + if (this.__actions__.length) { + value = new LazyWrapper(this); + } + return new LodashWrapper(value.reverse()); + } + return this.thru(function(value) { + return value.reverse(); + }); + } + + /** + * Produces the result of coercing the unwrapped value to a string. + * + * @name toString + * @memberOf _ + * @category Chain + * @returns {string} Returns the coerced string value. + * @example + * + * _([1, 2, 3]).toString(); + * // => '1,2,3' + */ + function wrapperToString() { + return (this.value() + ''); + } + + /** + * Executes the chained sequence to extract the unwrapped value. + * + * @name value + * @memberOf _ + * @alias toJSON, valueOf + * @category Chain + * @returns {*} Returns the resolved unwrapped value. + * @example + * + * _([1, 2, 3]).value(); + * // => [1, 2, 3] + */ + function wrapperValue() { + return baseWrapperValue(this.__wrapped__, this.__actions__); + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates an array of elements corresponding to the given keys, or indexes, + * of `collection`. Keys may be specified as individual arguments or as arrays + * of keys. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {...(number|number[]|string|string[])} [props] The property names + * or indexes of elements to pick, specified individually or in arrays. + * @returns {Array} Returns the new array of picked elements. + * @example + * + * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]); + * // => ['a', 'c', 'e'] + * + * _.at(['fred', 'barney', 'pebbles'], 0, 2); + * // => ['fred', 'pebbles'] + */ + function at(collection) { + var length = collection ? collection.length : 0; + if (isLength(length)) { + collection = toIterable(collection); + } + return baseAt(collection, baseFlatten(arguments, false, false, 1)); + } + + /** + * Checks if `value` is in `collection` using `SameValueZero` for equality + * comparisons. If `fromIndex` is negative, it is used as the offset from + * the end of `collection`. + * + * **Note:** `SameValueZero` comparisons are like strict equality comparisons, + * e.g. `===`, except that `NaN` matches `NaN`. See the + * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * for more details. + * + * @static + * @memberOf _ + * @alias contains, include + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {*} target The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @returns {boolean} Returns `true` if a matching element is found, else `false`. + * @example + * + * _.includes([1, 2, 3], 1); + * // => true + * + * _.includes([1, 2, 3], 1, 2); + * // => false + * + * _.includes({ 'user': 'fred', 'age': 40 }, 'fred'); + * // => true + * + * _.includes('pebbles', 'eb'); + * // => true + */ + function includes(collection, target, fromIndex) { + var length = collection ? collection.length : 0; + if (!isLength(length)) { + collection = values(collection); + length = collection.length; + } + if (!length) { + return false; + } + if (typeof fromIndex == 'number') { + fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0); + } else { + fromIndex = 0; + } + return (typeof collection == 'string' || !isArray(collection) && isString(collection)) + ? (fromIndex < length && collection.indexOf(target, fromIndex) > -1) + : (getIndexOf(collection, target, fromIndex) > -1); + } + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is the number of times the key was returned by `iteratee`. + * The `iteratee` is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). + * + * If a property name is provided for `predicate` the created "_.property" + * style callback returns the property value of the given element. + * + * If an object is provided for `predicate` the created "_.matches" style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. If a property name or object is provided it is used to + * create a "_.property" or "_.matches" style callback respectively. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.countBy([4.3, 6.1, 6.4], function(n) { return Math.floor(n); }); + * // => { '4': 1, '6': 2 } + * + * _.countBy([4.3, 6.1, 6.4], function(n) { return this.floor(n); }, Math); + * // => { '4': 1, '6': 2 } + * + * _.countBy(['one', 'two', 'three'], 'length'); + * // => { '3': 2, '5': 1 } + */ + var countBy = createAggregator(function(result, value, key) { + hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1); + }); + + /** + * Checks if `predicate` returns truthy for **all** elements of `collection`. + * The predicate is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). + * + * If a property name is provided for `predicate` the created "_.property" + * style callback returns the property value of the given element. + * + * If an object is provided for `predicate` the created "_.matches" style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias all + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. If a property name or object is provided it is used to + * create a "_.property" or "_.matches" style callback respectively. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false`. + * @example + * + * _.every([true, 1, null, 'yes']); + * // => false + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * // using the "_.property" callback shorthand + * _.every(users, 'age'); + * // => true + * + * // using the "_.matches" callback shorthand + * _.every(users, { 'age': 36 }); + * // => false + */ + function every(collection, predicate, thisArg) { + var func = isArray(collection) ? arrayEvery : baseEvery; + if (typeof predicate != 'function' || typeof thisArg != 'undefined') { + predicate = getCallback(predicate, thisArg, 3); + } + return func(collection, predicate); + } + + /** + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is bound to `thisArg` and + * invoked with three arguments; (value, index|key, collection). + * + * If a property name is provided for `predicate` the created "_.property" + * style callback returns the property value of the given element. + * + * If an object is provided for `predicate` the created "_.matches" style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias select + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. If a property name or object is provided it is used to + * create a "_.property" or "_.matches" style callback respectively. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the new filtered array. + * @example + * + * var evens = _.filter([1, 2, 3, 4], function(n) { return n % 2 == 0; }); + * // => [2, 4] + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': true } + * ]; + * + * // using the "_.property" callback shorthand + * _.pluck(_.filter(users, 'active'), 'user'); + * // => ['fred'] + * + * // using the "_.matches" callback shorthand + * _.pluck(_.filter(users, { 'age': 36 }), 'user'); + * // => ['barney'] + */ + function filter(collection, predicate, thisArg) { + var func = isArray(collection) ? arrayFilter : baseFilter; + predicate = getCallback(predicate, thisArg, 3); + return func(collection, predicate); + } + + /** + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is bound to `thisArg` and + * invoked with three arguments; (value, index|key, collection). + * + * If a property name is provided for `predicate` the created "_.property" + * style callback returns the property value of the given element. + * + * If an object is provided for `predicate` the created "_.matches" style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias detect + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. If a property name or object is provided it is used to + * create a "_.property" or "_.matches" style callback respectively. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': true }, + * { 'user': 'pebbles', 'age': 1, 'active': false } + * ]; + * + * _.result(_.find(users, function(chr) { return chr.age < 40; }), 'user'); + * // => 'barney' + * + * // using the "_.matches" callback shorthand + * _.result(_.find(users, { 'age': 1 }), 'user'); + * // => 'pebbles' + * + * // using the "_.property" callback shorthand + * _.result(_.find(users, 'active'), 'user'); + * // => 'fred' + */ + function find(collection, predicate, thisArg) { + if (isArray(collection)) { + var index = findIndex(collection, predicate, thisArg); + return index > -1 ? collection[index] : undefined; + } + predicate = getCallback(predicate, thisArg, 3); + return baseFind(collection, predicate, baseEach); + } + + /** + * This method is like `_.find` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. If a property name or object is provided it is used to + * create a "_.property" or "_.matches" style callback respectively. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * _.findLast([1, 2, 3, 4], function(n) { return n % 2 == 1; }); + * // => 3 + */ + function findLast(collection, predicate, thisArg) { + predicate = getCallback(predicate, thisArg, 3); + return baseFind(collection, predicate, baseEachRight); + } + + /** + * Performs a deep comparison between each element in `collection` and the + * source object, returning the first element that has equivalent property + * values. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Object} source The object of property values to match. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'status': 'busy' }, + * { 'user': 'fred', 'age': 40, 'status': 'busy' } + * ]; + * + * _.result(_.findWhere(users, { 'status': 'busy' }), 'user'); + * // => 'barney' + * + * _.result(_.findWhere(users, { 'age': 40 }), 'user'); + * // => 'fred' + */ + function findWhere(collection, source) { + return find(collection, baseMatches(source)); + } + + /** + * Iterates over elements of `collection` invoking `iteratee` for each element. + * The `iteratee` is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). Iterator functions may exit iteration early + * by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a `length` property + * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` + * may be used for object iteration. + * + * @static + * @memberOf _ + * @alias each + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array|Object|string} Returns `collection`. + * @example + * + * _([1, 2, 3]).forEach(function(n) { console.log(n); }).value(); + * // => logs each value from left to right and returns the array + * + * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(n, key) { console.log(n, key); }); + * // => logs each value-key pair and returns the object (iteration order is not guaranteed) + */ + function forEach(collection, iteratee, thisArg) { + return (typeof iteratee == 'function' && typeof thisArg == 'undefined' && isArray(collection)) + ? arrayEach(collection, iteratee) + : baseEach(collection, bindCallback(iteratee, thisArg, 3)); + } + + /** + * This method is like `_.forEach` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @alias eachRight + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array|Object|string} Returns `collection`. + * @example + * + * _([1, 2, 3]).forEachRight(function(n) { console.log(n); }).join(','); + * // => logs each value from right to left and returns the array + */ + function forEachRight(collection, iteratee, thisArg) { + return (typeof iteratee == 'function' && typeof thisArg == 'undefined' && isArray(collection)) + ? arrayEachRight(collection, iteratee) + : baseEachRight(collection, bindCallback(iteratee, thisArg, 3)); + } + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is an array of the elements responsible for generating the key. + * The `iteratee` is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). + * + * If a property name is provided for `predicate` the created "_.property" + * style callback returns the property value of the given element. + * + * If an object is provided for `predicate` the created "_.matches" style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. If a property name or object is provided it is used to + * create a "_.property" or "_.matches" style callback respectively. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.groupBy([4.2, 6.1, 6.4], function(n) { return Math.floor(n); }); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * _.groupBy([4.2, 6.1, 6.4], function(n) { return this.floor(n); }, Math); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * // using the "_.property" callback shorthand + * _.groupBy(['one', 'two', 'three'], 'length'); + * // => { '3': ['one', 'two'], '5': ['three'] } + */ + var groupBy = createAggregator(function(result, value, key) { + if (hasOwnProperty.call(result, key)) { + result[key].push(value); + } else { + result[key] = [value]; + } + }); + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is the last element responsible for generating the key. The + * iteratee function is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). + * + * If a property name is provided for `predicate` the created "_.property" + * style callback returns the property value of the given element. + * + * If an object is provided for `predicate` the created "_.matches" style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. If a property name or object is provided it is used to + * create a "_.property" or "_.matches" style callback respectively. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * var keyData = [ + * { 'dir': 'left', 'code': 97 }, + * { 'dir': 'right', 'code': 100 } + * ]; + * + * _.indexBy(keyData, 'dir'); + * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(keyData, function(object) { return String.fromCharCode(object.code); }); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(keyData, function(object) { return this.fromCharCode(object.code); }, String); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + */ + var indexBy = createAggregator(function(result, value, key) { + result[key] = value; + }); + + /** + * Invokes the method named by `methodName` on each element in `collection`, + * returning an array of the results of each invoked method. Any additional + * arguments are provided to each invoked method. If `methodName` is a function + * it is invoked for, and `this` bound to, each element in `collection`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|string} methodName The name of the method to invoke or + * the function invoked per iteration. + * @param {...*} [args] The arguments to invoke the method with. + * @returns {Array} Returns the array of results. + * @example + * + * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); + * // => [[1, 5, 7], [1, 2, 3]] + * + * _.invoke([123, 456], String.prototype.split, ''); + * // => [['1', '2', '3'], ['4', '5', '6']] + */ + function invoke(collection, methodName) { + return baseInvoke(collection, methodName, baseSlice(arguments, 2)); + } + + /** + * Creates an array of values by running each element in `collection` through + * `iteratee`. The `iteratee` is bound to `thisArg` and invoked with three + * arguments; (value, index|key, collection). + * + * If a property name is provided for `predicate` the created "_.property" + * style callback returns the property value of the given element. + * + * If an object is provided for `predicate` the created "_.matches" style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias collect + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. If a property name or object is provided it is used to + * create a "_.property" or "_.matches" style callback respectively. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new mapped array. + * @example + * + * _.map([1, 2, 3], function(n) { return n * 3; }); + * // => [3, 6, 9] + * + * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(n) { return n * 3; }); + * // => [3, 6, 9] (iteration order is not guaranteed) + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * // using the "_.property" callback shorthand + * _.map(users, 'user'); + * // => ['barney', 'fred'] + */ + function map(collection, iteratee, thisArg) { + var func = isArray(collection) ? arrayMap : baseMap; + iteratee = getCallback(iteratee, thisArg, 3); + return func(collection, iteratee); + } + + /** + * Gets the maximum value of `collection`. If `collection` is empty or falsey + * `-Infinity` is returned. If an iteratee function is provided it is invoked + * for each value in `collection` to generate the criterion by which the value + * is ranked. The `iteratee` is bound to `thisArg` and invoked with three + * arguments; (value, index, collection). + * + * If a property name is provided for `predicate` the created "_.property" + * style callback returns the property value of the given element. + * + * If an object is provided for `predicate` the created "_.matches" style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee] The function invoked per iteration. + * If a property name or object is provided it is used to create a "_.property" + * or "_.matches" style callback respectively. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {*} Returns the maximum value. + * @example + * + * _.max([4, 2, 8, 6]); + * // => 8 + * + * _.max([]); + * // => -Infinity + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * _.max(users, function(chr) { return chr.age; }); + * // => { 'user': 'fred', 'age': 40 }; + * + * // using the "_.property" callback shorthand + * _.max(users, 'age'); + * // => { 'user': 'fred', 'age': 40 }; + */ + var max = createExtremum(arrayMax); + + /** + * Gets the minimum value of `collection`. If `collection` is empty or falsey + * `Infinity` is returned. If an iteratee function is provided it is invoked + * for each value in `collection` to generate the criterion by which the value + * is ranked. The `iteratee` is bound to `thisArg` and invoked with three + * arguments; (value, index, collection). + * + * If a property name is provided for `predicate` the created "_.property" + * style callback returns the property value of the given element. + * + * If an object is provided for `predicate` the created "_.matches" style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee] The function invoked per iteration. + * If a property name or object is provided it is used to create a "_.property" + * or "_.matches" style callback respectively. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {*} Returns the minimum value. + * @example + * + * _.min([4, 2, 8, 6]); + * // => 2 + * + * _.min([]); + * // => Infinity + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * _.min(users, function(chr) { return chr.age; }); + * // => { 'user': 'barney', 'age': 36 }; + * + * // using the "_.property" callback shorthand + * _.min(users, 'age'); + * // => { 'user': 'barney', 'age': 36 }; + */ + var min = createExtremum(arrayMin, true); + + /** + * Creates an array of elements split into two groups, the first of which + * contains elements `predicate` returns truthy for, while the second of which + * contains elements `predicate` returns falsey for. The predicate is bound + * to `thisArg` and invoked with three arguments; (value, index|key, collection). + * + * If a property name is provided for `predicate` the created "_.property" + * style callback returns the property value of the given element. + * + * If an object is provided for `predicate` the created "_.matches" style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. If a property name or object is provided it is used to + * create a "_.property" or "_.matches" style callback respectively. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the array of grouped elements. + * @example + * + * _.partition([1, 2, 3], function(n) { return n % 2; }); + * // => [[1, 3], [2]] + * + * _.partition([1.2, 2.3, 3.4], function(n) { return this.floor(n) % 2; }, Math); + * // => [[1, 3], [2]] + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': true }, + * { 'user': 'pebbles', 'age': 1, 'active': false } + * ]; + * + * // using the "_.matches" callback shorthand + * _.map(_.partition(users, { 'age': 1 }), function(array) { return _.pluck(array, 'user'); }); + * // => [['pebbles'], ['barney', 'fred']] + * + * // using the "_.property" callback shorthand + * _.map(_.partition(users, 'active'), function(array) { return _.pluck(array, 'user'); }); + * // => [['fred'], ['barney', 'pebbles']] + */ + var partition = createAggregator(function(result, value, key) { + result[key ? 0 : 1].push(value); + }, function() { return [[], []]; }); + + /** + * Gets the value of `key` from all elements in `collection`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {string} key The key of the property to pluck. + * @returns {Array} Returns the property values. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * _.pluck(users, 'user'); + * // => ['barney', 'fred'] + * + * var userIndex = _.indexBy(users, 'user'); + * _.pluck(userIndex, 'age'); + * // => [36, 40] (iteration order is not guaranteed) + */ + function pluck(collection, key) { + return map(collection, baseProperty(key + '')); + } + + /** + * Reduces `collection` to a value which is the accumulated result of running + * each element in `collection` through `iteratee`, where each successive + * invocation is supplied the return value of the previous. If `accumulator` + * is not provided the first element of `collection` is used as the initial + * value. The `iteratee` is bound to `thisArg`and invoked with four arguments; + * (accumulator, value, index|key, collection). + * + * @static + * @memberOf _ + * @alias foldl, inject + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {*} Returns the accumulated value. + * @example + * + * var sum = _.reduce([1, 2, 3], function(sum, n) { return sum + n; }); + * // => 6 + * + * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, n, key) { + * result[key] = n * 3; + * return result; + * }, {}); + * // => { 'a': 3, 'b': 6, 'c': 9 } (iteration order is not guaranteed) + */ + function reduce(collection, iteratee, accumulator, thisArg) { + var func = isArray(collection) ? arrayReduce : baseReduce; + return func(collection, getCallback(iteratee, thisArg, 4), accumulator, arguments.length < 3, baseEach); + } + + /** + * This method is like `_.reduce` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @alias foldr + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {*} Returns the accumulated value. + * @example + * + * var array = [[0, 1], [2, 3], [4, 5]]; + * _.reduceRight(array, function(flattened, other) { return flattened.concat(other); }, []); + * // => [4, 5, 2, 3, 0, 1] + */ + function reduceRight(collection, iteratee, accumulator, thisArg) { + var func = isArray(collection) ? arrayReduceRight : baseReduce; + return func(collection, getCallback(iteratee, thisArg, 4), accumulator, arguments.length < 3, baseEachRight); + } + + /** + * The opposite of `_.filter`; this method returns the elements of `collection` + * that `predicate` does **not** return truthy for. + * + * If a property name is provided for `predicate` the created "_.property" + * style callback returns the property value of the given element. + * + * If an object is provided for `predicate` the created "_.matches" style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. If a property name or object is provided it is used to + * create a "_.property" or "_.matches" style callback respectively. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the new filtered array. + * @example + * + * var odds = _.reject([1, 2, 3, 4], function(n) { return n % 2 == 0; }); + * // => [1, 3] + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': true } + * ]; + * + * // using the "_.property" callback shorthand + * _.pluck(_.reject(users, 'active'), 'user'); + * // => ['barney'] + * + * // using the "_.matches" callback shorthand + * _.pluck(_.reject(users, { 'age': 36 }), 'user'); + * // => ['fred'] + */ + function reject(collection, predicate, thisArg) { + var func = isArray(collection) ? arrayFilter : baseFilter; + predicate = getCallback(predicate, thisArg, 3); + return func(collection, function(value, index, collection) { + return !predicate(value, index, collection); + }); + } + + /** + * Gets a random element or `n` random elements from a collection. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to sample. + * @param {number} [n] The number of elements to sample. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {*} Returns the random sample(s). + * @example + * + * _.sample([1, 2, 3, 4]); + * // => 2 + * + * _.sample([1, 2, 3, 4], 2); + * // => [3, 1] + */ + function sample(collection, n, guard) { + if (guard ? isIterateeCall(collection, n, guard) : n == null) { + collection = toIterable(collection); + var length = collection.length; + return length > 0 ? collection[baseRandom(0, length - 1)] : undefined; + } + var result = shuffle(collection); + result.length = nativeMin(n < 0 ? 0 : (+n || 0), result.length); + return result; + } + + /** + * Creates an array of shuffled values, using a version of the Fisher-Yates + * shuffle. See [Wikipedia](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle) + * for more details. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to shuffle. + * @returns {Array} Returns the new shuffled array. + * @example + * + * _.shuffle([1, 2, 3, 4]); + * // => [4, 1, 3, 2] + */ + function shuffle(collection) { + collection = toIterable(collection); + + var index = -1, + length = collection.length, + result = Array(length); + + while (++index < length) { + var rand = baseRandom(0, index); + if (index != rand) { + result[index] = result[rand]; + } + result[rand] = collection[index]; + } + return result; + } + + /** + * Gets the size of `collection` by returning `collection.length` for + * array-like values or the number of own enumerable properties for objects. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns the size of `collection`. + * @example + * + * _.size([1, 2]); + * // => 2 + * + * _.size({ 'one': 1, 'two': 2, 'three': 3 }); + * // => 3 + * + * _.size('pebbles'); + * // => 7 + */ + function size(collection) { + var length = collection ? collection.length : 0; + return isLength(length) ? length : keys(collection).length; + } + + /** + * Checks if `predicate` returns truthy for **any** element of `collection`. + * The function returns as soon as it finds a passing value and does not iterate + * over the entire collection. The predicate is bound to `thisArg` and invoked + * with three arguments; (value, index|key, collection). + * + * If a property name is provided for `predicate` the created "_.property" + * style callback returns the property value of the given element. + * + * If an object is provided for `predicate` the created "_.matches" style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias any + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. If a property name or object is provided it is used to + * create a "_.property" or "_.matches" style callback respectively. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + * @example + * + * _.some([null, 0, 'yes', false], Boolean); + * // => true + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': true } + * ]; + * + * // using the "_.property" callback shorthand + * _.some(users, 'active'); + * // => true + * + * // using the "_.matches" callback shorthand + * _.some(users, { 'age': 1 }); + * // => false + */ + function some(collection, predicate, thisArg) { + var func = isArray(collection) ? arraySome : baseSome; + if (typeof predicate != 'function' || typeof thisArg != 'undefined') { + predicate = getCallback(predicate, thisArg, 3); + } + return func(collection, predicate); + } + + /** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection through `iteratee`. This method performs + * a stable sort, that is, it preserves the original sort order of equal elements. + * The `iteratee` is bound to `thisArg` and invoked with three arguments; + * (value, index|key, collection). + * + * If a property name is provided for `predicate` the created "_.property" + * style callback returns the property value of the given element. + * + * If an object is provided for `predicate` the created "_.matches" style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|Function|Object|string} [iteratee=_.identity] The function + * invoked per iteration. If a property name or an object is provided it is + * used to create a "_.property" or "_.matches" style callback respectively. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new sorted array. + * @example + * + * _.sortBy([1, 2, 3], function(n) { return Math.sin(n); }); + * // => [3, 1, 2] + * + * _.sortBy([1, 2, 3], function(n) { return this.sin(n); }, Math); + * // => [3, 1, 2] + * + * var users = [ + * { 'user': 'fred' }, + * { 'user': 'pebbles' }, + * { 'user': 'barney' } + * ]; + * + * // using the "_.property" callback shorthand + * _.pluck(_.sortBy(users, 'user'), 'user'); + * // => ['barney', 'fred', 'pebbles'] + */ + function sortBy(collection, iteratee, thisArg) { + var index = -1, + length = collection ? collection.length : 0, + result = isLength(length) ? Array(length) : []; + + if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { + iteratee = null; + } + iteratee = getCallback(iteratee, thisArg, 3); + baseEach(collection, function(value, key, collection) { + result[++index] = { 'criteria': iteratee(value, key, collection), 'index': index, 'value': value }; + }); + return baseSortBy(result, compareAscending); + } + + /** + * This method is like `_.sortBy` except that it sorts by property names + * instead of an iteratee function. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {...(string|string[])} props The property names to sort by, + * specified as individual property names or arrays of property names. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'barney', 'age': 26 }, + * { 'user': 'fred', 'age': 30 } + * ]; + * + * _.map(_.sortByAll(users, ['user', 'age']), _.values); + * // => [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]] + */ + function sortByAll(collection) { + var args = arguments; + if (args.length > 3 && isIterateeCall(args[1], args[2], args[3])) { + args = [collection, args[1]]; + } + var index = -1, + length = collection ? collection.length : 0, + props = baseFlatten(args, false, false, 1), + result = isLength(length) ? Array(length) : []; + + baseEach(collection, function(value, key, collection) { + var length = props.length, + criteria = Array(length); + + while (length--) { + criteria[length] = value == null ? undefined : value[props[length]]; + } + result[++index] = { 'criteria': criteria, 'index': index, 'value': value }; + }); + return baseSortBy(result, compareMultipleAscending); + } + + /** + * Performs a deep comparison between each element in `collection` and the + * source object, returning an array of all elements that have equivalent + * property values. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Object} source The object of property values to match. + * @returns {Array} Returns the new filtered array. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'status': 'busy', 'pets': ['hoppy'] }, + * { 'user': 'fred', 'age': 40, 'status': 'busy', 'pets': ['baby puss', 'dino'] } + * ]; + * + * _.pluck(_.where(users, { 'age': 36 }), 'user'); + * // => ['barney'] + * + * _.pluck(_.where(users, { 'pets': ['dino'] }), 'user'); + * // => ['fred'] + * + * _.pluck(_.where(users, { 'status': 'busy' }), 'user'); + * // => ['barney', 'fred'] + */ + function where(collection, source) { + return filter(collection, baseMatches(source)); + } + + /*------------------------------------------------------------------------*/ + + /** + * Gets the number of milliseconds that have elapsed since the Unix epoch + * (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @category Date + * @example + * + * _.defer(function(stamp) { console.log(_.now() - stamp); }, _.now()); + * // => logs the number of milliseconds it took for the deferred function to be invoked + */ + var now = nativeNow || function() { + return new Date().getTime(); + }; + + /*------------------------------------------------------------------------*/ + + /** + * The opposite of `_.before`; this method creates a function that invokes + * `func` once it is called `n` or more times. + * + * @static + * @memberOf _ + * @category Function + * @param {number} n The number of calls before `func` is invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var saves = ['profile', 'settings']; + * + * var done = _.after(saves.length, function() { + * console.log('done saving!'); + * }); + * + * _.forEach(saves, function(type) { + * asyncSave({ 'type': type, 'complete': done }); + * }); + * // => logs 'done saving!' after the two async saves have completed + */ + function after(n, func) { + if (!isFunction(func)) { + if (isFunction(n)) { + var temp = n; + n = func; + func = temp; + } else { + throw new TypeError(FUNC_ERROR_TEXT); + } + } + n = nativeIsFinite(n = +n) ? n : 0; + return function() { + if (--n < 1) { + return func.apply(this, arguments); + } + }; + } + + /** + * Creates a function that accepts up to `n` arguments ignoring any + * additional arguments. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to cap arguments for. + * @param {number} [n=func.length] The arity cap. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Function} Returns the new function. + * @example + * + * _.map(['6', '8', '10'], _.ary(parseInt, 1)); + * // => [6, 8, 10] + */ + function ary(func, n, guard) { + if (guard && isIterateeCall(func, n, guard)) { + n = null; + } + n = (func && n == null) ? func.length : nativeMax(+n || 0, 0); + return createWrapper(func, ARY_FLAG, null, null, null, null, n); + } + + /** + * Creates a function that invokes `func`, with the `this` binding and arguments + * of the created function, while it is called less than `n` times. Subsequent + * calls to the created function return the result of the last `func` invocation. + * + * @static + * @memberOf _ + * @category Function + * @param {number} n The number of calls at which `func` is no longer invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * jQuery('#add').on('click', _.before(5, addContactToList)); + * // => allows adding up to 4 contacts to the list + */ + function before(n, func) { + var result; + if (!isFunction(func)) { + if (isFunction(n)) { + var temp = n; + n = func; + func = temp; + } else { + throw new TypeError(FUNC_ERROR_TEXT); + } + } + return function() { + if (--n > 0) { + result = func.apply(this, arguments); + } else { + func = null; + } + return result; + }; + } + + /** + * Creates a function that invokes `func` with the `this` binding of `thisArg` + * and prepends any additional `_.bind` arguments to those provided to the + * bound function. + * + * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for partially applied arguments. + * + * **Note:** Unlike native `Function#bind` this method does not set the `length` + * property of bound functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to bind. + * @param {*} thisArg The `this` binding of `func`. + * @param {...*} [args] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var greet = function(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * }; + * + * var object = { 'user': 'fred' }; + * + * var bound = _.bind(greet, object, 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * // using placeholders + * var bound = _.bind(greet, object, _, '!'); + * bound('hi'); + * // => 'hi fred!' + */ + function bind(func, thisArg) { + var bitmask = BIND_FLAG; + if (arguments.length > 2) { + var partials = baseSlice(arguments, 2), + holders = replaceHolders(partials, bind.placeholder); + + bitmask |= PARTIAL_FLAG; + } + return createWrapper(func, bitmask, thisArg, partials, holders); + } + + /** + * Binds methods of an object to the object itself, overwriting the existing + * method. Method names may be specified as individual arguments or as arrays + * of method names. If no method names are provided all enumerable function + * properties, own and inherited, of `object` are bound. + * + * **Note:** This method does not set the `length` property of bound functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Object} object The object to bind and assign the bound methods to. + * @param {...(string|string[])} [methodNames] The object method names to bind, + * specified as individual method names or arrays of method names. + * @returns {Object} Returns `object`. + * @example + * + * var view = { + * 'label': 'docs', + * 'onClick': function() { console.log('clicked ' + this.label); } + * }; + * + * _.bindAll(view); + * jQuery('#docs').on('click', view.onClick); + * // => logs 'clicked docs' when the element is clicked + */ + function bindAll(object) { + return baseBindAll(object, + arguments.length > 1 + ? baseFlatten(arguments, false, false, 1) + : functions(object) + ); + } + + /** + * Creates a function that invokes the method at `object[key]` and prepends + * any additional `_.bindKey` arguments to those provided to the bound function. + * + * This method differs from `_.bind` by allowing bound functions to reference + * methods that may be redefined or don't yet exist. + * See [Peter Michaux's article](http://michaux.ca/articles/lazy-function-definition-pattern) + * for more details. + * + * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * @static + * @memberOf _ + * @category Function + * @param {Object} object The object the method belongs to. + * @param {string} key The key of the method. + * @param {...*} [args] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var object = { + * 'user': 'fred', + * 'greet': function(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * } + * }; + * + * var bound = _.bindKey(object, 'greet', 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * object.greet = function(greeting, punctuation) { + * return greeting + 'ya ' + this.user + punctuation; + * }; + * + * bound('!'); + * // => 'hiya fred!' + * + * // using placeholders + * var bound = _.bindKey(object, 'greet', _, '!'); + * bound('hi'); + * // => 'hiya fred!' + */ + function bindKey(object, key) { + var bitmask = BIND_FLAG | BIND_KEY_FLAG; + if (arguments.length > 2) { + var partials = baseSlice(arguments, 2), + holders = replaceHolders(partials, bindKey.placeholder); + + bitmask |= PARTIAL_FLAG; + } + return createWrapper(key, bitmask, object, partials, holders); + } + + /** + * Creates a function that accepts one or more arguments of `func` that when + * called either invokes `func` returning its result, if all `func` arguments + * have been provided, or returns a function that accepts one or more of the + * remaining `func` arguments, and so on. The arity of `func` may be specified + * if `func.length` is not sufficient. + * + * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for provided arguments. + * + * **Note:** This method does not set the `length` property of curried functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Function} Returns the new curried function. + * @example + * + * var abc = function(a, b, c) { + * return [a, b, c]; + * }; + * + * var curried = _.curry(abc); + * + * curried(1)(2)(3); + * // => [1, 2, 3] + * + * curried(1, 2)(3); + * // => [1, 2, 3] + * + * curried(1, 2, 3); + * // => [1, 2, 3] + * + * // using placeholders + * curried(1)(_, 3)(2); + * // => [1, 2, 3] + */ + function curry(func, arity, guard) { + if (guard && isIterateeCall(func, arity, guard)) { + arity = null; + } + var result = createWrapper(func, CURRY_FLAG, null, null, null, null, null, arity); + result.placeholder = curry.placeholder; + return result; + } + + /** + * This method is like `_.curry` except that arguments are applied to `func` + * in the manner of `_.partialRight` instead of `_.partial`. + * + * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for provided arguments. + * + * **Note:** This method does not set the `length` property of curried functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Function} Returns the new curried function. + * @example + * + * var abc = function(a, b, c) { + * return [a, b, c]; + * }; + * + * var curried = _.curryRight(abc); + * + * curried(3)(2)(1); + * // => [1, 2, 3] + * + * curried(2, 3)(1); + * // => [1, 2, 3] + * + * curried(1, 2, 3); + * // => [1, 2, 3] + * + * // using placeholders + * curried(3)(1, _)(2); + * // => [1, 2, 3] + */ + function curryRight(func, arity, guard) { + if (guard && isIterateeCall(func, arity, guard)) { + arity = null; + } + var result = createWrapper(func, CURRY_RIGHT_FLAG, null, null, null, null, null, arity); + result.placeholder = curryRight.placeholder; + return result; + } + + /** + * Creates a function that delays invoking `func` until after `wait` milliseconds + * have elapsed since the last time it was invoked. The created function comes + * with a `cancel` method to cancel delayed invocations. Provide an options + * object to indicate that `func` should be invoked on the leading and/or + * trailing edge of the `wait` timeout. Subsequent calls to the debounced + * function return the result of the last `func` invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked + * on the trailing edge of the timeout only if the the debounced function is + * invoked more than once during the `wait` timeout. + * + * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) + * for details over the differences between `_.debounce` and `_.throttle`. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to debounce. + * @param {number} wait The number of milliseconds to delay. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=false] Specify invoking on the leading + * edge of the timeout. + * @param {number} [options.maxWait] The maximum time `func` is allowed to be + * delayed before it is invoked. + * @param {boolean} [options.trailing=true] Specify invoking on the trailing + * edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * // avoid costly calculations while the window size is in flux + * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); + * + * // invoke `sendMail` when the click event is fired, debouncing subsequent calls + * jQuery('#postbox').on('click', _.debounce(sendMail, 300, { + * 'leading': true, + * 'trailing': false + * })); + * + * // ensure `batchLog` is invoked once after 1 second of debounced calls + * var source = new EventSource('/stream'); + * jQuery(source).on('message', _.debounce(batchLog, 250, { + * 'maxWait': 1000 + * })); + * + * // cancel a debounced call + * var todoChanges = _.debounce(batchLog, 1000); + * Object.observe(models.todo, todoChanges); + * + * Object.observe(models, function(changes) { + * if (_.find(changes, { 'user': 'todo', 'type': 'delete'})) { + * todoChanges.cancel(); + * } + * }, ['delete']); + * + * // ...at some point `models.todo` is changed + * models.todo.completed = true; + * + * // ...before 1 second has passed `models.todo` is deleted + * // which cancels the debounced `todoChanges` call + * delete models.todo; + */ + function debounce(func, wait, options) { + var args, + maxTimeoutId, + result, + stamp, + thisArg, + timeoutId, + trailingCall, + lastCalled = 0, + maxWait = false, + trailing = true; + + if (!isFunction(func)) { + throw new TypeError(FUNC_ERROR_TEXT); + } + wait = wait < 0 ? 0 : wait; + if (options === true) { + var leading = true; + trailing = false; + } else if (isObject(options)) { + leading = options.leading; + maxWait = 'maxWait' in options && nativeMax(+options.maxWait || 0, wait); + trailing = 'trailing' in options ? options.trailing : trailing; + } + + function cancel() { + if (timeoutId) { + clearTimeout(timeoutId); + } + if (maxTimeoutId) { + clearTimeout(maxTimeoutId); + } + maxTimeoutId = timeoutId = trailingCall = undefined; + } + + function delayed() { + var remaining = wait - (now() - stamp); + if (remaining <= 0 || remaining > wait) { + if (maxTimeoutId) { + clearTimeout(maxTimeoutId); + } + var isCalled = trailingCall; + maxTimeoutId = timeoutId = trailingCall = undefined; + if (isCalled) { + lastCalled = now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = null; + } + } + } else { + timeoutId = setTimeout(delayed, remaining); + } + } + + function maxDelayed() { + if (timeoutId) { + clearTimeout(timeoutId); + } + maxTimeoutId = timeoutId = trailingCall = undefined; + if (trailing || (maxWait !== wait)) { + lastCalled = now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = null; + } + } + } + + function debounced() { + args = arguments; + stamp = now(); + thisArg = this; + trailingCall = trailing && (timeoutId || !leading); + + if (maxWait === false) { + var leadingCall = leading && !timeoutId; + } else { + if (!maxTimeoutId && !leading) { + lastCalled = stamp; + } + var remaining = maxWait - (stamp - lastCalled), + isCalled = remaining <= 0 || remaining > maxWait; + + if (isCalled) { + if (maxTimeoutId) { + maxTimeoutId = clearTimeout(maxTimeoutId); + } + lastCalled = stamp; + result = func.apply(thisArg, args); + } + else if (!maxTimeoutId) { + maxTimeoutId = setTimeout(maxDelayed, remaining); + } + } + if (isCalled && timeoutId) { + timeoutId = clearTimeout(timeoutId); + } + else if (!timeoutId && wait !== maxWait) { + timeoutId = setTimeout(delayed, wait); + } + if (leadingCall) { + isCalled = true; + result = func.apply(thisArg, args); + } + if (isCalled && !timeoutId && !maxTimeoutId) { + args = thisArg = null; + } + return result; + } + debounced.cancel = cancel; + return debounced; + } + + /** + * Defers invoking the `func` until the current call stack has cleared. Any + * additional arguments are provided to `func` when it is invoked. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to defer. + * @param {...*} [args] The arguments to invoke the function with. + * @returns {number} Returns the timer id. + * @example + * + * _.defer(function(text) { console.log(text); }, 'deferred'); + * // logs 'deferred' after one or more milliseconds + */ + function defer(func) { + return baseDelay(func, 1, arguments, 1); + } + + /** + * Invokes `func` after `wait` milliseconds. Any additional arguments are + * provided to `func` when it is invoked. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {...*} [args] The arguments to invoke the function with. + * @returns {number} Returns the timer id. + * @example + * + * _.delay(function(text) { console.log(text); }, 1000, 'later'); + * // => logs 'later' after one second + */ + function delay(func, wait) { + return baseDelay(func, wait, arguments, 2); + } + + /** + * Creates a function that returns the result of invoking the provided + * functions with the `this` binding of the created function, where each + * successive invocation is supplied the return value of the previous. + * + * @static + * @memberOf _ + * @category Function + * @param {...Function} [funcs] Functions to invoke. + * @returns {Function} Returns the new function. + * @example + * + * function add(x, y) { + * return x + y; + * } + * + * function square(n) { + * return n * n; + * } + * + * var addSquare = _.flow(add, square); + * addSquare(1, 2); + * // => 9 + */ + function flow() { + var funcs = arguments, + length = funcs.length; + + if (!length) { + return function() {}; + } + if (!arrayEvery(funcs, isFunction)) { + throw new TypeError(FUNC_ERROR_TEXT); + } + return function() { + var index = 0, + result = funcs[index].apply(this, arguments); + + while (++index < length) { + result = funcs[index].call(this, result); + } + return result; + }; + } + + /** + * This method is like `_.flow` except that it creates a function that + * invokes the provided functions from right to left. + * + * @static + * @memberOf _ + * @alias backflow, compose + * @category Function + * @param {...Function} [funcs] Functions to invoke. + * @returns {Function} Returns the new function. + * @example + * + * function add(x, y) { + * return x + y; + * } + * + * function square(n) { + * return n * n; + * } + * + * var addSquare = _.flowRight(square, add); + * addSquare(1, 2); + * // => 9 + */ + function flowRight() { + var funcs = arguments, + fromIndex = funcs.length - 1; + + if (fromIndex < 0) { + return function() {}; + } + if (!arrayEvery(funcs, isFunction)) { + throw new TypeError(FUNC_ERROR_TEXT); + } + return function() { + var index = fromIndex, + result = funcs[index].apply(this, arguments); + + while (index--) { + result = funcs[index].call(this, result); + } + return result; + }; + } + + /** + * Creates a function that memoizes the result of `func`. If `resolver` is + * provided it determines the cache key for storing the result based on the + * arguments provided to the memoized function. By default, the first argument + * provided to the memoized function is coerced to a string and used as the + * cache key. The `func` is invoked with the `this` binding of the memoized + * function. + * + * **Note:** The cache is exposed as the `cache` property on the memoized + * function. Its creation may be customized by replacing the `_.memoize.Cache` + * constructor with one whose instances implement the ES `Map` method interface + * of `get`, `has`, and `set`. See the + * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-properties-of-the-map-prototype-object) + * for more details. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] The function to resolve the cache key. + * @returns {Function} Returns the new memoizing function. + * @example + * + * var upperCase = _.memoize(function(string) { + * return string.toUpperCase(); + * }); + * + * upperCase('fred'); + * // => 'FRED' + * + * // modifying the result cache + * upperCase.cache.set('fred', 'BARNEY'); + * upperCase('fred'); + * // => 'BARNEY' + * + * // replacing `_.memoize.Cache` + * var object = { 'user': 'fred' }; + * var other = { 'user': 'barney' }; + * var identity = _.memoize(_.identity); + * + * identity(object); + * // => { 'user': 'fred' } + * identity(other); + * // => { 'user': 'fred' } + * + * _.memoize.Cache = WeakMap; + * var identity = _.memoize(_.identity); + * + * identity(object); + * // => { 'user': 'fred' } + * identity(other); + * // => { 'user': 'barney' } + */ + function memoize(func, resolver) { + if (!isFunction(func) || (resolver && !isFunction(resolver))) { + throw new TypeError(FUNC_ERROR_TEXT); + } + var memoized = function() { + var cache = memoized.cache, + key = resolver ? resolver.apply(this, arguments) : arguments[0]; + + if (cache.has(key)) { + return cache.get(key); + } + var result = func.apply(this, arguments); + cache.set(key, result); + return result; + }; + memoized.cache = new memoize.Cache; + return memoized; + } + + /** + * Creates a function that negates the result of the predicate `func`. The + * `func` predicate is invoked with the `this` binding and arguments of the + * created function. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} predicate The predicate to negate. + * @returns {Function} Returns the new function. + * @example + * + * function isEven(n) { + * return n % 2 == 0; + * } + * + * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); + * // => [1, 3, 5] + */ + function negate(predicate) { + if (!isFunction(predicate)) { + throw new TypeError(FUNC_ERROR_TEXT); + } + return function() { + return !predicate.apply(this, arguments); + }; + } + + /** + * Creates a function that is restricted to invoking `func` once. Repeat calls + * to the function return the value of the first call. The `func` is invoked + * with the `this` binding of the created function. + * + * @static + * @memberOf _ + * @type Function + * @category Function + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var initialize = _.once(createApplication); + * initialize(); + * initialize(); + * // `initialize` invokes `createApplication` once + */ + function once(func) { + return before(func, 2); + } + + /** + * Creates a function that invokes `func` with `partial` arguments prepended + * to those provided to the new function. This method is like `_.bind` except + * it does **not** alter the `this` binding. + * + * The `_.partial.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * **Note:** This method does not set the `length` property of partially + * applied functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [args] The arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var greet = function(greeting, name) { + * return greeting + ' ' + name; + * }; + * + * var sayHelloTo = _.partial(greet, 'hello'); + * sayHelloTo('fred'); + * // => 'hello fred' + * + * // using placeholders + * var greetFred = _.partial(greet, _, 'fred'); + * greetFred('hi'); + * // => 'hi fred' + */ + function partial(func) { + var partials = baseSlice(arguments, 1), + holders = replaceHolders(partials, partial.placeholder); + + return createWrapper(func, PARTIAL_FLAG, null, partials, holders); + } + + /** + * This method is like `_.partial` except that partially applied arguments + * are appended to those provided to the new function. + * + * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * **Note:** This method does not set the `length` property of partially + * applied functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [args] The arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. + * @example + * + * var greet = function(greeting, name) { + * return greeting + ' ' + name; + * }; + * + * var greetFred = _.partialRight(greet, 'fred'); + * greetFred('hi'); + * // => 'hi fred' + * + * // using placeholders + * var sayHelloTo = _.partialRight(greet, 'hello', _); + * sayHelloTo('fred'); + * // => 'hello fred' + */ + function partialRight(func) { + var partials = baseSlice(arguments, 1), + holders = replaceHolders(partials, partialRight.placeholder); + + return createWrapper(func, PARTIAL_RIGHT_FLAG, null, partials, holders); + } + + /** + * Creates a function that invokes `func` with arguments arranged according + * to the specified indexes where the argument value at the first index is + * provided as the first argument, the argument value at the second index is + * provided as the second argument, and so on. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to rearrange arguments for. + * @param {...(number|number[])} indexes The arranged argument indexes, + * specified as individual indexes or arrays of indexes. + * @returns {Function} Returns the new function. + * @example + * + * var rearged = _.rearg(function(a, b, c) { + * return [a, b, c]; + * }, 2, 0, 1); + * + * rearged('b', 'c', 'a') + * // => ['a', 'b', 'c'] + * + * var map = _.rearg(_.map, [1, 0]); + * map(function(n) { return n * 3; }, [1, 2, 3]); + * // => [3, 6, 9] + */ + function rearg(func) { + var indexes = baseFlatten(arguments, false, false, 1); + return createWrapper(func, REARG_FLAG, null, null, null, indexes); + } + + /** + * Creates a function that only invokes `func` at most once per every `wait` + * milliseconds. The created function comes with a `cancel` method to cancel + * delayed invocations. Provide an options object to indicate that `func` + * should be invoked on the leading and/or trailing edge of the `wait` timeout. + * Subsequent calls to the throttled function return the result of the last + * `func` call. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked + * on the trailing edge of the timeout only if the the throttled function is + * invoked more than once during the `wait` timeout. + * + * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) + * for details over the differences between `_.throttle` and `_.debounce`. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to throttle. + * @param {number} wait The number of milliseconds to throttle invocations to. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=true] Specify invoking on the leading + * edge of the timeout. + * @param {boolean} [options.trailing=true] Specify invoking on the trailing + * edge of the timeout. + * @returns {Function} Returns the new throttled function. + * @example + * + * // avoid excessively updating the position while scrolling + * jQuery(window).on('scroll', _.throttle(updatePosition, 100)); + * + * // invoke `renewToken` when the click event is fired, but not more than once every 5 minutes + * var throttled = _.throttle(renewToken, 300000, { 'trailing': false }) + * jQuery('.interactive').on('click', throttled); + * + * // cancel a trailing throttled call + * jQuery(window).on('popstate', throttled.cancel); + */ + function throttle(func, wait, options) { + var leading = true, + trailing = true; + + if (!isFunction(func)) { + throw new TypeError(FUNC_ERROR_TEXT); + } + if (options === false) { + leading = false; + } else if (isObject(options)) { + leading = 'leading' in options ? !!options.leading : leading; + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + debounceOptions.leading = leading; + debounceOptions.maxWait = +wait; + debounceOptions.trailing = trailing; + return debounce(func, wait, debounceOptions); + } + + /** + * Creates a function that provides `value` to the wrapper function as its + * first argument. Any additional arguments provided to the function are + * appended to those provided to the wrapper function. The wrapper is invoked + * with the `this` binding of the created function. + * + * @static + * @memberOf _ + * @category Function + * @param {*} value The value to wrap. + * @param {Function} wrapper The wrapper function. + * @returns {Function} Returns the new function. + * @example + * + * var p = _.wrap(_.escape, function(func, text) { + * return '

' + func(text) + '

'; + * }); + * + * p('fred, barney, & pebbles'); + * // => '

fred, barney, & pebbles

' + */ + function wrap(value, wrapper) { + wrapper = wrapper == null ? identity : wrapper; + return createWrapper(wrapper, PARTIAL_FLAG, null, [value], []); + } + + /*------------------------------------------------------------------------*/ + + /** + * Creates a clone of `value`. If `isDeep` is `true` nested objects are cloned, + * otherwise they are assigned by reference. If `customizer` is provided it is + * invoked to produce the cloned values. If `customizer` returns `undefined` + * cloning is handled by the method instead. The `customizer` is bound to + * `thisArg` and invoked with two argument; (value [, index|key, object]). + * + * **Note:** This method is loosely based on the structured clone algorithm. + * The enumerable properties of `arguments` objects and objects created by + * constructors other than `Object` are cloned to plain `Object` objects. An + * empty object is returned for uncloneable values such as functions, DOM nodes, + * Maps, Sets, and WeakMaps. See the [HTML5 specification](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm) + * for more details. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @param {Function} [customizer] The function to customize cloning values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {*} Returns the cloned value. + * @example + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * var shallow = _.clone(users); + * shallow[0] === users[0]; + * // => true + * + * var deep = _.clone(users, true); + * deep[0] === users[0]; + * // => false + * + * // using a customizer callback + * var body = _.clone(document.body, function(value) { + * return _.isElement(value) ? value.cloneNode(false) : undefined; + * }); + * + * body === document.body + * // => false + * body.nodeName + * // => BODY + * body.childNodes.length; + * // => 0 + */ + function clone(value, isDeep, customizer, thisArg) { + // Juggle arguments. + if (typeof isDeep != 'boolean' && isDeep != null) { + thisArg = customizer; + customizer = isIterateeCall(value, isDeep, thisArg) ? null : isDeep; + isDeep = false; + } + customizer = typeof customizer == 'function' && bindCallback(customizer, thisArg, 1); + return baseClone(value, isDeep, customizer); + } + + /** + * Creates a deep clone of `value`. If `customizer` is provided it is invoked + * to produce the cloned values. If `customizer` returns `undefined` cloning + * is handled by the method instead. The `customizer` is bound to `thisArg` + * and invoked with two argument; (value [, index|key, object]). + * + * **Note:** This method is loosely based on the structured clone algorithm. + * The enumerable properties of `arguments` objects and objects created by + * constructors other than `Object` are cloned to plain `Object` objects. An + * empty object is returned for uncloneable values such as functions, DOM nodes, + * Maps, Sets, and WeakMaps. See the [HTML5 specification](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm) + * for more details. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to deep clone. + * @param {Function} [customizer] The function to customize cloning values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {*} Returns the deep cloned value. + * @example + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * var deep = _.cloneDeep(users); + * deep[0] === users[0]; + * // => false + * + * // using a customizer callback + * var el = _.cloneDeep(document.body, function(value) { + * return _.isElement(value) ? value.cloneNode(true) : undefined; + * }); + * + * body === document.body + * // => false + * body.nodeName + * // => BODY + * body.childNodes.length; + * // => 20 + */ + function cloneDeep(value, customizer, thisArg) { + customizer = typeof customizer == 'function' && bindCallback(customizer, thisArg, 1); + return baseClone(value, true, customizer); + } + + /** + * Checks if `value` is classified as an `arguments` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * (function() { return _.isArguments(arguments); })(); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + function isArguments(value) { + var length = isObjectLike(value) ? value.length : undefined; + return (isLength(length) && objToString.call(value) == argsTag) || false; + } + + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * (function() { return _.isArray(arguments); })(); + * // => false + */ + var isArray = nativeIsArray || function(value) { + return (isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag) || false; + }; + + /** + * Checks if `value` is classified as a boolean primitive or object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isBoolean(false); + * // => true + * + * _.isBoolean(null); + * // => false + */ + function isBoolean(value) { + return (value === true || value === false || isObjectLike(value) && objToString.call(value) == boolTag) || false; + } + + /** + * Checks if `value` is classified as a `Date` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isDate(new Date); + * // => true + * + * _.isDate('Mon April 23 2012'); + * // => false + */ + function isDate(value) { + return (isObjectLike(value) && objToString.call(value) == dateTag) || false; + } + + /** + * Checks if `value` is a DOM element. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`. + * @example + * + * _.isElement(document.body); + * // => true + * + * _.isElement(''); + * // => false + */ + function isElement(value) { + return (value && value.nodeType === 1 && isObjectLike(value) && + objToString.call(value).indexOf('Element') > -1) || false; + } + // Fallback for environments without DOM support. + if (!support.dom) { + isElement = function(value) { + return (value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value)) || false; + }; + } + + /** + * Checks if a value is empty. A value is considered empty unless it is an + * `arguments` object, array, string, or jQuery-like collection with a length + * greater than `0` or an object with own enumerable properties. + * + * @static + * @memberOf _ + * @category Lang + * @param {Array|Object|string} value The value to inspect. + * @returns {boolean} Returns `true` if `value` is empty, else `false`. + * @example + * + * _.isEmpty(null); + * // => true + * + * _.isEmpty(true); + * // => true + * + * _.isEmpty(1); + * // => true + * + * _.isEmpty([1, 2, 3]); + * // => false + * + * _.isEmpty({ 'a': 1 }); + * // => false + */ + function isEmpty(value) { + if (value == null) { + return true; + } + var length = value.length; + if (isLength(length) && (isArray(value) || isString(value) || isArguments(value) || + (isObjectLike(value) && isFunction(value.splice)))) { + return !length; + } + return !keys(value).length; + } + + /** + * Performs a deep comparison between two values to determine if they are + * equivalent. If `customizer` is provided it is invoked to compare values. + * If `customizer` returns `undefined` comparisons are handled by the method + * instead. The `customizer` is bound to `thisArg` and invoked with three + * arguments; (value, other [, index|key]). + * + * **Note:** This method supports comparing arrays, booleans, `Date` objects, + * numbers, `Object` objects, regexes, and strings. Functions and DOM nodes + * are **not** supported. Provide a customizer function to extend support + * for comparing other values. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {Function} [customizer] The function to customize comparing values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'user': 'fred' }; + * var other = { 'user': 'fred' }; + * + * object == other; + * // => false + * + * _.isEqual(object, other); + * // => true + * + * // using a customizer callback + * var array = ['hello', 'goodbye']; + * var other = ['hi', 'goodbye']; + * + * _.isEqual(array, other, function(value, other) { + * return _.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/) || undefined; + * }); + * // => true + */ + function isEqual(value, other, customizer, thisArg) { + customizer = typeof customizer == 'function' && bindCallback(customizer, thisArg, 3); + if (!customizer && isStrictComparable(value) && isStrictComparable(other)) { + return value === other; + } + var result = customizer ? customizer(value, other) : undefined; + return typeof result == 'undefined' ? baseIsEqual(value, other, customizer) : !!result; + } + + /** + * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`, + * `SyntaxError`, `TypeError`, or `URIError` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an error object, else `false`. + * @example + * + * _.isError(new Error); + * // => true + * + * _.isError(Error); + * // => false + */ + function isError(value) { + return (isObjectLike(value) && typeof value.message == 'string' && objToString.call(value) == errorTag) || false; + } + + /** + * Checks if `value` is a finite primitive number. + * + * **Note:** This method is based on ES `Number.isFinite`. See the + * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isfinite) + * for more details. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a finite number, else `false`. + * @example + * + * _.isFinite(10); + * // => true + * + * _.isFinite('10'); + * // => false + * + * _.isFinite(true); + * // => false + * + * _.isFinite(Object(10)); + * // => false + * + * _.isFinite(Infinity); + * // => false + */ + var isFinite = nativeNumIsFinite || function(value) { + return typeof value == 'number' && nativeIsFinite(value); + }; + + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + function isFunction(value) { + // Avoid a Chakra JIT bug in compatibility modes of IE 11. + // See https://github.com/jashkenas/underscore/issues/1621 for more details. + return typeof value == 'function' || false; + } + // Fallback for environments that return incorrect `typeof` operator results. + if (isFunction(/x/) || (Uint8Array && !isFunction(Uint8Array))) { + isFunction = function(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in older versions of Chrome and Safari which return 'function' for regexes + // and Safari 8 equivalents which return 'object' for typed array constructors. + return objToString.call(value) == funcTag; + }; + } + + /** + * Checks if `value` is the language type of `Object`. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * **Note:** See the [ES5 spec](https://es5.github.io/#x8) for more details. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(1); + * // => false + */ + function isObject(value) { + // Avoid a V8 JIT bug in Chrome 19-20. + // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. + var type = typeof value; + return type == 'function' || (value && type == 'object') || false; + } + + /** + * Performs a deep comparison between `object` and `source` to determine if + * `object` contains equivalent property values. If `customizer` is provided + * it is invoked to compare values. If `customizer` returns `undefined` + * comparisons are handled by the method instead. The `customizer` is bound + * to `thisArg` and invoked with three arguments; (value, other, index|key). + * + * **Note:** This method supports comparing properties of arrays, booleans, + * `Date` objects, numbers, `Object` objects, regexes, and strings. Functions + * and DOM nodes are **not** supported. Provide a customizer function to extend + * support for comparing other values. + * + * @static + * @memberOf _ + * @category Lang + * @param {Object} source The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Function} [customizer] The function to customize comparing values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + * @example + * + * var object = { 'user': 'fred', 'age': 40 }; + * + * _.isMatch(object, { 'age': 40 }); + * // => true + * + * _.isMatch(object, { 'age': 36 }); + * // => false + * + * // using a customizer callback + * var object = { 'greeting': 'hello' }; + * var source = { 'greeting': 'hi' }; + * + * _.isMatch(object, source, function(value, other) { + * return _.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/) || undefined; + * }); + * // => true + */ + function isMatch(object, source, customizer, thisArg) { + var props = keys(source), + length = props.length; + + customizer = typeof customizer == 'function' && bindCallback(customizer, thisArg, 3); + if (!customizer && length == 1) { + var key = props[0], + value = source[key]; + + if (isStrictComparable(value)) { + return object != null && value === object[key] && hasOwnProperty.call(object, key); + } + } + var values = Array(length), + strictCompareFlags = Array(length); + + while (length--) { + value = values[length] = source[props[length]]; + strictCompareFlags[length] = isStrictComparable(value); + } + return baseIsMatch(object, props, values, strictCompareFlags, customizer); + } + + /** + * Checks if `value` is `NaN`. + * + * **Note:** This method is not the same as native `isNaN` which returns `true` + * for `undefined` and other non-numeric values. See the [ES5 spec](https://es5.github.io/#x15.1.2.4) + * for more details. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + * @example + * + * _.isNaN(NaN); + * // => true + * + * _.isNaN(new Number(NaN)); + * // => true + * + * isNaN(undefined); + * // => true + * + * _.isNaN(undefined); + * // => false + */ + function isNaN(value) { + // An `NaN` primitive is the only value that is not equal to itself. + // Perform the `toStringTag` check first to avoid errors with some host objects in IE. + return isNumber(value) && value != +value; + } + + /** + * Checks if `value` is a native function. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, else `false`. + * @example + * + * _.isNative(Array.prototype.push); + * // => true + * + * _.isNative(_); + * // => false + */ + function isNative(value) { + if (value == null) { + return false; + } + if (objToString.call(value) == funcTag) { + return reNative.test(fnToString.call(value)); + } + return (isObjectLike(value) && reHostCtor.test(value)) || false; + } + + /** + * Checks if `value` is `null`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `null`, else `false`. + * @example + * + * _.isNull(null); + * // => true + * + * _.isNull(void 0); + * // => false + */ + function isNull(value) { + return value === null; + } + + /** + * Checks if `value` is classified as a `Number` primitive or object. + * + * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are classified + * as numbers, use the `_.isFinite` method. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isNumber(8.4); + * // => true + * + * _.isNumber(NaN); + * // => true + * + * _.isNumber('8.4'); + * // => false + */ + function isNumber(value) { + return typeof value == 'number' || (isObjectLike(value) && objToString.call(value) == numberTag) || false; + } + + /** + * Checks if `value` is a plain object, that is, an object created by the + * `Object` constructor or one with a `[[Prototype]]` of `null`. + * + * **Note:** This method assumes objects created by the `Object` constructor + * have no inherited enumerable properties. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * _.isPlainObject(new Foo); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + * + * _.isPlainObject(Object.create(null)); + * // => true + */ + var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) { + if (!(value && objToString.call(value) == objectTag)) { + return false; + } + var valueOf = value.valueOf, + objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto); + + return objProto + ? (value == objProto || getPrototypeOf(value) == objProto) + : shimIsPlainObject(value); + }; + + /** + * Checks if `value` is classified as a `RegExp` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isRegExp(/abc/); + * // => true + * + * _.isRegExp('/abc/'); + * // => false + */ + function isRegExp(value) { + return (isObjectLike(value) && objToString.call(value) == regexpTag) || false; + } + + /** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ + function isString(value) { + return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag) || false; + } + + /** + * Checks if `value` is classified as a typed array. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * _.isTypedArray(new Uint8Array); + * // => true + * + * _.isTypedArray([]); + * // => false + */ + function isTypedArray(value) { + return (isObjectLike(value) && isLength(value.length) && typedArrayTags[objToString.call(value)]) || false; + } + + /** + * Checks if `value` is `undefined`. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ + function isUndefined(value) { + return typeof value == 'undefined'; + } + + /** + * Converts `value` to an array. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {Array} Returns the converted array. + * @example + * + * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3); + * // => [2, 3] + */ + function toArray(value) { + var length = value ? value.length : 0; + if (!isLength(length)) { + return values(value); + } + if (!length) { + return []; + } + return arrayCopy(value); + } + + /** + * Converts `value` to a plain object flattening inherited enumerable + * properties of `value` to own properties of the plain object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {Object} Returns the converted plain object. + * @example + * + * function Foo() { + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.assign({ 'a': 1 }, new Foo); + * // => { 'a': 1, 'b': 2 } + * + * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); + * // => { 'a': 1, 'b': 2, 'c': 3 } + */ + function toPlainObject(value) { + return baseCopy(value, keysIn(value)); + } + + /*------------------------------------------------------------------------*/ + + /** + * Assigns own enumerable properties of source object(s) to the destination + * object. Subsequent sources overwrite property assignments of previous sources. + * If `customizer` is provided it is invoked to produce the assigned values. + * The `customizer` is bound to `thisArg` and invoked with five arguments; + * (objectValue, sourceValue, key, object, source). + * + * @static + * @memberOf _ + * @alias extend + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @param {Function} [customizer] The function to customize assigning values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {Object} Returns `object`. + * @example + * + * _.assign({ 'user': 'barney' }, { 'age': 40 }, { 'user': 'fred' }); + * // => { 'user': 'fred', 'age': 40 } + * + * // using a customizer callback + * var defaults = _.partialRight(_.assign, function(value, other) { + * return typeof value == 'undefined' ? other : value; + * }); + * + * defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); + * // => { 'user': 'barney', 'age': 36 } + */ + var assign = createAssigner(baseAssign); + + /** + * Creates an object that inherits from the given `prototype` object. If a + * `properties` object is provided its own enumerable properties are assigned + * to the created object. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} prototype The object to inherit from. + * @param {Object} [properties] The properties to assign to the object. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Object} Returns the new object. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * function Circle() { + * Shape.call(this); + * } + * + * Circle.prototype = _.create(Shape.prototype, { 'constructor': Circle }); + * + * var circle = new Circle; + * circle instanceof Circle; + * // => true + * + * circle instanceof Shape; + * // => true + */ + function create(prototype, properties, guard) { + var result = baseCreate(prototype); + if (guard && isIterateeCall(prototype, properties, guard)) { + properties = null; + } + return properties ? baseCopy(properties, result, keys(properties)) : result; + } + + /** + * Assigns own enumerable properties of source object(s) to the destination + * object for all destination properties that resolve to `undefined`. Once a + * property is set, additional defaults of the same property are ignored. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example + * + * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); + * // => { 'user': 'barney', 'age': 36 } + */ + function defaults(object) { + if (object == null) { + return object; + } + var args = arrayCopy(arguments); + args.push(assignDefaults); + return assign.apply(undefined, args); + } + + /** + * This method is like `_.findIndex` except that it returns the key of the + * first element `predicate` returns truthy for, instead of the element itself. + * + * If a property name is provided for `predicate` the created "_.property" + * style callback returns the property value of the given element. + * + * If an object is provided for `predicate` the created "_.matches" style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. If a property name or object is provided it is used to + * create a "_.property" or "_.matches" style callback respectively. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {string|undefined} Returns the key of the matched element, else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findKey(users, function(chr) { return chr.age < 40; }); + * // => 'barney' (iteration order is not guaranteed) + * + * // using the "_.matches" callback shorthand + * _.findKey(users, { 'age': 1 }); + * // => 'pebbles' + * + * // using the "_.property" callback shorthand + * _.findKey(users, 'active'); + * // => 'barney' + */ + function findKey(object, predicate, thisArg) { + predicate = getCallback(predicate, thisArg, 3); + return baseFind(object, predicate, baseForOwn, true); + } + + /** + * This method is like `_.findKey` except that it iterates over elements of + * a collection in the opposite order. + * + * If a property name is provided for `predicate` the created "_.property" + * style callback returns the property value of the given element. + * + * If an object is provided for `predicate` the created "_.matches" style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. If a property name or object is provided it is used to + * create a "_.property" or "_.matches" style callback respectively. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {string|undefined} Returns the key of the matched element, else `undefined`. + * @example + * + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findLastKey(users, function(chr) { return chr.age < 40; }); + * // => returns `pebbles` assuming `_.findKey` returns `barney` + * + * // using the "_.matches" callback shorthand + * _.findLastKey(users, { 'age': 36 }); + * // => 'barney' + * + * // using the "_.property" callback shorthand + * _.findLastKey(users, 'active'); + * // => 'pebbles' + */ + function findLastKey(object, predicate, thisArg) { + predicate = getCallback(predicate, thisArg, 3); + return baseFind(object, predicate, baseForOwnRight, true); + } + + /** + * Iterates over own and inherited enumerable properties of an object invoking + * `iteratee` for each property. The `iteratee` is bound to `thisArg` and invoked + * with three arguments; (value, key, object). Iterator functions may exit + * iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forIn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'a', 'b', and 'c' (iteration order is not guaranteed) + */ + function forIn(object, iteratee, thisArg) { + if (typeof iteratee != 'function' || typeof thisArg != 'undefined') { + iteratee = bindCallback(iteratee, thisArg, 3); + } + return baseFor(object, iteratee, keysIn); + } + + /** + * This method is like `_.forIn` except that it iterates over properties of + * `object` in the opposite order. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns `object`. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forInRight(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'c', 'b', and 'a' assuming `_.forIn ` logs 'a', 'b', and 'c' + */ + function forInRight(object, iteratee, thisArg) { + iteratee = bindCallback(iteratee, thisArg, 3); + return baseForRight(object, iteratee, keysIn); + } + + /** + * Iterates over own enumerable properties of an object invoking `iteratee` + * for each property. The `iteratee` is bound to `thisArg` and invoked with + * three arguments; (value, key, object). Iterator functions may exit iteration + * early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns `object`. + * @example + * + * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(n, key) { + * console.log(key); + * }); + * // => logs '0', '1', and 'length' (iteration order is not guaranteed) + */ + function forOwn(object, iteratee, thisArg) { + if (typeof iteratee != 'function' || typeof thisArg != 'undefined') { + iteratee = bindCallback(iteratee, thisArg, 3); + } + return baseForOwn(object, iteratee); + } + + /** + * This method is like `_.forOwn` except that it iterates over properties of + * `object` in the opposite order. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns `object`. + * @example + * + * _.forOwnRight({ '0': 'zero', '1': 'one', 'length': 2 }, function(n, key) { + * console.log(key); + * }); + * // => logs 'length', '1', and '0' assuming `_.forOwn` logs '0', '1', and 'length' + */ + function forOwnRight(object, iteratee, thisArg) { + iteratee = bindCallback(iteratee, thisArg, 3); + return baseForRight(object, iteratee, keys); + } + + /** + * Creates an array of function property names from all enumerable properties, + * own and inherited, of `object`. + * + * @static + * @memberOf _ + * @alias methods + * @category Object + * @param {Object} object The object to inspect. + * @returns {Array} Returns the new array of property names. + * @example + * + * _.functions(_); + * // => ['all', 'any', 'bind', ...] + */ + function functions(object) { + return baseFunctions(object, keysIn(object)); + } + + /** + * Checks if `key` exists as a direct property of `object` instead of an + * inherited property. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to inspect. + * @param {string} key The key to check. + * @returns {boolean} Returns `true` if `key` is a direct property, else `false`. + * @example + * + * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b'); + * // => true + */ + function has(object, key) { + return object ? hasOwnProperty.call(object, key) : false; + } + + /** + * Creates an object composed of the inverted keys and values of `object`. + * If `object` contains duplicate values, subsequent values overwrite property + * assignments of previous values unless `multiValue` is `true`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to invert. + * @param {boolean} [multiValue] Allow multiple values per key. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Object} Returns the new inverted object. + * @example + * + * _.invert({ 'first': 'fred', 'second': 'barney' }); + * // => { 'fred': 'first', 'barney': 'second' } + * + * // without `multiValue` + * _.invert({ 'first': 'fred', 'second': 'barney', 'third': 'fred' }); + * // => { 'fred': 'third', 'barney': 'second' } + * + * // with `multiValue` + * _.invert({ 'first': 'fred', 'second': 'barney', 'third': 'fred' }, true); + * // => { 'fred': ['first', 'third'], 'barney': ['second'] } + */ + function invert(object, multiValue, guard) { + if (guard && isIterateeCall(object, multiValue, guard)) { + multiValue = null; + } + var index = -1, + props = keys(object), + length = props.length, + result = {}; + + while (++index < length) { + var key = props[index], + value = object[key]; + + if (multiValue) { + if (hasOwnProperty.call(result, value)) { + result[value].push(key); + } else { + result[value] = [key]; + } + } + else { + result[value] = key; + } + } + return result; + } + + /** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.keys) + * for more details. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to inspect. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ + var keys = !nativeKeys ? shimKeys : function(object) { + if (object) { + var Ctor = object.constructor, + length = object.length; + } + if ((typeof Ctor == 'function' && Ctor.prototype === object) || + (typeof object != 'function' && (length && isLength(length)))) { + return shimKeys(object); + } + return isObject(object) ? nativeKeys(object) : []; + }; + + /** + * Creates an array of the own and inherited enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to inspect. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keysIn(new Foo); + * // => ['a', 'b', 'c'] (iteration order is not guaranteed) + */ + function keysIn(object) { + if (object == null) { + return []; + } + if (!isObject(object)) { + object = Object(object); + } + var length = object.length; + length = (length && isLength(length) && + (isArray(object) || (support.nonEnumArgs && isArguments(object))) && length) || 0; + + var Ctor = object.constructor, + index = -1, + isProto = typeof Ctor == 'function' && Ctor.prototype == object, + result = Array(length), + skipIndexes = length > 0; + + while (++index < length) { + result[index] = (index + ''); + } + for (var key in object) { + if (!(skipIndexes && isIndex(key, length)) && + !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { + result.push(key); + } + } + return result; + } + + /** + * Creates an object with the same keys as `object` and values generated by + * running each own enumerable property of `object` through `iteratee`. The + * iteratee function is bound to `thisArg` and invoked with three arguments; + * (value, key, object). + * + * If a property name is provided for `iteratee` the created "_.property" + * style callback returns the property value of the given element. + * + * If an object is provided for `iteratee` the created "_.matches" style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. If a property name or object is provided it is used to + * create a "_.property" or "_.matches" style callback respectively. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the new mapped object. + * @example + * + * _.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(n) { return n * 3; }); + * // => { 'a': 3, 'b': 6, 'c': 9 } + * + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } + * }; + * + * // using the "_.property" callback shorthand + * _.mapValues(users, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + */ + function mapValues(object, iteratee, thisArg) { + var result = {}; + iteratee = getCallback(iteratee, thisArg, 3); + + baseForOwn(object, function(value, key, object) { + result[key] = iteratee(value, key, object); + }); + return result; + } + + /** + * Recursively merges own enumerable properties of the source object(s), that + * don't resolve to `undefined` into the destination object. Subsequent sources + * overwrite property assignments of previous sources. If `customizer` is + * provided it is invoked to produce the merged values of the destination and + * source properties. If `customizer` returns `undefined` merging is handled + * by the method instead. The `customizer` is bound to `thisArg` and invoked + * with five arguments; (objectValue, sourceValue, key, object, source). + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @param {Function} [customizer] The function to customize merging properties. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {Object} Returns `object`. + * @example + * + * var users = { + * 'data': [{ 'user': 'barney' }, { 'user': 'fred' }] + * }; + * + * var ages = { + * 'data': [{ 'age': 36 }, { 'age': 40 }] + * }; + * + * _.merge(users, ages); + * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] } + * + * // using a customizer callback + * var object = { + * 'fruits': ['apple'], + * 'vegetables': ['beet'] + * }; + * + * var other = { + * 'fruits': ['banana'], + * 'vegetables': ['carrot'] + * }; + * + * _.merge(object, other, function(a, b) { + * return _.isArray(a) ? a.concat(b) : undefined; + * }); + * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] } + */ + var merge = createAssigner(baseMerge); + + /** + * The opposite of `_.pick`; this method creates an object composed of the + * own and inherited enumerable properties of `object` that are not omitted. + * Property names may be specified as individual arguments or as arrays of + * property names. If `predicate` is provided it is invoked for each property + * of `object` omitting the properties `predicate` returns truthy for. The + * predicate is bound to `thisArg` and invoked with three arguments; + * (value, key, object). + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {Function|...(string|string[])} [predicate] The function invoked per + * iteration or property names to omit, specified as individual property + * names or arrays of property names. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'user': 'fred', 'age': 40 }; + * + * _.omit(object, 'age'); + * // => { 'user': 'fred' } + * + * _.omit(object, _.isNumber); + * // => { 'user': 'fred' } + */ + function omit(object, predicate, thisArg) { + if (object == null) { + return {}; + } + if (typeof predicate != 'function') { + var props = arrayMap(baseFlatten(arguments, false, false, 1), String); + return pickByArray(object, baseDifference(keysIn(object), props)); + } + predicate = bindCallback(predicate, thisArg, 3); + return pickByCallback(object, function(value, key, object) { + return !predicate(value, key, object); + }); + } + + /** + * Creates a two dimensional array of the key-value pairs for `object`, + * e.g. `[[key1, value1], [key2, value2]]`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to inspect. + * @returns {Array} Returns the new array of key-value pairs. + * @example + * + * _.pairs({ 'barney': 36, 'fred': 40 }); + * // => [['barney', 36], ['fred', 40]] (iteration order is not guaranteed) + */ + function pairs(object) { + var index = -1, + props = keys(object), + length = props.length, + result = Array(length); + + while (++index < length) { + var key = props[index]; + result[index] = [key, object[key]]; + } + return result; + } + + /** + * Creates an object composed of the picked `object` properties. Property + * names may be specified as individual arguments or as arrays of property + * names. If `predicate` is provided it is invoked for each property of `object` + * picking the properties `predicate` returns truthy for. The predicate is + * bound to `thisArg` and invoked with three arguments; (value, key, object). + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {Function|...(string|string[])} [predicate] The function invoked per + * iteration or property names to pick, specified as individual property + * names or arrays of property names. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'user': 'fred', 'age': 40 }; + * + * _.pick(object, 'user'); + * // => { 'user': 'fred' } + * + * _.pick(object, _.isString); + * // => { 'user': 'fred' } + */ + function pick(object, predicate, thisArg) { + if (object == null) { + return {}; + } + return typeof predicate == 'function' + ? pickByCallback(object, bindCallback(predicate, thisArg, 3)) + : pickByArray(object, baseFlatten(arguments, false, false, 1)); + } + + /** + * Resolves the value of property `key` on `object`. If the value of `key` is + * a function it is invoked with the `this` binding of `object` and its result + * is returned, else the property value is returned. If the property value is + * `undefined` the `defaultValue` is used in its place. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {string} key The key of the property to resolve. + * @param {*} [defaultValue] The value returned if the property value + * resolves to `undefined`. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'user': 'fred', 'age': _.constant(40) }; + * + * _.result(object, 'user'); + * // => 'fred' + * + * _.result(object, 'age'); + * // => 40 + * + * _.result(object, 'status', 'busy'); + * // => 'busy' + * + * _.result(object, 'status', _.constant('busy')); + * // => 'busy' + */ + function result(object, key, defaultValue) { + var value = object == null ? undefined : object[key]; + if (typeof value == 'undefined') { + value = defaultValue; + } + return isFunction(value) ? value.call(object) : value; + } + + /** + * An alternative to `_.reduce`; this method transforms `object` to a new + * `accumulator` object which is the result of running each of its own enumerable + * properties through `iteratee`, with each invocation potentially mutating + * the `accumulator` object. The `iteratee` is bound to `thisArg` and invoked + * with four arguments; (accumulator, value, key, object). Iterator functions + * may exit iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @category Object + * @param {Array|Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The custom accumulator value. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {*} Returns the accumulated value. + * @example + * + * var squares = _.transform([1, 2, 3, 4, 5, 6], function(result, n) { + * n *= n; + * if (n % 2) { + * return result.push(n) < 3; + * } + * }); + * // => [1, 9, 25] + * + * var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result, n, key) { + * result[key] = n * 3; + * }); + * // => { 'a': 3, 'b': 6, 'c': 9 } + */ + function transform(object, iteratee, accumulator, thisArg) { + var isArr = isArray(object) || isTypedArray(object); + iteratee = getCallback(iteratee, thisArg, 4); + + if (accumulator == null) { + if (isArr || isObject(object)) { + var Ctor = object.constructor; + if (isArr) { + accumulator = isArray(object) ? new Ctor : []; + } else { + accumulator = baseCreate(typeof Ctor == 'function' && Ctor.prototype); + } + } else { + accumulator = {}; + } + } + (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) { + return iteratee(accumulator, value, index, object); + }); + return accumulator; + } + + /** + * Creates an array of the own enumerable property values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.values(new Foo); + * // => [1, 2] (iteration order is not guaranteed) + * + * _.values('hi'); + * // => ['h', 'i'] + */ + function values(object) { + return baseValues(object, keys(object)); + } + + /** + * Creates an array of the own and inherited enumerable property values + * of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.valuesIn(new Foo); + * // => [1, 2, 3] (iteration order is not guaranteed) + */ + function valuesIn(object) { + return baseValues(object, keysIn(object)); + } + + /*------------------------------------------------------------------------*/ + + /** + * Produces a random number between `min` and `max` (inclusive). If only one + * argument is provided a number between `0` and the given number is returned. + * If `floating` is `true`, or either `min` or `max` are floats, a floating-point + * number is returned instead of an integer. + * + * @static + * @memberOf _ + * @category Number + * @param {number} [min=0] The minimum possible value. + * @param {number} [max=1] The maximum possible value. + * @param {boolean} [floating] Specify returning a floating-point number. + * @returns {number} Returns the random number. + * @example + * + * _.random(0, 5); + * // => an integer between 0 and 5 + * + * _.random(5); + * // => also an integer between 0 and 5 + * + * _.random(5, true); + * // => a floating-point number between 0 and 5 + * + * _.random(1.2, 5.2); + * // => a floating-point number between 1.2 and 5.2 + */ + function random(min, max, floating) { + if (floating && isIterateeCall(min, max, floating)) { + max = floating = null; + } + var noMin = min == null, + noMax = max == null; + + if (floating == null) { + if (noMax && typeof min == 'boolean') { + floating = min; + min = 1; + } + else if (typeof max == 'boolean') { + floating = max; + noMax = true; + } + } + if (noMin && noMax) { + max = 1; + noMax = false; + } + min = +min || 0; + if (noMax) { + max = min; + min = 0; + } else { + max = +max || 0; + } + if (floating || min % 1 || max % 1) { + var rand = nativeRandom(); + return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand + '').length - 1)))), max); + } + return baseRandom(min, max); + } + + /*------------------------------------------------------------------------*/ + + /** + * Converts `string` to camel case. + * See [Wikipedia](https://en.wikipedia.org/wiki/CamelCase) for more details. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the camel cased string. + * @example + * + * _.camelCase('Foo Bar'); + * // => 'fooBar' + * + * _.camelCase('--foo-bar'); + * // => 'fooBar' + * + * _.camelCase('__foo_bar__'); + * // => 'fooBar' + */ + var camelCase = createCompounder(function(result, word, index) { + word = word.toLowerCase(); + return result + (index ? (word.charAt(0).toUpperCase() + word.slice(1)) : word); + }); + + /** + * Capitalizes the first character of `string`. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to capitalize. + * @returns {string} Returns the capitalized string. + * @example + * + * _.capitalize('fred'); + * // => 'Fred' + */ + function capitalize(string) { + string = baseToString(string); + return string && (string.charAt(0).toUpperCase() + string.slice(1)); + } + + /** + * Deburrs `string` by converting latin-1 supplementary letters to basic latin letters. + * See [Wikipedia](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) + * for more details. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to deburr. + * @returns {string} Returns the deburred string. + * @example + * + * _.deburr('déjà vu'); + * // => 'deja vu' + */ + function deburr(string) { + string = baseToString(string); + return string && string.replace(reLatin1, deburrLetter); + } + + /** + * Checks if `string` ends with the given target string. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to search. + * @param {string} [target] The string to search for. + * @param {number} [position=string.length] The position to search from. + * @returns {boolean} Returns `true` if `string` ends with `target`, else `false`. + * @example + * + * _.endsWith('abc', 'c'); + * // => true + * + * _.endsWith('abc', 'b'); + * // => false + * + * _.endsWith('abc', 'b', 2); + * // => true + */ + function endsWith(string, target, position) { + string = baseToString(string); + target = (target + ''); + + var length = string.length; + position = (typeof position == 'undefined' ? length : nativeMin(position < 0 ? 0 : (+position || 0), length)) - target.length; + return position >= 0 && string.indexOf(target, position) == position; + } + + /** + * Converts the characters "&", "<", ">", '"', "'", and '`', in `string` to + * their corresponding HTML entities. + * + * **Note:** No other characters are escaped. To escape additional characters + * use a third-party library like [_he_](https://mths.be/he). + * + * Though the ">" character is escaped for symmetry, characters like + * ">" and "/" don't require escaping in HTML and have no special meaning + * unless they're part of a tag or unquoted attribute value. + * See [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands) + * (under "semi-related fun fact") for more details. + * + * Backticks are escaped because in Internet Explorer < 9, they can break out + * of attribute values or HTML comments. See [#102](https://html5sec.org/#102), + * [#108](https://html5sec.org/#108), and [#133](https://html5sec.org/#133) of + * the [HTML5 Security Cheatsheet](https://html5sec.org/) for more details. + * + * When working with HTML you should always quote attribute values to reduce + * XSS vectors. See [Ryan Grove's article](http://wonko.com/post/html-escaping) + * for more details. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escape('fred, barney, & pebbles'); + * // => 'fred, barney, & pebbles' + */ + function escape(string) { + // Reset `lastIndex` because in IE < 9 `String#replace` does not. + string = baseToString(string); + return (string && reHasUnescapedHtml.test(string)) + ? string.replace(reUnescapedHtml, escapeHtmlChar) + : string; + } + + /** + * Escapes the `RegExp` special characters "\", "^", "$", ".", "|", "?", "*", + * "+", "(", ")", "[", "]", "{" and "}" in `string`. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. + * @example + * + * _.escapeRegExp('[lodash](https://lodash.com/)'); + * // => '\[lodash\]\(https://lodash\.com/\)' + */ + function escapeRegExp(string) { + string = baseToString(string); + return (string && reHasRegExpChars.test(string)) + ? string.replace(reRegExpChars, '\\$&') + : string; + } + + /** + * Converts `string` to kebab case (a.k.a. spinal case). + * See [Wikipedia](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles) for + * more details. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the kebab cased string. + * @example + * + * _.kebabCase('Foo Bar'); + * // => 'foo-bar' + * + * _.kebabCase('fooBar'); + * // => 'foo-bar' + * + * _.kebabCase('__foo_bar__'); + * // => 'foo-bar' + */ + var kebabCase = createCompounder(function(result, word, index) { + return result + (index ? '-' : '') + word.toLowerCase(); + }); + + /** + * Pads `string` on the left and right sides if it is shorter then the given + * padding length. The `chars` string may be truncated if the number of padding + * characters can't be evenly divided by the padding length. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.pad('abc', 8); + * // => ' abc ' + * + * _.pad('abc', 8, '_-'); + * // => '_-abc_-_' + * + * _.pad('abc', 3); + * // => 'abc' + */ + function pad(string, length, chars) { + string = baseToString(string); + length = +length; + + var strLength = string.length; + if (strLength >= length || !nativeIsFinite(length)) { + return string; + } + var mid = (length - strLength) / 2, + leftLength = floor(mid), + rightLength = ceil(mid); + + chars = createPad('', rightLength, chars); + return chars.slice(0, leftLength) + string + chars; + } + + /** + * Pads `string` on the left side if it is shorter then the given padding + * length. The `chars` string may be truncated if the number of padding + * characters exceeds the padding length. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.padLeft('abc', 6); + * // => ' abc' + * + * _.padLeft('abc', 6, '_-'); + * // => '_-_abc' + * + * _.padLeft('abc', 3); + * // => 'abc' + */ + function padLeft(string, length, chars) { + string = baseToString(string); + return string && (createPad(string, length, chars) + string); + } + + /** + * Pads `string` on the right side if it is shorter then the given padding + * length. The `chars` string may be truncated if the number of padding + * characters exceeds the padding length. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. + * @example + * + * _.padRight('abc', 6); + * // => 'abc ' + * + * _.padRight('abc', 6, '_-'); + * // => 'abc_-_' + * + * _.padRight('abc', 3); + * // => 'abc' + */ + function padRight(string, length, chars) { + string = baseToString(string); + return string && (string + createPad(string, length, chars)); + } + + /** + * Converts `string` to an integer of the specified radix. If `radix` is + * `undefined` or `0`, a `radix` of `10` is used unless `value` is a hexadecimal, + * in which case a `radix` of `16` is used. + * + * **Note:** This method aligns with the ES5 implementation of `parseInt`. + * See the [ES5 spec](https://es5.github.io/#E) for more details. + * + * @static + * @memberOf _ + * @category String + * @param {string} string The string to convert. + * @param {number} [radix] The radix to interpret `value` by. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {number} Returns the converted integer. + * @example + * + * _.parseInt('08'); + * // => 8 + * + * _.map(['6', '08', '10'], _.parseInt); + * // => [6, 8, 10] + */ + function parseInt(string, radix, guard) { + if (guard && isIterateeCall(string, radix, guard)) { + radix = 0; + } + return nativeParseInt(string, radix); + } + // Fallback for environments with pre-ES5 implementations. + if (nativeParseInt(whitespace + '08') != 8) { + parseInt = function(string, radix, guard) { + // Firefox < 21 and Opera < 15 follow ES3 for `parseInt`. + // Chrome fails to trim leading whitespace characters. + // See https://code.google.com/p/v8/issues/detail?id=3109 for more details. + if (guard ? isIterateeCall(string, radix, guard) : radix == null) { + radix = 0; + } else if (radix) { + radix = +radix; + } + string = trim(string); + return nativeParseInt(string, radix || (reHexPrefix.test(string) ? 16 : 10)); + }; + } + + /** + * Repeats the given string `n` times. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to repeat. + * @param {number} [n=0] The number of times to repeat the string. + * @returns {string} Returns the repeated string. + * @example + * + * _.repeat('*', 3); + * // => '***' + * + * _.repeat('abc', 2); + * // => 'abcabc' + * + * _.repeat('abc', 0); + * // => '' + */ + function repeat(string, n) { + var result = ''; + string = baseToString(string); + n = +n; + if (n < 1 || !string || !nativeIsFinite(n)) { + return result; + } + // Leverage the exponentiation by squaring algorithm for a faster repeat. + // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details. + do { + if (n % 2) { + result += string; + } + n = floor(n / 2); + string += string; + } while (n); + + return result; + } + + /** + * Converts `string` to snake case. + * See [Wikipedia](https://en.wikipedia.org/wiki/Snake_case) for more details. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the snake cased string. + * @example + * + * _.snakeCase('Foo Bar'); + * // => 'foo_bar' + * + * _.snakeCase('fooBar'); + * // => 'foo_bar' + * + * _.snakeCase('--foo-bar'); + * // => 'foo_bar' + */ + var snakeCase = createCompounder(function(result, word, index) { + return result + (index ? '_' : '') + word.toLowerCase(); + }); + + /** + * Converts `string` to start case. + * See [Wikipedia](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage) + * for more details. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the start cased string. + * @example + * + * _.startCase('--foo-bar'); + * // => 'Foo Bar' + * + * _.startCase('fooBar'); + * // => 'Foo Bar' + * + * _.startCase('__foo_bar__'); + * // => 'Foo Bar' + */ + var startCase = createCompounder(function(result, word, index) { + return result + (index ? ' ' : '') + (word.charAt(0).toUpperCase() + word.slice(1)); + }); + + /** + * Checks if `string` starts with the given target string. + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to search. + * @param {string} [target] The string to search for. + * @param {number} [position=0] The position to search from. + * @returns {boolean} Returns `true` if `string` starts with `target`, else `false`. + * @example + * + * _.startsWith('abc', 'a'); + * // => true + * + * _.startsWith('abc', 'b'); + * // => false + * + * _.startsWith('abc', 'b', 1); + * // => true + */ + function startsWith(string, target, position) { + string = baseToString(string); + position = position == null ? 0 : nativeMin(position < 0 ? 0 : (+position || 0), string.length); + return string.lastIndexOf(target, position) == position; + } + + /** + * Creates a compiled template function that can interpolate data properties + * in "interpolate" delimiters, HTML-escape interpolated data properties in + * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data + * properties may be accessed as free variables in the template. If a setting + * object is provided it takes precedence over `_.templateSettings` values. + * + * **Note:** In the development build `_.template` utilizes sourceURLs for easier debugging. + * See the [HTML5 Rocks article on sourcemaps](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) + * for more details. + * + * For more information on precompiling templates see + * [lodash's custom builds documentation](https://lodash.com/custom-builds). + * + * For more information on Chrome extension sandboxes see + * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval). + * + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The template string. + * @param {Object} [options] The options object. + * @param {RegExp} [options.escape] The HTML "escape" delimiter. + * @param {RegExp} [options.evaluate] The "evaluate" delimiter. + * @param {Object} [options.imports] An object to import into the template as free variables. + * @param {RegExp} [options.interpolate] The "interpolate" delimiter. + * @param {string} [options.sourceURL] The sourceURL of the template's compiled source. + * @param {string} [options.variable] The data object variable name. + * @param- {Object} [otherOptions] Enables the legacy `options` param signature. + * @returns {Function} Returns the compiled template function. + * @example + * + * // using the "interpolate" delimiter to create a compiled template + * var compiled = _.template('hello <%= user %>!'); + * compiled({ 'user': 'fred' }); + * // => 'hello fred!' + * + * // using the HTML "escape" delimiter to escape data property values + * var compiled = _.template('<%- value %>'); + * compiled({ 'value': ' + + + + + + + +
+ + + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/responsive/examples/gantt.html b/iguana/js/amcharts/plugins/responsive/examples/gantt.html new file mode 100755 index 000000000..145f97789 --- /dev/null +++ b/iguana/js/amcharts/plugins/responsive/examples/gantt.html @@ -0,0 +1,304 @@ + + + + + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/responsive/examples/gauge.html b/iguana/js/amcharts/plugins/responsive/examples/gauge.html new file mode 100755 index 000000000..6f9c1d41b --- /dev/null +++ b/iguana/js/amcharts/plugins/responsive/examples/gauge.html @@ -0,0 +1,71 @@ + + + + + + + amCharts Responsive Example + + + + + + + + +
+ + + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/responsive/examples/images/bicycle.png b/iguana/js/amcharts/plugins/responsive/examples/images/bicycle.png new file mode 100755 index 000000000..0873bf9b3 Binary files /dev/null and b/iguana/js/amcharts/plugins/responsive/examples/images/bicycle.png differ diff --git a/iguana/js/amcharts/plugins/responsive/examples/images/car.png b/iguana/js/amcharts/plugins/responsive/examples/images/car.png new file mode 100755 index 000000000..4214fb721 Binary files /dev/null and b/iguana/js/amcharts/plugins/responsive/examples/images/car.png differ diff --git a/iguana/js/amcharts/plugins/responsive/examples/images/motorcycle.png b/iguana/js/amcharts/plugins/responsive/examples/images/motorcycle.png new file mode 100755 index 000000000..47c6ce83f Binary files /dev/null and b/iguana/js/amcharts/plugins/responsive/examples/images/motorcycle.png differ diff --git a/iguana/js/amcharts/plugins/responsive/examples/index.html b/iguana/js/amcharts/plugins/responsive/examples/index.html new file mode 100755 index 000000000..07e6d697a --- /dev/null +++ b/iguana/js/amcharts/plugins/responsive/examples/index.html @@ -0,0 +1,112 @@ + + + + + + amCharts Responsive Example + + + + + + + + + + +
+ + + + + + +
+ +
800x500px
+
+ +
+ + + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/responsive/examples/map.html b/iguana/js/amcharts/plugins/responsive/examples/map.html new file mode 100755 index 000000000..fba6ae7e9 --- /dev/null +++ b/iguana/js/amcharts/plugins/responsive/examples/map.html @@ -0,0 +1,198 @@ + + + + + + + amCharts Responsive Example + + + + + + + + + +
+ + + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/responsive/examples/pie1.html b/iguana/js/amcharts/plugins/responsive/examples/pie1.html new file mode 100755 index 000000000..5b69183e2 --- /dev/null +++ b/iguana/js/amcharts/plugins/responsive/examples/pie1.html @@ -0,0 +1,71 @@ + + + + + + + amCharts Responsive Example + + + + + + + + +
+ + + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/responsive/examples/pie2.html b/iguana/js/amcharts/plugins/responsive/examples/pie2.html new file mode 100755 index 000000000..4b41a3b9c --- /dev/null +++ b/iguana/js/amcharts/plugins/responsive/examples/pie2.html @@ -0,0 +1,73 @@ + + + + + + + amCharts Responsive Example + + + + + + + + +
+ + + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/responsive/examples/pie3.html b/iguana/js/amcharts/plugins/responsive/examples/pie3.html new file mode 100755 index 000000000..e0f2d7de0 --- /dev/null +++ b/iguana/js/amcharts/plugins/responsive/examples/pie3.html @@ -0,0 +1,106 @@ + + + + + + + amCharts Responsive Example + + + + + + + + +
+
+ + + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/responsive/examples/radar.html b/iguana/js/amcharts/plugins/responsive/examples/radar.html new file mode 100755 index 000000000..dbfb3146d --- /dev/null +++ b/iguana/js/amcharts/plugins/responsive/examples/radar.html @@ -0,0 +1,67 @@ + + + + + + + amCharts Responsive Example + + + + + + + + +
+ + + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/responsive/examples/serial1.html b/iguana/js/amcharts/plugins/responsive/examples/serial1.html new file mode 100755 index 000000000..fcdce9906 --- /dev/null +++ b/iguana/js/amcharts/plugins/responsive/examples/serial1.html @@ -0,0 +1,203 @@ + + + + + + + amCharts Responsive Example + + + + + + + + +
+ + + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/responsive/examples/serial2.html b/iguana/js/amcharts/plugins/responsive/examples/serial2.html new file mode 100755 index 000000000..66105159e --- /dev/null +++ b/iguana/js/amcharts/plugins/responsive/examples/serial2.html @@ -0,0 +1,84 @@ + + + + + + + amCharts Responsive Example + + + + + + + + + +
+ + + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/responsive/examples/serial3.html b/iguana/js/amcharts/plugins/responsive/examples/serial3.html new file mode 100755 index 000000000..351d1eb86 --- /dev/null +++ b/iguana/js/amcharts/plugins/responsive/examples/serial3.html @@ -0,0 +1,103 @@ + + + + + + + amCharts Responsive Example + + + + + + + + +
+ + + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/responsive/examples/stock.html b/iguana/js/amcharts/plugins/responsive/examples/stock.html new file mode 100755 index 000000000..71b50dcf1 --- /dev/null +++ b/iguana/js/amcharts/plugins/responsive/examples/stock.html @@ -0,0 +1,210 @@ + + + + + + + amCharts Responsive Example + + + + + + + + + +
+ + + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/responsive/examples/xy.html b/iguana/js/amcharts/plugins/responsive/examples/xy.html new file mode 100755 index 000000000..8d61d7092 --- /dev/null +++ b/iguana/js/amcharts/plugins/responsive/examples/xy.html @@ -0,0 +1,145 @@ + + + + + + + amCharts Responsive Example + + + + + + + + +
+ + + \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/responsive/license.txt b/iguana/js/amcharts/plugins/responsive/license.txt new file mode 100755 index 000000000..a765bc16b --- /dev/null +++ b/iguana/js/amcharts/plugins/responsive/license.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/responsive/readme.md b/iguana/js/amcharts/plugins/responsive/readme.md new file mode 100755 index 000000000..72938f01b --- /dev/null +++ b/iguana/js/amcharts/plugins/responsive/readme.md @@ -0,0 +1,363 @@ +# amCharts Responsive + +Version: 1.0.2 + + +## Description + +Use this plugin to enable "responsive" features for amCharts' JavaScript Charts, +JavaScript Stock Chart, or JavaScript Maps. + +"Responsive" chart or map will modify it's features dynamically (even as you +resize the container) based on the available area. For example: a full fledged +line chart with legend guides, labels, titles and other elements will be +displayed in all its glory if container is big enough. + +If the container shrinks (i.e. you resize a browser window or view it on an +iPad), it starts "compacting" the chart. First the legend is removed. Shrink it +even further, axis titles are removed and its value labels are moved inside the +plot area. Going even smaller, bullets, labels gone. All the way to the +sparkline representation of the chart. + +Plugin brings a universal set of pre-defined rules that you can use to instantly +enable responsiveness. Those are custom-tailored for each chart/map type and +will probably fit your requirements out-of the-box. All you need to do is to +enable "responsive" plugin for your chart instance. + +You can modify those defaults rules, or make your own list. The plugin allows +that. (see further down this file for instructions) + + +## Usage + +1. Include the minified version of file of this plugin. I.e.: + +``` + +``` + +(this needs to go after all the other amCharts includes) + +2. Add the following setting to your chart configuration: + +``` +AmCharts.makeChart( "chartdiv", { + ..., + "responsive": { + "enabled": true + } +} ); +``` + +Or if you are using non-JSON setup: + +``` +chart.responsive = { + "enabled": true +}; +``` + +That's it. + + +## Advanced use + +### Rules + +You can modify (or completely overwrite) the default responsive rules used by +the plugin. + +A plugin works by checking chart area dimensions after each resize. (or after +initial build / mobile device orientation change) It then overrides particular +settings suitable for these particular dimensions. + +Override rules are implemented by defining chart rules, or just "rules" moving +forward. Each rule has two things: + +1. Dimension conditions; +2. Overrides. (a set of properties to override for this particular rule) + +A rule is an object, for example: + +``` +{ + "minWidth": 200, + "maxWidth": 400, + "maxHeight": 400, + "minHeight": 200, + "overrides": { + "precision": 2, + "legend": { + "enabled": false + }, + "valueAxes": { + "inside": true + } + } +} +``` + +The above rule will be applicable to a chart that is between 200px and 400px in +width and height. + +It is not necessary to add all of the dimensional properties. You just neat at +least one. + +So for example to make the rule apply to all charts with width 400px or lower, +you would do something like this: + +``` +{ + "maxWidth": 400, + "overrides": { + "precision": 2, + "legend": { + "enabled": false + }, + "valueAxes": { + "inside": true + } + } +} +``` + +Please note that there are several other conditional properties besides the ones +that deal with chart's dimensions: + +* "rotate" (true|false) - set this property if you want to make this rule + applicable to rotated serial chart only (i.e. bar chart) + +* "legendPosition" ("top|bottom|left|right") - set this property if you want the + rule applied only when the chart legend is set to particular position. + Please note that this does not check whether the legend is enabled at all. + +Now, on to explaining "overrides". It's an object, that contains properties that +you want to override the chart's initial ones with. + +It can be either simple properties, like "fontSize" or "precision", or complext +types like object, or array. + +To override a property of a child object, such as "legend", you would simply go +with JSON representation of the properties you need to override. I.e.: + +``` +"legend": { + "enabled": false +} +``` + +This will look for a "legend" property in chart object, then change it's +"enabled" property to false. + +### Overriding arrays of objects + +Some objects in charts are collected in arrays, i.e. "graphs", "valueAxes", etc. + +There are some ways to override their properties as well. + +To override properties for ALL objects in the array, you would provide an +override instruction as an object. I.e.: + +``` +"graphs": { + "bullet": "round", + "lineThickness": 5 +} +``` + +The above will add a round bullet and set line thickness to all of the graphs on +the chart. + +You can also target individual items in the array. There are two ways to do +that: + +a) Use "id" property; +b) Apply using the same index. + +To individually apply property overrides, you will need to supply override +instructions as an array: + +``` +"graphs": [ + { + "id": "g1", + "bullet": "round", + "lineThickness": 5 + } +] +``` + +The above will apply the same properties for the graph with an id of "g1" only. +It will not touch the rest of the graphs. + +Please note that original graph definition in your chart settings needs to have +the "id" property set so this plugin can target it. + +Or you can omit the "id" and just apply overrides in the same order as you have +them defined. I.e.: + +``` +"graphs": [ + { + "bullet": "round" + }, + { + "bullet": "square" + } +] +``` + +The above will apply round bullets to the first defined graph, and square +bullets to the second graph. + +### Chaining multiple rules + +The cool pat is that you can daisy-chain the override rules, much like in CSS. + +The plugin will examine all of the rules if their dimensional conditions match +current chart condition and will apply their overrides in the same order they +are defined. + +Consider this rule set: + +``` +"responsive": { + "enabled": true, + "rules": [ + // at 400px wide, we hide legend + { + "maxWidth": 400, + "overrides": { + "legend": { + "enabled" + } + } + }, + + // at 300px or less, we move value axis labels inside plot area + // the legend is still hidden because the above rule is still applicable + { + "maxWidth": 300, + "overrides": { + "valueAxes": { + "inside": true + } + } + }, + + // at 200 px we hide value axis labels altogether + { + "maxWidth": 200, + "overrides": { + "valueAxes": { + "labelsEnabled": false + } + } + } + + ] +} +``` + +In case several rules modify the same property, the last one will always "win". + +### Combining custom rules with pre-defined ones + +The plugin will combine your custom rules with pre-defined ones automatically. + +In case you want to go pure and set only your own responsive rules, you can set +property "addDefaultRules" to false. I.e.: + +``` +"responsive": { + "enabled": true, + "addDefaultRules": false, + "rules": [ + { + "maxWidth": 400, + "overrides": { + "legend": { + "enabled" + } + } + } + ] +} +``` + +When your custom rules are combined with pre-defined ones, yours are appended at +the end of the list. This means that your rules will always have the "last +word". + + +## Requirements + +This plugin requires at least 3.13 version of JavaScript Charts, JavaScript +Stock Chart or JavaScript Maps. + +Any older versions will be ignored by this plugin. The charts will function but +no responsive rules will be applied to them. + + +## Demos + +Run the index.html in the subdirectory /examples. It will allow viewing misc +chart types at various resolutions. + + +## Extending this plugin + +You're encouraged to modify, extend and make derivative plugins out of this +plugin. + +You can modify files, included in this archive or, better yet, fork this project +on GitHub: + +https://github.com/amcharts/responsive + +We're curious types. Please let us know (contact@amcharts.com) if you do create +something new out of this plugin. + + +## License + +This plugin is licensed under Apache License 2.0. + +This basically means you're free to use or modify this plugin, even make your +own versions or completely different products out of it. + +Please see attached file "license.txt" for the complete license or online here: + +http://www.apache.org/licenses/LICENSE-2.0 + + +## Contact us + +* Email:contact@amcharts.com +* Web: http://www.amcharts.com/ +* Facebook: https://www.facebook.com/amcharts +* Twitter: https://twitter.com/amcharts + + +## Changelog + +### 1.0.2 +* Fixed a bug where the plugin was causing an error when chart/map container was being hidden + +### 1.0.1 +* Fixed bug with overrides being overwritten with chart object in some cases +* V3.14 compatibility + +### 1.0 +* Added support for GANTT chart type (available sin JavaScript Charts V3.14) + +### 0.9.2 +* Fixed a custom rules being applied in the wrong order + +### 0.9.1 +* Made all examples use minified version of the plugin +* Introduced removal of grid lines on micro charts +* Tweaked legend hiding dimensions for pie chart + +### 0.9 +* Initial release \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/responsive/responsive.js b/iguana/js/amcharts/plugins/responsive/responsive.js new file mode 100755 index 000000000..c00682e9a --- /dev/null +++ b/iguana/js/amcharts/plugins/responsive/responsive.js @@ -0,0 +1,1245 @@ +/* +Plugin Name: amCharts Responsive +Description: This plugin add responsive functionality to JavaScript Charts and Maps. +Author: Martynas Majeris, amCharts +Contributors: Ohad Schneider +Version: 1.0.2 +Author URI: http://www.amcharts.com/ + +Copyright 2015 amCharts + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +Please note that the above license covers only this plugin. It by all means does +not apply to any other amCharts products that are covered by different licenses. +*/ + +/*global AmCharts*/ + +AmCharts.addInitHandler( function( chart ) { + "use strict"; + + if ( chart.responsive === undefined || chart.responsive.ready === true || chart.responsive.enabled !== true ) + return; + + var version = chart.version.split( '.' ); + if ( ( version.length < 2 ) || Number( version[ 0 ] ) < 3 || ( Number( version[ 0 ] ) === 3 && Number( version[ 1 ] ) < 13 ) ) + return; + + // a short variable for easy reference + var r = chart.responsive; + + r.ready = true; + r.currentRules = {}; + r.overridden = []; + + // defaults per chart type + var defaults = { + + /** + * AmPie + */ + 'pie': [ + + /** + * Disable legend in certain cases + */ + { + "maxWidth": 550, + "legendPosition": "left", + "overrides": { + "legend": { + "enabled": false + } + } + }, { + "maxWidth": 550, + "legendPosition": "right", + "overrides": { + "legend": { + "enabled": false + } + } + }, { + "maxWidth": 150, + "overrides": { + "legend": { + "enabled": false + } + } + }, { + "maxHeight": 350, + "legendPosition": "top", + "overrides": { + "legend": { + "enabled": false + } + } + }, { + "maxHeight": 350, + "legendPosition": "bottom", + "overrides": { + "legend": { + "enabled": false + } + } + }, { + "maxHeight": 150, + "overrides": { + "legend": { + "enabled": false + } + } + }, + + /** + * Narrow chart + */ + { + "maxWidth": 400, + "overrides": { + "labelsEnabled": false + } + }, { + "maxWidth": 100, + "overrides": { + "legend": { + "enabled": false + } + } + }, + + /** + * Short chart + */ + { + "maxHeight": 350, + "overrides": { + "pullOutRadius": 0 + } + }, { + "maxHeight": 200, + "overrides": { + "titles": { + "enabled": false + }, + "labelsEnabled": false + } + }, + + /** + * Supersmall + */ + { + "maxWidth": 60, + "overrides": { + "autoMargins": false, + "marginTop": 0, + "marginBottom": 0, + "marginLeft": 0, + "marginRight": 0, + "radius": "50%", + "innerRadius": 0, + "balloon": { + "enabled": false + }, + "legend": { + "enabled": false + } + } + }, { + "maxHeight": 60, + "overrides": { + "marginTop": 0, + "marginBottom": 0, + "marginLeft": 0, + "marginRight": 0, + "radius": "50%", + "innerRadius": 0, + "balloon": { + "enabled": false + }, + "legend": { + "enabled": false + } + } + } + ], + + /** + * AmFunnel + */ + + 'funnel': [ { + "maxWidth": 550, + "legendPosition": "left", + "overrides": { + "legend": { + "enabled": false + } + } + }, { + "maxWidth": 550, + "legendPosition": "right", + "overrides": { + "legend": { + "enabled": false + } + } + }, { + "maxWidth": 150, + "overrides": { + "legend": { + "enabled": false + } + } + }, { + "maxHeight": 500, + "legendPosition": "top", + "overrides": { + "legend": { + "enabled": false + } + } + }, { + "maxHeight": 500, + "legendPosition": "bottom", + "overrides": { + "legend": { + "enabled": false + } + } + }, { + "maxHeight": 150, + "overrides": { + "legend": { + "enabled": false + } + } + }, { + "maxWidth": 400, + "overrides": { + "labelsEnabled": false, + "marginLeft": 10, + "marginRight": 10, + "legend": { + "enabled": false + } + } + }, { + "maxHeight": 350, + "overrides": { + "pullOutRadius": 0, + "legend": { + "enabled": false + } + } + }, { + "maxHeight": 300, + "overrides": { + "titles": { + "enabled": false + } + } + } ], + + /** + * AmRadar + */ + + "radar": [ { + "maxWidth": 550, + "legendPosition": "left", + "overrides": { + "legend": { + "enabled": false + } + } + }, { + "maxWidth": 550, + "legendPosition": "right", + "overrides": { + "legend": { + "enabled": false + } + } + }, { + "maxWidth": 150, + "overrides": { + "legend": { + "enabled": false + } + } + }, { + "maxHeight": 350, + "legendPosition": "top", + "overrides": { + "legend": { + "enabled": false + } + } + }, { + "maxHeight": 350, + "legendPosition": "bottom", + "overrides": { + "legend": { + "enabled": false + } + } + }, { + "maxHeight": 150, + "overrides": { + "legend": { + "enabled": false + } + } + }, { + "maxWidth": 300, + "overrides": { + "labelsEnabled": false + } + }, { + "maxWidth": 200, + "overrides": { + "autoMargins": false, + "marginTop": 0, + "marginBottom": 0, + "marginLeft": 0, + "marginRight": 0, + "radius": "50%", + "titles": { + "enabled": false + }, + "valueAxes": { + "labelsEnabled": false, + "radarCategoriesEnabled": false + } + } + }, { + "maxHeight": 300, + "overrides": { + "labelsEnabled": false + } + }, { + "maxHeight": 200, + "overrides": { + "autoMargins": false, + "marginTop": 0, + "marginBottom": 0, + "marginLeft": 0, + "marginRight": 0, + "radius": "50%", + "titles": { + "enabled": false + }, + "valueAxes": { + "radarCategoriesEnabled": false + } + } + }, { + "maxHeight": 100, + "overrides": { + "valueAxes": { + "labelsEnabled": false + } + } + } ], + + /** + * AmGauge + */ + + 'gauge': [ { + "maxWidth": 550, + "legendPosition": "left", + "overrides": { + "legend": { + "enabled": false + } + } + }, { + "maxWidth": 550, + "legendPosition": "right", + "overrides": { + "legend": { + "enabled": false + } + } + }, { + "maxWidth": 150, + "overrides": { + "legend": { + "enabled": false + } + } + }, { + "maxHeight": 500, + "legendPosition": "top", + "overrides": { + "legend": { + "enabled": false + } + } + }, { + "maxHeight": 500, + "legendPosition": "bottom", + "overrides": { + "legend": { + "enabled": false + } + } + }, { + "maxHeight": 150, + "overrides": { + "legend": { + "enabled": false + } + } + }, { + "maxWidth": 200, + "overrides": { + "titles": { + "enabled": false + }, + "allLabels": { + "enabled": false + }, + "axes": { + "labelsEnabled": false + } + } + }, { + "maxHeight": 200, + "overrides": { + "titles": { + "enabled": false + }, + "allLabels": { + "enabled": false + }, + "axes": { + "labelsEnabled": false + } + } + } ], + + /** + * AmSerial + */ + "serial": [ + + /** + * Disable legend in certain cases + */ + { + "maxWidth": 550, + "legendPosition": "left", + "overrides": { + "legend": { + "enabled": false + } + } + }, { + "maxWidth": 550, + "legendPosition": "right", + "overrides": { + "legend": { + "enabled": false + } + } + }, { + "maxWidth": 100, + "overrides": { + "legend": { + "enabled": false + } + } + }, { + "maxHeight": 350, + "legendPosition": "top", + "overrides": { + "legend": { + "enabled": false + } + } + }, { + "maxHeight": 350, + "legendPosition": "bottom", + "overrides": { + "legend": { + "enabled": false + } + } + }, { + "maxHeight": 100, + "overrides": { + "legend": { + "enabled": false + } + } + }, + + + /** + * Narrow chart + */ + { + "maxWidth": 350, + "overrides": { + "autoMarginOffset": 0, + "graphs": { + "hideBulletsCount": 10 + } + } + }, { + "maxWidth": 350, + "rotate": false, + "overrides": { + "marginLeft": 10, + "marginRight": 10, + "valueAxes": { + "ignoreAxisWidth": true, + "inside": true, + "title": "", + "showFirstLabel": false, + "showLastLabel": false + }, + "graphs": { + "bullet": "none" + } + } + }, { + "maxWidth": 350, + "rotate": true, + "overrides": { + "marginLeft": 10, + "marginRight": 10, + "categoryAxis": { + "ignoreAxisWidth": true, + "inside": true, + "title": "" + } + } + }, { + "maxWidth": 200, + "rotate": false, + "overrides": { + "marginLeft": 10, + "marginRight": 10, + "marginTop": 10, + "marginBottom": 10, + "categoryAxis": { + "ignoreAxisWidth": true, + "labelsEnabled": false, + "inside": true, + "title": "", + "guides": { + "inside": true + } + }, + "valueAxes": { + "ignoreAxisWidth": true, + "labelsEnabled": false, + "axisAlpha": 0, + "guides": { + "label": "" + } + }, + "legend": { + "enabled": false + } + } + }, { + "maxWidth": 200, + "rotate": true, + "overrides": { + "chartScrollbar": { + "scrollbarHeight": 4, + "graph": "", + "resizeEnabled": false + }, + "categoryAxis": { + "labelsEnabled": false, + "axisAlpha": 0, + "guides": { + "label": "" + } + }, + "legend": { + "enabled": false + } + } + }, { + "maxWidth": 100, + "rotate": false, + "overrides": { + "valueAxes": { + "gridAlpha": 0 + } + } + }, { + "maxWidth": 100, + "rotate": true, + "overrides": { + "categoryAxis": { + "gridAlpha": 0 + } + } + }, + + /** + * Short chart + */ + { + "maxHeight": 300, + "overrides": { + "autoMarginOffset": 0, + "graphs": { + "hideBulletsCount": 10 + } + } + }, { + "maxHeight": 200, + "rotate": false, + "overrides": { + "marginTop": 10, + "marginBottom": 10, + "categoryAxis": { + "ignoreAxisWidth": true, + "inside": true, + "title": "", + "showFirstLabel": false, + "showLastLabel": false + } + } + }, { + "maxHeight": 200, + "rotate": true, + "overrides": { + "marginTop": 10, + "marginBottom": 10, + "valueAxes": { + "ignoreAxisWidth": true, + "inside": true, + "title": "", + "showFirstLabel": false, + "showLastLabel": false + }, + "graphs": { + "bullet": "none" + } + } + }, { + "maxHeight": 150, + "rotate": false, + "overrides": { + "titles": { + "enabled": false + }, + "chartScrollbar": { + "scrollbarHeight": 4, + "graph": "", + "resizeEnabled": false + }, + "categoryAxis": { + "labelsEnabled": false, + "ignoreAxisWidth": true, + "axisAlpha": 0, + "guides": { + "label": "" + } + } + } + }, { + "maxHeight": 150, + "rotate": true, + "overrides": { + "titles": { + "enabled": false + }, + "valueAxes": { + "labelsEnabled": false, + "ignoreAxisWidth": true, + "axisAlpha": 0, + "guides": { + "label": "" + } + } + } + }, { + "maxHeight": 100, + "rotate": false, + "overrides": { + "valueAxes": { + "labelsEnabled": false, + "ignoreAxisWidth": true, + "axisAlpha": 0, + "gridAlpha": 0, + "guides": { + "label": "" + } + } + } + }, { + "maxHeight": 100, + "rotate": true, + "overrides": { + "categoryAxis": { + "labelsEnabled": false, + "ignoreAxisWidth": true, + "axisAlpha": 0, + "gridAlpha": 0, + "guides": { + "label": "" + } + } + } + }, + + /** + * Really small charts: microcharts and sparklines + */ + { + "maxWidth": 100, + "overrides": { + "autoMargins": false, + "marginTop": 0, + "marginBottom": 0, + "marginLeft": 0, + "marginRight": 0, + "categoryAxis": { + "labelsEnabled": false + }, + "valueAxes": { + "labelsEnabled": false + } + } + }, { + "maxHeight": 100, + "overrides": { + "autoMargins": false, + "marginTop": 0, + "marginBottom": 0, + "marginLeft": 0, + "marginRight": 0, + "categoryAxis": { + "labelsEnabled": false + }, + "valueAxes": { + "labelsEnabled": false + } + } + } + ], + + /** + * AmXY + */ + "xy": [ + + /** + * Disable legend in certain cases + */ + { + "maxWidth": 550, + "legendPosition": "left", + "overrides": { + "legend": { + "enabled": false + } + } + }, { + "maxWidth": 550, + "legendPosition": "right", + "overrides": { + "legend": { + "enabled": false + } + } + }, { + "maxWidth": 100, + "overrides": { + "legend": { + "enabled": false + } + } + }, { + "maxHeight": 350, + "legendPosition": "top", + "overrides": { + "legend": { + "enabled": false + } + } + }, { + "maxHeight": 350, + "legendPosition": "bottom", + "overrides": { + "legend": { + "enabled": false + } + } + }, { + "maxHeight": 100, + "overrides": { + "legend": { + "enabled": false + } + } + }, + + /** + * Narrow chart + */ + { + "maxWidth": 250, + "overrides": { + "autoMarginOffset": 0, + "autoMargins": false, + "marginTop": 0, + "marginBottom": 0, + "marginLeft": 0, + "marginRight": 0, + "valueAxes": { + "inside": true, + "title": "", + "showFirstLabel": false, + "showLastLabel": false + }, + "legend": { + "enabled": false + } + } + }, { + "maxWidth": 150, + "overrides": { + "valueyAxes": { + "labelsEnabled": false, + "axisAlpha": 0, + "gridAlpha": 0, + "guides": { + "label": "" + } + } + } + }, + + /** + * Short chart + */ + { + "maxHeight": 250, + "overrides": { + "autoMarginOffset": 0, + "autoMargins": false, + "marginTop": 0, + "marginBottom": 0, + "marginLeft": 0, + "marginRight": 0, + "valueAxes": { + "inside": true, + "title": "", + "showFirstLabel": false, + "showLastLabel": false + }, + "legend": { + "enabled": false + } + } + }, { + "maxWidth": 150, + "overrides": { + "valueyAxes": { + "labelsEnabled": false, + "axisAlpha": 0, + "gridAlpha": 0, + "guides": { + "label": "" + } + } + } + } + ], + + /** + * AmStock + */ + + 'stock': [ { + "maxWidth": 500, + "overrides": { + "dataSetSelector": { + "position": "top" + }, + "periodSelector": { + "position": "bottom" + } + } + }, { + "maxWidth": 400, + "overrides": { + "dataSetSelector": { + "selectText": "", + "compareText": "" + }, + "periodSelector": { + "periodsText": "", + "inputFieldsEnabled": false + } + } + } ], + + /** + * AmMap + */ + + 'map': [ { + "maxWidth": 200, + "overrides": { + "zoomControl": { + "zoomControlEnabled": false + }, + "smallMap": { + "enabled": false + }, + "valueLegend": { + "enabled": false + }, + "dataProvider": { + "areas": { + "descriptionWindowWidth": 160, + "descriptionWindowRight": 10, + "descriptionWindowTop": 10 + }, + "images": { + "descriptionWindowWidth": 160, + "descriptionWindowRight": 10, + "descriptionWindowTop": 10 + }, + "lines": { + "descriptionWindowWidth": 160, + "descriptionWindowRight": 10, + "descriptionWindowTop": 10 + } + } + } + }, { + "maxWidth": 150, + "overrides": { + "dataProvider": { + "areas": { + "descriptionWindowWidth": 110, + "descriptionWindowRight": 10, + "descriptionWindowTop": 10 + }, + "images": { + "descriptionWindowWidth": 110, + "descriptionWindowRight": 10, + "descriptionWindowTop": 10 + }, + "lines": { + "descriptionWindowWidth": 110, + "descriptionWindowLeft": 10, + "descriptionWindowRight": 10 + } + } + } + }, { + "maxHeight": 200, + "overrides": { + "zoomControl": { + "zoomControlEnabled": false + }, + "smallMap": { + "enabled": false + }, + "valueLegend": { + "enabled": false + }, + "dataProvider": { + "areas": { + "descriptionWindowHeight": 160, + "descriptionWindowRight": 10, + "descriptionWindowTop": 10 + }, + "images": { + "descriptionWindowHeight": 160, + "descriptionWindowRight": 10, + "descriptionWindowTop": 10 + }, + "lines": { + "descriptionWindowHeight": 160, + "descriptionWindowRight": 10, + "descriptionWindowTop": 10 + } + } + } + }, { + "maxHeight": 150, + "overrides": { + "dataProvider": { + "areas": { + "descriptionWindowHeight": 110, + "descriptionWindowRight": 10, + "descriptionWindowTop": 10 + }, + "images": { + "descriptionWindowHeight": 110, + "descriptionWindowRight": 10, + "descriptionWindowTop": 10 + }, + "lines": { + "descriptionWindowHeight": 110, + "descriptionWindowLeft": 10, + "descriptionWindowRight": 10 + } + } + } + } ] + }; + + var isNullOrUndefined = function( obj ) { + return ( obj === null ) || ( obj === undefined ); + }; + + var isArray = function( obj ) { + return ( !isNullOrUndefined( obj ) && Object.prototype.toString.call( obj ) === '[object Array]' ); + }; + + var isObject = function( obj ) { + return ( obj !== null && typeof obj === 'object' ); //the null check is necessary - recall that typeof null === 'object' ! + }; + + var findArrayObjectById = function( arr, id ) { + for ( var i = 0; i < arr.length; i++ ) { + if ( isObject( arr[ i ] ) && arr[ i ].id === id ) + return arr[ i ]; + } + return undefined; //we can use undefined as it doesn't have an Id property and so will never be the desired object from the array + }; + + var cloneWithoutPrototypes = function( obj ) { + if ( !isObject( obj ) ) { + return obj; + } + + if ( isArray( obj ) ) { + return obj.slice(); //effectively clones the array + } + + var clone = {}; //here is where we lose the prototype + for ( var property in obj ) { + if ( Object.prototype.hasOwnProperty.call( obj, property ) ) { + clone[ property ] = cloneWithoutPrototypes( obj[ property ] ); + } + } + return clone; + }; + + var originalValueRetainerPrefix = '{F0578839-A214-4E2D-8D1B-44941ECE8332}_'; + var noOriginalPropertyStub = {}; + + var overrideProperty = function( object, property, overrideValue ) { + + var originalValueRetainerProperty = originalValueRetainerPrefix + property; + if ( !( originalValueRetainerProperty in object ) ) { + object[ originalValueRetainerProperty ] = ( property in object ) ? object[ property ] : noOriginalPropertyStub; + } + + object[ property ] = cloneWithoutPrototypes( overrideValue ); + + r.overridden.push( { + object: object, + property: property + } ); + }; + + var restoreOriginalProperty = function( object, property ) { + var originalValue = object[ originalValueRetainerPrefix + property ]; + if ( originalValue === noOriginalPropertyStub ) { + delete object[ property ]; + } else { + object[ property ] = originalValue; + } + }; + + var restoreOriginals = function() { + while ( r.overridden.length > 0 ) { + var override = r.overridden.pop(); + restoreOriginalProperty( override.object, override.property ); + } + }; + + var redrawChart = function() { + chart.dataChanged = true; + if ( chart.type !== 'xy' ) { + chart.marginsUpdated = false; + } + chart.zoomOutOnDataUpdate = false; + chart.validateNow( true ); + restoreOriginalProperty( chart, 'zoomOutOnDataUpdate' ); + }; + + var applyConfig = function( current, override ) { + if ( isNullOrUndefined( override ) ) { + return; + } + + for ( var property in override ) { + if ( !Object.prototype.hasOwnProperty.call( override, property ) ) { + continue; + } + + var currentValue = current[ property ]; + var overrideValue = override[ property ]; + + //property doesn't exist on current object or it exists as null/undefined => completely override it + if ( isNullOrUndefined( currentValue ) ) { + overrideProperty( current, property, overrideValue ); + continue; + } + + //current value is an array => override method depends on override form + if ( isArray( currentValue ) ) { + + //override value is an array => override method depends on array elements + if ( isArray( overrideValue ) ) { + + //current value is an array of non-objects => override the entire array + //we assume a uniformly-typed array, so checking the first value should suffice + if ( ( currentValue.length > 0 && !isObject( currentValue[ 0 ] ) ) || ( overrideValue.length > 0 && !isObject( overrideValue[ 0 ] ) ) ) { + overrideProperty( current, property, overrideValue ); + continue; + } + + var idPresentOnAllOverrideElements = true; + for ( var k = 0; k < overrideValue.length; k++ ) { + if ( isNullOrUndefined( overrideValue[ k ] ) || isNullOrUndefined( overrideValue[ k ].id ) ) { + idPresentOnAllOverrideElements = false; + break; + } + } + + //Id property is present on all override elements => override elements by ID + if ( idPresentOnAllOverrideElements ) { + for ( var i = 0; i < overrideValue.length; i++ ) { + var correspondingCurrentElement = findArrayObjectById( currentValue, overrideValue[ i ].id ); + if ( correspondingCurrentElement === undefined ) { + throw ( 'could not find element to override in "' + property + '" with ID: ' + overrideValue[ i ].id ); + } + applyConfig( correspondingCurrentElement, overrideValue[ i ] ); + } + continue; + } + + //Id property is not set on all override elements and there aren't too many overrides => override objects by their index + if ( overrideValue.length <= currentValue.length ) { + for ( var l = 0; l < overrideValue.length; l++ ) { + applyConfig( currentValue[ l ], overrideValue[ l ] ); + } + continue; + } + + throw 'too many index-based overrides specified for object array property: ' + property; + } + + // override value is a single object => override all current array objects with that object + if ( isObject( overrideValue ) ) { + for ( var j = 0; j < currentValue.length; j++ ) { + applyConfig( currentValue[ j ], overrideValue ); + } + continue; + } + + throw ( 'non-object override detected for array property: ' + property ); + } + + if ( isObject( currentValue ) ) { + applyConfig( currentValue, overrideValue ); + continue; + } + + //if we reached this point, the property is defined on the current object but is not an object => override it + overrideProperty( current, property, overrideValue ); + } + }; + + var checkRules = function() { + + var width = chart.divRealWidth; + var height = chart.divRealHeight; + + // do nothing if the container is hidden (has no size) + if ( width === 0 || height === 0 ) + return; + + // update current rules + var rulesChanged = false; + for ( var i = 0; i < r.rules.length; i++ ) { + var rule = r.rules[ i ]; + + var ruleMatches = + ( rule.minWidth === undefined || ( rule.minWidth <= width ) ) && ( rule.maxWidth === undefined || ( rule.maxWidth >= width ) ) && + ( rule.minHeight === undefined || ( rule.minHeight <= height ) ) && ( rule.maxHeight === undefined || ( rule.maxHeight >= height ) ) && + ( rule.rotate === undefined || ( rule.rotate === true && chart.rotate === true ) || ( rule.rotate === false && ( chart.rotate === undefined || chart.rotate === false ) ) ) && + ( rule.legendPosition === undefined || ( chart.legend !== undefined && chart.legend.position !== undefined && chart.legend.position === rule.legendPosition ) ); + + if ( ruleMatches ) { + if ( r.currentRules[ i ] === undefined ) { + r.currentRules[ i ] = true; + rulesChanged = true; + } + } else if ( r.currentRules[ i ] !== undefined ) { + r.currentRules[ i ] = undefined; + rulesChanged = true; + } + } + + if ( !rulesChanged ) + return; + + restoreOriginals(); + + for ( var key in r.currentRules ) { + if ( !Object.prototype.hasOwnProperty.call( r.currentRules, key ) ) { + continue; + } + + if ( r.currentRules[ key ] !== undefined ) { + if ( isNullOrUndefined( r.rules[ key ] ) ) { + throw 'null or undefined rule in index: ' + key; + } + applyConfig( chart, r.rules[ key ].overrides ); + } + } + + // TODO - re-apply zooms/slices as necessary + + redrawChart(); + }; + + defaults.gantt = defaults.serial; + + if ( !isArray( r.rules ) ) { + r.rules = defaults[ chart.type ]; + } else if ( r.addDefaultRules !== false ) { + r.rules = defaults[ chart.type ].concat( r.rules ); + } + + //retain original zoomOutOnDataUpdate value + overrideProperty( chart, 'zoomOutOnDataUpdate', chart.zoomOutOnDataUpdate ); + + chart.addListener( 'resized', checkRules ); + chart.addListener( 'init', checkRules ); + +}, [ 'pie', 'serial', 'xy', 'funnel', 'radar', 'gauge', 'gantt', 'stock', 'map' ] ); \ No newline at end of file diff --git a/iguana/js/amcharts/plugins/responsive/responsive.min.js b/iguana/js/amcharts/plugins/responsive/responsive.min.js new file mode 100755 index 000000000..dad9ba016 --- /dev/null +++ b/iguana/js/amcharts/plugins/responsive/responsive.min.js @@ -0,0 +1,2 @@ +AmCharts.addInitHandler(function(n){"use strict";var u,t;if(n.responsive!==undefined&&n.responsive.ready!==!0&&n.responsive.enabled===!0&&(u=n.version.split("."),!(u.length<2)&&!(Number(u[0])<3)&&(Number(u[0])!==3||!(Number(u[1])<13)))){t=n.responsive;t.ready=!0;t.currentRules={};t.overridden=[];var e={pie:[{maxWidth:550,legendPosition:"left",overrides:{legend:{enabled:!1}}},{maxWidth:550,legendPosition:"right",overrides:{legend:{enabled:!1}}},{maxWidth:150,overrides:{legend:{enabled:!1}}},{maxHeight:350,legendPosition:"top",overrides:{legend:{enabled:!1}}},{maxHeight:350,legendPosition:"bottom",overrides:{legend:{enabled:!1}}},{maxHeight:150,overrides:{legend:{enabled:!1}}},{maxWidth:400,overrides:{labelsEnabled:!1}},{maxWidth:100,overrides:{legend:{enabled:!1}}},{maxHeight:350,overrides:{pullOutRadius:0}},{maxHeight:200,overrides:{titles:{enabled:!1},labelsEnabled:!1}},{maxWidth:60,overrides:{autoMargins:!1,marginTop:0,marginBottom:0,marginLeft:0,marginRight:0,radius:"50%",innerRadius:0,balloon:{enabled:!1},legend:{enabled:!1}}},{maxHeight:60,overrides:{marginTop:0,marginBottom:0,marginLeft:0,marginRight:0,radius:"50%",innerRadius:0,balloon:{enabled:!1},legend:{enabled:!1}}}],funnel:[{maxWidth:550,legendPosition:"left",overrides:{legend:{enabled:!1}}},{maxWidth:550,legendPosition:"right",overrides:{legend:{enabled:!1}}},{maxWidth:150,overrides:{legend:{enabled:!1}}},{maxHeight:500,legendPosition:"top",overrides:{legend:{enabled:!1}}},{maxHeight:500,legendPosition:"bottom",overrides:{legend:{enabled:!1}}},{maxHeight:150,overrides:{legend:{enabled:!1}}},{maxWidth:400,overrides:{labelsEnabled:!1,marginLeft:10,marginRight:10,legend:{enabled:!1}}},{maxHeight:350,overrides:{pullOutRadius:0,legend:{enabled:!1}}},{maxHeight:300,overrides:{titles:{enabled:!1}}}],radar:[{maxWidth:550,legendPosition:"left",overrides:{legend:{enabled:!1}}},{maxWidth:550,legendPosition:"right",overrides:{legend:{enabled:!1}}},{maxWidth:150,overrides:{legend:{enabled:!1}}},{maxHeight:350,legendPosition:"top",overrides:{legend:{enabled:!1}}},{maxHeight:350,legendPosition:"bottom",overrides:{legend:{enabled:!1}}},{maxHeight:150,overrides:{legend:{enabled:!1}}},{maxWidth:300,overrides:{labelsEnabled:!1}},{maxWidth:200,overrides:{autoMargins:!1,marginTop:0,marginBottom:0,marginLeft:0,marginRight:0,radius:"50%",titles:{enabled:!1},valueAxes:{labelsEnabled:!1,radarCategoriesEnabled:!1}}},{maxHeight:300,overrides:{labelsEnabled:!1}},{maxHeight:200,overrides:{autoMargins:!1,marginTop:0,marginBottom:0,marginLeft:0,marginRight:0,radius:"50%",titles:{enabled:!1},valueAxes:{radarCategoriesEnabled:!1}}},{maxHeight:100,overrides:{valueAxes:{labelsEnabled:!1}}}],gauge:[{maxWidth:550,legendPosition:"left",overrides:{legend:{enabled:!1}}},{maxWidth:550,legendPosition:"right",overrides:{legend:{enabled:!1}}},{maxWidth:150,overrides:{legend:{enabled:!1}}},{maxHeight:500,legendPosition:"top",overrides:{legend:{enabled:!1}}},{maxHeight:500,legendPosition:"bottom",overrides:{legend:{enabled:!1}}},{maxHeight:150,overrides:{legend:{enabled:!1}}},{maxWidth:200,overrides:{titles:{enabled:!1},allLabels:{enabled:!1},axes:{labelsEnabled:!1}}},{maxHeight:200,overrides:{titles:{enabled:!1},allLabels:{enabled:!1},axes:{labelsEnabled:!1}}}],serial:[{maxWidth:550,legendPosition:"left",overrides:{legend:{enabled:!1}}},{maxWidth:550,legendPosition:"right",overrides:{legend:{enabled:!1}}},{maxWidth:100,overrides:{legend:{enabled:!1}}},{maxHeight:350,legendPosition:"top",overrides:{legend:{enabled:!1}}},{maxHeight:350,legendPosition:"bottom",overrides:{legend:{enabled:!1}}},{maxHeight:100,overrides:{legend:{enabled:!1}}},{maxWidth:350,overrides:{autoMarginOffset:0,graphs:{hideBulletsCount:10}}},{maxWidth:350,rotate:!1,overrides:{marginLeft:10,marginRight:10,valueAxes:{ignoreAxisWidth:!0,inside:!0,title:"",showFirstLabel:!1,showLastLabel:!1},graphs:{bullet:"none"}}},{maxWidth:350,rotate:!0,overrides:{marginLeft:10,marginRight:10,categoryAxis:{ignoreAxisWidth:!0,inside:!0,title:""}}},{maxWidth:200,rotate:!1,overrides:{marginLeft:10,marginRight:10,marginTop:10,marginBottom:10,categoryAxis:{ignoreAxisWidth:!0,labelsEnabled:!1,inside:!0,title:"",guides:{inside:!0}},valueAxes:{ignoreAxisWidth:!0,labelsEnabled:!1,axisAlpha:0,guides:{label:""}},legend:{enabled:!1}}},{maxWidth:200,rotate:!0,overrides:{chartScrollbar:{scrollbarHeight:4,graph:"",resizeEnabled:!1},categoryAxis:{labelsEnabled:!1,axisAlpha:0,guides:{label:""}},legend:{enabled:!1}}},{maxWidth:100,rotate:!1,overrides:{valueAxes:{gridAlpha:0}}},{maxWidth:100,rotate:!0,overrides:{categoryAxis:{gridAlpha:0}}},{maxHeight:300,overrides:{autoMarginOffset:0,graphs:{hideBulletsCount:10}}},{maxHeight:200,rotate:!1,overrides:{marginTop:10,marginBottom:10,categoryAxis:{ignoreAxisWidth:!0,inside:!0,title:"",showFirstLabel:!1,showLastLabel:!1}}},{maxHeight:200,rotate:!0,overrides:{marginTop:10,marginBottom:10,valueAxes:{ignoreAxisWidth:!0,inside:!0,title:"",showFirstLabel:!1,showLastLabel:!1},graphs:{bullet:"none"}}},{maxHeight:150,rotate:!1,overrides:{titles:{enabled:!1},chartScrollbar:{scrollbarHeight:4,graph:"",resizeEnabled:!1},categoryAxis:{labelsEnabled:!1,ignoreAxisWidth:!0,axisAlpha:0,guides:{label:""}}}},{maxHeight:150,rotate:!0,overrides:{titles:{enabled:!1},valueAxes:{labelsEnabled:!1,ignoreAxisWidth:!0,axisAlpha:0,guides:{label:""}}}},{maxHeight:100,rotate:!1,overrides:{valueAxes:{labelsEnabled:!1,ignoreAxisWidth:!0,axisAlpha:0,gridAlpha:0,guides:{label:""}}}},{maxHeight:100,rotate:!0,overrides:{categoryAxis:{labelsEnabled:!1,ignoreAxisWidth:!0,axisAlpha:0,gridAlpha:0,guides:{label:""}}}},{maxWidth:100,overrides:{autoMargins:!1,marginTop:0,marginBottom:0,marginLeft:0,marginRight:0,categoryAxis:{labelsEnabled:!1},valueAxes:{labelsEnabled:!1}}},{maxHeight:100,overrides:{autoMargins:!1,marginTop:0,marginBottom:0,marginLeft:0,marginRight:0,categoryAxis:{labelsEnabled:!1},valueAxes:{labelsEnabled:!1}}}],xy:[{maxWidth:550,legendPosition:"left",overrides:{legend:{enabled:!1}}},{maxWidth:550,legendPosition:"right",overrides:{legend:{enabled:!1}}},{maxWidth:100,overrides:{legend:{enabled:!1}}},{maxHeight:350,legendPosition:"top",overrides:{legend:{enabled:!1}}},{maxHeight:350,legendPosition:"bottom",overrides:{legend:{enabled:!1}}},{maxHeight:100,overrides:{legend:{enabled:!1}}},{maxWidth:250,overrides:{autoMarginOffset:0,autoMargins:!1,marginTop:0,marginBottom:0,marginLeft:0,marginRight:0,valueAxes:{inside:!0,title:"",showFirstLabel:!1,showLastLabel:!1},legend:{enabled:!1}}},{maxWidth:150,overrides:{valueyAxes:{labelsEnabled:!1,axisAlpha:0,gridAlpha:0,guides:{label:""}}}},{maxHeight:250,overrides:{autoMarginOffset:0,autoMargins:!1,marginTop:0,marginBottom:0,marginLeft:0,marginRight:0,valueAxes:{inside:!0,title:"",showFirstLabel:!1,showLastLabel:!1},legend:{enabled:!1}}},{maxWidth:150,overrides:{valueyAxes:{labelsEnabled:!1,axisAlpha:0,gridAlpha:0,guides:{label:""}}}}],stock:[{maxWidth:500,overrides:{dataSetSelector:{position:"top"},periodSelector:{position:"bottom"}}},{maxWidth:400,overrides:{dataSetSelector:{selectText:"",compareText:""},periodSelector:{periodsText:"",inputFieldsEnabled:!1}}}],map:[{maxWidth:200,overrides:{zoomControl:{zoomControlEnabled:!1},smallMap:{enabled:!1},valueLegend:{enabled:!1},dataProvider:{areas:{descriptionWindowWidth:160,descriptionWindowRight:10,descriptionWindowTop:10},images:{descriptionWindowWidth:160,descriptionWindowRight:10,descriptionWindowTop:10},lines:{descriptionWindowWidth:160,descriptionWindowRight:10,descriptionWindowTop:10}}}},{maxWidth:150,overrides:{dataProvider:{areas:{descriptionWindowWidth:110,descriptionWindowRight:10,descriptionWindowTop:10},images:{descriptionWindowWidth:110,descriptionWindowRight:10,descriptionWindowTop:10},lines:{descriptionWindowWidth:110,descriptionWindowLeft:10,descriptionWindowRight:10}}}},{maxHeight:200,overrides:{zoomControl:{zoomControlEnabled:!1},smallMap:{enabled:!1},valueLegend:{enabled:!1},dataProvider:{areas:{descriptionWindowHeight:160,descriptionWindowRight:10,descriptionWindowTop:10},images:{descriptionWindowHeight:160,descriptionWindowRight:10,descriptionWindowTop:10},lines:{descriptionWindowHeight:160,descriptionWindowRight:10,descriptionWindowTop:10}}}},{maxHeight:150,overrides:{dataProvider:{areas:{descriptionWindowHeight:110,descriptionWindowRight:10,descriptionWindowTop:10},images:{descriptionWindowHeight:110,descriptionWindowRight:10,descriptionWindowTop:10},lines:{descriptionWindowHeight:110,descriptionWindowLeft:10,descriptionWindowRight:10}}}}]},i=function(n){return n===null||n===undefined},o=function(n){return!i(n)&&Object.prototype.toString.call(n)==="[object Array]"},r=function(n){return n!==null&&typeof n=="object"},y=function(n,t){for(var i=0;i0){var n=t.overridden.pop();a(n.object,n.property)}},w=function(){n.dataChanged=!0;n.type!=="xy"&&(n.marginsUpdated=!1);n.zoomOutOnDataUpdate=!1;n.validateNow(!0);a(n,"zoomOutOnDataUpdate")},f=function(n,t){var h,e,u,p,l,c,w,a,v;if(!i(t))for(h in t)if(Object.prototype.hasOwnProperty.call(t,h)){if(e=n[h],u=t[h],i(e)){s(n,h,u);continue}if(o(e)){if(o(u)){if(e.length>0&&!r(e[0])||u.length>0&&!r(u[0])){s(n,h,u);continue}for(p=!0,l=0;l=s)&&(r.minHeight===undefined||r.minHeight<=h)&&(r.maxHeight===undefined||r.maxHeight>=h)&&(r.rotate===undefined||r.rotate===!0&&n.rotate===!0||r.rotate===!1&&(n.rotate===undefined||n.rotate===!1))&&(r.legendPosition===undefined||n.legend!==undefined&&n.legend.position!==undefined&&n.legend.position===r.legendPosition),c?t.currentRules[u]===undefined&&(t.currentRules[u]=!0,o=!0):t.currentRules[u]!==undefined&&(t.currentRules[u]=undefined,o=!0);if(o){p();for(e in t.currentRules)if(Object.prototype.hasOwnProperty.call(t.currentRules,e)&&t.currentRules[e]!==undefined){if(i(t.rules[e]))throw"null or undefined rule in index: "+e;f(n,t.rules[e].overrides)}w()}}};e.gantt=e.serial;o(t.rules)?t.addDefaultRules!==!1&&(t.rules=e[n.type].concat(t.rules)):t.rules=e[n.type];s(n,"zoomOutOnDataUpdate",n.zoomOutOnDataUpdate);n.addListener("resized",v);n.addListener("init",v)}},["pie","serial","xy","funnel","radar","gauge","gantt","stock","map"]); +//# sourceMappingURL=responsive.min.js.map diff --git a/iguana/js/amcharts/plugins/responsive/responsive.min.js.map b/iguana/js/amcharts/plugins/responsive/responsive.min.js.map new file mode 100755 index 000000000..a65b429ce --- /dev/null +++ b/iguana/js/amcharts/plugins/responsive/responsive.min.js.map @@ -0,0 +1,8 @@ +{ +"version":3, +"file":"responsive.min.js", +"lineCount":1, +"mappings":"AA4BAA,QAAQC,eAAe,CAAE,QAAQ,CAAEC,CAAF,CAAU,CACzC,Y,CAKA,IAAIC,EAKAC,CALoC,CAHxC,GAAKF,CAAKG,WAAY,GAAIC,SAAU,EAAGJ,CAAKG,WAAWE,MAAO,GAAI,CAAA,CAAK,EAAGL,CAAKG,WAAWG,QAAS,GAAI,CAAA,C,GAGnGL,CAAQ,CAAED,CAAKC,QAAQM,MAAM,CAAE,GAAF,C,CAC1B,EAAAN,CAAOO,OAAQ,CAAE,EAAI,EAAG,EAAAC,MAAM,CAAER,CAAS,CAAA,CAAA,CAAX,CAAiB,CAAE,EAAE,GAAKQ,MAAM,CAAER,CAAS,CAAA,CAAA,CAAX,CAAiB,GAAI,CAAE,EAAG,EAAAQ,MAAM,CAAER,CAAS,CAAA,CAAA,CAAX,CAAiB,CAAE,MACtH,CAGEC,CAAE,CAAEF,CAAKG,W,CAEbD,CAACG,MAAO,CAAE,CAAA,CAAI,CACdH,CAACQ,aAAc,CAAE,CAAA,CAAE,CACnBR,CAACS,WAAY,CAAE,CAAA,CAAE,CAGjB,IAAIC,EAAW,CAKb,GAAK,CAAE,CAKL,CACE,QAAU,CAAE,GAAG,CACf,cAAgB,CAAE,MAAM,CACxB,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CADC,CAHf,CAQC,CAAE,CACD,QAAU,CAAE,GAAG,CACf,cAAgB,CAAE,OAAO,CACzB,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CADC,CAHZ,CAQF,CAAE,CACD,QAAU,CAAE,GAAG,CACf,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CADC,CAFZ,CAOF,CAAE,CACD,SAAW,CAAE,GAAG,CAChB,cAAgB,CAAE,KAAK,CACvB,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CADC,CAHZ,CAQF,CAAE,CACD,SAAW,CAAE,GAAG,CAChB,cAAgB,CAAE,QAAQ,CAC1B,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CADC,CAHZ,CAQF,CAAE,CACD,SAAW,CAAE,GAAG,CAChB,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CADC,CAFZ,CAOF,CAKD,CACE,QAAU,CAAE,GAAG,CACf,SAAW,CAAE,CACX,aAAe,CAAE,CAAA,CADN,CAFf,CAKC,CAAE,CACD,QAAU,CAAE,GAAG,CACf,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CADC,CAFZ,CAOF,CAKD,CACE,SAAW,CAAE,GAAG,CAChB,SAAW,CAAE,CACX,aAAe,CAAE,CADN,CAFf,CAKC,CAAE,CACD,SAAW,CAAE,GAAG,CAChB,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CAET,CACD,aAAe,CAAE,CAAA,CAJN,CAFZ,CAQF,CAKD,CACE,QAAU,CAAE,EAAE,CACd,SAAW,CAAE,CACX,WAAa,CAAE,CAAA,CAAK,CACpB,SAAW,CAAE,CAAC,CACd,YAAc,CAAE,CAAC,CACjB,UAAY,CAAE,CAAC,CACf,WAAa,CAAE,CAAC,CAChB,MAAQ,CAAE,KAAK,CACf,WAAa,CAAE,CAAC,CAChB,OAAS,CAAE,CACT,OAAS,CAAE,CAAA,CADF,CAEV,CACD,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CAXC,CAFf,CAiBC,CAAE,CACD,SAAW,CAAE,EAAE,CACf,SAAW,CAAE,CACX,SAAW,CAAE,CAAC,CACd,YAAc,CAAE,CAAC,CACjB,UAAY,CAAE,CAAC,CACf,WAAa,CAAE,CAAC,CAChB,MAAQ,CAAE,KAAK,CACf,WAAa,CAAE,CAAC,CAChB,OAAS,CAAE,CACT,OAAS,CAAE,CAAA,CADF,CAEV,CACD,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CAVC,CAFZ,CA5GE,CA6HN,CAMD,MAAQ,CAAE,CAAE,CACV,QAAU,CAAE,GAAG,CACf,cAAgB,CAAE,MAAM,CACxB,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CADC,CAHH,CAQX,CAAE,CACD,QAAU,CAAE,GAAG,CACf,cAAgB,CAAE,OAAO,CACzB,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CADC,CAHZ,CAQF,CAAE,CACD,QAAU,CAAE,GAAG,CACf,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CADC,CAFZ,CAOF,CAAE,CACD,SAAW,CAAE,GAAG,CAChB,cAAgB,CAAE,KAAK,CACvB,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CADC,CAHZ,CAQF,CAAE,CACD,SAAW,CAAE,GAAG,CAChB,cAAgB,CAAE,QAAQ,CAC1B,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CADC,CAHZ,CAQF,CAAE,CACD,SAAW,CAAE,GAAG,CAChB,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CADC,CAFZ,CAOF,CAAE,CACD,QAAU,CAAE,GAAG,CACf,SAAW,CAAE,CACX,aAAe,CAAE,CAAA,CAAK,CACtB,UAAY,CAAE,EAAE,CAChB,WAAa,CAAE,EAAE,CACjB,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CAJC,CAFZ,CAUF,CAAE,CACD,SAAW,CAAE,GAAG,CAChB,SAAW,CAAE,CACX,aAAe,CAAE,CAAC,CAClB,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CAFC,CAFZ,CAQF,CAAE,CACD,SAAW,CAAE,GAAG,CAChB,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CADC,CAFZ,CAhEO,CAuEP,CAMH,KAAO,CAAE,CAAE,CACT,QAAU,CAAE,GAAG,CACf,cAAgB,CAAE,MAAM,CACxB,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CADC,CAHJ,CAQV,CAAE,CACD,QAAU,CAAE,GAAG,CACf,cAAgB,CAAE,OAAO,CACzB,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CADC,CAHZ,CAQF,CAAE,CACD,QAAU,CAAE,GAAG,CACf,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CADC,CAFZ,CAOF,CAAE,CACD,SAAW,CAAE,GAAG,CAChB,cAAgB,CAAE,KAAK,CACvB,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CADC,CAHZ,CAQF,CAAE,CACD,SAAW,CAAE,GAAG,CAChB,cAAgB,CAAE,QAAQ,CAC1B,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CADC,CAHZ,CAQF,CAAE,CACD,SAAW,CAAE,GAAG,CAChB,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CADC,CAFZ,CAOF,CAAE,CACD,QAAU,CAAE,GAAG,CACf,SAAW,CAAE,CACX,aAAe,CAAE,CAAA,CADN,CAFZ,CAKF,CAAE,CACD,QAAU,CAAE,GAAG,CACf,SAAW,CAAE,CACX,WAAa,CAAE,CAAA,CAAK,CACpB,SAAW,CAAE,CAAC,CACd,YAAc,CAAE,CAAC,CACjB,UAAY,CAAE,CAAC,CACf,WAAa,CAAE,CAAC,CAChB,MAAQ,CAAE,KAAK,CACf,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CAET,CACD,SAAW,CAAE,CACX,aAAe,CAAE,CAAA,CAAK,CACtB,sBAAwB,CAAE,CAAA,CAFf,CAVF,CAFZ,CAiBF,CAAE,CACD,SAAW,CAAE,GAAG,CAChB,SAAW,CAAE,CACX,aAAe,CAAE,CAAA,CADN,CAFZ,CAKF,CAAE,CACD,SAAW,CAAE,GAAG,CAChB,SAAW,CAAE,CACX,WAAa,CAAE,CAAA,CAAK,CACpB,SAAW,CAAE,CAAC,CACd,YAAc,CAAE,CAAC,CACjB,UAAY,CAAE,CAAC,CACf,WAAa,CAAE,CAAC,CAChB,MAAQ,CAAE,KAAK,CACf,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CAET,CACD,SAAW,CAAE,CACX,sBAAwB,CAAE,CAAA,CADf,CAVF,CAFZ,CAgBF,CAAE,CACD,SAAW,CAAE,GAAG,CAChB,SAAW,CAAE,CACX,SAAW,CAAE,CACX,aAAe,CAAE,CAAA,CADN,CADF,CAFZ,CAzFM,CAgGN,CAMH,KAAO,CAAE,CAAE,CACT,QAAU,CAAE,GAAG,CACf,cAAgB,CAAE,MAAM,CACxB,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CADC,CAHJ,CAQV,CAAE,CACD,QAAU,CAAE,GAAG,CACf,cAAgB,CAAE,OAAO,CACzB,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CADC,CAHZ,CAQF,CAAE,CACD,QAAU,CAAE,GAAG,CACf,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CADC,CAFZ,CAOF,CAAE,CACD,SAAW,CAAE,GAAG,CAChB,cAAgB,CAAE,KAAK,CACvB,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CADC,CAHZ,CAQF,CAAE,CACD,SAAW,CAAE,GAAG,CAChB,cAAgB,CAAE,QAAQ,CAC1B,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CADC,CAHZ,CAQF,CAAE,CACD,SAAW,CAAE,GAAG,CAChB,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CADC,CAFZ,CAOF,CAAE,CACD,QAAU,CAAE,GAAG,CACf,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CAET,CACD,SAAW,CAAE,CACX,OAAS,CAAE,CAAA,CADA,CAEZ,CACD,IAAM,CAAE,CACN,aAAe,CAAE,CAAA,CADX,CAPG,CAFZ,CAaF,CAAE,CACD,SAAW,CAAE,GAAG,CAChB,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CAET,CACD,SAAW,CAAE,CACX,OAAS,CAAE,CAAA,CADA,CAEZ,CACD,IAAM,CAAE,CACN,aAAe,CAAE,CAAA,CADX,CAPG,CAFZ,CA3DM,CAwEN,CAKH,MAAQ,CAAE,CAKR,CACE,QAAU,CAAE,GAAG,CACf,cAAgB,CAAE,MAAM,CACxB,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CADC,CAHf,CAQC,CAAE,CACD,QAAU,CAAE,GAAG,CACf,cAAgB,CAAE,OAAO,CACzB,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CADC,CAHZ,CAQF,CAAE,CACD,QAAU,CAAE,GAAG,CACf,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CADC,CAFZ,CAOF,CAAE,CACD,SAAW,CAAE,GAAG,CAChB,cAAgB,CAAE,KAAK,CACvB,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CADC,CAHZ,CAQF,CAAE,CACD,SAAW,CAAE,GAAG,CAChB,cAAgB,CAAE,QAAQ,CAC1B,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CADC,CAHZ,CAQF,CAAE,CACD,SAAW,CAAE,GAAG,CAChB,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CADC,CAFZ,CAOF,CAMD,CACE,QAAU,CAAE,GAAG,CACf,SAAW,CAAE,CACX,gBAAkB,CAAE,CAAC,CACrB,MAAQ,CAAE,CACR,gBAAkB,CAAE,EADZ,CAFC,CAFf,CAQC,CAAE,CACD,QAAU,CAAE,GAAG,CACf,MAAQ,CAAE,CAAA,CAAK,CACf,SAAW,CAAE,CACX,UAAY,CAAE,EAAE,CAChB,WAAa,CAAE,EAAE,CACjB,SAAW,CAAE,CACX,eAAiB,CAAE,CAAA,CAAI,CACvB,MAAQ,CAAE,CAAA,CAAI,CACd,KAAO,CAAE,EAAE,CACX,cAAgB,CAAE,CAAA,CAAK,CACvB,aAAe,CAAE,CAAA,CALN,CAMZ,CACD,MAAQ,CAAE,CACR,MAAQ,CAAE,MADF,CAVC,CAHZ,CAiBF,CAAE,CACD,QAAU,CAAE,GAAG,CACf,MAAQ,CAAE,CAAA,CAAI,CACd,SAAW,CAAE,CACX,UAAY,CAAE,EAAE,CAChB,WAAa,CAAE,EAAE,CACjB,YAAc,CAAE,CACd,eAAiB,CAAE,CAAA,CAAI,CACvB,MAAQ,CAAE,CAAA,CAAI,CACd,KAAO,CAAE,EAHK,CAHL,CAHZ,CAYF,CAAE,CACD,QAAU,CAAE,GAAG,CACf,MAAQ,CAAE,CAAA,CAAK,CACf,SAAW,CAAE,CACX,UAAY,CAAE,EAAE,CAChB,WAAa,CAAE,EAAE,CACjB,SAAW,CAAE,EAAE,CACf,YAAc,CAAE,EAAE,CAClB,YAAc,CAAE,CACd,eAAiB,CAAE,CAAA,CAAI,CACvB,aAAe,CAAE,CAAA,CAAK,CACtB,MAAQ,CAAE,CAAA,CAAI,CACd,KAAO,CAAE,EAAE,CACX,MAAQ,CAAE,CACR,MAAQ,CAAE,CAAA,CADF,CALI,CAQf,CACD,SAAW,CAAE,CACX,eAAiB,CAAE,CAAA,CAAI,CACvB,aAAe,CAAE,CAAA,CAAK,CACtB,SAAW,CAAE,CAAC,CACd,MAAQ,CAAE,CACR,KAAO,CAAE,EADD,CAJC,CAOZ,CACD,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CAtBC,CAHZ,CA6BF,CAAE,CACD,QAAU,CAAE,GAAG,CACf,MAAQ,CAAE,CAAA,CAAI,CACd,SAAW,CAAE,CACX,cAAgB,CAAE,CAChB,eAAiB,CAAE,CAAC,CACpB,KAAO,CAAE,EAAE,CACX,aAAe,CAAE,CAAA,CAHD,CAIjB,CACD,YAAc,CAAE,CACd,aAAe,CAAE,CAAA,CAAK,CACtB,SAAW,CAAE,CAAC,CACd,MAAQ,CAAE,CACR,KAAO,CAAE,EADD,CAHI,CAMf,CACD,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CAbC,CAHZ,CAoBF,CAAE,CACD,QAAU,CAAE,GAAG,CACf,MAAQ,CAAE,CAAA,CAAK,CACf,SAAW,CAAE,CACX,SAAW,CAAE,CACX,SAAW,CAAE,CADF,CADF,CAHZ,CAQF,CAAE,CACD,QAAU,CAAE,GAAG,CACf,MAAQ,CAAE,CAAA,CAAI,CACd,SAAW,CAAE,CACX,YAAc,CAAE,CACd,SAAW,CAAE,CADC,CADL,CAHZ,CAQF,CAKD,CACE,SAAW,CAAE,GAAG,CAChB,SAAW,CAAE,CACX,gBAAkB,CAAE,CAAC,CACrB,MAAQ,CAAE,CACR,gBAAkB,CAAE,EADZ,CAFC,CAFf,CAQC,CAAE,CACD,SAAW,CAAE,GAAG,CAChB,MAAQ,CAAE,CAAA,CAAK,CACf,SAAW,CAAE,CACX,SAAW,CAAE,EAAE,CACf,YAAc,CAAE,EAAE,CAClB,YAAc,CAAE,CACd,eAAiB,CAAE,CAAA,CAAI,CACvB,MAAQ,CAAE,CAAA,CAAI,CACd,KAAO,CAAE,EAAE,CACX,cAAgB,CAAE,CAAA,CAAK,CACvB,aAAe,CAAE,CAAA,CALH,CAHL,CAHZ,CAcF,CAAE,CACD,SAAW,CAAE,GAAG,CAChB,MAAQ,CAAE,CAAA,CAAI,CACd,SAAW,CAAE,CACX,SAAW,CAAE,EAAE,CACf,YAAc,CAAE,EAAE,CAClB,SAAW,CAAE,CACX,eAAiB,CAAE,CAAA,CAAI,CACvB,MAAQ,CAAE,CAAA,CAAI,CACd,KAAO,CAAE,EAAE,CACX,cAAgB,CAAE,CAAA,CAAK,CACvB,aAAe,CAAE,CAAA,CALN,CAMZ,CACD,MAAQ,CAAE,CACR,MAAQ,CAAE,MADF,CAVC,CAHZ,CAiBF,CAAE,CACD,SAAW,CAAE,GAAG,CAChB,MAAQ,CAAE,CAAA,CAAK,CACf,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CAET,CACD,cAAgB,CAAE,CAChB,eAAiB,CAAE,CAAC,CACpB,KAAO,CAAE,EAAE,CACX,aAAe,CAAE,CAAA,CAHD,CAIjB,CACD,YAAc,CAAE,CACd,aAAe,CAAE,CAAA,CAAK,CACtB,eAAiB,CAAE,CAAA,CAAI,CACvB,SAAW,CAAE,CAAC,CACd,MAAQ,CAAE,CACR,KAAO,CAAE,EADD,CAJI,CATL,CAHZ,CAqBF,CAAE,CACD,SAAW,CAAE,GAAG,CAChB,MAAQ,CAAE,CAAA,CAAI,CACd,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CAET,CACD,SAAW,CAAE,CACX,aAAe,CAAE,CAAA,CAAK,CACtB,eAAiB,CAAE,CAAA,CAAI,CACvB,SAAW,CAAE,CAAC,CACd,MAAQ,CAAE,CACR,KAAO,CAAE,EADD,CAJC,CAJF,CAHZ,CAgBF,CAAE,CACD,SAAW,CAAE,GAAG,CAChB,MAAQ,CAAE,CAAA,CAAK,CACf,SAAW,CAAE,CACX,SAAW,CAAE,CACX,aAAe,CAAE,CAAA,CAAK,CACtB,eAAiB,CAAE,CAAA,CAAI,CACvB,SAAW,CAAE,CAAC,CACd,SAAW,CAAE,CAAC,CACd,MAAQ,CAAE,CACR,KAAO,CAAE,EADD,CALC,CADF,CAHZ,CAcF,CAAE,CACD,SAAW,CAAE,GAAG,CAChB,MAAQ,CAAE,CAAA,CAAI,CACd,SAAW,CAAE,CACX,YAAc,CAAE,CACd,aAAe,CAAE,CAAA,CAAK,CACtB,eAAiB,CAAE,CAAA,CAAI,CACvB,SAAW,CAAE,CAAC,CACd,SAAW,CAAE,CAAC,CACd,MAAQ,CAAE,CACR,KAAO,CAAE,EADD,CALI,CADL,CAHZ,CAcF,CAKD,CACE,QAAU,CAAE,GAAG,CACf,SAAW,CAAE,CACX,WAAa,CAAE,CAAA,CAAK,CACpB,SAAW,CAAE,CAAC,CACd,YAAc,CAAE,CAAC,CACjB,UAAY,CAAE,CAAC,CACf,WAAa,CAAE,CAAC,CAChB,YAAc,CAAE,CACd,aAAe,CAAE,CAAA,CADH,CAEf,CACD,SAAW,CAAE,CACX,aAAe,CAAE,CAAA,CADN,CATF,CAFf,CAeC,CAAE,CACD,SAAW,CAAE,GAAG,CAChB,SAAW,CAAE,CACX,WAAa,CAAE,CAAA,CAAK,CACpB,SAAW,CAAE,CAAC,CACd,YAAc,CAAE,CAAC,CACjB,UAAY,CAAE,CAAC,CACf,WAAa,CAAE,CAAC,CAChB,YAAc,CAAE,CACd,aAAe,CAAE,CAAA,CADH,CAEf,CACD,SAAW,CAAE,CACX,aAAe,CAAE,CAAA,CADN,CATF,CAFZ,CAhSK,CAgTT,CAKD,EAAI,CAAE,CAKJ,CACE,QAAU,CAAE,GAAG,CACf,cAAgB,CAAE,MAAM,CACxB,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CADC,CAHf,CAQC,CAAE,CACD,QAAU,CAAE,GAAG,CACf,cAAgB,CAAE,OAAO,CACzB,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CADC,CAHZ,CAQF,CAAE,CACD,QAAU,CAAE,GAAG,CACf,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CADC,CAFZ,CAOF,CAAE,CACD,SAAW,CAAE,GAAG,CAChB,cAAgB,CAAE,KAAK,CACvB,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CADC,CAHZ,CAQF,CAAE,CACD,SAAW,CAAE,GAAG,CAChB,cAAgB,CAAE,QAAQ,CAC1B,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CADC,CAHZ,CAQF,CAAE,CACD,SAAW,CAAE,GAAG,CAChB,SAAW,CAAE,CACX,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CADC,CAFZ,CAOF,CAKD,CACE,QAAU,CAAE,GAAG,CACf,SAAW,CAAE,CACX,gBAAkB,CAAE,CAAC,CACrB,WAAa,CAAE,CAAA,CAAK,CACpB,SAAW,CAAE,CAAC,CACd,YAAc,CAAE,CAAC,CACjB,UAAY,CAAE,CAAC,CACf,WAAa,CAAE,CAAC,CAChB,SAAW,CAAE,CACX,MAAQ,CAAE,CAAA,CAAI,CACd,KAAO,CAAE,EAAE,CACX,cAAgB,CAAE,CAAA,CAAK,CACvB,aAAe,CAAE,CAAA,CAJN,CAKZ,CACD,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CAbC,CAFf,CAmBC,CAAE,CACD,QAAU,CAAE,GAAG,CACf,SAAW,CAAE,CACX,UAAY,CAAE,CACZ,aAAe,CAAE,CAAA,CAAK,CACtB,SAAW,CAAE,CAAC,CACd,SAAW,CAAE,CAAC,CACd,MAAQ,CAAE,CACR,KAAO,CAAE,EADD,CAJE,CADH,CAFZ,CAYF,CAKD,CACE,SAAW,CAAE,GAAG,CAChB,SAAW,CAAE,CACX,gBAAkB,CAAE,CAAC,CACrB,WAAa,CAAE,CAAA,CAAK,CACpB,SAAW,CAAE,CAAC,CACd,YAAc,CAAE,CAAC,CACjB,UAAY,CAAE,CAAC,CACf,WAAa,CAAE,CAAC,CAChB,SAAW,CAAE,CACX,MAAQ,CAAE,CAAA,CAAI,CACd,KAAO,CAAE,EAAE,CACX,cAAgB,CAAE,CAAA,CAAK,CACvB,aAAe,CAAE,CAAA,CAJN,CAKZ,CACD,MAAQ,CAAE,CACR,OAAS,CAAE,CAAA,CADH,CAbC,CAFf,CAmBC,CAAE,CACD,QAAU,CAAE,GAAG,CACf,SAAW,CAAE,CACX,UAAY,CAAE,CACZ,aAAe,CAAE,CAAA,CAAK,CACtB,SAAW,CAAE,CAAC,CACd,SAAW,CAAE,CAAC,CACd,MAAQ,CAAE,CACR,KAAO,CAAE,EADD,CAJE,CADH,CAFZ,CA/GC,CA4HL,CAMD,KAAO,CAAE,CAAE,CACT,QAAU,CAAE,GAAG,CACf,SAAW,CAAE,CACX,eAAiB,CAAE,CACjB,QAAU,CAAE,KADK,CAElB,CACD,cAAgB,CAAE,CAChB,QAAU,CAAE,QADI,CAJP,CAFJ,CAUV,CAAE,CACD,QAAU,CAAE,GAAG,CACf,SAAW,CAAE,CACX,eAAiB,CAAE,CACjB,UAAY,CAAE,EAAE,CAChB,WAAa,CAAE,EAFE,CAGlB,CACD,cAAgB,CAAE,CAChB,WAAa,CAAE,EAAE,CACjB,kBAAoB,CAAE,CAAA,CAFN,CALP,CAFZ,CAVM,CAsBN,CAMH,GAAK,CAAE,CAAE,CACP,QAAU,CAAE,GAAG,CACf,SAAW,CAAE,CACX,WAAa,CAAE,CACb,kBAAoB,CAAE,CAAA,CADT,CAEd,CACD,QAAU,CAAE,CACV,OAAS,CAAE,CAAA,CADD,CAEX,CACD,WAAa,CAAE,CACb,OAAS,CAAE,CAAA,CADE,CAEd,CACD,YAAc,CAAE,CACd,KAAO,CAAE,CACP,sBAAwB,CAAE,GAAG,CAC7B,sBAAwB,CAAE,EAAE,CAC5B,oBAAsB,CAAE,EAHjB,CAIR,CACD,MAAQ,CAAE,CACR,sBAAwB,CAAE,GAAG,CAC7B,sBAAwB,CAAE,EAAE,CAC5B,oBAAsB,CAAE,EAHhB,CAIT,CACD,KAAO,CAAE,CACP,sBAAwB,CAAE,GAAG,CAC7B,sBAAwB,CAAE,EAAE,CAC5B,oBAAsB,CAAE,EAHjB,CAXK,CAVL,CAFN,CA8BR,CAAE,CACD,QAAU,CAAE,GAAG,CACf,SAAW,CAAE,CACX,YAAc,CAAE,CACd,KAAO,CAAE,CACP,sBAAwB,CAAE,GAAG,CAC7B,sBAAwB,CAAE,EAAE,CAC5B,oBAAsB,CAAE,EAHjB,CAIR,CACD,MAAQ,CAAE,CACR,sBAAwB,CAAE,GAAG,CAC7B,sBAAwB,CAAE,EAAE,CAC5B,oBAAsB,CAAE,EAHhB,CAIT,CACD,KAAO,CAAE,CACP,sBAAwB,CAAE,GAAG,CAC7B,qBAAuB,CAAE,EAAE,CAC3B,sBAAwB,CAAE,EAHnB,CAXK,CADL,CAFZ,CAqBF,CAAE,CACD,SAAW,CAAE,GAAG,CAChB,SAAW,CAAE,CACX,WAAa,CAAE,CACb,kBAAoB,CAAE,CAAA,CADT,CAEd,CACD,QAAU,CAAE,CACV,OAAS,CAAE,CAAA,CADD,CAEX,CACD,WAAa,CAAE,CACb,OAAS,CAAE,CAAA,CADE,CAEd,CACD,YAAc,CAAE,CACd,KAAO,CAAE,CACP,uBAAyB,CAAE,GAAG,CAC9B,sBAAwB,CAAE,EAAE,CAC5B,oBAAsB,CAAE,EAHjB,CAIR,CACD,MAAQ,CAAE,CACR,uBAAyB,CAAE,GAAG,CAC9B,sBAAwB,CAAE,EAAE,CAC5B,oBAAsB,CAAE,EAHhB,CAIT,CACD,KAAO,CAAE,CACP,uBAAyB,CAAE,GAAG,CAC9B,sBAAwB,CAAE,EAAE,CAC5B,oBAAsB,CAAE,EAHjB,CAXK,CAVL,CAFZ,CA8BF,CAAE,CACD,SAAW,CAAE,GAAG,CAChB,SAAW,CAAE,CACX,YAAc,CAAE,CACd,KAAO,CAAE,CACP,uBAAyB,CAAE,GAAG,CAC9B,sBAAwB,CAAE,EAAE,CAC5B,oBAAsB,CAAE,EAHjB,CAIR,CACD,MAAQ,CAAE,CACR,uBAAyB,CAAE,GAAG,CAC9B,sBAAwB,CAAE,EAAE,CAC5B,oBAAsB,CAAE,EAHhB,CAIT,CACD,KAAO,CAAE,CACP,uBAAyB,CAAE,GAAG,CAC9B,qBAAuB,CAAE,EAAE,CAC3B,sBAAwB,CAAE,EAHnB,CAXK,CADL,CAFZ,CAjFI,CA31BM,EAo8BXC,EAAoB,QAAQ,CAAEC,CAAF,CAAQ,CACtC,OAASA,CAAI,GAAI,IAAO,EAAKA,CAAI,GAAIV,SADC,EAIpCW,EAAU,QAAQ,CAAED,CAAF,CAAQ,CAC5B,MAAS,CAACD,CAAiB,CAAEC,CAAF,CAAQ,EAAGE,MAAMC,UAAUC,SAASC,KAAK,CAAEL,CAAF,CAAQ,GAAI,gBADpD,EAI1BM,EAAW,QAAQ,CAAEN,CAAF,CAAQ,CAC7B,OAASA,CAAI,GAAI,IAAK,EAAG,OAAOA,CAAI,EAAI,QADX,EAI3BO,EAAsB,QAAQ,CAAEC,CAAG,CAAEC,CAAP,CAAY,CAC5C,IAAM,IAAIC,EAAI,CAAC,CAAEA,CAAE,CAAEF,CAAGd,OAAO,CAAEgB,CAAC,EAAlC,CACE,GAAKJ,CAAQ,CAAEE,CAAK,CAAAE,CAAA,CAAP,CAAa,EAAGF,CAAK,CAAAE,CAAA,CAAGD,GAAI,GAAIA,EAC3C,OAAOD,CAAK,CAAAE,CAAA,CAChB,CACA,OAAOpB,SALqC,EAQ1CqB,EAAyB,QAAQ,CAAEX,CAAF,CAAQ,CAS3C,IAAIY,EACMC,CADI,CARd,GAAK,CAACP,CAAQ,CAAEN,CAAF,EACZ,OAAOA,CACT,CAEA,GAAKC,CAAO,CAAED,CAAF,EACV,OAAOA,CAAGc,MAAM,CAAA,CAClB,CAEIF,CAAM,CAAE,CAAA,C,CACZ,IAAUC,EAAS,GAAGb,CAAtB,CACOE,MAAMC,UAAUY,eAAeV,KAAK,CAAEL,CAAG,CAAEa,CAAP,C,GACvCD,CAAO,CAAAC,CAAA,CAAW,CAAEF,CAAsB,CAAEX,CAAK,CAAAa,CAAA,CAAP,EAE9C,CACA,OAAOD,CAfoC,EAkBzCI,EAA8B,0CAC9BC,EAAyB,CAAA,EAEzBC,EAAmB,QAAQ,CAAEC,CAAM,CAAEN,CAAQ,CAAEO,CAApB,CAAoC,CAEjE,IAAIC,EAAgCL,CAA4B,CAAEH,CAAQ,CAClEQ,EAA8B,GAAGF,C,GACvCA,CAAQ,CAAAE,CAAA,CAAgC,CAAIR,EAAS,GAAGM,CAAS,CAAEA,CAAQ,CAAAN,CAAA,CAAW,CAAEI,EAAsB,CAGhHE,CAAQ,CAAAN,CAAA,CAAW,CAAEF,CAAsB,CAAES,CAAF,CAAiB,CAE5DhC,CAACS,WAAWyB,KAAK,CAAE,CACjB,MAAM,CAAEH,CAAM,CACd,QAAQ,CAAEN,CAFO,CAAF,CATgD,EAe/DU,EAA0B,QAAQ,CAAEJ,CAAM,CAAEN,CAAV,CAAqB,CACzD,IAAIW,EAAgBL,CAAQ,CAAAH,CAA4B,CAAEH,CAA9B,CAAwC,CAC/DW,CAAc,GAAIP,CAAvB,CACE,OAAOE,CAAQ,CAAAN,CAAA,CADjB,CAGEM,CAAQ,CAAAN,CAAA,CAAW,CAAEW,CALkC,EASvDC,EAAmB,QAAQ,CAAA,CAAG,OACxBrC,CAACS,WAAWH,OAAQ,CAAE,EAAI,CAChC,IAAIgC,EAAWtC,CAACS,WAAW8B,IAAI,CAAA,CAAE,CACjCJ,CAAuB,CAAEG,CAAQP,OAAO,CAAEO,CAAQb,SAA3B,CAFS,CADF,EAO9Be,EAAc,QAAQ,CAAA,CAAG,CAC3B1C,CAAK2C,YAAa,CAAE,CAAA,CAAI,CACnB3C,CAAK4C,KAAM,GAAI,I,GAClB5C,CAAK6C,eAAgB,CAAE,CAAA,EAAK,CAE9B7C,CAAK8C,oBAAqB,CAAE,CAAA,CAAK,CACjC9C,CAAK+C,YAAY,CAAE,CAAA,CAAF,CAAQ,CACzBV,CAAuB,CAAErC,CAAK,CAAE,qBAAT,CAPI,EAUzBgD,EAAc,QAAQ,CAAEC,CAAO,CAAET,CAAX,CAAsB,CAKxC,IAAIb,EAKJuB,EACAhB,EAqBIiB,EACMC,EASE5B,EACJ6B,EAWIC,EAWFC,C,CAhEhB,GAAK,CAAA1C,CAAiB,CAAE2B,CAAF,EAItB,IAAUb,EAAS,GAAGa,CAAtB,CACE,GAAMxB,MAAMC,UAAUY,eAAeV,KAAK,CAAEqB,CAAQ,CAAEb,CAAZ,EAAyB,CAQnE,GAJIuB,CAAa,CAAED,CAAS,CAAAtB,CAAA,C,CACxBO,CAAc,CAAEM,CAAU,CAAAb,CAAA,C,CAGzBd,CAAiB,CAAEqC,CAAF,EAAmB,CACvClB,CAAgB,CAAEiB,CAAO,CAAEtB,CAAQ,CAAEO,CAArB,CAAoC,CACpD,QAFuC,CAMzC,GAAKnB,CAAO,CAAEmC,CAAF,EAAmB,CAG7B,GAAKnC,CAAO,CAAEmB,CAAF,EAAoB,CAI9B,GAAOgB,CAAY1C,OAAQ,CAAE,CAAE,EAAG,CAACY,CAAQ,CAAE8B,CAAc,CAAA,CAAA,CAAhB,CAAwB,EAAKhB,CAAa1B,OAAQ,CAAE,CAAE,EAAG,CAACY,CAAQ,CAAEc,CAAe,CAAA,CAAA,CAAjB,EAA2B,CACtIF,CAAgB,CAAEiB,CAAO,CAAEtB,CAAQ,CAAEO,CAArB,CAAoC,CACpD,QAFsI,CAMxI,IADIiB,CAA+B,CAAE,CAAA,C,CAC3BC,CAAE,CAAE,CAAC,CAAEA,CAAE,CAAElB,CAAa1B,OAAO,CAAE4C,CAAC,EAA5C,CACE,GAAKvC,CAAiB,CAAEqB,CAAe,CAAAkB,CAAA,CAAjB,CAAuB,EAAGvC,CAAiB,CAAEqB,CAAe,CAAAkB,CAAA,CAAG7B,GAApB,EAA4B,CAC3F4B,CAA+B,CAAE,CAAA,CAAK,CACtC,KAF2F,CAO/F,GAAKA,EAAiC,CACpC,IAAU3B,CAAE,CAAE,CAAC,CAAEA,CAAE,CAAEU,CAAa1B,OAAO,CAAEgB,CAAC,EAA5C,CAAiD,CAE/C,GADI6B,CAA4B,CAAEhC,CAAmB,CAAE6B,CAAY,CAAEhB,CAAe,CAAAV,CAAA,CAAGD,GAAlC,C,CAChD8B,CAA4B,GAAIjD,UACnC,KAAQ,yCAA0C,CAAEuB,CAAS,CAAE,aAAc,CAAEO,CAAe,CAAAV,CAAA,CAAGD,GAAK,CAExGyB,CAAW,CAAEK,CAA2B,CAAEnB,CAAe,CAAAV,CAAA,CAA9C,CALoC,CAOjD,QARoC,CAYtC,GAAKU,CAAa1B,OAAQ,EAAG0C,CAAY1C,QAAU,CACjD,IAAU8C,CAAE,CAAE,CAAC,CAAEA,CAAE,CAAEpB,CAAa1B,OAAO,CAAE8C,CAAC,EAA5C,CACEN,CAAW,CAAEE,CAAc,CAAAI,CAAA,CAAG,CAAEpB,CAAe,CAAAoB,CAAA,CAApC,CACb,CACA,QAJiD,CAOnD,KAAM,sEAAuE,CAAE3B,CAAQ,CArCzD,CAyChC,GAAKP,CAAQ,CAAEc,CAAF,EAAoB,CAC/B,IAAUqB,CAAE,CAAE,CAAC,CAAEA,CAAE,CAAEL,CAAY1C,OAAO,CAAE+C,CAAC,EAA3C,CACEP,CAAW,CAAEE,CAAc,CAAAK,CAAA,CAAG,CAAErB,CAArB,CACb,CACA,QAJ+B,CAOjC,KAAQ,mDAAoD,CAAEP,CAAU,CAnD3C,CAsD/B,GAAKP,CAAQ,CAAE8B,CAAF,EAAmB,CAC9BF,CAAW,CAAEE,CAAY,CAAEhB,CAAhB,CAA+B,CAC1C,QAF8B,CAMhCF,CAAgB,CAAEiB,CAAO,CAAEtB,CAAQ,CAAEO,CAArB,CA1EmD,CANvB,EAoF5CsB,EAAa,QAAQ,CAAA,CAAG,CAE1B,IAAIC,EAAQzD,CAAK0D,cACbC,EAAS3D,CAAK4D,eAOdC,EACMrC,EACJsC,EAEAC,EAsBIC,CAlCoB,CAI9B,GAAKP,CAAM,GAAI,CAAE,EAAGE,CAAO,GAAI,EAC7B,CAIF,IADIE,CAAa,CAAE,CAAA,C,CACTrC,CAAE,CAAE,CAAC,CAAEA,CAAE,CAAEtB,CAAC+D,MAAMzD,OAAO,CAAEgB,CAAC,EAAtC,CACMsC,CAAK,CAAE5D,CAAC+D,MAAQ,CAAAzC,CAAA,C,CAEhBuC,CAAY,CACd,CAAED,CAAII,SAAU,GAAI9D,SAAU,EAAK0D,CAAII,SAAU,EAAGT,CAApD,CAA8D,EAAG,CAAEK,CAAIK,SAAU,GAAI/D,SAAU,EAAK0D,CAAIK,SAAU,EAAGV,CAApD,CAA8D,EAC/H,CAAEK,CAAIM,UAAW,GAAIhE,SAAU,EAAK0D,CAAIM,UAAW,EAAGT,CAAtD,CAAiE,EAAG,CAAEG,CAAIO,UAAW,GAAIjE,SAAU,EAAK0D,CAAIO,UAAW,EAAGV,CAAtD,CAAiE,EACrI,CAAEG,CAAIQ,OAAQ,GAAIlE,SAAU,EAAK0D,CAAIQ,OAAQ,GAAI,CAAA,CAAK,EAAGtE,CAAKsE,OAAQ,GAAI,CAAA,CAAO,EAAKR,CAAIQ,OAAQ,GAAI,CAAA,CAAM,EAAG,CAAEtE,CAAKsE,OAAQ,GAAIlE,SAAU,EAAGJ,CAAKsE,OAAQ,GAAI,CAAA,CAAjD,CAA/G,CAA4K,EAC5K,CAAER,CAAIS,eAAgB,GAAInE,SAAU,EAAKJ,CAAKwE,OAAQ,GAAIpE,SAAU,EAAGJ,CAAKwE,OAAOC,SAAU,GAAIrE,SAAU,EAAGJ,CAAKwE,OAAOC,SAAU,GAAIX,CAAIS,eAA5I,C,CAEGR,CAAL,CACO7D,CAACQ,aAAe,CAAAc,CAAA,CAAI,GAAIpB,S,GAC3BF,CAACQ,aAAe,CAAAc,CAAA,CAAI,CAAE,CAAA,CAAI,CAC1BqC,CAAa,CAAE,CAAA,EAHnB,CAKY3D,CAACQ,aAAe,CAAAc,CAAA,CAAI,GAAIpB,S,GAClCF,CAACQ,aAAe,CAAAc,CAAA,CAAI,CAAEpB,SAAS,CAC/ByD,CAAa,CAAE,CAAA,EAEnB,CAEA,GAAMA,EACJ,CAEFtB,CAAgB,CAAA,CAAE,CAElB,IAAUyB,EAAI,GAAG9D,CAACQ,aAAlB,CACE,GAAMM,MAAMC,UAAUY,eAAeV,KAAK,CAAEjB,CAACQ,aAAa,CAAEsD,CAAlB,C,EAIrC9D,CAACQ,aAAe,CAAAsD,CAAA,CAAM,GAAI5D,UAAY,CACzC,GAAKS,CAAiB,CAAEX,CAAC+D,MAAQ,CAAAD,CAAA,CAAX,EACpB,KAAM,mCAAoC,CAAEA,CAAG,CAEjDhB,CAAW,CAAEhD,CAAK,CAAEE,CAAC+D,MAAQ,CAAAD,CAAA,CAAKU,UAAvB,CAJ8B,CAU7ChC,CAAW,CAAA,CAnBT,CAzBA,CAPwB,CAxK3B,CA8ND9B,CAAQ+D,MAAO,CAAE/D,CAAQgE,OAAO,CAE1B7D,CAAO,CAAEb,CAAC+D,MAAH,CAAb,CAEY/D,CAAC2E,gBAAiB,GAAI,CAAA,C,GAChC3E,CAAC+D,MAAO,CAAErD,CAAU,CAAAZ,CAAK4C,KAAL,CAAYkC,OAAO,CAAE5E,CAAC+D,MAAH,EAHzC,CACE/D,CAAC+D,MAAO,CAAErD,CAAU,CAAAZ,CAAK4C,KAAL,C,CAMtBZ,CAAgB,CAAEhC,CAAK,CAAE,qBAAqB,CAAEA,CAAK8C,oBAArC,CAA2D,CAE3E9C,CAAK+E,YAAY,CAAE,SAAS,CAAEvB,CAAb,CAAyB,CAC1CxD,CAAK+E,YAAY,CAAE,MAAM,CAAEvB,CAAV,CAtrCf,CARuC,CAgsC1C,CAAE,CAAE,KAAK,CAAE,QAAQ,CAAE,IAAI,CAAE,QAAQ,CAAE,OAAO,CAAE,OAAO,CAAE,OAAO,CAAE,OAAO,CAAE,KAAvE,CAhsCoB,CAgsC4D", +"sources":["responsive.js"], +"names":["AmCharts","addInitHandler","chart","version","r","responsive","undefined","ready","enabled","split","length","Number","currentRules","overridden","defaults","isNullOrUndefined","obj","isArray","Object","prototype","toString","call","isObject","findArrayObjectById","arr","id","i","cloneWithoutPrototypes","clone","property","slice","hasOwnProperty","originalValueRetainerPrefix","noOriginalPropertyStub","overrideProperty","object","overrideValue","originalValueRetainerProperty","push","restoreOriginalProperty","originalValue","restoreOriginals","override","pop","redrawChart","dataChanged","type","marginsUpdated","zoomOutOnDataUpdate","validateNow","applyConfig","current","currentValue","idPresentOnAllOverrideElements","k","correspondingCurrentElement","l","j","checkRules","width","divRealWidth","height","divRealHeight","rulesChanged","rule","ruleMatches","key","rules","minWidth","maxWidth","minHeight","maxHeight","rotate","legendPosition","legend","position","overrides","gantt","serial","addDefaultRules","concat","addListener"] +} diff --git a/iguana/js/amcharts/serial.js b/iguana/js/amcharts/serial.js new file mode 100755 index 000000000..12c6435e4 --- /dev/null +++ b/iguana/js/amcharts/serial.js @@ -0,0 +1,93 @@ +(function(){var e=window.AmCharts;e.AmRectangularChart=e.Class({inherits:e.AmCoordinateChart,construct:function(a){e.AmRectangularChart.base.construct.call(this,a);this.theme=a;this.createEvents("zoomed","changed");this.marginRight=this.marginBottom=this.marginTop=this.marginLeft=20;this.depth3D=this.angle=0;this.plotAreaFillColors="#FFFFFF";this.plotAreaFillAlphas=0;this.plotAreaBorderColor="#000000";this.plotAreaBorderAlpha=0;this.maxZoomFactor=20;this.zoomOutButtonImageSize=19;this.zoomOutButtonImage= +"lens";this.zoomOutText="Show all";this.zoomOutButtonColor="#e5e5e5";this.zoomOutButtonAlpha=0;this.zoomOutButtonRollOverAlpha=1;this.zoomOutButtonPadding=8;this.trendLines=[];this.autoMargins=!0;this.marginsUpdated=!1;this.autoMarginOffset=10;e.applyTheme(this,a,"AmRectangularChart")},initChart:function(){e.AmRectangularChart.base.initChart.call(this);this.updateDxy();!this.marginsUpdated&&this.autoMargins&&(this.resetMargins(),this.drawGraphs=!1);this.processScrollbars();this.updateMargins();this.updatePlotArea(); +this.updateScrollbars();this.updateTrendLines();this.updateChartCursor();this.updateValueAxes();this.scrollbarOnly||this.updateGraphs()},drawChart:function(){e.AmRectangularChart.base.drawChart.call(this);this.drawPlotArea();if(e.ifArray(this.chartData)){var a=this.chartCursor;a&&a.draw()}},resetMargins:function(){var a={},b;if("xy"==this.type){var c=this.xAxes,d=this.yAxes;for(b=0;b=g-c&&(this.marginRight=Math.round(k-g+c),!isNaN(this.minMarginRight)&&this.marginRighth-c&&(this.marginBottom=Math.round(this.marginBottom+b-h+c),!isNaN(this.minMarginBottom)&& +this.marginBottoma&&(d=a);break;case "bottom":a=h.y+h.height;ga&&(b=a)}}return{l:b,t:d,r:c,b:g}},drawZoomOutButton:function(){var a=this;if(!a.zbSet){var b=a.container.set(); +a.zoomButtonSet.push(b);var c=a.color,d=a.fontSize,g=a.zoomOutButtonImageSize,h=a.zoomOutButtonImage.replace(/\.[a-z]*$/i,""),f=e.lang.zoomOutText||a.zoomOutText,l=a.zoomOutButtonColor,k=a.zoomOutButtonAlpha,m=a.zoomOutButtonFontSize,p=a.zoomOutButtonPadding;isNaN(m)||(d=m);(m=a.zoomOutButtonFontColor)&&(c=m);var m=a.zoomOutButton,n;m&&(m.fontSize&&(d=m.fontSize),m.color&&(c=m.color),m.backgroundColor&&(l=m.backgroundColor),isNaN(m.backgroundAlpha)||(a.zoomOutButtonRollOverAlpha=m.backgroundAlpha)); +var r=m=0;void 0!==a.pathToImages&&h&&(n=a.container.image(a.pathToImages+h+a.extension,0,0,g,g),e.setCN(a,n,"zoom-out-image"),b.push(n),n=n.getBBox(),m=n.width+5);void 0!==f&&(c=e.text(a.container,f,c,a.fontFamily,d,"start"),e.setCN(a,c,"zoom-out-label"),d=c.getBBox(),r=n?n.height/2-3:d.height/2,c.translate(m,r),b.push(c));n=b.getBBox();c=1;e.isModern||(c=0);l=e.rect(a.container,n.width+2*p+5,n.height+2*p-2,l,1,1,l,c);l.setAttr("opacity",k);l.translate(-p,-p);e.setCN(a,l,"zoom-out-bg");b.push(l); +l.toBack();a.zbBG=l;n=l.getBBox();b.translate(a.marginLeftReal+a.plotAreaWidth-n.width+p,a.marginTopReal+p);b.hide();b.mouseover(function(){a.rollOverZB()}).mouseout(function(){a.rollOutZB()}).click(function(){a.clickZB()}).touchstart(function(){a.rollOverZB()}).touchend(function(){a.rollOutZB();a.clickZB()});for(k=0;ka&&(a=1);1>b&&(b=1);this.plotAreaWidth=Math.round(a);this.plotAreaHeight=Math.round(b); +this.plotBalloonsSet.translate(c,d)},updateDxy:function(){this.dx=Math.round(this.depth3D*Math.cos(this.angle*Math.PI/180));this.dy=Math.round(-this.depth3D*Math.sin(this.angle*Math.PI/180));this.d3x=Math.round(this.columnSpacing3D*Math.cos(this.angle*Math.PI/180));this.d3y=Math.round(-this.columnSpacing3D*Math.sin(this.angle*Math.PI/180))},updateMargins:function(){var a=this.getTitleHeight();this.titleHeight=a;this.marginTopReal=this.marginTop-this.dy;this.fixMargins&&!this.fixMargins.top&&(this.marginTopReal+= +a);this.marginBottomReal=this.marginBottom;this.marginLeftReal=this.marginLeft;this.marginRightReal=this.marginRight},updateValueAxes:function(){var a=this.valueAxes,b;for(b=0;bd)var g=c,c=d,d=g;this.relativeZoomValueAxes(b,c,d);this.updateAfterValueZoom()}, +updateAfterValueZoom:function(){this.zoomAxesAndGraphs();this.zoomScrollbar()},relativeZoomValueAxes:function(a,b,c){b=e.fitToBounds(b,0,1);c=e.fitToBounds(c,0,1);if(b>c){var d=b;b=c;c=d}var d=1/this.maxZoomFactor,g=e.getDecimals(d)+4;c-bk&&(k=1);h*=k;f*=k;if(!d||c.equalSpacing)h=Math.round(h),f=Math.round(f)}e=this.chartData.length;c=this.lastTime;k=this.firstTime; +0>a?d?(e=this.endTime-this.startTime,d=this.startTime+h*g,g=this.endTime+f*g,0=c&&(g=c,d=c-e),this.zoomToDates(new Date(d),new Date(g))):(0=e-1&&(h=f=0),d=this.start+h,g=this.end+f,this.zoomToIndexes(d,g)):d?(e=this.endTime-this.startTime,d=this.startTime-h*g,g=this.endTime-f*g,0this.start&&(h=f=0),d=this.start-h,g=this.end-f,this.zoomToIndexes(d,g))}},validateData:function(a){this.marginsUpdated= +!1;this.zoomOutOnDataUpdate&&!a&&(this.endTime=this.end=this.startTime=this.start=NaN);e.AmSerialChart.base.validateData.call(this)},drawChart:function(){if(0c&&(a=b-c),a!=this.startTime&&b-a>c&&(b=a+c));var d=this.minSelectedTime;if(0l&&(a=l);bl&&(b=l);bthis.firstTime&&(a=!0),this.endTimec&&(a=b-c),a!=this.start&&b-a>c&&(b=a+c));if(a!=this.start||b!=this.end){var d=this.chartData.length-1;isNaN(a)&&(a=0,isNaN(c)||(a=d-c));isNaN(b)&&(b=d);bd&&(b=d);a>d&&(a=d-1);0>a&&(a=0);this.start=a;this.end=b;this.categoryAxis.zoom(a,b);this.zoomAxesAndGraphs();this.zoomScrollbar();this.fixCursor();0!==a||b!=this.chartData.length-1?this.showZB(!0):this.showZB(!1);this.syncGrid(); +this.updateColumnsDepth();this.dispatchIndexZoomEvent()}},updateGraphs:function(){e.AmSerialChart.base.updateGraphs.call(this);var a=this.graphs,b;for(b=0;bb.depth?1:-1},zoomScrollbar:function(){var a= +this.chartScrollbar,b=this.categoryAxis;if(a){if(!this.zoomedByScrollbar){var c=a.dragger;c&&c.stop()}this.zoomedByScrollbar=!1;b.parseDates&&!b.equalSpacing?a.timeZoom(this.startTime,this.endTime):a.zoom(this.start,this.end)}this.zoomValueScrollbar(this.valueScrollbar)},updateTrendLines:function(){var a=this.trendLines,b;for(b=0;b +g&&(g=0);e>a.length-1&&(e=a.length-1);var f=g+Math.round((e-g)/2),l=a[f][b];return c==l?f:1>=e-g?d?g:Math.abs(a[g][b]-c)a&&(a=0),b>d-1&&(b=d-1),d=this.categoryAxis,d.parseDates&&!d.equalSpacing?this.zoom(c[a].time,this.getEndTime(c[b].time)):this.zoom(a,b))}},zoomToDates:function(a,b){var c=this.chartData;if(c)if(this.categoryAxis.equalSpacing){var d= +this.getClosestIndex(c,"time",a.getTime(),!0,0,c.length);b=e.resetDateToMin(b,this.categoryAxis.minPeriod,1);c=this.getClosestIndex(c,"time",b.getTime(),!1,0,c.length);this.zoom(d,c)}else this.zoom(a.getTime(),b.getTime())},zoomToCategoryValues:function(a,b){this.chartData&&this.zoom(this.getCategoryIndexByValue(a),this.getCategoryIndexByValue(b))},formatPeriodString:function(a,b){if(b){var c=["value","open","low","high","close"],d="value open low high close average sum count".split(" "),g=b.valueAxis, +h=this.chartData,f=b.numberFormatter;f||(f=this.nf);for(var l=0;ly.x||y.x>y.graph.height)C=NaN}else if(0>y.x||y.x>y.graph.width)C=NaN;if(!isNaN(C)){isNaN(n)&&(n=C);r=C;if(isNaN(w)||w>C)w=C;if(isNaN(z)||zy)x=y;if(isNaN(B)||Bb&&0===p&&(p=180):0>c&&270==p&&(p=90);this.gradientRotation=p;0===d&&0===e&&(this.cornerRadius=n);this.draw()},draw:function(){var a=this.set;a.clear(); +var b=this.container,c=b.chart,d=this.w,g=this.h,h=this.dx,f=this.dy,l=this.colors,k=this.alpha,m=this.bwidth,p=this.bcolor,n=this.balpha,r=this.gradientRotation,w=this.cornerRadius,z=this.dashLength,u=this.pattern,q=this.topRadius,D=this.bcn,v=l,t=l;"object"==typeof l&&(v=l[0],t=l[l.length-1]);var x,B,A,G,y,C,F,L,M,Q=k;u&&(k=0);var E,H,I,J,K=this.rotate;if(0Math.abs(g)&&(g=0);1>Math.abs(d)&&(d=0);!isNaN(q)&&(0g&&(m=" A"),k+=m+Math.round(d/2-I)+","+Math.round(g-J)+","+Math.round(d/2+I)+","+Math.round(g+J)+",0,"+g+","+d+","+g,k+=" L"+d+",0",k+=m+Math.round(d/ +2+E)+","+Math.round(H)+","+Math.round(d/2-E)+","+Math.round(-H)+","+d+",0,0,0"):(k+="A"+I+","+J+",0,0,0,"+(d-d/2*(1-q))+","+g+"L"+d+",0",k+="A"+E+","+H+",0,0,1,0,0"),E=180),b=b.path(k).attr(l),b.gradient("linearGradient",[v,e.adjustLuminosity(v,-.3),e.adjustLuminosity(v,-.3),v],E),K?b.translate(h/2,0):b.translate(0,f/2)):b=0===g?e.line(b,[0,d],[0,0],p,n,m,z):0===d?e.line(b,[0,0],[0,g],p,n,m,z):0g?[x, +M,B,A,G,y,C,F,L,b]:[F,L,B,A,G,y,x,M,C,b]:K?0g?[x,b,F]:[F,b,x];e.setCN(c,b,D+"front");e.setCN(c,B,D+"back");e.setCN(c,F,D+"top");e.setCN(c,x,D+"bottom");e.setCN(c,G,D+"left");e.setCN(c,y,D+"right");for(x=0;xb&&(this.endTime=b);q=this.minorGridEnabled;z=this.gridAlpha;var x=0,B=0;if(this.widthField)for(b=this.start;b<=this.end;b++)if(t=this.data[b]){var A=Number(this.data[b].dataContext[this.widthField]);isNaN(A)||(x+=A,t.widthValue=A)}if(this.parseDates&&!this.equalSpacing)this.lastTime=a[a.length-1].time,this.maxTime=e.resetDateToMin(new Date(this.lastTime+1.05*r),this.minPeriod, +1,p).getTime(),this.timeDifference=this.endTime-this.startTime,this.parseDatesDraw();else if(!this.parseDates){if(this.cellWidth=this.getStepWidth(f),ff&&(f=0),l=0,this.widthField&&(f=this.start),this.end-f+1>=this.autoRotateCount&&(this.labelRotationR=this.autoRotateAngle),b=f;b<=this.end+2;b++){p=!1;0<=b&&bthis.end&&"start"==this.tickPosition&&(n=" ");this.rotate&&this.inside&&(u-=2);isNaN(w.widthValue)||(w.percentWidthValue=w.widthValue/x*100,A=this.rotate?this.height*w.widthValue/x:this.width*w.widthValue/x,f=B,B+=A,u=A/2);u=new this.axisItemRenderer(this,f,n,p,A,u,void 0,t,a,!1,w.labelColor,w.className);u.serialDataItem=w;this.pushAxisItem(u);this.gridAlpha= +z}}else if(this.parseDates&&this.equalSpacing){h=this.start;this.startTime=this.data[this.start].time;this.endTime=this.data[this.end].time;this.timeDifference=this.endTime-this.startTime;b=this.choosePeriod(0);g=b.period;w=b.count;b=e.getPeriodDuration(g,w);bf&&(f=0);B=this.end+2;B>=this.data.length&&(B=this.data.length);a=!1;a=!k;this.previousPos=-1E3;20=A){f=this.getCoordinate(b-this.start);q=!1;this.nextPeriod[z]&&(q=this.checkPeriodChange(this.nextPeriod[z],1,r,n,z))&&e.resetDateToMin(new Date(r),this.nextPeriod[z],1,p).getTime()!=r&&(q=!1);t=!1;q&&this.markPeriodChange?(q=this.dateFormatsObject[this.nextPeriod[z]],t=!0):q=this.dateFormatsObject[z];n=e.formatDate(new Date(r),q,c);if(b==d&&!k||b==l&&!m)n=" ";a?a=!1:(v||(t=!1),f-this.previousPos>this.safeDistance* +Math.cos(this.labelRotationR*Math.PI/180)&&(this.labelFunction&&(n=this.labelFunction(n,new Date(r),this,g,w,u)),this.boldLabels&&(t=!0),u=new this.axisItemRenderer(this,f,n,void 0,void 0,void 0,void 0,t),q=u.graphics(),this.pushAxisItem(u),q=q.getBBox().width,e.isModern||(q-=f),this.previousPos=f+q));u=n=r}}for(b=k=0;bthis.height+1&&h--:l>this.width+1&&h--;0>l&&h++;return h=e.fitToBounds(h,0,b.length-1)},dateToCoordinate:function(a){return this.parseDates&& +!this.equalSpacing?(a.getTime()-this.startTime)*this.stepWidth:this.parseDates&&this.equalSpacing?(a=this.chart.getClosestIndex(this.data,"time",a.getTime(),!1,0,this.data.length-1),this.getCoordinate(a-this.start)):NaN},categoryToCoordinate:function(a){if(this.chart){if(this.parseDates)return this.dateToCoordinate(new Date(a));a=this.chart.getCategoryIndexByValue(a);if(!isNaN(a))return this.getCoordinate(a-this.start)}else return NaN},coordinateToDate:function(a){return this.equalSpacing?(a=this.xToIndex(a), +new Date(this.data[a].time)):new Date(this.startTime+a/this.stepWidth)},coordinateToValue:function(a){a=this.xToIndex(a);if(a=this.data[a])return this.parseDates?a.time:a.category},getCoordinate:function(a){a*=this.stepWidth;this.startOnAxis||(a+=this.stepWidth/2);return Math.round(a)},formatValue:function(a,b){b||(b=this.currentDateFormat);this.parseDates&&(a=e.formatDate(new Date(a),b,this.chart));return a},showBalloonAt:function(a){a=this.parseDates?this.dateToCoordinate(new Date(a)):this.categoryToCoordinate(a); +return this.adjustBalloonCoordinate(a)},formatBalloonText:function(a,b,c){var d="",g="",h=this.chart,f=this.data[b];if(f)if(this.parseDates)d=e.formatDate(f.category,c,h),b=e.changeDate(new Date(f.category),this.minPeriod,1),g=e.formatDate(b,c,h),-1!=d.indexOf("fff")&&(d=e.formatMilliseconds(d,f.category),g=e.formatMilliseconds(g,b));else{var l;this.data[b+1]&&(l=this.data[b+1]);d=e.fixNewLines(f.category);l&&(g=e.fixNewLines(l.category))}a=a.replace(/\[\[category\]\]/g,String(d));return a=a.replace(/\[\[toCategory\]\]/g, +String(g))},adjustBalloonCoordinate:function(a,b){var c=this.xToIndex(a),d=this.chart.chartCursor;if(this.stickBalloonToCategory){var e=this.data[c];e&&(a=e.x[this.id]);this.stickBalloonToStart&&(a-=this.cellWidth/2);var h=0;if(d){var f=d.limitToGraph;if(f){var l=f.valueAxis.id;f.hidden||(h=e.axes[l].graphs[f.id].y)}this.rotate?("left"==this.position?(f&&(h-=d.width),0h&&(h=0),d.fixHLine(a,h)):("top"==this.position?(f&&(h-=d.height),0h&&(h=0),d.fixVLine(a,h))}}d&&!b&&(d.setIndex(c), +this.parseDates&&d.setTimestamp(this.coordinateToDate(a).getTime()));return a}})})(); diff --git a/iguana/js/amcharts/style.css b/iguana/js/amcharts/style.css new file mode 100755 index 000000000..31b12ede2 --- /dev/null +++ b/iguana/js/amcharts/style.css @@ -0,0 +1,84 @@ +.amChartsDataSetSelector +{ + font-size:12px; + font-family:verdana,helvetica,arial,sans-serif; +} + +.amChartsPeriodSelector +{ + font-size:12px; + font-family:verdana,helvetica,arial,sans-serif; +} + +.amChartsButtonSelected +{ + background-color:#CC0000; + border-style:solid; + border-color:#CC0000; + border-width:1px; + color:#FFFFFF; + -moz-border-radius: 5px; + border-radius: 5px; + margin: 1px; + outline: none; + box-sizing: border-box; +} + +.amChartsButton +{ + color: #000000; + background: transparent; + opacity: 0.7; + border: 1px solid rgba(0, 0, 0, .3); + -moz-border-radius: 5px; + border-radius: 5px; + margin: 1px; + outline: none; + box-sizing: border-box; +} + +.amChartsCompareList +{ + border-style:solid; + border-color:#CCCCCC; + border-width:1px; +} + +.amChartsCompareList div +{ + -webkit-box-sizing: initial; + box-sizing: initial; +} + +.amChartsInputField +{ + +} + +.amChartsLegend +{ + +} + +.amChartsPanel +{ + +} + +#chartdiv, .chart { + width: 95%; + height: 500px; + position: relative; +} + +.chart .zoom { + position: absolute; + top: 25px; + right: 25px; + border: 1px solid #ccc; + border-radius: 3px; + padding: 5px 12px; + background: rgba(255, 255, 255, 0.5); + cursor: pointer; + z-index: 20; +} diff --git a/iguana/js/amcharts/themes/black.js b/iguana/js/amcharts/themes/black.js new file mode 100755 index 000000000..632fa44c8 --- /dev/null +++ b/iguana/js/amcharts/themes/black.js @@ -0,0 +1,196 @@ +AmCharts.themes.black = { + + themeName: "black", + + AmChart: { + color: "#e7e7e7", + backgroundColor: "#222222" + }, + + AmCoordinateChart: { + colors: ["#de4c4f", "#d8854f", "#eea638", "#a7a737", "#86a965", "#8aabb0", "#69c8ff", "#cfd27e", "#9d9888", "#916b8a", "#724887", "#7256bc"] + }, + + AmStockChart: { + colors: ["#de4c4f", "#d8854f", "#eea638", "#a7a737", "#86a965", "#8aabb0", "#69c8ff", "#cfd27e", "#9d9888", "#916b8a", "#724887", "#7256bc"] + }, + + AmSlicedChart: { + outlineAlpha: 1, + outlineThickness: 2, + labelTickColor: "#FFFFFF", + labelTickAlpha: 0.3, + colors: ["#de4c4f", "#d8854f", "#eea638", "#a7a737", "#86a965", "#8aabb0", "#69c8ff", "#cfd27e", "#9d9888", "#916b8a", "#724887", "#7256bc"] + }, + + AmRectangularChart: { + zoomOutButtonColor: "#FFFFFF", + zoomOutButtonRollOverAlpha: 0.15, + zoomOutButtonImage: "lensWhite" + }, + + AxisBase: { + axisColor: "#FFFFFF", + axisAlpha: 0.3, + gridAlpha: 0.1, + gridColor: "#FFFFFF", + dashLength: 3 + }, + + ChartScrollbar: { + backgroundColor: "#000000", + backgroundAlpha: 0.2, + graphFillAlpha: 0.2, + graphLineAlpha: 0, + graphFillColor: "#FFFFFF", + selectedGraphFillColor: "#FFFFFF", + selectedGraphFillAlpha: 0.4, + selectedGraphLineColor: "#FFFFFF", + selectedBackgroundColor: "#FFFFFF", + selectedBackgroundAlpha: 0.09, + gridAlpha: 0.15 + }, + + ChartCursor: { + cursorColor: "#FFFFFF", + color: "#000000", + cursorAlpha: 0.5 + }, + + AmLegend: { + color: "#e7e7e7" + }, + + AmGraph: { + lineAlpha: 0.9 + }, + + + GaugeArrow: { + color: "#FFFFFF", + alpha: 0.8, + nailAlpha: 0, + innerRadius: "40%", + nailRadius: 15, + startWidth: 15, + borderAlpha: 0.8, + nailBorderAlpha: 0 + }, + + GaugeAxis: { + tickColor: "#FFFFFF", + tickAlpha: 1, + tickLength: 15, + minorTickLength: 8, + axisThickness: 3, + axisColor: "#FFFFFF", + axisAlpha: 1, + bandAlpha: 0.8 + }, + + TrendLine: { + lineColor: "#c03246", + lineAlpha: 0.8 + }, + + // ammap + AreasSettings: { + alpha: 0.8, + color: "#666666", + colorSolid: "#000000", + unlistedAreasAlpha: 0.4, + unlistedAreasColor: "#555555", + outlineColor: "#000000", + outlineAlpha: 0.5, + outlineThickness: 0.5, + rollOverBrightness: 30, + slectedBrightness: 50, + rollOverOutlineColor: "#000000", + selectedOutlineColor: "#000000", + unlistedAreasOutlineColor: "#000000", + unlistedAreasOutlineAlpha: 0.5 + }, + + LinesSettings: { + color: "#555555", + alpha: 0.8 + }, + + ImagesSettings: { + alpha: 0.8, + labelColor: "#FFFFFF", + color: "#FFFFFF", + labelRollOverColor: "#3c5bdc" + }, + + ZoomControl: { + buttonFillAlpha: 0.4 + }, + + SmallMap: { + mapColor: "#444444", + rectangleColor: "#666666", + backgroundColor: "#000000", + backgroundAlpha: 0.5, + borderColor:"#555555", + borderThickness: 1, + borderAlpha: 0.8 + }, + + // the defaults below are set using CSS syntax, you can use any existing css property + // if you don't use Stock chart, you can delete lines below + PeriodSelector: { + color: "#e7e7e7" + }, + + PeriodButton: { + color: "#e7e7e7", + background: "transparent", + opacity: 0.7, + border: "1px solid rgba(255, 255, 255, .15)", + MozBorderRadius: "5px", + borderRadius: "5px", + margin: "1px", + outline: "none", + boxSizing: "border-box" + }, + + PeriodButtonSelected: { + color: "#e7e7e7", + backgroundColor: "rgba(255, 255, 255, 0.1)", + border: "1px solid rgba(255, 255, 255, .3)", + MozBorderRadius: "5px", + borderRadius: "5px", + margin: "1px", + outline: "none", + opacity: 1, + boxSizing: "border-box" + }, + + PeriodInputField: { + color: "#e7e7e7", + background: "transparent", + border: "1px solid rgba(255, 255, 255, .15)", + outline: "none" + }, + + DataSetSelector: { + color: "#e7e7e7", + selectedBackgroundColor: "rgba(255, 255, 255, .25)", + rollOverBackgroundColor: "rgba(255, 255, 255, .15)" + }, + + DataSetCompareList: { + color: "#e7e7e7", + lineHeight: "100%", + boxSizing: "initial", + webkitBoxSizing: "initial", + border: "1px solid rgba(255, 255, 255, .15)" + }, + + DataSetSelect: { + border: "1px solid rgba(255, 255, 255, .15)", + outline: "none" + } + +}; \ No newline at end of file diff --git a/iguana/js/amcharts/themes/chalk.js b/iguana/js/amcharts/themes/chalk.js new file mode 100755 index 000000000..a471cefe5 --- /dev/null +++ b/iguana/js/amcharts/themes/chalk.js @@ -0,0 +1,213 @@ +AmCharts.themes.chalk = { + + themeName: "chalk", + + AmChart: { + color: "#e7e7e7", + fontFamily: "Covered By Your Grace", + fontSize: 18, + handDrawn: true, + backgroundColor: "#282828" + }, + + AmCoordinateChart: { + colors: ["#FFFFFF", "#e384a6", "#f4d499", "#4d90d6", "#c7e38c", "#9986c8", "#edf28c", "#ffd1d4", "#5ee1dc", "#b0eead", "#fef85a", "#8badd2"] + }, + + AmSlicedChart: { + outlineAlpha: 1, + labelTickColor: "#FFFFFF", + labelTickAlpha: 0.3, + colors: ["#FFFFFF", "#e384a6", "#f4d499", "#4d90d6", "#c7e38c", "#9986c8", "#edf28c", "#ffd1d4", "#5ee1dc", "#b0eead", "#fef85a", "#8badd2"] + }, + + AmStockChart: { + colors: ["#FFFFFF", "#e384a6", "#f4d499", "#4d90d6", "#c7e38c", "#9986c8", "#edf28c", "#ffd1d4", "#5ee1dc", "#b0eead", "#fef85a", "#8badd2"] + }, + + AmRectangularChart: { + zoomOutButtonColor: '#FFFFFF', + zoomOutButtonRollOverAlpha: 0.15, + zoomOutButtonImage: "lensWhite" + }, + + AxisBase: { + axisColor: "#FFFFFF", + gridColor: "#FFFFFF" + }, + + ChartScrollbar: { + backgroundColor: "#FFFFFF", + backgroundAlpha: 0.2, + graphFillAlpha: 0.5, + graphLineAlpha: 0, + selectedBackgroundColor: "#000000", + selectedBackgroundAlpha: 0.25, + fontSize: 15, + gridAlpha: 0.15 + }, + + ChartCursor: { + cursorColor: "#FFFFFF", + color: "#000000" + }, + + AmLegend: { + color: "#e7e7e7", + markerSize: 20 + }, + + AmGraph: { + lineAlpha: 0.8 + }, + + + GaugeArrow: { + color: "#FFFFFF", + alpha: 0.1, + nailAlpha: 0, + innerRadius: "40%", + nailRadius: 15, + startWidth: 15, + borderAlpha: 0.8, + nailBorderAlpha: 0 + }, + + GaugeAxis: { + tickColor: "#FFFFFF", + tickAlpha: 0.8, + tickLength: 15, + minorTickLength: 8, + axisThickness: 3, + axisColor: '#FFFFFF', + axisAlpha: 0.8, + bandAlpha: 0.4 + }, + + TrendLine: { + lineColor: "#c03246", + lineAlpha: 0.8 + }, + + // ammap + AmMap: { + handDrawn: false + }, + + AreasSettings: { + alpha: 0.8, + color: "#FFFFFF", + colorSolid: "#000000", + unlistedAreasAlpha: 0.4, + unlistedAreasColor: "#FFFFFF", + outlineColor: "#000000", + outlineAlpha: 0.5, + outlineThickness: 0.5, + rollOverColor: "#4d90d6", + rollOverOutlineColor: "#000000", + selectedOutlineColor: "#000000", + selectedColor: "#e384a6", + unlistedAreasOutlineColor: "#000000", + unlistedAreasOutlineAlpha: 0.5 + }, + + LinesSettings: { + color: "#FFFFFF", + alpha: 0.8 + }, + + ImagesSettings: { + alpha: 0.8, + labelFontSize: 16, + labelColor: "#FFFFFF", + color: "#FFFFFF", + labelRollOverColor: "#4d90d6" + }, + + ZoomControl: { + buttonRollOverColor: "#4d90d6", + buttonFillColor: "#e384a6", + buttonFillAlpha: 0.8 + }, + + SmallMap: { + mapColor: "#FFFFFF", + rectangleColor: "#FFFFFF", + backgroundColor: "#000000", + backgroundAlpha: 0.7, + borderThickness: 1, + borderAlpha: 0.8 + }, + + + // the defaults below are set using CSS syntax, you can use any existing css property + // if you don't use Stock chart, you can delete lines below + PeriodSelector: { + fontFamily: "Covered By Your Grace", + fontSize:"16px", + color: "#e7e7e7" + }, + + PeriodButton: { + fontFamily: "Covered By Your Grace", + fontSize:"16px", + color: "#e7e7e7", + background: "transparent", + opacity: 0.7, + border: "1px solid rgba(255, 255, 255, .15)", + MozBorderRadius: "5px", + borderRadius: "5px", + margin: "1px", + outline: "none", + boxSizing: "border-box" + }, + + PeriodButtonSelected: { + fontFamily: "Covered By Your Grace", + fontSize:"16px", + color: "#e7e7e7", + backgroundColor: "rgba(255, 255, 255, 0.1)", + border: "1px solid rgba(255, 255, 255, .3)", + MozBorderRadius: "5px", + borderRadius: "5px", + margin: "1px", + outline: "none", + opacity: 1, + boxSizing: "border-box" + }, + + PeriodInputField: { + fontFamily: "Covered By Your Grace", + fontSize:"16px", + color: "#e7e7e7", + background: "transparent", + border: "1px solid rgba(255, 255, 255, .15)", + outline: "none" + }, + + DataSetSelector: { + fontFamily: "Covered By Your Grace", + fontSize:"16px", + color: "#e7e7e7", + selectedBackgroundColor: "rgba(255, 255, 255, .25)", + rollOverBackgroundColor: "rgba(255, 255, 255, .15)" + }, + + DataSetCompareList: { + fontFamily: "Covered By Your Grace", + fontSize:"16px", + color: "#e7e7e7", + lineHeight: "100%", + boxSizing: "initial", + webkitBoxSizing: "initial", + border: "1px solid rgba(255, 255, 255, .15)" + }, + + DataSetSelect: { + fontFamily: "Covered By Your Grace", + fontSize:"16px", + border: "1px solid rgba(255, 255, 255, .15)", + outline: "none" + } + +}; \ No newline at end of file diff --git a/iguana/js/amcharts/themes/dark.js b/iguana/js/amcharts/themes/dark.js new file mode 100755 index 000000000..d97a01ae2 --- /dev/null +++ b/iguana/js/amcharts/themes/dark.js @@ -0,0 +1,195 @@ +AmCharts.themes.dark = { + + themeName: "dark", + + AmChart: { + color: "#e7e7e7", backgroundColor: "#282828" + }, + + AmCoordinateChart: { + colors: ["#ae85c9", "#aab9f7", "#b6d2ff", "#c9e6f2", "#c9f0e1", "#e8d685", "#e0ad63", "#d48652", "#d27362", "#495fba", "#7a629b", "#8881cc"] + }, + + AmStockChart: { + colors: ["#639dbd", "#e8d685", "#ae85c9", "#c9f0e1", "#d48652", "#629b6d", "#719dc3", "#719dc3"] + }, + + AmSlicedChart: { + outlineAlpha: 1, + outlineThickness: 2, + labelTickColor: "#FFFFFF", + labelTickAlpha: 0.3, + colors: ["#495fba", "#e8d685", "#ae85c9", "#c9f0e1", "#d48652", "#629b6d", "#719dc3", "#719dc3"] + }, + + AmRectangularChart: { + zoomOutButtonColor: '#FFFFFF', + zoomOutButtonRollOverAlpha: 0.15, + zoomOutButtonImage: "lensWhite" + }, + + AxisBase: { + axisColor: "#FFFFFF", + axisAlpha: 0.3, + gridAlpha: 0.1, + gridColor: "#FFFFFF", + dashLength: 3 + }, + + ChartScrollbar: { + backgroundColor: "#000000", + backgroundAlpha: 0.2, + graphFillAlpha: 0.2, + graphLineAlpha: 0, + graphFillColor: "#FFFFFF", + selectedGraphFillColor: "#FFFFFF", + selectedGraphFillAlpha: 0.4, + selectedGraphLineColor: "#FFFFFF", + selectedBackgroundColor: "#FFFFFF", + selectedBackgroundAlpha: 0.09, + gridAlpha: 0.15 + }, + + ChartCursor: { + cursorColor: "#FFFFFF", + color: "#000000", + cursorAlpha: 0.5 + }, + + AmLegend: { + color: "#e7e7e7" + }, + + AmGraph: { + lineAlpha: 0.9 + }, + + + GaugeArrow: { + color: "#FFFFFF", + alpha: 0.8, + nailAlpha: 0, + innerRadius: "40%", + nailRadius: 15, + startWidth: 15, + borderAlpha: 0.8, + nailBorderAlpha: 0 + }, + + GaugeAxis: { + tickColor: "#FFFFFF", + tickAlpha: 1, + tickLength: 15, + minorTickLength: 8, + axisThickness: 3, + axisColor: '#FFFFFF', + axisAlpha: 1, + bandAlpha: 0.8 + }, + + TrendLine: { + lineColor: "#c03246", + lineAlpha: 0.8 + }, + + // ammap + AreasSettings: { + alpha: 0.8, + color: "#FFFFFF", + colorSolid: "#000000", + unlistedAreasAlpha: 0.4, + unlistedAreasColor: "#FFFFFF", + outlineColor: "#000000", + outlineAlpha: 0.5, + outlineThickness: 0.5, + rollOverColor: "#3c5bdc", + rollOverOutlineColor: "#000000", + selectedOutlineColor: "#000000", + selectedColor: "#f15135", + unlistedAreasOutlineColor: "#000000", + unlistedAreasOutlineAlpha: 0.5 + }, + + LinesSettings: { + color: "#FFFFFF", + alpha: 0.8 + }, + + ImagesSettings: { + alpha: 0.8, + labelColor: "#FFFFFF", + color: "#FFFFFF", + labelRollOverColor: "#3c5bdc" + }, + + ZoomControl: { + buttonFillAlpha:0.7, + buttonIconColor:"#494949" + }, + + SmallMap: { + mapColor: "#FFFFFF", + rectangleColor: "#FFFFFF", + backgroundColor: "#000000", + backgroundAlpha: 0.7, + borderThickness: 1, + borderAlpha: 0.8 + }, + + // the defaults below are set using CSS syntax, you can use any existing css property + // if you don't use Stock chart, you can delete lines below + PeriodSelector: { + color: "#e7e7e7" + }, + + PeriodButton: { + color: "#e7e7e7", + background: "transparent", + opacity: 0.7, + border: "1px solid rgba(255, 255, 255, .15)", + MozBorderRadius: "5px", + borderRadius: "5px", + margin: "1px", + outline: "none", + boxSizing: "border-box" + }, + + PeriodButtonSelected: { + color: "#e7e7e7", + backgroundColor: "rgba(255, 255, 255, 0.1)", + border: "1px solid rgba(255, 255, 255, .3)", + MozBorderRadius: "5px", + borderRadius: "5px", + margin: "1px", + outline: "none", + opacity: 1, + boxSizing: "border-box" + }, + + PeriodInputField: { + color: "#e7e7e7", + background: "transparent", + border: "1px solid rgba(255, 255, 255, .15)", + outline: "none" + }, + + DataSetSelector: { + color: "#e7e7e7", + selectedBackgroundColor: "rgba(255, 255, 255, .25)", + rollOverBackgroundColor: "rgba(255, 255, 255, .15)" + }, + + DataSetCompareList: { + color: "#e7e7e7", + lineHeight: "100%", + boxSizing: "initial", + webkitBoxSizing: "initial", + border: "1px solid rgba(255, 255, 255, .15)" + }, + + DataSetSelect: { + border: "1px solid rgba(255, 255, 255, .15)", + outline: "none" + } + +}; \ No newline at end of file diff --git a/iguana/js/amcharts/themes/light.js b/iguana/js/amcharts/themes/light.js new file mode 100755 index 000000000..5b57a4497 --- /dev/null +++ b/iguana/js/amcharts/themes/light.js @@ -0,0 +1,189 @@ +AmCharts.themes.light = { + + themeName:"light", + + AmChart: { + color: "#000000", backgroundColor: "#FFFFFF" + }, + + AmCoordinateChart: { + colors: ["#67b7dc", "#fdd400", "#84b761", "#cc4748", "#cd82ad", "#2f4074", "#448e4d", "#b7b83f", "#b9783f", "#b93e3d", "#913167"] + }, + + AmStockChart: { + colors: ["#67b7dc", "#fdd400", "#84b761", "#cc4748", "#cd82ad", "#2f4074", "#448e4d", "#b7b83f", "#b9783f", "#b93e3d", "#913167"] + }, + + AmSlicedChart: { + colors: ["#67b7dc", "#fdd400", "#84b761", "#cc4748", "#cd82ad", "#2f4074", "#448e4d", "#b7b83f", "#b9783f", "#b93e3d", "#913167"], + outlineAlpha: 1, + outlineThickness: 2, + labelTickColor: "#000000", + labelTickAlpha: 0.3 + }, + + AmRectangularChart: { + zoomOutButtonColor: '#000000', + zoomOutButtonRollOverAlpha: 0.15, + zoomOutButtonImage: "lens" + }, + + AxisBase: { + axisColor: "#000000", + axisAlpha: 0.3, + gridAlpha: 0.1, + gridColor: "#000000" + }, + + ChartScrollbar: { + backgroundColor: "#000000", + backgroundAlpha: 0.12, + graphFillAlpha: 0.5, + graphLineAlpha: 0, + selectedBackgroundColor: "#FFFFFF", + selectedBackgroundAlpha: 0.4, + gridAlpha: 0.15 + }, + + ChartCursor: { + cursorColor: "#000000", + color: "#FFFFFF", + cursorAlpha: 0.5 + }, + + AmLegend: { + color: "#000000" + }, + + AmGraph: { + lineAlpha: 0.9 + }, + GaugeArrow: { + color: "#000000", + alpha: 0.8, + nailAlpha: 0, + innerRadius: "40%", + nailRadius: 15, + startWidth: 15, + borderAlpha: 0.8, + nailBorderAlpha: 0 + }, + + GaugeAxis: { + tickColor: "#000000", + tickAlpha: 1, + tickLength: 15, + minorTickLength: 8, + axisThickness: 3, + axisColor: '#000000', + axisAlpha: 1, + bandAlpha: 0.8 + }, + + TrendLine: { + lineColor: "#c03246", + lineAlpha: 0.8 + }, + + // ammap + AreasSettings: { + alpha: 0.8, + color: "#67b7dc", + colorSolid: "#003767", + unlistedAreasAlpha: 0.4, + unlistedAreasColor: "#000000", + outlineColor: "#FFFFFF", + outlineAlpha: 0.5, + outlineThickness: 0.5, + rollOverColor: "#3c5bdc", + rollOverOutlineColor: "#FFFFFF", + selectedOutlineColor: "#FFFFFF", + selectedColor: "#f15135", + unlistedAreasOutlineColor: "#FFFFFF", + unlistedAreasOutlineAlpha: 0.5 + }, + + LinesSettings: { + color: "#000000", + alpha: 0.8 + }, + + ImagesSettings: { + alpha: 0.8, + labelColor: "#000000", + color: "#000000", + labelRollOverColor: "#3c5bdc" + }, + + ZoomControl: { + buttonFillAlpha:0.7, + buttonIconColor:"#a7a7a7" + }, + + SmallMap: { + mapColor: "#000000", + rectangleColor: "#f15135", + backgroundColor: "#FFFFFF", + backgroundAlpha: 0.7, + borderThickness: 1, + borderAlpha: 0.8 + }, + + // the defaults below are set using CSS syntax, you can use any existing css property + // if you don't use Stock chart, you can delete lines below + PeriodSelector: { + color: "#000000" + }, + + PeriodButton: { + color: "#000000", + background: "transparent", + opacity: 0.7, + border: "1px solid rgba(0, 0, 0, .3)", + MozBorderRadius: "5px", + borderRadius: "5px", + margin: "1px", + outline: "none", + boxSizing: "border-box" + }, + + PeriodButtonSelected: { + color: "#000000", + backgroundColor: "#b9cdf5", + border: "1px solid rgba(0, 0, 0, .3)", + MozBorderRadius: "5px", + borderRadius: "5px", + margin: "1px", + outline: "none", + opacity: 1, + boxSizing: "border-box" + }, + + PeriodInputField: { + color: "#000000", + background: "transparent", + border: "1px solid rgba(0, 0, 0, .3)", + outline: "none" + }, + + DataSetSelector: { + + color: "#000000", + selectedBackgroundColor: "#b9cdf5", + rollOverBackgroundColor: "#a8b0e4" + }, + + DataSetCompareList: { + color: "#000000", + lineHeight: "100%", + boxSizing: "initial", + webkitBoxSizing: "initial", + border: "1px solid rgba(0, 0, 0, .3)" + }, + + DataSetSelect: { + border: "1px solid rgba(0, 0, 0, .3)", + outline: "none" + } + +}; \ No newline at end of file diff --git a/iguana/js/amcharts/themes/patterns.js b/iguana/js/amcharts/themes/patterns.js new file mode 100755 index 000000000..dc082835d --- /dev/null +++ b/iguana/js/amcharts/themes/patterns.js @@ -0,0 +1,256 @@ +AmCharts.themes.patterns = { + + themeName:"patterns", + + AmChart: { + color: "#000000", backgroundColor: "#FFFFFF" + }, + + AmCoordinateChart: { + colors:["#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000"], + patterns:[ + {"url":"patterns/black/pattern1.png", "width":4, "height":4}, + {"url":"patterns/black/pattern2.png", "width":4, "height":4}, + {"url":"patterns/black/pattern3.png", "width":4, "height":4}, + {"url":"patterns/black/pattern4.png", "width":4, "height":4}, + {"url":"patterns/black/pattern5.png", "width":4, "height":4}, + {"url":"patterns/black/pattern6.png", "width":4, "height":4}, + {"url":"patterns/black/pattern7.png", "width":4, "height":4}, + {"url":"patterns/black/pattern8.png", "width":4, "height":4}, + {"url":"patterns/black/pattern9.png", "width":4, "height":4}, + {"url":"patterns/black/pattern10.png", "width":4, "height":4}, + {"url":"patterns/black/pattern11.png", "width":4, "height":4}, + {"url":"patterns/black/pattern12.png", "width":4, "height":4}, + {"url":"patterns/black/pattern13.png", "width":4, "height":4}, + {"url":"patterns/black/pattern14.png", "width":4, "height":4}, + {"url":"patterns/black/pattern15.png", "width":4, "height":4}, + {"url":"patterns/black/pattern16.png", "width":4, "height":4}, + {"url":"patterns/black/pattern17.png", "width":4, "height":4}, + {"url":"patterns/black/pattern18.png", "width":4, "height":4}, + {"url":"patterns/black/pattern19.png", "width":4, "height":4}, + {"url":"patterns/black/pattern20.png", "width":4, "height":4}, + {"url":"patterns/black/pattern21.png", "width":4, "height":4}] + }, + + + AmStockChart: { + colors:["#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000"] + }, + + AmPieChart: { + depth3D:0, + angle:0, + labelRadius:10 + }, + + AmSlicedChart: { + outlineAlpha: 0.3, + colors:["#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000"], + outlineThickness: 1, + outlineColor:"#000000", + labelTickColor: "#000000", + labelTickAlpha: 0.3, + patterns:[ + {"url":"patterns/black/pattern1.png", "width":4, "height":4}, + {"url":"patterns/black/pattern2.png", "width":4, "height":4}, + {"url":"patterns/black/pattern3.png", "width":4, "height":4}, + {"url":"patterns/black/pattern4.png", "width":4, "height":4}, + {"url":"patterns/black/pattern5.png", "width":4, "height":4}, + {"url":"patterns/black/pattern6.png", "width":4, "height":4}, + {"url":"patterns/black/pattern7.png", "width":4, "height":4}, + {"url":"patterns/black/pattern8.png", "width":4, "height":4}, + {"url":"patterns/black/pattern9.png", "width":4, "height":4}, + {"url":"patterns/black/pattern10.png", "width":4, "height":4}, + {"url":"patterns/black/pattern11.png", "width":4, "height":4}, + {"url":"patterns/black/pattern12.png", "width":4, "height":4}, + {"url":"patterns/black/pattern13.png", "width":4, "height":4}, + {"url":"patterns/black/pattern14.png", "width":4, "height":4}, + {"url":"patterns/black/pattern15.png", "width":4, "height":4}, + {"url":"patterns/black/pattern16.png", "width":4, "height":4}, + {"url":"patterns/black/pattern17.png", "width":4, "height":4}, + {"url":"patterns/black/pattern18.png", "width":4, "height":4}, + {"url":"patterns/black/pattern19.png", "width":4, "height":4}, + {"url":"patterns/black/pattern20.png", "width":4, "height":4}, + {"url":"patterns/black/pattern21.png", "width":4, "height":4}] + }, + + AmRectangularChart: { + zoomOutButtonColor: '#000000', + zoomOutButtonRollOverAlpha: 0.15, + zoomOutButtonImage: "lens" + }, + + + + AxisBase: { + axisColor: "#000000", + axisAlpha: 0.3, + gridAlpha: 0.05, + gridColor: "#000000" + }, + + ChartScrollbar: { + backgroundColor: "#000000", + backgroundAlpha: 0.13, + graphFillAlpha: 0.4, + selectedGraphFillAlpha: 0.7, + graphLineAlpha: 0, + selectedBackgroundColor: "#FFFFFF", + selectedBackgroundAlpha: 0.9, + gridAlpha: 0.15 + }, + + ChartCursor: { + cursorColor: "#000000", + color: "#FFFFFF", + cursorAlpha: 0.5 + }, + + AmLegend: { + color: "#000000", + markerBorderAlpha:0.1, + markerSize:20, + switchColor:"#000000" + }, + + AmGraph: { + lineAlpha: 0.4, + fillAlphas:0.5 + }, + + AmAngularGauge:{ + faceAlpha:0.5, + facePattern:{"url":"patterns/black/pattern1.png", "width":4, "height":4} + }, + + + GaugeArrow: { + color: "#000000", + alpha: 1, + nailAlpha: 1, + innerRadius: "0%", + nailRadius: 15, + startWidth: 15, + borderAlpha: 1, + radius:"70%", + nailBorderAlpha: 1 + }, + + GaugeAxis: { + tickColor: "#000000", + tickAlpha: 1, + tickLength: 15, + minorTickLength: 8, + axisThickness: 1, + axisColor: '#000000', + axisAlpha: 1, + bandAlpha: 1 + }, + + TrendLine: { + lineColor: "#c03246", + lineAlpha: 0.8 + }, + + // ammap + AreasSettings: { + alpha: 0.8, + color: "#000000", + colorSolid: "#000000", + unlistedAreasAlpha: 0.4, + unlistedAreasColor: "#000000", + outlineColor: "#FFFFFF", + outlineAlpha: 0.5, + outlineThickness: 0.5, + rollOverColor: "#3c5bdc", + rollOverOutlineColor: "#FFFFFF", + selectedOutlineColor: "#FFFFFF", + selectedColor: "#f15135", + unlistedAreasOutlineColor: "#FFFFFF", + unlistedAreasOutlineAlpha: 0.5 + }, + + LinesSettings: { + color: "#000000", + alpha: 0.8 + }, + + ImagesSettings: { + alpha: 0.8, + labelColor: "#000000", + color: "#000000", + labelRollOverColor: "#3c5bdc" + }, + + ZoomControl: { + buttonRollOverColor: "#3c5bdc", + buttonFillColor: "#f15135", + buttonFillAlpha: 0.8 + }, + + SmallMap: { + mapColor: "#000000", + rectangleColor: "#FFFFFF", + backgroundColor: "#FFFFFF", + backgroundAlpha: 0.7, + borderThickness: 1, + borderAlpha: 0.8 + }, + + // the defaults below are set using CSS syntax, you can use any existing css property + // if you don't use Stock chart, you can delete lines below + PeriodSelector: { + color: "#000000" + }, + + PeriodButton: { + color: "#000000", + background: "transparent", + opacity: 0.7, + border: "1px solid rgba(0, 0, 0, .3)", + MozBorderRadius: "5px", + borderRadius: "5px", + margin: "1px", + outline: "none", + boxSizing: "border-box" + }, + + PeriodButtonSelected: { + color: "#000000", + backgroundColor: "rgba(0, 0, 0, 0.1)", + border: "1px solid rgba(0, 0, 0, .3)", + MozBorderRadius: "5px", + borderRadius: "5px", + margin: "1px", + outline: "none", + opacity: 1, + boxSizing: "border-box" + }, + + PeriodInputField: { + color: "#000000", + background: "transparent", + border: "1px solid rgba(0, 0, 0, .3)", + outline: "none" + }, + + DataSetSelector: { + color: "#000000", + selectedBackgroundColor: "rgba(0, 0, 0, .25)", + rollOverBackgroundColor: "rgba(0, 0, 0, .15)" + }, + + DataSetCompareList: { + color: "#000000", + lineHeight: "100%", + boxSizing: "initial", + webkitBoxSizing: "initial", + border: "1px solid rgba(0, 0, 0, .3)" + }, + + DataSetSelect: { + border: "1px solid rgba(0, 0, 0, .3)", + outline: "none" + } + +}; \ No newline at end of file diff --git a/iguana/js/amcharts_licence.txt b/iguana/js/amcharts_licence.txt new file mode 100755 index 000000000..edb853722 --- /dev/null +++ b/iguana/js/amcharts_licence.txt @@ -0,0 +1,16 @@ +********************************************************************************* +This AmCharts software is free under a linkware license. + +This means you may not remove or hide in any other way link to amcharts +web site - www.amcharts.com. + +If you wish to remove the link, you should purchase commercial license. + +You may not redistribute, sublicense or sell this program without written +permission of Antanas Marcelionis, the author of amcharts software. + +This software is provided without warranty. +********************************************************************************* +A commercial version (without link) is available at amCharts's website: +http://www.amcharts.com/online-store/ +********************************************************************************* \ No newline at end of file diff --git a/iguana/js/api.js b/iguana/js/api.js index 75a367902..8aff0bae6 100755 --- a/iguana/js/api.js +++ b/iguana/js/api.js @@ -153,7 +153,7 @@ var SPNAPI = (function(SPNAPI, $, undefined) { SPNAPI.useGETRequest=function(request){ if(request.method && (request.method==='apikeypair' || request.method==='setuserid' || request.method==='encryptjson' || request.method==='decryptjson')){ - return false; + return true; }else{ return true; } diff --git a/iguana/js/blockexplorer.js b/iguana/js/blockexplorer.js index 167b5947e..1d922ed44 100755 --- a/iguana/js/blockexplorer.js +++ b/iguana/js/blockexplorer.js @@ -36,64 +36,7 @@ document.getElementById('BlockExpCoin').innerHTML = html; * to start RPC for particular coin */ -var callBlockEXPRPC=function(coin){ - - var request="{\"agent\":\"SuperNET\",\"method\":\"bitcoinrpc\",\"setcoin\":\""+coin+"\"}"; - - SPNAPI.makeRequest(request, function(request,response){ - response=JSON.parse(response); - if(response.result && response.result==='set bitcoin RPC coin'){ - - blockExp_input_table(); - } - }); -}; - -/* - * - * @param {type} height - * @returns {undefined} - * Function gets the blockhash when called and is stored in global variable - * (initially height is set to zero) - * - */ - -var filterInt = function (value) { - if(/^(\-|\+)?([0-9]+|Infinity)$/.test(value)) - return Number(value); - return "NaN"; -}; - -var getBlockhash= function(height){ - - var height=($('#BlockExp_height').val()); - /* - if (height === "NaN" || height ==='Infinity') { - height=0; - }*/ - var request="{\"agent\":\"ramchain\",\"method\":\"getblockhash\",\"height\":\""+height+"\"}"; - - SPNAPI.makeRequest(request, function(request,response){ - response=JSON.parse(response); - if(response.result){ - BlockHash=response.result; - //Blockhashoutput - document.getElementById('block_output_table').innerHTML=''+'Blockhash is: '+BlockHash+''; - $('#BlockExp_blockhash').val(BlockHash); - - } - }); - -}; - -/* - * - * @param {type} hash - * @returns {undefined} - * Function gets Block for a paritculat blockhash - * and store inside global varianle - * - */ +var callBlockEXPRds var getBlock= function(hash){ var inputhash=$('#BlockExp_blockhash').val(); if(inputhash!==hash){ diff --git a/iguana/js/imgAPI.js b/iguana/js/imgAPI.js index f467cd830..2438326f6 100755 --- a/iguana/js/imgAPI.js +++ b/iguana/js/imgAPI.js @@ -8,7 +8,7 @@ var prevXY={"X":0,"Y":0}; var prevID=0; $(document).ready(function() { - loadImages(); +// loadImages(); caused internal error with local storage $('.imagAPI').click(function(e){ diff --git a/iguana/js/index.js b/iguana/js/index.js new file mode 100644 index 000000000..5cc330fbc --- /dev/null +++ b/iguana/js/index.js @@ -0,0 +1,42 @@ +$(document).ready(function() { + var val; + var val1; + $("#currancy2").on('change', function() { + var option1 = $("#currancy1 option:selected").text(); + var option2 = $("#currancy2 option:selected").text(); + if (option1 == option2) { + alert("Please slect diffrent Currancy"); + } + }); + + $("#currancy1").on('change', function() { + var option1 = $("#currancy1 option:selected").text(); + var option2 = $("#currancy2 option:selected").text(); + + if (option1 == option2) { + + alert("Please slect diffrent Currancy"); + } else { + $("#one_coin1_value").each(function() { + }); + } + }); + + $("#one_coin1_value").keyup(function() { + calculateSum(); + }); +}); + +function calculateSum() { + var texboxval = parseFloat($("#one_coin1_value").val()) + var value = parseFloat($("#currancy1").val()); + var value1 = parseFloat($("#currancy2").val()); + + var sum = texboxval + value; + var result = (sum) / (value1); + + $("#one_coin2_value").val(result); + //$("#one_coin2_value").text(result); + //.toFixed() method will roundoff the final sum to 2 decimal places + //$("#one_coin2_value").html(sum.toFixed(2)); +} \ No newline at end of file diff --git a/iguana/js/instantdex.js b/iguana/js/instantdex.js index a19516d48..cd1b664a3 100755 --- a/iguana/js/instantdex.js +++ b/iguana/js/instantdex.js @@ -41,7 +41,7 @@ var show_resposnse=function(response){ if(i==='tag') continue; if(isJsonArray(response[i]) ){ - //return_json_table({"orderid":"16800917935208460084","offerer":"0","type":"bid","base":"BTCD","rel":"BTCD","timestamp":1454949273,"price":0.00250000,"volume":11,"nonce":2684223522,"pendingvolume":0,"expiresin":3496}) + //return_json_table({"orderid":"16800917935208460084","account":"0","type":"bid","base":"BTCD","rel":"BTCD","timestamp":1454949273,"price":0.00250000,"volume":11,"nonce":2684223522,"pendingvolume":0,"expiresin":3496}) $('#Instandex_output_table').append(""+i+""+return_json_table(response[i])+""); continue; } diff --git a/iguana/js/stockchart.js b/iguana/js/stockchart.js new file mode 100644 index 000000000..9d0b8518a --- /dev/null +++ b/iguana/js/stockchart.js @@ -0,0 +1,249 @@ +var httpresult; + +function http_handler() { + if (this.status == 200 && this.responseText != null) { + alert(this.responseText); + httpresult = this.responseText; + } +} + +function httpGet(url) { + var client; + if (window.XMLHttpRequest) { + client = new XMLHttpRequest(); + } else { + client = new ActiveXObject('Microsoft.XMLHTTP'); + } + client.onload = http_handler; + client.open('GET', url); + client.send(); +} + +AmCharts.ready(function() { + createStockChart(); +}); +var interval, BASE = "BTCD", + REL = "BTC"; + +function createStockChart() { + var chartData = []; + var chart = AmCharts.makeChart("chartdiv", { + "type": "serial", + "theme": "dark", + "valueAxes": [{ + "title": "BTC", + "id": "vert", + "axisAlpha": 0, + "dashLength": 1, + "position": "left" + }, { + "id": "horiz", + "axisAlpha": 0, + "dashLength": 1, + "position": "bottom", + "labelFunction": function(value) { + var date = new Date(value); + return AmCharts.formatDate(date, "MMM DD HH:NN:SS"); + } + }], + "graphs": [{ + "id": "g1", + "lineColor": "#00FFFF", + "bullet": "round", + "valueField": "bid", + "balloonText": "[[category]] [[h]]:[[m]]:[[s]] account:[[offerer]] id:[[orderid]] volume:[[volume]] bid:[[bid]]" + }, { + "id": "g2", + "lineColor": "#FF8800", + "bullet": "round", + "valueField": "ask", + "balloonText": "[[category]] [[h]]:[[m]]:[[s]] account:[[offerer]] id:[[orderid]] volume:[[volume]] ask:[[ask]]" + }], + "categoryField": "date", + "categoryAxis": { + "parseDates": true, + "equalSpacing": true, + "dashLength": 1, + "minorGridEnabled": true + }, + "chartScrollbar": {}, + "chartCursor": {}, + "dataProvider": chartData + }); + + var startButton = document.getElementById('start'); + var endButton = document.getElementById('stop'); + var buyButton = document.getElementById('buy'); + var sellButton = document.getElementById('sell'); + /* + var BTCbutton = document.getElementById('BTC'); + var CNYbutton = document.getElementById('CNY'); + var USDbutton = document.getElementById('USD'); + var EURbutton = document.getElementById('EUR'); + var JPYbutton = document.getElementById('JPY'); + var GBPbutton = document.getElementById('GBP'); + var AUDbutton = document.getElementById('AUD'); + var CADbutton = document.getElementById('CAD'); + var CHFbutton = document.getElementById('CHF'); + var NZDbutton = document.getElementById('NZD'); + + USDbutton.addEventListener('click', USDrel); + EURbutton.addEventListener('click', EURrel); + JPYbutton.addEventListener('click', JPYrel); + GBPbutton.addEventListener('click', GBPrel); + AUDbutton.addEventListener('click', AUDrel); + CADbutton.addEventListener('click', CADrel); + CHFbutton.addEventListener('click', CHFrel); + NZDbutton.addEventListener('click', NZDrel); + CNYbutton.addEventListener('click', CNYrel); + BTCbutton.addEventListener('click', BTCrel); + */ + + var BTCDbutton = document.getElementById('BTCD'); + var VPNbutton = document.getElementById('VPN'); + var VRCbutton = document.getElementById('VRC'); + var SYSbutton = document.getElementById('SYS'); + var SuperNETbutton = document.getElementById('SuperNET'); + var crypto777button = document.getElementById('crypto777'); + var pangeabutton = document.getElementById('Pangea'); + var InstantDEXbutton = document.getElementById('InstantDEX'); + var Tradebotsbutton = document.getElementById('Tradebots'); + var NXTprivacybutton = document.getElementById('NXTprivacy'); + + + startButton.addEventListener('click', startDemo); + endButton.addEventListener('click', endDemo); + buyButton.addEventListener('click', buyaction); + sellButton.addEventListener('click', sellaction); + + BTCDbutton.addEventListener('click', BTCDbase); + VPNbutton.addEventListener('click', VPNbase); + SYSbutton.addEventListener('click', SYSbase); + SuperNETbutton.addEventListener('click', SuperNETbase); + crypto777button.addEventListener('click', crypto777base); + pangeabutton.addEventListener('click', Pangeabase); + InstantDEXbutton.addEventListener('click', InstantDEXbase); + Tradebotsbutton.addEventListener('click', Tradebotsbase); + NXTprivacybutton.addEventListener('click', NXTprivacybase); + + function changebase(newbase) { + BASE = newbase; + if (chartData.length > 0) { + chartData.splice(0, chartData.length); + chart.validateData(); + } + } + + function BTCDbase() { + changebase("BTCD"); + } + + function VPNbase() { + changebase("VPN"); + } + + function SYSbase() { + changebase("SYS"); + } + + function SuperNETbase() { + changebase("SuperNET"); + } + + function crypto777base() { + changebase("crypto777"); + } + + function Pangeabase() { + changebase("Pangea"); + } + + function InstantDEXbase() { + changebase("InstantDEX"); + } + + function Tradebotsbase() { + changebase("Tradebots"); + } + + function NXTprivacybase() { + changebase("NXTprivacy"); + } + + function USDrel() { + REL = "USD"; + } + + function EURrel() { + REL = "EUR"; + } + + function JPYrel() { + REL = "JPY"; + } + + function GBPrel() { + REL = "GBP"; + } + + function AUDrel() { + REL = "AUD"; + } + + function CADrel() { + REL = "CAD"; + } + + function CHFrel() { + REL = "CHF"; + } + + function NZDrel() { + REL = "NZD"; + } + + function CNYrel() { + REL = "CNY"; + } + + function BTCrel() { + REL = "CNY"; + } + + function startDemo() { + startButton.disabled = "disabled"; + endButton.disabled = ""; + interval = setInterval(getDataFromServer, 1000); + } + + function endDemo() { + startButton.disabled = ""; + endButton.disabled = "disabled"; + clearInterval(interval); + } + + function buyaction() { + alert("need to do market buy"); + } + + function sellaction() { + alert("need to do market sell"); + } + + function getDataFromServer() { + var i, newData = []; + var request = '{"agent":"InstantDEX","method":"events","base":"' + BASE + '","rel":"' + REL + '"}'; + SPNAPI.makeRequest(request, + function(request, response) { + newData = JSON.parse(response); + if (newData.length > 0) { + alert(response); + chartData.push.apply(chartData, newData); + if (chartData.length > 50) + chartData.splice(0, chartData.length - 50); + chart.validateData(); //call to redraw the chart with new data + } + }); + // newData = JSON.parse("[{\"h\":14,\"m\":44,\"s\":32,\"date\":1407877200000,\"bid\":30,\"ask\":35},{\"date\":1407877200000,\"bid\":40,\"ask\":44},{\"date\":1407877200000,\"bid\":49,\"ask\":45},{\"date\":1407877200000,\"ask\":28},{\"date\":1407877200000,\"ask\":52}]"); + } +} \ No newline at end of file diff --git a/iguana/js/style.css b/iguana/js/style.css new file mode 100755 index 000000000..be9936142 --- /dev/null +++ b/iguana/js/style.css @@ -0,0 +1,10 @@ +body { + font-family: Tahoma,Arial,Verdana; + font-size: 12px; + color: black; +} + +a:link {color: #84c4e2;} +a:visited {color:#84c4e2;} +a:hover {color: #cd82ad;} +a:active {color: #84c4e2;} \ No newline at end of file diff --git a/iguana/m_BTC b/iguana/m_BTC deleted file mode 100755 index 45ea685bb..000000000 --- a/iguana/m_BTC +++ /dev/null @@ -1 +0,0 @@ -../agents/iguana "{\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"BTC\",\"active\":1,\"maxpeers\":128,\"services\":0,\"poll\":1,\"RAM\":6}" diff --git a/iguana/m_BTCD b/iguana/m_BTCD deleted file mode 100755 index 7b9b1f53b..000000000 --- a/iguana/m_BTCD +++ /dev/null @@ -1 +0,0 @@ -../agents/iguana "{\"agent\":\"iguana\",\"method\":\"addcoin\",\"newcoin\":\"BTCD\",\"active\":1,\"maxpeers\":128,\"services\":0,\"poll\":1}" diff --git a/iguana/m_LP b/iguana/m_LP new file mode 100755 index 000000000..efcf9f5c0 --- /dev/null +++ b/iguana/m_LP @@ -0,0 +1,8 @@ +#./configure --enable-endomorphism --enable-module-ecdh --enable-module-schnorr --enable-module-rangeproof --enable-experimental --enable-module_recovery +rm -f ../agents/iguana *.o +git pull +cd secp256k1; ./m_unix; cd .. +cd ../crypto777; ./m_LP; cd ../iguana +gcc -g -fno-aggressive-loop-optimizations -Wno-deprecated -c -O2 -DLIQUIDITY_PROVIDER=1 *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c +gcc -g -fno-aggressive-loop-optimizations -Wno-deprecated -c -DLIQUIDITY_PROVIDER=1 main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c +gcc -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lcurl -lssl -lcrypto -lpthread -lz -lm diff --git a/iguana/m_android b/iguana/m_android index e723b2921..1e3d0b717 100755 --- a/iguana/m_android +++ b/iguana/m_android @@ -1,8 +1,18 @@ +#!/bin/bash + rm ../agents/iguana *.o -git pull -cd secp256k1; ./m_unix; cd .. -$CC2 -g -Wno-deprecated -c -O2 *.c databases/iguana_DB.c -$CC2 -g -Wno-deprecated -c main.c iguana777.c iguana_bundles.c -#$CC2 -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lcurl -lssl -lcrypto -lpthread -lm #../includes/libsecp256k1.a -lgmp -$CC2 -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lpthread -lm +if [[ $# -eq 0 ]]; then + git pull +fi + +echo "Compiling libsecp256k1.a ..." +cd secp256k1; ./m_android; cd .. + +#$CC2 -o ../agents/iguana -O2 *.c ../basilisk/*.c -I $NDK/platforms/android-19/arch-arm/usr/include ../agents/libcrypto777.a ../agents/libsecp256k1.a ../OSlibs/android/lib/libcurl.a -lssl -lcrypto -lm -lc -lz + +echo "Compiling iguana ... " +#$CC2 -o ../agents/iguana -O2 *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c -I ./secp256k1/include -I $NDK/platforms/android-21/arch-arm/usr/include ../agents/libcrypto777.a ../agents/libsecp256k1.a ../OSlibs/android/lib/libcurl.a -L../OSlibs/android/lib/ -lssl -lcrypto -L$NDK/platforms/android-21/arch-arm/usr/lib -lm -lc -lz -nostdlib -lgcc +$CC2 -g -Wno-deprecated -c -O2 -DLIQUIDITY_PROVIDER=1 *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c +$CC2 -g -Wno-deprecated -c -DLIQUIDITY_PROVIDER=1 main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c +$CC2 -g -o ../agents/iguana -O2 *.o ../agents/libcrypto777.a ../OSlibs/android/lib/libcurl.a -L../OSlibs/android/lib/ -lcurl -lssl -lcrypto -lm diff --git a/iguana/m_ios b/iguana/m_ios index ccce1734a..ac23ad00a 100755 --- a/iguana/m_ios +++ b/iguana/m_ios @@ -1,9 +1,20 @@ -set -x +#!/bin/bash -CC="$(xcrun --sdk iphoneos --find clang) -isysroot $(xcrun --sdk iphoneos --show-sdk-path) -arch arm64 -ONLY_ACTIVE_ARCH=YES" +#set -x -git pull +CC="$(xcrun --sdk iphoneos --find clang) -isysroot $(xcrun --sdk iphoneos --show-sdk-path) -arch armv7 -arch arm64 -arch armv7s" + +rm ../agents/iguana *.o + +if [[ $# -eq 0 ]]; then + git pull +fi + +cd secp256k1; ./m_ios; cd .. echo CC=$CC -$CC -v -o ../agents/iguana -O2 *.c ../ios/lib/libssl.a ../ios/lib/libcrypto.a ../agents/libcrypto777.a -L $(xcrun --sdk iphonesimulator --show-sdk-path)/usr/lib -L ../ios/lib -lcurl -lm +$CC -v -Wno-deprecated -O2 -c -DLIQUIDITY_PROVIDER=1 *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c +$CC -v -Wno-deprecated -c -DLIQUIDITY_PROVIDER=1 main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c + +$CC -v -Wno-deprecated -o ../agents/iguana -O2 *.o ../OSlibs/ios/lib/libssl.a ../OSlibs/ios/lib/libcrypto.a ../agents/libcrypto777.a -L $(xcrun --sdk iphoneos --show-sdk-path)/usr/lib ../OSlibs/ios/lib/libcurl.a -framework Foundation -lz -framework Security -lm diff --git a/iguana/m_js b/iguana/m_js index f64f820c5..712f6b993 100755 --- a/iguana/m_js +++ b/iguana/m_js @@ -1,6 +1,4 @@ rm ../agents/iguana *.o git pull -cd secp256k1; ./m_js; cd .. -emcc -s USE_PTHREADS=1 -s ALLOW_MEMORY_GROWTH=1 -Wno-deprecated -c -O2 *.c databases/iguana_DB.c -#emcc -s USE_PTHREADS=1 -Wno-deprecated -c main.c iguana777.c iguana_bundles.c -emcc -s USE_PTHREADS=1 -s ALLOW_MEMORY_GROWTH=1 -o iguana.html -O2 *.o ../agents/libcrypto777.a -lm +emcc -s ALLOW_MEMORY_GROWTH=1 -s PTHREAD_POOL_SIZE=40 -s USE_PTHREADS=2 -o iguana.html -O3 -I. -Isecp256k1./src -Isecp256k1/include -Isecp256k1/src -Wno-unused-parameter -Wnested-externs -Wstrict-prototypes -Wno-unused-function -Wno-long-long -Wno-overlength-strings -fvisibility=hidden -DHAVE_CONFIG_H *.c ../crypto777/*.c ../crypto777/jpeg/*.c ../crypto777/jpeg/unix/*.c secp256k1/src/secp256k1.c -lm +cp iguana.html iguana.js pthread-main.js iguana.html.mem /var/www/html diff --git a/iguana/m_osx b/iguana/m_osx index e41de9c2b..222dccae4 100755 --- a/iguana/m_osx +++ b/iguana/m_osx @@ -1,6 +1,7 @@ +#./configure --enable-endomorphism --enable-module-ecdh --enable-module-schnorr --enable-module-rangeproof --enable-experimental --enable-module_recovery rm ../agents/iguana *.o git pull -cd secp256k1; ./m_osx; cd .. -gcc -g -Wno-deprecated -c -O2 *.c databases/iguana_DB.c -gcc -g -Wno-deprecated -c main.c iguana777.c iguana_bundles.c -gcc -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lpthread -lm +cd secp256k1; ./m_unix; cd .. +gcc -g -Wno-deprecated -c -O2 -DLIQUIDITY_PROVIDER=1 *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c +gcc -g -Wno-deprecated -c -DLIQUIDITY_PROVIDER=1 main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c +gcc -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lcurl -lssl -lcrypto -lpthread -lz -lm diff --git a/iguana/m_unix b/iguana/m_unix index 27d67a482..7859bb3c9 100755 --- a/iguana/m_unix +++ b/iguana/m_unix @@ -1,8 +1,12 @@ +#!/bin/bash + #./configure --enable-endomorphism --enable-module-ecdh --enable-module-schnorr --enable-module-rangeproof --enable-experimental --enable-module_recovery rm ../agents/iguana *.o -git pull +if [[ $# -eq 0 ]]; then + git pull +fi cd secp256k1; ./m_unix; cd .. -gcc -g -Wno-deprecated -c -O2 *.c databases/iguana_DB.c -gcc -g -Wno-deprecated -c main.c iguana777.c iguana_bundles.c -#gcc -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lcurl -lssl -lcrypto -lpthread -lm #../includes/libsecp256k1.a -lgmp -gcc -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lpthread -lm +cd ../crypto777; ./m_unix; cd ../iguana +gcc -g -fno-aggressive-loop-optimizations -Wno-deprecated -c *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c +gcc -g -fno-aggressive-loop-optimizations -Wno-deprecated -c main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c +gcc -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lpthread -lm diff --git a/iguana/main.c b/iguana/main.c index 4cce2ad19..34ebe7c8f 100755 --- a/iguana/main.c +++ b/iguana/main.c @@ -19,77 +19,12 @@ #define CHROMEAPP_MAIN iguana_main #define CHROMEAPP_JSON iguana_JSON #define CHROMEAPP_HANDLER Handler_iguana - +#define ACTIVELY_DECLARE +#define HAVE_STRUCT_TIMESPEC #include "../pnacl_main.h" #include "iguana777.h" -#include "SuperNET.h" -#include "secp256k1/include/secp256k1.h" -//#include "../../secp256k1-zkp/include/secp256k1.h" - -/*#undef fopen -#undef fclose -int32_t Fopen_count,Fclose_count; - -FILE *myfopen(char *fname,char *mode) -{ - FILE *fp; - if ( (fp= fopen(fname,mode)) != 0 ) - { - Fopen_count++; - if ( Fopen_count > 2*Fclose_count ) - printf("Fopens.%d vs Fcloses.%d [%d]\n",Fopen_count,Fclose_count,Fopen_count-Fclose_count); - return(fp); - } - return(0); -} - -int32_t myfclose(FILE *fp) -{ - Fclose_count++; - return(fclose(fp)); -}*/ - -// ALL globals must be here! -char *Iguana_validcommands[] = -{ - "SuperNET", "SuperNETb", - "version", "verack", "getaddr", "addr", "inv", "getdata", "notfound", "getblocks", "getheaders", "headers", "tx", "block", "mempool", "ping", "pong", - "reject", "filterload", "filteradd", "filterclear", "merkleblock", "alert", "" -}; -int32_t Showmode,Autofold,PANGEA_MAXTHREADS = 1; - -struct category_info *Categories; -struct iguana_info *Coins[IGUANA_MAXCOINS]; -char Userhome[512]; -int32_t USE_JAY,FIRST_EXTERNAL,IGUANA_disableNXT,Debuglevel,BIGENDIAN; -uint32_t prices777_NXTBLOCK,MAX_DEPTH = 100; -queue_t helperQ,jsonQ,finishedQ,bundlesQ,emitQ; -struct supernet_info MYINFO,**MYINFOS; -int32_t MAIN_initflag; -int32_t HDRnet,netBLOCKS; -cJSON *API_json; - -#ifdef __PNACL__ -char GLOBAL_TMPDIR[512] = "/DB/tmp2"; -char GLOBAL_DBDIR[512] = "/DB"; -char GLOBAL_HELPDIR[512] = "/DB/help"; -char GLOBAL_VALIDATEDIR[512] = "/DB/purgeable"; -char GLOBAL_CONFSDIR[512] = "/DB/confs"; -int32_t IGUANA_NUMHELPERS = 1; -#else -char GLOBAL_TMPDIR[512] = "tmp"; -char GLOBAL_HELPDIR[512] = "help"; -char GLOBAL_DBDIR[512] = "DB"; -char GLOBAL_VALIDATEDIR[512] = "DB/purgeable"; -char GLOBAL_CONFSDIR[512] = "confs"; -#ifdef __linux -int32_t IGUANA_NUMHELPERS = 8; -#else -int32_t IGUANA_NUMHELPERS = 4; -#endif -#endif -struct iguana_jsonitem { struct queueitem DL; struct supernet_info *myinfo; uint32_t fallback,expired,allocsize; char **retjsonstrp; char remoteaddr[64]; uint16_t port; char jsonstr[]; }; +struct iguana_jsonitem { struct queueitem DL; struct supernet_info *myinfo; uint32_t fallback,expired,allocsize; char *retjsonstr; char remoteaddr[64]; uint16_t port; char jsonstr[]; }; uint16_t SuperNET_API2num(char *agent,char *method) { @@ -141,7 +76,12 @@ void SuperNET_hex2str(char *str,uint8_t *hex,int32_t len) struct supernet_info *SuperNET_MYINFO(char *passphrase) { if ( MYINFO.ctx == 0 ) - MYINFO.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); + { + OS_randombytes(MYINFO.privkey.bytes,sizeof(MYINFO.privkey)); + MYINFO.myaddr.pubkey = curve25519(MYINFO.privkey,curve25519_basepoint9()); + printf("SuperNET_MYINFO: generate session keypair\n"); + RELAYID = -1; + } if ( passphrase == 0 || passphrase[0] == 0 ) return(&MYINFO); else @@ -210,7 +150,7 @@ char *iguana_JSON(char *jsonstr,uint16_t port) char *SuperNET_jsonstr(struct supernet_info *myinfo,char *jsonstr,char *remoteaddr,uint16_t port) { cJSON *json; char *agent,*method,*retstr = 0; - //char str[65]; printf("SuperNET_jsonstr %p %s\n",&myinfo->privkey,bits256_str(str,myinfo->privkey)); + //printf("SuperNET_jsonstr.(%s)\n",jsonstr); if ( (json= cJSON_Parse(jsonstr)) != 0 ) { method = jstr(json,"method"); @@ -227,22 +167,38 @@ char *SuperNET_jsonstr(struct supernet_info *myinfo,char *jsonstr,char *remotead int32_t iguana_jsonQ() { - struct iguana_jsonitem *ptr; + struct iguana_jsonitem *ptr; char *str; + if ( COMMANDLINE_ARGFILE != 0 ) + { + ptr = calloc(1,sizeof(*ptr) + strlen(COMMANDLINE_ARGFILE) + 1); + ptr->myinfo = SuperNET_MYINFO(0); + strcpy(ptr->jsonstr,COMMANDLINE_ARGFILE); + free(COMMANDLINE_ARGFILE); + COMMANDLINE_ARGFILE = 0; + if ( (ptr->retjsonstr= SuperNET_jsonstr(ptr->myinfo,ptr->jsonstr,ptr->remoteaddr,ptr->port)) == 0 ) + ptr->retjsonstr = clonestr("{\"error\":\"null return from iguana_jsonstr\"}"); + printf("COMMANDLINE_ARGFILE.(%s) -> (%s) %.0f\n",ptr->jsonstr,ptr->retjsonstr!=0?ptr->retjsonstr:"null return",OS_milliseconds()); + queue_enqueue("finishedQ",&finishedQ,&ptr->DL,0); + return(1); + } if ( (ptr= queue_dequeue(&finishedQ,0)) != 0 ) { if ( ptr->expired != 0 ) { - if ( ptr->retjsonstrp != 0 && *ptr->retjsonstrp != 0 ) - free(*ptr->retjsonstrp); // *ptr->retjsonstrp = clonestr("{\"error\":\"request timeout\"}"); + if ( (str= ptr->retjsonstr) != 0 ) + { + ptr->retjsonstr = 0; + free(str); + } printf("garbage collection: expired.(%s)\n",ptr->jsonstr); myfree(ptr,ptr->allocsize); } else queue_enqueue("finishedQ",&finishedQ,&ptr->DL,0); } if ( (ptr= queue_dequeue(&jsonQ,0)) != 0 ) { - if ( ptr->retjsonstrp != 0 && (*ptr->retjsonstrp= SuperNET_jsonstr(ptr->myinfo,ptr->jsonstr,ptr->remoteaddr,ptr->port)) == 0 ) - *ptr->retjsonstrp = clonestr("{\"error\":\"null return from iguana_jsonstr\"}"); - //printf("finished.(%s) -> (%s) %.0f\n",ptr->jsonstr,*ptr->retjsonstrp!=0?*ptr->retjsonstrp:"null return",OS_milliseconds()); + if ( (ptr->retjsonstr= SuperNET_jsonstr(ptr->myinfo,ptr->jsonstr,ptr->remoteaddr,ptr->port)) == 0 ) + ptr->retjsonstr = clonestr("{\"error\":\"null return from iguana_jsonstr\"}"); + printf("finished.(%s) -> (%s) %.0f\n",ptr->jsonstr,ptr->retjsonstr!=0?ptr->retjsonstr:"null return",OS_milliseconds()); queue_enqueue("finishedQ",&finishedQ,&ptr->DL,0); return(1); } @@ -251,27 +207,27 @@ int32_t iguana_jsonQ() char *iguana_blockingjsonstr(struct supernet_info *myinfo,char *jsonstr,uint64_t tag,int32_t maxmillis,char *remoteaddr,uint16_t port) { - struct iguana_jsonitem *ptr; char *retjsonstr = 0; int32_t len,allocsize; double expiration; + struct iguana_jsonitem *ptr; int32_t len,allocsize; double expiration; expiration = OS_milliseconds() + maxmillis; - printf("blocking case.(%s) %.0f maxmillis.%d\n",jsonstr,OS_milliseconds(),maxmillis); + //printf("blocking case.(%s) %.0f maxmillis.%d\n",jsonstr,OS_milliseconds(),maxmillis); len = (int32_t)strlen(jsonstr); allocsize = sizeof(*ptr) + len + 1; ptr = mycalloc('J',1,allocsize); ptr->allocsize = allocsize; ptr->myinfo = myinfo; ptr->port = port; - ptr->retjsonstrp = &retjsonstr; + ptr->retjsonstr = 0; safecopy(ptr->remoteaddr,remoteaddr,sizeof(ptr->remoteaddr)); memcpy(ptr->jsonstr,jsonstr,len+1); queue_enqueue("jsonQ",&jsonQ,&ptr->DL,0); while ( OS_milliseconds() < expiration ) { usleep(100); - if ( retjsonstr != 0 ) + if ( ptr->retjsonstr != 0 ) { //printf("got blocking retjsonstr.(%s) delete allocsize.%d:%d\n",retjsonstr,allocsize,ptr->allocsize); queue_delete(&finishedQ,&ptr->DL,ptr->allocsize,1); - return(retjsonstr); + return(ptr->retjsonstr); } usleep(1000); } @@ -282,7 +238,7 @@ char *iguana_blockingjsonstr(struct supernet_info *myinfo,char *jsonstr,uint64_t char *SuperNET_processJSON(struct supernet_info *myinfo,cJSON *json,char *remoteaddr,uint16_t port) { - cJSON *retjson; uint64_t tag; uint32_t timeout; char *jsonstr,*method,*retjsonstr,*retstr = 0; + cJSON *retjson; uint64_t tag; uint32_t timeout; char *jsonstr,*retjsonstr,*retstr = 0; //*hexmsg,*method, //char str[65]; printf("processJSON %p %s\n",&myinfo->privkey,bits256_str(str,myinfo->privkey)); if ( json != 0 ) { @@ -293,15 +249,15 @@ char *SuperNET_processJSON(struct supernet_info *myinfo,cJSON *json,char *remote } if ( (timeout= juint(json,"timeout")) == 0 ) timeout = IGUANA_JSONTIMEOUT; - if ( (method= jstr(json,"method")) != 0 && strcmp(method,"DHT") == 0 && remoteaddr != 0 ) + /*if ( (method= jstr(json,"method")) != 0 && strcmp(method,"DHT") == 0 && remoteaddr != 0 && (hexmsg= jstr(json,"hexmsg")) != 0 ) { - printf("hexmsgprocess\n"); - SuperNET_hexmsgprocess(myinfo,0,json,jstr(json,"hexmsg"),remoteaddr); + //printf("hexmsgprocess myinfo.%p\n",myinfo); + SuperNET_hexmsgprocess(myinfo,0,json,hexmsg,remoteaddr); return(clonestr("{\"result\":\"processed remote DHT\"}")); - } + }*/ jsonstr = jprint(json,0); //printf("RPC? (%s)\n",jsonstr); - if ( (remoteaddr == 0 || remoteaddr[0] == 0 || jstr(json,"immediate") != 0) && port == IGUANA_RPCPORT ) + if ( jstr(json,"immediate") != 0 || ((remoteaddr == 0 || remoteaddr[0] == 0) && port == IGUANA_RPCPORT) ) retjsonstr = SuperNET_jsonstr(myinfo,jsonstr,remoteaddr,port); else retjsonstr = iguana_blockingjsonstr(myinfo,jsonstr,tag,timeout,remoteaddr,port); if ( retjsonstr != 0 ) @@ -330,34 +286,73 @@ char *SuperNET_processJSON(struct supernet_info *myinfo,cJSON *json,char *remote return(retstr); } +char *SuperNET_JSON(struct supernet_info *myinfo,cJSON *json,char *remoteaddr,uint16_t port) +{ + int32_t autologin = 0; uint32_t timestamp; char *retstr=0,*agent=0,*method=0,*jsonstr=0; uint64_t tag; + //printf("SuperNET_JSON.(%s)\n",jprint(json,0)); + if ( remoteaddr != 0 && strcmp(remoteaddr,"127.0.0.1") == 0 ) + remoteaddr = 0; + if ( (agent = jstr(json,"agent")) == 0 ) + agent = "bitcoinrpc"; + if ( (method= jstr(json,"method")) == 0 ) + { + printf("no method in request.(%s)\n",jprint(json,0)); + return(clonestr("{\"error\":\"no method\"}")); + } + if ( strcmp(method,"login") == 0 || strcmp(method,"logout") == 0 ) + return(clonestr("{\"error\":\"login and logout are internal only functions\"}")); + if ( remoteaddr == 0 ) + { + if ( jobj(json,"timestamp") != 0 ) + jdelete(json,"timestamp"); + timestamp = (uint32_t)time(NULL); + jaddnum(json,"timestamp",timestamp); + } + if ( (tag= j64bits(json,"tag")) == 0 ) + { + OS_randombytes((uint8_t *)&tag,sizeof(tag)); + jadd64bits(json,"tag",tag); + } + if ( (retstr= SuperNET_processJSON(myinfo,json,remoteaddr,port)) == 0 ) + printf("null retstr from SuperNET_JSON\n"); + if ( jsonstr != 0 ) + free(jsonstr); + if ( autologin != 0 ) + SuperNET_logout(myinfo,0,json,remoteaddr); + return(retstr); +} + void iguana_exit() { - int32_t i,j,iter; char *stopstr = SUPERNET_STOPSTR; + int32_t j,iter; struct iguana_info *coin,*tmp; printf("start EXIT\n"); for (iter=0; iter<3; iter++) { - for (i=0; ipeers != 0 ) { - switch ( iter ) + for (j=0; jpeers.active[j].usock >= 0 && Coins[i]->peers.active[j].supernet != 0 ) - iguana_send_supernet(Coins[i],&Coins[i]->peers.active[j],stopstr,0); - break; - case 1: Coins[i]->peers.active[j].dead = (uint32_t)time(NULL); break; - case 2: - if ( Coins[i]->peers.active[j].usock >= 0 ) - closesocket(Coins[i]->peers.active[j].usock); - break; + switch ( iter ) + { + case 1: coin->peers->active[j].dead = (uint32_t)time(NULL); break; + case 2: + if ( coin->peers->active[j].usock >= 0 ) + closesocket(coin->peers->active[j].usock); + break; + } } } } + //portable_mutex_unlock(&Allcoins_mutex); } - sleep(5); + sleep(3); } printf("sockets closed, now EXIT\n"); exit(0); @@ -410,743 +405,137 @@ rm BTC.xz; mksquashfs DB/BTC BTC.xz -comp xz -b 1048576 -comp xz -Xdict-size 102 https://github.com/vasi/squashfuse */ - void mainloop(struct supernet_info *myinfo) { - int32_t i,j,n,flag,isRT,numpeers; struct iguana_info *coin; struct iguana_bundle *bp; + struct iguana_info *coin,*tmp; int32_t i,counter=0,depth; portable_mutex_t *stack[IGUANA_MAXCOINS]; + double lastmilli = 0; sleep(3); printf("mainloop\n"); while ( 1 ) { //printf("main iteration\n"); - if ( myinfo->expiration != 0 && time(NULL) > myinfo->expiration ) - iguana_walletlock(myinfo,0); - flag = 0; - isRT = 1; - numpeers = 0; if ( 1 ) { - for (i=0; icurrent != 0 ) + if ( OS_milliseconds() > lastmilli+100 ) + { + //fprintf(stderr,"."); + counter++; + coin = 0; + depth = 0; + if ( 0 ) { - if ( coin->active != 0 && coin->started != 0 ) + HASH_ITER(hh,myinfo->allcoins,coin,tmp) { - isRT *= coin->isRT; - numpeers += coin->peers.numranked; - if ( time(NULL) > coin->startutc+10 && coin->spendvectorsaved == 0 && coin->blocks.hwmchain.height/coin->chain->bundlesize >= (coin->longestchain-coin->minconfirms)/coin->chain->bundlesize ) - { - n = coin->bundlescount-1; - if ( iguana_emitfinished(coin,1) >= n ) - { - if ( coin->PREFETCHLAG >= 0 && coin->fastfind == 0 ) - { - for (j=0; jbundles[j]->ramchain); - sleep(3); - } - if ( iguana_validated(coin) < n || iguana_utxofinished(coin) < n || iguana_balancefinished(coin) < n ) - { - coin->spendvectorsaved = 1; - printf("update volatile data, need.%d vs utxo.%d balances.%d validated.%d\n",n,iguana_utxofinished(coin),iguana_balancefinished(coin),iguana_validated(coin)); - } - else - { - coin->spendvectorsaved = (uint32_t)time(NULL); - //printf("already done UTXOGEN (%d %d) (%d %d)\n",iguana_utxofinished(coin),n,iguana_balancefinished(coin),n); - } - } //else printf("only emit.%d vs %d\n",iguana_emitfinished(coin),n); - } - if ( (bp= coin->current) != 0 && coin->stucktime != 0 && coin->isRT == 0 && coin->RTheight == 0 && (time(NULL) - coin->stucktime) > coin->MAXSTUCKTIME ) - { - if ( 0 ) - { - printf("%s is stuck too long, restarting due to %d\n",coin->symbol,bp->hdrsi); - if ( coin->started != 0 ) - { - iguana_coinpurge(coin); - sleep(3); - while ( coin->started == 0 ) - { - printf("wait for coin to reactivate\n"); - sleep(1); - } - sleep(3); - } - } - } - if ( 0 && flag != 0 ) - printf("call RT update busy.%d\n",coin->RTramchain_busy); + portable_mutex_lock(&coin->allcoins_mutex); + stack[depth++] = &coin->allcoins_mutex; } } - } - pangea_queues(SuperNET_MYINFO(0)); - if ( flag == 0 ) - usleep(10000 + isRT*100000 + (numpeers == 0)*1000000); - //iguana_jsonQ(); // cant do this here safely, need to send to coin specific queue - } -} - -int32_t calcmofn(uint8_t *allshares,uint8_t *myshares[],uint8_t *sharenrs,int32_t M,uint8_t *data,int32_t datasize,int32_t N) -{ - int32_t j; - calc_shares(allshares,(void *)data,datasize,datasize,M,N,sharenrs); - for (j=0; j 2006,2015 - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - */ - -//#include "config.h" -//#include "libgfshare.h" -//#include "libgfshare_tables.h" - -#ifndef LIBGFSHARE_H -#define LIBGFSHARE_H - - -typedef struct _gfshare_ctx gfshare_ctx; - -typedef void (*gfshare_rand_func_t)(uint8_t*, unsigned int); - -/* This will, use random(). It's not very good so you should not use it unless - * you must. If you can't be bothered to write your own, be sure to srandom() - * before you use any of the gfshare_ctx_enc_* functions - */ -extern const gfshare_rand_func_t gfshare_bad_idea_but_fill_rand_using_random; -/* This must be filled out before running any of the gfshare_ctx_enc_* calls - * or bad things will happen since it is initialised to NULL be default. - * You should fill this with a routine which uses urandom or similar ideally. - * If you cannot do that on your platform, you can use the function provided - * which does random() calls, but I recommend against it unless you must. - */ -extern gfshare_rand_func_t gfshare_fill_rand; - -/* ------------------------------------------------------[ Preparation ]---- */ - -/* Initialise a gfshare context for producing shares */ -gfshare_ctx* gfshare_ctx_init_enc(uint8_t* /* sharenrs */,unsigned int /* sharecount */, uint8_t /* threshold */,unsigned int /* size */); - -/* Initialise a gfshare context for recombining shares */ -gfshare_ctx* gfshare_ctx_init_dec(uint8_t* /* sharenrs */,unsigned int /* sharecount */,unsigned int /* size */); - -/* Free a share context's memory. */ -void gfshare_ctx_free(gfshare_ctx* /* ctx */); - -/* --------------------------------------------------------[ Splitting ]---- */ - -/* Provide a secret to the encoder. (this re-scrambles the coefficients) */ -void gfshare_ctx_enc_setsecret(gfshare_ctx* /* ctx */,uint8_t* /* secret */); - -/* Extract a share from the context. - * 'share' must be preallocated and at least 'size' bytes long. - * 'sharenr' is the index into the 'sharenrs' array of the share you want. - */ -void gfshare_ctx_enc_getshare(gfshare_ctx* /* ctx */,uint8_t /* sharenr */,uint8_t* /* share */); - -/* ----------------------------------------------------[ Recombination ]---- */ - -/* Inform a recombination context of a change in share indexes */ -void gfshare_ctx_dec_newshares(gfshare_ctx* /* ctx */, uint8_t* /* sharenrs */); - -/* Provide a share context with one of the shares. - * The 'sharenr' is the index into the 'sharenrs' array - */ -void gfshare_ctx_dec_giveshare(gfshare_ctx* /* ctx */,uint8_t /* sharenr */,uint8_t* /* share */); - -/* Extract the secret by interpolation of the shares. - * secretbuf must be allocated and at least 'size' bytes long - */ -void gfshare_ctx_dec_extract(gfshare_ctx* /* ctx */,uint8_t* /* secretbuf */); - -#endif /* LIBGFSHARE_H */ - - -#include -#include -#include - -#define XMALLOC malloc -#define XFREE free - -struct _gfshare_ctx { - unsigned int sharecount; - unsigned int threshold; - unsigned int size; - uint8_t* sharenrs; - uint8_t* buffer; - unsigned int buffersize; -}; - -static void _gfshare_fill_rand_using_random( uint8_t* buffer,unsigned int count ) -{ - OS_randombytes(buffer,count); - /*unsigned int i; - for( i = 0; i < count; ++i ) - buffer[i] = (random() & 0xff00) >> 8; apparently the bottom 8 aren't - * very random but the middles ones - * are - */ -} -const gfshare_rand_func_t gfshare_bad_idea_but_fill_rand_using_random = (void *)_gfshare_fill_rand_using_random; -gfshare_rand_func_t gfshare_fill_rand = NULL; - -/* ------------------------------------------------------[ Preparation ]---- */ - -static gfshare_ctx * _gfshare_ctx_init_core( uint8_t *sharenrs,unsigned int sharecount,uint8_t threshold,unsigned int size ) -{ - gfshare_ctx *ctx; - - ctx = XMALLOC( sizeof(struct _gfshare_ctx) ); - if( ctx == NULL ) - return NULL; /* errno should still be set from XMALLOC() */ - - ctx->sharecount = sharecount; - ctx->threshold = threshold; - ctx->size = size; - ctx->sharenrs = XMALLOC( sharecount ); - - if( ctx->sharenrs == NULL ) { - int saved_errno = errno; - XFREE( ctx ); - errno = saved_errno; - return NULL; - } - - memcpy( ctx->sharenrs, sharenrs, sharecount ); - ctx->buffersize = threshold * size; - ctx->buffer = XMALLOC( ctx->buffersize ); - - if( ctx->buffer == NULL ) { - int saved_errno = errno; - XFREE( ctx->sharenrs ); - XFREE( ctx ); - errno = saved_errno; - return NULL; - } - - return ctx; -} - -/* Initialise a gfshare context for producing shares */ -gfshare_ctx * gfshare_ctx_init_enc( uint8_t* sharenrs,unsigned int sharecount,uint8_t threshold,unsigned int size ) -{ - unsigned int i; - - for (i = 0; i < sharecount; i++) { - if (sharenrs[i] == 0) { - /* can't have x[i] = 0 - that would just be a copy of the secret, in - * theory (in fact, due to the way we use exp/log for multiplication and - * treat log(0) as 0, it ends up as a copy of x[i] = 1) */ - errno = EINVAL; - return NULL; - } - } - - return _gfshare_ctx_init_core( sharenrs, sharecount, threshold, size ); -} - -/* Initialise a gfshare context for recombining shares */ -gfshare_ctx* gfshare_ctx_init_dec( uint8_t* sharenrs,unsigned int sharecount,unsigned int size ) -{ - gfshare_ctx *ctx = _gfshare_ctx_init_core( sharenrs, sharecount, sharecount, size ); - - if( ctx != NULL ) - ctx->threshold = 0; - - return ctx; -} - -/* Free a share context's memory. */ -void gfshare_ctx_free( gfshare_ctx* ctx ) -{ - gfshare_fill_rand( ctx->buffer, ctx->buffersize ); - gfshare_fill_rand( ctx->sharenrs, ctx->sharecount ); - XFREE( ctx->sharenrs ); - XFREE( ctx->buffer ); - gfshare_fill_rand( (uint8_t*)ctx, sizeof(struct _gfshare_ctx) ); - XFREE( ctx ); -} - -/* --------------------------------------------------------[ Splitting ]---- */ - -/* Provide a secret to the encoder. (this re-scrambles the coefficients) */ -void gfshare_ctx_enc_setsecret( gfshare_ctx* ctx,uint8_t* secret) -{ - memcpy( ctx->buffer + ((ctx->threshold-1) * ctx->size), - secret, - ctx->size ); - gfshare_fill_rand( ctx->buffer, (ctx->threshold-1) * ctx->size ); -} - -/* Extract a share from the context. - * 'share' must be preallocated and at least 'size' bytes long. - * 'sharenr' is the index into the 'sharenrs' array of the share you want. - */ -void gfshare_ctx_enc_getshare( gfshare_ctx* ctx,uint8_t sharenr,uint8_t* share) -{ - unsigned int pos, coefficient; - unsigned int ilog = logs[ctx->sharenrs[sharenr]]; - uint8_t *coefficient_ptr = ctx->buffer; - uint8_t *share_ptr; - for( pos = 0; pos < ctx->size; ++pos ) - share[pos] = *(coefficient_ptr++); - for( coefficient = 1; coefficient < ctx->threshold; ++coefficient ) { - share_ptr = share; - for( pos = 0; pos < ctx->size; ++pos ) { - uint8_t share_byte = *share_ptr; - if( share_byte ) - share_byte = exps[ilog + logs[share_byte]]; - *share_ptr++ = share_byte ^ *coefficient_ptr++; - } - } -} - -/* ----------------------------------------------------[ Recombination ]---- */ - -/* Inform a recombination context of a change in share indexes */ -void gfshare_ctx_dec_newshares( gfshare_ctx* ctx,uint8_t* sharenrs) -{ - memcpy( ctx->sharenrs, sharenrs, ctx->sharecount ); -} - -/* Provide a share context with one of the shares. - * The 'sharenr' is the index into the 'sharenrs' array - */ -void gfshare_ctx_dec_giveshare( gfshare_ctx* ctx,uint8_t sharenr,uint8_t* share ) -{ - memcpy( ctx->buffer + (sharenr * ctx->size), share, ctx->size ); -} - -/* Extract the secret by interpolation of the shares. - * secretbuf must be allocated and at least 'size' bytes long - */ -void gfshare_ctx_dec_extract( gfshare_ctx* ctx,uint8_t* secretbuf ) -{ - unsigned int i, j; - uint8_t *secret_ptr, *share_ptr, sharei,sharej; - - for( i = 0; i < ctx->size; ++i ) - secretbuf[i] = 0; - - for( i = 0; i < ctx->sharecount; ++i ) - { - // Compute L(i) as per Lagrange Interpolation - unsigned Li_top = 0, Li_bottom = 0; - if ( (sharei= ctx->sharenrs[i]) != 0 ) - { - for ( j = 0; j < ctx->sharecount; ++j ) - { - if ( i != j && sharei != (sharej= ctx->sharenrs[j]) ) + //printf("check jsonQ\n"); + while ( iguana_jsonQ() != 0 ) + ; + if ( 0 ) { - if ( sharej == 0 ) - continue; // skip empty share */ - Li_top += logs[sharej]; - if ( Li_top >= 0xff ) - Li_top -= 0xff; - Li_bottom += logs[sharei ^ sharej]; - if ( Li_bottom >= 0xff ) - Li_bottom -= 0xff; + if ( depth > 0 ) + { + for (i=depth-1; i>=0; i--) + portable_mutex_unlock(stack[i]); + } } + lastmilli = OS_milliseconds(); } - if ( Li_bottom > Li_top ) - Li_top += 0xff; - Li_top -= Li_bottom; // Li_top is now log(L(i)) - secret_ptr = secretbuf, share_ptr = ctx->buffer + (ctx->size * i); - for (j=0; jsize; j++) - { - if ( *share_ptr != 0 ) - *secret_ptr ^= exps[Li_top + logs[*share_ptr]]; - share_ptr++, secret_ptr++; - } + usleep(30000); } + //pangea_queues(SuperNET_MYINFO(0)); + //if ( flag == 0 ) + // usleep(100000 + isRT*100000 + (numpeers == 0)*1000000); + //iguana_jsonQ(); // cant do this here safely, need to send to coin specific queue } } -void calc_share(uint8_t *buffer,int32_t size,int32_t M,uint32_t ilog,uint8_t *share) -{ - uint32_t pos,coefficient;//,ilog = ctx_logs[ctx->sharenrs[sharenr]]; - //uint8_t *coefficient_ptr = buffer; - uint8_t *share_ptr,share_byte; - for (pos=0; pos -int32_t test(int32_t M,int32_t N,int32_t datasize) +void iguana_accounts(char *keytype) { - int ok = 1, i; - uint8_t * secret = malloc(datasize); - uint8_t *shares[255]; - uint8_t *recomb = malloc(datasize); - uint8_t sharenrs[255],newsharenrs[255];// = (uint8_t *)strdup("0124z89abehtr"); - gfshare_ctx *G; - gfshare_fill_rand = gfshare_bad_idea_but_fill_rand_using_random; - for (i=0; i> 8; - /* Stage 2, split it N ways with a threshold of M */ - G = gfshare_ctx_init_enc( sharenrs, N, M, datasize ); - gfshare_ctx_enc_setsecret( G, secret ); - for (i=0; i n || n >= 0xff ) // reserve 255 for illegal sharei - { - printf("illegal M.%d of N.%d\n",m,n); - return(-1); - } - randvals = calloc(1,65536); - OS_randombytes(randvals,65536); - if ( orig == 0 && n == m ) - { - memset(sharenrs,0,n); - for (i=0; i<255; i++) - valid[i] = (i + 1); - remains = orign = 255; - for (i=0; i %s",key,fname); + if ( system(cmd) != 0 ) + printf("Error issuing.(%s)\n",cmd); + if ( (str2= OS_filestr(&filesize,fname)) != 0 ) + { + if ( (json2= cJSON_Parse(str2)) != 0 ) + { + if ( (postingkey= jstr(json2,"result")) != 0 ) + fprintf(postingkeys,"{ \"%s\", \"%s\" },",name,postingkey); + else printf("no result in (%s)\n",jprint(json2,0)); + free_json(json2); + } else printf("couldnt parse (%s)\n",str2); + free(str2); + } else printf("couldnt load (%s)\n",fname); + } + } + } + } + fprintf(postingkeys,"\n};\n"); + fclose(postingkeys); } + free_json(json); } + free(str); } - return(0); -} - -/* Construct and write out the tables for the gfshare code */ - -int maingen(int argc, char** argv) -{ - uint8_t logs[256]; - uint8_t exps[255]; - unsigned int x; - unsigned int i; - - x = 1; - for( i = 0; i < 255; ++i ) { - exps[i] = x; - logs[x] = i; - x <<= 1; - if( x & 0x100 ) - x ^= 0x11d; /* Unset the 8th bit and mix in 0x1d */ - } - logs[0] = 0; /* can't log(0) so just set it neatly to 0 */ - - /* The above generation algorithm clearly demonstrates that - * logs[exps[i]] == i for 0 <= i <= 254 - * exps[logs[i]] == i for 1 <= i <= 255 - */ - - /* Spew out the tables */ - - fprintf(stdout, "\ - /*\n\ - * This file is autogenerated by gfshare_maketable.\n\ - */\n\ - \n\ - static uint8_t logs[256] = {\n "); - for( i = 0; i < 256; ++i ) { - fprintf(stdout, "0x%02x", logs[i]); - if( i == 255 ) - fprintf(stdout, " };\n"); - else if( (i % 8) == 7 ) - fprintf(stdout, ",\n "); - else - fprintf(stdout, ", "); - } - - /* The exp table we output from 0 to 509 because that way when we - * do the lagrange interpolation we don't have to be quite so strict - * with staying inside the field which makes it quicker - */ - - fprintf(stdout, "\ - \n\ - static uint8_t exps[510] = {\n "); - for( i = 0; i < 510; ++i ) { - fprintf(stdout, "0x%02x", exps[i % 255]); /* exps[255]==exps[0] */ - if( i == 509 ) - fprintf(stdout, " };\n"); - else if( (i % 8) == 7) - fprintf(stdout, ",\n "); - else - fprintf(stdout, ", "); - } - - return 0; } void iguana_appletests(struct supernet_info *myinfo) { char *str; - void ztest(); ztest(); //iguana_chaingenesis(1,1403138561,0x1e0fffff,8359109,bits256_conv("fd1751cc6963d88feca94c0d01da8883852647a37a0a67ce254d62dd8c9d5b2b")); // BTCD - //iguana_chaingenesis(1,1409839200,0x1e0fffff,64881664,bits256_conv("698a93a1cacd495a7a4fb3864ad8d06ed4421dedbc57f9aaad733ea53b1b5828")); // VPN - //char genesisblock[1024]; - //iguana_chaingenesis(genesisblock,"sha256",1,1317972665,0x1e0ffff0,2084524493,bits256_conv("97ddfbbae6be97fd6cdf3e7ca13232a3afff2353e29badfab7f73011edd4ced9")); // LTC + if ( 0 ) + { + char genesisblock[1024]; + //iguana_chaingenesis("VPN",0,bits256_conv("00000ac7d764e7119da60d3c832b1d4458da9bc9ef9d5dd0d91a15f690a46d99"),genesisblock,"scrypt",1,1409839200,0x1e0fffff,64881664,bits256_conv("698a93a1cacd495a7a4fb3864ad8d06ed4421dedbc57f9aaad733ea53b1b5828")); // VPN + + iguana_chaingenesis("LTC",0,0,0,bits256_conv("12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2"),genesisblock,"sha256",1,1317972665,0x1e0ffff0,2084524493,bits256_conv("97ddfbbae6be97fd6cdf3e7ca13232a3afff2353e29badfab7f73011edd4ced9")); // LTC + //char *Str = "01000000f615f7ce3b4fc6b8f61e8f89aedb1d0852507650533a9e3b10b9bbcc30639f279fcaa86746e1ef52d3edb3c4ad8259920d509bd073605c9bf1d59983752a6b06b817bb4ea78e011d012d59d4"; + // https://litecoin.info/Scrypt 0000000110c8357966576df46f3b802ca897deb7ad18b12f1c24ecff6386ebd9 + //uint8_t buf[1000]; bits256 shash,hash2; char str[65],str2[65]; + //decode_hex(buf,(int32_t)strlen(Str)>>1,Str); + //calc_scrypthash(shash.uints,buf); + //blockhash_sha256(&hash2,buf,80); + //printf("shash -> %s sha256x2 %s\n",bits256_str(str,shash),bits256_str(str2,hash2)); + getchar(); + } if ( 1 ) { - if ( 1 && (str= SuperNET_JSON(myinfo,cJSON_Parse("{\"RELAY\":1,\"VALIDATE\":1,\"prefetchlag\":-1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":64,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":4,\"poll\":1}"),0,myinfo->rpcport)) != 0 ) + /*int32_t i; ;bits256 hash2; uint8_t pubkey[33]; + double startmillis = OS_milliseconds(); + for (i=0; i<1000; i++) + hash2 = curve25519_shared(hash2,rand256(0)); + printf("curve25519 elapsed %.3f for %d iterations\n",OS_milliseconds() - startmillis,i); + startmillis = OS_milliseconds(); + bitcoin_pubkey33(myinfo->ctx,pubkey,hash2); + for (i=0; i<1000; i++) + bitcoin_sharedsecret(myinfo->ctx,hash2,pubkey,33); + printf("secp256k1 elapsed %.3f for %d iterations\n",OS_milliseconds() - startmillis,i); + getchar();**/ + if ( 1 && (str= SuperNET_JSON(myinfo,cJSON_Parse("{\"protover\":70002,\"RELAY\":1,\"VALIDATE\":1,\"portp2p\":14631,\"rpc\":14632,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":512,\"endpend\":512,\"services\":129,\"maxpeers\":8,\"newcoin\":\"BTCD\",\"active\":1,\"numhelpers\":1,\"poll\":100}"),0,myinfo->rpcport)) != 0 ) { free(str); - if ( 0 && (str= SuperNET_JSON(myinfo,cJSON_Parse("{\"userhome\":\"/Users/jimbolaptop/Library/Application Support\",\"agent\":\"iguana\",\"method\":\"addcoin\",\"services\":1024,\"maxpeers\":256,\"newcoin\":\"BTCD\",\"active\":1}"),0,myinfo->rpcport)) != 0 ) + if ( 1 && (str= SuperNET_JSON(myinfo,cJSON_Parse("{\"portp2p\":8333,\"RELAY\":0,\"VALIDATE\":0,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":1,\"endpend\":1,\"services\":128,\"maxpeers\":8,\"newcoin\":\"BTC\",\"active\":0,\"numhelpers\":1,\"poll\":100}"),0,myinfo->rpcport)) != 0 ) { free(str); if ( 0 && (str= SuperNET_JSON(myinfo,cJSON_Parse("{\"agent\":\"SuperNET\",\"method\":\"login\",\"handle\":\"alice\",\"password\":\"alice\",\"passphrase\":\"alice\"}"),0,myinfo->rpcport)) != 0 ) @@ -1161,17 +550,32 @@ void iguana_appletests(struct supernet_info *myinfo) } } -void iguana_commandline(struct supernet_info *myinfo,char *arg) +int32_t iguana_commandline(struct supernet_info *myinfo,char *arg) { - cJSON *argjson,*array; char *coinargs,*argstr,*str; int32_t i,n; long filesize = 0; + cJSON *argjson,*array; char *coinargs,*argstr=0,*str; int32_t i,n; long filesize = 0; if ( arg == 0 ) arg = "iguana.conf"; - if ( arg != 0 ) + else if ( (COMMANDLINE_ARGFILE= OS_filestr(&filesize,arg)) != 0 ) + { + if ( (argjson= cJSON_Parse(COMMANDLINE_ARGFILE)) == 0 ) + { + printf("couldnt parse %s: (%s) after initialized\n",arg,COMMANDLINE_ARGFILE); + free(COMMANDLINE_ARGFILE); + COMMANDLINE_ARGFILE = 0; + } + else + { + IGUANA_NUMHELPERS = juint(argjson,"numhelpers"); + free_json(argjson); + printf("Will run (%s) after initialized with %d threads\n",COMMANDLINE_ARGFILE,IGUANA_NUMHELPERS); + } + } + else if ( arg != 0 ) { if ( arg[0] == '{' || arg[0] == '[' ) argstr = arg; - else argstr = OS_filestr(&filesize,arg); - if ( (argjson= cJSON_Parse(argstr)) != 0 ) + //else argstr = OS_filestr(&filesize,arg); + if ( argstr != 0 && (argjson= cJSON_Parse(argstr)) != 0 ) { IGUANA_NUMHELPERS = juint(argjson,"numhelpers"); if ( (myinfo->rpcport= juint(argjson,"port")) == 0 ) @@ -1197,18 +601,36 @@ void iguana_commandline(struct supernet_info *myinfo,char *arg) free(str); } free_json(argjson); - } else printf("error parsing.(%s)\n",(char *)argstr); - if ( argstr != arg ) - free(argstr); + if ( 0 ) + { + uint32_t buf[81],c; + OS_randombytes((void *)buf,sizeof(buf)); + printf("("); + for (i=0; i<81; i++) + { + c = buf[i] % 27; + if ( c == 26 ) + c = '9'; + else c += 'a'; + printf("%c",c); + } + printf(") <- IOTA random passphrase\n"); + } + } //else printf("error parsing.(%s)\n",(char *)argstr); + //if ( argstr != arg ) + // free(argstr); } + return(COMMANDLINE_ARGFILE != 0); } void iguana_ensuredirs() { char dirname[512]; sprintf(dirname,"%s",GLOBAL_HELPDIR), OS_ensure_directory(dirname); + sprintf(dirname,"%s",GLOBAL_GENESISDIR), OS_ensure_directory(dirname); sprintf(dirname,"%s",GLOBAL_CONFSDIR), OS_ensure_directory(dirname); sprintf(dirname,"%s",GLOBAL_DBDIR), OS_ensure_directory(dirname); + sprintf(dirname,"%s/purgeable",GLOBAL_DBDIR), OS_ensure_directory(dirname); sprintf(dirname,"%s",GLOBAL_TMPDIR), OS_ensure_directory(dirname); sprintf(dirname,"%s",GLOBAL_VALIDATEDIR), OS_ensure_directory(dirname); sprintf(dirname,"%s/ECB",GLOBAL_DBDIR), OS_ensure_directory(dirname); @@ -1223,7 +645,7 @@ void iguana_Qinit() iguana_initQ(&finishedQ,"finishedQ"); iguana_initQ(&bundlesQ,"bundlesQ"); iguana_initQ(&emitQ,"emitQ"); - iguana_initQ(&TerminateQ,"TerminateQ"); + //iguana_initQ(&TerminateQ,"TerminateQ"); } void iguana_helpinit(struct supernet_info *myinfo) @@ -1269,16 +691,17 @@ void iguana_urlinit(struct supernet_info *myinfo,int32_t ismainnet,int32_t usess void iguana_launchdaemons(struct supernet_info *myinfo) { int32_t i; char *helperargs,helperstr[512]; - if ( IGUANA_NUMHELPERS == 0 ) + if ( IGUANA_NUMHELPERS == 0 )//|| COMMANDLINE_ARGFILE != 0 ) IGUANA_NUMHELPERS = 1; for (i=0; i bufsize ) + { + message = calloc(1,cipherlen); + *ptrp = (void *)message; + } + else message = buf; + origptr = cipher; + if ( bits256_nonz(srcpubkey) == 0 ) + { + memcpy(srcpubkey.bytes,cipher,sizeof(srcpubkey)); + char str[65]; printf("use attached pubkey.(%s)\n",bits256_str(str,srcpubkey)); + cipher += sizeof(srcpubkey); + cipherlen -= sizeof(srcpubkey); + } + nonce = cipher; + cipher += crypto_box_NONCEBYTES, cipherlen -= crypto_box_NONCEBYTES; + *msglenp = cipherlen - crypto_box_ZEROBYTES; + if ( (retptr= _SuperNET_decipher(nonce,cipher,message,cipherlen,srcpubkey,privkey)) == 0 ) + { + *msglenp = -1; + free(*ptrp); + } + return(retptr); +} + +uint8_t *SuperNET_ciphercalc(void **ptrp,int32_t *cipherlenp,bits256 *privkeyp,bits256 *destpubkeyp,uint8_t *data,int32_t datalen,uint8_t *space2,int32_t space2size) +{ + bits256 mypubkey; uint8_t *buf,*nonce,*cipher,*origptr,space[8192]; int32_t onetimeflag=0,allocsize; + *ptrp = 0; + allocsize = (datalen + crypto_box_NONCEBYTES + crypto_box_ZEROBYTES); + if ( bits256_nonz(*destpubkeyp) == 0 || memcmp(destpubkeyp->bytes,GENESIS_PUBKEY.bytes,sizeof(*destpubkeyp)) == 0 ) + { + *destpubkeyp = GENESIS_PUBKEY; + onetimeflag = 2; // prevent any possible leakage of privkey by encrypting to known destpub + } + if ( bits256_nonz(*privkeyp) == 0 ) + onetimeflag = 1; + if ( onetimeflag != 0 ) + { + crypto_box_keypair(mypubkey.bytes,privkeyp->bytes); + allocsize += sizeof(bits256); + } + if ( allocsize > sizeof(space) ) + buf = calloc(1,allocsize); + else buf = space; + if ( allocsize+sizeof(struct iguana_msghdr) > space2size ) + { + cipher = calloc(1,allocsize + sizeof(struct iguana_msghdr)); + *ptrp = (void *)cipher; + } else cipher = space2; + cipher = &cipher[sizeof(struct iguana_msghdr)]; + origptr = nonce = cipher; + if ( onetimeflag != 0 ) + { + memcpy(cipher,mypubkey.bytes,sizeof(mypubkey)); + nonce = &cipher[sizeof(mypubkey)]; + } + OS_randombytes(nonce,crypto_box_NONCEBYTES); + cipher = &nonce[crypto_box_NONCEBYTES]; + _SuperNET_cipher(nonce,cipher,(void *)data,datalen,*destpubkeyp,*privkeyp,buf); + if ( buf != space ) + free(buf); + *cipherlenp = allocsize; + return(origptr); +} + +cJSON *SuperNET_rosettajson(struct supernet_info *myinfo,bits256 privkey,int32_t showprivs) +{ + uint8_t rmd160[20],pub[33]; uint64_t nxt64bits; bits256 pubkey; + char str2[41],wifbuf[64],addr[64],str[128],coinwif[16]; cJSON *retjson; struct iguana_info *coin,*tmp; + pubkey = acct777_pubkey(privkey); + nxt64bits = acct777_nxt64bits(pubkey); + retjson = cJSON_CreateObject(); + jaddbits256(retjson,"pubkey",pubkey); + RS_encode(str,nxt64bits); + jaddstr(retjson,"RS",str); + jadd64bits(retjson,"NXT",nxt64bits); + bitcoin_pubkey33(0,pub,privkey); + init_hexbytes_noT(str,pub,33); + jaddstr(retjson,"btcpubkey",str); + calc_OP_HASH160(str2,rmd160,str); + jaddstr(retjson,"rmd160",str2); + HASH_ITER(hh,myinfo->allcoins,coin,tmp) + { + if ( coin != 0 && coin->symbol[0] != 0 ) + { + if ( bitcoin_address(addr,coin->chain->pubtype,pub,33) != 0 ) + { + jaddstr(retjson,coin->symbol,addr); + sprintf(coinwif,"%swif",coin->symbol); + if ( showprivs != 0 ) + { + bitcoin_priv2wif(wifbuf,privkey,coin->chain->wiftype); + jaddstr(retjson,coinwif,wifbuf); + } + } + } + } + /*if ( bitcoin_address(addr,0,pub,33) != 0 ) + { + jaddstr(retjson,"BTC",addr); + if ( showprivs != 0 ) + { + bitcoin_priv2wif(wifbuf,privkey,128); + jaddstr(retjson,"BTCwif",wifbuf); + } + } + if ( bitcoin_address(addr,60,pub,33) != 0 ) + { + jaddstr(retjson,"BTCD",addr); + if ( showprivs != 0 ) + { + bitcoin_priv2wif(wifbuf,privkey,188); + jaddstr(retjson,"BTCDwif",wifbuf); + } + }*/ + if ( showprivs != 0 ) + jaddbits256(retjson,"privkey",privkey); + return(retjson); +} + +cJSON *SuperNET_peerarray(struct iguana_info *coin,int32_t max,int32_t supernetflag) +{ + int32_t i,r,j,n = 0; struct iguana_peer *addr; cJSON *array = cJSON_CreateArray(); + if ( coin->peers == 0 ) + return(array); + r = rand(); + for (j=0; jpeers->active[i]; + if ( addr->usock >= 0 && supernetflag == (addr->supernet != 0) ) + { + jaddistr(array,addr->ipaddr); + if ( ++n >= max ) + break; + } + } + if ( n == 0 ) + { + free_json(array); + return(0); + } + return(array); +} + +int32_t SuperNET_coinpeers(struct iguana_info *coin,cJSON *SNjson,cJSON *rawjson,int32_t max) +{ + cJSON *array,*item; + if ( (array= SuperNET_peerarray(coin,max,1)) != 0 ) + { + max -= cJSON_GetArraySize(array); + item = cJSON_CreateObject(); + jaddstr(item,"coin",coin->symbol); + jadd(item,"peers",array); + jaddi(SNjson,item); + } + if ( max > 0 && (array= SuperNET_peerarray(coin,max,0)) != 0 ) + { + max -= cJSON_GetArraySize(array); + item = cJSON_CreateObject(); + jaddstr(item,"coin",coin->symbol); + jadd(item,"peers",array); + jaddi(rawjson,item); + } + return(max); +} + +void SuperNET_remotepeer(struct supernet_info *myinfo,struct iguana_info *coin,char *symbol,char *ipaddr,int32_t supernetflag) +{ + uint64_t ipbits; struct iguana_peer *addr; + ipbits = calc_ipbits(ipaddr); + printf("got %s remotepeer.(%s) supernet.%d\n",symbol,ipaddr,supernetflag); + if ( supernetflag != 0 && (uint32_t)myinfo->myaddr.selfipbits != (uint32_t)ipbits ) + { + if ( (addr= iguana_peerslot(coin,ipbits,0)) != 0 ) + { + printf("launch startconnection to supernet peer.(%s)\n",ipaddr); + iguana_launch(coin,"connection",iguana_startconnection,addr,IGUANA_CONNTHREAD); + return; + } + } + iguana_possible_peer(coin,ipaddr); +} + +void SuperNET_parsepeers(struct supernet_info *myinfo,cJSON *array,int32_t n,int32_t supernetflag) +{ + int32_t i,j,m; cJSON *coinarray,*item; char *symbol,*ipaddr; struct iguana_info *ptr; + if ( array != 0 && n > 0 ) + { + for (i=0; ichain->pubtype,rmdbuf,20); + bitcoin_address(p2shaddr,coin->chain->p2shtype,rmdbuf,20); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"address",coinaddr); + jaddstr(retjson,"p2sh",p2shaddr); + } + return(jprint(retjson,1)); +} + +HASH_AND_INT(SuperNET,priv2pub,privkey,addrtype) +{ + cJSON *retjson; bits256 pub; uint8_t pubkey[33]; char coinaddr[64],pubkeystr[67]; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + retjson = cJSON_CreateObject(); + crypto_box_priv2pub(pub.bytes,privkey.bytes); + jaddbits256(retjson,"curve25519",pub); + pub = bitcoin_pubkey33(myinfo->ctx,pubkey,privkey); + init_hexbytes_noT(pubkeystr,pubkey,33); + jaddstr(retjson,"secp256k1",pubkeystr); + bitcoin_address(coinaddr,addrtype,pubkey,33); + jaddstr(retjson,"result",coinaddr); + return(jprint(retjson,1)); +} + +ZERO_ARGS(SuperNET,keypair) +{ + cJSON *retjson; bits256 pubkey,privkey; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + retjson = cJSON_CreateObject(); + crypto_box_keypair(pubkey.bytes,privkey.bytes); + jaddstr(retjson,"result","generated keypair"); + jaddbits256(retjson,"privkey",privkey); + jaddbits256(retjson,"pubkey",pubkey); + return(jprint(retjson,1)); +} + +TWOHASHES_AND_STRING(SuperNET,decipher,privkey,srcpubkey,cipherstr) +{ + int32_t cipherlen=0,msglen; char *retstr; cJSON *retjson; void *ptr = 0; uint8_t *cipher,*message,space[8192]; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( cipherstr != 0 ) + cipherlen = (int32_t)strlen(cipherstr) >> 1; + if ( cipherlen < crypto_box_NONCEBYTES ) + return(clonestr("{\"error\":\"cipher is too short\"}")); + cipher = calloc(1,cipherlen); + decode_hex(cipher,cipherlen,cipherstr); + if ( (message= SuperNET_deciphercalc(&ptr,&msglen,privkey,srcpubkey,cipher,cipherlen,space,sizeof(space))) != 0 ) + { + message[msglen] = 0; + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","deciphered message"); + jaddstr(retjson,"message",(char *)message); + retstr = jprint(retjson,1); + if ( ptr != 0 ) + free(ptr); + } else retstr = clonestr("{\"error\":\"couldnt decipher message\"}"); + return(retstr); +} + +TWOHASHES_AND_STRING(SuperNET,cipher,privkey,destpubkey,message) +{ + cJSON *retjson; char *retstr,*hexstr,space[8129]; uint8_t space2[8129]; + uint8_t *cipher; int32_t cipherlen,onetimeflag; bits256 origprivkey; void *ptr = 0; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( (cipher= SuperNET_ciphercalc(&ptr,&cipherlen,&privkey,&destpubkey,(uint8_t *)message,(int32_t)strlen(message)+1,space2,sizeof(space2))) != 0 ) + { + if ( cipherlen > sizeof(space)/2 ) + hexstr = calloc(1,(cipherlen<<1)+1); + else hexstr = (void *)space; + init_hexbytes_noT(hexstr,cipher,cipherlen); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result",hexstr); + onetimeflag = memcmp(origprivkey.bytes,privkey.bytes,sizeof(privkey)); + if ( onetimeflag != 0 ) + { + //jaddbits256(retjson,"onetime_privkey",privkey); + jaddbits256(retjson,"onetime_pubkey",destpubkey); + if ( onetimeflag == 2 ) + jaddstr(retjson,"warning","onetime keypair was used to broadcast"); + } + retstr = jprint(retjson,1); + if ( hexstr != (void *)space ) + free(hexstr); + if ( ptr != 0 ) + free(ptr); + return(retstr); + } + printf("error encrypting message.(%s)\n",message); + return(clonestr("{\"error\":\"cant encrypt message\"}")); +} + +bits256 SuperNET_pindecipher(IGUANA_ARGS,char *pin,char *privcipher) +{ + cJSON *testjson; char *mstr,*cstr; bits256 privkey,pinpriv,pinpub; + conv_NXTpassword(pinpriv.bytes,pinpub.bytes,(uint8_t *)pin,(int32_t)strlen(pin)); + privkey = GENESIS_PRIVKEY; + if ( (cstr= SuperNET_decipher(IGUANA_CALLARGS,pinpriv,pinpub,privcipher)) != 0 ) + { + if ( (testjson= cJSON_Parse(cstr)) != 0 ) + { + if ( (mstr= jstr(testjson,"message")) != 0 && strlen(mstr) == sizeof(bits256)*2 ) + { + decode_hex(privkey.bytes,sizeof(privkey),mstr); + } else printf("error cant find message privcipher\n"); + free_json(testjson); + } else printf("Error decipher.(%s)\n",cstr); + free(cstr); + } else printf("null return from deciphering privcipher\n"); + return(privkey); +} + +THREE_STRINGS(SuperNET,rosetta,passphrase,pin,showprivkey) +{ + uint8_t flag = 0; uint64_t nxt64bits; bits256 check,privkey,pubkey,pinpriv,pinpub; + char str[128],privcipher[512],*privcipherstr,*cstr; cJSON *retjson; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + nxt64bits = conv_NXTpassword(privkey.bytes,pubkey.bytes,(uint8_t *)passphrase,(int32_t)strlen(passphrase)); + if ( showprivkey != 0 && strcmp(showprivkey,"yes") == 0 ) + flag = 1; + privcipher[0] = 0; + conv_NXTpassword(pinpriv.bytes,pinpub.bytes,(uint8_t *)pin,(int32_t)strlen(pin)); + if ( (cstr= SuperNET_cipher(IGUANA_CALLARGS,pinpriv,pinpub,bits256_str(str,privkey))) != 0 ) + { + if ( (retjson= cJSON_Parse(cstr)) != 0 ) + { + if ( (privcipherstr= jstr(retjson,"result")) != 0 ) + strcpy(privcipher,privcipherstr); + free_json(retjson); + } else printf("error parsing cipher retstr.(%s)\n",cstr); + free(cstr); + } else printf("error SuperNET_cipher null return\n"); + retjson = SuperNET_rosettajson(myinfo,privkey,flag); + jaddstr(retjson,"privcipher",privcipher); + check = SuperNET_pindecipher(IGUANA_CALLARGS,pin,privcipher); + if ( memcmp(check.bytes,privkey.bytes,sizeof(check)) != 0 ) + { + jaddbits256(retjson,"deciphered",check); + jaddstr(retjson,"error","cant recreate privkey from (pin + privcipher)"); + } + else if ( flag != 0 ) + jaddbits256(retjson,"deciphered",check); + if ( jobj(retjson,"error") == 0 ) + jaddstr(retjson,"result","use pin and privcipher to access wallet"); + return(jprint(retjson,1)); +} + +STRING_ARG(SuperNET,broadcastcipher,message) +{ + bits256 zero; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + memset(zero.bytes,0,sizeof(zero)); + return(SuperNET_cipher(IGUANA_CALLARGS,zero,zero,message)); +} + +STRING_ARG(SuperNET,broadcastdecipher,message) +{ + bits256 zero; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + memset(zero.bytes,0,sizeof(zero)); + return(SuperNET_decipher(IGUANA_CALLARGS,zero,zero,message)); +} + +HASH_AND_STRING(SuperNET,multicastcipher,pubkey,message) +{ + bits256 zero; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + memset(zero.bytes,0,sizeof(zero)); + return(SuperNET_cipher(IGUANA_CALLARGS,zero,pubkey,message)); +} + +HASH_AND_STRING(SuperNET,multicastdecipher,privkey,cipherstr) +{ + bits256 zero; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + memset(zero.bytes,0,sizeof(zero)); + return(SuperNET_decipher(IGUANA_CALLARGS,privkey,zero,cipherstr)); +} + +ZERO_ARGS(SuperNET,stop) +{ + if ( remoteaddr == 0 || strncmp(remoteaddr,"127.0.0.1",strlen("127.0.0.1")) == 0 ) + { + iguana_exit(); + return(clonestr("{\"result\":\"exit started\"}")); + } else return(clonestr("{\"error\":\"cant do a remote stop of this node\"}")); +} + +TWO_ARRAYS(SuperNET,mypeers,supernet,rawpeers) +{ + SuperNET_parsepeers(myinfo,supernet,cJSON_GetArraySize(supernet),1); + SuperNET_parsepeers(myinfo,rawpeers,cJSON_GetArraySize(rawpeers),0); + return(clonestr("{\"result\":\"peers parsed\"}")); +} + +STRING_ARG(SuperNET,getpeers,activecoin) +{ + int32_t max = 64; struct iguana_info *tmp; cJSON *SNjson,*rawjson,*retjson = cJSON_CreateObject(); + SNjson = cJSON_CreateArray(); + rawjson = cJSON_CreateArray(); + if ( coin != 0 ) + max = SuperNET_coinpeers(coin,SNjson,rawjson,max); + else + { + //portable_mutex_lock(&myinfo->allcoins_mutex); + HASH_ITER(hh,myinfo->allcoins,coin,tmp) + { + max = SuperNET_coinpeers(coin,SNjson,rawjson,max); + } + //portable_mutex_unlock(&myinfo->allcoins_mutex); + } + if ( max != 64 ) + { + jaddstr(retjson,"agent","SuperNET"); + jaddstr(retjson,"method","mypeers"); + jadd(retjson,"supernet",SNjson); + jadd(retjson,"rawpeers",rawjson); + } + else + { + jaddstr(retjson,"error","no peers"); + free_json(SNjson); + free_json(rawjson); + } + return(jprint(retjson,1)); +} + +/*TWOSTRINGS_AND_TWOHASHES_AND_TWOINTS(SuperNET,DHT,hexmsg,destip,categoryhash,subhash,maxdelay,broadcast) + { + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"cant remote DHT\"}")); + else if ( hexmsg == 0 || is_hexstr(hexmsg,(int32_t)strlen(hexmsg)) <= 0 ) + return(clonestr("{\"error\":\"hexmsg missing or not in hex\"}")); + return(SuperNET_DHTencode(myinfo,destip,categoryhash,subhash,hexmsg,maxdelay,broadcast,juint(json,"plaintext")!=0)); + }*/ + +HASH_AND_STRING(SuperNET,saveconf,wallethash,confjsonstr) +{ + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + return(clonestr("{\"result\":\"saveconf here\"}")); +} + +HASH_ARRAY_STRING(SuperNET,layer,mypriv,otherpubs,str) +{ + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + return(clonestr("{\"result\":\"layer encrypt here\"}")); +} + +/*TWO_STRINGS(SuperNET,categoryhashes,category,subcategory) +{ + bits256 categoryhash,subhash; cJSON *retjson = cJSON_CreateObject(); + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + categoryhash = calc_categoryhashes(&subhash,category,subcategory); + jaddstr(retjson,"result","category hashes calculated"); + jaddbits256(retjson,"categoryhash",categoryhash); + jaddbits256(retjson,"subhash",subhash); + return(jprint(retjson,1)); +} + +TWO_STRINGS(SuperNET,subscribe,category,subcategory) +{ + bits256 categoryhash,subhash; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + categoryhash = calc_categoryhashes(&subhash,category,subcategory); + if ( category_subscribe(myinfo,categoryhash,subhash) != 0 ) + return(clonestr("{\"result\":\"subscribed\"}")); + else return(clonestr("{\"error\":\"couldnt subscribe\"}")); +} + +TWO_STRINGS(SuperNET,gethexmsg,category,subcategory) +{ + bits256 categoryhash,subhash; struct category_msg *m; char *hexstr; cJSON *retjson; struct private_chain *cat; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + categoryhash = calc_categoryhashes(&subhash,category,subcategory); + if ( (m= category_gethexmsg(myinfo,&cat,categoryhash,subhash)) != 0 ) + { + hexstr = calloc(1,m->len*2+1); + init_hexbytes_noT(hexstr,m->msg,m->len); + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result",hexstr); + free(hexstr); + return(jprint(retjson,1)); + } else return(clonestr("{\"result\":\"no message\"}")); +} + +THREE_STRINGS(SuperNET,posthexmsg,category,subcategory,hexmsg) +{ + bits256 categoryhash,subhash; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + categoryhash = calc_categoryhashes(&subhash,category,subcategory); + category_posthexmsg(myinfo,categoryhash,subhash,hexmsg,tai_now(),remoteaddr); + return(clonestr("{\"result\":\"posted message\"}")); +} + +THREE_STRINGS(SuperNET,announce,category,subcategory,message) +{ + bits256 categoryhash,subhash; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + categoryhash = calc_categoryhashes(&subhash,category,subcategory); + return(SuperNET_categorymulticast(myinfo,0,categoryhash,subhash,message,juint(json,"maxdelay"),juint(json,"broadcast"),juint(json,"plaintext"),json,remoteaddr)); +} + +THREE_STRINGS(SuperNET,survey,category,subcategory,message) +{ + bits256 categoryhash,subhash; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + categoryhash = calc_categoryhashes(&subhash,category,subcategory); + return(SuperNET_categorymulticast(myinfo,1,categoryhash,subhash,message,juint(json,"maxdelay"),juint(json,"broadcast"),juint(json,"plaintext"),json,remoteaddr)); +}*/ + +STRING_ARG(SuperNET,wif2priv,wif) +{ + bits256 privkey; char str[65]; uint8_t privkeytype; cJSON *retjson = cJSON_CreateObject(); + if ( bitcoin_wif2priv(&privkeytype,&privkey,wif) == sizeof(privkey) ) + { + jaddstr(retjson,"result","success"); + jaddstr(retjson,"privkey",bits256_str(str,privkey)); + jaddnum(retjson,"type",privkeytype); + } else jaddstr(retjson,"error","couldnt convert wif"); + return(jprint(retjson,1)); +} + +STRING_ARG(SuperNET,priv2wif,priv) +{ + bits256 privkey; char wifstr[65]; uint8_t wiftype; cJSON *retjson = cJSON_CreateObject(); + if ( is_hexstr(priv,0) == sizeof(bits256)*2 ) + { + wiftype = coin != 0 ? coin->chain->wiftype : 0x80; + decode_hex(privkey.bytes,sizeof(privkey),priv); + if ( bitcoin_priv2wif(wifstr,privkey,wiftype) > 0 ) + { + jaddstr(retjson,"result","success"); + jaddstr(retjson,"privkey",priv); + jaddnum(retjson,"type",wiftype); + jaddstr(retjson,"wif",wifstr); + } else jaddstr(retjson,"error","couldnt convert privkey"); + } else jaddstr(retjson,"error","non 32 byte hex privkey"); + return(jprint(retjson,1)); +} + +STRING_ARG(SuperNET,myipaddr,ipaddr) +{ + cJSON *retjson = cJSON_CreateObject(); + RELAYID = -1; + if ( myinfo->ipaddr[0] == 0 ) + { + if ( is_ipaddr(ipaddr) != 0 ) + { + strcpy(myinfo->ipaddr,ipaddr); + myinfo->myaddr.myipbits = (uint32_t)calc_ipbits(ipaddr); + basilisk_setmyid(myinfo); + } + } + jaddstr(retjson,"result",myinfo->ipaddr); + if ( RELAYID >= 0 ) + { + jaddnum(retjson,"relayid",RELAYID); + jaddnum(retjson,"numrelays",NUMRELAYS); + } + return(jprint(retjson,1)); +} + +STRING_ARG(SuperNET,setmyipaddr,ipaddr) +{ + cJSON *retjson = cJSON_CreateObject(); + if ( is_ipaddr(ipaddr) != 0 ) + { + strcpy(myinfo->ipaddr,ipaddr); + basilisk_setmyid(myinfo); + jaddstr(retjson,"result",myinfo->ipaddr); + } else jaddstr(retjson,"error","illegal ipaddr"); + return(jprint(retjson,1)); +} + +STRING_ARG(SuperNET,utime2utc,utime) +{ + uint32_t utc = 0; cJSON *retjson = cJSON_CreateObject(); + utc = OS_conv_utime(utime); + char str[65]; printf("utime.%s -> %u -> %s\n",utime,utc,utc_str(str,utc)); + jaddnum(retjson,"result",utc); + return(jprint(retjson,1)); +} + +INT_ARG(SuperNET,utc2utime,utc) +{ + char str[65]; cJSON *retjson = cJSON_CreateObject(); + jaddstr(retjson,"result",utc_str(str,utc)); + return(jprint(retjson,1)); +} + +ZERO_ARGS(SuperNET,logout) +{ + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + iguana_walletlock(myinfo,coin); + return(clonestr("{\"result\":\"logged out\"}")); +} + +ZERO_ARGS(SuperNET,activehandle) +{ + cJSON *retjson; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + retjson = SuperNET_rosettajson(myinfo,myinfo->persistent_priv,0); + jaddstr(retjson,"result","success"); + jaddstr(retjson,"handle",myinfo->handle); + jaddbits256(retjson,"persistent",myinfo->myaddr.persistent); + if ( myinfo->expiration != 0 ) + { + jaddstr(retjson,"status","unlocked"); + jaddnum(retjson,"duration",myinfo->expiration - time(NULL)); + } else jaddstr(retjson,"status","locked"); + SuperNET_MYINFOadd(myinfo); + return(jprint(retjson,1)); +} + +struct supernet_info *SuperNET_accountfind(cJSON *json) +{ + int32_t num; char *decryptstr; struct supernet_info M,*myinfo; struct iguana_info *coin = 0; + char *password,*permanentfile,*passphrase,*remoteaddr,*perspriv; + myinfo = 0; + if ( (password= jstr(json,"password")) == 0 ) + password = ""; + if ( (permanentfile= jstr(json,"permanentfile")) == 0 ) + permanentfile = ""; + if ( (passphrase= jstr(json,"passphrase")) == 0 ) + passphrase = ""; + remoteaddr = jstr(json,"remoteaddr"); + if ( (passphrase == 0 || passphrase[0] == 0) && (decryptstr= SuperNET_decryptjson(IGUANA_CALLARGS,password,permanentfile)) != 0 ) + { + if ( (json= cJSON_Parse(decryptstr)) != 0 ) + { + memset(&M,0,sizeof(M)); + if ( (perspriv= jstr(json,"persistent_priv")) != 0 && strlen(perspriv) == sizeof(bits256)*2 ) + { + M.persistent_priv = bits256_conv(perspriv); + SuperNET_setkeys(&M,0,0,0); + if ( (myinfo = SuperNET_MYINFOfind(&num,M.myaddr.persistent)) != 0 ) + { + //printf("found account.(%s) %s %llu\n",myinfo!=0?myinfo->handle:"",M.myaddr.NXTADDR,(long long)M.myaddr.nxt64bits); + return(myinfo); + } + } + else if ( (passphrase= jstr(json,"result")) != 0 || (passphrase= jstr(json,"passphrase")) != 0 ) + { + SuperNET_setkeys(&M,passphrase,(int32_t)strlen(passphrase),1); + if ( (myinfo= SuperNET_MYINFOfind(&num,M.myaddr.persistent)) != 0 ) + { + //printf("found account.(%s) %s %llu\n",myinfo!=0?myinfo->handle:"",M.myaddr.NXTADDR,(long long)M.myaddr.nxt64bits); + return(myinfo); + } + } else printf("no passphrase in (%s)\n",jprint(json,0)); + free_json(json); + } else printf("cant parse.(%s)\n",decryptstr); + free(decryptstr); + } + return(SuperNET_MYINFO(0)); +} + +FOUR_STRINGS(SuperNET,login,handle,password,permanentfile,passphrase) +{ + char *str,*decryptstr = 0; cJSON *argjson,*item,*walletitem; + if ( remoteaddr != 0 ) + return(clonestr("{\"error\":\"no remote\"}")); + if ( handle != 0 && handle[0] != 0 ) + safecopy(myinfo->handle,handle,sizeof(myinfo->handle)); + else memset(myinfo->handle,0,sizeof(myinfo->handle)); + if ( password == 0 || password[0] == 0 ) + password = passphrase; + /*if ( password != 0 && password[0] != 0 ) + safecopy(myinfo->secret,password,sizeof(myinfo->secret)); + else if ( passphrase != 0 && passphrase[0] != 0 ) + safecopy(myinfo->secret,passphrase,sizeof(myinfo->secret));*/ + if ( permanentfile != 0 ) + safecopy(myinfo->permanentfile,permanentfile,sizeof(myinfo->permanentfile)); + if ( (decryptstr= SuperNET_decryptjson(IGUANA_CALLARGS,password,myinfo->permanentfile)) != 0 ) + { + printf("decryptstr.(%s)\n",decryptstr); + if ( (argjson= cJSON_Parse(decryptstr)) != 0 ) + { + if ( jobj(argjson,"error") == 0 ) + { + printf("decrypted.(%s) exp.%u pass.(%s)\n",decryptstr,myinfo->expiration,password); + if ( myinfo->decryptstr != 0 ) + free(myinfo->decryptstr); + myinfo->decryptstr = decryptstr; + if ( (passphrase= jstr(argjson,"passphrase")) != 0 ) + { + SuperNET_setkeys(myinfo,passphrase,(int32_t)strlen(passphrase),1); + free_json(argjson); + myinfo->expiration = (uint32_t)(time(NULL) + 3600); + return(SuperNET_activehandle(IGUANA_CALLARGS)); + } + else + { + free_json(argjson); + return(clonestr("{\"error\":\"cant find passphrase in decrypted json\"}")); + } + } else free_json(argjson); + } + else + { + free(decryptstr); + return(clonestr("{\"error\":\"cant parse decrypted json\"}")); + } + } + else if ( myinfo->decryptstr != 0 ) + { + free(myinfo->decryptstr); + myinfo->decryptstr = 0; + } + if ( passphrase != 0 && passphrase[0] != 0 ) + { + SuperNET_setkeys(myinfo,passphrase,(int32_t)strlen(passphrase),1); + if ( myinfo->decryptstr != 0 && (argjson= cJSON_Parse(myinfo->decryptstr)) != 0 ) + { + if ( jobj(argjson,"passphrase") != 0 ) + jdelete(argjson,"passphrase"); + if ( jobj(argjson,"error") != 0 ) + jdelete(argjson,"error"); + } + else + { + char rmd160str[41],str[65]; uint8_t rmd160[20]; + item = cJSON_CreateObject(); + calc_rmd160_sha256(rmd160,myinfo->persistent_pubkey33,33); + init_hexbytes_noT(rmd160str,rmd160,20); + jaddstr(item,rmd160str,bits256_str(str,myinfo->persistent_priv)); + walletitem = cJSON_CreateObject(); + jadd(walletitem,"default",item); + argjson = cJSON_CreateObject(); + jadd(argjson,"wallet",walletitem); + myinfo->dirty = (uint32_t)time(NULL); + } + jaddstr(argjson,"passphrase",passphrase); + if ( (str= SuperNET_encryptjson(myinfo,coin,argjson,remoteaddr,password,myinfo->permanentfile,myinfo->decryptstr == 0 ? "" : myinfo->decryptstr)) != 0 ) + free(str); + myinfo->expiration = (uint32_t)(time(NULL) + 3600); + printf("(%s) logged into (%s) %s %s\n",password,myinfo->myaddr.NXTADDR,myinfo->myaddr.BTC,myinfo->myaddr.BTCD); + return(SuperNET_activehandle(IGUANA_CALLARGS)); + } else return(clonestr("{\"error\":\"need passphrase\"}")); + printf("(%s) logged into (%s) %s %s\n",password,myinfo->myaddr.NXTADDR,myinfo->myaddr.BTC,myinfo->myaddr.BTCD); + return(SuperNET_activehandle(IGUANA_CALLARGS)); +} + +#include "../includes/iguana_apiundefs.h" + +void iguana_relays_init(struct supernet_info *myinfo) +{ + static char *ipaddrs[] = { "89.248.160.237", "89.248.160.238", "89.248.160.239", "89.248.160.240", "89.248.160.241", "89.248.160.242", "89.248.160.243", "89.248.160.244" }; + char *str; int32_t i; + for (i=0; i 0 ) + int32_t usessl = 0, ismainnet = 1; struct supernet_info *myinfo; //cJSON *argjson = 0; + if ( (IGUANA_BIGENDIAN= iguana_isbigendian()) > 0 ) printf("BIGENDIAN\n"); - else if ( BIGENDIAN == 0 ) + else if ( IGUANA_BIGENDIAN == 0 ) printf("LITTLE ENDIAN arg.%p\n",arg); else printf("ENDIAN ERROR\n"); mycalloc(0,0,0); - if ( 0 ) - iguana_signalsinit(); + decode_hex(CRYPTO777_RMD160,20,CRYPTO777_RMD160STR); + decode_hex(CRYPTO777_PUBSECP33,33,CRYPTO777_PUBSECPSTR); iguana_ensuredirs(); iguana_Qinit(); myinfo = SuperNET_MYINFO(0); + libgfshare_init(myinfo,myinfo->logs,myinfo->exps); + //void test_mimblewimble(void *ctx); + //test_mimblewimble(myinfo->ctx); + if ( 0 ) + { + int32_t i; for (i=0; i<10; i++) + iguana_schnorr(myinfo); + getchar(); + } myinfo->rpcport = IGUANA_RPCPORT; strcpy(myinfo->rpcsymbol,"BTCD"); iguana_urlinit(myinfo,ismainnet,usessl); - category_init(myinfo); - iguana_helpinit(myinfo); - iguana_commandline(myinfo,arg); +#if LIQUIDITY_PROVIDER + myinfo->tradingexchanges[myinfo->numexchanges++] = exchange_create(clonestr("bitcoin"),0); + myinfo->tradingexchanges[myinfo->numexchanges++] = exchange_create(clonestr("poloniex"),0); + myinfo->tradingexchanges[myinfo->numexchanges++] = exchange_create(clonestr("bittrex"),0); + myinfo->tradingexchanges[myinfo->numexchanges++] = exchange_create(clonestr("btc38"),0); + myinfo->tradingexchanges[myinfo->numexchanges++] = exchange_create(clonestr("huobi"),0); + myinfo->tradingexchanges[myinfo->numexchanges++] = exchange_create(clonestr("coinbase"),0); + myinfo->tradingexchanges[myinfo->numexchanges++] = exchange_create(clonestr("lakebtc"),0); + myinfo->tradingexchanges[myinfo->numexchanges++] = exchange_create(clonestr("quadriga"),0); + myinfo->tradingexchanges[myinfo->numexchanges++] = exchange_create(clonestr("okcoin"),0); + myinfo->tradingexchanges[myinfo->numexchanges++] = exchange_create(clonestr("btce"),0); + myinfo->tradingexchanges[myinfo->numexchanges++] = exchange_create(clonestr("bitstamp"),0); +#endif + if ( iguana_commandline(myinfo,arg) == 0 ) + { + iguana_helpinit(myinfo); + iguana_relays_init(myinfo); + basilisks_init(myinfo); #ifdef __APPLE__ - iguana_appletests(myinfo); + iguana_appletests(myinfo); #endif + } iguana_launchdaemons(myinfo); } diff --git a/iguana/make_win32 b/iguana/make_win32 index e2209cb0e..83bd33783 100644 --- a/iguana/make_win32 +++ b/iguana/make_win32 @@ -6,10 +6,10 @@ all: clean check build build: @echo "\nBuilding iguana......" - $(TOOL_DIR)/$(MINGW)-gcc -w -o ../agents/win32/iguana.exe -D __MINGW -D __CURL_CURLBUILD_H -D __CURL_CURL_H -D __CURL_EASY_H $(SOURCES) $(LIBS) || (echo -e "\033[4mERROR: Failed to build iguana\033[0m"; exit 1; ) + $(TOOL_DIR)/bin/$(MINGW) -w -D__CLEANUP_C -DPTW32_STATIC_LIB -o ../agents/win32/iguana.exe -D __MINGW -D __CURL_CURLBUILD_H -D __CURL_CURL_H -D __CURL_EASY_H $(SOURCES) $(LIBS) || (echo -e "\033[4mERROR: Failed to build iguana\033[0m"; exit 1; ) - $(TOOL_DIR)/$(MINGW)-strip --strip-all ../agents/win32/iguana.exe + $(TOOL_DIR)/bin/strip --strip-all ../agents/win32/iguana.exe @echo "\nBuild successfully......" check: diff --git a/iguana/make_win64 b/iguana/make_win64 index cd8d3f1fe..a279311bb 100644 --- a/iguana/make_win64 +++ b/iguana/make_win64 @@ -1,17 +1,17 @@ include iguana.sources include ../mingw.path64 -LIBS := ../win/libsecp256k1.a ../win/libcrypto.a ../win/libssl.a ../win/libpthreadGC2_64.a ../agents/win64/libcrypto777.a ../win/libcurldll.a /usr/share/mingw-w64/lib/libws2_32.a /usr/share/mingw-w64/lib/libgdi32.a -I/usr/share/mingw-w64/include -I/usr/i386/include -I/usr/i386/include/curl -I/home/user/SuperNET/iguana -I/home/user/SuperNET/includes -I/home/user/SuperNET/crypto777 +LIBS := ../OSlibs/win/libsecp256k1.a ../OSlibs/win/libcrypto.a ../OSlibs/win/libssl.a ../agents/win64/libcrypto777.a ../OSlibs/win/libcurldll.a $(TOOL_DIR)/x86_64-w64-mingw32/lib/libws2_32.a $(TOOL_DIR)/x86_64-w64-mingw32/lib/libgdi32.a -I$(TOOL_DIR)/include -I../iguana -I../includes -I../crypto777 -I../OSlibs/win -L../OSlibs/win/x64 -lpthreadGC2 include mingw64_inc all: check build build: - $(TOOL_DIR)/$(MINGW)-gcc -w -o ../agents/win64/iguana.exe -D __MINGW -D __CURL_CURLBUILD_H -D __CURL_CURL_H -D __CURL_EASY_H $(SOURCES) $(LIBS) || (echo -e "\033[4mERROR: Failed to build iguana\033[0m"; exit 1; ) - - $(TOOL_DIR)/$(MINGW)-strip --strip-all ../agents/win64/iguana.exe || (echo -e "\033[4mERROR: Failed to strip iguana\033[0m"; exit 1; ) + $(TOOL_DIR)/bin/$(MINGW) -w -D__CLEANUP_C -DPTW32_STATIC_LIB -o ../agents/win64/iguana.exe -D __MINGW -D __CURL_CURLBUILD_H -D __CURL_CURL_H -D __CURL_EASY_H $(SOURCES) $(LIBS) || (echo -e "\033[4mERROR: Failed to build iguana\033[0m"; exit 1; ) + $(TOOL_DIR)/bin/strip --strip-all ../agents/win64/iguana.exe || (echo -e "\033[4mERROR: Failed to strip iguana\033[0m"; exit 1; ) + @echo "\Build Successful......" check: test -s ../agents/win64/libcrypto777.a || (echo -e "\033[4mERROR: libcrypto777.a does not exists\033[0m"; exit 1; ) diff --git a/iguana/manifest.json b/iguana/manifest.json index 611f17313..ff1e6a9a2 100755 --- a/iguana/manifest.json +++ b/iguana/manifest.json @@ -1,32 +1,40 @@ { +"update_url": "https://clients2.google.com/service/update2/crx", + "app": { "background": { "scripts": ["background.js"] } }, "name": "iguana", "short_name": "iguana", - "version": "44.1.2", + "version": "44.2.1", "manifest_version": 2, "description": "iguana", + "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'", "offline_enabled": true, "icons": { "128": "icon128.png" }, "icons": { "128": "icon128.png" }, "minimum_chrome_version": "36", - "sockets": { - "tcp": { - "connect": "*" - }, - "tcpServer": { - "listen": "*" - } - }, + "web_accessible_resources":[ + "help/*" + ], "permissions": [ + { "socket": [ + "tcp-listen:*:*", + "tcp-connect", + "resolve-host", + "udp-bind:*:*", + "udp-send-to:*:*" + ] + }, "unlimitedStorage", - {"fileSystem": ["write"]}, + {"fileSystem": ["write", + "retainEntries", + "directory"]}, "storage", "system.storage", "system.display", "system.network", "system.cpu" ] -} \ No newline at end of file +} diff --git a/iguana/mingw b/iguana/mingw index 50a9812e0..01f2624fe 100755 --- a/iguana/mingw +++ b/iguana/mingw @@ -1,6 +1,5 @@ include iguana.sources all: - $(TOOL_DIR)/$(MINGW)-gcc -w -o ../agents/win32/iguana.exe -D __MINGW -D __CURL_CURLBUILD_H -D __CURL_CURL_H -D __CURL_EASY_H $(SOURCES) $(LIBS) - $(TOOL_DIR)/$(MINGW)-strip --strip-all ../agents/win32/iguana.exe - + $(TOOL_DIR)/bin/$(MINGW) -w -D__CLEANUP_C -DPTW32_STATIC_LIB -o ../agents/win32/iguana.exe -D __MINGW -D __CURL_CURLBUILD_H -D __CURL_CURL_H -D __CURL_EASY_H $(SOURCES) $(LIBS) + $(TOOL_DIR)/bin/strip --strip-all ../agents/win32/iguana.exe diff --git a/iguana/mingw32 b/iguana/mingw32 index 44431b990..279159960 100755 --- a/iguana/mingw32 +++ b/iguana/mingw32 @@ -1,4 +1,4 @@ include ../mingw.path -LIBS := ../win/libsecp256k1.a ../win/libcrypto.a ../win/libssl.a /usr/share/mingw-w64/lib/libpthread.a ../agents/win32/libcrypto777.a ../win/libcurldll.a /usr/i586-mingw32msvc/lib/libws2_32.a /usr/i586-mingw32msvc/lib/libgdi32.a -I/usr/mingw32/include -I/usr/i386/include -I/usr/i386/include/curl -I/home/user/SuperNET/iguana -I/home/user/SuperNET/includes -I/home/user/SuperNET/crypto777 +LIBS := ../agents/win32/libcrypto777.a $(TOOL_DIR)/lib/libws2_32.a $(TOOL_DIR)/lib/libgdi32.a -I$(TOOL_DIR)/include -I../iguana -I../includes -I../crypto777 -I../OSlibs/win -L../OSlibs/win -lpthreadGC2 include mingw diff --git a/iguana/mingw64 b/iguana/mingw64 index a29a3cdb3..856d6acc5 100755 --- a/iguana/mingw64 +++ b/iguana/mingw64 @@ -1,3 +1,3 @@ include ../mingw.path64 -LIBS := ../win/libsecp256k1.a ../win/libcrypto.a ../win/libssl.a ../win/libpthreadGC2_64.a ../agents/win64/libcrypto777.a ../win/libcurldll.a /usr/share/mingw-w64/lib/libws2_32.a /usr/share/mingw-w64/lib/libgdi32.a -I/usr/share/mingw-w64/include -I/usr/i386/include -I/usr/i386/include/curl -I/home/user/SuperNET/iguana -I/home/user/SuperNET/includes -I/home/user/SuperNET/crypto777 +LIBS := ../OSlibs/win/libsecp256k1.a ../OSlibs/win/libcrypto.a ../OSlibs/win/libssl.a ../agents/win64/libcrypto777.a ../OSlibs/win/libcurldll.a $(TOOL_DIR)/lib/libws2_32.a $(TOOL_DIR)/lib/libgdi32.a -I$(TOOL_DIR)/include -I$(APP)/iguana -I$(APP)/includes -I$(APP)/crypto777 -I../OSlibs/win -L../OSlibs/win/x64 -lpthreadGC2 include mingw64_inc diff --git a/iguana/mingw64_inc b/iguana/mingw64_inc index 4993450e2..e1101a800 100755 --- a/iguana/mingw64_inc +++ b/iguana/mingw64_inc @@ -1,6 +1,6 @@ include iguana.sources all: - $(TOOL_DIR)/$(MINGW)-gcc -w -o ../agents/win64/iguana.exe -D __MINGW -D __CURL_CURLBUILD_H -D __CURL_CURL_H -D __CURL_EASY_H $(SOURCES) $(LIBS) - $(TOOL_DIR)/$(MINGW)-strip --strip-all ../agents/win64/iguana.exe + $(TOOL_DIR)/bin/$(MINGW) -w -D__CLEANUP_C -DPTW32_STATIC_LIB -o ../agents/win64/iguana.exe -D __MINGW -D __CURL_CURLBUILD_H -D __CURL_CURL_H -D __CURL_EASY_H $(SOURCES) $(LIBS) + $(TOOL_DIR)/bin/strip --strip-all ../agents/win64/iguana.exe diff --git a/iguana/mini-gmp.c b/iguana/mini-gmp.c index 86b2d6250..4b330f255 100644 --- a/iguana/mini-gmp.c +++ b/iguana/mini-gmp.c @@ -60,8 +60,8 @@ see https://www.gnu.org/licenses/. */ #define GMP_HLIMB_BIT ((mp_limb_t) 1 << (GMP_LIMB_BITS / 2)) #define GMP_LLIMB_MASK (GMP_HLIMB_BIT - 1) -#define GMP_ULONG_BITS (sizeof(unsigned long) * CHAR_BIT) -#define GMP_ULONG_HIGHBIT ((unsigned long) 1 << (GMP_ULONG_BITS - 1)) +#define GMP_ULONG_BITS (sizeof(uint64_t) * CHAR_BIT) +#define GMP_ULONG_HIGHBIT ((uint64_t) 1 << (GMP_ULONG_BITS - 1)) #define GMP_ABS(x) ((x) >= 0 ? (x) : -(x)) #define GMP_NEG_CAST(T,x) (-((T)((x) + 1) - 1)) @@ -77,7 +77,7 @@ see https://www.gnu.org/licenses/. */ #define gmp_clz(count, x) do { \ mp_limb_t __clz_x = (x); \ - unsigned __clz_c; \ + uint32_t __clz_c; \ for (__clz_c = 0; \ (__clz_x & ((mp_limb_t) 0xff << (GMP_LIMB_BITS - 8))) == 0; \ __clz_c += 8) \ @@ -89,7 +89,7 @@ see https://www.gnu.org/licenses/. */ #define gmp_ctz(count, x) do { \ mp_limb_t __ctz_x = (x); \ - unsigned __ctz_c = 0; \ + uint32_t __ctz_c = 0; \ gmp_clz (__ctz_c, __ctz_x & - __ctz_x); \ (count) = GMP_LIMB_BITS - 1 - __ctz_c; \ } while (0) @@ -113,7 +113,7 @@ see https://www.gnu.org/licenses/. */ #define gmp_umul_ppmm(w1, w0, u, v) \ do { \ mp_limb_t __x0, __x1, __x2, __x3; \ - unsigned __ul, __vl, __uh, __vh; \ + uint32_t __ul, __vl, __uh, __vh; \ mp_limb_t __u = (u), __v = (v); \ \ __ul = __u & GMP_LLIMB_MASK; \ @@ -253,7 +253,7 @@ uint32_t __mp_size_t_swap__tmp = (x); \ struct gmp_div_inverse { /* Normalization shift count. */ - unsigned shift; + uint32_t shift; /* Normalized divisor (d0 unused for mpn_div_qr_1) */ mp_limb_t d1, d0; /* Inverse, for 2/1 or 3/2. */ @@ -270,7 +270,7 @@ struct mpn_base_info { /* bb is the largest power of the base which fits in one limb, and exp is the corresponding exponent. */ - unsigned exp; + uint32_t exp; mp_limb_t bb; }; @@ -355,27 +355,14 @@ mp_set_memory_functions (void *(*alloc_func) (size_t), -void -mpn_copyd (mp_ptr d, mp_srcptr s, mp_size_t n) -{ - while (--n >= 0) - d[n] = s[n]; -} -int -mpn_zero_p(mp_srcptr rp, mp_size_t n) +int mpn_zero_p(mp_srcptr rp, mp_size_t n) { return mpn_normalized_size (rp, n) == 0; } -void -mpn_zero (mp_ptr rp, mp_size_t n) -{ - while (--n >= 0) - rp[n] = 0; -} @@ -397,7 +384,7 @@ static mp_bitcnt_t mpn_common_scan (mp_limb_t limb, mp_size_t i, mp_srcptr up, mp_size_t un, mp_limb_t ux) { - unsigned cnt; + uint32_t cnt; assert (ux == 0 || ux == GMP_LIMB_MAX); assert (0 <= i && i <= un ); @@ -437,35 +424,6 @@ mpn_scan0 (mp_srcptr ptr, mp_bitcnt_t bit) -static mp_limb_t -mpn_div_qr_1 (mp_ptr qp, mp_srcptr np, mp_size_t nn, mp_limb_t d) -{ - assert (d > 0); - - /* Special case for powers of two. */ - if ((d & (d-1)) == 0) - { - mp_limb_t r = np[0] & (d-1); - if (qp) - { - if (d <= 1) - mpn_copyi (qp, np, nn); - else - { - unsigned shift; - gmp_ctz (shift, d); - mpn_rshift (qp, np, nn, shift); - } - } - return r; - } - else - { - struct gmp_div_inverse inv; - mpn_div_qr_1_invert (&inv, d); - return mpn_div_qr_1_preinv (qp, np, nn, &inv); - } -} #if 0 @@ -487,7 +445,7 @@ mpn_div_qr_2 (mp_ptr qp, mp_ptr rp, mp_srcptr np, mp_size_t nn, static mp_bitcnt_t mpn_limb_size_in_base_2 (mp_limb_t u) { - unsigned shift; + uint32_t shift; assert (u > 0); gmp_clz (shift, u); @@ -495,9 +453,9 @@ mpn_limb_size_in_base_2 (mp_limb_t u) } static size_t -mpn_get_str_bits (unsigned char *sp, unsigned bits, mp_srcptr up, mp_size_t un) +mpn_get_str_bits (uint8_t *sp, uint32_t bits, mp_srcptr up, mp_size_t un) { - unsigned char mask; + uint8_t mask; size_t sn, j; mp_size_t i; int shift; @@ -509,7 +467,7 @@ mpn_get_str_bits (unsigned char *sp, unsigned bits, mp_srcptr up, mp_size_t un) for (i = 0, j = sn, shift = 0; j-- > 0;) { - unsigned char digit = up[i] >> shift; + uint8_t digit = up[i] >> shift; shift += bits; @@ -526,7 +484,7 @@ mpn_get_str_bits (unsigned char *sp, unsigned bits, mp_srcptr up, mp_size_t un) /* We generate digits from the least significant end, and reverse at the end. */ static size_t -mpn_limb_get_str (unsigned char *sp, mp_limb_t w, +mpn_limb_get_str (uint8_t *sp, mp_limb_t w, const struct gmp_div_inverse *binv) { mp_size_t i; @@ -547,7 +505,7 @@ mpn_limb_get_str (unsigned char *sp, mp_limb_t w, } static size_t -mpn_get_str_other (unsigned char *sp, +mpn_get_str_other (uint8_t *sp, int base, const struct mpn_base_info *info, mp_ptr up, mp_size_t un) { @@ -582,7 +540,7 @@ mpn_get_str_other (unsigned char *sp, /* Reverse order */ for (i = 0; 2*i + 1 < sn; i++) { - unsigned char t = sp[i]; + uint8_t t = sp[i]; sp[i] = sp[sn - i - 1]; sp[sn - i - 1] = t; } @@ -591,9 +549,9 @@ mpn_get_str_other (unsigned char *sp, } size_t -mpn_get_str (unsigned char *sp, int base, mp_ptr up, mp_size_t un) +mpn_get_str (uint8_t *sp, int base, mp_ptr up, mp_size_t un) { - unsigned bits; + uint32_t bits; assert (un > 0); assert (up[un-1] > 0); @@ -611,9 +569,9 @@ mpn_get_str (unsigned char *sp, int base, mp_ptr up, mp_size_t un) } mp_size_t -mpn_set_str (mp_ptr rp, const unsigned char *sp, size_t sn, int base) +mpn_set_str (mp_ptr rp, const uint8_t *sp, size_t sn, int base) { - unsigned bits; + uint32_t bits; if (sn == 0) return 0; @@ -639,7 +597,7 @@ mpn_set_str (mp_ptr rp, const unsigned char *sp, size_t sn, int base) /* MPZ assignment and basic conversions. */ void -mpz_init_set_si (mpz_t r, signed long int x) +mpz_init_set_si (mpz_t r, int64_t x) { mpz_init (r); mpz_set_si (r, x); @@ -907,15 +865,15 @@ mpz_cmp_si (const mpz_t u, long v) else /* usize == -1 */ { mp_limb_t ul = u->_mp_d[0]; - if ((mp_limb_t)GMP_NEG_CAST (unsigned long int, v) < ul) + if ((mp_limb_t)GMP_NEG_CAST (uint64_t, v) < ul) return -1; else - return (mp_limb_t)GMP_NEG_CAST (unsigned long int, v) > ul; + return (mp_limb_t)GMP_NEG_CAST (uint64_t, v) > ul; } } int -mpz_cmp_ui (const mpz_t u, unsigned long v) +mpz_cmp_ui (const mpz_t u, uint64_t v) { mp_size_t usize = u->_mp_size; @@ -931,7 +889,7 @@ mpz_cmp_ui (const mpz_t u, unsigned long v) } int -mpz_cmpabs_ui (const mpz_t u, unsigned long v) +mpz_cmpabs_ui (const mpz_t u, uint64_t v) { mp_size_t un = GMP_ABS (u->_mp_size); mp_limb_t ul; @@ -976,7 +934,7 @@ mpz_neg (mpz_t r, const mpz_t u) void -mpz_ui_sub (mpz_t r, unsigned long a, const mpz_t b) +mpz_ui_sub (mpz_t r, uint64_t a, const mpz_t b) { if (b->_mp_size < 0) r->_mp_size = mpz_abs_add_ui (r, b, a); @@ -994,76 +952,18 @@ mpz_mul_si (mpz_t r, const mpz_t u, long int v) { if (v < 0) { - mpz_mul_ui (r, u, GMP_NEG_CAST (unsigned long int, v)); + mpz_mul_ui (r, u, GMP_NEG_CAST (uint64_t, v)); mpz_neg (r, r); } else - mpz_mul_ui (r, u, (unsigned long int) v); -} - -void -mpz_mul_ui (mpz_t r, const mpz_t u, unsigned long int v) -{ - mp_size_t un, us; - mp_ptr tp; - mp_limb_t cy; - - us = u->_mp_size; - - if (us == 0 || v == 0) - { - r->_mp_size = 0; - return; - } - - un = GMP_ABS (us); - - tp = MPZ_REALLOC (r, un + 1); - cy = mpn_mul_1 (tp, u->_mp_d, un, v); - tp[un] = cy; - - un += (cy > 0); - r->_mp_size = (us < 0) ? - un : un; + mpz_mul_ui (r, u, (uint64_t) v); } -void -mpz_mul_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t bits) -{ - mp_size_t un, rn; - mp_size_t limbs; - unsigned shift; - mp_ptr rp; - - un = GMP_ABS (u->_mp_size); - if (un == 0) - { - r->_mp_size = 0; - return; - } - - limbs = bits / GMP_LIMB_BITS; - shift = bits % GMP_LIMB_BITS; - - rn = un + limbs + (shift > 0); - rp = MPZ_REALLOC (r, rn); - if (shift > 0) - { - mp_limb_t cy = mpn_lshift (rp + limbs, u->_mp_d, un, shift); - rp[rn-1] = cy; - rn -= (cy == 0); - } - else - mpn_copyd (rp + limbs, u->_mp_d, un); - - mpn_zero (rp, limbs); - - r->_mp_size = (u->_mp_size < 0) ? - rn : rn; -} void -mpz_addmul_ui (mpz_t r, const mpz_t u, unsigned long int v) +mpz_addmul_ui (mpz_t r, const mpz_t u, uint64_t v) { mpz_t t; mpz_init (t); @@ -1073,7 +973,7 @@ mpz_addmul_ui (mpz_t r, const mpz_t u, unsigned long int v) } void -mpz_submul_ui (mpz_t r, const mpz_t u, unsigned long int v) +mpz_submul_ui (mpz_t r, const mpz_t u, uint64_t v) { mpz_t t; mpz_init (t); @@ -1362,146 +1262,91 @@ mpz_congruent_p (const mpz_t a, const mpz_t b, const mpz_t m) return res; } -static unsigned long -mpz_div_qr_ui (mpz_t q, mpz_t r, - const mpz_t n, unsigned long d, enum mpz_div_round_mode mode) -{ - mp_size_t ns, qn; - mp_ptr qp; - mp_limb_t rl; - mp_size_t rs; - - ns = n->_mp_size; - if (ns == 0) - { - if (q) - q->_mp_size = 0; - if (r) - r->_mp_size = 0; - return 0; - } - - qn = GMP_ABS (ns); - if (q) - qp = MPZ_REALLOC (q, qn); - else - qp = NULL; - - rl = mpn_div_qr_1 (qp, n->_mp_d, qn, d); - assert (rl < d); - - rs = rl > 0; - rs = (ns < 0) ? -rs : rs; - - if (rl > 0 && ( (mode == GMP_DIV_FLOOR && ns < 0) - || (mode == GMP_DIV_CEIL && ns >= 0))) - { - if (q) - gmp_assert_nocarry (mpn_add_1 (qp, qp, qn, 1)); - rl = d - rl; - rs = -rs; - } - - if (r) - { - r->_mp_d[0] = rl; - r->_mp_size = rs; - } - if (q) - { - qn -= (qp[qn-1] == 0); - assert (qn == 0 || qp[qn-1] > 0); - - q->_mp_size = (ns < 0) ? - qn : qn; - } - return rl; -} - -unsigned long -mpz_cdiv_qr_ui (mpz_t q, mpz_t r, const mpz_t n, unsigned long d) +uint64_t +mpz_cdiv_qr_ui (mpz_t q, mpz_t r, const mpz_t n, uint64_t d) { return mpz_div_qr_ui (q, r, n, d, GMP_DIV_CEIL); } -unsigned long -mpz_fdiv_qr_ui (mpz_t q, mpz_t r, const mpz_t n, unsigned long d) +uint64_t +mpz_fdiv_qr_ui (mpz_t q, mpz_t r, const mpz_t n, uint64_t d) { return mpz_div_qr_ui (q, r, n, d, GMP_DIV_FLOOR); } -unsigned long -mpz_tdiv_qr_ui (mpz_t q, mpz_t r, const mpz_t n, unsigned long d) +uint64_t +mpz_tdiv_qr_ui (mpz_t q, mpz_t r, const mpz_t n, uint64_t d) { return mpz_div_qr_ui (q, r, n, d, GMP_DIV_TRUNC); } -unsigned long -mpz_cdiv_q_ui (mpz_t q, const mpz_t n, unsigned long d) +uint64_t +mpz_cdiv_q_ui (mpz_t q, const mpz_t n, uint64_t d) { return mpz_div_qr_ui (q, NULL, n, d, GMP_DIV_CEIL); } -unsigned long -mpz_fdiv_q_ui (mpz_t q, const mpz_t n, unsigned long d) +uint64_t +mpz_fdiv_q_ui (mpz_t q, const mpz_t n, uint64_t d) { return mpz_div_qr_ui (q, NULL, n, d, GMP_DIV_FLOOR); } -unsigned long -mpz_tdiv_q_ui (mpz_t q, const mpz_t n, unsigned long d) +uint64_t +mpz_tdiv_q_ui (mpz_t q, const mpz_t n, uint64_t d) { return mpz_div_qr_ui (q, NULL, n, d, GMP_DIV_TRUNC); } -unsigned long -mpz_cdiv_r_ui (mpz_t r, const mpz_t n, unsigned long d) +uint64_t +mpz_cdiv_r_ui (mpz_t r, const mpz_t n, uint64_t d) { return mpz_div_qr_ui (NULL, r, n, d, GMP_DIV_CEIL); } -unsigned long -mpz_fdiv_r_ui (mpz_t r, const mpz_t n, unsigned long d) +uint64_t +mpz_fdiv_r_ui (mpz_t r, const mpz_t n, uint64_t d) { return mpz_div_qr_ui (NULL, r, n, d, GMP_DIV_FLOOR); } -unsigned long -mpz_tdiv_r_ui (mpz_t r, const mpz_t n, unsigned long d) +uint64_t +mpz_tdiv_r_ui (mpz_t r, const mpz_t n, uint64_t d) { return mpz_div_qr_ui (NULL, r, n, d, GMP_DIV_TRUNC); } -unsigned long -mpz_cdiv_ui (const mpz_t n, unsigned long d) +uint64_t +mpz_cdiv_ui (const mpz_t n, uint64_t d) { return mpz_div_qr_ui (NULL, NULL, n, d, GMP_DIV_CEIL); } -unsigned long -mpz_fdiv_ui (const mpz_t n, unsigned long d) +uint64_t +mpz_fdiv_ui (const mpz_t n, uint64_t d) { return mpz_div_qr_ui (NULL, NULL, n, d, GMP_DIV_FLOOR); } -unsigned long -mpz_tdiv_ui (const mpz_t n, unsigned long d) +uint64_t +mpz_tdiv_ui (const mpz_t n, uint64_t d) { return mpz_div_qr_ui (NULL, NULL, n, d, GMP_DIV_TRUNC); } -unsigned long -mpz_mod_ui (mpz_t r, const mpz_t n, unsigned long d) +uint64_t +mpz_mod_ui (mpz_t r, const mpz_t n, uint64_t d) { return mpz_div_qr_ui (NULL, r, n, d, GMP_DIV_FLOOR); } void -mpz_divexact_ui (mpz_t q, const mpz_t n, unsigned long d) +mpz_divexact_ui (mpz_t q, const mpz_t n, uint64_t d) { gmp_assert_nocarry (mpz_div_qr_ui (q, NULL, n, d, GMP_DIV_TRUNC)); } int -mpz_divisible_ui_p (const mpz_t n, unsigned long d) +mpz_divisible_ui_p (const mpz_t n, uint64_t d) { return mpz_div_qr_ui (NULL, NULL, n, d, GMP_DIV_TRUNC) == 0; } @@ -1511,7 +1356,7 @@ mpz_divisible_ui_p (const mpz_t n, unsigned long d) static mp_limb_t mpn_gcd_11 (mp_limb_t u, mp_limb_t v) { - unsigned shift; + uint32_t shift; assert ( (u | v) > 0); @@ -1551,8 +1396,8 @@ mpn_gcd_11 (mp_limb_t u, mp_limb_t v) return u << shift; } -unsigned long -mpz_gcd_ui (mpz_t g, const mpz_t u, unsigned long v) +uint64_t +mpz_gcd_ui (mpz_t g, const mpz_t u, uint64_t v) { mp_size_t un; @@ -1660,7 +1505,7 @@ mpz_gcdext (mpz_t g, mpz_t s, mpz_t t, const mpz_t u, const mpz_t v) if (u->_mp_size == 0) { /* g = 0 u + sgn(v) v */ - signed long sign = mpz_sgn (v); + int64_t sign = mpz_sgn (v); mpz_abs (g, v); if (s) mpz_set_ui (s, 0); @@ -1672,7 +1517,7 @@ mpz_gcdext (mpz_t g, mpz_t s, mpz_t t, const mpz_t u, const mpz_t v) if (v->_mp_size == 0) { /* g = sgn(u) u + 0 v */ - signed long sign = mpz_sgn (u); + int64_t sign = mpz_sgn (u); mpz_abs (g, u); if (s) mpz_set_si (s, sign); @@ -1854,7 +1699,7 @@ mpz_lcm (mpz_t r, const mpz_t u, const mpz_t v) } void -mpz_lcm_ui (mpz_t r, const mpz_t u, unsigned long v) +mpz_lcm_ui (mpz_t r, const mpz_t u, uint64_t v) { if (v == 0 || u->_mp_size == 0) { @@ -1904,9 +1749,9 @@ mpz_invert (mpz_t r, const mpz_t u, const mpz_t m) /* Higher level operations (sqrt, pow and root) */ void -mpz_pow_ui (mpz_t r, const mpz_t b, unsigned long e) +mpz_pow_ui (mpz_t r, const mpz_t b, uint64_t e) { - unsigned long bit; + uint64_t bit; mpz_t tr; mpz_init_set_ui (tr, 1); @@ -1925,7 +1770,7 @@ mpz_pow_ui (mpz_t r, const mpz_t b, unsigned long e) } void -mpz_ui_pow_ui (mpz_t r, unsigned long blimb, unsigned long e) +mpz_ui_pow_ui (mpz_t r, uint64_t blimb, uint64_t e) { mpz_t b; mpz_pow_ui (r, mpz_roinit_n (b, &blimb, 1), e); @@ -1939,7 +1784,7 @@ mpz_powm (mpz_t r, const mpz_t b, const mpz_t e, const mpz_t m) mp_size_t en, mn; mp_srcptr mp; struct gmp_div_inverse minv; - unsigned shift; + uint32_t shift; mp_ptr tp = NULL; en = GMP_ABS (e->_mp_size); @@ -2037,7 +1882,7 @@ mpz_powm (mpz_t r, const mpz_t b, const mpz_t e, const mpz_t m) } void -mpz_powm_ui (mpz_t r, const mpz_t b, unsigned long elimb, const mpz_t m) +mpz_powm_ui (mpz_t r, const mpz_t b, uint64_t elimb, const mpz_t m) { mpz_t e; mpz_powm (r, b, mpz_roinit_n (e, &elimb, 1), m); @@ -2045,7 +1890,7 @@ mpz_powm_ui (mpz_t r, const mpz_t b, unsigned long elimb, const mpz_t m) /* x=trunc(y^(1/z)), r=y-x^z */ void -mpz_rootrem (mpz_t x, mpz_t r, const mpz_t y, unsigned long z) +mpz_rootrem (mpz_t x, mpz_t r, const mpz_t y, uint64_t z) { int sgn; mpz_t t, u; @@ -2109,7 +1954,7 @@ mpz_rootrem (mpz_t x, mpz_t r, const mpz_t y, unsigned long z) } int -mpz_root (mpz_t x, const mpz_t y, unsigned long z) +mpz_root (mpz_t x, const mpz_t y, uint64_t z) { int res; mpz_t r; @@ -2180,7 +2025,7 @@ mpn_sqrtrem (mp_ptr sp, mp_ptr rp, mp_srcptr p, mp_size_t n) /* Combinatorics */ void -mpz_fac_ui (mpz_t x, unsigned long n) +mpz_fac_ui (mpz_t x, uint64_t n) { mpz_set_ui (x, n + (n == 0)); while (n > 2) @@ -2188,7 +2033,7 @@ mpz_fac_ui (mpz_t x, unsigned long n) } void -mpz_bin_uiui (mpz_t r, unsigned long n, unsigned long k) +mpz_bin_uiui (mpz_t r, uint64_t n, uint64_t k) { mpz_t t; @@ -2286,7 +2131,7 @@ mpz_probab_prime_p (const mpz_t n, int reps) for (j = 0, is_prime = 1; is_prime & (j < reps); j++) { - mpz_set_ui (y, (unsigned long) j*j+j+41); + mpz_set_ui (y, (uint64_t) j*j+j+41); if (mpz_cmp (y, nm1) >= 0) { /* Don't try any further bases. This "early" break does not affect @@ -2332,7 +2177,7 @@ int mpz_tstbit (const mpz_t d, mp_bitcnt_t bit_index) { mp_size_t limb_index; - unsigned shift; + uint32_t shift; mp_size_t ds; mp_size_t dn; mp_limb_t w; @@ -2677,15 +2522,15 @@ mpz_xor (mpz_t r, const mpz_t u, const mpz_t v) r->_mp_size = rx ? -un : un; } -static unsigned +static uint32_t gmp_popcount_limb (mp_limb_t x) { - unsigned c; + uint32_t c; /* Do 16 bits at a time, to avoid limb-sized constants. */ for (c = 0; x > 0; x >>= 16) { - unsigned w = ((x >> 1) & 0x5555) + (x & 0x5555); + uint32_t w = ((x >> 1) & 0x5555) + (x & 0x5555); w = ((w >> 2) & 0x3333) + (w & 0x3333); w = ((w >> 4) & 0x0f0f) + (w & 0x0f0f); w = (w >> 8) + (w & 0x00ff); @@ -2894,7 +2739,7 @@ mpz_sizeinbase (const mpz_t u, int base) char * mpz_get_str (char *sp, int base, const mpz_t u) { - unsigned bits; + uint32_t bits; const char *digits; mp_size_t un; size_t i, sn; @@ -2935,7 +2780,7 @@ mpz_get_str (char *sp, int base, const mpz_t u) if (bits) /* Not modified in this case. */ - sn = i + mpn_get_str_bits ((unsigned char *) sp + i, bits, u->_mp_d, un); + sn = i + mpn_get_str_bits ((uint8_t *) sp + i, bits, u->_mp_d, un); else { struct mpn_base_info info; @@ -2945,12 +2790,12 @@ mpz_get_str (char *sp, int base, const mpz_t u) tp = gmp_xalloc_limbs (un); mpn_copyi (tp, u->_mp_d, un); - sn = i + mpn_get_str_other ((unsigned char *) sp + i, base, &info, tp, un); + sn = i + mpn_get_str_other ((uint8_t *) sp + i, base, &info, tp, un); gmp_free (tp); } for (; i < sn; i++) - sp[i] = digits[(unsigned char) sp[i]]; + sp[i] = digits[(uint8_t) sp[i]]; sp[sn] = '\0'; return sp; @@ -2985,7 +2830,7 @@ static mp_ptr gmp_xalloc_limbs (mp_size_t size) static int gmp_detect_endian (void) { static const int i = 2; - const unsigned char *p = (const unsigned char *) &i; + const uint8_t *p = (const uint8_t *) &i; return 1 - *p; } @@ -3006,7 +2851,7 @@ void *mpz_export (void *r, size_t *countp, int order, size_t size, int endian,si if (un != 0) { size_t k; - unsigned char *p; + uint8_t *p; ptrdiff_t word_step; /* The current (partial) limb. */ mp_limb_t limb; @@ -3034,7 +2879,7 @@ void *mpz_export (void *r, size_t *countp, int order, size_t size, int endian,si if (endian == 0) endian = gmp_detect_endian (); - p = (unsigned char *) r; + p = (uint8_t *) r; word_step = (order != endian) ? 2 * size : 0; @@ -3112,7 +2957,7 @@ mpz_realloc (mpz_t r, mp_size_t size) void mpz_import (mpz_t r, size_t count, int order, size_t size, int endian,size_t nails, const void *src) { - const unsigned char *p; + const uint8_t *p; ptrdiff_t word_step; mp_ptr rp; mp_size_t rn; @@ -3133,25 +2978,21 @@ mpz_import (mpz_t r, size_t count, int order, size_t size, int endian,size_t nai if (endian == 0) endian = gmp_detect_endian (); - p = (unsigned char *) src; + p = (uint8_t *) src; word_step = (order != endian) ? 2 * size : 0; - /* Process bytes from the least significant end, so point p at the - least significant word. */ + // Process bytes from the least significant end, so point p at the least significant word if (order == 1) { p += size * (count - 1); word_step = - word_step; } - - /* And at least significant byte of that word. */ + // And at least significant byte of that word if (endian == 1) p += (size - 1); - rn = (size * count + sizeof(mp_limb_t) - 1) / sizeof(mp_limb_t); rp = MPZ_REALLOC (r, rn); - for (limb = 0, bytes = 0, i = 0; count > 0; count--, p += word_step) { size_t j; @@ -3169,9 +3010,7 @@ mpz_import (mpz_t r, size_t count, int order, size_t size, int endian,size_t nai assert (i + (bytes > 0) == rn); if (limb != 0) rp[i++] = limb; - else - i = mpn_normalized_size (rp, i); - + else i = mpn_normalized_size (rp, i); r->_mp_size = (int32_t)i; } @@ -3193,7 +3032,7 @@ mpn_get_base_info (struct mpn_base_info *info, mp_limb_t b) { mp_limb_t m; mp_limb_t p; - unsigned exp; + uint32_t exp; m = GMP_LIMB_MAX / b; for (exp = 1, p = b; p <= m; exp++) @@ -3203,7 +3042,7 @@ mpn_get_base_info (struct mpn_base_info *info, mp_limb_t b) info->bb = p; } -static unsigned mpn_base_power_of_two_p (unsigned b) +static uint32_t mpn_base_power_of_two_p (uint32_t b) { switch (b) { @@ -3220,11 +3059,11 @@ static unsigned mpn_base_power_of_two_p (unsigned b) } -static mp_size_t mpn_set_str_bits (mp_ptr rp, const unsigned char *sp, size_t sn, unsigned bits) +static mp_size_t mpn_set_str_bits (mp_ptr rp, const uint8_t *sp, size_t sn, uint32_t bits) { mp_size_t rn; size_t j; - unsigned shift; + uint32_t shift; for (j = sn, rn = 0, shift = 0; j-- > 0; ) { @@ -3292,12 +3131,12 @@ mpn_mul_1 (mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t vl) } static mp_size_t -mpn_set_str_other (mp_ptr rp, const unsigned char *sp, size_t sn, +mpn_set_str_other (mp_ptr rp, const uint8_t *sp, size_t sn, mp_limb_t b, const struct mpn_base_info *info) { mp_size_t rn; mp_limb_t w; - unsigned k; + uint32_t k; size_t j; k = 1 + (sn - 1) % info->exp; @@ -3352,16 +3191,16 @@ void mpz_set (mpz_t r, const mpz_t x) int mpz_set_str (mpz_t r, const char *sp, int base) { - unsigned bits; + uint32_t bits; mp_size_t rn, alloc; mp_ptr rp; size_t sn; int sign; - unsigned char *dp; + uint8_t *dp; assert (base == 0 || (base >= 2 && base <= 36)); - while (isspace( (unsigned char) *sp)) + while (isspace( (uint8_t) *sp)) sp++; sign = (*sp == '-'); @@ -3390,13 +3229,13 @@ int mpz_set_str (mpz_t r, const char *sp, int base) } sn = strlen (sp); - dp = (unsigned char *) malloc (sn + (sn == 0)); + dp = (uint8_t *) malloc (sn + (sn == 0)); for (sn = 0; *sp; sp++) { - unsigned digit; + uint32_t digit; - if (isspace ((unsigned char) *sp)) + if (isspace ((uint8_t) *sp)) continue; if (*sp >= '0' && *sp <= '9') digit = *sp - '0'; @@ -3478,7 +3317,7 @@ int mpz_cmp (const mpz_t a, const mpz_t b) static void mpn_div_qr_1_invert (struct gmp_div_inverse *inv, mp_limb_t d) { - unsigned shift; + uint32_t shift; assert (d > 0); gmp_clz (shift, d); @@ -3492,8 +3331,8 @@ mp_limb_t mpn_invert_3by2 (mp_limb_t u1, mp_limb_t u0) { mp_limb_t r, p, m; - unsigned ul, uh; - unsigned ql, qh; + uint32_t ul, uh; + uint32_t ql, qh; /* First, do a 2/1 inverse. */ /* The inverse m is defined as floor( (B^2 - 1 - u1)/u1 ), so that 0 < @@ -3503,7 +3342,7 @@ mpn_invert_3by2 (mp_limb_t u1, mp_limb_t u0) ul = u1 & GMP_LLIMB_MASK; uh = u1 >> (GMP_LIMB_BITS / 2); - qh = (unsigned)(~u1 / uh); + qh = (uint32_t)(~u1 / uh); r = ((~u1 - (mp_limb_t) qh * uh) << (GMP_LIMB_BITS / 2)) | GMP_LLIMB_MASK; p = (mp_limb_t) qh * ul; @@ -3569,7 +3408,7 @@ mpn_invert_3by2 (mp_limb_t u1, mp_limb_t u0) static void mpn_div_qr_2_invert (struct gmp_div_inverse *inv,mp_limb_t d1, mp_limb_t d0) { - unsigned shift; + uint32_t shift; assert (d1 > 0); gmp_clz (shift, d1); @@ -3594,7 +3433,7 @@ static void mpn_div_qr_invert (struct gmp_div_inverse *inv, mp_srcptr dp, mp_siz mpn_div_qr_2_invert (inv, dp[1], dp[0]); else { - unsigned shift; + uint32_t shift; mp_limb_t d1, d0; d1 = dp[dn-1]; @@ -3613,10 +3452,10 @@ static void mpn_div_qr_invert (struct gmp_div_inverse *inv, mp_srcptr dp, mp_siz } } -mp_limb_t mpn_lshift(mp_ptr rp, mp_srcptr up, mp_size_t n, unsigned int cnt) +mp_limb_t mpn_lshift(mp_ptr rp, mp_srcptr up, mp_size_t n, uint32_t cnt) { mp_limb_t high_limb, low_limb; - unsigned int tnc; + uint32_t tnc; mp_limb_t retval; assert (n >= 1); @@ -3675,7 +3514,7 @@ static mp_limb_t mpn_div_qr_1_preinv (mp_ptr qp, mp_srcptr np, mp_size_t nn,cons } static void mpn_div_qr_2_preinv (mp_ptr qp, mp_ptr rp, mp_srcptr np, mp_size_t nn, const struct gmp_div_inverse *inv) { - unsigned shift; + uint32_t shift; mp_size_t i; mp_limb_t d1, d0, di, r1, r0; mp_ptr tp; @@ -3835,10 +3674,10 @@ static void mpn_div_qr_pi1 (mp_ptr qp,mp_ptr np, mp_size_t nn, mp_limb_t n1,mp_s np[dn - 1] = n1; } -mp_limb_t mpn_rshift (mp_ptr rp, mp_srcptr up, mp_size_t n, unsigned int cnt) +mp_limb_t mpn_rshift (mp_ptr rp, mp_srcptr up, mp_size_t n, uint32_t cnt) { mp_limb_t high_limb, low_limb; - unsigned int tnc; + uint32_t tnc; mp_limb_t retval; assert (n >= 1); @@ -3873,7 +3712,7 @@ static void mpn_div_qr_preinv (mp_ptr qp, mp_ptr np, mp_size_t nn,mp_srcptr dp, else { mp_limb_t nh; - unsigned shift; + uint32_t shift; assert (inv->d1 == dp[dn-1]); assert (inv->d0 == dp[dn-2]); @@ -4011,7 +3850,7 @@ void mpz_sub (mpz_t r, const mpz_t a, const mpz_t b) } /* Adds to the absolute value. Returns new size, but doesn't store it. */ -static mp_size_t mpz_abs_add_ui (mpz_t r, const mpz_t a, unsigned long b) +static mp_size_t mpz_abs_add_ui (mpz_t r, const mpz_t a, uint64_t b) { mp_size_t an; mp_ptr rp; @@ -4054,7 +3893,7 @@ mp_limb_t mpn_sub_1 (mp_ptr rp, mp_srcptr ap, mp_size_t n, mp_limb_t b) } // Subtract from the absolute value. Returns new size, (or -1 on underflow), but doesn't store it. -static mp_size_t mpz_abs_sub_ui (mpz_t r, const mpz_t a, unsigned long b) +static mp_size_t mpz_abs_sub_ui (mpz_t r, const mpz_t a, uint64_t b) { mp_size_t an = GMP_ABS (a->_mp_size); mp_ptr rp = MPZ_REALLOC (r, an); @@ -4076,7 +3915,7 @@ static mp_size_t mpz_abs_sub_ui (mpz_t r, const mpz_t a, unsigned long b) } } -void mpz_sub_ui (mpz_t r, const mpz_t a, unsigned long b) +void mpz_sub_ui (mpz_t r, const mpz_t a, uint64_t b) { if (a->_mp_size < 0) r->_mp_size = (int)-mpz_abs_add_ui (r, a, b); @@ -4096,7 +3935,7 @@ void mpz_add (mpz_t r, const mpz_t a, const mpz_t b) r->_mp_size = (int32_t)(a->_mp_size >= 0 ? rn : - rn); } -void mpz_add_ui (mpz_t r, const mpz_t a, unsigned long b) +void mpz_add_ui (mpz_t r, const mpz_t a, uint64_t b) { if (a->_mp_size >= 0) r->_mp_size = (int32_t)mpz_abs_add_ui (r, a, b); @@ -4118,7 +3957,7 @@ void mpz_init2 (mpz_t r, mp_bitcnt_t bits) r->_mp_d = gmp_xalloc_limbs (rn); } -void mpz_set_ui (mpz_t r, unsigned long int x) +void mpz_set_ui (mpz_t r, uint64_t x) { if (x > 0) { @@ -4129,14 +3968,14 @@ void mpz_set_ui (mpz_t r, unsigned long int x) r->_mp_size = 0; } -void mpz_set_si (mpz_t r, signed long int x) +void mpz_set_si (mpz_t r, int64_t x) { if (x >= 0) mpz_set_ui (r, x); else /* (x < 0) */ { r->_mp_size = -1; - r->_mp_d[0] = GMP_NEG_CAST (unsigned long int, x); + r->_mp_d[0] = GMP_NEG_CAST (uint64_t, x); } } @@ -4224,10 +4063,10 @@ static int mpz_div_qr (mpz_t q, mpz_t r,const mpz_t n, const mpz_t d, enum mpz_d { qn -= (qp[qn-1] == 0); - tq->_mp_size = (unsigned)(qs < 0 ? -qn : qn); + tq->_mp_size = (uint32_t)(qs < 0 ? -qn : qn); } rn = mpn_normalized_size (np, dn); - tr->_mp_size = (unsigned)(ns < 0 ? - rn : rn); + tr->_mp_size = (uint32_t)(ns < 0 ? - rn : rn); if (mode == GMP_DIV_FLOOR && qs < 0 && rn != 0) { @@ -4263,7 +4102,7 @@ void mpz_cdiv_qr (mpz_t q, mpz_t r, const mpz_t n, const mpz_t d) mpz_div_qr (q, r, n, d, GMP_DIV_CEIL); } -unsigned long int mpz_get_ui (const mpz_t u) +uint64_t mpz_get_ui (const mpz_t u) { return u->_mp_size == 0 ? 0 : u->_mp_d[0]; } @@ -4273,7 +4112,7 @@ void mpz_tdiv_qr (mpz_t q, mpz_t r, const mpz_t n, const mpz_t d) mpz_div_qr (q, r, n, d, GMP_DIV_TRUNC); } -void mpz_init_set_ui (mpz_t r, unsigned long int x) +void mpz_init_set_ui (mpz_t r, uint64_t x) { mpz_init (r); mpz_set_ui (r, x); @@ -4362,6 +4201,133 @@ void mpz_mul (mpz_t r, const mpz_t u, const mpz_t v) mpz_swap (r, t); mpz_clear (t); } +void mpz_mul_ui (mpz_t r, const mpz_t u, uint64_t v) +{ + mp_size_t un, us; mp_ptr tp; mp_limb_t cy; + + us = u->_mp_size; + if (us == 0 || v == 0) + { + r->_mp_size = 0; + return; + } + un = GMP_ABS (us); + tp = MPZ_REALLOC (r, un + 1); + cy = mpn_mul_1 (tp, u->_mp_d, un, v); + tp[un] = cy; + un += (cy > 0); + r->_mp_size = (int32_t)((us < 0) ? -un : un); +} + +static mp_limb_t mpn_div_qr_1 (mp_ptr qp, mp_srcptr np, mp_size_t nn, mp_limb_t d) +{ + assert (d > 0); + // Special case for powers of two. + if ((d & (d-1)) == 0) + { + mp_limb_t r = np[0] & (d-1); + if (qp) + { + if (d <= 1) + mpn_copyi (qp, np, nn); + else + { + uint32_t shift; + gmp_ctz (shift, d); + mpn_rshift (qp, np, nn, shift); + } + } + return r; + } + else + { + struct gmp_div_inverse inv; + mpn_div_qr_1_invert (&inv, d); + return mpn_div_qr_1_preinv (qp, np, nn, &inv); + } +} + +static uint64_t mpz_div_qr_ui (mpz_t q, mpz_t r,const mpz_t n, uint64_t d, enum mpz_div_round_mode mode) +{ + mp_size_t ns,qn; mp_ptr qp; mp_limb_t rl; mp_size_t rs; + ns = n->_mp_size; + if (ns == 0) + { + if (q) + q->_mp_size = 0; + if (r) + r->_mp_size = 0; + return 0; + } + qn = GMP_ABS (ns); + if (q) + qp = MPZ_REALLOC (q, qn); + else qp = NULL; + rl = mpn_div_qr_1 (qp, n->_mp_d, qn, d); + assert (rl < d); + rs = rl > 0; + rs = (ns < 0) ? -rs : rs; + if (rl > 0 && ( (mode == GMP_DIV_FLOOR && ns < 0) || (mode == GMP_DIV_CEIL && ns >= 0))) + { + if (q) + gmp_assert_nocarry (mpn_add_1 (qp, qp, qn, 1)); + rl = d - rl; + rs = -rs; + } + if (r) + { + r->_mp_d[0] = rl; + r->_mp_size = (int32_t)rs; + } + if (q) + { + qn -= (qp[qn-1] == 0); + assert (qn == 0 || qp[qn-1] > 0); + q->_mp_size = (int32_t)((ns < 0) ? -qn : qn); + } + return rl; +} + +uint64_t mpz_tdiv_qr_ui (mpz_t q, mpz_t r, const mpz_t n, uint64_t d) +{ + return mpz_div_qr_ui (q, r, n, d, GMP_DIV_TRUNC); +} + +void mpn_copyd (mp_ptr d, mp_srcptr s, mp_size_t n) +{ + while (--n >= 0) + d[n] = s[n]; +} + +void mpn_zero(mp_ptr rp, mp_size_t n) +{ + while (--n >= 0) + rp[n] = 0; +} + +void mpz_mul_2exp (mpz_t r, const mpz_t u, mp_bitcnt_t bits) +{ + mp_size_t un,rn,limbs; uint32_t shift; mp_ptr rp; + un = GMP_ABS (u->_mp_size); + if (un == 0) + { + r->_mp_size = 0; + return; + } + limbs = bits / GMP_LIMB_BITS; + shift = bits % GMP_LIMB_BITS; + rn = un + limbs + (shift > 0); + rp = MPZ_REALLOC (r, rn); + if (shift > 0) + { + mp_limb_t cy = mpn_lshift (rp + limbs, u->_mp_d, un, shift); + rp[rn-1] = cy; + rn -= (cy == 0); + } + else mpn_copyd (rp + limbs, u->_mp_d, un); + mpn_zero (rp, limbs); + r->_mp_size = (int32_t)((u->_mp_size < 0) ? - rn : rn); +} #include @@ -4420,7 +4386,7 @@ int32_t bitcoin_base58decode(uint8_t *data,char *coinaddr) } zeroes = 0; for (p=coinaddr; *p==base58_chars[0]; p++) - zeroes++; + data[zeroes++] = 0; mpz_export(data+zeroes,&count,1,sizeof(data[0]),-1,0,bn); if ( count >= 2 && data[count - 1] == 0 && data[count - 2] >= 0x80 ) count--; @@ -4428,8 +4394,60 @@ int32_t bitcoin_base58decode(uint8_t *data,char *coinaddr) //memset(data,0,be_sz); //for (i=0; i=0; i--) + { + mpz_mul_2exp(bn,bn,64); + if ( x.ulongs[i] != 0 ) + mpz_add_ui(bn,bn,x.ulongs[i]); + } +} + +bits256 mpz_to_bits256(mpz_t bn) +{ + bits256 x,rev; size_t count; int32_t i; + mpz_export(rev.bytes,&count,1,sizeof(uint64_t),1,0,bn); + for (i=0; i<32; i++) + x.bytes[i] = rev.bytes[31-i]; + return(x); +} + +bits256 mpz_muldivcmp(bits256 oldval,int32_t mulval,int32_t divval,bits256 targetval) +{ + mpz_t bn,target; bits256 newval; + //printf("mulval.%d divval.%d]\n",mulval,divval); + mpz_init(bn), mpz_init(target); + mpz_from_bits256(bn,oldval); + mpz_mul_ui(bn,bn,mulval); + mpz_tdiv_qr_ui(bn,NULL,bn,divval); + if ( bn->_mp_size <= 0 || mpz_cmp(bn,target) > 0 ) + newval = targetval; + newval = mpz_to_bits256(bn); + //char *bits256_str(char *,bits256); + //char str[65],str2[65]; printf("%s mul.%d div.%d -> %s size.%d\n",bits256_str(str,oldval),mulval,divval,bits256_str(str2,newval),bn->_mp_size); + mpz_clear(bn), mpz_clear(target); + return(newval); +} + +bits256 mpz_div64(bits256 hash,uint64_t divval) +{ + mpz_t bn; bits256 newval; + mpz_init(bn); + mpz_from_bits256(bn,hash); + mpz_tdiv_qr_ui(bn,NULL,bn,divval); + newval = mpz_to_bits256(bn); + //char *bits256_str(char *,bits256); + //char str[65],str2[65]; printf("%s div.%lld -> %s size.%d\n",bits256_str(str,hash),(long long)divval,bits256_str(str2,newval),bn->_mp_size); + mpz_clear(bn); + return(newval); +} diff --git a/iguana/mini-gmp.h b/iguana/mini-gmp.h index 8fb56babf..75f5a3aac 100644 --- a/iguana/mini-gmp.h +++ b/iguana/mini-gmp.h @@ -55,18 +55,18 @@ void mp_get_memory_functions (void *(**) (size_t), void *(**) (void *, size_t, size_t), void (**) (void *, size_t)); -typedef unsigned long mp_limb_t; -typedef long mp_size_t; -typedef unsigned long mp_bitcnt_t; +typedef uint64_t mp_limb_t; +typedef int64_t mp_size_t; +typedef uint64_t mp_bitcnt_t; typedef mp_limb_t *mp_ptr; typedef const mp_limb_t *mp_srcptr; typedef struct { - int _mp_alloc; /* Number of *limbs* allocated and pointed + int32_t _mp_alloc; /* Number of *limbs* allocated and pointed to by the _mp_d field. */ - int _mp_size; /* abs(_mp_size) is the number of limbs the + int32_t _mp_size; /* abs(_mp_size) is the number of limbs the last field points to. If _mp_size is negative this is a negative number. */ mp_limb_t *_mp_d; /* Pointer to the limbs. */ @@ -77,14 +77,14 @@ typedef __mpz_struct mpz_t[1]; typedef __mpz_struct *mpz_ptr; typedef const __mpz_struct *mpz_srcptr; -extern const int mp_bits_per_limb; +extern const int32_t mp_bits_per_limb; void mpn_copyi (mp_ptr, mp_srcptr, mp_size_t); void mpn_copyd (mp_ptr, mp_srcptr, mp_size_t); void mpn_zero (mp_ptr, mp_size_t); -int mpn_cmp (mp_srcptr, mp_srcptr, mp_size_t); -int mpn_zero_p (mp_srcptr, mp_size_t); +int32_t mpn_cmp (mp_srcptr, mp_srcptr, mp_size_t); +int32_t mpn_zero_p (mp_srcptr, mp_size_t); mp_limb_t mpn_add_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t); mp_limb_t mpn_add_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t); @@ -101,11 +101,11 @@ mp_limb_t mpn_submul_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t); mp_limb_t mpn_mul (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t); void mpn_mul_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t); void mpn_sqr (mp_ptr, mp_srcptr, mp_size_t); -int mpn_perfect_square_p (mp_srcptr, mp_size_t); +int32_t mpn_perfect_square_p (mp_srcptr, mp_size_t); mp_size_t mpn_sqrtrem (mp_ptr, mp_ptr, mp_srcptr, mp_size_t); -mp_limb_t mpn_lshift (mp_ptr, mp_srcptr, mp_size_t, unsigned int); -mp_limb_t mpn_rshift (mp_ptr, mp_srcptr, mp_size_t, unsigned int); +mp_limb_t mpn_lshift (mp_ptr, mp_srcptr, mp_size_t, uint32_t); +mp_limb_t mpn_rshift (mp_ptr, mp_srcptr, mp_size_t, uint32_t); mp_bitcnt_t mpn_scan0 (mp_srcptr, mp_bitcnt_t); mp_bitcnt_t mpn_scan1 (mp_srcptr, mp_bitcnt_t); @@ -115,42 +115,42 @@ mp_bitcnt_t mpn_popcount (mp_srcptr, mp_size_t); mp_limb_t mpn_invert_3by2 (mp_limb_t, mp_limb_t); #define mpn_invert_limb(x) mpn_invert_3by2 ((x), 0) -size_t mpn_get_str (unsigned char *, int, mp_ptr, mp_size_t); -mp_size_t mpn_set_str (mp_ptr, const unsigned char *, size_t, int); +size_t mpn_get_str (uint8_t *, int32_t, mp_ptr, mp_size_t); +mp_size_t mpn_set_str (mp_ptr, const uint8_t *, size_t, int32_t); void mpz_init (mpz_t); void mpz_init2 (mpz_t, mp_bitcnt_t); void mpz_clear (mpz_t); -#define mpz_odd_p(z) (((z)->_mp_size != 0) & (int) (z)->_mp_d[0]) +#define mpz_odd_p(z) (((z)->_mp_size != 0) & (int32_t) (z)->_mp_d[0]) #define mpz_even_p(z) (! mpz_odd_p (z)) -int mpz_sgn (const mpz_t); -int mpz_cmp_si (const mpz_t, long); -int mpz_cmp_ui (const mpz_t, unsigned long); -int mpz_cmp (const mpz_t, const mpz_t); -int mpz_cmpabs_ui (const mpz_t, unsigned long); -int mpz_cmpabs (const mpz_t, const mpz_t); -int mpz_cmp_d (const mpz_t, double); -int mpz_cmpabs_d (const mpz_t, double); +int32_t mpz_sgn (const mpz_t); +int32_t mpz_cmp_si (const mpz_t, int64_t); +int32_t mpz_cmp_ui (const mpz_t, uint64_t); +int32_t mpz_cmp (const mpz_t, const mpz_t); +int32_t mpz_cmpabs_ui (const mpz_t, uint64_t); +int32_t mpz_cmpabs (const mpz_t, const mpz_t); +int32_t mpz_cmp_d (const mpz_t, double); +int32_t mpz_cmpabs_d (const mpz_t, double); void mpz_abs (mpz_t, const mpz_t); void mpz_neg (mpz_t, const mpz_t); void mpz_swap (mpz_t, mpz_t); -void mpz_add_ui (mpz_t, const mpz_t, unsigned long); +void mpz_add_ui (mpz_t, const mpz_t, uint64_t); void mpz_add (mpz_t, const mpz_t, const mpz_t); -void mpz_sub_ui (mpz_t, const mpz_t, unsigned long); -void mpz_ui_sub (mpz_t, unsigned long, const mpz_t); +void mpz_sub_ui (mpz_t, const mpz_t, uint64_t); +void mpz_ui_sub (mpz_t, uint64_t, const mpz_t); void mpz_sub (mpz_t, const mpz_t, const mpz_t); -void mpz_mul_si (mpz_t, const mpz_t, long int); -void mpz_mul_ui (mpz_t, const mpz_t, unsigned long int); +void mpz_mul_si (mpz_t, const mpz_t, int64_t); +void mpz_mul_ui (mpz_t, const mpz_t, uint64_t); void mpz_mul (mpz_t, const mpz_t, const mpz_t); void mpz_mul_2exp (mpz_t, const mpz_t, mp_bitcnt_t); -void mpz_addmul_ui (mpz_t, const mpz_t, unsigned long int); +void mpz_addmul_ui (mpz_t, const mpz_t, uint64_t); void mpz_addmul (mpz_t, const mpz_t, const mpz_t); -void mpz_submul_ui (mpz_t, const mpz_t, unsigned long int); +void mpz_submul_ui (mpz_t, const mpz_t, uint64_t); void mpz_submul (mpz_t, const mpz_t, const mpz_t); void mpz_cdiv_qr (mpz_t, mpz_t, const mpz_t, const mpz_t); @@ -174,53 +174,53 @@ void mpz_mod (mpz_t, const mpz_t, const mpz_t); void mpz_divexact (mpz_t, const mpz_t, const mpz_t); -int mpz_divisible_p (const mpz_t, const mpz_t); -int mpz_congruent_p (const mpz_t, const mpz_t, const mpz_t); +int32_t mpz_divisible_p (const mpz_t, const mpz_t); +int32_t mpz_congruent_p (const mpz_t, const mpz_t, const mpz_t); -unsigned long mpz_cdiv_qr_ui (mpz_t, mpz_t, const mpz_t, unsigned long); -unsigned long mpz_fdiv_qr_ui (mpz_t, mpz_t, const mpz_t, unsigned long); -unsigned long mpz_tdiv_qr_ui (mpz_t, mpz_t, const mpz_t, unsigned long); -unsigned long mpz_cdiv_q_ui (mpz_t, const mpz_t, unsigned long); -unsigned long mpz_fdiv_q_ui (mpz_t, const mpz_t, unsigned long); -unsigned long mpz_tdiv_q_ui (mpz_t, const mpz_t, unsigned long); -unsigned long mpz_cdiv_r_ui (mpz_t, const mpz_t, unsigned long); -unsigned long mpz_fdiv_r_ui (mpz_t, const mpz_t, unsigned long); -unsigned long mpz_tdiv_r_ui (mpz_t, const mpz_t, unsigned long); -unsigned long mpz_cdiv_ui (const mpz_t, unsigned long); -unsigned long mpz_fdiv_ui (const mpz_t, unsigned long); -unsigned long mpz_tdiv_ui (const mpz_t, unsigned long); +uint64_t mpz_cdiv_qr_ui (mpz_t, mpz_t, const mpz_t, uint64_t); +uint64_t mpz_fdiv_qr_ui (mpz_t, mpz_t, const mpz_t, uint64_t); +uint64_t mpz_tdiv_qr_ui (mpz_t, mpz_t, const mpz_t, uint64_t); +uint64_t mpz_cdiv_q_ui (mpz_t, const mpz_t, uint64_t); +uint64_t mpz_fdiv_q_ui (mpz_t, const mpz_t, uint64_t); +uint64_t mpz_tdiv_q_ui (mpz_t, const mpz_t, uint64_t); +uint64_t mpz_cdiv_r_ui (mpz_t, const mpz_t, uint64_t); +uint64_t mpz_fdiv_r_ui (mpz_t, const mpz_t, uint64_t); +uint64_t mpz_tdiv_r_ui (mpz_t, const mpz_t, uint64_t); +uint64_t mpz_cdiv_ui (const mpz_t, uint64_t); +uint64_t mpz_fdiv_ui (const mpz_t, uint64_t); +uint64_t mpz_tdiv_ui (const mpz_t, uint64_t); -unsigned long mpz_mod_ui (mpz_t, const mpz_t, unsigned long); +uint64_t mpz_mod_ui (mpz_t, const mpz_t, uint64_t); -void mpz_divexact_ui (mpz_t, const mpz_t, unsigned long); +void mpz_divexact_ui (mpz_t, const mpz_t, uint64_t); -int mpz_divisible_ui_p (const mpz_t, unsigned long); +int32_t mpz_divisible_ui_p (const mpz_t, uint64_t); -unsigned long mpz_gcd_ui (mpz_t, const mpz_t, unsigned long); +uint64_t mpz_gcd_ui (mpz_t, const mpz_t, uint64_t); void mpz_gcd (mpz_t, const mpz_t, const mpz_t); void mpz_gcdext (mpz_t, mpz_t, mpz_t, const mpz_t, const mpz_t); -void mpz_lcm_ui (mpz_t, const mpz_t, unsigned long); +void mpz_lcm_ui (mpz_t, const mpz_t, uint64_t); void mpz_lcm (mpz_t, const mpz_t, const mpz_t); -int mpz_invert (mpz_t, const mpz_t, const mpz_t); +int32_t mpz_invert (mpz_t, const mpz_t, const mpz_t); void mpz_sqrtrem (mpz_t, mpz_t, const mpz_t); void mpz_sqrt (mpz_t, const mpz_t); -int mpz_perfect_square_p (const mpz_t); +int32_t mpz_perfect_square_p (const mpz_t); -void mpz_pow_ui (mpz_t, const mpz_t, unsigned long); -void mpz_ui_pow_ui (mpz_t, unsigned long, unsigned long); +void mpz_pow_ui (mpz_t, const mpz_t, uint64_t); +void mpz_ui_pow_ui (mpz_t, uint64_t, uint64_t); void mpz_powm (mpz_t, const mpz_t, const mpz_t, const mpz_t); -void mpz_powm_ui (mpz_t, const mpz_t, unsigned long, const mpz_t); +void mpz_powm_ui (mpz_t, const mpz_t, uint64_t, const mpz_t); -void mpz_rootrem (mpz_t, mpz_t, const mpz_t, unsigned long); -int mpz_root (mpz_t, const mpz_t, unsigned long); +void mpz_rootrem (mpz_t, mpz_t, const mpz_t, uint64_t); +int32_t mpz_root (mpz_t, const mpz_t, uint64_t); -void mpz_fac_ui (mpz_t, unsigned long); -void mpz_bin_uiui (mpz_t, unsigned long, unsigned long); +void mpz_fac_ui (mpz_t, uint64_t); +void mpz_bin_uiui (mpz_t, uint64_t, uint64_t); -int mpz_probab_prime_p (const mpz_t, int); +int32_t mpz_probab_prime_p (const mpz_t, int32_t); -int mpz_tstbit (const mpz_t, mp_bitcnt_t); +int32_t mpz_tstbit (const mpz_t, mp_bitcnt_t); void mpz_setbit (mpz_t, mp_bitcnt_t); void mpz_clrbit (mpz_t, mp_bitcnt_t); void mpz_combit (mpz_t, mp_bitcnt_t); @@ -235,10 +235,10 @@ mp_bitcnt_t mpz_hamdist (const mpz_t, const mpz_t); mp_bitcnt_t mpz_scan0 (const mpz_t, mp_bitcnt_t); mp_bitcnt_t mpz_scan1 (const mpz_t, mp_bitcnt_t); -int mpz_fits_slong_p (const mpz_t); -int mpz_fits_ulong_p (const mpz_t); -long int mpz_get_si (const mpz_t); -unsigned long int mpz_get_ui (const mpz_t); +int32_t mpz_fits_slong_p (const mpz_t); +int32_t mpz_fits_ulong_p (const mpz_t); +int64_t mpz_get_si (const mpz_t); +uint64_t mpz_get_ui (const mpz_t); double mpz_get_d (const mpz_t); size_t mpz_size (const mpz_t); mp_limb_t mpz_getlimbn (const mpz_t, mp_size_t); @@ -252,20 +252,20 @@ mpz_srcptr mpz_roinit_n (mpz_t, mp_srcptr, mp_size_t); #define MPZ_ROINIT_N(xp, xs) {{0, (xs),(xp) }} -void mpz_set_si (mpz_t, signed long int); -void mpz_set_ui (mpz_t, unsigned long int); +void mpz_set_si (mpz_t, int64_t); +void mpz_set_ui (mpz_t, uint64_t); void mpz_set (mpz_t, const mpz_t); void mpz_set_d (mpz_t, double); -void mpz_init_set_si (mpz_t, signed long int); -void mpz_init_set_ui (mpz_t, unsigned long int); +void mpz_init_set_si (mpz_t, int64_t); +void mpz_init_set_ui (mpz_t, uint64_t); void mpz_init_set (mpz_t, const mpz_t); void mpz_init_set_d (mpz_t, double); -size_t mpz_sizeinbase (const mpz_t, int); -char *mpz_get_str (char *, int, const mpz_t); -int mpz_set_str (mpz_t, const char *, int); -int mpz_init_set_str (mpz_t, const char *, int); +size_t mpz_sizeinbase (const mpz_t, int32_t); +char *mpz_get_str (char *, int32_t, const mpz_t); +int32_t mpz_set_str (mpz_t, const char *, int32_t); +int32_t mpz_init_set_str (mpz_t, const char *, int32_t); /* This long list taken from gmp.h. */ /* For reference, "defined(EOF)" cannot be used here. In g++ 2.95.4, @@ -285,11 +285,11 @@ int mpz_init_set_str (mpz_t, const char *, int); || defined (_STDIO_H_INCLUDED) /* QNX4 */ \ || defined (_ISO_STDIO_ISO_H) /* Sun C++ */ \ || defined (__STDIO_LOADED) /* VMS */ -size_t mpz_out_str (FILE *, int, const mpz_t); +size_t mpz_out_str (FILE *, int32_t, const mpz_t); #endif -void mpz_import (mpz_t, size_t, int, size_t, int, size_t, const void *); -void *mpz_export (void *, size_t *, int, size_t, int, size_t, const mpz_t); +void mpz_import (mpz_t, size_t, int32_t, size_t, int32_t, size_t, const void *); +void *mpz_export (void *, size_t *, int32_t, size_t, int32_t, size_t, const mpz_t); #define GMP_LIMB_BITS (sizeof(mp_limb_t) * CHAR_BIT) #define GMP_NAIL_BITS 0 #define GMP_NUMB_BITS (GMP_LIMB_BITS - GMP_NAIL_BITS) diff --git a/iguana/pangea777.h b/iguana/pangea777.h index e20e1d294..56a71e57b 100755 --- a/iguana/pangea777.h +++ b/iguana/pangea777.h @@ -118,7 +118,6 @@ bits256 xoverz_donna(bits256 a); bits256 crecip_donna(bits256 a); bits256 fmul_donna(bits256 a,bits256 b); -void calc_shares(unsigned char *shares,unsigned char *secret,int32_t size,int32_t width,int32_t M,int32_t N,unsigned char *sharenrs); int32_t init_sharenrs(unsigned char sharenrs[255],unsigned char *orig,int32_t m,int32_t n); struct pangea_msghdr @@ -146,7 +145,7 @@ bits256 cards777_pubkeys(bits256 *pubkeys,int32_t numcards,bits256 cmppubkey); int32_t cards777_checkcard(bits256 *cardprivp,int32_t cardi,int32_t slot,int32_t destplayer,bits256 playerpriv,bits256 *cardpubs,int32_t numcards,bits256 card); int32_t cards777_validate(bits256 cardpriv,bits256 final,bits256 *cardpubs,int32_t numcards,bits256 *audit,int32_t numplayers,bits256 playerpub); bits256 cards777_decode(bits256 *seedp,bits256 *xoverz,int32_t destplayer,bits256 cipher,bits256 *outcards,int32_t numcards,int32_t N); -uint8_t *cards777_encode(bits256 *encoded,bits256 *xoverz,uint8_t *allshares,uint8_t *myshares[],uint8_t sharenrs[255],int32_t M,bits256 *ciphers,int32_t numcards,int32_t N); +uint8_t *cards777_encode(struct supernet_info *myinfo,bits256 *encoded,bits256 *xoverz,uint8_t *allshares,uint8_t *myshares[],uint8_t sharenrs[255],int32_t M,bits256 *ciphers,int32_t numcards,int32_t N); void pangea_sendcmd(struct supernet_info *myinfo,struct table_info *tp,char *cmdstr,int32_t destplayer,uint8_t *data,int32_t datalen,int32_t cardi,int32_t turni); void pangea_summaryadd(struct supernet_info *myinfo,struct table_info *tp,uint8_t type,void *arg0,int32_t size0,void *arg1,int32_t size1); diff --git a/iguana/pangea_api.c b/iguana/pangea_api.c index 551def012..3329fd45f 100755 --- a/iguana/pangea_api.c +++ b/iguana/pangea_api.c @@ -181,11 +181,10 @@ struct table_info *pangea_tablealloc(struct table_info *tp,int32_t N) return(tp); } -struct table_info *pangea_table(bits256 tablehash,int32_t N) +struct table_info *pangea_table(struct supernet_info *myinfo,bits256 tablehash,int32_t N) { - struct table_info *tp; bits256 pangeahash; char str[65]; - pangeahash = calc_categoryhashes(0,"pangea",0); - if ( (tp= category_info(pangeahash,tablehash)) == 0 && N > 0 ) + /*struct table_info *tp; char str[65]; + if ( (tp= gecko_chain(myinfo->pangea_category,tablehash)) == 0 && N > 0 ) { tp = pangea_tablealloc(0,N); memset(tp,0,sizeof(*tp)); @@ -197,12 +196,13 @@ struct table_info *pangea_table(bits256 tablehash,int32_t N) } if ( tp != 0 ) { - category_subscribe(SuperNET_MYINFO(0),pangeahash,tablehash); - if ( category_infoset(pangeahash,tablehash,tp) == 0 ) + category_subscribe(SuperNET_MYINFO(0),myinfo->pangea_category,tablehash); + if ( gecko_chainset(myinfo->pangea_category,tablehash,tp) == 0 ) printf("error: couldnt set table.(%s)\n",bits256_str(str,tablehash)), tp = 0; //else tp->G.allocsize = allocsize; } - return(tp); + return(tp);*/ + return(0); } struct player_info *pangea_playerfind(struct supernet_info *myinfo,struct table_info *tp) @@ -220,11 +220,9 @@ struct player_info *pangea_playerfind(struct supernet_info *myinfo,struct table_ char *pangea_jsondatacmd(struct supernet_info *myinfo,bits256 tablehash,struct pangea_msghdr *pm,cJSON *json,char *cmdstr,char *ipaddr) { - cJSON *argjson; char *reqstr,hexstr[8192]; uint64_t nxt64bits; - struct table_info *tp; int32_t i,datalen; bits256 pangeahash; - pangeahash = calc_categoryhashes(0,"pangea",0); - category_subscribe(myinfo,pangeahash,GENESIS_PUBKEY); - category_subscribe(myinfo,pangeahash,tablehash); + /*cJSON *argjson; char *reqstr,hexstr[8192]; uint64_t nxt64bits; struct table_info *tp; int32_t i,datalen; + category_subscribe(myinfo,myinfo->pangea_category,GENESIS_PUBKEY); + category_subscribe(myinfo,myinfo->pangea_category,tablehash); argjson = json != 0 ? jduplicate(json) : cJSON_CreateObject(); jaddstr(argjson,"cmd",cmdstr); if ( myinfo->ipaddr[0] == 0 || strncmp(myinfo->ipaddr,"127.0.0.1",strlen("127.0.0.1")) == 0 ) @@ -232,13 +230,13 @@ char *pangea_jsondatacmd(struct supernet_info *myinfo,bits256 tablehash,struct p jaddstr(argjson,"agent","SuperNET"); jaddstr(argjson,"method","DHT"); jaddstr(argjson,"playeripaddr",ipaddr); - jaddbits256(argjson,"categoryhash",pangeahash); + jaddbits256(argjson,"categoryhash",myinfo->pangea_category); jaddbits256(argjson,"subhash",tablehash); jaddbits256(argjson,"mypub",myinfo->myaddr.pubkey); jaddbits256(argjson,"playerpub",myinfo->myaddr.persistent); jaddstr(argjson,"handle",jstr(json,"handle")); nxt64bits = acct777_nxt64bits(myinfo->myaddr.persistent); - if ( (tp= pangea_table(tablehash,9)) != 0 && tp->G.numactive < tp->G.maxplayers ) + if ( (tp= pangea_table(myinfo,tablehash,9)) != 0 && tp->G.numactive < tp->G.maxplayers ) { for (i=0; iG.numactive; i++) if ( tp->G.P[i].nxt64bits == nxt64bits ) @@ -263,18 +261,19 @@ char *pangea_jsondatacmd(struct supernet_info *myinfo,bits256 tablehash,struct p { printf("pangea send.(%s)\n",cmdstr); init_hexbytes_noT(hexstr,(uint8_t *)pm,pm->sig.allocsize); - return(SuperNET_categorymulticast(myinfo,0,pangeahash,tablehash,hexstr,0,2,1,argjson,0)); + return(SuperNET_categorymulticast(myinfo,0,myinfo->pangea_category,tablehash,hexstr,0,2,1,argjson,0)); } else { printf("cant msgcreate\n"); return(clonestr("{\"error\":\"couldnt create pangea message\"}")); - } + }*/ + return(0); } void pangea_sendcmd(struct supernet_info *myinfo,struct table_info *tp,char *cmdstr,int32_t destplayer,uint8_t *data,int32_t datalen,int32_t cardi,int32_t turni) { - struct player_info *p; struct pangea_msghdr *pm; char *str,*hexstr; int32_t plaintext,loopback = 0; + /*struct player_info *p; struct pangea_msghdr *pm; char *str,*hexstr; int32_t plaintext,loopback = 0; pm = calloc(1,sizeof(*pm) + datalen);//(void *)tp->space; memset(pm,0,sizeof(*pm)); strncpy(pm->cmd,cmdstr,8); @@ -297,8 +296,8 @@ void pangea_sendcmd(struct supernet_info *myinfo,struct table_info *tp,char *cmd } else if ( (p= tp->active[destplayer]) != 0 ) { - if ( (str= SuperNET_DHTsend(myinfo,p->ipbits,tp->G.gamehash,tp->G.tablehash,hexstr,0,0,plaintext)) != 0 ) - free(str); + //if ( (str= SuperNET_DHTsend(myinfo,p->ipbits,tp->G.gamehash,tp->G.tablehash,hexstr,0,0,plaintext)) != 0 ) + // free(str); } if ( loopback != 0 ) { @@ -307,7 +306,7 @@ void pangea_sendcmd(struct supernet_info *myinfo,struct table_info *tp,char *cmd } free(hexstr); } - free(pm); + free(pm);*/ } void pangea_tablejoin(struct supernet_info *myinfo,struct table_info *tp,uint8_t *data,int32_t datalen,uint64_t signer64bits,uint32_t sigtimestamp,bits256 sigtablehash) @@ -408,7 +407,7 @@ void pangea_parse(struct supernet_info *myinfo,struct pangea_msghdr *pm,cJSON *a { bits256 tablehash; char *method; struct table_info *tp; tablehash = jbits256(argjson,"subhash"); - tp = pangea_table(tablehash,9); + tp = pangea_table(myinfo,tablehash,9); if ( (method= jstr(argjson,"cmd")) != 0 ) { if ( strcmp(method,"lobby") == 0 ) @@ -454,7 +453,7 @@ void pangea_addfunds(PANGEA_HANDARGS) printf("got remote addfunds\n"); } -char *pangea_hexmsg(struct supernet_info *myinfo,struct category_info *cat,void *data,int32_t len,char *remoteaddr) +char *pangea_hexmsg(struct supernet_info *myinfo,struct gecko_chain *cat,void *data,int32_t len,char *remoteaddr) { static struct { char *cmdstr; void (*func)(PANGEA_HANDARGS); uint64_t cmdbits; } tablecmds[] = { @@ -504,7 +503,7 @@ char *pangea_hexmsg(struct supernet_info *myinfo,struct category_info *cat,void } else { - if ( (tp= pangea_table(tablehash,9)) != 0 && pangea_rwdata(0,pm->serialized,len-(int32_t)((long)pm->serialized-(long)pm),pm->serialized) > 0 ) + if ( (tp= pangea_table(myinfo,tablehash,9)) != 0 && pangea_rwdata(0,pm->serialized,len-(int32_t)((long)pm->serialized-(long)pm),pm->serialized) > 0 ) { cmdbits = stringbits(pm->cmd); for (i=0; iG.allocsize < allocsize ) tp = pangea_tablealloc(tp,9); - category_infoset(tp->G.gamehash,tp->G.tablehash,tp); + printf("deprecated usage of chainset\n"); + //gecko_chainset(tp->G.gamehash,tp->G.tablehash,tp); if ( strcmp(tablecmds[i].cmdstr,"newhand") == 0 ) { tp->G.numactive = pm->turni; @@ -541,9 +541,8 @@ char *pangea_hexmsg(struct supernet_info *myinfo,struct category_info *cat,void void pangea_update(struct supernet_info *myinfo) { - struct pangea_msghdr *pm; struct category_msg *m; bits256 pangeahash; char remoteaddr[64],*str; struct category_info *cat = 0; - pangeahash = calc_categoryhashes(0,"pangea",0); - while ( (m= category_gethexmsg(myinfo,&cat,pangeahash,GENESIS_PUBKEY)) != 0 ) + /*struct pangea_msghdr *pm; struct category_msg *m; char remoteaddr[64],*str; struct gecko_chain *cat = 0; + while ( (m= category_gethexmsg(myinfo,&cat,myinfo->pangea_category,GENESIS_PUBKEY)) != 0 ) { pm = (struct pangea_msghdr *)m->msg; if ( m->remoteipbits != 0 ) @@ -552,7 +551,7 @@ void pangea_update(struct supernet_info *myinfo) if ( (str= pangea_hexmsg(myinfo,cat,pm,m->len,remoteaddr)) != 0 ) free(str); free(m); - } + }*/ } /* char *_pangea_status(struct supernet_info *myinfo,bits256 tablehash,cJSON *json) @@ -713,7 +712,7 @@ HASH_ARG(pangea,call,tablehash) struct table_info *tp; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); - if ( (tp= pangea_table(tablehash,0)) == 0 ) + if ( (tp= pangea_table(myinfo,tablehash,0)) == 0 ) return(clonestr("{\"result\":\"table doesnt exist\"}")); else return(pangea_submitaction(myinfo,tp,0,CARDS777_CALL,"call")); } @@ -723,7 +722,7 @@ HASH_AND_INT(pangea,raise,tablehash,numchips) struct table_info *tp; int64_t value; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); - if ( (tp= pangea_table(tablehash,0)) == 0 ) + if ( (tp= pangea_table(myinfo,tablehash,0)) == 0 ) return(clonestr("{\"result\":\"table doesnt exist\"}")); else { @@ -737,7 +736,7 @@ HASH_ARG(pangea,allin,tablehash) struct table_info *tp; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); - if ( (tp= pangea_table(tablehash,0)) == 0 ) + if ( (tp= pangea_table(myinfo,tablehash,0)) == 0 ) return(clonestr("{\"result\":\"table doesnt exist\"}")); else return(pangea_submitaction(myinfo,tp,0,CARDS777_ALLIN,"allin")); } @@ -747,7 +746,7 @@ HASH_AND_INT(pangea,bet,tablehash,numchips) struct table_info *tp; int64_t value; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); - if ( (tp= pangea_table(tablehash,0)) == 0 ) + if ( (tp= pangea_table(myinfo,tablehash,0)) == 0 ) return(clonestr("{\"result\":\"table doesnt exist\"}")); else { @@ -761,7 +760,7 @@ HASH_ARG(pangea,check,tablehash) struct table_info *tp; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); - if ( (tp= pangea_table(tablehash,0)) == 0 ) + if ( (tp= pangea_table(myinfo,tablehash,0)) == 0 ) return(clonestr("{\"result\":\"table doesnt exist\"}")); else return(pangea_submitaction(myinfo,tp,0,CARDS777_CHECK,"check")); } @@ -771,7 +770,7 @@ HASH_ARG(pangea,fold,tablehash) struct table_info *tp; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); - if ( (tp= pangea_table(tablehash,0)) == 0 ) + if ( (tp= pangea_table(myinfo,tablehash,0)) == 0 ) return(clonestr("{\"result\":\"table doesnt exist\"}")); else return(pangea_submitaction(myinfo,tp,0,CARDS777_FOLD,"fold")); } @@ -781,7 +780,7 @@ HASH_ARG(pangea,status,tablehash) struct table_info *tp; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); - if ( (tp= pangea_table(tablehash,0)) == 0 ) + if ( (tp= pangea_table(myinfo,tablehash,0)) == 0 ) return(clonestr("{\"result\":\"table doesnt exist\"}")); else return(jprint(pangea_tablestatus(myinfo,tp),1)); } @@ -812,8 +811,7 @@ ZERO_ARGS(pangea,lobby) //cJSON *retjson,*argjson; char *retstr,*result; uint8_t *buf; int32_t flag,len; struct pangea_msghdr *pm; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); - bits256 pangeahash = calc_categoryhashes(0,"pangea",0); - category_subscribe(myinfo,pangeahash,GENESIS_PUBKEY); + category_subscribe(myinfo,myinfo->pangea_category,GENESIS_PUBKEY); pangea_update(myinfo); return(jprint(pangea_lobbyjson(myinfo),1)); } @@ -824,7 +822,7 @@ INT_AND_ARRAY(pangea,host,minplayers,params) if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); OS_randombytes(tablehash.bytes,sizeof(tablehash)); - tp = pangea_table(tablehash,9); + tp = pangea_table(myinfo,tablehash,9); if ( tp != 0 ) { pangea_gamecreate(&tp->G,(uint32_t)time(NULL),tablehash,json); @@ -846,7 +844,7 @@ HASH_AND_INT(pangea,buyin,tablehash,numchips) uint8_t space[sizeof(struct pangea_msghdr) + 4096]; struct table_info *tp; int64_t value; cJSON *fundsjson; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); - if ( (tp= pangea_table(tablehash,0)) == 0 ) + if ( (tp= pangea_table(myinfo,tablehash,0)) == 0 ) return(clonestr("{\"result\":\"table doesnt exist\"}")); else { @@ -862,7 +860,7 @@ HASH_ARG(pangea,start,tablehash) struct table_info *tp; int32_t allocsize; if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); - if ( (tp= pangea_table(tablehash,9)) != 0 ) + if ( (tp= pangea_table(myinfo,tablehash,9)) != 0 ) { if ( tp->G.numactive >= tp->G.minplayers && pangea_tableismine(myinfo,tp) >= 0 ) { @@ -870,7 +868,8 @@ HASH_ARG(pangea,start,tablehash) if ( tp->G.allocsize < allocsize ) { tp = pangea_tablealloc(tp,9); - category_infoset(tp->G.gamehash,tp->G.tablehash,tp); + printf("deprecated usage of chainset\n"); + //gecko_chainset(tp->G.gamehash,tp->G.tablehash,tp); } if ( tp->G.creatorbits == myinfo->myaddr.nxt64bits ) pangea_newdeck(myinfo,tp); diff --git a/iguana/pangea_hand.c b/iguana/pangea_hand.c index 2cdd26d2d..9cd6a671b 100755 --- a/iguana/pangea_hand.c +++ b/iguana/pangea_hand.c @@ -336,7 +336,7 @@ void pangea_encoded(PANGEA_HANDARGS) return; } hand->encodestarted = (uint32_t)time(NULL);//pm->sig.timestamp; - cards777_encode(tp->priv.outcards,tp->priv.xoverz,tp->priv.allshares,tp->priv.myshares,hand->sharenrs[tp->priv.myind],tp->G.M,(void *)data,tp->G.numcards,N); + cards777_encode(myinfo,tp->priv.outcards,tp->priv.xoverz,tp->priv.allshares,tp->priv.myshares,hand->sharenrs[tp->priv.myind],tp->G.M,(void *)data,tp->G.numcards,N); PNACL_message("player.%d ind.%d encodes into %p %llx -> %llx next.%d N %d\n",tp->priv.myind,tp->priv.myind,tp->priv.outcards,(long long)*(uint64_t *)data,(long long)tp->priv.outcards[0].txid,pangea_nextnode(tp),N); if ( tp->priv.myind > 0 ) { @@ -418,14 +418,15 @@ int32_t pangea_queueprocess(struct supernet_info *myinfo,struct table_info *tp) void pangea_queues(struct supernet_info *myinfo) { - struct category_info *cat,*sub,*tmp; struct table_info *tp; + struct gecko_chain *cat,*subchain,*tmp; //struct table_info *tp; pangea_update(myinfo); if ( (cat= category_find(calc_categoryhashes(0,"pangea",0),GENESIS_PUBKEY)) != 0 ) { - HASH_ITER(hh,cat->sub,sub,tmp) + HASH_ITER(hh,cat->subchains,subchain,tmp) { - if ( (tp= sub->info) != 0 ) - pangea_queueprocess(myinfo,tp); + printf("undeprecate\n"); + //if ( (tp= sub->info) != 0 ) + // pangea_queueprocess(myinfo,tp); } } } diff --git a/iguana/pangea_json.c b/iguana/pangea_json.c index cc2499128..c325c4a69 100755 --- a/iguana/pangea_json.c +++ b/iguana/pangea_json.c @@ -107,15 +107,16 @@ int32_t pangea_opentable(struct game_info *gp) cJSON *pangea_lobbyjson(struct supernet_info *myinfo) { - struct category_info *cat,*sub,*tmp; struct table_info *tp; cJSON *array,*retjson; + struct gecko_chain *cat,*subchain,*tmp; cJSON *array,*retjson; //struct table_info *tp; retjson = cJSON_CreateObject(); array = cJSON_CreateArray(); if ( (cat= category_find(calc_categoryhashes(0,"pangea",0),GENESIS_PUBKEY)) != 0 ) { - HASH_ITER(hh,cat->sub,sub,tmp) + HASH_ITER(hh,cat->subchains,subchain,tmp) { - if ( (tp= sub->info) != 0 && pangea_opentable(&tp->G) > 0 ) - jaddi(array,pangea_tablestatus(myinfo,tp)); + printf("undeprecate\n"); + //if ( (tp= sub->info) != 0 && pangea_opentable(&tp->G) > 0 ) + // jaddi(array,pangea_tablestatus(myinfo,tp)); } } jadd(retjson,"tables",array); diff --git a/iguana/pangea_summary.c b/iguana/pangea_summary.c index 864ea5676..6bd05741b 100755 --- a/iguana/pangea_summary.c +++ b/iguana/pangea_summary.c @@ -126,10 +126,10 @@ cJSON *pangea_handitem(int32_t *cardip,cJSON **pitemp,uint8_t type,uint64_t valA int32_t pangea_parsesummary(uint8_t *typep,uint64_t *valAp,uint64_t *bits64p,bits256 *cardp,uint8_t *summary,int32_t len) { - int32_t handid; uint16_t cardi_player; uint32_t changes=0; uint8_t player; + //int32_t handid; uint16_t cardi_player; uint32_t changes=0; uint8_t player; *bits64p = 0; memset(cardp,0,sizeof(*cardp)); - len += SuperNET_copybits(1,&summary[len],(void *)typep,sizeof(*typep)); + /*len += SuperNET_copybits(1,&summary[len],(void *)typep,sizeof(*typep)); if ( *typep == 0 ) { printf("len.%d type.%d [%d]\n",len,*typep,summary[len-1]); @@ -152,7 +152,7 @@ int32_t pangea_parsesummary(uint8_t *typep,uint64_t *valAp,uint64_t *bits64p,bit len += SuperNET_copybits(1,&summary[len],(void *)bits64p,sizeof(*bits64p) * CARDS777_MAXPLAYERS); else if ( *typep == CARDS777_CHANGES ) len += SuperNET_copybits(1,&summary[len],(void *)bits64p,sizeof(*bits64p) * (changes & 0xf)); - else len += SuperNET_copybits(1,&summary[len],(void *)bits64p,sizeof(*bits64p)); + else len += SuperNET_copybits(1,&summary[len],(void *)bits64p,sizeof(*bits64p));*/ return(len); } @@ -218,14 +218,14 @@ char *pangea_dispsummary(struct supernet_info *myinfo,struct table_info *tp,int3 void pangea_summaryadd(struct supernet_info *myinfo,struct table_info *tp,uint8_t type,void *arg0,int32_t size0,void *arg1,int32_t size1) { - uint64_t valA,bits64[CARDS777_MAXPLAYERS + (CARDS777_MAXCARDS+1)*4]; - bits256 card; uint8_t checktype; int32_t len,startlen = tp->summarysize; + //uint64_t valA,bits64[CARDS777_MAXPLAYERS + (CARDS777_MAXCARDS+1)*4]; + //bits256 card; uint8_t checktype; int32_t len,startlen = tp->summarysize; if ( type == 0 ) { printf("type.0\n"); getchar(); } //printf("summarysize.%d type.%d [%02x %02x]\n",dp->summarysize,type,*(uint8_t *)arg0,*(uint8_t *)arg1); - tp->summarysize += SuperNET_copybits(0,&tp->summary[tp->summarysize],(void *)&type,sizeof(type)); + /*tp->summarysize += SuperNET_copybits(0,&tp->summary[tp->summarysize],(void *)&type,sizeof(type)); //printf("-> %d\n",tp->summary[tp->summarysize-1]); tp->summarysize += SuperNET_copybits(0,&tp->summary[tp->summarysize],arg0,size0); tp->summarysize += SuperNET_copybits(0,&tp->summary[tp->summarysize],arg1,size1); @@ -236,7 +236,7 @@ void pangea_summaryadd(struct supernet_info *myinfo,struct table_info *tp,uint8_ if ( card.txid != 0 && memcmp(card.bytes,arg1,sizeof(card)) != 0 ) printf("pangea_summary: parse error card mismatch %llx != %llx\n",(long long)card.txid,*(long long *)arg1); else if ( card.txid == 0 && memcmp(arg1,bits64,size1) != 0 ) - printf("pangea_summary: parse error bits64 %llx != %llx\n",(long long)bits64[0],*(long long *)arg0); + printf("pangea_summary: parse error bits64 %llx != %llx\n",(long long)bits64[0],*(long long *)arg0);*/ /*if ( 1 && hn->client->H.slot == pangea_slotA(tp->table) ) { if ( (item= pangea_handitem(&cardi,&pitem,type,valA,bits64,card,tp->G.N)) != 0 ) diff --git a/iguana/peggy.c b/iguana/peggy.c index 2d5073a03..c56c0a98d 100755 --- a/iguana/peggy.c +++ b/iguana/peggy.c @@ -280,7 +280,7 @@ struct peggy *peggy_createpair(struct peggy_info *PEGS,int64_t quorum,int64_t de return(PEG); } -struct peggy_info *peggy_init(char *path,int32_t maxdays,char *maincurrency,uint64_t maincurrencyunitsize,uint64_t quorum,uint64_t decisionthreshold,struct price_resolution spread,uint32_t dailyrate,int32_t interesttenths,int32_t posboost,int32_t negpenalty,int32_t feediv,int32_t feemult,uint32_t firsttimestamp,uint32_t BTCD_price0) +struct peggy_info *peggy_init(int32_t maxdays,char *maincurrency,uint64_t maincurrencyunitsize,uint64_t quorum,uint64_t decisionthreshold,struct price_resolution spread,uint32_t dailyrate,int32_t interesttenths,int32_t posboost,int32_t negpenalty,int32_t feediv,int32_t feemult,uint32_t firsttimestamp,uint32_t BTCD_price0) { //struct peggy_limits limits = { { PERCENTAGE(10), PERCENTAGE(25), PERCENTAGE(33), PERCENTAGE(50) }, SATOSHIDEN * 10000, SATOSHIDEN * 1000, { 0, 30, 90, 180 }, 4 }; struct peggy_lock default_lockparms = { 7, 365, 7, 0, 180, 0, -1 }; @@ -288,7 +288,7 @@ struct peggy_info *peggy_init(char *path,int32_t maxdays,char *maincurrency,uint //if ( default_limits != 0 ) // limits = *default_limits; spread.Pval = PERCENTAGE(1); - OS_ensure_directory(path); + //OS_ensure_directory(path); strcpy(PEGS->maincurrency,maincurrency); PEGS->mainbits = stringbits(maincurrency), PEGS->mainunitsize = maincurrencyunitsize, PEGS->quorum = quorum, PEGS->decisionthreshold = decisionthreshold; PEGS->default_lockparms = default_lockparms, PEGS->default_lockparms.maxlockdays = maxdays; @@ -324,48 +324,11 @@ long hdecode_varint(uint64_t *valp,uint8_t *ptr,long offset,long mappedsize) return(offset); } -struct peggy_info *peggy_genesis(int32_t lookbacks[OPRETURNS_CONTEXTS],struct peggy_info *PEGS,char *path,uint32_t firsttimestamp,char *opreturnstr) +void peggy_priceinits(struct peggy_info *PEGS,uint32_t firsttimestamp,uint32_t *allprices) { - //struct peggy_limits limits = { { PERCENTAGE(10), PERCENTAGE(25), PERCENTAGE(33), PERCENTAGE(50) }, SATOSHIDEN * 10000, SATOSHIDEN * 1000, { 0, 30, 90, 180 }, 4 }; - char name[64],base[64],rel[64]; uint8_t opret[1024]; struct peggy_tx Ptx; struct peggy *PEG; - struct price_resolution mindenom,spread,price; uint64_t len; long offset; uint64_t maxsupply=0,maxnetbalance=0; - int32_t i,c,baseid,relid,peggymils=0,signedcount,datalen,n=0,maxmargin=0,numprices,err=-1; uint32_t pval = 0; - numprices = 1; - datalen = (int32_t)strlen(opreturnstr) / 2; - decode_hex(opret,datalen,opreturnstr); - printf("peggy_genesis(%s)\n",opreturnstr); - if ( opret[0] == OP_RETURN_OPCODE ) - { - offset = hdecode_varint(&len,opret,1,sizeof(opret)); - if ( opret[offset] == 'P' && opret[offset+1] == 'A' && opret[offset+2] == 'X' ) - { - printf("deser\n"); - if ( (n= serdes777_deserialize(&signedcount,&Ptx,firsttimestamp,opret+offset+3,(int32_t)len-3)) > 0 ) - { - err = 0; - for (i=0; iaccts = accts777_init(path,0); - PEGS->genesis = opreturnstr, opreturnstr = 0; - } - } else printf("i.%d vs %d\n",i,Ptx.details.price.num); - } else printf("deser got n.%d\n",n); - } else printf("illegal opret.(%c%c%c)\n",opret[offset],opret[offset+1],opret[offset+2]); - } else printf("opret[0] %d\n",opret[0]); - if ( err < 0 || PEGS == 0 ) - return(0); + char name[64],base[64],rel[64]; struct peggy *PEG; + struct price_resolution mindenom,spread,price; uint64_t maxsupply=0,maxnetbalance=0; + int32_t i,c,baseid,relid,peggymils=0,n=0,maxmargin=0; uint32_t pval = 0; mindenom.Pval = PRICE_RESOLUTION; spread.Pval = PERCENTAGE(1); for (i=1; icontracts[baseid]->peggymils * 10000) / PEGS->contracts[relid]->peggymils; if ( strcmp(PEGS->contracts[baseid]->name.base,base) == 0 && strcmp(PEGS->contracts[relid]->name.base,rel) == 0 ) - price.Pval = (PRICE_RESOLUTION * Ptx.details.price.feed[baseid]) / Ptx.details.price.feed[relid]; + price.Pval = (PRICE_RESOLUTION * allprices[baseid]) / allprices[relid]; else printf("mismatched %p base.(%s) baseid.%d (%s) or %p rel.(%s) relid.%d (%s)\n",PEGS->contracts[baseid],PEGS->contracts[baseid]->name.base,baseid,base,PEGS->contracts[relid],PEGS->contracts[relid]->name.base,relid,rel); pval = (uint32_t)price.Pval; } else printf("peggy_genesis RAN out of space\n"); - if ( (PEG= peggy_createpair(PEGS,0,0,name,base,rel,maxsupply,maxnetbalance,0,SATOSHIDEN*10,PEGGY_RATE_777,firsttimestamp,&price,numprices,spread,maxmargin,mindenom,i,i 0 ) + { + err = 0; + for (i=0; iaccts = accts777_init(path,0); + PEGS->genesis = opreturnstr, opreturnstr = 0; + } + } else printf("i.%d vs %d\n",i,Ptx.details.price.num); + } else printf("deser got n.%d\n",n); + } else printf("illegal opret.(%c%c%c)\n",opret[offset],opret[offset+1],opret[offset+2]); + } else printf("opret[0] %d\n",opret[0]); + if ( err < 0 || PEGS == 0 ) + return(0); + peggy_priceinits(PEGS,firsttimestamp,Ptx.details.price.feed); printf("genesis prices t%u vs %u\n",Ptx.timestamp,firsttimestamp); return(PEGS); } @@ -662,7 +669,7 @@ struct peggy_info *peggy_lchain(struct txinds777_info *opreturns,char *path) int32_t peggy_init_contexts(struct txinds777_info *opreturns,uint32_t RTblocknum,uint32_t RTblocktimestamp,char *path,void *globals[OPRETURNS_CONTEXTS],int32_t lookbacks[OPRETURNS_CONTEXTS],int32_t maxcontexts) { - double startmilli; char buf[512]; struct price_resolution spread; struct peggy_info *PEGS=0,*PEGS2=0; +/* double startmilli; char buf[512]; struct price_resolution spread; struct peggy_info *PEGS=0,*PEGS2=0; if ( maxcontexts != 2 ) { printf("peggy needs 2 contexts\n"); @@ -684,6 +691,17 @@ int32_t peggy_init_contexts(struct txinds777_info *opreturns,uint32_t RTblocknum globals[1] = PEGS2 = peggy_init(buf,PEGGY_MAXLOCKDAYS,"BTCD",SATOSHIDEN/100,1,1,spread,PEGGY_RATE_777,40,10,2,5,2,PEGS->genesistime,PEGS->BTCD_price0); startmilli = OS_milliseconds(); peggy_clone(buf,PEGS2,PEGS); - printf("cloned %d in %.3f millis per opreturn\n",PEGS->numopreturns,(OS_milliseconds() - startmilli)/PEGS->numopreturns); sleep(3); + printf("cloned %d in %.3f millis per opreturn\n",PEGS->numopreturns,(OS_milliseconds() - startmilli)/PEGS->numopreturns); sleep(3);*/ return(2); } + +void peggy_indsinit() +{ + if ( sizeof(Peggy_inds)/sizeof(*Peggy_inds) != PEGGY_NUMCOEFFS ) + { + peggy_geninds(); + printf("need to update Peggy_inds with above\n"); + exit(-1); + } + peggy_dailyrates(); +} diff --git a/iguana/peggy.h b/iguana/peggy.h index c53b219f7..8487269b4 100755 --- a/iguana/peggy.h +++ b/iguana/peggy.h @@ -235,7 +235,7 @@ struct peggy_info int32_t default_dailyrate,interesttenths,posboost,negpenalty,feediv,feemult; int32_t numpegs,numpairedpegs,numpricedpegs,numopreturns,numvoters; struct accts777_info *accts; - struct PAX_data data,tmp; double cryptovols[2][8][2],btcusd,btcdbtc,cnyusd; + struct PAX_data data,tmp; double cryptovols[2][9][2],btcusd,btcdbtc,cnyusd; char path[512],*genesis; uint32_t genesistime,BTCD_price0,lastupdate; struct PAX_spline splines[128]; struct peggy_vote votes[PEGGY_MAXPRICEDPEGS][PEGGY_MAXVOTERS]; @@ -307,13 +307,13 @@ extern int32_t MINDENOMS[],Peggy_inds[],dailyrates[]; struct price_resolution peggy_scaleprice(struct price_resolution price,int64_t peggymils); char *peggy_tx(char *jsonstr); -void _crypto_update(struct peggy_info *PEGS,double cryptovols[2][8][2],struct PAX_data *dp,int32_t selector,int32_t peggyflag); +void _crypto_update(struct peggy_info *PEGS,double cryptovols[2][9][2],struct PAX_data *dp,int32_t selector,int32_t peggyflag); int32_t PAX_idle(struct peggy_info *PEGS,int32_t peggyflag,int32_t idlegap); int32_t PAX_genspline(struct PAX_spline *spline,int32_t splineid,char *name,uint32_t *utc32,double *splinevals,int32_t maxsplines,double *refvals); int32_t PAX_contractnum(char *base,char *rel); int32_t PAX_basenum(char *base); int32_t PAX_ispair(char *base,char *rel,char *contract); -void PAX_init(struct peggy_info *PEGS); +struct peggy_info *PAX_init(); uint32_t peggy_mils(int32_t i); void calc_smooth_code(int32_t smoothwidth,int32_t _maxprimes); struct peggy *peggy_find(struct peggy_entry *entry,struct peggy_info *PEGS,char *name,int32_t polarity); @@ -368,10 +368,13 @@ int32_t peggy_init_contexts(struct txinds777_info *opreturns,uint32_t blocknum,u uint32_t peggy_clone(char *path,void *dest,void *src); void *peggy_replay(char *path,struct txinds777_info *opreturns,void *_PEGS,uint32_t blocknum,char *opreturnstr,uint8_t *data,int32_t datalen); uint32_t peggy_currentblock(void *globals); +struct peggy_info *peggy_init(int32_t maxdays,char *maincurrency,uint64_t maincurrencyunitsize,uint64_t quorum,uint64_t decisionthreshold,struct price_resolution spread,uint32_t dailyrate,int32_t interesttenths,int32_t posboost,int32_t negpenalty,int32_t feediv,int32_t feemult,uint32_t firsttimestamp,uint32_t BTCD_price0); struct peggy_unit *peggy_match(struct accts777_info *accts,int32_t peg,uint64_t nxt64bits,bits256 lockhash,uint16_t lockdays); int32_t peggy_addunit(struct accts777_info *accts,struct peggy_unit *U,bits256 lockhash); FILE *myfopen(char *fname,char *mode); int32_t myfclose(FILE *fp); +void peggy_priceinits(struct peggy_info *PEGS,uint32_t firsttimestamp,uint32_t *allprices); +double PAX_aveprice(struct supernet_info *myinfo,char *base); #endif diff --git a/iguana/peggy_price.c b/iguana/peggy_price.c index cf8997b59..3f0bc77d1 100755 --- a/iguana/peggy_price.c +++ b/iguana/peggy_price.c @@ -76,7 +76,7 @@ short Currency_contractothers[NUM_CURRENCIES+1][NUM_CURRENCIES] = // buggy! int32_t MINDENOMS[] = { 1000, 1000, 100000, 1000, 1000, 1000, 1000, 1000, // major currencies 10000, 100000, 10000, 1000, 100000, 10000, 1000, 10000, 1000, 10000, 10000, 10000, 10000, 100000, 1000, 1000000, 1000, 10000, 1000, 1000, 10000, 1000, 10000000, 10000, // end of currencies 1, 100, 1, 1, // metals, gold must be first - 1, 10, 100000, 100, 100, 10000000, 10000, 1000, 1000, 1000, 100000, 100000, 1000000 // cryptos + 100, 1, 10000, 100, 100, 1000, 100000, 1000, 1000, 1000 }; int32_t PAX_mindenomination(int32_t base) @@ -195,14 +195,14 @@ uint32_t peggy_mils(int32_t i) minmils = 10; else if ( strcmp(peggy_bases[i],"BUND") == 0 || strcmp(peggy_bases[i],"UKOIL") == 0 || strcmp(peggy_bases[i],"USOIL") == 0 ) minmils = 100; - else if ( strncmp(peggy_bases[i],"LTC",3) == 0 || strcmp(peggy_bases[i],"SuperNET") == 0 || strncmp(peggy_bases[i],"XAG",3) == 0 || strncmp(peggy_bases[i],"ETH",3) == 0 || strncmp(peggy_bases[i],"XCP",3) == 0 ) + else if ( strncmp(peggy_bases[i],"ETC",3) == 0 || strcmp(peggy_bases[i],"SuperNET") == 0 || strncmp(peggy_bases[i],"XAG",3) == 0 || strncmp(peggy_bases[i],"ETH",3) == 0 || strncmp(peggy_bases[i],"XCP",3) == 0 ) minmils = 1000; else if ( strncmp(peggy_bases[i],"XMR",3) == 0 ) minmils = 10000; else if ( strncmp(peggy_bases[i],"NXT",3) == 0 || strncmp(peggy_bases[i],"BTS",3) == 0 ) minmils = 1000000; - else if ( strncmp(peggy_bases[i],"DOGE",3) == 0 ) - minmils = 100000000; + else if ( strncmp(peggy_bases[i],"STEEM",5) == 0 ) + minmils = 1000; else minmils = 10000; } return(minmils); @@ -682,9 +682,9 @@ int32_t PAX_getmatrix(double *basevals,struct peggy_info *PEGS,double Hmatrix[32 RTprices[i] = PEGS->data.cryptos[7]; else if ( i < 32 ) { - basevals[i] = Hmatrix[i][i]; + PEGS->data.RTmatrix[i][i] = basevals[i] = Hmatrix[i][i]; //if ( Debuglevel > 2 ) - printf("(%s %f).%d ",CURRENCIES[i],basevals[i],i); + //printf("(%s %f).%d ",CURRENCIES[i],basevals[i],i); } else if ( (c= PAX_contractnum(contracts[i],0)) >= 0 ) { @@ -716,10 +716,12 @@ char *peggy_emitprices(int32_t *nonzp,struct peggy_info *PEGS,uint32_t blocktime double matrix[32][32],RTmatrix[32][32],cprices[64],basevals[64]; struct price_resolution prices[256]; cJSON *json,*array; char *jsonstr,*opreturnstr = 0; int32_t i,nonz = 0; memset(cprices,0,sizeof(cprices)); - //printf("peggy_emitprices\n"); + printf("peggy_emitprices\n"); if ( PAX_getmatrix(basevals,PEGS,matrix,cprices+1,peggy_bases+1,sizeof(peggy_bases)/sizeof(*peggy_bases)-1,blocktimestamp) > 0 ) { cprices[0] = PEGS->btcdbtc; + for (i=0; i<32; i++) + PEGS->data.RTmatrix[i][i] = basevals[i]; /*for (i=0; i<32; i++) printf("%f ",basevals[i]); printf("basevals\n"); @@ -825,13 +827,37 @@ double PAX_getprice(char *retbuf,char *base,char *rel,char *contract,struct pegg #include "../includes/iguana_apidefs.h" #include "../includes/iguana_apideclares.h" -void PAX_init(struct peggy_info *PEGS) +double PAX_aveprice(struct supernet_info *myinfo,char *base) +{ + struct peggy_info *PEGS; int32_t basenum; + if ( (PEGS= myinfo->PEGS) != 0 && (basenum= PAX_basenum(base)) >= 0 ) + { + return(PEGS->data.RTmatrix[basenum][basenum]); + } + return(0.); +} + +struct peggy_info *PAX_init() { - double commission = 0.; + void peggy_indsinit(); + struct peggy_info *PEGS; struct price_resolution spread; double commission = 0.; init_Currencymasks(); + //calc_smooth_code(127,7); + peggy_indsinit(); tradebot_monitorall(0,0,0,0,"fxcm",commission); tradebot_monitorall(0,0,0,0,"truefx",commission); tradebot_monitorall(0,0,0,0,"instaforex",commission); + spread.Pval = PERCENTAGE(1); + PEGS = peggy_init(PEGGY_MAXLOCKDAYS,"BTCD",SATOSHIDEN/100,100,10,spread,PEGGY_RATE_777,40,10,2,5,2,0,0); + exchange_create("PAX",0); + //peggy_priceinits(PEGS,(uint32_t)time(NULL),allprices); + return(PEGS); +} + +ZERO_ARGS(pax,start) +{ + myinfo->PEGS = PAX_init(); + return(clonestr("{\"result\":\"success\"}")); } #include "../includes/iguana_apiundefs.h" diff --git a/iguana/peggy_update.c b/iguana/peggy_update.c index fa3caff34..d23b190f6 100755 --- a/iguana/peggy_update.c +++ b/iguana/peggy_update.c @@ -47,7 +47,7 @@ static char *Yahoo_metals[] = { YAHOO_METALS }; char CURRENCIES[][8] = { "USD", "EUR", "JPY", "GBP", "AUD", "CAD", "CHF", "NZD", // major currencies "CNY", "RUB", "MXN", "BRL", "INR", "HKD", "TRY", "ZAR", "PLN", "NOK", "SEK", "DKK", "CZK", "HUF", "ILS", "KRW", "MYR", "PHP", "RON", "SGD", "THB", "BGN", "IDR", "HRK", // end of currencies "XAU", "XAG", "XPT", "XPD", // metals, gold must be first - "BTCD", "BTC", "NXT", "LTC", "ETH", "DOGE", "BTS", "MAID", "XCP", "XMR" // cryptos + "BTCD", "BTC", "NXT", "ETC", "ETH", "STEEM", "BTS", "MAID", "XCP", "XMR" // cryptos }; char CONTRACTS[][16] = { "NZDUSD", "NZDCHF", "NZDCAD", "NZDJPY", "GBPNZD", "EURNZD", "AUDNZD", "CADJPY", "CADCHF", "USDCAD", "EURCAD", "GBPCAD", "AUDCAD", "USDCHF", "CHFJPY", "EURCHF", "GBPCHF", "AUDCHF", "EURUSD", "EURAUD", "EURJPY", "EURGBP", "GBPUSD", "GBPJPY", "GBPAUD", "USDJPY", "AUDJPY", "AUDUSD", "USDCNY", "USDHKD", "USDMXN", "USDZAR", "USDTRY", "EURTRY", "TRYJPY", "USDSGD", "EURNOK", "USDNOK","USDSEK","USDDKK","EURSEK","EURDKK","NOKJPY","SEKJPY","USDPLN","EURPLN","USDILS", // no more currencies @@ -91,9 +91,11 @@ int32_t PAX_ispair(char *base,char *rel,char *contract) return(-1); } -int32_t PAX_basenum(char *base) +int32_t PAX_basenum(char *_base) { - int32_t i,j; + int32_t i,j; char base[64]; + strcpy(base,_base); + touppercase(base); if ( 1 ) { for (i=0; i SMALLVAL ) break; i = 3; - } else i = j; + } else*/ + i = j; for (iter=0; iter<1; iter++) { if ( i == 0 && iter == 0 ) @@ -582,9 +585,9 @@ void _crypto_update(struct peggy_info *PEGS,double cryptovols[2][8][2],struct PA } } -void PAX_RTupdate(struct peggy_info *PEGS,double cryptovols[2][8][2],double RTmetals[4],double *RTprices,struct PAX_data *dp) +void PAX_RTupdate(struct peggy_info *PEGS,double cryptovols[2][9][2],double RTmetals[4],double *RTprices,struct PAX_data *dp) { - char *cryptostrs[8] = { "btc", "nxt", "unity", "eth", "ltc", "xmr", "bts", "xcp" }; + char *cryptostrs[9] = { "btc", "nxt", "unity", "eth", "etc", "steem", "xmr", "bts", "xcp" }; int32_t iter,i,c,baserel,basenum,relnum; double cnyusd,btcusd,btcdbtc,bid,ask,price,vol,prices[8][2],volumes[8][2]; char base[16],rel[16]; PAX_update(PEGS,&btcusd,&btcdbtc); @@ -592,7 +595,10 @@ void PAX_RTupdate(struct peggy_info *PEGS,double cryptovols[2][8][2],double RTme memset(volumes,0,sizeof(volumes)); for (i=0; i SMALLVAL ) dxblend(&btcdbtc,prices[0][0],.9); dxblend(&dp->btcdbtc,btcdbtc,.995); @@ -616,7 +622,9 @@ void PAX_RTupdate(struct peggy_info *PEGS,double cryptovols[2][8][2],double RTme } for (i=1; i SMALLVAL ) + vol = volumes[i][0]; + vol += volumes[i][1]; + if ( vol > SMALLVAL ) { price = ((prices[i][0] * volumes[i][0]) + (prices[i][1] * volumes[i][1])) / vol; if ( Debuglevel > 2 ) diff --git a/iguana/pnacl/Release/iguana.nmf b/iguana/pnacl/Release/iguana.nmf deleted file mode 100644 index 9d37ed227..000000000 --- a/iguana/pnacl/Release/iguana.nmf +++ /dev/null @@ -1,12 +0,0 @@ -{ - "program": { - "portable": { - "pnacl-translate": { - "url": "iguana.pexe" - }, - "pnacl-debug": { - "url": "iguana_unstripped.bc" - } - } - } -} diff --git a/iguana/ramchain_api.c b/iguana/ramchain_api.c index 5f851a69e..5db58b16d 100755 --- a/iguana/ramchain_api.c +++ b/iguana/ramchain_api.c @@ -27,8 +27,7 @@ STRING_ARG(iguana,initfastfind,activecoin) TWO_STRINGS_AND_TWO_DOUBLES(iguana,balance,activecoin,address,lastheightd,minconfd) { - int32_t lastheight,minconf,maxconf=SATOSHIDEN; int64_t total=0; uint8_t rmd160[20],pubkey33[33],addrtype; - struct iguana_pkhash *P; cJSON *array,*retjson = cJSON_CreateObject(); + int32_t lastheight,minconf,maxconf=SATOSHIDEN; uint64_t total=0; uint8_t rmd160[20],pubkey33[33],addrtype; struct iguana_pkhash *P; cJSON *array,*retjson = cJSON_CreateObject(); if ( activecoin != 0 && activecoin[0] != 0 ) coin = iguana_coinfind(activecoin); if ( coin != 0 ) @@ -42,6 +41,7 @@ TWO_STRINGS_AND_TWO_DOUBLES(iguana,balance,activecoin,address,lastheightd,mincon jaddstr(retjson,"error","illegal address"); return(jprint(retjson,1)); } + jadd64bits(retjson,"RTbalance",iguana_RTbalance(coin,address)); if ( bitcoin_addr2rmd160(&addrtype,rmd160,address) < 0 ) { jaddstr(retjson,"error","cant convert address"); @@ -50,15 +50,15 @@ TWO_STRINGS_AND_TWO_DOUBLES(iguana,balance,activecoin,address,lastheightd,mincon memset(pubkey33,0,sizeof(pubkey33)); P = calloc(coin->bundlescount,sizeof(*P)); array = cJSON_CreateArray(); - printf("Start %s balance.(%s) height.%d\n",coin->symbol,address,lastheight); + //printf("Start %s balance.(%s) height.%d\n",coin->symbol,address,lastheight); if ( lastheight == 0 ) lastheight = IGUANA_MAXHEIGHT; - iguana_pkhasharray(myinfo,coin,array,minconf,maxconf,&total,P,coin->bundlescount,rmd160,address,pubkey33,lastheight,0,0,0); + iguana_RTpkhasharray(myinfo,coin,array,minconf,maxconf,&total,P,coin->bundlescount,rmd160,address,pubkey33,lastheight,0,0,0,remoteaddr,1); free(P); jadd(retjson,"unspents",array); jaddnum(retjson,"balance",dstr(total)); if ( lastheight > 0 ) - jaddnum(retjson,"lastheight",lastheight); + jaddnum(retjson,"RTheight",coin->RTheight); } return(jprint(retjson,1)); } @@ -92,28 +92,32 @@ STRING_ARG(iguana,removecoin,activecoin) { coin->active = 0; coin->started = 0; - for (i=0; isymbol,i), OS_removefile(fname,0); - sprintf(fname,"%s/%s/%04d.vins",coin->VALIDATEDIR,coin->symbol,i), OS_removefile(fname,0); - } - sprintf(fname,"%s/%s/vouts/*",GLOBAL_DBDIR,coin->symbol), OS_removefile(fname,0); - sprintf(fname,"%s/%s/*",coin->VALIDATEDIR,coin->symbol), OS_removefile(fname,0); - for (i=0; ibundlescount; i++) - { - sprintf(fname,"%s/%s/balancecrc.%d",GLOBAL_DBDIR,coin->symbol,i), OS_removefile(fname,0); - if ( (bp= coin->bundles[i]) != 0 ) + for (i=0; ihdrsi,1); + sprintf(fname,"%s/%s/vouts/%04d.vouts",GLOBAL_DBDIR,coin->symbol,i), OS_removefile(fname,0); + sprintf(fname,"%s/%s/%04d.vins",coin->VALIDATEDIR,coin->symbol,i), OS_removefile(fname,0); } + sprintf(fname,"%s/%s/vouts/*",GLOBAL_DBDIR,coin->symbol), OS_removefile(fname,0); + sprintf(fname,"%s/%s/*",coin->VALIDATEDIR,coin->symbol), OS_removefile(fname,0); + for (i=0; ibundlescount; i++) + { + sprintf(fname,"%s/%s/balancecrc.%d",GLOBAL_DBDIR,coin->symbol,i), OS_removefile(fname,0); + if ( (bp= coin->bundles[i]) != 0 ) + { + iguana_bundlepurgefiles(coin,bp); + iguana_bundleremove(coin,bp->hdrsi,1); + } + } + for (height=0; heightlongestchain; height+=IGUANA_SUBDIRDIVISOR) + { + sprintf(fname,"%s/%s/%d",GLOBAL_DBDIR,coin->symbol,height/IGUANA_SUBDIRDIVISOR); + OS_remove_directory(fname); + } + sprintf(fname,"%s/%s/*",GLOBAL_DBDIR,coin->symbol), OS_remove_directory(fname); } - for (height=0; heightlongestchain; height+=IGUANA_SUBDIRDIVISOR) - { - sprintf(fname,"%s/%s/%d",GLOBAL_DBDIR,coin->symbol,height/IGUANA_SUBDIRDIVISOR); - OS_remove_directory(fname); - } - sprintf(fname,"%s/%s/*",GLOBAL_DBDIR,coin->symbol), OS_remove_directory(fname); + return(clonestr("{\"result\":\"success\"}")); } return(clonestr("{\"error\":\"no active coin\"}")); } @@ -136,7 +140,7 @@ HASH_AND_TWOINTS(bitcoinrpc,getblock,blockhash,verbose,remoteonly) return(jprint(iguana_blockjson(coin,block,1),1)); else { - if ( (len= iguana_peerblockrequest(coin,coin->blockspace,sizeof(coin->blockspace),0,blockhash,0)) > 0 ) + if ( (len= iguana_peerblockrequest(coin,coin->blockspace,coin->blockspacesize,0,blockhash,0)) > 0 ) { datastr = malloc(len*2 + 1); init_hexbytes_noT(datastr,coin->blockspace,len); @@ -171,6 +175,7 @@ ZERO_ARGS(bitcoinrpc,getbestblockhash) ZERO_ARGS(bitcoinrpc,getblockcount) { cJSON *retjson = cJSON_CreateObject(); + //printf("result %d\n",coin->blocks.hwmchain.height); jaddnum(retjson,"result",coin->blocks.hwmchain.height); return(jprint(retjson,1)); } @@ -183,6 +188,63 @@ STRING_AND_INT(iguana,bundleaddresses,activecoin,height) else return(clonestr("{\"error\":\"activecoin is not active\"}")); } +STRING_AND_INT(iguana,PoSweights,activecoin,height) +{ + struct iguana_info *ptr; int32_t num,nonz,errs,bundleheight; struct iguana_pkhash *refP; int64_t *weights,supply; cJSON *retjson; + if ( (ptr= iguana_coinfind(activecoin)) != 0 ) + { + //for (bundleheight=coin->chain->bundlesize; bundleheightchain->bundlesize) + { + bundleheight = (height / ptr->chain->bundlesize) * ptr->chain->bundlesize; + if ( (weights= iguana_PoS_weights(myinfo,ptr,&refP,&supply,&num,&nonz,&errs,bundleheight)) != 0 ) + { + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result",errs == 0 ? "success" : "error"); + jaddnum(retjson,"bundleheight",bundleheight); + jaddnum(retjson,"numaddresses",num); + jaddnum(retjson,"nonzero",nonz); + jaddnum(retjson,"errors",errs); + jaddnum(retjson,"supply",dstr(supply)); + free(weights); + return(jprint(retjson,1)); + } else return(clonestr("{\"error\":\"iguana_PoS_weights returned null\"}")); + } + } + return(clonestr("{\"error\":\"activecoin is not active\"}")); +} + +STRING_ARG(iguana,stakers,activecoin) +{ + struct iguana_info *ptr; int32_t i,datalen,pkind,hdrsi; bits256 hash2; struct iguana_bundle *bp; cJSON *retjson,*array; struct iguana_pkhash *refP; struct iguana_ramchaindata *rdata; char coinaddr[64]; uint8_t refrmd160[20]; bits256 *sortbuf; + if ( (ptr= iguana_coinfind(activecoin)) != 0 && ptr->RTheight > ptr->chain->bundlesize ) + { + hdrsi = (ptr->RTheight / ptr->chain->bundlesize) - 1; + if ( (bp= ptr->bundles[hdrsi]) != 0 && bp->weights != 0 && (rdata= bp->ramchain.H.data) != 0 && bp->weights != 0 ) + { + sortbuf = calloc(bp->numweights,2 * sizeof(*sortbuf)); + for (i=datalen=0; inumweights; i++) + datalen += iguana_rwnum(1,&((uint8_t *)sortbuf)[datalen],sizeof(bp->weights[i]),(void *)&bp->weights[i]); + hash2 = bits256_doublesha256(0,(uint8_t *)sortbuf,datalen); + refP = RAMCHAIN_PTR(rdata,Poffset); + retjson = cJSON_CreateObject(); + array = cJSON_CreateArray(); + memset(refrmd160,0,sizeof(refrmd160)); + for (i=0; ichain->bundlesize; i++) + { + if ( (pkind= iguana_staker_sort(ptr,&hash2,refrmd160,refP,bp->weights,bp->numweights,sortbuf)) > 0 ) + { + bitcoin_address(coinaddr,ptr->chain->pubtype,refP[pkind].rmd160,sizeof(refP[pkind].rmd160)); + jaddistr(array,coinaddr); + } else jaddistr(array,"error"); + } + jaddstr(retjson,"result","success"); + jadd(retjson,"stakers",array); + return(jprint(retjson,1)); + } else return(clonestr("{\"error\":\"iguana_stakers needs PoSweights and weights\"}")); + } + return(clonestr("{\"error\":\"activecoin is not active\"}")); +} + STRING_AND_INT(iguana,bundlehashes,activecoin,height) { struct iguana_info *ptr; struct iguana_bundle *bp; int32_t i,hdrsi; cJSON *retjson,*array; struct iguana_ramchaindata *rdata; @@ -228,12 +290,14 @@ HASH_AND_TWOINTS(bitcoinrpc,listsinceblock,blockhash,target,flag) "timereceived" : 1418924714 },*/ cJSON *retjson = cJSON_CreateObject(); + jaddstr(retjson,"error","low priority RPC not implemented"); return(jprint(retjson,1)); } ZERO_ARGS(bitcoinrpc,gettxoutsetinfo) { cJSON *retjson = cJSON_CreateObject(); + jaddstr(retjson,"error","low priority RPC not implemented"); return(jprint(retjson,1)); } @@ -241,13 +305,7 @@ ZERO_ARGS(bitcoinrpc,listaddressgroupings) { if ( remoteaddr != 0 ) return(clonestr("{\"error\":\"no remote\"}")); - return(clonestr("{\"result\":\"success\"}")); -} - -ZERO_ARGS(bitcoinrpc,getrawchangeaddress) -{ - cJSON *retjson = cJSON_CreateObject(); - return(jprint(retjson,1)); + return(clonestr("{\"error\":\"low priority RPC not implemented\"}")); } SS_D_I_S(bitcoinrpc,move,fromaccount,toaccount,amount,minconf,comment) diff --git a/iguana/secp256k1/include/secp256k1.h b/iguana/secp256k1/include/secp256k1.h index 7145dbcc5..617493ae5 100644 --- a/iguana/secp256k1/include/secp256k1.h +++ b/iguana/secp256k1/include/secp256k1.h @@ -170,27 +170,21 @@ typedef int (*secp256k1_nonce_function)( * Returns: a newly created context object. * In: flags: which parts of the context to initialize. */ -SECP256K1_API secp256k1_context* secp256k1_context_create( - unsigned int flags -) SECP256K1_WARN_UNUSED_RESULT; +SECP256K1_API secp256k1_context* secp256k1_context_create(unsigned int flags) SECP256K1_WARN_UNUSED_RESULT; /** Copies a secp256k1 context object. * * Returns: a newly created context object. * Args: ctx: an existing context to copy (cannot be NULL) */ -SECP256K1_API secp256k1_context* secp256k1_context_clone( - const secp256k1_context* ctx -) SECP256K1_ARG_NONNULL(1) SECP256K1_WARN_UNUSED_RESULT; +SECP256K1_API secp256k1_context* secp256k1_context_clone(const secp256k1_context* ctx) SECP256K1_ARG_NONNULL(1) SECP256K1_WARN_UNUSED_RESULT; /** Destroy a secp256k1 context object. * * The context pointer may not be used afterwards. * Args: ctx: an existing context to destroy (cannot be NULL) */ -SECP256K1_API void secp256k1_context_destroy( - secp256k1_context* ctx -); +SECP256K1_API void secp256k1_context_destroy(secp256k1_context *ctx); /** Set a callback function to be called when an illegal argument is passed to * an API call. It will only trigger for violations that are mentioned @@ -212,11 +206,7 @@ SECP256K1_API void secp256k1_context_destroy( * (NULL restores a default handler that calls abort). * data: the opaque pointer to pass to fun above. */ -SECP256K1_API void secp256k1_context_set_illegal_callback( - secp256k1_context* ctx, - void (*fun)(const char* message, void* data), - const void* data -) SECP256K1_ARG_NONNULL(1); +SECP256K1_API void secp256k1_context_set_illegal_callback(secp256k1_context* ctx,void (*fun)(const char* message, void* data),const void* data) SECP256K1_ARG_NONNULL(1); /** Set a callback function to be called when an internal consistency check * fails. The default is crashing. @@ -234,11 +224,7 @@ SECP256K1_API void secp256k1_context_set_illegal_callback( * handler that calls abort). * data: the opaque pointer to pass to fun above. */ -SECP256K1_API void secp256k1_context_set_error_callback( - secp256k1_context* ctx, - void (*fun)(const char* message, void* data), - const void* data -) SECP256K1_ARG_NONNULL(1); +SECP256K1_API void secp256k1_context_set_error_callback(secp256k1_context *ctx,void (*fun)(const char *message,void *data),const void *data) SECP256K1_ARG_NONNULL(1); /** Parse a variable-length public key into the pubkey object. * @@ -254,12 +240,7 @@ SECP256K1_API void secp256k1_context_set_error_callback( * 0x03), uncompressed (65 bytes, header byte 0x04), or hybrid (65 bytes, header * byte 0x06 or 0x07) format public keys. */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_parse( - const secp256k1_context* ctx, - secp256k1_pubkey* pubkey, - const unsigned char *input, - size_t inputlen -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_parse(const secp256k1_context *ctx,secp256k1_pubkey *pubkey,const unsigned char *input,size_t inputlen) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); /** Serialize a pubkey object into a serialized byte sequence. * @@ -276,13 +257,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_parse( * flags: SECP256K1_EC_COMPRESSED if serialization should be in * compressed format, otherwise SECP256K1_EC_UNCOMPRESSED. */ -SECP256K1_API int secp256k1_ec_pubkey_serialize( - const secp256k1_context* ctx, - unsigned char *output, - size_t *outputlen, - const secp256k1_pubkey* pubkey, - unsigned int flags -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); +SECP256K1_API int secp256k1_ec_pubkey_serialize(const secp256k1_context *ctx,unsigned char *output,size_t *outputlen,const secp256k1_pubkey *pubkey,unsigned int flags) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); /** Parse an ECDSA signature in compact (64 bytes) format. * @@ -299,11 +274,7 @@ SECP256K1_API int secp256k1_ec_pubkey_serialize( * S are zero, the resulting sig value is guaranteed to fail validation for any * message and public key. */ -SECP256K1_API int secp256k1_ecdsa_signature_parse_compact( - const secp256k1_context* ctx, - secp256k1_ecdsa_signature* sig, - const unsigned char *input64 -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); +SECP256K1_API int secp256k1_ecdsa_signature_parse_compact(const secp256k1_context *ctx,secp256k1_ecdsa_signature *sig,const unsigned char *input64) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); /** Parse a DER ECDSA signature. * @@ -320,12 +291,7 @@ SECP256K1_API int secp256k1_ecdsa_signature_parse_compact( * encoded numbers are out of range, signature validation with it is * guaranteed to fail for every message and public key. */ -SECP256K1_API int secp256k1_ecdsa_signature_parse_der( - const secp256k1_context* ctx, - secp256k1_ecdsa_signature* sig, - const unsigned char *input, - size_t inputlen -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); +SECP256K1_API int secp256k1_ecdsa_signature_parse_der(const secp256k1_context *ctx,secp256k1_ecdsa_signature *sig,const unsigned char *input,size_t inputlen) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); /** Serialize an ECDSA signature in DER format. * @@ -338,12 +304,7 @@ SECP256K1_API int secp256k1_ecdsa_signature_parse_der( * if 0 was returned). * In: sig: a pointer to an initialized signature object */ -SECP256K1_API int secp256k1_ecdsa_signature_serialize_der( - const secp256k1_context* ctx, - unsigned char *output, - size_t *outputlen, - const secp256k1_ecdsa_signature* sig -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); +SECP256K1_API int secp256k1_ecdsa_signature_serialize_der(const secp256k1_context *ctx,unsigned char *output,size_t *outputlen,const secp256k1_ecdsa_signature *sig) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); /** Serialize an ECDSA signature in compact (64 byte) format. * @@ -354,11 +315,7 @@ SECP256K1_API int secp256k1_ecdsa_signature_serialize_der( * * See secp256k1_ecdsa_signature_parse_compact for details about the encoding. */ -SECP256K1_API int secp256k1_ecdsa_signature_serialize_compact( - const secp256k1_context* ctx, - unsigned char *output64, - const secp256k1_ecdsa_signature* sig -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); +SECP256K1_API int secp256k1_ecdsa_signature_serialize_compact(const secp256k1_context *ctx,unsigned char *output64,const secp256k1_ecdsa_signature *sig) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); /** Verify an ECDSA signature. * @@ -378,12 +335,7 @@ SECP256K1_API int secp256k1_ecdsa_signature_serialize_compact( * * For details, see the comments for that function. */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify( - const secp256k1_context* ctx, - const secp256k1_ecdsa_signature *sig, - const unsigned char *msg32, - const secp256k1_pubkey *pubkey -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify(const secp256k1_context *ctx,const secp256k1_ecdsa_signature *sig,const unsigned char *msg32,const secp256k1_pubkey *pubkey) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); /** Convert a signature to a normalized lower-S form. * @@ -427,11 +379,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify( * signatures come from a system that cannot enforce this property, * secp256k1_ecdsa_signature_normalize must be called before verification. */ -SECP256K1_API int secp256k1_ecdsa_signature_normalize( - const secp256k1_context* ctx, - secp256k1_ecdsa_signature *sigout, - const secp256k1_ecdsa_signature *sigin -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3); +SECP256K1_API int secp256k1_ecdsa_signature_normalize(const secp256k1_context *ctx,secp256k1_ecdsa_signature *sigout,const secp256k1_ecdsa_signature *sigin) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3); /** An implementation of RFC6979 (using HMAC-SHA256) as nonce generation function. * If a data pointer is passed, it is assumed to be a pointer to 32 bytes of @@ -456,14 +404,7 @@ SECP256K1_API extern const secp256k1_nonce_function secp256k1_nonce_function_def * The created signature is always in lower-S form. See * secp256k1_ecdsa_signature_normalize for more details. */ -SECP256K1_API int secp256k1_ecdsa_sign( - const secp256k1_context* ctx, - secp256k1_ecdsa_signature *sig, - const unsigned char *msg32, - const unsigned char *seckey, - secp256k1_nonce_function noncefp, - const void *ndata -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); +SECP256K1_API int secp256k1_ecdsa_sign(const secp256k1_context *ctx,secp256k1_ecdsa_signature *sig,const unsigned char *msg32,const unsigned char *seckey,secp256k1_nonce_function noncefp,const void *ndata) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); /** Verify an ECDSA secret key. * @@ -472,10 +413,7 @@ SECP256K1_API int secp256k1_ecdsa_sign( * Args: ctx: pointer to a context object (cannot be NULL) * In: seckey: pointer to a 32-byte secret key (cannot be NULL) */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_verify( - const secp256k1_context* ctx, - const unsigned char *seckey -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2); +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_verify(const secp256k1_context *ctx,const unsigned char *seckey) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2); /** Compute the public key for a secret key. * @@ -485,11 +423,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_verify( * Out: pubkey: pointer to the created public key (cannot be NULL) * In: seckey: pointer to a 32-byte private key (cannot be NULL) */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create( - const secp256k1_context* ctx, - secp256k1_pubkey *pubkey, - const unsigned char *seckey -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create(const secp256k1_context *ctx,secp256k1_pubkey *pubkey,const unsigned char *seckey) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); /** Tweak a private key by adding tweak to it. * Returns: 0 if the tweak was out of range (chance of around 1 in 2^128 for @@ -500,11 +434,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create( * In/Out: seckey: pointer to a 32-byte private key. * In: tweak: pointer to a 32-byte tweak. */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_add( - const secp256k1_context* ctx, - unsigned char *seckey, - const unsigned char *tweak -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_add(const secp256k1_context *ctx,unsigned char *seckey,const unsigned char *tweak) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); /** Tweak a public key by adding tweak times the generator to it. * Returns: 0 if the tweak was out of range (chance of around 1 in 2^128 for @@ -516,11 +446,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_add( * In/Out: pubkey: pointer to a public key object. * In: tweak: pointer to a 32-byte tweak. */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_add( - const secp256k1_context* ctx, - secp256k1_pubkey *pubkey, - const unsigned char *tweak -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_add(const secp256k1_context *ctx,secp256k1_pubkey *pubkey,const unsigned char *tweak) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); /** Tweak a private key by multiplying it by a tweak. * Returns: 0 if the tweak was out of range (chance of around 1 in 2^128 for @@ -529,11 +455,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_add( * In/Out: seckey: pointer to a 32-byte private key. * In: tweak: pointer to a 32-byte tweak. */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_mul( - const secp256k1_context* ctx, - unsigned char *seckey, - const unsigned char *tweak -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_mul(const secp256k1_context *ctx,unsigned char *seckey,const unsigned char *tweak) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); /** Tweak a public key by multiplying it by a tweak value. * Returns: 0 if the tweak was out of range (chance of around 1 in 2^128 for @@ -543,11 +465,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_mul( * In/Out: pubkey: pointer to a public key obkect. * In: tweak: pointer to a 32-byte tweak. */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_mul( - const secp256k1_context* ctx, - secp256k1_pubkey *pubkey, - const unsigned char *tweak -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_mul(const secp256k1_context *ctx,secp256k1_pubkey *pubkey,const unsigned char *tweak) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); /** Updates the context randomization. * Returns: 1: randomization successfully updated @@ -555,10 +473,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_mul( * Args: ctx: pointer to a context object (cannot be NULL) * In: seed32: pointer to a 32-byte random seed (NULL resets to initial state) */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_context_randomize( - secp256k1_context* ctx, - const unsigned char *seed32 -) SECP256K1_ARG_NONNULL(1); +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_context_randomize(secp256k1_context *ctx,const unsigned char *seed32) SECP256K1_ARG_NONNULL(1); /** Add a number of public keys together. * Returns: 1: the sum of the public keys is valid. @@ -569,12 +484,7 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_context_randomize( * In: ins: pointer to array of pointers to public keys (cannot be NULL) * n: the number of public keys to add together (must be at least 1) */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_combine( - const secp256k1_context* ctx, - secp256k1_pubkey *out, - const secp256k1_pubkey * const * ins, - size_t n -) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_combine(const secp256k1_context *ctx,secp256k1_pubkey *out,const secp256k1_pubkey * const *ins,size_t n) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); # ifdef __cplusplus } diff --git a/iguana/secp256k1/include/secp256k1_ecdh.h b/iguana/secp256k1/include/secp256k1_ecdh.h index 4b84d7a96..1745d15f9 100644 --- a/iguana/secp256k1/include/secp256k1_ecdh.h +++ b/iguana/secp256k1/include/secp256k1_ecdh.h @@ -13,16 +13,10 @@ extern "C" { * Args: ctx: pointer to a context object (cannot be NULL) * Out: result: a 32-byte array which will be populated by an ECDH * secret computed from the point and scalar - * In: pubkey: a pointer to a secp256k1_pubkey containing an - * initialized public key + * In: pubkey: a pointer to a secp256k1_pubkey containing an initialized public key * privkey: a 32-byte scalar with which to multiply the point */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdh( - const secp256k1_context* ctx, - unsigned char *result, - const secp256k1_pubkey *pubkey, - const unsigned char *privkey -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdh(const secp256k1_context *ctx,unsigned char *result,const secp256k1_pubkey *pubkey,const unsigned char *privkey) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); # ifdef __cplusplus } diff --git a/iguana/secp256k1/include/secp256k1_rangeproof.h b/iguana/secp256k1/include/secp256k1_rangeproof.h index 54b454ef6..a22be8491 100644 --- a/iguana/secp256k1/include/secp256k1_rangeproof.h +++ b/iguana/secp256k1/include/secp256k1_rangeproof.h @@ -49,7 +49,7 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_blind_sum( /** Verify a tally of pedersen commitments * Returns 1: commitments successfully sum to zero. * 0: Commitments do not sum to zero or other error. - * In: ctx: pointer to a context object, initialized for Pedersen commitment (cannot be NULL) + * In: ctx: pointer to a context object, initialized for Pedersen commitment (cannot be NULL) * commits: pointer to pointers to 33-byte character arrays for the commitments. (cannot be NULL if pcnt is non-zero) * pcnt: number of commitments pointed to by commits. * ncommits: pointer to pointers to 33-byte character arrays for negative commitments. (cannot be NULL if ncnt is non-zero) @@ -146,7 +146,7 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_rangeproof_rewind( * */ SECP256K1_WARN_UNUSED_RESULT int secp256k1_rangeproof_sign( - const secp256k1_context* ctx, + const secp256k1_context *ctx, unsigned char *proof, int *plen, uint64_t min_value, @@ -170,7 +170,7 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_rangeproof_sign( * max_value: pointer to an unsigned int64 which will be updated with the maximum value that commit could have. (cannot be NULL) */ SECP256K1_WARN_UNUSED_RESULT int secp256k1_rangeproof_info( - const secp256k1_context* ctx, + const secp256k1_context *ctx, int *exp, int *mantissa, uint64_t *min_value, diff --git a/iguana/secp256k1/include/secp256k1_recovery.h b/iguana/secp256k1/include/secp256k1_recovery.h index 055379725..5e4d89b81 100644 --- a/iguana/secp256k1/include/secp256k1_recovery.h +++ b/iguana/secp256k1/include/secp256k1_recovery.h @@ -21,9 +21,7 @@ extern "C" { * recoverability) will have identical representation, so they can be * memcmp'ed. */ -typedef struct { - unsigned char data[65]; -} secp256k1_ecdsa_recoverable_signature; +typedef struct { uint8_t data[65]; } secp256k1_ecdsa_recoverable_signature; /** Parse a compact ECDSA signature (64 bytes + recovery id). * @@ -33,12 +31,7 @@ typedef struct { * In: input64: a pointer to a 64-byte compact signature * recid: the recovery id (0, 1, 2 or 3) */ -SECP256K1_API int secp256k1_ecdsa_recoverable_signature_parse_compact( - const secp256k1_context* ctx, - secp256k1_ecdsa_recoverable_signature* sig, - const unsigned char *input64, - int recid -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); +SECP256K1_API int secp256k1_ecdsa_recoverable_signature_parse_compact(const secp256k1_context *ctx,secp256k1_ecdsa_recoverable_signature *sig,const uint8_t *input64,int32_t recid) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); /** Convert a recoverable signature into a normal signature. * @@ -46,11 +39,7 @@ SECP256K1_API int secp256k1_ecdsa_recoverable_signature_parse_compact( * Out: sig: a pointer to a normal signature (cannot be NULL). * In: sigin: a pointer to a recoverable signature (cannot be NULL). */ -SECP256K1_API int secp256k1_ecdsa_recoverable_signature_convert( - const secp256k1_context* ctx, - secp256k1_ecdsa_signature* sig, - const secp256k1_ecdsa_recoverable_signature* sigin -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); +SECP256K1_API int secp256k1_ecdsa_recoverable_signature_convert(const secp256k1_context *ctx,secp256k1_ecdsa_signature *sig,const secp256k1_ecdsa_recoverable_signature *sigin) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); /** Serialize an ECDSA signature in compact format (64 bytes + recovery id). * @@ -60,12 +49,7 @@ SECP256K1_API int secp256k1_ecdsa_recoverable_signature_convert( * recid: a pointer to an integer to hold the recovery id (can be NULL). * In: sig: a pointer to an initialized signature object (cannot be NULL) */ -SECP256K1_API int secp256k1_ecdsa_recoverable_signature_serialize_compact( - const secp256k1_context* ctx, - unsigned char *output64, - int *recid, - const secp256k1_ecdsa_recoverable_signature* sig -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); +SECP256K1_API int secp256k1_ecdsa_recoverable_signature_serialize_compact(const secp256k1_context *ctx,uint8_t *output64,int32_t *recid,const secp256k1_ecdsa_recoverable_signature *sig) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); /** Create a recoverable ECDSA signature. * @@ -78,14 +62,7 @@ SECP256K1_API int secp256k1_ecdsa_recoverable_signature_serialize_compact( * noncefp:pointer to a nonce generation function. If NULL, secp256k1_nonce_function_default is used * ndata: pointer to arbitrary data used by the nonce generation function (can be NULL) */ -SECP256K1_API int secp256k1_ecdsa_sign_recoverable( - const secp256k1_context* ctx, - secp256k1_ecdsa_recoverable_signature *sig, - const unsigned char *msg32, - const unsigned char *seckey, - secp256k1_nonce_function noncefp, - const void *ndata -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); +SECP256K1_API int secp256k1_ecdsa_sign_recoverable(const secp256k1_context *ctx,secp256k1_ecdsa_recoverable_signature *sig,const uint8_t *msg32,const uint8_t *seckey,secp256k1_nonce_function noncefp,const void *ndata) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); /** Recover an ECDSA public key from a signature. * @@ -96,12 +73,7 @@ SECP256K1_API int secp256k1_ecdsa_sign_recoverable( * In: sig: pointer to initialized signature that supports pubkey recovery (cannot be NULL) * msg32: the 32-byte message hash assumed to be signed (cannot be NULL) */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_recover( - const secp256k1_context* ctx, - secp256k1_pubkey *pubkey, - const secp256k1_ecdsa_recoverable_signature *sig, - const unsigned char *msg32 -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_recover(const secp256k1_context *ctx,secp256k1_pubkey *pubkey,const secp256k1_ecdsa_recoverable_signature *sig,const uint8_t *msg32) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); # ifdef __cplusplus } diff --git a/iguana/secp256k1/include/secp256k1_schnorr.h b/iguana/secp256k1/include/secp256k1_schnorr.h index dc32fec1e..b3dbc9918 100644 --- a/iguana/secp256k1/include/secp256k1_schnorr.h +++ b/iguana/secp256k1/include/secp256k1_schnorr.h @@ -13,25 +13,14 @@ extern "C" { * Returns: 1: signature created * 0: the nonce generation function failed, or the private key was * invalid. - * Args: ctx: pointer to a context object, initialized for signing - * (cannot be NULL) - * Out: sig64: pointer to a 64-byte array where the signature will be - * placed (cannot be NULL) + * Args: ctx: pointer to a context object, initialized for signing (cannot be NULL) + * Out: sig64: pointer to a 64-byte array where the signature will be placed (cannot be NULL) * In: msg32: the 32-byte message hash being signed (cannot be NULL) * seckey: pointer to a 32-byte secret key (cannot be NULL) - * noncefp:pointer to a nonce generation function. If NULL, - * secp256k1_nonce_function_default is used - * ndata: pointer to arbitrary data used by the nonce generation - * function (can be NULL) + * noncefp:pointer to a nonce generation function. If NULL, secp256k1_nonce_function_default + * ndata: pointer to arbitrary data used by the nonce generation function (can be NULL) */ -SECP256K1_API int secp256k1_schnorr_sign( - const secp256k1_context* ctx, - unsigned char *sig64, - const unsigned char *msg32, - const unsigned char *seckey, - secp256k1_nonce_function noncefp, - const void *ndata -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); +SECP256K1_API int secp256k1_schnorr_sign(const secp256k1_context *ctx,unsigned char *sig64,const unsigned char *msg32,const unsigned char *seckey,secp256k1_nonce_function noncefp,const void *ndata) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); /** Verify a signature created by secp256k1_schnorr_sign. * Returns: 1: correct signature @@ -41,60 +30,33 @@ SECP256K1_API int secp256k1_schnorr_sign( * msg32: the 32-byte message hash being verified (cannot be NULL) * pubkey: the public key to verify with (cannot be NULL) */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorr_verify( - const secp256k1_context* ctx, - const unsigned char *sig64, - const unsigned char *msg32, - const secp256k1_pubkey *pubkey -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorr_verify(const secp256k1_context *ctx,const unsigned char *sig64,const unsigned char *msg32,const secp256k1_pubkey *pubkey) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); -/** Recover an EC public key from a Schnorr signature created using - * secp256k1_schnorr_sign. - * Returns: 1: public key successfully recovered (which guarantees a correct - * signature). +/** Recover an EC public key from a Schnorr signature created using secp256k1_schnorr_sign. + * Returns: 1: public key successfully recovered (which guarantees a correct signature). * 0: otherwise. - * Args: ctx: pointer to a context object, initialized for - * verification (cannot be NULL) - * Out: pubkey: pointer to a pubkey to set to the recovered public key - * (cannot be NULL). + * Args: ctx: pointer to a context object, initialized for verification (cannot be NULL) + * Out: pubkey: pointer to a pubkey to set to the recovered public key (cannot be NULL). * In: sig64: signature as 64 byte array (cannot be NULL) - * msg32: the 32-byte message hash assumed to be signed (cannot - * be NULL) + * msg32: the 32-byte message hash assumed to be signed (cannot be NULL) */ -SECP256K1_API int secp256k1_schnorr_recover( - const secp256k1_context* ctx, - secp256k1_pubkey *pubkey, - const unsigned char *sig64, - const unsigned char *msg32 -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); +SECP256K1_API int secp256k1_schnorr_recover(const secp256k1_context *ctx,secp256k1_pubkey *pubkey,const unsigned char *sig64,const unsigned char *msg32) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); -/** Generate a nonce pair deterministically for use with - * secp256k1_schnorr_partial_sign. +/** Generate a nonce pair deterministically for use with secp256k1_schnorr_partial_sign. * Returns: 1: valid nonce pair was generated. * 0: otherwise (nonce generation function failed) - * Args: ctx: pointer to a context object, initialized for signing - * (cannot be NULL) + * Args: ctx: pointer to a context object, initialized for signing (cannot be NULL) * Out: pubnonce: public side of the nonce (cannot be NULL) * privnonce32: private side of the nonce (32 byte) (cannot be NULL) - * In: msg32: the 32-byte message hash assumed to be signed (cannot - * be NULL) + * In: msg32: the 32-byte message hash assumed to be signed (cannot be NULL) * sec32: the 32-byte private key (cannot be NULL) * noncefp: pointer to a nonce generation function. If NULL, * secp256k1_nonce_function_default is used - * noncedata: pointer to arbitrary data used by the nonce generation - * function (can be NULL) + * noncedata: pointer to arbitrary data used by the nonce generation function (can be NULL) * * Do not use the output as a private/public key pair for signing/validation. */ -SECP256K1_API int secp256k1_schnorr_generate_nonce_pair( - const secp256k1_context* ctx, - secp256k1_pubkey *pubnonce, - unsigned char *privnonce32, - const unsigned char *msg32, - const unsigned char *sec32, - secp256k1_nonce_function noncefp, - const void* noncedata -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); +SECP256K1_API int secp256k1_schnorr_generate_nonce_pair(const secp256k1_context *ctx,secp256k1_pubkey *pubnonce,unsigned char *privnonce32,const unsigned char *msg32,const unsigned char *sec32,secp256k1_nonce_function noncefp,const void *noncedata) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); /** Produce a partial Schnorr signature, which can be combined using * secp256k1_schnorr_partial_combine, to end up with a full signature that is @@ -103,8 +65,7 @@ SECP256K1_API int secp256k1_schnorr_generate_nonce_pair( * 0: no valid signature exists with this combination of keys, nonces * and message (chance around 1 in 2^128) * -1: invalid private key, nonce, or public nonces. - * Args: ctx: pointer to context object, initialized for signing (cannot - * be NULL) + * Args: ctx: pointer to context object, initialized for signing (cannot be NULL) * Out: sig64: pointer to 64-byte array to put partial signature in * In: msg32: pointer to 32-byte message to sign * sec32: pointer to 32-byte private key @@ -114,24 +75,18 @@ SECP256K1_API int secp256k1_schnorr_generate_nonce_pair( * * The intended procedure for creating a multiparty signature is: * - Each signer S[i] with private key x[i] and public key Q[i] runs - * secp256k1_schnorr_generate_nonce_pair to produce a pair (k[i],R[i]) of - * private/public nonces. + * secp256k1_schnorr_generate_nonce_pair to produce a pair (k[i],R[i]) of private/public nonces. * - All signers communicate their public nonces to each other (revealing your - * private nonce can lead to discovery of your private key, so it should be - * considered secret). + * private nonce can lead to discovery of your private key, so it should be considered secret). * - All signers combine all the public nonces they received (excluding their - * own) using secp256k1_ec_pubkey_combine to obtain an - * Rall[i] = sum(R[0..i-1,i+1..n]). + * own) using secp256k1_ec_pubkey_combine to obtain an Rall[i] = sum(R[0..i-1,i+1..n]). * - All signers produce a partial signature using * secp256k1_schnorr_partial_sign, passing in their own private key x[i], - * their own private nonce k[i], and the sum of the others' public nonces - * Rall[i]. + * their own private nonce k[i], and the sum of the others' public nonces Rall[i]. * - All signers communicate their partial signatures to each other. - * - Someone combines all partial signatures using - * secp256k1_schnorr_partial_combine, to obtain a full signature. + * - Someone combines all partial signatures using secp256k1_schnorr_partial_combine, to obtain a full signature. * - The resulting signature is validatable using secp256k1_schnorr_verify, with - * public key equal to the result of secp256k1_ec_pubkey_combine of the - * signers' public keys (sum(Q[0..n])). + * public key equal to the result of secp256k1_ec_pubkey_combine of the signers' public keys (sum(Q[0..n])). * * Note that secp256k1_schnorr_partial_combine and secp256k1_ec_pubkey_combine * function take their arguments in any order, and it is possible to @@ -153,10 +108,8 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorr_partial_sign( * -1: some inputs were invalid, or the signatures were not created * using the same set of nonces * Args: ctx: pointer to a context object - * Out: sig64: pointer to a 64-byte array to place the combined signature - * (cannot be NULL) - * In: sig64sin: pointer to an array of n pointers to 64-byte input - * signatures + * Out: sig64: pointer to a 64-byte array to place the combined signature (cannot be NULL) + * In: sig64sin: pointer to an array of n pointers to 64-byte input signatures * n: the number of signatures to combine (at least 1) */ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorr_partial_combine( diff --git a/iguana/secp256k1/m_android b/iguana/secp256k1/m_android index 2409bd7f4..5e2421160 100755 --- a/iguana/secp256k1/m_android +++ b/iguana/secp256k1/m_android @@ -1 +1,6 @@ -$CC2 -c -o ../secp256k1.o -I. -I./src -I./include -I./src -O3 -W -std=c89 -pedantic -Wall -Wextra -Wcast-align -Wnested-externs -Wshadow -Wstrict-prototypes -Wno-unused-function -Wno-long-long -Wno-overlength-strings -fvisibility=hidden -DHAVE_CONFIG_H src/secp256k1.c +#$CC -c -o ../secp256k1.o -I. -I./src -I /Newpub/android-ndk-r9b/platforms/android-19/arch-arm/usr/include -I./include -I./src -O3 -W -std=c89 -pedantic -Wall -Wextra -Wcast-align -Wnested-externs -Wshadow -Wstrict-prototypes -Wno-unused-function -Wno-long-long -Wno-overlength-strings -fvisibility=hidden -DHAVE_CONFIG_H src/secp256k1.c + +#$CC -c -O2 src/secp256k1.c -I $NDK/platforms/android-21/arch-arm/usr/include +#rm -f ../../agents/libsecp256k1.a; $AR rcu ../../agents/libsecp256k1.a *.o + +$CC2 -c -o ../sec256k1.o -I. -I./src -I./include -I./src -O3 -W -std=c89 -pedantic -Wall -Wextra -Wcast-align -Wnested-externs -Wshadow -Wstrict-prototypes -Wno-unused-function -Wno-long-long -Wno-overlength-strings -fvisibility=hidden -DHAVE_CONFIG_H src/secp256k1.c diff --git a/iguana/secp256k1/m_ios b/iguana/secp256k1/m_ios new file mode 100755 index 000000000..0e76ee092 --- /dev/null +++ b/iguana/secp256k1/m_ios @@ -0,0 +1,3 @@ +CC="$(xcrun --sdk iphoneos --find clang) -isysroot $(xcrun --sdk iphoneos --show-sdk-path) -arch arm64 -arch armv7 -arch armv7s -ONLY_ACTIVE_ARCH=YES" + +$CC -o ../sec256k1.o -I. -I./src -I./include -I./src -O3 -W -std=c89 -pedantic -Wall -Wextra -Wcast-align -Wnested-externs -Wshadow -Wstrict-prototypes -Wno-unused-function -Wno-long-long -Wno-overlength-strings -fvisibility=hidden -DHAVE_CONFIG_H -c src/secp256k1.c diff --git a/iguana/secp256k1/m_js b/iguana/secp256k1/m_js index ccf5301bc..926ba3602 100755 --- a/iguana/secp256k1/m_js +++ b/iguana/secp256k1/m_js @@ -1 +1 @@ -emcc -c -o ../secp256k1.o -s USE_PTHREADS=1 -s ALLOW_MEMORY_GROWTH=1 -I. -I./src -I./include -I./src -O3 -W -std=c89 -pedantic -Wall -Wextra -Wcast-align -Wnested-externs -Wshadow -Wstrict-prototypes -Wno-unused-function -Wno-long-long -Wno-overlength-strings -fvisibility=hidden -DHAVE_CONFIG_H src/secp256k1.c +emcc -c -o ../secp256k1.o -s USE_PTHREADS=1 -O3 -I. -I./src -I./include -I./src -W -std=c89 -pedantic -Wall -Wextra -Wcast-align -Wnested-externs -Wshadow -Wstrict-prototypes -Wno-unused-function -Wno-long-long -Wno-overlength-strings -fvisibility=hidden -DHAVE_CONFIG_H src/secp256k1.c diff --git a/iguana/secp256k1/src/bench_rangeproof.c b/iguana/secp256k1/src/bench_rangeproof.c index c4e49c3e4..6885c0f22 100644 --- a/iguana/secp256k1/src/bench_rangeproof.c +++ b/iguana/secp256k1/src/bench_rangeproof.c @@ -6,35 +6,65 @@ #include -#include "include/secp256k1_rangeproof.h" +#include "../include/secp256k1_rangeproof.h" #include "util.h" #include "bench.h" typedef struct { - secp256k1_context_t* ctx; + secp256k1_context *ctx; unsigned char commit[33]; unsigned char proof[5134]; + unsigned char message[4096]; unsigned char blind[32]; - int len; + unsigned char nonce[32]; + int prooflen; int min_bits; uint64_t v; } bench_rangeproof_t; -static void bench_rangeproof_setup(void* arg) { +static void bench_rangeproof_setup(void* arg) +{ int i; uint64_t minv; uint64_t maxv; - bench_rangeproof_t *data = (bench_rangeproof_t*)arg; - - data->v = 0; - for (i = 0; i < 32; i++) data->blind[i] = i + 1; + bench_rangeproof_t *data = (bench_rangeproof_t *)arg; + for (i = 0; i < 32; i++) + { + data->blind[i] = rand(); + data->nonce[i] = rand(); + } +#define PRIVATEBITS 32 +#define PUBLICDIGITS 0 +#define ENCODEVALUE 2 + data->v = ENCODEVALUE; CHECK(secp256k1_pedersen_commit(data->ctx, data->commit, data->blind, data->v)); - data->len = 5134; - CHECK(secp256k1_rangeproof_sign(data->ctx, data->proof, &data->len, 0, data->commit, data->blind, data->commit, 0, data->min_bits, data->v)); - CHECK(secp256k1_rangeproof_verify(data->ctx, &minv, &maxv, data->commit, data->proof, data->len)); + data->prooflen = 5134; + for (i=0; iprooflen; i++) + { + //data->proof[i] = i; + if ( i < sizeof(data->prooflen) ) + data->message[i] = i; + } + CHECK(secp256k1_rangeproof_sign(data->ctx, data->proof, &data->prooflen,0, data->commit, data->blind, data->nonce, PUBLICDIGITS, data->min_bits, data->v)); + //for (i=0; iprooflen; i++) + // printf("%02x",data->proof[i]); + CHECK(secp256k1_rangeproof_verify(data->ctx, &minv, &maxv, data->commit, data->proof, data->prooflen)); + printf(" proof.%d [%llx, %llx]\n",data->prooflen,(long long)minv,(long long)maxv); + uint8_t blindout[32],message_out[5134]; uint64_t value_out,min_value,max_value; int32_t outlen; + for (i=0; i<32; i++) + message_out[i] = 0; + CHECK(secp256k1_rangeproof_rewind(data->ctx,blindout,&value_out,message_out,&outlen,data->nonce,&min_value,&max_value,data->commit,data->proof,data->prooflen)); + for (i=0; i<32; i++) + printf("%02x:%02x",data->blind[i],blindout[i]); + printf(" blind, "); + for (i=0; iprooflen); } -static void bench_rangeproof(void* arg) { +static void bench_rangeproof(void* arg) +{ int i; bench_rangeproof_t *data = (bench_rangeproof_t*)arg; @@ -42,21 +72,23 @@ static void bench_rangeproof(void* arg) { int j; uint64_t minv; uint64_t maxv; - j = secp256k1_rangeproof_verify(data->ctx, &minv, &maxv, data->commit, data->proof, data->len); - for (j = 0; j < 4; j++) { + j = secp256k1_rangeproof_verify(data->ctx, &minv, &maxv, data->commit, data->proof, data->prooflen); + for (j = 0; j < 4; j++) + { data->proof[j + 2 + 32 *((data->min_bits + 1) >> 1) - 4] = (i >> 8)&255; } } } -int main(void) { +int proofmain(void) +{ bench_rangeproof_t data; data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); secp256k1_pedersen_context_initialize(data.ctx); secp256k1_rangeproof_context_initialize(data.ctx); - data.min_bits = 32; + data.min_bits = PRIVATEBITS; run_benchmark("rangeproof_verify_bit", bench_rangeproof, bench_rangeproof_setup, NULL, &data, 10, 1000 * data.min_bits); diff --git a/iguana/secp256k1/src/libsecp256k1-config.h b/iguana/secp256k1/src/libsecp256k1-config.h index 40fec6326..bd8713134 100644 --- a/iguana/secp256k1/src/libsecp256k1-config.h +++ b/iguana/secp256k1/src/libsecp256k1-config.h @@ -25,16 +25,16 @@ /* #undef ENABLE_OPENSSL_TESTS */ /* Define this symbol if __builtin_clzll is available */ -#define HAVE_BUILTIN_CLZLL 1 +#define HAVE_BUILTIN_CLZLL 0 /* Define this symbol if __builtin_expect is available */ -#define HAVE_BUILTIN_EXPECT 1 +#define HAVE_BUILTIN_EXPECT 0 /* Define to 1 if you have the header file. */ -#define HAVE_DLFCN_H 1 +#define HAVE_DLFCN_H 0 /* Define to 1 if you have the header file. */ -#define HAVE_INTTYPES_H 1 +#define HAVE_INTTYPES_H 0 /* Define this symbol if libcrypto is installed */ /* #undef HAVE_LIBCRYPTO */ @@ -43,28 +43,28 @@ /* #undef HAVE_LIBGMP */ /* Define to 1 if you have the header file. */ -#define HAVE_MEMORY_H 1 +#define HAVE_MEMORY_H 0 /* Define to 1 if you have the header file. */ -#define HAVE_STDINT_H 1 +#define HAVE_STDINT_H 0 /* Define to 1 if you have the header file. */ -#define HAVE_STDLIB_H 1 +#define HAVE_STDLIB_H 0 /* Define to 1 if you have the header file. */ -#define HAVE_STRINGS_H 1 +#define HAVE_STRINGS_H 0 /* Define to 1 if you have the header file. */ -#define HAVE_STRING_H 1 +#define HAVE_STRING_H 0 /* Define to 1 if you have the header file. */ -#define HAVE_SYS_STAT_H 1 +#define HAVE_SYS_STAT_H 0 /* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 +#define HAVE_SYS_TYPES_H 0 /* Define to 1 if you have the header file. */ -#define HAVE_UNISTD_H 1 +#define HAVE_UNISTD_H 0 /* Define to 1 if the system has the type `__int128'. */ /* #undef HAVE___INT128 */ diff --git a/iguana/secp256k1/src/modules/rangeproof/borromean.h b/iguana/secp256k1/src/modules/rangeproof/borromean.h index 801e1b2e4..56b0ed55c 100644 --- a/iguana/secp256k1/src/modules/rangeproof/borromean.h +++ b/iguana/secp256k1/src/modules/rangeproof/borromean.h @@ -14,11 +14,8 @@ #include "../../ecmult.h" #include "../../ecmult_gen.h" -int secp256k1_borromean_verify(const secp256k1_ecmult_context* ecmult_ctx, secp256k1_scalar *evalues, const unsigned char *e0, const secp256k1_scalar *s, - const secp256k1_gej *pubs, const int *rsizes, int nrings, const unsigned char *m, int mlen); +int secp256k1_borromean_verify(const secp256k1_ecmult_context* ecmult_ctx, secp256k1_scalar *evalues, const unsigned char *e0, const secp256k1_scalar *s,const secp256k1_gej *pubs, const int *rsizes, int nrings, const unsigned char *m, int mlen); -int secp256k1_borromean_sign(const secp256k1_ecmult_context* ecmult_ctx, const secp256k1_ecmult_gen_context *ecmult_gen_ctx, - unsigned char *e0, secp256k1_scalar *s, const secp256k1_gej *pubs, const secp256k1_scalar *k, const secp256k1_scalar *sec, - const int *rsizes, const int *secidx, int nrings, const unsigned char *m, int mlen); +int secp256k1_borromean_sign(const secp256k1_ecmult_context* ecmult_ctx, const secp256k1_ecmult_gen_context *ecmult_gen_ctx,unsigned char *e0, secp256k1_scalar *s, const secp256k1_gej *pubs, const secp256k1_scalar *k, const secp256k1_scalar *sec,const int *rsizes, const int *secidx, int nrings, const unsigned char *m, int mlen); #endif diff --git a/iguana/secp256k1/src/modules/rangeproof/borromean_impl.h b/iguana/secp256k1/src/modules/rangeproof/borromean_impl.h index aeaa4687a..e71c8c360 100644 --- a/iguana/secp256k1/src/modules/rangeproof/borromean_impl.h +++ b/iguana/secp256k1/src/modules/rangeproof/borromean_impl.h @@ -23,8 +23,8 @@ #define BE32(p) ((((p) & 0xFF) << 24) | (((p) & 0xFF00) << 8) | (((p) & 0xFF0000) >> 8) | (((p) & 0xFF000000) >> 24)) #endif -SECP256K1_INLINE static void secp256k1_borromean_hash(unsigned char *hash, const unsigned char *m, int mlen, const unsigned char *e, int elen, - int ridx, int eidx) { +SECP256K1_INLINE static void secp256k1_borromean_hash(unsigned char *hash, const unsigned char *m, int mlen, const unsigned char *e, int elen,int ridx, int eidx) +{ uint32_t ring; uint32_t epos; secp256k1_sha256_t sha256_en; @@ -52,18 +52,10 @@ SECP256K1_INLINE static void secp256k1_borromean_hash(unsigned char *hash, const * | | r_i = r * | return e_0 ==== H(r_{0..i}||m) */ -int secp256k1_borromean_verify(const secp256k1_ecmult_context* ecmult_ctx, secp256k1_scalar *evalues, const unsigned char *e0, - const secp256k1_scalar *s, const secp256k1_gej *pubs, const int *rsizes, int nrings, const unsigned char *m, int mlen) { - secp256k1_gej rgej; - secp256k1_ge rge; - secp256k1_scalar ens; - secp256k1_sha256_t sha256_e0; - unsigned char tmp[33]; - int i; - int j; - int count; - size_t size; - int overflow; +int secp256k1_borromean_verify(const secp256k1_ecmult_context *ecmult_ctx,secp256k1_scalar *evalues, const unsigned char *e0,const secp256k1_scalar *s,const secp256k1_gej *pubs,const int *rsizes,int nrings,const unsigned char *m,int mlen) +{ + secp256k1_gej rgej; secp256k1_ge rge; secp256k1_scalar ens; secp256k1_sha256_t sha256_e0; + unsigned char tmp[33]; int i,j,count,overflow; size_t size; VERIFY_CHECK(ecmult_ctx != NULL); VERIFY_CHECK(e0 != NULL); VERIFY_CHECK(s != NULL); @@ -73,31 +65,27 @@ int secp256k1_borromean_verify(const secp256k1_ecmult_context* ecmult_ctx, secp2 VERIFY_CHECK(m != NULL); count = 0; secp256k1_sha256_initialize(&sha256_e0); - for (i = 0; i < nrings; i++) { + for (i = 0; i < nrings; i++) + { VERIFY_CHECK(INT_MAX - count > rsizes[i]); secp256k1_borromean_hash(tmp, m, mlen, e0, 32, i, 0); secp256k1_scalar_set_b32(&ens, tmp, &overflow); - for (j = 0; j < rsizes[i]; j++) { - if (overflow || secp256k1_scalar_is_zero(&s[count]) || secp256k1_scalar_is_zero(&ens) || secp256k1_gej_is_infinity(&pubs[count])) { + for (j = 0; j < rsizes[i]; j++) + { + if (overflow || secp256k1_scalar_is_zero(&s[count]) || secp256k1_scalar_is_zero(&ens) || secp256k1_gej_is_infinity(&pubs[count])) return 0; - } - if (evalues) { - /*If requested, save the challenges for proof rewind.*/ + if (evalues) evalues[count] = ens; - } secp256k1_ecmult(ecmult_ctx, &rgej, &pubs[count], &ens, &s[count]); - if (secp256k1_gej_is_infinity(&rgej)) { + if (secp256k1_gej_is_infinity(&rgej)) return 0; - } - /* OPT: loop can be hoisted and split to use batch inversion across all the rings; this would make it much faster. */ secp256k1_ge_set_gej_var(&rge, &rgej); secp256k1_eckey_pubkey_serialize(&rge, tmp, &size, 1); - if (j != rsizes[i] - 1) { + if (j != rsizes[i] - 1) + { secp256k1_borromean_hash(tmp, m, mlen, tmp, 33, i, j + 1); secp256k1_scalar_set_b32(&ens, tmp, &overflow); - } else { - secp256k1_sha256_write(&sha256_e0, tmp, size); - } + } else secp256k1_sha256_write(&sha256_e0, tmp, size); count++; } } @@ -106,19 +94,10 @@ int secp256k1_borromean_verify(const secp256k1_ecmult_context* ecmult_ctx, secp2 return memcmp(e0, tmp, 32) == 0; } -int secp256k1_borromean_sign(const secp256k1_ecmult_context* ecmult_ctx, const secp256k1_ecmult_gen_context *ecmult_gen_ctx, - unsigned char *e0, secp256k1_scalar *s, const secp256k1_gej *pubs, const secp256k1_scalar *k, const secp256k1_scalar *sec, - const int *rsizes, const int *secidx, int nrings, const unsigned char *m, int mlen) { - secp256k1_gej rgej; - secp256k1_ge rge; - secp256k1_scalar ens; - secp256k1_sha256_t sha256_e0; - unsigned char tmp[33]; - int i; - int j; - int count; - size_t size; - int overflow; +int secp256k1_borromean_sign(const secp256k1_ecmult_context* ecmult_ctx, const secp256k1_ecmult_gen_context *ecmult_gen_ctx,unsigned char *e0, secp256k1_scalar *s, const secp256k1_gej *pubs, const secp256k1_scalar *k, const secp256k1_scalar *sec,const int *rsizes, const int *secidx, int nrings, const unsigned char *m, int mlen) +{ + secp256k1_gej rgej; secp256k1_ge rge; secp256k1_scalar ens; secp256k1_sha256_t sha256_e0; + unsigned char tmp[33]; int i,j,count,overflow; size_t size; VERIFY_CHECK(ecmult_ctx != NULL); VERIFY_CHECK(ecmult_gen_ctx != NULL); VERIFY_CHECK(e0 != NULL); @@ -132,28 +111,25 @@ int secp256k1_borromean_sign(const secp256k1_ecmult_context* ecmult_ctx, const s VERIFY_CHECK(m != NULL); secp256k1_sha256_initialize(&sha256_e0); count = 0; - for (i = 0; i < nrings; i++) { + for (i = 0; i < nrings; i++) + { VERIFY_CHECK(INT_MAX - count > rsizes[i]); secp256k1_ecmult_gen(ecmult_gen_ctx, &rgej, &k[i]); secp256k1_ge_set_gej(&rge, &rgej); - if (secp256k1_gej_is_infinity(&rgej)) { + if (secp256k1_gej_is_infinity(&rgej)) return 0; - } secp256k1_eckey_pubkey_serialize(&rge, tmp, &size, 1); - for (j = secidx[i] + 1; j < rsizes[i]; j++) { + for (j = secidx[i] + 1; j < rsizes[i]; j++) + { secp256k1_borromean_hash(tmp, m, mlen, tmp, 33, i, j); secp256k1_scalar_set_b32(&ens, tmp, &overflow); - if (overflow || secp256k1_scalar_is_zero(&ens)) { + if (overflow || secp256k1_scalar_is_zero(&ens)) return 0; - } - /** The signing algorithm as a whole is not memory uniform so there is likely a cache sidechannel that - * leaks which members are non-forgeries. That the forgeries themselves are variable time may leave - * an additional privacy impacting timing side-channel, but not a key loss one. + /** The signing algorithm as a whole is not memory uniform so there is likely a cache sidechannel that leaks which members are non-forgeries. That the forgeries themselves are variable time may leave an additional privacy impacting timing side-channel, but not a key loss one. */ secp256k1_ecmult(ecmult_ctx, &rgej, &pubs[count + j], &ens, &s[count + j]); - if (secp256k1_gej_is_infinity(&rgej)) { + if (secp256k1_gej_is_infinity(&rgej)) return 0; - } secp256k1_ge_set_gej_var(&rge, &rgej); secp256k1_eckey_pubkey_serialize(&rge, tmp, &size, 1); } @@ -163,32 +139,30 @@ int secp256k1_borromean_sign(const secp256k1_ecmult_context* ecmult_ctx, const s secp256k1_sha256_write(&sha256_e0, m, mlen); secp256k1_sha256_finalize(&sha256_e0, e0); count = 0; - for (i = 0; i < nrings; i++) { + for (i = 0; i < nrings; i++) + { VERIFY_CHECK(INT_MAX - count > rsizes[i]); secp256k1_borromean_hash(tmp, m, mlen, e0, 32, i, 0); secp256k1_scalar_set_b32(&ens, tmp, &overflow); - if (overflow || secp256k1_scalar_is_zero(&ens)) { + if (overflow || secp256k1_scalar_is_zero(&ens)) return 0; - } - for (j = 0; j < secidx[i]; j++) { + for (j = 0; j < secidx[i]; j++) + { secp256k1_ecmult(ecmult_ctx, &rgej, &pubs[count + j], &ens, &s[count + j]); - if (secp256k1_gej_is_infinity(&rgej)) { + if (secp256k1_gej_is_infinity(&rgej)) return 0; - } secp256k1_ge_set_gej_var(&rge, &rgej); secp256k1_eckey_pubkey_serialize(&rge, tmp, &size, 1); secp256k1_borromean_hash(tmp, m, mlen, tmp, 33, i, j + 1); secp256k1_scalar_set_b32(&ens, tmp, &overflow); - if (overflow || secp256k1_scalar_is_zero(&ens)) { + if (overflow || secp256k1_scalar_is_zero(&ens)) return 0; - } } secp256k1_scalar_mul(&s[count + j], &ens, &sec[i]); secp256k1_scalar_negate(&s[count + j], &s[count + j]); secp256k1_scalar_add(&s[count + j], &s[count + j], &k[i]); - if (secp256k1_scalar_is_zero(&s[count + j])) { + if (secp256k1_scalar_is_zero(&s[count + j])) return 0; - } count += rsizes[i]; } secp256k1_scalar_clear(&ens); diff --git a/iguana/secp256k1/src/modules/rangeproof/main_impl.h b/iguana/secp256k1/src/modules/rangeproof/main_impl.h index 7a36bc894..87de981ab 100644 --- a/iguana/secp256k1/src/modules/rangeproof/main_impl.h +++ b/iguana/secp256k1/src/modules/rangeproof/main_impl.h @@ -16,7 +16,8 @@ void secp256k1_pedersen_context_initialize(secp256k1_context* ctx) { } /* Generates a pedersen commitment: *commit = blind * G + value * G2. The commitment is 33 bytes, the blinding factor is 32 bytes.*/ -int secp256k1_pedersen_commit(const secp256k1_context* ctx, unsigned char *commit, unsigned char *blind, uint64_t value) { +int secp256k1_pedersen_commit(const secp256k1_context* ctx, unsigned char *commit, unsigned char *blind, uint64_t value) +{ secp256k1_gej rj; secp256k1_ge r; secp256k1_scalar sec; @@ -126,10 +127,8 @@ int secp256k1_rangeproof_info(const secp256k1_context* ctx, int *exp, int *manti return secp256k1_rangeproof_getheader_impl(&offset, exp, mantissa, &scale, min_value, max_value, proof, plen); } -int secp256k1_rangeproof_rewind(const secp256k1_context* ctx, - unsigned char *blind_out, uint64_t *value_out, unsigned char *message_out, int *outlen, const unsigned char *nonce, - uint64_t *min_value, uint64_t *max_value, - const unsigned char *commit, const unsigned char *proof, int plen) { +int secp256k1_rangeproof_rewind(const secp256k1_context* ctx,unsigned char *blind_out, uint64_t *value_out, unsigned char *message_out, int *outlen, const unsigned char *nonce,uint64_t *min_value, uint64_t *max_value,const unsigned char *commit, const unsigned char *proof, int plen) +{ ARG_CHECK(ctx != NULL); ARG_CHECK(commit != NULL); ARG_CHECK(proof != NULL); @@ -139,12 +138,12 @@ int secp256k1_rangeproof_rewind(const secp256k1_context* ctx, ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); ARG_CHECK(secp256k1_pedersen_context_is_built(&ctx->pedersen_ctx)); ARG_CHECK(secp256k1_rangeproof_context_is_built(&ctx->rangeproof_ctx)); - return secp256k1_rangeproof_verify_impl(&ctx->ecmult_ctx, &ctx->ecmult_gen_ctx, &ctx->pedersen_ctx, &ctx->rangeproof_ctx, - blind_out, value_out, message_out, outlen, nonce, min_value, max_value, commit, proof, plen); + return secp256k1_rangeproof_verify_impl(&ctx->ecmult_ctx, &ctx->ecmult_gen_ctx, &ctx->pedersen_ctx, &ctx->rangeproof_ctx,blind_out, value_out, message_out, outlen, nonce, min_value, max_value, commit, proof, plen); } int secp256k1_rangeproof_verify(const secp256k1_context* ctx, uint64_t *min_value, uint64_t *max_value, - const unsigned char *commit, const unsigned char *proof, int plen) { + const unsigned char *commit, const unsigned char *proof, int plen) +{ ARG_CHECK(ctx != NULL); ARG_CHECK(commit != NULL); ARG_CHECK(proof != NULL); @@ -153,12 +152,11 @@ int secp256k1_rangeproof_verify(const secp256k1_context* ctx, uint64_t *min_valu ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); ARG_CHECK(secp256k1_pedersen_context_is_built(&ctx->pedersen_ctx)); ARG_CHECK(secp256k1_rangeproof_context_is_built(&ctx->rangeproof_ctx)); - return secp256k1_rangeproof_verify_impl(&ctx->ecmult_ctx, NULL, &ctx->pedersen_ctx, &ctx->rangeproof_ctx, - NULL, NULL, NULL, NULL, NULL, min_value, max_value, commit, proof, plen); + return secp256k1_rangeproof_verify_impl(&ctx->ecmult_ctx, NULL, &ctx->pedersen_ctx, &ctx->rangeproof_ctx,NULL, NULL, NULL, NULL, NULL, min_value, max_value, commit, proof, plen); } -int secp256k1_rangeproof_sign(const secp256k1_context* ctx, unsigned char *proof, int *plen, uint64_t min_value, - const unsigned char *commit, const unsigned char *blind, const unsigned char *nonce, int exp, int min_bits, uint64_t value){ +int secp256k1_rangeproof_sign(const secp256k1_context *ctx, unsigned char *proof, int *plen,uint64_t min_value,const unsigned char *commit, const unsigned char *blind, const unsigned char *nonce,int exp,int min_bits, uint64_t value) +{ ARG_CHECK(ctx != NULL); ARG_CHECK(proof != NULL); ARG_CHECK(plen != NULL); @@ -169,8 +167,7 @@ int secp256k1_rangeproof_sign(const secp256k1_context* ctx, unsigned char *proof ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); ARG_CHECK(secp256k1_pedersen_context_is_built(&ctx->pedersen_ctx)); ARG_CHECK(secp256k1_rangeproof_context_is_built(&ctx->rangeproof_ctx)); - return secp256k1_rangeproof_sign_impl(&ctx->ecmult_ctx, &ctx->ecmult_gen_ctx, &ctx->pedersen_ctx, &ctx->rangeproof_ctx, - proof, plen, min_value, commit, blind, nonce, exp, min_bits, value); + return secp256k1_rangeproof_sign_impl(&ctx->ecmult_ctx, &ctx->ecmult_gen_ctx, &ctx->pedersen_ctx, &ctx->rangeproof_ctx,proof, plen, min_value, commit, blind, nonce, exp, min_bits, value); } #endif diff --git a/iguana/secp256k1/src/modules/rangeproof/rangeproof.h b/iguana/secp256k1/src/modules/rangeproof/rangeproof.h index 1f19ba922..71188dd9c 100644 --- a/iguana/secp256k1/src/modules/rangeproof/rangeproof.h +++ b/iguana/secp256k1/src/modules/rangeproof/rangeproof.h @@ -10,22 +10,15 @@ #include "../../scalar.h" #include "../../group.h" -typedef struct { - secp256k1_ge_storage (*prec)[1005]; -} secp256k1_rangeproof_context; +typedef struct { secp256k1_ge_storage (*prec)[1005]; } secp256k1_rangeproof_context; static void secp256k1_rangeproof_context_init(secp256k1_rangeproof_context* ctx); static void secp256k1_rangeproof_context_build(secp256k1_rangeproof_context* ctx, const secp256k1_callback* cb); -static void secp256k1_rangeproof_context_clone(secp256k1_rangeproof_context *dst, - const secp256k1_rangeproof_context* src, const secp256k1_callback* cb); +static void secp256k1_rangeproof_context_clone(secp256k1_rangeproof_context *dst,const secp256k1_rangeproof_context* src, const secp256k1_callback* cb); static void secp256k1_rangeproof_context_clear(secp256k1_rangeproof_context* ctx); static int secp256k1_rangeproof_context_is_built(const secp256k1_rangeproof_context* ctx); - static int secp256k1_rangeproof_verify_impl(const secp256k1_ecmult_context* ecmult_ctx, - const secp256k1_ecmult_gen_context* ecmult_gen_ctx, - const secp256k1_pedersen_context* pedersen_ctx, const secp256k1_rangeproof_context* rangeproof_ctx, - unsigned char *blindout, uint64_t *value_out, unsigned char *message_out, int *outlen, const unsigned char *nonce, - uint64_t *min_value, uint64_t *max_value, const unsigned char *commit, const unsigned char *proof, int plen); + const secp256k1_ecmult_gen_context* ecmult_gen_ctx,const secp256k1_pedersen_context* pedersen_ctx, const secp256k1_rangeproof_context* rangeproof_ctx,unsigned char *blindout, uint64_t *value_out, unsigned char *message_out, int *outlen, const unsigned char *nonce, uint64_t *min_value, uint64_t *max_value, const unsigned char *commit, const unsigned char *proof, int plen); #endif diff --git a/iguana/secp256k1/src/modules/rangeproof/rangeproof_impl.h b/iguana/secp256k1/src/modules/rangeproof/rangeproof_impl.h index 125c3c004..22b245cf2 100644 --- a/iguana/secp256k1/src/modules/rangeproof/rangeproof_impl.h +++ b/iguana/secp256k1/src/modules/rangeproof/rangeproof_impl.h @@ -107,26 +107,24 @@ static void secp256k1_rangeproof_context_clone(secp256k1_rangeproof_context *dst } } -static void secp256k1_rangeproof_context_clear(secp256k1_rangeproof_context *ctx) { +static void secp256k1_rangeproof_context_clear(secp256k1_rangeproof_context *ctx) +{ free(ctx->prec); ctx->prec = NULL; } -SECP256K1_INLINE static void secp256k1_rangeproof_pub_expand(const secp256k1_rangeproof_context *ctx, secp256k1_gej *pubs, - int exp, int *rsizes, int rings) { - secp256k1_ge ge; - secp256k1_ge_storage *basis; - int i; - int j; - int npub; +SECP256K1_INLINE static void secp256k1_rangeproof_pub_expand(const secp256k1_rangeproof_context *ctx, secp256k1_gej *pubs,int exp, int *rsizes, int rings) +{ + secp256k1_ge ge; secp256k1_ge_storage *basis; int i,j,npub; VERIFY_CHECK(exp < 19); - if (exp < 0) { + if (exp < 0) exp = 0; - } basis = &(*ctx->prec)[secp256k1_rangeproof_offsets[exp]]; npub = 0; - for (i = 0; i < rings; i++) { - for (j = 1; j < rsizes[i]; j++) { + for (i = 0; i < rings; i++) + { + for (j = 1; j < rsizes[i]; j++) + { secp256k1_ge_from_storage(&ge, &basis[i * 3 + j - 1]); secp256k1_gej_add_ge_var(&pubs[npub + j], &pubs[npub], &ge, NULL); } @@ -134,18 +132,10 @@ SECP256K1_INLINE static void secp256k1_rangeproof_pub_expand(const secp256k1_ran } } -SECP256K1_INLINE static int secp256k1_rangeproof_genrand(secp256k1_scalar *sec, secp256k1_scalar *s, unsigned char *message, - int *rsizes, int rings, const unsigned char *nonce, const unsigned char *commit, const unsigned char *proof, int len) { - unsigned char tmp[32]; - unsigned char rngseed[32 + 33 + 10]; - secp256k1_rfc6979_hmac_sha256_t rng; - secp256k1_scalar acc; - int overflow; - int ret; - int i; - int j; - int b; - int npub; +SECP256K1_INLINE static int secp256k1_rangeproof_genrand(secp256k1_scalar *sec, secp256k1_scalar *s, unsigned char *message,int *rsizes, int rings, const unsigned char *nonce, const unsigned char *commit, const unsigned char *proof, int len) +{ + unsigned char tmp[32]; unsigned char rngseed[32 + 33 + 10]; secp256k1_rfc6979_hmac_sha256_t rng; + secp256k1_scalar acc; int overflow,ret,i,j,b,npub; VERIFY_CHECK(len <= 10); memcpy(rngseed, nonce, 32); memcpy(rngseed + 32, commit, 33); @@ -154,22 +144,30 @@ SECP256K1_INLINE static int secp256k1_rangeproof_genrand(secp256k1_scalar *sec, secp256k1_scalar_clear(&acc); npub = 0; ret = 1; - for (i = 0; i < rings; i++) { - if (i < rings - 1) { + for (i = 0; i < rings; i++) + { + if (i < rings - 1) + { secp256k1_rfc6979_hmac_sha256_generate(&rng, tmp, 32); - do { + do + { secp256k1_rfc6979_hmac_sha256_generate(&rng, tmp, 32); secp256k1_scalar_set_b32(&sec[i], tmp, &overflow); } while (overflow || secp256k1_scalar_is_zero(&sec[i])); secp256k1_scalar_add(&acc, &acc, &sec[i]); - } else { + } + else + { secp256k1_scalar_negate(&acc, &acc); sec[i] = acc; } - for (j = 0; j < rsizes[i]; j++) { + for (j = 0; j < rsizes[i]; j++) + { secp256k1_rfc6979_hmac_sha256_generate(&rng, tmp, 32); - if (message) { - for (b = 0; b < 32; b++) { + if (message) + { + for (b = 0; b < 32; b++) + { tmp[b] ^= message[(i * 4 + j) * 32 + b]; message[(i * 4 + j) * 32 + b] = tmp[b]; } @@ -185,8 +183,8 @@ SECP256K1_INLINE static int secp256k1_rangeproof_genrand(secp256k1_scalar *sec, return ret; } -SECP256K1_INLINE static int secp256k1_range_proveparams(uint64_t *v, int *rings, int *rsizes, int *npub, int *secidx, uint64_t *min_value, - int *mantissa, uint64_t *scale, int *exp, int *min_bits, uint64_t value) { +SECP256K1_INLINE static int secp256k1_range_proveparams(uint64_t *v,int *rings,int *rsizes,int *npub,int *secidx,uint64_t *min_value,int *mantissa, uint64_t *scale,int *exp,int *min_bits,uint64_t value) +{ int i; *rings = 1; rsizes[0] = 1; @@ -194,22 +192,20 @@ SECP256K1_INLINE static int secp256k1_range_proveparams(uint64_t *v, int *rings, *scale = 1; *mantissa = 0; *npub = 0; - if (*min_value == UINT64_MAX) { - /* If the minimum value is the maximal representable value, then we cannot code a range. */ + if ( *min_value == UINT64_MAX ) *exp = -1; - } - if (*exp >= 0) { - int max_bits; - uint64_t v2; - if ((*min_value && value > INT64_MAX) || (value && *min_value >= INT64_MAX)) { - /* If either value or min_value is >= 2^63-1 then the other must by zero to avoid overflowing the proven range. */ + if ( *exp >= 0 ) + { + int max_bits; uint64_t v2; + if ((*min_value && value > INT64_MAX) || (value && *min_value >= INT64_MAX)) + { return 0; } max_bits = *min_value ? secp256k1_clz64_var(*min_value) : 64; - if (*min_bits > max_bits) { + if (*min_bits > max_bits) *min_bits = max_bits; - } - if (*min_bits > 61 || value > INT64_MAX) { + if (*min_bits > 61 || value > INT64_MAX) + { /** Ten is not a power of two, so dividing by ten and then representing in base-2 times ten * expands the representable range. The verifier requires the proven range is within 0..2**64. * For very large numbers (all over 2**63) we must change our exponent to compensate. @@ -217,39 +213,36 @@ SECP256K1_INLINE static int secp256k1_range_proveparams(uint64_t *v, int *rings, */ *exp = 0; } - /* Mask off the least significant digits, as requested. */ *v = value - *min_value; - /* If the user has asked for more bits of proof then there is room for in the exponent, reduce the exponent. */ v2 = *min_bits ? (UINT64_MAX>>(64-*min_bits)) : 0; - for (i = 0; i < *exp && (v2 <= UINT64_MAX / 10); i++) { + for (i = 0; i < *exp && (v2 <= UINT64_MAX / 10); i++) + { *v /= 10; v2 *= 10; } *exp = i; v2 = *v; - for (i = 0; i < *exp; i++) { + for (i = 0; i < *exp; i++) + { v2 *= 10; *scale *= 10; } - /* If the masked number isn't precise, compute the public offset. */ *min_value = value - v2; - /* How many bits do we need to represent our value? */ *mantissa = *v ? 64 - secp256k1_clz64_var(*v) : 1; - if (*min_bits > *mantissa) { - /* If the user asked for more precision, give it to them. */ + if (*min_bits > *mantissa) *mantissa = *min_bits; - } - /* Digits in radix-4, except for the last digit if our mantissa length is odd. */ *rings = (*mantissa + 1) >> 1; - for (i = 0; i < *rings; i++) { + for (i = 0; i < *rings; i++) + { rsizes[i] = ((i < *rings - 1) | (!(*mantissa&1))) ? 4 : 2; *npub += rsizes[i]; secidx[i] = (*v >> (i*2)) & 3; } VERIFY_CHECK(*mantissa>0); - VERIFY_CHECK((*v & ~(UINT64_MAX>>(64-*mantissa))) == 0); /* Did this get all the bits? */ - } else { - /* A proof for an exact value. */ + VERIFY_CHECK((*v & ~(UINT64_MAX>>(64-*mantissa))) == 0); + } + else + { *exp = 0; *min_value = value; *v = 0; @@ -262,19 +255,18 @@ SECP256K1_INLINE static int secp256k1_range_proveparams(uint64_t *v, int *rings, return 1; } -/* strawman interface, writes proof in proof, a buffer of plen, proves with respect to min_value the range for commit which has the provided blinding factor and value. */ -SECP256K1_INLINE static int secp256k1_rangeproof_sign_impl(const secp256k1_ecmult_context* ecmult_ctx, - const secp256k1_ecmult_gen_context* ecmult_gen_ctx, const secp256k1_pedersen_context* pedersen_ctx, - const secp256k1_rangeproof_context* rangeproof_ctx, unsigned char *proof, int *plen, uint64_t min_value, - const unsigned char *commit, const unsigned char *blind, const unsigned char *nonce, int exp, int min_bits, uint64_t value){ +SECP256K1_INLINE static int secp256k1_rangeproof_sign_impl(const secp256k1_ecmult_context *ecmult_ctx, + const secp256k1_ecmult_gen_context *ecmult_gen_ctx,const secp256k1_pedersen_context *pedersen_ctx, + const secp256k1_rangeproof_context *rangeproof_ctx,unsigned char *proof,int *plen,uint64_t min_value, + const unsigned char *commit,const unsigned char *blind,const unsigned char *nonce,int exp,int min_bits,uint64_t value) +{ secp256k1_gej pubs[128]; /* Candidate digits for our proof, most inferred. */ secp256k1_scalar s[128]; /* Signatures in our proof, most forged. */ secp256k1_scalar sec[32]; /* Blinding factors for the correct digits. */ secp256k1_scalar k[32]; /* Nonces for our non-forged signatures. */ secp256k1_scalar stmp; secp256k1_sha256_t sha256_m; - unsigned char prep[4096]; - unsigned char tmp[33]; + unsigned char tmp[33],prep[4096]; unsigned char *signs; /* Location of sign flags in the proof. */ uint64_t v; uint64_t scale; /* scale = 10^exp. */ @@ -283,57 +275,55 @@ SECP256K1_INLINE static int secp256k1_rangeproof_sign_impl(const secp256k1_ecmul int rsizes[32]; /* How many possible values there are for each place. */ int secidx[32]; /* Which digit is the correct one. */ int len; /* Number of bytes used so far. */ - int i; - int overflow; - int npub; + int i,overflow,npub,idx = 0; len = 0; - if (*plen < 65 || min_value > value || min_bits > 64 || min_bits < 0 || exp < -1 || exp > 18) { + if (*plen < 65 || min_value > value || min_bits > 64 || min_bits < 0 || exp < -1 || exp > 18) return 0; - } - if (!secp256k1_range_proveparams(&v, &rings, rsizes, &npub, secidx, &min_value, &mantissa, &scale, &exp, &min_bits, value)) { + if (!secp256k1_range_proveparams(&v, &rings, rsizes, &npub, secidx, &min_value, &mantissa, &scale, &exp, &min_bits, value)) return 0; - } proof[len] = (rsizes[0] > 1 ? (64 | exp) : 0) | (min_value ? 32 : 0); len++; - if (rsizes[0] > 1) { + if (rsizes[0] > 1) + { VERIFY_CHECK(mantissa > 0 && mantissa <= 64); proof[len] = mantissa - 1; len++; } - if (min_value) { - for (i = 0; i < 8; i++) { + if (min_value) + { + for (i = 0; i < 8; i++) proof[len + i] = (min_value >> ((7-i) * 8)) & 255; - } len += 8; } - /* Do we have enough room for the proof? */ - if (*plen - len < 32 * (npub + rings - 1) + 32 + ((rings+6) >> 3)) { + if (*plen - len < 32 * (npub + rings - 1) + 32 + ((rings+6) >> 3)) return 0; - } secp256k1_sha256_initialize(&sha256_m); secp256k1_sha256_write(&sha256_m, commit, 33); secp256k1_sha256_write(&sha256_m, proof, len); - memset(prep, 0, 4096); - /* Note, the data corresponding to the blinding factors must be zero. */ - if (rsizes[rings - 1] > 1) { - int idx; - /* Value encoding sidechannel. */ + if (rsizes[rings - 1] > 1) + { idx = rsizes[rings - 1] - 1; idx -= secidx[rings - 1] == idx; idx = ((rings - 1) * 4 + idx) * 32; - for (i = 0; i < 8; i++) { + for (i = 0; i < 8; i++) + { prep[8 + i + idx] = prep[16 + i + idx] = prep[24 + i + idx] = (v >> (56 - i * 8)) & 255; prep[i + idx] = 0; } prep[idx] = 128; } - if (!secp256k1_rangeproof_genrand(sec, s, prep, rsizes, rings, nonce, commit, proof, len)) { - return 0; + /*for (i=0; i<4096; i++) + { + if ( prep[i] != 0 ) + printf("(%d:%02x) ",i,prep[i]); } + printf("prep\n");*/ + if (!secp256k1_rangeproof_genrand(sec, s, prep, rsizes, rings, nonce, commit, proof, len)) + return 0; memset(prep, 0, 4096); - for (i = 0; i < rings; i++) { - /* Sign will overwrite the non-forged signature, move that random value into the nonce. */ + for (i = 0; i < rings; i++) + { k[i] = s[i * 4 + secidx[i]]; secp256k1_scalar_clear(&s[i * 4 + secidx[i]]); } @@ -345,30 +335,26 @@ SECP256K1_INLINE static int secp256k1_rangeproof_sign_impl(const secp256k1_ecmul */ secp256k1_scalar_set_b32(&stmp, blind, &overflow); secp256k1_scalar_add(&sec[rings - 1], &sec[rings - 1], &stmp); - if (overflow || secp256k1_scalar_is_zero(&sec[rings - 1])) { + if (overflow || secp256k1_scalar_is_zero(&sec[rings - 1])) return 0; - } signs = &proof[len]; - /* We need one sign bit for each blinded value we send. */ - for (i = 0; i < (rings + 6) >> 3; i++) { + for (i = 0; i < (rings + 6) >> 3; i++) + { signs[i] = 0; len++; } npub = 0; - for (i = 0; i < rings; i++) { - /*OPT: Use the precomputed gen2 basis?*/ + for (i = 0; i < rings; i++) + { secp256k1_pedersen_ecmult(ecmult_gen_ctx, pedersen_ctx, &pubs[npub], &sec[i], ((uint64_t)secidx[i] * scale) << (i*2)); - if (secp256k1_gej_is_infinity(&pubs[npub])) { + if (secp256k1_gej_is_infinity(&pubs[npub])) return 0; - } - if (i < rings - 1) { - size_t size = 33; - secp256k1_ge c; - /*OPT: split loop and batch invert.*/ + if (i < rings - 1) + { + secp256k1_ge c; size_t size = 33; secp256k1_ge_set_gej_var(&c, &pubs[npub]); - if(!secp256k1_eckey_pubkey_serialize(&c, tmp, &size, 1)) { + if(!secp256k1_eckey_pubkey_serialize(&c, tmp, &size, 1)) return 0; - } secp256k1_sha256_write(&sha256_m, tmp, 33); signs[i>>3] |= (tmp[0] == 3) << (i&7); memcpy(&proof[len], &tmp[1], 32); @@ -378,11 +364,11 @@ SECP256K1_INLINE static int secp256k1_rangeproof_sign_impl(const secp256k1_ecmul } secp256k1_rangeproof_pub_expand(rangeproof_ctx, pubs, exp, rsizes, rings); secp256k1_sha256_finalize(&sha256_m, tmp); - if (!secp256k1_borromean_sign(ecmult_ctx, ecmult_gen_ctx, &proof[len], s, pubs, k, sec, rsizes, secidx, rings, tmp, 32)) { + if (!secp256k1_borromean_sign(ecmult_ctx, ecmult_gen_ctx, &proof[len], s, pubs, k, sec, rsizes, secidx, rings, tmp, 32)) return 0; - } len += 32; - for (i = 0; i < npub; i++) { + for (i = 0; i < npub; i++) + { secp256k1_scalar_get_b32(&proof[len],&s[i]); len += 32; } @@ -393,8 +379,8 @@ SECP256K1_INLINE static int secp256k1_rangeproof_sign_impl(const secp256k1_ecmul } /* Computes blinding factor x given k, s, and the challenge e. */ -SECP256K1_INLINE static void secp256k1_rangeproof_recover_x(secp256k1_scalar *x, const secp256k1_scalar *k, const secp256k1_scalar *e, - const secp256k1_scalar *s) { +SECP256K1_INLINE static void secp256k1_rangeproof_recover_x(secp256k1_scalar *x, const secp256k1_scalar *k, const secp256k1_scalar *e,const secp256k1_scalar *s) +{ secp256k1_scalar stmp; secp256k1_scalar_negate(x, s); secp256k1_scalar_add(x, x, k); @@ -403,271 +389,216 @@ SECP256K1_INLINE static void secp256k1_rangeproof_recover_x(secp256k1_scalar *x, } /* Computes ring's nonce given the blinding factor x, the challenge e, and the signature s. */ -SECP256K1_INLINE static void secp256k1_rangeproof_recover_k(secp256k1_scalar *k, const secp256k1_scalar *x, const secp256k1_scalar *e, - const secp256k1_scalar *s) { +SECP256K1_INLINE static void secp256k1_rangeproof_recover_k(secp256k1_scalar *k, const secp256k1_scalar *x, const secp256k1_scalar *e,const secp256k1_scalar *s) +{ secp256k1_scalar stmp; secp256k1_scalar_mul(&stmp, x, e); secp256k1_scalar_add(k, s, &stmp); } -SECP256K1_INLINE static void secp256k1_rangeproof_ch32xor(unsigned char *x, const unsigned char *y) { +SECP256K1_INLINE static void secp256k1_rangeproof_ch32xor(unsigned char *x, const unsigned char *y) +{ int i; - for (i = 0; i < 32; i++) { + for (i = 0; i < 32; i++) x[i] ^= y[i]; - } } -SECP256K1_INLINE static int secp256k1_rangeproof_rewind_inner(secp256k1_scalar *blind, uint64_t *v, - unsigned char *m, int *mlen, secp256k1_scalar *ev, secp256k1_scalar *s, - int *rsizes, int rings, const unsigned char *nonce, const unsigned char *commit, const unsigned char *proof, int len) { - secp256k1_scalar s_orig[128]; - secp256k1_scalar sec[32]; - secp256k1_scalar stmp; - unsigned char prep[4096]; - unsigned char tmp[32]; - uint64_t value; - int offset; - int i; - int j; - int b; - int skip1; - int skip2; - int npub; +SECP256K1_INLINE static int secp256k1_rangeproof_rewind_inner(secp256k1_scalar *blind,uint64_t *v, + unsigned char *message,int *mlen,secp256k1_scalar *ev,secp256k1_scalar *s,int *rsizes,int rings, const unsigned char *nonce,const unsigned char *commit,const unsigned char *proof,int len) +{ + unsigned char prep[4096]; unsigned char tmp[32]; uint64_t value; int offset,i,j,b,skip1,skip2,npub; + secp256k1_scalar s_orig[128]; secp256k1_scalar sec[32]; secp256k1_scalar stmp; npub = ((rings - 1) << 2) + rsizes[rings-1]; VERIFY_CHECK(npub <= 128); VERIFY_CHECK(npub >= 1); - memset(prep, 0, 4096); - /* Reconstruct the provers random values. */ + memset(prep,0,4096); secp256k1_rangeproof_genrand(sec, s_orig, prep, rsizes, rings, nonce, commit, proof, len); *v = UINT64_MAX; secp256k1_scalar_clear(blind); - if (rings == 1 && rsizes[0] == 1) { - /* With only a single proof, we can only recover the blinding factor. */ - secp256k1_rangeproof_recover_x(blind, &s_orig[0], &ev[0], &s[0]); - if (v) { + if ( rings == 1 && rsizes[0] == 1 ) + { + secp256k1_rangeproof_recover_x(blind,&s_orig[0],&ev[0],&s[0]); + if (v) *v = 0; - } - if (mlen) { + if (mlen) *mlen = 0; - } return 1; } npub = (rings - 1) << 2; - for (j = 0; j < 2; j++) { + for (j = 0; j < 2; j++) + { int idx; - /* Look for a value encoding in the last ring. */ idx = npub + rsizes[rings - 1] - 1 - j; secp256k1_scalar_get_b32(tmp, &s[idx]); secp256k1_rangeproof_ch32xor(tmp, &prep[idx * 32]); - if ((tmp[0] & 128) && (memcmp(&tmp[16], &tmp[24], 8) == 0) && (memcmp(&tmp[8], &tmp[16], 8) == 0)) { + if ( (tmp[0] & 128) && memcmp(&tmp[16],&tmp[24],8) == 0 && memcmp(&tmp[8],&tmp[16],8) == 0 ) + { value = 0; - for (i = 0; i < 8; i++) { + for (i = 0; i < 8; i++) value = (value << 8) + tmp[24 + i]; - } - if (v) { + if (v) *v = value; - } memcpy(&prep[idx * 32], tmp, 32); break; } } - if (j > 1) { - /* Couldn't extract a value. */ - if (mlen) { + if ( j > 1 ) + { + if (mlen) *mlen = 0; - } return 0; } skip1 = rsizes[rings - 1] - 1 - j; skip2 = ((value >> ((rings - 1) << 1)) & 3); - if (skip1 == skip2) { - /*Value is in wrong position.*/ - if (mlen) { + if (skip1 == skip2) + { + if (mlen) *mlen = 0; - } return 0; } skip1 += (rings - 1) << 2; skip2 += (rings - 1) << 2; - /* Like in the rsize[] == 1 case, Having figured out which s is the one which was not forged, we can recover the blinding factor. */ secp256k1_rangeproof_recover_x(&stmp, &s_orig[skip2], &ev[skip2], &s[skip2]); secp256k1_scalar_negate(&sec[rings - 1], &sec[rings - 1]); secp256k1_scalar_add(blind, &stmp, &sec[rings - 1]); - if (!m || !mlen || *mlen == 0) { - if (mlen) { + if (!message || !mlen || *mlen == 0) + { + if (mlen) *mlen = 0; - } - /* FIXME: cleanup in early out/failure cases. */ return 1; } offset = 0; npub = 0; - for (i = 0; i < rings; i++) { + for (i = 0; i < rings; i++) + { int idx; idx = (value >> (i << 1)) & 3; - for (j = 0; j < rsizes[i]; j++) { - if (npub == skip1 || npub == skip2) { + for (j = 0; j < rsizes[i]; j++) + { + if ( npub == skip1 || npub == skip2 ) + { npub++; continue; } - if (idx == j) { + if ( idx == j ) + { /** For the non-forged signatures the signature is calculated instead of random, instead we recover the prover's nonces. * this could just as well recover the blinding factors and messages could be put there as is done for recovering the * blinding factor in the last ring, but it takes an inversion to recover x so it's faster to put the message data in k. */ - secp256k1_rangeproof_recover_k(&stmp, &sec[i], &ev[npub], &s[npub]); - } else { - stmp = s[npub]; - } - secp256k1_scalar_get_b32(tmp, &stmp); - secp256k1_rangeproof_ch32xor(tmp, &prep[npub * 32]); - for (b = 0; b < 32 && offset < *mlen; b++) { - m[offset] = tmp[b]; - offset++; - } + secp256k1_rangeproof_recover_k(&stmp,&sec[i],&ev[npub],&s[npub]); + } else stmp = s[npub]; + secp256k1_scalar_get_b32(tmp,&stmp); + secp256k1_rangeproof_ch32xor(tmp,&prep[npub * 32]); + for (b = 0; b < 32 && offset < *mlen; b++) + message[offset++] = tmp[b]; npub++; } } *mlen = offset; - memset(prep, 0, 4096); - for (i = 0; i < 128; i++) { + memset(prep,0,4096); + for (i = 0; i < 128; i++) secp256k1_scalar_clear(&s_orig[i]); - } - for (i = 0; i < 32; i++) { + for (i = 0; i < 32; i++) secp256k1_scalar_clear(&sec[i]); - } secp256k1_scalar_clear(&stmp); return 1; } -SECP256K1_INLINE static int secp256k1_rangeproof_getheader_impl(int *offset, int *exp, int *mantissa, uint64_t *scale, - uint64_t *min_value, uint64_t *max_value, const unsigned char *proof, int plen) { - int i; - int has_nz_range; - int has_min; - if (plen < 65 || ((proof[*offset] & 128) != 0)) { +SECP256K1_INLINE static int secp256k1_rangeproof_getheader_impl(int *offset, int *exp, int *mantissa, uint64_t *scale, uint64_t *min_value, uint64_t *max_value, const unsigned char *proof, int plen) +{ + int i,has_nz_range,has_min; + if (plen < 65 || ((proof[*offset] & 128) != 0)) return 0; - } has_nz_range = proof[*offset] & 64; has_min = proof[*offset] & 32; *exp = -1; *mantissa = 0; - if (has_nz_range) { + if (has_nz_range) + { *exp = proof[*offset] & 31; *offset += 1; - if (*exp > 18) { + if (*exp > 18) return 0; - } *mantissa = proof[*offset] + 1; - if (*mantissa > 64) { + if (*mantissa > 64) return 0; - } *max_value = UINT64_MAX>>(64-*mantissa); - } else { - *max_value = 0; - } + } else *max_value = 0; *offset += 1; *scale = 1; - for (i = 0; i < *exp; i++) { - if (*max_value > UINT64_MAX / 10) { + for (i = 0; i < *exp; i++) + { + if (*max_value > UINT64_MAX / 10) return 0; - } *max_value *= 10; *scale *= 10; } *min_value = 0; - if (has_min) { - if(plen - *offset < 8) { + if (has_min) + { + if(plen - *offset < 8) return 0; - } - /*FIXME: Compact minvalue encoding?*/ - for (i = 0; i < 8; i++) { + for (i = 0; i < 8; i++) *min_value = (*min_value << 8) | proof[*offset + i]; - } *offset += 8; } - if (*max_value > UINT64_MAX - *min_value) { + if (*max_value > UINT64_MAX - *min_value) return 0; - } *max_value += *min_value; return 1; } -/* Verifies range proof (len plen) for 33-byte commit, the min/max values proven are put in the min/max arguments; returns 0 on failure 1 on success.*/ -SECP256K1_INLINE static int secp256k1_rangeproof_verify_impl(const secp256k1_ecmult_context* ecmult_ctx, - const secp256k1_ecmult_gen_context* ecmult_gen_ctx, - const secp256k1_pedersen_context* pedersen_ctx, const secp256k1_rangeproof_context* rangeproof_ctx, - unsigned char *blindout, uint64_t *value_out, unsigned char *message_out, int *outlen, const unsigned char *nonce, - uint64_t *min_value, uint64_t *max_value, const unsigned char *commit, const unsigned char *proof, int plen) { - secp256k1_gej accj; - secp256k1_gej pubs[128]; - secp256k1_ge c; - secp256k1_scalar s[128]; - secp256k1_scalar evalues[128]; /* Challenges, only used during proof rewind. */ - secp256k1_sha256_t sha256_m; - int rsizes[32]; - int ret; - int i; - size_t size; - int exp; - int mantissa; - int offset; - int rings; - int overflow; - int npub; - int offset_post_header; - uint64_t scale; - unsigned char signs[31]; - unsigned char m[33]; - const unsigned char *e0; +SECP256K1_INLINE static int secp256k1_rangeproof_verify_impl(const secp256k1_ecmult_context *ecmult_ctx,const secp256k1_ecmult_gen_context *ecmult_gen_ctx,const secp256k1_pedersen_context *pedersen_ctx, const secp256k1_rangeproof_context *rangeproof_ctx,unsigned char *blindout,uint64_t *value_out, unsigned char *message_out,int *outlen,const unsigned char *nonce,uint64_t *min_value,uint64_t *max_value,const unsigned char *commit,const unsigned char *proof,int plen) +{ + secp256k1_gej accj,pubs[128]; secp256k1_ge c; secp256k1_sha256_t sha256_m; + secp256k1_scalar s[128],evalues[128]; + int rsizes[32],ret,i,exp,mantissa,offset,rings,overflow,npub,offset_post_header; + size_t size; uint64_t scale; unsigned char signs[31],m[33]; const unsigned char *e0; offset = 0; - if (!secp256k1_rangeproof_getheader_impl(&offset, &exp, &mantissa, &scale, min_value, max_value, proof, plen)) { + if ( !secp256k1_rangeproof_getheader_impl(&offset, &exp, &mantissa, &scale, min_value, max_value, proof, plen) ) return 0; - } offset_post_header = offset; rings = 1; rsizes[0] = 1; npub = 1; - if (mantissa != 0) { + if (mantissa != 0) + { rings = (mantissa >> 1); - for (i = 0; i < rings; i++) { + for (i = 0; i < rings; i++) rsizes[i] = 4; - } npub = (mantissa >> 1) << 2; - if (mantissa & 1) { + if (mantissa & 1) + { rsizes[rings] = 2; npub += rsizes[rings]; rings++; } } VERIFY_CHECK(rings <= 32); - if (plen - offset < 32 * (npub + rings - 1) + 32 + ((rings+6) >> 3)) { + if (plen - offset < 32 * (npub + rings - 1) + 32 + ((rings+6) >> 3)) return 0; - } secp256k1_sha256_initialize(&sha256_m); secp256k1_sha256_write(&sha256_m, commit, 33); secp256k1_sha256_write(&sha256_m, proof, offset); - for(i = 0; i < rings - 1; i++) { - signs[i] = (proof[offset + ( i>> 3)] & (1 << (i & 7))) != 0; - } + for(i = 0; i < rings - 1; i++) + signs[i] = (proof[offset + (i >> 3)] & (1 << (i & 7))) != 0; offset += (rings + 6) >> 3; - if ((rings - 1) & 7) { - /* Number of coded blinded points is not a multiple of 8, force extra sign bits to 0 to reject mutation. */ - if ((proof[offset - 1] >> ((rings - 1) & 7)) != 0) { + if ( (rings - 1) & 7 ) + { + if ( (proof[offset - 1] >> ((rings - 1) & 7)) != 0 ) return 0; - } } npub = 0; secp256k1_gej_set_infinity(&accj); - if (*min_value) { + if (*min_value) secp256k1_pedersen_ecmult_small(pedersen_ctx, &accj, *min_value); - } - for(i = 0; i < rings - 1; i++) { + for(i = 0; i < rings - 1; i++) + { memcpy(&m[1], &proof[offset], 32); m[0] = 2 + signs[i]; - if (!secp256k1_eckey_pubkey_parse(&c, m, 33)) { + if (!secp256k1_eckey_pubkey_parse(&c, m, 33)) return 0; - } secp256k1_sha256_write(&sha256_m, m, 33); secp256k1_gej_set_ge(&pubs[npub], &c); secp256k1_gej_add_ge_var(&accj, &accj, &c, NULL); @@ -675,60 +606,46 @@ SECP256K1_INLINE static int secp256k1_rangeproof_verify_impl(const secp256k1_ecm npub += rsizes[i]; } secp256k1_gej_neg(&accj, &accj); - if (!secp256k1_eckey_pubkey_parse(&c, commit, 33)) { + if (!secp256k1_eckey_pubkey_parse(&c, commit, 33)) return 0; - } secp256k1_gej_add_ge_var(&pubs[npub], &accj, &c, NULL); - if (secp256k1_gej_is_infinity(&pubs[npub])) { + if (secp256k1_gej_is_infinity(&pubs[npub])) return 0; - } secp256k1_rangeproof_pub_expand(rangeproof_ctx, pubs, exp, rsizes, rings); npub += rsizes[rings - 1]; e0 = &proof[offset]; offset += 32; - for (i = 0; i < npub; i++) { + for (i = 0; i < npub; i++) + { secp256k1_scalar_set_b32(&s[i], &proof[offset], &overflow); - if (overflow) { + if (overflow) return 0; - } offset += 32; } - if (offset != plen) { - /*Extra data found, reject.*/ + if (offset != plen) return 0; - } secp256k1_sha256_finalize(&sha256_m, m); ret = secp256k1_borromean_verify(ecmult_ctx, nonce ? evalues : NULL, e0, s, pubs, rsizes, rings, m, 32); - if (ret && nonce) { - /* Given the nonce, try rewinding the witness to recover its initial state. */ - secp256k1_scalar blind; - unsigned char commitrec[33]; - uint64_t vv; - if (!ecmult_gen_ctx) { + if (ret && nonce) + { + secp256k1_scalar blind; unsigned char commitrec[33]; uint64_t vv; + if (!ecmult_gen_ctx) return 0; - } - if (!secp256k1_rangeproof_rewind_inner(&blind, &vv, message_out, outlen, evalues, s, rsizes, rings, nonce, commit, proof, offset_post_header)) { + if (!secp256k1_rangeproof_rewind_inner(&blind, &vv, message_out, outlen, evalues, s, rsizes, rings, nonce, commit, proof, offset_post_header)) return 0; - } - /* Unwind apparently successful, see if the commitment can be reconstructed. */ - /* FIXME: should check vv is in the mantissa's range. */ vv = (vv * scale) + *min_value; secp256k1_pedersen_ecmult(ecmult_gen_ctx, pedersen_ctx, &accj, &blind, vv); - if (secp256k1_gej_is_infinity(&accj)) { + if (secp256k1_gej_is_infinity(&accj)) return 0; - } secp256k1_ge_set_gej(&c, &accj); size = 33; secp256k1_eckey_pubkey_serialize(&c, commitrec, &size, 1); - if (size != 33 || memcmp(commitrec, commit, 33) != 0) { + if (size != 33 || memcmp(commitrec, commit, 33) != 0) return 0; - } - if (blindout) { + if (blindout) secp256k1_scalar_get_b32(blindout, &blind); - } - if (value_out) { + if (value_out) *value_out = vv; - } } return ret; } diff --git a/iguana/secp256k1/src/modules/schnorr/schnorr_impl.h b/iguana/secp256k1/src/modules/schnorr/schnorr_impl.h index d70d1e466..b6666ab30 100644 --- a/iguana/secp256k1/src/modules/schnorr/schnorr_impl.h +++ b/iguana/secp256k1/src/modules/schnorr/schnorr_impl.h @@ -66,12 +66,12 @@ static int secp256k1_schnorr_sig_sign(const secp256k1_ecmult_gen_context* ctx, u secp256k1_scalar h, s; int overflow; secp256k1_scalar n; - + if (secp256k1_scalar_is_zero(key) || secp256k1_scalar_is_zero(nonce)) { return 0; } n = *nonce; - + secp256k1_ecmult_gen(ctx, &Rj, &n); if (pubnonce != NULL) { secp256k1_gej_add_ge(&Rj, &Rj, pubnonce); @@ -80,10 +80,10 @@ static int secp256k1_schnorr_sig_sign(const secp256k1_ecmult_gen_context* ctx, u secp256k1_fe_normalize(&Ra.y); if (secp256k1_fe_is_odd(&Ra.y)) { /* R's y coordinate is odd, which is not allowed (see rationale above). - Force it to be even by negating the nonce. Note that this even works - for multiparty signing, as the R point is known to all participants, - which can all decide to flip the sign in unison, resulting in the - overall R point to be negated too. */ + Force it to be even by negating the nonce. Note that this even works + for multiparty signing, as the R point is known to all participants, + which can all decide to flip the sign in unison, resulting in the + overall R point to be negated too. */ secp256k1_scalar_negate(&n, &n); } secp256k1_fe_normalize(&Ra.x); @@ -110,7 +110,7 @@ static int secp256k1_schnorr_sig_verify(const secp256k1_ecmult_context* ctx, con secp256k1_scalar h, s; unsigned char hh[32]; int overflow; - + if (secp256k1_ge_is_infinity(pubkey)) { return 0; } @@ -148,7 +148,7 @@ static int secp256k1_schnorr_sig_recover(const secp256k1_ecmult_context* ctx, co secp256k1_scalar h, s; unsigned char hh[32]; int overflow; - + hash(hh, sig64, msg32); overflow = 0; secp256k1_scalar_set_b32(&h, hh, &overflow); diff --git a/iguana/secp256k1/src/modules/schnorr/tests_impl.h b/iguana/secp256k1/src/modules/schnorr/tests_impl.h index 5bd14a03e..8ebf71c9f 100644 --- a/iguana/secp256k1/src/modules/schnorr/tests_impl.h +++ b/iguana/secp256k1/src/modules/schnorr/tests_impl.h @@ -7,7 +7,9 @@ #ifndef SECP256K1_MODULE_SCHNORR_TESTS #define SECP256K1_MODULE_SCHNORR_TESTS -#include "include/secp256k1_schnorr.h" +#include "../../../include/secp256k1_schnorr.h" +#include "../../../include/secp256k1.h" + void test_schnorr_end_to_end(void) { unsigned char privkey[32]; diff --git a/iguana/secp256k1/src/secp256k1.c b/iguana/secp256k1/src/secp256k1.c index b748bbfe3..922caf6cb 100644 --- a/iguana/secp256k1/src/secp256k1.c +++ b/iguana/secp256k1/src/secp256k1.c @@ -545,32 +545,29 @@ int secp256k1_ec_pubkey_tweak_mul(const secp256k1_context* ctx, secp256k1_pubkey return ret; } -int secp256k1_context_randomize(secp256k1_context* ctx, const unsigned char *seed32) { +int secp256k1_context_randomize(secp256k1_context* ctx, const unsigned char *seed32) +{ VERIFY_CHECK(ctx != NULL); ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); secp256k1_ecmult_gen_blind(&ctx->ecmult_gen_ctx, seed32); return 1; } -int secp256k1_ec_pubkey_combine(const secp256k1_context* ctx, secp256k1_pubkey *pubnonce, const secp256k1_pubkey * const *pubnonces, size_t n) { - size_t i; - secp256k1_gej Qj; - secp256k1_ge Q; - +int secp256k1_ec_pubkey_combine(const secp256k1_context* ctx, secp256k1_pubkey *pubnonce, const secp256k1_pubkey * const *pubnonces, size_t n) +{ + size_t i; secp256k1_gej Qj; secp256k1_ge Q; ARG_CHECK(pubnonce != NULL); memset(pubnonce, 0, sizeof(*pubnonce)); ARG_CHECK(n >= 1); ARG_CHECK(pubnonces != NULL); - secp256k1_gej_set_infinity(&Qj); - - for (i = 0; i < n; i++) { + for (i = 0; i < n; i++) + { secp256k1_pubkey_load(ctx, &Q, pubnonces[i]); secp256k1_gej_add_ge(&Qj, &Qj, &Q); } - if (secp256k1_gej_is_infinity(&Qj)) { + if (secp256k1_gej_is_infinity(&Qj)) return 0; - } secp256k1_ge_set_gej(&Q, &Qj); secp256k1_pubkey_save(pubnonce, &Q); return 1; diff --git a/iguana/secp256k1/src/testrand_impl.h b/iguana/secp256k1/src/testrand_impl.h index b5450401d..81ba13868 100644 --- a/iguana/secp256k1/src/testrand_impl.h +++ b/iguana/secp256k1/src/testrand_impl.h @@ -37,7 +37,7 @@ static uint32_t secp256k1_rand_bits(int bits) { secp256k1_test_rng_integer |= (((uint64_t)secp256k1_rand32()) << secp256k1_test_rng_integer_bits_left); secp256k1_test_rng_integer_bits_left += 32; } - ret = secp256k1_test_rng_integer; + ret = (uint32_t)secp256k1_test_rng_integer; secp256k1_test_rng_integer >>= bits; secp256k1_test_rng_integer_bits_left -= bits; ret &= ((~((uint32_t)0)) >> (32 - bits)); diff --git a/iguana/swaps/iguana_BTCswap.c b/iguana/swaps/iguana_BTCswap.c index 9b8a7b9d1..9fe44f2bd 100755 --- a/iguana/swaps/iguana_BTCswap.c +++ b/iguana/swaps/iguana_BTCswap.c @@ -13,51 +13,85 @@ * * ******************************************************************************/ -#define IGUANA_BTCDMULT 40. #include "../exchanges/bitcoin.h" +#include "../../basilisk/basilisk.h" /* https://bitcointalk.org/index.php?topic=1340621.msg13828271#msg13828271 - https://bitcointalk.org/index.php?topic=1364951 -Tier Nolan's approach is followed with the following changes: - a) instead of cutting 1000 keypairs, only INSTANTDEX_DECKSIZE are a - b) instead of sending the entire 256 bits, it is truncated to 64 bits. With odds of collision being so low, it is dwarfed by the ~0.1% insurance factor. - c) D is set to 100x the insurance rate of 1/777 12.87% + BTC amount - d) insurance is added to Bob's payment, which is after the deposit and bailin - e) BEFORE Bob broadcasts deposit, Alice broadcasts BTC denominated fee in cltv so if trade isnt done fee is reclaimed -*/ + https://bitcointalk.org/index.php?topic=1364951 + Tier Nolan's approach is followed with the following changes: + a) instead of cutting 1000 keypairs, only INSTANTDEX_DECKSIZE are a + b) instead of sending the entire 256 bits, it is truncated to 64 bits. With odds of collision being so low, it is dwarfed by the ~0.1% insurance factor. + c) D is set to 100x the insurance rate of 1/777 12.87% + BTC amount + d) insurance is added to Bob's payment, which is after the deposit and bailin + e) BEFORE Bob broadcasts deposit, Alice broadcasts BTC denominated fee in cltv so if trade isnt done fee is reclaimed + */ /* both fees are standard payments: OP_DUP OP_HASH160 FEE_RMD160 OP_EQUALVERIFY OP_CHECKSIG Alice altpayment: OP_2 OP_2 OP_CHECKMULTISIG - Bob deposit: if ( (swap->deposit= instantdex_bobtx(myinfo,coinbtc,&swap->deposittxid,swap->otherpubs[0],swap->mypubs[0],swap->privkeys[swap->choosei],reftime,swap->satoshis[1],1)) != 0 ) +Bob deposit: OP_IF - OP_CLTV OP_DROP OP_CHECKSIG + OP_CLTV OP_DROP OP_CHECKSIG OP_ELSE - OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG +OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG OP_ENDIF - - Bob paytx: if ( (swap->payment= instantdex_bobtx(myinfo,coinbtc,&swap->deposittxid,swap->mypubs[1],swap->otherpubs[0],swap->privkeys[swap->otherschoosei],reftime,swap->satoshis[1],0)) != 0 ) + +Bob paytx: OP_IF - OP_CLTV OP_DROP OP_CHECKSIG + OP_CLTV OP_DROP OP_CHECKSIG OP_ELSE - OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG +OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG OP_ENDIF + +Naming convention are pubAi are alice's pubkeys (seems only pubA0 and not pubA1) +pubBi are Bob's pubkeys + +privN is Bob's privkey from the cut and choose deck as selected by Alice +privM is Alice's counterpart +pubN and pubM are the corresponding pubkeys for these chosen privkeys + +Alice timeout event is triggered if INSTANTDEX_LOCKTIME elapses from the start of a FSM instance. Bob timeout event is triggered after INSTANTDEX_LOCKTIME*2 */ -int32_t instantdex_bobscript(uint8_t *script,int32_t n,int32_t *secretstartp,uint32_t locktime,bits256 cltvpub,uint8_t secret160[20],bits256 destpub) +int32_t instantdex_bobscript(uint8_t *script,int32_t n,uint32_t *locktimep,int32_t *secretstartp,struct bitcoin_swapinfo *swap,int32_t depositflag) { - uint8_t pubkeyA[33],pubkeyB[33]; - memcpy(pubkeyA+1,cltvpub.bytes,sizeof(cltvpub)), pubkeyA[0] = 0x02; - memcpy(pubkeyB+1,destpub.bytes,sizeof(destpub)), pubkeyB[0] = 0x03; + uint8_t pubkeyA[33],pubkeyB[33],*secret160; bits256 cltvpub,destpub; int32_t i; + *locktimep = swap->locktime; + if ( depositflag != 0 ) + { + *locktimep += INSTANTDEX_LOCKTIME; + cltvpub = swap->pubA0; + destpub = swap->pubB0; + secret160 = swap->secretBn; + pubkeyA[0] = 0x02; + pubkeyB[0] = 0x03; + } + else + { + cltvpub = swap->pubB1; + destpub = swap->pubA0; + secret160 = swap->secretAm; + pubkeyA[0] = 0x03; + pubkeyB[0] = 0x02; + } + if ( bits256_nonz(cltvpub) == 0 || bits256_nonz(destpub) == 0 ) + return(-1); + for (i=0; i<20; i++) + if ( secret160[i] != 0 ) + break; + if ( i == 20 ) + return(-1); + memcpy(pubkeyA+1,cltvpub.bytes,sizeof(cltvpub)); + memcpy(pubkeyB+1,destpub.bytes,sizeof(destpub)); script[n++] = SCRIPT_OP_IF; - n = bitcoin_checklocktimeverify(script,n,locktime); - n = bitcoin_pubkeyspend(script,n,pubkeyA); + n = bitcoin_checklocktimeverify(script,n,*locktimep); + n = bitcoin_pubkeyspend(script,n,pubkeyA); script[n++] = SCRIPT_OP_ELSE; if ( secretstartp != 0 ) *secretstartp = n + 2; - n = bitcoin_revealsecret160(script,n,secret160); - n = bitcoin_pubkeyspend(script,n,pubkeyB); + n = bitcoin_revealsecret160(script,n,secret160); + n = bitcoin_pubkeyspend(script,n,pubkeyB); script[n++] = SCRIPT_OP_ENDIF; return(n); } @@ -74,22 +108,48 @@ int32_t instantdex_alicescript(uint8_t *script,int32_t n,char *msigaddr,uint8_t return(n); } -int32_t instantdex_outputinsurance(uint8_t *script,int32_t n,int64_t insurance,uint64_t orderid) +int32_t instantdex_outputinsurance(char *coinaddr,uint8_t addrtype,uint8_t *script,int64_t insurance,uint64_t r,uint64_t dest) { - uint8_t rmd160[20]; - decode_hex(rmd160,sizeof(rmd160),(orderid % 10) == 0 ? TIERNOLAN_RMD160 : INSTANTDEX_RMD160); - script[n++] = sizeof(orderid); - n += iguana_rwnum(1,&script[n],sizeof(orderid),&orderid); - script[n++] = SCRIPT_OP_DROP; + uint8_t rmd160[20]; int32_t n = 0; + decode_hex(rmd160,sizeof(rmd160),(dest % 10) == 9 ? TIERNOLAN_RMD160 : INSTANTDEX_RMD160); + //script[n++] = sizeof(r); + //n += iguana_rwnum(1,&script[n],sizeof(r),&r); + //script[n++] = SCRIPT_OP_DROP; + bitcoin_address(coinaddr,addrtype,rmd160,20); n = bitcoin_standardspend(script,n,rmd160); return(n); } -void disp_tx(struct supernet_info *myinfo,struct iguana_info *coin,char *str,char *txbytes) +/*void disp_tx(struct supernet_info *myinfo,struct iguana_info *coin,char *str,char *txbytes) { cJSON *txobj; bits256 txid; - txobj = bitcoin_hex2json(coin,&txid,0,txbytes); + txobj = bitcoin_hex2json(coin,&txid,0,txbytes,extraspace,extralen); printf("disp_tx (%s) -> %s.(%s)\n",txbytes,str,jprint(txobj,1)); +}*/ + +struct bitcoin_statetx *instantdex_getstatetx(struct bitcoin_swapinfo *swap,char *txname) +{ + //char *txnames[] = { "fee", "dep", "alt", "acl", "bre", "bcl", "bfr", "are", "adp" }; + if ( strcmp(txname,"fee") == 0 ) + return(swap->otherfee); + else if ( strcmp(txname,"dep") == 0 ) + return(swap->deposit); + else if ( strcmp(txname,"alt") == 0 ) + return(swap->altpayment); + else if ( strcmp(txname,"acl") == 0 ) + return(swap->payment); + else if ( strcmp(txname,"bre") == 0 ) + return(swap->deposit); + else if ( strcmp(txname,"bcl") == 0 ) + return(swap->altpayment); + else if ( strcmp(txname,"bfr") == 0 ) + return(swap->myfee); + else if ( strcmp(txname,"are") == 0 ) + return(swap->altpayment); + else if ( strcmp(txname,"adp") == 0 ) + return(swap->deposit); + printf("unrecognized txname.(%s)\n",txname); + return(0); } void iguana_addinputs(struct iguana_info *coin,struct bitcoin_spend *spend,cJSON *txobj,uint32_t sequence) @@ -108,149 +168,170 @@ void iguana_addinputs(struct iguana_info *coin,struct bitcoin_spend *spend,cJSON } } -struct bitcoin_statetx *instantdex_feetx(struct supernet_info *myinfo,struct instantdex_accept *A) +struct bitcoin_statetx *instantdex_signtx(char *str,struct supernet_info *myinfo,struct iguana_info *coin,uint32_t locktime,char *scriptstr,int64_t satoshis,int64_t txfee,int32_t minconf,int32_t myside) { - int32_t n,len; char *feetx = 0; struct iguana_info *coin; bits256 txid; cJSON *txobj; struct bitcoin_spend *spend; int64_t insurance; uint8_t paymentscript[128]; struct bitcoin_statetx *ptr = 0; - if ( (coin= iguana_coinfind("BTCD")) != 0 ) + struct iguana_waddress *waddr; struct iguana_waccount *wacct; struct bitcoin_statetx *tx=0; char coinaddr[64],wifstr[64]; char *rawtx=0,*signedtx,*retstr; bits256 signedtxid; uint32_t basilisktag; int32_t flag,completed; cJSON *valsobj,*vins=0,*retjson=0,*privkey,*addresses; + if ( (waddr= iguana_getaccountaddress(myinfo,coin,0,0,coin->changeaddr,"change")) == 0 ) + { + printf("no change addr error\n"); + return(0); + } + privkey = cJSON_CreateArray(); + addresses = cJSON_CreateArray(); + if ( coin->changeaddr[0] == 0 ) + bitcoin_address(coin->changeaddr,coin->chain->pubtype,waddr->rmd160,20); + //bitcoin_pubkey33(myinfo->ctx,pubkey33,myinfo->persistent_priv); + bitcoin_address(coinaddr,coin->chain->pubtype,myinfo->persistent_pubkey33,33); + //printf("%s persistent.(%s) (%s) change.(%s) scriptstr.(%s)\n",coin->symbol,myinfo->myaddr.BTC,coinaddr,coin->changeaddr,scriptstr); + if ( (waddr= iguana_waddresssearch(myinfo,&wacct,coinaddr)) != 0 ) { - insurance = IGUANA_BTCDMULT * instantdex_insurance(coin,instantdex_BTCsatoshis(A->offer.price64,A->offer.basevolume64)); - if ( (spend= iguana_spendset(myinfo,coin,insurance,coin->chain->txfee,0)) != 0 ) + bitcoin_priv2wif(wifstr,waddr->privkey,coin->chain->wiftype); + jaddistr(privkey,waddr->wifstr); + } + basilisktag = (uint32_t)rand(); + jaddistr(addresses,coinaddr); + valsobj = cJSON_CreateObject(); + jadd(valsobj,"addresses",addresses); + jaddstr(valsobj,"coin",coin->symbol); + jaddstr(valsobj,"spendscript",scriptstr); + jaddstr(valsobj,"changeaddr",coin->changeaddr); + jadd64bits(valsobj,"satoshis",satoshis); + jadd64bits(valsobj,"txfee",txfee); + jaddnum(valsobj,"minconf",minconf); + jaddnum(valsobj,"basilisktag",basilisktag); + jaddnum(valsobj,"locktime",locktime); + jaddnum(valsobj,"timeout",30000); + if ( (retstr= basilisk_rawtx(myinfo,coin,0,0,myinfo->myaddr.persistent,valsobj,"")) != 0 ) + { + //printf("%s got.(%s)\n",str,retstr); + flag = 0; + if ( (retjson= cJSON_Parse(retstr)) != 0 ) { - txobj = bitcoin_txcreate(coin,0); - n = instantdex_outputinsurance(paymentscript,0,insurance,A->orderid); - bitcoin_txoutput(coin,txobj,paymentscript,n,insurance); - iguana_addinputs(coin,spend,txobj,0xffffffff); - if ( spend->change > coin->chain->txfee ) - { - len = bitcoin_standardspend(paymentscript,0,spend->change160); - bitcoin_txoutput(coin,txobj,paymentscript,len,spend->change); - } - txobj = iguana_signtx(myinfo,coin,&txid,&feetx,spend,txobj,0); - if ( feetx != 0 ) + if ( (rawtx= jstr(retjson,"rawtx")) != 0 && (vins= jobj(retjson,"vins")) != 0 ) + flag = 1; + else printf("missing rawtx.%p or vins.%p\n",rawtx,vins); + } else printf("error parsing.(%s)\n",retstr); + if ( flag != 0 && vins != 0 ) + { + //printf("vins.(%s)\n",jprint(vins,0)); + if ( (signedtx= iguana_signrawtx(myinfo,coin,&signedtxid,&completed,vins,rawtx,privkey)) != 0 ) { - ptr = calloc(1,sizeof(*ptr) + strlen(feetx) + 1); - strcpy(ptr->txbytes,feetx); - ptr->txid = txid; - //printf("%s feetx.%s\n",A->offer.myside != 0 ? "BOB" : "ALICE",feetx); - //disp_tx(myinfo,coin,"feetx",feetx); - free(feetx); - } - else printf("error signing %s feetx numinputs.%d\n",A->offer.myside != 0 ? "BOB" : "ALICE",spend->numinputs); - free(spend); + iguana_RTunspentslock(myinfo,coin,vins); + tx = calloc(1,sizeof(*tx) + strlen(signedtx) + 1); + strcpy(tx->txbytes,signedtx); + tx->txid = signedtxid; + printf("%s %s.%s\n",myside != 0 ? "BOB" : "ALICE",str,signedtx); + free(signedtx); + } else printf("error signrawtx\n"); //do a very short timeout so it finishes via local poll } - else + if ( retjson != 0 ) + free_json(retjson); + if ( flag == 2 ) { - printf("no unspents to spend\n"); + free_json(vins); + printf("Free rawtx\n"); + free(rawtx); } - } + free(retstr); + } else printf("error creating %s feetx\n",myside != 0 ? "BOB" : "ALICE"); + free_json(addresses); + return(tx); +} + +struct bitcoin_statetx *instantdex_feetx(struct supernet_info *myinfo,struct instantdex_accept *A,struct bitcoin_swapinfo *swap,struct iguana_info *coin) +{ + int32_t n; uint8_t paymentscript[128]; char scriptstr[512],coinaddr[64]; struct bitcoin_statetx *ptr = 0; uint64_t r; + r = swap->mine.orderid; + n = instantdex_outputinsurance(coinaddr,coin->chain->pubtype,paymentscript,swap->insurance + swap->coinbtc->chain->txfee,r,r * (strcmp("BTC",coin->symbol) == 0)); + init_hexbytes_noT(scriptstr,paymentscript,n); + printf("instantdex_feetx %s %.8f (%s)\n",coin->symbol,dstr(swap->insurance + swap->coinbtc->chain->txfee),scriptstr); + if ( (ptr= instantdex_signtx("feetx",myinfo,coin,0,scriptstr,swap->insurance + swap->coinbtc->chain->txfee,coin->txfee,0,A->offer.myside)) != 0 ) + strcpy(ptr->destaddr,coinaddr); return(ptr); } int32_t instantdex_feetxverify(struct supernet_info *myinfo,struct iguana_info *coin,struct bitcoin_swapinfo *swap,cJSON *argjson) { - cJSON *txobj; bits256 txid; uint32_t n; int32_t i,retval = -1; int64_t insurance; - struct iguana_msgtx msgtx; uint8_t script[512]; - if ( swap->otherfee != 0 && swap->otherfee->numconfirms < 0 ) + cJSON *txobj; bits256 txid; uint32_t n; int32_t i,retval = -1,extralen=65536; int64_t insurance; uint64_t r; + struct iguana_msgtx msgtx; uint8_t script[512],serialized[8192],*extraspace=0; char coinaddr[64]; + if ( swap->otherfee != 0 ) { - if ( (txobj= bitcoin_hex2json(coin,&txid,&msgtx,swap->otherfee->txbytes)) != 0 ) + extraspace = calloc(1,extralen); + if ( (txobj= bitcoin_hex2json(coin,&txid,&msgtx,swap->otherfee->txbytes,extraspace,extralen,serialized)) != 0 ) { - insurance = swap->insurance;//instantdex_insurance(coin,swap->BTCsatoshis); - if ( strcmp(coin->symbol,"BTCD") == 0 ) - insurance *= IGUANA_BTCDMULT; - n = instantdex_outputinsurance(script,0,insurance,swap->matched64); + r = swap->other.orderid; + if ( strcmp(coin->symbol,"BTC") == 0 ) + insurance = swap->insurance + swap->coinbtc->chain->txfee; + else insurance = swap->altinsurance + swap->altcoin->chain->txfee; + n = instantdex_outputinsurance(coinaddr,coin->chain->pubtype,script,insurance,r,r * (strcmp("BTC",coin->symbol) == 0)); if ( n == msgtx.vouts[0].pk_scriptlen ) { if ( memcmp(script,msgtx.vouts[0].pk_script,n) == 0 ) { - //printf("feetx script verified.(%s)\n",swap->otherfeetx); + printf("feetx script verified.(%s)\n",swap->otherfee->txbytes); retval = 0; - swap->otherfee->numconfirms = 0.; } else { for (i=0; iotherfee->txbytes); - } else if ( swap->otherfee != 0 && swap->otherfee->numconfirms >= 0 ) - retval = 0; - else printf("no feetx to verify\n"); + } else printf("no feetx to verify\n"); + if ( extraspace != 0 ) + free(extraspace); return(retval); } -/*char *instantdex_addfeetx(struct supernet_info *myinfo,cJSON *newjson,struct instantdex_accept *ap,struct bitcoin_swapinfo *swap,char *bobstate,char *alicestate) -{ - if ( (swap->myfee= instantdex_feetx(myinfo,&swap->myfee->txid,ap)) != 0 ) - { - jaddstr(newjson,"feetx",swap->myfee->txbytes); - jaddbits256(newjson,"feetxid",swap->myfee->txid); - swap->state = instantdex_statefind(BTC_states,BTC_numstates,instantdex_isbob(swap) != 0 ? bobstate : alicestate); - return(0); - } - return(clonestr("{\"error\":\"couldnt create feetx\"}")); -}*/ - -struct bitcoin_statetx *instantdex_bobtx(struct supernet_info *myinfo,struct iguana_info *coin,bits256 pub1,bits256 pub2,bits256 priv,uint32_t reftime,int64_t amount,int32_t depositflag) +struct bitcoin_statetx *instantdex_bobtx(struct supernet_info *myinfo,struct bitcoin_swapinfo *swap,struct iguana_info *coin,int64_t amount,int32_t depositflag) { - cJSON *txobj; int32_t n,secretstart; char *signedtx = 0; struct bitcoin_statetx *ptr = 0; - uint8_t script[1024],secret[20]; bits256 txid; struct bitcoin_spend *spend; uint32_t locktime; int64_t insurance; + int32_t n,secretstart; struct bitcoin_statetx *ptr = 0; uint8_t script[1024]; uint32_t locktime; int64_t satoshis; char scriptstr[512]; if ( coin == 0 ) return(0); - locktime = (uint32_t)(reftime + INSTANTDEX_LOCKTIME * (1 + depositflag)); - txobj = bitcoin_txcreate(coin,locktime); - insurance = instantdex_insurance(coin,amount); - if ( (spend= iguana_spendset(myinfo,coin,amount + insurance,coin->chain->txfee,0)) != 0 ) + satoshis = amount + depositflag*swap->insurance*100 + swap->coinbtc->chain->txfee; + n = instantdex_bobscript(script,0,&locktime,&secretstart,swap,depositflag); + if ( n < 0 ) { - calc_rmd160_sha256(secret,priv.bytes,sizeof(priv)); - n = instantdex_bobscript(script,0,&secretstart,locktime,pub1,secret,pub2); - bitcoin_txoutput(coin,txobj,script,n,amount + depositflag*insurance*100); - iguana_addinputs(coin,spend,txobj,0xffffffff); - txobj = iguana_signtx(myinfo,coin,&txid,&signedtx,spend,txobj,0); - if ( signedtx != 0 ) - { - ptr = calloc(1,sizeof(*ptr) + strlen(signedtx) + 1); - strcpy(ptr->txbytes,signedtx); - ptr->txid = txid; - //printf("bob deposit.%s\n",signedtx); - //disp_tx(myinfo,coin,depositflag != 0 ? "deposit" : "payment",signedtx); - free(signedtx); - } else printf("error signing bobdeposit numinputs.%d\n",spend->numinputs); - free(spend); + printf("instantdex_bobtx couldnt generate bobscript deposit.%d\n",depositflag); + return(0); } - free_json(txobj); + printf("locktime.%u amount %.8f satoshis %.8f\n",locktime,dstr(amount),dstr(satoshis)); + init_hexbytes_noT(scriptstr,script,n); + if ( (ptr= instantdex_signtx(depositflag != 0 ? "deposit" : "payment",myinfo,coin,locktime,scriptstr,satoshis,coin->txfee,swap->mine.minconfirms,swap->mine.offer.myside)) != 0 ) + { + bitcoin_address(ptr->destaddr,coin->chain->p2shtype,script,n); + printf("BOBTX.%d (%s) -> %s\n",depositflag,ptr->txbytes,ptr->destaddr); + } else printf("sign error for bottx\n"); return(ptr); } int32_t instantdex_paymentverify(struct supernet_info *myinfo,struct iguana_info *coin,struct bitcoin_swapinfo *swap,cJSON *argjson,int32_t depositflag) { - cJSON *txobj; bits256 txid; uint32_t n,locktime; int32_t i,secretstart,retval = -1; uint64_t x; - struct iguana_msgtx msgtx; uint8_t script[512],rmd160[20]; int64_t relsatoshis,amount,insurance = 0; - if ( coin != 0 && jstr(argjson,depositflag != 0 ? "deposit" : "payment") != 0 ) + cJSON *txobj; bits256 txid; uint32_t n,locktime; int32_t i,secretstart,retval = -1,extralen=65536; uint64_t x; + struct iguana_msgtx msgtx; uint8_t script[512],serialized[8192],*extraspace=0; int64_t amount; + if ( coin != 0 && swap->deposit != 0 ) { - relsatoshis = swap->altsatoshis; - if ( depositflag != 0 ) - insurance = 100 * (relsatoshis * INSTANTDEX_INSURANCERATE + coin->chain->txfee); - amount = relsatoshis + insurance; - if ( swap->deposit != 0 && (txobj= bitcoin_hex2json(coin,&txid,&msgtx,swap->deposit->txbytes)) != 0 ) + amount = swap->BTCsatoshis + depositflag*swap->insurance*100 + swap->coinbtc->chain->txfee; + if ( (n= instantdex_bobscript(script,0,&locktime,&secretstart,swap,depositflag)) <= 0 ) + return(retval); + extraspace = calloc(1,extralen); + if ( (txobj= bitcoin_hex2json(coin,&txid,&msgtx,swap->deposit->txbytes,extraspace,extralen,serialized)) != 0 ) { - locktime = swap->expiration; - if ( depositflag == 0 ) - memset(rmd160,0,sizeof(rmd160)); - else calc_rmd160_sha256(rmd160,swap->privkeys[0].bytes,sizeof(rmd160)); - n = instantdex_bobscript(script,0,&secretstart,locktime,swap->mypubs[0],rmd160,swap->otherpubs[0]); + memcpy(&script[secretstart],&msgtx.vouts[0].pk_script[secretstart],20); + printf("locktime.%u amount %.8f satoshis %.8f\n",locktime,dstr(amount),dstr(amount)); if ( msgtx.lock_time == locktime && msgtx.vouts[0].value == amount && n == msgtx.vouts[0].pk_scriptlen ) { - memcpy(&script[secretstart],&msgtx.vouts[0].pk_script[secretstart],20); if ( memcmp(script,msgtx.vouts[0].pk_script,n) == 0 ) { iguana_rwnum(0,&script[secretstart],sizeof(x),&x); - printf("deposit script verified x.%llx vs otherdeck %llx\n",(long long)x,(long long)swap->otherdeck[swap->choosei][0]); + printf("deposit script verified\n"); if ( x == swap->otherdeck[swap->choosei][0] ) retval = 0; else printf("deposit script verified but secret mismatch x.%llx vs otherdeck %llx\n",(long long)x,(long long)swap->otherdeck[swap->choosei][0]); @@ -268,179 +349,142 @@ int32_t instantdex_paymentverify(struct supernet_info *myinfo,struct iguana_info free_json(txobj); } } + if ( extraspace != 0 ) + free(extraspace); return(retval); } int32_t instantdex_altpaymentverify(struct supernet_info *myinfo,struct iguana_info *coin,struct bitcoin_swapinfo *swap,cJSON *argjson) { - cJSON *txobj; bits256 txid; uint32_t n; int32_t i,retval = -1; - struct iguana_msgtx msgtx; uint8_t script[512]; char *altmsigaddr,msigaddr[64]; - if ( jstr(argjson,"altpayment") != 0 && (altmsigaddr= jstr(argjson,"altmsigaddr")) != 0 ) + cJSON *txobj; bits256 txid; uint32_t n; int32_t i,retval = -1,extralen = 65536; + struct iguana_msgtx msgtx; uint8_t script[512],serialized[8192],*extraspace=0; char *altmsigaddr=0,msigaddr[64]; + if ( swap->altpayment != 0 && (altmsigaddr= jstr(argjson,"altmsigaddr")) != 0 ) { - if ( swap->altpayment != 0 && (txobj= bitcoin_hex2json(coin,&txid,&msgtx,swap->altpayment->txbytes)) != 0 ) + extraspace = calloc(1,extralen); + if ( (txobj= bitcoin_hex2json(coin,&txid,&msgtx,swap->altpayment->txbytes,extraspace,extralen,serialized)) != 0 ) { n = instantdex_alicescript(script,0,msigaddr,coin->chain->p2shtype,swap->pubAm,swap->pubBn); if ( strcmp(msigaddr,altmsigaddr) == 0 && n == msgtx.vouts[0].pk_scriptlen ) { if ( memcmp(script,msgtx.vouts[0].pk_script,n) == 0 ) { - printf("deposit script verified\n"); + printf("altpayment script verified\n"); + retval = 0; } else { for (i=0; ialtpayment,altmsigaddr!=0?altmsigaddr:""); + if ( extraspace != 0 ) + free(extraspace); return(retval); } -struct bitcoin_statetx *instantdex_alicetx(struct supernet_info *myinfo,struct iguana_info *altcoin,char *msigaddr,bits256 pubAm,bits256 pubBn,int64_t amount) +struct bitcoin_statetx *instantdex_alicetx(struct supernet_info *myinfo,struct iguana_info *altcoin,char *msigaddr,bits256 pubAm,bits256 pubBn,int64_t amount,struct bitcoin_swapinfo *swap) { - cJSON *txobj; int32_t n; char *signedtx = 0; uint8_t script[1024]; struct bitcoin_spend *spend; struct bitcoin_statetx *ptr = 0; bits256 txid; - if ( altcoin != 0 && (spend= iguana_spendset(myinfo,altcoin,amount,altcoin->chain->txfee,0)) != 0 ) + int32_t n; uint8_t script[1024]; char scriptstr[2048]; struct bitcoin_statetx *ptr = 0; + if ( altcoin != 0 ) { - txobj = bitcoin_txcreate(altcoin,0); + if ( bits256_nonz(pubAm) == 0 || bits256_nonz(pubBn) == 0 ) + { + printf("instantdex_bobtx null pubAm.%llx or pubBn.%llx\n",(long long)pubAm.txid,(long long)pubBn.txid); + return(0); + } n = instantdex_alicescript(script,0,msigaddr,altcoin->chain->p2shtype,pubAm,pubBn); - bitcoin_txoutput(altcoin,txobj,script,n,amount); - iguana_addinputs(altcoin,spend,txobj,0xffffffff); - txobj = iguana_signtx(myinfo,altcoin,&txid,&signedtx,spend,txobj,0); - if ( signedtx != 0 ) + init_hexbytes_noT(scriptstr,script,n); + if ( (ptr= instantdex_signtx("altpayment",myinfo,altcoin,0,scriptstr,amount,altcoin->txfee,swap->mine.minconfirms,swap->mine.offer.myside)) != 0 ) { - printf("alice payment.%s\n",signedtx); - //disp_tx(myinfo,altcoin,"altpayment",signedtx); - ptr = calloc(1,sizeof(*ptr) + strlen(signedtx) + 1); - ptr->txid = txid; - strcpy(ptr->txbytes,signedtx); - free(signedtx); + strcpy(ptr->destaddr,msigaddr); + printf("ALICETX (%s) -> %s\n",ptr->txbytes,ptr->destaddr); } - else printf("error signing alicetx numinputs.%d\n",spend->numinputs); - free(spend); - free_json(txobj); } return(ptr); } -cJSON *BOB_reclaimfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) -{ - *serdatap = 0, *serdatalenp = 0; - if ( swap->deposit != 0 ) - printf("reclaim deposit.(%s) to %s\n",swap->deposit->txbytes,myinfo->myaddr.BTC); - strcpy(swap->waitfortx,"bre"); - // reclaim deposit - return(newjson); -} - -cJSON *BOB_feereclaimfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) -{ - *serdatap = 0, *serdatalenp = 0; - if ( swap->myfee != 0 ) - printf("reclaim fee.(%s)\n",swap->myfee->txbytes); - strcpy(swap->waitfortx,"bfr"); - // reclaim deposit - return(newjson); -} - -cJSON *BOB_claimaltfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) -{ - *serdatap = 0, *serdatalenp = 0; char altcoinaddr[64]; - if ( swap->altpayment != 0 ) - printf("spend altpayment.(%s) -> %s\n",swap->altpayment->txbytes,altcoinaddr); - strcpy(swap->waitfortx,"bcl"); - // spend altpayment - return(newjson); -} - -cJSON *ALICE_reclaimfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) -{ - *serdatap = 0, *serdatalenp = 0; char altcoinaddr[64]; - // reclaim altpayment - if ( swap->altpayment != 0 ) - printf("reclaim altpayment.(%s) -> %s\n",swap->altpayment->txbytes,altcoinaddr); - strcpy(swap->waitfortx,"are"); - return(newjson); -} - -cJSON *ALICE_feereclaimfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) -{ - *serdatap = 0, *serdatalenp = 0; - // reclaim fee - if ( swap->myfee != 0 ) - printf("reclaim fee.(%s)\n",swap->myfee->txbytes); - strcpy(swap->waitfortx,"afr"); - return(newjson); -} - -cJSON *ALICE_claimdepositfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) -{ - *serdatap = 0, *serdatalenp = 0; - if ( swap->deposit != 0 ) - printf("reclaim deposit.(%s)\n",swap->deposit->txbytes); - strcpy(swap->waitfortx,"adp"); - // reclaim deposit - return(newjson); -} - -cJSON *ALICE_claimbtcfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) +cJSON *BTC_makeclaimfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) { + int32_t got_payment=1,bob_reclaimed=0; *serdatap = 0, *serdatalenp = 0; - if ( swap->payment != 0 ) - printf("spend BTC payment.(%s) -> %s\n",swap->payment->txbytes,myinfo->myaddr.BTC); - strcpy(swap->waitfortx,"acl"); - // spend BTC + if ( instantdex_isbob(swap) == 0 ) + { + // [BLOCKING: payfound] now Alice's turn to make sure payment is confrmed and send in claim or see bob's reclaim and reclaim + if ( got_payment != 0 ) + { + //swap->privAm = swap->privkeys[swap->otherchoosei]; + // sign if/else payment + } + else if ( bob_reclaimed != 0 ) + { + + } + } + else + { + // [BLOCKING: privM] Bob waits for privM either from Alice or alt blockchain + if ( bits256_nonz(swap->privAm) != 0 ) + { + // a multisig tx for altcoin + } + } return(newjson); } -bits256 instantdex_derivekeypair(bits256 *newprivp,uint8_t pubkey[33],bits256 privkey,bits256 orderhash) +bits256 instantdex_derivekeypair(struct supernet_info *myinfo,bits256 *newprivp,uint8_t pubkey[33],bits256 privkey,bits256 orderhash) { bits256 sharedsecret; sharedsecret = curve25519_shared(privkey,orderhash); vcalc_sha256cat(newprivp->bytes,orderhash.bytes,sizeof(orderhash),sharedsecret.bytes,sizeof(sharedsecret)); - return(bitcoin_pubkey33(0,pubkey,*newprivp)); + return(bitcoin_pubkey33(myinfo->ctx,pubkey,*newprivp)); } -int32_t instantdex_pubkeyargs(struct bitcoin_swapinfo *swap,cJSON *newjson,int32_t numpubs,bits256 privkey,bits256 hash,int32_t firstbyte) +int32_t instantdex_pubkeyargs(struct supernet_info *myinfo,struct bitcoin_swapinfo *swap,int32_t numpubs,bits256 privkey,bits256 hash,int32_t firstbyte) { char buf[3]; int32_t i,n,m,len=0; bits256 pubi; uint64_t txid; uint8_t secret160[20],pubkey[33]; sprintf(buf,"%c0",'A' - 0x02 + firstbyte); - printf(">>>>>> start generating %s\n",buf); + if ( numpubs > 2 ) + { + if ( swap->numpubs+2 >= numpubs ) + return(numpubs); + printf(">>>>>> start generating %s\n",buf); + } for (i=n=m=0; iprivkeys[n],pubkey,privkey,hash); - privkey = swap->privkeys[n]; - printf("i.%d n.%d numpubs.%d %02x vs %02x\n",i,n,numpubs,pubkey[0],firstbyte); + pubi = instantdex_derivekeypair(myinfo,&privkey,pubkey,privkey,hash); + //printf("i.%d n.%d numpubs.%d %02x vs %02x\n",i,n,numpubs,pubkey[0],firstbyte); if ( pubkey[0] != firstbyte ) continue; - if ( n < 2 && numpubs > 2 ) + if ( n < 2 ) { - sprintf(buf+1,"%d",n); - if ( jobj(newjson,buf) == 0 ) - jaddbits256(newjson,buf,pubi); + if ( bits256_nonz(swap->mypubs[n]) == 0 ) + { + swap->myprivs[n] = privkey; + memcpy(swap->mypubs[n].bytes,pubkey+1,sizeof(bits256)); + } } - else + if ( swap->numpubs < INSTANTDEX_DECKSIZE ) { - calc_rmd160_sha256(secret160,swap->privkeys[n].bytes,sizeof(swap->privkeys[n])); + swap->privkeys[m] = privkey; + calc_rmd160_sha256(secret160,privkey.bytes,sizeof(privkey)); memcpy(&txid,secret160,sizeof(txid)); - /*txid = (m+1) | ((m+1)<<16); - txid <<= 32; - txid = (m+1) | ((m+1)<<16); - pubi.txid = (m+1) | ((m+1)<<16); - pubi.txid <<= 32; - pubi.txid = (m+1) | ((m+1)<<16);*/ len += iguana_rwnum(1,(uint8_t *)&swap->deck[m][0],sizeof(txid),&txid); len += iguana_rwnum(1,(uint8_t *)&swap->deck[m][1],sizeof(pubi.txid),&pubi.txid); m++; + if ( m > swap->numpubs ) + swap->numpubs = m; } n++; } - printf("n.%d m.%d len.%d\n",n,m,len); + if ( n > 2 || m > 2 ) + printf("n.%d m.%d len.%d numpubs.%d\n",n,m,len,swap->numpubs); return(n); } @@ -458,92 +502,112 @@ char *instantdex_choosei(struct bitcoin_swapinfo *swap,cJSON *newjson,cJSON *arg swap->choosei = -swap->choosei; swap->choosei %= max; jaddnum(newjson,"mychoosei",swap->choosei); - printf("%llu/%llu %s send mychoosei.%d of max.%d\n",(long long)swap->mine.orderid,(long long)swap->other.orderid,instantdex_isbob(swap)!=0?"BOB":"alice",swap->choosei,max); + printf("%llu/%llu %s send mychoosei.%d of max.%d deck.(%llx %llx)\n",(long long)swap->mine.orderid,(long long)swap->other.orderid,instantdex_isbob(swap)!=0?"BOB":"alice",swap->choosei,max,(long long)swap->otherdeck[0][0],(long long)swap->otherdeck[0][1]); return(0); } else { - printf("invalid datalen.%d vs %d\n",datalen,(int32_t)sizeof(swap->deck)); + printf("choosei.%d or null serdata.%p or invalid datalen.%d vs %d\n",swap->choosei,serdata,datalen,(int32_t)sizeof(swap->deck)); return(clonestr("{\"error\":\"instantdex_BTCswap offer no cut\"}")); } } -void instantdex_getpubs(struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson) -{ - char fields[2][2][3]; int32_t i,j,myind,otherind; - memset(fields,0,sizeof(fields)); - fields[0][0][0] = fields[0][1][0] = 'A'; - fields[1][0][0] = fields[1][1][0] = 'B'; - for (i=0; i<2; i++) - for (j=0; j<2; j++) - fields[i][j][1] = '0' + j; - myind = instantdex_isbob(swap); - otherind = (myind ^ 1); - for (j=0; j<2; j++) - { - if ( bits256_nonz(swap->mypubs[j]) == 0 && jobj(argjson,fields[myind][j]) != 0 ) - swap->mypubs[j] = jbits256(newjson,fields[myind][j]); - if ( bits256_nonz(swap->otherpubs[j]) == 0 && jobj(argjson,fields[otherind][j]) != 0 ) - swap->otherpubs[j] = jbits256(argjson,fields[otherind][j]); - } -} - void instantdex_privkeyextract(struct supernet_info *myinfo,struct bitcoin_swapinfo *swap,uint8_t *serdata,int32_t serdatalen) { - int32_t i,wrongfirstbyte,errs,len = 0; bits256 hashpriv,otherpriv,pubi; uint8_t otherpubkey[33]; + int32_t i,j,wrongfirstbyte,errs,len = 0; bits256 otherpriv,pubi; uint8_t secret160[20],otherpubkey[33],pubkey[33]; uint64_t txid; if ( swap->cutverified == 0 && swap->choosei >= 0 && serdatalen == sizeof(swap->privkeys) ) { - printf("got instantdex_privkeyextract serdatalen.%d choosei.%d cutverified.%d\n",serdatalen,swap->choosei,swap->cutverified); for (i=wrongfirstbyte=errs=0; iprivkeys)/sizeof(*swap->privkeys); i++) { - len += iguana_rwbignum(0,&serdata[len],sizeof(bits256),otherpriv.bytes); + for (j=0; j<32; j++) + otherpriv.bytes[j] = serdata[len++]; if ( i == swap->choosei ) { if ( bits256_nonz(otherpriv) != 0 ) { - printf("got privkey in slot.%d my choosi??\n",i); + printf("got privkey in slot.%d my choosei??\n",i); errs++; } + if ( instantdex_isbob(swap) != 0 ) + { + if ( otherpubkey[0] == 0x02 ) + { + if ( bits256_nonz(swap->privkeys[i]) != 0 ) + { + swap->privBn = swap->privkeys[i]; + calc_rmd160_sha256(swap->secretBn,swap->privBn.bytes,sizeof(swap->privBn)); + printf("set secretBn\n"); + swap->pubBn = bitcoin_pubkey33(myinfo->ctx,pubkey,swap->privBn); + } + } else printf("wrong first byte.%02x\n",otherpubkey[0]); + } + else + { + if ( otherpubkey[0] == 0x03 ) + { + if ( bits256_nonz(swap->privkeys[i]) != 0 ) + { + swap->privAm = swap->privkeys[i]; + calc_rmd160_sha256(swap->secretAm,swap->privAm.bytes,sizeof(swap->privAm)); + printf("set secretAm\n"); + swap->pubAm = bitcoin_pubkey33(myinfo->ctx,pubkey,swap->privAm); + } + } else printf("wrong first byte.%02x\n",otherpubkey[0]); + } continue; } pubi = bitcoin_pubkey33(myinfo->ctx,otherpubkey,otherpriv); - vcalc_sha256(0,hashpriv.bytes,otherpriv.bytes,sizeof(otherpriv)); + calc_rmd160_sha256(secret160,otherpriv.bytes,sizeof(otherpriv)); + memcpy(&txid,secret160,sizeof(txid)); if ( otherpubkey[0] != (instantdex_isbob(swap) ^ 1) + 0x02 ) { wrongfirstbyte++; printf("wrongfirstbyte[%d] %02x\n",i,otherpubkey[0]); } - else if ( swap->otherdeck[i][0] != hashpriv.txid ) + else if ( swap->otherdeck[i][1] != pubi.txid ) { - printf("otherdeck[%d] priv mismatch %llx != %llx\n",i,(long long)swap->otherdeck[i][0],(long long)hashpriv.txid); + printf("otherdeck[%d] priv ->pub mismatch %llx != %llx\n",i,(long long)swap->otherdeck[i][1],(long long)pubi.txid); errs++; } - else if ( swap->otherdeck[i][1] != pubi.txid ) + else if ( swap->otherdeck[i][0] != txid ) { - printf("otherdeck[%d] priv mismatch %llx != %llx\n",i,(long long)swap->otherdeck[i][1],(long long)pubi.txid); + printf("otherdeck[%d] priv mismatch %llx != %llx\n",i,(long long)swap->otherdeck[i][0],(long long)txid); errs++; } } if ( errs == 0 && wrongfirstbyte == 0 ) - swap->cutverified = 1; + swap->cutverified = 1, printf("CUT VERIFIED\n"); else printf("failed verification: wrong firstbyte.%d errs.%d\n",wrongfirstbyte,errs); } } -void instantdex_swaptxupdate(struct bitcoin_statetx **ptrp,cJSON *argjson,char *txname,char *txidfield) +int32_t instantdex_swaptxupdate(struct iguana_info *coin,struct bitcoin_statetx **ptrp,cJSON *argjson,char *txname,char *txidfield) { - char *str; + char *str; int32_t retval = 0; if ( (str= jstr(argjson,txname)) != 0 ) { if ( *ptrp != 0 ) { - //printf("got replacement %s? (%s)\n",txname,str); - free(*ptrp); - } + if ( strcmp((*ptrp)->txbytes,str) != 0 ) + { + printf("got replacement %s?\n",txname); + free(*ptrp); + } else return(0); + } else printf("instantdex_swaptxupdate got (%s) %s\n",txname,str); *ptrp = calloc(1,sizeof(**ptrp) + strlen(str) + 1); strcpy((*ptrp)->txbytes,str); (*ptrp)->txid = jbits256(argjson,txidfield); + iguana_txidmonitor(coin,(*ptrp)->txid); + if ( strcmp("feetx",txname) == 0 ) + retval = INSTANTDEX_ORDERSTATE_HAVEOTHERFEE; + else if ( strcmp("deposit",txname) == 0 ) + retval = INSTANTDEX_ORDERSTATE_HAVEDEPOSIT; + else if ( strcmp("payment",txname) == 0 ) + retval = INSTANTDEX_ORDERSTATE_HAVEPAYMENT; + else if ( strcmp("altpayment",txname) == 0 ) + retval = INSTANTDEX_ORDERSTATE_HAVEALTPAYMENT; } + return(retval); } void instantdex_swapbits256update(bits256 *txidp,cJSON *argjson,char *fieldname) @@ -552,12 +616,122 @@ void instantdex_swapbits256update(bits256 *txidp,cJSON *argjson,char *fieldname) txid = jbits256(argjson,fieldname); if ( bits256_nonz(txid) > 0 ) { - if ( bits256_nonz(*txidp) > 0 ) + if ( 0 && bits256_nonz(*txidp) > 0 ) printf("swapbits256: %s sent again\n",bits256_str(str,*txidp)); *txidp = txid; } } +void instantdex_newjson(struct supernet_info *myinfo,struct bitcoin_swapinfo *swap,cJSON *newjson) +{ + uint8_t pubkey[33],*secret160; int32_t i,deckflag; char secretstr[41],*field; + deckflag = (newjson != 0 && swap->otherchoosei < 0) ? 1 : 0; + if ( instantdex_pubkeyargs(myinfo,swap,2 + deckflag*INSTANTDEX_DECKSIZE,myinfo->persistent_priv,swap->myorderhash,0x02+instantdex_isbob(swap)) != 2 + deckflag*INSTANTDEX_DECKSIZE ) + printf("ERROR: couldnt generate pubkeys deckflag.%d\n",deckflag); + jaddnum(newjson,"have",swap->havestate); + if ( swap->choosei >= 0 ) + jaddnum(newjson,"mychoosei",swap->choosei); + if ( swap->otherchoosei >= 0 ) + { + jaddnum(newjson,"otherchoosei",swap->otherchoosei); + if ( instantdex_isbob(swap) != 0 ) + { + for (i=0; i<20; i++) + if ( swap->secretBn[i] != 0 ) + break; + if ( i == 20 ) + { + calc_rmd160_sha256(swap->secretBn,swap->privBn.bytes,sizeof(swap->privBn)); + swap->pubBn = bitcoin_pubkey33(myinfo->ctx,pubkey,swap->privBn); + } + secret160 = swap->secretBn; + field = "secretBn"; + } + else + { + for (i=0; i<20; i++) + if ( swap->secretAm[i] != 0 ) + break; + if ( i == 20 ) + { + calc_rmd160_sha256(swap->secretAm,swap->privAm.bytes,sizeof(swap->privAm)); + swap->pubAm = bitcoin_pubkey33(myinfo->ctx,pubkey,swap->privAm); + } + secret160 = swap->secretAm; + field = "secretAm"; + } + init_hexbytes_noT(secretstr,secret160,20); + jaddstr(newjson,field,secretstr); + printf("send secretstr.(%s)\n",secretstr); + } + if ( jobj(newjson,"feetx") == 0 && swap->myfee != 0 ) // && (swap->otherhavestate & INSTANTDEX_ORDERSTATE_HAVEOTHERFEE) == 0 ) + { + jaddbits256(newjson,"feetxid",swap->myfee->txid); + jaddstr(newjson,"feetx",swap->myfee->txbytes); + printf("add feetx to newjson have.%x\n",swap->havestate); + } + if ( instantdex_isbob(swap) == 0 ) + { + if ( swap->altpayment != 0 ) + { + if ( swap->altpayment->destaddr[0] != 0 ) + { + jaddstr(newjson,"altmsigaddr",swap->altpayment->destaddr); + printf("add altmsig.%s\n",swap->altpayment->destaddr); + } + if ( (swap->otherhavestate & INSTANTDEX_ORDERSTATE_HAVEALTPAYMENT) == 0 && jobj(newjson,"altpayment") == 0 ) + { + jaddbits256(newjson,"altpaymenttxid",swap->altpayment->txid); + jaddstr(newjson,"altpayment",swap->altpayment->txbytes); + printf("add altpayment.(%s) have.%x\n",swap->altpayment->txbytes,swap->havestate); + } + } + jaddbits256(newjson,"A0",swap->mypubs[0]); + jaddbits256(newjson,"A1",swap->mypubs[1]); + swap->pubA0 = swap->mypubs[0]; + //swap->pubA1 = swap->mypubs[1]; + if ( bits256_nonz(swap->pubAm) == 0 && swap->otherchoosei >= 0 && bits256_nonz(swap->privkeys[swap->otherchoosei]) != 0 ) + { + swap->pubAm = bitcoin_pubkey33(myinfo->ctx,pubkey,swap->privkeys[swap->otherchoosei]); + swap->privAm = swap->privkeys[swap->otherchoosei]; + calc_rmd160_sha256(swap->secretAm,swap->privAm.bytes,sizeof(swap->privAm)); + memset(&swap->privkeys[swap->otherchoosei],0,sizeof(swap->privkeys[swap->otherchoosei])); + } + } + else + { + if ( bits256_nonz(swap->pubBn) == 0 && swap->otherchoosei >= 0 && bits256_nonz(swap->privkeys[swap->otherchoosei]) != 0 ) + { + swap->pubBn = bitcoin_pubkey33(myinfo->ctx,pubkey,swap->privkeys[swap->otherchoosei]); + swap->privBn = swap->privkeys[swap->otherchoosei]; + calc_rmd160_sha256(swap->secretBn,swap->privBn.bytes,sizeof(swap->privBn)); + memset(&swap->privkeys[swap->otherchoosei],0,sizeof(swap->privkeys[swap->otherchoosei])); + } + jaddbits256(newjson,"B0",swap->mypubs[0]); + jaddbits256(newjson,"B1",swap->mypubs[1]); + swap->pubB0 = swap->mypubs[0]; + swap->pubB1 = swap->mypubs[1]; + if ( (swap->otherhavestate & INSTANTDEX_ORDERSTATE_HAVEDEPOSIT) == 0 && swap->deposit != 0 && jobj(newjson,"deposit") == 0 ) + { + jaddbits256(newjson,"deposittxid",swap->deposit->txid); + jaddstr(newjson,"deposit",swap->deposit->txbytes); + printf("add deposit.(%s) have.%x\n",swap->deposit->txbytes,swap->havestate); + } + else if ( (swap->otherhavestate & INSTANTDEX_ORDERSTATE_HAVEPAYMENT) == 0 && swap->payment != 0 && jobj(newjson,"payment") == 0 ) + { + jaddbits256(newjson,"paymenttxid",swap->payment->txid); + jaddstr(newjson,"payment",swap->payment->txbytes); + printf("add payment.(%s) have.%x\n",swap->payment->txbytes,swap->havestate); + } + } + if ( bits256_nonz(swap->pubAm) != 0 ) + jaddbits256(newjson,"pubAm",swap->pubAm); + if ( bits256_nonz(swap->privAm) != 0 ) + jaddbits256(newjson,"privAm",swap->privAm); + if ( bits256_nonz(swap->pubBn) != 0 ) + jaddbits256(newjson,"pubBn",swap->pubBn); +} + cJSON *instantdex_parseargjson(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,int32_t deckflag) { cJSON *newjson; @@ -568,273 +742,214 @@ cJSON *instantdex_parseargjson(struct supernet_info *myinfo,struct exchange_info { if ( instantdex_isbob(swap) != 0 ) { - instantdex_swapbits256update(&swap->otherpubs[0],argjson,"pubA0"); - instantdex_swapbits256update(&swap->otherpubs[1],argjson,"pubA1"); + if ( jobj(argjson,"secretAm") != 0 ) + decode_hex(swap->secretAm,20,jstr(argjson,"secretAm")); + instantdex_swapbits256update(&swap->otherpubs[0],argjson,"A0"); + instantdex_swapbits256update(&swap->otherpubs[1],argjson,"A1"); + if ( bits256_nonz(swap->otherpubs[0]) != 0 ) + swap->pubA0 = swap->otherpubs[0]; + //if ( bits256_nonz(swap->otherpubs[1]) != 0 ) + // swap->pubA1 = swap->otherpubs[1]; instantdex_swapbits256update(&swap->pubAm,argjson,"pubAm"); instantdex_swapbits256update(&swap->privAm,argjson,"privAm"); - instantdex_swaptxupdate(&swap->altpayment,argjson,"altpayment","altpaymenttxid"); + swap->havestate |= instantdex_swaptxupdate(swap->altcoin,&swap->altpayment,argjson,"altpayment","altpaymenttxid"); } else { - instantdex_swapbits256update(&swap->otherpubs[0],argjson,"pubB0"); - instantdex_swapbits256update(&swap->otherpubs[1],argjson,"pubB1"); + if ( jobj(argjson,"secretBn") != 0 ) + decode_hex(swap->secretBn,20,jstr(argjson,"secretBn")); + instantdex_swapbits256update(&swap->otherpubs[0],argjson,"B0"); + instantdex_swapbits256update(&swap->otherpubs[1],argjson,"B1"); + if ( bits256_nonz(swap->otherpubs[0]) != 0 ) + swap->pubB0 = swap->otherpubs[0]; + if ( bits256_nonz(swap->otherpubs[1]) != 0 ) + swap->pubB1 = swap->otherpubs[1]; instantdex_swapbits256update(&swap->pubBn,argjson,"pubBn"); instantdex_swapbits256update(&swap->privBn,argjson,"privBn"); - instantdex_swaptxupdate(&swap->deposit,argjson,"deposit","deposittxid"); - instantdex_swaptxupdate(&swap->payment,argjson,"payment","paymenttxid"); + swap->havestate |= instantdex_swaptxupdate(swap->coinbtc,&swap->deposit,argjson,"deposit","deposittxid"); + swap->havestate |= instantdex_swaptxupdate(swap->coinbtc,&swap->payment,argjson,"payment","paymenttxid"); } - instantdex_swaptxupdate(&swap->otherfee,argjson,"feetx","feetxid"); + swap->havestate |= instantdex_swaptxupdate(swap->coinbtc,&swap->otherfee,argjson,"feetx","feetxid"); if ( swap->otherchoosei < 0 && jobj(argjson,"mychoosei") != 0 ) { - //printf("otherschoosei.%d\n",swap->otherschoosei); + printf("otherschoosei.%d\n",swap->otherchoosei); if ( (swap->otherchoosei= juint(argjson,"mychoosei")) >= sizeof(swap->otherdeck)/sizeof(*swap->otherdeck) ) swap->otherchoosei = -1; } + if ( swap->otherchoosei >= 0 ) + { + char str[65],str2[65]; + if ( instantdex_isbob(swap) != 0 ) + { + if ( bits256_nonz(swap->pubAm) == 0 ) + swap->pubAm = jbits256(argjson,"pubAm"); + else if ( bits256_cmp(swap->pubAm,jbits256(argjson,"pubAm")) != 0 ) + { + printf("mismatched pubAm %s vs %s\n",bits256_str(str,swap->pubAm),bits256_str(str2,jbits256(argjson,"pubAm"))); + } + } + else + { + if ( bits256_nonz(swap->pubBn) == 0 ) + swap->pubBn = jbits256(argjson,"pubBn"); + else if ( bits256_cmp(swap->pubBn,jbits256(argjson,"pubBn")) != 0 ) + { + printf("mismatched pubBn %s vs %s\n",bits256_str(str,swap->pubBn),bits256_str(str2,jbits256(argjson,"pubBn"))); + } + } + } + if ( jobj(argjson,"mychoosei") != 0 ) + { + if ( swap->otherchoosei < 0 ) + swap->otherchoosei = jnum(argjson,"mychoosei"); + else if ( swap->otherchoosei != jnum(argjson,"mychoosei") ) + { + printf("otherchoosei mismatch %d vs %d\n",swap->otherchoosei,jnum(argjson,"mychoosei")); + } + } if ( juint(argjson,"verified") != 0 ) swap->otherverifiedcut = 1; - jaddnum(newjson,"verified",swap->otherverifiedcut); - if ( instantdex_pubkeyargs(swap,newjson,2 + deckflag*INSTANTDEX_DECKSIZE,myinfo->persistent_priv,swap->myorderhash,0x02+instantdex_isbob(swap)) == 2 + deckflag*INSTANTDEX_DECKSIZE ) - instantdex_getpubs(swap,argjson,newjson); - else printf("ERROR: couldnt generate pubkeys deckflag.%d\n",deckflag); + if ( juint(argjson,"have") != 0 ) + swap->otherhavestate |= juint(argjson,"have"); + printf("got other.%x myhave.%x choosei.(%d %d) otherfee.%p dep.%p pay.%p alt.%p\n",swap->otherhavestate,swap->havestate,swap->choosei,swap->otherchoosei,swap->otherfee,swap->deposit,swap->payment,swap->altpayment); } return(newjson); } -double iguana_numconfs(struct iguana_info *coin,bits256 txid,int32_t height) +cJSON *BTC_checkdeckfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) { - if ( coin->longestchain >= height ) - return((double)coin->longestchain - height); - else return(0.); // 0.5 if zeroconfs + *serdatap = 0, *serdatalenp = 0; + if ( swap->choosei >= 0 )//&& swap->otherchoosei >= 0 ) + jaddstr(newjson,"virtevent","gotdeck"); + else printf("no choosei yet\n"); + return(newjson); } -char *BTC_txconfirmed(struct supernet_info *myinfo,struct iguana_info *coin,struct bitcoin_swapinfo *swap,cJSON *newjson,bits256 txid,double *numconfirmsp,char *virtualevent,double requiredconfs) +cJSON *BTC_waitfeefunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) { - int32_t height,firstvout; char *retstr; double confs; - *numconfirmsp = -1.; - if ( coin != 0 && *numconfirmsp < 0 ) + *serdatap = 0, *serdatalenp = 0; + if ( swap->otherfee != 0 && iguana_txidstatus(swap->coinbtc,swap->otherfee->txid) >= 0. ) { - if ( (firstvout= iguana_unspentindfind(coin,0,0,0,0,&height,txid,0,coin->bundlescount-1)) != 0 && (confs= iguana_numconfs(coin,txid,height)) >= requiredconfs ) + if ( instantdex_feetxverify(myinfo,swap->coinbtc,swap,argjson) < 0 ) { - *numconfirmsp = confs; - if ( (retstr= instantdex_sendcmd(myinfo,&swap->mine.offer,newjson,virtualevent,myinfo->myaddr.persistent,0,0,0)) != 0 ) - return(retstr); + printf("fee didnt verify\n"); + return(cJSON_Parse("{\"error\":\"fee didnt verify\"}")); } + if ( instantdex_isbob(swap) != 0 ) + jaddstr(newjson,"virtevent","gendep"); + else jaddstr(newjson,"virtevent","waitdep"); } - return(0); -} - -cJSON *BTC_waitdeckCfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) -{ - *serdatap = 0, *serdatalenp = 0; - strcmp(swap->expectedcmdstr,"BTCdeckC"); - return(newjson); -} - -cJSON *BTC_waitprivCfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) -{ - strcmp(swap->expectedcmdstr,"BTCprivC"); - printf("call privkey extract from serdatalen.%d\n",*serdatalenp); - instantdex_privkeyextract(myinfo,swap,*serdatap,*serdatalenp); - *serdatap = 0, *serdatalenp = 0; - return(newjson); -} - -cJSON *BOB_waitBTCalttxfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) -{ - *serdatap = 0, *serdatalenp = 0; - strcmp(swap->expectedcmdstr,"BTCalttx"); - if ( instantdex_altpaymentverify(myinfo,iguana_coinfind(swap->mine.offer.base),swap,argjson) != 0 ) - return(cJSON_Parse("{\"error\":\"altpayment didnt verify\"}")); - return(newjson); -} - -cJSON *ALICE_waitBTCpaytxfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) -{ - *serdatap = 0, *serdatalenp = 0; - strcmp(swap->expectedcmdstr,"BTCpaytx"); return(newjson); } -cJSON *BOB_waitfeefunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) +cJSON *BTC_gendepositfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) { - char *retstr; struct iguana_info *coinbtc; - coinbtc = iguana_coinfind("BTC"); + int32_t i; *serdatap = 0, *serdatalenp = 0; - strcpy(swap->waitfortx,"fee"); - if ( coinbtc != 0 && swap->otherfee != 0 )//swap->deposit == 0 && (retstr= BTC_txconfirmed(myinfo,coinbtc,swap,newjson,swap->otherfee->txid,&swap->otherfee->numconfirms,"feefound",0)) != 0 ) + if ( instantdex_isbob(swap) != 0 ) { - retstr = swap->otherfee->txbytes; - jaddstr(newjson,"feefound",retstr); - if ( (swap->deposit= instantdex_bobtx(myinfo,coinbtc,swap->otherpubs[0],swap->mypubs[0],swap->privkeys[swap->choosei],swap->reftime,swap->BTCsatoshis,1)) != 0 ) + for (i=0; i<20; i++) + if ( swap->secretBn[i] != 0 ) + break; + if ( i != 20 ) { - // broadcast deposit - jaddstr(newjson,"deposit",swap->deposit->txbytes); - jaddbits256(newjson,"deposittxid",swap->deposit->txid); + if ( bits256_nonz(swap->pubA0) != 0 && bits256_nonz(swap->pubB0) != 0 ) + { + if ( swap->deposit == 0 && (swap->deposit= instantdex_bobtx(myinfo,swap,swap->coinbtc,swap->BTCsatoshis,1)) == 0 ) + printf("bobtx deposit couldnt be created\n"); + else jaddstr(newjson,"virtevent","depmade"); + } else printf("null pubA0.%llx or pubB0.%llx\n",(long long)swap->pubA0.txid,(long long)swap->pubB0.txid); } - else jaddstr(newjson,"error","couldnt create paymenttx"); - return(newjson); } - return(0); -} - -cJSON *BOB_waitprivMfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) -{ - char *retstr; - strcmp(swap->expectedcmdstr,"BTCprivM"); - if ( swap->payment != 0 && (retstr= BTC_txconfirmed(myinfo,iguana_coinfind("BTC"),swap,newjson,swap->payment->txid,&swap->payment->numconfirms,"btcfound",0)) != 0 ) - jaddstr(newjson,"btcfound",retstr); - printf("search for payment spend in blockchain\n"); - *serdatap = 0, *serdatalenp = 0; return(newjson); } -cJSON *BOB_waitaltconfirmfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) +cJSON *BTC_waitdepositfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) { - char *retstr; struct iguana_info *altcoin; //uint32_t reftime; - altcoin = iguana_coinfind(swap->mine.offer.base); + char msigaddr[64]; *serdatap = 0, *serdatalenp = 0; - strcpy(swap->waitfortx,"alt"); - //reftime = (uint32_t)(ap->offer.expiration - INSTANTDEX_LOCKTIME*2); - if ( altcoin != 0 && swap->altpayment != 0 && (retstr= BTC_txconfirmed(myinfo,altcoin,swap,newjson,swap->altpayment->txid,&swap->altpayment->numconfirms,"altfound",altcoin->chain->minconfirms)) != 0 ) + if ( instantdex_isbob(swap) == 0 ) { - jaddstr(newjson,"altfound",retstr); - if ( (swap->payment= instantdex_bobtx(myinfo,altcoin,swap->mypubs[1],swap->otherpubs[0],swap->privkeys[swap->otherchoosei],swap->reftime,swap->BTCsatoshis,0)) != 0 ) + if ( swap->deposit != 0 && iguana_txidstatus(swap->coinbtc,swap->deposit->txid) >= swap->btcconfirms ) { - // broadcast payment - jaddstr(newjson,"payment",swap->payment->txbytes); - jaddbits256(newjson,"paymenttxid",swap->payment->txid); + if ( instantdex_paymentverify(myinfo,swap->coinbtc,swap,argjson,1) < 0 ) + { + printf("deposit didnt verify\n"); + return(cJSON_Parse("{\"error\":\"deposit didnt verify\"}")); + } + printf("deposit verified\n"); + if ( swap->altpayment == 0 && (swap->altpayment= instantdex_alicetx(myinfo,swap->altcoin,msigaddr,swap->pubAm,swap->pubBn,swap->altsatoshis,swap)) == 0 ) + printf("error creating altpayment\n"); + else + { + jaddstr(newjson,"virtevent","depfound"); + strcpy(swap->altpayment->destaddr,msigaddr); + } } - else jaddstr(newjson,"error","couldnt create paymenttx"); - return(newjson); } - return(0); -} - -cJSON *BTC_waitprivsfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) -{ - *serdatap = 0, *serdatalenp = 0; - strcmp(swap->expectedcmdstr,"BTCprivs"); - instantdex_privkeyextract(myinfo,swap,*serdatap,*serdatalenp); - if ( (swap->myfee= instantdex_feetx(myinfo,&swap->mine)) != 0 ) - { - jaddstr(newjson,"feetx",swap->myfee->txbytes); - jaddbits256(newjson,"feetxid",swap->myfee->txid); - } else printf("error generating feetx\n"); return(newjson); } -cJSON *ALICE_waitfeefunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) +cJSON *BTC_waitaltpaymentfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) { - char *retstr; struct iguana_info *coinbtc; - coinbtc = iguana_coinfind("BTC"); *serdatap = 0, *serdatalenp = 0; - strcpy(swap->waitfortx,"fee"); - if ( coinbtc != 0 && swap->otherfee != 0 )//&& (retstr= BTC_txconfirmed(myinfo,coinbtc,swap,newjson,swap->otherfee->txid,&swap->otherfee->numconfirms,"feefound",0)) != 0 ) + printf("check for altpayment\n"); + if ( swap->altpayment != 0 && iguana_txidstatus(swap->altcoin,swap->altpayment->txid) >= swap->altconfirms ) { - retstr = swap->otherfee->txbytes; - jaddstr(newjson,"feefound",retstr); - return(newjson); - } else return(0); + if ( instantdex_isbob(swap) != 0 ) + { + if ( instantdex_altpaymentverify(myinfo,swap->altcoin,swap,argjson) == 0 ) + { + if ( swap->payment == 0 && (swap->payment= instantdex_bobtx(myinfo,swap,swap->coinbtc,swap->BTCsatoshis,0)) == 0 ) + printf("couldnt create Bob's payment\n"); + else printf("ALTFOUND\n"); + jaddstr(newjson,"virtevent","altfound"); + } else printf("alt payment didnt verify\n"); + } //else jaddstr(newjson,"virtevent","altfound"); + } else printf("altpayment not ready.%p or status %f\n",swap->altpayment,iguana_txidstatus(swap->altcoin,swap->altpayment->txid)); + return(newjson); } -cJSON *ALICE_waitdepositfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) +cJSON *BTC_waitpaymentfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) { - char *retstr; struct iguana_info *coinbtc,*altcoin; - coinbtc = iguana_coinfind("BTC"); - altcoin = iguana_coinfind(swap->mine.offer.rel); - strcpy(swap->waitfortx,"dep"); *serdatap = 0, *serdatalenp = 0; - if ( swap->deposit != 0 && (retstr= BTC_txconfirmed(myinfo,coinbtc,swap,newjson,swap->deposit->txid,&swap->deposit->numconfirms,"depfound",0.5)) != 0 ) + if ( swap->payment != 0 && iguana_txidstatus(swap->coinbtc,swap->payment->txid) >= swap->btcconfirms ) { - jaddstr(newjson,"depfound",retstr); - if ( instantdex_paymentverify(myinfo,iguana_coinfind("BTC"),swap,argjson,1) != 0 ) - return(cJSON_Parse("{\"error\":\"deposit didnt verify\"}")); - if ( (swap->altpayment= instantdex_alicetx(myinfo,altcoin,swap->altpayment->destaddr,swap->pubAm,swap->pubBn,swap->altsatoshis)) != 0 ) + if ( instantdex_isbob(swap) == 0 ) { - // broadcast altpayment - jaddstr(newjson,"altpayment",swap->altpayment->txbytes); - jaddbits256(newjson,"altpaymenttxid",swap->altpayment->txid); - } else return(cJSON_Parse("{\"error\":\"couldnt create altpayment\"}")); + if ( instantdex_paymentverify(myinfo,swap->altcoin,swap,argjson,0) == 0 ) + jaddstr(newjson,"virtevent","payfound"); + } //else jaddstr(newjson,"virtevent","payfound"); } return(newjson); } -cJSON *ALICE_waitconfirmsfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) +cJSON *BTC_cashmsigfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) { - char *retstr; double btcconfirms; struct iguana_info *coinbtc; - coinbtc = iguana_coinfind("BTC"); *serdatap = 0, *serdatalenp = 0; - if ( swap->BTCsatoshis < SATOSHIDEN/10 ) - btcconfirms = 0; - else btcconfirms = 1. + sqrt((double)swap->BTCsatoshis / SATOSHIDEN); - if ( swap->payment != 0 && (retstr= BTC_txconfirmed(myinfo,coinbtc,swap,newjson,swap->payment->txid,&swap->payment->numconfirms,"payfound",btcconfirms)) != 0 ) - { - jaddstr(newjson,"payfound",retstr); - // if bobreclaimed is there, then reclaim altpayment - printf("search for Bob's reclaim in blockchain\n"); - return(newjson); - } else return(0); + return(newjson); } -cJSON *ALICE_checkbobreclaimfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) +cJSON *BTC_donefunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) { - char *retstr; double btcconfirms; struct iguana_info *coinbtc; - coinbtc = iguana_coinfind("BTC"); *serdatap = 0, *serdatalenp = 0; - if ( swap->BTCsatoshis < SATOSHIDEN/10 ) - btcconfirms = 0; - else btcconfirms = 1. + sqrt((double)swap->BTCsatoshis / SATOSHIDEN); - if ( swap->payment != 0 && (retstr= BTC_txconfirmed(myinfo,coinbtc,swap,newjson,swap->payment->txid,&swap->payment->numconfirms,"payfound",btcconfirms)) != 0 ) - { - jaddstr(newjson,"payfound",retstr); - // if bobreclaimed is there, then reclaim altpayment - printf("search for Bob's reclaim in blockchain\n"); - return(newjson); - } else return(0); + return(newjson); } cJSON *BTC_cleanupfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) { *serdatap = 0, *serdatalenp = 0; - jaddstr(newjson,"error","need to cleanup"); swap->dead = (uint32_t)time(NULL); swap->mine.dead = (uint32_t)time(NULL); swap->other.dead = (uint32_t)time(NULL); + portable_mutex_lock(&exchange->mutexS); + DL_DELETE(exchange->statemachines,swap); + portable_mutex_unlock(&exchange->mutexS); + instantdex_historyadd(exchange,swap); + printf("delete from statemachines, add to history\n"); return(newjson); } -cJSON *BTC_idlerecvfunc(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,cJSON *argjson,cJSON *newjson,uint8_t **serdatap,int32_t *serdatalenp) -{ - *serdatap = 0, *serdatalenp = 0; - jaddstr(newjson,"error","need to cleanup"); - return(newjson); -} - -struct bitcoin_statetx *instantdex_getstatetx(struct bitcoin_swapinfo *swap,char *txname) -{ - //char *txnames[] = { "fee", "dep", "alt", "acl", "bre", "bcl", "bfr", "are", "adp" }; - if ( strcmp(txname,"fee") == 0 ) - return(swap->otherfee); - else if ( strcmp(txname,"dep") == 0 ) - return(swap->deposit); - else if ( strcmp(txname,"alt") == 0 ) - return(swap->altpayment); - else if ( strcmp(txname,"acl") == 0 ) - return(swap->payment); - else if ( strcmp(txname,"bre") == 0 ) - return(swap->deposit); - else if ( strcmp(txname,"bcl") == 0 ) - return(swap->altpayment); - else if ( strcmp(txname,"bfr") == 0 ) - return(swap->myfee); - else if ( strcmp(txname,"are") == 0 ) - return(swap->altpayment); - else if ( strcmp(txname,"adp") == 0 ) - return(swap->deposit); - printf("unrecognized txname.(%s)\n",txname); - return(0); -} - struct instantdex_stateinfo *BTC_initFSM(int32_t *n) { struct instantdex_stateinfo *s = 0; @@ -853,130 +968,82 @@ struct instantdex_stateinfo *BTC_initFSM(int32_t *n) // states instantdex_statecreate(s,n,,handlerfunc,errorhandler,, // a given state has a couple of handlers and custom events, with timeouts and errors invoking a bypass // events instantdex_addevent(s,*n,,,,) - *n = 2; + *n = 2; // start with state 2 s = instantdex_statecreate(s,n,"BTC_cleanup",BTC_cleanupfunc,0,0,0,-1); // from states without any commits - memset(s,0,sizeof(*s) * 2); + memset(s,0,sizeof(*s) * 2); // make sure state 0 and 1 are cleared // terminal [BLOCKING] states for the corresponding transaction // if all goes well both alice and bob get to claim the other's payments - s = instantdex_statecreate(s,n,"ALICE_claimedbtc",ALICE_claimbtcfunc,0,0,0,0); - instantdex_addevent(s,*n,"ALICE_claimedbtc","aclfound","poll","BTC_cleanup"); - instantdex_addevent(s,*n,"ALICE_claimedbtc","poll","poll","ALICE_claimedbtc"); + + // after offer is sent, wait for other side to choose and sent their deck, then send privs + s = instantdex_statecreate(s,n,"BTC_idle",BTC_checkdeckfunc,0,"BTC_cleanup",0,1); + s = instantdex_statecreate(s,n,"BTC_waitdeck",BTC_checkdeckfunc,0,"BTC_cleanup",0,0); + s = instantdex_statecreate(s,n,"BTC_gotdeck",BTC_checkdeckfunc,0,"BTC_cleanup",0,0); + s = instantdex_statecreate(s,n,"BTC_waitfee",BTC_waitfeefunc,0,"BTC_cleanup",0,0); + s = instantdex_statecreate(s,n,"BTC_gendeposit",BTC_gendepositfunc,0,"BTC_cleanup",0,0); + s = instantdex_statecreate(s,n,"BTC_waitdeposit",BTC_waitdepositfunc,0,"BTC_cleanup",0,0); + s = instantdex_statecreate(s,n,"BTC_waitaltpayment",BTC_waitaltpaymentfunc,0,"BTC_cleanup",0,0); + s = instantdex_statecreate(s,n,"BTC_waitpayment",BTC_waitpaymentfunc,0,"BTC_cleanup",0,0); + s = instantdex_statecreate(s,n,"BTC_makeclaim",BTC_makeclaimfunc,0,"BTC_cleanup",0,0); + s = instantdex_statecreate(s,n,"BTC_cashmsig",BTC_cashmsigfunc,0,"BTC_cleanup",0,0); + s = instantdex_statecreate(s,n,"BTC_done",BTC_donefunc,0,"BTC_cleanup",0,0); + + instantdex_addevent(s,*n,"BTC_idle","BTCoffer","poll","BTC_waitdeck"); // send deck + Chose + instantdex_addevent(s,*n,"BTC_waitdeck","gotdeck","havedeck","BTC_gotdeck"); // virt event + instantdex_addevent(s,*n,"BTC_waitdeck","havedeck","poll","BTC_waitdeck"); // other side gotdeck + instantdex_addevent(s,*n,"BTC_waitdeck","sentpriv","sentpriv","BTC_waitdeck"); + instantdex_addevent(s,*n,"BTC_waitdeck","poll","sentpriv","BTC_waitdeck"); - s = instantdex_statecreate(s,n,"BOB_depclaimed",BOB_reclaimfunc,0,0,0,0); // deposit back - instantdex_addevent(s,*n,"BOB_depclaimed","brefound","poll","BTC_cleanup"); - instantdex_addevent(s,*n,"BOB_depclaimed","poll","poll","BOB_depclaimed"); - - s = instantdex_statecreate(s,n,"BOB_claimedalt",BOB_claimaltfunc,0,0,0,0); - instantdex_addevent(s,*n,"BOB_claimedalt","bclfound","poll","BOB_depclaimed"); - instantdex_addevent(s,*n,"BOB_claimedalt","poll","poll","BOB_claimedalt"); + // to goto BTC_waitfee, both must have sent/recv deck and Chosen and verified cut and choose + instantdex_addevent(s,*n,"BTC_gotdeck","gotdeck","sentpriv","BTC_waitfee"); // other gotdeck + instantdex_addevent(s,*n,"BTC_gotdeck","havedeck","poll","BTC_gotdeck"); + instantdex_addevent(s,*n,"BTC_gotdeck","sentpriv","poll","BTC_gotdeck"); + instantdex_addevent(s,*n,"BTC_gotdeck","poll","sentpriv","BTC_gotdeck"); - // if things go wrong, bob gets his deposit and fee back - s = instantdex_statecreate(s,n,"BOB_feereclaimed",BOB_feereclaimfunc,0,0,0,0); - instantdex_addevent(s,*n,"BOB_feereclaimed","bfrfound","poll","BTC_cleanup"); - instantdex_addevent(s,*n,"BOB_feereclaimed","poll","poll","BOB_feereclaimed"); + // [BLOCKING: feefound] Bob waits for fee and sends deposit when it appears, alice skips past + instantdex_addevent(s,*n,"BTC_waitfee","gendep","poll","BTC_gendeposit"); // bob's virt + instantdex_addevent(s,*n,"BTC_waitfee","waitdep","poll","BTC_waitdeposit"); // alice's virt + instantdex_addevent(s,*n,"BTC_waitfee","sentpriv","poll","BTC_waitfee"); + instantdex_addevent(s,*n,"BTC_waitfee","poll","sentpriv","BTC_waitfee"); + + instantdex_addevent(s,*n,"BTC_gendeposit","depmade","poll","BTC_waitaltpayment"); + instantdex_addevent(s,*n,"BTC_gendeposit","sentpriv","poll","BTC_gendeposit"); + instantdex_addevent(s,*n,"BTC_gendeposit","poll","sentpriv","BTC_gendeposit"); + + // [BLOCKING: depfound] Alice waits for deposit to confirm and sends altpayment, bob skips + instantdex_addevent(s,*n,"BTC_waitdeposit","depfound","gotdep","BTC_waitpayment"); // alice virt + instantdex_addevent(s,*n,"BTC_waitdeposit","gotdep","poll","BTC_waitdeposit"); + instantdex_addevent(s,*n,"BTC_waitdeposit","sentpriv","poll","BTC_waitdeposit"); + instantdex_addevent(s,*n,"BTC_waitdeposit","poll","sentpriv","BTC_waitdeposit"); + + // [BLOCKING: altfound] now Bob's turn to make sure altpayment is confirmed and send payment + instantdex_addevent(s,*n,"BTC_waitaltpayment","altfound","gotalt","BTC_waitpayment"); // virt + instantdex_addevent(s,*n,"BTC_waitaltpayment","gotdep","sentpriv","BTC_waitaltpayment"); + instantdex_addevent(s,*n,"BTC_waitaltpayment","gotalt","poll","BTC_waitaltpayment"); + instantdex_addevent(s,*n,"BTC_waitaltpayment","sentpriv","poll","BTC_waitaltpayment"); + instantdex_addevent(s,*n,"BTC_waitaltpayment","poll","sentpriv","BTC_waitaltpayment"); - s = instantdex_statecreate(s,n,"BOB_reclaimed",BOB_reclaimfunc,0,0,0,0); // deposit back - instantdex_addevent(s,*n,"BOB_reclaimed","brefound","poll","BOB_feereclaimed"); - instantdex_addevent(s,*n,"BOB_reclaimed","poll","poll","BOB_reclaimed"); - - // if things go wrong, alice reclaims her altpayment or claims the deposit and then fee - s = instantdex_statecreate(s,n,"ALICE_feereclaimed",ALICE_feereclaimfunc,0,0,0,0); - instantdex_addevent(s,*n,"ALICE_feereclaimed","afrfound","poll","BTC_cleanup"); - instantdex_addevent(s,*n,"ALICE_feereclaimed","poll","poll","ALICE_feereclaimed"); - - s = instantdex_statecreate(s,n,"ALICE_reclaimed",ALICE_reclaimfunc,0,0,0,0); // altpayment - instantdex_addevent(s,*n,"ALICE_reclaimed","arefound","poll","ALICE_feereclaimed"); - instantdex_addevent(s,*n,"ALICE_reclaimed","poll","poll","ALICE_reclaimed"); - s = instantdex_statecreate(s,n,"ALICE_depositclaimed",ALICE_claimdepositfunc,0,0,0,0); // altpayment - instantdex_addevent(s,*n,"ALICE_depositclaimed","adpfound","poll","ALICE_feereclaimed"); - instantdex_addevent(s,*n,"ALICE_depositclaimed","poll","poll","ALICE_depositclaimed"); - // end terminal [BLOCKING] states + // [BLOCKING: payfound] now Alice's turn to make sure payment is confrmed and send in claim or see bob's reclaim and reclaim + instantdex_addevent(s,*n,"BTC_waitpayment","payfound","gotpaytx","BTC_makeclaim"); // virt + instantdex_addevent(s,*n,"BTC_waitpayment","gotpaytx","poll","BTC_waitpayment"); + instantdex_addevent(s,*n,"BTC_waitpayment","sentpriv","poll","BTC_waitpayment"); + instantdex_addevent(s,*n,"BTC_waitpayment","poll","sentpriv","BTC_waitpayment"); - // need to create states before they can be referred to, that way a one pass FSM compile is possible - s = instantdex_statecreate(s,n,"BOB_gotoffer",BTC_waitprivCfunc,0,"BTC_cleanup",0,1); - s = instantdex_statecreate(s,n,"ALICE_gotoffer",BTC_waitprivCfunc,0,"BTC_cleanup",0,1); - s = instantdex_statecreate(s,n,"BOB_sentprivs",BTC_waitprivsfunc,0,"BTC_cleanup",0,0); - s = instantdex_statecreate(s,n,"BOB_waitfee",BOB_waitfeefunc,0,"BTC_cleanup",0,0); - s = instantdex_statecreate(s,n,"BOB_sentdeposit",BOB_waitBTCalttxfunc,0,"BOB_reclaimed",0,0); - s = instantdex_statecreate(s,n,"BOB_altconfirm",BOB_waitaltconfirmfunc,0,"BOB_reclaimed",0,0); - s = instantdex_statecreate(s,n,"BOB_sentpayment",BOB_waitprivMfunc,0,"BOB_reclaimed",0,0); - s = instantdex_statecreate(s,n,"ALICE_sentprivs",BTC_waitprivsfunc,0,"BTC_cleanup",0,0); - s = instantdex_statecreate(s,n,"Alice_waitfee",ALICE_waitfeefunc,0,"BTC_cleanup",0,0); - s = instantdex_statecreate(s,n,"ALICE_waitdeposit",ALICE_waitdepositfunc,0,"BTC_cleanup",0,0); - s = instantdex_statecreate(s,n,"ALICE_sentalt",ALICE_waitBTCpaytxfunc,0,"ALICE_reclaimed",0,0); - s = instantdex_statecreate(s,n,"ALICE_waitconfirms",ALICE_waitconfirmsfunc,0,"ALICE_reclaimed",0,0); - s = instantdex_statecreate(s,n,"ALICE_checkbobreclaim",ALICE_checkbobreclaimfunc,0,"ALICE_reclaimed",0,0); - - if ( 0 ) // following are implicit states and events handled externally to setup datastructures - { - instantdex_addevent(s,*n,"BOB_idle","usrorder","BTCoffer","BOB_sentoffer"); // send deck - instantdex_addevent(s,*n,"ALICE_idle","usrorder","BTCoffer","ALICE_sentoffer"); - } - s = instantdex_statecreate(s,n,"BOB_idle",BTC_idlerecvfunc,0,"BTC_cleanup",0,1); - instantdex_addevent(s,*n,"BOB_idle","BTCoffer","BTCdeckC","BOB_gotoffer"); // send deck + Chose - s = instantdex_statecreate(s,n,"ALICE_idle",BTC_idlerecvfunc,0,"BTC_cleanup",0,1); - instantdex_addevent(s,*n,"ALICE_idle","BTCoffer","BTCdeckC","ALICE_gotoffer"); + // [BLOCKING: privM] Bob waits for privM either from Alice or alt blockchain + instantdex_addevent(s,*n,"BTC_makeclaim","claimed","didclaim","BTC_done"); + instantdex_addevent(s,*n,"BTC_makeclaim","didclaim","poll","BTC_cashmsig"); + instantdex_addevent(s,*n,"BTC_makeclaim","poll","sentpriv","BTC_makeclaim"); - // after offer is sent, wait for other side to choose and sent their deck, then send privs - s = instantdex_statecreate(s,n,"BOB_sentoffer",BTC_waitdeckCfunc,0,"BTC_cleanup",0,1); - s = instantdex_statecreate(s,n,"ALICE_sentoffer",BTC_waitdeckCfunc,0,"BTC_cleanup",0,1); - instantdex_addevent(s,*n,"BOB_sentoffer","BTCdeckC","BTCprivC","BOB_sentprivs"); // send privs + Chose - instantdex_addevent(s,*n,"ALICE_sentoffer","BTCdeckC","BTCprivC","ALICE_sentprivs"); - - // gotoffer states have received deck and sent BTCdeckC already (along with deck) - s = instantdex_statecreate(s,n,"BOB_gotoffer",BTC_waitprivCfunc,0,"BTC_cleanup",0,1); - s = instantdex_statecreate(s,n,"ALICE_gotoffer",BTC_waitprivCfunc,0,"BTC_cleanup",0,1); - instantdex_addevent(s,*n,"BOB_gotoffer","BTCprivC","BTCprivs","BOB_sentprivs"); // send privs - instantdex_addevent(s,*n,"ALICE_gotoffer","BTCprivC","BTCprivs","ALICE_sentprivs"); - - // to reach sentprivs, all paths must have sent/recv deck and Chose and verified cut and choose - s = instantdex_statecreate(s,n,"BOB_sentprivs",BTC_waitprivsfunc,0,"BTC_cleanup",0,0); - instantdex_addevent(s,*n,"BOB_sentprivs","BTCprivs","poll","BOB_waitfee"); - instantdex_addevent(s,*n,"BOB_sentprivs","poll","poll","BOB_sentprivs"); - - s = instantdex_statecreate(s,n,"ALICE_sentprivs",BTC_waitprivsfunc,0,"BTC_cleanup",0,0); - instantdex_addevent(s,*n,"ALICE_sentprivs","BTCprivs","poll","Alice_waitfee"); - instantdex_addevent(s,*n,"ALICE_sentprivs","poll","poll","ALICE_sentprivs"); - - // [BLOCKING: fee] Bob waits for fee and sends deposit when it appears - s = instantdex_statecreate(s,n,"BOB_waitfee",BOB_waitfeefunc,0,"BTC_cleanup",0,0); - instantdex_addevent(s,*n,"BOB_waitfee","feefound","BTCdeptx","BOB_sentdeposit"); - instantdex_addevent(s,*n,"BOB_waitfee","poll","poll","BOB_waitfee"); - - // [BLOCKING: fee and deposit] Alice waits for fee and then waits for deposit to confirm and sends altpayment - s = instantdex_statecreate(s,n,"Alice_waitfee",ALICE_waitfeefunc,0,"BTC_cleanup",0,0); - instantdex_addevent(s,*n,"Alice_waitfee","feefound","poll","ALICE_waitdeposit"); - instantdex_addevent(s,*n,"Alice_waitfee","poll","poll","Alice_waitfee"); - - s = instantdex_statecreate(s,n,"ALICE_waitdeposit",ALICE_waitdepositfunc,0,"BTC_cleanup",0,0); - instantdex_addevent(s,*n,"ALICE_waitdeposit","depfound","BTCalttx","ALICE_sentalt"); - instantdex_addevent(s,*n,"ALICE_waitdeposit","poll","poll","ALICE_waitdeposit"); + instantdex_addevent(s,*n,"BTC_cashmsig","gotprivM","didmsig","BTC_done"); + instantdex_addevent(s,*n,"BTC_cashmsig","poll","sentpriv","BTC_cashmsig"); - // [BLOCKING: BTCalttx and altfound] now Bob's turn to make sure altpayment is confirmed and send real payment - s = instantdex_statecreate(s,n,"BOB_sentdeposit",BOB_waitBTCalttxfunc,0,"BOB_reclaimed",0,0); - instantdex_addevent(s,*n,"BOB_sentdeposit","BTCalttx","poll","BOB_altconfirm"); - - s = instantdex_statecreate(s,n,"BOB_altconfirm",BOB_waitaltconfirmfunc,0,"BOB_reclaimed",0,0); - instantdex_addevent(s,*n,"BOB_altconfirm","altfound","BTCpaytx","BOB_sentpayment"); - instantdex_addevent(s,*n,"BOB_altconfirm","poll","poll","BOB_altconfirm"); - - // [BLOCKING: BTCpaytx] now Alice's turn to make sure payment is confrmed and send in claim or see bob's reclaim and reclaim - s = instantdex_statecreate(s,n,"ALICE_sentalt",ALICE_waitBTCpaytxfunc,0,"ALICE_reclaimed",0,0); - instantdex_addevent(s,*n,"ALICE_sentalt","BTCpaytx","poll","ALICE_waitconfirms"); - - s = instantdex_statecreate(s,n,"ALICE_waitconfirms",ALICE_waitconfirmsfunc,0,"ALICE_reclaimed",0,0); - instantdex_addevent(s,*n,"ALICE_waitconfirms","altfound","BTCprivM","ALICE_claimedbtc"); - instantdex_addevent(s,*n,"ALICE_waitconfirms","poll","poll","ALICE_checkbobreclaim"); - - s = instantdex_statecreate(s,n,"ALICE_checkbobreclaim",ALICE_checkbobreclaimfunc,0,"ALICE_reclaimed",0,0); + /*s = instantdex_statecreate(s,n,"ALICE_checkbobreclaim",ALICE_checkbobreclaimfunc,0,"ALICE_reclaimed",0,0); instantdex_addevent(s,*n,"ALICE_checkbobreclaim","brefound","poll","ALICE_reclaimed"); instantdex_addevent(s,*n,"ALICE_checkbobreclaim","poll","poll","ALICE_waitconfirms"); - // [BLOCKING: privM] Bob waits for privM either from Alice or alt blockchain s = instantdex_statecreate(s,n,"BOB_sentpayment",BOB_waitprivMfunc,0,"BOB_reclaimed",0,0); instantdex_addevent(s,*n,"BOB_sentpayment","aclfound","BTCdone","BOB_claimedalt"); instantdex_addevent(s,*n,"BOB_sentpayment","BTCprivM","BTCdone","BOB_claimedalt"); - instantdex_addevent(s,*n,"BOB_sentpayment","poll","poll","BOB_sentpayment"); + instantdex_addevent(s,*n,"BOB_sentpayment","poll","poll","BOB_sentpayment");*/ { double startmillis = OS_milliseconds(); instantdex_FSMtest(s,*n,1000); @@ -985,33 +1052,64 @@ struct instantdex_stateinfo *BTC_initFSM(int32_t *n) return(s); } +struct bitcoin_eventitem *instantdex_event(char *cmdstr,cJSON *argjson,cJSON *newjson,uint8_t *serdata,int32_t serdatalen) +{ + struct bitcoin_eventitem *ptr; + ptr = calloc(1,sizeof(*ptr) + serdatalen); + strcpy(ptr->cmd,cmdstr); + ptr->newjson = jduplicate(newjson); + ptr->argjson = jduplicate(argjson); + if ( serdatalen != 0 ) + { + memcpy(ptr->serdata,serdata,serdatalen); + ptr->serdatalen = serdatalen; + } + return(ptr); +} + +void instantdex_eventfree(struct bitcoin_eventitem *ptr) +{ + if ( ptr != 0 ) + { + if ( ptr->argjson != 0 ) + free_json(ptr->argjson); + if ( ptr->newjson != 0 ) + free_json(ptr->newjson); + free(ptr); + } +} + char *instantdex_statemachine(struct instantdex_stateinfo *states,int32_t numstates,struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap,char *cmdstr,cJSON *argjson,cJSON *newjson,uint8_t *serdata,int32_t serdatalen) { - uint32_t i; struct iguana_info *altcoin=0,*coinbtc=0; struct instantdex_stateinfo *state=0; cJSON *origjson = newjson; - if ( swap == 0 || (state= swap->state) == 0 || (coinbtc= iguana_coinfind("BTC")) == 0 || (altcoin= iguana_coinfind(swap->mine.offer.base)) == 0 ) + uint32_t i; struct instantdex_stateinfo *state=0; + if ( swap == 0 || (state= swap->state) == 0 ) { - printf("state.%s btc.%p altcoin.%p\n",state->name,coinbtc,altcoin); + printf("state.%s (%s)\n",state->name,swap->mine.offer.base); return(clonestr("{\"error\":\"instantdex_BTCswap missing coin info\"}")); } - printf("%llu/%llu cmd.(%s) state.(%s)\n",(long long)swap->mine.orderid,(long long)swap->other.orderid,cmdstr,swap->state->name); - if ( swap->expiration != 0 && time(NULL) > swap->expiration ) + printf("%llu/%llu cmd.(%s) state.(%s) newlen.%d isbob.%d have.%x myhave.%x otherfee.%p\n",(long long)swap->mine.orderid,(long long)swap->other.orderid,cmdstr,swap->state->name,(int32_t)strlen(jprint(newjson,0)),instantdex_isbob(swap),juint(argjson,"have"),swap->havestate,swap->otherfee); + if ( jobj(argjson,"have") != 0 ) + swap->otherhavestate |= juint(argjson,"have"); + if ( jobj(argjson,"mychoosei") != 0 ) + swap->otherchoosei |= juint(argjson,"mychoosei"); + if ( swap->state->name[0] == 0 || (swap->expiration != 0 && time(NULL) > swap->expiration) ) { swap->state = &states[state->timeoutind]; - if ( (newjson= (*state->timeout)(myinfo,exchange,swap,argjson,newjson,&serdata,&serdatalen)) == 0 ) + swap->dead = (uint32_t)time(NULL); + if ( state->timeout == 0 || (newjson= (*state->timeout)(myinfo,exchange,swap,argjson,newjson,&serdata,&serdatalen)) == 0 ) return(clonestr("{\"error\":\"instantdex_BTCswap null return from timeoutfunc\"}")); - return(jprint(newjson,1)); + else return(jprint(newjson,0)); } for (i=0; inumevents; i++) { if ( strcmp(cmdstr,state->events[i].cmdstr) == 0 ) { - if ( (newjson= (*state->process)(myinfo,exchange,swap,argjson,newjson,&serdata,&serdatalen)) == 0 ) + if ( state->process != 0 && (newjson= (*state->process)(myinfo,exchange,swap,argjson,newjson,&serdata,&serdatalen)) == 0 ) { - free_json(origjson); if ( strcmp("poll",state->events[i].sendcmd) == 0 ) { - printf("poll event\n"); - return(instantdex_sendcmd(myinfo,&swap->mine.offer,newjson,state->events[i].sendcmd,myinfo->myaddr.persistent,0,serdata,serdatalen)); + printf("POLL for pending tx\n"); + //return(instantdex_sendcmd(myinfo,&swap->mine.offer,newjson,state->events[i].sendcmd,myinfo->myaddr.persistent,0,serdata,serdatalen,0)); } else { @@ -1022,12 +1120,40 @@ char *instantdex_statemachine(struct instantdex_stateinfo *states,int32_t numsta } else { + /*if ( 0 && strcmp(cmdstr,"poll") != 0 ) + { + if ( swap->pollevent != 0 ) + instantdex_eventfree(swap->pollevent); + swap->pollevent = instantdex_event("poll",argjson,newjson,serdata,serdatalen); + }*/ + if ( jstr(newjson,"virtevent") != 0 ) + { + printf("VIRTEVENT.(%s)\n",jstr(newjson,"virtevent")); + for (i=0; inumevents; i++) + if ( strcmp(jstr(newjson,"virtevent"),state->events[i].cmdstr) == 0 ) + { + cmdstr = state->events[i].cmdstr; + break; + } + if ( i == state->numevents ) + { + printf("error cant find.(%s)\n",jstr(newjson,"virtevent")); + return(clonestr("{\"error\":\"instantdex_statemachine: unexpected virtevent\"}")); + } + else + { + //printf("found.%d event.%s -> %s next.%d\n",i,state->events[i].cmdstr,states[state->events[i].nextstateind].name,state->events[i].nextstateind); + } + } if ( state->events[i].sendcmd[0] != 0 ) { + //printf("i.%d send.%s, next state.%s.[%d] %p\n",i,state->events[i].sendcmd,states[state->events[i].nextstateind].name,state->events[i].nextstateind,&states[state->events[i].nextstateind]); if ( state->events[i].nextstateind > 1 ) { + instantdex_newjson(myinfo,swap,newjson); + //printf("i.%d (%s) %s %s.%d -> %s.%d send.(%s) %p\n",i,jprint(newjson,0),cmdstr,swap->state->name,state->ind,states[state->events[i].nextstateind].name,state->events[i].nextstateind,state->events[i].sendcmd,&states[state->events[i].nextstateind]); swap->state = &states[state->events[i].nextstateind]; - return(instantdex_sendcmd(myinfo,&swap->mine.offer,newjson,state->events[i].sendcmd,swap->othertrader,INSTANTDEX_HOPS,serdata,serdatalen)); + return(instantdex_sendcmd(myinfo,&swap->mine.offer,newjson,state->events[i].sendcmd,swap->othertrader,INSTANTDEX_HOPS,serdata,serdatalen,0,swap)); } else return(clonestr("{\"error\":\"instantdex_statemachine: illegal state\"}")); } else return(clonestr("{\"result\":\"instantdex_statemachine: processed\"}")); } @@ -1036,6 +1162,32 @@ char *instantdex_statemachine(struct instantdex_stateinfo *states,int32_t numsta return(clonestr("{\"error\":\"instantdex_statemachine: unexpected state\"}")); } +void instantdex_statemachine_iter(struct supernet_info *myinfo,struct exchange_info *exchange,struct bitcoin_swapinfo *swap) +{ + char *str; struct bitcoin_eventitem *ptr; cJSON *newjson; int32_t flag = 0; + if ( swap->dead != 0 || swap->mine.dead != 0 || swap->other.dead != 0 ) + return; + if ( swap->myfee == 0 ) + swap->myfee = instantdex_feetx(myinfo,&swap->mine,swap,swap->coinbtc); + //printf("state(%s) %llx/%llx\n",swap->state->name,(long long)swap->mine.orderid,(long long)swap->other.orderid); + while ( (ptr= queue_dequeue(&swap->eventsQ,0)) != 0 ) + { + //printf("dequeued (%s)\n",ptr->cmd); + if ( (str= instantdex_statemachine(BTC_states,BTC_numstates,myinfo,exchange,swap,ptr->cmd,ptr->argjson,ptr->newjson,ptr->serdata,ptr->serdatalen)) != 0 ) + free(str); + instantdex_eventfree(ptr); + flag++; + } + if ( flag == 0 && swap->dead == 0 && swap->pollevent != 0 ) + { + //printf("send poll event\n"); + newjson = jduplicate(swap->pollevent->newjson); + if ( (str= instantdex_statemachine(BTC_states,BTC_numstates,myinfo,exchange,swap,"poll",swap->pollevent->argjson,newjson,swap->pollevent->serdata,swap->pollevent->serdatalen)) != 0 ) + free(str); + free_json(newjson); + } +} + #ifdef oldway // https://github.com/TierNolan/bips/blob/bip4x/bip-atom.mediawiki @@ -1268,8 +1420,11 @@ char *instantdex_BTCswap(struct supernet_info *myinfo,struct exchange_info *exch //printf("got offer.(%s) offerside.%d offerdir.%d\n",jprint(argjson,0),A->offer.myside,A->offer.acceptdir); if ( strcmp(cmdstr,"offer") == 0 ) // sender is Bob, receiver is network (Alice) { - if ( A->offer.expiration < (time(NULL) + INSTANTDEX_DURATION) ) + if ( 0 && A->offer.expiration < (time(NULL) + INSTANTDEX_DURATION) ) + { + printf("too close to expiration: %u >= %lu\n",A->offer.expiration,(time(NULL) + INSTANTDEX_DURATION)); return(clonestr("{\"error\":\"instantdex_BTCswap offer too close to expiration\"}")); + } if ( (ap= instantdex_acceptable(exchange,A,myinfo->myaddr.nxt64bits)) != 0 ) { isbob = 0; diff --git a/iguana/tests/DEX b/iguana/tests/DEX new file mode 100755 index 000000000..1a807d6d7 --- /dev/null +++ b/iguana/tests/DEX @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"basilisk\",\"method\":\"genesis_opreturn\",\"vals\":{\"issuer\":\"RXL3YXG2ceaB6C5hfJcN4fvmLH2C34knhA\",\"stake\":1000000,\"blocktime\":1,\"name\":\"InstantDEX\",\"symbol\":\"DEX\",\"p2sh\":5,\"wif\":128,\"nBits\":\"1effffff\"}}" + diff --git a/iguana/tests/DEXtx b/iguana/tests/DEXtx new file mode 100755 index 000000000..302997a86 --- /dev/null +++ b/iguana/tests/DEXtx @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"method\":\"sendtoaddress\",\"params\":[\"RXL3YXG2ceaB6C5hfJcN4fvmLH2C34knhA\", 0.0001, \"4e4557444558000000496e7374616e74444558000000000000407a10f35a0000dffc6993a2216d57ffffff1e1f4e010001000cba013c0580f1dce4182fce875748c4986b240ff7d7bc3fffb0\", \"sendcomment\"]}" + diff --git a/iguana/tests/HOT b/iguana/tests/HOT new file mode 100755 index 000000000..261ef44ce --- /dev/null +++ b/iguana/tests/HOT @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"basilisk\",\"method\":\"genesis_opreturn\",\"vals\":{\"issuer\":\"RXL3YXG2ceaB6C5hfJcN4fvmLH2C34knhA\",\"stake\":1000000,\"blocktime\":1,\"name\":\"HOT ICO\",\"symbol\":\"HOT\",\"p2sh\":5,\"wif\":128,\"nBits\":\"1effffff\"}}" + diff --git a/iguana/tests/HOTtx b/iguana/tests/HOTtx new file mode 100755 index 000000000..f84d2d4b9 --- /dev/null +++ b/iguana/tests/HOTtx @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"method\":\"sendtoaddress\",\"params\":[\"RXL3YXG2ceaB6C5hfJcN4fvmLH2C34knhA\", 0.0001, \"4e4557484f54000000484f542049434f000000000000000000407a10f35a00007f53009145d46b57ffffff1e0000000001009577013c0580f1dce4182fce875748c4986b240ff7d7bc3fffb0\", \"sendcomment\"]}" + diff --git a/iguana/tests/PAX b/iguana/tests/PAX new file mode 100755 index 000000000..f4d6950e8 --- /dev/null +++ b/iguana/tests/PAX @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"pax\",\"method\":\"start\"}" diff --git a/iguana/tests/PoS b/iguana/tests/PoS new file mode 100755 index 000000000..f3ee99728 --- /dev/null +++ b/iguana/tests/PoS @@ -0,0 +1,7 @@ +curl --url "http://127.0.0.1:7778" --data "{\"timeout\":60000,\"agent\":\"iguana\",\"method\":\"PoSweights\",\"activecoin\":\"BTCD\",\"height\":1192000}" +curl --url "http://127.0.0.1:7778" --data "{\"timeout\":60000,\"agent\":\"iguana\",\"method\":\"PoSweights\",\"activecoin\":\"BTCD\",\"height\":1192500}" +curl --url "http://127.0.0.1:7778" --data "{\"timeout\":60000,\"agent\":\"iguana\",\"method\":\"PoSweights\",\"activecoin\":\"BTCD\",\"height\":1193000}" +curl --url "http://127.0.0.1:7778" --data "{\"timeout\":60000,\"agent\":\"iguana\",\"method\":\"PoSweights\",\"activecoin\":\"BTCD\",\"height\":1193500}" +curl --url "http://127.0.0.1:7778" --data "{\"timeout\":60000,\"agent\":\"iguana\",\"method\":\"PoSweights\",\"activecoin\":\"BTCD\",\"height\":1194000}" +curl --url "http://127.0.0.1:7778" --data "{\"timeout\":60000,\"agent\":\"iguana\",\"method\":\"PoSweights\",\"activecoin\":\"BTCD\",\"height\":1194500}" +curl --url "http://127.0.0.1:7778" --data "{\"timeout\":60000,\"agent\":\"iguana\",\"method\":\"PoSweights\",\"activecoin\":\"BTCD\",\"height\":1195000}" diff --git a/iguana/tests/accept b/iguana/tests/accept new file mode 100755 index 000000000..bdf736e9a --- /dev/null +++ b/iguana/tests/accept @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"method\":\"accept\",\"requestid\":1728286611,\"quoteid\":123456}" diff --git a/iguana/tests/addnode b/iguana/tests/addnode new file mode 100755 index 000000000..b9fd550f7 --- /dev/null +++ b/iguana/tests/addnode @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"BTCD\",\"ipaddr\":\"5.9.102.210\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"BTCD\",\"ipaddr\":\"78.47.196.146\"}" diff --git a/iguana/tests/addnodeSYS b/iguana/tests/addnodeSYS new file mode 100755 index 000000000..b4a548e1c --- /dev/null +++ b/iguana/tests/addnodeSYS @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"SYS\",\"ipaddr\":\"198.147.29.138\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"SYS\",\"ipaddr\":\"118.244.207.7\"}" diff --git a/iguana/tests/addrelays b/iguana/tests/addrelays new file mode 100755 index 000000000..26dd60206 --- /dev/null +++ b/iguana/tests/addrelays @@ -0,0 +1,8 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"BTCD\",\"ipaddr\":\"89.248.160.237\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"BTCD\",\"ipaddr\":\"89.248.160.238\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"BTCD\",\"ipaddr\":\"89.248.160.239\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"BTCD\",\"ipaddr\":\"89.248.160.240\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"BTCD\",\"ipaddr\":\"89.248.160.241\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"BTCD\",\"ipaddr\":\"89.248.160.242\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"BTCD\",\"ipaddr\":\"89.248.160.243\"}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"addnode\",\"activecoin\":\"BTCD\",\"ipaddr\":\"89.248.160.244\"}" diff --git a/iguana/tests/ahloop b/iguana/tests/ahloop new file mode 100755 index 000000000..e9f287381 --- /dev/null +++ b/iguana/tests/ahloop @@ -0,0 +1,9 @@ +ind=0 +one=1 +while true +do +./activehandle +ind=`expr $ind + $one` +echo $ind +done + diff --git a/iguana/tests/allcoins b/iguana/tests/allcoins new file mode 100755 index 000000000..1454b39b7 --- /dev/null +++ b/iguana/tests/allcoins @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"method\":\"allcoins\"}" diff --git a/iguana/tests/arraytest b/iguana/tests/arraytest new file mode 100755 index 000000000..4191fd1cf --- /dev/null +++ b/iguana/tests/arraytest @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "[{\"agent\":\"SuperNET\",\"method\":\"activehandle\"}, {\"agent\":\"bitcoinrpc\",\"activecoin\":\"BTCD\",\"method\":\"getdifficulty\"}]" diff --git a/iguana/tests/automatched b/iguana/tests/automatched new file mode 100755 index 000000000..4475dce0b --- /dev/null +++ b/iguana/tests/automatched @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"method\":\"automatched\",\"requestid\":1728286611}" diff --git a/iguana/tests/available b/iguana/tests/available new file mode 100755 index 000000000..fbe1a0e22 --- /dev/null +++ b/iguana/tests/available @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"method\":\"available\",\"source\":\"BTCD\"}" diff --git a/iguana/tests/aveprice b/iguana/tests/aveprice new file mode 100755 index 000000000..cc176176e --- /dev/null +++ b/iguana/tests/aveprice @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"tradebot\",\"method\":\"aveprice\",\"base\":\"BTCD\",\"rel\":\"BTC\",\"basevolume\":1.0}" + diff --git a/iguana/tests/backupwallet b/iguana/tests/backupwallet index c7a3b1e8a..8b0222eb7 100755 --- a/iguana/tests/backupwallet +++ b/iguana/tests/backupwallet @@ -1 +1 @@ -curl --url "http://127.0.0.1:7778" --data "{\"method\":\"backupwallet\",\"params\":[\"testwallet\"]}" +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTC\",\"method\":\"backupwallet\",\"params\":[\"testwallet\"]}" diff --git a/iguana/tests/balances b/iguana/tests/balances new file mode 100755 index 000000000..4a899475f --- /dev/null +++ b/iguana/tests/balances @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"timeout\":20000,\"agent\":\"basilisk\",\"method\":\"balances\",\"vals\":{\"minconf\":1}}" diff --git a/iguana/tests/buy b/iguana/tests/buy new file mode 100755 index 000000000..67c07d1a0 --- /dev/null +++ b/iguana/tests/buy @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"dotrade\":1,\"agent\":\"InstantDEX\",\"exchange\":\"bitcoin\",\"method\":\"buy\",\"base\":\"BTCD\",\"rel\":\"BTC\",\"price\":0.0029,\"volume\":1.0}" diff --git a/iguana/tests/buy2 b/iguana/tests/buy2 new file mode 100755 index 000000000..252ab3c60 --- /dev/null +++ b/iguana/tests/buy2 @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"dotrade\":1,\"agent\":\"InstantDEX\",\"exchange\":\"bitcoin\",\"method\":\"buy\",\"base\":\"BTCD\",\"rel\":\"BTC\",\"price\":0.0027,\"volume\":1.0}" diff --git a/iguana/tests/creategtx b/iguana/tests/creategtx new file mode 100755 index 000000000..fedeb0764 --- /dev/null +++ b/iguana/tests/creategtx @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"DEX\",\"method\":\"createrawtransaction\",\"params\":[[], {\"data\":\"deadbeef\"}] }" + diff --git a/iguana/tests/createrawtransactionA b/iguana/tests/createrawtransactionA new file mode 100755 index 000000000..9673ce27e --- /dev/null +++ b/iguana/tests/createrawtransactionA @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"createrawtransaction\",\"params\":[[{\"txid\":\"e8a0cc971e769de1fcf9d4abb734acb9ab4ab7f44d9eb7d9cd96707b847dd1f6\",\"vout\":0}], [{\"RAoMou7euzvDwa9dQwjrNB5A41hrAWgvBt\":0.01,\"RV37MfeBD1QTeoLHteab3j4mFVrsSaGMJx\":0.0093}]] }" + diff --git a/iguana/tests/createrawtransactionT b/iguana/tests/createrawtransactionT new file mode 100755 index 000000000..1e48c0e7f --- /dev/null +++ b/iguana/tests/createrawtransactionT @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"createrawtransaction\",\"params\":[[{\"txid\":\"2196c07f71f206728301b03ffbffb7fd383744d03c1a3e0a1e03b6fb9ffd4ece\",\"vout\":1}], {\"1E4EadLDvqRWgSPRLqTM5YXefdaxsPPZVs\":0.009}] }" diff --git a/iguana/tests/createrelay b/iguana/tests/createrelay new file mode 100755 index 000000000..1ed85c205 --- /dev/null +++ b/iguana/tests/createrelay @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:14632" --data "{\"method\":\"createrelay\",\"params\":[\"ipaddr\", \"secp\", \"curve25519\"] }" + diff --git a/iguana/tests/d b/iguana/tests/d new file mode 100755 index 000000000..feb7a8e97 --- /dev/null +++ b/iguana/tests/d @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"method\":\"decoderawtransaction\",\"params\":[\"010000009049a757019cb804dc1c70059d45c8d135bd630b2be9fcd27dd6c9d5510aec0d25e43f734b01000000834730440220777a24cf3b508571eeb597c3c8055dbf84e5a2bd17ff574a6fab7b258c10a37902200241979f977098b6691572642251bdc8f5737ec2fe7c20e95871774fb0e675200121020ce8ffc263769bfa15579b2757873ea5690107acfafb6dc1b77cd7057ac3834900000000000000000000000000000000000000000000000000ffffffff028096980000000000475221021193f3676d50b15b51a386af7a93bac569a8a71536cb3f41775cc1906771e97121032991f9c5088fca3d839c1971889c2f671d98551af2386c89628ea49f7c0b0df552ae00947604000000001976a91421e112f4211cbc612bc5f3de86acf0017b88b67d88ac00000000\", 0]}" diff --git a/iguana/tests/decodegtx b/iguana/tests/decodegtx new file mode 100755 index 000000000..54f389941 --- /dev/null +++ b/iguana/tests/decodegtx @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"DEX\",\"method\":\"decoderawtransaction\",\"params\":[\"01000000018efaaa9bdf615b126eb7c84aad2b2dfa3517cd885d35be4584cceec61f619d0a0000000001014c68630405c5a357b1752102a9669e63ef1ab04913615c2f3887ea3584f81e5f08feee9535b19ab3739d8afdac67a914f0a979f6abfb2f9e2e76b96b9252307d3b873f5088210398a4cb9f6ea7c52a4e27455028a95e2e4e397a110fb75f072c2c58a8bdcbf4baac68510000000001db390000000000001976a914b7128d2ee837cf03e30a2c0e3e0181f7b9669bb688ac05c5a357\"]}" diff --git a/iguana/tests/decoderawtransaction b/iguana/tests/decoderawtransaction index d39a4f0c8..8a4671500 100755 --- a/iguana/tests/decoderawtransaction +++ b/iguana/tests/decoderawtransaction @@ -1 +1 @@ -curl --url "http://127.0.0.1:7778" --data "{\"method\":\"decoderawtransaction\",\"params\":[\"0100000095f4265701f6d17d847b7096cdd9b79e4df4b74aabb9ac34b7abd4f9fce19d761e97cca0e8000000006b483045022100929efad52915fc1033f5266eb7e9b7b8d55422894aabba1a0d5deda8ccf591d10220674776a3c760b3ad6972f42fb355bc0552df9f7c95d04ef9977b825171c94d37012102d14a195654f536df6dfe5a38278d1b470d00f17de78eeb5ce9e9eea9edb2c212ffffffff0240420f00000000001976a91410acba3a841fae68aba4b5ff162714c493bcc04e88acd0300e00000000001976a914d8b8c039206af6cec82bca950f592801e62808cb88ac00000000\"]}" +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"method\":\"decoderawtransaction\",\"params\":[\"010000000f0ea95701466304197095eeceb34a9b8cc57b34a9d069f37cb3c0aedcb71c5f3c0858afd50000000090004730440220626010de8205712edb16560410fb2e99c1c602aa25d77575471321c62c1b33e30220684ab1e4037e1b38c25fb1f175e07a54621ffca4e37659019dcfa1d7ac463b0e0147304402205f907d97d9b229ce660f4bf13382e04132e042d49d1ea043a3043ea76e4c6f710220177f69d1be52744c0f55b2be106575159efffd5c8d84ca85b2cb0741d022fbaa01ffffffff01706f9800000000001976a91454a752f0d71b89d7c014ed0be29ca231c9546f9f88ac00000000\", 1]}" diff --git a/iguana/tests/decoderawtransactionB b/iguana/tests/decoderawtransactionB index 5338b3df9..695f44691 100755 --- a/iguana/tests/decoderawtransactionB +++ b/iguana/tests/decoderawtransactionB @@ -1 +1 @@ -curl --url "http://127.0.0.1:7778" --data "{\"method\":\"decoderawtransaction\",\"params\":[\"01000000dc4f24570156bb006164173811be6647f68f9a46eab4322e6fdef816aeb3e71e419ca49bfe180000006a473044022027e0e1983c88832e9adcad681692e905333f32905553bedc6df2fcacc250574d0220259aa91c7fb0378561c37477c2b5e7872b5c9a1daababe087945639fe79593e0012102d14a195654f536df6dfe5a38278d1b470d00f17de78eeb5ce9e9eea9edb2c212ffffffff01588c0200000000001976a914d8b8c039206af6cec82bca950f592801e62808cb88ac00000000\"]}" +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"method\":\"decoderawtransaction\",\"params\":[\"01000000e37486570105cbd4d0058c3d7842966917456cbb4202ba90489abaa142dc093755b10a077d010000000100ffffffff0200e1f505000000004752210211a23a9bbbb43784b0b0198bab1cc6dbf2bab6cf3dd96a428ec6916267c80e70210372e08a8a353ba0190f513b3980d8229f4afecddbf014052199799875a924e56752ae50677235000000001976a914c210f6711e98fe9971757ede2b2dcb0507f3f25e88ac00000000\"]}" diff --git a/iguana/tests/encryptwallet2 b/iguana/tests/encryptwallet2 new file mode 100755 index 000000000..36fd9d69e --- /dev/null +++ b/iguana/tests/encryptwallet2 @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"encryptwallet\",\"passphrase\":\"test2\"}" diff --git a/iguana/tests/events b/iguana/tests/events new file mode 100755 index 000000000..a51fc4cf7 --- /dev/null +++ b/iguana/tests/events @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"exchange\":\"bitcoin\",\"method\":\"events\",\"base\":\"BTCD\",\"rel\":\"BTC\"}" diff --git a/iguana/tests/eventsV b/iguana/tests/eventsV new file mode 100755 index 000000000..975f88de8 --- /dev/null +++ b/iguana/tests/eventsV @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"exchange\":\"bitcoin\",\"method\":\"events\",\"base\":\"VPN\",\"rel\":\"BTC\"}" diff --git a/iguana/tests/firstheight b/iguana/tests/firstheight new file mode 100755 index 000000000..d5b181d7c --- /dev/null +++ b/iguana/tests/firstheight @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"timeout\":20000,\"agent\":\"basilisk\",\"method\":\"balances\",\"vals\":{\"minconf\":1,\"history\":3,\"firstheight\":1181452}}" diff --git a/iguana/tests/genesis b/iguana/tests/genesis new file mode 100755 index 000000000..01bcfd446 --- /dev/null +++ b/iguana/tests/genesis @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"basilisk\",\"method\":\"geckogenesis\"}" diff --git a/iguana/tests/get b/iguana/tests/get new file mode 100755 index 000000000..fa1f49360 --- /dev/null +++ b/iguana/tests/get @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"basilisk\",\"method\":\"getmessage\",\"vals\":{\"channel\":12345,\"msgid\":1}}" diff --git a/iguana/tests/getaddressesbyaccount b/iguana/tests/getaddressesbyaccount new file mode 100755 index 000000000..1ec011ea1 --- /dev/null +++ b/iguana/tests/getaddressesbyaccount @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"agent\":\"bitcoinrpc\",\"method\":\"getaddressesbyaccount\",\"account\":\"*\"}" diff --git a/iguana/tests/getbalance b/iguana/tests/getbalance new file mode 100755 index 000000000..5256439f2 --- /dev/null +++ b/iguana/tests/getbalance @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"getbalance\",\"params\":[\"RSyKVKNxrSDc1Vwvh4guYb9ZDEpvMFz2rm\"]}" diff --git a/iguana/tests/getbalanceall b/iguana/tests/getbalanceall new file mode 100755 index 000000000..86b6fe557 --- /dev/null +++ b/iguana/tests/getbalanceall @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"getbalance\",\"params\":[\"*\"]}" diff --git a/iguana/tests/getblock b/iguana/tests/getblock new file mode 100755 index 000000000..b051ba6a5 --- /dev/null +++ b/iguana/tests/getblock @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:14632" --data "{\"method\":\"getblock\",\"params\":[\"0000044966f40703b516c5af180582d53f783bfd319bb045e2dc3e05ea695d46\"]}" diff --git a/iguana/tests/getblockcount b/iguana/tests/getblockcount new file mode 100755 index 000000000..ca9ec4b9f --- /dev/null +++ b/iguana/tests/getblockcount @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:14632" --data "{\"method\":\"getblockcount\",\"params\":[]}" diff --git a/iguana/tests/getblockhash b/iguana/tests/getblockhash new file mode 100755 index 000000000..9537a87d3 --- /dev/null +++ b/iguana/tests/getblockhash @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:14632" --data "{\"method\":\"getblockhash\",\"params\":[0]}" diff --git a/iguana/tests/getconnectioncount b/iguana/tests/getconnectioncount new file mode 100755 index 000000000..efcec901f --- /dev/null +++ b/iguana/tests/getconnectioncount @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:14632" --data "{\"method\":\"getconnectioncount\",\"params\":[]}" diff --git a/iguana/tests/getdifficulty b/iguana/tests/getdifficulty new file mode 100755 index 000000000..06f406304 --- /dev/null +++ b/iguana/tests/getdifficulty @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:14632" --data "{\"method\":\"getdifficulty\",\"params\":[]}" diff --git a/iguana/tests/getinfo b/iguana/tests/getinfo new file mode 100755 index 000000000..755bee524 --- /dev/null +++ b/iguana/tests/getinfo @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"getinfo\",\"params\":[]}" diff --git a/iguana/tests/getmessage b/iguana/tests/getmessage new file mode 100755 index 000000000..571382e44 --- /dev/null +++ b/iguana/tests/getmessage @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"basilisk\",\"method\":\"getmessage\",\"vals\":{\"channel\":5784900,\"width\":60}}" diff --git a/iguana/tests/getpeers b/iguana/tests/getpeers new file mode 100755 index 000000000..d7cb39eb3 --- /dev/null +++ b/iguana/tests/getpeers @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"SuperNET\",\"method\":\"getpeers\",\"activecoin\":\"BTCD\"}" diff --git a/iguana/tests/getreceivedbyaddress b/iguana/tests/getreceivedbyaddress index 675193ac3..6f652200a 100755 --- a/iguana/tests/getreceivedbyaddress +++ b/iguana/tests/getreceivedbyaddress @@ -1 +1 @@ -curl --url "http://127.0.0.1:7778" --data "{\"method\":\"getreceivedbyaddress\",\"params\":[\"17outUgtsnLkguDuXm14tcQ7dMbdD8KZGK\"]}" +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"getreceivedbyaddress\",\"params\":[\"RL1tyXPK5NzT1d4upgcHnujgG5v3xjLaYC\"]}" diff --git a/iguana/tests/gettransaction b/iguana/tests/gettransaction index 4564ba314..a03d7fd7a 100755 --- a/iguana/tests/gettransaction +++ b/iguana/tests/gettransaction @@ -1,2 +1,2 @@ -curl --url "http://127.0.0.1:7778" --data "{\"method\":\"gettransaction\",\"params\":[\"fe9ba49c411ee7b3ae16f8de6f2e32b4ea469a8ff64766be113817646100bb56\"]}" +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"gettransaction\",\"coin\":\"BTCD\",\"params\":[\"f19aa5e469be3864030f44f184638d55ddc6bf66c7eecf1697c22092421901e7\"]}" diff --git a/iguana/tests/gtx b/iguana/tests/gtx new file mode 100755 index 000000000..cc81e80df --- /dev/null +++ b/iguana/tests/gtx @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"basilisk\",\"method\":\"geckotx\",\"vals\":{\"chain\":\"InstantDEX\",\"symbol\":\"DEX\"},\"hexstr\":\"01000000c3e763570001000000000000000006056adeadbeef00000000\"}" diff --git a/iguana/tests/history b/iguana/tests/history new file mode 100755 index 000000000..0546e0f11 --- /dev/null +++ b/iguana/tests/history @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"timeout\":20000,\"agent\":\"basilisk\",\"method\":\"history\",\"vals\":{\"coin\":\"BTCD\"}}" diff --git a/iguana/tests/historyB b/iguana/tests/historyB new file mode 100755 index 000000000..7b63b6ee7 --- /dev/null +++ b/iguana/tests/historyB @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"timeout\":20000,\"agent\":\"basilisk\",\"method\":\"history\",\"vals\":{\"coin\":\"BTC\"}}" diff --git a/iguana/tests/historyS b/iguana/tests/historyS new file mode 100755 index 000000000..b4f745b8d --- /dev/null +++ b/iguana/tests/historyS @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"timeout\":20000,\"agent\":\"basilisk\",\"method\":\"balances\",\"vals\":{\"minconf\":1,\"history\":2}}" diff --git a/iguana/tests/historyU b/iguana/tests/historyU new file mode 100755 index 000000000..9f2dbf278 --- /dev/null +++ b/iguana/tests/historyU @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"timeout\":20000,\"agent\":\"basilisk\",\"method\":\"balances\",\"vals\":{\"minconf\":1,\"history\":1}}" diff --git a/iguana/tests/igget b/iguana/tests/igget new file mode 100755 index 000000000..f92792b80 --- /dev/null +++ b/iguana/tests/igget @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"getaccount\",\"params\":[\"RMd1Ek7bG7UknByTjfdDvJSXNUTahQKKWG\"]}" diff --git a/iguana/tests/igphrase b/iguana/tests/igphrase new file mode 100755 index 000000000..6f008031f --- /dev/null +++ b/iguana/tests/igphrase @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"walletpassphrase\",\"params\":[\"igtest\", 66600]}" diff --git a/iguana/tests/igset b/iguana/tests/igset new file mode 100755 index 000000000..529097447 --- /dev/null +++ b/iguana/tests/igset @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"setaccount\",\"params\":[\"RMd1Ek7bG7UknByTjfdDvJSXNUTahQKKWG\", \"igacct\"]}" diff --git a/iguana/tests/importprivkey b/iguana/tests/importprivkey index eaffafce9..26a53c9df 100755 --- a/iguana/tests/importprivkey +++ b/iguana/tests/importprivkey @@ -1 +1 @@ -curl --url "http://127.0.0.1:7778" --data "{\"method\":\"importprivkey\",\"params\":[\"UvBSu7PtUcGFeCd4fJdWSN6NKH4DPzmMoZtPn4Sb94Tj3CyXj9Fn\"]}" +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"importprivkey\",\"params\":[\"UvBSu7PtUcGFeCd4fJdWSN6NKH4DPzmMoZtPn4Sb94Tj3CyXj9Fn\", \"testing\"]}" diff --git a/iguana/tests/importprivkeyB b/iguana/tests/importprivkeyB index fea5c86cc..daf596641 100755 --- a/iguana/tests/importprivkeyB +++ b/iguana/tests/importprivkeyB @@ -1 +1 @@ -curl --url "http://127.0.0.1:7778" --data "{\"method\":\"importprivkey\",\"params\":[\"b81e824a58cefff953eb53e9743059d001be0f5cfeb7599fbdd6bd18dba6616c\"]}" +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"importprivkey\",\"params\":[\"Kzw1ordPLaxDqgn2Uz8UyjszcjyPsSM8a16CpHQ4DJF2DiVtFSX1\"]}" diff --git a/iguana/tests/incoming b/iguana/tests/incoming new file mode 100755 index 000000000..baceca9a8 --- /dev/null +++ b/iguana/tests/incoming @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"method\":\"incoming\",\"requestid\":1728286611}" diff --git a/iguana/tests/json_extract.c b/iguana/tests/json_extract.c new file mode 100644 index 000000000..60143e3a3 --- /dev/null +++ b/iguana/tests/json_extract.c @@ -0,0 +1,25 @@ +#include +#include +#include "../../includes/cJSON.h" +#include "../../crypto777/OS_portable.h" + +int32_t main(int32_t argc,char **argv) +{ + cJSON *filejson; char *fname,*filestr,*field; long filesize; + if ( argc > 2 ) + { + fname = argv[1]; + field = argv[2]; + if ( (filestr= OS_filestr(&filesize,fname)) != 0 ) + { + if ( (filejson= cJSON_Parse(filestr)) != 0 ) + { + if ( jstr(filejson,field) != 0 ) + printf("%s\n",jstr(filejson,field)); + free_json(filejson); + } else fprintf(stderr,"cant parse.(%s)\n",filestr); + free(filestr); + } else fprintf(stderr,"cant load (%s)\n",fname); + } else fprintf(stderr,"argc.%d fname.(%s) error\n",argc,argv[1]); +} + diff --git a/iguana/tests/json_extracta.c b/iguana/tests/json_extracta.c new file mode 100644 index 000000000..1283f061d --- /dev/null +++ b/iguana/tests/json_extracta.c @@ -0,0 +1,25 @@ +#include +#include +#include "../../includes/cJSON.h" +#include "../../crypto777/OS_portable.h" + +int32_t main(int32_t argc,char **argv) +{ + cJSON *filejson; char *fname,*filestr,*field; long filesize; int32_t n; + if ( argc > 2 ) + { + fname = argv[1]; + field = argv[2]; + if ( (filestr= OS_filestr(&filesize,fname)) != 0 ) + { + if ( (filejson= cJSON_Parse(filestr)) != 0 ) + { + if ( jarray(&n,filejson,field) != 0 ) + printf("%s\n",jprint(jobj(filejson,field),0)); + free_json(filejson); + } else fprintf(stderr,"cant parse.(%s)\n",filestr); + free(filestr); + } else fprintf(stderr,"cant load (%s)\n",fname); + } else fprintf(stderr,"argc.%d fname.(%s) error\n",argc,argv[1]); +} + diff --git a/iguana/tests/json_extractd.c b/iguana/tests/json_extractd.c new file mode 100644 index 000000000..8c0cca0e1 --- /dev/null +++ b/iguana/tests/json_extractd.c @@ -0,0 +1,25 @@ +#include +#include +#include "../../includes/cJSON.h" +#include "../../crypto777/OS_portable.h" + +int32_t main(int32_t argc,char **argv) +{ + cJSON *filejson; char *fname,*filestr,*field; long filesize; + if ( argc > 2 ) + { + fname = argv[1]; + field = argv[2]; + if ( (filestr= OS_filestr(&filesize,fname)) != 0 ) + { + if ( (filejson= cJSON_Parse(filestr)) != 0 ) + { + if ( jobj(filejson,field) != 0 ) + printf("%.8f\n",jdouble(filejson,field)); + free_json(filejson); + } else fprintf(stderr,"cant parse.(%s)\n",filestr); + free(filestr); + } else fprintf(stderr,"cant load (%s)\n",fname); + } else fprintf(stderr,"argc.%d fname.(%s) error\n",argc,argv[1]); +} + diff --git a/iguana/tests/json_extracti.c b/iguana/tests/json_extracti.c new file mode 100644 index 000000000..6b300e150 --- /dev/null +++ b/iguana/tests/json_extracti.c @@ -0,0 +1,25 @@ +#include +#include +#include "../../includes/cJSON.h" +#include "../../crypto777/OS_portable.h" + +int32_t main(int32_t argc,char **argv) +{ + cJSON *filejson; char *fname,*filestr,*field; long filesize; + if ( argc > 2 ) + { + fname = argv[1]; + field = argv[2]; + if ( (filestr= OS_filestr(&filesize,fname)) != 0 ) + { + if ( (filejson= cJSON_Parse(filestr)) != 0 ) + { + if ( jobj(filejson,field) != 0 ) + printf("%d\n",jint(filejson,field)); + free_json(filejson); + } else fprintf(stderr,"cant parse.(%s)\n",filestr); + free(filestr); + } else fprintf(stderr,"cant load (%s)\n",fname); + } else fprintf(stderr,"argc.%d fname.(%s) error\n",argc,argv[1]); +} + diff --git a/iguana/tests/listreceivedbyaccount b/iguana/tests/listreceivedbyaccount new file mode 100755 index 000000000..3d9771fdf --- /dev/null +++ b/iguana/tests/listreceivedbyaccount @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"method\":\"listreceivedbyaccount\",\"params\":[1, 9999999, [\"RUXwXF37SMA63vL4bUPnytP3KUwp69PCVv\"]]}" diff --git a/iguana/tests/listtransactions b/iguana/tests/listtransactions new file mode 100755 index 000000000..0b719dc7f --- /dev/null +++ b/iguana/tests/listtransactions @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"method\":\"listtransactions\",\"params\":[1, 9999999, [\"RUXwXF37SMA63vL4bUPnytP3KUwp69PCVv\"]]}" diff --git a/iguana/tests/listunspent b/iguana/tests/listunspent index fa94582f6..e5ce5c0d9 100755 --- a/iguana/tests/listunspent +++ b/iguana/tests/listunspent @@ -1 +1 @@ -curl --url "http://127.0.0.1:7778" --data "{\"method\":\"listunspent\",\"params\":[\"185oPvxk7SxxSAe121r8pmFjQEHZNREYUc\"]}" +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"method\":\"listunspent\",\"params\":[1, 9999999, [\"RThtXup6Zo7LZAi8kRWgjAyi1s4u6U9Cpf\"]]}" diff --git a/iguana/tests/listunspentB b/iguana/tests/listunspentB new file mode 100755 index 000000000..e7fbcc744 --- /dev/null +++ b/iguana/tests/listunspentB @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"listunspent\",\"params\":[1, 9999999, [\"RVQV5spiARDTqfwBCxstWnMbrT6Q8mhRYz\"]]}" diff --git a/iguana/tests/loop b/iguana/tests/loop new file mode 100755 index 000000000..cae5818c0 --- /dev/null +++ b/iguana/tests/loop @@ -0,0 +1,7 @@ +pkill iguana +while true +do +../../agents/iguana +sleep 3 +done + diff --git a/iguana/tests/loop2 b/iguana/tests/loop2 new file mode 100755 index 000000000..b23fc5b8d --- /dev/null +++ b/iguana/tests/loop2 @@ -0,0 +1,15 @@ +cd .. +pkill iguana +./m_LP +while true +do ../agents/iguana & +sleep 10 +coins/btcd +tests/wp +tests/myip2; +tests/addnode; +coins/genbtc +wait +sleep 100 +done + diff --git a/iguana/tests/ltest b/iguana/tests/ltest new file mode 100755 index 000000000..76fd2fe8f --- /dev/null +++ b/iguana/tests/ltest @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"listunspent\",\"params\":[1, 9999999, [\"RDxggCVF42Ds19DLNSjC6e3BaFk4ScCb2T\"]]}" diff --git a/iguana/tests/make_jsoncmp b/iguana/tests/make_jsoncmp index 9e8b79ce8..26548619e 100755 --- a/iguana/tests/make_jsoncmp +++ b/iguana/tests/make_jsoncmp @@ -1 +1,5 @@ gcc -o jsoncmp jsoncmp.c ../../agents/libcrypto777.a -pthread -lm +gcc -o json_extract json_extract.c ../../agents/libcrypto777.a -pthread -lm +gcc -o json_extracti json_extracti.c ../../agents/libcrypto777.a -pthread -lm +gcc -o json_extractd json_extractd.c ../../agents/libcrypto777.a -pthread -lm +gcc -o json_extracta json_extracta.c ../../agents/libcrypto777.a -pthread -lm diff --git a/iguana/tests/myip2 b/iguana/tests/myip2 new file mode 100755 index 000000000..b8a2f0f00 --- /dev/null +++ b/iguana/tests/myip2 @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"SuperNET\",\"method\":\"myipaddr\",\"ipaddr\":\"5.9.102.210\"}" diff --git a/iguana/tests/myip4 b/iguana/tests/myip4 new file mode 100755 index 000000000..145bd98e7 --- /dev/null +++ b/iguana/tests/myip4 @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"SuperNET\",\"method\":\"myipaddr\",\"ipaddr\":\"78.47.196.146\"}" diff --git a/iguana/tests/new b/iguana/tests/new new file mode 100755 index 000000000..59ff44b82 --- /dev/null +++ b/iguana/tests/new @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"basilisk\",\"method\":\"newgeckochain\",\"vals\":{\"RELAY\":1,\"blocktime\":10,\"chain\":\"InstantDEX\",\"symbol\":\"DEX\"}}" diff --git a/iguana/tests/newtest b/iguana/tests/newtest new file mode 100755 index 000000000..ba46a7827 --- /dev/null +++ b/iguana/tests/newtest @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"basilisk\",\"method\":\"newgeckochain\",\"vals\":{\"RELAY\":1,\"blocktime\":10,\"chain\":\"testchain\",\"symbol\":\"test\"}}" diff --git a/iguana/tests/openorders b/iguana/tests/openorders new file mode 100755 index 000000000..8f3e4db9d --- /dev/null +++ b/iguana/tests/openorders @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"exchange\":\"bitcoin\",\"method\":\"openorders\",\"base\":\"BTCD\",\"rel\":\"BTC\"}" diff --git a/iguana/tests/orderbook b/iguana/tests/orderbook new file mode 100755 index 000000000..b5799ba80 --- /dev/null +++ b/iguana/tests/orderbook @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"allfields\":1,\"agent\":\"InstantDEX\",\"exchange\":\"bitcoin\",\"method\":\"orderbook\",\"base\":\"BTCD\",\"rel\":\"BTC\"}" diff --git a/iguana/tests/paxrates b/iguana/tests/paxrates new file mode 100755 index 000000000..e37b7f985 --- /dev/null +++ b/iguana/tests/paxrates @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"rates\",\"quotes\":[\"USD\", \"EUR\", \"JPY\", \"GBP\", \"AUD\", \"CAD\", \"CHF\", \"NZD\", \"CNY\", \"RUB\", \"MXN\", \"BRL\", \"INR\", \"HKD\", \"TRY\", \"ZAR\", \"PLN\", \"NOK\", \"SEK\", \"DKK\", \"CZK\", \"HUF\", \"ILS\", \"KRW\", \"MYR\", \"PHP\", \"RON\", \"SGD\", \"THB\", \"BGN\", \"IDR\", \"HRK\"]}" diff --git a/iguana/tests/peers.txt b/iguana/tests/peers.txt new file mode 100644 index 000000000..76848e4b4 --- /dev/null +++ b/iguana/tests/peers.txt @@ -0,0 +1,974 @@ +[ + { + "addr" : "85.25.217.233:14631", + "services" : "00000001", + "lastsend" : 1470702663, + "lastrecv" : 1470702649, + "conntime" : 1467588887, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : false, + "startingheight" : 1175995, + "banscore" : 0 + }, + { + "addr" : "65.15.37.140:57568", + "services" : "00000001", + "lastsend" : 1470702664, + "lastrecv" : 1470702647, + "conntime" : 1468327042, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1188921, + "banscore" : 0 + }, + { + "addr" : "62.75.145.171:14631", + "services" : "00000001", + "lastsend" : 1470702664, + "lastrecv" : 1470702658, + "conntime" : 1469977194, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : false, + "startingheight" : 1219477, + "banscore" : 0 + }, + { + "addr" : "176.9.13.13:14631", + "services" : "00000001", + "lastsend" : 1470702646, + "lastrecv" : 1470702647, + "conntime" : 1469977357, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : false, + "startingheight" : 1219481, + "banscore" : 0 + }, + { + "addr" : "88.198.15.19:14631", + "services" : "00000001", + "lastsend" : 1470702648, + "lastrecv" : 1470702647, + "conntime" : 1469977602, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : false, + "startingheight" : 1219485, + "banscore" : 0 + }, + { + "addr" : "51.255.38.28:34066", + "services" : "00000001", + "lastsend" : 1470702648, + "lastrecv" : 1470702647, + "conntime" : 1469978213, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1219498, + "banscore" : 0 + }, + { + "addr" : "121.108.241.247:14631", + "services" : "00000001", + "lastsend" : 1470702648, + "lastrecv" : 1470702652, + "conntime" : 1469978358, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : false, + "startingheight" : 1219503, + "banscore" : 0 + }, + { + "addr" : "82.229.201.131:49263", + "services" : "00000001", + "lastsend" : 1470702648, + "lastrecv" : 1470702653, + "conntime" : 1469978392, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1219504, + "banscore" : 0 + }, + { + "addr" : "162.13.4.69:14631", + "services" : "00000001", + "lastsend" : 1470702648, + "lastrecv" : 1470702650, + "conntime" : 1469978896, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : false, + "startingheight" : 1219517, + "banscore" : 0 + }, + { + "addr" : "78.226.160.96:45153", + "services" : "00000001", + "lastsend" : 1470702648, + "lastrecv" : 1470702649, + "conntime" : 1469980802, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1219549, + "banscore" : 0 + }, + { + "addr" : "115.28.42.60:36021", + "services" : "00000001", + "lastsend" : 1470702648, + "lastrecv" : 1470702647, + "conntime" : 1469987166, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1219681, + "banscore" : 0 + }, + { + "addr" : "178.62.185.131:43074", + "services" : "00000001", + "lastsend" : 1470702648, + "lastrecv" : 1470702648, + "conntime" : 1469993286, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1219793, + "banscore" : 0 + }, + { + "addr" : "167.114.249.196:56817", + "services" : "00000001", + "lastsend" : 1470702648, + "lastrecv" : 1470702661, + "conntime" : 1469995061, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1219831, + "banscore" : 0 + }, + { + "addr" : "81.181.155.53:52714", + "services" : "00000001", + "lastsend" : 1470702648, + "lastrecv" : 1470702649, + "conntime" : 1469997941, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1219894, + "banscore" : 0 + }, + { + "addr" : "76.169.236.235:43778", + "services" : "00000001", + "lastsend" : 1470702649, + "lastrecv" : 1470702648, + "conntime" : 1470018321, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1220359, + "banscore" : 0 + }, + { + "addr" : "67.165.77.192:51216", + "services" : "00000001", + "lastsend" : 1470702649, + "lastrecv" : 1470702650, + "conntime" : 1470035323, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1220254, + "banscore" : 0 + }, + { + "addr" : "75.130.163.51:57566", + "services" : "00000001", + "lastsend" : 1470702649, + "lastrecv" : 1470702647, + "conntime" : 1470051591, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1221047, + "banscore" : 0 + }, + { + "addr" : "72.55.148.203:54752", + "services" : "00000001", + "lastsend" : 1470702649, + "lastrecv" : 1470702647, + "conntime" : 1470107466, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1222176, + "banscore" : 0 + }, + { + "addr" : "96.127.136.18:38601", + "services" : "00000001", + "lastsend" : 1470702649, + "lastrecv" : 1470702653, + "conntime" : 1470115380, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1222317, + "banscore" : 0 + }, + { + "addr" : "88.198.53.194:55692", + "services" : "00000001", + "lastsend" : 1470702649, + "lastrecv" : 1470702647, + "conntime" : 1470126103, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1222512, + "banscore" : 0 + }, + { + "addr" : "63.247.147.166:50823", + "services" : "00000001", + "lastsend" : 1470702650, + "lastrecv" : 1470702649, + "conntime" : 1470126764, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1222528, + "banscore" : 0 + }, + { + "addr" : "88.206.186.58:37299", + "services" : "00000001", + "lastsend" : 1470702650, + "lastrecv" : 1470702648, + "conntime" : 1470146882, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1222884, + "banscore" : 0 + }, + { + "addr" : "217.8.62.188:48160", + "services" : "00000001", + "lastsend" : 1470702650, + "lastrecv" : 1470702647, + "conntime" : 1470161200, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1223123, + "banscore" : 0 + }, + { + "addr" : "46.231.137.186:62276", + "services" : "00000001", + "lastsend" : 1470702650, + "lastrecv" : 1470702647, + "conntime" : 1470164568, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1223173, + "banscore" : 0 + }, + { + "addr" : "217.215.190.134:52487", + "services" : "00000001", + "lastsend" : 1470702651, + "lastrecv" : 1470702647, + "conntime" : 1470188460, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1223624, + "banscore" : 0 + }, + { + "addr" : "2.86.63.69:50332", + "services" : "00000001", + "lastsend" : 1470702651, + "lastrecv" : 1470702117, + "conntime" : 1470190048, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1221833, + "banscore" : 0 + }, + { + "addr" : "59.147.43.232:51236", + "services" : "00000001", + "lastsend" : 1470702651, + "lastrecv" : 1470702649, + "conntime" : 1470212486, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1224028, + "banscore" : 0 + }, + { + "addr" : "104.42.224.48:1336", + "services" : "00000001", + "lastsend" : 1470702651, + "lastrecv" : 1470702650, + "conntime" : 1470248520, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1224679, + "banscore" : 0 + }, + { + "addr" : "24.168.17.50:49185", + "services" : "00000001", + "lastsend" : 1470702651, + "lastrecv" : 1470702653, + "conntime" : 1470250619, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1216084, + "banscore" : 0 + }, + { + "addr" : "173.65.129.85:54180", + "services" : "00000001", + "lastsend" : 1470702651, + "lastrecv" : 1470702647, + "conntime" : 1470261818, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1224924, + "banscore" : 0 + }, + { + "addr" : "84.119.62.223:14631", + "services" : "00000001", + "lastsend" : 1470702652, + "lastrecv" : 1470702647, + "conntime" : 1470308221, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : false, + "startingheight" : 1225817, + "banscore" : 0 + }, + { + "addr" : "59.147.43.232:51139", + "services" : "00000001", + "lastsend" : 1470702652, + "lastrecv" : 1470702649, + "conntime" : 1470349631, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1226425, + "banscore" : 0 + }, + { + "addr" : "2.239.61.146:14631", + "services" : "00000001", + "lastsend" : 1470702652, + "lastrecv" : 1470702653, + "conntime" : 1470349644, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : false, + "startingheight" : 1226609, + "banscore" : 0 + }, + { + "addr" : "176.28.45.179:63639", + "services" : "00000001", + "lastsend" : 1470702652, + "lastrecv" : 1470702647, + "conntime" : 1470370607, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1227008, + "banscore" : 0 + }, + { + "addr" : "73.211.90.130:41871", + "services" : "00000001", + "lastsend" : 1470702653, + "lastrecv" : 1470702647, + "conntime" : 1470390498, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1227384, + "banscore" : 0 + }, + { + "addr" : "185.48.78.78:49690", + "services" : "00000001", + "lastsend" : 1470702653, + "lastrecv" : 1470702648, + "conntime" : 1470396672, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1227500, + "banscore" : 0 + }, + { + "addr" : "77.21.104.176:56725", + "services" : "00000001", + "lastsend" : 1470702653, + "lastrecv" : 1470702647, + "conntime" : 1470409137, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 167660, + "banscore" : 0 + }, + { + "addr" : "46.253.169.134:57623", + "services" : "00000001", + "lastsend" : 1470702653, + "lastrecv" : 1470702649, + "conntime" : 1470425052, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1118641, + "banscore" : 0 + }, + { + "addr" : "163.172.156.107:14631", + "services" : "00000001", + "lastsend" : 1470702654, + "lastrecv" : 1470702648, + "conntime" : 1470431176, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : false, + "startingheight" : 1228162, + "banscore" : 0 + }, + { + "addr" : "74.120.222.234:63181", + "services" : "00000001", + "lastsend" : 1470702654, + "lastrecv" : 1470702647, + "conntime" : 1470432991, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1228200, + "banscore" : 0 + }, + { + "addr" : "192.99.233.217:15888", + "services" : "00000001", + "lastsend" : 1470702654, + "lastrecv" : 1470702647, + "conntime" : 1470455175, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1228648, + "banscore" : 0 + }, + { + "addr" : "162.255.117.105:62461", + "services" : "00000001", + "lastsend" : 1470702654, + "lastrecv" : 1470702647, + "conntime" : 1470459314, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1228733, + "banscore" : 0 + }, + { + "addr" : "188.166.91.37:39774", + "services" : "00000001", + "lastsend" : 1470702654, + "lastrecv" : 1470702610, + "conntime" : 1470461455, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1228775, + "banscore" : 0 + }, + { + "addr" : "149.56.122.72:14631", + "services" : "00000001", + "lastsend" : 1470702655, + "lastrecv" : 1470702647, + "conntime" : 1470461716, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : false, + "startingheight" : 1228778, + "banscore" : 0 + }, + { + "addr" : "71.1.13.122:62242", + "services" : "00000001", + "lastsend" : 1470702655, + "lastrecv" : 1470702650, + "conntime" : 1470462024, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1228786, + "banscore" : 0 + }, + { + "addr" : "88.113.76.138:60913", + "services" : "00000001", + "lastsend" : 1470702655, + "lastrecv" : 1470702649, + "conntime" : 1470484989, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1229269, + "banscore" : 0 + }, + { + "addr" : "81.205.30.207:50538", + "services" : "00000001", + "lastsend" : 1470702656, + "lastrecv" : 1470702647, + "conntime" : 1470519933, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1229188, + "banscore" : 0 + }, + { + "addr" : "203.189.127.54:49495", + "services" : "00000001", + "lastsend" : 1470702656, + "lastrecv" : 1470702653, + "conntime" : 1470557228, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1230826, + "banscore" : 0 + }, + { + "addr" : "68.190.213.46:50643", + "services" : "00000001", + "lastsend" : 1470702656, + "lastrecv" : 1470702647, + "conntime" : 1470568861, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1231075, + "banscore" : 0 + }, + { + "addr" : "98.202.147.55:50064", + "services" : "00000001", + "lastsend" : 1470702656, + "lastrecv" : 1470702647, + "conntime" : 1470579239, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1231295, + "banscore" : 0 + }, + { + "addr" : "89.212.19.49:58924", + "services" : "00000001", + "lastsend" : 1470702656, + "lastrecv" : 1470702664, + "conntime" : 1470595350, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1231645, + "banscore" : 0 + }, + { + "addr" : "162.210.92.46:37304", + "services" : "00000001", + "lastsend" : 1470702657, + "lastrecv" : 1470702650, + "conntime" : 1470601796, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1231787, + "banscore" : 0 + }, + { + "addr" : "115.70.19.28:50995", + "services" : "00000001", + "lastsend" : 1470702613, + "lastrecv" : 1470702646, + "conntime" : 1470602815, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1231811, + "banscore" : 0 + }, + { + "addr" : "68.43.220.127:3385", + "services" : "00000001", + "lastsend" : 1470702657, + "lastrecv" : 1470702649, + "conntime" : 1470605657, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1231872, + "banscore" : 0 + }, + { + "addr" : "79.227.171.148:60444", + "services" : "00000001", + "lastsend" : 1470702657, + "lastrecv" : 1470702649, + "conntime" : 1470624294, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1232290, + "banscore" : 0 + }, + { + "addr" : "68.46.103.181:51126", + "services" : "00000001", + "lastsend" : 1470702658, + "lastrecv" : 1470702647, + "conntime" : 1470629436, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1232408, + "banscore" : 0 + }, + { + "addr" : "98.207.117.83:51529", + "services" : "00000001", + "lastsend" : 1470702658, + "lastrecv" : 1470702647, + "conntime" : 1470644791, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1232745, + "banscore" : 0 + }, + { + "addr" : "79.200.255.204:4619", + "services" : "00000001", + "lastsend" : 1470702658, + "lastrecv" : 1470702647, + "conntime" : 1470648995, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 953802, + "banscore" : 0 + }, + { + "addr" : "82.8.59.60:60459", + "services" : "00000001", + "lastsend" : 1470702658, + "lastrecv" : 1470702648, + "conntime" : 1470650104, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1232858, + "banscore" : 0 + }, + { + "addr" : "71.241.204.215:50697", + "services" : "00000001", + "lastsend" : 1470702658, + "lastrecv" : 1470702216, + "conntime" : 1470652320, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1058787, + "banscore" : 0 + }, + { + "addr" : "108.247.198.39:61254", + "services" : "00000001", + "lastsend" : 1470702659, + "lastrecv" : 1470702647, + "conntime" : 1470659265, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1233061, + "banscore" : 0 + }, + { + "addr" : "156.57.141.221:51476", + "services" : "00000001", + "lastsend" : 1470702659, + "lastrecv" : 1470702648, + "conntime" : 1470661208, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1233102, + "banscore" : 0 + }, + { + "addr" : "92.26.168.113:14631", + "services" : "00000001", + "lastsend" : 1470702659, + "lastrecv" : 1470702650, + "conntime" : 1470661239, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : false, + "startingheight" : 1233104, + "banscore" : 0 + }, + { + "addr" : "71.53.157.49:14631", + "services" : "00000001", + "lastsend" : 1470702659, + "lastrecv" : 1470702649, + "conntime" : 1470664598, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : false, + "startingheight" : 1233179, + "banscore" : 0 + }, + { + "addr" : "68.45.147.145:14631", + "services" : "00000001", + "lastsend" : 1470702660, + "lastrecv" : 1470702649, + "conntime" : 1470670535, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : false, + "startingheight" : 1233309, + "banscore" : 0 + }, + { + "addr" : "79.54.185.53:59661", + "services" : "00000001", + "lastsend" : 1470702660, + "lastrecv" : 1470702647, + "conntime" : 1470674560, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1233387, + "banscore" : 0 + }, + { + "addr" : "110.202.11.148:63824", + "services" : "00000001", + "lastsend" : 1470702660, + "lastrecv" : 1470702659, + "conntime" : 1470678623, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1233468, + "banscore" : 0 + }, + { + "addr" : "91.82.171.9:62108", + "services" : "00000001", + "lastsend" : 1470702661, + "lastrecv" : 1470702648, + "conntime" : 1470679101, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1233476, + "banscore" : 0 + }, + { + "addr" : "74.14.104.167:18505", + "services" : "00000001", + "lastsend" : 1470702661, + "lastrecv" : 1470702649, + "conntime" : 1470691153, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1233750, + "banscore" : 0 + }, + { + "addr" : "95.116.195.148:43580", + "services" : "00000001", + "lastsend" : 1470702661, + "lastrecv" : 1470702648, + "conntime" : 1470692017, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1233773, + "banscore" : 0 + }, + { + "addr" : "90.113.82.59:14631", + "services" : "00000001", + "lastsend" : 1470702661, + "lastrecv" : 1470702647, + "conntime" : 1470697248, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : false, + "startingheight" : 1233892, + "banscore" : 0 + }, + { + "addr" : "98.118.105.12:53622", + "services" : "00000001", + "lastsend" : 1470702662, + "lastrecv" : 1470702647, + "conntime" : 1470699762, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1233953, + "banscore" : 0 + }, + { + "addr" : "82.241.71.230:50613", + "services" : "00000001", + "lastsend" : 1470702662, + "lastrecv" : 1470702648, + "conntime" : 1470699801, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1233955, + "banscore" : 0 + }, + { + "addr" : "98.161.16.55:14631", + "services" : "00000001", + "lastsend" : 1470702662, + "lastrecv" : 1470702652, + "conntime" : 1470700341, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : false, + "startingheight" : 1233968, + "banscore" : 0 + }, + { + "addr" : "89.248.160.237:41523", + "services" : "00000001", + "lastsend" : 1470702662, + "lastrecv" : 1470702488, + "conntime" : 1470701204, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1098838, + "banscore" : 0 + }, + { + "addr" : "93.211.231.89:49167", + "services" : "00000001", + "lastsend" : 1470702663, + "lastrecv" : 1470702649, + "conntime" : 1470701417, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 1233992, + "banscore" : 0 + }, + { + "addr" : "2.26.181.156:14631", + "services" : "00000001", + "lastsend" : 1470702663, + "lastrecv" : 1470702647, + "conntime" : 1470701448, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : false, + "startingheight" : 1233993, + "banscore" : 0 + }, + { + "addr" : "89.248.160.244:46492", + "services" : "00000001", + "lastsend" : 1470702697, + "lastrecv" : 1470702696, + "conntime" : 1470701862, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 0, + "banscore" : 0 + }, + { + "addr" : "89.248.160.243:51068", + "services" : "00000001", + "lastsend" : 1470702696, + "lastrecv" : 1470702695, + "conntime" : 1470701914, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 0, + "banscore" : 0 + }, + { + "addr" : "89.248.160.242:33106", + "services" : "00000001", + "lastsend" : 1470702681, + "lastrecv" : 1470702680, + "conntime" : 1470701958, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 0, + "banscore" : 0 + }, + { + "addr" : "89.248.160.241:57001", + "services" : "00000001", + "lastsend" : 1470702663, + "lastrecv" : 1470702117, + "conntime" : 1470702002, + "version" : 60013, + "subver" : "/Satoshi:1.0.0/", + "inbound" : true, + "startingheight" : 0, + "banscore" : 0 + } +] diff --git a/iguana/tests/pub b/iguana/tests/pub new file mode 100755 index 000000000..fcea54b8e --- /dev/null +++ b/iguana/tests/pub @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"basilisk\",\"method\":\"publish\",\"vals\":{\"testfield\":\"test\"},\"hexstr\":\"deadbeef\"}" diff --git a/iguana/tests/rate b/iguana/tests/rate new file mode 100755 index 000000000..4adef8cf3 --- /dev/null +++ b/iguana/tests/rate @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"rate\",\"base\":\"BTCD\",\"rel\":\"BTC\"}" diff --git a/iguana/tests/rates b/iguana/tests/rates new file mode 100755 index 000000000..c076f231e --- /dev/null +++ b/iguana/tests/rates @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"iguana\",\"method\":\"rates\",\"quotes\":[\"BTCD/BTC\", \"BTC/USD\", \"EUR/USD\", \"THB/BRL\"]}" diff --git a/iguana/tests/ratesloop b/iguana/tests/ratesloop new file mode 100755 index 000000000..764f0f684 --- /dev/null +++ b/iguana/tests/ratesloop @@ -0,0 +1,5 @@ +while true +do +./rates +done + diff --git a/iguana/tests/rawtx b/iguana/tests/rawtx new file mode 100755 index 000000000..84b5b8ab6 --- /dev/null +++ b/iguana/tests/rawtx @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTC\",\"agent\":\"basilisk\",\"method\":\"rawtx\",\"vals\":{\"changeaddr\":\"1FNhoaBYzf7safMBjoCsJYgxtah3K95sep\",\"addresses\":[\"1Hgzt5xsnbfc8UTWqWKSTLRm5bEYHYBoCE\"],\"timeout\":15000,\"satoshis\":\"20000\",\"spendscript\":\"76a914b7128d2ee837cf03e30a2c0e3e0181f7b9669bb688ac\"}}" diff --git a/iguana/tests/rawtx2 b/iguana/tests/rawtx2 new file mode 100755 index 000000000..e206fd012 --- /dev/null +++ b/iguana/tests/rawtx2 @@ -0,0 +1,3 @@ +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"agent\":\"basilisk\",\"method\":\"rawtx\",\"vals\":{\"changeaddr\":\"RSyKVKNxrSDc1Vwvh4guYb9ZDEpvMFz2rm\",\"addresses\":[\"RRyBxbrAPRUBCUpiJgJZYrkxqrh8x5ta9Z\", \"RPett64qbUvSefiPCyBzQ52Aer9dx32ngd\", \"RGxn8p5QWZXbs58mpRtVRD8aeATVkRq2Rh\", \"RD9HQdpu9Z7Xsvvbh9URdnwYi6RZVMTVAa\", \"RSZzYEEAVnYDnRvfj5oA3yL6vYtm1WmXHJ\", \"RC3k4XRZxrDDMyYFmvBunZCAsNEFepbpRQ\", \"RSyKVKNxrSDc1Vwvh4guYb9ZDEpvMFz2rm\"],\"timeout\":15000,\"satoshis\":\"128700\",\"spendscript\":\"76a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ac\",\"txfee\":\"1000000\",\"burn\":0.00010000}}" + +#{"coin":"BTCD","spendscript":"76a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ac","changeaddr":"RSyKVKNxrSDc1Vwvh4guYb9ZDEpvMFz2rm","satoshis":"128700","txfee":"1000000","minconf":1,"locktime":0,"timeout":30000,"burn":0.00010000,"addresses":["RRyBxbrAPRUBCUpiJgJZYrkxqrh8x5ta9Z", "RPett64qbUvSefiPCyBzQ52Aer9dx32ngd", "RGxn8p5QWZXbs58mpRtVRD8aeATVkRq2Rh", "RD9HQdpu9Z7Xsvvbh9URdnwYi6RZVMTVAa", "RSZzYEEAVnYDnRvfj5oA3yL6vYtm1WmXHJ", "RC3k4XRZxrDDMyYFmvBunZCAsNEFepbpRQ", "RSyKVKNxrSDc1Vwvh4guYb9ZDEpvMFz2rm"],"symbol":"BTCD"} diff --git a/iguana/tests/rawtx3 b/iguana/tests/rawtx3 new file mode 100755 index 000000000..ffa90d8d2 --- /dev/null +++ b/iguana/tests/rawtx3 @@ -0,0 +1,3 @@ +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTC\",\"agent\":\"basilisk\",\"method\":\"rawtx\",\"vals\":{\"changeaddr\":\"1GQHQ7vwVpGeir2kKrYATsLtrkUQSc7FGY\",\"addresses\":[\"16jsjc1YvzDXqKf7PorMhTyK8ym3ra3uxm\", \"1GQHQ7vwVpGeir2kKrYATsLtrkUQSc7FGY\"],\"timeout\":15000,\"satoshis\":\"20000\",\"spendscript\":\"76a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ac\"}}" + +#{"coin":"BTC","spendscript":"76a914ca1e04745e8ca0c60d8c5881531d51bec470743f88ac","changeaddr":"1GQHQ7vwVpGeir2kKrYATsLtrkUQSc7FGY","satoshis":"331","txfee":"10000","minconf":1,"locktime":0,"timeout":30000,"burn":0.00010000,"addresses":["16jsjc1YvzDXqKf7PorMhTyK8ym3ra3uxm", "1GQHQ7vwVpGeir2kKrYATsLtrkUQSc7FGY"]} diff --git a/iguana/tests/rawtxB b/iguana/tests/rawtxB new file mode 100755 index 000000000..a7ede91c9 --- /dev/null +++ b/iguana/tests/rawtxB @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"timeout\":25000,\"agent\":\"basilisk\",\"method\":\"rawtx\",\"vals\":{\"changeaddr\":\"RRyBxbrAPRUBCUpiJgJZYrkxqrh8x5ta9Z\",\"coin\":\"BTCD\",\"satoshis\":\"20000\",\"spendscript\":\"76a914b7128d2ee837cf03e30a2c0e3e0181f7b9669bb688ac\"}}" diff --git a/iguana/tests/request b/iguana/tests/request new file mode 100755 index 000000000..93fa2b351 --- /dev/null +++ b/iguana/tests/request @@ -0,0 +1,2 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"method\":\"request\",\"vals\":{\"source\":\"BTCD\",\"amount\":0.1,\"dest\":\"BTC\",\"minprice\":0.002}}" + diff --git a/iguana/tests/sell b/iguana/tests/sell new file mode 100755 index 000000000..c0eb0ae05 --- /dev/null +++ b/iguana/tests/sell @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"dotrade\":1,\"agent\":\"InstantDEX\",\"exchange\":\"bitcoin\",\"method\":\"sell\",\"base\":\"BTCD\",\"rel\":\"BTC\",\"price\":0.0029,\"volume\":1.0}" diff --git a/iguana/tests/sell2 b/iguana/tests/sell2 new file mode 100755 index 000000000..4db541c05 --- /dev/null +++ b/iguana/tests/sell2 @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"password\":\"test\",\"dotrade\":1,\"agent\":\"InstantDEX\",\"exchange\":\"bitcoin\",\"method\":\"sell\",\"base\":\"BTCD\",\"rel\":\"BTC\",\"price\":0.0029,\"volume\":1.0}" diff --git a/iguana/tests/sellV b/iguana/tests/sellV new file mode 100755 index 000000000..86f12afc6 --- /dev/null +++ b/iguana/tests/sellV @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"dotrade\":1,\"agent\":\"InstantDEX\",\"exchange\":\"bitcoin\",\"method\":\"sell\",\"base\":\"VPN\",\"rel\":\"BTC\",\"price\":0.000025,\"volume\":1.0}" diff --git a/iguana/tests/send b/iguana/tests/send new file mode 100755 index 000000000..309e1f3e1 --- /dev/null +++ b/iguana/tests/send @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"basilisk\",\"method\":\"sendmessage\",\"vals\":{\"channel\":12345,\"msgid\":1},\"hexstr\":\"deadbeef\"}" diff --git a/iguana/tests/sendrawtransaction b/iguana/tests/sendrawtransaction index 1b7acf455..09d9dbfda 100755 --- a/iguana/tests/sendrawtransaction +++ b/iguana/tests/sendrawtransaction @@ -1,2 +1,2 @@ -curl --url "http://127.0.0.1:7778" --data "{\"method\":\"sendrawtransaction\",\"params\":[\"0100000095f4265701f6d17d847b7096cdd9b79e4df4b74aabb9ac34b7abd4f9fce19d761e97cca0e800000000484730440220657fca67d3bbcb2e798de2119dc809e2245501a70fd97305dab958d0e69a4bc402205309c7f5eb7fa4e1c796eba9b2bba6c898eb8132be96bb05a6592126861fadee01ffffffff0240420f00000000001976a91410acba3a841fae68aba4b5ff162714c493bcc04e88acd0300e00000000001976a914d8b8c039206af6cec82bca950f592801e62808cb88ac00000000\"]}" +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"sendrawtransaction\",\"params\":[\"010000002ec9a45701048f2f330b71f5cbef5d7b1cd161b1cf2dee06ddb15b670d46a41fca3a25beed00000000904730440220039cc97a4b266bef6802db4ae6219637842e97db025529240c01ea207cbd317502204d3796090624c86c43ee150cdc99e313483fe41c6d630d22d167e828688caaeb014730440220388f36c50854292d4a62d631d012b33d1f02fdd8623180151548947eacc06a4002207fe79c455ba5860b15e7b74fa31cf25c4a0f93c1e488f446d3322712067fb73d01ffffffff01706f9800000000001976a91454a752f0d71b89d7c014ed0be29ca231c9546f9f88ac00000000\"]}" diff --git a/iguana/tests/sendtoaddress b/iguana/tests/sendtoaddress index 4d7806f61..e9e059e50 100755 --- a/iguana/tests/sendtoaddress +++ b/iguana/tests/sendtoaddress @@ -1,2 +1,2 @@ -curl --url "http://127.0.0.1:7778" --data "{\"method\":\"sendtoaddress\",\"params\":[\"RAoMou7euzvDwa9dQwjrNB5A41hrAWgvBt\", 0.0001, \"testcomment\", \"sendcomment\"]}" +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"sendtoaddress\",\"params\":[\"RKk3hmkHr3khf2aQRZW51oxnzFVHsQe4hf\", 0.001, \"testcomment\", \"sendcomment\"]}" diff --git a/iguana/tests/set b/iguana/tests/set new file mode 100755 index 000000000..1be121420 --- /dev/null +++ b/iguana/tests/set @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"basilisk\",\"method\":\"set\",\"vals\":{\"key\":\"testkey\",\"chain\":\"test\"},\"hexstr\":\"beefdead\"}" diff --git a/iguana/tests/setaccountB b/iguana/tests/setaccountB new file mode 100755 index 000000000..7106166d7 --- /dev/null +++ b/iguana/tests/setaccountB @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"setaccount\",\"params\":[\"RSM6HUAiQabjEzoXrtptdyMUrUsbYicTDE\", \"newaccount2\"]}" diff --git a/iguana/tests/signrawtransaction b/iguana/tests/signrawtransaction index 6063819fa..1cc56768c 100755 --- a/iguana/tests/signrawtransaction +++ b/iguana/tests/signrawtransaction @@ -1,2 +1,2 @@ -curl --url "http://127.0.0.1:7778" --data "{\"method\":\"signrawtransaction\",\"params\":[\"0100000086cc2c5701f6d17d847b7096cdd9b79e4df4b74aabb9ac34b7abd4f9fce19d761e97cca0e80000000000ffffffff0240420f00000000001976a91410acba3a841fae68aba4b5ff162714c493bcc04e88acd0300e00000000001976a914d8b8c039206af6cec82bca950f592801e62808cb88ac00000000\", [{\"txid\":\"e8a0cc971e769de1fcf9d4abb734acb9ab4ab7f44d9eb7d9cd96707b847dd1f6\",\"vout\":0,\"scriptPubKey\":\"2102d14a195654f536df6dfe5a38278d1b470d00f17de78eeb5ce9e9eea9edb2c212ac\"}], [\"UqvuZXEAVXDXJkL4j4Xq6qoMdeJfPF1aNsCzmzfZaQ1ZgBTwfmWn\"], \"ALL\"] }" +curl --url "http://127.0.0.1:7778" --data "{\"method\":\"signrawtransaction\",\"params\":[\"0100000093b7325701f6d17d847b7096cdd9b79e4df4b74aabb9ac34b7abd4f9fce19d761e97cca0e80000000000ffffffff0240420f00000000001976a91410acba3a841fae68aba4b5ff162714c493bcc04e88acd0300e00000000001976a914d8b8c039206af6cec82bca950f592801e62808cb88ac00000000\", [{\"txid\":\"e8a0cc971e769de1fcf9d4abb734acb9ab4ab7f44d9eb7d9cd96707b847dd1f6\",\"vout\":0,\"scriptPubKey\":\"2102d14a195654f536df6dfe5a38278d1b470d00f17de78eeb5ce9e9eea9edb2c212ac\"}], [\"UqvuZXEAVXDXJkL4j4Xq6qoMdeJfPF1aNsCzmzfZaQ1ZgBTwfmWn\"], \"ALL\"] }" diff --git a/iguana/tests/stakers b/iguana/tests/stakers new file mode 100755 index 000000000..bf6c5f5f9 --- /dev/null +++ b/iguana/tests/stakers @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"timeout\":60000,\"agent\":\"iguana\",\"method\":\"stakers\",\"activecoin\":\"BTCD\"}" diff --git a/iguana/tests/swapstatus b/iguana/tests/swapstatus new file mode 100755 index 000000000..325a1f1ac --- /dev/null +++ b/iguana/tests/swapstatus @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"InstantDEX\",\"method\":\"swapstatus\",\"requestid\":1728286611,\"quoteid\":123456}" diff --git a/iguana/tests/validateaddress b/iguana/tests/validateaddress index ef1426b77..1ea44c657 100755 --- a/iguana/tests/validateaddress +++ b/iguana/tests/validateaddress @@ -1 +1 @@ -curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTC\",\"method\":\"validateaddress\",\"params\":[\"1BnPHAZuPvYSgWkRfEu6wHDL8uGRzDcTjt\"]}" +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTCD\",\"method\":\"validateaddress\",\"params\":[\"RSyKVKNxrSDc1Vwvh4guYb9ZDEpvMFz2rm\"]}" diff --git a/iguana/tests/validaterawtransaction b/iguana/tests/validaterawtransaction new file mode 100755 index 000000000..d28b172a2 --- /dev/null +++ b/iguana/tests/validaterawtransaction @@ -0,0 +1 @@ +curl --url "http://127.0.0.1:7778" --data "{\"coin\":\"BTC\",\"method\":\"validaterawtransaction\",\"params\":[\"0100000001d330b1a60b68272d1249a178605ef699e26772a642a68d2e0558a7a558dc420100000000b4483045022100c4de2343865be62552137fc594a5acbe8db036aa7fc811ed7819966f6b30a0400220522776e79aff3ec77947837c03c2a6a11a1c1953f551fc0b6e87350a10c86b6601514c676304b762a657b1752102a9669e63ef1ab04913615c2f3887ea3584f81e5f08feee9535b19ab3739d8afdac67a91418a616c8617d1bbae6369e5d41c2cd1e5d4c0f9c88210398a4cb9f6ea7c52a4e27455028a95e2e4e397a110fb75f072c2c58a8bdcbf4baac685100000000000001d441\", 1]}" diff --git a/iguana/tests/walletpassphrase b/iguana/tests/walletpassphrase index 16c6669bf..d5c8f0fcb 100755 --- a/iguana/tests/walletpassphrase +++ b/iguana/tests/walletpassphrase @@ -1,2 +1,2 @@ #curl --url "http://127.0.0.1:7778" --data "{\"method\":\"walletpassphrase\",\"params\":[\"test\", 600]}" -curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"walletpassphrase\",\"password\":\"test\",\"timeout\":300}" +curl --url "http://127.0.0.1:7778" --data "{\"agent\":\"bitcoinrpc\",\"method\":\"walletpassphrase\",\"password\":\"test\",\"timeout\":86444}" diff --git a/includes/cJSON.h b/includes/cJSON.h index 7c1cbaec8..2de29d8d7 100755 --- a/includes/cJSON.h +++ b/includes/cJSON.h @@ -53,6 +53,7 @@ extern "C" #define cJSON_Array 5 #define cJSON_Object 6 +#define is_cJSON_Null(json) ((json) != 0 && ((json)->type & 0xff) == cJSON_NULL) #define is_cJSON_Array(json) ((json) != 0 && ((json)->type & 0xff) == cJSON_Array) #define is_cJSON_String(json) ((json) != 0 && ((json)->type & 0xff) == cJSON_String) #define is_cJSON_Number(json) ((json) != 0 && ((json)->type & 0xff) == cJSON_Number) diff --git a/includes/curve25519.h b/includes/curve25519.h index d37b0688e..cff0e0e02 100755 --- a/includes/curve25519.h +++ b/includes/curve25519.h @@ -76,5 +76,12 @@ uint64_t acct777_sign(struct acct777_sig *sig,bits256 privkey,bits256 otherpubke uint64_t acct777_validate(struct acct777_sig *sig,bits256 privkey,bits256 pubkey); uint64_t acct777_signtx(struct acct777_sig *sig,bits256 privkey,uint32_t timestamp,uint8_t *data,int32_t datalen); uint64_t acct777_swaptx(bits256 privkey,struct acct777_sig *sig,uint32_t timestamp,uint8_t *data,int32_t datalen); +void calc_hmac_sha256(uint8_t *mac,int32_t maclen,uint8_t *key,int32_t key_size,uint8_t *message,int32_t len); + +#include "../includes/tweetnacl.h" +int32_t _SuperNET_cipher(uint8_t nonce[crypto_box_NONCEBYTES],uint8_t *cipher,uint8_t *message,int32_t len,bits256 destpub,bits256 srcpriv,uint8_t *buf); +uint8_t *_SuperNET_decipher(uint8_t nonce[crypto_box_NONCEBYTES],uint8_t *cipher,uint8_t *message,int32_t len,bits256 srcpub,bits256 mypriv); +void *SuperNET_deciphercalc(void **ptrp,int32_t *msglenp,bits256 privkey,bits256 srcpubkey,uint8_t *cipher,int32_t cipherlen,uint8_t *buf,int32_t bufsize); +uint8_t *SuperNET_ciphercalc(void **ptrp,int32_t *cipherlenp,bits256 *privkeyp,bits256 *destpubkeyp,uint8_t *data,int32_t datalen,uint8_t *space2,int32_t space2size); #endif diff --git a/includes/iguana_api.h b/includes/iguana_api.h index dcb3c05d8..efc97352b 100755 --- a/includes/iguana_api.h +++ b/includes/iguana_api.h @@ -20,4 +20,4 @@ #include "../includes/iguana_apideclares.h" #include "../includes/iguana_apiundefs.h" -#endif \ No newline at end of file +#endif diff --git a/includes/iguana_apideclares.h b/includes/iguana_apideclares.h index 66464ad10..c600ac69e 100755 --- a/includes/iguana_apideclares.h +++ b/includes/iguana_apideclares.h @@ -13,9 +13,59 @@ * * ******************************************************************************/ +#ifdef INCLUDE_PAX +ZERO_ARGS(pax,start); +#endif +HASH_ARRAY_STRING(tradebot,liquidity,hash,vals,targetcoin); +ZERO_ARGS(tradebot,amlp); +ZERO_ARGS(tradebot,notlp); + +INT_AND_ARRAY(iguana,rates,unused,quotes); +TWO_STRINGS(iguana,rate,base,rel); +THREE_STRINGS_AND_THREE_INTS(iguana,prices,exchange,base,rel,period,start,end); + +ZERO_ARGS(InstantDEX,allcoins); +STRING_ARG(InstantDEX,available,source); +HASH_ARRAY_STRING(InstantDEX,request,hash,vals,hexstr); + +INT_ARG(InstantDEX,incoming,requestid); +INT_ARG(InstantDEX,automatched,requestid); + +TWO_INTS(InstantDEX,accept,requestid,quoteid); +//TWO_INTS(InstantDEX,swapstatus,requestid,quoteid); + +HASH_ARRAY_STRING(basilisk,genesis_opreturn,hash,vals,hexstr); +HASH_ARRAY_STRING(basilisk,history,hash,vals,hexstr); + +HASH_ARRAY_STRING(basilisk,balances,hash,vals,hexstr); +HASH_ARRAY_STRING(basilisk,value,hash,vals,hexstr); +//HASH_ARRAY_STRING(basilisk,rawtx,hash,vals,hexstr); + +HASH_ARRAY_STRING(basilisk,getmessage,hash,vals,hexstr); +HASH_ARRAY_STRING(basilisk,sendmessage,hash,vals,hexstr); + +HASH_ARRAY_STRING(basilisk,geckoheaders,hash,vals,hexstr); +HASH_ARRAY_STRING(basilisk,geckoblock,hash,vals,hexstr); +HASH_ARRAY_STRING(basilisk,geckotx,hash,vals,hexstr); +HASH_ARRAY_STRING(basilisk,geckoget,hash,vals,hexstr); + +HASH_ARRAY_STRING(basilisk,addrelay,hash,vals,hexstr); +HASH_ARRAY_STRING(basilisk,dispatch,hash,vals,hexstr); +HASH_ARRAY_STRING(basilisk,publish,hash,vals,hexstr); +HASH_ARRAY_STRING(basilisk,subscribe,hash,vals,hexstr); +HASH_ARRAY_STRING(basilisk,forward,hash,vals,hexstr); +HASH_ARRAY_STRING(basilisk,mailbox,hash,vals,hexstr); + +HASH_ARRAY_STRING(basilisk,VPNcreate,hash,vals,hexstr); +HASH_ARRAY_STRING(basilisk,VPNjoin,hash,vals,hexstr); +HASH_ARRAY_STRING(basilisk,VPNmessage,hash,vals,hexstr); +HASH_ARRAY_STRING(basilisk,VPNbroadcast,hash,vals,hexstr); +HASH_ARRAY_STRING(basilisk,VPNreceive,hash,vals,hexstr); +HASH_ARRAY_STRING(basilisk,VPNlogout,hash,vals,hexstr); ZERO_ARGS(bitcoinrpc,getinfo); ZERO_ARGS(bitcoinrpc,getblockcount); +ZERO_ARGS(bitcoinrpc,getdifficulty); ZERO_ARGS(bitcoinrpc,getbestblockhash); INT_ARG(bitcoinrpc,getblockhash,height); HASH_AND_TWOINTS(bitcoinrpc,getblock,blockhash,verbose,remoteonly); @@ -26,10 +76,12 @@ HASH_AND_TWOINTS(bitcoinrpc,gettxout,txid,vout,mempool); TWOINTS_AND_ARRAY(bitcoinrpc,listunspent,minconf,maxconf,array); STRING_ARG(bitcoinrpc,decodescript,scriptstr); -STRING_ARG(bitcoinrpc,decoderawtransaction,rawtx); +//STRING_ARG(bitcoinrpc,decoderawtransaction,rawtx); +STRING_AND_INT(bitcoinrpc,decoderawtransaction,rawtx,suppress); +STRING_AND_INT(bitcoinrpc,validaterawtransaction,rawtx,suppress); ARRAY_OBJ_INT(bitcoinrpc,createrawtransaction,vins,vouts,locktime); -ZERO_ARGS(bitcoinrpc,makekeypair); +ZERO_ARGS(iguana,makekeypair); STRING_ARG(bitcoinrpc,validatepubkey,pubkey); STRING_ARG(bitcoinrpc,validateaddress,address); @@ -67,14 +119,14 @@ ZERO_ARGS(bitcoinrpc,repairwallet); STRING_ARRAY_OBJ_STRING(bitcoinrpc,signrawtransaction,rawtx,vins,privkeys,sighash); TWO_STRINGS(bitcoinrpc,signmessage,address,message); THREE_STRINGS(bitcoinrpc,verifymessage,address,sig,message); -STRING_AND_INT(bitcoinrpc,sendrawtransaction,rawtx,allowhighfees); // -STRING_ARG(bitcoinrpc,submitblock,rawbytes); // +STRING_AND_INT(bitcoinrpc,sendrawtransaction,rawtx,allowhighfees); -SS_D_I_SS(bitcoinrpc,sendfrom,fromaccount,toaddress,amount,minconf,comment,comment2); // -S_A_I_S(bitcoinrpc,sendmany,fromaccount,payments,minconf,comment); // -S_D_SS(bitcoinrpc,sendtoaddress,address,amount,comment,comment2); // +SS_D_I_SS(bitcoinrpc,sendfrom,fromaccount,toaddress,amount,minconf,comment,comment2); +S_A_I_S(bitcoinrpc,sendmany,fromaccount,payments,minconf,comment); +S_D_SS(bitcoinrpc,sendtoaddress,address,amount,comment,comment2); INT_AND_ARRAY(bitcoinrpc,lockunspent,flag,array); // ZERO_ARGS(bitcoinrpc,listlockunspent); // +STRING_ARG(bitcoinrpc,submitblock,rawbytes); // // maybe later HASH_AND_TWOINTS(bitcoinrpc,listsinceblock,blockhash,target,flag); @@ -101,27 +153,31 @@ TWO_STRINGS_AND_TWO_DOUBLES(iguana,balance,activecoin,address,heightd,minconfd); P2SH_SPENDAPI(iguana,spendmsig,activecoin,vintxid,vinvout,destaddress,destamount,destaddress2,destamount2,M,N,pubA,wifA,pubB,wifB,pubC,wifC); STRING_AND_INT(iguana,bundleaddresses,activecoin,height); STRING_AND_INT(iguana,bundlehashes,activecoin,height); +STRING_AND_INT(iguana,PoSweights,activecoin,height); +STRING_ARG(iguana,stakers,activecoin); -TWO_STRINGS_AND_TWO_DOUBLES(InstantDEX,minaccept,base,rel,minprice,basevolume); -TWO_STRINGS_AND_TWO_DOUBLES(InstantDEX,maxaccept,base,rel,maxprice,basevolume); -THREE_STRINGS_AND_THREE_INTS(InstantDEX,orderbook,exchange,base,rel,depth,allfields,ignore); +//TWO_STRINGS_AND_TWO_DOUBLES(InstantDEX,minaccept,base,rel,minprice,basevolume); +//TWO_STRINGS_AND_TWO_DOUBLES(InstantDEX,maxaccept,base,rel,maxprice,basevolume); THREE_STRINGS_AND_THREE_DOUBLES(InstantDEX,buy,exchange,base,rel,price,volume,dotrade); THREE_STRINGS_AND_THREE_DOUBLES(InstantDEX,sell,exchange,base,rel,price,volume,dotrade); THREE_STRINGS_AND_DOUBLE(InstantDEX,withdraw,exchange,base,destaddr,amount); THREE_STRINGS(InstantDEX,apikeypair,exchange,apikey,apisecret); THREE_STRINGS(InstantDEX,setuserid,exchange,userid,tradepassword); -THREE_STRINGS(InstantDEX,supports,exchange,base,rel); TWO_STRINGS(InstantDEX,balance,exchange,base); TWO_STRINGS(InstantDEX,orderstatus,exchange,orderid); TWO_STRINGS(InstantDEX,cancelorder,exchange,orderid); STRING_ARG(InstantDEX,openorders,exchange); STRING_ARG(InstantDEX,tradehistory,exchange); + +THREE_STRINGS_AND_THREE_INTS(InstantDEX,orderbook,exchange,base,rel,depth,allfields,ignore); STRING_AND_INT(InstantDEX,pollgap,exchange,pollgap); +//TWO_STRINGS(InstantDEX,events,base,rel); ZERO_ARGS(InstantDEX,allexchanges); STRING_ARG(InstantDEX,allpairs,exchange); +THREE_STRINGS(InstantDEX,supports,exchange,base,rel); -THREE_STRINGS(atomic,approve,myorderid,otherid,txname); -THREE_STRINGS(atomic,claim,myorderid,otherid,txname); +//THREE_STRINGS(atomic,approve,myorderid,otherid,txname); +//THREE_STRINGS(atomic,claim,myorderid,otherid,txname); //TWOSTRINGS_AND_TWOHASHES_AND_TWOINTS(InstantDEX,proposal,reference,message,basetxid,reltxid,duration,flags); //TWOSTRINGS_AND_TWOHASHES_AND_TWOINTS(InstantDEX,accept,reference,message,basetxid,reltxid,duration,flags); @@ -175,7 +231,7 @@ THREE_STRINGS(SuperNET,encryptjson,password,permanentfile,payload); TWO_STRINGS(SuperNET,decryptjson,password,permanentfile); TWO_STRINGS(SuperNET,html,agentform,htmlfile); -TWOSTRINGS_AND_TWOHASHES_AND_TWOINTS(SuperNET,DHT,hexmsg,destip,categoryhash,subhash,maxdelay,broadcast); +//TWOSTRINGS_AND_TWOHASHES_AND_TWOINTS(SuperNET,DHT,hexmsg,destip,categoryhash,subhash,maxdelay,broadcast); THREE_STRINGS(SuperNET,rosetta,passphrase,pin,showprivkey); ZERO_ARGS(SuperNET,keypair); @@ -183,6 +239,7 @@ HASH_AND_INT(SuperNET,priv2pub,privkey,addrtype); STRING_ARG(SuperNET,wif2priv,wif); STRING_ARG(SuperNET,priv2wif,priv); STRING_ARG(SuperNET,addr2rmd160,address); +STRING_ARG(SuperNET,rmd160conv,rmd160); TWOHASHES_AND_STRING(SuperNET,cipher,privkey,destpubkey,message); TWOHASHES_AND_STRING(SuperNET,decipher,privkey,srcpubkey,cipherstr); @@ -193,12 +250,12 @@ STRING_ARG(SuperNET,broadcastdecipher,message); HASH_AND_STRING(SuperNET,multicastcipher,pubkey,message); HASH_AND_STRING(SuperNET,multicastdecipher,privkey,cipherstr); -TWO_STRINGS(SuperNET,subscribe,category,subcategory); +/*TWO_STRINGS(SuperNET,subscribe,category,subcategory); TWO_STRINGS(SuperNET,gethexmsg,category,subcategory); THREE_STRINGS(SuperNET,posthexmsg,category,subcategory,hexmsg); THREE_STRINGS(SuperNET,announce,category,subcategory,message); THREE_STRINGS(SuperNET,survey,category,subcategory,message); -TWO_STRINGS(SuperNET,categoryhashes,category,subcategory); +TWO_STRINGS(SuperNET,categoryhashes,category,subcategory);*/ STRING_AND_TWOINTS(mouse,image,name,x,y); STRING_AND_TWOINTS(mouse,change,name,x,y); diff --git a/includes/iguana_apidefs.h b/includes/iguana_apidefs.h index 2e37feb8b..7668e1475 100755 --- a/includes/iguana_apidefs.h +++ b/includes/iguana_apidefs.h @@ -16,6 +16,7 @@ #define IGUANA_CFUNC_IA(agent,name,val,array) char *agent ## _ ## name(IGUANA_ARGS,int32_t val,cJSON *array) #define IGUANA_CFUNC_IAS(agent,name,val,array,str) char *agent ## _ ## name(IGUANA_ARGS,int32_t val,cJSON *array,char *str) #define IGUANA_CFUNC_II(agent,name,val,val2) char *agent ## _ ## name(IGUANA_ARGS,int32_t val,int32_t val2) +#define IGUANA_CFUNC_ID(agent,name,val,val2) char *agent ## _ ## name(IGUANA_ARGS,int32_t val,double val2) #define IGUANA_CFUNC_III(agent,name,val,val2,val3) char *agent ## _ ## name(IGUANA_ARGS,int32_t val,int32_t val2,int32_t val3) #define IGUANA_CFUNC_SIII(agent,name,str,val,val2,val3) char *agent ## _ ## name(IGUANA_ARGS,char *str,int32_t val,int32_t val2,int32_t val3) #define IGUANA_CFUNC_IIA(agent,name,val,val2,array) char *agent ## _ ## name(IGUANA_ARGS,int32_t val,int32_t val2,cJSON *array) @@ -53,6 +54,7 @@ // API functions #define ZERO_ARGS IGUANA_CFUNC0 #define INT_ARG IGUANA_CFUNC_I +#define INT_AND_DOUBLE IGUANA_CFUNC_ID #define TWO_INTS IGUANA_CFUNC_II #define STRING_ARG IGUANA_CFUNC_S #define TWO_STRINGS IGUANA_CFUNC_SS diff --git a/includes/iguana_apiundefs.h b/includes/iguana_apiundefs.h index c69c0f2db..7f70ed381 100755 --- a/includes/iguana_apiundefs.h +++ b/includes/iguana_apiundefs.h @@ -17,6 +17,7 @@ #undef DOUBLE_ARG #undef ARRAY_OBJ_INT #undef STRING_AND_ARRAY +#undef INT_AND_DOUBLE #undef INT_AND_ARRAY #undef INT_ARRAY_STRING #undef TWO_ARRAYS diff --git a/includes/iguana_defines.h b/includes/iguana_defines.h new file mode 100755 index 000000000..7c7e7ed4d --- /dev/null +++ b/includes/iguana_defines.h @@ -0,0 +1,215 @@ +/****************************************************************************** + * Copyright © 2014-2016 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#ifndef H_IGUANADEFINES_H +#define H_IGUANADEFINES_H + +#define SPARSECOUNT(x) ((x) << 1) + +#define IGUANA_MAXSCRIPTSIZE 10001 +#define IGUANA_SERIALIZE_SPENDVECTORGEN +//#define IGUANA_DISABLEPEERS +#define _IGUANA_MAXSTUCKTIME 10 +#ifdef __PNACL__ +#define IGUANA_MAXITERATIONS 77 +#else +#define IGUANA_MAXITERATIONS 7777 +#endif +#define IGUANA_DEFAULTLAG 30 + +#define IGUANA_MAXHEIGHT (1 << 30) +#define IGUANA_MAXCOINS 64 +#define IGUANA_MAXDELAY_MILLIS (3600 * 1000 * 24) +#define IGUANA_DEFAULT_POLLTIMEOUT 10 +#define IGUANA_SEQUENCEID_FINAL 0xfffffffe + +#define IGUANA_EXCHANGEIDLE 10 +#define IGUANS_JSMILLIS 100 + +#define IGUANA_WIDTH 1024 +#define IGUANA_HEIGHT 200 + +#define IGUANA_HEADPERCENTAGE 0. +#define IGUANA_TAILPERCENTAGE 1.0 +#define IGUANA_MAXPENDHDRS 1 +#define IGUANA_MAXPENDINGREQUESTS 8 +#define IGUANA_PENDINGREQUESTS 500 +#define IGUANA_MINPENDBUNDLES 4 +#define IGUANA_MAXPENDBUNDLES 64 +#define IGUANA_RPCPORT 7778 +#define IGUANA_MAXRAMCHAINSIZE ((uint64_t)1024L * 1024L * 1024L * 16) + +#define IGUANA_MAPHASHTABLES 1 +#define IGUANA_DEFAULTRAM 4 +#define IGUANA_MAXRECVCACHE ((int64_t)1024L * 1024 * 1024L) +#define IGUANA_MAXBUNDLES (50000000 / 500) + +#define IGUANA_MINPEERS 64 +#define IGUANA_LOG2MAXPEERS 11 +#define IGUANA_LOG2PEERFILESIZE 23 + +#define IGUANA_MAXPEERS (1 << IGUANA_LOG2MAXPEERS) +#define IGUANA_LOG2PACKETSIZE 21 +#define IGUANA_MAXPACKETSIZE (1 << IGUANA_LOG2PACKETSIZE) +#define IGUANA_PEERFILESIZE (1 << IGUANA_LOG2PEERFILESIZE) +struct iguana_txdatabits { uint64_t addrind:IGUANA_LOG2MAXPEERS,filecount:10,fpos:IGUANA_LOG2PEERFILESIZE,datalen:IGUANA_LOG2PACKETSIZE,isdir:1; }; + +#define IGUANA_MAXFILEITEMS 8192 +#define IGUANA_RECENTPEER (3600 * 24 * 7) + +#define IGUANA_PERMTHREAD 0 +#define IGUANA_CONNTHREAD 1 +#define IGUANA_SENDTHREAD 2 +#define IGUANA_RECVTHREAD 3 +#define IGUANA_HELPERTHREAD 4 +#define IGUANA_EXCHANGETHREAD 5 + +#define IGUANA_DEDICATED_THREADS +#ifdef IGUANA_DEDICATED_THREADS +#define IGUANA_MAXCONNTHREADS 16 +#define IGUANA_MAXSENDTHREADS (IGUANA_MAXPEERS>>2) +#define IGUANA_MAXRECVTHREADS (IGUANA_MAXPEERS>>2) +#else +#define IGUANA_MAXCONNTHREADS 16 +#define IGUANA_MAXSENDTHREADS 16 +#define IGUANA_MAXRECVTHREADS 16 +#endif +#define BASILISK_MAXRELAYS 64 + +#define IGUANA_SUBDIRDIVISOR 28000 +#define NTARGETSPACING 60 + +#define IGUANA_PROTOCOL_BITCOIN 'b' +#define IGUANA_PROTOCOL_NXT 'n' +#define IGUANA_PROTOCOL_ETHER 'e' +#define IGUANA_PROTOCOL_LISK 'l' +#define IGUANA_PROTOCOL_WAVES 'w' +#define IGUANA_PROTOCOL_IOTA 'i' + +#ifdef __PNACL +void PNACL_message(const char* format, ...); +#endif + +extern int32_t IGUANA_NUMHELPERS; + +#ifdef __PNACL +#define printf PNACL_message +#define MS_ASYNC 1 /* Sync memory asynchronously. */ +#define MS_SYNC 4 /* Synchronous memory sync. */ +#else +#define PNACL_message printf +#endif + +#ifndef MSG_NOSIGNAL +#define MSG_NOSIGNAL 0x4000 // Do not generate SIGPIPE +#endif + +#if defined(_WIN32) || defined(_WIN64) +#define MSG_NOSIGNAL 0 +#endif + +#define BIP0031_VERSION 60000 +#define CADDR_TIME_VERSION 31402 +#define MIN_PROTO_VERSION 209 +#define MAX_BLOCK_SIZE 1000000 +#define COINBASE_MATURITY 100 + +#define _IGUANA_HDRSCOUNT 2000 +#define _IGUANA_BLOCKHASHES 500 +#define IGUANA_MAXBUNDLESIZE _IGUANA_HDRSCOUNT + +#define NODE_NETWORK (1 << 0) +#define NODE_GETUTXO (1 << 1) +#define NODE_BLOOM (1 << 2) + +#define INIT_PROTO_VERSION 209 // initial proto version, to be increased after version/verack negotiation +#define GETHEADERS_VERSION 31800 // In this version, 'getheaders' was introduced. +#define MIN_PEER_PROTO_VERSION GETHEADERS_VERSION // disconnect from peers older than this proto version +// nTime field added to CAddress, starting with this version, if possible, avoid requesting addresses nodes older than this +#define CADDR_TIME_VERSION 31402 +// only request blocks from nodes outside this range of versions +#define NOBLKS_VERSION_START 32000 +#define NOBLKS_VERSION_END 32400 + +#define BIP0031_VERSION 60000 // BIP 0031, pong message, is enabled for all versions AFTER this one +#define MEMPOOL_GD_VERSION 60002 // "mempool" command, enhanced "getdata" behavior starts with this version +#define NO_BLOOM_VERSION 70011 // "filter*" disabled without NODE_BLOOM after and including this version +#define PROTOCOL_HEADERS_VERSION 70012 +#define PROTOCOL_VERSION 70003 +//#define PROTOCOL_VERSION PROTOCOL_HEADERS_VERSION + +#define MSG_TX 1 +#define MSG_BLOCK 2 +#define MSG_FILTERED_BLOCK 3 +//#define MSG_QUOTE 253 +#define MSG_BUNDLE 254 +#define MSG_BUNDLE_HEADERS 255 + +#define IGUANA_MAXLOCATORS 64 +#define IGUANA_MAXINV 50000 + +#define IGUANA_VOLATILE 1 +#define IGUANA_ITEMIND_DATA 2 +#define IGUANA_MAPPED_ITEM 4 +#define IGUANA_SHA256 0x80 +#define IGUANA_ALLOC_MULT 1.1 +#define IGUANA_ALLOC_INCR 1000 + +#define IGUANA_JSONTIMEOUT 10000 + +#define IGUANA_MAPRECVDATA 1 +#define IGUANA_MAPTXIDITEMS 2 +#define IGUANA_MAPPKITEMS 4 +#define IGUANA_MAPBLOCKITEMS 8 +#define IGUANA_MAPPEERITEMS 16 + +#define IGUANA_PEER_ELIGIBLE 1 +#define IGUANA_PEER_CONNECTING 2 +#define IGUANA_PEER_READY 3 +#define IGUANA_PEER_KILLED 4 + +#define IGUANA_NORMAL_TXVERSION 1 +#define IGUANA_LOCKTIME_TXVERSION 1 + +#define IGUANA_SEARCHBUNDLE 1 +#define IGUANA_SEARCHNOLAST (IGUANA_SEARCHBUNDLE | 2) +#define IGUANA_SEARCHPREV 4 +#define IGUANA_SEARCHNEXT 8 +#define IGUANA_SEARCHALL (IGUANA_SEARCHBUNDLE | IGUANA_SEARCHPREV | IGUANA_SEARCHNEXT) + +#define SUPERNET_MAXEXCHANGES 64 +#define SUPERNET_APIVERSION 0 + + +#define IGUANA_SCRIPT_NULL 0 +#define IGUANA_SCRIPT_76AC 1 +#define IGUANA_SCRIPT_76A988AC 2 +#define IGUANA_SCRIPT_P2SH 3 +#define IGUANA_SCRIPT_OPRETURN 4 +#define IGUANA_SCRIPT_3of3 5 +#define IGUANA_SCRIPT_2of3 6 +#define IGUANA_SCRIPT_1of3 7 +#define IGUANA_SCRIPT_2of2 8 +#define IGUANA_SCRIPT_1of2 9 +#define IGUANA_SCRIPT_MSIG 10 +#define IGUANA_SCRIPT_DATA 11 +#define IGUANA_SCRIPT_AC 12 +#define IGUANA_SCRIPT_1of1 13 +#define IGUANA_SCRIPT_STRANGE 15 + +#define IGUANA_MAXSCRIPTSIZE 10001 + +#endif + diff --git a/includes/iguana_funcs.h b/includes/iguana_funcs.h new file mode 100755 index 000000000..61a31b0d1 --- /dev/null +++ b/includes/iguana_funcs.h @@ -0,0 +1,602 @@ +/****************************************************************************** + * Copyright © 2014-2016 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#ifndef H_IGUANAFUNCS_H +#define H_IGUANAFUNCS_H +// peers +int32_t iguana_verifypeer(struct iguana_info *coin,void *key,void *value,int32_t itemind,int32_t itemsize); +int32_t iguana_peermetrics(struct supernet_info *myinfo,struct iguana_info *coin); +void iguana_peersloop(void *arg); +int32_t iguana_queue_send(struct iguana_peer *addr,int32_t delay,uint8_t *serialized,char *cmd,int32_t len); +uint32_t iguana_rwiAddrind(struct iguana_info *coin,int32_t rwflag,struct iguana_iAddr *iA,uint32_t ind); +void iguana_connections(void *arg); +uint32_t iguana_possible_peer(struct iguana_info *coin,char *ip_port); +//int32_t iguana_set_iAddrheight(struct iguana_info *coin,uint32_t ipbits,int32_t height); +//struct iguana_peer *iguana_choosepeer(struct iguana_info *coin); +void iguana_initpeer(struct iguana_info *coin,struct iguana_peer *addr,uint64_t ipbits); +void iguana_startconnection(void *arg); +void iguana_shutdownpeers(struct iguana_info *coin,int32_t forceflag); +void iguana_acceptloop(void *args); +void iguana_recvloop(void *args); +int32_t iguana_send(struct iguana_info *coin,struct iguana_peer *addr,uint8_t *serialized,int32_t len); +uint32_t iguana_updatemetrics(struct supernet_info *myinfo,struct iguana_info *coin); +void *iguana_peeralloc(struct iguana_info *coin,struct iguana_peer *addr,int32_t datalen); +int64_t iguana_peerfree(struct iguana_info *coin,struct iguana_peer *addr,void *ptr,int32_t datalen); +int64_t iguana_peerallocated(struct iguana_info *coin,struct iguana_peer *addr); + +// serdes +int32_t iguana_rwmem(int32_t rwflag,uint8_t *serialized,int32_t len,void *endianedp); +int32_t iguana_rwnum(int32_t rwflag,uint8_t *serialized,int32_t len,void *endianedp); +int32_t iguana_rwvarint32(int32_t rwflag,uint8_t *serialized,uint32_t *int32p); +int32_t iguana_rwbignum(int32_t rwflag,uint8_t *serialized,int32_t len,uint8_t *endianedp); +int32_t iguana_rwblock(char *symbol,uint8_t zcash,uint8_t auxpow,int32_t (*hashalgo)(uint8_t *blockhashp,uint8_t *serialized,int32_t len),int32_t rwflag,bits256 *hash2p,uint8_t *serialized,struct iguana_msgblock *msg,int32_t maxlen); +int32_t iguana_serialize_block(struct iguana_chain *chain,bits256 *hash2p,uint8_t serialized[sizeof(struct iguana_msgblock)],struct iguana_block *block); +void iguana_blockconv(uint8_t zcash,uint8_t auxpow,struct iguana_block *dest,struct iguana_msgblock *msg,bits256 hash2,int32_t height); +//void iguana_freetx(struct iguana_msgtx *tx,int32_t n); +int32_t iguana_msgparser(struct iguana_info *coin,struct iguana_peer *addr,struct OS_memspace *rawmem,struct OS_memspace *txmem,struct OS_memspace *hashmem,struct iguana_msghdr *H,uint8_t *data,int32_t datalen,int32_t fromcache); + +// send message +int32_t iguana_validatehdr(char *symbol,struct iguana_msghdr *H); +int32_t iguana_sethdr(struct iguana_msghdr *H,const uint8_t netmagic[4],char *command,uint8_t *data,int32_t datalen); +int32_t iguana_send_version(struct iguana_info *coin,struct iguana_peer *addr,uint64_t myservices); +int32_t iguana_gentxarray(struct iguana_info *coin,struct OS_memspace *mem,struct iguana_txblock *txblock,int32_t *lenp,uint8_t *data,int32_t datalen); +int32_t iguana_gethdrs(struct iguana_info *coin,uint8_t *serialized,char *cmd,char *hashstr); +int32_t iguana_getdata(struct iguana_info *coin,uint8_t *serialized,int32_t type,bits256 *hashes,int32_t n); +void iguana_blockunconv(uint8_t zcash,uint8_t auxpow,struct iguana_msgblock *msg,struct iguana_block *src,int32_t cleartxn_count); +int32_t iguana_peerblockrequest(struct iguana_info *coin,uint8_t *blockspace,int32_t max,struct iguana_peer *addr,bits256 hash2,int32_t validatesigs); +int32_t iguana_validatesigs(struct iguana_info *coin,struct iguana_msgvin *vin); + +// ramchain +int64_t iguana_verifyaccount(struct iguana_info *coin,struct iguana_account *acct,uint32_t pkind); +int32_t iguana_initramchain(struct iguana_info *coin,int32_t initialheight,int32_t mapflags,int32_t fullverify); +void iguana_syncramchain(struct iguana_info *coin); +//int32_t iguana_validateramchain(struct iguana_info *coin,int64_t *netp,uint64_t *creditsp,uint64_t *debitsp,int32_t height,struct iguana_block *block,int32_t hwmheight,struct iguana_prevdep *lp); +int32_t iguana_calcrmd160(struct iguana_info *coin,char *asmstr,struct vin_info *vp,uint8_t *pk_script,int32_t pk_scriptlen,bits256 debugtxid,int32_t vout,uint32_t sequence); +uint32_t iguana_updatescript(struct iguana_info *coin,uint32_t blocknum,uint32_t txidind,uint32_t spendind,uint32_t unspentind,uint64_t value,uint8_t *script,int32_t scriptlen,uint32_t sequence); +void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_txblock *txdata,struct iguana_msgtx *txarray,struct iguana_msghdr *H,uint8_t *data,int32_t datalen,int32_t fromcache); +int32_t iguana_parseblock(struct iguana_info *coin,struct iguana_block *block,struct iguana_msgtx *tx,int32_t numtx); +uint32_t iguana_txidind(struct iguana_info *coin,uint32_t *firstvoutp,uint32_t *firstvinp,bits256 txid); +bits256 iguana_txidstr(struct iguana_info *coin,uint32_t *firstvoutp,uint32_t *firstvinp,char *txidstr,uint32_t txidind); +int32_t iguana_updateramchain(struct iguana_info *coin); +//void iguana_emittxarray(struct iguana_info *coin,FILE *fp,struct iguana_bundle *bundle,struct iguana_block *block,struct iguana_msgtx *txarray,int32_t numtx); + +// blockchain +int32_t iguana_needhdrs(struct iguana_info *coin); +struct iguana_chain *iguana_chainfind(char *name,cJSON *argjson,int32_t createflag); +int32_t iguana_chainextend(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_block *newblock); +uint64_t iguana_miningreward(struct iguana_info *coin,uint32_t blocknum); + +// tx +int32_t iguana_rwtx(uint8_t zcash,int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized,struct iguana_msgtx *msg,int32_t maxsize,bits256 *txidp,int32_t hastimestamp,int32_t isvpncoin); +void iguana_gottxidsM(struct iguana_info *coin,struct iguana_peer *addr,bits256 *txids,int32_t n); +void iguana_gotquotesM(struct iguana_info *coin,struct iguana_peer *addr,bits256 *quotes,int32_t n); +void iguana_gotunconfirmedM(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_msgtx *tx,uint8_t *data,int32_t datalen); +void iguana_gotblockhashesM(struct iguana_info *coin,struct iguana_peer *addr,bits256 *blockhashes,int32_t n); + +// blocks +bits256 iguana_blockhash(struct iguana_info *coin,int32_t height); +#define iguana_blockfind(str,coin,hash2) iguana_blockhashset(str,coin,-1,hash2,0) +struct iguana_block *iguana_blockhashset(char *debugstr,struct iguana_info *coin,int32_t height,bits256 hash2,int32_t createflag); +struct iguana_block *iguana_prevblock(struct iguana_info *coin,struct iguana_block *block,int32_t PoSflag); +uint32_t iguana_targetbits(struct iguana_info *coin,struct iguana_block *hwmchain,struct iguana_block *prev,struct iguana_block *prev2,int32_t PoSflag,int32_t targetspacing,int32_t targettimespan); + +uint32_t iguana_syncs(struct iguana_info *coin); +void iguana_gotdata(struct iguana_info *coin,struct iguana_peer *addr,int32_t height); +//int64_t iguana_getbalance(struct iguana_info *coin,uint64_t *creditsp,uint64_t *debitsp,int32_t *nump,uint32_t *unspents,long max,struct iguana_pkhash *P,uint32_t pkind); +int32_t iguana_queueblock(struct iguana_info *coin,int32_t height,bits256 hash2,int32_t priority); +int32_t iguana_updatewaiting(struct iguana_info *coin,int32_t starti,int32_t max); + +// recvbits +int32_t iguana_recvinit(struct iguana_info *coin,int32_t initialheight); +int32_t ramcoder_decompress(uint8_t *data,int32_t maxlen,uint8_t *bits,uint32_t numbits,bits256 seed); +int32_t ramcoder_compress(uint8_t *bits,int32_t maxlen,uint8_t *data,int32_t datalen,bits256 seed); +uint64_t hconv_bitlen(uint64_t bitlen); +struct iguana_block *iguana_blockptr(char *debugstr,struct iguana_info *coin,int32_t height); +int32_t iguana_processrecv(struct supernet_info *myinfo,struct iguana_info *coin); // single threaded +//void iguana_recvalloc(struct iguana_info *coin,int32_t numitems); +void iguana_coins(void *arg); +int32_t iguana_savehdrs(struct iguana_info *coin); + +// hdrs +struct iguana_bundle *iguana_bundlecreate(struct iguana_info *coin,int32_t *bundleip,int32_t bundleheight,bits256 bundlehash2,bits256 allhash,int32_t issueflag); +struct iguana_block *iguana_updatehdrs(struct iguana_info *coin,int32_t *newhwmp,struct iguana_block *block,bits256 prevhash2,bits256 hash2); +void iguana_parseline(struct supernet_info *myinfo,struct iguana_info *coin,int32_t iter,FILE *fp); +int32_t iguana_gotheadersM(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_zblock *zblocks,int32_t n); +void iguana_emittxdata(struct iguana_info *coin,struct iguana_bundle *bp); +int32_t iguana_pollQsPT(struct iguana_info *coin,struct iguana_peer *addr); +int32_t iguana_avail(struct iguana_info *coin,int32_t height,int32_t n); +int32_t iguana_updatebundles(struct iguana_info *coin); +uint64_t iguana_utxoaddrtablefind(struct iguana_info *coin,int16_t search_hdrsi,uint32_t search_pkind,uint8_t rmd160[20]); +void iguana_bundlestats(struct supernet_info *myinfo,struct iguana_info *coin,char *str,int32_t lag); +void iguana_chaininit(struct iguana_chain *chain,int32_t hasheaders,cJSON *argjson); +void iguana_coinargs(char *symbol,int64_t *maxrecvcachep,int32_t *minconfirmsp,int32_t *maxpeersp,int32_t *initialheightp,uint64_t *servicesp,int32_t *maxrequestsp,int32_t *maxbundlesp,cJSON *json); +struct iguana_info *iguana_setcoin(char *symbol,void *launched,int32_t maxpeers,int64_t maxrecvcache,uint64_t services,int32_t initialheight,int32_t maphash,int32_t minconfirms,int32_t maxrequests,int32_t maxbundles,cJSON *json,int32_t virtcoin); + +// init +struct iguana_info *iguana_coinstart(struct iguana_info *coin,int32_t initialheight,int32_t mapflags); +void iguana_callcoinstart(struct supernet_info *myinfo,struct iguana_info *coin); +void iguana_initcoin(struct iguana_info *coin,cJSON *argjson); +void iguana_coinloop(void *arg); + +// utils +double PoW_from_compact(uint32_t nBits,uint8_t unitval); +void calc_rmd160(char *hexstr,uint8_t buf[20],uint8_t *msg,int32_t len); +void calc_OP_HASH160(char *hexstr,uint8_t hash160[20],char *msg); +double dxblend(double *destp,double val,double decay); + +// json +int32_t iguana_processjsonQ(struct iguana_info *coin); // reentrant, can be called during any idletime +char *iguana_JSON(char *,uint16_t port); +char *SuperNET_p2p(struct iguana_info *coin,struct iguana_peer *addr,int32_t *delaymillisp,char *ipaddr,uint8_t *data,int32_t datalen,int32_t compressed); + +char *mbstr(char *str,double); +int init_hexbytes_noT(char *hexbytes,unsigned char *message,long len); +int32_t decode_hex(unsigned char *bytes,int32_t n,char *hex); +char hexbyte(int32_t c); +char *clonestr(char *str); +long _stripwhite(char *buf,int accept); +int32_t myatoi(char *str,int32_t range); +int32_t safecopy(char *dest,char *src,long len); +void escape_code(char *escaped,char *str); +int32_t is_zeroes(char *str); +int64_t conv_floatstr(char *numstr); +int32_t has_backslash(char *str); + +struct iguana_thread *iguana_launch(struct iguana_info *coin,char *name,iguana_func funcp,void *arg,uint8_t type); +int32_t iguana_numthreads(struct iguana_info *coin,int32_t mask); +void iguana_terminator(void *arg); + +int32_t is_hexstr(char *str,int32_t n); +void iguana_initQ(queue_t *Q,char *name); +void iguana_emitQ(struct iguana_info *coin,struct iguana_bundle *bp); +void iguana_txdataQ(struct iguana_info *coin,struct iguana_peer *addr,FILE *fp,long fpos,int32_t datalen); +void iguana_helper(void *arg); + +struct iguana_helper { struct queueitem DL; void *coin,*addr,*bp,*nextbp,*fp; long fpos; int32_t allocsize,type,hdrsi,bundlei,datalen,timelimit; uint32_t starttime; }; +int32_t iguana_helpertask(FILE *fp,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_helper *ptr); +void iguana_flushQ(struct iguana_info *coin,struct iguana_peer *addr); +//struct iguana_txdatabits iguana_peerfilePT(struct iguana_info *coin,struct iguana_peer *addr,bits256 hash2,struct iguana_txdatabits txdatabits,int32_t recvlen); +struct iguana_txdatabits iguana_calctxidbits(uint32_t addrind,uint32_t filecount,uint32_t fpos,uint32_t datalen); +int32_t iguana_bundlesaveHT(struct supernet_info *myinfo,struct iguana_info *coin,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_bundle *bp,uint32_t starttime); // helper thread +int32_t iguana_bundlemergeHT(struct supernet_info *myinfo,char *fname,struct iguana_info *coin,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_bundle *bp,struct iguana_bundle *nextbp,uint32_t starttime); // helper thread + +void iguana_peerfilename(struct iguana_info *coin,char *fname,uint32_t addrind,uint32_t filecount); + +struct iguana_txblock *iguana_ramchainptrs(struct iguana_txid **Tptrp,struct iguana_unspent20 **Uptrp,struct iguana_spend256 **Sptrp,struct iguana_pkhash **Pptrp,bits256 **externalTptrp,struct OS_memspace *mem,struct iguana_txblock *origtxdata); + +int32_t iguana_ramchainsave(struct iguana_info *coin,struct iguana_ramchain *ramchain); +int32_t iguana_ramchainfree(struct iguana_info *coin,struct OS_memspace *mem,struct iguana_ramchain *ramchain); +struct iguana_ramchain *iguana_ramchainmergeHT(struct iguana_info *coin,struct OS_memspace *mem,struct iguana_ramchain *ramchains[],int32_t n,struct iguana_bundle *bp); +void iguana_ramchainmerge(struct iguana_info *coin); + +int32_t iguana_blockQ(char *argstr,struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,int32_t priority); +void iguana_blockcopy(uint8_t zcash,uint8_t auxpow,struct iguana_info *coin,struct iguana_block *block,struct iguana_block *origblock); +int32_t iguana_rpctest(struct iguana_info *coin); +extern queue_t helperQ; +extern const char *Hardcoded_coins[][3]; +void iguana_main(void *arg); + +int32_t iguana_peerfname(struct iguana_info *coin,int32_t *hdrsip,char *dirname,char *fname,uint32_t ipbits,bits256 hash2,bits256 prevhash2,int32_t numblocks,int32_t dispflag); +struct iguana_txblock *iguana_peertxdata(struct iguana_info *coin,int32_t *bundleip,char *fname,struct OS_memspace *mem,uint32_t ipbits,bits256 hash2); +int32_t iguana_peerfile_exists(struct iguana_info *coin,struct iguana_peer *addr,char *dirname,char *fname,bits256 hash2,bits256 prevhash2,int32_t numblocks); +struct iguana_ramchain *iguana_ramchainset(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct iguana_txblock *txdata); +void *iguana_iAddriterator(struct iguana_info *coin,struct iguana_iAddr *iA); +long iguana_ramchain_data(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_txblock *origtxdata,struct iguana_msgtx *txarray,int32_t txn_count,uint8_t *data,int32_t recvlen); +int32_t iguana_bundlehash2add(struct iguana_info *coin,struct iguana_block **blockp,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2); +struct iguana_block *iguana_bundleblockadd(struct iguana_info *coin,struct iguana_bundle **bpp,int32_t *bundleip,struct iguana_block *origblock); +int32_t iguana_chainextend(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_block *newblock); +int32_t iguana_blockvalidate(struct iguana_info *coin,int32_t *validp,struct iguana_block *block,int32_t dispflag); +char *iguana_bundledisp(struct iguana_info *coin,struct iguana_bundle *prevbp,struct iguana_bundle *bp,struct iguana_bundle *nextbp,int32_t m); +struct iguana_bundle *iguana_bundlefind(struct iguana_info *coin,struct iguana_bundle **bpp,int32_t *bundleip,bits256 hash2); +//int32_t iguana_chainheight(struct iguana_info *coin,struct iguana_block *origblock); +bits256 *iguana_blockhashptr(struct iguana_info *coin,int32_t height); +int32_t iguana_hash2set(struct iguana_info *coin,char *debugstr,struct iguana_bundle *bp,int32_t bundlei,bits256 newhash2); +struct iguana_block *_iguana_chainlink(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_block *newblock); +int32_t iguana_hashfree(struct iguana_kvitem *hashtable,int32_t freeitem); +int32_t iguana_processbundlesQ(struct iguana_info *coin,int32_t *newhwmp); // single threaded +int32_t iguana_ramchainverifyPT(struct iguana_info *coin,struct iguana_ramchain *ramchain); +void *map_file(char *fname,long *filesizep,int32_t enablewrite); +void iguana_rpcloop(void *args); +int32_t iguana_socket(int32_t bindflag,char *hostname,uint16_t port); +void iguana_mergeQ(struct iguana_info *coin,struct iguana_bundle *bp,struct iguana_bundle *nextbp); + +#define bits256_nonz(a) (((a).ulongs[0] | (a).ulongs[1] | (a).ulongs[2] | (a).ulongs[3]) != 0) +//int32_t btc_addr2univ(uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr); + +struct iguana_agent +{ + char name[32],hostname[64]; void *methods; uint16_t port; int32_t sock,nummethods; + bits256 pubkey,privkey; + char *(*parsefunc)(struct iguana_agent *agent,char *method,void *json,char *remoteaddr); +}; + +int32_t iguana_txbytes(struct iguana_info *coin,uint8_t *serialized,int32_t maxlen,bits256 *txidp,struct iguana_txid *tx,int32_t height,struct iguana_msgvin *vins,struct iguana_msgvout *vouts); +int32_t iguana_vinset(struct iguana_info *coin,uint8_t *scriptspace,int32_t height,struct iguana_msgvin *vin,struct iguana_txid *tx,int32_t i); +int32_t iguana_voutset(struct iguana_info *coin,uint8_t *scriptspace,char *asmstr,int32_t height,struct iguana_msgvout *vout,struct iguana_txid *tx,int32_t i); +//int32_t btc_convrmd160(char *coinaddr,uint8_t addrtype,uint8_t rmd160[20]); +struct iguana_txid *iguana_bundletx(struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei,struct iguana_txid *tx,int32_t txidind); +int32_t iguana_txidreq(struct iguana_info *coin,char **retstrp,bits256 txid); +void iguana_bundleiclear(struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei); +int32_t hcalc_bitsize(uint64_t x); +struct iguana_txid *iguana_txidfind(struct iguana_info *coin,int32_t *heightp,struct iguana_txid *tx,bits256 txid,int32_t lasthdrsi); +int32_t iguana_scriptgen(struct iguana_info *coin,int32_t *Mp,int32_t *nump,char *coinaddr,uint8_t *script,char *asmstr,uint8_t rmd160[20],uint8_t type,const struct vin_info *vp,int32_t txi); +int32_t iguana_ramchain_spendtxid(struct iguana_info *coin,uint32_t *unspentindp,bits256 *txidp,struct iguana_txid *T,int32_t numtxids,bits256 *X,int32_t numexternaltxids,struct iguana_spend *s); +void iguana_dedicatedloop(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr); +struct iguana_peer *iguana_peerslot(struct iguana_info *coin,uint64_t ipbits,int32_t forceflag); +void iguana_dedicatedglue(void *arg); +void SuperNET_remotepeer(struct supernet_info *myinfo,struct iguana_info *coin,char *symbol,char *ipaddr,int32_t supernetflag); +void SuperNET_yourip(struct supernet_info *myinfo,char *yourip); +void iguana_peerkill(struct iguana_info *coin); +int32_t blockhash_sha256(uint8_t *blockhashp,uint8_t *serialized,int32_t len); +void iguana_nameset(char name[64],char *symbol,cJSON *json); + +char *busdata_sync(uint32_t *noncep,char *jsonstr,char *broadcastmode,char *destNXTaddr); +void peggy(); +int32_t opreturns_init(uint32_t blocknum,uint32_t blocktimestamp,char *path); +struct iguana_info *iguana_coinfind(char *symbol); +struct iguana_info *iguana_coinadd(char *symbol,char *nane,cJSON *json,int32_t virtcoin); +struct iguana_ramchain *iguana_bundleload(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct iguana_bundle *bp,int32_t extraflag); +int32_t iguana_sendblockreq(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,int32_t iamthreadsafe); +int32_t iguana_send_supernet(struct iguana_peer *addr,char *jsonstr,int32_t delay); + +struct iguana_waccount *iguana_waccountfind(struct supernet_info *myinfo,char *account); +struct iguana_waddress *iguana_waccountadd(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waccount **wacctp,char *walletaccount,char *coinaddr); +struct iguana_waddress *iguana_waccountswitch(struct supernet_info *myinfo,struct iguana_info *coin,char *account,char *coinaddr,char *redeemScript); +struct iguana_waddress *iguana_waddresscalc(struct supernet_info *myinfo,uint8_t pubval,uint8_t wiftype,struct iguana_waddress *addr,bits256 privkey); +struct iguana_waddress *iguana_waddressfind(struct supernet_info *myinfo,struct iguana_waccount *wacct,char *coinaddr); +char *iguana_coinjson(struct iguana_info *coin,char *method,cJSON *json); +cJSON *iguana_peersjson(struct iguana_info *coin,int32_t addronly); +//int32_t btc_priv2wif(char *wifstr,uint8_t privkey[32],uint8_t addrtype); +//int32_t btc_pub2rmd(uint8_t rmd160[20],uint8_t pubkey[33]); +int32_t iguana_launchcoin(struct supernet_info *myinfo,char *symbol,cJSON *json,int32_t virtcoin); +int32_t iguana_bundleinitmap(struct iguana_info *coin,struct iguana_bundle *bp,int32_t height,bits256 hash2,bits256 hash1); +int32_t iguana_jsonQ(); +int32_t is_bitcoinrpc(struct supernet_info *myinfo,char *method,char *remoteaddr); +char *iguana_bitcoinRPC(struct supernet_info *myinfo,char *method,cJSON *json,char *remoteaddr,uint16_t port); +cJSON *iguana_pubkeyjson(struct iguana_info *coin,char *pubkeystr); +void iguana_bundleQ(struct iguana_info *coin,struct iguana_bundle *bp,int32_t timelimit); +int32_t iguana_bundleiters(struct supernet_info *myinfo,struct iguana_info *coin,struct OS_memspace *mem,struct OS_memspace *memB,struct iguana_bundle *bp,int32_t timelimit,int32_t lag); +void ramcoder_test(void *data,int64_t len); +void iguana_exit(); +int32_t iguana_pendingaccept(struct iguana_info *coin); +char *iguana_blockingjsonstr(struct supernet_info *myinfo,char *jsonstr,uint64_t tag,int32_t maxmillis,char *remoteaddr,uint16_t port); +void iguana_iAkill(struct iguana_info *coin,struct iguana_peer *addr,int32_t markflag); +cJSON *SuperNET_bits2json(uint8_t *serialized,int32_t datalen); +int32_t SuperNET_sendmsg(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,bits256 destpub,bits256 mypriv,bits256 mypub,uint8_t *msg,int32_t len,uint8_t *data,int32_t delaymillis); +int32_t category_peer(struct supernet_info *myinfo,struct iguana_peer *addr,bits256 category,bits256 subhash); +int32_t bitcoin_wif2priv(uint8_t *addrtypep,bits256 *privkeyp,char *wifstr); +int32_t bitcoin_priv2wif(char *wifstr,bits256 privkey,uint8_t addrtype); +bits256 iguana_chaingenesis(char *symbol,uint8_t zcash,uint8_t auxpow,int32_t (*hashalgo)(uint8_t *blockhashp,uint8_t *serialized,int32_t len),bits256 genesishash,char *genesisblock,char *hashalgostr,int32_t version,uint32_t timestamp,uint32_t bits,uint32_t nonce,bits256 merkle_root); +int32_t iguana_send_ConnectTo(struct iguana_info *coin,struct iguana_peer *addr); +cJSON *iguana_txjson(struct iguana_info *coin,struct iguana_txid *tx,int32_t height,struct vin_info *V); +char *iguana_txscan(struct iguana_info *coin,cJSON *json,uint8_t *data,int32_t recvlen,bits256 txid); +char *iguana_rawtxbytes(struct iguana_info *coin,int32_t height,cJSON *json,struct iguana_msgtx *msgtx,int32_t suppress_pubkeys); +int32_t iguana_send_VPNversion(struct iguana_info *coin,struct iguana_peer *addr,uint64_t myservices); +void exchanges777_init(struct supernet_info *myinfo,cJSON *exchanges,int32_t sleepflag); +int32_t iguana_rwvout(int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized,struct iguana_msgvout *msg); +int32_t iguana_rwvin(int32_t rwflag,struct OS_memspace *mem,uint8_t *serialized,struct iguana_msgvin *msg); +int32_t iguana_rwmsgtx(struct iguana_info *coin,int32_t height,int32_t rwflag,cJSON *json,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,bits256 *txidp,char *vpnstr,uint8_t *extraspace,int32_t extralen,cJSON *vins,int32_t suppress_pubkeys); +int32_t iguana_ramtxbytes(struct iguana_info *coin,uint8_t *serialized,int32_t maxlen,bits256 *txidp,struct iguana_txid *tx,int32_t height,struct iguana_msgvin *vins,struct iguana_msgvout *vouts,int32_t validatesigs); +cJSON *bitcoin_txtest(struct iguana_info *coin,char *rawtxstr,bits256 txid); +cJSON *iguana_blockjson(struct iguana_info *coin,struct iguana_block *block,int32_t txidsflag); +int32_t iguana_rwblockhdr(int32_t rwflag,uint8_t zcash,uint8_t *serialized,struct iguana_msgblock *msg); +//int32_t iguana_sig(uint8_t *sig,int32_t maxsize,uint8_t *data,int32_t datalen,bits256 privkey); +//int32_t iguana_ver(uint8_t *sig,int32_t siglen,uint8_t *data,int32_t datalen,bits256 pubkey); +//int32_t iguana_ver(uint8_t *sig,int32_t siglen,uint8_t *data,int32_t datalen,uint8_t *pubkey); +void calc_rmd160_sha256(uint8_t rmd160[20],uint8_t *data,int32_t datalen); +int32_t bitcoin_checklocktimeverify(uint8_t *script,int32_t n,uint32_t locktime); +struct bitcoin_spend *iguana_spendset(struct supernet_info *myinfo,struct iguana_info *coin,int64_t amount,int64_t txfee,cJSON *addresses,int32_t minconf); +cJSON *bitcoin_hex2json(struct iguana_info *coin,int32_t height,bits256 *txidp,struct iguana_msgtx *msgtx,char *txbytes,uint8_t *extrapace,int32_t extralen,uint8_t *serialized,cJSON *vins,int32_t suppress_pubkeys); +cJSON *iguana_signtx(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,char **signedtxp,struct bitcoin_spend *spend,cJSON *txobj,cJSON *vins); +void iguana_addscript(struct iguana_info *coin,cJSON *dest,uint8_t *script,int32_t scriptlen,char *fieldname); +bits256 iguana_genesis(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_chain *chain); + +cJSON *bitcoin_txcreate(int32_t isPoS,int64_t locktime,uint32_t txversion); +cJSON *bitcoin_txoutput(cJSON *txobj,uint8_t *paymentscript,int32_t len,uint64_t satoshis); +cJSON *bitcoin_txinput(struct iguana_info *coin,cJSON *txobj,bits256 txid,int32_t vout,uint32_t sequenceid,uint8_t *spendscript,int32_t spendlen,uint8_t *redeemscript,int32_t p2shlen,uint8_t *pubkeys[],int32_t numpubkeys); + +int32_t bitcoin_changescript(struct iguana_info *coin,uint8_t *changescript,int32_t n,uint64_t *changep,char *changeaddr,uint64_t inputsatoshis,uint64_t satoshis,uint64_t txfee); +//cJSON *bitcoin_addinput(struct iguana_info *coin,cJSON *txobj,bits256 txid,int32_t vout,uint32_t sequenceid,uint8_t *spendscript,int32_t spendlen,uint8_t *redeemscript,int32_t p2shlen,uint8_t *pubkeys[],int32_t numpubkeys); +int32_t bitcoin_verifytx(struct iguana_info *coin,bits256 *signedtxidp,char **signedtx,char *rawtxstr,struct vin_info *V,int32_t numinputs); +int32_t bitcoin_verify(void *ctx,uint8_t *sig,int32_t siglen,bits256 txhash2,uint8_t *pubkey,int32_t plen); +char *bitcoin_json2hex(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,cJSON *txjson,struct vin_info *V); +int32_t bitcoin_addr2rmd160(uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr); +char *issue_startForging(struct supernet_info *myinfo,char *secret); +struct bitcoin_unspent *iguana_unspentsget(struct supernet_info *myinfo,struct iguana_info *coin,char **retstrp,double *balancep,int32_t *numunspentsp,double minconfirms,char *address); +void iguana_chainparms(struct iguana_chain *chain,cJSON *argjson); +int32_t iguana_RTpkhasharray(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *array,int32_t minconf,int32_t maxconf,uint64_t *totalp,struct iguana_pkhash *P,int32_t max,uint8_t rmd160[20],char *coinaddr,uint8_t *pubkey33,int32_t lastheight,struct iguana_outpoint *unspents,int32_t *numunspentsp,int32_t maxunspents,char *remoteaddr,int32_t includespent); +long iguana_spentsfile(struct iguana_info *coin,int32_t n); +uint8_t *iguana_rmdarray(struct supernet_info *myinfo,struct iguana_info *coin,int32_t *numrmdsp,cJSON *array,int32_t firsti); +int64_t iguana_RTunspents(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *array,int32_t minconf,int32_t maxconf,uint8_t *rmdarray,int32_t numrmds,int32_t lastheight,struct iguana_outpoint *unspents,int32_t *numunspentsp,char *remoteaddr,int32_t includespent); +uint8_t *iguana_walletrmds(struct supernet_info *myinfo,struct iguana_info *coin,int32_t *numrmdsp); +void iguana_hhutxo_purge(struct iguana_info *coin); +char *iguana_bundleaddrs(struct iguana_info *coin,int32_t hdrsi); +uint32_t iguana_sparseaddpk(uint8_t *bits,int32_t width,uint32_t tablesize,uint8_t rmd160[20],struct iguana_pkhash *P,uint32_t pkind,struct iguana_ramchain *ramchain); +int32_t iguana_vinscriptparse(struct iguana_info *coin,struct vin_info *vp,uint32_t *sigsizep,uint32_t *pubkeysizep,uint32_t *p2shsizep,uint32_t *suffixp,uint8_t *vinscript,int32_t scriptlen); +void iguana_parsebuf(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_msghdr *H,uint8_t *buf,int32_t len,int32_t fromcache); +int32_t _iguana_calcrmd160(struct iguana_info *coin,struct vin_info *vp); +int32_t iguana_spendvectors(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_bundle *bp,struct iguana_ramchain *ramchain,int32_t starti,int32_t numblocks,int32_t convertflag,int32_t iterate); +int32_t iguana_balancegen(struct iguana_info *coin,int32_t incremental,struct iguana_bundle *bp,int32_t startheight,int32_t endheight,int32_t startemit); +struct iguana_utxoaddr *iguana_utxoaddrfind(int32_t createflag,struct iguana_info *coin,int16_t hdrsi,uint32_t pkind,uint8_t rmd160[20],struct iguana_utxoaddr **prevp); +int32_t iguana_bundlevalidate(struct iguana_info *coin,struct iguana_bundle *bp,int32_t forceflag); +void iguana_validateQ(struct iguana_info *coin,struct iguana_bundle *bp); +struct iguana_bloominds iguana_calcbloom(bits256 hash2); +int32_t iguana_bloomfind(struct iguana_info *coin,struct iguana_bloom16 *bloom,int32_t incr,struct iguana_bloominds bit); +struct iguana_bloominds iguana_bloomset(struct iguana_info *coin,struct iguana_bloom16 *bloom,int32_t incr,struct iguana_bloominds bit); +int32_t iguana_Xspendmap(struct iguana_info *coin,struct iguana_ramchain *ramchain,struct iguana_bundle *bp); +//void iguana_balancesQ(struct iguana_info *coin,struct iguana_bundle *bp); +int32_t iguana_balanceflush(struct supernet_info *myinfo,struct iguana_info *coin,int32_t refhdrsi); +int32_t iguana_bundleissue(struct iguana_info *coin,struct iguana_bundle *bp,int32_t starti,int32_t max); +int32_t iguana_balancecalc(struct iguana_info *coin,struct iguana_bundle *bp,int32_t startheight,int32_t endheight); +int32_t iguana_sendblockreqPT(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_bundle *bp,int32_t bundlei,bits256 hash2,int32_t iamthreadsafe); +int32_t iguana_blockreq(struct iguana_info *coin,int32_t height,int32_t priority); +int64_t iguana_bundlecalcs(struct iguana_info *coin,struct iguana_bundle *bp,int32_t lag); +int32_t iguana_ramchain_prefetch(struct iguana_info *coin,struct iguana_ramchain *ramchain,int32_t txonly); +int32_t iguana_realtime_update(struct supernet_info *myinfo,struct iguana_info *coin); +int32_t iguana_volatilesmap(struct iguana_info *coin,struct iguana_ramchain *ramchain); +void iguana_volatilespurge(struct iguana_info *coin,struct iguana_ramchain *ramchain); +int32_t iguana_volatilesinit(struct supernet_info *myinfo,struct iguana_info *coin); +void iguana_initfinal(struct supernet_info *myinfo,struct iguana_info *coin,bits256 lastbundle); +int64_t iguana_ramchainopen(char *fname,struct iguana_info *coin,struct iguana_ramchain *ramchain,struct OS_memspace *mem,struct OS_memspace *hashmem,int32_t bundleheight,bits256 hash2); +int32_t iguana_ramchain_free(struct iguana_info *coin,struct iguana_ramchain *ramchain,int32_t deleteflag); +void iguana_blocksetcounters(struct iguana_info *coin,struct iguana_block *block,struct iguana_ramchain * ramchain); +int32_t iguana_ramchain_iterate(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_ramchain *dest,struct iguana_ramchain *ramchain,struct iguana_bundle *bp,int16_t bundlei); +void *iguana_bundlefile(struct iguana_info *coin,char *fname,long *filesizep,struct iguana_bundle *bp,int32_t bundlei); +int32_t iguana_mapchaininit(char *fname,struct iguana_info *coin,struct iguana_ramchain *mapchain,struct iguana_bundle *bp,int32_t bundlei,struct iguana_block *block,void *ptr,long filesize); +void iguana_RTdataset_free(struct iguana_info *coin); +void iguana_autoextend(struct iguana_info *coin,struct iguana_bundle *bp); +//void iguana_RTramchainfree(struct iguana_info *coin,struct iguana_bundle *bp); +void iguana_coinpurge(struct iguana_info *coin); +void tradebot_liquidity_command(struct supernet_info *myinfo,char *targetcoin,bits256 hash,cJSON *vals); +int32_t iguana_setmaxbundles(struct iguana_info *coin); +void iguana_bundlepurgefiles(struct iguana_info *coin,struct iguana_bundle *bp); +uint32_t iguana_sparseaddtx(uint8_t *bits,int32_t width,uint32_t tablesize,bits256 txid,struct iguana_txid *T,uint32_t txidind,struct iguana_ramchain *ramchain); +void iguana_launchpeer(struct iguana_info *coin,char *ipaddr,int32_t forceflag); +//void iguana_spendvectorsQ(struct iguana_info *coin,struct iguana_bundle *bp); +int8_t iguana_blockstatus(struct iguana_info *coin,struct iguana_block *block); +int32_t iguana_peerslotinit(struct iguana_info *coin,struct iguana_peer *addr,int32_t slotid,uint64_t ipbits); +void iguana_blockunmark(struct iguana_info *coin,struct iguana_block *block,struct iguana_bundle *bp,int32_t i,int32_t deletefile); +int32_t iguana_reqblocks(struct supernet_info *myinfo,struct iguana_info *coin); +void iguana_walletlock(struct supernet_info *myinfo,struct iguana_info *coin); +int32_t _SuperNET_encryptjson(struct supernet_info *myinfo,char *destfname,char *passphrase,int32_t passsize,char *fname2fa,int32_t fnamesize,cJSON *argjson); +int32_t bitcoin_pubkeylen(const uint8_t *pubkey); +struct iguana_block *iguana_bundleblock(struct iguana_info *coin,bits256 *hash2p,struct iguana_bundle *bp,int32_t i); +void *iguana_ramchainfile(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_ramchain *dest,struct iguana_ramchain *R,struct iguana_bundle *bp,int32_t bundlei,struct iguana_block *block); +int32_t iguana_bundlehashadd(struct iguana_info *coin,struct iguana_bundle *bp,int32_t bundlei,struct iguana_block *block); +int32_t iguana_convert(struct iguana_info *coin,int32_t helperid,struct iguana_bundle *bp,int32_t RTflag,int32_t starti); +int32_t iguana_bundleissuemissing(struct iguana_info *coin,struct iguana_bundle *bp,int32_t priority,double mult); +FILE *myfopen(char *fname,char *mode); +int32_t myfclose(FILE *fp); +int32_t iguana_walkchain(struct iguana_info *coin,int32_t skipflag); +struct iguana_block *iguana_fastlink(struct iguana_info *coin,int32_t hwmheight); +int32_t iguana_balancenormal(struct iguana_info *coin,struct iguana_bundle *bp,int32_t startheight,int32_t endheight); +int32_t iguana_spendvectorsaves(struct iguana_info *coin); +int32_t iguana_convertfinished(struct iguana_info *coin); +int32_t iguana_emitfinished(struct iguana_info *coin,int32_t queueincomplete); +int32_t iguana_utxofinished(struct iguana_info *coin); +int32_t iguana_balancefinished(struct iguana_info *coin); +int32_t iguana_alloctxbits(struct iguana_info *coin,struct iguana_ramchain *ramchain); +void iguana_allocvolatile(struct iguana_info *coin,struct iguana_ramchain *ramchain); +int32_t iguana_rwaddr(int32_t rwflag,uint8_t *serialized,struct iguana_msgaddress *addr,int32_t protover); +struct iguana_bundle *iguana_bundleset(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_block **blockp,int32_t *bundleip,struct iguana_block *origblock); +struct iguana_waddress *iguana_waddresscreate(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waccount *wacct,char *coinaddr,char *redeemScript); + +int32_t iguana_peerhdrrequest(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_peer *addr,bits256 hash2); +int32_t iguana_peeraddrrequest(struct iguana_info *coin,struct iguana_peer *addr,uint8_t *space,int32_t max); +int32_t iguana_peerdatarequest(struct iguana_info *coin,struct iguana_peer *addr,uint8_t *space,int32_t max); +int32_t iguana_peergetrequest(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,uint8_t *data,int32_t recvlen,int32_t getblock); +int32_t iguana_bundlefname(struct iguana_info *coin,struct iguana_bundle *bp,char *fname); +int32_t iguana_bundleremove(struct iguana_info *coin,int32_t hdrsi,int32_t tmpfiles); +int32_t iguana_voutsfname(struct iguana_info *coin,int32_t roflag,char *fname,int32_t slotid); +int32_t iguana_vinsfname(struct iguana_info *coin,int32_t roflag,char *fname,int32_t slotid); +bits256 iguana_merkle(bits256 *tree,int32_t txn_count); +int32_t iguana_bundleready(struct iguana_info *coin,struct iguana_bundle *bp,int32_t requiredflag); +int32_t iguana_blast(struct iguana_info *coin,struct iguana_peer *addr); +int32_t iguana_validated(struct iguana_info *coin); +void iguana_volatilesalloc(struct iguana_info *coin,struct iguana_ramchain *ramchain,int32_t copyflag); +int32_t iguana_send_ping(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr); +int32_t iguana_process_msgrequestQ(struct supernet_info *myinfo,struct iguana_info *coin); +uint32_t iguana_fastfindinit(struct iguana_info *coin); +int32_t iguana_unspentindfind(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr,uint8_t *spendscript,int32_t *scriptlenp,uint64_t *valuep,int32_t *heightp,bits256 txid,int32_t vout,int32_t lasthdrsi,int32_t mempool); +int32_t iguana_RTunspentindfind(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr,uint8_t *spendscript,int32_t *scriptlenp,uint64_t *valuep,int32_t *heightp,bits256 txid,int32_t vout,int32_t lasthdrsi,int32_t mempool); +int32_t iguana_addressvalidate(struct iguana_info *coin,uint8_t *addrtypep,char *address); +int32_t bitcoin_sign(void *ctx,char *symbol,uint8_t *sig,bits256 txhash2,bits256 privkey,int32_t recoverflag); +struct iguana_utxo iguana_utxofind(struct iguana_info *coin,struct iguana_outpoint spentpt,int32_t *RTspendflagp,int32_t lockflag); +bits256 iguana_str2priv(struct supernet_info *myinfo,struct iguana_info *coin,char *str); +int32_t iguana_RTspentflag(struct supernet_info *myinfo,struct iguana_info *coin,int64_t *RTspendp,int32_t *spentheightp,struct iguana_ramchain *ramchain,struct iguana_outpoint spentpt,int32_t height,int32_t minconf,int32_t maxconf,uint64_t amount); +int32_t iguana_RTspentflag(struct supernet_info *myinfo,struct iguana_info *coin,int64_t *RTspendp,int32_t *spentheightp,struct iguana_ramchain *ramchain,struct iguana_outpoint spentpt,int32_t height,int32_t minconf,int32_t maxconf,uint64_t amount); +int32_t iguana_voutscript(struct iguana_info *coin,struct iguana_bundle *bp,uint8_t *scriptspace,char *asmstr,struct iguana_unspent *u,struct iguana_pkhash *p,int32_t txi); +struct iguana_RTaddr *iguana_RTaddrfind(struct iguana_info *coin,uint8_t *rmd160,char *coinaddr); +cJSON *iguana_RTunspentjson(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_outpoint outpt,bits256 txid,int32_t vout,int64_t value,struct iguana_unspent *up,uint8_t rmd160[20],char *coinaddr,uint8_t *pubkey33,int32_t spentheight,char *remoteaddr); +int32_t bitcoin_standardspend(uint8_t *script,int32_t n,uint8_t rmd160[20]); +struct iguana_waddress *iguana_waddresssearch(struct supernet_info *myinfo,struct iguana_waccount **wacctp,char *coinaddr); +cJSON *iguana_RTlistunspent(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *argarray,int32_t minconf,int32_t maxconf,char *remoteaddr); +void calc_shares(struct supernet_info *myinfo,uint8_t *shares,uint8_t *secret,int32_t size,int32_t width,int32_t M,int32_t N,uint8_t *sharenrs,uint8_t *space,int32_t spacesize); +struct basilisk_spend *basilisk_addspend(struct supernet_info *myinfo,char *symbol,bits256 txid,uint16_t vout,int32_t addflag); +int64_t _RTgettxout(struct iguana_info *coin,int32_t *height,int32_t *scriptlen,uint8_t *script,uint8_t *rmd160,char *coinaddr,bits256 txid,int32_t vout,int32_t mempool); +int32_t _iguana_RTunspentfind(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,int32_t *voutp,uint8_t *spendscript,struct iguana_outpoint outpt,int64_t value); +int32_t basilisk_unspentfind(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,int32_t *voutp,uint8_t *spendscript,struct iguana_outpoint outpt,int64_t value); +int64_t iguana_addressreceived(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *json,char *remoteaddr,cJSON *txids,cJSON *vouts,cJSON *unspents,cJSON *spends,char *coinaddr,int32_t minconf,int32_t firstheight); +cJSON *iguana_walletjson(struct supernet_info *myinfo); +int32_t iguana_payloadupdate(struct supernet_info *myinfo,struct iguana_info *coin,char *retstr,struct iguana_waddress *waddr,char *account); +int32_t bitcoin_MofNspendscript(uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,const struct vin_info *vp); +void basilisk_unspents_update(struct supernet_info *myinfo,struct iguana_info *coin); +struct iguana_txid *iguana_blocktx(struct iguana_info *coin,struct iguana_txid *tx,struct iguana_block *block,int32_t i); +cJSON *iguana_p2shjson(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *retjson,struct iguana_waddress *waddr); +char *setaccount(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waddress **waddrp,char *account,char *coinaddr,char *redeemScript); +char *iguana_APIrequest(struct iguana_info *coin,bits256 blockhash,bits256 txid,int32_t seconds); +int32_t bitcoin_verifyvins(struct iguana_info *coin,int32_t height,bits256 *signedtxidp,char **signedtx,struct iguana_msgtx *msgtx,uint8_t *serialized,int32_t maxsize,struct vin_info *V,int32_t sighash,int32_t signtx,int32_t suppress_pubkeys); +char *iguana_validaterawtx(struct supernet_info *myinfo,struct iguana_info *coin,int32_t height,struct iguana_msgtx *msgtx,uint8_t *extraspace,int32_t extralen,char *rawtx,int32_t mempool,int32_t suppress_pubkeys); +int64_t iguana_fastfindcreate(struct iguana_info *coin); +int32_t bitcoin_validaddress(struct iguana_info *coin,char *coinaddr); +int32_t iguana_volatileupdate(struct iguana_info *coin,int32_t incremental,struct iguana_ramchain *spentchain,int16_t spent_hdrsi,uint32_t spent_unspentind,uint32_t spent_pkind,uint64_t spent_value,uint32_t spendind,uint32_t fromheight); +void iguana_utxoaddrs_purge(struct iguana_info *coin); +int32_t iguana_utxoupdate(struct iguana_info *coin,int16_t spent_hdrsi,uint32_t spent_unspentind,uint32_t spent_pkind,uint64_t spent_value,uint32_t spendind,uint32_t fromheight,uint8_t *rmd160); +int32_t iguana_RTunspentslists(struct supernet_info *myinfo,struct iguana_info *coin,uint64_t *totalp,struct iguana_outpoint *unspents,int32_t max,uint64_t required,int32_t minconf,cJSON *addresses,char *remoteaddr); +int64_t iguana_unspentset(struct supernet_info *myinfo,struct iguana_info *coin); +int32_t iguana_txidfastfind(struct iguana_info *coin,int32_t *heightp,bits256 txid,int32_t lasthdrsi); +uint8_t iguana_addrtype(struct iguana_info *coin,uint8_t script_type); +struct iguana_waddress *iguana_waddressadd(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_waccount *wacct,struct iguana_waddress *addwaddr,char *redeemScript); +cJSON *iguana_createvins(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *txobj,cJSON *vins); +bits256 bitcoin_pubkey33(void *ctx,uint8_t *data,bits256 privkey); +bits256 bitcoin_randkey(void *ctx); +int32_t bitcoin_recoververify(void *ctx,char *symbol,uint8_t *sig64,bits256 messagehash2,uint8_t *pubkey); +int32_t bitcoin_assembler(struct iguana_info *coin,cJSON *logarray,uint8_t script[IGUANA_MAXSCRIPTSIZE],cJSON *scriptobj,int32_t interpret,int64_t nLockTime,struct vin_info *V); +cJSON *iguana_spendasm(struct iguana_info *coin,uint8_t *spendscript,int32_t spendlen); +uint64_t iguana_unspentavail(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_outpoint outpt,int32_t minconf,int32_t maxconf); +int32_t iguana_RTutxofunc(struct iguana_info *coin,int32_t *fromheightp,int32_t *lockedflagp,struct iguana_outpoint spentpt,int32_t *RTspendflagp,int32_t lockflag,int32_t spentheight); +int32_t iguana_signrawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,int32_t height,struct iguana_msgtx *msgtx,char **signedtxp,bits256 *signedtxidp,struct vin_info *V,int32_t numinputs,char *rawtx,cJSON *vins,cJSON *privkeys); +cJSON *iguana_privkeysjson(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *vins); +char *iguana_RTinputaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr,struct iguana_outpoint *spentptp,cJSON *vinobj); +struct iguana_waddress *iguana_getaccountaddress(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *json,char *remoteaddr,char *coinaddr,char *account); +int32_t iguana_RTuvaltxid(struct supernet_info *myinfo,bits256 *txidp,struct iguana_info *coin,struct iguana_outpoint outpt); +struct instantdex_accept *instantdex_quotefind(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,bits256 encodedhash); +int32_t instantdex_quoterequest(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t *serialized,int32_t maxlen,struct iguana_peer *addr,bits256 encodedhash); +int32_t instantdex_peerhas_clear(struct iguana_info *coin,struct iguana_peer *addr); +int32_t instantdex_quotep2p(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,uint8_t *serialized,int32_t recvlen); +void instantdex_update(struct supernet_info *myinfo); +cJSON *iguana_getaddressesbyaccount(struct supernet_info *myinfo,struct iguana_info *coin,char *account); +int32_t iguana_interpreter(struct iguana_info *coin,cJSON *logarray,int64_t nLockTime,struct vin_info *V,int32_t numvins); +int32_t iguana_parsevinobj(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_msgvin *vin,cJSON *vinobj,struct vin_info *V); +//int64_t iguana_availunspents(struct supernet_info *myinfo,uint64_t **unspentsp,int32_t *nump,struct iguana_info *coin,int32_t minconf,char *account,void *ptr,int32_t maxsize); +char *iguana_signunspents(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *signedtxidp,int32_t *completedp,cJSON *txobj,uint64_t satoshis,char *changeaddr,uint64_t txfee,struct iguana_outpoint *unspents,int32_t num); +bits256 iguana_sendrawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,char *signedtx); +int32_t iguana_inv2packet(uint8_t *serialized,int32_t maxsize,int32_t type,bits256 *hashes,int32_t n); +int32_t instantdex_inv2data(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_peer *addr,struct exchange_info *exchange); +struct iguana_bundlereq *instantdex_recvquotes(struct iguana_info *coin,struct iguana_bundlereq *req,bits256 *encodedhash,int32_t n); +struct exchange_info *exchange_create(char *exchangestr,cJSON *argjson); +int32_t iguana_inv2poll(struct supernet_info *myinfo,struct iguana_info *coin); +struct iguana_bundlereq *iguana_bundlereq(struct iguana_info *coin,struct iguana_peer *addr,int32_t type,uint8_t *data,int32_t datalen); +void instantdex_FSMinit(); +int32_t bitcoin_p2shspend(uint8_t *script,int32_t n,uint8_t rmd160[20]); +void iguana_RTunspentslock(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *vins); +char *iguana_calcrawtx(struct supernet_info *myinfo,struct iguana_info *coin,cJSON **vinsp,cJSON *txobj,int64_t satoshis,char *changeaddr,int64_t txfee,cJSON *addresses,int32_t minconf,uint8_t *opreturn,int32_t oplen,int64_t burnamount,char *remoteaddr); +int64_t datachain_update(struct supernet_info *myinfo,int32_t ordered,struct iguana_info *coin,uint32_t timestamp,struct iguana_bundle *bp,uint8_t rmd160[20],int64_t crypto777_payment,uint8_t type,int32_t height,uint64_t hdrsi_unspentind,int64_t burned,uint32_t fileid,uint64_t scriptpos,int32_t scriptlen,bits256 txid,int32_t vout); +void datachain_update_spend(struct supernet_info *myinfo,int32_t ordered,struct iguana_info *coin,uint32_t timestamp,struct iguana_bundle *bp,int32_t height,bits256 txid,int32_t vout,uint8_t rmd160[20],int64_t value); +cJSON *bitcoin_data2json(struct iguana_info *coin,int32_t height,bits256 *txidp,struct iguana_msgtx *msgtx,uint8_t *extraspace,int32_t extralen,uint8_t *serialized,int32_t len,cJSON *vins,int32_t suppress_pubkeys); +int32_t iguana_unspentind2txid(struct supernet_info *myinfo,struct iguana_info *coin,int32_t *spentheightp,bits256 *txidp,int32_t *voutp,struct iguana_outpoint outpt); +int32_t iguana_RTunspent_check(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_outpoint outpt); +char *basilisk_bitcoinrawtx(struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,int32_t timeoutmillis,cJSON *valsobj); + +char *iguana_signrawtx(struct supernet_info *myinfo,struct iguana_info *coin,int32_t height,bits256 *signedtxidp,int32_t *completedp,cJSON *vins,char *rawtx,cJSON *privkey,struct vin_info *V); +bits256 scrypt_blockhash(const void *input); +bits256 iguana_calcblockhash(char *symbol,int32_t (*hashalgo)(uint8_t *blockhashp,uint8_t *serialized,int32_t len),uint8_t *serialized,int32_t len); +struct bitcoin_eventitem *instantdex_event(char *cmdstr,cJSON *argjson,cJSON *newjson,uint8_t *serdata,int32_t serdatalen); +void instantdex_eventfree(struct bitcoin_eventitem *ptr); +struct iguana_monitorinfo *iguana_txidmonitor(struct iguana_info *coin,bits256 txid); +struct iguana_monitorinfo *iguana_txidreport(struct iguana_info *coin,bits256 txid,struct iguana_peer *addr); +double iguana_txidstatus(struct supernet_info *myinfo,struct iguana_info *coin,bits256 txid); +void basilisk_functions(struct iguana_info *coin,int32_t protocol); +char *bitcoind_passthru(char *coinstr,char *serverport,char *userpass,char *method,char *params); +char *bitcoin_calcrawtx(struct supernet_info *myinfo,struct iguana_info *coin,cJSON **vinsp,int64_t satoshis,char *paymentscriptstr,char *changeaddr,int64_t txfee,cJSON *addresses,int32_t minconf,uint32_t locktime); +char *bitcoin_blockhashstr(char *coinstr,char *serverport,char *userpass,int32_t height); +bits256 basilisk_blockhash(struct iguana_info *coin,bits256 prevhash2); +void calc_scrypthash(uint32_t *hash,void *data); +int32_t iguana_rwvarstr(int32_t rwflag,uint8_t *serialized,int32_t maxlen,char *endianedp); +bits256 bitcoin_sharedsecret(void *ctx,bits256 privkey,uint8_t *pubkey,int32_t plen); +int32_t iguana_blockhdrsize(char *symbol,uint8_t zcash,uint8_t auxpow);//,uint8_t *serialized,int32_t maxlen); +int32_t iguana_blockROsize(uint8_t zcash); +void *iguana_blockzcopyRO(uint8_t zcash,struct iguana_blockRO *dest,int32_t desti,struct iguana_blockRO *src,int32_t srci); +void iguana_blockzcopy(uint8_t zcash,struct iguana_block *dest,struct iguana_block *src); +int32_t iguana_blocksizecheck(char *debugstr,uint8_t zcash,struct iguana_block *block); +void basilisk_miner(struct supernet_info *myinfo,struct iguana_info *btcd,struct iguana_info *virt,int32_t maxmillis,char *mineraddr); +int32_t bitcoin_pubkeyspend(uint8_t *script,int32_t n,uint8_t pubkey[66]); +int32_t basilisk_blocksubmit(struct supernet_info *myinfo,struct iguana_info *btcd,struct iguana_info *virt,struct iguana_peer *addr,char *blockstr,bits256 hash2,int32_t height); +struct supernet_info *SuperNET_MYINFO(char *passphrase); +bits256 calc_categoryhashes(bits256 *subhashp,char *category,char *subcategory); +struct gecko_chain *category_find(bits256 categoryhash,bits256 subhash); +void *category_subscribe(struct supernet_info *myinfo,bits256 category,bits256 keyhash); +char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey_or_rmd160,int32_t len); +char *SuperNET_JSON(struct supernet_info *myinfo,cJSON *json,char *remoteaddr,uint16_t port); +struct supernet_info *SuperNET_accountfind(cJSON *json); +cJSON *SuperNET_rosettajson(struct supernet_info *myinfo,bits256 privkey,int32_t showprivs); +double instantdex_aveprice(struct supernet_info *myinfo,struct exchange_quote *sortbuf,int32_t max,double *totalvolp,char *base,char *rel,double basevolume,cJSON *argjson); +char *SuperNET_keysinit(struct supernet_info *myinfo,char *argjsonstr); +char *SuperNET_parser(struct supernet_info *myinfo,char *agentstr,char *method,cJSON *json,char *remoteaddr); +char *SuperNET_htmlstr(char *fname,char *htmlstr,int32_t maxsize,char *agentstr); +void SuperNET_setkeys(struct supernet_info *myinfo,void *pass,int32_t passlen,int32_t dosha256); +int32_t iguana_headerget(struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_block *block); +int32_t iguana_bundlefinalize(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_bundle *bp,struct OS_memspace *mem,struct OS_memspace *memB); +bits256 iguana_parsetxobj(struct supernet_info *myinfo,struct iguana_info *coin,int32_t *txstartp,uint8_t *serialized,int32_t maxsize,struct iguana_msgtx *msg,cJSON *txobj,struct vin_info *V); +int32_t iguana_ROallocsize(struct iguana_info *virt); +uint64_t iguana_utxoaddr_gen(struct supernet_info *myinfo,struct iguana_info *coin,int32_t maxheight); +long iguana_bundlesload(struct supernet_info *myinfo,struct iguana_info *coin); +void basilisk_wait(struct supernet_info *myinfo,struct iguana_info *coin); +int32_t bitcoin_pubkey_combine(void *ctx,uint8_t *combined_pub,uint8_t *skipkey,bits256 *evenkeys,int32_t n,bits256 *oddkeys,int32_t m); +bits256 bitcoin_pub256(void *ctx,bits256 *privkeyp,uint8_t odd_even); +bits256 bitcoin_schnorr_noncepair(void *ctx,uint8_t *pubnonce,bits256 txhash2,bits256 privkey); +int32_t bitcoin_schnorr_combine(void *ctx,uint8_t *sig64,uint8_t *allpub,uint8_t **sigs,int32_t n,bits256 txhash2); +int32_t bitcoin_schnorr_verify(void *ctx,uint8_t *sig64,bits256 txhash2,uint8_t *pubkey,int32_t plen); +int32_t iguana_parsevoutobj(struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_msgvout *vout,cJSON *voutobj); +struct gecko_memtx *gecko_unspentfind(struct gecko_memtx ***ptrpp,struct iguana_info *virt,bits256 txid); +int64_t *gecko_valueptr(struct gecko_memtx *memtx,int32_t vout); +struct iguana_peer *iguana_peerfindipaddr(struct iguana_info *coin,char *ipaddr,int32_t needalive); +struct iguana_peer *iguana_peerfindipbits(struct iguana_info *coin,uint32_t ipbits,int32_t needalive); +//int32_t basilisk_relays_send(struct supernet_info *myinfo,struct iguana_peer *addr); +int32_t basilisk_hashes_send(struct supernet_info *myinfo,struct iguana_info *virt,struct iguana_peer *addr,char *CMD,bits256 *txids,int32_t num); +int32_t iguana_opreturn(struct supernet_info *myinfo,int32_t ordered,struct iguana_info *coin,uint32_t timestamp,struct iguana_bundle *bp,int64_t crypto777_payment,int32_t height,uint64_t hdrsi_unspentind,int64_t payment,uint32_t fileid,uint64_t scriptpos,uint32_t scriptlen); +int32_t iguana_scriptdata(struct iguana_info *coin,uint8_t *scriptspace,long fileptr[2],char *fname,uint64_t scriptpos,int32_t scriptlen); +struct iguana_peer *basilisk_ensurerelay(struct supernet_info *myinfo,struct iguana_info *btcd,uint32_t ipbits); +int32_t iguana_datachain_scan(struct supernet_info *myinfo,struct iguana_info *coin,uint8_t rmd160[20]); +int32_t iguana_RTramchaindata(struct supernet_info *myinfo,struct iguana_info *coin,struct OS_memspace *TXDATA,struct OS_memspace *HASHMEM,int64_t polarity,struct iguana_block *block,struct iguana_msgtx *txarray,int32_t txn_count); +struct iguana_RTtxid *iguana_RTtxid_create(struct iguana_info *coin,struct iguana_block *block,int64_t polarity,int32_t txi,int32_t txn_count,bits256 txid,int32_t numvouts,int32_t numvins,uint32_t locktime,uint32_t version,uint32_t timestamp,uint8_t *serialized,int32_t txlen); +void iguana_RTspend(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_RTtxid *RTptr,struct iguana_block *block,int64_t polarity,uint8_t *script,int32_t scriptlen,bits256 txid,int32_t vini,bits256 prev_hash,int32_t prev_vout); +void iguana_RTunspent(struct iguana_info *coin,struct iguana_RTtxid *RTptr,struct iguana_block *block,int64_t polarity,char *coinaddr,uint8_t *rmd160,int32_t type,uint8_t *script,int32_t scriptlen,bits256 txid,int32_t vout,int64_t value); + +void iguana_RTreset(struct iguana_info *coin); +void iguana_RTpurge(struct iguana_info *coin,int32_t lastheight); +void iguana_RTnewblock(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_block *block); +void *iguana_RTrawdata(struct iguana_info *coin,bits256 hash2,uint8_t *data,int32_t *recvlenp,int32_t *numtxp,int32_t checkonly); +int32_t iguana_bundlehash2_check(struct iguana_info *coin,bits256 hash2); +void iguana_RTramchainalloc(char *fname,struct iguana_info *coin,struct iguana_bundle *bp); +void iguana_update_balances(struct iguana_info *coin); +void iguana_RTspendvectors(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_bundle *bp); +int64_t iguana_RTbalance(struct iguana_info *coin,char *coinaddr); +double instantdex_avehbla(struct supernet_info *myinfo,double retvals[4],char *base,char *rel,double basevolume); +int32_t bitcoin_revealsecret160(uint8_t *script,int32_t n,uint8_t secret160[20]); +int64_t iguana_lockval(int32_t finalized,int64_t locktime); +int64_t *iguana_PoS_weights(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_pkhash **Ptrp,int64_t *supplyp,int32_t *numacctsp,int32_t *nonzp,int32_t *errsp,int32_t lastheight); +int32_t iguana_staker_sort(struct iguana_info *coin,bits256 *hash2p,uint8_t *refrmd160,struct iguana_pkhash *refP,int64_t *weights,int32_t numweights,bits256 *sortbuf); +bits256 mpz_div64(bits256 hash,uint64_t divval); +void iguana_walletinitcheck(struct supernet_info *myinfo,struct iguana_info *coin); + +// ------------------------------------------------------[ Preparation ]---- +// Initialise a gfshare context for producing shares +gfshare_ctx *gfshare_ctx_initenc(uint8_t * /* sharenrs */,uint32_t /* sharecount */, uint8_t /* threshold */,uint32_t /* size */,void *,int32_t); +// Initialise a gfshare context for recombining shares +gfshare_ctx *gfshare_ctx_initdec(uint8_t * /* sharenrs */,uint32_t /* sharecount */,uint32_t /* size */,void *,int32_t); +// Free a share context's memory +void gfshare_ctx_free(gfshare_ctx * /* ctx */); +// --------------------------------------------------------[ Splitting ]---- +// Provide a secret to the encoder. (this re-scrambles the coefficients) +void gfshare_ctx_enc_setsecret(gfshare_ctx * /* ctx */,uint8_t * /* secret */); +// Extract a share from the context. 'share' must be preallocated and at least 'size' bytes long. 'sharenr' is the index into the 'sharenrs' array of the share you want. +void gfshare_ctx_encgetshare(uint8_t *logs,uint8_t *exps,gfshare_ctx * /* ctx */,uint8_t /* sharenr */,uint8_t * /* share */); +// ----------------------------------------------------[ Recombination ]---- +// Inform a recombination context of a change in share indexes +void gfshare_ctx_dec_newshares(gfshare_ctx * /* ctx */, uint8_t * /* sharenrs */); +// Provide a share context with one of the shares. The 'sharenr' is the index into the 'sharenrs' array +void gfshare_ctx_dec_giveshare(gfshare_ctx * /* ctx */,uint8_t /* sharenr */,uint8_t * /* share */); +// Extract the secret by interpolation of the shares. secretbuf must be allocated and at least 'size' bytes long +void gfshare_ctx_decextract(uint8_t *logs,uint8_t *exps,gfshare_ctx * /* ctx */,uint8_t * /* secretbuf */); +void libgfshare_init(struct supernet_info *myinfo,uint8_t _logs[256],uint8_t _exps[510]); +int32_t init_sharenrs(uint8_t sharenrs[255],uint8_t *orig,int32_t m,int32_t n); +void iguana_schnorr(struct supernet_info *myinfo); + +#include "../includes/iguana_api.h" + + +#endif + diff --git a/includes/iguana_globals.h b/includes/iguana_globals.h new file mode 100755 index 000000000..8ff140ae9 --- /dev/null +++ b/includes/iguana_globals.h @@ -0,0 +1,91 @@ +/****************************************************************************** + * Copyright © 2014-2016 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#ifndef H_IGUANAGLOBALS_H +#define H_IGUANAGLOBALS_H + +#ifdef ACTIVELY_DECLARE +#define CONDEXTERN +int32_t PANGEA_MAXTHREADS = 1,MAX_DEPTH = 100; +char *Iguana_validcommands[] = +{ + "inv2", "getdata2", "ConnectTo", + "version", "verack", "getaddr", "addr", "inv", "getdata", "notfound", "getblocks", "getheaders", "headers", "tx", "block", "mempool", "ping", "pong", + "reject", "filterload", "filteradd", "filterclear", "merkleblock", "alert", "" +}; + +#ifdef __PNACL__ +char GLOBAL_TMPDIR[512] = "/tmp"; +char GLOBAL_DBDIR[512] = "DB"; +char GLOBAL_GENESISDIR[512] = "genesis"; +char GLOBAL_HELPDIR[512] = "DB/help"; +char GLOBAL_VALIDATEDIR[512] = "DB/purgeable"; +char GLOBAL_CONFSDIR[512] = "DB"; +int32_t IGUANA_NUMHELPERS = 1; +#else +char GLOBAL_TMPDIR[512] = "tmp"; +char GLOBAL_HELPDIR[512] = "help"; +char GLOBAL_DBDIR[512] = "DB"; +char GLOBAL_GENESISDIR[512] = "genesis"; +char GLOBAL_VALIDATEDIR[512] = "DB/purgeable"; +char GLOBAL_CONFSDIR[512] = "confs"; +#ifdef __linux +int32_t IGUANA_NUMHELPERS = 8; +#else +int32_t IGUANA_NUMHELPERS = 1; +#endif +#endif + +#else +#define CONDEXTERN extern +#endif + + +// ALL globals must be here! +CONDEXTERN struct basilisk_relay RELAYS[BASILISK_MAXRELAYS]; +CONDEXTERN int32_t NUMRELAYS,RELAYID; + +CONDEXTERN char *COMMANDLINE_ARGFILE; +CONDEXTERN char *Iguana_validcommands[]; +CONDEXTERN int32_t Showmode,Autofold,PANGEA_MAXTHREADS,QUEUEITEMS; + +CONDEXTERN struct gecko_chain *Categories; +CONDEXTERN struct iguana_info *Allcoins; +CONDEXTERN char Userhome[512]; +CONDEXTERN int32_t USE_JAY,FIRST_EXTERNAL,IGUANA_disableNXT,Debuglevel,IGUANA_BIGENDIAN; +CONDEXTERN uint32_t prices777_NXTBLOCK; +CONDEXTERN queue_t helperQ,jsonQ,finishedQ,bundlesQ,emitQ; +CONDEXTERN struct supernet_info MYINFO,**MYINFOS; +CONDEXTERN int32_t MAIN_initflag,MAX_DEPTH; +CONDEXTERN int32_t HDRnet,netBLOCKS; +CONDEXTERN cJSON *API_json; + +CONDEXTERN char GLOBAL_TMPDIR[512]; +CONDEXTERN char GLOBAL_DBDIR[512]; +CONDEXTERN char GLOBAL_GENESISDIR[512]; +CONDEXTERN char GLOBAL_HELPDIR[512]; +CONDEXTERN char GLOBAL_VALIDATEDIR[512]; +CONDEXTERN char GLOBAL_CONFSDIR[512]; +CONDEXTERN int32_t IGUANA_NUMHELPERS; + +#define CRYPTO777_PUBSECPSTR "020e46e79a2a8d12b9b5d12c7a91adb4e454edfae43c0a0cb805427d2ac7613fd9" +#define CRYPTO777_RMD160STR "f1dce4182fce875748c4986b240ff7d7bc3fffb0" +#define CRYPTO777_BTCADDR "1P3rU1Nk1pmc2BiWC8dEy9bZa1ZbMp5jfg" +#define CRYPTO777_BTCDADDR "RXL3YXG2ceaB6C5hfJcN4fvmLH2C34knhA" + +CONDEXTERN uint8_t CRYPTO777_RMD160[20],CRYPTO777_PUBSECP33[33]; + +#endif + diff --git a/includes/iguana_structs.h b/includes/iguana_structs.h new file mode 100755 index 000000000..1223095e8 --- /dev/null +++ b/includes/iguana_structs.h @@ -0,0 +1,539 @@ +/****************************************************************************** + * Copyright © 2014-2016 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#ifndef H_IGUANASTRUCTS_H +#define H_IGUANASTRUCTS_H + +struct iguana_thread +{ + struct queueitem DL; + pthread_t handle; + struct iguana_info *coin; + char name[16]; + uint8_t type; + iguana_func funcp; + void *arg; +}; + +struct iguana_blockreq { struct queueitem DL; bits256 hash2,*blockhashes; struct iguana_bundle *bp; int32_t n,height,bundlei; }; + +struct iguana_peermsgrequest { struct queueitem DL; struct iguana_peer *addr; bits256 hash2; int32_t type; }; + +struct iguana_chain +{ + //const int32_t chain_id; + char name[32],symbol[8],messagemagic[64]; + uint8_t pubtype,p2shtype,wiftype,netmagic[4]; + char *genesis_hash,*genesis_hex; // hex string + uint16_t portp2p,rpcport; + uint8_t isPoS,unitval; + uint64_t rewards[512][2]; + uint8_t genesis_hashdata[32],minconfirms; + uint16_t bundlesize,hasheaders; + char gethdrsmsg[16]; + uint64_t txfee,minoutput,dust,halvingduration,initialreward; + blockhashfunc hashalgo; + char userhome[512],serverport[128],userpass[1024]; + char use_addmultisig,do_opreturn; + int32_t estblocktime,protover; + bits256 genesishash2,PoWtarget,PoStargets[16]; int32_t numPoStargets,PoSheights[16]; + uint8_t zcash,auxpow,havecltv,alertpubkey[65]; + uint16_t targetspacing,targettimespan; uint32_t nBits,normal_txversion,locktime_txversion; +}; + +struct iguana_msgaddress { uint32_t nTime; uint64_t nServices; uint8_t ip[16]; uint16_t port; } __attribute__((packed)); + +struct iguana_msgversion +{ + uint32_t nVersion; + uint64_t nServices; + int64_t nTime; + struct iguana_msgaddress addrTo,addrFrom; + uint64_t nonce; + char strSubVer[80]; + uint32_t nStartingHeight; + uint8_t relayflag; +} __attribute__((packed)); + +struct iguana_msgalert // warning, many varints/variable length fields, struct is 1:1 +{ + int32_t version; + int64_t relayuntil,expiration; + int32_t ID,cancel; + uint32_t numcancellist; + int32_t minver,maxver; + uint32_t setsubvervar; char subver[1024]; + int32_t priority; + char comment[1024],statusbar[1024],reserved[1024]; + uint8_t siglen,sig[74]; + uint32_t list[64]; +}; + +struct iguana_VPNversion +{ + uint32_t nVersion; + uint64_t nServices; + int64_t nTime; + struct iguana_msgaddress addrTo,addrFrom; + uint64_t nonce; + char strSubVer[80]; + uint32_t nStartingHeight; + uint32_t iVer,v_Network_id; uint16_t wPort; uint8_t bIsGui; uint16_t wCtPort,wPrPort; +} __attribute__((packed)); + +struct iguana_msgblockhdr +{ + uint32_t version; + bits256 prev_block,merkle_root; + uint32_t timestamp,bits,nonce; +} __attribute__((packed)); + +#define ZKSNARK_PROOF_SIZE 584 +#define ZCASH_SOLUTION_ELEMENTS 32 + +struct iguana_msgblockhdr_zcash +{ + bits256 bignonce; + uint8_t numelements; + uint32_t solution[ZCASH_SOLUTION_ELEMENTS]; + //bits256 reserved; // only here if auxpow is set +} __attribute__((packed)); + +struct iguana_msgmerkle +{ + uint32_t branch_length; + bits256 branch_hash[4096]; + uint32_t branch_side_mask; +} __attribute__((packed)); + +struct iguana_msgblock +{ + struct iguana_msgblockhdr H; // double hashed for blockhash + struct iguana_msgblockhdr_zcash zH; + uint32_t txn_count; +} __attribute__((packed)); + +struct iguana_msgvin { bits256 prev_hash; uint8_t *vinscript,*userdata,*spendscript,*redeemscript; uint32_t prev_vout,sequence; uint16_t scriptlen,p2shlen,userdatalen,spendlen; } __attribute__((packed)); + +struct iguana_msgvout { uint64_t value; uint32_t pk_scriptlen; uint8_t *pk_script; } __attribute__((packed)); + +struct iguana_msgtx +{ + uint32_t version,tx_in,tx_out,lock_time; + struct iguana_msgvin *vins; + struct iguana_msgvout *vouts; + bits256 txid; + int32_t allocsize,timestamp,numinputs,numoutputs; + int64_t inputsum,outputsum,txfee; + uint8_t *serialized; +} __attribute__((packed)); + +struct iguana_msgjoinsplit +{ + uint64_t vpub_old,vpub_new; + bits256 anchor,nullifiers[2],commitments[2],ephemeralkey; + uint8_t ciphertexts[2][217]; + bits256 randomseed,vmacs[2]; + uint8_t zkproof[ZKSNARK_PROOF_SIZE-1]; +} __attribute__((packed)); + +struct iguana_packet { struct queueitem DL; struct iguana_peer *addr; struct tai embargo; int32_t datalen,getdatablock; uint8_t serialized[]; }; + +struct msgcounts { uint32_t version,verack,getaddr,addr,inv,getdata,notfound,getblocks,getheaders,headers,tx,block,mempool,ping,pong,reject,filterload,filteradd,filterclear,merkleblock,alert; }; + +struct iguana_fileitem { bits256 hash2; struct iguana_txdatabits txdatabits; }; + +struct iguana_kvitem { UT_hash_handle hh; uint8_t keyvalue[]; };// __attribute__((packed)); + +struct iguana_iAddr +{ + UT_hash_handle hh; uint64_t ipbits; + uint32_t lastkilled,lastconnect; + int32_t status,height,numkilled,numconnects; +}; + +struct iguana_cacheptr { struct queueitem DL; int32_t allocsize,recvlen; uint8_t *data; }; + +// iguana blocks +struct iguana_blockRO +{ + bits256 hash2,prev_block,merkle_root; + uint32_t timestamp,nonce,bits,version; + uint32_t firsttxidind,firstvin,firstvout,firstpkind,firstexternalind,recvlen:24,tbd:8; + uint16_t txn_count,numvouts,numvins,allocsize; +} __attribute__((packed)); + +struct iguana_zcashRO { bits256 bignonce; uint32_t solution[ZCASH_SOLUTION_ELEMENTS]; } __attribute__((packed)); + +struct iguana_zblockRO +{ + struct iguana_blockRO RO; + struct iguana_zcashRO zRO; +} __attribute__((packed)); + +#define iguana_blockfields double PoW; \ +int32_t height,fpos; uint32_t fpipbits,issued,lag:19,protected:1,peerid:12; \ +uint16_t hdrsi:15,mainchain:1,bundlei:11,valid:1,queued:1,txvalid:1,newtx:1,processed:1; \ +UT_hash_handle hh; struct iguana_bundlereq *req; \ +struct iguana_blockRO RO + +struct iguana_block +{ + iguana_blockfields; + struct iguana_zcashRO zRO[]; +} __attribute__((packed)); + +struct iguana_zblock // mu +{ + iguana_blockfields; + struct iguana_zcashRO zRO; +} __attribute__((packed)); + +#define IGUANA_LHASH_BLOCKS 0 +#define IGUANA_LHASH_TXIDS 1 // +#define IGUANA_LHASH_UNSPENTS 2 // +#define IGUANA_LHASH_SPENDS 3 // +#define IGUANA_LHASH_PKHASHES 4 // +#define IGUANA_LHASH_ACCOUNTS 5 // +#define IGUANA_LHASH_EXTERNALS 6 // +#define IGUANA_LHASH_KSPACE 7 // +#define IGUANA_LHASH_TXBITS 8 // +#define IGUANA_LHASH_PKBITS 9 // +#define IGUANA_NUMLHASHES (IGUANA_LHASH_PKBITS + 1) + +struct iguana_counts +{ + uint32_t firsttxidind,firstunspentind,firstspendind,firstpkind; + uint64_t credits,debits; + struct iguana_block block; +} __attribute__((packed)); + +struct iguana_blocks +{ + char coin[8]; + struct iguanakv *db; + struct iguana_block *hash; //struct iguana_blockRO *RO; int32_t maxbits; + int32_t maxblocks,initblocks,hashblocks,pending,issuedblocks,recvblocks,emitblocks,parsedblocks,dirty; + struct iguana_zblock hwmchain,prev,prev2; +}; + +struct iguana_ledger +{ + struct iguana_counts snapshot; + //struct iguana_account accounts[]; +} __attribute__((packed)); + +// ramchain temp file structures +struct iguana_unspent20 { uint64_t value; uint32_t scriptpos,txidind:28,type:4; uint16_t scriptlen,fileid; uint8_t rmd160[20]; } __attribute__((packed)); +struct iguana_spend256 { bits256 prevhash2; uint64_t scriptpos:48,vinscriptlen:16; uint32_t sequenceid; int16_t prevout; uint16_t spendind,fileid; } __attribute__((packed)); + +// permanent readonly structs +struct iguana_txid { bits256 txid; uint64_t txidind:29,firstvout:28,firstvin:28,bundlei:11,locktime:32,version:32,timestamp:32,extraoffset:32; uint16_t numvouts,numvins; } __attribute__((packed)); + +struct iguana_unspent { uint64_t value; uint32_t txidind,pkind,prevunspentind,scriptpos; uint16_t scriptlen,hdrsi; uint16_t fileid:11,type:5; int16_t vout; } __attribute__((packed)); + +struct iguana_spend { uint64_t scriptpos:48,scriptlen:16; uint32_t spendtxidind,sequenceid; int16_t prevout; uint16_t fileid:15,external:1; } __attribute__((packed)); // numsigs:4,numpubkeys:4,p2sh:1,sighash:4 + +struct iguana_pkhash { uint8_t rmd160[20]; uint32_t pkind; } __attribute__((packed)); //firstunspentind,pubkeyoffset + +// dynamic +struct iguana_account { int64_t total; uint32_t lastunspentind; } __attribute__((packed)); +struct iguana_utxo { uint32_t fromheight:31,lockedflag:1,prevunspentind:31,spentflag:1,spendind; } __attribute__((packed)); + +#ifdef DEPRECATED_HHUTXO +struct iguana_hhaccount { UT_hash_handle hh; uint64_t pval; struct iguana_account a; } __attribute__((packed)); +#endif +struct iguana_hhutxo { UT_hash_handle hh; uint64_t uval; struct iguana_utxo u; } __attribute__((packed)); +struct iguana_utxoaddr { UT_hash_handle hh; int64_t histbalance; uint32_t pkind:31,searchedhist:1; uint16_t hdrsi; uint8_t rmd160[20]; } __attribute__((packed)); + +// GLOBAL one zero to non-zero write (unless reorg) +struct iguana_spendvector { uint64_t value; uint32_t pkind,unspentind; int32_t fromheight; uint16_t hdrsi:15,tmpflag:1; } __attribute__((packed)); // unspentind +//struct iguana_pkextra { uint32_t firstspendind; } __attribute__((packed)); // pkind + +struct iguana_txblock +{ + uint32_t numtxids,numunspents,numspends,extralen,recvlen; + // following set during second pass (still in peer context) + uint32_t numpkinds,numexternaltxids,datalen,pkoffset; + uint8_t space[256]; // order: extra[], T, U, S, P, external txids + struct iguana_zblock zblock; +}; + +#define RAMCHAIN_PTR(rdata,offset) ((void *)(long)((long)(rdata) + (long)(rdata)->offset)) +struct iguana_ramchaindata +{ + bits256 sha256; + bits256 lhashes[IGUANA_NUMLHASHES],firsthash2,prevhash2; + int64_t allocsize,Boffset,Toffset,Uoffset,Soffset,Poffset,Aoffset,Xoffset,TXoffset,PKoffset,Koffset; + int32_t numblocks,height,firsti,hdrsi,txsparsebits,pksparsebits; + uint32_t numtxids,numunspents,numspends,numpkinds,numexternaltxids,numtxsparse,numpksparse,scriptspace,stackspace; + uint8_t rdata[]; +}; + +struct iguana_ramchain_hdr +{ + uint32_t txidind,unspentind,spendind,scriptoffset,stacksize; uint16_t hdrsi,bundlei:15,ROflag:1; + struct iguana_ramchaindata *data; +}; + +struct iguana_ramchain +{ + struct iguana_ramchain_hdr H; bits256 lasthash2; uint64_t datasize,allocatedA2,allocatedU2; + uint32_t numblocks:31,expanded:1,pkind,externalind,height,numXspends; + long sparseadds,sparsesearches,sparseadditers,sparsesearchiters,sparsehits,sparsemax; + struct iguana_kvitem *txids,*pkhashes; + struct OS_memspace *hashmem; long filesize,sigsfilesize,debitsfilesize,lastspendsfilesize; + void *fileptr,*sigsfileptr,*Xspendptr,*debitsfileptr,*lastspendsfileptr; + char from_ro,from_roX,from_roA,from_roU; + struct iguana_account *A,*A2,*creditsA; struct iguana_spendvector *Xspendinds; + struct iguana_utxo *Uextras; uint8_t *txbits; struct iguana_txid *cacheT; + //int16_t permutation[IGUANA_MAXBUNDLES]; + //struct iguana_Uextra *U2,*roU2; struct iguana_pkextra *P2,*roP2; +}; + +struct iguana_peer +{ + struct queueitem DL; + queue_t sendQ; + bits256 iphash,pubkey,persistent; uint32_t lastpersist; uint8_t netmagic[4]; + struct iguana_msgaddress A; + char ipaddr[64],lastcommand[16],coinname[64],symbol[64]; + uint64_t pingnonce,totalsent,totalrecv,ipbits; double pingtime,sendmillis,pingsum,getdatamillis; + uint32_t lastcontact,sendtime,ready,startsend,startrecv,pending,lastgotaddr,lastblockrecv,pendtime,lastflush,lastpoll,myipbits,persistent_peer,protover; + int32_t supernet,basilisk,dead,addrind,usock,lastheight,relayflag,numpackets,numpings,ipv6,height,rank,pendhdrs,pendblocks,recvhdrs,lastlefti,validpub,othervalid,dirty[2],laggard,headerserror,lastsent,isrelay; + double recvblocks,recvtotal; + int64_t allocated,freed; + bits256 RThashes[IGUANA_MAXBUNDLESIZE]; int32_t numRThashes; + struct msgcounts msgcounts; + struct OS_memspace RAWMEM,TXDATA,HASHMEM; + struct iguana_ramchain ramchain; + struct iguana_fileitem *filehash2; int32_t numfilehash2,maxfilehash2; + FILE *voutsfp,*vinsfp; + uint8_t *blockspace;//[IGUANA_MAXPACKETSIZE + 8192]; +#ifdef IGUANA_PEERALLOC + struct OS_memspace *SEROUT[128]; +#endif +}; + +struct iguana_peers +{ + bits256 lastrequest; + struct iguana_peer active[IGUANA_MAXPEERS+1],*ranked[IGUANA_MAXPEERS+1],*localaddr; + struct iguana_thread *peersloop,*recvloop; pthread_t *acceptloop; + double topmetrics[IGUANA_MAXPEERS+1],avemetric; + uint32_t numranked,mostreceived,shuttingdown,lastpeer,lastmetrics,numconnected; + int32_t numfiles; +}; + +struct iguana_bloom16 { uint8_t hash2bits[65536 / 8]; }; +struct iguana_bloominds { uint16_t inds[8]; }; + +struct iguana_bundle +{ + struct queueitem DL; struct iguana_info *coin; struct iguana_bundle *nextbp; + struct iguana_bloom16 bloom; int64_t totaldurations,duplicatedurations; int32_t durationscount,duplicatescount; + uint32_t issuetime,hdrtime,emitfinish,mergefinish,purgetime,queued,startutxo,utxofinish,balancefinish,validated,lastspeculative,dirty,nexttime,currenttime,lastprefetch,lastRT,missingstime,unsticktime,converted; + int32_t numhashes,numrecv,numsaved,numcached,generrs,currentflag,origmissings,numissued,Xvalid; + int32_t minrequests,n,hdrsi,bundleheight,numtxids,numspends,numunspents,numspec,isRT; + double avetime,threshold,metric; uint64_t datasize,estsize; + struct iguana_block *blocks[IGUANA_MAXBUNDLESIZE]; + uint8_t *speculativecache[IGUANA_MAXBUNDLESIZE],haveblock[IGUANA_MAXBUNDLESIZE/3+1]; + uint32_t issued[IGUANA_MAXBUNDLESIZE]; + bits256 prevbundlehash2,hashes[IGUANA_MAXBUNDLESIZE+1],nextbundlehash2,allhash,*speculative,validatehash; + struct iguana_ramchain ramchain; uint8_t red,green,blue; + struct iguana_spendvector *tmpspends; int32_t numtmpspends; + int64_t *weights,supply; int32_t numweights; +}; + +struct iguana_bundlereq +{ + struct queueitem DL; struct iguana_info *coin; int32_t type; + struct iguana_peer *addr; struct iguana_zblock *blocks; bits256 *hashes,txid; + struct iguana_txdatabits txdatabits; + struct iguana_msghdr H; + int32_t allocsize,datalen,n,recvlen,numtx; uint32_t ipbits; + struct iguana_zblock zblock; + uint8_t copyflag,serializeddata[]; +}; + +struct iguana_bitmap { int32_t width,height,amplitude; char name[52]; uint8_t data[IGUANA_WIDTH*IGUANA_HEIGHT*3]; }; + +struct basilisk_spend { bits256 txid,spentfrom; uint64_t relaymask,value; uint32_t timestamp; int32_t vini,vout,height,unspentheight,ismine; char destaddr[64],symbol[16]; }; + +struct basilisk_unspent { bits256 txid; uint64_t value,relaymask; uint32_t unspentind,timestamp; int32_t RTheight,height,spentheight; int16_t status,hdrsi,vout,spendlen; char symbol[16]; uint8_t script[256]; }; + +struct iguana_waddress { UT_hash_handle hh; struct basilisk_unspent *unspents; uint64_t balance; uint32_t maxunspents,numunspents; uint16_t scriptlen; uint8_t rmd160[20],pubkey[33],wiftype,addrtype; bits256 privkey; char symbol[8],coinaddr[36],wifstr[54]; uint8_t redeemScript[]; }; +struct iguana_waccount { UT_hash_handle hh; struct iguana_waddress *waddr,*current; char account[]; }; +struct iguana_wallet { UT_hash_handle hh; struct iguana_waccount *wacct; }; + +struct scriptinfo { UT_hash_handle hh; uint32_t fpos; uint16_t scriptlen; uint8_t script[]; }; +struct hhbits256 { UT_hash_handle hh; bits256 txid; int32_t height; uint16_t firstvout; }; + +struct iguana_monitorinfo { bits256 txid; int32_t numreported; uint8_t peerbits[IGUANA_MAXPEERS >> 3]; }; + +struct iguana_RTspend +{ + bits256 prev_hash; int16_t prev_vout,scriptlen; + uint8_t vinscript[]; +}; + +struct iguana_RTunspent +{ + uint8_t rmd160[20]; + int64_t value; + int32_t vout,height,fromheight; + struct iguana_RTtxid *parent; + struct iguana_RTspend *spend; + struct iguana_RTunspent *prevunspent; + int16_t scriptlen; + uint8_t locked,validflag; + uint8_t script[]; +}; + +struct iguana_RTaddr +{ + UT_hash_handle hh; + char coinaddr[64]; + int64_t histbalance,debits,credits; + int32_t numunspents; + struct iguana_RTunspent *lastunspent; +}; + +struct iguana_RTtxid +{ + UT_hash_handle hh; struct iguana_info *coin; struct iguana_block *block; + bits256 txid; + int32_t height,txi,txn_count,numvouts,numvins,txlen; + uint32_t locktime,version,timestamp; + uint8_t *rawtxbytes; + struct iguana_RTunspent **unspents; + struct iguana_RTspend *spends[]; +}; + +struct iguana_info +{ + UT_hash_handle hh; + char name[64],symbol[64],protocol,statusstr[512],scriptsfname[2][512]; + struct iguana_peers *peers; struct iguana_peer internaladdr; + //basilisk_func basilisk_rawtx,basilisk_balances,basilisk_value; + //basilisk_metricfunc basilisk_rawtxmetric,basilisk_balancesmetric,basilisk_valuemetric; + long vinptrs[IGUANA_MAXPEERS+1][2],voutptrs[IGUANA_MAXPEERS+1][2]; + uint32_t fastfind; FILE *fastfps[0x100]; uint8_t *fast[0x100]; int32_t *fasttables[0x100]; long fastsizes[0x100]; + uint64_t instance_nonce,myservices,totalsize,totalrecv,totalpackets,sleeptime; + int64_t mining,totalfees,TMPallocated,MAXRECVCACHE,MAXMEM,PREFETCHLAG,estsize,activebundles; + int32_t MAXPEERS,MAXPENDINGREQUESTS,MAXBUNDLES,MAXSTUCKTIME,active,closestbundle,numemitted,lastsweep,numemit,startutc,newramchain,numcached,cachefreed,helperdepth,startPEND,endPEND,enableCACHE,FULLNODE,VALIDATENODE,origbalanceswritten,balanceswritten,lastRTheight,RTdatabad; + bits256 balancehash,allbundles; + uint32_t lastsync,parsetime,numiAddrs,lastpossible,bundlescount,savedblocks,backlog,spendvectorsaved,laststats,lastinv2,symbolcrc,spendvalidated; char VALIDATEDIR[512]; + int32_t longestchain,badlongestchain,longestchain_strange,RTramchain_busy,emitbusy,stuckiters,virtualchain,RTheight; + struct tai starttime; double startmillis; + struct iguana_chain *chain; + struct iguana_iAddr *iAddrs; + void *ctx; + struct iguana_bitmap *screen; + struct OS_memspace TXMEM,MEM,MEMB[IGUANA_MAXBUNDLESIZE]; + queue_t acceptQ,hdrsQ,blocksQ,priorityQ,possibleQ,cacheQ,recvQ,msgrequestQ; + double parsemillis,avetime; uint32_t Launched[8],Terminated[8]; + portable_mutex_t peers_mutex,blocks_mutex,special_mutex,RTmutex,allcoins_mutex; + char changeaddr[64]; + struct iguana_bundle *bundles[IGUANA_MAXBUNDLES],*current,*lastpending; + struct OS_memspace RTrawmem,RTmem,RThashmem; // struct iguana_ramchain RTramchain; + bits256 RThash1; + int32_t numremain,numpendings,zcount,recvcount,bcount,pcount,lastbundle,numsaved,pendbalances,numverified,blockdepth; + uint32_t recvtime,hdrstime,backstoptime,lastbundletime,numreqsent,numbundlesQ,lastbundleitime,lastdisp,RTgenesis,firstRTgenesis,RTstarti,idletime,stucktime,stuckmonitor,maxstuck,lastreqtime,RThdrstime,nextchecked,lastcheckpoint; + double bandwidth,maxbandwidth,backstopmillis; bits256 backstophash2; int64_t spaceused; + int32_t disableUTXO,initialheight,mapflags,minconfirms,numrecv,bindsock,isRT,backstop,blocksrecv,merging,firstRTheight,polltimeout,numreqtxids,allhashes,balanceflush,basilisk_busy; bits256 reqtxids[64]; + void *launched,*started,*rpcloop; + uint64_t bloomsearches,bloomhits,bloomfalse,collisions,txfee_perkb,txfee; + uint8_t *blockspace; int32_t blockspacesize; struct OS_memspace blockMEM,RTHASHMEM; + bits256 APIblockhash,APItxid; char *APIblockstr; + struct iguana_hhutxo *utxotable; +#ifdef DEPRECATED_HHUTXO + struct iguana_hhaccount *accountstable; +#endif + char lastdispstr[2048]; + double txidfind_totalmillis,txidfind_num,spendtxid_totalmillis,spendtxid_num; + struct iguana_monitorinfo monitoring[256]; + struct datachain_info dPoW; + struct iguana_zblock newblock; char *newblockstr; + int32_t relay_RTheights[BASILISK_MAXRELAYS]; + struct iguana_blocks blocks; void *mempool; void *mempools[BASILISK_MAXRELAYS]; + + struct iguana_utxoaddr *utxoaddrs,*RTprev; uint32_t utxodatasize,utxoaddrind; + uint64_t histbalance,RTcredits,RTdebits; + void *utxoaddrfileptr; long utxoaddrfilesize; + uint32_t utxoaddrlastcount,*utxoaddroffsets,lastunspentsupdate; uint8_t *utxoaddrtable; bits256 utxoaddrhash; + struct iguana_block *RTblocks[65536]; uint8_t *RTrawdata[65536]; int32_t RTrecvlens[65536],RTnumtx[65536]; + struct iguana_RTtxid *RTdataset; struct iguana_RTaddr *RTaddrs; +}; + +struct vin_signer { bits256 privkey; char coinaddr[64]; uint8_t siglen,sig[80],rmd160[20],pubkey[66]; }; + +struct vin_info +{ + struct iguana_msgvin vin; uint64_t amount; cJSON *extras; bits256 sigtxid; + int32_t M,N,validmask,spendlen,type,p2shlen,numpubkeys,numsigs,height,hashtype,userdatalen,suppress_pubkeys; + uint32_t sequence,unspentind; struct vin_signer signers[16]; char coinaddr[65]; + uint8_t rmd160[20],spendscript[IGUANA_MAXSCRIPTSIZE],p2shscript[IGUANA_MAXSCRIPTSIZE],userdata[IGUANA_MAXSCRIPTSIZE]; +}; + +struct bitcoin_unspent +{ + bits256 txid,privkeys[16]; uint64_t value; int32_t vout,spendlen,p2shlen,numpubkeys; uint32_t sequence; + uint8_t addrtype,rmd160[20],pubkeys[16][65],spendscript[IGUANA_MAXSCRIPTSIZE],p2shscript[IGUANA_MAXSCRIPTSIZE]; +}; + +struct bitcoin_spend +{ + char changeaddr[64]; uint8_t change160[20]; + int32_t numinputs; + int64_t txfee,input_satoshis,satoshis,change; + struct bitcoin_unspent inputs[]; +}; + +struct iguana_outpoint { void *ptr; int64_t value; uint32_t unspentind:31,isptr:1; int16_t hdrsi; }; + +struct exchange_quote { uint64_t satoshis,orderid,offerNXT,exchangebits; double price,volume; uint32_t timestamp,val; }; + +struct _gfshare_ctx +{ + uint32_t sharecount,threshold,size,buffersize,allocsize; + uint8_t sharenrs[255],buffer[]; +}; + +struct basilisk_request +{ + uint32_t requestid,timestamp,quoteid,quotetime; // 0 to 15 + uint64_t srcamount,minamount; // 16 to 31 + bits256 hash; // 32 to 63 + bits256 desthash; + char src[8],dest[8]; + //char volatile_start,message[43]; + uint64_t destamount; + uint32_t relaybits; +} __attribute__((packed)); +struct basilisk_relaystatus +{ + uint8_t pingdelay; +}; + +struct basilisk_relay +{ + bits256 pubkey; int32_t relayid,oldrelayid; uint32_t ipbits,lastping; uint8_t pubkey33[33]; + struct basilisk_request *requests; int32_t maxrequests,numrequests; + struct basilisk_relaystatus direct,reported[BASILISK_MAXRELAYS]; +}; + +#endif + diff --git a/includes/iguana_types.h b/includes/iguana_types.h new file mode 100755 index 000000000..7b953cea1 --- /dev/null +++ b/includes/iguana_types.h @@ -0,0 +1,27 @@ +/****************************************************************************** + * Copyright © 2014-2016 The SuperNET Developers. * + * * + * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * SuperNET software, including this file may be copied, modified, propagated * + * or distributed except according to the terms contained in the LICENSE file * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +#ifndef H_IGUANATYPES_H +#define H_IGUANATYPES_H + + +typedef void (*iguana_func)(void *); +typedef int32_t (*blockhashfunc)(uint8_t *blockhashp,uint8_t *serialized,int32_t len); +//typedef void *(*basilisk_func)(struct basilisk_item *Lptr,struct supernet_info *myinfo,struct iguana_info *coin,char *remoteaddr,uint32_t basilisktag,int32_t timeoutmillis,cJSON *vals); +//typedef double (*basilisk_metricfunc)(struct supernet_info *myinfo,struct basilisk_item *ptr,char *result); +//typedef struct _gfshare_ctx gfshare_ctx; + +#endif + diff --git a/includes/libgfshare.h b/includes/libgfshare.h index 2499dee9c..a4d494aff 100755 --- a/includes/libgfshare.h +++ b/includes/libgfshare.h @@ -64,9 +64,8 @@ void gfshare_ctx_enc_setsecret(gfshare_ctx* /* ctx */, * 'share' must be preallocated and at least 'size' bytes long. * 'sharenr' is the index into the 'sharenrs' array of the share you want. */ -void gfshare_ctx_enc_getshare(gfshare_ctx* /* ctx */, - unsigned char /* sharenr */, - unsigned char* /* share */); +void gfshare_ctx_encgetshare(uint8_t *logs,uint8_t *exps,gfshare_ctx* /* ctx */, unsigned char /* sharenr */, unsigned char* /* share */); +void gfshare_ctx_enc_getshare(gfshare_ctx* /* ctx */, unsigned char /* sharenr */, unsigned char* /* share */); /* ----------------------------------------------------[ Recombination ]---- */ @@ -84,8 +83,9 @@ void gfshare_ctx_dec_giveshare(gfshare_ctx* /* ctx */, /* Extract the secret by interpolation of the shares. * secretbuf must be allocated and at least 'size' bytes long */ -void gfshare_ctx_dec_extract(gfshare_ctx* /* ctx */, - unsigned char* /* secretbuf */); + +void gfshare_ctx_decextract(uint8_t *logs,uint8_t *exps,gfshare_ctx* /* ctx */, unsigned char* /* secretbuf */); +void gfshare_ctx_dec_extract(gfshare_ctx* /* ctx */, unsigned char* /* secretbuf */); #endif /* LIBGFSHARE_H */ diff --git a/ios/lib/libcrypto.a b/ios/lib/libcrypto.a deleted file mode 100755 index 4ff511a72..000000000 Binary files a/ios/lib/libcrypto.a and /dev/null differ diff --git a/ios/lib/libcurl.a b/ios/lib/libcurl.a deleted file mode 100755 index d146f86ba..000000000 Binary files a/ios/lib/libcurl.a and /dev/null differ diff --git a/ios/lib/libssl.a b/ios/lib/libssl.a deleted file mode 100755 index a778abab6..000000000 Binary files a/ios/lib/libssl.a and /dev/null differ diff --git a/m_ios b/m_ios index e31b7612d..f555ddc59 100755 --- a/m_ios +++ b/m_ios @@ -1,2 +1,4 @@ -git pull +if [[ $# -eq 0 ]]; then + git pull +fi cd iguana; ./m_ios; cd .. diff --git a/m_onetime_ios b/m_onetime_ios new file mode 100755 index 000000000..61470adfe --- /dev/null +++ b/m_onetime_ios @@ -0,0 +1,4 @@ +git pull +cd crypto777 +./m_ios +cd .. diff --git a/m_unix b/m_unix index c39b4ce45..17696b26d 100755 --- a/m_unix +++ b/m_unix @@ -1,3 +1,5 @@ -git pull +if [[ $# -eq 0 ]]; then + git pull +fi cd iguana; ./m_unix; cd .. #cd SuperNET; ./m_unix; cd .. diff --git a/mingw.path b/mingw.path index 0f758932e..3acd274f4 100755 --- a/mingw.path +++ b/mingw.path @@ -1,2 +1,2 @@ -TOOL_DIR := /usr/bin -MINGW := i586-mingw32msvc +TOOL_DIR := C:/MinGW/32 +MINGW := gcc diff --git a/mingw.path64 b/mingw.path64 index 713a49292..9c1c5236d 100755 --- a/mingw.path64 +++ b/mingw.path64 @@ -1,2 +1,2 @@ -TOOL_DIR := /usr/bin -MINGW := i686-w64-mingw32 +TOOL_DIR := C:/MinGW/64 +MINGW := gcc \ No newline at end of file diff --git a/pnacl_main.h b/pnacl_main.h index b46d0fff1..9d3c0f4d7 100755 --- a/pnacl_main.h +++ b/pnacl_main.h @@ -8,7 +8,7 @@ #include #include #ifdef _WIN32 -#include "win/pthread.h" +#include "OSlibs/win/pthread.h" #include //static inline void sleep(unsigned ms) { Sleep(ms*1000); } @@ -360,10 +360,10 @@ static PP_Bool Instance_DidCreate(PP_Instance instance,uint32_t argc,const char* nacl_io_init_ppapi(instance,g_get_browser_interface); umount("/"); mount("", "/", "memfs", 0, ""); - mkdir("/tmp",0755); - mkdir("/DB",0755); - mount("","/tmp","html5fs",0,"type=TEMPORARY,expected_size=2000000000"); - mount("","/DB","html5fs",0,"type=PERSISTENT,expected_size=10000000000"); + //mkdir("/tmp",0755); + mkdir("DB",0755); + //mount("","/tmp","html5fs",0,"type=TEMPORARY,expected_size=2000000000"); + mount("","DB","html5fs",0,"type=PERSISTENT,expected_size=10000000000"); /*mount("", // source. Use relative URL "/http", // target "httpfs", // filesystemtype diff --git a/tradebots/main.c b/tradebots/main.c index a45455fd7..2729cbfc7 100755 --- a/tradebots/main.c +++ b/tradebots/main.c @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright © 2014-2015 The SuperNET Developers. * + * Copyright © 2014-2016 The SuperNET Developers. * * * * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at * * the top-level directory of this distribution for the individual copyright * @@ -13,24 +13,14 @@ * * ******************************************************************************/ -#define CHROMEAPP_NAME tradebots -#define CHROMEAPP_STR "tradebots" -#define CHROMEAPP_CONF "tradebots.conf" -#define CHROMEAPP_MAIN tradebots_main -#define CHROMEAPP_JSON tradebots_JSON -#define CHROMEAPP_HANDLER Handler_tradebots +#include "../iguana/iguana777.h" -#include "../pnacl_main.h" +void tradebots_LP(char *jsonstr,char *arg); -// ALL globals must be here! - -void tradebots_main(void *arg) -{ - while ( 1 ) - sleep(777); -} - -char *tradebots_JSON(char *jsonstr) +int main(int argc,char **argv) { - return(clonestr("{\"error\":\"tradebots is just a stub for now\"}")); + long filesize; + printf("Start Liquidity Provider\n"); + tradebots_LP(OS_filestr(&filesize,"LP.conf"),(argc > 1) ? argv[1]:""); + return(0); } \ No newline at end of file diff --git a/webui/create-account.html b/webui/create-account.html new file mode 100644 index 000000000..20b81b104 --- /dev/null +++ b/webui/create-account.html @@ -0,0 +1,64 @@ + + + + + + + Iguana / Create account + + + + + + + + + + + + + + +
+
+ + + + + + + +
+
+ + \ No newline at end of file diff --git a/webui/css/auth.css b/webui/css/auth.css new file mode 100644 index 000000000..639d1be3a --- /dev/null +++ b/webui/css/auth.css @@ -0,0 +1,180 @@ +/*! + * Iguana authentication + * + */ + + body, + html { + display: table; + } + .container-fluid { + display: table-cell; + vertical-align: middle; + } + .box-shadow-all { + box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.15); + } + .box-shadow-bottom { + box-shadow: 0 1px 1px 0px rgba(0, 0, 0, 0.2); + } + .form-container { + margin: 0 auto; + background-color: #f4f7fb; + } + .login-form, + .create-account-form, + .verify-passphrase-form { + padding: 0; + float: none; + max-width: 375px; + } + .login-or-delim { + font-family: sans-serif; + padding: 26px 0; + letter-spacing: 1px; + } + textarea { + width: 100%; + height: 120px; + border-radius: 4px; + border: solid 1px #C7CCD0; + padding: 10px 12px; + font-family: proxima-nova-semibold, sans-serif; + font-size: 1.16em; + } + .passphrase-container { + width: 100%; + border-radius: 4px; + background: #fff; + box-shadow: 0 2px 3px 1px rgba(0, 0, 0, 0.1); + padding: 40px 12px; + font-family: proxima-nova-semibold, sans-serif; + font-size: 1.16em; + } + .passphrase-container .title { + font-family: sans-serif; + font-size: 0.91em; + margin-bottom: 2px; + } + .bi_interface-cross { + color: #fff; + font-size: 20px; + position: relative; + top: 12px; + left: 10px; + text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.3); + } + .bi_interface-arrow-left { + color: #fff; + font-size: 26px; + position: absolute; + z-index: 20; + margin-top: 8px; + margin-left: 10px; + text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.3); + } + .form-header .title { + position: relative; + z-index: 10; + text-align: center; + font-family: proxima-nova-semibold, sans-serif; + color: #fff; + font-size: 1.30em; + padding-top: 12px; + } + textarea.error { + border: solid 1px #FF0000; + } + .center { + text-align: center; + } + .offset-bottom-sm { + margin: 0 auto; + margin-bottom: 15px; + width: 264px; + } + .offset-bottom-md { + margin: 0 auto; + margin-bottom: 30px; + } + .header { + background-color: #fe700d; + color: white; + padding: 15px 10px; + text-align: center; + } + .form-content { + padding: 115px 16px 158px 16px; + font-size: 1.05em; + color: #363639; + } + .form-content .row { + width: 99%; + margin-right: 0; + margin-left: 0; + } + .form-header { + height: 50px; + } + .btn { + font-family: proxima-nova-semibold, sans-serif; + color: #fff; + font-size: 1.20em; + height: 44px; + } + .text-shadow { + text-shadow: 0px 1px 3px rgba(0, 0, 0, 0.25); + } + .btn:hover, + .btn:focus { + color: #fff; + box-shadow: 0 0 2px 1px rgba(0, 0, 0, 0.2); + } + .btn.disabled, + .btn.disabled:focus { + pointer-events: none; + background: #B2B4B7; + text-shadow: none; + } + .btn.disabled:hover { + box-shadow: none; + text-shadow: none; + } + .checkbox { + display: inline-block; + } + .label-text { + cursor: hand; + cursor: pointer; + font-size: 1.05em; + } + input[type="checkbox"] { + display: none; + } + input[type="checkbox"] + label { + font-weight: normal; + display: block; + text-align: center; + } + input[type="checkbox"] + label .box { + display: inline-block; + width: 20px; + height: 20px; + margin: -2px 17px 0 0; + vertical-align: middle; + background: transparent; + border: solid 2px #C7CCD0; + border-radius: 4px; + } + input[type="checkbox"]:checked + label .box { + background: #FE450D; + border-color: #FE450D; + } + input[type="checkbox"]:checked + label .box:before { + font-family: "budicon"; + content: "\eb23"; + color: #fff; + font-weight: bold; + position: relative; + top: -1px; + } \ No newline at end of file diff --git a/webui/css/bootstrap.min.css b/webui/css/bootstrap.min.css new file mode 100644 index 000000000..243529a72 --- /dev/null +++ b/webui/css/bootstrap.min.css @@ -0,0 +1,5 @@ +/*! + * Bootstrap v3.3.6 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-plus:before{content:"\002b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:focus,a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:focus,a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control::-ms-expand{background-color:transparent;border:0}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px\9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:11px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled.focus,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled].focus,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled.focus,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled].focus,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled.focus,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled].focus,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled.focus,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled].focus,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled.focus,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled].focus,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled.focus,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled].focus,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:2;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:3;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{padding-right:15px;padding-left:15px;border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover,button.list-group-item:focus,button.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;filter:alpha(opacity=0);opacity:0;line-break:auto}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);line-break:auto}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);background-color:rgba(0,0,0,0);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000\9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.modal-header:after,.modal-header:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.modal-header:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} \ No newline at end of file diff --git a/webui/css/budicon-codes.css b/webui/css/budicon-codes.css new file mode 100644 index 000000000..d481b0c42 --- /dev/null +++ b/webui/css/budicon-codes.css @@ -0,0 +1,853 @@ + +.bi_animal-fish:before { content: '\e800'; } /* '' */ +.bi_animal-fox:before { content: '\e801'; } /* '' */ +.bi_animal-frog:before { content: '\e802'; } /* '' */ +.bi_animal-goose:before { content: '\e803'; } /* '' */ +.bi_animal-husky:before { content: '\e804'; } /* '' */ +.bi_animal-lion:before { content: '\e805'; } /* '' */ +.bi_animal-monkey:before { content: '\e806'; } /* '' */ +.bi_animal-monkey-a:before { content: '\e807'; } /* '' */ +.bi_animal-mouse:before { content: '\e808'; } /* '' */ +.bi_animal-pig:before { content: '\e809'; } /* '' */ +.bi_animal-pig-a:before { content: '\e80a'; } /* '' */ +.bi_animal-sheep:before { content: '\e80b'; } /* '' */ +.bi_animal-shrimp:before { content: '\e80c'; } /* '' */ +.bi_animal-wolf:before { content: '\e80d'; } /* '' */ +.bi_animal-bull:before { content: '\e80e'; } /* '' */ +.bi_animal-cat:before { content: '\e80f'; } /* '' */ +.bi_animal-chicken:before { content: '\e810'; } /* '' */ +.bi_animal-cow:before { content: '\e811'; } /* '' */ +.bi_animal-cow-a:before { content: '\e812'; } /* '' */ +.bi_animal-dog:before { content: '\e813'; } /* '' */ +.bi_com-bubble-dot-b:before { content: '\e814'; } /* '' */ +.bi_com-bubble-line:before { content: '\e815'; } /* '' */ +.bi_com-bubble-line-a:before { content: '\e816'; } /* '' */ +.bi_com-bubble-line-b:before { content: '\e817'; } /* '' */ +.bi_com-chat:before { content: '\e818'; } /* '' */ +.bi_com-check-box:before { content: '\e819'; } /* '' */ +.bi_com-email:before { content: '\e81a'; } /* '' */ +.bi_com-email-cross:before { content: '\e81b'; } /* '' */ +.bi_com-email-minus:before { content: '\e81c'; } /* '' */ +.bi_com-email-o:before { content: '\e81d'; } /* '' */ +.bi_com-email-plus:before { content: '\e81e'; } /* '' */ +.bi_com-email-tick:before { content: '\e81f'; } /* '' */ +.bi_com-envelope:before { content: '\e820'; } /* '' */ +.bi_com-feather-pen:before { content: '\e821'; } /* '' */ +.bi_com-fountain-pen:before { content: '\e822'; } /* '' */ +.bi_com-group-bubble:before { content: '\e823'; } /* '' */ +.bi_com-group-bubble-a:before { content: '\e824'; } /* '' */ +.bi_com-group-bubble-b:before { content: '\e825'; } /* '' */ +.bi_com-group-bubble-c:before { content: '\e826'; } /* '' */ +.bi_com-group-bubble-d:before { content: '\e827'; } /* '' */ +.bi_com-help:before { content: '\e828'; } /* '' */ +.bi_com-help-a:before { content: '\e829'; } /* '' */ +.bi_com-megaphone:before { content: '\e82a'; } /* '' */ +.bi_com-megaphone-a:before { content: '\e82b'; } /* '' */ +.bi_com-mic:before { content: '\e82c'; } /* '' */ +.bi_com-mic-mute:before { content: '\e82d'; } /* '' */ +.bi_com-paperplane:before { content: '\e82e'; } /* '' */ +.bi_com-phone:before { content: '\e82f'; } /* '' */ +.bi_com-phone-a:before { content: '\e830'; } /* '' */ +.bi_com-pictures:before { content: '\e831'; } /* '' */ +.bi_com-voicemail:before { content: '\e832'; } /* '' */ +.bi_com-bell:before { content: '\e833'; } /* '' */ +.bi_com-bell-a:before { content: '\e834'; } /* '' */ +.bi_com-broadcast:before { content: '\e835'; } /* '' */ +.bi_com-broadcast-a:before { content: '\e836'; } /* '' */ +.bi_com-bubble:before { content: '\e837'; } /* '' */ +.bi_com-bubble-a:before { content: '\e838'; } /* '' */ +.bi_com-bubble-b:before { content: '\e839'; } /* '' */ +.bi_com-bubble-dot:before { content: '\e83a'; } /* '' */ +.bi_com-bubble-dot-a:before { content: '\e83b'; } /* '' */ +.bi_doc-analytic-blank:before { content: '\e83c'; } /* '' */ +.bi_doc-analytic-line:before { content: '\e83d'; } /* '' */ +.bi_doc-analytic-line-a:before { content: '\e83e'; } /* '' */ +.bi_doc-article:before { content: '\e83f'; } /* '' */ +.bi_doc-article-a:before { content: '\e840'; } /* '' */ +.bi_doc-article-b:before { content: '\e841'; } /* '' */ +.bi_doc-attachment:before { content: '\e842'; } /* '' */ +.bi_doc-attachment-a:before { content: '\e843'; } /* '' */ +.bi_doc-binder-blank:before { content: '\e844'; } /* '' */ +.bi_doc-binder-four:before { content: '\e845'; } /* '' */ +.bi_doc-binder-one:before { content: '\e846'; } /* '' */ +.bi_doc-binder-three:before { content: '\e847'; } /* '' */ +.bi_doc-binder-two:before { content: '\e848'; } /* '' */ +.bi_doc-binder-zero:before { content: '\e849'; } /* '' */ +.bi_doc-book:before { content: '\e84a'; } /* '' */ +.bi_doc-book-a:before { content: '\e84b'; } /* '' */ +.bi_doc-book-b:before { content: '\e84c'; } /* '' */ +.bi_doc-book-c:before { content: '\e84d'; } /* '' */ +.bi_doc-book-d:before { content: '\e84e'; } /* '' */ +.bi_doc-bookmark:before { content: '\e84f'; } /* '' */ +.bi_doc-book-mark:before { content: '\e850'; } /* '' */ +.bi_doc-box:before { content: '\e851'; } /* '' */ +.bi_doc-briefcase:before { content: '\e852'; } /* '' */ +.bi_doc-briefcase-a:before { content: '\e853'; } /* '' */ +.bi_doc-briefcase-b:before { content: '\e854'; } /* '' */ +.bi_doc-briefcase-c:before { content: '\e855'; } /* '' */ +.bi_doc-briefcase-d:before { content: '\e856'; } /* '' */ +.bi_doc-compose:before { content: '\e857'; } /* '' */ +.bi_doc-compose-a:before { content: '\e858'; } /* '' */ +.bi_doc-documents:before { content: '\e859'; } /* '' */ +.bi_doc-documents-minus:before { content: '\e85a'; } /* '' */ +.bi_doc-documents-plus:before { content: '\e85b'; } /* '' */ +.bi_doc-download:before { content: '\e85c'; } /* '' */ +.bi_doc-drawer:before { content: '\e85d'; } /* '' */ +.bi_doc-drawer-a:before { content: '\e85e'; } /* '' */ +.bi_doc-drawer-b:before { content: '\e85f'; } /* '' */ +.bi_doc-drawer-blank:before { content: '\e860'; } /* '' */ +.bi_doc-drawer-download:before { content: '\e861'; } /* '' */ +.bi_doc-drawer-line:before { content: '\e862'; } /* '' */ +.bi_doc-drawer-upload:before { content: '\e863'; } /* '' */ +.bi_doc-envelope:before { content: '\e864'; } /* '' */ +.bi_doc-file-blank:before { content: '\e865'; } /* '' */ +.bi_doc-file-blank-a:before { content: '\e866'; } /* '' */ +.bi_doc-file-cross:before { content: '\e867'; } /* '' */ +.bi_doc-file-cross-a:before { content: '\e868'; } /* '' */ +.bi_doc-file-line:before { content: '\e869'; } /* '' */ +.bi_doc-file-line-a:before { content: '\e86a'; } /* '' */ +.bi_doc-file-minus:before { content: '\e86b'; } /* '' */ +.bi_doc-file-minus-a:before { content: '\e86c'; } /* '' */ +.bi_doc-file-plus:before { content: '\e86d'; } /* '' */ +.bi_doc-file-plus-a:before { content: '\e86e'; } /* '' */ +.bi_doc-file-stack:before { content: '\e86f'; } /* '' */ +.bi_doc-file-tick:before { content: '\e870'; } /* '' */ +.bi_doc-file-tick-a:before { content: '\e871'; } /* '' */ +.bi_doc-folder:before { content: '\e872'; } /* '' */ +.bi_doc-folder-a:before { content: '\e873'; } /* '' */ +.bi_doc-folder-check-a:before { content: '\e874'; } /* '' */ +.bi_doc-folder-cross:before { content: '\e875'; } /* '' */ +.bi_doc-folder-cross-a:before { content: '\e876'; } /* '' */ +.bi_doc-folder-minus:before { content: '\e877'; } /* '' */ +.bi_doc-folder-minus-a:before { content: '\e878'; } /* '' */ +.bi_doc-folder-plus:before { content: '\e879'; } /* '' */ +.bi_doc-folder-plus-a:before { content: '\e87a'; } /* '' */ +.bi_doc-folder-s:before { content: '\e87b'; } /* '' */ +.bi_doc-folder-sync:before { content: '\e87c'; } /* '' */ +.bi_doc-folder-tick:before { content: '\e87d'; } /* '' */ +.bi_doc-list:before { content: '\e87e'; } /* '' */ +.bi_doc-news:before { content: '\e87f'; } /* '' */ +.bi_doc-newspaper:before { content: '\e880'; } /* '' */ +.bi_doc-newspaper-a:before { content: '\e881'; } /* '' */ +.bi_doc-newspaper-b:before { content: '\e882'; } /* '' */ +.bi_doc-notebook:before { content: '\e883'; } /* '' */ +.bi_doc-notebook-a:before { content: '\e884'; } /* '' */ +.bi_doc-note-pen:before { content: '\e885'; } /* '' */ +.bi_doc-paper-line:before { content: '\e886'; } /* '' */ +.bi_doc-papers:before { content: '\e887'; } /* '' */ +.bi_doc-paper-stack:before { content: '\e888'; } /* '' */ +.bi_doc-photo-stack:before { content: '\e889'; } /* '' */ +.bi_doc-pie:before { content: '\e88a'; } /* '' */ +.bi_doc-pie-a:before { content: '\e88b'; } /* '' */ +.bi_doc-pie-b:before { content: '\e88c'; } /* '' */ +.bi_doc-pin:before { content: '\e88d'; } /* '' */ +.bi_doc-pin-a:before { content: '\e88e'; } /* '' */ +.bi_doc-print:before { content: '\e88f'; } /* '' */ +.bi_doc-print-a:before { content: '\e890'; } /* '' */ +.bi_doc-profile:before { content: '\e891'; } /* '' */ +.bi_doc-profile-a:before { content: '\e892'; } /* '' */ +.bi_doc-upload:before { content: '\e893'; } /* '' */ +.bi_doc-wboard-line:before { content: '\e894'; } /* '' */ +.bi_doc-wboard-tick:before { content: '\e895'; } /* '' */ +.bi_media-glass:before { content: '\e896'; } /* '' */ +.bi_media-glass-a:before { content: '\e897'; } /* '' */ +.bi_media-image:before { content: '\e898'; } /* '' */ +.bi_media-image-a:before { content: '\e899'; } /* '' */ +.bi_media-image-b:before { content: '\e89a'; } /* '' */ +.bi_media-image-c:before { content: '\e89b'; } /* '' */ +.bi_media-image-d:before { content: '\e89c'; } /* '' */ +.bi_media-negative:before { content: '\e89d'; } /* '' */ +.bi_media-negative-a:before { content: '\e89e'; } /* '' */ +.bi_media-video:before { content: '\e89f'; } /* '' */ +.bi_media-video-a:before { content: '\e8a0'; } /* '' */ +.bi_media-video-clip:before { content: '\e8a1'; } /* '' */ +.bi_media-video-r:before { content: '\e8a2'; } /* '' */ +.bi_business-tie:before { content: '\e8a3'; } /* '' */ +.bi_business-tie-a:before { content: '\e8a4'; } /* '' */ +.bi_business-tie-b:before { content: '\e8a5'; } /* '' */ +.bi_doc-analytic-bar:before { content: '\e8a6'; } /* '' */ +.bi_ecommerce-basket:before { content: '\e8a7'; } /* '' */ +.bi_ecommerce-bill:before { content: '\e8a8'; } /* '' */ +.bi_ecommerce-bill-a:before { content: '\e8a9'; } /* '' */ +.bi_ecommerce-bill-b:before { content: '\e8aa'; } /* '' */ +.bi_ecommerce-bowtie:before { content: '\e8ab'; } /* '' */ +.bi_ecommerce-cash:before { content: '\e8ac'; } /* '' */ +.bi_ecommerce-cash-a:before { content: '\e8ad'; } /* '' */ +.bi_ecommerce-coins:before { content: '\e8ae'; } /* '' */ +.bi_ecommerce-coins-a:before { content: '\e8af'; } /* '' */ +.bi_ecommerce-creditcard:before { content: '\e8b0'; } /* '' */ +.bi_ecommerce-creditcard-b:before { content: '\e8b1'; } /* '' */ +.bi_ecommerce-creditcard-c:before { content: '\e8b2'; } /* '' */ +.bi_ecommerce-creditcard-d:before { content: '\e8b3'; } /* '' */ +.bi_ecommerce-diamon:before { content: '\e8b4'; } /* '' */ +.bi_ecommerce-digital-download:before { content: '\e8b5'; } /* '' */ +.bi_ecommerce-digital-upload:before { content: '\e8b6'; } /* '' */ +.bi_ecommerce-dollar:before { content: '\e8b7'; } /* '' */ +.bi_ecommerce-euro:before { content: '\e8b8'; } /* '' */ +.bi_ecommerce-gift:before { content: '\e8b9'; } /* '' */ +.bi_ecommerce-hanger:before { content: '\e8ba'; } /* '' */ +.bi_ecommerce-jeans:before { content: '\e8bb'; } /* '' */ +.bi_ecommerce-lipstick:before { content: '\e8bc'; } /* '' */ +.bi_ecommerce-market:before { content: '\e8bd'; } /* '' */ +.bi_ecommerce-mastercard:before { content: '\e8be'; } /* '' */ +.bi_ecommerce-pack:before { content: '\e8bf'; } /* '' */ +.bi_ecommerce-pack-a:before { content: '\e8c0'; } /* '' */ +.bi_ecommerce-pounds:before { content: '\e8c1'; } /* '' */ +.bi_ecommerce-ring:before { content: '\e8c2'; } /* '' */ +.bi_ecommerce-safebox:before { content: '\e8c3'; } /* '' */ +.bi_ecommerce-shirt:before { content: '\e8c4'; } /* '' */ +.bi_ecommerce-shirt-a:before { content: '\e8c5'; } /* '' */ +.bi_ecommerce-shoes:before { content: '\e8c6'; } /* '' */ +.bi_ecommerce-shop:before { content: '\e8c7'; } /* '' */ +.bi_ecommerce-shopcart:before { content: '\e8c8'; } /* '' */ +.bi_ecommerce-shopcart-a:before { content: '\e8c9'; } /* '' */ +.bi_ecommerce-shopcart-a-download:before { content: '\e8ca'; } /* '' */ +.bi_ecommerce-shopcart-a-fill:before { content: '\e8cb'; } /* '' */ +.bi_ecommerce-shopcart-c:before { content: '\e8cc'; } /* '' */ +.bi_ecommerce-shopcart-d:before { content: '\e8cd'; } /* '' */ +.bi_ecommerce-shopcart-download:before { content: '\e8ce'; } /* '' */ +.bi_ecommerce-shopcart-fill:before { content: '\e8cf'; } /* '' */ +.bi_ecommerce-short:before { content: '\e8d0'; } /* '' */ +.bi_ecommerce-suitcase:before { content: '\e8d1'; } /* '' */ +.bi_ecommerce-suitcase-a:before { content: '\e8d2'; } /* '' */ +.bi_ecommerce-tag:before { content: '\e8d3'; } /* '' */ +.bi_ecommerce-tag-a:before { content: '\e8d4'; } /* '' */ +.bi_ecommerce-tag-a-s:before { content: '\e8d5'; } /* '' */ +.bi_ecommerce-tag-b:before { content: '\e8d6'; } /* '' */ +.bi_ecommerce-tag-b-s:before { content: '\e8d7'; } /* '' */ +.bi_ecommerce-tag-c:before { content: '\e8d8'; } /* '' */ +.bi_ecommerce-tag-cross:before { content: '\e8d9'; } /* '' */ +.bi_ecommerce-tag-c-s:before { content: '\e8da'; } /* '' */ +.bi_ecommerce-tag-minus:before { content: '\e8db'; } /* '' */ +.bi_ecommerce-tag-plus:before { content: '\e8dc'; } /* '' */ +.bi_ecommerce-tag-tick:before { content: '\e8dd'; } /* '' */ +.bi_ecommerce-tracking:before { content: '\e8de'; } /* '' */ +.bi_ecommerce-tshirt:before { content: '\e8df'; } /* '' */ +.bi_ecommerce-wallet:before { content: '\e8e0'; } /* '' */ +.bi_ecommerce-wallet-a:before { content: '\e8e1'; } /* '' */ +.bi_ecommerce-woman-bag:before { content: '\e8e2'; } /* '' */ +.bi_ecommerce-yen:before { content: '\e8e3'; } /* '' */ +.bi_ecommerce-backpack:before { content: '\e8e4'; } /* '' */ +.bi_ecommerce-backpack-a:before { content: '\e8e5'; } /* '' */ +.bi_ecommerce-bag:before { content: '\e8e6'; } /* '' */ +.bi_ecommerce-bag-a:before { content: '\e8e7'; } /* '' */ +.bi_ecommerce-bag-b:before { content: '\e8e8'; } /* '' */ +.bi_editorial-pencil-s:before { content: '\e8e9'; } /* '' */ +.bi_editorial-pen-s:before { content: '\e8ea'; } /* '' */ +.bi_editorial-redo:before { content: '\e8eb'; } /* '' */ +.bi_editorial-right-align:before { content: '\e8ec'; } /* '' */ +.bi_editorial-trash:before { content: '\e8ed'; } /* '' */ +.bi_editorial-trash-a:before { content: '\e8ee'; } /* '' */ +.bi_editorial-trash-a-l:before { content: '\e8ef'; } /* '' */ +.bi_editorial-trash-l:before { content: '\e8f0'; } /* '' */ +.bi_editorial-undo:before { content: '\e8f1'; } /* '' */ +.bi_editorial-write:before { content: '\e8f2'; } /* '' */ +.bi_editorial-write-s:before { content: '\e8f3'; } /* '' */ +.bi_editorial-ascending:before { content: '\e8f4'; } /* '' */ +.bi_editorial-bookmark:before { content: '\e8f5'; } /* '' */ +.bi_editorial-bookmark-a:before { content: '\e8f6'; } /* '' */ +.bi_editorial-brush:before { content: '\e8f7'; } /* '' */ +.bi_editorial-center-align:before { content: '\e8f8'; } /* '' */ +.bi_editorial-compose:before { content: '\e8f9'; } /* '' */ +.bi_editorial-descending:before { content: '\e8fa'; } /* '' */ +.bi_editorial-left-align:before { content: '\e8fb'; } /* '' */ +.bi_editorial-pen:before { content: '\e8fc'; } /* '' */ +.bi_editorial-pencil:before { content: '\e8fd'; } /* '' */ +.bi_editorial-pencil-a:before { content: '\e8fe'; } /* '' */ +.bi_editorial-pencil-a-s:before { content: '\e8ff'; } /* '' */ +.bi_building-drawer-a:before { content: '\e900'; } /* '' */ +.bi_building-house:before { content: '\e901'; } /* '' */ +.bi_building-house-a:before { content: '\e902'; } /* '' */ +.bi_building-museum:before { content: '\e903'; } /* '' */ +.bi_building-office:before { content: '\e904'; } /* '' */ +.bi_building-office-a:before { content: '\e905'; } /* '' */ +.bi_building-office-b:before { content: '\e906'; } /* '' */ +.bi_building-sofa:before { content: '\e907'; } /* '' */ +.bi_building-sofa-a:before { content: '\e908'; } /* '' */ +.bi_building-sofa-b:before { content: '\e909'; } /* '' */ +.bi_building-sofa-twin:before { content: '\e90a'; } /* '' */ +.bi_building-sofa-twin-a:before { content: '\e90b'; } /* '' */ +.bi_building-table-lamp:before { content: '\e90c'; } /* '' */ +.bi_building-table-lamp-a:before { content: '\e90d'; } /* '' */ +.bi_building-tower:before { content: '\e90e'; } /* '' */ +.bi_building-tree:before { content: '\e90f'; } /* '' */ +.bi_environment-flower:before { content: '\e910'; } /* '' */ +.bi_environment-flower-a:before { content: '\e911'; } /* '' */ +.bi_environment-flower-b:before { content: '\e912'; } /* '' */ +.bi_environment-leaf:before { content: '\e913'; } /* '' */ +.bi_environment-leaf-a:before { content: '\e914'; } /* '' */ +.bi_environment-mountain:before { content: '\e915'; } /* '' */ +.bi_environment-mountain-a:before { content: '\e916'; } /* '' */ +.bi_environment-no-smoke:before { content: '\e917'; } /* '' */ +.bi_environment-plant:before { content: '\e918'; } /* '' */ +.bi_environment-sign:before { content: '\e919'; } /* '' */ +.bi_environment-smoke:before { content: '\e91a'; } /* '' */ +.bi_environment-tree:before { content: '\e91b'; } /* '' */ +.bi_building-apartment:before { content: '\e91c'; } /* '' */ +.bi_building-bed:before { content: '\e91d'; } /* '' */ +.bi_building-bulb:before { content: '\e91e'; } /* '' */ +.bi_building-cabinet:before { content: '\e91f'; } /* '' */ +.bi_building-desk:before { content: '\e920'; } /* '' */ +.bi_building-desk-a:before { content: '\e921'; } /* '' */ +.bi_building-desk-b:before { content: '\e922'; } /* '' */ +.bi_building-desk-c:before { content: '\e923'; } /* '' */ +.bi_building-door:before { content: '\e924'; } /* '' */ +.bi_building-drawer:before { content: '\e925'; } /* '' */ +.bi_beverage-cocktail-a:before { content: '\e926'; } /* '' */ +.bi_beverage-coffee:before { content: '\e927'; } /* '' */ +.bi_beverage-coffee-a:before { content: '\e928'; } /* '' */ +.bi_beverage-coffee-b:before { content: '\e929'; } /* '' */ +.bi_beverage-coffee-cup:before { content: '\e92a'; } /* '' */ +.bi_beverage-coffee-cup-a:before { content: '\e92b'; } /* '' */ +.bi_beverage-cokctail:before { content: '\e92c'; } /* '' */ +.bi_beverage-cup-straw:before { content: '\e92d'; } /* '' */ +.bi_beverage-empty-glass:before { content: '\e92e'; } /* '' */ +.bi_beverage-milk:before { content: '\e92f'; } /* '' */ +.bi_beverage-milk-a:before { content: '\e930'; } /* '' */ +.bi_beverage-tea:before { content: '\e931'; } /* '' */ +.bi_beverage-tea-a:before { content: '\e932'; } /* '' */ +.bi_beverage-tea-cup:before { content: '\e933'; } /* '' */ +.bi_beverage-tea-cup-a:before { content: '\e934'; } /* '' */ +.bi_beverage-water:before { content: '\e935'; } /* '' */ +.bi_beverage-water-a:before { content: '\e936'; } /* '' */ +.bi_beverage-water-glass:before { content: '\e937'; } /* '' */ +.bi_beverage-wine:before { content: '\e938'; } /* '' */ +.bi_food-apple:before { content: '\e939'; } /* '' */ +.bi_food-bowl:before { content: '\e93a'; } /* '' */ +.bi_food-cherry:before { content: '\e93b'; } /* '' */ +.bi_food-cherry-a:before { content: '\e93c'; } /* '' */ +.bi_food-chinese-food:before { content: '\e93d'; } /* '' */ +.bi_food-chinese-food-a:before { content: '\e93e'; } /* '' */ +.bi_food-chinese-food-b:before { content: '\e93f'; } /* '' */ +.bi_food-drumstick:before { content: '\e940'; } /* '' */ +.bi_food-egg:before { content: '\e941'; } /* '' */ +.bi_food-grape:before { content: '\e942'; } /* '' */ +.bi_food-hamburger:before { content: '\e943'; } /* '' */ +.bi_food-hamburger-a:before { content: '\e944'; } /* '' */ +.bi_food-ice-cream:before { content: '\e945'; } /* '' */ +.bi_food-ice-cream-a:before { content: '\e946'; } /* '' */ +.bi_food-ice-cream-b:before { content: '\e947'; } /* '' */ +.bi_food-ice-cream-c:before { content: '\e948'; } /* '' */ +.bi_food-melon:before { content: '\e949'; } /* '' */ +.bi_food-noodle:before { content: '\e94a'; } /* '' */ +.bi_food-noodle-a:before { content: '\e94b'; } /* '' */ +.bi_food-onigiri:before { content: '\e94c'; } /* '' */ +.bi_food-onigiri-a:before { content: '\e94d'; } /* '' */ +.bi_food-white-bread:before { content: '\e94e'; } /* '' */ +.bi_kitchen-fork-knife:before { content: '\e94f'; } /* '' */ +.bi_kitchen-fork-knife-a:before { content: '\e950'; } /* '' */ +.bi_kitchen-fridge:before { content: '\e951'; } /* '' */ +.bi_kitchen-grill:before { content: '\e952'; } /* '' */ +.bi_kitchen-heat:before { content: '\e953'; } /* '' */ +.bi_kitchen-heat-a:before { content: '\e954'; } /* '' */ +.bi_kitchen-hood:before { content: '\e955'; } /* '' */ +.bi_kitchen-hood-a:before { content: '\e956'; } /* '' */ +.bi_kitchen-jam:before { content: '\e957'; } /* '' */ +.bi_kitchen-ketchup:before { content: '\e958'; } /* '' */ +.bi_kitchen-leaf:before { content: '\e959'; } /* '' */ +.bi_kitchen-microwave:before { content: '\e95a'; } /* '' */ +.bi_kitchen-pepper:before { content: '\e95b'; } /* '' */ +.bi_kitchen-plate:before { content: '\e95c'; } /* '' */ +.bi_kitchen-recipe-book:before { content: '\e95d'; } /* '' */ +.bi_kitchen-salt:before { content: '\e95e'; } /* '' */ +.bi_kitchen-spatula:before { content: '\e95f'; } /* '' */ +.bi_kitchen-spoon-fork:before { content: '\e960'; } /* '' */ +.bi_kitchen-spoon-fork-a:before { content: '\e961'; } /* '' */ +.bi_kitchen-tissue:before { content: '\e962'; } /* '' */ +.bi_kitchen-water:before { content: '\e963'; } /* '' */ +.bi_beverage-alt-glass:before { content: '\e964'; } /* '' */ +.bi_beverage-alt-glass-a:before { content: '\e965'; } /* '' */ +.bi_beverage-alt-glass-b:before { content: '\e966'; } /* '' */ +.bi_beverage-alt-glass-c:before { content: '\e967'; } /* '' */ +.bi_beverage-beer:before { content: '\e968'; } /* '' */ +.bi_beverage-chinese-tea:before { content: '\e969'; } /* '' */ +.bi_beverage-chinese-tea-a:before { content: '\e96a'; } /* '' */ +.bi_beverage-chinese-tea-a-s:before { content: '\e96b'; } /* '' */ +.bi_beverage-chinese-tea-s:before { content: '\e96c'; } /* '' */ +.bi_setting-switch:before { content: '\e96d'; } /* '' */ +.bi_setting-switch-a:before { content: '\e96e'; } /* '' */ +.bi_setting-wrench:before { content: '\e96f'; } /* '' */ +.bi_setting-wrench-a:before { content: '\e970'; } /* '' */ +.bi_setting-airplane:before { content: '\e971'; } /* '' */ +.bi_setting-component:before { content: '\e972'; } /* '' */ +.bi_setting-eq:before { content: '\e973'; } /* '' */ +.bi_setting-eq-a:before { content: '\e974'; } /* '' */ +.bi_setting-gear:before { content: '\e975'; } /* '' */ +.bi_setting-gear-a:before { content: '\e976'; } /* '' */ +.bi_setting-gear-b:before { content: '\e977'; } /* '' */ +.bi_setting-hotspot:before { content: '\e978'; } /* '' */ +.bi_setting-notification:before { content: '\e979'; } /* '' */ +.bi_sport-tape:before { content: '\e97a'; } /* '' */ +.bi_sport-tennisball:before { content: '\e97b'; } /* '' */ +.bi_sport-time:before { content: '\e97c'; } /* '' */ +.bi_sport-trophy:before { content: '\e97d'; } /* '' */ +.bi_sport-trophy-a:before { content: '\e97e'; } /* '' */ +.bi_sport-tv:before { content: '\e97f'; } /* '' */ +.bi_sport-tv-a:before { content: '\e980'; } /* '' */ +.bi_medicine-heart:before { content: '\e981'; } /* '' */ +.bi_medicine-lab:before { content: '\e982'; } /* '' */ +.bi_medicine-lab-a:before { content: '\e983'; } /* '' */ +.bi_sport-alt-badge:before { content: '\e984'; } /* '' */ +.bi_sport-alt-badge-a:before { content: '\e985'; } /* '' */ +.bi_sport-badge:before { content: '\e986'; } /* '' */ +.bi_sport-badge-a:before { content: '\e987'; } /* '' */ +.bi_sport-badge-b:before { content: '\e988'; } /* '' */ +.bi_sport-badge-c:before { content: '\e989'; } /* '' */ +.bi_sport-badge-one:before { content: '\e98a'; } /* '' */ +.bi_sport-badge-one-a:before { content: '\e98b'; } /* '' */ +.bi_sport-baseball:before { content: '\e98c'; } /* '' */ +.bi_sport-basketball:before { content: '\e98d'; } /* '' */ +.bi_sport-basketball-a:before { content: '\e98e'; } /* '' */ +.bi_sport-bottle:before { content: '\e98f'; } /* '' */ +.bi_sport-cards:before { content: '\e990'; } /* '' */ +.bi_sport-dumbell:before { content: '\e991'; } /* '' */ +.bi_sport-dumbell-a:before { content: '\e992'; } /* '' */ +.bi_sport-flag:before { content: '\e993'; } /* '' */ +.bi_sport-flag-a:before { content: '\e994'; } /* '' */ +.bi_sport-football:before { content: '\e995'; } /* '' */ +.bi_sport-medic:before { content: '\e996'; } /* '' */ +.bi_sport-mic:before { content: '\e997'; } /* '' */ +.bi_sport-puzzle:before { content: '\e998'; } /* '' */ +.bi_sport-stadium:before { content: '\e999'; } /* '' */ +.bi_sport-stadium-a:before { content: '\e99a'; } /* '' */ +.bi_time-alarm:before { content: '\e99b'; } /* '' */ +.bi_time-alt-wall-clock:before { content: '\e99c'; } /* '' */ +.bi_time-calendar:before { content: '\e99d'; } /* '' */ +.bi_time-calendar-a:before { content: '\e99e'; } /* '' */ +.bi_time-calendar-b:before { content: '\e99f'; } /* '' */ +.bi_time-clock:before { content: '\e9a0'; } /* '' */ +.bi_time-clock-a:before { content: '\e9a1'; } /* '' */ +.bi_time-clock-b:before { content: '\e9a2'; } /* '' */ +.bi_time-clock-c:before { content: '\e9a3'; } /* '' */ +.bi_time-hour-glass:before { content: '\e9a4'; } /* '' */ +.bi_time-speed-meter:before { content: '\e9a5'; } /* '' */ +.bi_time-stopwatch:before { content: '\e9a6'; } /* '' */ +.bi_time-stopwatch-a:before { content: '\e9a7'; } /* '' */ +.bi_time-stopwatch-b:before { content: '\e9a8'; } /* '' */ +.bi_time-timer:before { content: '\e9a9'; } /* '' */ +.bi_time-wall-clock:before { content: '\e9aa'; } /* '' */ +.bi_time-watches:before { content: '\e9ab'; } /* '' */ +.bi_time-watches-a:before { content: '\e9ac'; } /* '' */ +.bi_time-watches-b:before { content: '\e9ad'; } /* '' */ +.bi_location-alt-pin:before { content: '\e9ae'; } /* '' */ +.bi_location-avenue:before { content: '\e9af'; } /* '' */ +.bi_location-compass:before { content: '\e9b0'; } /* '' */ +.bi_location-map:before { content: '\e9b1'; } /* '' */ +.bi_location-pin:before { content: '\e9b2'; } /* '' */ +.bi_location-pin-blank:before { content: '\e9b3'; } /* '' */ +.bi_location-pin-check:before { content: '\e9b4'; } /* '' */ +.bi_location-pin-map:before { content: '\e9b5'; } /* '' */ +.bi_location-pin-map-a:before { content: '\e9b6'; } /* '' */ +.bi_location-pin-minus:before { content: '\e9b7'; } /* '' */ +.bi_location-pin-plus:before { content: '\e9b8'; } /* '' */ +.bi_location-pin-regular:before { content: '\e9b9'; } /* '' */ +.bi_location-sign-street:before { content: '\e9ba'; } /* '' */ +.bi_tool-console:before { content: '\e9bb'; } /* '' */ +.bi_tool-console-a:before { content: '\e9bc'; } /* '' */ +.bi_tool-console-old:before { content: '\e9bd'; } /* '' */ +.bi_tool-disk:before { content: '\e9be'; } /* '' */ +.bi_tool-disk-a:before { content: '\e9bf'; } /* '' */ +.bi_tool-flashlight:before { content: '\e9c0'; } /* '' */ +.bi_tool-flashlight-a:before { content: '\e9c1'; } /* '' */ +.bi_tool-flashlight-a-s:before { content: '\e9c2'; } /* '' */ +.bi_tool-flashlight-s:before { content: '\e9c3'; } /* '' */ +.bi_tool-gameboy:before { content: '\e9c4'; } /* '' */ +.bi_tool-hammer:before { content: '\e9c5'; } /* '' */ +.bi_tool-headphone:before { content: '\e9c6'; } /* '' */ +.bi_tool-headphone-a:before { content: '\e9c7'; } /* '' */ +.bi_tool-laptop:before { content: '\e9c8'; } /* '' */ +.bi_tool-magic-wand:before { content: '\e9c9'; } /* '' */ +.bi_tool-magic-wand-a:before { content: '\e9ca'; } /* '' */ +.bi_tool-magnet:before { content: '\e9cb'; } /* '' */ +.bi_tool-magnifier:before { content: '\e9cc'; } /* '' */ +.bi_tool-medical-tape:before { content: '\e9cd'; } /* '' */ +.bi_tool-mobile:before { content: '\e9ce'; } /* '' */ +.bi_tool-mobile-l:before { content: '\e9cf'; } /* '' */ +.bi_tool-monitor:before { content: '\e9d0'; } /* '' */ +.bi_tool-monitor-a:before { content: '\e9d1'; } /* '' */ +.bi_tool-mouse:before { content: '\e9d2'; } /* '' */ +.bi_tool-net:before { content: '\e9d3'; } /* '' */ +.bi_tool-paint-roler:before { content: '\e9d4'; } /* '' */ +.bi_tool-projector:before { content: '\e9d5'; } /* '' */ +.bi_tool-radio:before { content: '\e9d6'; } /* '' */ +.bi_tool-ruler:before { content: '\e9d7'; } /* '' */ +.bi_tool-scissor:before { content: '\e9d8'; } /* '' */ +.bi_tool-tablet:before { content: '\e9d9'; } /* '' */ +.bi_tool-tablet-l:before { content: '\e9da'; } /* '' */ +.bi_tool-television:before { content: '\e9db'; } /* '' */ +.bi_tool-toothbrush:before { content: '\e9dc'; } /* '' */ +.bi_tool-umbrella:before { content: '\e9dd'; } /* '' */ +.bi_tool-video:before { content: '\e9de'; } /* '' */ +.bi_tool-alt-camera:before { content: '\e9df'; } /* '' */ +.bi_tool-alt-camera-a:before { content: '\e9e0'; } /* '' */ +.bi_tool-android:before { content: '\e9e1'; } /* '' */ +.bi_tool-android-l:before { content: '\e9e2'; } /* '' */ +.bi_tool-binoculars:before { content: '\e9e3'; } /* '' */ +.bi_tool-brush:before { content: '\e9e4'; } /* '' */ +.bi_tool-brush-a:before { content: '\e9e5'; } /* '' */ +.bi_tool-calculator:before { content: '\e9e6'; } /* '' */ +.bi_tool-camera:before { content: '\e9e7'; } /* '' */ +.bi_tool-camera-a:before { content: '\e9e8'; } /* '' */ +.bi_tool-camera-b:before { content: '\e9e9'; } /* '' */ +.bi_tool-compass:before { content: '\e9ea'; } /* '' */ +.bi_transport-car-b:before { content: '\e9eb'; } /* '' */ +.bi_transport-car-c:before { content: '\e9ec'; } /* '' */ +.bi_transport-ship:before { content: '\e9ed'; } /* '' */ +.bi_transport-train:before { content: '\e9ee'; } /* '' */ +.bi_transport-truck:before { content: '\e9ef'; } /* '' */ +.bi_transport-truck-a:before { content: '\e9f0'; } /* '' */ +.bi_transport-alt-bus:before { content: '\e9f1'; } /* '' */ +.bi_transport-bicycle:before { content: '\e9f2'; } /* '' */ +.bi_transport-bicycle-a:before { content: '\e9f3'; } /* '' */ +.bi_transport-boat:before { content: '\e9f4'; } /* '' */ +.bi_transport-bus:before { content: '\e9f5'; } /* '' */ +.bi_transport-bus-a:before { content: '\e9f6'; } /* '' */ +.bi_transport-car:before { content: '\e9f7'; } /* '' */ +.bi_transport-car-a:before { content: '\e9f8'; } /* '' */ +.bi_user-male:before { content: '\e9f9'; } /* '' */ +.bi_user-male-check:before { content: '\e9fa'; } /* '' */ +.bi_user-male-cross:before { content: '\e9fb'; } /* '' */ +.bi_user-male-minus:before { content: '\e9fc'; } /* '' */ +.bi_user-male-plus:before { content: '\e9fd'; } /* '' */ +.bi_user-male-sign:before { content: '\e9fe'; } /* '' */ +.bi_user-password:before { content: '\e9ff'; } /* '' */ +.bi_user-password-u:before { content: '\ea00'; } /* '' */ +.bi_user-password-u-a:before { content: '\ea01'; } /* '' */ +.bi_user-single:before { content: '\ea02'; } /* '' */ +.bi_user-single-a:before { content: '\ea03'; } /* '' */ +.bi_user-single-a-check:before { content: '\ea04'; } /* '' */ +.bi_user-single-a-cross:before { content: '\ea05'; } /* '' */ +.bi_user-single-a-group:before { content: '\ea06'; } /* '' */ +.bi_user-single-a-list:before { content: '\ea07'; } /* '' */ +.bi_user-single-a-minus:before { content: '\ea08'; } /* '' */ +.bi_user-single-a-plus:before { content: '\ea09'; } /* '' */ +.bi_user-single-check:before { content: '\ea0a'; } /* '' */ +.bi_user-single-cross:before { content: '\ea0b'; } /* '' */ +.bi_user-single-minus:before { content: '\ea0c'; } /* '' */ +.bi_user-single-plus:before { content: '\ea0d'; } /* '' */ +.bi_user-single-round:before { content: '\ea0e'; } /* '' */ +.bi_user-alt:before { content: '\ea0f'; } /* '' */ +.bi_user-alt-check:before { content: '\ea10'; } /* '' */ +.bi_user-alt-cross:before { content: '\ea11'; } /* '' */ +.bi_user-alt-group:before { content: '\ea12'; } /* '' */ +.bi_user-alt-list:before { content: '\ea13'; } /* '' */ +.bi_user-alt-minus:before { content: '\ea14'; } /* '' */ +.bi_user-alt-plus:before { content: '\ea15'; } /* '' */ +.bi_user-contact-book:before { content: '\ea16'; } /* '' */ +.bi_user-female:before { content: '\ea17'; } /* '' */ +.bi_user-female-cross:before { content: '\ea18'; } /* '' */ +.bi_user-female-group:before { content: '\ea19'; } /* '' */ +.bi_user-female-list:before { content: '\ea1a'; } /* '' */ +.bi_user-female-minus:before { content: '\ea1b'; } /* '' */ +.bi_user-female-plus:before { content: '\ea1c'; } /* '' */ +.bi_user-female-sign:before { content: '\ea1d'; } /* '' */ +.bi_user-female-tick:before { content: '\ea1e'; } /* '' */ +.bi_user-key:before { content: '\ea1f'; } /* '' */ +.bi_user-lock:before { content: '\ea20'; } /* '' */ +.bi_user-lock-u:before { content: '\ea21'; } /* '' */ +.bi_user-lock-u-a:before { content: '\ea22'; } /* '' */ +.bi_weather-sunset-a:before { content: '\ea23'; } /* '' */ +.bi_weather-wind:before { content: '\ea24'; } /* '' */ +.bi_weather-wind-pressure:before { content: '\ea25'; } /* '' */ +.bi_weather-wind-pressure-a:before { content: '\ea26'; } /* '' */ +.bi_weather-cloud:before { content: '\ea27'; } /* '' */ +.bi_weather-cloud-a:before { content: '\ea28'; } /* '' */ +.bi_weather-cloud-rainy:before { content: '\ea29'; } /* '' */ +.bi_weather-cloud-rainy-a:before { content: '\ea2a'; } /* '' */ +.bi_weather-cloud-snow:before { content: '\ea2b'; } /* '' */ +.bi_weather-cloud-snow-a:before { content: '\ea2c'; } /* '' */ +.bi_weather-cloud-stormy:before { content: '\ea2d'; } /* '' */ +.bi_weather-cloud-stormy-a:before { content: '\ea2e'; } /* '' */ +.bi_weather-cloud-sun:before { content: '\ea2f'; } /* '' */ +.bi_weather-humid:before { content: '\ea30'; } /* '' */ +.bi_weather-moon:before { content: '\ea31'; } /* '' */ +.bi_weather-moon-a:before { content: '\ea32'; } /* '' */ +.bi_weather-moon-b:before { content: '\ea33'; } /* '' */ +.bi_weather-moon-r:before { content: '\ea34'; } /* '' */ +.bi_weather-sun-a:before { content: '\ea35'; } /* '' */ +.bi_weather-sun-b:before { content: '\ea36'; } /* '' */ +.bi_weather-sun-r:before { content: '\ea37'; } /* '' */ +.bi_weather-sunrise:before { content: '\ea38'; } /* '' */ +.bi_web-bug:before { content: '\ea39'; } /* '' */ +.bi_web-code:before { content: '\ea3a'; } /* '' */ +.bi_web-database:before { content: '\ea3b'; } /* '' */ +.bi_web-download:before { content: '\ea3c'; } /* '' */ +.bi_web-graph:before { content: '\ea3d'; } /* '' */ +.bi_web-inspect:before { content: '\ea3e'; } /* '' */ +.bi_web-internet:before { content: '\ea3f'; } /* '' */ +.bi_web-internet-a:before { content: '\ea40'; } /* '' */ +.bi_web-logout:before { content: '\ea41'; } /* '' */ +.bi_web-menu-collapse-down:before { content: '\ea42'; } /* '' */ +.bi_web-menu-collapse-left:before { content: '\ea43'; } /* '' */ +.bi_web-menu-collapse-right:before { content: '\ea44'; } /* '' */ +.bi_web-menu-collapse-up:before { content: '\ea45'; } /* '' */ +.bi_web-reading-list:before { content: '\ea46'; } /* '' */ +.bi_web-report:before { content: '\ea47'; } /* '' */ +.bi_web-report-a:before { content: '\ea48'; } /* '' */ +.bi_web-rss:before { content: '\ea49'; } /* '' */ +.bi_web-share:before { content: '\ea4a'; } /* '' */ +.bi_web-share-a:before { content: '\ea4b'; } /* '' */ +.bi_web-share-b:before { content: '\ea4c'; } /* '' */ +.bi_web-statistic:before { content: '\ea4d'; } /* '' */ +.bi_web-traffic:before { content: '\ea4e'; } /* '' */ +.bi_web-traffic-a:before { content: '\ea4f'; } /* '' */ +.bi_web-traffic-b:before { content: '\ea50'; } /* '' */ +.bi_web-traffic-c:before { content: '\ea51'; } /* '' */ +.bi_web-upload:before { content: '\ea52'; } /* '' */ +.bi_web-url:before { content: '\ea53'; } /* '' */ +.bi_web-url-a:before { content: '\ea54'; } /* '' */ +.bi_web-url-b:before { content: '\ea55'; } /* '' */ +.bi_web-warning:before { content: '\ea56'; } /* '' */ +.bi_web-webcam:before { content: '\ea57'; } /* '' */ +.bi_web-broken-link:before { content: '\ea58'; } /* '' */ +.bi_web-browser:before { content: '\ea59'; } /* '' */ +.bi_web-browser-a:before { content: '\ea5a'; } /* '' */ +.bi_web-browser-b:before { content: '\ea5b'; } /* '' */ +.bi_web-browser-cross:before { content: '\ea5c'; } /* '' */ +.bi_web-browser-minus:before { content: '\ea5d'; } /* '' */ +.bi_web-browser-plus:before { content: '\ea5e'; } /* '' */ +.bi_web-browser-tab:before { content: '\ea5f'; } /* '' */ +.bi_web-browser-tab-cross:before { content: '\ea60'; } /* '' */ +.bi_web-browser-tab-minus:before { content: '\ea61'; } /* '' */ +.bi_web-browser-tab-plus:before { content: '\ea62'; } /* '' */ +.bi_web-browser-tab-tick:before { content: '\ea63'; } /* '' */ +.bi_web-browser-tick:before { content: '\ea64'; } /* '' */ +.bi_web-browser-window:before { content: '\ea65'; } /* '' */ +.bi_logo-vimeo:before { content: '\ea66'; } /* '' */ +.bi_logo-windows:before { content: '\ea67'; } /* '' */ +.bi_logo-zerply:before { content: '\ea68'; } /* '' */ +.bi_logo-amazon:before { content: '\ea69'; } /* '' */ +.bi_logo-dribbble:before { content: '\ea6a'; } /* '' */ +.bi_logo-dropbox:before { content: '\ea6b'; } /* '' */ +.bi_logo-evernote:before { content: '\ea6c'; } /* '' */ +.bi_logo-facebook:before { content: '\ea6d'; } /* '' */ +.bi_logo-grooveshark:before { content: '\ea6e'; } /* '' */ +.bi_logo-instagram:before { content: '\ea6f'; } /* '' */ +.bi_logo-linkedin:before { content: '\ea70'; } /* '' */ +.bi_logo-musio:before { content: '\ea71'; } /* '' */ +.bi_logo-path:before { content: '\ea72'; } /* '' */ +.bi_logo-paypal:before { content: '\ea73'; } /* '' */ +.bi_logo-picasa:before { content: '\ea74'; } /* '' */ +.bi_logo-pinterest:before { content: '\ea75'; } /* '' */ +.bi_logo-rdio:before { content: '\ea76'; } /* '' */ +.bi_logo-squarespace:before { content: '\ea77'; } /* '' */ +.bi_logo-squareup:before { content: '\ea78'; } /* '' */ +.bi_logo-twitter:before { content: '\ea79'; } /* '' */ +.bi_misc-one-click:before { content: '\ea7a'; } /* '' */ +.bi_misc-pointer:before { content: '\ea7b'; } /* '' */ +.bi_misc-pointer-swipe-l:before { content: '\ea7c'; } /* '' */ +.bi_misc-pointer-swipe-r:before { content: '\ea7d'; } /* '' */ +.bi_misc-puzzle:before { content: '\ea7e'; } /* '' */ +.bi_misc-wifi:before { content: '\ea7f'; } /* '' */ +.bi_misc-crown:before { content: '\ea80'; } /* '' */ +.bi_misc-cube:before { content: '\ea81'; } /* '' */ +.bi_misc-dice-five:before { content: '\ea82'; } /* '' */ +.bi_misc-dice-four:before { content: '\ea83'; } /* '' */ +.bi_misc-dice-one:before { content: '\ea84'; } /* '' */ +.bi_misc-dice-six:before { content: '\ea85'; } /* '' */ +.bi_misc-dice-three:before { content: '\ea86'; } /* '' */ +.bi_misc-dice-two:before { content: '\ea87'; } /* '' */ +.bi_misc-double-click:before { content: '\ea88'; } /* '' */ +.bi_misc-female-gender:before { content: '\ea89'; } /* '' */ +.bi_misc-globe:before { content: '\ea8a'; } /* '' */ +.bi_misc-male-gender:before { content: '\ea8b'; } /* '' */ +.bi_misc-mood-happy:before { content: '\ea8c'; } /* '' */ +.bi_misc-mood-sad:before { content: '\ea8d'; } /* '' */ +.bi_music-mic:before { content: '\ea8e'; } /* '' */ +.bi_music-mic-a:before { content: '\ea8f'; } /* '' */ +.bi_music-next:before { content: '\ea90'; } /* '' */ +.bi_music-next-l:before { content: '\ea91'; } /* '' */ +.bi_music-next-l-a:before { content: '\ea92'; } /* '' */ +.bi_music-pause:before { content: '\ea93'; } /* '' */ +.bi_music-pause-a:before { content: '\ea94'; } /* '' */ +.bi_music-pause-b:before { content: '\ea95'; } /* '' */ +.bi_music-play:before { content: '\ea96'; } /* '' */ +.bi_music-playlist:before { content: '\ea97'; } /* '' */ +.bi_music-previous:before { content: '\ea98'; } /* '' */ +.bi_music-previous-l:before { content: '\ea99'; } /* '' */ +.bi_music-previous-l-a:before { content: '\ea9a'; } /* '' */ +.bi_music-radio:before { content: '\ea9b'; } /* '' */ +.bi_music-record:before { content: '\ea9c'; } /* '' */ +.bi_music-record-a:before { content: '\ea9d'; } /* '' */ +.bi_music-repeat:before { content: '\ea9e'; } /* '' */ +.bi_music-repeat-a:before { content: '\ea9f'; } /* '' */ +.bi_music-repeat-one:before { content: '\eaa0'; } /* '' */ +.bi_music-repeat-one-a:before { content: '\eaa1'; } /* '' */ +.bi_music-shuffle:before { content: '\eaa2'; } /* '' */ +.bi_music-shuffle-a:before { content: '\eaa3'; } /* '' */ +.bi_music-song-note:before { content: '\eaa4'; } /* '' */ +.bi_music-song-note-a:before { content: '\eaa5'; } /* '' */ +.bi_music-speaker:before { content: '\eaa6'; } /* '' */ +.bi_music-speaker-a:before { content: '\eaa7'; } /* '' */ +.bi_music-stop:before { content: '\eaa8'; } /* '' */ +.bi_music-stop-a:before { content: '\eaa9'; } /* '' */ +.bi_volume-high:before { content: '\eaaa'; } /* '' */ +.bi_volume-high-a:before { content: '\eaab'; } /* '' */ +.bi_volume-low:before { content: '\eaac'; } /* '' */ +.bi_volume-low-a:before { content: '\eaad'; } /* '' */ +.bi_volume-medium:before { content: '\eaae'; } /* '' */ +.bi_volume-medium-a:before { content: '\eaaf'; } /* '' */ +.bi_volume-mute:before { content: '\eab0'; } /* '' */ +.bi_volume-mute-a:before { content: '\eab1'; } /* '' */ +.bi_music-album:before { content: '\eab2'; } /* '' */ +.bi_music-album-a:before { content: '\eab3'; } /* '' */ +.bi_music-album-b:before { content: '\eab4'; } /* '' */ +.bi_music-album-c:before { content: '\eab5'; } /* '' */ +.bi_music-album-cd:before { content: '\eab6'; } /* '' */ +.bi_music-cd:before { content: '\eab7'; } /* '' */ +.bi_music-eject:before { content: '\eab8'; } /* '' */ +.bi_music-eq:before { content: '\eab9'; } /* '' */ +.bi_music-eq-a:before { content: '\eaba'; } /* '' */ +.bi_music-group-note:before { content: '\eabb'; } /* '' */ +.bi_music-group-note-a:before { content: '\eabc'; } /* '' */ +.bi_music-headphone:before { content: '\eabd'; } /* '' */ +.bi_music-headphone-a:before { content: '\eabe'; } /* '' */ +.bi_music-list:before { content: '\eabf'; } /* '' */ +.bi_interface-backspace:before { content: '\eac0'; } /* '' */ +.bi_interface-backspace-a:before { content: '\eac1'; } /* '' */ +.bi_interface-bell:before { content: '\eac2'; } /* '' */ +.bi_interface-bell-a:before { content: '\eac3'; } /* '' */ +.bi_interface-block:before { content: '\eac4'; } /* '' */ +.bi_interface-bottom:before { content: '\eac5'; } /* '' */ +.bi_interface-bottom-k:before { content: '\eac6'; } /* '' */ +.bi_interface-bottom-r:before { content: '\eac7'; } /* '' */ +.bi_interface-box-bottom:before { content: '\eac8'; } /* '' */ +.bi_interface-box-bottom-a:before { content: '\eac9'; } /* '' */ +.bi_interface-box-cross:before { content: '\eaca'; } /* '' */ +.bi_interface-box-left:before { content: '\eacb'; } /* '' */ +.bi_interface-box-left-a:before { content: '\eacc'; } /* '' */ +.bi_interface-box-minus:before { content: '\eacd'; } /* '' */ +.bi_interface-box-plus:before { content: '\eace'; } /* '' */ +.bi_interface-box-right:before { content: '\eacf'; } /* '' */ +.bi_interface-box-right-a:before { content: '\ead0'; } /* '' */ +.bi_interface-box-tick:before { content: '\ead1'; } /* '' */ +.bi_interface-box-top:before { content: '\ead2'; } /* '' */ +.bi_interface-box-top-a:before { content: '\ead3'; } /* '' */ +.bi_interface-bulleye:before { content: '\ead4'; } /* '' */ +.bi_interface-calendar:before { content: '\ead5'; } /* '' */ +.bi_interface-circle:before { content: '\ead6'; } /* '' */ +.bi_interface-circle-cross:before { content: '\ead7'; } /* '' */ +.bi_interface-circle-minus:before { content: '\ead8'; } /* '' */ +.bi_interface-circle-plus:before { content: '\ead9'; } /* '' */ +.bi_interface-circle-tick:before { content: '\eada'; } /* '' */ +.bi_interface-circle-tick-a:before { content: '\eadb'; } /* '' */ +.bi_interface-clock:before { content: '\eadc'; } /* '' */ +.bi_interface-clock-a:before { content: '\eadd'; } /* '' */ +.bi_interface-clock-b:before { content: '\eade'; } /* '' */ +.bi_interface-cloud-download:before { content: '\eadf'; } /* '' */ +.bi_interface-cloud-upload:before { content: '\eae0'; } /* '' */ +.bi_interface-cmd:before { content: '\eae1'; } /* '' */ +.bi_interface-crop:before { content: '\eae2'; } /* '' */ +.bi_interface-cross:before { content: '\eae3'; } /* '' */ +.bi_interface-dashboard:before { content: '\eae4'; } /* '' */ +.bi_interface-direction:before { content: '\eae7'; } /* '' */ +.bi_interface-downloading:before { content: '\eae8'; } /* '' */ +.bi_interface-enlarge:before { content: '\eae9'; } /* '' */ +.bi_interface-enlarge-a:before { content: '\eaea'; } /* '' */ +.bi_interface-enlarge-c:before { content: '\eaeb'; } /* '' */ +.bi_interface-expand:before { content: '\eaec'; } /* '' */ +.bi_interface-forward:before { content: '\eaed'; } /* '' */ +.bi_interface-fullscreen:before { content: '\eaee'; } /* '' */ +.bi_interface-fullscreen-a:before { content: '\eaef'; } /* '' */ +.bi_interface-fullscreen-wide:before { content: '\eaf0'; } /* '' */ +.bi_interface-hamburger:before { content: '\eaf1'; } /* '' */ +.bi_interface-heart:before { content: '\eaf2'; } /* '' */ +.bi_interface-help:before { content: '\eaf3'; } /* '' */ +.bi_interface-help-a:before { content: '\eaf4'; } /* '' */ +.bi_interface-home:before { content: '\eaf5'; } /* '' */ +.bi_interface-home-a:before { content: '\eaf6'; } /* '' */ +.bi_interface-horizontal:before { content: '\eaf7'; } /* '' */ +.bi_interface-horizontal-a:before { content: '\eaf8'; } /* '' */ +.bi_interface-in-link:before { content: '\eaf9'; } /* '' */ +.bi_interface-left:before { content: '\eafa'; } /* '' */ +.bi_interface-left-b-k:before { content: '\eafb'; } /* '' */ +.bi_interface-left-k:before { content: '\eafc'; } /* '' */ +.bi_interface-left-r:before { content: '\eafd'; } /* '' */ +.bi_interface-left-t-k:before { content: '\eafe'; } /* '' */ +.bi_interface-list-view:before { content: '\eaff'; } /* '' */ +.bi_interface-login:before { content: '\eb00'; } /* '' */ +.bi_interface-logout-a:before { content: '\eb01'; } /* '' */ +.bi_interface-minimize:before { content: '\eb02'; } /* '' */ +.bi_interface-minus:before { content: '\eb03'; } /* '' */ +.bi_interface-more:before { content: '\eb04'; } /* '' */ +.bi_interface-number:before { content: '\eb05'; } /* '' */ +.bi_interface-out-link:before { content: '\eb06'; } /* '' */ +.bi_interface-pixel:before { content: '\eb07'; } /* '' */ +.bi_interface-places:before { content: '\eb08'; } /* '' */ +.bi_interface-places-a:before { content: '\eb09'; } /* '' */ +.bi_interface-plus:before { content: '\eb0a'; } /* '' */ +.bi_interface-popup:before { content: '\eb0b'; } /* '' */ +.bi_interface-power:before { content: '\eb0c'; } /* '' */ +.bi_interface-refresh:before { content: '\eb0d'; } /* '' */ +.bi_interface-repeating:before { content: '\eb0e'; } /* '' */ +.bi_interface-reply:before { content: '\eb0f'; } /* '' */ +.bi_interface-resize-full:before { content: '\eb10'; } /* '' */ +.bi_interface-resize-full-a:before { content: '\eb11'; } /* '' */ +.bi_interface-resize-normal:before { content: '\eb12'; } /* '' */ +.bi_interface-reverse:before { content: '\eb13'; } /* '' */ +.bi_interface-right:before { content: '\eb14'; } /* '' */ +.bi_interface-right-k:before { content: '\eb15'; } /* '' */ +.bi_interface-right-r:before { content: '\eb16'; } /* '' */ +.bi_interface-rigth-b-k:before { content: '\eb17'; } /* '' */ +.bi_interface-rigth-t-k:before { content: '\eb18'; } /* '' */ +.bi_interface-search:before { content: '\eb19'; } /* '' */ +.bi_interface-search-cross:before { content: '\eb1a'; } /* '' */ +.bi_interface-search-minus:before { content: '\eb1b'; } /* '' */ +.bi_interface-search-plus:before { content: '\eb1c'; } /* '' */ +.bi_interface-search-tick:before { content: '\eb1d'; } /* '' */ +.bi_interface-sidebar-hamburger:before { content: '\eb1e'; } /* '' */ +.bi_interface-star:before { content: '\eb1f'; } /* '' */ +.bi_interface-star-a:before { content: '\eb20'; } /* '' */ +.bi_interface-target:before { content: '\eb21'; } /* '' */ +.bi_interface-thumbnail:before { content: '\eb22'; } /* '' */ +.bi_interface-tick:before { content: '\eb23'; } /* '' */ +.bi_interface-top:before { content: '\eb24'; } /* '' */ +.bi_interface-top-k:before { content: '\eb25'; } /* '' */ +.bi_interface-top-r:before { content: '\eb26'; } /* '' */ +.bi_interface-undo:before { content: '\eb27'; } /* '' */ +.bi_interface-uploading:before { content: '\eb28'; } /* '' */ +.bi_interface-vertical:before { content: '\eb29'; } /* '' */ +.bi_interface-vertical-a:before { content: '\eb2a'; } /* '' */ +.bi_interface-view:before { content: '\eb2b'; } /* '' */ +.bi_interface-warning:before { content: '\eb2c'; } /* '' */ +.bi_interface-window:before { content: '\eb2d'; } /* '' */ +.bi_layout-footer:before { content: '\eb2e'; } /* '' */ +.bi_layout-grid:before { content: '\eb2f'; } /* '' */ +.bi_layout-half:before { content: '\eb30'; } /* '' */ +.bi_layout-header:before { content: '\eb31'; } /* '' */ +.bi_layout-sidebar-l:before { content: '\eb32'; } /* '' */ +.bi_layout-sidebar-l-a:before { content: '\eb33'; } /* '' */ +.bi_layout-sidebar-l-half:before { content: '\eb34'; } /* '' */ +.bi_layout-sidebar-l-half-a:before { content: '\eb35'; } /* '' */ +.bi_layout-sidebar-r:before { content: '\eb36'; } /* '' */ +.bi_layout-sidebar-r-a:before { content: '\eb37'; } /* '' */ +.bi_layout-sidebar-r-half:before { content: '\eb38'; } /* '' */ +.bi_layout-sidebar-r-half-a:before { content: '\eb39'; } /* '' */ +.bi_layout-third-h:before { content: '\eb3a'; } /* '' */ +.bi_layout-third-v:before { content: '\eb3b'; } /* '' */ +.bi_layout-wireframe:before { content: '\eb3c'; } /* '' */ +.bi_layout-wireframe-a:before { content: '\eb3d'; } /* '' */ +.bi_interface-alt-cross:before { content: '\eb3e'; } /* '' */ +.bi_interface-alt-fullscreen:before { content: '\eb3f'; } /* '' */ +.bi_interface-alt-minus:before { content: '\eb40'; } /* '' */ +.bi_interface-alt-plus:before { content: '\eb41'; } /* '' */ +.bi_interface-alt-tick:before { content: '\eb42'; } /* '' */ +.bi_interface-alt-widescreen:before { content: '\eb43'; } /* '' */ +.bi_interface-arrow-all:before { content: '\eb44'; } /* '' */ +.bi_interface-arrow-bottom:before { content: '\eb45'; } /* '' */ +.bi_interface-arrow-bottom-circle:before { content: '\eb46'; } /* '' */ +.bi_interface-arrow-left:before { content: '\eb47'; } /* '' */ +.bi_interface-arrow-left-b:before { content: '\eb48'; } /* '' */ +.bi_interface-arrow-left-circle:before { content: '\eb49'; } /* '' */ +.bi_interface-arrow-left-t:before { content: '\eb4a'; } /* '' */ +.bi_interface-arrow-right:before { content: '\eb4b'; } /* '' */ +.bi_interface-arrow-right-b:before { content: '\eb4c'; } /* '' */ +.bi_interface-arrow-right-circle:before { content: '\eb4d'; } /* '' */ +.bi_interface-arrow-right-t:before { content: '\eb4e'; } /* '' */ +.bi_interface-arrow-top:before { content: '\eb4f'; } /* '' */ +.bi_interface-arrow-top-circle:before { content: '\eb50'; } /* '' */ +.bi_animal-dog-a:before { content: '\eb51'; } /* '' */ +.bi_interface-horizontal-a-1:before { content: '\eb52'; } /* '' */ +.bi_interface-vertical-a-1:before { content: '\eb53'; } /* '' */ +.bi_interface-diag:before { content: '\eb54'; } /* '' */ +.bi_interface-diag-a:before { content: '\eb55'; } /* '' */ \ No newline at end of file diff --git a/webui/css/budicon.css b/webui/css/budicon.css new file mode 100644 index 000000000..3335455ef --- /dev/null +++ b/webui/css/budicon.css @@ -0,0 +1,900 @@ +@font-face { + font-family: 'budicon'; + src: url('../fonts/budicon.ttf?42886572') format('truetype'); + font-weight: normal; + font-style: normal; +} +/* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */ +/* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */ +/* +@media screen and (-webkit-min-device-pixel-ratio:0) { + @font-face { + font-family: 'budicon'; + src: url('../font/budicon.svg?42886572#budicon') format('svg'); + } +} +*/ + + [class^="bi_"]:before, [class*=" bi_"]:before { + font-family: "budicon"; + font-style: normal; + font-weight: normal; + speak: none; + + display: inline-block; + text-decoration: inherit; + width: 1em; + margin-right: .2em; + text-align: center; + /* opacity: .8; */ + + /* For safety - reset parent styles, that can break glyph codes*/ + font-variant: normal; + text-transform: none; + + /* fix buttons height, for twitter bootstrap */ + line-height: 1em; + + /* Animation center compensation - margins should be symmetric */ + /* remove if not needed */ + margin-left: .2em; + + /* you can be more comfortable with increased icons size */ + /* font-size: 120%; */ + + /* Uncomment for 3D effect */ + /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */ +} + +.bi_animal-fish:before { content: '\e800'; } /* '' */ +.bi_animal-fox:before { content: '\e801'; } /* '' */ +.bi_animal-frog:before { content: '\e802'; } /* '' */ +.bi_animal-goose:before { content: '\e803'; } /* '' */ +.bi_animal-husky:before { content: '\e804'; } /* '' */ +.bi_animal-lion:before { content: '\e805'; } /* '' */ +.bi_animal-monkey:before { content: '\e806'; } /* '' */ +.bi_animal-monkey-a:before { content: '\e807'; } /* '' */ +.bi_animal-mouse:before { content: '\e808'; } /* '' */ +.bi_animal-pig:before { content: '\e809'; } /* '' */ +.bi_animal-pig-a:before { content: '\e80a'; } /* '' */ +.bi_animal-sheep:before { content: '\e80b'; } /* '' */ +.bi_animal-shrimp:before { content: '\e80c'; } /* '' */ +.bi_animal-wolf:before { content: '\e80d'; } /* '' */ +.bi_animal-bull:before { content: '\e80e'; } /* '' */ +.bi_animal-cat:before { content: '\e80f'; } /* '' */ +.bi_animal-chicken:before { content: '\e810'; } /* '' */ +.bi_animal-cow:before { content: '\e811'; } /* '' */ +.bi_animal-cow-a:before { content: '\e812'; } /* '' */ +.bi_animal-dog:before { content: '\e813'; } /* '' */ +.bi_com-bubble-dot-b:before { content: '\e814'; } /* '' */ +.bi_com-bubble-line:before { content: '\e815'; } /* '' */ +.bi_com-bubble-line-a:before { content: '\e816'; } /* '' */ +.bi_com-bubble-line-b:before { content: '\e817'; } /* '' */ +.bi_com-chat:before { content: '\e818'; } /* '' */ +.bi_com-check-box:before { content: '\e819'; } /* '' */ +.bi_com-email:before { content: '\e81a'; } /* '' */ +.bi_com-email-cross:before { content: '\e81b'; } /* '' */ +.bi_com-email-minus:before { content: '\e81c'; } /* '' */ +.bi_com-email-o:before { content: '\e81d'; } /* '' */ +.bi_com-email-plus:before { content: '\e81e'; } /* '' */ +.bi_com-email-tick:before { content: '\e81f'; } /* '' */ +.bi_com-envelope:before { content: '\e820'; } /* '' */ +.bi_com-feather-pen:before { content: '\e821'; } /* '' */ +.bi_com-fountain-pen:before { content: '\e822'; } /* '' */ +.bi_com-group-bubble:before { content: '\e823'; } /* '' */ +.bi_com-group-bubble-a:before { content: '\e824'; } /* '' */ +.bi_com-group-bubble-b:before { content: '\e825'; } /* '' */ +.bi_com-group-bubble-c:before { content: '\e826'; } /* '' */ +.bi_com-group-bubble-d:before { content: '\e827'; } /* '' */ +.bi_com-help:before { content: '\e828'; } /* '' */ +.bi_com-help-a:before { content: '\e829'; } /* '' */ +.bi_com-megaphone:before { content: '\e82a'; } /* '' */ +.bi_com-megaphone-a:before { content: '\e82b'; } /* '' */ +.bi_com-mic:before { content: '\e82c'; } /* '' */ +.bi_com-mic-mute:before { content: '\e82d'; } /* '' */ +.bi_com-paperplane:before { content: '\e82e'; } /* '' */ +.bi_com-phone:before { content: '\e82f'; } /* '' */ +.bi_com-phone-a:before { content: '\e830'; } /* '' */ +.bi_com-pictures:before { content: '\e831'; } /* '' */ +.bi_com-voicemail:before { content: '\e832'; } /* '' */ +.bi_com-bell:before { content: '\e833'; } /* '' */ +.bi_com-bell-a:before { content: '\e834'; } /* '' */ +.bi_com-broadcast:before { content: '\e835'; } /* '' */ +.bi_com-broadcast-a:before { content: '\e836'; } /* '' */ +.bi_com-bubble:before { content: '\e837'; } /* '' */ +.bi_com-bubble-a:before { content: '\e838'; } /* '' */ +.bi_com-bubble-b:before { content: '\e839'; } /* '' */ +.bi_com-bubble-dot:before { content: '\e83a'; } /* '' */ +.bi_com-bubble-dot-a:before { content: '\e83b'; } /* '' */ +.bi_doc-analytic-blank:before { content: '\e83c'; } /* '' */ +.bi_doc-analytic-line:before { content: '\e83d'; } /* '' */ +.bi_doc-analytic-line-a:before { content: '\e83e'; } /* '' */ +.bi_doc-article:before { content: '\e83f'; } /* '' */ +.bi_doc-article-a:before { content: '\e840'; } /* '' */ +.bi_doc-article-b:before { content: '\e841'; } /* '' */ +.bi_doc-attachment:before { content: '\e842'; } /* '' */ +.bi_doc-attachment-a:before { content: '\e843'; } /* '' */ +.bi_doc-binder-blank:before { content: '\e844'; } /* '' */ +.bi_doc-binder-four:before { content: '\e845'; } /* '' */ +.bi_doc-binder-one:before { content: '\e846'; } /* '' */ +.bi_doc-binder-three:before { content: '\e847'; } /* '' */ +.bi_doc-binder-two:before { content: '\e848'; } /* '' */ +.bi_doc-binder-zero:before { content: '\e849'; } /* '' */ +.bi_doc-book:before { content: '\e84a'; } /* '' */ +.bi_doc-book-a:before { content: '\e84b'; } /* '' */ +.bi_doc-book-b:before { content: '\e84c'; } /* '' */ +.bi_doc-book-c:before { content: '\e84d'; } /* '' */ +.bi_doc-book-d:before { content: '\e84e'; } /* '' */ +.bi_doc-bookmark:before { content: '\e84f'; } /* '' */ +.bi_doc-book-mark:before { content: '\e850'; } /* '' */ +.bi_doc-box:before { content: '\e851'; } /* '' */ +.bi_doc-briefcase:before { content: '\e852'; } /* '' */ +.bi_doc-briefcase-a:before { content: '\e853'; } /* '' */ +.bi_doc-briefcase-b:before { content: '\e854'; } /* '' */ +.bi_doc-briefcase-c:before { content: '\e855'; } /* '' */ +.bi_doc-briefcase-d:before { content: '\e856'; } /* '' */ +.bi_doc-compose:before { content: '\e857'; } /* '' */ +.bi_doc-compose-a:before { content: '\e858'; } /* '' */ +.bi_doc-documents:before { content: '\e859'; } /* '' */ +.bi_doc-documents-minus:before { content: '\e85a'; } /* '' */ +.bi_doc-documents-plus:before { content: '\e85b'; } /* '' */ +.bi_doc-download:before { content: '\e85c'; } /* '' */ +.bi_doc-drawer:before { content: '\e85d'; } /* '' */ +.bi_doc-drawer-a:before { content: '\e85e'; } /* '' */ +.bi_doc-drawer-b:before { content: '\e85f'; } /* '' */ +.bi_doc-drawer-blank:before { content: '\e860'; } /* '' */ +.bi_doc-drawer-download:before { content: '\e861'; } /* '' */ +.bi_doc-drawer-line:before { content: '\e862'; } /* '' */ +.bi_doc-drawer-upload:before { content: '\e863'; } /* '' */ +.bi_doc-envelope:before { content: '\e864'; } /* '' */ +.bi_doc-file-blank:before { content: '\e865'; } /* '' */ +.bi_doc-file-blank-a:before { content: '\e866'; } /* '' */ +.bi_doc-file-cross:before { content: '\e867'; } /* '' */ +.bi_doc-file-cross-a:before { content: '\e868'; } /* '' */ +.bi_doc-file-line:before { content: '\e869'; } /* '' */ +.bi_doc-file-line-a:before { content: '\e86a'; } /* '' */ +.bi_doc-file-minus:before { content: '\e86b'; } /* '' */ +.bi_doc-file-minus-a:before { content: '\e86c'; } /* '' */ +.bi_doc-file-plus:before { content: '\e86d'; } /* '' */ +.bi_doc-file-plus-a:before { content: '\e86e'; } /* '' */ +.bi_doc-file-stack:before { content: '\e86f'; } /* '' */ +.bi_doc-file-tick:before { content: '\e870'; } /* '' */ +.bi_doc-file-tick-a:before { content: '\e871'; } /* '' */ +.bi_doc-folder:before { content: '\e872'; } /* '' */ +.bi_doc-folder-a:before { content: '\e873'; } /* '' */ +.bi_doc-folder-check-a:before { content: '\e874'; } /* '' */ +.bi_doc-folder-cross:before { content: '\e875'; } /* '' */ +.bi_doc-folder-cross-a:before { content: '\e876'; } /* '' */ +.bi_doc-folder-minus:before { content: '\e877'; } /* '' */ +.bi_doc-folder-minus-a:before { content: '\e878'; } /* '' */ +.bi_doc-folder-plus:before { content: '\e879'; } /* '' */ +.bi_doc-folder-plus-a:before { content: '\e87a'; } /* '' */ +.bi_doc-folder-s:before { content: '\e87b'; } /* '' */ +.bi_doc-folder-sync:before { content: '\e87c'; } /* '' */ +.bi_doc-folder-tick:before { content: '\e87d'; } /* '' */ +.bi_doc-list:before { content: '\e87e'; } /* '' */ +.bi_doc-news:before { content: '\e87f'; } /* '' */ +.bi_doc-newspaper:before { content: '\e880'; } /* '' */ +.bi_doc-newspaper-a:before { content: '\e881'; } /* '' */ +.bi_doc-newspaper-b:before { content: '\e882'; } /* '' */ +.bi_doc-notebook:before { content: '\e883'; } /* '' */ +.bi_doc-notebook-a:before { content: '\e884'; } /* '' */ +.bi_doc-note-pen:before { content: '\e885'; } /* '' */ +.bi_doc-paper-line:before { content: '\e886'; } /* '' */ +.bi_doc-papers:before { content: '\e887'; } /* '' */ +.bi_doc-paper-stack:before { content: '\e888'; } /* '' */ +.bi_doc-photo-stack:before { content: '\e889'; } /* '' */ +.bi_doc-pie:before { content: '\e88a'; } /* '' */ +.bi_doc-pie-a:before { content: '\e88b'; } /* '' */ +.bi_doc-pie-b:before { content: '\e88c'; } /* '' */ +.bi_doc-pin:before { content: '\e88d'; } /* '' */ +.bi_doc-pin-a:before { content: '\e88e'; } /* '' */ +.bi_doc-print:before { content: '\e88f'; } /* '' */ +.bi_doc-print-a:before { content: '\e890'; } /* '' */ +.bi_doc-profile:before { content: '\e891'; } /* '' */ +.bi_doc-profile-a:before { content: '\e892'; } /* '' */ +.bi_doc-upload:before { content: '\e893'; } /* '' */ +.bi_doc-wboard-line:before { content: '\e894'; } /* '' */ +.bi_doc-wboard-tick:before { content: '\e895'; } /* '' */ +.bi_media-glass:before { content: '\e896'; } /* '' */ +.bi_media-glass-a:before { content: '\e897'; } /* '' */ +.bi_media-image:before { content: '\e898'; } /* '' */ +.bi_media-image-a:before { content: '\e899'; } /* '' */ +.bi_media-image-b:before { content: '\e89a'; } /* '' */ +.bi_media-image-c:before { content: '\e89b'; } /* '' */ +.bi_media-image-d:before { content: '\e89c'; } /* '' */ +.bi_media-negative:before { content: '\e89d'; } /* '' */ +.bi_media-negative-a:before { content: '\e89e'; } /* '' */ +.bi_media-video:before { content: '\e89f'; } /* '' */ +.bi_media-video-a:before { content: '\e8a0'; } /* '' */ +.bi_media-video-clip:before { content: '\e8a1'; } /* '' */ +.bi_media-video-r:before { content: '\e8a2'; } /* '' */ +.bi_business-tie:before { content: '\e8a3'; } /* '' */ +.bi_business-tie-a:before { content: '\e8a4'; } /* '' */ +.bi_business-tie-b:before { content: '\e8a5'; } /* '' */ +.bi_doc-analytic-bar:before { content: '\e8a6'; } /* '' */ +.bi_ecommerce-basket:before { content: '\e8a7'; } /* '' */ +.bi_ecommerce-bill:before { content: '\e8a8'; } /* '' */ +.bi_ecommerce-bill-a:before { content: '\e8a9'; } /* '' */ +.bi_ecommerce-bill-b:before { content: '\e8aa'; } /* '' */ +.bi_ecommerce-bowtie:before { content: '\e8ab'; } /* '' */ +.bi_ecommerce-cash:before { content: '\e8ac'; } /* '' */ +.bi_ecommerce-cash-a:before { content: '\e8ad'; } /* '' */ +.bi_ecommerce-coins:before { content: '\e8ae'; } /* '' */ +.bi_ecommerce-coins-a:before { content: '\e8af'; } /* '' */ +.bi_ecommerce-creditcard:before { content: '\e8b0'; } /* '' */ +.bi_ecommerce-creditcard-b:before { content: '\e8b1'; } /* '' */ +.bi_ecommerce-creditcard-c:before { content: '\e8b2'; } /* '' */ +.bi_ecommerce-creditcard-d:before { content: '\e8b3'; } /* '' */ +.bi_ecommerce-diamon:before { content: '\e8b4'; } /* '' */ +.bi_ecommerce-digital-download:before { content: '\e8b5'; } /* '' */ +.bi_ecommerce-digital-upload:before { content: '\e8b6'; } /* '' */ +.bi_ecommerce-dollar:before { content: '\e8b7'; } /* '' */ +.bi_ecommerce-euro:before { content: '\e8b8'; } /* '' */ +.bi_ecommerce-gift:before { content: '\e8b9'; } /* '' */ +.bi_ecommerce-hanger:before { content: '\e8ba'; } /* '' */ +.bi_ecommerce-jeans:before { content: '\e8bb'; } /* '' */ +.bi_ecommerce-lipstick:before { content: '\e8bc'; } /* '' */ +.bi_ecommerce-market:before { content: '\e8bd'; } /* '' */ +.bi_ecommerce-mastercard:before { content: '\e8be'; } /* '' */ +.bi_ecommerce-pack:before { content: '\e8bf'; } /* '' */ +.bi_ecommerce-pack-a:before { content: '\e8c0'; } /* '' */ +.bi_ecommerce-pounds:before { content: '\e8c1'; } /* '' */ +.bi_ecommerce-ring:before { content: '\e8c2'; } /* '' */ +.bi_ecommerce-safebox:before { content: '\e8c3'; } /* '' */ +.bi_ecommerce-shirt:before { content: '\e8c4'; } /* '' */ +.bi_ecommerce-shirt-a:before { content: '\e8c5'; } /* '' */ +.bi_ecommerce-shoes:before { content: '\e8c6'; } /* '' */ +.bi_ecommerce-shop:before { content: '\e8c7'; } /* '' */ +.bi_ecommerce-shopcart:before { content: '\e8c8'; } /* '' */ +.bi_ecommerce-shopcart-a:before { content: '\e8c9'; } /* '' */ +.bi_ecommerce-shopcart-a-download:before { content: '\e8ca'; } /* '' */ +.bi_ecommerce-shopcart-a-fill:before { content: '\e8cb'; } /* '' */ +.bi_ecommerce-shopcart-c:before { content: '\e8cc'; } /* '' */ +.bi_ecommerce-shopcart-d:before { content: '\e8cd'; } /* '' */ +.bi_ecommerce-shopcart-download:before { content: '\e8ce'; } /* '' */ +.bi_ecommerce-shopcart-fill:before { content: '\e8cf'; } /* '' */ +.bi_ecommerce-short:before { content: '\e8d0'; } /* '' */ +.bi_ecommerce-suitcase:before { content: '\e8d1'; } /* '' */ +.bi_ecommerce-suitcase-a:before { content: '\e8d2'; } /* '' */ +.bi_ecommerce-tag:before { content: '\e8d3'; } /* '' */ +.bi_ecommerce-tag-a:before { content: '\e8d4'; } /* '' */ +.bi_ecommerce-tag-a-s:before { content: '\e8d5'; } /* '' */ +.bi_ecommerce-tag-b:before { content: '\e8d6'; } /* '' */ +.bi_ecommerce-tag-b-s:before { content: '\e8d7'; } /* '' */ +.bi_ecommerce-tag-c:before { content: '\e8d8'; } /* '' */ +.bi_ecommerce-tag-cross:before { content: '\e8d9'; } /* '' */ +.bi_ecommerce-tag-c-s:before { content: '\e8da'; } /* '' */ +.bi_ecommerce-tag-minus:before { content: '\e8db'; } /* '' */ +.bi_ecommerce-tag-plus:before { content: '\e8dc'; } /* '' */ +.bi_ecommerce-tag-tick:before { content: '\e8dd'; } /* '' */ +.bi_ecommerce-tracking:before { content: '\e8de'; } /* '' */ +.bi_ecommerce-tshirt:before { content: '\e8df'; } /* '' */ +.bi_ecommerce-wallet:before { content: '\e8e0'; } /* '' */ +.bi_ecommerce-wallet-a:before { content: '\e8e1'; } /* '' */ +.bi_ecommerce-woman-bag:before { content: '\e8e2'; } /* '' */ +.bi_ecommerce-yen:before { content: '\e8e3'; } /* '' */ +.bi_ecommerce-backpack:before { content: '\e8e4'; } /* '' */ +.bi_ecommerce-backpack-a:before { content: '\e8e5'; } /* '' */ +.bi_ecommerce-bag:before { content: '\e8e6'; } /* '' */ +.bi_ecommerce-bag-a:before { content: '\e8e7'; } /* '' */ +.bi_ecommerce-bag-b:before { content: '\e8e8'; } /* '' */ +.bi_editorial-pencil-s:before { content: '\e8e9'; } /* '' */ +.bi_editorial-pen-s:before { content: '\e8ea'; } /* '' */ +.bi_editorial-redo:before { content: '\e8eb'; } /* '' */ +.bi_editorial-right-align:before { content: '\e8ec'; } /* '' */ +.bi_editorial-trash:before { content: '\e8ed'; } /* '' */ +.bi_editorial-trash-a:before { content: '\e8ee'; } /* '' */ +.bi_editorial-trash-a-l:before { content: '\e8ef'; } /* '' */ +.bi_editorial-trash-l:before { content: '\e8f0'; } /* '' */ +.bi_editorial-undo:before { content: '\e8f1'; } /* '' */ +.bi_editorial-write:before { content: '\e8f2'; } /* '' */ +.bi_editorial-write-s:before { content: '\e8f3'; } /* '' */ +.bi_editorial-ascending:before { content: '\e8f4'; } /* '' */ +.bi_editorial-bookmark:before { content: '\e8f5'; } /* '' */ +.bi_editorial-bookmark-a:before { content: '\e8f6'; } /* '' */ +.bi_editorial-brush:before { content: '\e8f7'; } /* '' */ +.bi_editorial-center-align:before { content: '\e8f8'; } /* '' */ +.bi_editorial-compose:before { content: '\e8f9'; } /* '' */ +.bi_editorial-descending:before { content: '\e8fa'; } /* '' */ +.bi_editorial-left-align:before { content: '\e8fb'; } /* '' */ +.bi_editorial-pen:before { content: '\e8fc'; } /* '' */ +.bi_editorial-pencil:before { content: '\e8fd'; } /* '' */ +.bi_editorial-pencil-a:before { content: '\e8fe'; } /* '' */ +.bi_editorial-pencil-a-s:before { content: '\e8ff'; } /* '' */ +.bi_building-drawer-a:before { content: '\e900'; } /* '' */ +.bi_building-house:before { content: '\e901'; } /* '' */ +.bi_building-house-a:before { content: '\e902'; } /* '' */ +.bi_building-museum:before { content: '\e903'; } /* '' */ +.bi_building-office:before { content: '\e904'; } /* '' */ +.bi_building-office-a:before { content: '\e905'; } /* '' */ +.bi_building-office-b:before { content: '\e906'; } /* '' */ +.bi_building-sofa:before { content: '\e907'; } /* '' */ +.bi_building-sofa-a:before { content: '\e908'; } /* '' */ +.bi_building-sofa-b:before { content: '\e909'; } /* '' */ +.bi_building-sofa-twin:before { content: '\e90a'; } /* '' */ +.bi_building-sofa-twin-a:before { content: '\e90b'; } /* '' */ +.bi_building-table-lamp:before { content: '\e90c'; } /* '' */ +.bi_building-table-lamp-a:before { content: '\e90d'; } /* '' */ +.bi_building-tower:before { content: '\e90e'; } /* '' */ +.bi_building-tree:before { content: '\e90f'; } /* '' */ +.bi_environment-flower:before { content: '\e910'; } /* '' */ +.bi_environment-flower-a:before { content: '\e911'; } /* '' */ +.bi_environment-flower-b:before { content: '\e912'; } /* '' */ +.bi_environment-leaf:before { content: '\e913'; } /* '' */ +.bi_environment-leaf-a:before { content: '\e914'; } /* '' */ +.bi_environment-mountain:before { content: '\e915'; } /* '' */ +.bi_environment-mountain-a:before { content: '\e916'; } /* '' */ +.bi_environment-no-smoke:before { content: '\e917'; } /* '' */ +.bi_environment-plant:before { content: '\e918'; } /* '' */ +.bi_environment-sign:before { content: '\e919'; } /* '' */ +.bi_environment-smoke:before { content: '\e91a'; } /* '' */ +.bi_environment-tree:before { content: '\e91b'; } /* '' */ +.bi_building-apartment:before { content: '\e91c'; } /* '' */ +.bi_building-bed:before { content: '\e91d'; } /* '' */ +.bi_building-bulb:before { content: '\e91e'; } /* '' */ +.bi_building-cabinet:before { content: '\e91f'; } /* '' */ +.bi_building-desk:before { content: '\e920'; } /* '' */ +.bi_building-desk-a:before { content: '\e921'; } /* '' */ +.bi_building-desk-b:before { content: '\e922'; } /* '' */ +.bi_building-desk-c:before { content: '\e923'; } /* '' */ +.bi_building-door:before { content: '\e924'; } /* '' */ +.bi_building-drawer:before { content: '\e925'; } /* '' */ +.bi_beverage-cocktail-a:before { content: '\e926'; } /* '' */ +.bi_beverage-coffee:before { content: '\e927'; } /* '' */ +.bi_beverage-coffee-a:before { content: '\e928'; } /* '' */ +.bi_beverage-coffee-b:before { content: '\e929'; } /* '' */ +.bi_beverage-coffee-cup:before { content: '\e92a'; } /* '' */ +.bi_beverage-coffee-cup-a:before { content: '\e92b'; } /* '' */ +.bi_beverage-cokctail:before { content: '\e92c'; } /* '' */ +.bi_beverage-cup-straw:before { content: '\e92d'; } /* '' */ +.bi_beverage-empty-glass:before { content: '\e92e'; } /* '' */ +.bi_beverage-milk:before { content: '\e92f'; } /* '' */ +.bi_beverage-milk-a:before { content: '\e930'; } /* '' */ +.bi_beverage-tea:before { content: '\e931'; } /* '' */ +.bi_beverage-tea-a:before { content: '\e932'; } /* '' */ +.bi_beverage-tea-cup:before { content: '\e933'; } /* '' */ +.bi_beverage-tea-cup-a:before { content: '\e934'; } /* '' */ +.bi_beverage-water:before { content: '\e935'; } /* '' */ +.bi_beverage-water-a:before { content: '\e936'; } /* '' */ +.bi_beverage-water-glass:before { content: '\e937'; } /* '' */ +.bi_beverage-wine:before { content: '\e938'; } /* '' */ +.bi_food-apple:before { content: '\e939'; } /* '' */ +.bi_food-bowl:before { content: '\e93a'; } /* '' */ +.bi_food-cherry:before { content: '\e93b'; } /* '' */ +.bi_food-cherry-a:before { content: '\e93c'; } /* '' */ +.bi_food-chinese-food:before { content: '\e93d'; } /* '' */ +.bi_food-chinese-food-a:before { content: '\e93e'; } /* '' */ +.bi_food-chinese-food-b:before { content: '\e93f'; } /* '' */ +.bi_food-drumstick:before { content: '\e940'; } /* '' */ +.bi_food-egg:before { content: '\e941'; } /* '' */ +.bi_food-grape:before { content: '\e942'; } /* '' */ +.bi_food-hamburger:before { content: '\e943'; } /* '' */ +.bi_food-hamburger-a:before { content: '\e944'; } /* '' */ +.bi_food-ice-cream:before { content: '\e945'; } /* '' */ +.bi_food-ice-cream-a:before { content: '\e946'; } /* '' */ +.bi_food-ice-cream-b:before { content: '\e947'; } /* '' */ +.bi_food-ice-cream-c:before { content: '\e948'; } /* '' */ +.bi_food-melon:before { content: '\e949'; } /* '' */ +.bi_food-noodle:before { content: '\e94a'; } /* '' */ +.bi_food-noodle-a:before { content: '\e94b'; } /* '' */ +.bi_food-onigiri:before { content: '\e94c'; } /* '' */ +.bi_food-onigiri-a:before { content: '\e94d'; } /* '' */ +.bi_food-white-bread:before { content: '\e94e'; } /* '' */ +.bi_kitchen-fork-knife:before { content: '\e94f'; } /* '' */ +.bi_kitchen-fork-knife-a:before { content: '\e950'; } /* '' */ +.bi_kitchen-fridge:before { content: '\e951'; } /* '' */ +.bi_kitchen-grill:before { content: '\e952'; } /* '' */ +.bi_kitchen-heat:before { content: '\e953'; } /* '' */ +.bi_kitchen-heat-a:before { content: '\e954'; } /* '' */ +.bi_kitchen-hood:before { content: '\e955'; } /* '' */ +.bi_kitchen-hood-a:before { content: '\e956'; } /* '' */ +.bi_kitchen-jam:before { content: '\e957'; } /* '' */ +.bi_kitchen-ketchup:before { content: '\e958'; } /* '' */ +.bi_kitchen-leaf:before { content: '\e959'; } /* '' */ +.bi_kitchen-microwave:before { content: '\e95a'; } /* '' */ +.bi_kitchen-pepper:before { content: '\e95b'; } /* '' */ +.bi_kitchen-plate:before { content: '\e95c'; } /* '' */ +.bi_kitchen-recipe-book:before { content: '\e95d'; } /* '' */ +.bi_kitchen-salt:before { content: '\e95e'; } /* '' */ +.bi_kitchen-spatula:before { content: '\e95f'; } /* '' */ +.bi_kitchen-spoon-fork:before { content: '\e960'; } /* '' */ +.bi_kitchen-spoon-fork-a:before { content: '\e961'; } /* '' */ +.bi_kitchen-tissue:before { content: '\e962'; } /* '' */ +.bi_kitchen-water:before { content: '\e963'; } /* '' */ +.bi_beverage-alt-glass:before { content: '\e964'; } /* '' */ +.bi_beverage-alt-glass-a:before { content: '\e965'; } /* '' */ +.bi_beverage-alt-glass-b:before { content: '\e966'; } /* '' */ +.bi_beverage-alt-glass-c:before { content: '\e967'; } /* '' */ +.bi_beverage-beer:before { content: '\e968'; } /* '' */ +.bi_beverage-chinese-tea:before { content: '\e969'; } /* '' */ +.bi_beverage-chinese-tea-a:before { content: '\e96a'; } /* '' */ +.bi_beverage-chinese-tea-a-s:before { content: '\e96b'; } /* '' */ +.bi_beverage-chinese-tea-s:before { content: '\e96c'; } /* '' */ +.bi_setting-switch:before { content: '\e96d'; } /* '' */ +.bi_setting-switch-a:before { content: '\e96e'; } /* '' */ +.bi_setting-wrench:before { content: '\e96f'; } /* '' */ +.bi_setting-wrench-a:before { content: '\e970'; } /* '' */ +.bi_setting-airplane:before { content: '\e971'; } /* '' */ +.bi_setting-component:before { content: '\e972'; } /* '' */ +.bi_setting-eq:before { content: '\e973'; } /* '' */ +.bi_setting-eq-a:before { content: '\e974'; } /* '' */ +.bi_setting-gear:before { content: '\e975'; } /* '' */ +.bi_setting-gear-a:before { content: '\e976'; } /* '' */ +.bi_setting-gear-b:before { content: '\e977'; } /* '' */ +.bi_setting-hotspot:before { content: '\e978'; } /* '' */ +.bi_setting-notification:before { content: '\e979'; } /* '' */ +.bi_sport-tape:before { content: '\e97a'; } /* '' */ +.bi_sport-tennisball:before { content: '\e97b'; } /* '' */ +.bi_sport-time:before { content: '\e97c'; } /* '' */ +.bi_sport-trophy:before { content: '\e97d'; } /* '' */ +.bi_sport-trophy-a:before { content: '\e97e'; } /* '' */ +.bi_sport-tv:before { content: '\e97f'; } /* '' */ +.bi_sport-tv-a:before { content: '\e980'; } /* '' */ +.bi_medicine-heart:before { content: '\e981'; } /* '' */ +.bi_medicine-lab:before { content: '\e982'; } /* '' */ +.bi_medicine-lab-a:before { content: '\e983'; } /* '' */ +.bi_sport-alt-badge:before { content: '\e984'; } /* '' */ +.bi_sport-alt-badge-a:before { content: '\e985'; } /* '' */ +.bi_sport-badge:before { content: '\e986'; } /* '' */ +.bi_sport-badge-a:before { content: '\e987'; } /* '' */ +.bi_sport-badge-b:before { content: '\e988'; } /* '' */ +.bi_sport-badge-c:before { content: '\e989'; } /* '' */ +.bi_sport-badge-one:before { content: '\e98a'; } /* '' */ +.bi_sport-badge-one-a:before { content: '\e98b'; } /* '' */ +.bi_sport-baseball:before { content: '\e98c'; } /* '' */ +.bi_sport-basketball:before { content: '\e98d'; } /* '' */ +.bi_sport-basketball-a:before { content: '\e98e'; } /* '' */ +.bi_sport-bottle:before { content: '\e98f'; } /* '' */ +.bi_sport-cards:before { content: '\e990'; } /* '' */ +.bi_sport-dumbell:before { content: '\e991'; } /* '' */ +.bi_sport-dumbell-a:before { content: '\e992'; } /* '' */ +.bi_sport-flag:before { content: '\e993'; } /* '' */ +.bi_sport-flag-a:before { content: '\e994'; } /* '' */ +.bi_sport-football:before { content: '\e995'; } /* '' */ +.bi_sport-medic:before { content: '\e996'; } /* '' */ +.bi_sport-mic:before { content: '\e997'; } /* '' */ +.bi_sport-puzzle:before { content: '\e998'; } /* '' */ +.bi_sport-stadium:before { content: '\e999'; } /* '' */ +.bi_sport-stadium-a:before { content: '\e99a'; } /* '' */ +.bi_time-alarm:before { content: '\e99b'; } /* '' */ +.bi_time-alt-wall-clock:before { content: '\e99c'; } /* '' */ +.bi_time-calendar:before { content: '\e99d'; } /* '' */ +.bi_time-calendar-a:before { content: '\e99e'; } /* '' */ +.bi_time-calendar-b:before { content: '\e99f'; } /* '' */ +.bi_time-clock:before { content: '\e9a0'; } /* '' */ +.bi_time-clock-a:before { content: '\e9a1'; } /* '' */ +.bi_time-clock-b:before { content: '\e9a2'; } /* '' */ +.bi_time-clock-c:before { content: '\e9a3'; } /* '' */ +.bi_time-hour-glass:before { content: '\e9a4'; } /* '' */ +.bi_time-speed-meter:before { content: '\e9a5'; } /* '' */ +.bi_time-stopwatch:before { content: '\e9a6'; } /* '' */ +.bi_time-stopwatch-a:before { content: '\e9a7'; } /* '' */ +.bi_time-stopwatch-b:before { content: '\e9a8'; } /* '' */ +.bi_time-timer:before { content: '\e9a9'; } /* '' */ +.bi_time-wall-clock:before { content: '\e9aa'; } /* '' */ +.bi_time-watches:before { content: '\e9ab'; } /* '' */ +.bi_time-watches-a:before { content: '\e9ac'; } /* '' */ +.bi_time-watches-b:before { content: '\e9ad'; } /* '' */ +.bi_location-alt-pin:before { content: '\e9ae'; } /* '' */ +.bi_location-avenue:before { content: '\e9af'; } /* '' */ +.bi_location-compass:before { content: '\e9b0'; } /* '' */ +.bi_location-map:before { content: '\e9b1'; } /* '' */ +.bi_location-pin:before { content: '\e9b2'; } /* '' */ +.bi_location-pin-blank:before { content: '\e9b3'; } /* '' */ +.bi_location-pin-check:before { content: '\e9b4'; } /* '' */ +.bi_location-pin-map:before { content: '\e9b5'; } /* '' */ +.bi_location-pin-map-a:before { content: '\e9b6'; } /* '' */ +.bi_location-pin-minus:before { content: '\e9b7'; } /* '' */ +.bi_location-pin-plus:before { content: '\e9b8'; } /* '' */ +.bi_location-pin-regular:before { content: '\e9b9'; } /* '' */ +.bi_location-sign-street:before { content: '\e9ba'; } /* '' */ +.bi_tool-console:before { content: '\e9bb'; } /* '' */ +.bi_tool-console-a:before { content: '\e9bc'; } /* '' */ +.bi_tool-console-old:before { content: '\e9bd'; } /* '' */ +.bi_tool-disk:before { content: '\e9be'; } /* '' */ +.bi_tool-disk-a:before { content: '\e9bf'; } /* '' */ +.bi_tool-flashlight:before { content: '\e9c0'; } /* '' */ +.bi_tool-flashlight-a:before { content: '\e9c1'; } /* '' */ +.bi_tool-flashlight-a-s:before { content: '\e9c2'; } /* '' */ +.bi_tool-flashlight-s:before { content: '\e9c3'; } /* '' */ +.bi_tool-gameboy:before { content: '\e9c4'; } /* '' */ +.bi_tool-hammer:before { content: '\e9c5'; } /* '' */ +.bi_tool-headphone:before { content: '\e9c6'; } /* '' */ +.bi_tool-headphone-a:before { content: '\e9c7'; } /* '' */ +.bi_tool-laptop:before { content: '\e9c8'; } /* '' */ +.bi_tool-magic-wand:before { content: '\e9c9'; } /* '' */ +.bi_tool-magic-wand-a:before { content: '\e9ca'; } /* '' */ +.bi_tool-magnet:before { content: '\e9cb'; } /* '' */ +.bi_tool-magnifier:before { content: '\e9cc'; } /* '' */ +.bi_tool-medical-tape:before { content: '\e9cd'; } /* '' */ +.bi_tool-mobile:before { content: '\e9ce'; } /* '' */ +.bi_tool-mobile-l:before { content: '\e9cf'; } /* '' */ +.bi_tool-monitor:before { content: '\e9d0'; } /* '' */ +.bi_tool-monitor-a:before { content: '\e9d1'; } /* '' */ +.bi_tool-mouse:before { content: '\e9d2'; } /* '' */ +.bi_tool-net:before { content: '\e9d3'; } /* '' */ +.bi_tool-paint-roler:before { content: '\e9d4'; } /* '' */ +.bi_tool-projector:before { content: '\e9d5'; } /* '' */ +.bi_tool-radio:before { content: '\e9d6'; } /* '' */ +.bi_tool-ruler:before { content: '\e9d7'; } /* '' */ +.bi_tool-scissor:before { content: '\e9d8'; } /* '' */ +.bi_tool-tablet:before { content: '\e9d9'; } /* '' */ +.bi_tool-tablet-l:before { content: '\e9da'; } /* '' */ +.bi_tool-television:before { content: '\e9db'; } /* '' */ +.bi_tool-toothbrush:before { content: '\e9dc'; } /* '' */ +.bi_tool-umbrella:before { content: '\e9dd'; } /* '' */ +.bi_tool-video:before { content: '\e9de'; } /* '' */ +.bi_tool-alt-camera:before { content: '\e9df'; } /* '' */ +.bi_tool-alt-camera-a:before { content: '\e9e0'; } /* '' */ +.bi_tool-android:before { content: '\e9e1'; } /* '' */ +.bi_tool-android-l:before { content: '\e9e2'; } /* '' */ +.bi_tool-binoculars:before { content: '\e9e3'; } /* '' */ +.bi_tool-brush:before { content: '\e9e4'; } /* '' */ +.bi_tool-brush-a:before { content: '\e9e5'; } /* '' */ +.bi_tool-calculator:before { content: '\e9e6'; } /* '' */ +.bi_tool-camera:before { content: '\e9e7'; } /* '' */ +.bi_tool-camera-a:before { content: '\e9e8'; } /* '' */ +.bi_tool-camera-b:before { content: '\e9e9'; } /* '' */ +.bi_tool-compass:before { content: '\e9ea'; } /* '' */ +.bi_transport-car-b:before { content: '\e9eb'; } /* '' */ +.bi_transport-car-c:before { content: '\e9ec'; } /* '' */ +.bi_transport-ship:before { content: '\e9ed'; } /* '' */ +.bi_transport-train:before { content: '\e9ee'; } /* '' */ +.bi_transport-truck:before { content: '\e9ef'; } /* '' */ +.bi_transport-truck-a:before { content: '\e9f0'; } /* '' */ +.bi_transport-alt-bus:before { content: '\e9f1'; } /* '' */ +.bi_transport-bicycle:before { content: '\e9f2'; } /* '' */ +.bi_transport-bicycle-a:before { content: '\e9f3'; } /* '' */ +.bi_transport-boat:before { content: '\e9f4'; } /* '' */ +.bi_transport-bus:before { content: '\e9f5'; } /* '' */ +.bi_transport-bus-a:before { content: '\e9f6'; } /* '' */ +.bi_transport-car:before { content: '\e9f7'; } /* '' */ +.bi_transport-car-a:before { content: '\e9f8'; } /* '' */ +.bi_user-male:before { content: '\e9f9'; } /* '' */ +.bi_user-male-check:before { content: '\e9fa'; } /* '' */ +.bi_user-male-cross:before { content: '\e9fb'; } /* '' */ +.bi_user-male-minus:before { content: '\e9fc'; } /* '' */ +.bi_user-male-plus:before { content: '\e9fd'; } /* '' */ +.bi_user-male-sign:before { content: '\e9fe'; } /* '' */ +.bi_user-password:before { content: '\e9ff'; } /* '' */ +.bi_user-password-u:before { content: '\ea00'; } /* '' */ +.bi_user-password-u-a:before { content: '\ea01'; } /* '' */ +.bi_user-single:before { content: '\ea02'; } /* '' */ +.bi_user-single-a:before { content: '\ea03'; } /* '' */ +.bi_user-single-a-check:before { content: '\ea04'; } /* '' */ +.bi_user-single-a-cross:before { content: '\ea05'; } /* '' */ +.bi_user-single-a-group:before { content: '\ea06'; } /* '' */ +.bi_user-single-a-list:before { content: '\ea07'; } /* '' */ +.bi_user-single-a-minus:before { content: '\ea08'; } /* '' */ +.bi_user-single-a-plus:before { content: '\ea09'; } /* '' */ +.bi_user-single-check:before { content: '\ea0a'; } /* '' */ +.bi_user-single-cross:before { content: '\ea0b'; } /* '' */ +.bi_user-single-minus:before { content: '\ea0c'; } /* '' */ +.bi_user-single-plus:before { content: '\ea0d'; } /* '' */ +.bi_user-single-round:before { content: '\ea0e'; } /* '' */ +.bi_user-alt:before { content: '\ea0f'; } /* '' */ +.bi_user-alt-check:before { content: '\ea10'; } /* '' */ +.bi_user-alt-cross:before { content: '\ea11'; } /* '' */ +.bi_user-alt-group:before { content: '\ea12'; } /* '' */ +.bi_user-alt-list:before { content: '\ea13'; } /* '' */ +.bi_user-alt-minus:before { content: '\ea14'; } /* '' */ +.bi_user-alt-plus:before { content: '\ea15'; } /* '' */ +.bi_user-contact-book:before { content: '\ea16'; } /* '' */ +.bi_user-female:before { content: '\ea17'; } /* '' */ +.bi_user-female-cross:before { content: '\ea18'; } /* '' */ +.bi_user-female-group:before { content: '\ea19'; } /* '' */ +.bi_user-female-list:before { content: '\ea1a'; } /* '' */ +.bi_user-female-minus:before { content: '\ea1b'; } /* '' */ +.bi_user-female-plus:before { content: '\ea1c'; } /* '' */ +.bi_user-female-sign:before { content: '\ea1d'; } /* '' */ +.bi_user-female-tick:before { content: '\ea1e'; } /* '' */ +.bi_user-key:before { content: '\ea1f'; } /* '' */ +.bi_user-lock:before { content: '\ea20'; } /* '' */ +.bi_user-lock-u:before { content: '\ea21'; } /* '' */ +.bi_user-lock-u-a:before { content: '\ea22'; } /* '' */ +.bi_weather-sunset-a:before { content: '\ea23'; } /* '' */ +.bi_weather-wind:before { content: '\ea24'; } /* '' */ +.bi_weather-wind-pressure:before { content: '\ea25'; } /* '' */ +.bi_weather-wind-pressure-a:before { content: '\ea26'; } /* '' */ +.bi_weather-cloud:before { content: '\ea27'; } /* '' */ +.bi_weather-cloud-a:before { content: '\ea28'; } /* '' */ +.bi_weather-cloud-rainy:before { content: '\ea29'; } /* '' */ +.bi_weather-cloud-rainy-a:before { content: '\ea2a'; } /* '' */ +.bi_weather-cloud-snow:before { content: '\ea2b'; } /* '' */ +.bi_weather-cloud-snow-a:before { content: '\ea2c'; } /* '' */ +.bi_weather-cloud-stormy:before { content: '\ea2d'; } /* '' */ +.bi_weather-cloud-stormy-a:before { content: '\ea2e'; } /* '' */ +.bi_weather-cloud-sun:before { content: '\ea2f'; } /* '' */ +.bi_weather-humid:before { content: '\ea30'; } /* '' */ +.bi_weather-moon:before { content: '\ea31'; } /* '' */ +.bi_weather-moon-a:before { content: '\ea32'; } /* '' */ +.bi_weather-moon-b:before { content: '\ea33'; } /* '' */ +.bi_weather-moon-r:before { content: '\ea34'; } /* '' */ +.bi_weather-sun-a:before { content: '\ea35'; } /* '' */ +.bi_weather-sun-b:before { content: '\ea36'; } /* '' */ +.bi_weather-sun-r:before { content: '\ea37'; } /* '' */ +.bi_weather-sunrise:before { content: '\ea38'; } /* '' */ +.bi_web-bug:before { content: '\ea39'; } /* '' */ +.bi_web-code:before { content: '\ea3a'; } /* '' */ +.bi_web-database:before { content: '\ea3b'; } /* '' */ +.bi_web-download:before { content: '\ea3c'; } /* '' */ +.bi_web-graph:before { content: '\ea3d'; } /* '' */ +.bi_web-inspect:before { content: '\ea3e'; } /* '' */ +.bi_web-internet:before { content: '\ea3f'; } /* '' */ +.bi_web-internet-a:before { content: '\ea40'; } /* '' */ +.bi_web-logout:before { content: '\ea41'; } /* '' */ +.bi_web-menu-collapse-down:before { content: '\ea42'; } /* '' */ +.bi_web-menu-collapse-left:before { content: '\ea43'; } /* '' */ +.bi_web-menu-collapse-right:before { content: '\ea44'; } /* '' */ +.bi_web-menu-collapse-up:before { content: '\ea45'; } /* '' */ +.bi_web-reading-list:before { content: '\ea46'; } /* '' */ +.bi_web-report:before { content: '\ea47'; } /* '' */ +.bi_web-report-a:before { content: '\ea48'; } /* '' */ +.bi_web-rss:before { content: '\ea49'; } /* '' */ +.bi_web-share:before { content: '\ea4a'; } /* '' */ +.bi_web-share-a:before { content: '\ea4b'; } /* '' */ +.bi_web-share-b:before { content: '\ea4c'; } /* '' */ +.bi_web-statistic:before { content: '\ea4d'; } /* '' */ +.bi_web-traffic:before { content: '\ea4e'; } /* '' */ +.bi_web-traffic-a:before { content: '\ea4f'; } /* '' */ +.bi_web-traffic-b:before { content: '\ea50'; } /* '' */ +.bi_web-traffic-c:before { content: '\ea51'; } /* '' */ +.bi_web-upload:before { content: '\ea52'; } /* '' */ +.bi_web-url:before { content: '\ea53'; } /* '' */ +.bi_web-url-a:before { content: '\ea54'; } /* '' */ +.bi_web-url-b:before { content: '\ea55'; } /* '' */ +.bi_web-warning:before { content: '\ea56'; } /* '' */ +.bi_web-webcam:before { content: '\ea57'; } /* '' */ +.bi_web-broken-link:before { content: '\ea58'; } /* '' */ +.bi_web-browser:before { content: '\ea59'; } /* '' */ +.bi_web-browser-a:before { content: '\ea5a'; } /* '' */ +.bi_web-browser-b:before { content: '\ea5b'; } /* '' */ +.bi_web-browser-cross:before { content: '\ea5c'; } /* '' */ +.bi_web-browser-minus:before { content: '\ea5d'; } /* '' */ +.bi_web-browser-plus:before { content: '\ea5e'; } /* '' */ +.bi_web-browser-tab:before { content: '\ea5f'; } /* '' */ +.bi_web-browser-tab-cross:before { content: '\ea60'; } /* '' */ +.bi_web-browser-tab-minus:before { content: '\ea61'; } /* '' */ +.bi_web-browser-tab-plus:before { content: '\ea62'; } /* '' */ +.bi_web-browser-tab-tick:before { content: '\ea63'; } /* '' */ +.bi_web-browser-tick:before { content: '\ea64'; } /* '' */ +.bi_web-browser-window:before { content: '\ea65'; } /* '' */ +.bi_logo-vimeo:before { content: '\ea66'; } /* '' */ +.bi_logo-windows:before { content: '\ea67'; } /* '' */ +.bi_logo-zerply:before { content: '\ea68'; } /* '' */ +.bi_logo-amazon:before { content: '\ea69'; } /* '' */ +.bi_logo-dribbble:before { content: '\ea6a'; } /* '' */ +.bi_logo-dropbox:before { content: '\ea6b'; } /* '' */ +.bi_logo-evernote:before { content: '\ea6c'; } /* '' */ +.bi_logo-facebook:before { content: '\ea6d'; } /* '' */ +.bi_logo-grooveshark:before { content: '\ea6e'; } /* '' */ +.bi_logo-instagram:before { content: '\ea6f'; } /* '' */ +.bi_logo-linkedin:before { content: '\ea70'; } /* '' */ +.bi_logo-musio:before { content: '\ea71'; } /* '' */ +.bi_logo-path:before { content: '\ea72'; } /* '' */ +.bi_logo-paypal:before { content: '\ea73'; } /* '' */ +.bi_logo-picasa:before { content: '\ea74'; } /* '' */ +.bi_logo-pinterest:before { content: '\ea75'; } /* '' */ +.bi_logo-rdio:before { content: '\ea76'; } /* '' */ +.bi_logo-squarespace:before { content: '\ea77'; } /* '' */ +.bi_logo-squareup:before { content: '\ea78'; } /* '' */ +.bi_logo-twitter:before { content: '\ea79'; } /* '' */ +.bi_misc-one-click:before { content: '\ea7a'; } /* '' */ +.bi_misc-pointer:before { content: '\ea7b'; } /* '' */ +.bi_misc-pointer-swipe-l:before { content: '\ea7c'; } /* '' */ +.bi_misc-pointer-swipe-r:before { content: '\ea7d'; } /* '' */ +.bi_misc-puzzle:before { content: '\ea7e'; } /* '' */ +.bi_misc-wifi:before { content: '\ea7f'; } /* '' */ +.bi_misc-crown:before { content: '\ea80'; } /* '' */ +.bi_misc-cube:before { content: '\ea81'; } /* '' */ +.bi_misc-dice-five:before { content: '\ea82'; } /* '' */ +.bi_misc-dice-four:before { content: '\ea83'; } /* '' */ +.bi_misc-dice-one:before { content: '\ea84'; } /* '' */ +.bi_misc-dice-six:before { content: '\ea85'; } /* '' */ +.bi_misc-dice-three:before { content: '\ea86'; } /* '' */ +.bi_misc-dice-two:before { content: '\ea87'; } /* '' */ +.bi_misc-double-click:before { content: '\ea88'; } /* '' */ +.bi_misc-female-gender:before { content: '\ea89'; } /* '' */ +.bi_misc-globe:before { content: '\ea8a'; } /* '' */ +.bi_misc-male-gender:before { content: '\ea8b'; } /* '' */ +.bi_misc-mood-happy:before { content: '\ea8c'; } /* '' */ +.bi_misc-mood-sad:before { content: '\ea8d'; } /* '' */ +.bi_music-mic:before { content: '\ea8e'; } /* '' */ +.bi_music-mic-a:before { content: '\ea8f'; } /* '' */ +.bi_music-next:before { content: '\ea90'; } /* '' */ +.bi_music-next-l:before { content: '\ea91'; } /* '' */ +.bi_music-next-l-a:before { content: '\ea92'; } /* '' */ +.bi_music-pause:before { content: '\ea93'; } /* '' */ +.bi_music-pause-a:before { content: '\ea94'; } /* '' */ +.bi_music-pause-b:before { content: '\ea95'; } /* '' */ +.bi_music-play:before { content: '\ea96'; } /* '' */ +.bi_music-playlist:before { content: '\ea97'; } /* '' */ +.bi_music-previous:before { content: '\ea98'; } /* '' */ +.bi_music-previous-l:before { content: '\ea99'; } /* '' */ +.bi_music-previous-l-a:before { content: '\ea9a'; } /* '' */ +.bi_music-radio:before { content: '\ea9b'; } /* '' */ +.bi_music-record:before { content: '\ea9c'; } /* '' */ +.bi_music-record-a:before { content: '\ea9d'; } /* '' */ +.bi_music-repeat:before { content: '\ea9e'; } /* '' */ +.bi_music-repeat-a:before { content: '\ea9f'; } /* '' */ +.bi_music-repeat-one:before { content: '\eaa0'; } /* '' */ +.bi_music-repeat-one-a:before { content: '\eaa1'; } /* '' */ +.bi_music-shuffle:before { content: '\eaa2'; } /* '' */ +.bi_music-shuffle-a:before { content: '\eaa3'; } /* '' */ +.bi_music-song-note:before { content: '\eaa4'; } /* '' */ +.bi_music-song-note-a:before { content: '\eaa5'; } /* '' */ +.bi_music-speaker:before { content: '\eaa6'; } /* '' */ +.bi_music-speaker-a:before { content: '\eaa7'; } /* '' */ +.bi_music-stop:before { content: '\eaa8'; } /* '' */ +.bi_music-stop-a:before { content: '\eaa9'; } /* '' */ +.bi_volume-high:before { content: '\eaaa'; } /* '' */ +.bi_volume-high-a:before { content: '\eaab'; } /* '' */ +.bi_volume-low:before { content: '\eaac'; } /* '' */ +.bi_volume-low-a:before { content: '\eaad'; } /* '' */ +.bi_volume-medium:before { content: '\eaae'; } /* '' */ +.bi_volume-medium-a:before { content: '\eaaf'; } /* '' */ +.bi_volume-mute:before { content: '\eab0'; } /* '' */ +.bi_volume-mute-a:before { content: '\eab1'; } /* '' */ +.bi_music-album:before { content: '\eab2'; } /* '' */ +.bi_music-album-a:before { content: '\eab3'; } /* '' */ +.bi_music-album-b:before { content: '\eab4'; } /* '' */ +.bi_music-album-c:before { content: '\eab5'; } /* '' */ +.bi_music-album-cd:before { content: '\eab6'; } /* '' */ +.bi_music-cd:before { content: '\eab7'; } /* '' */ +.bi_music-eject:before { content: '\eab8'; } /* '' */ +.bi_music-eq:before { content: '\eab9'; } /* '' */ +.bi_music-eq-a:before { content: '\eaba'; } /* '' */ +.bi_music-group-note:before { content: '\eabb'; } /* '' */ +.bi_music-group-note-a:before { content: '\eabc'; } /* '' */ +.bi_music-headphone:before { content: '\eabd'; } /* '' */ +.bi_music-headphone-a:before { content: '\eabe'; } /* '' */ +.bi_music-list:before { content: '\eabf'; } /* '' */ +.bi_interface-backspace:before { content: '\eac0'; } /* '' */ +.bi_interface-backspace-a:before { content: '\eac1'; } /* '' */ +.bi_interface-bell:before { content: '\eac2'; } /* '' */ +.bi_interface-bell-a:before { content: '\eac3'; } /* '' */ +.bi_interface-block:before { content: '\eac4'; } /* '' */ +.bi_interface-bottom:before { content: '\eac5'; } /* '' */ +.bi_interface-bottom-k:before { content: '\eac6'; } /* '' */ +.bi_interface-bottom-r:before { content: '\eac7'; } /* '' */ +.bi_interface-box-bottom:before { content: '\eac8'; } /* '' */ +.bi_interface-box-bottom-a:before { content: '\eac9'; } /* '' */ +.bi_interface-box-cross:before { content: '\eaca'; } /* '' */ +.bi_interface-box-left:before { content: '\eacb'; } /* '' */ +.bi_interface-box-left-a:before { content: '\eacc'; } /* '' */ +.bi_interface-box-minus:before { content: '\eacd'; } /* '' */ +.bi_interface-box-plus:before { content: '\eace'; } /* '' */ +.bi_interface-box-right:before { content: '\eacf'; } /* '' */ +.bi_interface-box-right-a:before { content: '\ead0'; } /* '' */ +.bi_interface-box-tick:before { content: '\ead1'; } /* '' */ +.bi_interface-box-top:before { content: '\ead2'; } /* '' */ +.bi_interface-box-top-a:before { content: '\ead3'; } /* '' */ +.bi_interface-bulleye:before { content: '\ead4'; } /* '' */ +.bi_interface-calendar:before { content: '\ead5'; } /* '' */ +.bi_interface-circle:before { content: '\ead6'; } /* '' */ +.bi_interface-circle-cross:before { content: '\ead7'; } /* '' */ +.bi_interface-circle-minus:before { content: '\ead8'; } /* '' */ +.bi_interface-circle-plus:before { content: '\ead9'; } /* '' */ +.bi_interface-circle-tick:before { content: '\eada'; } /* '' */ +.bi_interface-circle-tick-a:before { content: '\eadb'; } /* '' */ +.bi_interface-clock:before { content: '\eadc'; } /* '' */ +.bi_interface-clock-a:before { content: '\eadd'; } /* '' */ +.bi_interface-clock-b:before { content: '\eade'; } /* '' */ +.bi_interface-cloud-download:before { content: '\eadf'; } /* '' */ +.bi_interface-cloud-upload:before { content: '\eae0'; } /* '' */ +.bi_interface-cmd:before { content: '\eae1'; } /* '' */ +.bi_interface-crop:before { content: '\eae2'; } /* '' */ +.bi_interface-cross:before { content: '\eae3'; } /* '' */ +.bi_interface-dashboard:before { content: '\eae4'; } /* '' */ +.bi_interface-direction:before { content: '\eae7'; } /* '' */ +.bi_interface-downloading:before { content: '\eae8'; } /* '' */ +.bi_interface-enlarge:before { content: '\eae9'; } /* '' */ +.bi_interface-enlarge-a:before { content: '\eaea'; } /* '' */ +.bi_interface-enlarge-c:before { content: '\eaeb'; } /* '' */ +.bi_interface-expand:before { content: '\eaec'; } /* '' */ +.bi_interface-forward:before { content: '\eaed'; } /* '' */ +.bi_interface-fullscreen:before { content: '\eaee'; } /* '' */ +.bi_interface-fullscreen-a:before { content: '\eaef'; } /* '' */ +.bi_interface-fullscreen-wide:before { content: '\eaf0'; } /* '' */ +.bi_interface-hamburger:before { content: '\eaf1'; } /* '' */ +.bi_interface-heart:before { content: '\eaf2'; } /* '' */ +.bi_interface-help:before { content: '\eaf3'; } /* '' */ +.bi_interface-help-a:before { content: '\eaf4'; } /* '' */ +.bi_interface-home:before { content: '\eaf5'; } /* '' */ +.bi_interface-home-a:before { content: '\eaf6'; } /* '' */ +.bi_interface-horizontal:before { content: '\eaf7'; } /* '' */ +.bi_interface-horizontal-a:before { content: '\eaf8'; } /* '' */ +.bi_interface-in-link:before { content: '\eaf9'; } /* '' */ +.bi_interface-left:before { content: '\eafa'; } /* '' */ +.bi_interface-left-b-k:before { content: '\eafb'; } /* '' */ +.bi_interface-left-k:before { content: '\eafc'; } /* '' */ +.bi_interface-left-r:before { content: '\eafd'; } /* '' */ +.bi_interface-left-t-k:before { content: '\eafe'; } /* '' */ +.bi_interface-list-view:before { content: '\eaff'; } /* '' */ +.bi_interface-login:before { content: '\eb00'; } /* '' */ +.bi_interface-logout-a:before { content: '\eb01'; } /* '' */ +.bi_interface-minimize:before { content: '\eb02'; } /* '' */ +.bi_interface-minus:before { content: '\eb03'; } /* '' */ +.bi_interface-more:before { content: '\eb04'; } /* '' */ +.bi_interface-number:before { content: '\eb05'; } /* '' */ +.bi_interface-out-link:before { content: '\eb06'; } /* '' */ +.bi_interface-pixel:before { content: '\eb07'; } /* '' */ +.bi_interface-places:before { content: '\eb08'; } /* '' */ +.bi_interface-places-a:before { content: '\eb09'; } /* '' */ +.bi_interface-plus:before { content: '\eb0a'; } /* '' */ +.bi_interface-popup:before { content: '\eb0b'; } /* '' */ +.bi_interface-power:before { content: '\eb0c'; } /* '' */ +.bi_interface-refresh:before { content: '\eb0d'; } /* '' */ +.bi_interface-repeating:before { content: '\eb0e'; } /* '' */ +.bi_interface-reply:before { content: '\eb0f'; } /* '' */ +.bi_interface-resize-full:before { content: '\eb10'; } /* '' */ +.bi_interface-resize-full-a:before { content: '\eb11'; } /* '' */ +.bi_interface-resize-normal:before { content: '\eb12'; } /* '' */ +.bi_interface-reverse:before { content: '\eb13'; } /* '' */ +.bi_interface-right:before { content: '\eb14'; } /* '' */ +.bi_interface-right-k:before { content: '\eb15'; } /* '' */ +.bi_interface-right-r:before { content: '\eb16'; } /* '' */ +.bi_interface-rigth-b-k:before { content: '\eb17'; } /* '' */ +.bi_interface-rigth-t-k:before { content: '\eb18'; } /* '' */ +.bi_interface-search:before { content: '\eb19'; } /* '' */ +.bi_interface-search-cross:before { content: '\eb1a'; } /* '' */ +.bi_interface-search-minus:before { content: '\eb1b'; } /* '' */ +.bi_interface-search-plus:before { content: '\eb1c'; } /* '' */ +.bi_interface-search-tick:before { content: '\eb1d'; } /* '' */ +.bi_interface-sidebar-hamburger:before { content: '\eb1e'; } /* '' */ +.bi_interface-star:before { content: '\eb1f'; } /* '' */ +.bi_interface-star-a:before { content: '\eb20'; } /* '' */ +.bi_interface-target:before { content: '\eb21'; } /* '' */ +.bi_interface-thumbnail:before { content: '\eb22'; } /* '' */ +.bi_interface-tick:before { content: '\eb23'; } /* '' */ +.bi_interface-top:before { content: '\eb24'; } /* '' */ +.bi_interface-top-k:before { content: '\eb25'; } /* '' */ +.bi_interface-top-r:before { content: '\eb26'; } /* '' */ +.bi_interface-undo:before { content: '\eb27'; } /* '' */ +.bi_interface-uploading:before { content: '\eb28'; } /* '' */ +.bi_interface-vertical:before { content: '\eb29'; } /* '' */ +.bi_interface-vertical-a:before { content: '\eb2a'; } /* '' */ +.bi_interface-view:before { content: '\eb2b'; } /* '' */ +.bi_interface-warning:before { content: '\eb2c'; } /* '' */ +.bi_interface-window:before { content: '\eb2d'; } /* '' */ +.bi_layout-footer:before { content: '\eb2e'; } /* '' */ +.bi_layout-grid:before { content: '\eb2f'; } /* '' */ +.bi_layout-half:before { content: '\eb30'; } /* '' */ +.bi_layout-header:before { content: '\eb31'; } /* '' */ +.bi_layout-sidebar-l:before { content: '\eb32'; } /* '' */ +.bi_layout-sidebar-l-a:before { content: '\eb33'; } /* '' */ +.bi_layout-sidebar-l-half:before { content: '\eb34'; } /* '' */ +.bi_layout-sidebar-l-half-a:before { content: '\eb35'; } /* '' */ +.bi_layout-sidebar-r:before { content: '\eb36'; } /* '' */ +.bi_layout-sidebar-r-a:before { content: '\eb37'; } /* '' */ +.bi_layout-sidebar-r-half:before { content: '\eb38'; } /* '' */ +.bi_layout-sidebar-r-half-a:before { content: '\eb39'; } /* '' */ +.bi_layout-third-h:before { content: '\eb3a'; } /* '' */ +.bi_layout-third-v:before { content: '\eb3b'; } /* '' */ +.bi_layout-wireframe:before { content: '\eb3c'; } /* '' */ +.bi_layout-wireframe-a:before { content: '\eb3d'; } /* '' */ +.bi_interface-alt-cross:before { content: '\eb3e'; } /* '' */ +.bi_interface-alt-fullscreen:before { content: '\eb3f'; } /* '' */ +.bi_interface-alt-minus:before { content: '\eb40'; } /* '' */ +.bi_interface-alt-plus:before { content: '\eb41'; } /* '' */ +.bi_interface-alt-tick:before { content: '\eb42'; } /* '' */ +.bi_interface-alt-widescreen:before { content: '\eb43'; } /* '' */ +.bi_interface-arrow-all:before { content: '\eb44'; } /* '' */ +.bi_interface-arrow-bottom:before { content: '\eb45'; } /* '' */ +.bi_interface-arrow-bottom-circle:before { content: '\eb46'; } /* '' */ +.bi_interface-arrow-left:before { content: '\eb47'; } /* '' */ +.bi_interface-arrow-left-b:before { content: '\eb48'; } /* '' */ +.bi_interface-arrow-left-circle:before { content: '\eb49'; } /* '' */ +.bi_interface-arrow-left-t:before { content: '\eb4a'; } /* '' */ +.bi_interface-arrow-right:before { content: '\eb4b'; } /* '' */ +.bi_interface-arrow-right-b:before { content: '\eb4c'; } /* '' */ +.bi_interface-arrow-right-circle:before { content: '\eb4d'; } /* '' */ +.bi_interface-arrow-right-t:before { content: '\eb4e'; } /* '' */ +.bi_interface-arrow-top:before { content: '\eb4f'; } /* '' */ +.bi_interface-arrow-top-circle:before { content: '\eb50'; } /* '' */ +.bi_animal-dog-a:before { content: '\eb51'; } /* '' */ +.bi_interface-horizontal-a-1:before { content: '\eb52'; } /* '' */ +.bi_interface-vertical-a-1:before { content: '\eb53'; } /* '' */ +.bi_interface-diag:before { content: '\eb54'; } /* '' */ +.bi_interface-diag-a:before { content: '\eb55'; } /* '' */ \ No newline at end of file diff --git a/webui/css/common.css b/webui/css/common.css new file mode 100644 index 000000000..56827e2c8 --- /dev/null +++ b/webui/css/common.css @@ -0,0 +1,40 @@ +/*! + * Iguana common + * + */ + + @font-face { + font-family: proxima-nova-semibold; + src: url(../fonts/proxima_nova_semibold.otf); + } + + body, + html { + padding: 0; + margin: 0; + height: 100%; + width: 100%; + } + .orange-gradient, + .btn.orange-gradient:focus { + /* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#fe640d+8,fe640d+26,fe4b0d+77,fe450d+100 */ + background: #fe640d; /* Old browsers */ + background: -moz-linear-gradient(top, #fe640d 8%, #fe640d 26%, #fe4b0d 77%, #fe450d 100%); /* FF3.6-15 */ + background: -webkit-linear-gradient(top, #fe640d 8%, #fe640d 26%, #fe4b0d 77%, #fe450d 100%); /* Chrome10-25,Safari5.1-6 */ + background: linear-gradient(to bottom, #fe640d 8%, #fe640d 26%, #fe4b0d 77%, #fe450d 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */ + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fe640d', endColorstr='#fe450d', GradientType=0); /* IE6-9 */ + } + .cursor-pointer { + cursor: pointer; + cursor: hand; + } + .unselectable { + cursor: default; + user-select: none; + -moz-user-select: none; + -ms-user-select: none; + -webkit-user-select: none; + } + .col-red { + color: #FF0000; + } \ No newline at end of file diff --git a/webui/css/create-account.css b/webui/css/create-account.css new file mode 100644 index 000000000..1c278e692 --- /dev/null +++ b/webui/css/create-account.css @@ -0,0 +1,437 @@ +body { + font-family: proxima-nova, sans-serif; + font-size: 15px; + color: #252528; +} + +.center { + background-color: #f4f7fb; + color: #252528; +} + + +@media (min-width:320px) { +/* smartphones, Android phones, landscape iPhone */ + .center { + margin: 0; + padding: 0; + margin-bottom: -99999px; + padding-bottom: 99999px; + overflow: hidden; + } + .content { + width: 85%; + margin: 0 auto; + padding-top: 25%; + } + .buttonsWrapper { + width: 100%; + } + .block-btns { + display: block; + width: 100%; + padding-left: 0; + padding-right: 0; + padding: 10px 16px; + font-size: 18px; + line-height: 1.33; + border-radius: 6px; + } + +} +@media (min-width:480px) { +/* smartphones, Android phones, landscape iPhone */ + .center { + margin: 0; + padding: 0; + margin-bottom: -99999px; + padding-bottom: 99999px; + overflow: hidden; + } + .content { + width: 85%; + margin: 0 auto; + padding-top: 25%; + } + .buttonsWrapper { + width: 100%; + } + .block-btns { + display: block; + width: 100%; + padding-left: 0; + padding-right: 0; + padding: 10px 16px; + font-size: 18px; + line-height: 1.33; + border-radius: 6px; + } + +} +@media (min-width:600px) { +/* portrait tablets, portrait iPad, e-readers (Nook/Kindle), landscape 800x480 phones (Android) */ + .center { + margin: 0; + padding: 0; + margin-bottom: -99999px; + padding-bottom: 99999px; + overflow: hidden; + } + .content { + width: 85%; + margin: 0 auto; + padding-top: 10%; + + } + .buttonsWrapper { + width: 100%; + } + .block-btns { + display: block; + width: 100%; + padding-left: 0; + padding-right: 0; + padding: 10px 16px; + font-size: 18px; + line-height: 1.33; + border-radius: 6px; + } + +} +@media (min-width:801px) { +/* tablet, landscape iPad, lo-res laptops ands desktops */ + .center { + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + margin: auto; + box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 50px 0 rgba(0, 0, 0, 0.19); + padding: 0; + } + .content { + width: 75%; + margin: 0 auto; + padding: 25px; + + } + + .buttonsWrapper { + width: 70%; + } + .block-btns { + display: block; + width: 100%; + padding-left: 0; + padding-right: 0; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; + } + +} +@media (min-width:990px) { +/* big landscape tablets, laptops, and desktops */ + .center { + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + margin: auto; + box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 50px 0 rgba(0, 0, 0, 0.19); + padding: 0; + height: 526px; + width: 60%; + border-radius: 4px; + } + .content { + width: 75%; + margin: 0 auto; + padding: 25px; + + } + + .buttonsWrapper { + width: 70%; + } + .block-btns { + display: block; + width: 100%; + padding-left: 0; + padding-right: 0; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; + } + #window-close { + font-size: 15px; + } + + } +@media (min-width:1025px) { +/* big landscape tablets, laptops, and desktops */ + .center { + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + margin: auto; + box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 50px 0 rgba(0, 0, 0, 0.19); + padding: 0; + height: 526px; + width: 53.5%; + border-radius: 4px; + } + .content { + width: 75%; + margin: 0 auto; + padding: 25px; + + } + + .buttonsWrapper { + width: 70%; + } + .block-btns { + display: block; + width: 100%; + padding-left: 0; + padding-right: 0; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; + } + #window-close { + font-size: 15px; + } + + } +@media (min-width:1281px) { +/* hi-res laptops and desktops */ + .center { + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + margin: auto; + box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 50px 0 rgba(0, 0, 0, 0.19); + padding: 0; + height: 526px; + width: 46.7%; + border-radius: 4px; + } + .content { + width: 75%; + margin: 0 auto; + padding: 25px; + + } + + .buttonsWrapper { + width: 70%; + } + .block-btns { + display: block; + width: 100%; + padding-left: 0; + padding-right: 0; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; + } + #window-close { + font-size: 15px; + } + + +} +@media (min-width:1440px) { +/* hi-res laptops and desktops */ + .center { + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + margin: auto; + box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 50px 0 rgba(0, 0, 0, 0.19); + padding: 0; + height: 526px; + width: 40.1%; + border-radius: 4px; + } + .content { + width: 75%; + margin: 0 auto; + padding: 25px; + + } + + .buttonsWrapper { + width: 70%; + } + .block-btns { + display: block; + width: 100%; + padding-left: 0; + padding-right: 0; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; + } + #window-close { + font-size: 15px; + } + + +} +@media (min-width:1600px) { +/* hi-res laptops and desktops */ + .center { + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + margin: auto; + box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 50px 0 rgba(0, 0, 0, 0.19); + padding: 0; + height: 526px; + width: 31.3%; + border-radius: 4px; + } + .content { + width: 75%; + margin: 0 auto; + padding: 25px; + + } + + .buttonsWrapper { + width: 75%; + } + .block-btns { + display: block; + width: 100%; + padding-left: 0; + padding-right: 0; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; + } + #window-close { + font-size: 15px; + } + + +} +.btn-action { + color: #ffffff; + background-image:radial-gradient(50% 100%, #fe7a0d 0%, #fe450d 100%); + box-shadow:0px 2px 4px 0px rgba(0,0,0,0.12), 0px 0px 2px 0px rgba(0,0,0,0.24); + border-radius:4px; + width:100%; + height:34px; + font-family: ProximaNova-Semibold, sans-serif; + font-size:15px; + color:#ffffff ; + text-shadow:0px 2px 4px rgba(0,0,0,0.20); + text-align:center; + } + + .header { + background-image:radial-gradient(50% 100%, #fe7a0d 0%, #fe450d 100%); + color: white; + height: 60px; + font-size: 20px; + line-height: 2; + text-align: center; + padding: 10px; + } + .header-action-btn { + float: left; + } + #window-action { + margin-top: 10%; + } + + .btn-account { + background-color: #ffffff; + color: #cb6d51; + margin-bottom: 15px; + } + #messages { + color: #252528; + } + + a { + text-decoration: none; + color: #ffffff; + } + button:hover, a:hover{ + color: #252528 !important; + opacity: 6% !important; + /*text-shadow: 0px 0px 2px #000000;*/ + } + + #content-hints{ + text-align: center; + margin-bottom: 5%; + } + .hide { + display: none; + } + textarea { + resize: none; +} + +#passphrase textarea{ + font-weight: bold; + text-align: center; +} +.disabled { + background-color: #C7CCD0; + background: -webkit-radial-gradient(#C7CCD0, #C7CCD0); /*Safari 5.1 to 6.0 */ + background: -o-radial-gradient(#C7CCD0, #C7CCD0); /* For Opera 11.6 to 12.0 */ + background: -moz-radial-gradient(#C7CCD0, #C7CCD0); /* For Firefox 3.6 to 15 */ + background: radial-gradient(#C7CCD0, #C7CCD0); /* Standard syntax (must be last) */ +} + +.marginbottom30px { + margin-bottom: 30px; +} +small.help-block { + font-size: 14px; + color: #fd2323; +} +.has-error .form-control { + border-color: #fd2323; +} +.has-error .form-control-feedback { + display: none !important; +} +.has-error .form-control:focus { + border-color: #fd2323; +} +.checkbox-inguana input[type="checkbox"]:checked + label::before, +.checkbox-inguana input[type="radio"]:checked + label::before { + background-color: #FE450D; + border-color: #FE450D + color:#ffffff; +} +.checkbox label::after { + color: #ffffff; +} +.errorMessage { + color: #fd2323; +} \ No newline at end of file diff --git a/webui/css/dashboard.css b/webui/css/dashboard.css new file mode 100644 index 000000000..03dbbb0e3 --- /dev/null +++ b/webui/css/dashboard.css @@ -0,0 +1,9 @@ +/*! + * Iguana dashboard + * + */ + + body, + html { + background: #F5F8FB; + } \ No newline at end of file diff --git a/webui/dashboard.html b/webui/dashboard.html new file mode 100755 index 000000000..10fb92f79 --- /dev/null +++ b/webui/dashboard.html @@ -0,0 +1,36 @@ + + + + + + + Iguana / Dashboard + + + + + + + +
+ +
+
Total balance
+
+ + +
+
+
+ + \ No newline at end of file diff --git a/webui/fonts/budicon.ttf b/webui/fonts/budicon.ttf new file mode 100644 index 000000000..e7a912baa Binary files /dev/null and b/webui/fonts/budicon.ttf differ diff --git a/webui/fonts/proxima_nova_semibold.otf b/webui/fonts/proxima_nova_semibold.otf new file mode 100644 index 000000000..132cdd5b0 Binary files /dev/null and b/webui/fonts/proxima_nova_semibold.otf differ diff --git a/webui/js/api.js b/webui/js/api.js new file mode 100644 index 000000000..c60454912 --- /dev/null +++ b/webui/js/api.js @@ -0,0 +1,76 @@ +/*! + * Iguana api config + * + */ + +var server = { + "protocol": "http://", + "ip": "localhost", + "port": "7778" +}; +var apiRoutes = { + "bitcoinRPC" : { + "walletPassphrase" : "bitcoinrpc/walletpassphrase", // params: password String, timeout Int + "encryptWallet" : "bitcoinrpc/encryptwallet" // params: passphrase String + } +}; + +function getServerUrl() { + return server.protocol + server.ip + ":" + server.port + "/api/"; +} + +function walletLogin(passphrase) { + var result = false; + + $.ajax({ + url: getServerUrl() + apiRoutes.bitcoinRPC.walletPassphrase + "?password=" + passphrase + "&timeout=300", + cache: false, + dataType: "text", + async: false + }) + .done(function(_response) { + var response = $.parseJSON(_response); + + if (response.error) { + // do something + console.log("error: " + response.error); + result = false; + } else { + if (response.result === "success") { + result = true; + } else { + result = false; + } + } + }); + + return result; +} + +function walletCreate(passphrase) { + var result = false; + + $.ajax({ + url: getServerUrl() + apiRoutes.bitcoinRPC.encryptWallet + "?passphrase=" + passphrase, + cache: false, + dataType: "text", + async: false + }) + .done(function(_response) { + var response = $.parseJSON(_response); + + if (response.error) { + // do something + console.log("error: " + response.error); + result = false; + } else { + if (response.result === "success") { + result = true; + } else { + result = false; + } + } + }); + + return result; +} \ No newline at end of file diff --git a/webui/js/auth.js b/webui/js/auth.js new file mode 100644 index 000000000..ed3feedb4 --- /dev/null +++ b/webui/js/auth.js @@ -0,0 +1,121 @@ +/*! + * Iguana authorization + * + */ + +$(document).ready(function() { + // this should do as simple check whether it's a login or account create page + if ($(".login-form").width()) { + var savedPassphrase = JSON.parse(localstorageGetVal("iguanaPassphrase")); + + addAuthorizationButtonAction("signin"); + watchPassphraseKeyUpEvent("signin"); + + if (savedPassphrase.passphrase && savedPassphrase.isConfirmed === "yes") + $("#passphrase").val(savedPassphrase.passphrase); + $(".btn-signin").removeClass("disabled"); + + $(".login-form .btn-signup").click(function() { + openPage("create-account"); + }); + } + + if ($(".create-account-form").width()) { + addAuthorizationButtonAction("add-account"); + watchPassphraseKeyUpEvent("add-account"); + initCreateAccountForm(); + } +}); + +function addAuthorizationButtonAction(buttonClassName) { + $(".btn-" + buttonClassName).click(function() { + // validate passphrase + // condition: 24 words in lower case followed by a single space character + var passphraseInput = $("#passphrase").val(); + var totalSubstr = passphraseInput.match(/\b\w+\b/g); + var totalSubstrAlpha = passphraseInput.match(/\b[a-z]+\b/g); // count only words consist of characters + var totalSpaces = passphraseInput.match(/\s/g); + + if (totalSubstr && totalSubstrAlpha && totalSpaces) + if (totalSubstr.length === 24 && totalSubstrAlpha.length === 24 && totalSpaces.length === 23) { + if (buttonClassName === "signin" ? walletLogin(passphraseInput) : walletCreate(passphraseInput) && verifyNewPassphrase()) { + toggleLoginErrorStyling(false); + openPage("dashboard"); + } else { + toggleLoginErrorStyling(true); + } + } else { + toggleLoginErrorStyling(true); + } + else + toggleLoginErrorStyling(true); + }); +} + +function watchPassphraseKeyUpEvent(buttonClassName) { + $("#passphrase").keyup(function() { + if ($("#passphrase").val().length > 0) { + $(".btn-" + buttonClassName).removeClass("disabled"); + } else { + $(".btn-" + buttonClassName).addClass("disabled"); + } + }); +} + +function toggleLoginErrorStyling(isError) { + if (isError) { + $("#passphrase").addClass("error"); + $(".login-input-directions-error.col-red").removeClass("hidden"); + $(".login-input-directions").addClass("hidden"); + } else { + $("#passphrase").removeClass("error"); + $(".login-input-directions-error.col-red").addClass("hidden"); + } + $("#passphrase").val(""); +} + +function verifyNewPassphrase() { + var savedPassphrase = JSON.parse(localstorageGetVal("iguanaPassphrase")); + + if (savedPassphrase.passphrase === $("#passphrase").val() && savedPassphrase.isConfirmed === "no") { + savedPassphrase.isConfirmed = "yes"; + localstorageSetVal("iguanaPassphrase", savedPassphrase); + return true; + } else { + return false; + } +} + +function initCreateAccountForm() { + var newPassphrase = PassPhraseGenerator.generatePassPhrase(); + + $(".create-account-form").removeClass("hidden"); + $(".verify-passphrase-form").addClass("hidden"); + $("#passphrase").val(""); + + $("#passphrase-saved-checkbox").prop("checked", false); + $(".generated-passhprase").html(newPassphrase); + $(".btn-verify-passphrase").addClass("disabled"); + + $("#passphrase-saved-checkbox").click(function() { + if ($("#passphrase-saved-checkbox").prop("checked")) + $(".btn-verify-passphrase").removeClass("disabled"); + else + $(".btn-verify-passphrase").addClass("disabled"); + }); + + $(".verify-passphrase-form .btn-back").click(function() { + initCreateAccountForm(); + }); + + $(".create-account-form .btn-back").click(function() { + openPage("login"); + }); + + $(".btn-verify-passphrase").click(function() { + // isConfirmed is required to check if a user can verify a passphrase on the 2nd step + localstorageSetVal("iguanaPassphrase", { "passphrase" : $(".generated-passhprase").text(), "isConfirmed": "no" }); + $(".create-account-form").addClass("hidden"); + $(".verify-passphrase-form").removeClass("hidden"); + }); +} \ No newline at end of file diff --git a/webui/js/bootstrap.min.js b/webui/js/bootstrap.min.js new file mode 100644 index 000000000..e79c06513 --- /dev/null +++ b/webui/js/bootstrap.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v3.3.6 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under the MIT license + */ +if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1||b[0]>2)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 3")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.6",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.6",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),a(c.target).is('input[type="radio"]')||a(c.target).is('input[type="checkbox"]')||c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.6",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.6",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger(a.Event("hidden.bs.dropdown",f)))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.6",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger(a.Event("shown.bs.dropdown",h))}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&jdocument.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth
',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),c.isInStateTrue()?void 0:(clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide())},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-mo.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.6",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.6",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b=e[a]&&(void 0===e[a+1]||b .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.6",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery); \ No newline at end of file diff --git a/webui/js/create-account.js b/webui/js/create-account.js new file mode 100644 index 000000000..b8fe20122 --- /dev/null +++ b/webui/js/create-account.js @@ -0,0 +1,163 @@ +$('document').ready(function(){ + + $('#login-form').formValidation({ + framework: 'bootstrap', + err: { + container: '#messages' + }, + icon: { + valid: 'glyphicon glyphicon-ok', + invalid: 'glyphicon glyphicon-remove', + validating: 'glyphicon glyphicon-refresh' + }, + fields: { + passphrasetext: { + validators: { + callback: { + message: 'Incorrect passphrase, it consist of 24-word. Try to type or paste the passphrase one more time.', + callback: function (value, validator, $field) { + if($("#passphrase-text").val().length) { + $('#login-hint').removeClass('hide'); + $('#account-login').removeClass('disabled'); + $('#account-login').prop('disabled', false); + return true; + } else { + $('#login-hint').addClass('hide'); + $('#account-login').addClass('disabled'); + $('#account-login').prop('disabled', true); + return { + valid: false, + message: 'Incorrect passphrase, it consist of 24-word. Try to type or paste the passphrase one more time.' + } + } + return true; + } + } + } + } + } + }); + + + + $('#add-passphrase-text').keyup(function(e){ + e.preventDefault(); + if($(this).val().length) { + if(createdPassPhrase.trim() == $(this).val().trim()) { + $('#paassphrase-confirmation-hint').removeClass('hide'); + $('#add-account').removeClass('disabled'); + $('#add-account').prop('disabled', false); + } else { + $('#paassphrase-confirmation-hint').removeClass('hide'); + $('#confirmation-message').text('Incorrect passphrase, it consist of 24-word. Try to type or paste the passphrase one more time.'); + $('#confirmation-message').addClass('errorMessage'); + $('#add-account').addClass('disabled'); + $('#add-account').prop('disabled', true); + } + $('#passphrase-text').removeClass('disabled'); + } else { + $('#confirmation-message').text('Type or paste the passphrease to confirm you saved it properly'); + $('#confirmation-message').removeClass('errorMessage'); + } + }); + + $('#create-account').click(function(e) { + e.preventDefault(); + loadCreateAccountScreen(); + + }); + + $('#login-back').click(function(e) { + e.preventDefault(); + loadLoginScreen(); + + }); + + $('#create-account-next').click(function(e) { + e.preventDefault(); + loadSaveAccountScreen(); + + }); + + $('#account-back').click(function(e) { + e.preventDefault(); + loadBacktoAccountScreen(); + + }); + + function loadCreateAccountScreen() { + $('#login-form').data('formValidation').resetForm(); + $('#window-close').addClass('hide'); + $('#login-hint').addClass('hide'); + $('#login-form').addClass('hide'); + $('#login-acreen-actions').addClass('hide'); + + + $('#login-back').removeClass('hide'); + $('#accounts-label').removeClass('hide'); + $('#passphrase-hint').removeClass('hide'); + $('#create-account-form').removeClass('hide'); + $('#create-account-actions').removeClass('hide'); + + var passphrase = PassPhraseGenerator.generatePassPhrase(); + + $('#create-passphrase-text').html(passphrase); + $( '#passphrase-save-check' ).prop( "checked", false ).trigger('change'); + }; + + function loadLoginScreen() { + $('#window-close').removeClass('hide'); + $('#login-hint').removeClass('hide'); + $('#login-form').removeClass('hide'); + $('#login-form').removeClass('hide'); + $('#login-acreen-actions').removeClass('hide'); + + $('#login-back').addClass('hide'); + $('#accounts-label').addClass('hide'); + $('#passphrase-hint').addClass('hide'); + $('#create-account-form').addClass('hide'); + $('#create-account-actions').addClass('hide'); + $('#create-passphrase-text').html(''); + $("#create-passphrase-text").prop("disabled", false); + }; + + function loadSaveAccountScreen() { + $('#account-back').removeClass('hide'); + $('#paassphrase-confirmation-hint').removeClass('hide'); + $('#add-account-form').removeClass('hide'); + $('#add-account-actions').removeClass('hide'); + $('#add-passphrase-text').html('').val(''); + + createdPassPhrase = $('#create-passphrase-text').val(); + + $('#login-back').addClass('hide'); + $('#passphrase-hint').addClass('hide'); + $('#create-account-form').addClass('hide'); + $('#create-account-actions').addClass('hide'); + } + + function loadBacktoAccountScreen() { + $('#account-back').addClass('hide'); + $('#paassphrase-confirmation-hint').addClass('hide'); + $('#add-account-form').addClass('hide'); + $('#add-account-actions').addClass('hide'); + + $('#login-back').removeClass('hide'); + $('#passphrase-hint').removeClass('hide'); + $('#create-account-form').removeClass('hide'); + $('#create-account-actions').removeClass('hide'); + $( '#passphrase-save-check' ).prop( "checked", false ).trigger('change'); + }; + + $('#passphrase-save-check').change(function(e) { + e.preventDefault(); + + if($(this).is(":checked")) { + $('#create-account-next').removeClass('disabled'); + $('#create-account-next').prop('disabled', false); + } else { + $('#create-account-next').addClass('disabled'); + $('#create-account-next').prop('disabled', true); + } + }); +}); \ No newline at end of file diff --git a/webui/js/crypto/passphrasegenerator.js b/webui/js/crypto/passphrasegenerator.js new file mode 100644 index 000000000..774598332 --- /dev/null +++ b/webui/js/crypto/passphrasegenerator.js @@ -0,0 +1,85 @@ +/****************************************************************************** + * Copyright © 2016 The Waves Core Developers. * + * * + * See the LICENSE files at * + * the top-level directory of this distribution for the individual copyright * + * holder information and the developer policies on copyright and licensing. * + * * + * Unless otherwise agreed in a custom licensing agreement, no part of the * + * Waves software, including this file, may be copied, modified, propagated, * + * or distributed except according to the terms contained in the LICENSE.txt * + * file. * + * * + * Removal or modification of this copyright notice is prohibited. * + * * + ******************************************************************************/ + +/** + * @depends {../3rdparty/jquery-2.1.0.js} + */ + +var PassPhraseGenerator = { + seeds: 0, + seedLimit: 512, + + push: function(seed) { + Math.seedrandom(seed, true); + this.seeds++; + }, + + isDone: function() { + if (this.seeds == this.seedLimit) { + return true; + } + return false; + }, + + percentage: function() { + return Math.round((this.seeds / this.seedLimit) * 100) + }, + + passPhrase: "", + + wordCount: 2048, + + words: ClientWordList, + + generatePassPhrase: function() { + + var crypto = window.crypto || window.msCrypto; + + bits = 280; + + var random = new Uint32Array(bits / 32); + + crypto.getRandomValues(random); + + var i = 0, + l = random.length, + n = this.wordCount, + words = [], + x, w1, w2, w3; + + for (; i < l; i++) { + x = random[i]; + w1 = x % n; + w2 = (((x / n) >> 0) + w1) % n; + w3 = (((((x / n) >> 0) / n) >> 0) + w2) % n; + + words.push(this.words[w1]); + words.push(this.words[w2]); + words.push(this.words[w3]); + } + + this.passPhrase = words.join(" "); + + crypto.getRandomValues(random); + + return this.passPhrase; + }, + + reset: function() { + this.passPhrase = ""; + this.seeds = 0; + } +} \ No newline at end of file diff --git a/webui/js/crypto/wordlist.js b/webui/js/crypto/wordlist.js new file mode 100644 index 000000000..4299dd599 --- /dev/null +++ b/webui/js/crypto/wordlist.js @@ -0,0 +1,2 @@ +//https://github.com/bitcoin/bips/blob/master/bip-0039/bip-0039-wordlists.md +var ClientWordList = ["abandon","ability","able","about","above","absent","absorb","abstract","absurd","abuse","access","accident","account","accuse","achieve","acid","acoustic","acquire","across","act","action","actor","actress","actual","adapt","add","addict","address","adjust","admit","adult","advance","advice","aerobic","affair","afford","afraid","again","age","agent","agree","ahead","aim","air","airport","aisle","alarm","album","alcohol","alert","alien","all","alley","allow","almost","alone","alpha","already","also","alter","always","amateur","amazing","among","amount","amused","analyst","anchor","ancient","anger","angle","angry","animal","ankle","announce","annual","another","answer","antenna","antique","anxiety","any","apart","apology","appear","apple","approve","april","arch","arctic","area","arena","argue","arm","armed","armor","army","around","arrange","arrest","arrive","arrow","art","artefact","artist","artwork","ask","aspect","assault","asset","assist","assume","asthma","athlete","atom","attack","attend","attitude","attract","auction","audit","august","aunt","author","auto","autumn","average","avocado","avoid","awake","aware","away","awesome","awful","awkward","axis","baby","bachelor","bacon","badge","bag","balance","balcony","ball","bamboo","banana","banner","bar","barely","bargain","barrel","base","basic","basket","battle","beach","bean","beauty","because","become","beef","before","begin","behave","behind","believe","below","belt","bench","benefit","best","betray","better","between","beyond","bicycle","bid","bike","bind","biology","bird","birth","bitter","black","blade","blame","blanket","blast","bleak","bless","blind","blood","blossom","blouse","blue","blur","blush","board","boat","body","boil","bomb","bone","bonus","book","boost","border","boring","borrow","boss","bottom","bounce","box","boy","bracket","brain","brand","brass","brave","bread","breeze","brick","bridge","brief","bright","bring","brisk","broccoli","broken","bronze","broom","brother","brown","brush","bubble","buddy","budget","buffalo","build","bulb","bulk","bullet","bundle","bunker","burden","burger","burst","bus","business","busy","butter","buyer","buzz","cabbage","cabin","cable","cactus","cage","cake","call","calm","camera","camp","can","canal","cancel","candy","cannon","canoe","canvas","canyon","capable","capital","captain","car","carbon","card","cargo","carpet","carry","cart","case","cash","casino","castle","casual","cat","catalog","catch","category","cattle","caught","cause","caution","cave","ceiling","celery","cement","census","century","cereal","certain","chair","chalk","champion","change","chaos","chapter","charge","chase","chat","cheap","check","cheese","chef","cherry","chest","chicken","chief","child","chimney","choice","choose","chronic","chuckle","chunk","churn","cigar","cinnamon","circle","citizen","city","civil","claim","clap","clarify","claw","clay","clean","clerk","clever","click","client","cliff","climb","clinic","clip","clock","clog","close","cloth","cloud","clown","club","clump","cluster","clutch","coach","coast","coconut","code","coffee","coil","coin","collect","color","column","combine","come","comfort","comic","common","company","concert","conduct","confirm","congress","connect","consider","control","convince","cook","cool","copper","copy","coral","core","corn","correct","cost","cotton","couch","country","couple","course","cousin","cover","coyote","crack","cradle","craft","cram","crane","crash","crater","crawl","crazy","cream","credit","creek","crew","cricket","crime","crisp","critic","crop","cross","crouch","crowd","crucial","cruel","cruise","crumble","crunch","crush","cry","crystal","cube","culture","cup","cupboard","curious","current","curtain","curve","cushion","custom","cute","cycle","dad","damage","damp","dance","danger","daring","dash","daughter","dawn","day","deal","debate","debris","decade","december","decide","decline","decorate","decrease","deer","defense","define","defy","degree","delay","deliver","demand","demise","denial","dentist","deny","depart","depend","deposit","depth","deputy","derive","describe","desert","design","desk","despair","destroy","detail","detect","develop","device","devote","diagram","dial","diamond","diary","dice","diesel","diet","differ","digital","dignity","dilemma","dinner","dinosaur","direct","dirt","disagree","discover","disease","dish","dismiss","disorder","display","distance","divert","divide","divorce","dizzy","doctor","document","dog","doll","dolphin","domain","donate","donkey","donor","door","dose","double","dove","draft","dragon","drama","drastic","draw","dream","dress","drift","drill","drink","drip","drive","drop","drum","dry","duck","dumb","dune","during","dust","dutch","duty","dwarf","dynamic","eager","eagle","early","earn","earth","easily","east","easy","echo","ecology","economy","edge","edit","educate","effort","egg","eight","either","elbow","elder","electric","elegant","element","elephant","elevator","elite","else","embark","embody","embrace","emerge","emotion","employ","empower","empty","enable","enact","end","endless","endorse","enemy","energy","enforce","engage","engine","enhance","enjoy","enlist","enough","enrich","enroll","ensure","enter","entire","entry","envelope","episode","equal","equip","era","erase","erode","erosion","error","erupt","escape","essay","essence","estate","eternal","ethics","evidence","evil","evoke","evolve","exact","example","excess","exchange","excite","exclude","excuse","execute","exercise","exhaust","exhibit","exile","exist","exit","exotic","expand","expect","expire","explain","expose","express","extend","extra","eye","eyebrow","fabric","face","faculty","fade","faint","faith","fall","false","fame","family","famous","fan","fancy","fantasy","farm","fashion","fat","fatal","father","fatigue","fault","favorite","feature","february","federal","fee","feed","feel","female","fence","festival","fetch","fever","few","fiber","fiction","field","figure","file","film","filter","final","find","fine","finger","finish","fire","firm","first","fiscal","fish","fit","fitness","fix","flag","flame","flash","flat","flavor","flee","flight","flip","float","flock","floor","flower","fluid","flush","fly","foam","focus","fog","foil","fold","follow","food","foot","force","forest","forget","fork","fortune","forum","forward","fossil","foster","found","fox","fragile","frame","frequent","fresh","friend","fringe","frog","front","frost","frown","frozen","fruit","fuel","fun","funny","furnace","fury","future","gadget","gain","galaxy","gallery","game","gap","garage","garbage","garden","garlic","garment","gas","gasp","gate","gather","gauge","gaze","general","genius","genre","gentle","genuine","gesture","ghost","giant","gift","giggle","ginger","giraffe","girl","give","glad","glance","glare","glass","glide","glimpse","globe","gloom","glory","glove","glow","glue","goat","goddess","gold","good","goose","gorilla","gospel","gossip","govern","gown","grab","grace","grain","grant","grape","grass","gravity","great","green","grid","grief","grit","grocery","group","grow","grunt","guard","guess","guide","guilt","guitar","gun","gym","habit","hair","half","hammer","hamster","hand","happy","harbor","hard","harsh","harvest","hat","have","hawk","hazard","head","health","heart","heavy","hedgehog","height","hello","helmet","help","hen","hero","hidden","high","hill","hint","hip","hire","history","hobby","hockey","hold","hole","holiday","hollow","home","honey","hood","hope","horn","horror","horse","hospital","host","hotel","hour","hover","hub","huge","human","humble","humor","hundred","hungry","hunt","hurdle","hurry","hurt","husband","hybrid","ice","icon","idea","identify","idle","ignore","ill","illegal","illness","image","imitate","immense","immune","impact","impose","improve","impulse","inch","include","income","increase","index","indicate","indoor","industry","infant","inflict","inform","inhale","inherit","initial","inject","injury","inmate","inner","innocent","input","inquiry","insane","insect","inside","inspire","install","intact","interest","into","invest","invite","involve","iron","island","isolate","issue","item","ivory","jacket","jaguar","jar","jazz","jealous","jeans","jelly","jewel","job","join","joke","journey","joy","judge","juice","jump","jungle","junior","junk","just","kangaroo","keen","keep","ketchup","key","kick","kid","kidney","kind","kingdom","kiss","kit","kitchen","kite","kitten","kiwi","knee","knife","knock","know","lab","label","labor","ladder","lady","lake","lamp","language","laptop","large","later","latin","laugh","laundry","lava","law","lawn","lawsuit","layer","lazy","leader","leaf","learn","leave","lecture","left","leg","legal","legend","leisure","lemon","lend","length","lens","leopard","lesson","letter","level","liar","liberty","library","license","life","lift","light","like","limb","limit","link","lion","liquid","list","little","live","lizard","load","loan","lobster","local","lock","logic","lonely","long","loop","lottery","loud","lounge","love","loyal","lucky","luggage","lumber","lunar","lunch","luxury","lyrics","machine","mad","magic","magnet","maid","mail","main","major","make","mammal","man","manage","mandate","mango","mansion","manual","maple","marble","march","margin","marine","market","marriage","mask","mass","master","match","material","math","matrix","matter","maximum","maze","meadow","mean","measure","meat","mechanic","medal","media","melody","melt","member","memory","mention","menu","mercy","merge","merit","merry","mesh","message","metal","method","middle","midnight","milk","million","mimic","mind","minimum","minor","minute","miracle","mirror","misery","miss","mistake","mix","mixed","mixture","mobile","model","modify","mom","moment","monitor","monkey","monster","month","moon","moral","more","morning","mosquito","mother","motion","motor","mountain","mouse","move","movie","much","muffin","mule","multiply","muscle","museum","mushroom","music","must","mutual","myself","mystery","myth","naive","name","napkin","narrow","nasty","nation","nature","near","neck","need","negative","neglect","neither","nephew","nerve","nest","net","network","neutral","never","news","next","nice","night","noble","noise","nominee","noodle","normal","north","nose","notable","note","nothing","notice","novel","now","nuclear","number","nurse","nut","oak","obey","object","oblige","obscure","observe","obtain","obvious","occur","ocean","october","odor","off","offer","office","often","oil","okay","old","olive","olympic","omit","once","one","onion","online","only","open","opera","opinion","oppose","option","orange","orbit","orchard","order","ordinary","organ","orient","original","orphan","ostrich","other","outdoor","outer","output","outside","oval","oven","over","own","owner","oxygen","oyster","ozone","pact","paddle","page","pair","palace","palm","panda","panel","panic","panther","paper","parade","parent","park","parrot","party","pass","patch","path","patient","patrol","pattern","pause","pave","payment","peace","peanut","pear","peasant","pelican","pen","penalty","pencil","people","pepper","perfect","permit","person","pet","phone","photo","phrase","physical","piano","picnic","picture","piece","pig","pigeon","pill","pilot","pink","pioneer","pipe","pistol","pitch","pizza","place","planet","plastic","plate","play","please","pledge","pluck","plug","plunge","poem","poet","point","polar","pole","police","pond","pony","pool","popular","portion","position","possible","post","potato","pottery","poverty","powder","power","practice","praise","predict","prefer","prepare","present","pretty","prevent","price","pride","primary","print","priority","prison","private","prize","problem","process","produce","profit","program","project","promote","proof","property","prosper","protect","proud","provide","public","pudding","pull","pulp","pulse","pumpkin","punch","pupil","puppy","purchase","purity","purpose","purse","push","put","puzzle","pyramid","quality","quantum","quarter","question","quick","quit","quiz","quote","rabbit","raccoon","race","rack","radar","radio","rail","rain","raise","rally","ramp","ranch","random","range","rapid","rare","rate","rather","raven","raw","razor","ready","real","reason","rebel","rebuild","recall","receive","recipe","record","recycle","reduce","reflect","reform","refuse","region","regret","regular","reject","relax","release","relief","rely","remain","remember","remind","remove","render","renew","rent","reopen","repair","repeat","replace","report","require","rescue","resemble","resist","resource","response","result","retire","retreat","return","reunion","reveal","review","reward","rhythm","rib","ribbon","rice","rich","ride","ridge","rifle","right","rigid","ring","riot","ripple","risk","ritual","rival","river","road","roast","robot","robust","rocket","romance","roof","rookie","room","rose","rotate","rough","round","route","royal","rubber","rude","rug","rule","run","runway","rural","sad","saddle","sadness","safe","sail","salad","salmon","salon","salt","salute","same","sample","sand","satisfy","satoshi","sauce","sausage","save","say","scale","scan","scare","scatter","scene","scheme","school","science","scissors","scorpion","scout","scrap","screen","script","scrub","sea","search","season","seat","second","secret","section","security","seed","seek","segment","select","sell","seminar","senior","sense","sentence","series","service","session","settle","setup","seven","shadow","shaft","shallow","share","shed","shell","sheriff","shield","shift","shine","ship","shiver","shock","shoe","shoot","shop","short","shoulder","shove","shrimp","shrug","shuffle","shy","sibling","sick","side","siege","sight","sign","silent","silk","silly","silver","similar","simple","since","sing","siren","sister","situate","six","size","skate","sketch","ski","skill","skin","skirt","skull","slab","slam","sleep","slender","slice","slide","slight","slim","slogan","slot","slow","slush","small","smart","smile","smoke","smooth","snack","snake","snap","sniff","snow","soap","soccer","social","sock","soda","soft","solar","soldier","solid","solution","solve","someone","song","soon","sorry","sort","soul","sound","soup","source","south","space","spare","spatial","spawn","speak","special","speed","spell","spend","sphere","spice","spider","spike","spin","spirit","split","spoil","sponsor","spoon","sport","spot","spray","spread","spring","spy","square","squeeze","squirrel","stable","stadium","staff","stage","stairs","stamp","stand","start","state","stay","steak","steel","stem","step","stereo","stick","still","sting","stock","stomach","stone","stool","story","stove","strategy","street","strike","strong","struggle","student","stuff","stumble","style","subject","submit","subway","success","such","sudden","suffer","sugar","suggest","suit","summer","sun","sunny","sunset","super","supply","supreme","sure","surface","surge","surprise","surround","survey","suspect","sustain","swallow","swamp","swap","swarm","swear","sweet","swift","swim","swing","switch","sword","symbol","symptom","syrup","system","table","tackle","tag","tail","talent","talk","tank","tape","target","task","taste","tattoo","taxi","teach","team","tell","ten","tenant","tennis","tent","term","test","text","thank","that","theme","then","theory","there","they","thing","this","thought","three","thrive","throw","thumb","thunder","ticket","tide","tiger","tilt","timber","time","tiny","tip","tired","tissue","title","toast","tobacco","today","toddler","toe","together","toilet","token","tomato","tomorrow","tone","tongue","tonight","tool","tooth","top","topic","topple","torch","tornado","tortoise","toss","total","tourist","toward","tower","town","toy","track","trade","traffic","tragic","train","transfer","trap","trash","travel","tray","treat","tree","trend","trial","tribe","trick","trigger","trim","trip","trophy","trouble","truck","true","truly","trumpet","trust","truth","try","tube","tuition","tumble","tuna","tunnel","turkey","turn","turtle","twelve","twenty","twice","twin","twist","two","type","typical","ugly","umbrella","unable","unaware","uncle","uncover","under","undo","unfair","unfold","unhappy","uniform","unique","unit","universe","unknown","unlock","until","unusual","unveil","update","upgrade","uphold","upon","upper","upset","urban","urge","usage","use","used","useful","useless","usual","utility","vacant","vacuum","vague","valid","valley","valve","van","vanish","vapor","various","vast","vault","vehicle","velvet","vendor","venture","venue","verb","verify","version","very","vessel","veteran","viable","vibrant","vicious","victory","video","view","village","vintage","violin","virtual","virus","visa","visit","visual","vital","vivid","vocal","voice","void","volcano","volume","vote","voyage","wage","wagon","wait","walk","wall","walnut","want","warfare","warm","warrior","wash","wasp","waste","water","wave","way","wealth","weapon","wear","weasel","weather","web","wedding","weekend","weird","welcome","west","wet","whale","what","wheat","wheel","when","where","whip","whisper","wide","width","wife","wild","will","win","window","wine","wing","wink","winner","winter","wire","wisdom","wise","wish","witness","wolf","woman","wonder","wood","wool","word","work","world","worry","worth","wrap","wreck","wrestle","wrist","write","wrong","yard","year","yellow","you","young","youth","zebra","zero","zone","zoo"]; \ No newline at end of file diff --git a/webui/js/jquery-3.0.0.min.js b/webui/js/jquery-3.0.0.min.js new file mode 100644 index 000000000..62d410d95 --- /dev/null +++ b/webui/js/jquery-3.0.0.min.js @@ -0,0 +1,4 @@ +/*! jQuery v3.0.0 | (c) jQuery Foundation | jquery.org/license */ +!function(a,b){"use strict";"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){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.0.0",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:f.call(this)},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:h,sort:c.sort,splice:c.splice},r.extend=r.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||r.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&&(r.isPlainObject(d)||(e=r.isArray(d)))?(e?(e=!1,f=c&&r.isArray(c)?c:[]):f=c&&r.isPlainObject(c)?c:{},g[b]=r.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},r.extend({expando:"jQuery"+(q+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===r.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){var b=r.type(a);return("number"===b||"string"===b)&&!isNaN(a-parseFloat(a))},isPlainObject:function(a){var b,c;return a&&"[object Object]"===k.call(a)?(b=e(a))?(c=l.call(b,"constructor")&&b.constructor,"function"==typeof c&&m.call(c)===n):!0:!1},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?j[k.call(a)]||"object":typeof a},globalEval:function(a){p(a)},camelCase:function(a){return a.replace(t,"ms-").replace(u,v)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(w(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(s,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(w(Object(a))?r.merge(c,"string"==typeof a?[a]:a):h.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:i.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,f=0,h=[];if(w(a))for(d=a.length;d>f;f++)e=b(a[f],f,c),null!=e&&h.push(e);else for(f in a)e=b(a[f],f,c),null!=e&&h.push(e);return g.apply([],h)},guid:1,proxy:function(a,b){var c,d,e;return"string"==typeof b&&(c=a[b],b=a,a=c),r.isFunction(a)?(d=f.call(arguments,2),e=function(){return a.apply(b||this,d.concat(f.call(arguments)))},e.guid=a.guid=a.guid||r.guid++,e):void 0},now:Date.now,support:o}),"function"==typeof Symbol&&(r.fn[Symbol.iterator]=c[Symbol.iterator]),r.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){j["[object "+b+"]"]=b.toLowerCase()});function w(a){var b=!!a&&"length"in a&&a.length,c=r.type(a);return"function"===c||r.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var x=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=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\x00-\\xa0])+",M="\\["+K+"*("+L+")(?:"+K+"*([*^$|!~]?=)"+K+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+L+"))|)"+K+"*\\]",N=":("+L+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+M+")*)|.*)\\)|)",O=new RegExp(K+"+","g"),P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=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)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g,ca=function(a,b){return b?"\x00"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"label"in b&&b.disabled===a||"form"in b&&b.disabled===a||"form"in b&&b.disabled===!1&&(b.isDisabled===a||b.isDisabled!==!a&&("label"in b||!ea(b))!==a)}}function pa(a){return ia(function(b){return b=+b,ia(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 qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return"undefined"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML="";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.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},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.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=ga.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=ga.selectors={cacheLength:50,createPseudo:ia,match:V,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(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===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]||ga.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]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.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(_,aa).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("(^|"+K+")"+a+"("+K+"|$)"))&&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=ga.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(O," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(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:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).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:oa(!1),disabled:oa(!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 X.test(a.nodeName)},input:function(a){return W.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:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[0>c?c+b:c]}),even:pa(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:pa(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:pa(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function ta(a,b,c){var d=b.dir,e=b.next,f=e||d,g=c&&"parentNode"===f,h=x++;return b.first?function(b,c,e){while(b=b[d])if(1===b.nodeType||g)return a(b,c,e)}:function(b,c,i){var j,k,l,m=[w,h];if(i){while(b=b[d])if((1===b.nodeType||g)&&a(b,c,i))return!0}else while(b=b[d])if(1===b.nodeType||g)if(l=b[u]||(b[u]={}),k=l[b.uniqueID]||(l[b.uniqueID]={}),e&&e===b.nodeName.toLowerCase())b=b[d]||b;else{if((j=k[f])&&j[0]===w&&j[1]===h)return m[2]=j[2];if(k[f]=m,m[2]=a(b,c,i))return!0}}}function ua(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 va(a,b,c){for(var d=0,e=b.length;e>d;d++)ga(a,b[d],c);return c}function wa(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 xa(a,b,c,d,e,f){return d&&!d[u]&&(d=xa(d)),e&&!e[u]&&(e=xa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||va(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:wa(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=wa(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?I(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(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=[ta(ua(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 xa(i>1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,e>i&&ya(a.slice(i,e)),f>e&&ya(a=a.slice(e)),f>e&&sa(a))}m.push(c)}return ua(m)}function za(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.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(_,aa),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=V.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(_,aa),$.test(j[0].type)&&qa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&sa(j),!a)return G.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||$.test(a)&&qa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext,B=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,C=/^.[^:#\[\.,]*$/;function D(a,b,c){if(r.isFunction(b))return r.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return r.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(C.test(b))return r.filter(b,a,c);b=r.filter(b,a)}return r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType})}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;d>b;b++)if(r.contains(e[b],this))return!0}));for(c=this.pushStack([]),b=0;d>b;b++)r.find(a,e[b],c);return d>1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(D(this,a||[],!1))},not:function(a){return this.pushStack(D(this,a||[],!0))},is:function(a){return!!D(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var E,F=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,G=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||E,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:F.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),B.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};G.prototype=r.fn,E=r(d);var H=/^(?:parents|prev(?:Until|All))/,I={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(r.contains(this,b[a]))return!0})},closest:function(a,b){var c,d=0,e=this.length,f=[],g="string"!=typeof a&&r(a);if(!A.test(a))for(;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&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function J(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return J(a,"nextSibling")},prev:function(a){return J(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return a.contentDocument||r.merge([],a.childNodes)}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(I[a]||r.uniqueSort(e),H.test(a)&&e.reverse()),this.pushStack(e)}});var K=/\S+/g;function L(a){var b={};return r.each(a.match(K)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?L(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function M(a){return a}function N(a){throw a}function O(a,b,c){var d;try{a&&r.isFunction(d=a.promise)?d.call(a).done(b).fail(c):a&&r.isFunction(d=a.then)?d.call(a,b,c):b.call(void 0,a)}catch(a){c.call(void 0,a)}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(f>b)){if(a=d.apply(h,i),a===c.promise())throw new TypeError("Thenable self-resolution");j=a&&("object"==typeof a||"function"==typeof a)&&a.then,r.isFunction(j)?e?j.call(a,g(f,c,M,e),g(f,c,N,e)):(f++,j.call(a,g(f,c,M,e),g(f,c,N,e),g(f,c,M,c.notifyWith))):(d!==M&&(h=void 0,i=[a]),(e||c.resolveWith)(h,i))}},k=e?j:function(){try{j()}catch(a){r.Deferred.exceptionHook&&r.Deferred.exceptionHook(a,k.stackTrace),b+1>=f&&(d!==N&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:M,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:M)),c[2][3].add(g(0,a,r.isFunction(d)?d:N))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(1>=b&&(O(a,g.done(h(c)).resolve,g.reject),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)O(e[c],h(c),g.reject);return g.promise()}});var P=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&P.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)};var Q=r.Deferred();r.fn.ready=function(a){return Q.then(a),this},r.extend({isReady:!1,readyWait:1,holdReady:function(a){a?r.readyWait++:r.ready(!0)},ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||Q.resolveWith(d,[r]))}}),r.ready.then=Q.then;function R(){d.removeEventListener("DOMContentLoaded",R),a.removeEventListener("load",R),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",R),a.addEventListener("load",R));var S=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)S(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){ +return j.call(r(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},T=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function U(){this.expando=r.expando+U.uid++}U.uid=1,U.prototype={cache:function(a){var b=a[this.expando];return b||(b={},T(a)&&(a.nodeType?a[this.expando]=b:Object.defineProperty(a,this.expando,{value:b,configurable:!0}))),b},set:function(a,b,c){var d,e=this.cache(a);if("string"==typeof b)e[r.camelCase(b)]=c;else for(d in b)e[r.camelCase(d)]=b[d];return e},get:function(a,b){return void 0===b?this.cache(a):a[this.expando]&&a[this.expando][r.camelCase(b)]},access:function(a,b,c){return void 0===b||b&&"string"==typeof b&&void 0===c?this.get(a,b):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d=a[this.expando];if(void 0!==d){if(void 0!==b){r.isArray(b)?b=b.map(r.camelCase):(b=r.camelCase(b),b=b in d?[b]:b.match(K)||[]),c=b.length;while(c--)delete d[b[c]]}(void 0===b||r.isEmptyObject(d))&&(a.nodeType?a[this.expando]=void 0:delete a[this.expando])}},hasData:function(a){var b=a[this.expando];return void 0!==b&&!r.isEmptyObject(b)}};var V=new U,W=new U,X=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Y=/[A-Z]/g;function Z(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Y,"-$&").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:X.test(c)?JSON.parse(c):c}catch(e){}W.set(a,b,c)}else c=void 0;return c}r.extend({hasData:function(a){return W.hasData(a)||V.hasData(a)},data:function(a,b,c){return W.access(a,b,c)},removeData:function(a,b){W.remove(a,b)},_data:function(a,b,c){return V.access(a,b,c)},_removeData:function(a,b){V.remove(a,b)}}),r.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=W.get(f),1===f.nodeType&&!V.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=r.camelCase(d.slice(5)),Z(f,d,e[d])));V.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){W.set(this,a)}):S(this,function(b){var c;if(f&&void 0===b){if(c=W.get(f,a),void 0!==c)return c;if(c=Z(f,a),void 0!==c)return c}else this.each(function(){W.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){W.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=V.get(a,b),c&&(!d||r.isArray(c)?d=V.access(a,b,r.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.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 V.get(a,c)||V.access(a,c,{empty:r.Callbacks("once memory").add(function(){V.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthf;f++)d=a[f],d.style&&(c=d.style.display,b?("none"===c&&(e[f]=V.get(d,"display")||null,e[f]||(d.style.display="")),""===d.style.display&&ba(d)&&(e[f]=fa(d))):"none"!==c&&(e[f]="none",V.set(d,"display",c)));for(f=0;g>f;f++)null!=e[f]&&(a[f].style.display=e[f]);return a}r.fn.extend({show:function(){return ga(this,!0)},hide:function(){return ga(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){ba(this)?r(this).show():r(this).hide()})}});var ha=/^(?:checkbox|radio)$/i,ia=/<([a-z][^\/\0>\x20\t\r\n\f]+)/i,ja=/^$|\/(?:java|ecma)script/i,ka={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ka.optgroup=ka.option,ka.tbody=ka.tfoot=ka.colgroup=ka.caption=ka.thead,ka.th=ka.td;function la(a,b){var c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&r.nodeName(a,b)?r.merge([a],c):c}function ma(a,b){for(var c=0,d=a.length;d>c;c++)V.set(a[c],"globalEval",!b||V.get(b[c],"globalEval"))}var na=/<|&#?\w+;/;function oa(a,b,c,d,e){for(var f,g,h,i,j,k,l=b.createDocumentFragment(),m=[],n=0,o=a.length;o>n;n++)if(f=a[n],f||0===f)if("object"===r.type(f))r.merge(m,f.nodeType?[f]:f);else if(na.test(f)){g=g||l.appendChild(b.createElement("div")),h=(ia.exec(f)||["",""])[1].toLowerCase(),i=ka[h]||ka._default,g.innerHTML=i[1]+r.htmlPrefilter(f)+i[2],k=i[0];while(k--)g=g.lastChild;r.merge(m,g.childNodes),g=l.firstChild,g.textContent=""}else m.push(b.createTextNode(f));l.textContent="",n=0;while(f=m[n++])if(d&&r.inArray(f,d)>-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=la(l.appendChild(f),"script"),j&&ma(g),c){k=0;while(f=g[k++])ja.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var pa=d.documentElement,qa=/^key/,ra=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,sa=/^([^.]*)(?:\.(.+)|)/;function ta(){return!0}function ua(){return!1}function va(){try{return d.activeElement}catch(a){}}function wa(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)wa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=ua;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(pa,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(K)||[""],j=b.length;while(j--)h=sa.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.hasData(a)&&V.get(a);if(q&&(i=q.events)){b=(b||"").match(K)||[""],j=b.length;while(j--)if(h=sa.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==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,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&V.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(V.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;cc;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?r(e,this).index(i)>-1:r.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h\x20\t\r\n\f]*)[^>]*)\/>/gi,ya=/\s*$/g;function Ca(a,b){return r.nodeName(a,"table")&&r.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a:a}function Da(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function Ea(a){var b=Aa.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Fa(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(V.hasData(a)&&(f=V.access(a),g=V.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++)r.event.add(b,e,j[e][c])}W.hasData(a)&&(h=W.access(a),i=r.extend({},h),W.set(b,i))}}function Ga(a,b){var c=b.nodeName.toLowerCase();"input"===c&&ha.test(a.type)?b.checked=a.checked:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}function Ha(a,b,c,d){b=g.apply([],b);var e,f,h,i,j,k,l=0,m=a.length,n=m-1,q=b[0],s=r.isFunction(q);if(s||m>1&&"string"==typeof q&&!o.checkClone&&za.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ha(f,b,c,d)});if(m&&(e=oa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(la(e,"script"),Da),i=h.length;m>l;l++)j=e,l!==n&&(j=r.clone(j,!0,!0),i&&r.merge(h,la(j,"script"))),c.call(a[l],j,l);if(i)for(k=h[h.length-1].ownerDocument,r.map(h,Ea),l=0;i>l;l++)j=h[l],ja.test(j.type||"")&&!V.access(j,"globalEval")&&r.contains(k,j)&&(j.src?r._evalUrl&&r._evalUrl(j.src):p(j.textContent.replace(Ba,""),k))}return a}function Ia(a,b,c){for(var d,e=b?r.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||r.cleanData(la(d)),d.parentNode&&(c&&r.contains(d.ownerDocument,d)&&ma(la(d,"script")),d.parentNode.removeChild(d));return a}r.extend({htmlPrefilter:function(a){return a.replace(xa,"<$1>")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=la(h),f=la(a),d=0,e=f.length;e>d;d++)Ga(f[d],g[d]);if(b)if(c)for(f=f||la(a),g=g||la(h),d=0,e=f.length;e>d;d++)Fa(f[d],g[d]);else Fa(a,h);return g=la(h,"script"),g.length>0&&ma(g,!i&&la(a,"script")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(T(c)){if(b=c[V.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[V.expando]=void 0}c[W.expando]&&(c[W.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ia(this,a,!0)},remove:function(a){return Ia(this,a)},text:function(a){return S(this,function(a){return void 0===a?r.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 Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.appendChild(a)}})},prepend:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(la(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 r.clone(this,a,b)})},html:function(a){return S(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&&!ya.test(a)&&!ka[(ia.exec(a)||["",""])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(r.cleanData(la(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ha(this,arguments,function(b){var c=this.parentNode;r.inArray(this,a)<0&&(r.cleanData(la(this)),c&&c.replaceChild(b,this))},a)}}),r.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){r.fn[a]=function(a){for(var c,d=[],e=r(a),f=e.length-1,g=0;f>=g;g++)c=g===f?this:this.clone(!0),r(e[g])[b](c),h.apply(d,c.get());return this.pushStack(d)}});var Ja=/^margin/,Ka=new RegExp("^("+$+")(?!px)[a-z%]+$","i"),La=function(b){var c=b.ownerDocument.defaultView;return c&&c.opener||(c=a),c.getComputedStyle(b)};!function(){function b(){if(i){i.style.cssText="box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",i.innerHTML="",pa.appendChild(h);var b=a.getComputedStyle(i);c="1%"!==b.top,g="2px"===b.marginLeft,e="4px"===b.width,i.style.marginRight="50%",f="4px"===b.marginRight,pa.removeChild(h),i=null}}var c,e,f,g,h=d.createElement("div"),i=d.createElement("div");i.style&&(i.style.backgroundClip="content-box",i.cloneNode(!0).style.backgroundClip="",o.clearCloneStyle="content-box"===i.style.backgroundClip,h.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",h.appendChild(i),r.extend(o,{pixelPosition:function(){return b(),c},boxSizingReliable:function(){return b(),e},pixelMarginRight:function(){return b(),f},reliableMarginLeft:function(){return b(),g}}))}();function Ma(a,b,c){var d,e,f,g,h=a.style;return c=c||La(a),c&&(g=c.getPropertyValue(b)||c[b],""!==g||r.contains(a.ownerDocument,a)||(g=r.style(a,b)),!o.pixelMarginRight()&&Ka.test(g)&&Ja.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function Na(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Oa=/^(none|table(?!-c[ea]).+)/,Pa={position:"absolute",visibility:"hidden",display:"block"},Qa={letterSpacing:"0",fontWeight:"400"},Ra=["Webkit","Moz","ms"],Sa=d.createElement("div").style;function Ta(a){if(a in Sa)return a;var b=a[0].toUpperCase()+a.slice(1),c=Ra.length;while(c--)if(a=Ra[c]+b,a in Sa)return a}function Ua(a,b,c){var d=_.exec(b);return d?Math.max(0,d[2]-(c||0))+(d[3]||"px"):b}function Va(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=r.css(a,c+aa[f],!0,e)),d?("content"===c&&(g-=r.css(a,"padding"+aa[f],!0,e)),"margin"!==c&&(g-=r.css(a,"border"+aa[f]+"Width",!0,e))):(g+=r.css(a,"padding"+aa[f],!0,e),"padding"!==c&&(g+=r.css(a,"border"+aa[f]+"Width",!0,e)));return g}function Wa(a,b,c){var d,e=!0,f=La(a),g="border-box"===r.css(a,"boxSizing",!1,f);if(a.getClientRects().length&&(d=a.getBoundingClientRect()[b]),0>=d||null==d){if(d=Ma(a,b,f),(0>d||null==d)&&(d=a.style[b]),Ka.test(d))return d;e=g&&(o.boxSizingReliable()||d===a.style[b]),d=parseFloat(d)||0}return d+Va(a,b,c||(g?"border":"content"),e,f)+"px"}r.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Ma(a,"opacity");return""===c?"1":c}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=r.camelCase(b),i=a.style;return b=r.cssProps[h]||(r.cssProps[h]=Ta(h)||h),g=r.cssHooks[b]||r.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b]:(f=typeof c,"string"===f&&(e=_.exec(c))&&e[1]&&(c=da(a,b,e),f="number"),null!=c&&c===c&&("number"===f&&(c+=e&&e[3]||(r.cssNumber[h]?"":"px")),o.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=r.camelCase(b);return b=r.cssProps[h]||(r.cssProps[h]=Ta(h)||h),g=r.cssHooks[b]||r.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=Ma(a,b,d)),"normal"===e&&b in Qa&&(e=Qa[b]),""===c||c?(f=parseFloat(e),c===!0||isFinite(f)?f||0:e):e}}),r.each(["height","width"],function(a,b){r.cssHooks[b]={get:function(a,c,d){return c?!Oa.test(r.css(a,"display"))||a.getClientRects().length&&a.getBoundingClientRect().width?Wa(a,b,d):ca(a,Pa,function(){return Wa(a,b,d)}):void 0},set:function(a,c,d){var e,f=d&&La(a),g=d&&Va(a,b,d,"border-box"===r.css(a,"boxSizing",!1,f),f);return g&&(e=_.exec(c))&&"px"!==(e[3]||"px")&&(a.style[b]=c,c=r.css(a,b)),Ua(a,c,g)}}}),r.cssHooks.marginLeft=Na(o.reliableMarginLeft,function(a,b){return b?(parseFloat(Ma(a,"marginLeft"))||a.getBoundingClientRect().left-ca(a,{marginLeft:0},function(){return a.getBoundingClientRect().left}))+"px":void 0}),r.each({margin:"",padding:"",border:"Width"},function(a,b){r.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+aa[d]+b]=f[d]||f[d-2]||f[0];return e}},Ja.test(a)||(r.cssHooks[a+b].set=Ua)}),r.fn.extend({css:function(a,b){return S(this,function(a,b,c){var d,e,f={},g=0;if(r.isArray(b)){for(d=La(a),e=b.length;e>g;g++)f[b[g]]=r.css(a,b[g],!1,d);return f}return void 0!==c?r.style(a,b,c):r.css(a,b)},a,b,arguments.length>1)}});function Xa(a,b,c,d,e){return new Xa.prototype.init(a,b,c,d,e)}r.Tween=Xa,Xa.prototype={constructor:Xa,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?"":"px")},cur:function(){var a=Xa.propHooks[this.prop];return a&&a.get?a.get(this):Xa.propHooks._default.get(this)},run:function(a){var b,c=Xa.propHooks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Xa.propHooks._default.set(this),this}},Xa.prototype.init.prototype=Xa.prototype,Xa.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},Xa.propHooks.scrollTop=Xa.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},r.fx=Xa.prototype.init,r.fx.step={};var Ya,Za,$a=/^(?:toggle|show|hide)$/,_a=/queueHooks$/;function ab(){Za&&(a.requestAnimationFrame(ab),r.fx.tick())}function bb(){return a.setTimeout(function(){Ya=void 0}),Ya=r.now()}function cb(a,b){var c,d=0,e={height:a};for(b=b?1:0;4>d;d+=2-b)c=aa[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function db(a,b,c){for(var d,e=(gb.tweeners[b]||[]).concat(gb.tweeners["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function eb(a,b,c){var d,e,f,g,h,i,j,k,l="width"in b||"height"in b,m=this,n={},o=a.style,p=a.nodeType&&ba(a),q=V.get(a,"fxshow");c.queue||(g=r._queueHooks(a,"fx"),null==g.unqueued&&(g.unqueued=0,h=g.empty.fire,g.empty.fire=function(){g.unqueued||h()}),g.unqueued++,m.always(function(){m.always(function(){g.unqueued--,r.queue(a,"fx").length||g.empty.fire()})}));for(d in b)if(e=b[d],$a.test(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}n[d]=q&&q[d]||r.style(a,d)}if(i=!r.isEmptyObject(b),i||!r.isEmptyObject(n)){l&&1===a.nodeType&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=q&&q.display,null==j&&(j=V.get(a,"display")),k=r.css(a,"display"),"none"===k&&(j?k=j:(ga([a],!0),j=a.style.display||j,k=r.css(a,"display"),ga([a]))),("inline"===k||"inline-block"===k&&null!=j)&&"none"===r.css(a,"float")&&(i||(m.done(function(){o.display=j}),null==j&&(k=o.display,j="none"===k?"":k)),o.display="inline-block")),c.overflow&&(o.overflow="hidden",m.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]})),i=!1;for(d in n)i||(q?"hidden"in q&&(p=q.hidden):q=V.access(a,"fxshow",{display:j}),f&&(q.hidden=!p),p&&ga([a],!0),m.done(function(){p||ga([a]),V.remove(a,"fxshow");for(d in n)r.style(a,d,n[d])})),i=db(p?q[d]:0,d,m),d in q||(q[d]=i.start,p&&(i.end=i.start,i.start=0))}}function fb(a,b){var c,d,e,f,g;for(c in a)if(d=r.camelCase(c),e=b[d],f=a[c],r.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=r.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function gb(a,b,c){var d,e,f=0,g=gb.prefilters.length,h=r.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=Ya||bb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:r.extend({},b),opts:r.extend(!0,{specialEasing:{},easing:r.easing._default},c),originalProperties:b,originalOptions:c,startTime:Ya||bb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=r.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?(h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]),this}}),k=j.props;for(fb(k,j.opts.specialEasing);g>f;f++)if(d=gb.prefilters[f].call(j,a,k,j.opts))return r.isFunction(d.stop)&&(r._queueHooks(j.elem,j.opts.queue).stop=r.proxy(d.stop,d)),d;return r.map(k,db,j),r.isFunction(j.opts.start)&&j.opts.start.call(a,j),r.fx.timer(r.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}r.Animation=r.extend(gb,{tweeners:{"*":[function(a,b){var c=this.createTween(a,b);return da(c.elem,a,_.exec(b),c),c}]},tweener:function(a,b){r.isFunction(a)?(b=a,a=["*"]):a=a.match(K);for(var c,d=0,e=a.length;e>d;d++)c=a[d],gb.tweeners[c]=gb.tweeners[c]||[],gb.tweeners[c].unshift(b)},prefilters:[eb],prefilter:function(a,b){b?gb.prefilters.unshift(a):gb.prefilters.push(a)}}),r.speed=function(a,b,c){var e=a&&"object"==typeof a?r.extend({},a):{complete:c||!c&&b||r.isFunction(a)&&a,duration:a,easing:c&&b||b&&!r.isFunction(b)&&b};return r.fx.off||d.hidden?e.duration=0:e.duration="number"==typeof e.duration?e.duration:e.duration in r.fx.speeds?r.fx.speeds[e.duration]:r.fx.speeds._default,null!=e.queue&&e.queue!==!0||(e.queue="fx"),e.old=e.complete,e.complete=function(){r.isFunction(e.old)&&e.old.call(this),e.queue&&r.dequeue(this,e.queue)},e},r.fn.extend({fadeTo:function(a,b,c,d){return this.filter(ba).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=r.isEmptyObject(a),f=r.speed(b,c,d),g=function(){var b=gb(this,r.extend({},a),f);(e||V.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=r.timers,g=V.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&_a.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));!b&&c||r.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=V.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=r.timers,g=d?d.length:0;for(c.finish=!0,r.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),r.each(["toggle","show","hide"],function(a,b){var c=r.fn[b];r.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(cb(b,!0),a,d,e)}}),r.each({slideDown:cb("show"),slideUp:cb("hide"),slideToggle:cb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){r.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),r.timers=[],r.fx.tick=function(){var a,b=0,c=r.timers;for(Ya=r.now();b1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?hb:void 0)),void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b),null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&r.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(K);if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c); +}}),hb={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=ib[b]||r.find.attr;ib[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=ib[g],ib[g]=e,e=null!=c(a,b,d)?g:null,ib[g]=f),e}});var jb=/^(?:input|select|textarea|button)$/i,kb=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return S(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):jb.test(a.nodeName)||kb.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});var lb=/[\t\r\n\f]/g;function mb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,mb(this)))});if("string"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=mb(c),d=1===c.nodeType&&(" "+e+" ").replace(lb," ")){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=r.trim(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,mb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=mb(c),d=1===c.nodeType&&(" "+e+" ").replace(lb," ")){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=r.trim(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,mb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r(this),f=a.match(K)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=mb(this),b&&V.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":V.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+mb(c)+" ").replace(lb," ").indexOf(b)>-1)return!0;return!1}});var nb=/\r/g,ob=/[\x20\t\r\n\f]+/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":r.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(nb,""):null==c?"":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:r.trim(r.text(a)).replace(ob," ")}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],(c.selected||i===e)&&!c.disabled&&(!c.parentNode.disabled||!r.nodeName(c.parentNode,"optgroup"))){if(b=r(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=r.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=r.inArray(r.valHooks.option.get(d),f)>-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){return r.isArray(b)?a.checked=r.inArray(r(a).val(),b)>-1:void 0}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var pb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!pb.test(p+r.event.triggered)&&(p.indexOf(".")>-1&&(q=p.split("."),p=q.shift(),q.sort()),k=p.indexOf(":")<0&&"on"+p,b=b[r.expando]?b:new r.Event(p,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,pb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(V.get(h,"events")||{})[b.type]&&V.get(h,"handle"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&T(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!T(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?r.event.trigger(a,b,c,!0):void 0}}),r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin="onfocusin"in a,o.focusin||r.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=V.access(d,b);e||d.addEventListener(a,c,!0),V.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=V.access(d,b)-1;e?V.access(d,b,e):(d.removeEventListener(a,c,!0),V.remove(d,b))}}});var qb=a.location,rb=r.now(),sb=/\?/;r.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||r.error("Invalid XML: "+b),c};var tb=/\[\]$/,ub=/\r?\n/g,vb=/^(?:submit|button|image|reset|file)$/i,wb=/^(?:input|select|textarea|keygen)/i;function xb(a,b,c,d){var e;if(r.isArray(b))r.each(b,function(b,e){c||tb.test(a)?d(a,e):xb(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==r.type(b))d(a,b);else for(e in b)xb(a+"["+e+"]",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(null==c?"":c)};if(r.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)xb(c,a[c],b,e);return d.join("&")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,"elements");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(":disabled")&&wb.test(this.nodeName)&&!vb.test(a)&&(this.checked||!ha.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:r.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(ub,"\r\n")}}):{name:b.name,value:c.replace(ub,"\r\n")}}).get()}});var yb=/%20/g,zb=/#.*$/,Ab=/([?&])_=[^&]*/,Bb=/^(.*?):[ \t]*([^\r\n]*)$/gm,Cb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Db=/^(?:GET|HEAD)$/,Eb=/^\/\//,Fb={},Gb={},Hb="*/".concat("*"),Ib=d.createElement("a");Ib.href=qb.href;function Jb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(K)||[];if(r.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Kb(a,b,c,d){var e={},f=a===Gb;function g(h){var i;return e[h]=!0,r.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Lb(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Mb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Nb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:qb.href,type:"GET",isLocal:Cb.test(qb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Hb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Lb(Lb(a,r.ajaxSettings),b):Lb(r.ajaxSettings,a)},ajaxPrefilter:Jb(Fb),ajaxTransport:Jb(Gb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks("once memory"),u=o.statusCode||{},v={},w={},x="canceled",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Bb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||qb.href)+"").replace(Eb,qb.protocol+"//"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||"*").toLowerCase().match(K)||[""],null==o.crossDomain){j=d.createElement("a");try{j.href=o.url,j.href=j.href,o.crossDomain=Ib.protocol+"//"+Ib.host!=j.protocol+"//"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&"string"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Kb(Fb,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger("ajaxStart"),o.type=o.type.toUpperCase(),o.hasContent=!Db.test(o.type),f=o.url.replace(zb,""),o.hasContent?o.data&&o.processData&&0===(o.contentType||"").indexOf("application/x-www-form-urlencoded")&&(o.data=o.data.replace(yb,"+")):(n=o.url.slice(f.length),o.data&&(f+=(sb.test(f)?"&":"?")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Ab,""),n=(sb.test(f)?"&":"?")+"_="+rb++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader("If-Modified-Since",r.lastModified[f]),r.etag[f]&&y.setRequestHeader("If-None-Match",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader("Content-Type",o.contentType),y.setRequestHeader("Accept",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+("*"!==o.dataTypes[0]?", "+Hb+"; q=0.01":""):o.accepts["*"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x="abort",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Kb(Gb,o,c,y)){if(y.readyState=1,l&&q.trigger("ajaxSend",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort("timeout")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,"No Transport");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||"",y.readyState=b>0?4:0,j=b>=200&&300>b||304===b,d&&(v=Mb(o,y,d)),v=Nb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader("Last-Modified"),w&&(r.lastModified[f]=w),w=y.getResponseHeader("etag"),w&&(r.etag[f]=w)),204===b||"HEAD"===o.type?x="nocontent":304===b?x="notmodified":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x="error",0>b&&(b=0))),y.status=b,y.statusText=(c||x)+"",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?"ajaxSuccess":"ajaxError",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger("ajaxComplete",[y,o]),--r.active||r.event.trigger("ajaxStop")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,"json")},getScript:function(a,b){return r.get(a,void 0,b,"script")}}),r.each(["get","post"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not("body").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Ob={0:200,1223:204},Pb=r.ajaxSettings.xhr();o.cors=!!Pb&&"withCredentials"in Pb,o.ajax=Pb=!!Pb,r.ajaxTransport(function(b){var c,d;return o.cors||Pb&&!b.crossDomain?{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Ob[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}:void 0}),r.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),r.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r(" + + + + + + +
+
+ +
+
+ + \ No newline at end of file diff --git a/win/libpthreadGC2.a b/win/libpthreadGC2.a deleted file mode 100755 index df211759f..000000000 Binary files a/win/libpthreadGC2.a and /dev/null differ diff --git a/win/mingw.h b/win/mingw.h deleted file mode 100755 index 415e7d44b..000000000 --- a/win/mingw.h +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef MINGW_H -#define MINGW_H - -#include - -#define _USE_W32_SOCKETS 1 -#include -#include -/* -#define ENOTCONN WSAENOTCONN -#define EWOULDBLOCK WSAEWOULDBLOCK -#define ENOBUFS WSAENOBUFS -#define ECONNRESET WSAECONNRESET -#define ESHUTDOWN WSAESHUTDOWN -#define EAFNOSUPPORT WSAEAFNOSUPPORT -#define EPROTONOSUPPORT WSAEPROTONOSUPPORT -#define EINPROGRESS WSAEINPROGRESS -#define EISCONN WSAEISCONN -#define ECONNREFUSED WSAECONNREFUSED -#define EHOSTUNREACH WSAEHOSTUNREACH -*/ - -/* winsock doesn't feature poll(), so there is a version implemented - * in terms of select() in mingw.c. The following definitions - * are copied from linux man pages. A poll() macro is defined to - * call the version in mingw.c. - */ -#define POLLIN 0x0001 /* There is data to read */ -#define POLLPRI 0x0002 /* There is urgent data to read */ -#define POLLOUT 0x0004 /* Writing now will not block */ -#define POLLERR 0x0008 /* Error condition */ -#define POLLHUP 0x0010 /* Hung up */ -#define POLLNVAL 0x0020 /* Invalid request: fd not open */ -struct pollfd { - SOCKET fd; /* file descriptor */ - short events; /* requested events */ - short revents; /* returned events */ -}; -#define poll(x, y, z) win32_poll(x, y, z) - -/* These wrappers do nothing special except set the global errno variable if - * an error occurs (winsock doesn't do this by default). They set errno - * to unix-like values (i.e. WSAEWOULDBLOCK is mapped to EAGAIN), so code - * outside of this file "shouldn't" have to worry about winsock specific error - * handling. - */ -//#define socket(x, y, z) win32_socket(x, y, z) -//#define connect(x, y, z) win32_connect(x, y, z) -//#define accept(x, y, z) win32_accept(x, y, z) -//#define shutdown(x, y) win32_shutdown(x, y) -//#define read(x, y, z) win32_read_socket(x, y, z) -//#define write(x, y, z) win32_write_socket(x, y, z) - -/* Winsock uses int instead of the usual socklen_t */ -typedef int socklen_t; - -int win32_poll(struct pollfd *, unsigned int, int); -//SOCKET win32_socket(int, int, int); -//int win32_connect(SOCKET, struct sockaddr*, socklen_t); -//SOCKET win32_accept(SOCKET, struct sockaddr*, socklen_t *); -//int win32_shutdown(SOCKET, int); -//int win32_close_socket(SOCKET fd); - -//#define strtok_r(x, y, z) win32_strtok_r(x, y, z) -//#define strsep(x,y) win32_strsep(x,y) - -char *win32_strtok_r(char *s, const char *delim, char **lasts); -char *win32_strsep(char **stringp, const char *delim); - -ssize_t win32_read_socket(SOCKET fd, void *buf, int n); -ssize_t win32_write_socket(SOCKET fd, void *buf, int n); - -//static inline void sleep(unsigned ms) { Sleep(ms*1000); } - -#endif - diff --git a/win/pthread.h b/win/pthread.h deleted file mode 100755 index e69de29bb..000000000